/* Minification failed. Returning unminified contents.
(96071,48-49): run-time error JS1013: Syntax error in regular expression: ,
 */
/*!
 * Modernizr v2.8.3
 * www.modernizr.com
 *
 * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
 * Available under the BSD and MIT licenses: www.modernizr.com/license/
 */
/*
 * Modernizr tests which native CSS3 and HTML5 features are available in
 * the current UA and makes the results available to you in two ways:
 * as properties on a global Modernizr object, and as classes on the
 * <html> element. This information allows you to progressively enhance
 * your pages with a granular level of control over the experience.
 *
 * Modernizr has an optional (not included) conditional resource loader
 * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
 * To get a build that includes Modernizr.load(), as well as choosing
 * which tests to include, go to www.modernizr.com/download/
 *
 * Authors        Faruk Ates, Paul Irish, Alex Sexton
 * Contributors   Ryan Seddon, Ben Alman
 */
window.Modernizr=function(window,document,undefined){/**
     * setCss applies given styles to the Modernizr DOM node.
     */
function setCss(str){mStyle.cssText=str}/**
     * setCssAll extrapolates all vendor-specific css strings.
     */
function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}/**
     * is returns a boolean for if typeof obj is exactly type.
     */
function is(obj,type){return typeof obj===type}/**
     * contains returns a boolean for if substr is found within str.
     */
function contains(str,substr){return!!~(""+str).indexOf(substr)}/*>>testprop*/
// testProps is a generic CSS / DOM property test.
// In testing support for a given CSS property, it's legit to test:
//    `elem.style[styleName] !== undefined`
// If the property is supported it will return an empty string,
// if unsupported it will return undefined.
// We'll take advantage of this quick test and skip setting a style
// on our modernizr element, but instead just testing undefined vs
// empty string.
// Because the testing of the CSS property names (with "-", as
// opposed to the camelCase DOM properties) is non-portable and
// non-standard but works in WebKit and IE (but not Gecko or Opera),
// we explicitly reject properties with dashes so that authors
// developing in WebKit or IE first don't end up with
// browser-specific content by accident.
function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined)return"pfx"!=prefixed||prop}return!1}/*>>testprop*/
// TODO :: add testDOMProps
/**
     * testDOMProps is a generic DOM property test; if a browser supports
     *   a certain property, it won't return undefined for it.
     */
function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined)
// return the property name as a string
// return the property name as a string
// let's bind a function
return elem===!1?props[i]:is(item,"function")?item.bind(elem||obj):item}return!1}/*>>testallprops*/
/**
     * testPropsAll tests a list of DOM properties we want to check against.
     *   We specify literally ALL possible (known and/or likely) properties on
     *   the element including the non-vendor prefixed one, for forward-
     *   compatibility.
     */
function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");
// did they call .prefixed('boxSizing') or are we just testing a prop?
// did they call .prefixed('boxSizing') or are we just testing a prop?
return is(prefixed,"string")||is(prefixed,"undefined")?testProps(props,prefixed):(props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" "),testDOMProps(props,prefixed,elem))}/*>>webforms*/
// input features and input types go directly onto the ret object, bypassing the tests loop.
// Hold this guy to execute in a moment.
function webforms(){/*>>input*/
// Run through HTML5's new input attributes to see if the UA understands any.
// We're using f which is the <input> element created early on
// Mike Taylr has created a comprehensive resource for testing these attributes
//   when applied to all input types:
//   miketaylr.com/code/input-type-attr.html
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
// Only input placeholder is tested while textarea's placeholder is not.
// Currently Safari 4 and Opera 11 have support only for the input placeholder
// Both tests are available in feature-detects/forms-placeholder.js
Modernizr.input=function(props){for(var i=0,len=props.length;i<len;i++)attrs[props[i]]=!!(props[i]in inputElem);
// safari false positive's on datalist: webk.it/74252
// see also github.com/Modernizr/Modernizr/issues/146
return attrs.list&&(attrs.list=!(!document.createElement("datalist")||!window.HTMLDataListElement)),attrs}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),/*>>input*/
/*>>inputtypes*/
// Run through HTML5's new input types to see if the UA understands any.
//   This is put behind the tests runloop because it doesn't return a
//   true/false like all the other tests; instead, it returns an object
//   containing each input type with its corresponding true/false value
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
Modernizr.inputtypes=function(props){for(var bool,inputElemType,defaultView,i=0,len=props.length;i<len;i++)inputElem.setAttribute("type",inputElemType=props[i]),bool="text"!==inputElem.type,
// We first check to see if the type we give it sticks..
// If the type does, we feed it a textual value, which shouldn't be valid.
// If the value doesn't stick, we know there's input sanitization which infers a custom UI
bool&&(inputElem.value=smile,inputElem.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(inputElemType)&&inputElem.style.WebkitAppearance!==undefined?(docElement.appendChild(inputElem),defaultView=document.defaultView,
// Safari 2-4 allows the smiley as a value, despite making a slider
bool=defaultView.getComputedStyle&&"textfield"!==defaultView.getComputedStyle(inputElem,null).WebkitAppearance&&
// Mobile android web browser has false positive, so must
// check the height to see if the widget is actually there.
0!==inputElem.offsetHeight,docElement.removeChild(inputElem)):/^(search|tel)$/.test(inputElemType)||(
// Real url and email support comes with prebaked validation.
bool=/^(url|email)$/.test(inputElemType)?inputElem.checkValidity&&inputElem.checkValidity()===!1:inputElem.value!=smile)),inputs[props[i]]=!!bool;return inputs}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var featureName,hasOwnProp,version="2.8.3",Modernizr={},/*>>cssclasses*/
// option for enabling the HTML classes to be added
enableClasses=!0,/*>>cssclasses*/
docElement=document.documentElement,/**
     * Create our "modernizr" element that we do most feature tests on.
     */
mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,/**
     * Create the input element for various Web Forms feature tests.
     */
inputElem=document.createElement("input"),/*>>smile*/
smile=":)",/*>>smile*/
toString={}.toString,
// TODO :: make the prefixes more granular
/*>>prefixes*/
// List of property values to set for css tests. See ticket #21
prefixes=" -webkit- -moz- -o- -ms- ".split(" "),/*>>prefixes*/
/*>>domprefixes*/
// Following spec is to expose vendor-specific style properties as:
//   elem.style.WebkitBorderRadius
// and the following would be incorrect:
//   elem.style.webkitBorderRadius
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
//   erik.eae.net/archives/2008/03/10/21.48.10/
// More here: github.com/Modernizr/Modernizr/issues/issue/21
omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),/*>>domprefixes*/
/*>>ns*/
ns={svg:"http://www.w3.org/2000/svg"},/*>>ns*/
tests={},inputs={},attrs={},classes=[],slice=classes.slice,// used in testing loop
/*>>teststyles*/
// Inject element with style element and some CSS rules
injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),
// After page load injecting a fake body doesn't work so check if body exists
body=document.body,
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
fakeBody=body||document.createElement("body");if(parseInt(nodes,10))
// In order not to give false positives we create a node for each test
// This also allows the method to scale for unspecified uses
for(;nodes--;)node=document.createElement("div"),node.id=testnames?testnames[nodes]:mod+(nodes+1),div.appendChild(node);
// <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
// when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
// with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
// msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
// Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
//avoid crashing IE8, if background image is used
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
// If this is done after page load we don't want to remove the body so check if body exists
return style=["&#173;",'<style id="s',mod,'">',rule,"</style>"].join(""),div.id=mod,(body?div:fakeBody).innerHTML+=style,fakeBody.appendChild(div),body||(fakeBody.style.background="",fakeBody.style.overflow="hidden",docOverflow=docElement.style.overflow,docElement.style.overflow="hidden",docElement.appendChild(fakeBody)),ret=callback(div,rule),body?div.parentNode.removeChild(div):(fakeBody.parentNode.removeChild(fakeBody),docElement.style.overflow=docOverflow),!!ret},/*>>teststyles*/
/*>>mq*/
// adapted from matchMedia polyfill
// by Scott Jehl and Paul Irish
// gist.github.com/786768
testMediaQuery=function(mq){var matchMedia=window.matchMedia||window.msMatchMedia;if(matchMedia)return matchMedia(mq)&&matchMedia(mq).matches||!1;var bool;return injectElementWithStyles("@media "+mq+" { #"+mod+" { position: absolute; } }",function(node){bool="absolute"==(window.getComputedStyle?getComputedStyle(node,null):node.currentStyle).position}),bool},/*>>mq*/
/*>>hasevent*/
//
// isEventSupported determines if a given element supports the given event
// kangax.github.com/iseventsupported/
//
// The following results are known incorrects:
//   Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
//   Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
//   ...
isEventSupported=function(){function isEventSupported(eventName,element){element=element||document.createElement(TAGNAMES[eventName]||"div"),eventName="on"+eventName;
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
var isSupported=eventName in element;
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
// If property was created, "remove it" (by setting value to `undefined`)
return isSupported||(element.setAttribute||(element=document.createElement("div")),element.setAttribute&&element.removeAttribute&&(element.setAttribute(eventName,""),isSupported=is(element[eventName],"function"),is(element[eventName],"undefined")||(element[eventName]=undefined),element.removeAttribute(eventName))),element=null,isSupported}var TAGNAMES={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return isEventSupported}(),/*>>hasevent*/
// TODO :: Add flag for hasownprop ? didn't last time
// hasOwnProperty shim by kangax needed for Safari 2.0 support
_hasOwnProperty={}.hasOwnProperty;hasOwnProp=is(_hasOwnProperty,"undefined")||is(_hasOwnProperty.call,"undefined")?function(object,property){/* yes, this can give false positives/negatives, but most of the time we don't care about those */
return property in object&&is(object.constructor.prototype[property],"undefined")}:function(object,property){return _hasOwnProperty.call(object,property)},
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
// es5.github.com/#x15.3.4.5
Function.prototype.bind||(Function.prototype.bind=function(that){var target=this;if("function"!=typeof target)throw new TypeError;var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F,result=target.apply(self,args.concat(slice.call(arguments)));return Object(result)===result?result:self}return target.apply(that,args.concat(slice.call(arguments)))};return bound}),/*>>testallprops*/
/**
     * Tests
     * -----
     */
// The *new* flexbox
// dev.w3.org/csswg/css3-flexbox
tests.flexbox=function(){return testPropsAll("flexWrap")},
// The *old* flexbox
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/
tests.flexboxlegacy=function(){return testPropsAll("boxDirection")},
// On the S60 and BB Storm, getContext exists, but always returns undefined
// so we actually have to call getContext() to verify
// github.com/Modernizr/Modernizr/issues/issue/97/
tests.canvas=function(){var elem=document.createElement("canvas");return!(!elem.getContext||!elem.getContext("2d"))},tests.canvastext=function(){return!(!Modernizr.canvas||!is(document.createElement("canvas").getContext("2d").fillText,"function"))},
// webk.it/70117 is tracking a legit WebGL feature detect proposal
// We do a soft detect which may false positive in order to avoid
// an expensive context creation: bugzil.la/732441
tests.webgl=function(){return!!window.WebGLRenderingContext},/*
     * The Modernizr.touch test only indicates if the browser supports
     *    touch events, which does not necessarily reflect a touchscreen
     *    device, as evidenced by tablets running Windows 7 or, alas,
     *    the Palm Pre / WebOS (touch) phones.
     *
     * Additionally, Chrome (desktop) used to lie about its support on this,
     *    but that has since been rectified: crbug.com/36415
     *
     * We also test for Firefox 4 Multitouch Support.
     *
     * For more info, see: modernizr.github.com/Modernizr/touch.html
     */
tests.touch=function(){var bool;return"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch?bool=!0:injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=9===node.offsetTop}),bool},
// geolocation is often considered a trivial feature detect...
// Turns out, it's quite tricky to get right:
//
// Using !!navigator.geolocation does two things we don't want. It:
//   1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
//   2. Disables page caching in WebKit: webk.it/43956
//
// Meanwhile, in Firefox < 8, an about:config setting could expose
// a false positive that would throw an exception: bugzil.la/688158
tests.geolocation=function(){return"geolocation"in navigator},tests.postmessage=function(){return!!window.postMessage},
// Chrome incognito mode used to throw an exception when using openDatabase
// It doesn't anymore.
tests.websqldatabase=function(){return!!window.openDatabase},
// Vendors had inconsistent prefixing with the experimental Indexed DB:
// - Webkit's implementation is accessible through webkitIndexedDB
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
// For speed, we don't test the legacy (and beta-only) indexedDB
tests.indexedDB=function(){return!!testPropsAll("indexedDB",window)},
// documentMode logic from YUI to filter out IE8 Compat Mode
//   which false positives.
tests.hashchange=function(){return isEventSupported("hashchange",window)&&(document.documentMode===undefined||document.documentMode>7)},
// Per 1.6:
// This used to be Modernizr.historymanagement but the longer
// name has been deprecated in favor of a shorter and property-matching one.
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// and in the first release thereafter disappear entirely.
tests.history=function(){return!(!window.history||!history.pushState)},tests.draganddrop=function(){var div=document.createElement("div");return"draggable"in div||"ondragstart"in div&&"ondrop"in div},
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
// FF10 still uses prefixes, so check for it until then.
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
tests.websockets=function(){return"WebSocket"in window||"MozWebSocket"in window},
// css-tricks.com/rgba-browser-support/
tests.rgba=function(){
// Set an rgba() color and check the returned value
return setCss("background-color:rgba(150,255,150,.5)"),contains(mStyle.backgroundColor,"rgba")},tests.hsla=function(){
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
//   except IE9 who retains it as hsla
return setCss("background-color:hsla(120,40%,100%,.5)"),contains(mStyle.backgroundColor,"rgba")||contains(mStyle.backgroundColor,"hsla")},tests.multiplebgs=function(){
// If the UA supports multiple backgrounds, there should be three occurrences
//   of the string "url(" in the return value for elemStyle.background
// Setting multiple images AND a color on the background shorthand property
//  and then querying the style.background property value for the number of
//  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
return setCss("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(mStyle.background)},
// this will false positive in Opera Mini
//   github.com/Modernizr/Modernizr/issues/396
tests.backgroundsize=function(){return testPropsAll("backgroundSize")},tests.borderimage=function(){return testPropsAll("borderImage")},
// Super comprehensive table about all the unique implementations of
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
tests.borderradius=function(){return testPropsAll("borderRadius")},
// WebOS unfortunately false positives on this test.
tests.boxshadow=function(){return testPropsAll("boxShadow")},
// FF3.0 will false positive on this test
tests.textshadow=function(){return""===document.createElement("div").style.textShadow},tests.opacity=function(){
// The non-literal . in this regex is intentional:
//   German Chrome returns this value as 0,55
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
// Browsers that actually have CSS Opacity implemented have done so
//  according to spec, which means their return values are within the
//  range of [0.0,1.0] - including the leading zero.
return setCssAll("opacity:.55"),/^0.55$/.test(mStyle.opacity)},
// Note, Android < 4 will pass this test, but can only animate
//   a single property at a time
//   goo.gl/v3V4Gp
tests.cssanimations=function(){return testPropsAll("animationName")},tests.csscolumns=function(){return testPropsAll("columnCount")},tests.cssgradients=function(){/**
         * For CSS Gradients syntax, please see:
         * webkit.org/blog/175/introducing-css-gradients/
         * developer.mozilla.org/en/CSS/-moz-linear-gradient
         * developer.mozilla.org/en/CSS/-moz-radial-gradient
         * dev.w3.org/csswg/css3-images/#gradients-
         */
var str1="background-image:",str2="gradient(linear,left top,right bottom,from(#9f9),to(white));",str3="linear-gradient(left top,#9f9, white);";
// legacy webkit syntax (FIXME: remove when syntax not in use anymore)
// standard syntax             // trailing 'background-image:'
return setCss((str1+"-webkit- ".split(" ").join(str2+str1)+prefixes.join(str3+str1)).slice(0,-str1.length)),contains(mStyle.backgroundImage,"gradient")},tests.cssreflections=function(){return testPropsAll("boxReflect")},tests.csstransforms=function(){return!!testPropsAll("transform")},tests.csstransforms3d=function(){var ret=!!testPropsAll("perspective");
// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
//   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
//   some conditions. As a result, Webkit typically recognizes the syntax but
//   will sometimes throw a false positive, thus we must do a more thorough check:
// Webkit allows this media query to succeed only if the feature is enabled.
// `@media (transform-3d),(-webkit-transform-3d){ ... }`
return ret&&"webkitPerspective"in docElement.style&&injectElementWithStyles("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(node,rule){ret=9===node.offsetLeft&&3===node.offsetHeight}),ret},tests.csstransitions=function(){return testPropsAll("transition")},/*>>fontface*/
// @font-face detection routine by Diego Perini
// javascript.nwbox.com/CSSSupport/
// false positives:
//   WebOS github.com/Modernizr/Modernizr/issues/342
//   WP7   github.com/Modernizr/Modernizr/issues/538
tests.fontface=function(){var bool;return injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}',function(node,rule){var style=document.getElementById("smodernizr"),sheet=style.sheet||style.styleSheet,cssText=sheet?sheet.cssRules&&sheet.cssRules[0]?sheet.cssRules[0].cssText:sheet.cssText||"":"";bool=/src/i.test(cssText)&&0===cssText.indexOf(rule.split(" ")[0])}),bool},/*>>fontface*/
// CSS generated content detection
tests.generatedcontent=function(){var bool;return injectElementWithStyles(["#",mod,"{font:0/0 a}#",mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(""),function(node){bool=node.offsetHeight>=3}),bool},
// These tests evaluate support of the video/audio elements, as well as
// testing what types of content they support.
//
// We're using the Boolean constructor here, so that we can extend the value
// e.g.  Modernizr.video     // true
//       Modernizr.video.ogg // 'probably'
//
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
//                     thx to NielsLeenheer and zcorpan
// Note: in some older browsers, "no" was a return value instead of empty string.
//   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
//   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
tests.video=function(){var elem=document.createElement("video"),bool=!1;
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
try{(bool=!!elem.canPlayType)&&(bool=new Boolean(bool),bool.ogg=elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
bool.h264=elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),bool.webm=elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(e){}return bool},tests.audio=function(){var elem=document.createElement("audio"),bool=!1;try{(bool=!!elem.canPlayType)&&(bool=new Boolean(bool),bool.ogg=elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),bool.mp3=elem.canPlayType("audio/mpeg;").replace(/^no$/,""),
// Mimetypes accepted:
//   developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
//   bit.ly/iphoneoscodecs
bool.wav=elem.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),bool.m4a=(elem.canPlayType("audio/x-m4a;")||elem.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(e){}return bool},
// In FF4, if disabled, window.localStorage should === null.
// Normally, we could not test that directly and need to do a
//   `('localStorage' in window) && ` test first because otherwise Firefox will
//   throw bugzil.la/365772 if cookies are disabled
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
// will throw the exception:
//   QUOTA_EXCEEDED_ERRROR DOM Exception 22.
// Peculiarly, getItem and removeItem calls do not throw.
// Because we are forced to try/catch this, we'll go aggressive.
// Just FWIW: IE8 Compat mode supports these features completely:
//   www.quirksmode.org/dom/html5.html
// But IE8 doesn't support either with local files
tests.localstorage=function(){try{return localStorage.setItem(mod,mod),localStorage.removeItem(mod),!0}catch(e){return!1}},tests.sessionstorage=function(){try{return sessionStorage.setItem(mod,mod),sessionStorage.removeItem(mod),!0}catch(e){return!1}},tests.webworkers=function(){return!!window.Worker},tests.applicationcache=function(){return!!window.applicationCache},
// Thanks to Erik Dahlstrom
tests.svg=function(){return!!document.createElementNS&&!!document.createElementNS(ns.svg,"svg").createSVGRect},
// specifically for SVG inline in HTML, not within XHTML
// test page: paulirish.com/demo/inline-svg
tests.inlinesvg=function(){var div=document.createElement("div");return div.innerHTML="<svg/>",(div.firstChild&&div.firstChild.namespaceURI)==ns.svg},
// SVG SMIL animation
tests.smil=function(){return!!document.createElementNS&&/SVGAnimate/.test(toString.call(document.createElementNS(ns.svg,"animate")))},
// This test is only for clip paths in SVG proper, not clip paths on HTML content
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
// However read the comments to dig into applying SVG clippaths to HTML content here:
//   github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
tests.svgclippaths=function(){return!!document.createElementNS&&/SVGClipPath/.test(toString.call(document.createElementNS(ns.svg,"clipPath")))};/*>>webforms*/
// End of test definitions
// -----------------------
// Run through all tests and detect their support in the current UA.
// todo: hypothetically we could be doing an array of tests and use a basic loop here.
for(var feature in tests)hasOwnProp(tests,feature)&&(
// run the test, throw the return value into the Modernizr,
//   then based on that boolean, define an appropriate className
//   and push it into an array of classes we'll join later.
featureName=feature.toLowerCase(),Modernizr[featureName]=tests[feature](),classes.push((Modernizr[featureName]?"":"no-")+featureName));/*>>cssclasses*/
/*>>webforms*/
// input tests need to run.
/*>>webforms*/
/**
     * addTest allows the user to define their own feature tests
     * the result will be added onto the Modernizr object,
     * as well as an appropriate className set on the html element
     *
     * @param feature - String naming the feature
     * @param test - Function returning true if feature is supported, false if not
     */
// Reset modElem.cssText to nothing to reduce memory footprint.
/*>>shiv*/
// Assign private properties to the return object with prefix
// expose these for the plugin API. Look in the source for how to join() them against your input
/*>>prefixes*/
/*>>prefixes*/
/*>>domprefixes*/
/*>>domprefixes*/
/*>>mq*/
// Modernizr.mq tests a given media query, live against the current state of the window
// A few important notes:
//   * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
//   * A max-width or orientation query will be evaluated against the current state, which may change later.
//   * You must specify values. Eg. If you are testing support for the min-width media query use:
//       Modernizr.mq('(min-width:0)')
// usage:
// Modernizr.mq('only screen and (max-width:768)')
/*>>mq*/
/*>>hasevent*/
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on
// Modernizr.hasEvent('gesturestart', elem)
/*>>hasevent*/
/*>>testprop*/
// Modernizr.testProp() investigates whether a given style property is recognized
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testProp('pointerEvents')
/*>>testprop*/
/*>>testallprops*/
// Modernizr.testAllProps() investigates whether a given style property,
//   or any of its vendor-prefixed variants, is recognized
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testAllProps('boxSizing')
/*>>testallprops*/
/*>>teststyles*/
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
/*>>teststyles*/
/*>>prefixed*/
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
//
//     str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
// If you're trying to ascertain which transition end event to bind to, you might do something like...
//
//     var transEndEventNames = {
//       'WebkitTransition' : 'webkitTransitionEnd',
//       'MozTransition'    : 'transitionend',
//       'OTransition'      : 'oTransitionEnd',
//       'msTransition'     : 'MSTransitionEnd',
//       'transition'       : 'transitionend'
//     },
//     transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
/*>>prefixed*/
/*>>cssclasses*/
// Remove "no-js" class from <html> element, if it exists:
// Add the new classes to the <html> element.
return Modernizr.input||webforms(),Modernizr.addTest=function(feature,test){if("object"==typeof feature)for(var key in feature)hasOwnProp(feature,key)&&Modernizr.addTest(key,feature[key]);else{if(feature=feature.toLowerCase(),Modernizr[feature]!==undefined)
// we're going to quit if you're trying to overwrite an existing test
// if we were to allow it, we'd do this:
//   var re = new RegExp("\\b(no-)?" + feature + "\\b");
//   docElement.className = docElement.className.replace( re, '' );
// but, no rly, stuff 'em.
return Modernizr;test="function"==typeof test?test():test,"undefined"!=typeof enableClasses&&enableClasses&&(docElement.className+=" "+(test?"":"no-")+feature),Modernizr[feature]=test}return Modernizr},setCss(""),modElem=inputElem=null,function(window,document){/*--------------------------------------------------------------------------*/
/**
         * Creates a style sheet with the given CSS text and adds it to the document.
         * @private
         * @param {Document} ownerDocument The document.
         * @param {String} cssText The CSS text.
         * @returns {StyleSheet} The style element.
         */
function addStyleSheet(ownerDocument,cssText){var p=ownerDocument.createElement("p"),parent=ownerDocument.getElementsByTagName("head")[0]||ownerDocument.documentElement;return p.innerHTML="x<style>"+cssText+"</style>",parent.insertBefore(p.lastChild,parent.firstChild)}/**
         * Returns the value of `html5.elements` as an array.
         * @private
         * @returns {Array} An array of shived element node names.
         */
function getElements(){var elements=html5.elements;return"string"==typeof elements?elements.split(" "):elements}/**
         * Returns the data associated to the given document
         * @private
         * @param {Document} ownerDocument The document.
         * @returns {Object} An object of data.
         */
function getExpandoData(ownerDocument){var data=expandoData[ownerDocument[expando]];return data||(data={},expanID++,ownerDocument[expando]=expanID,expandoData[expanID]=data),data}/**
         * returns a shived element for the given nodeName and document
         * @memberOf html5
         * @param {String} nodeName name of the element
         * @param {Document} ownerDocument The context document.
         * @returns {Object} The shived element.
         */
function createElement(nodeName,ownerDocument,data){if(ownerDocument||(ownerDocument=document),supportsUnknownElements)return ownerDocument.createElement(nodeName);data||(data=getExpandoData(ownerDocument));var node;
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
//   is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
//   a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
//   or `text` property is set
return node=data.cache[nodeName]?data.cache[nodeName].cloneNode():saveClones.test(nodeName)?(data.cache[nodeName]=data.createElem(nodeName)).cloneNode():data.createElem(nodeName),!node.canHaveChildren||reSkip.test(nodeName)||node.tagUrn?node:data.frag.appendChild(node)}/**
         * returns a shived DocumentFragment for the given document
         * @memberOf html5
         * @param {Document} ownerDocument The context document.
         * @returns {Object} The shived DocumentFragment.
         */
function createDocumentFragment(ownerDocument,data){if(ownerDocument||(ownerDocument=document),supportsUnknownElements)return ownerDocument.createDocumentFragment();data=data||getExpandoData(ownerDocument);for(var clone=data.frag.cloneNode(),i=0,elems=getElements(),l=elems.length;i<l;i++)clone.createElement(elems[i]);return clone}/**
         * Shivs the `createElement` and `createDocumentFragment` methods of the document.
         * @private
         * @param {Document|DocumentFragment} ownerDocument The document.
         * @param {Object} data of the document.
         */
function shivMethods(ownerDocument,data){data.cache||(data.cache={},data.createElem=ownerDocument.createElement,data.createFrag=ownerDocument.createDocumentFragment,data.frag=data.createFrag()),ownerDocument.createElement=function(nodeName){
//abort shiv
//abort shiv
return html5.shivMethods?createElement(nodeName,ownerDocument,data):data.createElem(nodeName)},ownerDocument.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+
// unroll the `createElement` calls
getElements().join().replace(/[\w\-]+/g,function(nodeName){return data.createElem(nodeName),data.frag.createElement(nodeName),'c("'+nodeName+'")'})+");return n}")(html5,data.frag)}/*--------------------------------------------------------------------------*/
/**
         * Shivs the given document.
         * @memberOf html5
         * @param {Document} ownerDocument The document to shiv.
         * @returns {Document} The shived document.
         */
function shivDocument(ownerDocument){ownerDocument||(ownerDocument=document);var data=getExpandoData(ownerDocument);
// corrects block display not defined in IE6/7/8/9
return!html5.shivCSS||supportsHtml5Styles||data.hasCSS||(data.hasCSS=!!addStyleSheet(ownerDocument,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),supportsUnknownElements||shivMethods(ownerDocument,data),ownerDocument}/*jshint evil:true */
/** version */
var supportsHtml5Styles,supportsUnknownElements,version="3.7.0",options=window.html5||{},reSkip=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,saveClones=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,expando="_html5shiv",expanID=0,expandoData={};!function(){try{var a=document.createElement("a");a.innerHTML="<xyz></xyz>",
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles="hidden"in a,supportsUnknownElements=1==a.childNodes.length||function(){
// assign a false positive if unable to shiv
document.createElement("a");var frag=document.createDocumentFragment();return"undefined"==typeof frag.cloneNode||"undefined"==typeof frag.createDocumentFragment||"undefined"==typeof frag.createElement}()}catch(e){
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles=!0,supportsUnknownElements=!0}}();/*--------------------------------------------------------------------------*/
/**
         * The `html5` object is exposed so that more elements can be shived and
         * existing shiving can be detected on iframes.
         * @type Object
         * @example
         *
         * // options can be changed before the script is included
         * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
         */
var html5={/**
           * An array or space separated string of node names of the elements to shiv.
           * @memberOf html5
           * @type Array|String
           */
elements:options.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",/**
           * current version of html5shiv
           */
version:version,/**
           * A flag to indicate that the HTML5 style sheet should be inserted.
           * @memberOf html5
           * @type Boolean
           */
shivCSS:options.shivCSS!==!1,/**
           * Is equal to true if a browser supports creating unknown/HTML5 elements
           * @memberOf html5
           * @type boolean
           */
supportsUnknownElements:supportsUnknownElements,/**
           * A flag to indicate that the document's `createElement` and `createDocumentFragment`
           * methods should be overwritten.
           * @memberOf html5
           * @type Boolean
           */
shivMethods:options.shivMethods!==!1,/**
           * A string to describe the type of `html5` object ("default" or "default print").
           * @memberOf html5
           * @type String
           */
type:"default",
// shivs the document according to the specified `html5` object options
shivDocument:shivDocument,
//creates a shived element
createElement:createElement,
//creates a shived documentFragment
createDocumentFragment:createDocumentFragment};/*--------------------------------------------------------------------------*/
// expose html5
window.html5=html5,
// shiv the document
shivDocument(document)}(this,document),Modernizr._version=version,Modernizr._prefixes=prefixes,Modernizr._domPrefixes=domPrefixes,Modernizr._cssomPrefixes=cssomPrefixes,Modernizr.mq=testMediaQuery,Modernizr.hasEvent=isEventSupported,Modernizr.testProp=function(prop){return testProps([prop])},Modernizr.testAllProps=testPropsAll,Modernizr.testStyles=injectElementWithStyles,Modernizr.prefixed=function(prop,obj,elem){return obj?testPropsAll(prop,obj,elem):testPropsAll(prop,"pfx")},docElement.className=docElement.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(enableClasses?" js "+classes.join(" "):""),Modernizr}(this,this.document);;
(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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";

// rawAsap provides everything we need except exception management.
var rawAsap = require("./raw");
// RawTasks are recycled to reduce GC churn.
var freeTasks = [];
// We queue errors to ensure they are thrown in right order (FIFO).
// Array-as-queue is good enough here, since we are just dealing with exceptions.
var pendingErrors = [];
var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);

function throwFirstError() {
    if (pendingErrors.length) {
        throw pendingErrors.shift();
    }
}

/**
 * Calls a task as soon as possible after returning, in its own event, with priority
 * over other events like animation, reflow, and repaint. An error thrown from an
 * event will not interrupt, nor even substantially slow down the processing of
 * other events, but will be rather postponed to a lower priority event.
 * @param {{call}} task A callable object, typically a function that takes no
 * arguments.
 */
module.exports = asap;
function asap(task) {
    var rawTask;
    if (freeTasks.length) {
        rawTask = freeTasks.pop();
    } else {
        rawTask = new RawTask();
    }
    rawTask.task = task;
    rawAsap(rawTask);
}

// We wrap tasks with recyclable task objects.  A task object implements
// `call`, just like a function.
function RawTask() {
    this.task = null;
}

// The sole purpose of wrapping the task is to catch the exception and recycle
// the task object after its single use.
RawTask.prototype.call = function () {
    try {
        this.task.call();
    } catch (error) {
        if (asap.onerror) {
            // This hook exists purely for testing purposes.
            // Its name will be periodically randomized to break any code that
            // depends on its existence.
            asap.onerror(error);
        } else {
            // In a web browser, exceptions are not fatal. However, to avoid
            // slowing down the queue of pending tasks, we rethrow the error in a
            // lower priority turn.
            pendingErrors.push(error);
            requestErrorThrow();
        }
    } finally {
        this.task = null;
        freeTasks[freeTasks.length] = this;
    }
};

},{"./raw":2}],2:[function(require,module,exports){
(function (global){
"use strict";

// Use the fastest means possible to execute a task in its own turn, with
// priority over other events including IO, animation, reflow, and redraw
// events in browsers.
//
// An exception thrown by a task will permanently interrupt the processing of
// subsequent tasks. The higher level `asap` function ensures that if an
// exception is thrown by a task, that the task queue will continue flushing as
// soon as possible, but if you use `rawAsap` directly, you are responsible to
// either ensure that no exceptions are thrown from your task, or to manually
// call `rawAsap.requestFlush` if an exception is thrown.
module.exports = rawAsap;
function rawAsap(task) {
    if (!queue.length) {
        requestFlush();
        flushing = true;
    }
    // Equivalent to push, but avoids a function call.
    queue[queue.length] = task;
}

var queue = [];
// Once a flush has been requested, no further calls to `requestFlush` are
// necessary until the next `flush` completes.
var flushing = false;
// `requestFlush` is an implementation-specific method that attempts to kick
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
// the event queue before yielding to the browser's own event loop.
var requestFlush;
// The position of the next task to execute in the task queue. This is
// preserved between calls to `flush` so that it can be resumed if
// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grow
// unbounded. To prevent memory exhaustion, the task queue will periodically
// truncate already-completed tasks.
var capacity = 1024;

// The flush function processes all tasks that have been scheduled with
// `rawAsap` unless and until one of those tasks throws an exception.
// If a task throws an exception, `flush` ensures that its state will remain
// consistent and will resume where it left off when called again.
// However, `flush` does not make any arrangements to be called again if an
// exception is thrown.
function flush() {
    while (index < queue.length) {
        var currentIndex = index;
        // Advance the index before calling the task. This ensures that we will
        // begin flushing on the next task the task throws an error.
        index = index + 1;
        queue[currentIndex].call();
        // Prevent leaking memory for long chains of recursive calls to `asap`.
        // If we call `asap` within tasks scheduled by `asap`, the queue will
        // grow, but to avoid an O(n) walk for every task we execute, we don't
        // shift tasks off the queue after they have been executed.
        // Instead, we periodically shift 1024 tasks off the queue.
        if (index > capacity) {
            // Manually shift all values starting at the index back to the
            // beginning of the queue.
            for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
                queue[scan] = queue[scan + index];
            }
            queue.length -= index;
            index = 0;
        }
    }
    queue.length = 0;
    index = 0;
    flushing = false;
}

// `requestFlush` is implemented using a strategy based on data collected from
// every available SauceLabs Selenium web driver worker at time of writing.
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593

// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
// have WebKitMutationObserver but not un-prefixed MutationObserver.
// Must use `global` or `self` instead of `window` to work in both frames and web
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.

/* globals self */
var scope = typeof global !== "undefined" ? global : self;
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;

// MutationObservers are desirable because they have high priority and work
// reliably everywhere they are implemented.
// They are implemented in all modern browsers.
//
// - Android 4-4.3
// - Chrome 26-34
// - Firefox 14-29
// - Internet Explorer 11
// - iPad Safari 6-7.1
// - iPhone Safari 7-7.1
// - Safari 6-7
if (typeof BrowserMutationObserver === "function") {
    requestFlush = makeRequestCallFromMutationObserver(flush);

// MessageChannels are desirable because they give direct access to the HTML
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
// 11-12, and in web workers in many engines.
// Although message channels yield to any queued rendering and IO tasks, they
// would be better than imposing the 4ms delay of timers.
// However, they do not work reliably in Internet Explorer or Safari.

// Internet Explorer 10 is the only browser that has setImmediate but does
// not have MutationObservers.
// Although setImmediate yields to the browser's renderer, it would be
// preferrable to falling back to setTimeout since it does not have
// the minimum 4ms penalty.
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
// Desktop to a lesser extent) that renders both setImmediate and
// MessageChannel useless for the purposes of ASAP.
// https://github.com/kriskowal/q/issues/396

// Timers are implemented universally.
// We fall back to timers in workers in most engines, and in foreground
// contexts in the following browsers.
// However, note that even this simple case requires nuances to operate in a
// broad spectrum of browsers.
//
// - Firefox 3-13
// - Internet Explorer 6-9
// - iPad Safari 4.3
// - Lynx 2.8.7
} else {
    requestFlush = makeRequestCallFromTimer(flush);
}

// `requestFlush` requests that the high priority event queue be flushed as
// soon as possible.
// This is useful to prevent an error thrown in a task from stalling the event
// queue if the exception handled by Node.js’s
// `process.on("uncaughtException")` or by a domain.
rawAsap.requestFlush = requestFlush;

// To request a high priority event, we induce a mutation observer by toggling
// the text of a text node between "1" and "-1".
function makeRequestCallFromMutationObserver(callback) {
    var toggle = 1;
    var observer = new BrowserMutationObserver(callback);
    var node = document.createTextNode("");
    observer.observe(node, {characterData: true});
    return function requestCall() {
        toggle = -toggle;
        node.data = toggle;
    };
}

// The message channel technique was discovered by Malte Ubl and was the
// original foundation for this library.
// http://www.nonblocking.io/2011/06/windownexttick.html

// Safari 6.0.5 (at least) intermittently fails to create message ports on a
// page's first load. Thankfully, this version of Safari supports
// MutationObservers, so we don't need to fall back in that case.

// function makeRequestCallFromMessageChannel(callback) {
//     var channel = new MessageChannel();
//     channel.port1.onmessage = callback;
//     return function requestCall() {
//         channel.port2.postMessage(0);
//     };
// }

// For reasons explained above, we are also unable to use `setImmediate`
// under any circumstances.
// Even if we were, there is another bug in Internet Explorer 10.
// It is not sufficient to assign `setImmediate` to `requestFlush` because
// `setImmediate` must be called *by name* and therefore must be wrapped in a
// closure.
// Never forget.

// function makeRequestCallFromSetImmediate(callback) {
//     return function requestCall() {
//         setImmediate(callback);
//     };
// }

// Safari 6.0 has a problem where timers will get lost while the user is
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
// mutation observers, so that implementation is used instead.
// However, if we ever elect to use timers in Safari, the prevalent work-around
// is to add a scroll event listener that calls for a flush.

// `setTimeout` does not call the passed callback if the delay is less than
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
// even then.

function makeRequestCallFromTimer(callback) {
    return function requestCall() {
        // We dispatch a timeout with a specified delay of 0 for engines that
        // can reliably accommodate that request. This will usually be snapped
        // to a 4 milisecond delay, but once we're flushing, there's no delay
        // between events.
        var timeoutHandle = setTimeout(handleTimer, 0);
        // However, since this timer gets frequently dropped in Firefox
        // workers, we enlist an interval handle that will try to fire
        // an event 20 times per second until it succeeds.
        var intervalHandle = setInterval(handleTimer, 50);

        function handleTimer() {
            // Whichever timer succeeds will cancel both timers and
            // execute the callback.
            clearTimeout(timeoutHandle);
            clearInterval(intervalHandle);
            callback();
        }
    };
}

// This is for `asap.js` only.
// Its name will be periodically randomized to break any code that depends on
// its existence.
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;

// ASAP was originally a nextTick shim included in Q. This was factored out
// into this ASAP package. It was later adapted to RSVP which made further
// amendments. These decisions, particularly to marginalize MessageChannel and
// to capture the MutationObserver implementation in a closure, were integrated
// back into ASAP proper.
// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],3:[function(require,module,exports){
(function (global){
"use strict";

require("core-js/shim");

require("regenerator-runtime/runtime");

require("core-js/fn/regexp/escape");

if (global._babelPolyfill) {
  throw new Error("only one instance of babel-polyfill is allowed");
}
global._babelPolyfill = true;

var DEFINE_PROPERTY = "defineProperty";
function define(O, key, value) {
  O[key] || Object[DEFINE_PROPERTY](O, key, {
    writable: true,
    configurable: true,
    value: value
  });
}

define(String.prototype, "padLeft", "".padStart);
define(String.prototype, "padRight", "".padEnd);

"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function (key) {
  [][key] && define(Array, key, Function.call.bind([][key]));
});
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"core-js/fn/regexp/escape":4,"core-js/shim":297,"regenerator-runtime/runtime":545}],4:[function(require,module,exports){
require('../../modules/core.regexp.escape');
module.exports = require('../../modules/_core').RegExp.escape;
},{"../../modules/_core":25,"../../modules/core.regexp.escape":121}],5:[function(require,module,exports){
module.exports = function(it){
  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
  return it;
};
},{}],6:[function(require,module,exports){
var cof = require('./_cof');
module.exports = function(it, msg){
  if(typeof it != 'number' && cof(it) != 'Number')throw TypeError(msg);
  return +it;
};
},{"./_cof":20}],7:[function(require,module,exports){
// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = require('./_wks')('unscopables')
  , ArrayProto  = Array.prototype;
if(ArrayProto[UNSCOPABLES] == undefined)require('./_hide')(ArrayProto, UNSCOPABLES, {});
module.exports = function(key){
  ArrayProto[UNSCOPABLES][key] = true;
};
},{"./_hide":42,"./_wks":119}],8:[function(require,module,exports){
module.exports = function(it, Constructor, name, forbiddenField){
  if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){
    throw TypeError(name + ': incorrect invocation!');
  } return it;
};
},{}],9:[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function(it){
  if(!isObject(it))throw TypeError(it + ' is not an object!');
  return it;
};
},{"./_is-object":51}],10:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
'use strict';
var toObject = require('./_to-object')
  , toIndex  = require('./_to-index')
  , toLength = require('./_to-length');

module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){
  var O     = toObject(this)
    , len   = toLength(O.length)
    , to    = toIndex(target, len)
    , from  = toIndex(start, len)
    , end   = arguments.length > 2 ? arguments[2] : undefined
    , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)
    , inc   = 1;
  if(from < to && to < from + count){
    inc  = -1;
    from += count - 1;
    to   += count - 1;
  }
  while(count-- > 0){
    if(from in O)O[to] = O[from];
    else delete O[to];
    to   += inc;
    from += inc;
  } return O;
};
},{"./_to-index":107,"./_to-length":110,"./_to-object":111}],11:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
'use strict';
var toObject = require('./_to-object')
  , toIndex  = require('./_to-index')
  , toLength = require('./_to-length');
module.exports = function fill(value /*, start = 0, end = @length */){
  var O      = toObject(this)
    , length = toLength(O.length)
    , aLen   = arguments.length
    , index  = toIndex(aLen > 1 ? arguments[1] : undefined, length)
    , end    = aLen > 2 ? arguments[2] : undefined
    , endPos = end === undefined ? length : toIndex(end, length);
  while(endPos > index)O[index++] = value;
  return O;
};
},{"./_to-index":107,"./_to-length":110,"./_to-object":111}],12:[function(require,module,exports){
var forOf = require('./_for-of');

module.exports = function(iter, ITERATOR){
  var result = [];
  forOf(iter, false, result.push, result, ITERATOR);
  return result;
};

},{"./_for-of":39}],13:[function(require,module,exports){
// false -> Array#indexOf
// true  -> Array#includes
var toIObject = require('./_to-iobject')
  , toLength  = require('./_to-length')
  , toIndex   = require('./_to-index');
module.exports = function(IS_INCLUDES){
  return function($this, el, fromIndex){
    var O      = toIObject($this)
      , length = toLength(O.length)
      , index  = toIndex(fromIndex, length)
      , value;
    // Array#includes uses SameValueZero equality algorithm
    if(IS_INCLUDES && el != el)while(length > index){
      value = O[index++];
      if(value != value)return true;
    // Array#toIndex ignores holes, Array#includes - not
    } else for(;length > index; index++)if(IS_INCLUDES || index in O){
      if(O[index] === el)return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};
},{"./_to-index":107,"./_to-iobject":109,"./_to-length":110}],14:[function(require,module,exports){
// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx      = require('./_ctx')
  , IObject  = require('./_iobject')
  , toObject = require('./_to-object')
  , toLength = require('./_to-length')
  , asc      = require('./_array-species-create');
module.exports = function(TYPE, $create){
  var IS_MAP        = TYPE == 1
    , IS_FILTER     = TYPE == 2
    , IS_SOME       = TYPE == 3
    , IS_EVERY      = TYPE == 4
    , IS_FIND_INDEX = TYPE == 6
    , NO_HOLES      = TYPE == 5 || IS_FIND_INDEX
    , create        = $create || asc;
  return function($this, callbackfn, that){
    var O      = toObject($this)
      , self   = IObject(O)
      , f      = ctx(callbackfn, that, 3)
      , length = toLength(self.length)
      , index  = 0
      , result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined
      , val, res;
    for(;length > index; index++)if(NO_HOLES || index in self){
      val = self[index];
      res = f(val, index, O);
      if(TYPE){
        if(IS_MAP)result[index] = res;            // map
        else if(res)switch(TYPE){
          case 3: return true;                    // some
          case 5: return val;                     // find
          case 6: return index;                   // findIndex
          case 2: result.push(val);               // filter
        } else if(IS_EVERY)return false;          // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  };
};
},{"./_array-species-create":17,"./_ctx":27,"./_iobject":47,"./_to-length":110,"./_to-object":111}],15:[function(require,module,exports){
var aFunction = require('./_a-function')
  , toObject  = require('./_to-object')
  , IObject   = require('./_iobject')
  , toLength  = require('./_to-length');

module.exports = function(that, callbackfn, aLen, memo, isRight){
  aFunction(callbackfn);
  var O      = toObject(that)
    , self   = IObject(O)
    , length = toLength(O.length)
    , index  = isRight ? length - 1 : 0
    , i      = isRight ? -1 : 1;
  if(aLen < 2)for(;;){
    if(index in self){
      memo = self[index];
      index += i;
      break;
    }
    index += i;
    if(isRight ? index < 0 : length <= index){
      throw TypeError('Reduce of empty array with no initial value');
    }
  }
  for(;isRight ? index >= 0 : length > index; index += i)if(index in self){
    memo = callbackfn(memo, self[index], index, O);
  }
  return memo;
};
},{"./_a-function":5,"./_iobject":47,"./_to-length":110,"./_to-object":111}],16:[function(require,module,exports){
var isObject = require('./_is-object')
  , isArray  = require('./_is-array')
  , SPECIES  = require('./_wks')('species');

module.exports = function(original){
  var C;
  if(isArray(original)){
    C = original.constructor;
    // cross-realm fallback
    if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;
    if(isObject(C)){
      C = C[SPECIES];
      if(C === null)C = undefined;
    }
  } return C === undefined ? Array : C;
};
},{"./_is-array":49,"./_is-object":51,"./_wks":119}],17:[function(require,module,exports){
// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = require('./_array-species-constructor');

module.exports = function(original, length){
  return new (speciesConstructor(original))(length);
};
},{"./_array-species-constructor":16}],18:[function(require,module,exports){
'use strict';
var aFunction  = require('./_a-function')
  , isObject   = require('./_is-object')
  , invoke     = require('./_invoke')
  , arraySlice = [].slice
  , factories  = {};

var construct = function(F, len, args){
  if(!(len in factories)){
    for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';
    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
  } return factories[len](F, args);
};

module.exports = Function.bind || function bind(that /*, args... */){
  var fn       = aFunction(this)
    , partArgs = arraySlice.call(arguments, 1);
  var bound = function(/* args... */){
    var args = partArgs.concat(arraySlice.call(arguments));
    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
  };
  if(isObject(fn.prototype))bound.prototype = fn.prototype;
  return bound;
};
},{"./_a-function":5,"./_invoke":46,"./_is-object":51}],19:[function(require,module,exports){
// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = require('./_cof')
  , TAG = require('./_wks')('toStringTag')
  // ES3 wrong here
  , ARG = cof(function(){ return arguments; }()) == 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function(it, key){
  try {
    return it[key];
  } catch(e){ /* empty */ }
};

module.exports = function(it){
  var O, T, B;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
    // builtinTag case
    : ARG ? cof(O)
    // ES3 arguments fallback
    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};
},{"./_cof":20,"./_wks":119}],20:[function(require,module,exports){
var toString = {}.toString;

module.exports = function(it){
  return toString.call(it).slice(8, -1);
};
},{}],21:[function(require,module,exports){
'use strict';
var dP          = require('./_object-dp').f
  , create      = require('./_object-create')
  , redefineAll = require('./_redefine-all')
  , ctx         = require('./_ctx')
  , anInstance  = require('./_an-instance')
  , defined     = require('./_defined')
  , forOf       = require('./_for-of')
  , $iterDefine = require('./_iter-define')
  , step        = require('./_iter-step')
  , setSpecies  = require('./_set-species')
  , DESCRIPTORS = require('./_descriptors')
  , fastKey     = require('./_meta').fastKey
  , SIZE        = DESCRIPTORS ? '_s' : 'size';

var getEntry = function(that, key){
  // fast case
  var index = fastKey(key), entry;
  if(index !== 'F')return that._i[index];
  // frozen object case
  for(entry = that._f; entry; entry = entry.n){
    if(entry.k == key)return entry;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = create(null); // index
      that._f = undefined;    // first entry
      that._l = undefined;    // last entry
      that[SIZE] = 0;         // size
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear(){
        for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){
          entry.r = true;
          if(entry.p)entry.p = entry.p.n = undefined;
          delete data[entry.i];
        }
        that._f = that._l = undefined;
        that[SIZE] = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function(key){
        var that  = this
          , entry = getEntry(that, key);
        if(entry){
          var next = entry.n
            , prev = entry.p;
          delete that._i[entry.i];
          entry.r = true;
          if(prev)prev.n = next;
          if(next)next.p = prev;
          if(that._f == entry)that._f = next;
          if(that._l == entry)that._l = prev;
          that[SIZE]--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /*, that = undefined */){
        anInstance(this, C, 'forEach');
        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
          , entry;
        while(entry = entry ? entry.n : this._f){
          f(entry.v, entry.k, this);
          // revert to the last existing entry
          while(entry && entry.r)entry = entry.p;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key){
        return !!getEntry(this, key);
      }
    });
    if(DESCRIPTORS)dP(C.prototype, 'size', {
      get: function(){
        return defined(this[SIZE]);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var entry = getEntry(that, key)
      , prev, index;
    // change existing entry
    if(entry){
      entry.v = value;
    // create new entry
    } else {
      that._l = entry = {
        i: index = fastKey(key, true), // <- index
        k: key,                        // <- key
        v: value,                      // <- value
        p: prev = that._l,             // <- previous entry
        n: undefined,                  // <- next entry
        r: false                       // <- removed
      };
      if(!that._f)that._f = entry;
      if(prev)prev.n = entry;
      that[SIZE]++;
      // add to index
      if(index !== 'F')that._i[index] = entry;
    } return that;
  },
  getEntry: getEntry,
  setStrong: function(C, NAME, IS_MAP){
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    $iterDefine(C, NAME, function(iterated, kind){
      this._t = iterated;  // target
      this._k = kind;      // kind
      this._l = undefined; // previous
    }, function(){
      var that  = this
        , kind  = that._k
        , entry = that._l;
      // revert to the last existing entry
      while(entry && entry.r)entry = entry.p;
      // get next entry
      if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){
        // or finish the iteration
        that._t = undefined;
        return step(1);
      }
      // return step by kind
      if(kind == 'keys'  )return step(0, entry.k);
      if(kind == 'values')return step(0, entry.v);
      return step(0, [entry.k, entry.v]);
    }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(NAME);
  }
};
},{"./_an-instance":8,"./_ctx":27,"./_defined":29,"./_descriptors":30,"./_for-of":39,"./_iter-define":55,"./_iter-step":57,"./_meta":64,"./_object-create":68,"./_object-dp":69,"./_redefine-all":88,"./_set-species":93}],22:[function(require,module,exports){
// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var classof = require('./_classof')
  , from    = require('./_array-from-iterable');
module.exports = function(NAME){
  return function toJSON(){
    if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic");
    return from(this);
  };
};
},{"./_array-from-iterable":12,"./_classof":19}],23:[function(require,module,exports){
'use strict';
var redefineAll       = require('./_redefine-all')
  , getWeak           = require('./_meta').getWeak
  , anObject          = require('./_an-object')
  , isObject          = require('./_is-object')
  , anInstance        = require('./_an-instance')
  , forOf             = require('./_for-of')
  , createArrayMethod = require('./_array-methods')
  , $has              = require('./_has')
  , arrayFind         = createArrayMethod(5)
  , arrayFindIndex    = createArrayMethod(6)
  , id                = 0;

// fallback for uncaught frozen keys
var uncaughtFrozenStore = function(that){
  return that._l || (that._l = new UncaughtFrozenStore);
};
var UncaughtFrozenStore = function(){
  this.a = [];
};
var findUncaughtFrozen = function(store, key){
  return arrayFind(store.a, function(it){
    return it[0] === key;
  });
};
UncaughtFrozenStore.prototype = {
  get: function(key){
    var entry = findUncaughtFrozen(this, key);
    if(entry)return entry[1];
  },
  has: function(key){
    return !!findUncaughtFrozen(this, key);
  },
  set: function(key, value){
    var entry = findUncaughtFrozen(this, key);
    if(entry)entry[1] = value;
    else this.a.push([key, value]);
  },
  'delete': function(key){
    var index = arrayFindIndex(this.a, function(it){
      return it[0] === key;
    });
    if(~index)this.a.splice(index, 1);
    return !!~index;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = id++;      // collection id
      that._l = undefined; // leak store for uncaught frozen objects
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.3.3.2 WeakMap.prototype.delete(key)
      // 23.4.3.3 WeakSet.prototype.delete(value)
      'delete': function(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this)['delete'](key);
        return data && $has(data, this._i) && delete data[this._i];
      },
      // 23.3.3.4 WeakMap.prototype.has(key)
      // 23.4.3.4 WeakSet.prototype.has(value)
      has: function has(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this).has(key);
        return data && $has(data, this._i);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var data = getWeak(anObject(key), true);
    if(data === true)uncaughtFrozenStore(that).set(key, value);
    else data[that._i] = value;
    return that;
  },
  ufstore: uncaughtFrozenStore
};
},{"./_an-instance":8,"./_an-object":9,"./_array-methods":14,"./_for-of":39,"./_has":41,"./_is-object":51,"./_meta":64,"./_redefine-all":88}],24:[function(require,module,exports){
'use strict';
var global            = require('./_global')
  , $export           = require('./_export')
  , redefine          = require('./_redefine')
  , redefineAll       = require('./_redefine-all')
  , meta              = require('./_meta')
  , forOf             = require('./_for-of')
  , anInstance        = require('./_an-instance')
  , isObject          = require('./_is-object')
  , fails             = require('./_fails')
  , $iterDetect       = require('./_iter-detect')
  , setToStringTag    = require('./_set-to-string-tag')
  , inheritIfRequired = require('./_inherit-if-required');

module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
  var Base  = global[NAME]
    , C     = Base
    , ADDER = IS_MAP ? 'set' : 'add'
    , proto = C && C.prototype
    , O     = {};
  var fixMethod = function(KEY){
    var fn = proto[KEY];
    redefine(proto, KEY,
      KEY == 'delete' ? function(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a){
        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }
        : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }
    );
  };
  if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){
    new C().entries().next();
  }))){
    // create collection constructor
    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
    redefineAll(C.prototype, methods);
    meta.NEED = true;
  } else {
    var instance             = new C
      // early implementations not supports chaining
      , HASNT_CHAINING       = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance
      // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
      , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })
      // most early implementations doesn't supports iterables, most modern - not close it correctly
      , ACCEPT_ITERABLES     = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new
      // for early implementations -0 and +0 not the same
      , BUGGY_ZERO = !IS_WEAK && fails(function(){
        // V8 ~ Chromium 42- fails only with 5+ elements
        var $instance = new C()
          , index     = 5;
        while(index--)$instance[ADDER](index, index);
        return !$instance.has(-0);
      });
    if(!ACCEPT_ITERABLES){ 
      C = wrapper(function(target, iterable){
        anInstance(target, C, NAME);
        var that = inheritIfRequired(new Base, target, C);
        if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
        return that;
      });
      C.prototype = proto;
      proto.constructor = C;
    }
    if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }
    if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);
    // weak collections should not contains .clear method
    if(IS_WEAK && proto.clear)delete proto.clear;
  }

  setToStringTag(C, NAME);

  O[NAME] = C;
  $export($export.G + $export.W + $export.F * (C != Base), O);

  if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);

  return C;
};
},{"./_an-instance":8,"./_export":34,"./_fails":36,"./_for-of":39,"./_global":40,"./_inherit-if-required":45,"./_is-object":51,"./_iter-detect":56,"./_meta":64,"./_redefine":89,"./_redefine-all":88,"./_set-to-string-tag":94}],25:[function(require,module,exports){
var core = module.exports = {version: '2.4.0'};
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
},{}],26:[function(require,module,exports){
'use strict';
var $defineProperty = require('./_object-dp')
  , createDesc      = require('./_property-desc');

module.exports = function(object, index, value){
  if(index in object)$defineProperty.f(object, index, createDesc(0, value));
  else object[index] = value;
};
},{"./_object-dp":69,"./_property-desc":87}],27:[function(require,module,exports){
// optional / simple context binding
var aFunction = require('./_a-function');
module.exports = function(fn, that, length){
  aFunction(fn);
  if(that === undefined)return fn;
  switch(length){
    case 1: return function(a){
      return fn.call(that, a);
    };
    case 2: return function(a, b){
      return fn.call(that, a, b);
    };
    case 3: return function(a, b, c){
      return fn.call(that, a, b, c);
    };
  }
  return function(/* ...args */){
    return fn.apply(that, arguments);
  };
};
},{"./_a-function":5}],28:[function(require,module,exports){
'use strict';
var anObject    = require('./_an-object')
  , toPrimitive = require('./_to-primitive')
  , NUMBER      = 'number';

module.exports = function(hint){
  if(hint !== 'string' && hint !== NUMBER && hint !== 'default')throw TypeError('Incorrect hint');
  return toPrimitive(anObject(this), hint != NUMBER);
};
},{"./_an-object":9,"./_to-primitive":112}],29:[function(require,module,exports){
// 7.2.1 RequireObjectCoercible(argument)
module.exports = function(it){
  if(it == undefined)throw TypeError("Can't call method on  " + it);
  return it;
};
},{}],30:[function(require,module,exports){
// Thank's IE8 for his funny defineProperty
module.exports = !require('./_fails')(function(){
  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
});
},{"./_fails":36}],31:[function(require,module,exports){
var isObject = require('./_is-object')
  , document = require('./_global').document
  // in old IE typeof document.createElement is 'object'
  , is = isObject(document) && isObject(document.createElement);
module.exports = function(it){
  return is ? document.createElement(it) : {};
};
},{"./_global":40,"./_is-object":51}],32:[function(require,module,exports){
// IE 8- don't enum bug keys
module.exports = (
  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');
},{}],33:[function(require,module,exports){
// all enumerable object keys, includes symbols
var getKeys = require('./_object-keys')
  , gOPS    = require('./_object-gops')
  , pIE     = require('./_object-pie');
module.exports = function(it){
  var result     = getKeys(it)
    , getSymbols = gOPS.f;
  if(getSymbols){
    var symbols = getSymbols(it)
      , isEnum  = pIE.f
      , i       = 0
      , key;
    while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);
  } return result;
};
},{"./_object-gops":75,"./_object-keys":78,"./_object-pie":79}],34:[function(require,module,exports){
var global    = require('./_global')
  , core      = require('./_core')
  , hide      = require('./_hide')
  , redefine  = require('./_redefine')
  , ctx       = require('./_ctx')
  , PROTOTYPE = 'prototype';

var $export = function(type, name, source){
  var IS_FORCED = type & $export.F
    , IS_GLOBAL = type & $export.G
    , IS_STATIC = type & $export.S
    , IS_PROTO  = type & $export.P
    , IS_BIND   = type & $export.B
    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]
    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
    , expProto  = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})
    , key, own, out, exp;
  if(IS_GLOBAL)source = name;
  for(key in source){
    // contains in native
    own = !IS_FORCED && target && target[key] !== undefined;
    // export native or passed
    out = (own ? target : source)[key];
    // bind timers to global for call from export context
    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
    // extend global
    if(target)redefine(target, key, out, type & $export.U);
    // export
    if(exports[key] != out)hide(exports, key, exp);
    if(IS_PROTO && expProto[key] != out)expProto[key] = out;
  }
};
global.core = core;
// type bitmap
$export.F = 1;   // forced
$export.G = 2;   // global
$export.S = 4;   // static
$export.P = 8;   // proto
$export.B = 16;  // bind
$export.W = 32;  // wrap
$export.U = 64;  // safe
$export.R = 128; // real proto method for `library` 
module.exports = $export;
},{"./_core":25,"./_ctx":27,"./_global":40,"./_hide":42,"./_redefine":89}],35:[function(require,module,exports){
var MATCH = require('./_wks')('match');
module.exports = function(KEY){
  var re = /./;
  try {
    '/./'[KEY](re);
  } catch(e){
    try {
      re[MATCH] = false;
      return !'/./'[KEY](re);
    } catch(f){ /* empty */ }
  } return true;
};
},{"./_wks":119}],36:[function(require,module,exports){
module.exports = function(exec){
  try {
    return !!exec();
  } catch(e){
    return true;
  }
};
},{}],37:[function(require,module,exports){
'use strict';
var hide     = require('./_hide')
  , redefine = require('./_redefine')
  , fails    = require('./_fails')
  , defined  = require('./_defined')
  , wks      = require('./_wks');

module.exports = function(KEY, length, exec){
  var SYMBOL   = wks(KEY)
    , fns      = exec(defined, SYMBOL, ''[KEY])
    , strfn    = fns[0]
    , rxfn     = fns[1];
  if(fails(function(){
    var O = {};
    O[SYMBOL] = function(){ return 7; };
    return ''[KEY](O) != 7;
  })){
    redefine(String.prototype, KEY, strfn);
    hide(RegExp.prototype, SYMBOL, length == 2
      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
      ? function(string, arg){ return rxfn.call(string, this, arg); }
      // 21.2.5.6 RegExp.prototype[@@match](string)
      // 21.2.5.9 RegExp.prototype[@@search](string)
      : function(string){ return rxfn.call(string, this); }
    );
  }
};
},{"./_defined":29,"./_fails":36,"./_hide":42,"./_redefine":89,"./_wks":119}],38:[function(require,module,exports){
'use strict';
// 21.2.5.3 get RegExp.prototype.flags
var anObject = require('./_an-object');
module.exports = function(){
  var that   = anObject(this)
    , result = '';
  if(that.global)     result += 'g';
  if(that.ignoreCase) result += 'i';
  if(that.multiline)  result += 'm';
  if(that.unicode)    result += 'u';
  if(that.sticky)     result += 'y';
  return result;
};
},{"./_an-object":9}],39:[function(require,module,exports){
var ctx         = require('./_ctx')
  , call        = require('./_iter-call')
  , isArrayIter = require('./_is-array-iter')
  , anObject    = require('./_an-object')
  , toLength    = require('./_to-length')
  , getIterFn   = require('./core.get-iterator-method')
  , BREAK       = {}
  , RETURN      = {};
var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){
  var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)
    , f      = ctx(fn, that, entries ? 2 : 1)
    , index  = 0
    , length, step, iterator, result;
  if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
  // fast case for arrays with default iterator
  if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){
    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
    if(result === BREAK || result === RETURN)return result;
  } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
    result = call(iterator, f, step.value, entries);
    if(result === BREAK || result === RETURN)return result;
  }
};
exports.BREAK  = BREAK;
exports.RETURN = RETURN;
},{"./_an-object":9,"./_ctx":27,"./_is-array-iter":48,"./_iter-call":53,"./_to-length":110,"./core.get-iterator-method":120}],40:[function(require,module,exports){
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
},{}],41:[function(require,module,exports){
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function(it, key){
  return hasOwnProperty.call(it, key);
};
},{}],42:[function(require,module,exports){
var dP         = require('./_object-dp')
  , createDesc = require('./_property-desc');
module.exports = require('./_descriptors') ? function(object, key, value){
  return dP.f(object, key, createDesc(1, value));
} : function(object, key, value){
  object[key] = value;
  return object;
};
},{"./_descriptors":30,"./_object-dp":69,"./_property-desc":87}],43:[function(require,module,exports){
module.exports = require('./_global').document && document.documentElement;
},{"./_global":40}],44:[function(require,module,exports){
module.exports = !require('./_descriptors') && !require('./_fails')(function(){
  return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;
});
},{"./_descriptors":30,"./_dom-create":31,"./_fails":36}],45:[function(require,module,exports){
var isObject       = require('./_is-object')
  , setPrototypeOf = require('./_set-proto').set;
module.exports = function(that, target, C){
  var P, S = target.constructor;
  if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){
    setPrototypeOf(that, P);
  } return that;
};
},{"./_is-object":51,"./_set-proto":92}],46:[function(require,module,exports){
// fast apply, http://jsperf.lnkit.com/fast-apply/5
module.exports = function(fn, args, that){
  var un = that === undefined;
  switch(args.length){
    case 0: return un ? fn()
                      : fn.call(that);
    case 1: return un ? fn(args[0])
                      : fn.call(that, args[0]);
    case 2: return un ? fn(args[0], args[1])
                      : fn.call(that, args[0], args[1]);
    case 3: return un ? fn(args[0], args[1], args[2])
                      : fn.call(that, args[0], args[1], args[2]);
    case 4: return un ? fn(args[0], args[1], args[2], args[3])
                      : fn.call(that, args[0], args[1], args[2], args[3]);
  } return              fn.apply(that, args);
};
},{}],47:[function(require,module,exports){
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = require('./_cof');
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
  return cof(it) == 'String' ? it.split('') : Object(it);
};
},{"./_cof":20}],48:[function(require,module,exports){
// check on default Array iterator
var Iterators  = require('./_iterators')
  , ITERATOR   = require('./_wks')('iterator')
  , ArrayProto = Array.prototype;

module.exports = function(it){
  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};
},{"./_iterators":58,"./_wks":119}],49:[function(require,module,exports){
// 7.2.2 IsArray(argument)
var cof = require('./_cof');
module.exports = Array.isArray || function isArray(arg){
  return cof(arg) == 'Array';
};
},{"./_cof":20}],50:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var isObject = require('./_is-object')
  , floor    = Math.floor;
module.exports = function isInteger(it){
  return !isObject(it) && isFinite(it) && floor(it) === it;
};
},{"./_is-object":51}],51:[function(require,module,exports){
module.exports = function(it){
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};
},{}],52:[function(require,module,exports){
// 7.2.8 IsRegExp(argument)
var isObject = require('./_is-object')
  , cof      = require('./_cof')
  , MATCH    = require('./_wks')('match');
module.exports = function(it){
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};
},{"./_cof":20,"./_is-object":51,"./_wks":119}],53:[function(require,module,exports){
// call something on iterator step with safe closing on error
var anObject = require('./_an-object');
module.exports = function(iterator, fn, value, entries){
  try {
    return entries ? fn(anObject(value)[0], value[1]) : fn(value);
  // 7.4.6 IteratorClose(iterator, completion)
  } catch(e){
    var ret = iterator['return'];
    if(ret !== undefined)anObject(ret.call(iterator));
    throw e;
  }
};
},{"./_an-object":9}],54:[function(require,module,exports){
'use strict';
var create         = require('./_object-create')
  , descriptor     = require('./_property-desc')
  , setToStringTag = require('./_set-to-string-tag')
  , IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
require('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function(){ return this; });

module.exports = function(Constructor, NAME, next){
  Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});
  setToStringTag(Constructor, NAME + ' Iterator');
};
},{"./_hide":42,"./_object-create":68,"./_property-desc":87,"./_set-to-string-tag":94,"./_wks":119}],55:[function(require,module,exports){
'use strict';
var LIBRARY        = require('./_library')
  , $export        = require('./_export')
  , redefine       = require('./_redefine')
  , hide           = require('./_hide')
  , has            = require('./_has')
  , Iterators      = require('./_iterators')
  , $iterCreate    = require('./_iter-create')
  , setToStringTag = require('./_set-to-string-tag')
  , getPrototypeOf = require('./_object-gpo')
  , ITERATOR       = require('./_wks')('iterator')
  , BUGGY          = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
  , FF_ITERATOR    = '@@iterator'
  , KEYS           = 'keys'
  , VALUES         = 'values';

var returnThis = function(){ return this; };

module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
  $iterCreate(Constructor, NAME, next);
  var getMethod = function(kind){
    if(!BUGGY && kind in proto)return proto[kind];
    switch(kind){
      case KEYS: return function keys(){ return new Constructor(this, kind); };
      case VALUES: return function values(){ return new Constructor(this, kind); };
    } return function entries(){ return new Constructor(this, kind); };
  };
  var TAG        = NAME + ' Iterator'
    , DEF_VALUES = DEFAULT == VALUES
    , VALUES_BUG = false
    , proto      = Base.prototype
    , $native    = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
    , $default   = $native || getMethod(DEFAULT)
    , $entries   = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined
    , $anyNative = NAME == 'Array' ? proto.entries || $native : $native
    , methods, key, IteratorPrototype;
  // Fix native
  if($anyNative){
    IteratorPrototype = getPrototypeOf($anyNative.call(new Base));
    if(IteratorPrototype !== Object.prototype){
      // Set @@toStringTag to native iterators
      setToStringTag(IteratorPrototype, TAG, true);
      // fix for some old engines
      if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
    }
  }
  // fix Array#{values, @@iterator}.name in V8 / FF
  if(DEF_VALUES && $native && $native.name !== VALUES){
    VALUES_BUG = true;
    $default = function values(){ return $native.call(this); };
  }
  // Define iterator
  if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
    hide(proto, ITERATOR, $default);
  }
  // Plug for library
  Iterators[NAME] = $default;
  Iterators[TAG]  = returnThis;
  if(DEFAULT){
    methods = {
      values:  DEF_VALUES ? $default : getMethod(VALUES),
      keys:    IS_SET     ? $default : getMethod(KEYS),
      entries: $entries
    };
    if(FORCED)for(key in methods){
      if(!(key in proto))redefine(proto, key, methods[key]);
    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
  }
  return methods;
};
},{"./_export":34,"./_has":41,"./_hide":42,"./_iter-create":54,"./_iterators":58,"./_library":60,"./_object-gpo":76,"./_redefine":89,"./_set-to-string-tag":94,"./_wks":119}],56:[function(require,module,exports){
var ITERATOR     = require('./_wks')('iterator')
  , SAFE_CLOSING = false;

try {
  var riter = [7][ITERATOR]();
  riter['return'] = function(){ SAFE_CLOSING = true; };
  Array.from(riter, function(){ throw 2; });
} catch(e){ /* empty */ }

module.exports = function(exec, skipClosing){
  if(!skipClosing && !SAFE_CLOSING)return false;
  var safe = false;
  try {
    var arr  = [7]
      , iter = arr[ITERATOR]();
    iter.next = function(){ return {done: safe = true}; };
    arr[ITERATOR] = function(){ return iter; };
    exec(arr);
  } catch(e){ /* empty */ }
  return safe;
};
},{"./_wks":119}],57:[function(require,module,exports){
module.exports = function(done, value){
  return {value: value, done: !!done};
};
},{}],58:[function(require,module,exports){
module.exports = {};
},{}],59:[function(require,module,exports){
var getKeys   = require('./_object-keys')
  , toIObject = require('./_to-iobject');
module.exports = function(object, el){
  var O      = toIObject(object)
    , keys   = getKeys(O)
    , length = keys.length
    , index  = 0
    , key;
  while(length > index)if(O[key = keys[index++]] === el)return key;
};
},{"./_object-keys":78,"./_to-iobject":109}],60:[function(require,module,exports){
module.exports = false;
},{}],61:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $expm1 = Math.expm1;
module.exports = (!$expm1
  // Old FF bug
  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168
  // Tor Browser bug
  || $expm1(-2e-17) != -2e-17
) ? function expm1(x){
  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
} : $expm1;
},{}],62:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
module.exports = Math.log1p || function log1p(x){
  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
};
},{}],63:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
module.exports = Math.sign || function sign(x){
  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
};
},{}],64:[function(require,module,exports){
var META     = require('./_uid')('meta')
  , isObject = require('./_is-object')
  , has      = require('./_has')
  , setDesc  = require('./_object-dp').f
  , id       = 0;
var isExtensible = Object.isExtensible || function(){
  return true;
};
var FREEZE = !require('./_fails')(function(){
  return isExtensible(Object.preventExtensions({}));
});
var setMeta = function(it){
  setDesc(it, META, {value: {
    i: 'O' + ++id, // object ID
    w: {}          // weak collections IDs
  }});
};
var fastKey = function(it, create){
  // return primitive with prefix
  if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  if(!has(it, META)){
    // can't set metadata to uncaught frozen object
    if(!isExtensible(it))return 'F';
    // not necessary to add metadata
    if(!create)return 'E';
    // add missing metadata
    setMeta(it);
  // return object ID
  } return it[META].i;
};
var getWeak = function(it, create){
  if(!has(it, META)){
    // can't set metadata to uncaught frozen object
    if(!isExtensible(it))return true;
    // not necessary to add metadata
    if(!create)return false;
    // add missing metadata
    setMeta(it);
  // return hash weak collections IDs
  } return it[META].w;
};
// add metadata on freeze-family methods calling
var onFreeze = function(it){
  if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);
  return it;
};
var meta = module.exports = {
  KEY:      META,
  NEED:     false,
  fastKey:  fastKey,
  getWeak:  getWeak,
  onFreeze: onFreeze
};
},{"./_fails":36,"./_has":41,"./_is-object":51,"./_object-dp":69,"./_uid":116}],65:[function(require,module,exports){
var Map     = require('./es6.map')
  , $export = require('./_export')
  , shared  = require('./_shared')('metadata')
  , store   = shared.store || (shared.store = new (require('./es6.weak-map')));

var getOrCreateMetadataMap = function(target, targetKey, create){
  var targetMetadata = store.get(target);
  if(!targetMetadata){
    if(!create)return undefined;
    store.set(target, targetMetadata = new Map);
  }
  var keyMetadata = targetMetadata.get(targetKey);
  if(!keyMetadata){
    if(!create)return undefined;
    targetMetadata.set(targetKey, keyMetadata = new Map);
  } return keyMetadata;
};
var ordinaryHasOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? false : metadataMap.has(MetadataKey);
};
var ordinaryGetOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);
};
var ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){
  getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);
};
var ordinaryOwnMetadataKeys = function(target, targetKey){
  var metadataMap = getOrCreateMetadataMap(target, targetKey, false)
    , keys        = [];
  if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });
  return keys;
};
var toMetaKey = function(it){
  return it === undefined || typeof it == 'symbol' ? it : String(it);
};
var exp = function(O){
  $export($export.S, 'Reflect', O);
};

module.exports = {
  store: store,
  map: getOrCreateMetadataMap,
  has: ordinaryHasOwnMetadata,
  get: ordinaryGetOwnMetadata,
  set: ordinaryDefineOwnMetadata,
  keys: ordinaryOwnMetadataKeys,
  key: toMetaKey,
  exp: exp
};
},{"./_export":34,"./_shared":96,"./es6.map":151,"./es6.weak-map":257}],66:[function(require,module,exports){
var global    = require('./_global')
  , macrotask = require('./_task').set
  , Observer  = global.MutationObserver || global.WebKitMutationObserver
  , process   = global.process
  , Promise   = global.Promise
  , isNode    = require('./_cof')(process) == 'process';

module.exports = function(){
  var head, last, notify;

  var flush = function(){
    var parent, fn;
    if(isNode && (parent = process.domain))parent.exit();
    while(head){
      fn   = head.fn;
      head = head.next;
      try {
        fn();
      } catch(e){
        if(head)notify();
        else last = undefined;
        throw e;
      }
    } last = undefined;
    if(parent)parent.enter();
  };

  // Node.js
  if(isNode){
    notify = function(){
      process.nextTick(flush);
    };
  // browsers with MutationObserver
  } else if(Observer){
    var toggle = true
      , node   = document.createTextNode('');
    new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
    notify = function(){
      node.data = toggle = !toggle;
    };
  // environments with maybe non-completely correct, but existent Promise
  } else if(Promise && Promise.resolve){
    var promise = Promise.resolve();
    notify = function(){
      promise.then(flush);
    };
  // for other environments - macrotask based on:
  // - setImmediate
  // - MessageChannel
  // - window.postMessag
  // - onreadystatechange
  // - setTimeout
  } else {
    notify = function(){
      // strange IE + webpack dev server bug - use .call(global)
      macrotask.call(global, flush);
    };
  }

  return function(fn){
    var task = {fn: fn, next: undefined};
    if(last)last.next = task;
    if(!head){
      head = task;
      notify();
    } last = task;
  };
};
},{"./_cof":20,"./_global":40,"./_task":106}],67:[function(require,module,exports){
'use strict';
// 19.1.2.1 Object.assign(target, source, ...)
var getKeys  = require('./_object-keys')
  , gOPS     = require('./_object-gops')
  , pIE      = require('./_object-pie')
  , toObject = require('./_to-object')
  , IObject  = require('./_iobject')
  , $assign  = Object.assign;

// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !$assign || require('./_fails')(function(){
  var A = {}
    , B = {}
    , S = Symbol()
    , K = 'abcdefghijklmnopqrst';
  A[S] = 7;
  K.split('').forEach(function(k){ B[k] = k; });
  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
}) ? function assign(target, source){ // eslint-disable-line no-unused-vars
  var T     = toObject(target)
    , aLen  = arguments.length
    , index = 1
    , getSymbols = gOPS.f
    , isEnum     = pIE.f;
  while(aLen > index){
    var S      = IObject(arguments[index++])
      , keys   = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)
      , length = keys.length
      , j      = 0
      , key;
    while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];
  } return T;
} : $assign;
},{"./_fails":36,"./_iobject":47,"./_object-gops":75,"./_object-keys":78,"./_object-pie":79,"./_to-object":111}],68:[function(require,module,exports){
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject    = require('./_an-object')
  , dPs         = require('./_object-dps')
  , enumBugKeys = require('./_enum-bug-keys')
  , IE_PROTO    = require('./_shared-key')('IE_PROTO')
  , Empty       = function(){ /* empty */ }
  , PROTOTYPE   = 'prototype';

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function(){
  // Thrash, waste and sodomy: IE GC bug
  var iframe = require('./_dom-create')('iframe')
    , i      = enumBugKeys.length
    , lt     = '<'
    , gt     = '>'
    , iframeDocument;
  iframe.style.display = 'none';
  require('./_html').appendChild(iframe);
  iframe.src = 'javascript:'; // eslint-disable-line no-script-url
  // createDict = iframe.contentWindow.Object;
  // html.removeChild(iframe);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
  iframeDocument.close();
  createDict = iframeDocument.F;
  while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];
  return createDict();
};

module.exports = Object.create || function create(O, Properties){
  var result;
  if(O !== null){
    Empty[PROTOTYPE] = anObject(O);
    result = new Empty;
    Empty[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = createDict();
  return Properties === undefined ? result : dPs(result, Properties);
};

},{"./_an-object":9,"./_dom-create":31,"./_enum-bug-keys":32,"./_html":43,"./_object-dps":70,"./_shared-key":95}],69:[function(require,module,exports){
var anObject       = require('./_an-object')
  , IE8_DOM_DEFINE = require('./_ie8-dom-define')
  , toPrimitive    = require('./_to-primitive')
  , dP             = Object.defineProperty;

exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){
  anObject(O);
  P = toPrimitive(P, true);
  anObject(Attributes);
  if(IE8_DOM_DEFINE)try {
    return dP(O, P, Attributes);
  } catch(e){ /* empty */ }
  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
  if('value' in Attributes)O[P] = Attributes.value;
  return O;
};
},{"./_an-object":9,"./_descriptors":30,"./_ie8-dom-define":44,"./_to-primitive":112}],70:[function(require,module,exports){
var dP       = require('./_object-dp')
  , anObject = require('./_an-object')
  , getKeys  = require('./_object-keys');

module.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties){
  anObject(O);
  var keys   = getKeys(Properties)
    , length = keys.length
    , i = 0
    , P;
  while(length > i)dP.f(O, P = keys[i++], Properties[P]);
  return O;
};
},{"./_an-object":9,"./_descriptors":30,"./_object-dp":69,"./_object-keys":78}],71:[function(require,module,exports){
// Forced replacement prototype accessors methods
module.exports = require('./_library')|| !require('./_fails')(function(){
  var K = Math.random();
  // In FF throws only define methods
  __defineSetter__.call(null, K, function(){ /* empty */});
  delete require('./_global')[K];
});
},{"./_fails":36,"./_global":40,"./_library":60}],72:[function(require,module,exports){
var pIE            = require('./_object-pie')
  , createDesc     = require('./_property-desc')
  , toIObject      = require('./_to-iobject')
  , toPrimitive    = require('./_to-primitive')
  , has            = require('./_has')
  , IE8_DOM_DEFINE = require('./_ie8-dom-define')
  , gOPD           = Object.getOwnPropertyDescriptor;

exports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P){
  O = toIObject(O);
  P = toPrimitive(P, true);
  if(IE8_DOM_DEFINE)try {
    return gOPD(O, P);
  } catch(e){ /* empty */ }
  if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);
};
},{"./_descriptors":30,"./_has":41,"./_ie8-dom-define":44,"./_object-pie":79,"./_property-desc":87,"./_to-iobject":109,"./_to-primitive":112}],73:[function(require,module,exports){
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = require('./_to-iobject')
  , gOPN      = require('./_object-gopn').f
  , toString  = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function(it){
  try {
    return gOPN(it);
  } catch(e){
    return windowNames.slice();
  }
};

module.exports.f = function getOwnPropertyNames(it){
  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
};

},{"./_object-gopn":74,"./_to-iobject":109}],74:[function(require,module,exports){
// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys      = require('./_object-keys-internal')
  , hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){
  return $keys(O, hiddenKeys);
};
},{"./_enum-bug-keys":32,"./_object-keys-internal":77}],75:[function(require,module,exports){
exports.f = Object.getOwnPropertySymbols;
},{}],76:[function(require,module,exports){
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has         = require('./_has')
  , toObject    = require('./_to-object')
  , IE_PROTO    = require('./_shared-key')('IE_PROTO')
  , ObjectProto = Object.prototype;

module.exports = Object.getPrototypeOf || function(O){
  O = toObject(O);
  if(has(O, IE_PROTO))return O[IE_PROTO];
  if(typeof O.constructor == 'function' && O instanceof O.constructor){
    return O.constructor.prototype;
  } return O instanceof Object ? ObjectProto : null;
};
},{"./_has":41,"./_shared-key":95,"./_to-object":111}],77:[function(require,module,exports){
var has          = require('./_has')
  , toIObject    = require('./_to-iobject')
  , arrayIndexOf = require('./_array-includes')(false)
  , IE_PROTO     = require('./_shared-key')('IE_PROTO');

module.exports = function(object, names){
  var O      = toIObject(object)
    , i      = 0
    , result = []
    , key;
  for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);
  // Don't enum bug & hidden keys
  while(names.length > i)if(has(O, key = names[i++])){
    ~arrayIndexOf(result, key) || result.push(key);
  }
  return result;
};
},{"./_array-includes":13,"./_has":41,"./_shared-key":95,"./_to-iobject":109}],78:[function(require,module,exports){
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys       = require('./_object-keys-internal')
  , enumBugKeys = require('./_enum-bug-keys');

module.exports = Object.keys || function keys(O){
  return $keys(O, enumBugKeys);
};
},{"./_enum-bug-keys":32,"./_object-keys-internal":77}],79:[function(require,module,exports){
exports.f = {}.propertyIsEnumerable;
},{}],80:[function(require,module,exports){
// most Object methods by ES6 should accept primitives
var $export = require('./_export')
  , core    = require('./_core')
  , fails   = require('./_fails');
module.exports = function(KEY, exec){
  var fn  = (core.Object || {})[KEY] || Object[KEY]
    , exp = {};
  exp[KEY] = exec(fn);
  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);
};
},{"./_core":25,"./_export":34,"./_fails":36}],81:[function(require,module,exports){
var getKeys   = require('./_object-keys')
  , toIObject = require('./_to-iobject')
  , isEnum    = require('./_object-pie').f;
module.exports = function(isEntries){
  return function(it){
    var O      = toIObject(it)
      , keys   = getKeys(O)
      , length = keys.length
      , i      = 0
      , result = []
      , key;
    while(length > i)if(isEnum.call(O, key = keys[i++])){
      result.push(isEntries ? [key, O[key]] : O[key]);
    } return result;
  };
};
},{"./_object-keys":78,"./_object-pie":79,"./_to-iobject":109}],82:[function(require,module,exports){
// all object keys, includes non-enumerable and symbols
var gOPN     = require('./_object-gopn')
  , gOPS     = require('./_object-gops')
  , anObject = require('./_an-object')
  , Reflect  = require('./_global').Reflect;
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){
  var keys       = gOPN.f(anObject(it))
    , getSymbols = gOPS.f;
  return getSymbols ? keys.concat(getSymbols(it)) : keys;
};
},{"./_an-object":9,"./_global":40,"./_object-gopn":74,"./_object-gops":75}],83:[function(require,module,exports){
var $parseFloat = require('./_global').parseFloat
  , $trim       = require('./_string-trim').trim;

module.exports = 1 / $parseFloat(require('./_string-ws') + '-0') !== -Infinity ? function parseFloat(str){
  var string = $trim(String(str), 3)
    , result = $parseFloat(string);
  return result === 0 && string.charAt(0) == '-' ? -0 : result;
} : $parseFloat;
},{"./_global":40,"./_string-trim":104,"./_string-ws":105}],84:[function(require,module,exports){
var $parseInt = require('./_global').parseInt
  , $trim     = require('./_string-trim').trim
  , ws        = require('./_string-ws')
  , hex       = /^[\-+]?0[xX]/;

module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix){
  var string = $trim(String(str), 3);
  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));
} : $parseInt;
},{"./_global":40,"./_string-trim":104,"./_string-ws":105}],85:[function(require,module,exports){
'use strict';
var path      = require('./_path')
  , invoke    = require('./_invoke')
  , aFunction = require('./_a-function');
module.exports = function(/* ...pargs */){
  var fn     = aFunction(this)
    , length = arguments.length
    , pargs  = Array(length)
    , i      = 0
    , _      = path._
    , holder = false;
  while(length > i)if((pargs[i] = arguments[i++]) === _)holder = true;
  return function(/* ...args */){
    var that = this
      , aLen = arguments.length
      , j = 0, k = 0, args;
    if(!holder && !aLen)return invoke(fn, pargs, that);
    args = pargs.slice();
    if(holder)for(;length > j; j++)if(args[j] === _)args[j] = arguments[k++];
    while(aLen > k)args.push(arguments[k++]);
    return invoke(fn, args, that);
  };
};
},{"./_a-function":5,"./_invoke":46,"./_path":86}],86:[function(require,module,exports){
module.exports = require('./_global');
},{"./_global":40}],87:[function(require,module,exports){
module.exports = function(bitmap, value){
  return {
    enumerable  : !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable    : !(bitmap & 4),
    value       : value
  };
};
},{}],88:[function(require,module,exports){
var redefine = require('./_redefine');
module.exports = function(target, src, safe){
  for(var key in src)redefine(target, key, src[key], safe);
  return target;
};
},{"./_redefine":89}],89:[function(require,module,exports){
var global    = require('./_global')
  , hide      = require('./_hide')
  , has       = require('./_has')
  , SRC       = require('./_uid')('src')
  , TO_STRING = 'toString'
  , $toString = Function[TO_STRING]
  , TPL       = ('' + $toString).split(TO_STRING);

require('./_core').inspectSource = function(it){
  return $toString.call(it);
};

(module.exports = function(O, key, val, safe){
  var isFunction = typeof val == 'function';
  if(isFunction)has(val, 'name') || hide(val, 'name', key);
  if(O[key] === val)return;
  if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  if(O === global){
    O[key] = val;
  } else {
    if(!safe){
      delete O[key];
      hide(O, key, val);
    } else {
      if(O[key])O[key] = val;
      else hide(O, key, val);
    }
  }
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString(){
  return typeof this == 'function' && this[SRC] || $toString.call(this);
});
},{"./_core":25,"./_global":40,"./_has":41,"./_hide":42,"./_uid":116}],90:[function(require,module,exports){
module.exports = function(regExp, replace){
  var replacer = replace === Object(replace) ? function(part){
    return replace[part];
  } : replace;
  return function(it){
    return String(it).replace(regExp, replacer);
  };
};
},{}],91:[function(require,module,exports){
// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y){
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};
},{}],92:[function(require,module,exports){
// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = require('./_is-object')
  , anObject = require('./_an-object');
var check = function(O, proto){
  anObject(O);
  if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
    function(test, buggy, set){
      try {
        set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);
        set(test, []);
        buggy = !(test instanceof Array);
      } catch(e){ buggy = true; }
      return function setPrototypeOf(O, proto){
        check(O, proto);
        if(buggy)O.__proto__ = proto;
        else set(O, proto);
        return O;
      };
    }({}, false) : undefined),
  check: check
};
},{"./_an-object":9,"./_ctx":27,"./_is-object":51,"./_object-gopd":72}],93:[function(require,module,exports){
'use strict';
var global      = require('./_global')
  , dP          = require('./_object-dp')
  , DESCRIPTORS = require('./_descriptors')
  , SPECIES     = require('./_wks')('species');

module.exports = function(KEY){
  var C = global[KEY];
  if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {
    configurable: true,
    get: function(){ return this; }
  });
};
},{"./_descriptors":30,"./_global":40,"./_object-dp":69,"./_wks":119}],94:[function(require,module,exports){
var def = require('./_object-dp').f
  , has = require('./_has')
  , TAG = require('./_wks')('toStringTag');

module.exports = function(it, tag, stat){
  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
};
},{"./_has":41,"./_object-dp":69,"./_wks":119}],95:[function(require,module,exports){
var shared = require('./_shared')('keys')
  , uid    = require('./_uid');
module.exports = function(key){
  return shared[key] || (shared[key] = uid(key));
};
},{"./_shared":96,"./_uid":116}],96:[function(require,module,exports){
var global = require('./_global')
  , SHARED = '__core-js_shared__'
  , store  = global[SHARED] || (global[SHARED] = {});
module.exports = function(key){
  return store[key] || (store[key] = {});
};
},{"./_global":40}],97:[function(require,module,exports){
// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject  = require('./_an-object')
  , aFunction = require('./_a-function')
  , SPECIES   = require('./_wks')('species');
module.exports = function(O, D){
  var C = anObject(O).constructor, S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};
},{"./_a-function":5,"./_an-object":9,"./_wks":119}],98:[function(require,module,exports){
var fails = require('./_fails');

module.exports = function(method, arg){
  return !!method && fails(function(){
    arg ? method.call(null, function(){}, 1) : method.call(null);
  });
};
},{"./_fails":36}],99:[function(require,module,exports){
var toInteger = require('./_to-integer')
  , defined   = require('./_defined');
// true  -> String#at
// false -> String#codePointAt
module.exports = function(TO_STRING){
  return function(that, pos){
    var s = String(defined(that))
      , i = toInteger(pos)
      , l = s.length
      , a, b;
    if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
    a = s.charCodeAt(i);
    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
      ? TO_STRING ? s.charAt(i) : a
      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
  };
};
},{"./_defined":29,"./_to-integer":108}],100:[function(require,module,exports){
// helper for String#{startsWith, endsWith, includes}
var isRegExp = require('./_is-regexp')
  , defined  = require('./_defined');

module.exports = function(that, searchString, NAME){
  if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!");
  return String(defined(that));
};
},{"./_defined":29,"./_is-regexp":52}],101:[function(require,module,exports){
var $export = require('./_export')
  , fails   = require('./_fails')
  , defined = require('./_defined')
  , quot    = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
var createHTML = function(string, tag, attribute, value) {
  var S  = String(defined(string))
    , p1 = '<' + tag;
  if(attribute !== '')p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
  return p1 + '>' + S + '</' + tag + '>';
};
module.exports = function(NAME, exec){
  var O = {};
  O[NAME] = exec(createHTML);
  $export($export.P + $export.F * fails(function(){
    var test = ''[NAME]('"');
    return test !== test.toLowerCase() || test.split('"').length > 3;
  }), 'String', O);
};
},{"./_defined":29,"./_export":34,"./_fails":36}],102:[function(require,module,exports){
// https://github.com/tc39/proposal-string-pad-start-end
var toLength = require('./_to-length')
  , repeat   = require('./_string-repeat')
  , defined  = require('./_defined');

module.exports = function(that, maxLength, fillString, left){
  var S            = String(defined(that))
    , stringLength = S.length
    , fillStr      = fillString === undefined ? ' ' : String(fillString)
    , intMaxLength = toLength(maxLength);
  if(intMaxLength <= stringLength || fillStr == '')return S;
  var fillLen = intMaxLength - stringLength
    , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
  if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);
  return left ? stringFiller + S : S + stringFiller;
};

},{"./_defined":29,"./_string-repeat":103,"./_to-length":110}],103:[function(require,module,exports){
'use strict';
var toInteger = require('./_to-integer')
  , defined   = require('./_defined');

module.exports = function repeat(count){
  var str = String(defined(this))
    , res = ''
    , n   = toInteger(count);
  if(n < 0 || n == Infinity)throw RangeError("Count can't be negative");
  for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;
  return res;
};
},{"./_defined":29,"./_to-integer":108}],104:[function(require,module,exports){
var $export = require('./_export')
  , defined = require('./_defined')
  , fails   = require('./_fails')
  , spaces  = require('./_string-ws')
  , space   = '[' + spaces + ']'
  , non     = '\u200b\u0085'
  , ltrim   = RegExp('^' + space + space + '*')
  , rtrim   = RegExp(space + space + '*$');

var exporter = function(KEY, exec, ALIAS){
  var exp   = {};
  var FORCE = fails(function(){
    return !!spaces[KEY]() || non[KEY]() != non;
  });
  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];
  if(ALIAS)exp[ALIAS] = fn;
  $export($export.P + $export.F * FORCE, 'String', exp);
};

// 1 -> String#trimLeft
// 2 -> String#trimRight
// 3 -> String#trim
var trim = exporter.trim = function(string, TYPE){
  string = String(defined(string));
  if(TYPE & 1)string = string.replace(ltrim, '');
  if(TYPE & 2)string = string.replace(rtrim, '');
  return string;
};

module.exports = exporter;
},{"./_defined":29,"./_export":34,"./_fails":36,"./_string-ws":105}],105:[function(require,module,exports){
module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
},{}],106:[function(require,module,exports){
var ctx                = require('./_ctx')
  , invoke             = require('./_invoke')
  , html               = require('./_html')
  , cel                = require('./_dom-create')
  , global             = require('./_global')
  , process            = global.process
  , setTask            = global.setImmediate
  , clearTask          = global.clearImmediate
  , MessageChannel     = global.MessageChannel
  , counter            = 0
  , queue              = {}
  , ONREADYSTATECHANGE = 'onreadystatechange'
  , defer, channel, port;
var run = function(){
  var id = +this;
  if(queue.hasOwnProperty(id)){
    var fn = queue[id];
    delete queue[id];
    fn();
  }
};
var listener = function(event){
  run.call(event.data);
};
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if(!setTask || !clearTask){
  setTask = function setImmediate(fn){
    var args = [], i = 1;
    while(arguments.length > i)args.push(arguments[i++]);
    queue[++counter] = function(){
      invoke(typeof fn == 'function' ? fn : Function(fn), args);
    };
    defer(counter);
    return counter;
  };
  clearTask = function clearImmediate(id){
    delete queue[id];
  };
  // Node.js 0.8-
  if(require('./_cof')(process) == 'process'){
    defer = function(id){
      process.nextTick(ctx(run, id, 1));
    };
  // Browsers with MessageChannel, includes WebWorkers
  } else if(MessageChannel){
    channel = new MessageChannel;
    port    = channel.port2;
    channel.port1.onmessage = listener;
    defer = ctx(port.postMessage, port, 1);
  // Browsers with postMessage, skip WebWorkers
  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
    defer = function(id){
      global.postMessage(id + '', '*');
    };
    global.addEventListener('message', listener, false);
  // IE8-
  } else if(ONREADYSTATECHANGE in cel('script')){
    defer = function(id){
      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
        html.removeChild(this);
        run.call(id);
      };
    };
  // Rest old browsers
  } else {
    defer = function(id){
      setTimeout(ctx(run, id, 1), 0);
    };
  }
}
module.exports = {
  set:   setTask,
  clear: clearTask
};
},{"./_cof":20,"./_ctx":27,"./_dom-create":31,"./_global":40,"./_html":43,"./_invoke":46}],107:[function(require,module,exports){
var toInteger = require('./_to-integer')
  , max       = Math.max
  , min       = Math.min;
module.exports = function(index, length){
  index = toInteger(index);
  return index < 0 ? max(index + length, 0) : min(index, length);
};
},{"./_to-integer":108}],108:[function(require,module,exports){
// 7.1.4 ToInteger
var ceil  = Math.ceil
  , floor = Math.floor;
module.exports = function(it){
  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};
},{}],109:[function(require,module,exports){
// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = require('./_iobject')
  , defined = require('./_defined');
module.exports = function(it){
  return IObject(defined(it));
};
},{"./_defined":29,"./_iobject":47}],110:[function(require,module,exports){
// 7.1.15 ToLength
var toInteger = require('./_to-integer')
  , min       = Math.min;
module.exports = function(it){
  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};
},{"./_to-integer":108}],111:[function(require,module,exports){
// 7.1.13 ToObject(argument)
var defined = require('./_defined');
module.exports = function(it){
  return Object(defined(it));
};
},{"./_defined":29}],112:[function(require,module,exports){
// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = require('./_is-object');
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function(it, S){
  if(!isObject(it))return it;
  var fn, val;
  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  throw TypeError("Can't convert object to primitive value");
};
},{"./_is-object":51}],113:[function(require,module,exports){
'use strict';
if(require('./_descriptors')){
  var LIBRARY             = require('./_library')
    , global              = require('./_global')
    , fails               = require('./_fails')
    , $export             = require('./_export')
    , $typed              = require('./_typed')
    , $buffer             = require('./_typed-buffer')
    , ctx                 = require('./_ctx')
    , anInstance          = require('./_an-instance')
    , propertyDesc        = require('./_property-desc')
    , hide                = require('./_hide')
    , redefineAll         = require('./_redefine-all')
    , toInteger           = require('./_to-integer')
    , toLength            = require('./_to-length')
    , toIndex             = require('./_to-index')
    , toPrimitive         = require('./_to-primitive')
    , has                 = require('./_has')
    , same                = require('./_same-value')
    , classof             = require('./_classof')
    , isObject            = require('./_is-object')
    , toObject            = require('./_to-object')
    , isArrayIter         = require('./_is-array-iter')
    , create              = require('./_object-create')
    , getPrototypeOf      = require('./_object-gpo')
    , gOPN                = require('./_object-gopn').f
    , getIterFn           = require('./core.get-iterator-method')
    , uid                 = require('./_uid')
    , wks                 = require('./_wks')
    , createArrayMethod   = require('./_array-methods')
    , createArrayIncludes = require('./_array-includes')
    , speciesConstructor  = require('./_species-constructor')
    , ArrayIterators      = require('./es6.array.iterator')
    , Iterators           = require('./_iterators')
    , $iterDetect         = require('./_iter-detect')
    , setSpecies          = require('./_set-species')
    , arrayFill           = require('./_array-fill')
    , arrayCopyWithin     = require('./_array-copy-within')
    , $DP                 = require('./_object-dp')
    , $GOPD               = require('./_object-gopd')
    , dP                  = $DP.f
    , gOPD                = $GOPD.f
    , RangeError          = global.RangeError
    , TypeError           = global.TypeError
    , Uint8Array          = global.Uint8Array
    , ARRAY_BUFFER        = 'ArrayBuffer'
    , SHARED_BUFFER       = 'Shared' + ARRAY_BUFFER
    , BYTES_PER_ELEMENT   = 'BYTES_PER_ELEMENT'
    , PROTOTYPE           = 'prototype'
    , ArrayProto          = Array[PROTOTYPE]
    , $ArrayBuffer        = $buffer.ArrayBuffer
    , $DataView           = $buffer.DataView
    , arrayForEach        = createArrayMethod(0)
    , arrayFilter         = createArrayMethod(2)
    , arraySome           = createArrayMethod(3)
    , arrayEvery          = createArrayMethod(4)
    , arrayFind           = createArrayMethod(5)
    , arrayFindIndex      = createArrayMethod(6)
    , arrayIncludes       = createArrayIncludes(true)
    , arrayIndexOf        = createArrayIncludes(false)
    , arrayValues         = ArrayIterators.values
    , arrayKeys           = ArrayIterators.keys
    , arrayEntries        = ArrayIterators.entries
    , arrayLastIndexOf    = ArrayProto.lastIndexOf
    , arrayReduce         = ArrayProto.reduce
    , arrayReduceRight    = ArrayProto.reduceRight
    , arrayJoin           = ArrayProto.join
    , arraySort           = ArrayProto.sort
    , arraySlice          = ArrayProto.slice
    , arrayToString       = ArrayProto.toString
    , arrayToLocaleString = ArrayProto.toLocaleString
    , ITERATOR            = wks('iterator')
    , TAG                 = wks('toStringTag')
    , TYPED_CONSTRUCTOR   = uid('typed_constructor')
    , DEF_CONSTRUCTOR     = uid('def_constructor')
    , ALL_CONSTRUCTORS    = $typed.CONSTR
    , TYPED_ARRAY         = $typed.TYPED
    , VIEW                = $typed.VIEW
    , WRONG_LENGTH        = 'Wrong length!';

  var $map = createArrayMethod(1, function(O, length){
    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);
  });

  var LITTLE_ENDIAN = fails(function(){
    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
  });

  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function(){
    new Uint8Array(1).set({});
  });

  var strictToLength = function(it, SAME){
    if(it === undefined)throw TypeError(WRONG_LENGTH);
    var number = +it
      , length = toLength(it);
    if(SAME && !same(number, length))throw RangeError(WRONG_LENGTH);
    return length;
  };

  var toOffset = function(it, BYTES){
    var offset = toInteger(it);
    if(offset < 0 || offset % BYTES)throw RangeError('Wrong offset!');
    return offset;
  };

  var validate = function(it){
    if(isObject(it) && TYPED_ARRAY in it)return it;
    throw TypeError(it + ' is not a typed array!');
  };

  var allocate = function(C, length){
    if(!(isObject(C) && TYPED_CONSTRUCTOR in C)){
      throw TypeError('It is not a typed array constructor!');
    } return new C(length);
  };

  var speciesFromList = function(O, list){
    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);
  };

  var fromList = function(C, list){
    var index  = 0
      , length = list.length
      , result = allocate(C, length);
    while(length > index)result[index] = list[index++];
    return result;
  };

  var addGetter = function(it, key, internal){
    dP(it, key, {get: function(){ return this._d[internal]; }});
  };

  var $from = function from(source /*, mapfn, thisArg */){
    var O       = toObject(source)
      , aLen    = arguments.length
      , mapfn   = aLen > 1 ? arguments[1] : undefined
      , mapping = mapfn !== undefined
      , iterFn  = getIterFn(O)
      , i, length, values, result, step, iterator;
    if(iterFn != undefined && !isArrayIter(iterFn)){
      for(iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++){
        values.push(step.value);
      } O = values;
    }
    if(mapping && aLen > 2)mapfn = ctx(mapfn, arguments[2], 2);
    for(i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++){
      result[i] = mapping ? mapfn(O[i], i) : O[i];
    }
    return result;
  };

  var $of = function of(/*...items*/){
    var index  = 0
      , length = arguments.length
      , result = allocate(this, length);
    while(length > index)result[index] = arguments[index++];
    return result;
  };

  // iOS Safari 6.x fails here
  var TO_LOCALE_BUG = !!Uint8Array && fails(function(){ arrayToLocaleString.call(new Uint8Array(1)); });

  var $toLocaleString = function toLocaleString(){
    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);
  };

  var proto = {
    copyWithin: function copyWithin(target, start /*, end */){
      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
    },
    every: function every(callbackfn /*, thisArg */){
      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    fill: function fill(value /*, start, end */){ // eslint-disable-line no-unused-vars
      return arrayFill.apply(validate(this), arguments);
    },
    filter: function filter(callbackfn /*, thisArg */){
      return speciesFromList(this, arrayFilter(validate(this), callbackfn,
        arguments.length > 1 ? arguments[1] : undefined));
    },
    find: function find(predicate /*, thisArg */){
      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    findIndex: function findIndex(predicate /*, thisArg */){
      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    forEach: function forEach(callbackfn /*, thisArg */){
      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    indexOf: function indexOf(searchElement /*, fromIndex */){
      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    includes: function includes(searchElement /*, fromIndex */){
      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    join: function join(separator){ // eslint-disable-line no-unused-vars
      return arrayJoin.apply(validate(this), arguments);
    },
    lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */){ // eslint-disable-line no-unused-vars
      return arrayLastIndexOf.apply(validate(this), arguments);
    },
    map: function map(mapfn /*, thisArg */){
      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    reduce: function reduce(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduce.apply(validate(this), arguments);
    },
    reduceRight: function reduceRight(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduceRight.apply(validate(this), arguments);
    },
    reverse: function reverse(){
      var that   = this
        , length = validate(that).length
        , middle = Math.floor(length / 2)
        , index  = 0
        , value;
      while(index < middle){
        value         = that[index];
        that[index++] = that[--length];
        that[length]  = value;
      } return that;
    },
    some: function some(callbackfn /*, thisArg */){
      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    sort: function sort(comparefn){
      return arraySort.call(validate(this), comparefn);
    },
    subarray: function subarray(begin, end){
      var O      = validate(this)
        , length = O.length
        , $begin = toIndex(begin, length);
      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(
        O.buffer,
        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,
        toLength((end === undefined ? length : toIndex(end, length)) - $begin)
      );
    }
  };

  var $slice = function slice(start, end){
    return speciesFromList(this, arraySlice.call(validate(this), start, end));
  };

  var $set = function set(arrayLike /*, offset */){
    validate(this);
    var offset = toOffset(arguments[1], 1)
      , length = this.length
      , src    = toObject(arrayLike)
      , len    = toLength(src.length)
      , index  = 0;
    if(len + offset > length)throw RangeError(WRONG_LENGTH);
    while(index < len)this[offset + index] = src[index++];
  };

  var $iterators = {
    entries: function entries(){
      return arrayEntries.call(validate(this));
    },
    keys: function keys(){
      return arrayKeys.call(validate(this));
    },
    values: function values(){
      return arrayValues.call(validate(this));
    }
  };

  var isTAIndex = function(target, key){
    return isObject(target)
      && target[TYPED_ARRAY]
      && typeof key != 'symbol'
      && key in target
      && String(+key) == String(key);
  };
  var $getDesc = function getOwnPropertyDescriptor(target, key){
    return isTAIndex(target, key = toPrimitive(key, true))
      ? propertyDesc(2, target[key])
      : gOPD(target, key);
  };
  var $setDesc = function defineProperty(target, key, desc){
    if(isTAIndex(target, key = toPrimitive(key, true))
      && isObject(desc)
      && has(desc, 'value')
      && !has(desc, 'get')
      && !has(desc, 'set')
      // TODO: add validation descriptor w/o calling accessors
      && !desc.configurable
      && (!has(desc, 'writable') || desc.writable)
      && (!has(desc, 'enumerable') || desc.enumerable)
    ){
      target[key] = desc.value;
      return target;
    } else return dP(target, key, desc);
  };

  if(!ALL_CONSTRUCTORS){
    $GOPD.f = $getDesc;
    $DP.f   = $setDesc;
  }

  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {
    getOwnPropertyDescriptor: $getDesc,
    defineProperty:           $setDesc
  });

  if(fails(function(){ arrayToString.call({}); })){
    arrayToString = arrayToLocaleString = function toString(){
      return arrayJoin.call(this);
    }
  }

  var $TypedArrayPrototype$ = redefineAll({}, proto);
  redefineAll($TypedArrayPrototype$, $iterators);
  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);
  redefineAll($TypedArrayPrototype$, {
    slice:          $slice,
    set:            $set,
    constructor:    function(){ /* noop */ },
    toString:       arrayToString,
    toLocaleString: $toLocaleString
  });
  addGetter($TypedArrayPrototype$, 'buffer', 'b');
  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');
  addGetter($TypedArrayPrototype$, 'byteLength', 'l');
  addGetter($TypedArrayPrototype$, 'length', 'e');
  dP($TypedArrayPrototype$, TAG, {
    get: function(){ return this[TYPED_ARRAY]; }
  });

  module.exports = function(KEY, BYTES, wrapper, CLAMPED){
    CLAMPED = !!CLAMPED;
    var NAME       = KEY + (CLAMPED ? 'Clamped' : '') + 'Array'
      , ISNT_UINT8 = NAME != 'Uint8Array'
      , GETTER     = 'get' + KEY
      , SETTER     = 'set' + KEY
      , TypedArray = global[NAME]
      , Base       = TypedArray || {}
      , TAC        = TypedArray && getPrototypeOf(TypedArray)
      , FORCED     = !TypedArray || !$typed.ABV
      , O          = {}
      , TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];
    var getter = function(that, index){
      var data = that._d;
      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);
    };
    var setter = function(that, index, value){
      var data = that._d;
      if(CLAMPED)value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;
      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);
    };
    var addElement = function(that, index){
      dP(that, index, {
        get: function(){
          return getter(this, index);
        },
        set: function(value){
          return setter(this, index, value);
        },
        enumerable: true
      });
    };
    if(FORCED){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME, '_d');
        var index  = 0
          , offset = 0
          , buffer, byteLength, length, klass;
        if(!isObject(data)){
          length     = strictToLength(data, true)
          byteLength = length * BYTES;
          buffer     = new $ArrayBuffer(byteLength);
        } else if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          buffer = data;
          offset = toOffset($offset, BYTES);
          var $len = data.byteLength;
          if($length === undefined){
            if($len % BYTES)throw RangeError(WRONG_LENGTH);
            byteLength = $len - offset;
            if(byteLength < 0)throw RangeError(WRONG_LENGTH);
          } else {
            byteLength = toLength($length) * BYTES;
            if(byteLength + offset > $len)throw RangeError(WRONG_LENGTH);
          }
          length = byteLength / BYTES;
        } else if(TYPED_ARRAY in data){
          return fromList(TypedArray, data);
        } else {
          return $from.call(TypedArray, data);
        }
        hide(that, '_d', {
          b: buffer,
          o: offset,
          l: byteLength,
          e: length,
          v: new $DataView(buffer)
        });
        while(index < length)addElement(that, index++);
      });
      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);
      hide(TypedArrayPrototype, 'constructor', TypedArray);
    } else if(!$iterDetect(function(iter){
      // V8 works with iterators, but fails in many other cases
      // https://code.google.com/p/v8/issues/detail?id=4552
      new TypedArray(null); // eslint-disable-line no-new
      new TypedArray(iter); // eslint-disable-line no-new
    }, true)){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME);
        var klass;
        // `ws` module bug, temporarily remove validation length for Uint8Array
        // https://github.com/websockets/ws/pull/645
        if(!isObject(data))return new Base(strictToLength(data, ISNT_UINT8));
        if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          return $length !== undefined
            ? new Base(data, toOffset($offset, BYTES), $length)
            : $offset !== undefined
              ? new Base(data, toOffset($offset, BYTES))
              : new Base(data);
        }
        if(TYPED_ARRAY in data)return fromList(TypedArray, data);
        return $from.call(TypedArray, data);
      });
      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function(key){
        if(!(key in TypedArray))hide(TypedArray, key, Base[key]);
      });
      TypedArray[PROTOTYPE] = TypedArrayPrototype;
      if(!LIBRARY)TypedArrayPrototype.constructor = TypedArray;
    }
    var $nativeIterator   = TypedArrayPrototype[ITERATOR]
      , CORRECT_ITER_NAME = !!$nativeIterator && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined)
      , $iterator         = $iterators.values;
    hide(TypedArray, TYPED_CONSTRUCTOR, true);
    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);
    hide(TypedArrayPrototype, VIEW, true);
    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);

    if(CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)){
      dP(TypedArrayPrototype, TAG, {
        get: function(){ return NAME; }
      });
    }

    O[NAME] = TypedArray;

    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);

    $export($export.S, NAME, {
      BYTES_PER_ELEMENT: BYTES,
      from: $from,
      of: $of
    });

    if(!(BYTES_PER_ELEMENT in TypedArrayPrototype))hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);

    $export($export.P, NAME, proto);

    setSpecies(NAME);

    $export($export.P + $export.F * FORCED_SET, NAME, {set: $set});

    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);

    $export($export.P + $export.F * (TypedArrayPrototype.toString != arrayToString), NAME, {toString: arrayToString});

    $export($export.P + $export.F * fails(function(){
      new TypedArray(1).slice();
    }), NAME, {slice: $slice});

    $export($export.P + $export.F * (fails(function(){
      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString()
    }) || !fails(function(){
      TypedArrayPrototype.toLocaleString.call([1, 2]);
    })), NAME, {toLocaleString: $toLocaleString});

    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;
    if(!LIBRARY && !CORRECT_ITER_NAME)hide(TypedArrayPrototype, ITERATOR, $iterator);
  };
} else module.exports = function(){ /* empty */ };
},{"./_an-instance":8,"./_array-copy-within":10,"./_array-fill":11,"./_array-includes":13,"./_array-methods":14,"./_classof":19,"./_ctx":27,"./_descriptors":30,"./_export":34,"./_fails":36,"./_global":40,"./_has":41,"./_hide":42,"./_is-array-iter":48,"./_is-object":51,"./_iter-detect":56,"./_iterators":58,"./_library":60,"./_object-create":68,"./_object-dp":69,"./_object-gopd":72,"./_object-gopn":74,"./_object-gpo":76,"./_property-desc":87,"./_redefine-all":88,"./_same-value":91,"./_set-species":93,"./_species-constructor":97,"./_to-index":107,"./_to-integer":108,"./_to-length":110,"./_to-object":111,"./_to-primitive":112,"./_typed":115,"./_typed-buffer":114,"./_uid":116,"./_wks":119,"./core.get-iterator-method":120,"./es6.array.iterator":132}],114:[function(require,module,exports){
'use strict';
var global         = require('./_global')
  , DESCRIPTORS    = require('./_descriptors')
  , LIBRARY        = require('./_library')
  , $typed         = require('./_typed')
  , hide           = require('./_hide')
  , redefineAll    = require('./_redefine-all')
  , fails          = require('./_fails')
  , anInstance     = require('./_an-instance')
  , toInteger      = require('./_to-integer')
  , toLength       = require('./_to-length')
  , gOPN           = require('./_object-gopn').f
  , dP             = require('./_object-dp').f
  , arrayFill      = require('./_array-fill')
  , setToStringTag = require('./_set-to-string-tag')
  , ARRAY_BUFFER   = 'ArrayBuffer'
  , DATA_VIEW      = 'DataView'
  , PROTOTYPE      = 'prototype'
  , WRONG_LENGTH   = 'Wrong length!'
  , WRONG_INDEX    = 'Wrong index!'
  , $ArrayBuffer   = global[ARRAY_BUFFER]
  , $DataView      = global[DATA_VIEW]
  , Math           = global.Math
  , RangeError     = global.RangeError
  , Infinity       = global.Infinity
  , BaseBuffer     = $ArrayBuffer
  , abs            = Math.abs
  , pow            = Math.pow
  , floor          = Math.floor
  , log            = Math.log
  , LN2            = Math.LN2
  , BUFFER         = 'buffer'
  , BYTE_LENGTH    = 'byteLength'
  , BYTE_OFFSET    = 'byteOffset'
  , $BUFFER        = DESCRIPTORS ? '_b' : BUFFER
  , $LENGTH        = DESCRIPTORS ? '_l' : BYTE_LENGTH
  , $OFFSET        = DESCRIPTORS ? '_o' : BYTE_OFFSET;

// IEEE754 conversions based on https://github.com/feross/ieee754
var packIEEE754 = function(value, mLen, nBytes){
  var buffer = Array(nBytes)
    , eLen   = nBytes * 8 - mLen - 1
    , eMax   = (1 << eLen) - 1
    , eBias  = eMax >> 1
    , rt     = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0
    , i      = 0
    , s      = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0
    , e, m, c;
  value = abs(value)
  if(value != value || value === Infinity){
    m = value != value ? 1 : 0;
    e = eMax;
  } else {
    e = floor(log(value) / LN2);
    if(value * (c = pow(2, -e)) < 1){
      e--;
      c *= 2;
    }
    if(e + eBias >= 1){
      value += rt / c;
    } else {
      value += rt * pow(2, 1 - eBias);
    }
    if(value * c >= 2){
      e++;
      c /= 2;
    }
    if(e + eBias >= eMax){
      m = 0;
      e = eMax;
    } else if(e + eBias >= 1){
      m = (value * c - 1) * pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * pow(2, eBias - 1) * pow(2, mLen);
      e = 0;
    }
  }
  for(; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);
  e = e << mLen | m;
  eLen += mLen;
  for(; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);
  buffer[--i] |= s * 128;
  return buffer;
};
var unpackIEEE754 = function(buffer, mLen, nBytes){
  var eLen  = nBytes * 8 - mLen - 1
    , eMax  = (1 << eLen) - 1
    , eBias = eMax >> 1
    , nBits = eLen - 7
    , i     = nBytes - 1
    , s     = buffer[i--]
    , e     = s & 127
    , m;
  s >>= 7;
  for(; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);
  m = e & (1 << -nBits) - 1;
  e >>= -nBits;
  nBits += mLen;
  for(; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
  if(e === 0){
    e = 1 - eBias;
  } else if(e === eMax){
    return m ? NaN : s ? -Infinity : Infinity;
  } else {
    m = m + pow(2, mLen);
    e = e - eBias;
  } return (s ? -1 : 1) * m * pow(2, e - mLen);
};

var unpackI32 = function(bytes){
  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
};
var packI8 = function(it){
  return [it & 0xff];
};
var packI16 = function(it){
  return [it & 0xff, it >> 8 & 0xff];
};
var packI32 = function(it){
  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];
};
var packF64 = function(it){
  return packIEEE754(it, 52, 8);
};
var packF32 = function(it){
  return packIEEE754(it, 23, 4);
};

var addGetter = function(C, key, internal){
  dP(C[PROTOTYPE], key, {get: function(){ return this[internal]; }});
};

var get = function(view, bytes, index, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = store.slice(start, start + bytes);
  return isLittleEndian ? pack : pack.reverse();
};
var set = function(view, bytes, index, conversion, value, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = conversion(+value);
  for(var i = 0; i < bytes; i++)store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];
};

var validateArrayBufferArguments = function(that, length){
  anInstance(that, $ArrayBuffer, ARRAY_BUFFER);
  var numberLength = +length
    , byteLength   = toLength(numberLength);
  if(numberLength != byteLength)throw RangeError(WRONG_LENGTH);
  return byteLength;
};

if(!$typed.ABV){
  $ArrayBuffer = function ArrayBuffer(length){
    var byteLength = validateArrayBufferArguments(this, length);
    this._b       = arrayFill.call(Array(byteLength), 0);
    this[$LENGTH] = byteLength;
  };

  $DataView = function DataView(buffer, byteOffset, byteLength){
    anInstance(this, $DataView, DATA_VIEW);
    anInstance(buffer, $ArrayBuffer, DATA_VIEW);
    var bufferLength = buffer[$LENGTH]
      , offset       = toInteger(byteOffset);
    if(offset < 0 || offset > bufferLength)throw RangeError('Wrong offset!');
    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
    if(offset + byteLength > bufferLength)throw RangeError(WRONG_LENGTH);
    this[$BUFFER] = buffer;
    this[$OFFSET] = offset;
    this[$LENGTH] = byteLength;
  };

  if(DESCRIPTORS){
    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');
    addGetter($DataView, BUFFER, '_b');
    addGetter($DataView, BYTE_LENGTH, '_l');
    addGetter($DataView, BYTE_OFFSET, '_o');
  }

  redefineAll($DataView[PROTOTYPE], {
    getInt8: function getInt8(byteOffset){
      return get(this, 1, byteOffset)[0] << 24 >> 24;
    },
    getUint8: function getUint8(byteOffset){
      return get(this, 1, byteOffset)[0];
    },
    getInt16: function getInt16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
    },
    getUint16: function getUint16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return bytes[1] << 8 | bytes[0];
    },
    getInt32: function getInt32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1]));
    },
    getUint32: function getUint32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;
    },
    getFloat32: function getFloat32(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);
    },
    getFloat64: function getFloat64(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);
    },
    setInt8: function setInt8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setUint8: function setUint8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setInt16: function setInt16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setUint16: function setUint16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setInt32: function setInt32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setUint32: function setUint32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setFloat32: function setFloat32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packF32, value, arguments[2]);
    },
    setFloat64: function setFloat64(byteOffset, value /*, littleEndian */){
      set(this, 8, byteOffset, packF64, value, arguments[2]);
    }
  });
} else {
  if(!fails(function(){
    new $ArrayBuffer;     // eslint-disable-line no-new
  }) || !fails(function(){
    new $ArrayBuffer(.5); // eslint-disable-line no-new
  })){
    $ArrayBuffer = function ArrayBuffer(length){
      return new BaseBuffer(validateArrayBufferArguments(this, length));
    };
    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];
    for(var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j; ){
      if(!((key = keys[j++]) in $ArrayBuffer))hide($ArrayBuffer, key, BaseBuffer[key]);
    };
    if(!LIBRARY)ArrayBufferProto.constructor = $ArrayBuffer;
  }
  // iOS Safari 7.x bug
  var view = new $DataView(new $ArrayBuffer(2))
    , $setInt8 = $DataView[PROTOTYPE].setInt8;
  view.setInt8(0, 2147483648);
  view.setInt8(1, 2147483649);
  if(view.getInt8(0) || !view.getInt8(1))redefineAll($DataView[PROTOTYPE], {
    setInt8: function setInt8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    },
    setUint8: function setUint8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    }
  }, true);
}
setToStringTag($ArrayBuffer, ARRAY_BUFFER);
setToStringTag($DataView, DATA_VIEW);
hide($DataView[PROTOTYPE], $typed.VIEW, true);
exports[ARRAY_BUFFER] = $ArrayBuffer;
exports[DATA_VIEW] = $DataView;
},{"./_an-instance":8,"./_array-fill":11,"./_descriptors":30,"./_fails":36,"./_global":40,"./_hide":42,"./_library":60,"./_object-dp":69,"./_object-gopn":74,"./_redefine-all":88,"./_set-to-string-tag":94,"./_to-integer":108,"./_to-length":110,"./_typed":115}],115:[function(require,module,exports){
var global = require('./_global')
  , hide   = require('./_hide')
  , uid    = require('./_uid')
  , TYPED  = uid('typed_array')
  , VIEW   = uid('view')
  , ABV    = !!(global.ArrayBuffer && global.DataView)
  , CONSTR = ABV
  , i = 0, l = 9, Typed;

var TypedArrayConstructors = (
  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'
).split(',');

while(i < l){
  if(Typed = global[TypedArrayConstructors[i++]]){
    hide(Typed.prototype, TYPED, true);
    hide(Typed.prototype, VIEW, true);
  } else CONSTR = false;
}

module.exports = {
  ABV:    ABV,
  CONSTR: CONSTR,
  TYPED:  TYPED,
  VIEW:   VIEW
};
},{"./_global":40,"./_hide":42,"./_uid":116}],116:[function(require,module,exports){
var id = 0
  , px = Math.random();
module.exports = function(key){
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};
},{}],117:[function(require,module,exports){
var global         = require('./_global')
  , core           = require('./_core')
  , LIBRARY        = require('./_library')
  , wksExt         = require('./_wks-ext')
  , defineProperty = require('./_object-dp').f;
module.exports = function(name){
  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
  if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});
};
},{"./_core":25,"./_global":40,"./_library":60,"./_object-dp":69,"./_wks-ext":118}],118:[function(require,module,exports){
exports.f = require('./_wks');
},{"./_wks":119}],119:[function(require,module,exports){
var store      = require('./_shared')('wks')
  , uid        = require('./_uid')
  , Symbol     = require('./_global').Symbol
  , USE_SYMBOL = typeof Symbol == 'function';

var $exports = module.exports = function(name){
  return store[name] || (store[name] =
    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};

$exports.store = store;
},{"./_global":40,"./_shared":96,"./_uid":116}],120:[function(require,module,exports){
var classof   = require('./_classof')
  , ITERATOR  = require('./_wks')('iterator')
  , Iterators = require('./_iterators');
module.exports = require('./_core').getIteratorMethod = function(it){
  if(it != undefined)return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};
},{"./_classof":19,"./_core":25,"./_iterators":58,"./_wks":119}],121:[function(require,module,exports){
// https://github.com/benjamingr/RexExp.escape
var $export = require('./_export')
  , $re     = require('./_replacer')(/[\\^$*+?.()|[\]{}]/g, '\\$&');

$export($export.S, 'RegExp', {escape: function escape(it){ return $re(it); }});

},{"./_export":34,"./_replacer":90}],122:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
var $export = require('./_export');

$export($export.P, 'Array', {copyWithin: require('./_array-copy-within')});

require('./_add-to-unscopables')('copyWithin');
},{"./_add-to-unscopables":7,"./_array-copy-within":10,"./_export":34}],123:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $every  = require('./_array-methods')(4);

$export($export.P + $export.F * !require('./_strict-method')([].every, true), 'Array', {
  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
  every: function every(callbackfn /* , thisArg */){
    return $every(this, callbackfn, arguments[1]);
  }
});
},{"./_array-methods":14,"./_export":34,"./_strict-method":98}],124:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
var $export = require('./_export');

$export($export.P, 'Array', {fill: require('./_array-fill')});

require('./_add-to-unscopables')('fill');
},{"./_add-to-unscopables":7,"./_array-fill":11,"./_export":34}],125:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $filter = require('./_array-methods')(2);

$export($export.P + $export.F * !require('./_strict-method')([].filter, true), 'Array', {
  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
  filter: function filter(callbackfn /* , thisArg */){
    return $filter(this, callbackfn, arguments[1]);
  }
});
},{"./_array-methods":14,"./_export":34,"./_strict-method":98}],126:[function(require,module,exports){
'use strict';
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = require('./_export')
  , $find   = require('./_array-methods')(6)
  , KEY     = 'findIndex'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  findIndex: function findIndex(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);
},{"./_add-to-unscopables":7,"./_array-methods":14,"./_export":34}],127:[function(require,module,exports){
'use strict';
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = require('./_export')
  , $find   = require('./_array-methods')(5)
  , KEY     = 'find'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  find: function find(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);
},{"./_add-to-unscopables":7,"./_array-methods":14,"./_export":34}],128:[function(require,module,exports){
'use strict';
var $export  = require('./_export')
  , $forEach = require('./_array-methods')(0)
  , STRICT   = require('./_strict-method')([].forEach, true);

$export($export.P + $export.F * !STRICT, 'Array', {
  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
  forEach: function forEach(callbackfn /* , thisArg */){
    return $forEach(this, callbackfn, arguments[1]);
  }
});
},{"./_array-methods":14,"./_export":34,"./_strict-method":98}],129:[function(require,module,exports){
'use strict';
var ctx            = require('./_ctx')
  , $export        = require('./_export')
  , toObject       = require('./_to-object')
  , call           = require('./_iter-call')
  , isArrayIter    = require('./_is-array-iter')
  , toLength       = require('./_to-length')
  , createProperty = require('./_create-property')
  , getIterFn      = require('./core.get-iterator-method');

$export($export.S + $export.F * !require('./_iter-detect')(function(iter){ Array.from(iter); }), 'Array', {
  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
  from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){
    var O       = toObject(arrayLike)
      , C       = typeof this == 'function' ? this : Array
      , aLen    = arguments.length
      , mapfn   = aLen > 1 ? arguments[1] : undefined
      , mapping = mapfn !== undefined
      , index   = 0
      , iterFn  = getIterFn(O)
      , length, result, step, iterator;
    if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
    // if object isn't iterable or it's array with default iterator - use simple case
    if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){
      for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){
        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
      }
    } else {
      length = toLength(O.length);
      for(result = new C(length); length > index; index++){
        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
      }
    }
    result.length = index;
    return result;
  }
});

},{"./_create-property":26,"./_ctx":27,"./_export":34,"./_is-array-iter":48,"./_iter-call":53,"./_iter-detect":56,"./_to-length":110,"./_to-object":111,"./core.get-iterator-method":120}],130:[function(require,module,exports){
'use strict';
var $export       = require('./_export')
  , $indexOf      = require('./_array-includes')(false)
  , $native       = [].indexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
  indexOf: function indexOf(searchElement /*, fromIndex = 0 */){
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? $native.apply(this, arguments) || 0
      : $indexOf(this, searchElement, arguments[1]);
  }
});
},{"./_array-includes":13,"./_export":34,"./_strict-method":98}],131:[function(require,module,exports){
// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
var $export = require('./_export');

$export($export.S, 'Array', {isArray: require('./_is-array')});
},{"./_export":34,"./_is-array":49}],132:[function(require,module,exports){
'use strict';
var addToUnscopables = require('./_add-to-unscopables')
  , step             = require('./_iter-step')
  , Iterators        = require('./_iterators')
  , toIObject        = require('./_to-iobject');

// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = require('./_iter-define')(Array, 'Array', function(iterated, kind){
  this._t = toIObject(iterated); // target
  this._i = 0;                   // next index
  this._k = kind;                // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function(){
  var O     = this._t
    , kind  = this._k
    , index = this._i++;
  if(!O || index >= O.length){
    this._t = undefined;
    return step(1);
  }
  if(kind == 'keys'  )return step(0, index);
  if(kind == 'values')return step(0, O[index]);
  return step(0, [index, O[index]]);
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;

addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');
},{"./_add-to-unscopables":7,"./_iter-define":55,"./_iter-step":57,"./_iterators":58,"./_to-iobject":109}],133:[function(require,module,exports){
'use strict';
// 22.1.3.13 Array.prototype.join(separator)
var $export   = require('./_export')
  , toIObject = require('./_to-iobject')
  , arrayJoin = [].join;

// fallback for not array-like strings
$export($export.P + $export.F * (require('./_iobject') != Object || !require('./_strict-method')(arrayJoin)), 'Array', {
  join: function join(separator){
    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);
  }
});
},{"./_export":34,"./_iobject":47,"./_strict-method":98,"./_to-iobject":109}],134:[function(require,module,exports){
'use strict';
var $export       = require('./_export')
  , toIObject     = require('./_to-iobject')
  , toInteger     = require('./_to-integer')
  , toLength      = require('./_to-length')
  , $native       = [].lastIndexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
  lastIndexOf: function lastIndexOf(searchElement /*, fromIndex = @[*-1] */){
    // convert -0 to +0
    if(NEGATIVE_ZERO)return $native.apply(this, arguments) || 0;
    var O      = toIObject(this)
      , length = toLength(O.length)
      , index  = length - 1;
    if(arguments.length > 1)index = Math.min(index, toInteger(arguments[1]));
    if(index < 0)index = length + index;
    for(;index >= 0; index--)if(index in O)if(O[index] === searchElement)return index || 0;
    return -1;
  }
});
},{"./_export":34,"./_strict-method":98,"./_to-integer":108,"./_to-iobject":109,"./_to-length":110}],135:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $map    = require('./_array-methods')(1);

$export($export.P + $export.F * !require('./_strict-method')([].map, true), 'Array', {
  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
  map: function map(callbackfn /* , thisArg */){
    return $map(this, callbackfn, arguments[1]);
  }
});
},{"./_array-methods":14,"./_export":34,"./_strict-method":98}],136:[function(require,module,exports){
'use strict';
var $export        = require('./_export')
  , createProperty = require('./_create-property');

// WebKit Array.of isn't generic
$export($export.S + $export.F * require('./_fails')(function(){
  function F(){}
  return !(Array.of.call(F) instanceof F);
}), 'Array', {
  // 22.1.2.3 Array.of( ...items)
  of: function of(/* ...args */){
    var index  = 0
      , aLen   = arguments.length
      , result = new (typeof this == 'function' ? this : Array)(aLen);
    while(aLen > index)createProperty(result, index, arguments[index++]);
    result.length = aLen;
    return result;
  }
});
},{"./_create-property":26,"./_export":34,"./_fails":36}],137:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $reduce = require('./_array-reduce');

$export($export.P + $export.F * !require('./_strict-method')([].reduceRight, true), 'Array', {
  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
  reduceRight: function reduceRight(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], true);
  }
});
},{"./_array-reduce":15,"./_export":34,"./_strict-method":98}],138:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $reduce = require('./_array-reduce');

$export($export.P + $export.F * !require('./_strict-method')([].reduce, true), 'Array', {
  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
  reduce: function reduce(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], false);
  }
});
},{"./_array-reduce":15,"./_export":34,"./_strict-method":98}],139:[function(require,module,exports){
'use strict';
var $export    = require('./_export')
  , html       = require('./_html')
  , cof        = require('./_cof')
  , toIndex    = require('./_to-index')
  , toLength   = require('./_to-length')
  , arraySlice = [].slice;

// fallback for not array-like ES3 strings and DOM objects
$export($export.P + $export.F * require('./_fails')(function(){
  if(html)arraySlice.call(html);
}), 'Array', {
  slice: function slice(begin, end){
    var len   = toLength(this.length)
      , klass = cof(this);
    end = end === undefined ? len : end;
    if(klass == 'Array')return arraySlice.call(this, begin, end);
    var start  = toIndex(begin, len)
      , upTo   = toIndex(end, len)
      , size   = toLength(upTo - start)
      , cloned = Array(size)
      , i      = 0;
    for(; i < size; i++)cloned[i] = klass == 'String'
      ? this.charAt(start + i)
      : this[start + i];
    return cloned;
  }
});
},{"./_cof":20,"./_export":34,"./_fails":36,"./_html":43,"./_to-index":107,"./_to-length":110}],140:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $some   = require('./_array-methods')(3);

$export($export.P + $export.F * !require('./_strict-method')([].some, true), 'Array', {
  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
  some: function some(callbackfn /* , thisArg */){
    return $some(this, callbackfn, arguments[1]);
  }
});
},{"./_array-methods":14,"./_export":34,"./_strict-method":98}],141:[function(require,module,exports){
'use strict';
var $export   = require('./_export')
  , aFunction = require('./_a-function')
  , toObject  = require('./_to-object')
  , fails     = require('./_fails')
  , $sort     = [].sort
  , test      = [1, 2, 3];

$export($export.P + $export.F * (fails(function(){
  // IE8-
  test.sort(undefined);
}) || !fails(function(){
  // V8 bug
  test.sort(null);
  // Old WebKit
}) || !require('./_strict-method')($sort)), 'Array', {
  // 22.1.3.25 Array.prototype.sort(comparefn)
  sort: function sort(comparefn){
    return comparefn === undefined
      ? $sort.call(toObject(this))
      : $sort.call(toObject(this), aFunction(comparefn));
  }
});
},{"./_a-function":5,"./_export":34,"./_fails":36,"./_strict-method":98,"./_to-object":111}],142:[function(require,module,exports){
require('./_set-species')('Array');
},{"./_set-species":93}],143:[function(require,module,exports){
// 20.3.3.1 / 15.9.4.4 Date.now()
var $export = require('./_export');

$export($export.S, 'Date', {now: function(){ return new Date().getTime(); }});
},{"./_export":34}],144:[function(require,module,exports){
'use strict';
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var $export = require('./_export')
  , fails   = require('./_fails')
  , getTime = Date.prototype.getTime;

var lz = function(num){
  return num > 9 ? num : '0' + num;
};

// PhantomJS / old WebKit has a broken implementations
$export($export.P + $export.F * (fails(function(){
  return new Date(-5e13 - 1).toISOString() != '0385-07-25T07:06:39.999Z';
}) || !fails(function(){
  new Date(NaN).toISOString();
})), 'Date', {
  toISOString: function toISOString(){
    if(!isFinite(getTime.call(this)))throw RangeError('Invalid time value');
    var d = this
      , y = d.getUTCFullYear()
      , m = d.getUTCMilliseconds()
      , s = y < 0 ? '-' : y > 9999 ? '+' : '';
    return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
      '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
      'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
      ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
  }
});
},{"./_export":34,"./_fails":36}],145:[function(require,module,exports){
'use strict';
var $export     = require('./_export')
  , toObject    = require('./_to-object')
  , toPrimitive = require('./_to-primitive');

$export($export.P + $export.F * require('./_fails')(function(){
  return new Date(NaN).toJSON() !== null || Date.prototype.toJSON.call({toISOString: function(){ return 1; }}) !== 1;
}), 'Date', {
  toJSON: function toJSON(key){
    var O  = toObject(this)
      , pv = toPrimitive(O);
    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
  }
});
},{"./_export":34,"./_fails":36,"./_to-object":111,"./_to-primitive":112}],146:[function(require,module,exports){
var TO_PRIMITIVE = require('./_wks')('toPrimitive')
  , proto        = Date.prototype;

if(!(TO_PRIMITIVE in proto))require('./_hide')(proto, TO_PRIMITIVE, require('./_date-to-primitive'));
},{"./_date-to-primitive":28,"./_hide":42,"./_wks":119}],147:[function(require,module,exports){
var DateProto    = Date.prototype
  , INVALID_DATE = 'Invalid Date'
  , TO_STRING    = 'toString'
  , $toString    = DateProto[TO_STRING]
  , getTime      = DateProto.getTime;
if(new Date(NaN) + '' != INVALID_DATE){
  require('./_redefine')(DateProto, TO_STRING, function toString(){
    var value = getTime.call(this);
    return value === value ? $toString.call(this) : INVALID_DATE;
  });
}
},{"./_redefine":89}],148:[function(require,module,exports){
// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
var $export = require('./_export');

$export($export.P, 'Function', {bind: require('./_bind')});
},{"./_bind":18,"./_export":34}],149:[function(require,module,exports){
'use strict';
var isObject       = require('./_is-object')
  , getPrototypeOf = require('./_object-gpo')
  , HAS_INSTANCE   = require('./_wks')('hasInstance')
  , FunctionProto  = Function.prototype;
// 19.2.3.6 Function.prototype[@@hasInstance](V)
if(!(HAS_INSTANCE in FunctionProto))require('./_object-dp').f(FunctionProto, HAS_INSTANCE, {value: function(O){
  if(typeof this != 'function' || !isObject(O))return false;
  if(!isObject(this.prototype))return O instanceof this;
  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
  while(O = getPrototypeOf(O))if(this.prototype === O)return true;
  return false;
}});
},{"./_is-object":51,"./_object-dp":69,"./_object-gpo":76,"./_wks":119}],150:[function(require,module,exports){
var dP         = require('./_object-dp').f
  , createDesc = require('./_property-desc')
  , has        = require('./_has')
  , FProto     = Function.prototype
  , nameRE     = /^\s*function ([^ (]*)/
  , NAME       = 'name';

var isExtensible = Object.isExtensible || function(){
  return true;
};

// 19.2.4.2 name
NAME in FProto || require('./_descriptors') && dP(FProto, NAME, {
  configurable: true,
  get: function(){
    try {
      var that = this
        , name = ('' + that).match(nameRE)[1];
      has(that, NAME) || !isExtensible(that) || dP(that, NAME, createDesc(5, name));
      return name;
    } catch(e){
      return '';
    }
  }
});
},{"./_descriptors":30,"./_has":41,"./_object-dp":69,"./_property-desc":87}],151:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');

// 23.1 Map Objects
module.exports = require('./_collection')('Map', function(get){
  return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.1.3.6 Map.prototype.get(key)
  get: function get(key){
    var entry = strong.getEntry(this, key);
    return entry && entry.v;
  },
  // 23.1.3.9 Map.prototype.set(key, value)
  set: function set(key, value){
    return strong.def(this, key === 0 ? 0 : key, value);
  }
}, strong, true);
},{"./_collection":24,"./_collection-strong":21}],152:[function(require,module,exports){
// 20.2.2.3 Math.acosh(x)
var $export = require('./_export')
  , log1p   = require('./_math-log1p')
  , sqrt    = Math.sqrt
  , $acosh  = Math.acosh;

$export($export.S + $export.F * !($acosh
  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509
  && Math.floor($acosh(Number.MAX_VALUE)) == 710
  // Tor Browser bug: Math.acosh(Infinity) -> NaN 
  && $acosh(Infinity) == Infinity
), 'Math', {
  acosh: function acosh(x){
    return (x = +x) < 1 ? NaN : x > 94906265.62425156
      ? Math.log(x) + Math.LN2
      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
  }
});
},{"./_export":34,"./_math-log1p":62}],153:[function(require,module,exports){
// 20.2.2.5 Math.asinh(x)
var $export = require('./_export')
  , $asinh  = Math.asinh;

function asinh(x){
  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
}

// Tor Browser bug: Math.asinh(0) -> -0 
$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', {asinh: asinh});
},{"./_export":34}],154:[function(require,module,exports){
// 20.2.2.7 Math.atanh(x)
var $export = require('./_export')
  , $atanh  = Math.atanh;

// Tor Browser bug: Math.atanh(-0) -> 0 
$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {
  atanh: function atanh(x){
    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
  }
});
},{"./_export":34}],155:[function(require,module,exports){
// 20.2.2.9 Math.cbrt(x)
var $export = require('./_export')
  , sign    = require('./_math-sign');

$export($export.S, 'Math', {
  cbrt: function cbrt(x){
    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
  }
});
},{"./_export":34,"./_math-sign":63}],156:[function(require,module,exports){
// 20.2.2.11 Math.clz32(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  clz32: function clz32(x){
    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
  }
});
},{"./_export":34}],157:[function(require,module,exports){
// 20.2.2.12 Math.cosh(x)
var $export = require('./_export')
  , exp     = Math.exp;

$export($export.S, 'Math', {
  cosh: function cosh(x){
    return (exp(x = +x) + exp(-x)) / 2;
  }
});
},{"./_export":34}],158:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $export = require('./_export')
  , $expm1  = require('./_math-expm1');

$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', {expm1: $expm1});
},{"./_export":34,"./_math-expm1":61}],159:[function(require,module,exports){
// 20.2.2.16 Math.fround(x)
var $export   = require('./_export')
  , sign      = require('./_math-sign')
  , pow       = Math.pow
  , EPSILON   = pow(2, -52)
  , EPSILON32 = pow(2, -23)
  , MAX32     = pow(2, 127) * (2 - EPSILON32)
  , MIN32     = pow(2, -126);

var roundTiesToEven = function(n){
  return n + 1 / EPSILON - 1 / EPSILON;
};


$export($export.S, 'Math', {
  fround: function fround(x){
    var $abs  = Math.abs(x)
      , $sign = sign(x)
      , a, result;
    if($abs < MIN32)return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
    a = (1 + EPSILON32 / EPSILON) * $abs;
    result = a - (a - $abs);
    if(result > MAX32 || result != result)return $sign * Infinity;
    return $sign * result;
  }
});
},{"./_export":34,"./_math-sign":63}],160:[function(require,module,exports){
// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
var $export = require('./_export')
  , abs     = Math.abs;

$export($export.S, 'Math', {
  hypot: function hypot(value1, value2){ // eslint-disable-line no-unused-vars
    var sum  = 0
      , i    = 0
      , aLen = arguments.length
      , larg = 0
      , arg, div;
    while(i < aLen){
      arg = abs(arguments[i++]);
      if(larg < arg){
        div  = larg / arg;
        sum  = sum * div * div + 1;
        larg = arg;
      } else if(arg > 0){
        div  = arg / larg;
        sum += div * div;
      } else sum += arg;
    }
    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
  }
});
},{"./_export":34}],161:[function(require,module,exports){
// 20.2.2.18 Math.imul(x, y)
var $export = require('./_export')
  , $imul   = Math.imul;

// some WebKit versions fails with big numbers, some has wrong arity
$export($export.S + $export.F * require('./_fails')(function(){
  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
}), 'Math', {
  imul: function imul(x, y){
    var UINT16 = 0xffff
      , xn = +x
      , yn = +y
      , xl = UINT16 & xn
      , yl = UINT16 & yn;
    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
  }
});
},{"./_export":34,"./_fails":36}],162:[function(require,module,exports){
// 20.2.2.21 Math.log10(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  log10: function log10(x){
    return Math.log(x) / Math.LN10;
  }
});
},{"./_export":34}],163:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
var $export = require('./_export');

$export($export.S, 'Math', {log1p: require('./_math-log1p')});
},{"./_export":34,"./_math-log1p":62}],164:[function(require,module,exports){
// 20.2.2.22 Math.log2(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  log2: function log2(x){
    return Math.log(x) / Math.LN2;
  }
});
},{"./_export":34}],165:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
var $export = require('./_export');

$export($export.S, 'Math', {sign: require('./_math-sign')});
},{"./_export":34,"./_math-sign":63}],166:[function(require,module,exports){
// 20.2.2.30 Math.sinh(x)
var $export = require('./_export')
  , expm1   = require('./_math-expm1')
  , exp     = Math.exp;

// V8 near Chromium 38 has a problem with very small numbers
$export($export.S + $export.F * require('./_fails')(function(){
  return !Math.sinh(-2e-17) != -2e-17;
}), 'Math', {
  sinh: function sinh(x){
    return Math.abs(x = +x) < 1
      ? (expm1(x) - expm1(-x)) / 2
      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
  }
});
},{"./_export":34,"./_fails":36,"./_math-expm1":61}],167:[function(require,module,exports){
// 20.2.2.33 Math.tanh(x)
var $export = require('./_export')
  , expm1   = require('./_math-expm1')
  , exp     = Math.exp;

$export($export.S, 'Math', {
  tanh: function tanh(x){
    var a = expm1(x = +x)
      , b = expm1(-x);
    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
  }
});
},{"./_export":34,"./_math-expm1":61}],168:[function(require,module,exports){
// 20.2.2.34 Math.trunc(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  trunc: function trunc(it){
    return (it > 0 ? Math.floor : Math.ceil)(it);
  }
});
},{"./_export":34}],169:[function(require,module,exports){
'use strict';
var global            = require('./_global')
  , has               = require('./_has')
  , cof               = require('./_cof')
  , inheritIfRequired = require('./_inherit-if-required')
  , toPrimitive       = require('./_to-primitive')
  , fails             = require('./_fails')
  , gOPN              = require('./_object-gopn').f
  , gOPD              = require('./_object-gopd').f
  , dP                = require('./_object-dp').f
  , $trim             = require('./_string-trim').trim
  , NUMBER            = 'Number'
  , $Number           = global[NUMBER]
  , Base              = $Number
  , proto             = $Number.prototype
  // Opera ~12 has broken Object#toString
  , BROKEN_COF        = cof(require('./_object-create')(proto)) == NUMBER
  , TRIM              = 'trim' in String.prototype;

// 7.1.3 ToNumber(argument)
var toNumber = function(argument){
  var it = toPrimitive(argument, false);
  if(typeof it == 'string' && it.length > 2){
    it = TRIM ? it.trim() : $trim(it, 3);
    var first = it.charCodeAt(0)
      , third, radix, maxCode;
    if(first === 43 || first === 45){
      third = it.charCodeAt(2);
      if(third === 88 || third === 120)return NaN; // Number('+0x1') should be NaN, old V8 fix
    } else if(first === 48){
      switch(it.charCodeAt(1)){
        case 66 : case 98  : radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
        case 79 : case 111 : radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
        default : return +it;
      }
      for(var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++){
        code = digits.charCodeAt(i);
        // parseInt parses a string to a first unavailable symbol
        // but ToNumber should return NaN if a string contains unavailable symbols
        if(code < 48 || code > maxCode)return NaN;
      } return parseInt(digits, radix);
    }
  } return +it;
};

if(!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')){
  $Number = function Number(value){
    var it = arguments.length < 1 ? 0 : value
      , that = this;
    return that instanceof $Number
      // check on 1..constructor(foo) case
      && (BROKEN_COF ? fails(function(){ proto.valueOf.call(that); }) : cof(that) != NUMBER)
        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
  };
  for(var keys = require('./_descriptors') ? gOPN(Base) : (
    // ES3:
    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
    // ES6 (in case, if modules with ES6 Number statics required before):
    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
  ).split(','), j = 0, key; keys.length > j; j++){
    if(has(Base, key = keys[j]) && !has($Number, key)){
      dP($Number, key, gOPD(Base, key));
    }
  }
  $Number.prototype = proto;
  proto.constructor = $Number;
  require('./_redefine')(global, NUMBER, $Number);
}
},{"./_cof":20,"./_descriptors":30,"./_fails":36,"./_global":40,"./_has":41,"./_inherit-if-required":45,"./_object-create":68,"./_object-dp":69,"./_object-gopd":72,"./_object-gopn":74,"./_redefine":89,"./_string-trim":104,"./_to-primitive":112}],170:[function(require,module,exports){
// 20.1.2.1 Number.EPSILON
var $export = require('./_export');

$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});
},{"./_export":34}],171:[function(require,module,exports){
// 20.1.2.2 Number.isFinite(number)
var $export   = require('./_export')
  , _isFinite = require('./_global').isFinite;

$export($export.S, 'Number', {
  isFinite: function isFinite(it){
    return typeof it == 'number' && _isFinite(it);
  }
});
},{"./_export":34,"./_global":40}],172:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var $export = require('./_export');

$export($export.S, 'Number', {isInteger: require('./_is-integer')});
},{"./_export":34,"./_is-integer":50}],173:[function(require,module,exports){
// 20.1.2.4 Number.isNaN(number)
var $export = require('./_export');

$export($export.S, 'Number', {
  isNaN: function isNaN(number){
    return number != number;
  }
});
},{"./_export":34}],174:[function(require,module,exports){
// 20.1.2.5 Number.isSafeInteger(number)
var $export   = require('./_export')
  , isInteger = require('./_is-integer')
  , abs       = Math.abs;

$export($export.S, 'Number', {
  isSafeInteger: function isSafeInteger(number){
    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
  }
});
},{"./_export":34,"./_is-integer":50}],175:[function(require,module,exports){
// 20.1.2.6 Number.MAX_SAFE_INTEGER
var $export = require('./_export');

$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});
},{"./_export":34}],176:[function(require,module,exports){
// 20.1.2.10 Number.MIN_SAFE_INTEGER
var $export = require('./_export');

$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});
},{"./_export":34}],177:[function(require,module,exports){
var $export     = require('./_export')
  , $parseFloat = require('./_parse-float');
// 20.1.2.12 Number.parseFloat(string)
$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', {parseFloat: $parseFloat});
},{"./_export":34,"./_parse-float":83}],178:[function(require,module,exports){
var $export   = require('./_export')
  , $parseInt = require('./_parse-int');
// 20.1.2.13 Number.parseInt(string, radix)
$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', {parseInt: $parseInt});
},{"./_export":34,"./_parse-int":84}],179:[function(require,module,exports){
'use strict';
var $export      = require('./_export')
  , toInteger    = require('./_to-integer')
  , aNumberValue = require('./_a-number-value')
  , repeat       = require('./_string-repeat')
  , $toFixed     = 1..toFixed
  , floor        = Math.floor
  , data         = [0, 0, 0, 0, 0, 0]
  , ERROR        = 'Number.toFixed: incorrect invocation!'
  , ZERO         = '0';

var multiply = function(n, c){
  var i  = -1
    , c2 = c;
  while(++i < 6){
    c2 += n * data[i];
    data[i] = c2 % 1e7;
    c2 = floor(c2 / 1e7);
  }
};
var divide = function(n){
  var i = 6
    , c = 0;
  while(--i >= 0){
    c += data[i];
    data[i] = floor(c / n);
    c = (c % n) * 1e7;
  }
};
var numToString = function(){
  var i = 6
    , s = '';
  while(--i >= 0){
    if(s !== '' || i === 0 || data[i] !== 0){
      var t = String(data[i]);
      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;
    }
  } return s;
};
var pow = function(x, n, acc){
  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function(x){
  var n  = 0
    , x2 = x;
  while(x2 >= 4096){
    n += 12;
    x2 /= 4096;
  }
  while(x2 >= 2){
    n  += 1;
    x2 /= 2;
  } return n;
};

$export($export.P + $export.F * (!!$toFixed && (
  0.00008.toFixed(3) !== '0.000' ||
  0.9.toFixed(0) !== '1' ||
  1.255.toFixed(2) !== '1.25' ||
  1000000000000000128..toFixed(0) !== '1000000000000000128'
) || !require('./_fails')(function(){
  // V8 ~ Android 4.3-
  $toFixed.call({});
})), 'Number', {
  toFixed: function toFixed(fractionDigits){
    var x = aNumberValue(this, ERROR)
      , f = toInteger(fractionDigits)
      , s = ''
      , m = ZERO
      , e, z, j, k;
    if(f < 0 || f > 20)throw RangeError(ERROR);
    if(x != x)return 'NaN';
    if(x <= -1e21 || x >= 1e21)return String(x);
    if(x < 0){
      s = '-';
      x = -x;
    }
    if(x > 1e-21){
      e = log(x * pow(2, 69, 1)) - 69;
      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
      z *= 0x10000000000000;
      e = 52 - e;
      if(e > 0){
        multiply(0, z);
        j = f;
        while(j >= 7){
          multiply(1e7, 0);
          j -= 7;
        }
        multiply(pow(10, j, 1), 0);
        j = e - 1;
        while(j >= 23){
          divide(1 << 23);
          j -= 23;
        }
        divide(1 << j);
        multiply(1, 1);
        divide(2);
        m = numToString();
      } else {
        multiply(0, z);
        multiply(1 << -e, 0);
        m = numToString() + repeat.call(ZERO, f);
      }
    }
    if(f > 0){
      k = m.length;
      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
    } else {
      m = s + m;
    } return m;
  }
});
},{"./_a-number-value":6,"./_export":34,"./_fails":36,"./_string-repeat":103,"./_to-integer":108}],180:[function(require,module,exports){
'use strict';
var $export      = require('./_export')
  , $fails       = require('./_fails')
  , aNumberValue = require('./_a-number-value')
  , $toPrecision = 1..toPrecision;

$export($export.P + $export.F * ($fails(function(){
  // IE7-
  return $toPrecision.call(1, undefined) !== '1';
}) || !$fails(function(){
  // V8 ~ Android 4.3-
  $toPrecision.call({});
})), 'Number', {
  toPrecision: function toPrecision(precision){
    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');
    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision); 
  }
});
},{"./_a-number-value":6,"./_export":34,"./_fails":36}],181:[function(require,module,exports){
// 19.1.3.1 Object.assign(target, source)
var $export = require('./_export');

$export($export.S + $export.F, 'Object', {assign: require('./_object-assign')});
},{"./_export":34,"./_object-assign":67}],182:[function(require,module,exports){
var $export = require('./_export')
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
$export($export.S, 'Object', {create: require('./_object-create')});
},{"./_export":34,"./_object-create":68}],183:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', {defineProperties: require('./_object-dps')});
},{"./_descriptors":30,"./_export":34,"./_object-dps":70}],184:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', {defineProperty: require('./_object-dp').f});
},{"./_descriptors":30,"./_export":34,"./_object-dp":69}],185:[function(require,module,exports){
// 19.1.2.5 Object.freeze(O)
var isObject = require('./_is-object')
  , meta     = require('./_meta').onFreeze;

require('./_object-sap')('freeze', function($freeze){
  return function freeze(it){
    return $freeze && isObject(it) ? $freeze(meta(it)) : it;
  };
});
},{"./_is-object":51,"./_meta":64,"./_object-sap":80}],186:[function(require,module,exports){
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
var toIObject                 = require('./_to-iobject')
  , $getOwnPropertyDescriptor = require('./_object-gopd').f;

require('./_object-sap')('getOwnPropertyDescriptor', function(){
  return function getOwnPropertyDescriptor(it, key){
    return $getOwnPropertyDescriptor(toIObject(it), key);
  };
});
},{"./_object-gopd":72,"./_object-sap":80,"./_to-iobject":109}],187:[function(require,module,exports){
// 19.1.2.7 Object.getOwnPropertyNames(O)
require('./_object-sap')('getOwnPropertyNames', function(){
  return require('./_object-gopn-ext').f;
});
},{"./_object-gopn-ext":73,"./_object-sap":80}],188:[function(require,module,exports){
// 19.1.2.9 Object.getPrototypeOf(O)
var toObject        = require('./_to-object')
  , $getPrototypeOf = require('./_object-gpo');

require('./_object-sap')('getPrototypeOf', function(){
  return function getPrototypeOf(it){
    return $getPrototypeOf(toObject(it));
  };
});
},{"./_object-gpo":76,"./_object-sap":80,"./_to-object":111}],189:[function(require,module,exports){
// 19.1.2.11 Object.isExtensible(O)
var isObject = require('./_is-object');

require('./_object-sap')('isExtensible', function($isExtensible){
  return function isExtensible(it){
    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
  };
});
},{"./_is-object":51,"./_object-sap":80}],190:[function(require,module,exports){
// 19.1.2.12 Object.isFrozen(O)
var isObject = require('./_is-object');

require('./_object-sap')('isFrozen', function($isFrozen){
  return function isFrozen(it){
    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
  };
});
},{"./_is-object":51,"./_object-sap":80}],191:[function(require,module,exports){
// 19.1.2.13 Object.isSealed(O)
var isObject = require('./_is-object');

require('./_object-sap')('isSealed', function($isSealed){
  return function isSealed(it){
    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
  };
});
},{"./_is-object":51,"./_object-sap":80}],192:[function(require,module,exports){
// 19.1.3.10 Object.is(value1, value2)
var $export = require('./_export');
$export($export.S, 'Object', {is: require('./_same-value')});
},{"./_export":34,"./_same-value":91}],193:[function(require,module,exports){
// 19.1.2.14 Object.keys(O)
var toObject = require('./_to-object')
  , $keys    = require('./_object-keys');

require('./_object-sap')('keys', function(){
  return function keys(it){
    return $keys(toObject(it));
  };
});
},{"./_object-keys":78,"./_object-sap":80,"./_to-object":111}],194:[function(require,module,exports){
// 19.1.2.15 Object.preventExtensions(O)
var isObject = require('./_is-object')
  , meta     = require('./_meta').onFreeze;

require('./_object-sap')('preventExtensions', function($preventExtensions){
  return function preventExtensions(it){
    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;
  };
});
},{"./_is-object":51,"./_meta":64,"./_object-sap":80}],195:[function(require,module,exports){
// 19.1.2.17 Object.seal(O)
var isObject = require('./_is-object')
  , meta     = require('./_meta').onFreeze;

require('./_object-sap')('seal', function($seal){
  return function seal(it){
    return $seal && isObject(it) ? $seal(meta(it)) : it;
  };
});
},{"./_is-object":51,"./_meta":64,"./_object-sap":80}],196:[function(require,module,exports){
// 19.1.3.19 Object.setPrototypeOf(O, proto)
var $export = require('./_export');
$export($export.S, 'Object', {setPrototypeOf: require('./_set-proto').set});
},{"./_export":34,"./_set-proto":92}],197:[function(require,module,exports){
'use strict';
// 19.1.3.6 Object.prototype.toString()
var classof = require('./_classof')
  , test    = {};
test[require('./_wks')('toStringTag')] = 'z';
if(test + '' != '[object z]'){
  require('./_redefine')(Object.prototype, 'toString', function toString(){
    return '[object ' + classof(this) + ']';
  }, true);
}
},{"./_classof":19,"./_redefine":89,"./_wks":119}],198:[function(require,module,exports){
var $export     = require('./_export')
  , $parseFloat = require('./_parse-float');
// 18.2.4 parseFloat(string)
$export($export.G + $export.F * (parseFloat != $parseFloat), {parseFloat: $parseFloat});
},{"./_export":34,"./_parse-float":83}],199:[function(require,module,exports){
var $export   = require('./_export')
  , $parseInt = require('./_parse-int');
// 18.2.5 parseInt(string, radix)
$export($export.G + $export.F * (parseInt != $parseInt), {parseInt: $parseInt});
},{"./_export":34,"./_parse-int":84}],200:[function(require,module,exports){
'use strict';
var LIBRARY            = require('./_library')
  , global             = require('./_global')
  , ctx                = require('./_ctx')
  , classof            = require('./_classof')
  , $export            = require('./_export')
  , isObject           = require('./_is-object')
  , aFunction          = require('./_a-function')
  , anInstance         = require('./_an-instance')
  , forOf              = require('./_for-of')
  , speciesConstructor = require('./_species-constructor')
  , task               = require('./_task').set
  , microtask          = require('./_microtask')()
  , PROMISE            = 'Promise'
  , TypeError          = global.TypeError
  , process            = global.process
  , $Promise           = global[PROMISE]
  , process            = global.process
  , isNode             = classof(process) == 'process'
  , empty              = function(){ /* empty */ }
  , Internal, GenericPromiseCapability, Wrapper;

var USE_NATIVE = !!function(){
  try {
    // correct subclassing with @@species support
    var promise     = $Promise.resolve(1)
      , FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function(exec){ exec(empty, empty); };
    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
    return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
  } catch(e){ /* empty */ }
}();

// helpers
var sameConstructor = function(a, b){
  // with library wrapper special case
  return a === b || a === $Promise && b === Wrapper;
};
var isThenable = function(it){
  var then;
  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var newPromiseCapability = function(C){
  return sameConstructor($Promise, C)
    ? new PromiseCapability(C)
    : new GenericPromiseCapability(C);
};
var PromiseCapability = GenericPromiseCapability = function(C){
  var resolve, reject;
  this.promise = new C(function($$resolve, $$reject){
    if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');
    resolve = $$resolve;
    reject  = $$reject;
  });
  this.resolve = aFunction(resolve);
  this.reject  = aFunction(reject);
};
var perform = function(exec){
  try {
    exec();
  } catch(e){
    return {error: e};
  }
};
var notify = function(promise, isReject){
  if(promise._n)return;
  promise._n = true;
  var chain = promise._c;
  microtask(function(){
    var value = promise._v
      , ok    = promise._s == 1
      , i     = 0;
    var run = function(reaction){
      var handler = ok ? reaction.ok : reaction.fail
        , resolve = reaction.resolve
        , reject  = reaction.reject
        , domain  = reaction.domain
        , result, then;
      try {
        if(handler){
          if(!ok){
            if(promise._h == 2)onHandleUnhandled(promise);
            promise._h = 1;
          }
          if(handler === true)result = value;
          else {
            if(domain)domain.enter();
            result = handler(value);
            if(domain)domain.exit();
          }
          if(result === reaction.promise){
            reject(TypeError('Promise-chain cycle'));
          } else if(then = isThenable(result)){
            then.call(result, resolve, reject);
          } else resolve(result);
        } else reject(value);
      } catch(e){
        reject(e);
      }
    };
    while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
    promise._c = [];
    promise._n = false;
    if(isReject && !promise._h)onUnhandled(promise);
  });
};
var onUnhandled = function(promise){
  task.call(global, function(){
    var value = promise._v
      , abrupt, handler, console;
    if(isUnhandled(promise)){
      abrupt = perform(function(){
        if(isNode){
          process.emit('unhandledRejection', value, promise);
        } else if(handler = global.onunhandledrejection){
          handler({promise: promise, reason: value});
        } else if((console = global.console) && console.error){
          console.error('Unhandled promise rejection', value);
        }
      });
      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
      promise._h = isNode || isUnhandled(promise) ? 2 : 1;
    } promise._a = undefined;
    if(abrupt)throw abrupt.error;
  });
};
var isUnhandled = function(promise){
  if(promise._h == 1)return false;
  var chain = promise._a || promise._c
    , i     = 0
    , reaction;
  while(chain.length > i){
    reaction = chain[i++];
    if(reaction.fail || !isUnhandled(reaction.promise))return false;
  } return true;
};
var onHandleUnhandled = function(promise){
  task.call(global, function(){
    var handler;
    if(isNode){
      process.emit('rejectionHandled', promise);
    } else if(handler = global.onrejectionhandled){
      handler({promise: promise, reason: promise._v});
    }
  });
};
var $reject = function(value){
  var promise = this;
  if(promise._d)return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  promise._v = value;
  promise._s = 2;
  if(!promise._a)promise._a = promise._c.slice();
  notify(promise, true);
};
var $resolve = function(value){
  var promise = this
    , then;
  if(promise._d)return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  try {
    if(promise === value)throw TypeError("Promise can't be resolved itself");
    if(then = isThenable(value)){
      microtask(function(){
        var wrapper = {_w: promise, _d: false}; // wrap
        try {
          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
        } catch(e){
          $reject.call(wrapper, e);
        }
      });
    } else {
      promise._v = value;
      promise._s = 1;
      notify(promise, false);
    }
  } catch(e){
    $reject.call({_w: promise, _d: false}, e); // wrap
  }
};

// constructor polyfill
if(!USE_NATIVE){
  // 25.4.3.1 Promise(executor)
  $Promise = function Promise(executor){
    anInstance(this, $Promise, PROMISE, '_h');
    aFunction(executor);
    Internal.call(this);
    try {
      executor(ctx($resolve, this, 1), ctx($reject, this, 1));
    } catch(err){
      $reject.call(this, err);
    }
  };
  Internal = function Promise(executor){
    this._c = [];             // <- awaiting reactions
    this._a = undefined;      // <- checked in isUnhandled reactions
    this._s = 0;              // <- state
    this._d = false;          // <- done
    this._v = undefined;      // <- value
    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
    this._n = false;          // <- notify
  };
  Internal.prototype = require('./_redefine-all')($Promise.prototype, {
    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
    then: function then(onFulfilled, onRejected){
      var reaction    = newPromiseCapability(speciesConstructor(this, $Promise));
      reaction.ok     = typeof onFulfilled == 'function' ? onFulfilled : true;
      reaction.fail   = typeof onRejected == 'function' && onRejected;
      reaction.domain = isNode ? process.domain : undefined;
      this._c.push(reaction);
      if(this._a)this._a.push(reaction);
      if(this._s)notify(this, false);
      return reaction.promise;
    },
    // 25.4.5.1 Promise.prototype.catch(onRejected)
    'catch': function(onRejected){
      return this.then(undefined, onRejected);
    }
  });
  PromiseCapability = function(){
    var promise  = new Internal;
    this.promise = promise;
    this.resolve = ctx($resolve, promise, 1);
    this.reject  = ctx($reject, promise, 1);
  };
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});
require('./_set-to-string-tag')($Promise, PROMISE);
require('./_set-species')(PROMISE);
Wrapper = require('./_core')[PROMISE];

// statics
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
  // 25.4.4.5 Promise.reject(r)
  reject: function reject(r){
    var capability = newPromiseCapability(this)
      , $$reject   = capability.reject;
    $$reject(r);
    return capability.promise;
  }
});
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
  // 25.4.4.6 Promise.resolve(x)
  resolve: function resolve(x){
    // instanceof instead of internal slot check because we should fix it without replacement native Promise core
    if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;
    var capability = newPromiseCapability(this)
      , $$resolve  = capability.resolve;
    $$resolve(x);
    return capability.promise;
  }
});
$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function(iter){
  $Promise.all(iter)['catch'](empty);
})), PROMISE, {
  // 25.4.4.1 Promise.all(iterable)
  all: function all(iterable){
    var C          = this
      , capability = newPromiseCapability(C)
      , resolve    = capability.resolve
      , reject     = capability.reject;
    var abrupt = perform(function(){
      var values    = []
        , index     = 0
        , remaining = 1;
      forOf(iterable, false, function(promise){
        var $index        = index++
          , alreadyCalled = false;
        values.push(undefined);
        remaining++;
        C.resolve(promise).then(function(value){
          if(alreadyCalled)return;
          alreadyCalled  = true;
          values[$index] = value;
          --remaining || resolve(values);
        }, reject);
      });
      --remaining || resolve(values);
    });
    if(abrupt)reject(abrupt.error);
    return capability.promise;
  },
  // 25.4.4.4 Promise.race(iterable)
  race: function race(iterable){
    var C          = this
      , capability = newPromiseCapability(C)
      , reject     = capability.reject;
    var abrupt = perform(function(){
      forOf(iterable, false, function(promise){
        C.resolve(promise).then(capability.resolve, reject);
      });
    });
    if(abrupt)reject(abrupt.error);
    return capability.promise;
  }
});
},{"./_a-function":5,"./_an-instance":8,"./_classof":19,"./_core":25,"./_ctx":27,"./_export":34,"./_for-of":39,"./_global":40,"./_is-object":51,"./_iter-detect":56,"./_library":60,"./_microtask":66,"./_redefine-all":88,"./_set-species":93,"./_set-to-string-tag":94,"./_species-constructor":97,"./_task":106,"./_wks":119}],201:[function(require,module,exports){
// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
var $export   = require('./_export')
  , aFunction = require('./_a-function')
  , anObject  = require('./_an-object')
  , rApply    = (require('./_global').Reflect || {}).apply
  , fApply    = Function.apply;
// MS Edge argumentsList argument is optional
$export($export.S + $export.F * !require('./_fails')(function(){
  rApply(function(){});
}), 'Reflect', {
  apply: function apply(target, thisArgument, argumentsList){
    var T = aFunction(target)
      , L = anObject(argumentsList);
    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);
  }
});
},{"./_a-function":5,"./_an-object":9,"./_export":34,"./_fails":36,"./_global":40}],202:[function(require,module,exports){
// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
var $export    = require('./_export')
  , create     = require('./_object-create')
  , aFunction  = require('./_a-function')
  , anObject   = require('./_an-object')
  , isObject   = require('./_is-object')
  , fails      = require('./_fails')
  , bind       = require('./_bind')
  , rConstruct = (require('./_global').Reflect || {}).construct;

// MS Edge supports only 2 arguments and argumentsList argument is optional
// FF Nightly sets third argument as `new.target`, but does not create `this` from it
var NEW_TARGET_BUG = fails(function(){
  function F(){}
  return !(rConstruct(function(){}, [], F) instanceof F);
});
var ARGS_BUG = !fails(function(){
  rConstruct(function(){});
});

$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {
  construct: function construct(Target, args /*, newTarget*/){
    aFunction(Target);
    anObject(args);
    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
    if(ARGS_BUG && !NEW_TARGET_BUG)return rConstruct(Target, args, newTarget);
    if(Target == newTarget){
      // w/o altered newTarget, optimization for 0-4 arguments
      switch(args.length){
        case 0: return new Target;
        case 1: return new Target(args[0]);
        case 2: return new Target(args[0], args[1]);
        case 3: return new Target(args[0], args[1], args[2]);
        case 4: return new Target(args[0], args[1], args[2], args[3]);
      }
      // w/o altered newTarget, lot of arguments case
      var $args = [null];
      $args.push.apply($args, args);
      return new (bind.apply(Target, $args));
    }
    // with altered newTarget, not support built-in constructors
    var proto    = newTarget.prototype
      , instance = create(isObject(proto) ? proto : Object.prototype)
      , result   = Function.apply.call(Target, instance, args);
    return isObject(result) ? result : instance;
  }
});
},{"./_a-function":5,"./_an-object":9,"./_bind":18,"./_export":34,"./_fails":36,"./_global":40,"./_is-object":51,"./_object-create":68}],203:[function(require,module,exports){
// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
var dP          = require('./_object-dp')
  , $export     = require('./_export')
  , anObject    = require('./_an-object')
  , toPrimitive = require('./_to-primitive');

// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
$export($export.S + $export.F * require('./_fails')(function(){
  Reflect.defineProperty(dP.f({}, 1, {value: 1}), 1, {value: 2});
}), 'Reflect', {
  defineProperty: function defineProperty(target, propertyKey, attributes){
    anObject(target);
    propertyKey = toPrimitive(propertyKey, true);
    anObject(attributes);
    try {
      dP.f(target, propertyKey, attributes);
      return true;
    } catch(e){
      return false;
    }
  }
});
},{"./_an-object":9,"./_export":34,"./_fails":36,"./_object-dp":69,"./_to-primitive":112}],204:[function(require,module,exports){
// 26.1.4 Reflect.deleteProperty(target, propertyKey)
var $export  = require('./_export')
  , gOPD     = require('./_object-gopd').f
  , anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  deleteProperty: function deleteProperty(target, propertyKey){
    var desc = gOPD(anObject(target), propertyKey);
    return desc && !desc.configurable ? false : delete target[propertyKey];
  }
});
},{"./_an-object":9,"./_export":34,"./_object-gopd":72}],205:[function(require,module,exports){
'use strict';
// 26.1.5 Reflect.enumerate(target)
var $export  = require('./_export')
  , anObject = require('./_an-object');
var Enumerate = function(iterated){
  this._t = anObject(iterated); // target
  this._i = 0;                  // next index
  var keys = this._k = []       // keys
    , key;
  for(key in iterated)keys.push(key);
};
require('./_iter-create')(Enumerate, 'Object', function(){
  var that = this
    , keys = that._k
    , key;
  do {
    if(that._i >= keys.length)return {value: undefined, done: true};
  } while(!((key = keys[that._i++]) in that._t));
  return {value: key, done: false};
});

$export($export.S, 'Reflect', {
  enumerate: function enumerate(target){
    return new Enumerate(target);
  }
});
},{"./_an-object":9,"./_export":34,"./_iter-create":54}],206:[function(require,module,exports){
// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
var gOPD     = require('./_object-gopd')
  , $export  = require('./_export')
  , anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){
    return gOPD.f(anObject(target), propertyKey);
  }
});
},{"./_an-object":9,"./_export":34,"./_object-gopd":72}],207:[function(require,module,exports){
// 26.1.8 Reflect.getPrototypeOf(target)
var $export  = require('./_export')
  , getProto = require('./_object-gpo')
  , anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  getPrototypeOf: function getPrototypeOf(target){
    return getProto(anObject(target));
  }
});
},{"./_an-object":9,"./_export":34,"./_object-gpo":76}],208:[function(require,module,exports){
// 26.1.6 Reflect.get(target, propertyKey [, receiver])
var gOPD           = require('./_object-gopd')
  , getPrototypeOf = require('./_object-gpo')
  , has            = require('./_has')
  , $export        = require('./_export')
  , isObject       = require('./_is-object')
  , anObject       = require('./_an-object');

function get(target, propertyKey/*, receiver*/){
  var receiver = arguments.length < 3 ? target : arguments[2]
    , desc, proto;
  if(anObject(target) === receiver)return target[propertyKey];
  if(desc = gOPD.f(target, propertyKey))return has(desc, 'value')
    ? desc.value
    : desc.get !== undefined
      ? desc.get.call(receiver)
      : undefined;
  if(isObject(proto = getPrototypeOf(target)))return get(proto, propertyKey, receiver);
}

$export($export.S, 'Reflect', {get: get});
},{"./_an-object":9,"./_export":34,"./_has":41,"./_is-object":51,"./_object-gopd":72,"./_object-gpo":76}],209:[function(require,module,exports){
// 26.1.9 Reflect.has(target, propertyKey)
var $export = require('./_export');

$export($export.S, 'Reflect', {
  has: function has(target, propertyKey){
    return propertyKey in target;
  }
});
},{"./_export":34}],210:[function(require,module,exports){
// 26.1.10 Reflect.isExtensible(target)
var $export       = require('./_export')
  , anObject      = require('./_an-object')
  , $isExtensible = Object.isExtensible;

$export($export.S, 'Reflect', {
  isExtensible: function isExtensible(target){
    anObject(target);
    return $isExtensible ? $isExtensible(target) : true;
  }
});
},{"./_an-object":9,"./_export":34}],211:[function(require,module,exports){
// 26.1.11 Reflect.ownKeys(target)
var $export = require('./_export');

$export($export.S, 'Reflect', {ownKeys: require('./_own-keys')});
},{"./_export":34,"./_own-keys":82}],212:[function(require,module,exports){
// 26.1.12 Reflect.preventExtensions(target)
var $export            = require('./_export')
  , anObject           = require('./_an-object')
  , $preventExtensions = Object.preventExtensions;

$export($export.S, 'Reflect', {
  preventExtensions: function preventExtensions(target){
    anObject(target);
    try {
      if($preventExtensions)$preventExtensions(target);
      return true;
    } catch(e){
      return false;
    }
  }
});
},{"./_an-object":9,"./_export":34}],213:[function(require,module,exports){
// 26.1.14 Reflect.setPrototypeOf(target, proto)
var $export  = require('./_export')
  , setProto = require('./_set-proto');

if(setProto)$export($export.S, 'Reflect', {
  setPrototypeOf: function setPrototypeOf(target, proto){
    setProto.check(target, proto);
    try {
      setProto.set(target, proto);
      return true;
    } catch(e){
      return false;
    }
  }
});
},{"./_export":34,"./_set-proto":92}],214:[function(require,module,exports){
// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
var dP             = require('./_object-dp')
  , gOPD           = require('./_object-gopd')
  , getPrototypeOf = require('./_object-gpo')
  , has            = require('./_has')
  , $export        = require('./_export')
  , createDesc     = require('./_property-desc')
  , anObject       = require('./_an-object')
  , isObject       = require('./_is-object');

function set(target, propertyKey, V/*, receiver*/){
  var receiver = arguments.length < 4 ? target : arguments[3]
    , ownDesc  = gOPD.f(anObject(target), propertyKey)
    , existingDescriptor, proto;
  if(!ownDesc){
    if(isObject(proto = getPrototypeOf(target))){
      return set(proto, propertyKey, V, receiver);
    }
    ownDesc = createDesc(0);
  }
  if(has(ownDesc, 'value')){
    if(ownDesc.writable === false || !isObject(receiver))return false;
    existingDescriptor = gOPD.f(receiver, propertyKey) || createDesc(0);
    existingDescriptor.value = V;
    dP.f(receiver, propertyKey, existingDescriptor);
    return true;
  }
  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
}

$export($export.S, 'Reflect', {set: set});
},{"./_an-object":9,"./_export":34,"./_has":41,"./_is-object":51,"./_object-dp":69,"./_object-gopd":72,"./_object-gpo":76,"./_property-desc":87}],215:[function(require,module,exports){
var global            = require('./_global')
  , inheritIfRequired = require('./_inherit-if-required')
  , dP                = require('./_object-dp').f
  , gOPN              = require('./_object-gopn').f
  , isRegExp          = require('./_is-regexp')
  , $flags            = require('./_flags')
  , $RegExp           = global.RegExp
  , Base              = $RegExp
  , proto             = $RegExp.prototype
  , re1               = /a/g
  , re2               = /a/g
  // "new" creates a new object, old webkit buggy here
  , CORRECT_NEW       = new $RegExp(re1) !== re1;

if(require('./_descriptors') && (!CORRECT_NEW || require('./_fails')(function(){
  re2[require('./_wks')('match')] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
}))){
  $RegExp = function RegExp(p, f){
    var tiRE = this instanceof $RegExp
      , piRE = isRegExp(p)
      , fiU  = f === undefined;
    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p
      : inheritIfRequired(CORRECT_NEW
        ? new Base(piRE && !fiU ? p.source : p, f)
        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)
      , tiRE ? this : proto, $RegExp);
  };
  var proxy = function(key){
    key in $RegExp || dP($RegExp, key, {
      configurable: true,
      get: function(){ return Base[key]; },
      set: function(it){ Base[key] = it; }
    });
  };
  for(var keys = gOPN(Base), i = 0; keys.length > i; )proxy(keys[i++]);
  proto.constructor = $RegExp;
  $RegExp.prototype = proto;
  require('./_redefine')(global, 'RegExp', $RegExp);
}

require('./_set-species')('RegExp');
},{"./_descriptors":30,"./_fails":36,"./_flags":38,"./_global":40,"./_inherit-if-required":45,"./_is-regexp":52,"./_object-dp":69,"./_object-gopn":74,"./_redefine":89,"./_set-species":93,"./_wks":119}],216:[function(require,module,exports){
// 21.2.5.3 get RegExp.prototype.flags()
if(require('./_descriptors') && /./g.flags != 'g')require('./_object-dp').f(RegExp.prototype, 'flags', {
  configurable: true,
  get: require('./_flags')
});
},{"./_descriptors":30,"./_flags":38,"./_object-dp":69}],217:[function(require,module,exports){
// @@match logic
require('./_fix-re-wks')('match', 1, function(defined, MATCH, $match){
  // 21.1.3.11 String.prototype.match(regexp)
  return [function match(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[MATCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
  }, $match];
});
},{"./_fix-re-wks":37}],218:[function(require,module,exports){
// @@replace logic
require('./_fix-re-wks')('replace', 2, function(defined, REPLACE, $replace){
  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
  return [function replace(searchValue, replaceValue){
    'use strict';
    var O  = defined(this)
      , fn = searchValue == undefined ? undefined : searchValue[REPLACE];
    return fn !== undefined
      ? fn.call(searchValue, O, replaceValue)
      : $replace.call(String(O), searchValue, replaceValue);
  }, $replace];
});
},{"./_fix-re-wks":37}],219:[function(require,module,exports){
// @@search logic
require('./_fix-re-wks')('search', 1, function(defined, SEARCH, $search){
  // 21.1.3.15 String.prototype.search(regexp)
  return [function search(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[SEARCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
  }, $search];
});
},{"./_fix-re-wks":37}],220:[function(require,module,exports){
// @@split logic
require('./_fix-re-wks')('split', 2, function(defined, SPLIT, $split){
  'use strict';
  var isRegExp   = require('./_is-regexp')
    , _split     = $split
    , $push      = [].push
    , $SPLIT     = 'split'
    , LENGTH     = 'length'
    , LAST_INDEX = 'lastIndex';
  if(
    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||
    ''[$SPLIT](/.?/)[LENGTH]
  ){
    var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
    // based on es5-shim implementation, need to rework it
    $split = function(separator, limit){
      var string = String(this);
      if(separator === undefined && limit === 0)return [];
      // If `separator` is not a regex, use native split
      if(!isRegExp(separator))return _split.call(string, separator, limit);
      var output = [];
      var flags = (separator.ignoreCase ? 'i' : '') +
                  (separator.multiline ? 'm' : '') +
                  (separator.unicode ? 'u' : '') +
                  (separator.sticky ? 'y' : '');
      var lastLastIndex = 0;
      var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
      // Make `global` and avoid `lastIndex` issues by working with a copy
      var separatorCopy = new RegExp(separator.source, flags + 'g');
      var separator2, match, lastIndex, lastLength, i;
      // Doesn't need flags gy, but they don't hurt
      if(!NPCG)separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
      while(match = separatorCopy.exec(string)){
        // `separatorCopy.lastIndex` is not reliable cross-browser
        lastIndex = match.index + match[0][LENGTH];
        if(lastIndex > lastLastIndex){
          output.push(string.slice(lastLastIndex, match.index));
          // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
          if(!NPCG && match[LENGTH] > 1)match[0].replace(separator2, function(){
            for(i = 1; i < arguments[LENGTH] - 2; i++)if(arguments[i] === undefined)match[i] = undefined;
          });
          if(match[LENGTH] > 1 && match.index < string[LENGTH])$push.apply(output, match.slice(1));
          lastLength = match[0][LENGTH];
          lastLastIndex = lastIndex;
          if(output[LENGTH] >= splitLimit)break;
        }
        if(separatorCopy[LAST_INDEX] === match.index)separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
      }
      if(lastLastIndex === string[LENGTH]){
        if(lastLength || !separatorCopy.test(''))output.push('');
      } else output.push(string.slice(lastLastIndex));
      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
    };
  // Chakra, V8
  } else if('0'[$SPLIT](undefined, 0)[LENGTH]){
    $split = function(separator, limit){
      return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
    };
  }
  // 21.1.3.17 String.prototype.split(separator, limit)
  return [function split(separator, limit){
    var O  = defined(this)
      , fn = separator == undefined ? undefined : separator[SPLIT];
    return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
  }, $split];
});
},{"./_fix-re-wks":37,"./_is-regexp":52}],221:[function(require,module,exports){
'use strict';
require('./es6.regexp.flags');
var anObject    = require('./_an-object')
  , $flags      = require('./_flags')
  , DESCRIPTORS = require('./_descriptors')
  , TO_STRING   = 'toString'
  , $toString   = /./[TO_STRING];

var define = function(fn){
  require('./_redefine')(RegExp.prototype, TO_STRING, fn, true);
};

// 21.2.5.14 RegExp.prototype.toString()
if(require('./_fails')(function(){ return $toString.call({source: 'a', flags: 'b'}) != '/a/b'; })){
  define(function toString(){
    var R = anObject(this);
    return '/'.concat(R.source, '/',
      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);
  });
// FF44- RegExp#toString has a wrong name
} else if($toString.name != TO_STRING){
  define(function toString(){
    return $toString.call(this);
  });
}
},{"./_an-object":9,"./_descriptors":30,"./_fails":36,"./_flags":38,"./_redefine":89,"./es6.regexp.flags":216}],222:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');

// 23.2 Set Objects
module.exports = require('./_collection')('Set', function(get){
  return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.2.3.1 Set.prototype.add(value)
  add: function add(value){
    return strong.def(this, value = value === 0 ? 0 : value, value);
  }
}, strong);
},{"./_collection":24,"./_collection-strong":21}],223:[function(require,module,exports){
'use strict';
// B.2.3.2 String.prototype.anchor(name)
require('./_string-html')('anchor', function(createHTML){
  return function anchor(name){
    return createHTML(this, 'a', 'name', name);
  }
});
},{"./_string-html":101}],224:[function(require,module,exports){
'use strict';
// B.2.3.3 String.prototype.big()
require('./_string-html')('big', function(createHTML){
  return function big(){
    return createHTML(this, 'big', '', '');
  }
});
},{"./_string-html":101}],225:[function(require,module,exports){
'use strict';
// B.2.3.4 String.prototype.blink()
require('./_string-html')('blink', function(createHTML){
  return function blink(){
    return createHTML(this, 'blink', '', '');
  }
});
},{"./_string-html":101}],226:[function(require,module,exports){
'use strict';
// B.2.3.5 String.prototype.bold()
require('./_string-html')('bold', function(createHTML){
  return function bold(){
    return createHTML(this, 'b', '', '');
  }
});
},{"./_string-html":101}],227:[function(require,module,exports){
'use strict';
var $export = require('./_export')
  , $at     = require('./_string-at')(false);
$export($export.P, 'String', {
  // 21.1.3.3 String.prototype.codePointAt(pos)
  codePointAt: function codePointAt(pos){
    return $at(this, pos);
  }
});
},{"./_export":34,"./_string-at":99}],228:[function(require,module,exports){
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
'use strict';
var $export   = require('./_export')
  , toLength  = require('./_to-length')
  , context   = require('./_string-context')
  , ENDS_WITH = 'endsWith'
  , $endsWith = ''[ENDS_WITH];

$export($export.P + $export.F * require('./_fails-is-regexp')(ENDS_WITH), 'String', {
  endsWith: function endsWith(searchString /*, endPosition = @length */){
    var that = context(this, searchString, ENDS_WITH)
      , endPosition = arguments.length > 1 ? arguments[1] : undefined
      , len    = toLength(that.length)
      , end    = endPosition === undefined ? len : Math.min(toLength(endPosition), len)
      , search = String(searchString);
    return $endsWith
      ? $endsWith.call(that, search, end)
      : that.slice(end - search.length, end) === search;
  }
});
},{"./_export":34,"./_fails-is-regexp":35,"./_string-context":100,"./_to-length":110}],229:[function(require,module,exports){
'use strict';
// B.2.3.6 String.prototype.fixed()
require('./_string-html')('fixed', function(createHTML){
  return function fixed(){
    return createHTML(this, 'tt', '', '');
  }
});
},{"./_string-html":101}],230:[function(require,module,exports){
'use strict';
// B.2.3.7 String.prototype.fontcolor(color)
require('./_string-html')('fontcolor', function(createHTML){
  return function fontcolor(color){
    return createHTML(this, 'font', 'color', color);
  }
});
},{"./_string-html":101}],231:[function(require,module,exports){
'use strict';
// B.2.3.8 String.prototype.fontsize(size)
require('./_string-html')('fontsize', function(createHTML){
  return function fontsize(size){
    return createHTML(this, 'font', 'size', size);
  }
});
},{"./_string-html":101}],232:[function(require,module,exports){
var $export        = require('./_export')
  , toIndex        = require('./_to-index')
  , fromCharCode   = String.fromCharCode
  , $fromCodePoint = String.fromCodePoint;

// length should be 1, old FF problem
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
  // 21.1.2.2 String.fromCodePoint(...codePoints)
  fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars
    var res  = []
      , aLen = arguments.length
      , i    = 0
      , code;
    while(aLen > i){
      code = +arguments[i++];
      if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');
      res.push(code < 0x10000
        ? fromCharCode(code)
        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
      );
    } return res.join('');
  }
});
},{"./_export":34,"./_to-index":107}],233:[function(require,module,exports){
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
'use strict';
var $export  = require('./_export')
  , context  = require('./_string-context')
  , INCLUDES = 'includes';

$export($export.P + $export.F * require('./_fails-is-regexp')(INCLUDES), 'String', {
  includes: function includes(searchString /*, position = 0 */){
    return !!~context(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});
},{"./_export":34,"./_fails-is-regexp":35,"./_string-context":100}],234:[function(require,module,exports){
'use strict';
// B.2.3.9 String.prototype.italics()
require('./_string-html')('italics', function(createHTML){
  return function italics(){
    return createHTML(this, 'i', '', '');
  }
});
},{"./_string-html":101}],235:[function(require,module,exports){
'use strict';
var $at  = require('./_string-at')(true);

// 21.1.3.27 String.prototype[@@iterator]()
require('./_iter-define')(String, 'String', function(iterated){
  this._t = String(iterated); // target
  this._i = 0;                // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function(){
  var O     = this._t
    , index = this._i
    , point;
  if(index >= O.length)return {value: undefined, done: true};
  point = $at(O, index);
  this._i += point.length;
  return {value: point, done: false};
});
},{"./_iter-define":55,"./_string-at":99}],236:[function(require,module,exports){
'use strict';
// B.2.3.10 String.prototype.link(url)
require('./_string-html')('link', function(createHTML){
  return function link(url){
    return createHTML(this, 'a', 'href', url);
  }
});
},{"./_string-html":101}],237:[function(require,module,exports){
var $export   = require('./_export')
  , toIObject = require('./_to-iobject')
  , toLength  = require('./_to-length');

$export($export.S, 'String', {
  // 21.1.2.4 String.raw(callSite, ...substitutions)
  raw: function raw(callSite){
    var tpl  = toIObject(callSite.raw)
      , len  = toLength(tpl.length)
      , aLen = arguments.length
      , res  = []
      , i    = 0;
    while(len > i){
      res.push(String(tpl[i++]));
      if(i < aLen)res.push(String(arguments[i]));
    } return res.join('');
  }
});
},{"./_export":34,"./_to-iobject":109,"./_to-length":110}],238:[function(require,module,exports){
var $export = require('./_export');

$export($export.P, 'String', {
  // 21.1.3.13 String.prototype.repeat(count)
  repeat: require('./_string-repeat')
});
},{"./_export":34,"./_string-repeat":103}],239:[function(require,module,exports){
'use strict';
// B.2.3.11 String.prototype.small()
require('./_string-html')('small', function(createHTML){
  return function small(){
    return createHTML(this, 'small', '', '');
  }
});
},{"./_string-html":101}],240:[function(require,module,exports){
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
'use strict';
var $export     = require('./_export')
  , toLength    = require('./_to-length')
  , context     = require('./_string-context')
  , STARTS_WITH = 'startsWith'
  , $startsWith = ''[STARTS_WITH];

$export($export.P + $export.F * require('./_fails-is-regexp')(STARTS_WITH), 'String', {
  startsWith: function startsWith(searchString /*, position = 0 */){
    var that   = context(this, searchString, STARTS_WITH)
      , index  = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length))
      , search = String(searchString);
    return $startsWith
      ? $startsWith.call(that, search, index)
      : that.slice(index, index + search.length) === search;
  }
});
},{"./_export":34,"./_fails-is-regexp":35,"./_string-context":100,"./_to-length":110}],241:[function(require,module,exports){
'use strict';
// B.2.3.12 String.prototype.strike()
require('./_string-html')('strike', function(createHTML){
  return function strike(){
    return createHTML(this, 'strike', '', '');
  }
});
},{"./_string-html":101}],242:[function(require,module,exports){
'use strict';
// B.2.3.13 String.prototype.sub()
require('./_string-html')('sub', function(createHTML){
  return function sub(){
    return createHTML(this, 'sub', '', '');
  }
});
},{"./_string-html":101}],243:[function(require,module,exports){
'use strict';
// B.2.3.14 String.prototype.sup()
require('./_string-html')('sup', function(createHTML){
  return function sup(){
    return createHTML(this, 'sup', '', '');
  }
});
},{"./_string-html":101}],244:[function(require,module,exports){
'use strict';
// 21.1.3.25 String.prototype.trim()
require('./_string-trim')('trim', function($trim){
  return function trim(){
    return $trim(this, 3);
  };
});
},{"./_string-trim":104}],245:[function(require,module,exports){
'use strict';
// ECMAScript 6 symbols shim
var global         = require('./_global')
  , has            = require('./_has')
  , DESCRIPTORS    = require('./_descriptors')
  , $export        = require('./_export')
  , redefine       = require('./_redefine')
  , META           = require('./_meta').KEY
  , $fails         = require('./_fails')
  , shared         = require('./_shared')
  , setToStringTag = require('./_set-to-string-tag')
  , uid            = require('./_uid')
  , wks            = require('./_wks')
  , wksExt         = require('./_wks-ext')
  , wksDefine      = require('./_wks-define')
  , keyOf          = require('./_keyof')
  , enumKeys       = require('./_enum-keys')
  , isArray        = require('./_is-array')
  , anObject       = require('./_an-object')
  , toIObject      = require('./_to-iobject')
  , toPrimitive    = require('./_to-primitive')
  , createDesc     = require('./_property-desc')
  , _create        = require('./_object-create')
  , gOPNExt        = require('./_object-gopn-ext')
  , $GOPD          = require('./_object-gopd')
  , $DP            = require('./_object-dp')
  , $keys          = require('./_object-keys')
  , gOPD           = $GOPD.f
  , dP             = $DP.f
  , gOPN           = gOPNExt.f
  , $Symbol        = global.Symbol
  , $JSON          = global.JSON
  , _stringify     = $JSON && $JSON.stringify
  , PROTOTYPE      = 'prototype'
  , HIDDEN         = wks('_hidden')
  , TO_PRIMITIVE   = wks('toPrimitive')
  , isEnum         = {}.propertyIsEnumerable
  , SymbolRegistry = shared('symbol-registry')
  , AllSymbols     = shared('symbols')
  , OPSymbols      = shared('op-symbols')
  , ObjectProto    = Object[PROTOTYPE]
  , USE_NATIVE     = typeof $Symbol == 'function'
  , QObject        = global.QObject;
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDesc = DESCRIPTORS && $fails(function(){
  return _create(dP({}, 'a', {
    get: function(){ return dP(this, 'a', {value: 7}).a; }
  })).a != 7;
}) ? function(it, key, D){
  var protoDesc = gOPD(ObjectProto, key);
  if(protoDesc)delete ObjectProto[key];
  dP(it, key, D);
  if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);
} : dP;

var wrap = function(tag){
  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
  sym._k = tag;
  return sym;
};

var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){
  return typeof it == 'symbol';
} : function(it){
  return it instanceof $Symbol;
};

var $defineProperty = function defineProperty(it, key, D){
  if(it === ObjectProto)$defineProperty(OPSymbols, key, D);
  anObject(it);
  key = toPrimitive(key, true);
  anObject(D);
  if(has(AllSymbols, key)){
    if(!D.enumerable){
      if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));
      it[HIDDEN][key] = true;
    } else {
      if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
      D = _create(D, {enumerable: createDesc(0, false)});
    } return setSymbolDesc(it, key, D);
  } return dP(it, key, D);
};
var $defineProperties = function defineProperties(it, P){
  anObject(it);
  var keys = enumKeys(P = toIObject(P))
    , i    = 0
    , l = keys.length
    , key;
  while(l > i)$defineProperty(it, key = keys[i++], P[key]);
  return it;
};
var $create = function create(it, P){
  return P === undefined ? _create(it) : $defineProperties(_create(it), P);
};
var $propertyIsEnumerable = function propertyIsEnumerable(key){
  var E = isEnum.call(this, key = toPrimitive(key, true));
  if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;
  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
  it  = toIObject(it);
  key = toPrimitive(key, true);
  if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;
  var D = gOPD(it, key);
  if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
  return D;
};
var $getOwnPropertyNames = function getOwnPropertyNames(it){
  var names  = gOPN(toIObject(it))
    , result = []
    , i      = 0
    , key;
  while(names.length > i){
    if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);
  } return result;
};
var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
  var IS_OP  = it === ObjectProto
    , names  = gOPN(IS_OP ? OPSymbols : toIObject(it))
    , result = []
    , i      = 0
    , key;
  while(names.length > i){
    if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);
  } return result;
};

// 19.4.1.1 Symbol([description])
if(!USE_NATIVE){
  $Symbol = function Symbol(){
    if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');
    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
    var $set = function(value){
      if(this === ObjectProto)$set.call(OPSymbols, value);
      if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
      setSymbolDesc(this, tag, createDesc(1, value));
    };
    if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});
    return wrap(tag);
  };
  redefine($Symbol[PROTOTYPE], 'toString', function toString(){
    return this._k;
  });

  $GOPD.f = $getOwnPropertyDescriptor;
  $DP.f   = $defineProperty;
  require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;
  require('./_object-pie').f  = $propertyIsEnumerable;
  require('./_object-gops').f = $getOwnPropertySymbols;

  if(DESCRIPTORS && !require('./_library')){
    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
  }

  wksExt.f = function(name){
    return wrap(wks(name));
  }
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});

for(var symbols = (
  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);

for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);

$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
  // 19.4.2.1 Symbol.for(key)
  'for': function(key){
    return has(SymbolRegistry, key += '')
      ? SymbolRegistry[key]
      : SymbolRegistry[key] = $Symbol(key);
  },
  // 19.4.2.5 Symbol.keyFor(sym)
  keyFor: function keyFor(key){
    if(isSymbol(key))return keyOf(SymbolRegistry, key);
    throw TypeError(key + ' is not a symbol!');
  },
  useSetter: function(){ setter = true; },
  useSimple: function(){ setter = false; }
});

$export($export.S + $export.F * !USE_NATIVE, 'Object', {
  // 19.1.2.2 Object.create(O [, Properties])
  create: $create,
  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
  defineProperty: $defineProperty,
  // 19.1.2.3 Object.defineProperties(O, Properties)
  defineProperties: $defineProperties,
  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
  // 19.1.2.7 Object.getOwnPropertyNames(O)
  getOwnPropertyNames: $getOwnPropertyNames,
  // 19.1.2.8 Object.getOwnPropertySymbols(O)
  getOwnPropertySymbols: $getOwnPropertySymbols
});

// 24.3.2 JSON.stringify(value [, replacer [, space]])
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){
  var S = $Symbol();
  // MS Edge converts symbol values to JSON as {}
  // WebKit converts symbol values to JSON as null
  // V8 throws on boxed symbols
  return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
})), 'JSON', {
  stringify: function stringify(it){
    if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
    var args = [it]
      , i    = 1
      , replacer, $replacer;
    while(arguments.length > i)args.push(arguments[i++]);
    replacer = args[1];
    if(typeof replacer == 'function')$replacer = replacer;
    if($replacer || !isArray(replacer))replacer = function(key, value){
      if($replacer)value = $replacer.call(this, key, value);
      if(!isSymbol(value))return value;
    };
    args[1] = replacer;
    return _stringify.apply($JSON, args);
  }
});

// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// 19.4.3.5 Symbol.prototype[@@toStringTag]
setToStringTag($Symbol, 'Symbol');
// 20.2.1.9 Math[@@toStringTag]
setToStringTag(Math, 'Math', true);
// 24.3.3 JSON[@@toStringTag]
setToStringTag(global.JSON, 'JSON', true);
},{"./_an-object":9,"./_descriptors":30,"./_enum-keys":33,"./_export":34,"./_fails":36,"./_global":40,"./_has":41,"./_hide":42,"./_is-array":49,"./_keyof":59,"./_library":60,"./_meta":64,"./_object-create":68,"./_object-dp":69,"./_object-gopd":72,"./_object-gopn":74,"./_object-gopn-ext":73,"./_object-gops":75,"./_object-keys":78,"./_object-pie":79,"./_property-desc":87,"./_redefine":89,"./_set-to-string-tag":94,"./_shared":96,"./_to-iobject":109,"./_to-primitive":112,"./_uid":116,"./_wks":119,"./_wks-define":117,"./_wks-ext":118}],246:[function(require,module,exports){
'use strict';
var $export      = require('./_export')
  , $typed       = require('./_typed')
  , buffer       = require('./_typed-buffer')
  , anObject     = require('./_an-object')
  , toIndex      = require('./_to-index')
  , toLength     = require('./_to-length')
  , isObject     = require('./_is-object')
  , ArrayBuffer  = require('./_global').ArrayBuffer
  , speciesConstructor = require('./_species-constructor')
  , $ArrayBuffer = buffer.ArrayBuffer
  , $DataView    = buffer.DataView
  , $isView      = $typed.ABV && ArrayBuffer.isView
  , $slice       = $ArrayBuffer.prototype.slice
  , VIEW         = $typed.VIEW
  , ARRAY_BUFFER = 'ArrayBuffer';

$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), {ArrayBuffer: $ArrayBuffer});

$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {
  // 24.1.3.1 ArrayBuffer.isView(arg)
  isView: function isView(it){
    return $isView && $isView(it) || isObject(it) && VIEW in it;
  }
});

$export($export.P + $export.U + $export.F * require('./_fails')(function(){
  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;
}), ARRAY_BUFFER, {
  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)
  slice: function slice(start, end){
    if($slice !== undefined && end === undefined)return $slice.call(anObject(this), start); // FF fix
    var len    = anObject(this).byteLength
      , first  = toIndex(start, len)
      , final  = toIndex(end === undefined ? len : end, len)
      , result = new (speciesConstructor(this, $ArrayBuffer))(toLength(final - first))
      , viewS  = new $DataView(this)
      , viewT  = new $DataView(result)
      , index  = 0;
    while(first < final){
      viewT.setUint8(index++, viewS.getUint8(first++));
    } return result;
  }
});

require('./_set-species')(ARRAY_BUFFER);
},{"./_an-object":9,"./_export":34,"./_fails":36,"./_global":40,"./_is-object":51,"./_set-species":93,"./_species-constructor":97,"./_to-index":107,"./_to-length":110,"./_typed":115,"./_typed-buffer":114}],247:[function(require,module,exports){
var $export = require('./_export');
$export($export.G + $export.W + $export.F * !require('./_typed').ABV, {
  DataView: require('./_typed-buffer').DataView
});
},{"./_export":34,"./_typed":115,"./_typed-buffer":114}],248:[function(require,module,exports){
require('./_typed-array')('Float32', 4, function(init){
  return function Float32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],249:[function(require,module,exports){
require('./_typed-array')('Float64', 8, function(init){
  return function Float64Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],250:[function(require,module,exports){
require('./_typed-array')('Int16', 2, function(init){
  return function Int16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],251:[function(require,module,exports){
require('./_typed-array')('Int32', 4, function(init){
  return function Int32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],252:[function(require,module,exports){
require('./_typed-array')('Int8', 1, function(init){
  return function Int8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],253:[function(require,module,exports){
require('./_typed-array')('Uint16', 2, function(init){
  return function Uint16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],254:[function(require,module,exports){
require('./_typed-array')('Uint32', 4, function(init){
  return function Uint32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],255:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function(init){
  return function Uint8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});
},{"./_typed-array":113}],256:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function(init){
  return function Uint8ClampedArray(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
}, true);
},{"./_typed-array":113}],257:[function(require,module,exports){
'use strict';
var each         = require('./_array-methods')(0)
  , redefine     = require('./_redefine')
  , meta         = require('./_meta')
  , assign       = require('./_object-assign')
  , weak         = require('./_collection-weak')
  , isObject     = require('./_is-object')
  , getWeak      = meta.getWeak
  , isExtensible = Object.isExtensible
  , uncaughtFrozenStore = weak.ufstore
  , tmp          = {}
  , InternalMap;

var wrapper = function(get){
  return function WeakMap(){
    return get(this, arguments.length > 0 ? arguments[0] : undefined);
  };
};

var methods = {
  // 23.3.3.3 WeakMap.prototype.get(key)
  get: function get(key){
    if(isObject(key)){
      var data = getWeak(key);
      if(data === true)return uncaughtFrozenStore(this).get(key);
      return data ? data[this._i] : undefined;
    }
  },
  // 23.3.3.5 WeakMap.prototype.set(key, value)
  set: function set(key, value){
    return weak.def(this, key, value);
  }
};

// 23.3 WeakMap Objects
var $WeakMap = module.exports = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
  InternalMap = weak.getConstructor(wrapper);
  assign(InternalMap.prototype, methods);
  meta.NEED = true;
  each(['delete', 'has', 'get', 'set'], function(key){
    var proto  = $WeakMap.prototype
      , method = proto[key];
    redefine(proto, key, function(a, b){
      // store frozen objects on internal weakmap shim
      if(isObject(a) && !isExtensible(a)){
        if(!this._f)this._f = new InternalMap;
        var result = this._f[key](a, b);
        return key == 'set' ? this : result;
      // store all the rest on native weakmap
      } return method.call(this, a, b);
    });
  });
}
},{"./_array-methods":14,"./_collection":24,"./_collection-weak":23,"./_is-object":51,"./_meta":64,"./_object-assign":67,"./_redefine":89}],258:[function(require,module,exports){
'use strict';
var weak = require('./_collection-weak');

// 23.4 WeakSet Objects
require('./_collection')('WeakSet', function(get){
  return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.4.3.1 WeakSet.prototype.add(value)
  add: function add(value){
    return weak.def(this, value, true);
  }
}, weak, false, true);
},{"./_collection":24,"./_collection-weak":23}],259:[function(require,module,exports){
'use strict';
// https://github.com/tc39/Array.prototype.includes
var $export   = require('./_export')
  , $includes = require('./_array-includes')(true);

$export($export.P, 'Array', {
  includes: function includes(el /*, fromIndex = 0 */){
    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

require('./_add-to-unscopables')('includes');
},{"./_add-to-unscopables":7,"./_array-includes":13,"./_export":34}],260:[function(require,module,exports){
// https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask
var $export   = require('./_export')
  , microtask = require('./_microtask')()
  , process   = require('./_global').process
  , isNode    = require('./_cof')(process) == 'process';

$export($export.G, {
  asap: function asap(fn){
    var domain = isNode && process.domain;
    microtask(domain ? domain.bind(fn) : fn);
  }
});
},{"./_cof":20,"./_export":34,"./_global":40,"./_microtask":66}],261:[function(require,module,exports){
// https://github.com/ljharb/proposal-is-error
var $export = require('./_export')
  , cof     = require('./_cof');

$export($export.S, 'Error', {
  isError: function isError(it){
    return cof(it) === 'Error';
  }
});
},{"./_cof":20,"./_export":34}],262:[function(require,module,exports){
// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = require('./_export');

$export($export.P + $export.R, 'Map', {toJSON: require('./_collection-to-json')('Map')});
},{"./_collection-to-json":22,"./_export":34}],263:[function(require,module,exports){
// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = require('./_export');

$export($export.S, 'Math', {
  iaddh: function iaddh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0;
  }
});
},{"./_export":34}],264:[function(require,module,exports){
// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = require('./_export');

$export($export.S, 'Math', {
  imulh: function imulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >> 16
      , v1 = $v >> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16);
  }
});
},{"./_export":34}],265:[function(require,module,exports){
// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = require('./_export');

$export($export.S, 'Math', {
  isubh: function isubh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0;
  }
});
},{"./_export":34}],266:[function(require,module,exports){
// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = require('./_export');

$export($export.S, 'Math', {
  umulh: function umulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >>> 16
      , v1 = $v >>> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16);
  }
});
},{"./_export":34}],267:[function(require,module,exports){
'use strict';
var $export         = require('./_export')
  , toObject        = require('./_to-object')
  , aFunction       = require('./_a-function')
  , $defineProperty = require('./_object-dp');

// B.2.2.2 Object.prototype.__defineGetter__(P, getter)
require('./_descriptors') && $export($export.P + require('./_object-forced-pam'), 'Object', {
  __defineGetter__: function __defineGetter__(P, getter){
    $defineProperty.f(toObject(this), P, {get: aFunction(getter), enumerable: true, configurable: true});
  }
});
},{"./_a-function":5,"./_descriptors":30,"./_export":34,"./_object-dp":69,"./_object-forced-pam":71,"./_to-object":111}],268:[function(require,module,exports){
'use strict';
var $export         = require('./_export')
  , toObject        = require('./_to-object')
  , aFunction       = require('./_a-function')
  , $defineProperty = require('./_object-dp');

// B.2.2.3 Object.prototype.__defineSetter__(P, setter)
require('./_descriptors') && $export($export.P + require('./_object-forced-pam'), 'Object', {
  __defineSetter__: function __defineSetter__(P, setter){
    $defineProperty.f(toObject(this), P, {set: aFunction(setter), enumerable: true, configurable: true});
  }
});
},{"./_a-function":5,"./_descriptors":30,"./_export":34,"./_object-dp":69,"./_object-forced-pam":71,"./_to-object":111}],269:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export  = require('./_export')
  , $entries = require('./_object-to-array')(true);

$export($export.S, 'Object', {
  entries: function entries(it){
    return $entries(it);
  }
});
},{"./_export":34,"./_object-to-array":81}],270:[function(require,module,exports){
// https://github.com/tc39/proposal-object-getownpropertydescriptors
var $export        = require('./_export')
  , ownKeys        = require('./_own-keys')
  , toIObject      = require('./_to-iobject')
  , gOPD           = require('./_object-gopd')
  , createProperty = require('./_create-property');

$export($export.S, 'Object', {
  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){
    var O       = toIObject(object)
      , getDesc = gOPD.f
      , keys    = ownKeys(O)
      , result  = {}
      , i       = 0
      , key;
    while(keys.length > i)createProperty(result, key = keys[i++], getDesc(O, key));
    return result;
  }
});
},{"./_create-property":26,"./_export":34,"./_object-gopd":72,"./_own-keys":82,"./_to-iobject":109}],271:[function(require,module,exports){
'use strict';
var $export                  = require('./_export')
  , toObject                 = require('./_to-object')
  , toPrimitive              = require('./_to-primitive')
  , getPrototypeOf           = require('./_object-gpo')
  , getOwnPropertyDescriptor = require('./_object-gopd').f;

// B.2.2.4 Object.prototype.__lookupGetter__(P)
require('./_descriptors') && $export($export.P + require('./_object-forced-pam'), 'Object', {
  __lookupGetter__: function __lookupGetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.get;
    } while(O = getPrototypeOf(O));
  }
});
},{"./_descriptors":30,"./_export":34,"./_object-forced-pam":71,"./_object-gopd":72,"./_object-gpo":76,"./_to-object":111,"./_to-primitive":112}],272:[function(require,module,exports){
'use strict';
var $export                  = require('./_export')
  , toObject                 = require('./_to-object')
  , toPrimitive              = require('./_to-primitive')
  , getPrototypeOf           = require('./_object-gpo')
  , getOwnPropertyDescriptor = require('./_object-gopd').f;

// B.2.2.5 Object.prototype.__lookupSetter__(P)
require('./_descriptors') && $export($export.P + require('./_object-forced-pam'), 'Object', {
  __lookupSetter__: function __lookupSetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.set;
    } while(O = getPrototypeOf(O));
  }
});
},{"./_descriptors":30,"./_export":34,"./_object-forced-pam":71,"./_object-gopd":72,"./_object-gpo":76,"./_to-object":111,"./_to-primitive":112}],273:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export = require('./_export')
  , $values = require('./_object-to-array')(false);

$export($export.S, 'Object', {
  values: function values(it){
    return $values(it);
  }
});
},{"./_export":34,"./_object-to-array":81}],274:[function(require,module,exports){
'use strict';
// https://github.com/zenparsing/es-observable
var $export     = require('./_export')
  , global      = require('./_global')
  , core        = require('./_core')
  , microtask   = require('./_microtask')()
  , OBSERVABLE  = require('./_wks')('observable')
  , aFunction   = require('./_a-function')
  , anObject    = require('./_an-object')
  , anInstance  = require('./_an-instance')
  , redefineAll = require('./_redefine-all')
  , hide        = require('./_hide')
  , forOf       = require('./_for-of')
  , RETURN      = forOf.RETURN;

var getMethod = function(fn){
  return fn == null ? undefined : aFunction(fn);
};

var cleanupSubscription = function(subscription){
  var cleanup = subscription._c;
  if(cleanup){
    subscription._c = undefined;
    cleanup();
  }
};

var subscriptionClosed = function(subscription){
  return subscription._o === undefined;
};

var closeSubscription = function(subscription){
  if(!subscriptionClosed(subscription)){
    subscription._o = undefined;
    cleanupSubscription(subscription);
  }
};

var Subscription = function(observer, subscriber){
  anObject(observer);
  this._c = undefined;
  this._o = observer;
  observer = new SubscriptionObserver(this);
  try {
    var cleanup      = subscriber(observer)
      , subscription = cleanup;
    if(cleanup != null){
      if(typeof cleanup.unsubscribe === 'function')cleanup = function(){ subscription.unsubscribe(); };
      else aFunction(cleanup);
      this._c = cleanup;
    }
  } catch(e){
    observer.error(e);
    return;
  } if(subscriptionClosed(this))cleanupSubscription(this);
};

Subscription.prototype = redefineAll({}, {
  unsubscribe: function unsubscribe(){ closeSubscription(this); }
});

var SubscriptionObserver = function(subscription){
  this._s = subscription;
};

SubscriptionObserver.prototype = redefineAll({}, {
  next: function next(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      try {
        var m = getMethod(observer.next);
        if(m)return m.call(observer, value);
      } catch(e){
        try {
          closeSubscription(subscription);
        } finally {
          throw e;
        }
      }
    }
  },
  error: function error(value){
    var subscription = this._s;
    if(subscriptionClosed(subscription))throw value;
    var observer = subscription._o;
    subscription._o = undefined;
    try {
      var m = getMethod(observer.error);
      if(!m)throw value;
      value = m.call(observer, value);
    } catch(e){
      try {
        cleanupSubscription(subscription);
      } finally {
        throw e;
      }
    } cleanupSubscription(subscription);
    return value;
  },
  complete: function complete(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      subscription._o = undefined;
      try {
        var m = getMethod(observer.complete);
        value = m ? m.call(observer, value) : undefined;
      } catch(e){
        try {
          cleanupSubscription(subscription);
        } finally {
          throw e;
        }
      } cleanupSubscription(subscription);
      return value;
    }
  }
});

var $Observable = function Observable(subscriber){
  anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);
};

redefineAll($Observable.prototype, {
  subscribe: function subscribe(observer){
    return new Subscription(observer, this._f);
  },
  forEach: function forEach(fn){
    var that = this;
    return new (core.Promise || global.Promise)(function(resolve, reject){
      aFunction(fn);
      var subscription = that.subscribe({
        next : function(value){
          try {
            return fn(value);
          } catch(e){
            reject(e);
            subscription.unsubscribe();
          }
        },
        error: reject,
        complete: resolve
      });
    });
  }
});

redefineAll($Observable, {
  from: function from(x){
    var C = typeof this === 'function' ? this : $Observable;
    var method = getMethod(anObject(x)[OBSERVABLE]);
    if(method){
      var observable = anObject(method.call(x));
      return observable.constructor === C ? observable : new C(function(observer){
        return observable.subscribe(observer);
      });
    }
    return new C(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          try {
            if(forOf(x, false, function(it){
              observer.next(it);
              if(done)return RETURN;
            }) === RETURN)return;
          } catch(e){
            if(done)throw e;
            observer.error(e);
            return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  },
  of: function of(){
    for(var i = 0, l = arguments.length, items = Array(l); i < l;)items[i] = arguments[i++];
    return new (typeof this === 'function' ? this : $Observable)(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          for(var i = 0; i < items.length; ++i){
            observer.next(items[i]);
            if(done)return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  }
});

hide($Observable.prototype, OBSERVABLE, function(){ return this; });

$export($export.G, {Observable: $Observable});

require('./_set-species')('Observable');
},{"./_a-function":5,"./_an-instance":8,"./_an-object":9,"./_core":25,"./_export":34,"./_for-of":39,"./_global":40,"./_hide":42,"./_microtask":66,"./_redefine-all":88,"./_set-species":93,"./_wks":119}],275:[function(require,module,exports){
var metadata                  = require('./_metadata')
  , anObject                  = require('./_an-object')
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey){
  ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));
}});
},{"./_an-object":9,"./_metadata":65}],276:[function(require,module,exports){
var metadata               = require('./_metadata')
  , anObject               = require('./_an-object')
  , toMetaKey              = metadata.key
  , getOrCreateMetadataMap = metadata.map
  , store                  = metadata.store;

metadata.exp({deleteMetadata: function deleteMetadata(metadataKey, target /*, targetKey */){
  var targetKey   = arguments.length < 3 ? undefined : toMetaKey(arguments[2])
    , metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);
  if(metadataMap === undefined || !metadataMap['delete'](metadataKey))return false;
  if(metadataMap.size)return true;
  var targetMetadata = store.get(target);
  targetMetadata['delete'](targetKey);
  return !!targetMetadata.size || store['delete'](target);
}});
},{"./_an-object":9,"./_metadata":65}],277:[function(require,module,exports){
var Set                     = require('./es6.set')
  , from                    = require('./_array-from-iterable')
  , metadata                = require('./_metadata')
  , anObject                = require('./_an-object')
  , getPrototypeOf          = require('./_object-gpo')
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

var ordinaryMetadataKeys = function(O, P){
  var oKeys  = ordinaryOwnMetadataKeys(O, P)
    , parent = getPrototypeOf(O);
  if(parent === null)return oKeys;
  var pKeys  = ordinaryMetadataKeys(parent, P);
  return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;
};

metadata.exp({getMetadataKeys: function getMetadataKeys(target /*, targetKey */){
  return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});
},{"./_an-object":9,"./_array-from-iterable":12,"./_metadata":65,"./_object-gpo":76,"./es6.set":222}],278:[function(require,module,exports){
var metadata               = require('./_metadata')
  , anObject               = require('./_an-object')
  , getPrototypeOf         = require('./_object-gpo')
  , ordinaryHasOwnMetadata = metadata.has
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

var ordinaryGetMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return ordinaryGetOwnMetadata(MetadataKey, O, P);
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;
};

metadata.exp({getMetadata: function getMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});
},{"./_an-object":9,"./_metadata":65,"./_object-gpo":76}],279:[function(require,module,exports){
var metadata                = require('./_metadata')
  , anObject                = require('./_an-object')
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

metadata.exp({getOwnMetadataKeys: function getOwnMetadataKeys(target /*, targetKey */){
  return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});
},{"./_an-object":9,"./_metadata":65}],280:[function(require,module,exports){
var metadata               = require('./_metadata')
  , anObject               = require('./_an-object')
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

metadata.exp({getOwnMetadata: function getOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});
},{"./_an-object":9,"./_metadata":65}],281:[function(require,module,exports){
var metadata               = require('./_metadata')
  , anObject               = require('./_an-object')
  , getPrototypeOf         = require('./_object-gpo')
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

var ordinaryHasMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return true;
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;
};

metadata.exp({hasMetadata: function hasMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});
},{"./_an-object":9,"./_metadata":65,"./_object-gpo":76}],282:[function(require,module,exports){
var metadata               = require('./_metadata')
  , anObject               = require('./_an-object')
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

metadata.exp({hasOwnMetadata: function hasOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});
},{"./_an-object":9,"./_metadata":65}],283:[function(require,module,exports){
var metadata                  = require('./_metadata')
  , anObject                  = require('./_an-object')
  , aFunction                 = require('./_a-function')
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({metadata: function metadata(metadataKey, metadataValue){
  return function decorator(target, targetKey){
    ordinaryDefineOwnMetadata(
      metadataKey, metadataValue,
      (targetKey !== undefined ? anObject : aFunction)(target),
      toMetaKey(targetKey)
    );
  };
}});
},{"./_a-function":5,"./_an-object":9,"./_metadata":65}],284:[function(require,module,exports){
// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = require('./_export');

$export($export.P + $export.R, 'Set', {toJSON: require('./_collection-to-json')('Set')});
},{"./_collection-to-json":22,"./_export":34}],285:[function(require,module,exports){
'use strict';
// https://github.com/mathiasbynens/String.prototype.at
var $export = require('./_export')
  , $at     = require('./_string-at')(true);

$export($export.P, 'String', {
  at: function at(pos){
    return $at(this, pos);
  }
});
},{"./_export":34,"./_string-at":99}],286:[function(require,module,exports){
'use strict';
// https://tc39.github.io/String.prototype.matchAll/
var $export     = require('./_export')
  , defined     = require('./_defined')
  , toLength    = require('./_to-length')
  , isRegExp    = require('./_is-regexp')
  , getFlags    = require('./_flags')
  , RegExpProto = RegExp.prototype;

var $RegExpStringIterator = function(regexp, string){
  this._r = regexp;
  this._s = string;
};

require('./_iter-create')($RegExpStringIterator, 'RegExp String', function next(){
  var match = this._r.exec(this._s);
  return {value: match, done: match === null};
});

$export($export.P, 'String', {
  matchAll: function matchAll(regexp){
    defined(this);
    if(!isRegExp(regexp))throw TypeError(regexp + ' is not a regexp!');
    var S     = String(this)
      , flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp)
      , rx    = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags);
    rx.lastIndex = toLength(regexp.lastIndex);
    return new $RegExpStringIterator(rx, S);
  }
});
},{"./_defined":29,"./_export":34,"./_flags":38,"./_is-regexp":52,"./_iter-create":54,"./_to-length":110}],287:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export')
  , $pad    = require('./_string-pad');

$export($export.P, 'String', {
  padEnd: function padEnd(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
  }
});
},{"./_export":34,"./_string-pad":102}],288:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export')
  , $pad    = require('./_string-pad');

$export($export.P, 'String', {
  padStart: function padStart(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
  }
});
},{"./_export":34,"./_string-pad":102}],289:[function(require,module,exports){
'use strict';
// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
require('./_string-trim')('trimLeft', function($trim){
  return function trimLeft(){
    return $trim(this, 1);
  };
}, 'trimStart');
},{"./_string-trim":104}],290:[function(require,module,exports){
'use strict';
// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
require('./_string-trim')('trimRight', function($trim){
  return function trimRight(){
    return $trim(this, 2);
  };
}, 'trimEnd');
},{"./_string-trim":104}],291:[function(require,module,exports){
require('./_wks-define')('asyncIterator');
},{"./_wks-define":117}],292:[function(require,module,exports){
require('./_wks-define')('observable');
},{"./_wks-define":117}],293:[function(require,module,exports){
// https://github.com/ljharb/proposal-global
var $export = require('./_export');

$export($export.S, 'System', {global: require('./_global')});
},{"./_export":34,"./_global":40}],294:[function(require,module,exports){
var $iterators    = require('./es6.array.iterator')
  , redefine      = require('./_redefine')
  , global        = require('./_global')
  , hide          = require('./_hide')
  , Iterators     = require('./_iterators')
  , wks           = require('./_wks')
  , ITERATOR      = wks('iterator')
  , TO_STRING_TAG = wks('toStringTag')
  , ArrayValues   = Iterators.Array;

for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
  var NAME       = collections[i]
    , Collection = global[NAME]
    , proto      = Collection && Collection.prototype
    , key;
  if(proto){
    if(!proto[ITERATOR])hide(proto, ITERATOR, ArrayValues);
    if(!proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);
    Iterators[NAME] = ArrayValues;
    for(key in $iterators)if(!proto[key])redefine(proto, key, $iterators[key], true);
  }
}
},{"./_global":40,"./_hide":42,"./_iterators":58,"./_redefine":89,"./_wks":119,"./es6.array.iterator":132}],295:[function(require,module,exports){
var $export = require('./_export')
  , $task   = require('./_task');
$export($export.G + $export.B, {
  setImmediate:   $task.set,
  clearImmediate: $task.clear
});
},{"./_export":34,"./_task":106}],296:[function(require,module,exports){
// ie9- setTimeout & setInterval additional parameters fix
var global     = require('./_global')
  , $export    = require('./_export')
  , invoke     = require('./_invoke')
  , partial    = require('./_partial')
  , navigator  = global.navigator
  , MSIE       = !!navigator && /MSIE .\./.test(navigator.userAgent); // <- dirty ie9- check
var wrap = function(set){
  return MSIE ? function(fn, time /*, ...args */){
    return set(invoke(
      partial,
      [].slice.call(arguments, 2),
      typeof fn == 'function' ? fn : Function(fn)
    ), time);
  } : set;
};
$export($export.G + $export.B + $export.F * MSIE, {
  setTimeout:  wrap(global.setTimeout),
  setInterval: wrap(global.setInterval)
});
},{"./_export":34,"./_global":40,"./_invoke":46,"./_partial":85}],297:[function(require,module,exports){
require('./modules/es6.symbol');
require('./modules/es6.object.create');
require('./modules/es6.object.define-property');
require('./modules/es6.object.define-properties');
require('./modules/es6.object.get-own-property-descriptor');
require('./modules/es6.object.get-prototype-of');
require('./modules/es6.object.keys');
require('./modules/es6.object.get-own-property-names');
require('./modules/es6.object.freeze');
require('./modules/es6.object.seal');
require('./modules/es6.object.prevent-extensions');
require('./modules/es6.object.is-frozen');
require('./modules/es6.object.is-sealed');
require('./modules/es6.object.is-extensible');
require('./modules/es6.object.assign');
require('./modules/es6.object.is');
require('./modules/es6.object.set-prototype-of');
require('./modules/es6.object.to-string');
require('./modules/es6.function.bind');
require('./modules/es6.function.name');
require('./modules/es6.function.has-instance');
require('./modules/es6.parse-int');
require('./modules/es6.parse-float');
require('./modules/es6.number.constructor');
require('./modules/es6.number.to-fixed');
require('./modules/es6.number.to-precision');
require('./modules/es6.number.epsilon');
require('./modules/es6.number.is-finite');
require('./modules/es6.number.is-integer');
require('./modules/es6.number.is-nan');
require('./modules/es6.number.is-safe-integer');
require('./modules/es6.number.max-safe-integer');
require('./modules/es6.number.min-safe-integer');
require('./modules/es6.number.parse-float');
require('./modules/es6.number.parse-int');
require('./modules/es6.math.acosh');
require('./modules/es6.math.asinh');
require('./modules/es6.math.atanh');
require('./modules/es6.math.cbrt');
require('./modules/es6.math.clz32');
require('./modules/es6.math.cosh');
require('./modules/es6.math.expm1');
require('./modules/es6.math.fround');
require('./modules/es6.math.hypot');
require('./modules/es6.math.imul');
require('./modules/es6.math.log10');
require('./modules/es6.math.log1p');
require('./modules/es6.math.log2');
require('./modules/es6.math.sign');
require('./modules/es6.math.sinh');
require('./modules/es6.math.tanh');
require('./modules/es6.math.trunc');
require('./modules/es6.string.from-code-point');
require('./modules/es6.string.raw');
require('./modules/es6.string.trim');
require('./modules/es6.string.iterator');
require('./modules/es6.string.code-point-at');
require('./modules/es6.string.ends-with');
require('./modules/es6.string.includes');
require('./modules/es6.string.repeat');
require('./modules/es6.string.starts-with');
require('./modules/es6.string.anchor');
require('./modules/es6.string.big');
require('./modules/es6.string.blink');
require('./modules/es6.string.bold');
require('./modules/es6.string.fixed');
require('./modules/es6.string.fontcolor');
require('./modules/es6.string.fontsize');
require('./modules/es6.string.italics');
require('./modules/es6.string.link');
require('./modules/es6.string.small');
require('./modules/es6.string.strike');
require('./modules/es6.string.sub');
require('./modules/es6.string.sup');
require('./modules/es6.date.now');
require('./modules/es6.date.to-json');
require('./modules/es6.date.to-iso-string');
require('./modules/es6.date.to-string');
require('./modules/es6.date.to-primitive');
require('./modules/es6.array.is-array');
require('./modules/es6.array.from');
require('./modules/es6.array.of');
require('./modules/es6.array.join');
require('./modules/es6.array.slice');
require('./modules/es6.array.sort');
require('./modules/es6.array.for-each');
require('./modules/es6.array.map');
require('./modules/es6.array.filter');
require('./modules/es6.array.some');
require('./modules/es6.array.every');
require('./modules/es6.array.reduce');
require('./modules/es6.array.reduce-right');
require('./modules/es6.array.index-of');
require('./modules/es6.array.last-index-of');
require('./modules/es6.array.copy-within');
require('./modules/es6.array.fill');
require('./modules/es6.array.find');
require('./modules/es6.array.find-index');
require('./modules/es6.array.species');
require('./modules/es6.array.iterator');
require('./modules/es6.regexp.constructor');
require('./modules/es6.regexp.to-string');
require('./modules/es6.regexp.flags');
require('./modules/es6.regexp.match');
require('./modules/es6.regexp.replace');
require('./modules/es6.regexp.search');
require('./modules/es6.regexp.split');
require('./modules/es6.promise');
require('./modules/es6.map');
require('./modules/es6.set');
require('./modules/es6.weak-map');
require('./modules/es6.weak-set');
require('./modules/es6.typed.array-buffer');
require('./modules/es6.typed.data-view');
require('./modules/es6.typed.int8-array');
require('./modules/es6.typed.uint8-array');
require('./modules/es6.typed.uint8-clamped-array');
require('./modules/es6.typed.int16-array');
require('./modules/es6.typed.uint16-array');
require('./modules/es6.typed.int32-array');
require('./modules/es6.typed.uint32-array');
require('./modules/es6.typed.float32-array');
require('./modules/es6.typed.float64-array');
require('./modules/es6.reflect.apply');
require('./modules/es6.reflect.construct');
require('./modules/es6.reflect.define-property');
require('./modules/es6.reflect.delete-property');
require('./modules/es6.reflect.enumerate');
require('./modules/es6.reflect.get');
require('./modules/es6.reflect.get-own-property-descriptor');
require('./modules/es6.reflect.get-prototype-of');
require('./modules/es6.reflect.has');
require('./modules/es6.reflect.is-extensible');
require('./modules/es6.reflect.own-keys');
require('./modules/es6.reflect.prevent-extensions');
require('./modules/es6.reflect.set');
require('./modules/es6.reflect.set-prototype-of');
require('./modules/es7.array.includes');
require('./modules/es7.string.at');
require('./modules/es7.string.pad-start');
require('./modules/es7.string.pad-end');
require('./modules/es7.string.trim-left');
require('./modules/es7.string.trim-right');
require('./modules/es7.string.match-all');
require('./modules/es7.symbol.async-iterator');
require('./modules/es7.symbol.observable');
require('./modules/es7.object.get-own-property-descriptors');
require('./modules/es7.object.values');
require('./modules/es7.object.entries');
require('./modules/es7.object.define-getter');
require('./modules/es7.object.define-setter');
require('./modules/es7.object.lookup-getter');
require('./modules/es7.object.lookup-setter');
require('./modules/es7.map.to-json');
require('./modules/es7.set.to-json');
require('./modules/es7.system.global');
require('./modules/es7.error.is-error');
require('./modules/es7.math.iaddh');
require('./modules/es7.math.isubh');
require('./modules/es7.math.imulh');
require('./modules/es7.math.umulh');
require('./modules/es7.reflect.define-metadata');
require('./modules/es7.reflect.delete-metadata');
require('./modules/es7.reflect.get-metadata');
require('./modules/es7.reflect.get-metadata-keys');
require('./modules/es7.reflect.get-own-metadata');
require('./modules/es7.reflect.get-own-metadata-keys');
require('./modules/es7.reflect.has-metadata');
require('./modules/es7.reflect.has-own-metadata');
require('./modules/es7.reflect.metadata');
require('./modules/es7.asap');
require('./modules/es7.observable');
require('./modules/web.timers');
require('./modules/web.immediate');
require('./modules/web.dom.iterable');
module.exports = require('./modules/_core');
},{"./modules/_core":25,"./modules/es6.array.copy-within":122,"./modules/es6.array.every":123,"./modules/es6.array.fill":124,"./modules/es6.array.filter":125,"./modules/es6.array.find":127,"./modules/es6.array.find-index":126,"./modules/es6.array.for-each":128,"./modules/es6.array.from":129,"./modules/es6.array.index-of":130,"./modules/es6.array.is-array":131,"./modules/es6.array.iterator":132,"./modules/es6.array.join":133,"./modules/es6.array.last-index-of":134,"./modules/es6.array.map":135,"./modules/es6.array.of":136,"./modules/es6.array.reduce":138,"./modules/es6.array.reduce-right":137,"./modules/es6.array.slice":139,"./modules/es6.array.some":140,"./modules/es6.array.sort":141,"./modules/es6.array.species":142,"./modules/es6.date.now":143,"./modules/es6.date.to-iso-string":144,"./modules/es6.date.to-json":145,"./modules/es6.date.to-primitive":146,"./modules/es6.date.to-string":147,"./modules/es6.function.bind":148,"./modules/es6.function.has-instance":149,"./modules/es6.function.name":150,"./modules/es6.map":151,"./modules/es6.math.acosh":152,"./modules/es6.math.asinh":153,"./modules/es6.math.atanh":154,"./modules/es6.math.cbrt":155,"./modules/es6.math.clz32":156,"./modules/es6.math.cosh":157,"./modules/es6.math.expm1":158,"./modules/es6.math.fround":159,"./modules/es6.math.hypot":160,"./modules/es6.math.imul":161,"./modules/es6.math.log10":162,"./modules/es6.math.log1p":163,"./modules/es6.math.log2":164,"./modules/es6.math.sign":165,"./modules/es6.math.sinh":166,"./modules/es6.math.tanh":167,"./modules/es6.math.trunc":168,"./modules/es6.number.constructor":169,"./modules/es6.number.epsilon":170,"./modules/es6.number.is-finite":171,"./modules/es6.number.is-integer":172,"./modules/es6.number.is-nan":173,"./modules/es6.number.is-safe-integer":174,"./modules/es6.number.max-safe-integer":175,"./modules/es6.number.min-safe-integer":176,"./modules/es6.number.parse-float":177,"./modules/es6.number.parse-int":178,"./modules/es6.number.to-fixed":179,"./modules/es6.number.to-precision":180,"./modules/es6.object.assign":181,"./modules/es6.object.create":182,"./modules/es6.object.define-properties":183,"./modules/es6.object.define-property":184,"./modules/es6.object.freeze":185,"./modules/es6.object.get-own-property-descriptor":186,"./modules/es6.object.get-own-property-names":187,"./modules/es6.object.get-prototype-of":188,"./modules/es6.object.is":192,"./modules/es6.object.is-extensible":189,"./modules/es6.object.is-frozen":190,"./modules/es6.object.is-sealed":191,"./modules/es6.object.keys":193,"./modules/es6.object.prevent-extensions":194,"./modules/es6.object.seal":195,"./modules/es6.object.set-prototype-of":196,"./modules/es6.object.to-string":197,"./modules/es6.parse-float":198,"./modules/es6.parse-int":199,"./modules/es6.promise":200,"./modules/es6.reflect.apply":201,"./modules/es6.reflect.construct":202,"./modules/es6.reflect.define-property":203,"./modules/es6.reflect.delete-property":204,"./modules/es6.reflect.enumerate":205,"./modules/es6.reflect.get":208,"./modules/es6.reflect.get-own-property-descriptor":206,"./modules/es6.reflect.get-prototype-of":207,"./modules/es6.reflect.has":209,"./modules/es6.reflect.is-extensible":210,"./modules/es6.reflect.own-keys":211,"./modules/es6.reflect.prevent-extensions":212,"./modules/es6.reflect.set":214,"./modules/es6.reflect.set-prototype-of":213,"./modules/es6.regexp.constructor":215,"./modules/es6.regexp.flags":216,"./modules/es6.regexp.match":217,"./modules/es6.regexp.replace":218,"./modules/es6.regexp.search":219,"./modules/es6.regexp.split":220,"./modules/es6.regexp.to-string":221,"./modules/es6.set":222,"./modules/es6.string.anchor":223,"./modules/es6.string.big":224,"./modules/es6.string.blink":225,"./modules/es6.string.bold":226,"./modules/es6.string.code-point-at":227,"./modules/es6.string.ends-with":228,"./modules/es6.string.fixed":229,"./modules/es6.string.fontcolor":230,"./modules/es6.string.fontsize":231,"./modules/es6.string.from-code-point":232,"./modules/es6.string.includes":233,"./modules/es6.string.italics":234,"./modules/es6.string.iterator":235,"./modules/es6.string.link":236,"./modules/es6.string.raw":237,"./modules/es6.string.repeat":238,"./modules/es6.string.small":239,"./modules/es6.string.starts-with":240,"./modules/es6.string.strike":241,"./modules/es6.string.sub":242,"./modules/es6.string.sup":243,"./modules/es6.string.trim":244,"./modules/es6.symbol":245,"./modules/es6.typed.array-buffer":246,"./modules/es6.typed.data-view":247,"./modules/es6.typed.float32-array":248,"./modules/es6.typed.float64-array":249,"./modules/es6.typed.int16-array":250,"./modules/es6.typed.int32-array":251,"./modules/es6.typed.int8-array":252,"./modules/es6.typed.uint16-array":253,"./modules/es6.typed.uint32-array":254,"./modules/es6.typed.uint8-array":255,"./modules/es6.typed.uint8-clamped-array":256,"./modules/es6.weak-map":257,"./modules/es6.weak-set":258,"./modules/es7.array.includes":259,"./modules/es7.asap":260,"./modules/es7.error.is-error":261,"./modules/es7.map.to-json":262,"./modules/es7.math.iaddh":263,"./modules/es7.math.imulh":264,"./modules/es7.math.isubh":265,"./modules/es7.math.umulh":266,"./modules/es7.object.define-getter":267,"./modules/es7.object.define-setter":268,"./modules/es7.object.entries":269,"./modules/es7.object.get-own-property-descriptors":270,"./modules/es7.object.lookup-getter":271,"./modules/es7.object.lookup-setter":272,"./modules/es7.object.values":273,"./modules/es7.observable":274,"./modules/es7.reflect.define-metadata":275,"./modules/es7.reflect.delete-metadata":276,"./modules/es7.reflect.get-metadata":278,"./modules/es7.reflect.get-metadata-keys":277,"./modules/es7.reflect.get-own-metadata":280,"./modules/es7.reflect.get-own-metadata-keys":279,"./modules/es7.reflect.has-metadata":281,"./modules/es7.reflect.has-own-metadata":282,"./modules/es7.reflect.metadata":283,"./modules/es7.set.to-json":284,"./modules/es7.string.at":285,"./modules/es7.string.match-all":286,"./modules/es7.string.pad-end":287,"./modules/es7.string.pad-start":288,"./modules/es7.string.trim-left":289,"./modules/es7.string.trim-right":290,"./modules/es7.symbol.async-iterator":291,"./modules/es7.symbol.observable":292,"./modules/es7.system.global":293,"./modules/web.dom.iterable":294,"./modules/web.immediate":295,"./modules/web.timers":296}],298:[function(require,module,exports){
var canUseDOM = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
);

module.exports = canUseDOM;
},{}],299:[function(require,module,exports){
/*!
  Copyright (c) 2016 Jed Watson.
  Licensed under the MIT License (MIT), see
  http://jedwatson.github.io/classnames
*/
/* global define */

(function () {
	'use strict';

	var hasOwn = {}.hasOwnProperty;

	function classNames () {
		var classes = [];

		for (var i = 0; i < arguments.length; i++) {
			var arg = arguments[i];
			if (!arg) continue;

			var argType = typeof arg;

			if (argType === 'string' || argType === 'number') {
				classes.push(arg);
			} else if (Array.isArray(arg)) {
				classes.push(classNames.apply(null, arg));
			} else if (argType === 'object') {
				for (var key in arg) {
					if (hasOwn.call(arg, key) && arg[key]) {
						classes.push(key);
					}
				}
			}
		}

		return classes.join(' ');
	}

	if (typeof module !== 'undefined' && module.exports) {
		module.exports = classNames;
	} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
		// register as 'classnames', consistent with npm package name
		define('classnames', [], function () {
			return classNames;
		});
	} else {
		window.classNames = classNames;
	}
}());

},{}],300:[function(require,module,exports){

/**
 * Expose `Emitter`.
 */

if (typeof module !== 'undefined') {
  module.exports = Emitter;
}

/**
 * Initialize a new `Emitter`.
 *
 * @api public
 */

function Emitter(obj) {
  if (obj) return mixin(obj);
};

/**
 * Mixin the emitter properties.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

function mixin(obj) {
  for (var key in Emitter.prototype) {
    obj[key] = Emitter.prototype[key];
  }
  return obj;
}

/**
 * Listen on the given `event` with `fn`.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */

Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
  this._callbacks = this._callbacks || {};
  (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
    .push(fn);
  return this;
};

/**
 * Adds an `event` listener that will be invoked a single
 * time then automatically removed.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */

Emitter.prototype.once = function(event, fn){
  function on() {
    this.off(event, on);
    fn.apply(this, arguments);
  }

  on.fn = fn;
  this.on(event, on);
  return this;
};

/**
 * Remove the given callback for `event` or all
 * registered callbacks.
 *
 * @param {String} event
 * @param {Function} fn
 * @return {Emitter}
 * @api public
 */

Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
  this._callbacks = this._callbacks || {};

  // all
  if (0 == arguments.length) {
    this._callbacks = {};
    return this;
  }

  // specific event
  var callbacks = this._callbacks['$' + event];
  if (!callbacks) return this;

  // remove all handlers
  if (1 == arguments.length) {
    delete this._callbacks['$' + event];
    return this;
  }

  // remove specific handler
  var cb;
  for (var i = 0; i < callbacks.length; i++) {
    cb = callbacks[i];
    if (cb === fn || cb.fn === fn) {
      callbacks.splice(i, 1);
      break;
    }
  }
  return this;
};

/**
 * Emit `event` with the given args.
 *
 * @param {String} event
 * @param {Mixed} ...
 * @return {Emitter}
 */

Emitter.prototype.emit = function(event){
  this._callbacks = this._callbacks || {};
  var args = [].slice.call(arguments, 1)
    , callbacks = this._callbacks['$' + event];

  if (callbacks) {
    callbacks = callbacks.slice(0);
    for (var i = 0, len = callbacks.length; i < len; ++i) {
      callbacks[i].apply(this, args);
    }
  }

  return this;
};

/**
 * Return array of callbacks for `event`.
 *
 * @param {String} event
 * @return {Array}
 * @api public
 */

Emitter.prototype.listeners = function(event){
  this._callbacks = this._callbacks || {};
  return this._callbacks['$' + event] || [];
};

/**
 * Check if this emitter has `event` handlers.
 *
 * @param {String} event
 * @return {Boolean}
 * @api public
 */

Emitter.prototype.hasListeners = function(event){
  return !! this.listeners(event).length;
};

},{}],301:[function(require,module,exports){
'use strict';

var has = Object.prototype.hasOwnProperty;

//
// We store our EE objects in a plain object whose properties are event names.
// If `Object.create(null)` is not supported we prefix the event names with a
// `~` to make sure that the built-in object properties are not overridden or
// used as an attack vector.
// We also assume that `Object.create(null)` is available when the event name
// is an ES6 Symbol.
//
var prefix = typeof Object.create !== 'function' ? '~' : false;

/**
 * Representation of a single EventEmitter function.
 *
 * @param {Function} fn Event handler to be called.
 * @param {Mixed} context Context for function execution.
 * @param {Boolean} [once=false] Only emit once
 * @api private
 */
function EE(fn, context, once) {
  this.fn = fn;
  this.context = context;
  this.once = once || false;
}

/**
 * Minimal EventEmitter interface that is molded against the Node.js
 * EventEmitter interface.
 *
 * @constructor
 * @api public
 */
function EventEmitter() { /* Nothing to set */ }

/**
 * Hold the assigned EventEmitters by name.
 *
 * @type {Object}
 * @private
 */
EventEmitter.prototype._events = undefined;

/**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @api public
 */
EventEmitter.prototype.eventNames = function eventNames() {
  var events = this._events
    , names = []
    , name;

  if (!events) return names;

  for (name in events) {
    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  }

  if (Object.getOwnPropertySymbols) {
    return names.concat(Object.getOwnPropertySymbols(events));
  }

  return names;
};

/**
 * Return a list of assigned event listeners.
 *
 * @param {String} event The events that should be listed.
 * @param {Boolean} exists We only need to know if there are listeners.
 * @returns {Array|Boolean}
 * @api public
 */
EventEmitter.prototype.listeners = function listeners(event, exists) {
  var evt = prefix ? prefix + event : event
    , available = this._events && this._events[evt];

  if (exists) return !!available;
  if (!available) return [];
  if (available.fn) return [available.fn];

  for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
    ee[i] = available[i].fn;
  }

  return ee;
};

/**
 * Emit an event to all registered event listeners.
 *
 * @param {String} event The name of the event.
 * @returns {Boolean} Indication if we've emitted an event.
 * @api public
 */
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return false;

  var listeners = this._events[evt]
    , len = arguments.length
    , args
    , i;

  if ('function' === typeof listeners.fn) {
    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);

    switch (len) {
      case 1: return listeners.fn.call(listeners.context), true;
      case 2: return listeners.fn.call(listeners.context, a1), true;
      case 3: return listeners.fn.call(listeners.context, a1, a2), true;
      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
    }

    for (i = 1, args = new Array(len -1); i < len; i++) {
      args[i - 1] = arguments[i];
    }

    listeners.fn.apply(listeners.context, args);
  } else {
    var length = listeners.length
      , j;

    for (i = 0; i < length; i++) {
      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);

      switch (len) {
        case 1: listeners[i].fn.call(listeners[i].context); break;
        case 2: listeners[i].fn.call(listeners[i].context, a1); break;
        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
        default:
          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
            args[j - 1] = arguments[j];
          }

          listeners[i].fn.apply(listeners[i].context, args);
      }
    }
  }

  return true;
};

/**
 * Register a new EventListener for the given event.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.on = function on(event, fn, context) {
  var listener = new EE(fn, context || this)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Add an EventListener that's only called once.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.once = function once(event, fn, context) {
  var listener = new EE(fn, context || this, true)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Remove event listeners.
 *
 * @param {String} event The event we want to remove.
 * @param {Function} fn The listener that we need to find.
 * @param {Mixed} context Only remove listeners matching this context.
 * @param {Boolean} once Only remove once listeners.
 * @api public
 */
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return this;

  var listeners = this._events[evt]
    , events = [];

  if (fn) {
    if (listeners.fn) {
      if (
           listeners.fn !== fn
        || (once && !listeners.once)
        || (context && listeners.context !== context)
      ) {
        events.push(listeners);
      }
    } else {
      for (var i = 0, length = listeners.length; i < length; i++) {
        if (
             listeners[i].fn !== fn
          || (once && !listeners[i].once)
          || (context && listeners[i].context !== context)
        ) {
          events.push(listeners[i]);
        }
      }
    }
  }

  //
  // Reset the array, or remove it completely if we have no more listeners.
  //
  if (events.length) {
    this._events[evt] = events.length === 1 ? events[0] : events;
  } else {
    delete this._events[evt];
  }

  return this;
};

/**
 * Remove all listeners or only the listeners for the specified event.
 *
 * @param {String} event The event want to remove all listeners for.
 * @api public
 */
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  if (!this._events) return this;

  if (event) delete this._events[prefix ? prefix + event : event];
  else this._events = prefix ? {} : Object.create(null);

  return this;
};

//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;

//
// This function doesn't apply anymore.
//
EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
  return this;
};

//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;

//
// Expose the module.
//
if ('undefined' !== typeof module) {
  module.exports = EventEmitter;
}

},{}],302:[function(require,module,exports){
(function(root,factory){
    if (typeof define === 'function' && define.amd) {
        define(factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.eventListener = factory();
  }
}(this, function () {
	function wrap(standard, fallback) {
		return function (el, evtName, listener, useCapture) {
			if (el[standard]) {
				el[standard](evtName, listener, useCapture);
			} else if (el[fallback]) {
				el[fallback]('on' + evtName, listener);
			}
		}
	}

    return {
		add: wrap('addEventListener', 'attachEvent'),
		remove: wrap('removeEventListener', 'detachEvent')
	};
}));
},{}],303:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @providesModule EventListener
 * @typechecks
 */

'use strict';

var emptyFunction = require('./emptyFunction');

/**
 * Upstream version of event listener. Does not take into account specific
 * nature of platform.
 */
var EventListener = {
  /**
   * Listen to DOM events during the bubble phase.
   *
   * @param {DOMEventTarget} target DOM element to register listener on.
   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
   * @param {function} callback Callback function.
   * @return {object} Object with a `remove` method.
   */
  listen: function (target, eventType, callback) {
    if (target.addEventListener) {
      target.addEventListener(eventType, callback, false);
      return {
        remove: function () {
          target.removeEventListener(eventType, callback, false);
        }
      };
    } else if (target.attachEvent) {
      target.attachEvent('on' + eventType, callback);
      return {
        remove: function () {
          target.detachEvent('on' + eventType, callback);
        }
      };
    }
  },

  /**
   * Listen to DOM events during the capture phase.
   *
   * @param {DOMEventTarget} target DOM element to register listener on.
   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
   * @param {function} callback Callback function.
   * @return {object} Object with a `remove` method.
   */
  capture: function (target, eventType, callback) {
    if (target.addEventListener) {
      target.addEventListener(eventType, callback, true);
      return {
        remove: function () {
          target.removeEventListener(eventType, callback, true);
        }
      };
    } else {
      if (process.env.NODE_ENV !== 'production') {
        console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');
      }
      return {
        remove: emptyFunction
      };
    }
  },

  registerDefault: function () {}
};

module.exports = EventListener;
}).call(this,require('_process'))

},{"./emptyFunction":310,"_process":334}],304:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ExecutionEnvironment
 */

'use strict';

var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);

/**
 * Simple, lightweight module assisting with the detection and context of
 * Worker. Helps avoid circular dependencies and allows code to reason about
 * whether or not they are in a Worker, even if they never include the main
 * `ReactWorker` dependency.
 */
var ExecutionEnvironment = {

  canUseDOM: canUseDOM,

  canUseWorkers: typeof Worker !== 'undefined',

  canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),

  canUseViewport: canUseDOM && !!window.screen,

  isInWorker: !canUseDOM // For now, this is true - might change in the future.

};

module.exports = ExecutionEnvironment;
},{}],305:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule camelize
 * @typechecks
 */

"use strict";

var _hyphenPattern = /-(.)/g;

/**
 * Camelcases a hyphenated string, for example:
 *
 *   > camelize('background-color')
 *   < "backgroundColor"
 *
 * @param {string} string
 * @return {string}
 */
function camelize(string) {
  return string.replace(_hyphenPattern, function (_, character) {
    return character.toUpperCase();
  });
}

module.exports = camelize;
},{}],306:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule camelizeStyleName
 * @typechecks
 */

'use strict';

var camelize = require('./camelize');

var msPattern = /^-ms-/;

/**
 * Camelcases a hyphenated CSS property name, for example:
 *
 *   > camelizeStyleName('background-color')
 *   < "backgroundColor"
 *   > camelizeStyleName('-moz-transition')
 *   < "MozTransition"
 *   > camelizeStyleName('-ms-transition')
 *   < "msTransition"
 *
 * As Andi Smith suggests
 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
 * is converted to lowercase `ms`.
 *
 * @param {string} string
 * @return {string}
 */
function camelizeStyleName(string) {
  return camelize(string.replace(msPattern, 'ms-'));
}

module.exports = camelizeStyleName;
},{"./camelize":305}],307:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule containsNode
 * @typechecks
 */

'use strict';

var isTextNode = require('./isTextNode');

/*eslint-disable no-bitwise */

/**
 * Checks if a given DOM node contains or is another DOM node.
 *
 * @param {?DOMNode} outerNode Outer DOM node.
 * @param {?DOMNode} innerNode Inner DOM node.
 * @return {boolean} True if `outerNode` contains or is `innerNode`.
 */
function containsNode(_x, _x2) {
  var _again = true;

  _function: while (_again) {
    var outerNode = _x,
        innerNode = _x2;
    _again = false;

    if (!outerNode || !innerNode) {
      return false;
    } else if (outerNode === innerNode) {
      return true;
    } else if (isTextNode(outerNode)) {
      return false;
    } else if (isTextNode(innerNode)) {
      _x = outerNode;
      _x2 = innerNode.parentNode;
      _again = true;
      continue _function;
    } else if (outerNode.contains) {
      return outerNode.contains(innerNode);
    } else if (outerNode.compareDocumentPosition) {
      return !!(outerNode.compareDocumentPosition(innerNode) & 16);
    } else {
      return false;
    }
  }
}

module.exports = containsNode;
},{"./isTextNode":320}],308:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule createArrayFromMixed
 * @typechecks
 */

'use strict';

var toArray = require('./toArray');

/**
 * Perform a heuristic test to determine if an object is "array-like".
 *
 *   A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
 *   Joshu replied: "Mu."
 *
 * This function determines if its argument has "array nature": it returns
 * true if the argument is an actual array, an `arguments' object, or an
 * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
 *
 * It will return false for other array-like objects like Filelist.
 *
 * @param {*} obj
 * @return {boolean}
 */
function hasArrayNature(obj) {
  return(
    // not null/false
    !!obj && (
    // arrays are objects, NodeLists are functions in Safari
    typeof obj == 'object' || typeof obj == 'function') &&
    // quacks like an array
    'length' in obj &&
    // not window
    !('setInterval' in obj) &&
    // no DOM node should be considered an array-like
    // a 'select' element has 'length' and 'item' properties on IE8
    typeof obj.nodeType != 'number' && (
    // a real array
    Array.isArray(obj) ||
    // arguments
    'callee' in obj ||
    // HTMLCollection/NodeList
    'item' in obj)
  );
}

/**
 * Ensure that the argument is an array by wrapping it in an array if it is not.
 * Creates a copy of the argument if it is already an array.
 *
 * This is mostly useful idiomatically:
 *
 *   var createArrayFromMixed = require('createArrayFromMixed');
 *
 *   function takesOneOrMoreThings(things) {
 *     things = createArrayFromMixed(things);
 *     ...
 *   }
 *
 * This allows you to treat `things' as an array, but accept scalars in the API.
 *
 * If you need to convert an array-like object, like `arguments`, into an array
 * use toArray instead.
 *
 * @param {*} obj
 * @return {array}
 */
function createArrayFromMixed(obj) {
  if (!hasArrayNature(obj)) {
    return [obj];
  } else if (Array.isArray(obj)) {
    return obj.slice();
  } else {
    return toArray(obj);
  }
}

module.exports = createArrayFromMixed;
},{"./toArray":328}],309:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule createNodesFromMarkup
 * @typechecks
 */

/*eslint-disable fb-www/unsafe-html*/

'use strict';

var ExecutionEnvironment = require('./ExecutionEnvironment');

var createArrayFromMixed = require('./createArrayFromMixed');
var getMarkupWrap = require('./getMarkupWrap');
var invariant = require('./invariant');

/**
 * Dummy container used to render all markup.
 */
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;

/**
 * Pattern used by `getNodeName`.
 */
var nodeNamePattern = /^\s*<(\w+)/;

/**
 * Extracts the `nodeName` of the first element in a string of markup.
 *
 * @param {string} markup String of markup.
 * @return {?string} Node name of the supplied markup.
 */
function getNodeName(markup) {
  var nodeNameMatch = markup.match(nodeNamePattern);
  return nodeNameMatch && nodeNameMatch[1].toLowerCase();
}

/**
 * Creates an array containing the nodes rendered from the supplied markup. The
 * optionally supplied `handleScript` function will be invoked once for each
 * <script> element that is rendered. If no `handleScript` function is supplied,
 * an exception is thrown if any <script> elements are rendered.
 *
 * @param {string} markup A string of valid HTML markup.
 * @param {?function} handleScript Invoked once for each rendered <script>.
 * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
 */
function createNodesFromMarkup(markup, handleScript) {
  var node = dummyNode;
  !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : undefined;
  var nodeName = getNodeName(markup);

  var wrap = nodeName && getMarkupWrap(nodeName);
  if (wrap) {
    node.innerHTML = wrap[1] + markup + wrap[2];

    var wrapDepth = wrap[0];
    while (wrapDepth--) {
      node = node.lastChild;
    }
  } else {
    node.innerHTML = markup;
  }

  var scripts = node.getElementsByTagName('script');
  if (scripts.length) {
    !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : undefined;
    createArrayFromMixed(scripts).forEach(handleScript);
  }

  var nodes = createArrayFromMixed(node.childNodes);
  while (node.lastChild) {
    node.removeChild(node.lastChild);
  }
  return nodes;
}

module.exports = createNodesFromMarkup;
}).call(this,require('_process'))

},{"./ExecutionEnvironment":304,"./createArrayFromMixed":308,"./getMarkupWrap":314,"./invariant":318,"_process":334}],310:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule emptyFunction
 */

"use strict";

function makeEmptyFunction(arg) {
  return function () {
    return arg;
  };
}

/**
 * This function accepts and discards inputs; it has no side effects. This is
 * primarily useful idiomatically for overridable function endpoints which
 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
 */
function emptyFunction() {}

emptyFunction.thatReturns = makeEmptyFunction;
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
emptyFunction.thatReturnsThis = function () {
  return this;
};
emptyFunction.thatReturnsArgument = function (arg) {
  return arg;
};

module.exports = emptyFunction;
},{}],311:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule emptyObject
 */

'use strict';

var emptyObject = {};

if (process.env.NODE_ENV !== 'production') {
  Object.freeze(emptyObject);
}

module.exports = emptyObject;
}).call(this,require('_process'))

},{"_process":334}],312:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule focusNode
 */

'use strict';

/**
 * @param {DOMElement} node input/textarea to focus
 */
function focusNode(node) {
  // IE8 can throw "Can't move focus to the control because it is invisible,
  // not enabled, or of a type that does not accept the focus." for all kinds of
  // reasons that are too expensive and fragile to test.
  try {
    node.focus();
  } catch (e) {}
}

module.exports = focusNode;
},{}],313:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getActiveElement
 * @typechecks
 */

/* eslint-disable fb-www/typeof-undefined */

/**
 * Same as document.activeElement but wraps in a try-catch block. In IE it is
 * not safe to call document.activeElement if there is nothing focused.
 *
 * The activeElement will be null only if the document or document body is not
 * yet defined.
 */
'use strict';

function getActiveElement() /*?DOMElement*/{
  if (typeof document === 'undefined') {
    return null;
  }
  try {
    return document.activeElement || document.body;
  } catch (e) {
    return document.body;
  }
}

module.exports = getActiveElement;
},{}],314:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getMarkupWrap
 */

/*eslint-disable fb-www/unsafe-html */

'use strict';

var ExecutionEnvironment = require('./ExecutionEnvironment');

var invariant = require('./invariant');

/**
 * Dummy container used to detect which wraps are necessary.
 */
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;

/**
 * Some browsers cannot use `innerHTML` to render certain elements standalone,
 * so we wrap them, render the wrapped nodes, then extract the desired node.
 *
 * In IE8, certain elements cannot render alone, so wrap all elements ('*').
 */

var shouldWrap = {};

var selectWrap = [1, '<select multiple="true">', '</select>'];
var tableWrap = [1, '<table>', '</table>'];
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];

var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>'];

var markupWrap = {
  '*': [1, '?<div>', '</div>'],

  'area': [1, '<map>', '</map>'],
  'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  'legend': [1, '<fieldset>', '</fieldset>'],
  'param': [1, '<object>', '</object>'],
  'tr': [2, '<table><tbody>', '</tbody></table>'],

  'optgroup': selectWrap,
  'option': selectWrap,

  'caption': tableWrap,
  'colgroup': tableWrap,
  'tbody': tableWrap,
  'tfoot': tableWrap,
  'thead': tableWrap,

  'td': trWrap,
  'th': trWrap
};

// Initialize the SVG elements since we know they'll always need to be wrapped
// consistently. If they are created inside a <div> they will be initialized in
// the wrong namespace (and will not display).
var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan'];
svgElements.forEach(function (nodeName) {
  markupWrap[nodeName] = svgWrap;
  shouldWrap[nodeName] = true;
});

/**
 * Gets the markup wrap configuration for the supplied `nodeName`.
 *
 * NOTE: This lazily detects which wraps are necessary for the current browser.
 *
 * @param {string} nodeName Lowercase `nodeName`.
 * @return {?array} Markup wrap configuration, if applicable.
 */
function getMarkupWrap(nodeName) {
  !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : undefined;
  if (!markupWrap.hasOwnProperty(nodeName)) {
    nodeName = '*';
  }
  if (!shouldWrap.hasOwnProperty(nodeName)) {
    if (nodeName === '*') {
      dummyNode.innerHTML = '<link />';
    } else {
      dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
    }
    shouldWrap[nodeName] = !dummyNode.firstChild;
  }
  return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
}

module.exports = getMarkupWrap;
}).call(this,require('_process'))

},{"./ExecutionEnvironment":304,"./invariant":318,"_process":334}],315:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getUnboundedScrollPosition
 * @typechecks
 */

'use strict';

/**
 * Gets the scroll position of the supplied element or window.
 *
 * The return values are unbounded, unlike `getScrollPosition`. This means they
 * may be negative or exceed the element boundaries (which is possible using
 * inertial scrolling).
 *
 * @param {DOMWindow|DOMElement} scrollable
 * @return {object} Map with `x` and `y` keys.
 */
function getUnboundedScrollPosition(scrollable) {
  if (scrollable === window) {
    return {
      x: window.pageXOffset || document.documentElement.scrollLeft,
      y: window.pageYOffset || document.documentElement.scrollTop
    };
  }
  return {
    x: scrollable.scrollLeft,
    y: scrollable.scrollTop
  };
}

module.exports = getUnboundedScrollPosition;
},{}],316:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule hyphenate
 * @typechecks
 */

'use strict';

var _uppercasePattern = /([A-Z])/g;

/**
 * Hyphenates a camelcased string, for example:
 *
 *   > hyphenate('backgroundColor')
 *   < "background-color"
 *
 * For CSS style names, use `hyphenateStyleName` instead which works properly
 * with all vendor prefixes, including `ms`.
 *
 * @param {string} string
 * @return {string}
 */
function hyphenate(string) {
  return string.replace(_uppercasePattern, '-$1').toLowerCase();
}

module.exports = hyphenate;
},{}],317:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule hyphenateStyleName
 * @typechecks
 */

'use strict';

var hyphenate = require('./hyphenate');

var msPattern = /^ms-/;

/**
 * Hyphenates a camelcased CSS property name, for example:
 *
 *   > hyphenateStyleName('backgroundColor')
 *   < "background-color"
 *   > hyphenateStyleName('MozTransition')
 *   < "-moz-transition"
 *   > hyphenateStyleName('msTransition')
 *   < "-ms-transition"
 *
 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
 * is converted to `-ms-`.
 *
 * @param {string} string
 * @return {string}
 */
function hyphenateStyleName(string) {
  return hyphenate(string).replace(msPattern, '-ms-');
}

module.exports = hyphenateStyleName;
},{"./hyphenate":316}],318:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule invariant
 */

'use strict';

/**
 * Use invariant() to assert state which your program assumes to be true.
 *
 * Provide sprintf-style format (only %s is supported) and arguments
 * to provide information about what broke and what you were
 * expecting.
 *
 * The invariant message will be stripped in production, but the invariant
 * will remain to ensure logic does not differ in production.
 */

function invariant(condition, format, a, b, c, d, e, f) {
  if (process.env.NODE_ENV !== 'production') {
    if (format === undefined) {
      throw new Error('invariant requires an error message argument');
    }
  }

  if (!condition) {
    var error;
    if (format === undefined) {
      error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
    } else {
      var args = [a, b, c, d, e, f];
      var argIndex = 0;
      error = new Error(format.replace(/%s/g, function () {
        return args[argIndex++];
      }));
      error.name = 'Invariant Violation';
    }

    error.framesToPop = 1; // we don't care about invariant's own frame
    throw error;
  }
}

module.exports = invariant;
}).call(this,require('_process'))

},{"_process":334}],319:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule isNode
 * @typechecks
 */

/**
 * @param {*} object The object to check.
 * @return {boolean} Whether or not the object is a DOM node.
 */
'use strict';

function isNode(object) {
  return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
}

module.exports = isNode;
},{}],320:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule isTextNode
 * @typechecks
 */

'use strict';

var isNode = require('./isNode');

/**
 * @param {*} object The object to check.
 * @return {boolean} Whether or not the object is a DOM text node.
 */
function isTextNode(object) {
  return isNode(object) && object.nodeType == 3;
}

module.exports = isTextNode;
},{"./isNode":319}],321:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule keyMirror
 * @typechecks static-only
 */

'use strict';

var invariant = require('./invariant');

/**
 * Constructs an enumeration with keys equal to their value.
 *
 * For example:
 *
 *   var COLORS = keyMirror({blue: null, red: null});
 *   var myColor = COLORS.blue;
 *   var isColorValid = !!COLORS[myColor];
 *
 * The last line could not be performed if the values of the generated enum were
 * not equal to their keys.
 *
 *   Input:  {key1: val1, key2: val2}
 *   Output: {key1: key1, key2: key2}
 *
 * @param {object} obj
 * @return {object}
 */
var keyMirror = function (obj) {
  var ret = {};
  var key;
  !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : undefined;
  for (key in obj) {
    if (!obj.hasOwnProperty(key)) {
      continue;
    }
    ret[key] = key;
  }
  return ret;
};

module.exports = keyMirror;
}).call(this,require('_process'))

},{"./invariant":318,"_process":334}],322:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule keyOf
 */

/**
 * Allows extraction of a minified key. Let's the build system minify keys
 * without losing the ability to dynamically use key strings as values
 * themselves. Pass in an object with a single key/val pair and it will return
 * you the string key of that single record. Suppose you want to grab the
 * value for a key 'className' inside of an object. Key/val minification may
 * have aliased that key to be 'xa12'. keyOf({className: null}) will return
 * 'xa12' in that case. Resolve keys you want to use once at startup time, then
 * reuse those resolutions.
 */
"use strict";

var keyOf = function (oneKeyObj) {
  var key;
  for (key in oneKeyObj) {
    if (!oneKeyObj.hasOwnProperty(key)) {
      continue;
    }
    return key;
  }
  return null;
};

module.exports = keyOf;
},{}],323:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule mapObject
 */

'use strict';

var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * Executes the provided `callback` once for each enumerable own property in the
 * object and constructs a new object from the results. The `callback` is
 * invoked with three arguments:
 *
 *  - the property value
 *  - the property name
 *  - the object being traversed
 *
 * Properties that are added after the call to `mapObject` will not be visited
 * by `callback`. If the values of existing properties are changed, the value
 * passed to `callback` will be the value at the time `mapObject` visits them.
 * Properties that are deleted before being visited are not visited.
 *
 * @grep function objectMap()
 * @grep function objMap()
 *
 * @param {?object} object
 * @param {function} callback
 * @param {*} context
 * @return {?object}
 */
function mapObject(object, callback, context) {
  if (!object) {
    return null;
  }
  var result = {};
  for (var name in object) {
    if (hasOwnProperty.call(object, name)) {
      result[name] = callback.call(context, object[name], name, object);
    }
  }
  return result;
}

module.exports = mapObject;
},{}],324:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule memoizeStringOnly
 * @typechecks static-only
 */

'use strict';

/**
 * Memoizes the return value of a function that accepts one string argument.
 *
 * @param {function} callback
 * @return {function}
 */
function memoizeStringOnly(callback) {
  var cache = {};
  return function (string) {
    if (!cache.hasOwnProperty(string)) {
      cache[string] = callback.call(this, string);
    }
    return cache[string];
  };
}

module.exports = memoizeStringOnly;
},{}],325:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule performance
 * @typechecks
 */

'use strict';

var ExecutionEnvironment = require('./ExecutionEnvironment');

var performance;

if (ExecutionEnvironment.canUseDOM) {
  performance = window.performance || window.msPerformance || window.webkitPerformance;
}

module.exports = performance || {};
},{"./ExecutionEnvironment":304}],326:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule performanceNow
 * @typechecks
 */

'use strict';

var performance = require('./performance');

var performanceNow;

/**
 * Detect if we can use `window.performance.now()` and gracefully fallback to
 * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now
 * because of Facebook's testing infrastructure.
 */
if (performance.now) {
  performanceNow = function () {
    return performance.now();
  };
} else {
  performanceNow = function () {
    return Date.now();
  };
}

module.exports = performanceNow;
},{"./performance":325}],327:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule shallowEqual
 * @typechecks
 * 
 */

'use strict';

var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * Performs equality by iterating through keys on an object and returning false
 * when any key has values which are not strictly equal between the arguments.
 * Returns true when the values of all keys are strictly equal.
 */
function shallowEqual(objA, objB) {
  if (objA === objB) {
    return true;
  }

  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
    return false;
  }

  var keysA = Object.keys(objA);
  var keysB = Object.keys(objB);

  if (keysA.length !== keysB.length) {
    return false;
  }

  // Test for A's keys different from B.
  var bHasOwnProperty = hasOwnProperty.bind(objB);
  for (var i = 0; i < keysA.length; i++) {
    if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
      return false;
    }
  }

  return true;
}

module.exports = shallowEqual;
},{}],328:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule toArray
 * @typechecks
 */

'use strict';

var invariant = require('./invariant');

/**
 * Convert array-like objects to arrays.
 *
 * This API assumes the caller knows the contents of the data type. For less
 * well defined inputs use createArrayFromMixed.
 *
 * @param {object|function|filelist} obj
 * @return {array}
 */
function toArray(obj) {
  var length = obj.length;

  // Some browse builtin objects can report typeof 'function' (e.g. NodeList in
  // old versions of Safari).
  !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : undefined;

  !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : undefined;

  !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : undefined;

  // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
  // without method will throw during the slice call and skip straight to the
  // fallback.
  if (obj.hasOwnProperty) {
    try {
      return Array.prototype.slice.call(obj);
    } catch (e) {
      // IE < 9 does not support Array#slice on collections objects
    }
  }

  // Fall back to copying key by key. This assumes all keys have a value,
  // so will not preserve sparsely populated inputs.
  var ret = Array(length);
  for (var ii = 0; ii < length; ii++) {
    ret[ii] = obj[ii];
  }
  return ret;
}

module.exports = toArray;
}).call(this,require('_process'))

},{"./invariant":318,"_process":334}],329:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule warning
 */

'use strict';

var emptyFunction = require('./emptyFunction');

/**
 * Similar to invariant but only logs a warning if the condition is not met.
 * This can be used to log issues in development environments in critical
 * paths. Removing the logging code for production environments will keep the
 * same logic and follow the same code paths.
 */

var warning = emptyFunction;

if (process.env.NODE_ENV !== 'production') {
  warning = function (condition, format) {
    for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      args[_key - 2] = arguments[_key];
    }

    if (format === undefined) {
      throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
    }

    if (format.indexOf('Failed Composite propType: ') === 0) {
      return; // Ignore CompositeComponent proptype check.
    }

    if (!condition) {
      var argIndex = 0;
      var message = 'Warning: ' + format.replace(/%s/g, function () {
        return args[argIndex++];
      });
      if (typeof console !== 'undefined') {
        console.error(message);
      }
      try {
        // --- Welcome to debugging React ---
        // This error was thrown as a convenience so that you can use this stack
        // to find the callsite that caused this warning to fire.
        throw new Error(message);
      } catch (x) {}
    }
  };
}

module.exports = warning;
}).call(this,require('_process'))

},{"./emptyFunction":310,"_process":334}],330:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

/**
 * Use invariant() to assert state which your program assumes to be true.
 *
 * Provide sprintf-style format (only %s is supported) and arguments
 * to provide information about what broke and what you were
 * expecting.
 *
 * The invariant message will be stripped in production, but the invariant
 * will remain to ensure logic does not differ in production.
 */

var invariant = function(condition, format, a, b, c, d, e, f) {
  if (process.env.NODE_ENV !== 'production') {
    if (format === undefined) {
      throw new Error('invariant requires an error message argument');
    }
  }

  if (!condition) {
    var error;
    if (format === undefined) {
      error = new Error(
        'Minified exception occurred; use the non-minified dev environment ' +
        'for the full error message and additional helpful warnings.'
      );
    } else {
      var args = [a, b, c, d, e, f];
      var argIndex = 0;
      error = new Error(
        format.replace(/%s/g, function() { return args[argIndex++]; })
      );
      error.name = 'Invariant Violation';
    }

    error.framesToPop = 1; // we don't care about invariant's own frame
    throw error;
  }
};

module.exports = invariant;

}).call(this,require('_process'))

},{"_process":334}],331:[function(require,module,exports){
(function (global){
/**
 * lodash (Custom Build) <https://lodash.com/>
 * Build: `lodash modularize exports="npm" -o ./`
 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */

/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';

/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';

/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;

/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();

/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var objectToString = objectProto.toString;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
    nativeMin = Math.min;

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function() {
  return root.Date.now();
};

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce(func, wait, options) {
  var lastArgs,
      lastThis,
      maxWait,
      result,
      timerId,
      lastCallTime,
      lastInvokeTime = 0,
      leading = false,
      maxing = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = toNumber(wait) || 0;
  if (isObject(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function invokeFunc(time) {
    var args = lastArgs,
        thisArg = lastThis;

    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }

  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }

  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime,
        result = wait - timeSinceLastCall;

    return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
  }

  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  }

  function timerExpired() {
    var time = now();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }

  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }

  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }

  function flush() {
    return timerId === undefined ? result : trailingEdge(now());
  }

  function debounced() {
    var time = now(),
        isInvoking = shouldInvoke(time);

    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;

    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}

/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */
function isObject(value) {
  var type = typeof value;
  return !!value && (type == 'object' || type == 'function');
}

/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */
function isObjectLike(value) {
  return !!value && typeof value == 'object';
}

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */
function isSymbol(value) {
  return typeof value == 'symbol' ||
    (isObjectLike(value) && objectToString.call(value) == symbolTag);
}

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if (isSymbol(value)) {
    return NAN;
  }
  if (isObject(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = isObject(other) ? (other + '') : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = value.replace(reTrim, '');
  var isBinary = reIsBinary.test(value);
  return (isBinary || reIsOctal.test(value))
    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
    : (reIsBadHex.test(value) ? NAN : +value);
}

module.exports = debounce;

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],332:[function(require,module,exports){
(function (global){
/**
 * lodash (Custom Build) <https://lodash.com/>
 * Build: `lodash modularize exports="npm" -o ./`
 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */

/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';

/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';

/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;

/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();

/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var objectToString = objectProto.toString;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
    nativeMin = Math.min;

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function() {
  return root.Date.now();
};

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce(func, wait, options) {
  var lastArgs,
      lastThis,
      maxWait,
      result,
      timerId,
      lastCallTime,
      lastInvokeTime = 0,
      leading = false,
      maxing = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = toNumber(wait) || 0;
  if (isObject(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function invokeFunc(time) {
    var args = lastArgs,
        thisArg = lastThis;

    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }

  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }

  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime,
        result = wait - timeSinceLastCall;

    return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
  }

  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  }

  function timerExpired() {
    var time = now();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }

  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }

  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }

  function flush() {
    return timerId === undefined ? result : trailingEdge(now());
  }

  function debounced() {
    var time = now(),
        isInvoking = shouldInvoke(time);

    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;

    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}

/**
 * Creates a throttled function that only invokes `func` at most once per
 * every `wait` milliseconds. The throttled function comes with a `cancel`
 * method to cancel delayed `func` invocations and a `flush` method to
 * immediately invoke them. Provide `options` to indicate whether `func`
 * should be invoked on the leading and/or trailing edge of the `wait`
 * timeout. The `func` is invoked with the last arguments provided to the
 * throttled function. Subsequent calls to the throttled function return the
 * result of the last `func` invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the throttled function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.throttle` and `_.debounce`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to throttle.
 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=true]
 *  Specify invoking on the leading edge of the timeout.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new throttled function.
 * @example
 *
 * // Avoid excessively updating the position while scrolling.
 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
 *
 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
 * jQuery(element).on('click', throttled);
 *
 * // Cancel the trailing throttled invocation.
 * jQuery(window).on('popstate', throttled.cancel);
 */
function throttle(func, wait, options) {
  var leading = true,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  if (isObject(options)) {
    leading = 'leading' in options ? !!options.leading : leading;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }
  return debounce(func, wait, {
    'leading': leading,
    'maxWait': wait,
    'trailing': trailing
  });
}

/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */
function isObject(value) {
  var type = typeof value;
  return !!value && (type == 'object' || type == 'function');
}

/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */
function isObjectLike(value) {
  return !!value && typeof value == 'object';
}

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */
function isSymbol(value) {
  return typeof value == 'symbol' ||
    (isObjectLike(value) && objectToString.call(value) == symbolTag);
}

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if (isSymbol(value)) {
    return NAN;
  }
  if (isObject(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = isObject(other) ? (other + '') : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = value.replace(reTrim, '');
  var isBinary = reIsBinary.test(value);
  return (isBinary || reIsOctal.test(value))
    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
    : (reIsBadHex.test(value) ? NAN : +value);
}

module.exports = throttle;

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],333:[function(require,module,exports){
(function (global){
/**
 * @license
 * lodash 3.10.1 (Custom Build) <https://lodash.com/>
 * Build: `lodash modern -d -o ./index.js`
 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 * Available under MIT license <https://lodash.com/license>
 */
;(function() {

  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
  var undefined;

  /** Used as the semantic version number. */
  var VERSION = '3.10.1';

  /** Used to compose bitmasks for wrapper metadata. */
  var BIND_FLAG = 1,
      BIND_KEY_FLAG = 2,
      CURRY_BOUND_FLAG = 4,
      CURRY_FLAG = 8,
      CURRY_RIGHT_FLAG = 16,
      PARTIAL_FLAG = 32,
      PARTIAL_RIGHT_FLAG = 64,
      ARY_FLAG = 128,
      REARG_FLAG = 256;

  /** Used as default options for `_.trunc`. */
  var DEFAULT_TRUNC_LENGTH = 30,
      DEFAULT_TRUNC_OMISSION = '...';

  /** Used to detect when a function becomes hot. */
  var HOT_COUNT = 150,
      HOT_SPAN = 16;

  /** Used as the size to enable large array optimizations. */
  var LARGE_ARRAY_SIZE = 200;

  /** Used to indicate the type of lazy iteratees. */
  var LAZY_FILTER_FLAG = 1,
      LAZY_MAP_FLAG = 2;

  /** Used as the `TypeError` message for "Functions" methods. */
  var FUNC_ERROR_TEXT = 'Expected a function';

  /** Used as the internal argument placeholder. */
  var PLACEHOLDER = '__lodash_placeholder__';

  /** `Object#toString` result references. */
  var argsTag = '[object Arguments]',
      arrayTag = '[object Array]',
      boolTag = '[object Boolean]',
      dateTag = '[object Date]',
      errorTag = '[object Error]',
      funcTag = '[object Function]',
      mapTag = '[object Map]',
      numberTag = '[object Number]',
      objectTag = '[object Object]',
      regexpTag = '[object RegExp]',
      setTag = '[object Set]',
      stringTag = '[object String]',
      weakMapTag = '[object WeakMap]';

  var arrayBufferTag = '[object ArrayBuffer]',
      float32Tag = '[object Float32Array]',
      float64Tag = '[object Float64Array]',
      int8Tag = '[object Int8Array]',
      int16Tag = '[object Int16Array]',
      int32Tag = '[object Int32Array]',
      uint8Tag = '[object Uint8Array]',
      uint8ClampedTag = '[object Uint8ClampedArray]',
      uint16Tag = '[object Uint16Array]',
      uint32Tag = '[object Uint32Array]';

  /** Used to match empty string literals in compiled template source. */
  var reEmptyStringLeading = /\b__p \+= '';/g,
      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;

  /** Used to match HTML entities and HTML characters. */
  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
      reUnescapedHtml = /[&<>"'`]/g,
      reHasEscapedHtml = RegExp(reEscapedHtml.source),
      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);

  /** Used to match template delimiters. */
  var reEscape = /<%-([\s\S]+?)%>/g,
      reEvaluate = /<%([\s\S]+?)%>/g,
      reInterpolate = /<%=([\s\S]+?)%>/g;

  /** Used to match property names within property paths. */
  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
      reIsPlainProp = /^\w*$/,
      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;

  /**
   * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)
   * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).
   */
  var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
      reHasRegExpChars = RegExp(reRegExpChars.source);

  /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
  var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;

  /** Used to match backslashes in property paths. */
  var reEscapeChar = /\\(\\)?/g;

  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;

  /** Used to match `RegExp` flags from their coerced string values. */
  var reFlags = /\w*$/;

  /** Used to detect hexadecimal string values. */
  var reHasHexPrefix = /^0[xX]/;

  /** Used to detect host constructors (Safari > 5). */
  var reIsHostCtor = /^\[object .+?Constructor\]$/;

  /** Used to detect unsigned integer values. */
  var reIsUint = /^\d+$/;

  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;

  /** Used to ensure capturing order of template delimiters. */
  var reNoMatch = /($^)/;

  /** Used to match unescaped characters in compiled string literals. */
  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;

  /** Used to match words to create compound words. */
  var reWords = (function() {
    var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
        lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';

    return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
  }());

  /** Used to assign default `context` object properties. */
  var contextProps = [
    'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
    'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
    'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
  ];

  /** Used to make template sourceURLs easier to identify. */
  var templateCounter = -1;

  /** Used to identify `toStringTag` values of typed arrays. */
  var typedArrayTags = {};
  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  typedArrayTags[uint32Tag] = true;
  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;

  /** Used to identify `toStringTag` values supported by `_.clone`. */
  var cloneableTags = {};
  cloneableTags[argsTag] = cloneableTags[arrayTag] =
  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
  cloneableTags[dateTag] = cloneableTags[float32Tag] =
  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
  cloneableTags[numberTag] = cloneableTags[objectTag] =
  cloneableTags[regexpTag] = cloneableTags[stringTag] =
  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
  cloneableTags[errorTag] = cloneableTags[funcTag] =
  cloneableTags[mapTag] = cloneableTags[setTag] =
  cloneableTags[weakMapTag] = false;

  /** Used to map latin-1 supplementary letters to basic latin letters. */
  var deburredLetters = {
    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
    '\xc7': 'C',  '\xe7': 'c',
    '\xd0': 'D',  '\xf0': 'd',
    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
    '\xd1': 'N',  '\xf1': 'n',
    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
    '\xc6': 'Ae', '\xe6': 'ae',
    '\xde': 'Th', '\xfe': 'th',
    '\xdf': 'ss'
  };

  /** Used to map characters to HTML entities. */
  var htmlEscapes = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
    '`': '&#96;'
  };

  /** Used to map HTML entities to characters. */
  var htmlUnescapes = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
    '&quot;': '"',
    '&#39;': "'",
    '&#96;': '`'
  };

  /** Used to determine if values are of the language type `Object`. */
  var objectTypes = {
    'function': true,
    'object': true
  };

  /** Used to escape characters for inclusion in compiled regexes. */
  var regexpEscapes = {
    '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',
    '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',
    'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',
    'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',
    'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'
  };

  /** Used to escape characters for inclusion in compiled string literals. */
  var stringEscapes = {
    '\\': '\\',
    "'": "'",
    '\n': 'n',
    '\r': 'r',
    '\u2028': 'u2028',
    '\u2029': 'u2029'
  };

  /** Detect free variable `exports`. */
  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;

  /** Detect free variable `module`. */
  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;

  /** Detect free variable `global` from Node.js. */
  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;

  /** Detect free variable `self`. */
  var freeSelf = objectTypes[typeof self] && self && self.Object && self;

  /** Detect free variable `window`. */
  var freeWindow = objectTypes[typeof window] && window && window.Object && window;

  /** Detect the popular CommonJS extension `module.exports`. */
  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;

  /**
   * Used as a reference to the global object.
   *
   * The `this` value is used if it's the global object to avoid Greasemonkey's
   * restricted `window` object, otherwise the `window` object is used.
   */
  var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;

  /*--------------------------------------------------------------------------*/

  /**
   * The base implementation of `compareAscending` which compares values and
   * sorts them in ascending order without guaranteeing a stable sort.
   *
   * @private
   * @param {*} value The value to compare.
   * @param {*} other The other value to compare.
   * @returns {number} Returns the sort order indicator for `value`.
   */
  function baseCompareAscending(value, other) {
    if (value !== other) {
      var valIsNull = value === null,
          valIsUndef = value === undefined,
          valIsReflexive = value === value;

      var othIsNull = other === null,
          othIsUndef = other === undefined,
          othIsReflexive = other === other;

      if ((value > other && !othIsNull) || !valIsReflexive ||
          (valIsNull && !othIsUndef && othIsReflexive) ||
          (valIsUndef && othIsReflexive)) {
        return 1;
      }
      if ((value < other && !valIsNull) || !othIsReflexive ||
          (othIsNull && !valIsUndef && valIsReflexive) ||
          (othIsUndef && valIsReflexive)) {
        return -1;
      }
    }
    return 0;
  }

  /**
   * The base implementation of `_.findIndex` and `_.findLastIndex` without
   * support for callback shorthands and `this` binding.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {Function} predicate The function invoked per iteration.
   * @param {boolean} [fromRight] Specify iterating from right to left.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function baseFindIndex(array, predicate, fromRight) {
    var length = array.length,
        index = fromRight ? length : -1;

    while ((fromRight ? index-- : ++index < length)) {
      if (predicate(array[index], index, array)) {
        return index;
      }
    }
    return -1;
  }

  /**
   * The base implementation of `_.indexOf` without support for binary searches.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {*} value The value to search for.
   * @param {number} fromIndex The index to search from.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function baseIndexOf(array, value, fromIndex) {
    if (value !== value) {
      return indexOfNaN(array, fromIndex);
    }
    var index = fromIndex - 1,
        length = array.length;

    while (++index < length) {
      if (array[index] === value) {
        return index;
      }
    }
    return -1;
  }

  /**
   * The base implementation of `_.isFunction` without support for environments
   * with incorrect `typeof` results.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
   */
  function baseIsFunction(value) {
    // Avoid a Chakra JIT bug in compatibility modes of IE 11.
    // See https://github.com/jashkenas/underscore/issues/1621 for more details.
    return typeof value == 'function' || false;
  }

  /**
   * Converts `value` to a string if it's not one. An empty string is returned
   * for `null` or `undefined` values.
   *
   * @private
   * @param {*} value The value to process.
   * @returns {string} Returns the string.
   */
  function baseToString(value) {
    return value == null ? '' : (value + '');
  }

  /**
   * Used by `_.trim` and `_.trimLeft` to get the index of the first character
   * of `string` that is not found in `chars`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @param {string} chars The characters to find.
   * @returns {number} Returns the index of the first character not found in `chars`.
   */
  function charsLeftIndex(string, chars) {
    var index = -1,
        length = string.length;

    while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}
    return index;
  }

  /**
   * Used by `_.trim` and `_.trimRight` to get the index of the last character
   * of `string` that is not found in `chars`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @param {string} chars The characters to find.
   * @returns {number} Returns the index of the last character not found in `chars`.
   */
  function charsRightIndex(string, chars) {
    var index = string.length;

    while (index-- && chars.indexOf(string.charAt(index)) > -1) {}
    return index;
  }

  /**
   * Used by `_.sortBy` to compare transformed elements of a collection and stable
   * sort them in ascending order.
   *
   * @private
   * @param {Object} object The object to compare.
   * @param {Object} other The other object to compare.
   * @returns {number} Returns the sort order indicator for `object`.
   */
  function compareAscending(object, other) {
    return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
  }

  /**
   * Used by `_.sortByOrder` to compare multiple properties of a value to another
   * and stable sort them.
   *
   * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,
   * a value is sorted in ascending order if its corresponding order is "asc", and
   * descending if "desc".
   *
   * @private
   * @param {Object} object The object to compare.
   * @param {Object} other The other object to compare.
   * @param {boolean[]} orders The order to sort by for each property.
   * @returns {number} Returns the sort order indicator for `object`.
   */
  function compareMultiple(object, other, orders) {
    var index = -1,
        objCriteria = object.criteria,
        othCriteria = other.criteria,
        length = objCriteria.length,
        ordersLength = orders.length;

    while (++index < length) {
      var result = baseCompareAscending(objCriteria[index], othCriteria[index]);
      if (result) {
        if (index >= ordersLength) {
          return result;
        }
        var order = orders[index];
        return result * ((order === 'asc' || order === true) ? 1 : -1);
      }
    }
    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
    // that causes it, under certain circumstances, to provide the same value for
    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
    // for more details.
    //
    // This also ensures a stable sort in V8 and other engines.
    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
    return object.index - other.index;
  }

  /**
   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
   *
   * @private
   * @param {string} letter The matched letter to deburr.
   * @returns {string} Returns the deburred letter.
   */
  function deburrLetter(letter) {
    return deburredLetters[letter];
  }

  /**
   * Used by `_.escape` to convert characters to HTML entities.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @returns {string} Returns the escaped character.
   */
  function escapeHtmlChar(chr) {
    return htmlEscapes[chr];
  }

  /**
   * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @param {string} leadingChar The capture group for a leading character.
   * @param {string} whitespaceChar The capture group for a whitespace character.
   * @returns {string} Returns the escaped character.
   */
  function escapeRegExpChar(chr, leadingChar, whitespaceChar) {
    if (leadingChar) {
      chr = regexpEscapes[chr];
    } else if (whitespaceChar) {
      chr = stringEscapes[chr];
    }
    return '\\' + chr;
  }

  /**
   * Used by `_.template` to escape characters for inclusion in compiled string literals.
   *
   * @private
   * @param {string} chr The matched character to escape.
   * @returns {string} Returns the escaped character.
   */
  function escapeStringChar(chr) {
    return '\\' + stringEscapes[chr];
  }

  /**
   * Gets the index at which the first occurrence of `NaN` is found in `array`.
   *
   * @private
   * @param {Array} array The array to search.
   * @param {number} fromIndex The index to search from.
   * @param {boolean} [fromRight] Specify iterating from right to left.
   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
   */
  function indexOfNaN(array, fromIndex, fromRight) {
    var length = array.length,
        index = fromIndex + (fromRight ? 0 : -1);

    while ((fromRight ? index-- : ++index < length)) {
      var other = array[index];
      if (other !== other) {
        return index;
      }
    }
    return -1;
  }

  /**
   * Checks if `value` is object-like.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   */
  function isObjectLike(value) {
    return !!value && typeof value == 'object';
  }

  /**
   * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a
   * character code is whitespace.
   *
   * @private
   * @param {number} charCode The character code to inspect.
   * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.
   */
  function isSpace(charCode) {
    return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||
      (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));
  }

  /**
   * Replaces all `placeholder` elements in `array` with an internal placeholder
   * and returns an array of their indexes.
   *
   * @private
   * @param {Array} array The array to modify.
   * @param {*} placeholder The placeholder to replace.
   * @returns {Array} Returns the new array of placeholder indexes.
   */
  function replaceHolders(array, placeholder) {
    var index = -1,
        length = array.length,
        resIndex = -1,
        result = [];

    while (++index < length) {
      if (array[index] === placeholder) {
        array[index] = PLACEHOLDER;
        result[++resIndex] = index;
      }
    }
    return result;
  }

  /**
   * An implementation of `_.uniq` optimized for sorted arrays without support
   * for callback shorthands and `this` binding.
   *
   * @private
   * @param {Array} array The array to inspect.
   * @param {Function} [iteratee] The function invoked per iteration.
   * @returns {Array} Returns the new duplicate-value-free array.
   */
  function sortedUniq(array, iteratee) {
    var seen,
        index = -1,
        length = array.length,
        resIndex = -1,
        result = [];

    while (++index < length) {
      var value = array[index],
          computed = iteratee ? iteratee(value, index, array) : value;

      if (!index || seen !== computed) {
        seen = computed;
        result[++resIndex] = value;
      }
    }
    return result;
  }

  /**
   * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace
   * character of `string`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @returns {number} Returns the index of the first non-whitespace character.
   */
  function trimmedLeftIndex(string) {
    var index = -1,
        length = string.length;

    while (++index < length && isSpace(string.charCodeAt(index))) {}
    return index;
  }

  /**
   * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace
   * character of `string`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @returns {number} Returns the index of the last non-whitespace character.
   */
  function trimmedRightIndex(string) {
    var index = string.length;

    while (index-- && isSpace(string.charCodeAt(index))) {}
    return index;
  }

  /**
   * Used by `_.unescape` to convert HTML entities to characters.
   *
   * @private
   * @param {string} chr The matched character to unescape.
   * @returns {string} Returns the unescaped character.
   */
  function unescapeHtmlChar(chr) {
    return htmlUnescapes[chr];
  }

  /*--------------------------------------------------------------------------*/

  /**
   * Create a new pristine `lodash` function using the given `context` object.
   *
   * @static
   * @memberOf _
   * @category Utility
   * @param {Object} [context=root] The context object.
   * @returns {Function} Returns a new `lodash` function.
   * @example
   *
   * _.mixin({ 'foo': _.constant('foo') });
   *
   * var lodash = _.runInContext();
   * lodash.mixin({ 'bar': lodash.constant('bar') });
   *
   * _.isFunction(_.foo);
   * // => true
   * _.isFunction(_.bar);
   * // => false
   *
   * lodash.isFunction(lodash.foo);
   * // => false
   * lodash.isFunction(lodash.bar);
   * // => true
   *
   * // using `context` to mock `Date#getTime` use in `_.now`
   * var mock = _.runInContext({
   *   'Date': function() {
   *     return { 'getTime': getTimeMock };
   *   }
   * });
   *
   * // or creating a suped-up `defer` in Node.js
   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
   */
  function runInContext(context) {
    // Avoid issues with some ES3 environments that attempt to use values, named
    // after built-in constructors like `Object`, for the creation of literals.
    // ES5 clears this up by stating that literals must use built-in constructors.
    // See https://es5.github.io/#x11.1.5 for more details.
    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;

    /** Native constructor references. */
    var Array = context.Array,
        Date = context.Date,
        Error = context.Error,
        Function = context.Function,
        Math = context.Math,
        Number = context.Number,
        Object = context.Object,
        RegExp = context.RegExp,
        String = context.String,
        TypeError = context.TypeError;

    /** Used for native method references. */
    var arrayProto = Array.prototype,
        objectProto = Object.prototype,
        stringProto = String.prototype;

    /** Used to resolve the decompiled source of functions. */
    var fnToString = Function.prototype.toString;

    /** Used to check objects for own properties. */
    var hasOwnProperty = objectProto.hasOwnProperty;

    /** Used to generate unique IDs. */
    var idCounter = 0;

    /**
     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
     * of values.
     */
    var objToString = objectProto.toString;

    /** Used to restore the original `_` reference in `_.noConflict`. */
    var oldDash = root._;

    /** Used to detect if a method is native. */
    var reIsNative = RegExp('^' +
      fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
    );

    /** Native method references. */
    var ArrayBuffer = context.ArrayBuffer,
        clearTimeout = context.clearTimeout,
        parseFloat = context.parseFloat,
        pow = Math.pow,
        propertyIsEnumerable = objectProto.propertyIsEnumerable,
        Set = getNative(context, 'Set'),
        setTimeout = context.setTimeout,
        splice = arrayProto.splice,
        Uint8Array = context.Uint8Array,
        WeakMap = getNative(context, 'WeakMap');

    /* Native method references for those with the same name as other `lodash` methods. */
    var nativeCeil = Math.ceil,
        nativeCreate = getNative(Object, 'create'),
        nativeFloor = Math.floor,
        nativeIsArray = getNative(Array, 'isArray'),
        nativeIsFinite = context.isFinite,
        nativeKeys = getNative(Object, 'keys'),
        nativeMax = Math.max,
        nativeMin = Math.min,
        nativeNow = getNative(Date, 'now'),
        nativeParseInt = context.parseInt,
        nativeRandom = Math.random;

    /** Used as references for `-Infinity` and `Infinity`. */
    var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,
        POSITIVE_INFINITY = Number.POSITIVE_INFINITY;

    /** Used as references for the maximum length and index of an array. */
    var MAX_ARRAY_LENGTH = 4294967295,
        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;

    /**
     * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
     * of an array-like value.
     */
    var MAX_SAFE_INTEGER = 9007199254740991;

    /** Used to store function metadata. */
    var metaMap = WeakMap && new WeakMap;

    /** Used to lookup unminified function names. */
    var realNames = {};

    /*------------------------------------------------------------------------*/

    /**
     * Creates a `lodash` object which wraps `value` to enable implicit chaining.
     * Methods that operate on and return arrays, collections, and functions can
     * be chained together. Methods that retrieve a single value or may return a
     * primitive value will automatically end the chain returning the unwrapped
     * value. Explicit chaining may be enabled using `_.chain`. The execution of
     * chained methods is lazy, that is, execution is deferred until `_#value`
     * is implicitly or explicitly called.
     *
     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
     * fusion is an optimization strategy which merge iteratee calls; this can help
     * to avoid the creation of intermediate data structures and greatly reduce the
     * number of iteratee executions.
     *
     * Chaining is supported in custom builds as long as the `_#value` method is
     * directly or indirectly included in the build.
     *
     * In addition to lodash methods, wrappers have `Array` and `String` methods.
     *
     * The wrapper `Array` methods are:
     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
     * `splice`, and `unshift`
     *
     * The wrapper `String` methods are:
     * `replace` and `split`
     *
     * The wrapper methods that support shortcut fusion are:
     * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
     * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
     * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
     * and `where`
     *
     * The chainable wrapper methods are:
     * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
     * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
     * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
     * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
     * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
     * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
     * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
     * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
     * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
     * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
     * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
     * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
     * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
     * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
     *
     * The wrapper methods that are **not** chainable by default are:
     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
     * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
     * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
     * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
     * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
     * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
     * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
     * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
     * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
     * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
     * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
     * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
     * `unescape`, `uniqueId`, `value`, and `words`
     *
     * The wrapper method `sample` will return a wrapped value when `n` is provided,
     * otherwise an unwrapped value is returned.
     *
     * @name _
     * @constructor
     * @category Chain
     * @param {*} value The value to wrap in a `lodash` instance.
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var wrapped = _([1, 2, 3]);
     *
     * // returns an unwrapped value
     * wrapped.reduce(function(total, n) {
     *   return total + n;
     * });
     * // => 6
     *
     * // returns a wrapped value
     * var squares = wrapped.map(function(n) {
     *   return n * n;
     * });
     *
     * _.isArray(squares);
     * // => false
     *
     * _.isArray(squares.value());
     * // => true
     */
    function lodash(value) {
      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
        if (value instanceof LodashWrapper) {
          return value;
        }
        if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
          return wrapperClone(value);
        }
      }
      return new LodashWrapper(value);
    }

    /**
     * The function whose prototype all chaining wrappers inherit from.
     *
     * @private
     */
    function baseLodash() {
      // No operation performed.
    }

    /**
     * The base constructor for creating `lodash` wrapper objects.
     *
     * @private
     * @param {*} value The value to wrap.
     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
     * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
     */
    function LodashWrapper(value, chainAll, actions) {
      this.__wrapped__ = value;
      this.__actions__ = actions || [];
      this.__chain__ = !!chainAll;
    }

    /**
     * An object environment feature flags.
     *
     * @static
     * @memberOf _
     * @type Object
     */
    var support = lodash.support = {};

    /**
     * By default, the template delimiters used by lodash are like those in
     * embedded Ruby (ERB). Change the following template settings to use
     * alternative delimiters.
     *
     * @static
     * @memberOf _
     * @type Object
     */
    lodash.templateSettings = {

      /**
       * Used to detect `data` property values to be HTML-escaped.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'escape': reEscape,

      /**
       * Used to detect code to be evaluated.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'evaluate': reEvaluate,

      /**
       * Used to detect `data` property values to inject.
       *
       * @memberOf _.templateSettings
       * @type RegExp
       */
      'interpolate': reInterpolate,

      /**
       * Used to reference the data object in the template text.
       *
       * @memberOf _.templateSettings
       * @type string
       */
      'variable': '',

      /**
       * Used to import variables into the compiled template.
       *
       * @memberOf _.templateSettings
       * @type Object
       */
      'imports': {

        /**
         * A reference to the `lodash` function.
         *
         * @memberOf _.templateSettings.imports
         * @type Function
         */
        '_': lodash
      }
    };

    /*------------------------------------------------------------------------*/

    /**
     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
     *
     * @private
     * @param {*} value The value to wrap.
     */
    function LazyWrapper(value) {
      this.__wrapped__ = value;
      this.__actions__ = [];
      this.__dir__ = 1;
      this.__filtered__ = false;
      this.__iteratees__ = [];
      this.__takeCount__ = POSITIVE_INFINITY;
      this.__views__ = [];
    }

    /**
     * Creates a clone of the lazy wrapper object.
     *
     * @private
     * @name clone
     * @memberOf LazyWrapper
     * @returns {Object} Returns the cloned `LazyWrapper` object.
     */
    function lazyClone() {
      var result = new LazyWrapper(this.__wrapped__);
      result.__actions__ = arrayCopy(this.__actions__);
      result.__dir__ = this.__dir__;
      result.__filtered__ = this.__filtered__;
      result.__iteratees__ = arrayCopy(this.__iteratees__);
      result.__takeCount__ = this.__takeCount__;
      result.__views__ = arrayCopy(this.__views__);
      return result;
    }

    /**
     * Reverses the direction of lazy iteration.
     *
     * @private
     * @name reverse
     * @memberOf LazyWrapper
     * @returns {Object} Returns the new reversed `LazyWrapper` object.
     */
    function lazyReverse() {
      if (this.__filtered__) {
        var result = new LazyWrapper(this);
        result.__dir__ = -1;
        result.__filtered__ = true;
      } else {
        result = this.clone();
        result.__dir__ *= -1;
      }
      return result;
    }

    /**
     * Extracts the unwrapped value from its lazy wrapper.
     *
     * @private
     * @name value
     * @memberOf LazyWrapper
     * @returns {*} Returns the unwrapped value.
     */
    function lazyValue() {
      var array = this.__wrapped__.value(),
          dir = this.__dir__,
          isArr = isArray(array),
          isRight = dir < 0,
          arrLength = isArr ? array.length : 0,
          view = getView(0, arrLength, this.__views__),
          start = view.start,
          end = view.end,
          length = end - start,
          index = isRight ? end : (start - 1),
          iteratees = this.__iteratees__,
          iterLength = iteratees.length,
          resIndex = 0,
          takeCount = nativeMin(length, this.__takeCount__);

      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
        return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);
      }
      var result = [];

      outer:
      while (length-- && resIndex < takeCount) {
        index += dir;

        var iterIndex = -1,
            value = array[index];

        while (++iterIndex < iterLength) {
          var data = iteratees[iterIndex],
              iteratee = data.iteratee,
              type = data.type,
              computed = iteratee(value);

          if (type == LAZY_MAP_FLAG) {
            value = computed;
          } else if (!computed) {
            if (type == LAZY_FILTER_FLAG) {
              continue outer;
            } else {
              break outer;
            }
          }
        }
        result[resIndex++] = value;
      }
      return result;
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a cache object to store key/value pairs.
     *
     * @private
     * @static
     * @name Cache
     * @memberOf _.memoize
     */
    function MapCache() {
      this.__data__ = {};
    }

    /**
     * Removes `key` and its value from the cache.
     *
     * @private
     * @name delete
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.
     */
    function mapDelete(key) {
      return this.has(key) && delete this.__data__[key];
    }

    /**
     * Gets the cached value for `key`.
     *
     * @private
     * @name get
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the cached value.
     */
    function mapGet(key) {
      return key == '__proto__' ? undefined : this.__data__[key];
    }

    /**
     * Checks if a cached value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */
    function mapHas(key) {
      return key != '__proto__' && hasOwnProperty.call(this.__data__, key);
    }

    /**
     * Sets `value` to `key` of the cache.
     *
     * @private
     * @name set
     * @memberOf _.memoize.Cache
     * @param {string} key The key of the value to cache.
     * @param {*} value The value to cache.
     * @returns {Object} Returns the cache object.
     */
    function mapSet(key, value) {
      if (key != '__proto__') {
        this.__data__[key] = value;
      }
      return this;
    }

    /*------------------------------------------------------------------------*/

    /**
     *
     * Creates a cache object to store unique values.
     *
     * @private
     * @param {Array} [values] The values to cache.
     */
    function SetCache(values) {
      var length = values ? values.length : 0;

      this.data = { 'hash': nativeCreate(null), 'set': new Set };
      while (length--) {
        this.push(values[length]);
      }
    }

    /**
     * Checks if `value` is in `cache` mimicking the return signature of
     * `_.indexOf` by returning `0` if the value is found, else `-1`.
     *
     * @private
     * @param {Object} cache The cache to search.
     * @param {*} value The value to search for.
     * @returns {number} Returns `0` if `value` is found, else `-1`.
     */
    function cacheIndexOf(cache, value) {
      var data = cache.data,
          result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];

      return result ? 0 : -1;
    }

    /**
     * Adds `value` to the cache.
     *
     * @private
     * @name push
     * @memberOf SetCache
     * @param {*} value The value to cache.
     */
    function cachePush(value) {
      var data = this.data;
      if (typeof value == 'string' || isObject(value)) {
        data.set.add(value);
      } else {
        data.hash[value] = true;
      }
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a new array joining `array` with `other`.
     *
     * @private
     * @param {Array} array The array to join.
     * @param {Array} other The other array to join.
     * @returns {Array} Returns the new concatenated array.
     */
    function arrayConcat(array, other) {
      var index = -1,
          length = array.length,
          othIndex = -1,
          othLength = other.length,
          result = Array(length + othLength);

      while (++index < length) {
        result[index] = array[index];
      }
      while (++othIndex < othLength) {
        result[index++] = other[othIndex];
      }
      return result;
    }

    /**
     * Copies the values of `source` to `array`.
     *
     * @private
     * @param {Array} source The array to copy values from.
     * @param {Array} [array=[]] The array to copy values to.
     * @returns {Array} Returns `array`.
     */
    function arrayCopy(source, array) {
      var index = -1,
          length = source.length;

      array || (array = Array(length));
      while (++index < length) {
        array[index] = source[index];
      }
      return array;
    }

    /**
     * A specialized version of `_.forEach` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns `array`.
     */
    function arrayEach(array, iteratee) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (iteratee(array[index], index, array) === false) {
          break;
        }
      }
      return array;
    }

    /**
     * A specialized version of `_.forEachRight` for arrays without support for
     * callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns `array`.
     */
    function arrayEachRight(array, iteratee) {
      var length = array.length;

      while (length--) {
        if (iteratee(array[length], length, array) === false) {
          break;
        }
      }
      return array;
    }

    /**
     * A specialized version of `_.every` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`.
     */
    function arrayEvery(array, predicate) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (!predicate(array[index], index, array)) {
          return false;
        }
      }
      return true;
    }

    /**
     * A specialized version of `baseExtremum` for arrays which invokes `iteratee`
     * with one argument: (value).
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {*} Returns the extremum value.
     */
    function arrayExtremum(array, iteratee, comparator, exValue) {
      var index = -1,
          length = array.length,
          computed = exValue,
          result = computed;

      while (++index < length) {
        var value = array[index],
            current = +iteratee(value);

        if (comparator(current, computed)) {
          computed = current;
          result = value;
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.filter` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Array} Returns the new filtered array.
     */
    function arrayFilter(array, predicate) {
      var index = -1,
          length = array.length,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var value = array[index];
        if (predicate(value, index, array)) {
          result[++resIndex] = value;
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.map` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the new mapped array.
     */
    function arrayMap(array, iteratee) {
      var index = -1,
          length = array.length,
          result = Array(length);

      while (++index < length) {
        result[index] = iteratee(array[index], index, array);
      }
      return result;
    }

    /**
     * Appends the elements of `values` to `array`.
     *
     * @private
     * @param {Array} array The array to modify.
     * @param {Array} values The values to append.
     * @returns {Array} Returns `array`.
     */
    function arrayPush(array, values) {
      var index = -1,
          length = values.length,
          offset = array.length;

      while (++index < length) {
        array[offset + index] = values[index];
      }
      return array;
    }

    /**
     * A specialized version of `_.reduce` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {boolean} [initFromArray] Specify using the first element of `array`
     *  as the initial value.
     * @returns {*} Returns the accumulated value.
     */
    function arrayReduce(array, iteratee, accumulator, initFromArray) {
      var index = -1,
          length = array.length;

      if (initFromArray && length) {
        accumulator = array[++index];
      }
      while (++index < length) {
        accumulator = iteratee(accumulator, array[index], index, array);
      }
      return accumulator;
    }

    /**
     * A specialized version of `_.reduceRight` for arrays without support for
     * callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {boolean} [initFromArray] Specify using the last element of `array`
     *  as the initial value.
     * @returns {*} Returns the accumulated value.
     */
    function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
      var length = array.length;
      if (initFromArray && length) {
        accumulator = array[--length];
      }
      while (length--) {
        accumulator = iteratee(accumulator, array[length], length, array);
      }
      return accumulator;
    }

    /**
     * A specialized version of `_.some` for arrays without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     */
    function arraySome(array, predicate) {
      var index = -1,
          length = array.length;

      while (++index < length) {
        if (predicate(array[index], index, array)) {
          return true;
        }
      }
      return false;
    }

    /**
     * A specialized version of `_.sum` for arrays without support for callback
     * shorthands and `this` binding..
     *
     * @private
     * @param {Array} array The array to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {number} Returns the sum.
     */
    function arraySum(array, iteratee) {
      var length = array.length,
          result = 0;

      while (length--) {
        result += +iteratee(array[length]) || 0;
      }
      return result;
    }

    /**
     * Used by `_.defaults` to customize its `_.assign` use.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function assignDefaults(objectValue, sourceValue) {
      return objectValue === undefined ? sourceValue : objectValue;
    }

    /**
     * Used by `_.template` to customize its `_.assign` use.
     *
     * **Note:** This function is like `assignDefaults` except that it ignores
     * inherited property values when checking if a property is `undefined`.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @param {string} key The key associated with the object and source values.
     * @param {Object} object The destination object.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function assignOwnDefaults(objectValue, sourceValue, key, object) {
      return (objectValue === undefined || !hasOwnProperty.call(object, key))
        ? sourceValue
        : objectValue;
    }

    /**
     * A specialized version of `_.assign` for customizing assigned values without
     * support for argument juggling, multiple sources, and `this` binding `customizer`
     * functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {Function} customizer The function to customize assigned values.
     * @returns {Object} Returns `object`.
     */
    function assignWith(object, source, customizer) {
      var index = -1,
          props = keys(source),
          length = props.length;

      while (++index < length) {
        var key = props[index],
            value = object[key],
            result = customizer(value, source[key], key, object, source);

        if ((result === result ? (result !== value) : (value === value)) ||
            (value === undefined && !(key in object))) {
          object[key] = result;
        }
      }
      return object;
    }

    /**
     * The base implementation of `_.assign` without support for argument juggling,
     * multiple sources, and `customizer` functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @returns {Object} Returns `object`.
     */
    function baseAssign(object, source) {
      return source == null
        ? object
        : baseCopy(source, keys(source), object);
    }

    /**
     * The base implementation of `_.at` without support for string collections
     * and individual key arguments.
     *
     * @private
     * @param {Array|Object} collection The collection to iterate over.
     * @param {number[]|string[]} props The property names or indexes of elements to pick.
     * @returns {Array} Returns the new array of picked elements.
     */
    function baseAt(collection, props) {
      var index = -1,
          isNil = collection == null,
          isArr = !isNil && isArrayLike(collection),
          length = isArr ? collection.length : 0,
          propsLength = props.length,
          result = Array(propsLength);

      while(++index < propsLength) {
        var key = props[index];
        if (isArr) {
          result[index] = isIndex(key, length) ? collection[key] : undefined;
        } else {
          result[index] = isNil ? undefined : collection[key];
        }
      }
      return result;
    }

    /**
     * Copies properties of `source` to `object`.
     *
     * @private
     * @param {Object} source The object to copy properties from.
     * @param {Array} props The property names to copy.
     * @param {Object} [object={}] The object to copy properties to.
     * @returns {Object} Returns `object`.
     */
    function baseCopy(source, props, object) {
      object || (object = {});

      var index = -1,
          length = props.length;

      while (++index < length) {
        var key = props[index];
        object[key] = source[key];
      }
      return object;
    }

    /**
     * The base implementation of `_.callback` which supports specifying the
     * number of arguments to provide to `func`.
     *
     * @private
     * @param {*} [func=_.identity] The value to convert to a callback.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {number} [argCount] The number of arguments to provide to `func`.
     * @returns {Function} Returns the callback.
     */
    function baseCallback(func, thisArg, argCount) {
      var type = typeof func;
      if (type == 'function') {
        return thisArg === undefined
          ? func
          : bindCallback(func, thisArg, argCount);
      }
      if (func == null) {
        return identity;
      }
      if (type == 'object') {
        return baseMatches(func);
      }
      return thisArg === undefined
        ? property(func)
        : baseMatchesProperty(func, thisArg);
    }

    /**
     * The base implementation of `_.clone` without support for argument juggling
     * and `this` binding `customizer` functions.
     *
     * @private
     * @param {*} value The value to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {string} [key] The key of `value`.
     * @param {Object} [object] The object `value` belongs to.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates clones with source counterparts.
     * @returns {*} Returns the cloned value.
     */
    function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
      var result;
      if (customizer) {
        result = object ? customizer(value, key, object) : customizer(value);
      }
      if (result !== undefined) {
        return result;
      }
      if (!isObject(value)) {
        return value;
      }
      var isArr = isArray(value);
      if (isArr) {
        result = initCloneArray(value);
        if (!isDeep) {
          return arrayCopy(value, result);
        }
      } else {
        var tag = objToString.call(value),
            isFunc = tag == funcTag;

        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
          result = initCloneObject(isFunc ? {} : value);
          if (!isDeep) {
            return baseAssign(result, value);
          }
        } else {
          return cloneableTags[tag]
            ? initCloneByTag(value, tag, isDeep)
            : (object ? value : {});
        }
      }
      // Check for circular references and return its corresponding clone.
      stackA || (stackA = []);
      stackB || (stackB = []);

      var length = stackA.length;
      while (length--) {
        if (stackA[length] == value) {
          return stackB[length];
        }
      }
      // Add the source value to the stack of traversed objects and associate it with its clone.
      stackA.push(value);
      stackB.push(result);

      // Recursively populate clone (susceptible to call stack limits).
      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
        result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
      });
      return result;
    }

    /**
     * The base implementation of `_.create` without support for assigning
     * properties to the created object.
     *
     * @private
     * @param {Object} prototype The object to inherit from.
     * @returns {Object} Returns the new object.
     */
    var baseCreate = (function() {
      function object() {}
      return function(prototype) {
        if (isObject(prototype)) {
          object.prototype = prototype;
          var result = new object;
          object.prototype = undefined;
        }
        return result || {};
      };
    }());

    /**
     * The base implementation of `_.delay` and `_.defer` which accepts an index
     * of where to slice the arguments to provide to `func`.
     *
     * @private
     * @param {Function} func The function to delay.
     * @param {number} wait The number of milliseconds to delay invocation.
     * @param {Object} args The arguments provide to `func`.
     * @returns {number} Returns the timer id.
     */
    function baseDelay(func, wait, args) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return setTimeout(function() { func.apply(undefined, args); }, wait);
    }

    /**
     * The base implementation of `_.difference` which accepts a single array
     * of values to exclude.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Array} values The values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     */
    function baseDifference(array, values) {
      var length = array ? array.length : 0,
          result = [];

      if (!length) {
        return result;
      }
      var index = -1,
          indexOf = getIndexOf(),
          isCommon = indexOf == baseIndexOf,
          cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
          valuesLength = values.length;

      if (cache) {
        indexOf = cacheIndexOf;
        isCommon = false;
        values = cache;
      }
      outer:
      while (++index < length) {
        var value = array[index];

        if (isCommon && value === value) {
          var valuesIndex = valuesLength;
          while (valuesIndex--) {
            if (values[valuesIndex] === value) {
              continue outer;
            }
          }
          result.push(value);
        }
        else if (indexOf(values, value, 0) < 0) {
          result.push(value);
        }
      }
      return result;
    }

    /**
     * The base implementation of `_.forEach` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array|Object|string} Returns `collection`.
     */
    var baseEach = createBaseEach(baseForOwn);

    /**
     * The base implementation of `_.forEachRight` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array|Object|string} Returns `collection`.
     */
    var baseEachRight = createBaseEach(baseForOwnRight, true);

    /**
     * The base implementation of `_.every` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`
     */
    function baseEvery(collection, predicate) {
      var result = true;
      baseEach(collection, function(value, index, collection) {
        result = !!predicate(value, index, collection);
        return result;
      });
      return result;
    }

    /**
     * Gets the extremum value of `collection` invoking `iteratee` for each value
     * in `collection` to generate the criterion by which the value is ranked.
     * The `iteratee` is invoked with three arguments: (value, index|key, collection).
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {*} Returns the extremum value.
     */
    function baseExtremum(collection, iteratee, comparator, exValue) {
      var computed = exValue,
          result = computed;

      baseEach(collection, function(value, index, collection) {
        var current = +iteratee(value, index, collection);
        if (comparator(current, computed) || (current === exValue && current === result)) {
          computed = current;
          result = value;
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.fill` without an iteratee call guard.
     *
     * @private
     * @param {Array} array The array to fill.
     * @param {*} value The value to fill `array` with.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns `array`.
     */
    function baseFill(array, value, start, end) {
      var length = array.length;

      start = start == null ? 0 : (+start || 0);
      if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
      end = (end === undefined || end > length) ? length : (+end || 0);
      if (end < 0) {
        end += length;
      }
      length = start > end ? 0 : (end >>> 0);
      start >>>= 0;

      while (start < length) {
        array[start++] = value;
      }
      return array;
    }

    /**
     * The base implementation of `_.filter` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Array} Returns the new filtered array.
     */
    function baseFilter(collection, predicate) {
      var result = [];
      baseEach(collection, function(value, index, collection) {
        if (predicate(value, index, collection)) {
          result.push(value);
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
     * without support for callback shorthands and `this` binding, which iterates
     * over `collection` using the provided `eachFunc`.
     *
     * @private
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function} predicate The function invoked per iteration.
     * @param {Function} eachFunc The function to iterate over `collection`.
     * @param {boolean} [retKey] Specify returning the key of the found element
     *  instead of the element itself.
     * @returns {*} Returns the found element or its key, else `undefined`.
     */
    function baseFind(collection, predicate, eachFunc, retKey) {
      var result;
      eachFunc(collection, function(value, key, collection) {
        if (predicate(value, key, collection)) {
          result = retKey ? key : value;
          return false;
        }
      });
      return result;
    }

    /**
     * The base implementation of `_.flatten` with added support for restricting
     * flattening and specifying the start index.
     *
     * @private
     * @param {Array} array The array to flatten.
     * @param {boolean} [isDeep] Specify a deep flatten.
     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
     * @param {Array} [result=[]] The initial result value.
     * @returns {Array} Returns the new flattened array.
     */
    function baseFlatten(array, isDeep, isStrict, result) {
      result || (result = []);

      var index = -1,
          length = array.length;

      while (++index < length) {
        var value = array[index];
        if (isObjectLike(value) && isArrayLike(value) &&
            (isStrict || isArray(value) || isArguments(value))) {
          if (isDeep) {
            // Recursively flatten arrays (susceptible to call stack limits).
            baseFlatten(value, isDeep, isStrict, result);
          } else {
            arrayPush(result, value);
          }
        } else if (!isStrict) {
          result[result.length] = value;
        }
      }
      return result;
    }

    /**
     * The base implementation of `baseForIn` and `baseForOwn` which iterates
     * over `object` properties returned by `keysFunc` invoking `iteratee` for
     * each property. Iteratee functions may exit iteration early by explicitly
     * returning `false`.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} keysFunc The function to get the keys of `object`.
     * @returns {Object} Returns `object`.
     */
    var baseFor = createBaseFor();

    /**
     * This function is like `baseFor` except that it iterates over properties
     * in the opposite order.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {Function} keysFunc The function to get the keys of `object`.
     * @returns {Object} Returns `object`.
     */
    var baseForRight = createBaseFor(true);

    /**
     * The base implementation of `_.forIn` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForIn(object, iteratee) {
      return baseFor(object, iteratee, keysIn);
    }

    /**
     * The base implementation of `_.forOwn` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForOwn(object, iteratee) {
      return baseFor(object, iteratee, keys);
    }

    /**
     * The base implementation of `_.forOwnRight` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Object} Returns `object`.
     */
    function baseForOwnRight(object, iteratee) {
      return baseForRight(object, iteratee, keys);
    }

    /**
     * The base implementation of `_.functions` which creates an array of
     * `object` function property names filtered from those provided.
     *
     * @private
     * @param {Object} object The object to inspect.
     * @param {Array} props The property names to filter.
     * @returns {Array} Returns the new array of filtered property names.
     */
    function baseFunctions(object, props) {
      var index = -1,
          length = props.length,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var key = props[index];
        if (isFunction(object[key])) {
          result[++resIndex] = key;
        }
      }
      return result;
    }

    /**
     * The base implementation of `get` without support for string paths
     * and default values.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array} path The path of the property to get.
     * @param {string} [pathKey] The key representation of path.
     * @returns {*} Returns the resolved value.
     */
    function baseGet(object, path, pathKey) {
      if (object == null) {
        return;
      }
      if (pathKey !== undefined && pathKey in toObject(object)) {
        path = [pathKey];
      }
      var index = 0,
          length = path.length;

      while (object != null && index < length) {
        object = object[path[index++]];
      }
      return (index && index == length) ? object : undefined;
    }

    /**
     * The base implementation of `_.isEqual` without support for `this` binding
     * `customizer` functions.
     *
     * @private
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @param {Function} [customizer] The function to customize comparing values.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     */
    function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
      if (value === other) {
        return true;
      }
      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
        return value !== value && other !== other;
      }
      return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
    }

    /**
     * A specialized version of `baseIsEqual` for arrays and objects which performs
     * deep comparisons and tracks traversed objects enabling objects with circular
     * references to be compared.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing objects.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA=[]] Tracks traversed `value` objects.
     * @param {Array} [stackB=[]] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var objIsArr = isArray(object),
          othIsArr = isArray(other),
          objTag = arrayTag,
          othTag = arrayTag;

      if (!objIsArr) {
        objTag = objToString.call(object);
        if (objTag == argsTag) {
          objTag = objectTag;
        } else if (objTag != objectTag) {
          objIsArr = isTypedArray(object);
        }
      }
      if (!othIsArr) {
        othTag = objToString.call(other);
        if (othTag == argsTag) {
          othTag = objectTag;
        } else if (othTag != objectTag) {
          othIsArr = isTypedArray(other);
        }
      }
      var objIsObj = objTag == objectTag,
          othIsObj = othTag == objectTag,
          isSameTag = objTag == othTag;

      if (isSameTag && !(objIsArr || objIsObj)) {
        return equalByTag(object, other, objTag);
      }
      if (!isLoose) {
        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');

        if (objIsWrapped || othIsWrapped) {
          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
        }
      }
      if (!isSameTag) {
        return false;
      }
      // Assume cyclic values are equal.
      // For more information on detecting circular references see https://es5.github.io/#JO.
      stackA || (stackA = []);
      stackB || (stackB = []);

      var length = stackA.length;
      while (length--) {
        if (stackA[length] == object) {
          return stackB[length] == other;
        }
      }
      // Add `object` and `other` to the stack of traversed objects.
      stackA.push(object);
      stackB.push(other);

      var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);

      stackA.pop();
      stackB.pop();

      return result;
    }

    /**
     * The base implementation of `_.isMatch` without support for callback
     * shorthands and `this` binding.
     *
     * @private
     * @param {Object} object The object to inspect.
     * @param {Array} matchData The propery names, values, and compare flags to match.
     * @param {Function} [customizer] The function to customize comparing objects.
     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
     */
    function baseIsMatch(object, matchData, customizer) {
      var index = matchData.length,
          length = index,
          noCustomizer = !customizer;

      if (object == null) {
        return !length;
      }
      object = toObject(object);
      while (index--) {
        var data = matchData[index];
        if ((noCustomizer && data[2])
              ? data[1] !== object[data[0]]
              : !(data[0] in object)
            ) {
          return false;
        }
      }
      while (++index < length) {
        data = matchData[index];
        var key = data[0],
            objValue = object[key],
            srcValue = data[1];

        if (noCustomizer && data[2]) {
          if (objValue === undefined && !(key in object)) {
            return false;
          }
        } else {
          var result = customizer ? customizer(objValue, srcValue, key) : undefined;
          if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
            return false;
          }
        }
      }
      return true;
    }

    /**
     * The base implementation of `_.map` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {Array} Returns the new mapped array.
     */
    function baseMap(collection, iteratee) {
      var index = -1,
          result = isArrayLike(collection) ? Array(collection.length) : [];

      baseEach(collection, function(value, key, collection) {
        result[++index] = iteratee(value, key, collection);
      });
      return result;
    }

    /**
     * The base implementation of `_.matches` which does not clone `source`.
     *
     * @private
     * @param {Object} source The object of property values to match.
     * @returns {Function} Returns the new function.
     */
    function baseMatches(source) {
      var matchData = getMatchData(source);
      if (matchData.length == 1 && matchData[0][2]) {
        var key = matchData[0][0],
            value = matchData[0][1];

        return function(object) {
          if (object == null) {
            return false;
          }
          return object[key] === value && (value !== undefined || (key in toObject(object)));
        };
      }
      return function(object) {
        return baseIsMatch(object, matchData);
      };
    }

    /**
     * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
     *
     * @private
     * @param {string} path The path of the property to get.
     * @param {*} srcValue The value to compare.
     * @returns {Function} Returns the new function.
     */
    function baseMatchesProperty(path, srcValue) {
      var isArr = isArray(path),
          isCommon = isKey(path) && isStrictComparable(srcValue),
          pathKey = (path + '');

      path = toPath(path);
      return function(object) {
        if (object == null) {
          return false;
        }
        var key = pathKey;
        object = toObject(object);
        if ((isArr || !isCommon) && !(key in object)) {
          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
          if (object == null) {
            return false;
          }
          key = last(path);
          object = toObject(object);
        }
        return object[key] === srcValue
          ? (srcValue !== undefined || (key in object))
          : baseIsEqual(srcValue, object[key], undefined, true);
      };
    }

    /**
     * The base implementation of `_.merge` without support for argument juggling,
     * multiple sources, and `this` binding `customizer` functions.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {Function} [customizer] The function to customize merged values.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates values with source counterparts.
     * @returns {Object} Returns `object`.
     */
    function baseMerge(object, source, customizer, stackA, stackB) {
      if (!isObject(object)) {
        return object;
      }
      var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
          props = isSrcArr ? undefined : keys(source);

      arrayEach(props || source, function(srcValue, key) {
        if (props) {
          key = srcValue;
          srcValue = source[key];
        }
        if (isObjectLike(srcValue)) {
          stackA || (stackA = []);
          stackB || (stackB = []);
          baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
        }
        else {
          var value = object[key],
              result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
              isCommon = result === undefined;

          if (isCommon) {
            result = srcValue;
          }
          if ((result !== undefined || (isSrcArr && !(key in object))) &&
              (isCommon || (result === result ? (result !== value) : (value === value)))) {
            object[key] = result;
          }
        }
      });
      return object;
    }

    /**
     * A specialized version of `baseMerge` for arrays and objects which performs
     * deep merges and tracks traversed objects enabling objects with circular
     * references to be merged.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {string} key The key of the value to merge.
     * @param {Function} mergeFunc The function to merge values.
     * @param {Function} [customizer] The function to customize merged values.
     * @param {Array} [stackA=[]] Tracks traversed source objects.
     * @param {Array} [stackB=[]] Associates values with source counterparts.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
      var length = stackA.length,
          srcValue = source[key];

      while (length--) {
        if (stackA[length] == srcValue) {
          object[key] = stackB[length];
          return;
        }
      }
      var value = object[key],
          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
          isCommon = result === undefined;

      if (isCommon) {
        result = srcValue;
        if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
          result = isArray(value)
            ? value
            : (isArrayLike(value) ? arrayCopy(value) : []);
        }
        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
          result = isArguments(value)
            ? toPlainObject(value)
            : (isPlainObject(value) ? value : {});
        }
        else {
          isCommon = false;
        }
      }
      // Add the source value to the stack of traversed objects and associate
      // it with its merged value.
      stackA.push(srcValue);
      stackB.push(result);

      if (isCommon) {
        // Recursively merge objects and arrays (susceptible to call stack limits).
        object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
      } else if (result === result ? (result !== value) : (value === value)) {
        object[key] = result;
      }
    }

    /**
     * The base implementation of `_.property` without support for deep paths.
     *
     * @private
     * @param {string} key The key of the property to get.
     * @returns {Function} Returns the new function.
     */
    function baseProperty(key) {
      return function(object) {
        return object == null ? undefined : object[key];
      };
    }

    /**
     * A specialized version of `baseProperty` which supports deep paths.
     *
     * @private
     * @param {Array|string} path The path of the property to get.
     * @returns {Function} Returns the new function.
     */
    function basePropertyDeep(path) {
      var pathKey = (path + '');
      path = toPath(path);
      return function(object) {
        return baseGet(object, path, pathKey);
      };
    }

    /**
     * The base implementation of `_.pullAt` without support for individual
     * index arguments and capturing the removed elements.
     *
     * @private
     * @param {Array} array The array to modify.
     * @param {number[]} indexes The indexes of elements to remove.
     * @returns {Array} Returns `array`.
     */
    function basePullAt(array, indexes) {
      var length = array ? indexes.length : 0;
      while (length--) {
        var index = indexes[length];
        if (index != previous && isIndex(index)) {
          var previous = index;
          splice.call(array, index, 1);
        }
      }
      return array;
    }

    /**
     * The base implementation of `_.random` without support for argument juggling
     * and returning floating-point numbers.
     *
     * @private
     * @param {number} min The minimum possible value.
     * @param {number} max The maximum possible value.
     * @returns {number} Returns the random number.
     */
    function baseRandom(min, max) {
      return min + nativeFloor(nativeRandom() * (max - min + 1));
    }

    /**
     * The base implementation of `_.reduce` and `_.reduceRight` without support
     * for callback shorthands and `this` binding, which iterates over `collection`
     * using the provided `eachFunc`.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {*} accumulator The initial value.
     * @param {boolean} initFromCollection Specify using the first or last element
     *  of `collection` as the initial value.
     * @param {Function} eachFunc The function to iterate over `collection`.
     * @returns {*} Returns the accumulated value.
     */
    function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
      eachFunc(collection, function(value, index, collection) {
        accumulator = initFromCollection
          ? (initFromCollection = false, value)
          : iteratee(accumulator, value, index, collection);
      });
      return accumulator;
    }

    /**
     * The base implementation of `setData` without support for hot loop detection.
     *
     * @private
     * @param {Function} func The function to associate metadata with.
     * @param {*} data The metadata.
     * @returns {Function} Returns `func`.
     */
    var baseSetData = !metaMap ? identity : function(func, data) {
      metaMap.set(func, data);
      return func;
    };

    /**
     * The base implementation of `_.slice` without an iteratee call guard.
     *
     * @private
     * @param {Array} array The array to slice.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns the slice of `array`.
     */
    function baseSlice(array, start, end) {
      var index = -1,
          length = array.length;

      start = start == null ? 0 : (+start || 0);
      if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
      end = (end === undefined || end > length) ? length : (+end || 0);
      if (end < 0) {
        end += length;
      }
      length = start > end ? 0 : ((end - start) >>> 0);
      start >>>= 0;

      var result = Array(length);
      while (++index < length) {
        result[index] = array[index + start];
      }
      return result;
    }

    /**
     * The base implementation of `_.some` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     */
    function baseSome(collection, predicate) {
      var result;

      baseEach(collection, function(value, index, collection) {
        result = predicate(value, index, collection);
        return !result;
      });
      return !!result;
    }

    /**
     * The base implementation of `_.sortBy` which uses `comparer` to define
     * the sort order of `array` and replaces criteria objects with their
     * corresponding values.
     *
     * @private
     * @param {Array} array The array to sort.
     * @param {Function} comparer The function to define sort order.
     * @returns {Array} Returns `array`.
     */
    function baseSortBy(array, comparer) {
      var length = array.length;

      array.sort(comparer);
      while (length--) {
        array[length] = array[length].value;
      }
      return array;
    }

    /**
     * The base implementation of `_.sortByOrder` without param guards.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
     * @param {boolean[]} orders The sort orders of `iteratees`.
     * @returns {Array} Returns the new sorted array.
     */
    function baseSortByOrder(collection, iteratees, orders) {
      var callback = getCallback(),
          index = -1;

      iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); });

      var result = baseMap(collection, function(value) {
        var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });
        return { 'criteria': criteria, 'index': ++index, 'value': value };
      });

      return baseSortBy(result, function(object, other) {
        return compareMultiple(object, other, orders);
      });
    }

    /**
     * The base implementation of `_.sum` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} iteratee The function invoked per iteration.
     * @returns {number} Returns the sum.
     */
    function baseSum(collection, iteratee) {
      var result = 0;
      baseEach(collection, function(value, index, collection) {
        result += +iteratee(value, index, collection) || 0;
      });
      return result;
    }

    /**
     * The base implementation of `_.uniq` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} [iteratee] The function invoked per iteration.
     * @returns {Array} Returns the new duplicate-value-free array.
     */
    function baseUniq(array, iteratee) {
      var index = -1,
          indexOf = getIndexOf(),
          length = array.length,
          isCommon = indexOf == baseIndexOf,
          isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
          seen = isLarge ? createCache() : null,
          result = [];

      if (seen) {
        indexOf = cacheIndexOf;
        isCommon = false;
      } else {
        isLarge = false;
        seen = iteratee ? [] : result;
      }
      outer:
      while (++index < length) {
        var value = array[index],
            computed = iteratee ? iteratee(value, index, array) : value;

        if (isCommon && value === value) {
          var seenIndex = seen.length;
          while (seenIndex--) {
            if (seen[seenIndex] === computed) {
              continue outer;
            }
          }
          if (iteratee) {
            seen.push(computed);
          }
          result.push(value);
        }
        else if (indexOf(seen, computed, 0) < 0) {
          if (iteratee || isLarge) {
            seen.push(computed);
          }
          result.push(value);
        }
      }
      return result;
    }

    /**
     * The base implementation of `_.values` and `_.valuesIn` which creates an
     * array of `object` property values corresponding to the property names
     * of `props`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array} props The property names to get values for.
     * @returns {Object} Returns the array of property values.
     */
    function baseValues(object, props) {
      var index = -1,
          length = props.length,
          result = Array(length);

      while (++index < length) {
        result[index] = object[props[index]];
      }
      return result;
    }

    /**
     * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,
     * and `_.takeWhile` without support for callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to query.
     * @param {Function} predicate The function invoked per iteration.
     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Array} Returns the slice of `array`.
     */
    function baseWhile(array, predicate, isDrop, fromRight) {
      var length = array.length,
          index = fromRight ? length : -1;

      while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
      return isDrop
        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
    }

    /**
     * The base implementation of `wrapperValue` which returns the result of
     * performing a sequence of actions on the unwrapped `value`, where each
     * successive action is supplied the return value of the previous.
     *
     * @private
     * @param {*} value The unwrapped value.
     * @param {Array} actions Actions to peform to resolve the unwrapped value.
     * @returns {*} Returns the resolved value.
     */
    function baseWrapperValue(value, actions) {
      var result = value;
      if (result instanceof LazyWrapper) {
        result = result.value();
      }
      var index = -1,
          length = actions.length;

      while (++index < length) {
        var action = actions[index];
        result = action.func.apply(action.thisArg, arrayPush([result], action.args));
      }
      return result;
    }

    /**
     * Performs a binary search of `array` to determine the index at which `value`
     * should be inserted into `array` in order to maintain its sort order.
     *
     * @private
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function binaryIndex(array, value, retHighest) {
      var low = 0,
          high = array ? array.length : low;

      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
        while (low < high) {
          var mid = (low + high) >>> 1,
              computed = array[mid];

          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
            low = mid + 1;
          } else {
            high = mid;
          }
        }
        return high;
      }
      return binaryIndexBy(array, value, identity, retHighest);
    }

    /**
     * This function is like `binaryIndex` except that it invokes `iteratee` for
     * `value` and each element of `array` to compute their sort ranking. The
     * iteratee is invoked with one argument; (value).
     *
     * @private
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function} iteratee The function invoked per iteration.
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function binaryIndexBy(array, value, iteratee, retHighest) {
      value = iteratee(value);

      var low = 0,
          high = array ? array.length : 0,
          valIsNaN = value !== value,
          valIsNull = value === null,
          valIsUndef = value === undefined;

      while (low < high) {
        var mid = nativeFloor((low + high) / 2),
            computed = iteratee(array[mid]),
            isDef = computed !== undefined,
            isReflexive = computed === computed;

        if (valIsNaN) {
          var setLow = isReflexive || retHighest;
        } else if (valIsNull) {
          setLow = isReflexive && isDef && (retHighest || computed != null);
        } else if (valIsUndef) {
          setLow = isReflexive && (retHighest || isDef);
        } else if (computed == null) {
          setLow = false;
        } else {
          setLow = retHighest ? (computed <= value) : (computed < value);
        }
        if (setLow) {
          low = mid + 1;
        } else {
          high = mid;
        }
      }
      return nativeMin(high, MAX_ARRAY_INDEX);
    }

    /**
     * A specialized version of `baseCallback` which only supports `this` binding
     * and specifying the number of arguments to provide to `func`.
     *
     * @private
     * @param {Function} func The function to bind.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {number} [argCount] The number of arguments to provide to `func`.
     * @returns {Function} Returns the callback.
     */
    function bindCallback(func, thisArg, argCount) {
      if (typeof func != 'function') {
        return identity;
      }
      if (thisArg === undefined) {
        return func;
      }
      switch (argCount) {
        case 1: return function(value) {
          return func.call(thisArg, value);
        };
        case 3: return function(value, index, collection) {
          return func.call(thisArg, value, index, collection);
        };
        case 4: return function(accumulator, value, index, collection) {
          return func.call(thisArg, accumulator, value, index, collection);
        };
        case 5: return function(value, other, key, object, source) {
          return func.call(thisArg, value, other, key, object, source);
        };
      }
      return function() {
        return func.apply(thisArg, arguments);
      };
    }

    /**
     * Creates a clone of the given array buffer.
     *
     * @private
     * @param {ArrayBuffer} buffer The array buffer to clone.
     * @returns {ArrayBuffer} Returns the cloned array buffer.
     */
    function bufferClone(buffer) {
      var result = new ArrayBuffer(buffer.byteLength),
          view = new Uint8Array(result);

      view.set(new Uint8Array(buffer));
      return result;
    }

    /**
     * Creates an array that is the composition of partially applied arguments,
     * placeholders, and provided arguments into a single array of arguments.
     *
     * @private
     * @param {Array|Object} args The provided arguments.
     * @param {Array} partials The arguments to prepend to those provided.
     * @param {Array} holders The `partials` placeholder indexes.
     * @returns {Array} Returns the new array of composed arguments.
     */
    function composeArgs(args, partials, holders) {
      var holdersLength = holders.length,
          argsIndex = -1,
          argsLength = nativeMax(args.length - holdersLength, 0),
          leftIndex = -1,
          leftLength = partials.length,
          result = Array(leftLength + argsLength);

      while (++leftIndex < leftLength) {
        result[leftIndex] = partials[leftIndex];
      }
      while (++argsIndex < holdersLength) {
        result[holders[argsIndex]] = args[argsIndex];
      }
      while (argsLength--) {
        result[leftIndex++] = args[argsIndex++];
      }
      return result;
    }

    /**
     * This function is like `composeArgs` except that the arguments composition
     * is tailored for `_.partialRight`.
     *
     * @private
     * @param {Array|Object} args The provided arguments.
     * @param {Array} partials The arguments to append to those provided.
     * @param {Array} holders The `partials` placeholder indexes.
     * @returns {Array} Returns the new array of composed arguments.
     */
    function composeArgsRight(args, partials, holders) {
      var holdersIndex = -1,
          holdersLength = holders.length,
          argsIndex = -1,
          argsLength = nativeMax(args.length - holdersLength, 0),
          rightIndex = -1,
          rightLength = partials.length,
          result = Array(argsLength + rightLength);

      while (++argsIndex < argsLength) {
        result[argsIndex] = args[argsIndex];
      }
      var offset = argsIndex;
      while (++rightIndex < rightLength) {
        result[offset + rightIndex] = partials[rightIndex];
      }
      while (++holdersIndex < holdersLength) {
        result[offset + holders[holdersIndex]] = args[argsIndex++];
      }
      return result;
    }

    /**
     * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
     *
     * @private
     * @param {Function} setter The function to set keys and values of the accumulator object.
     * @param {Function} [initializer] The function to initialize the accumulator object.
     * @returns {Function} Returns the new aggregator function.
     */
    function createAggregator(setter, initializer) {
      return function(collection, iteratee, thisArg) {
        var result = initializer ? initializer() : {};
        iteratee = getCallback(iteratee, thisArg, 3);

        if (isArray(collection)) {
          var index = -1,
              length = collection.length;

          while (++index < length) {
            var value = collection[index];
            setter(result, value, iteratee(value, index, collection), collection);
          }
        } else {
          baseEach(collection, function(value, key, collection) {
            setter(result, value, iteratee(value, key, collection), collection);
          });
        }
        return result;
      };
    }

    /**
     * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
     *
     * @private
     * @param {Function} assigner The function to assign values.
     * @returns {Function} Returns the new assigner function.
     */
    function createAssigner(assigner) {
      return restParam(function(object, sources) {
        var index = -1,
            length = object == null ? 0 : sources.length,
            customizer = length > 2 ? sources[length - 2] : undefined,
            guard = length > 2 ? sources[2] : undefined,
            thisArg = length > 1 ? sources[length - 1] : undefined;

        if (typeof customizer == 'function') {
          customizer = bindCallback(customizer, thisArg, 5);
          length -= 2;
        } else {
          customizer = typeof thisArg == 'function' ? thisArg : undefined;
          length -= (customizer ? 1 : 0);
        }
        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
          customizer = length < 3 ? undefined : customizer;
          length = 1;
        }
        while (++index < length) {
          var source = sources[index];
          if (source) {
            assigner(object, source, customizer);
          }
        }
        return object;
      });
    }

    /**
     * Creates a `baseEach` or `baseEachRight` function.
     *
     * @private
     * @param {Function} eachFunc The function to iterate over a collection.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new base function.
     */
    function createBaseEach(eachFunc, fromRight) {
      return function(collection, iteratee) {
        var length = collection ? getLength(collection) : 0;
        if (!isLength(length)) {
          return eachFunc(collection, iteratee);
        }
        var index = fromRight ? length : -1,
            iterable = toObject(collection);

        while ((fromRight ? index-- : ++index < length)) {
          if (iteratee(iterable[index], index, iterable) === false) {
            break;
          }
        }
        return collection;
      };
    }

    /**
     * Creates a base function for `_.forIn` or `_.forInRight`.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new base function.
     */
    function createBaseFor(fromRight) {
      return function(object, iteratee, keysFunc) {
        var iterable = toObject(object),
            props = keysFunc(object),
            length = props.length,
            index = fromRight ? length : -1;

        while ((fromRight ? index-- : ++index < length)) {
          var key = props[index];
          if (iteratee(iterable[key], key, iterable) === false) {
            break;
          }
        }
        return object;
      };
    }

    /**
     * Creates a function that wraps `func` and invokes it with the `this`
     * binding of `thisArg`.
     *
     * @private
     * @param {Function} func The function to bind.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @returns {Function} Returns the new bound function.
     */
    function createBindWrapper(func, thisArg) {
      var Ctor = createCtorWrapper(func);

      function wrapper() {
        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
        return fn.apply(thisArg, arguments);
      }
      return wrapper;
    }

    /**
     * Creates a `Set` cache object to optimize linear searches of large arrays.
     *
     * @private
     * @param {Array} [values] The values to cache.
     * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
     */
    function createCache(values) {
      return (nativeCreate && Set) ? new SetCache(values) : null;
    }

    /**
     * Creates a function that produces compound words out of the words in a
     * given string.
     *
     * @private
     * @param {Function} callback The function to combine each word.
     * @returns {Function} Returns the new compounder function.
     */
    function createCompounder(callback) {
      return function(string) {
        var index = -1,
            array = words(deburr(string)),
            length = array.length,
            result = '';

        while (++index < length) {
          result = callback(result, array[index], index);
        }
        return result;
      };
    }

    /**
     * Creates a function that produces an instance of `Ctor` regardless of
     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
     *
     * @private
     * @param {Function} Ctor The constructor to wrap.
     * @returns {Function} Returns the new wrapped function.
     */
    function createCtorWrapper(Ctor) {
      return function() {
        // Use a `switch` statement to work with class constructors.
        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
        // for more details.
        var args = arguments;
        switch (args.length) {
          case 0: return new Ctor;
          case 1: return new Ctor(args[0]);
          case 2: return new Ctor(args[0], args[1]);
          case 3: return new Ctor(args[0], args[1], args[2]);
          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
        }
        var thisBinding = baseCreate(Ctor.prototype),
            result = Ctor.apply(thisBinding, args);

        // Mimic the constructor's `return` behavior.
        // See https://es5.github.io/#x13.2.2 for more details.
        return isObject(result) ? result : thisBinding;
      };
    }

    /**
     * Creates a `_.curry` or `_.curryRight` function.
     *
     * @private
     * @param {boolean} flag The curry bit flag.
     * @returns {Function} Returns the new curry function.
     */
    function createCurry(flag) {
      function curryFunc(func, arity, guard) {
        if (guard && isIterateeCall(func, arity, guard)) {
          arity = undefined;
        }
        var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
        result.placeholder = curryFunc.placeholder;
        return result;
      }
      return curryFunc;
    }

    /**
     * Creates a `_.defaults` or `_.defaultsDeep` function.
     *
     * @private
     * @param {Function} assigner The function to assign values.
     * @param {Function} customizer The function to customize assigned values.
     * @returns {Function} Returns the new defaults function.
     */
    function createDefaults(assigner, customizer) {
      return restParam(function(args) {
        var object = args[0];
        if (object == null) {
          return object;
        }
        args.push(customizer);
        return assigner.apply(undefined, args);
      });
    }

    /**
     * Creates a `_.max` or `_.min` function.
     *
     * @private
     * @param {Function} comparator The function used to compare values.
     * @param {*} exValue The initial extremum value.
     * @returns {Function} Returns the new extremum function.
     */
    function createExtremum(comparator, exValue) {
      return function(collection, iteratee, thisArg) {
        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
          iteratee = undefined;
        }
        iteratee = getCallback(iteratee, thisArg, 3);
        if (iteratee.length == 1) {
          collection = isArray(collection) ? collection : toIterable(collection);
          var result = arrayExtremum(collection, iteratee, comparator, exValue);
          if (!(collection.length && result === exValue)) {
            return result;
          }
        }
        return baseExtremum(collection, iteratee, comparator, exValue);
      };
    }

    /**
     * Creates a `_.find` or `_.findLast` function.
     *
     * @private
     * @param {Function} eachFunc The function to iterate over a collection.
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new find function.
     */
    function createFind(eachFunc, fromRight) {
      return function(collection, predicate, thisArg) {
        predicate = getCallback(predicate, thisArg, 3);
        if (isArray(collection)) {
          var index = baseFindIndex(collection, predicate, fromRight);
          return index > -1 ? collection[index] : undefined;
        }
        return baseFind(collection, predicate, eachFunc);
      };
    }

    /**
     * Creates a `_.findIndex` or `_.findLastIndex` function.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new find function.
     */
    function createFindIndex(fromRight) {
      return function(array, predicate, thisArg) {
        if (!(array && array.length)) {
          return -1;
        }
        predicate = getCallback(predicate, thisArg, 3);
        return baseFindIndex(array, predicate, fromRight);
      };
    }

    /**
     * Creates a `_.findKey` or `_.findLastKey` function.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new find function.
     */
    function createFindKey(objectFunc) {
      return function(object, predicate, thisArg) {
        predicate = getCallback(predicate, thisArg, 3);
        return baseFind(object, predicate, objectFunc, true);
      };
    }

    /**
     * Creates a `_.flow` or `_.flowRight` function.
     *
     * @private
     * @param {boolean} [fromRight] Specify iterating from right to left.
     * @returns {Function} Returns the new flow function.
     */
    function createFlow(fromRight) {
      return function() {
        var wrapper,
            length = arguments.length,
            index = fromRight ? length : -1,
            leftIndex = 0,
            funcs = Array(length);

        while ((fromRight ? index-- : ++index < length)) {
          var func = funcs[leftIndex++] = arguments[index];
          if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
          }
          if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
            wrapper = new LodashWrapper([], true);
          }
        }
        index = wrapper ? -1 : length;
        while (++index < length) {
          func = funcs[index];

          var funcName = getFuncName(func),
              data = funcName == 'wrapper' ? getData(func) : undefined;

          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
          } else {
            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
          }
        }
        return function() {
          var args = arguments,
              value = args[0];

          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
            return wrapper.plant(value).value();
          }
          var index = 0,
              result = length ? funcs[index].apply(this, args) : value;

          while (++index < length) {
            result = funcs[index].call(this, result);
          }
          return result;
        };
      };
    }

    /**
     * Creates a function for `_.forEach` or `_.forEachRight`.
     *
     * @private
     * @param {Function} arrayFunc The function to iterate over an array.
     * @param {Function} eachFunc The function to iterate over a collection.
     * @returns {Function} Returns the new each function.
     */
    function createForEach(arrayFunc, eachFunc) {
      return function(collection, iteratee, thisArg) {
        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
          ? arrayFunc(collection, iteratee)
          : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
      };
    }

    /**
     * Creates a function for `_.forIn` or `_.forInRight`.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new each function.
     */
    function createForIn(objectFunc) {
      return function(object, iteratee, thisArg) {
        if (typeof iteratee != 'function' || thisArg !== undefined) {
          iteratee = bindCallback(iteratee, thisArg, 3);
        }
        return objectFunc(object, iteratee, keysIn);
      };
    }

    /**
     * Creates a function for `_.forOwn` or `_.forOwnRight`.
     *
     * @private
     * @param {Function} objectFunc The function to iterate over an object.
     * @returns {Function} Returns the new each function.
     */
    function createForOwn(objectFunc) {
      return function(object, iteratee, thisArg) {
        if (typeof iteratee != 'function' || thisArg !== undefined) {
          iteratee = bindCallback(iteratee, thisArg, 3);
        }
        return objectFunc(object, iteratee);
      };
    }

    /**
     * Creates a function for `_.mapKeys` or `_.mapValues`.
     *
     * @private
     * @param {boolean} [isMapKeys] Specify mapping keys instead of values.
     * @returns {Function} Returns the new map function.
     */
    function createObjectMapper(isMapKeys) {
      return function(object, iteratee, thisArg) {
        var result = {};
        iteratee = getCallback(iteratee, thisArg, 3);

        baseForOwn(object, function(value, key, object) {
          var mapped = iteratee(value, key, object);
          key = isMapKeys ? mapped : key;
          value = isMapKeys ? value : mapped;
          result[key] = value;
        });
        return result;
      };
    }

    /**
     * Creates a function for `_.padLeft` or `_.padRight`.
     *
     * @private
     * @param {boolean} [fromRight] Specify padding from the right.
     * @returns {Function} Returns the new pad function.
     */
    function createPadDir(fromRight) {
      return function(string, length, chars) {
        string = baseToString(string);
        return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
      };
    }

    /**
     * Creates a `_.partial` or `_.partialRight` function.
     *
     * @private
     * @param {boolean} flag The partial bit flag.
     * @returns {Function} Returns the new partial function.
     */
    function createPartial(flag) {
      var partialFunc = restParam(function(func, partials) {
        var holders = replaceHolders(partials, partialFunc.placeholder);
        return createWrapper(func, flag, undefined, partials, holders);
      });
      return partialFunc;
    }

    /**
     * Creates a function for `_.reduce` or `_.reduceRight`.
     *
     * @private
     * @param {Function} arrayFunc The function to iterate over an array.
     * @param {Function} eachFunc The function to iterate over a collection.
     * @returns {Function} Returns the new each function.
     */
    function createReduce(arrayFunc, eachFunc) {
      return function(collection, iteratee, accumulator, thisArg) {
        var initFromArray = arguments.length < 3;
        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
          ? arrayFunc(collection, iteratee, accumulator, initFromArray)
          : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
      };
    }

    /**
     * Creates a function that wraps `func` and invokes it with optional `this`
     * binding of, partial application, and currying.
     *
     * @private
     * @param {Function|string} func The function or method name to reference.
     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
     * @param {Array} [holders] The `partials` placeholder indexes.
     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
     * @param {Array} [argPos] The argument positions of the new function.
     * @param {number} [ary] The arity cap of `func`.
     * @param {number} [arity] The arity of `func`.
     * @returns {Function} Returns the new wrapped function.
     */
    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
      var isAry = bitmask & ARY_FLAG,
          isBind = bitmask & BIND_FLAG,
          isBindKey = bitmask & BIND_KEY_FLAG,
          isCurry = bitmask & CURRY_FLAG,
          isCurryBound = bitmask & CURRY_BOUND_FLAG,
          isCurryRight = bitmask & CURRY_RIGHT_FLAG,
          Ctor = isBindKey ? undefined : createCtorWrapper(func);

      function wrapper() {
        // Avoid `arguments` object use disqualifying optimizations by
        // converting it to an array before providing it to other functions.
        var length = arguments.length,
            index = length,
            args = Array(length);

        while (index--) {
          args[index] = arguments[index];
        }
        if (partials) {
          args = composeArgs(args, partials, holders);
        }
        if (partialsRight) {
          args = composeArgsRight(args, partialsRight, holdersRight);
        }
        if (isCurry || isCurryRight) {
          var placeholder = wrapper.placeholder,
              argsHolders = replaceHolders(args, placeholder);

          length -= argsHolders.length;
          if (length < arity) {
            var newArgPos = argPos ? arrayCopy(argPos) : undefined,
                newArity = nativeMax(arity - length, 0),
                newsHolders = isCurry ? argsHolders : undefined,
                newHoldersRight = isCurry ? undefined : argsHolders,
                newPartials = isCurry ? args : undefined,
                newPartialsRight = isCurry ? undefined : args;

            bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
            bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);

            if (!isCurryBound) {
              bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
            }
            var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
                result = createHybridWrapper.apply(undefined, newData);

            if (isLaziable(func)) {
              setData(result, newData);
            }
            result.placeholder = placeholder;
            return result;
          }
        }
        var thisBinding = isBind ? thisArg : this,
            fn = isBindKey ? thisBinding[func] : func;

        if (argPos) {
          args = reorder(args, argPos);
        }
        if (isAry && ary < args.length) {
          args.length = ary;
        }
        if (this && this !== root && this instanceof wrapper) {
          fn = Ctor || createCtorWrapper(func);
        }
        return fn.apply(thisBinding, args);
      }
      return wrapper;
    }

    /**
     * Creates the padding required for `string` based on the given `length`.
     * The `chars` string is truncated if the number of characters exceeds `length`.
     *
     * @private
     * @param {string} string The string to create padding for.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the pad for `string`.
     */
    function createPadding(string, length, chars) {
      var strLength = string.length;
      length = +length;

      if (strLength >= length || !nativeIsFinite(length)) {
        return '';
      }
      var padLength = length - strLength;
      chars = chars == null ? ' ' : (chars + '');
      return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
    }

    /**
     * Creates a function that wraps `func` and invokes it with the optional `this`
     * binding of `thisArg` and the `partials` prepended to those provided to
     * the wrapper.
     *
     * @private
     * @param {Function} func The function to partially apply arguments to.
     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {Array} partials The arguments to prepend to those provided to the new function.
     * @returns {Function} Returns the new bound function.
     */
    function createPartialWrapper(func, bitmask, thisArg, partials) {
      var isBind = bitmask & BIND_FLAG,
          Ctor = createCtorWrapper(func);

      function wrapper() {
        // Avoid `arguments` object use disqualifying optimizations by
        // converting it to an array before providing it `func`.
        var argsIndex = -1,
            argsLength = arguments.length,
            leftIndex = -1,
            leftLength = partials.length,
            args = Array(leftLength + argsLength);

        while (++leftIndex < leftLength) {
          args[leftIndex] = partials[leftIndex];
        }
        while (argsLength--) {
          args[leftIndex++] = arguments[++argsIndex];
        }
        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
        return fn.apply(isBind ? thisArg : this, args);
      }
      return wrapper;
    }

    /**
     * Creates a `_.ceil`, `_.floor`, or `_.round` function.
     *
     * @private
     * @param {string} methodName The name of the `Math` method to use when rounding.
     * @returns {Function} Returns the new round function.
     */
    function createRound(methodName) {
      var func = Math[methodName];
      return function(number, precision) {
        precision = precision === undefined ? 0 : (+precision || 0);
        if (precision) {
          precision = pow(10, precision);
          return func(number * precision) / precision;
        }
        return func(number);
      };
    }

    /**
     * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
     *
     * @private
     * @param {boolean} [retHighest] Specify returning the highest qualified index.
     * @returns {Function} Returns the new index function.
     */
    function createSortedIndex(retHighest) {
      return function(array, value, iteratee, thisArg) {
        var callback = getCallback(iteratee);
        return (iteratee == null && callback === baseCallback)
          ? binaryIndex(array, value, retHighest)
          : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);
      };
    }

    /**
     * Creates a function that either curries or invokes `func` with optional
     * `this` binding and partially applied arguments.
     *
     * @private
     * @param {Function|string} func The function or method name to reference.
     * @param {number} bitmask The bitmask of flags.
     *  The bitmask may be composed of the following flags:
     *     1 - `_.bind`
     *     2 - `_.bindKey`
     *     4 - `_.curry` or `_.curryRight` of a bound function
     *     8 - `_.curry`
     *    16 - `_.curryRight`
     *    32 - `_.partial`
     *    64 - `_.partialRight`
     *   128 - `_.rearg`
     *   256 - `_.ary`
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param {Array} [partials] The arguments to be partially applied.
     * @param {Array} [holders] The `partials` placeholder indexes.
     * @param {Array} [argPos] The argument positions of the new function.
     * @param {number} [ary] The arity cap of `func`.
     * @param {number} [arity] The arity of `func`.
     * @returns {Function} Returns the new wrapped function.
     */
    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
      var isBindKey = bitmask & BIND_KEY_FLAG;
      if (!isBindKey && typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var length = partials ? partials.length : 0;
      if (!length) {
        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
        partials = holders = undefined;
      }
      length -= (holders ? holders.length : 0);
      if (bitmask & PARTIAL_RIGHT_FLAG) {
        var partialsRight = partials,
            holdersRight = holders;

        partials = holders = undefined;
      }
      var data = isBindKey ? undefined : getData(func),
          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];

      if (data) {
        mergeData(newData, data);
        bitmask = newData[1];
        arity = newData[9];
      }
      newData[9] = arity == null
        ? (isBindKey ? 0 : func.length)
        : (nativeMax(arity - length, 0) || 0);

      if (bitmask == BIND_FLAG) {
        var result = createBindWrapper(newData[0], newData[2]);
      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
        result = createPartialWrapper.apply(undefined, newData);
      } else {
        result = createHybridWrapper.apply(undefined, newData);
      }
      var setter = data ? baseSetData : setData;
      return setter(result, newData);
    }

    /**
     * A specialized version of `baseIsEqualDeep` for arrays with support for
     * partial deep comparisons.
     *
     * @private
     * @param {Array} array The array to compare.
     * @param {Array} other The other array to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing arrays.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
     */
    function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var index = -1,
          arrLength = array.length,
          othLength = other.length;

      if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
        return false;
      }
      // Ignore non-index properties.
      while (++index < arrLength) {
        var arrValue = array[index],
            othValue = other[index],
            result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;

        if (result !== undefined) {
          if (result) {
            continue;
          }
          return false;
        }
        // Recursively compare arrays (susceptible to call stack limits).
        if (isLoose) {
          if (!arraySome(other, function(othValue) {
                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
              })) {
            return false;
          }
        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
          return false;
        }
      }
      return true;
    }

    /**
     * A specialized version of `baseIsEqualDeep` for comparing objects of
     * the same `toStringTag`.
     *
     * **Note:** This function only supports comparing values with tags of
     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {string} tag The `toStringTag` of the objects to compare.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function equalByTag(object, other, tag) {
      switch (tag) {
        case boolTag:
        case dateTag:
          // Coerce dates and booleans to numbers, dates to milliseconds and booleans
          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
          return +object == +other;

        case errorTag:
          return object.name == other.name && object.message == other.message;

        case numberTag:
          // Treat `NaN` vs. `NaN` as equal.
          return (object != +object)
            ? other != +other
            : object == +other;

        case regexpTag:
        case stringTag:
          // Coerce regexes to strings and treat strings primitives and string
          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
          return object == (other + '');
      }
      return false;
    }

    /**
     * A specialized version of `baseIsEqualDeep` for objects with support for
     * partial deep comparisons.
     *
     * @private
     * @param {Object} object The object to compare.
     * @param {Object} other The other object to compare.
     * @param {Function} equalFunc The function to determine equivalents of values.
     * @param {Function} [customizer] The function to customize comparing values.
     * @param {boolean} [isLoose] Specify performing partial comparisons.
     * @param {Array} [stackA] Tracks traversed `value` objects.
     * @param {Array} [stackB] Tracks traversed `other` objects.
     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
     */
    function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
      var objProps = keys(object),
          objLength = objProps.length,
          othProps = keys(other),
          othLength = othProps.length;

      if (objLength != othLength && !isLoose) {
        return false;
      }
      var index = objLength;
      while (index--) {
        var key = objProps[index];
        if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
          return false;
        }
      }
      var skipCtor = isLoose;
      while (++index < objLength) {
        key = objProps[index];
        var objValue = object[key],
            othValue = other[key],
            result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;

        // Recursively compare objects (susceptible to call stack limits).
        if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
          return false;
        }
        skipCtor || (skipCtor = key == 'constructor');
      }
      if (!skipCtor) {
        var objCtor = object.constructor,
            othCtor = other.constructor;

        // Non `Object` object instances with different constructors are not equal.
        if (objCtor != othCtor &&
            ('constructor' in object && 'constructor' in other) &&
            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
          return false;
        }
      }
      return true;
    }

    /**
     * Gets the appropriate "callback" function. If the `_.callback` method is
     * customized this function returns the custom method, otherwise it returns
     * the `baseCallback` function. If arguments are provided the chosen function
     * is invoked with them and its result is returned.
     *
     * @private
     * @returns {Function} Returns the chosen function or its result.
     */
    function getCallback(func, thisArg, argCount) {
      var result = lodash.callback || callback;
      result = result === callback ? baseCallback : result;
      return argCount ? result(func, thisArg, argCount) : result;
    }

    /**
     * Gets metadata for `func`.
     *
     * @private
     * @param {Function} func The function to query.
     * @returns {*} Returns the metadata for `func`.
     */
    var getData = !metaMap ? noop : function(func) {
      return metaMap.get(func);
    };

    /**
     * Gets the name of `func`.
     *
     * @private
     * @param {Function} func The function to query.
     * @returns {string} Returns the function name.
     */
    function getFuncName(func) {
      var result = func.name,
          array = realNames[result],
          length = array ? array.length : 0;

      while (length--) {
        var data = array[length],
            otherFunc = data.func;
        if (otherFunc == null || otherFunc == func) {
          return data.name;
        }
      }
      return result;
    }

    /**
     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
     * customized this function returns the custom method, otherwise it returns
     * the `baseIndexOf` function. If arguments are provided the chosen function
     * is invoked with them and its result is returned.
     *
     * @private
     * @returns {Function|number} Returns the chosen function or its result.
     */
    function getIndexOf(collection, target, fromIndex) {
      var result = lodash.indexOf || indexOf;
      result = result === indexOf ? baseIndexOf : result;
      return collection ? result(collection, target, fromIndex) : result;
    }

    /**
     * Gets the "length" property value of `object`.
     *
     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
     * that affects Safari on at least iOS 8.1-8.3 ARM64.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {*} Returns the "length" value.
     */
    var getLength = baseProperty('length');

    /**
     * Gets the propery names, values, and compare flags of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {Array} Returns the match data of `object`.
     */
    function getMatchData(object) {
      var result = pairs(object),
          length = result.length;

      while (length--) {
        result[length][2] = isStrictComparable(result[length][1]);
      }
      return result;
    }

    /**
     * Gets the native function at `key` of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {string} key The key of the method to get.
     * @returns {*} Returns the function if it's native, else `undefined`.
     */
    function getNative(object, key) {
      var value = object == null ? undefined : object[key];
      return isNative(value) ? value : undefined;
    }

    /**
     * Gets the view, applying any `transforms` to the `start` and `end` positions.
     *
     * @private
     * @param {number} start The start of the view.
     * @param {number} end The end of the view.
     * @param {Array} transforms The transformations to apply to the view.
     * @returns {Object} Returns an object containing the `start` and `end`
     *  positions of the view.
     */
    function getView(start, end, transforms) {
      var index = -1,
          length = transforms.length;

      while (++index < length) {
        var data = transforms[index],
            size = data.size;

        switch (data.type) {
          case 'drop':      start += size; break;
          case 'dropRight': end -= size; break;
          case 'take':      end = nativeMin(end, start + size); break;
          case 'takeRight': start = nativeMax(start, end - size); break;
        }
      }
      return { 'start': start, 'end': end };
    }

    /**
     * Initializes an array clone.
     *
     * @private
     * @param {Array} array The array to clone.
     * @returns {Array} Returns the initialized clone.
     */
    function initCloneArray(array) {
      var length = array.length,
          result = new array.constructor(length);

      // Add array properties assigned by `RegExp#exec`.
      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
        result.index = array.index;
        result.input = array.input;
      }
      return result;
    }

    /**
     * Initializes an object clone.
     *
     * @private
     * @param {Object} object The object to clone.
     * @returns {Object} Returns the initialized clone.
     */
    function initCloneObject(object) {
      var Ctor = object.constructor;
      if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
        Ctor = Object;
      }
      return new Ctor;
    }

    /**
     * Initializes an object clone based on its `toStringTag`.
     *
     * **Note:** This function only supports cloning values with tags of
     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
     *
     * @private
     * @param {Object} object The object to clone.
     * @param {string} tag The `toStringTag` of the object to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @returns {Object} Returns the initialized clone.
     */
    function initCloneByTag(object, tag, isDeep) {
      var Ctor = object.constructor;
      switch (tag) {
        case arrayBufferTag:
          return bufferClone(object);

        case boolTag:
        case dateTag:
          return new Ctor(+object);

        case float32Tag: case float64Tag:
        case int8Tag: case int16Tag: case int32Tag:
        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
          var buffer = object.buffer;
          return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);

        case numberTag:
        case stringTag:
          return new Ctor(object);

        case regexpTag:
          var result = new Ctor(object.source, reFlags.exec(object));
          result.lastIndex = object.lastIndex;
      }
      return result;
    }

    /**
     * Invokes the method at `path` on `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the method to invoke.
     * @param {Array} args The arguments to invoke the method with.
     * @returns {*} Returns the result of the invoked method.
     */
    function invokePath(object, path, args) {
      if (object != null && !isKey(path, object)) {
        path = toPath(path);
        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
        path = last(path);
      }
      var func = object == null ? object : object[path];
      return func == null ? undefined : func.apply(object, args);
    }

    /**
     * Checks if `value` is array-like.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
     */
    function isArrayLike(value) {
      return value != null && isLength(getLength(value));
    }

    /**
     * Checks if `value` is a valid array-like index.
     *
     * @private
     * @param {*} value The value to check.
     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
     */
    function isIndex(value, length) {
      value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
      length = length == null ? MAX_SAFE_INTEGER : length;
      return value > -1 && value % 1 == 0 && value < length;
    }

    /**
     * Checks if the provided arguments are from an iteratee call.
     *
     * @private
     * @param {*} value The potential iteratee value argument.
     * @param {*} index The potential iteratee index or key argument.
     * @param {*} object The potential iteratee object argument.
     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
     */
    function isIterateeCall(value, index, object) {
      if (!isObject(object)) {
        return false;
      }
      var type = typeof index;
      if (type == 'number'
          ? (isArrayLike(object) && isIndex(index, object.length))
          : (type == 'string' && index in object)) {
        var other = object[index];
        return value === value ? (value === other) : (other !== other);
      }
      return false;
    }

    /**
     * Checks if `value` is a property name and not a property path.
     *
     * @private
     * @param {*} value The value to check.
     * @param {Object} [object] The object to query keys on.
     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
     */
    function isKey(value, object) {
      var type = typeof value;
      if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
        return true;
      }
      if (isArray(value)) {
        return false;
      }
      var result = !reIsDeepProp.test(value);
      return result || (object != null && value in toObject(object));
    }

    /**
     * Checks if `func` has a lazy counterpart.
     *
     * @private
     * @param {Function} func The function to check.
     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
     */
    function isLaziable(func) {
      var funcName = getFuncName(func);
      if (!(funcName in LazyWrapper.prototype)) {
        return false;
      }
      var other = lodash[funcName];
      if (func === other) {
        return true;
      }
      var data = getData(other);
      return !!data && func === data[0];
    }

    /**
     * Checks if `value` is a valid array-like length.
     *
     * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
     */
    function isLength(value) {
      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
    }

    /**
     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` if suitable for strict
     *  equality comparisons, else `false`.
     */
    function isStrictComparable(value) {
      return value === value && !isObject(value);
    }

    /**
     * Merges the function metadata of `source` into `data`.
     *
     * Merging metadata reduces the number of wrappers required to invoke a function.
     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
     * augment function arguments, making the order in which they are executed important,
     * preventing the merging of metadata. However, we make an exception for a safe
     * common case where curried functions have `_.ary` and or `_.rearg` applied.
     *
     * @private
     * @param {Array} data The destination metadata.
     * @param {Array} source The source metadata.
     * @returns {Array} Returns `data`.
     */
    function mergeData(data, source) {
      var bitmask = data[1],
          srcBitmask = source[1],
          newBitmask = bitmask | srcBitmask,
          isCommon = newBitmask < ARY_FLAG;

      var isCombo =
        (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
        (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
        (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);

      // Exit early if metadata can't be merged.
      if (!(isCommon || isCombo)) {
        return data;
      }
      // Use source `thisArg` if available.
      if (srcBitmask & BIND_FLAG) {
        data[2] = source[2];
        // Set when currying a bound function.
        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
      }
      // Compose partial arguments.
      var value = source[3];
      if (value) {
        var partials = data[3];
        data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
      }
      // Compose partial right arguments.
      value = source[5];
      if (value) {
        partials = data[5];
        data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
      }
      // Use source `argPos` if available.
      value = source[7];
      if (value) {
        data[7] = arrayCopy(value);
      }
      // Use source `ary` if it's smaller.
      if (srcBitmask & ARY_FLAG) {
        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
      }
      // Use source `arity` if one is not provided.
      if (data[9] == null) {
        data[9] = source[9];
      }
      // Use source `func` and merge bitmasks.
      data[0] = source[0];
      data[1] = newBitmask;

      return data;
    }

    /**
     * Used by `_.defaultsDeep` to customize its `_.merge` use.
     *
     * @private
     * @param {*} objectValue The destination object property value.
     * @param {*} sourceValue The source object property value.
     * @returns {*} Returns the value to assign to the destination object.
     */
    function mergeDefaults(objectValue, sourceValue) {
      return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
    }

    /**
     * A specialized version of `_.pick` which picks `object` properties specified
     * by `props`.
     *
     * @private
     * @param {Object} object The source object.
     * @param {string[]} props The property names to pick.
     * @returns {Object} Returns the new object.
     */
    function pickByArray(object, props) {
      object = toObject(object);

      var index = -1,
          length = props.length,
          result = {};

      while (++index < length) {
        var key = props[index];
        if (key in object) {
          result[key] = object[key];
        }
      }
      return result;
    }

    /**
     * A specialized version of `_.pick` which picks `object` properties `predicate`
     * returns truthy for.
     *
     * @private
     * @param {Object} object The source object.
     * @param {Function} predicate The function invoked per iteration.
     * @returns {Object} Returns the new object.
     */
    function pickByCallback(object, predicate) {
      var result = {};
      baseForIn(object, function(value, key, object) {
        if (predicate(value, key, object)) {
          result[key] = value;
        }
      });
      return result;
    }

    /**
     * Reorder `array` according to the specified indexes where the element at
     * the first index is assigned as the first element, the element at
     * the second index is assigned as the second element, and so on.
     *
     * @private
     * @param {Array} array The array to reorder.
     * @param {Array} indexes The arranged array indexes.
     * @returns {Array} Returns `array`.
     */
    function reorder(array, indexes) {
      var arrLength = array.length,
          length = nativeMin(indexes.length, arrLength),
          oldArray = arrayCopy(array);

      while (length--) {
        var index = indexes[length];
        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
      }
      return array;
    }

    /**
     * Sets metadata for `func`.
     *
     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
     * period of time, it will trip its breaker and transition to an identity function
     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
     * for more details.
     *
     * @private
     * @param {Function} func The function to associate metadata with.
     * @param {*} data The metadata.
     * @returns {Function} Returns `func`.
     */
    var setData = (function() {
      var count = 0,
          lastCalled = 0;

      return function(key, value) {
        var stamp = now(),
            remaining = HOT_SPAN - (stamp - lastCalled);

        lastCalled = stamp;
        if (remaining > 0) {
          if (++count >= HOT_COUNT) {
            return key;
          }
        } else {
          count = 0;
        }
        return baseSetData(key, value);
      };
    }());

    /**
     * A fallback implementation of `Object.keys` which creates an array of the
     * own enumerable property names of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     */
    function shimKeys(object) {
      var props = keysIn(object),
          propsLength = props.length,
          length = propsLength && object.length;

      var allowIndexes = !!length && isLength(length) &&
        (isArray(object) || isArguments(object));

      var index = -1,
          result = [];

      while (++index < propsLength) {
        var key = props[index];
        if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
          result.push(key);
        }
      }
      return result;
    }

    /**
     * Converts `value` to an array-like object if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Array|Object} Returns the array-like object.
     */
    function toIterable(value) {
      if (value == null) {
        return [];
      }
      if (!isArrayLike(value)) {
        return values(value);
      }
      return isObject(value) ? value : Object(value);
    }

    /**
     * Converts `value` to an object if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Object} Returns the object.
     */
    function toObject(value) {
      return isObject(value) ? value : Object(value);
    }

    /**
     * Converts `value` to property path array if it's not one.
     *
     * @private
     * @param {*} value The value to process.
     * @returns {Array} Returns the property path array.
     */
    function toPath(value) {
      if (isArray(value)) {
        return value;
      }
      var result = [];
      baseToString(value).replace(rePropName, function(match, number, quote, string) {
        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
      });
      return result;
    }

    /**
     * Creates a clone of `wrapper`.
     *
     * @private
     * @param {Object} wrapper The wrapper to clone.
     * @returns {Object} Returns the cloned wrapper.
     */
    function wrapperClone(wrapper) {
      return wrapper instanceof LazyWrapper
        ? wrapper.clone()
        : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates an array of elements split into groups the length of `size`.
     * If `collection` can't be split evenly, the final chunk will be the remaining
     * elements.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to process.
     * @param {number} [size=1] The length of each chunk.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the new array containing chunks.
     * @example
     *
     * _.chunk(['a', 'b', 'c', 'd'], 2);
     * // => [['a', 'b'], ['c', 'd']]
     *
     * _.chunk(['a', 'b', 'c', 'd'], 3);
     * // => [['a', 'b', 'c'], ['d']]
     */
    function chunk(array, size, guard) {
      if (guard ? isIterateeCall(array, size, guard) : size == null) {
        size = 1;
      } else {
        size = nativeMax(nativeFloor(size) || 1, 1);
      }
      var index = 0,
          length = array ? array.length : 0,
          resIndex = -1,
          result = Array(nativeCeil(length / size));

      while (index < length) {
        result[++resIndex] = baseSlice(array, index, (index += size));
      }
      return result;
    }

    /**
     * Creates an array with all falsey values removed. The values `false`, `null`,
     * `0`, `""`, `undefined`, and `NaN` are falsey.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to compact.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.compact([0, 1, false, 2, '', 3]);
     * // => [1, 2, 3]
     */
    function compact(array) {
      var index = -1,
          length = array ? array.length : 0,
          resIndex = -1,
          result = [];

      while (++index < length) {
        var value = array[index];
        if (value) {
          result[++resIndex] = value;
        }
      }
      return result;
    }

    /**
     * Creates an array of unique `array` values not included in the other
     * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to inspect.
     * @param {...Array} [values] The arrays of values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.difference([1, 2, 3], [4, 2]);
     * // => [1, 3]
     */
    var difference = restParam(function(array, values) {
      return (isObjectLike(array) && isArrayLike(array))
        ? baseDifference(array, baseFlatten(values, false, true))
        : [];
    });

    /**
     * Creates a slice of `array` with `n` elements dropped from the beginning.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to drop.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.drop([1, 2, 3]);
     * // => [2, 3]
     *
     * _.drop([1, 2, 3], 2);
     * // => [3]
     *
     * _.drop([1, 2, 3], 5);
     * // => []
     *
     * _.drop([1, 2, 3], 0);
     * // => [1, 2, 3]
     */
    function drop(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      return baseSlice(array, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with `n` elements dropped from the end.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to drop.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropRight([1, 2, 3]);
     * // => [1, 2]
     *
     * _.dropRight([1, 2, 3], 2);
     * // => [1]
     *
     * _.dropRight([1, 2, 3], 5);
     * // => []
     *
     * _.dropRight([1, 2, 3], 0);
     * // => [1, 2, 3]
     */
    function dropRight(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      n = length - (+n || 0);
      return baseSlice(array, 0, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` excluding elements dropped from the end.
     * Elements are dropped until `predicate` returns falsey. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that match the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropRightWhile([1, 2, 3], function(n) {
     *   return n > 1;
     * });
     * // => [1]
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
     * // => ['barney', 'fred']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.dropRightWhile(users, 'active', false), 'user');
     * // => ['barney']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.dropRightWhile(users, 'active'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function dropRightWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)
        : [];
    }

    /**
     * Creates a slice of `array` excluding elements dropped from the beginning.
     * Elements are dropped until `predicate` returns falsey. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.dropWhile([1, 2, 3], function(n) {
     *   return n < 3;
     * });
     * // => [3]
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');
     * // => ['fred', 'pebbles']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.dropWhile(users, 'active', false), 'user');
     * // => ['pebbles']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.dropWhile(users, 'active'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function dropWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), true)
        : [];
    }

    /**
     * Fills elements of `array` with `value` from `start` up to, but not
     * including, `end`.
     *
     * **Note:** This method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to fill.
     * @param {*} value The value to fill `array` with.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns `array`.
     * @example
     *
     * var array = [1, 2, 3];
     *
     * _.fill(array, 'a');
     * console.log(array);
     * // => ['a', 'a', 'a']
     *
     * _.fill(Array(3), 2);
     * // => [2, 2, 2]
     *
     * _.fill([4, 6, 8], '*', 1, 2);
     * // => [4, '*', 8]
     */
    function fill(array, value, start, end) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
        start = 0;
        end = length;
      }
      return baseFill(array, value, start, end);
    }

    /**
     * This method is like `_.find` except that it returns the index of the first
     * element `predicate` returns truthy for instead of the element itself.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {number} Returns the index of the found element, else `-1`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * _.findIndex(users, function(chr) {
     *   return chr.user == 'barney';
     * });
     * // => 0
     *
     * // using the `_.matches` callback shorthand
     * _.findIndex(users, { 'user': 'fred', 'active': false });
     * // => 1
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findIndex(users, 'active', false);
     * // => 0
     *
     * // using the `_.property` callback shorthand
     * _.findIndex(users, 'active');
     * // => 2
     */
    var findIndex = createFindIndex();

    /**
     * This method is like `_.findIndex` except that it iterates over elements
     * of `collection` from right to left.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {number} Returns the index of the found element, else `-1`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * _.findLastIndex(users, function(chr) {
     *   return chr.user == 'pebbles';
     * });
     * // => 2
     *
     * // using the `_.matches` callback shorthand
     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
     * // => 0
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findLastIndex(users, 'active', false);
     * // => 2
     *
     * // using the `_.property` callback shorthand
     * _.findLastIndex(users, 'active');
     * // => 0
     */
    var findLastIndex = createFindIndex(true);

    /**
     * Gets the first element of `array`.
     *
     * @static
     * @memberOf _
     * @alias head
     * @category Array
     * @param {Array} array The array to query.
     * @returns {*} Returns the first element of `array`.
     * @example
     *
     * _.first([1, 2, 3]);
     * // => 1
     *
     * _.first([]);
     * // => undefined
     */
    function first(array) {
      return array ? array[0] : undefined;
    }

    /**
     * Flattens a nested array. If `isDeep` is `true` the array is recursively
     * flattened, otherwise it is only flattened a single level.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to flatten.
     * @param {boolean} [isDeep] Specify a deep flatten.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the new flattened array.
     * @example
     *
     * _.flatten([1, [2, 3, [4]]]);
     * // => [1, 2, 3, [4]]
     *
     * // using `isDeep`
     * _.flatten([1, [2, 3, [4]]], true);
     * // => [1, 2, 3, 4]
     */
    function flatten(array, isDeep, guard) {
      var length = array ? array.length : 0;
      if (guard && isIterateeCall(array, isDeep, guard)) {
        isDeep = false;
      }
      return length ? baseFlatten(array, isDeep) : [];
    }

    /**
     * Recursively flattens a nested array.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to recursively flatten.
     * @returns {Array} Returns the new flattened array.
     * @example
     *
     * _.flattenDeep([1, [2, 3, [4]]]);
     * // => [1, 2, 3, 4]
     */
    function flattenDeep(array) {
      var length = array ? array.length : 0;
      return length ? baseFlatten(array, true) : [];
    }

    /**
     * Gets the index at which the first occurrence of `value` is found in `array`
     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons. If `fromIndex` is negative, it is used as the offset
     * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
     * performs a faster binary search.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {*} value The value to search for.
     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
     *  to perform a binary search on a sorted array.
     * @returns {number} Returns the index of the matched value, else `-1`.
     * @example
     *
     * _.indexOf([1, 2, 1, 2], 2);
     * // => 1
     *
     * // using `fromIndex`
     * _.indexOf([1, 2, 1, 2], 2, 2);
     * // => 3
     *
     * // performing a binary search
     * _.indexOf([1, 1, 2, 2], 2, true);
     * // => 2
     */
    function indexOf(array, value, fromIndex) {
      var length = array ? array.length : 0;
      if (!length) {
        return -1;
      }
      if (typeof fromIndex == 'number') {
        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
      } else if (fromIndex) {
        var index = binaryIndex(array, value);
        if (index < length &&
            (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
          return index;
        }
        return -1;
      }
      return baseIndexOf(array, value, fromIndex || 0);
    }

    /**
     * Gets all but the last element of `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.initial([1, 2, 3]);
     * // => [1, 2]
     */
    function initial(array) {
      return dropRight(array, 1);
    }

    /**
     * Creates an array of unique values that are included in all of the provided
     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of shared values.
     * @example
     * _.intersection([1, 2], [4, 2], [2, 1]);
     * // => [2]
     */
    var intersection = restParam(function(arrays) {
      var othLength = arrays.length,
          othIndex = othLength,
          caches = Array(length),
          indexOf = getIndexOf(),
          isCommon = indexOf == baseIndexOf,
          result = [];

      while (othIndex--) {
        var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];
        caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;
      }
      var array = arrays[0],
          index = -1,
          length = array ? array.length : 0,
          seen = caches[0];

      outer:
      while (++index < length) {
        value = array[index];
        if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {
          var othIndex = othLength;
          while (--othIndex) {
            var cache = caches[othIndex];
            if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {
              continue outer;
            }
          }
          if (seen) {
            seen.push(value);
          }
          result.push(value);
        }
      }
      return result;
    });

    /**
     * Gets the last element of `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @returns {*} Returns the last element of `array`.
     * @example
     *
     * _.last([1, 2, 3]);
     * // => 3
     */
    function last(array) {
      var length = array ? array.length : 0;
      return length ? array[length - 1] : undefined;
    }

    /**
     * This method is like `_.indexOf` except that it iterates over elements of
     * `array` from right to left.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to search.
     * @param {*} value The value to search for.
     * @param {boolean|number} [fromIndex=array.length-1] The index to search from
     *  or `true` to perform a binary search on a sorted array.
     * @returns {number} Returns the index of the matched value, else `-1`.
     * @example
     *
     * _.lastIndexOf([1, 2, 1, 2], 2);
     * // => 3
     *
     * // using `fromIndex`
     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
     * // => 1
     *
     * // performing a binary search
     * _.lastIndexOf([1, 1, 2, 2], 2, true);
     * // => 3
     */
    function lastIndexOf(array, value, fromIndex) {
      var length = array ? array.length : 0;
      if (!length) {
        return -1;
      }
      var index = length;
      if (typeof fromIndex == 'number') {
        index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;
      } else if (fromIndex) {
        index = binaryIndex(array, value, true) - 1;
        var other = array[index];
        if (value === value ? (value === other) : (other !== other)) {
          return index;
        }
        return -1;
      }
      if (value !== value) {
        return indexOfNaN(array, index, true);
      }
      while (index--) {
        if (array[index] === value) {
          return index;
        }
      }
      return -1;
    }

    /**
     * Removes all provided values from `array` using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * **Note:** Unlike `_.without`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {...*} [values] The values to remove.
     * @returns {Array} Returns `array`.
     * @example
     *
     * var array = [1, 2, 3, 1, 2, 3];
     *
     * _.pull(array, 2, 3);
     * console.log(array);
     * // => [1, 1]
     */
    function pull() {
      var args = arguments,
          array = args[0];

      if (!(array && array.length)) {
        return array;
      }
      var index = 0,
          indexOf = getIndexOf(),
          length = args.length;

      while (++index < length) {
        var fromIndex = 0,
            value = args[index];

        while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {
          splice.call(array, fromIndex, 1);
        }
      }
      return array;
    }

    /**
     * Removes elements from `array` corresponding to the given indexes and returns
     * an array of the removed elements. Indexes may be specified as an array of
     * indexes or as individual arguments.
     *
     * **Note:** Unlike `_.at`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {...(number|number[])} [indexes] The indexes of elements to remove,
     *  specified as individual indexes or arrays of indexes.
     * @returns {Array} Returns the new array of removed elements.
     * @example
     *
     * var array = [5, 10, 15, 20];
     * var evens = _.pullAt(array, 1, 3);
     *
     * console.log(array);
     * // => [5, 15]
     *
     * console.log(evens);
     * // => [10, 20]
     */
    var pullAt = restParam(function(array, indexes) {
      indexes = baseFlatten(indexes);

      var result = baseAt(array, indexes);
      basePullAt(array, indexes.sort(baseCompareAscending));
      return result;
    });

    /**
     * Removes all elements from `array` that `predicate` returns truthy for
     * and returns an array of the removed elements. The predicate is bound to
     * `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * **Note:** Unlike `_.filter`, this method mutates `array`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to modify.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new array of removed elements.
     * @example
     *
     * var array = [1, 2, 3, 4];
     * var evens = _.remove(array, function(n) {
     *   return n % 2 == 0;
     * });
     *
     * console.log(array);
     * // => [1, 3]
     *
     * console.log(evens);
     * // => [2, 4]
     */
    function remove(array, predicate, thisArg) {
      var result = [];
      if (!(array && array.length)) {
        return result;
      }
      var index = -1,
          indexes = [],
          length = array.length;

      predicate = getCallback(predicate, thisArg, 3);
      while (++index < length) {
        var value = array[index];
        if (predicate(value, index, array)) {
          result.push(value);
          indexes.push(index);
        }
      }
      basePullAt(array, indexes);
      return result;
    }

    /**
     * Gets all but the first element of `array`.
     *
     * @static
     * @memberOf _
     * @alias tail
     * @category Array
     * @param {Array} array The array to query.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.rest([1, 2, 3]);
     * // => [2, 3]
     */
    function rest(array) {
      return drop(array, 1);
    }

    /**
     * Creates a slice of `array` from `start` up to, but not including, `end`.
     *
     * **Note:** This method is used instead of `Array#slice` to support node
     * lists in IE < 9 and to ensure dense arrays are returned.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to slice.
     * @param {number} [start=0] The start position.
     * @param {number} [end=array.length] The end position.
     * @returns {Array} Returns the slice of `array`.
     */
    function slice(array, start, end) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
        start = 0;
        end = length;
      }
      return baseSlice(array, start, end);
    }

    /**
     * Uses a binary search to determine the lowest index at which `value` should
     * be inserted into `array` in order to maintain its sort order. If an iteratee
     * function is provided it is invoked for `value` and each element of `array`
     * to compute their sort ranking. The iteratee is bound to `thisArg` and
     * invoked with one argument; (value).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     * @example
     *
     * _.sortedIndex([30, 50], 40);
     * // => 1
     *
     * _.sortedIndex([4, 4, 5, 5], 5);
     * // => 2
     *
     * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };
     *
     * // using an iteratee function
     * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {
     *   return this.data[word];
     * }, dict);
     * // => 1
     *
     * // using the `_.property` callback shorthand
     * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
     * // => 1
     */
    var sortedIndex = createSortedIndex();

    /**
     * This method is like `_.sortedIndex` except that it returns the highest
     * index at which `value` should be inserted into `array` in order to
     * maintain its sort order.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The sorted array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     * @example
     *
     * _.sortedLastIndex([4, 4, 5, 5], 5);
     * // => 4
     */
    var sortedLastIndex = createSortedIndex(true);

    /**
     * Creates a slice of `array` with `n` elements taken from the beginning.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to take.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.take([1, 2, 3]);
     * // => [1]
     *
     * _.take([1, 2, 3], 2);
     * // => [1, 2]
     *
     * _.take([1, 2, 3], 5);
     * // => [1, 2, 3]
     *
     * _.take([1, 2, 3], 0);
     * // => []
     */
    function take(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      return baseSlice(array, 0, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with `n` elements taken from the end.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {number} [n=1] The number of elements to take.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeRight([1, 2, 3]);
     * // => [3]
     *
     * _.takeRight([1, 2, 3], 2);
     * // => [2, 3]
     *
     * _.takeRight([1, 2, 3], 5);
     * // => [1, 2, 3]
     *
     * _.takeRight([1, 2, 3], 0);
     * // => []
     */
    function takeRight(array, n, guard) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (guard ? isIterateeCall(array, n, guard) : n == null) {
        n = 1;
      }
      n = length - (+n || 0);
      return baseSlice(array, n < 0 ? 0 : n);
    }

    /**
     * Creates a slice of `array` with elements taken from the end. Elements are
     * taken until `predicate` returns falsey. The predicate is bound to `thisArg`
     * and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeRightWhile([1, 2, 3], function(n) {
     *   return n > 1;
     * });
     * // => [2, 3]
     *
     * var users = [
     *   { 'user': 'barney',  'active': true },
     *   { 'user': 'fred',    'active': false },
     *   { 'user': 'pebbles', 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');
     * // => ['pebbles']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.takeRightWhile(users, 'active', false), 'user');
     * // => ['fred', 'pebbles']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.takeRightWhile(users, 'active'), 'user');
     * // => []
     */
    function takeRightWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)
        : [];
    }

    /**
     * Creates a slice of `array` with elements taken from the beginning. Elements
     * are taken until `predicate` returns falsey. The predicate is bound to
     * `thisArg` and invoked with three arguments: (value, index, array).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to query.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the slice of `array`.
     * @example
     *
     * _.takeWhile([1, 2, 3], function(n) {
     *   return n < 3;
     * });
     * // => [1, 2]
     *
     * var users = [
     *   { 'user': 'barney',  'active': false },
     *   { 'user': 'fred',    'active': false},
     *   { 'user': 'pebbles', 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.takeWhile(users, 'active', false), 'user');
     * // => ['barney', 'fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.takeWhile(users, 'active'), 'user');
     * // => []
     */
    function takeWhile(array, predicate, thisArg) {
      return (array && array.length)
        ? baseWhile(array, getCallback(predicate, thisArg, 3))
        : [];
    }

    /**
     * Creates an array of unique values, in order, from all of the provided arrays
     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of combined values.
     * @example
     *
     * _.union([1, 2], [4, 2], [2, 1]);
     * // => [1, 2, 4]
     */
    var union = restParam(function(arrays) {
      return baseUniq(baseFlatten(arrays, false, true));
    });

    /**
     * Creates a duplicate-free version of an array, using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons, in which only the first occurence of each element
     * is kept. Providing `true` for `isSorted` performs a faster search algorithm
     * for sorted arrays. If an iteratee function is provided it is invoked for
     * each element in the array to generate the criterion by which uniqueness
     * is computed. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, array).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias unique
     * @category Array
     * @param {Array} array The array to inspect.
     * @param {boolean} [isSorted] Specify the array is sorted.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new duplicate-value-free array.
     * @example
     *
     * _.uniq([2, 1, 2]);
     * // => [2, 1]
     *
     * // using `isSorted`
     * _.uniq([1, 1, 2], true);
     * // => [1, 2]
     *
     * // using an iteratee function
     * _.uniq([1, 2.5, 1.5, 2], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => [1, 2.5]
     *
     * // using the `_.property` callback shorthand
     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
     * // => [{ 'x': 1 }, { 'x': 2 }]
     */
    function uniq(array, isSorted, iteratee, thisArg) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      if (isSorted != null && typeof isSorted != 'boolean') {
        thisArg = iteratee;
        iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
        isSorted = false;
      }
      var callback = getCallback();
      if (!(iteratee == null && callback === baseCallback)) {
        iteratee = callback(iteratee, thisArg, 3);
      }
      return (isSorted && getIndexOf() == baseIndexOf)
        ? sortedUniq(array, iteratee)
        : baseUniq(array, iteratee);
    }

    /**
     * This method is like `_.zip` except that it accepts an array of grouped
     * elements and creates an array regrouping the elements to their pre-zip
     * configuration.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array of grouped elements to process.
     * @returns {Array} Returns the new array of regrouped elements.
     * @example
     *
     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
     * // => [['fred', 30, true], ['barney', 40, false]]
     *
     * _.unzip(zipped);
     * // => [['fred', 'barney'], [30, 40], [true, false]]
     */
    function unzip(array) {
      if (!(array && array.length)) {
        return [];
      }
      var index = -1,
          length = 0;

      array = arrayFilter(array, function(group) {
        if (isArrayLike(group)) {
          length = nativeMax(group.length, length);
          return true;
        }
      });
      var result = Array(length);
      while (++index < length) {
        result[index] = arrayMap(array, baseProperty(index));
      }
      return result;
    }

    /**
     * This method is like `_.unzip` except that it accepts an iteratee to specify
     * how regrouped values should be combined. The `iteratee` is bound to `thisArg`
     * and invoked with four arguments: (accumulator, value, index, group).
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array of grouped elements to process.
     * @param {Function} [iteratee] The function to combine regrouped values.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new array of regrouped elements.
     * @example
     *
     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
     * // => [[1, 10, 100], [2, 20, 200]]
     *
     * _.unzipWith(zipped, _.add);
     * // => [3, 30, 300]
     */
    function unzipWith(array, iteratee, thisArg) {
      var length = array ? array.length : 0;
      if (!length) {
        return [];
      }
      var result = unzip(array);
      if (iteratee == null) {
        return result;
      }
      iteratee = bindCallback(iteratee, thisArg, 4);
      return arrayMap(result, function(group) {
        return arrayReduce(group, iteratee, undefined, true);
      });
    }

    /**
     * Creates an array excluding all provided values using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {Array} array The array to filter.
     * @param {...*} [values] The values to exclude.
     * @returns {Array} Returns the new array of filtered values.
     * @example
     *
     * _.without([1, 2, 1, 3], 1, 2);
     * // => [3]
     */
    var without = restParam(function(array, values) {
      return isArrayLike(array)
        ? baseDifference(array, values)
        : [];
    });

    /**
     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
     * of the provided arrays.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to inspect.
     * @returns {Array} Returns the new array of values.
     * @example
     *
     * _.xor([1, 2], [4, 2]);
     * // => [1, 4]
     */
    function xor() {
      var index = -1,
          length = arguments.length;

      while (++index < length) {
        var array = arguments[index];
        if (isArrayLike(array)) {
          var result = result
            ? arrayPush(baseDifference(result, array), baseDifference(array, result))
            : array;
        }
      }
      return result ? baseUniq(result) : [];
    }

    /**
     * Creates an array of grouped elements, the first of which contains the first
     * elements of the given arrays, the second of which contains the second elements
     * of the given arrays, and so on.
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to process.
     * @returns {Array} Returns the new array of grouped elements.
     * @example
     *
     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
     * // => [['fred', 30, true], ['barney', 40, false]]
     */
    var zip = restParam(unzip);

    /**
     * The inverse of `_.pairs`; this method returns an object composed from arrays
     * of property names and values. Provide either a single two dimensional array,
     * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
     * and one of corresponding values.
     *
     * @static
     * @memberOf _
     * @alias object
     * @category Array
     * @param {Array} props The property names.
     * @param {Array} [values=[]] The property values.
     * @returns {Object} Returns the new object.
     * @example
     *
     * _.zipObject([['fred', 30], ['barney', 40]]);
     * // => { 'fred': 30, 'barney': 40 }
     *
     * _.zipObject(['fred', 'barney'], [30, 40]);
     * // => { 'fred': 30, 'barney': 40 }
     */
    function zipObject(props, values) {
      var index = -1,
          length = props ? props.length : 0,
          result = {};

      if (length && !values && !isArray(props[0])) {
        values = [];
      }
      while (++index < length) {
        var key = props[index];
        if (values) {
          result[key] = values[index];
        } else if (key) {
          result[key[0]] = key[1];
        }
      }
      return result;
    }

    /**
     * This method is like `_.zip` except that it accepts an iteratee to specify
     * how grouped values should be combined. The `iteratee` is bound to `thisArg`
     * and invoked with four arguments: (accumulator, value, index, group).
     *
     * @static
     * @memberOf _
     * @category Array
     * @param {...Array} [arrays] The arrays to process.
     * @param {Function} [iteratee] The function to combine grouped values.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new array of grouped elements.
     * @example
     *
     * _.zipWith([1, 2], [10, 20], [100, 200], _.add);
     * // => [111, 222]
     */
    var zipWith = restParam(function(arrays) {
      var length = arrays.length,
          iteratee = length > 2 ? arrays[length - 2] : undefined,
          thisArg = length > 1 ? arrays[length - 1] : undefined;

      if (length > 2 && typeof iteratee == 'function') {
        length -= 2;
      } else {
        iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;
        thisArg = undefined;
      }
      arrays.length = length;
      return unzipWith(arrays, iteratee, thisArg);
    });

    /*------------------------------------------------------------------------*/

    /**
     * Creates a `lodash` object that wraps `value` with explicit method
     * chaining enabled.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to wrap.
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36 },
     *   { 'user': 'fred',    'age': 40 },
     *   { 'user': 'pebbles', 'age': 1 }
     * ];
     *
     * var youngest = _.chain(users)
     *   .sortBy('age')
     *   .map(function(chr) {
     *     return chr.user + ' is ' + chr.age;
     *   })
     *   .first()
     *   .value();
     * // => 'pebbles is 1'
     */
    function chain(value) {
      var result = lodash(value);
      result.__chain__ = true;
      return result;
    }

    /**
     * This method invokes `interceptor` and returns `value`. The interceptor is
     * bound to `thisArg` and invoked with one argument; (value). The purpose of
     * this method is to "tap into" a method chain in order to perform operations
     * on intermediate results within the chain.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to provide to `interceptor`.
     * @param {Function} interceptor The function to invoke.
     * @param {*} [thisArg] The `this` binding of `interceptor`.
     * @returns {*} Returns `value`.
     * @example
     *
     * _([1, 2, 3])
     *  .tap(function(array) {
     *    array.pop();
     *  })
     *  .reverse()
     *  .value();
     * // => [2, 1]
     */
    function tap(value, interceptor, thisArg) {
      interceptor.call(thisArg, value);
      return value;
    }

    /**
     * This method is like `_.tap` except that it returns the result of `interceptor`.
     *
     * @static
     * @memberOf _
     * @category Chain
     * @param {*} value The value to provide to `interceptor`.
     * @param {Function} interceptor The function to invoke.
     * @param {*} [thisArg] The `this` binding of `interceptor`.
     * @returns {*} Returns the result of `interceptor`.
     * @example
     *
     * _('  abc  ')
     *  .chain()
     *  .trim()
     *  .thru(function(value) {
     *    return [value];
     *  })
     *  .value();
     * // => ['abc']
     */
    function thru(value, interceptor, thisArg) {
      return interceptor.call(thisArg, value);
    }

    /**
     * Enables explicit method chaining on the wrapper object.
     *
     * @name chain
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * // without explicit chaining
     * _(users).first();
     * // => { 'user': 'barney', 'age': 36 }
     *
     * // with explicit chaining
     * _(users).chain()
     *   .first()
     *   .pick('user')
     *   .value();
     * // => { 'user': 'barney' }
     */
    function wrapperChain() {
      return chain(this);
    }

    /**
     * Executes the chained sequence and returns the wrapped result.
     *
     * @name commit
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2];
     * var wrapped = _(array).push(3);
     *
     * console.log(array);
     * // => [1, 2]
     *
     * wrapped = wrapped.commit();
     * console.log(array);
     * // => [1, 2, 3]
     *
     * wrapped.last();
     * // => 3
     *
     * console.log(array);
     * // => [1, 2, 3]
     */
    function wrapperCommit() {
      return new LodashWrapper(this.value(), this.__chain__);
    }

    /**
     * Creates a new array joining a wrapped array with any additional arrays
     * and/or values.
     *
     * @name concat
     * @memberOf _
     * @category Chain
     * @param {...*} [values] The values to concatenate.
     * @returns {Array} Returns the new concatenated array.
     * @example
     *
     * var array = [1];
     * var wrapped = _(array).concat(2, [3], [[4]]);
     *
     * console.log(wrapped.value());
     * // => [1, 2, 3, [4]]
     *
     * console.log(array);
     * // => [1]
     */
    var wrapperConcat = restParam(function(values) {
      values = baseFlatten(values);
      return this.thru(function(array) {
        return arrayConcat(isArray(array) ? array : [toObject(array)], values);
      });
    });

    /**
     * Creates a clone of the chained sequence planting `value` as the wrapped value.
     *
     * @name plant
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2];
     * var wrapped = _(array).map(function(value) {
     *   return Math.pow(value, 2);
     * });
     *
     * var other = [3, 4];
     * var otherWrapped = wrapped.plant(other);
     *
     * otherWrapped.value();
     * // => [9, 16]
     *
     * wrapped.value();
     * // => [1, 4]
     */
    function wrapperPlant(value) {
      var result,
          parent = this;

      while (parent instanceof baseLodash) {
        var clone = wrapperClone(parent);
        if (result) {
          previous.__wrapped__ = clone;
        } else {
          result = clone;
        }
        var previous = clone;
        parent = parent.__wrapped__;
      }
      previous.__wrapped__ = value;
      return result;
    }

    /**
     * Reverses the wrapped array so the first element becomes the last, the
     * second element becomes the second to last, and so on.
     *
     * **Note:** This method mutates the wrapped array.
     *
     * @name reverse
     * @memberOf _
     * @category Chain
     * @returns {Object} Returns the new reversed `lodash` wrapper instance.
     * @example
     *
     * var array = [1, 2, 3];
     *
     * _(array).reverse().value()
     * // => [3, 2, 1]
     *
     * console.log(array);
     * // => [3, 2, 1]
     */
    function wrapperReverse() {
      var value = this.__wrapped__;

      var interceptor = function(value) {
        return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();
      };
      if (value instanceof LazyWrapper) {
        var wrapped = value;
        if (this.__actions__.length) {
          wrapped = new LazyWrapper(this);
        }
        wrapped = wrapped.reverse();
        wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
        return new LodashWrapper(wrapped, this.__chain__);
      }
      return this.thru(interceptor);
    }

    /**
     * Produces the result of coercing the unwrapped value to a string.
     *
     * @name toString
     * @memberOf _
     * @category Chain
     * @returns {string} Returns the coerced string value.
     * @example
     *
     * _([1, 2, 3]).toString();
     * // => '1,2,3'
     */
    function wrapperToString() {
      return (this.value() + '');
    }

    /**
     * Executes the chained sequence to extract the unwrapped value.
     *
     * @name value
     * @memberOf _
     * @alias run, toJSON, valueOf
     * @category Chain
     * @returns {*} Returns the resolved unwrapped value.
     * @example
     *
     * _([1, 2, 3]).value();
     * // => [1, 2, 3]
     */
    function wrapperValue() {
      return baseWrapperValue(this.__wrapped__, this.__actions__);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates an array of elements corresponding to the given keys, or indexes,
     * of `collection`. Keys may be specified as individual arguments or as arrays
     * of keys.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {...(number|number[]|string|string[])} [props] The property names
     *  or indexes of elements to pick, specified individually or in arrays.
     * @returns {Array} Returns the new array of picked elements.
     * @example
     *
     * _.at(['a', 'b', 'c'], [0, 2]);
     * // => ['a', 'c']
     *
     * _.at(['barney', 'fred', 'pebbles'], 0, 2);
     * // => ['barney', 'pebbles']
     */
    var at = restParam(function(collection, props) {
      return baseAt(collection, baseFlatten(props));
    });

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is the number of times the key was returned by `iteratee`.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * _.countBy([4.3, 6.1, 6.4], function(n) {
     *   return Math.floor(n);
     * });
     * // => { '4': 1, '6': 2 }
     *
     * _.countBy([4.3, 6.1, 6.4], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => { '4': 1, '6': 2 }
     *
     * _.countBy(['one', 'two', 'three'], 'length');
     * // => { '3': 2, '5': 1 }
     */
    var countBy = createAggregator(function(result, value, key) {
      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
    });

    /**
     * Checks if `predicate` returns truthy for **all** elements of `collection`.
     * The predicate is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias all
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {boolean} Returns `true` if all elements pass the predicate check,
     *  else `false`.
     * @example
     *
     * _.every([true, 1, null, 'yes'], Boolean);
     * // => false
     *
     * var users = [
     *   { 'user': 'barney', 'active': false },
     *   { 'user': 'fred',   'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.every(users, { 'user': 'barney', 'active': false });
     * // => false
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.every(users, 'active', false);
     * // => true
     *
     * // using the `_.property` callback shorthand
     * _.every(users, 'active');
     * // => false
     */
    function every(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayEvery : baseEvery;
      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
        predicate = undefined;
      }
      if (typeof predicate != 'function' || thisArg !== undefined) {
        predicate = getCallback(predicate, thisArg, 3);
      }
      return func(collection, predicate);
    }

    /**
     * Iterates over elements of `collection`, returning an array of all elements
     * `predicate` returns truthy for. The predicate is bound to `thisArg` and
     * invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias select
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * _.filter([4, 5, 6], function(n) {
     *   return n % 2 == 0;
     * });
     * // => [4, 6]
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.filter(users, 'active', false), 'user');
     * // => ['fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.filter(users, 'active'), 'user');
     * // => ['barney']
     */
    function filter(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayFilter : baseFilter;
      predicate = getCallback(predicate, thisArg, 3);
      return func(collection, predicate);
    }

    /**
     * Iterates over elements of `collection`, returning the first element
     * `predicate` returns truthy for. The predicate is bound to `thisArg` and
     * invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias detect
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36, 'active': true },
     *   { 'user': 'fred',    'age': 40, 'active': false },
     *   { 'user': 'pebbles', 'age': 1,  'active': true }
     * ];
     *
     * _.result(_.find(users, function(chr) {
     *   return chr.age < 40;
     * }), 'user');
     * // => 'barney'
     *
     * // using the `_.matches` callback shorthand
     * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
     * // => 'pebbles'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.result(_.find(users, 'active', false), 'user');
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.result(_.find(users, 'active'), 'user');
     * // => 'barney'
     */
    var find = createFind(baseEach);

    /**
     * This method is like `_.find` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * _.findLast([1, 2, 3, 4], function(n) {
     *   return n % 2 == 1;
     * });
     * // => 3
     */
    var findLast = createFind(baseEachRight, true);

    /**
     * Performs a deep comparison between each element in `collection` and the
     * source object, returning the first element that has equivalent property
     * values.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Object} source The object of property values to match.
     * @returns {*} Returns the matched element, else `undefined`.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');
     * // => 'barney'
     *
     * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');
     * // => 'fred'
     */
    function findWhere(collection, source) {
      return find(collection, baseMatches(source));
    }

    /**
     * Iterates over elements of `collection` invoking `iteratee` for each element.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection). Iteratee functions may exit iteration early
     * by explicitly returning `false`.
     *
     * **Note:** As with other "Collections" methods, objects with a "length" property
     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
     * may be used for object iteration.
     *
     * @static
     * @memberOf _
     * @alias each
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array|Object|string} Returns `collection`.
     * @example
     *
     * _([1, 2]).forEach(function(n) {
     *   console.log(n);
     * }).value();
     * // => logs each value from left to right and returns the array
     *
     * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
     *   console.log(n, key);
     * });
     * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
     */
    var forEach = createForEach(arrayEach, baseEach);

    /**
     * This method is like `_.forEach` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @alias eachRight
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array|Object|string} Returns `collection`.
     * @example
     *
     * _([1, 2]).forEachRight(function(n) {
     *   console.log(n);
     * }).value();
     * // => logs each value from right to left and returns the array
     */
    var forEachRight = createForEach(arrayEachRight, baseEachRight);

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is an array of the elements responsible for generating the key.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * _.groupBy([4.2, 6.1, 6.4], function(n) {
     *   return Math.floor(n);
     * });
     * // => { '4': [4.2], '6': [6.1, 6.4] }
     *
     * _.groupBy([4.2, 6.1, 6.4], function(n) {
     *   return this.floor(n);
     * }, Math);
     * // => { '4': [4.2], '6': [6.1, 6.4] }
     *
     * // using the `_.property` callback shorthand
     * _.groupBy(['one', 'two', 'three'], 'length');
     * // => { '3': ['one', 'two'], '5': ['three'] }
     */
    var groupBy = createAggregator(function(result, value, key) {
      if (hasOwnProperty.call(result, key)) {
        result[key].push(value);
      } else {
        result[key] = [value];
      }
    });

    /**
     * Checks if `value` is in `collection` using
     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
     * for equality comparisons. If `fromIndex` is negative, it is used as the offset
     * from the end of `collection`.
     *
     * @static
     * @memberOf _
     * @alias contains, include
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {*} target The value to search for.
     * @param {number} [fromIndex=0] The index to search from.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
     * @returns {boolean} Returns `true` if a matching element is found, else `false`.
     * @example
     *
     * _.includes([1, 2, 3], 1);
     * // => true
     *
     * _.includes([1, 2, 3], 1, 2);
     * // => false
     *
     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
     * // => true
     *
     * _.includes('pebbles', 'eb');
     * // => true
     */
    function includes(collection, target, fromIndex, guard) {
      var length = collection ? getLength(collection) : 0;
      if (!isLength(length)) {
        collection = values(collection);
        length = collection.length;
      }
      if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
        fromIndex = 0;
      } else {
        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
      }
      return (typeof collection == 'string' || !isArray(collection) && isString(collection))
        ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
        : (!!length && getIndexOf(collection, target, fromIndex) > -1);
    }

    /**
     * Creates an object composed of keys generated from the results of running
     * each element of `collection` through `iteratee`. The corresponding value
     * of each key is the last element responsible for generating the key. The
     * iteratee function is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the composed aggregate object.
     * @example
     *
     * var keyData = [
     *   { 'dir': 'left', 'code': 97 },
     *   { 'dir': 'right', 'code': 100 }
     * ];
     *
     * _.indexBy(keyData, 'dir');
     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
     *
     * _.indexBy(keyData, function(object) {
     *   return String.fromCharCode(object.code);
     * });
     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
     *
     * _.indexBy(keyData, function(object) {
     *   return this.fromCharCode(object.code);
     * }, String);
     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
     */
    var indexBy = createAggregator(function(result, value, key) {
      result[key] = value;
    });

    /**
     * Invokes the method at `path` of each element in `collection`, returning
     * an array of the results of each invoked method. Any additional arguments
     * are provided to each invoked method. If `methodName` is a function it is
     * invoked for, and `this` bound to, each element in `collection`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Array|Function|string} path The path of the method to invoke or
     *  the function invoked per iteration.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Array} Returns the array of results.
     * @example
     *
     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
     * // => [[1, 5, 7], [1, 2, 3]]
     *
     * _.invoke([123, 456], String.prototype.split, '');
     * // => [['1', '2', '3'], ['4', '5', '6']]
     */
    var invoke = restParam(function(collection, path, args) {
      var index = -1,
          isFunc = typeof path == 'function',
          isProp = isKey(path),
          result = isArrayLike(collection) ? Array(collection.length) : [];

      baseEach(collection, function(value) {
        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
        result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
      });
      return result;
    });

    /**
     * Creates an array of values by running each element in `collection` through
     * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * Many lodash methods are guarded to work as iteratees for methods like
     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
     *
     * The guarded methods are:
     * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
     * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
     * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
     * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
     * `sum`, `uniq`, and `words`
     *
     * @static
     * @memberOf _
     * @alias collect
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new mapped array.
     * @example
     *
     * function timesThree(n) {
     *   return n * 3;
     * }
     *
     * _.map([1, 2], timesThree);
     * // => [3, 6]
     *
     * _.map({ 'a': 1, 'b': 2 }, timesThree);
     * // => [3, 6] (iteration order is not guaranteed)
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * // using the `_.property` callback shorthand
     * _.map(users, 'user');
     * // => ['barney', 'fred']
     */
    function map(collection, iteratee, thisArg) {
      var func = isArray(collection) ? arrayMap : baseMap;
      iteratee = getCallback(iteratee, thisArg, 3);
      return func(collection, iteratee);
    }

    /**
     * Creates an array of elements split into two groups, the first of which
     * contains elements `predicate` returns truthy for, while the second of which
     * contains elements `predicate` returns falsey for. The predicate is bound
     * to `thisArg` and invoked with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the array of grouped elements.
     * @example
     *
     * _.partition([1, 2, 3], function(n) {
     *   return n % 2;
     * });
     * // => [[1, 3], [2]]
     *
     * _.partition([1.2, 2.3, 3.4], function(n) {
     *   return this.floor(n) % 2;
     * }, Math);
     * // => [[1.2, 3.4], [2.3]]
     *
     * var users = [
     *   { 'user': 'barney',  'age': 36, 'active': false },
     *   { 'user': 'fred',    'age': 40, 'active': true },
     *   { 'user': 'pebbles', 'age': 1,  'active': false }
     * ];
     *
     * var mapper = function(array) {
     *   return _.pluck(array, 'user');
     * };
     *
     * // using the `_.matches` callback shorthand
     * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
     * // => [['pebbles'], ['barney', 'fred']]
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.map(_.partition(users, 'active', false), mapper);
     * // => [['barney', 'pebbles'], ['fred']]
     *
     * // using the `_.property` callback shorthand
     * _.map(_.partition(users, 'active'), mapper);
     * // => [['fred'], ['barney', 'pebbles']]
     */
    var partition = createAggregator(function(result, value, key) {
      result[key ? 0 : 1].push(value);
    }, function() { return [[], []]; });

    /**
     * Gets the property value of `path` from all elements in `collection`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Array|string} path The path of the property to pluck.
     * @returns {Array} Returns the property values.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.pluck(users, 'user');
     * // => ['barney', 'fred']
     *
     * var userIndex = _.indexBy(users, 'user');
     * _.pluck(userIndex, 'age');
     * // => [36, 40] (iteration order is not guaranteed)
     */
    function pluck(collection, path) {
      return map(collection, property(path));
    }

    /**
     * Reduces `collection` to a value which is the accumulated result of running
     * each element in `collection` through `iteratee`, where each successive
     * invocation is supplied the return value of the previous. If `accumulator`
     * is not provided the first element of `collection` is used as the initial
     * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:
     * (accumulator, value, index|key, collection).
     *
     * Many lodash methods are guarded to work as iteratees for methods like
     * `_.reduce`, `_.reduceRight`, and `_.transform`.
     *
     * The guarded methods are:
     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,
     * and `sortByOrder`
     *
     * @static
     * @memberOf _
     * @alias foldl, inject
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * _.reduce([1, 2], function(total, n) {
     *   return total + n;
     * });
     * // => 3
     *
     * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {
     *   result[key] = n * 3;
     *   return result;
     * }, {});
     * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
     */
    var reduce = createReduce(arrayReduce, baseEach);

    /**
     * This method is like `_.reduce` except that it iterates over elements of
     * `collection` from right to left.
     *
     * @static
     * @memberOf _
     * @alias foldr
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The initial value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * var array = [[0, 1], [2, 3], [4, 5]];
     *
     * _.reduceRight(array, function(flattened, other) {
     *   return flattened.concat(other);
     * }, []);
     * // => [4, 5, 2, 3, 0, 1]
     */
    var reduceRight = createReduce(arrayReduceRight, baseEachRight);

    /**
     * The opposite of `_.filter`; this method returns the elements of `collection`
     * that `predicate` does **not** return truthy for.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * _.reject([1, 2, 3, 4], function(n) {
     *   return n % 2 == 0;
     * });
     * // => [1, 3]
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': false },
     *   { 'user': 'fred',   'age': 40, 'active': true }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');
     * // => ['barney']
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.pluck(_.reject(users, 'active', false), 'user');
     * // => ['fred']
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.reject(users, 'active'), 'user');
     * // => ['barney']
     */
    function reject(collection, predicate, thisArg) {
      var func = isArray(collection) ? arrayFilter : baseFilter;
      predicate = getCallback(predicate, thisArg, 3);
      return func(collection, function(value, index, collection) {
        return !predicate(value, index, collection);
      });
    }

    /**
     * Gets a random element or `n` random elements from a collection.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to sample.
     * @param {number} [n] The number of elements to sample.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {*} Returns the random sample(s).
     * @example
     *
     * _.sample([1, 2, 3, 4]);
     * // => 2
     *
     * _.sample([1, 2, 3, 4], 2);
     * // => [3, 1]
     */
    function sample(collection, n, guard) {
      if (guard ? isIterateeCall(collection, n, guard) : n == null) {
        collection = toIterable(collection);
        var length = collection.length;
        return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
      }
      var index = -1,
          result = toArray(collection),
          length = result.length,
          lastIndex = length - 1;

      n = nativeMin(n < 0 ? 0 : (+n || 0), length);
      while (++index < n) {
        var rand = baseRandom(index, lastIndex),
            value = result[rand];

        result[rand] = result[index];
        result[index] = value;
      }
      result.length = n;
      return result;
    }

    /**
     * Creates an array of shuffled values, using a version of the
     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to shuffle.
     * @returns {Array} Returns the new shuffled array.
     * @example
     *
     * _.shuffle([1, 2, 3, 4]);
     * // => [4, 1, 3, 2]
     */
    function shuffle(collection) {
      return sample(collection, POSITIVE_INFINITY);
    }

    /**
     * Gets the size of `collection` by returning its length for array-like
     * values or the number of own enumerable properties for objects.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to inspect.
     * @returns {number} Returns the size of `collection`.
     * @example
     *
     * _.size([1, 2, 3]);
     * // => 3
     *
     * _.size({ 'a': 1, 'b': 2 });
     * // => 2
     *
     * _.size('pebbles');
     * // => 7
     */
    function size(collection) {
      var length = collection ? getLength(collection) : 0;
      return isLength(length) ? length : keys(collection).length;
    }

    /**
     * Checks if `predicate` returns truthy for **any** element of `collection`.
     * The function returns as soon as it finds a passing value and does not iterate
     * over the entire collection. The predicate is bound to `thisArg` and invoked
     * with three arguments: (value, index|key, collection).
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @alias any
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {boolean} Returns `true` if any element passes the predicate check,
     *  else `false`.
     * @example
     *
     * _.some([null, 0, 'yes', false], Boolean);
     * // => true
     *
     * var users = [
     *   { 'user': 'barney', 'active': true },
     *   { 'user': 'fred',   'active': false }
     * ];
     *
     * // using the `_.matches` callback shorthand
     * _.some(users, { 'user': 'barney', 'active': false });
     * // => false
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.some(users, 'active', false);
     * // => true
     *
     * // using the `_.property` callback shorthand
     * _.some(users, 'active');
     * // => true
     */
    function some(collection, predicate, thisArg) {
      var func = isArray(collection) ? arraySome : baseSome;
      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
        predicate = undefined;
      }
      if (typeof predicate != 'function' || thisArg !== undefined) {
        predicate = getCallback(predicate, thisArg, 3);
      }
      return func(collection, predicate);
    }

    /**
     * Creates an array of elements, sorted in ascending order by the results of
     * running each element in a collection through `iteratee`. This method performs
     * a stable sort, that is, it preserves the original sort order of equal elements.
     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
     * (value, index|key, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * _.sortBy([1, 2, 3], function(n) {
     *   return Math.sin(n);
     * });
     * // => [3, 1, 2]
     *
     * _.sortBy([1, 2, 3], function(n) {
     *   return this.sin(n);
     * }, Math);
     * // => [3, 1, 2]
     *
     * var users = [
     *   { 'user': 'fred' },
     *   { 'user': 'pebbles' },
     *   { 'user': 'barney' }
     * ];
     *
     * // using the `_.property` callback shorthand
     * _.pluck(_.sortBy(users, 'user'), 'user');
     * // => ['barney', 'fred', 'pebbles']
     */
    function sortBy(collection, iteratee, thisArg) {
      if (collection == null) {
        return [];
      }
      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
        iteratee = undefined;
      }
      var index = -1;
      iteratee = getCallback(iteratee, thisArg, 3);

      var result = baseMap(collection, function(value, key, collection) {
        return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };
      });
      return baseSortBy(result, compareAscending);
    }

    /**
     * This method is like `_.sortBy` except that it can sort by multiple iteratees
     * or property names.
     *
     * If a property name is provided for an iteratee the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If an object is provided for an iteratee the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees
     *  The iteratees to sort by, specified as individual values or arrays of values.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * var users = [
     *   { 'user': 'fred',   'age': 48 },
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 42 },
     *   { 'user': 'barney', 'age': 34 }
     * ];
     *
     * _.map(_.sortByAll(users, ['user', 'age']), _.values);
     * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
     *
     * _.map(_.sortByAll(users, 'user', function(chr) {
     *   return Math.floor(chr.age / 10);
     * }), _.values);
     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
     */
    var sortByAll = restParam(function(collection, iteratees) {
      if (collection == null) {
        return [];
      }
      var guard = iteratees[2];
      if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {
        iteratees.length = 1;
      }
      return baseSortByOrder(collection, baseFlatten(iteratees), []);
    });

    /**
     * This method is like `_.sortByAll` except that it allows specifying the
     * sort orders of the iteratees to sort by. If `orders` is unspecified, all
     * values are sorted in ascending order. Otherwise, a value is sorted in
     * ascending order if its corresponding order is "asc", and descending if "desc".
     *
     * If a property name is provided for an iteratee the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If an object is provided for an iteratee the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
     * @param {boolean[]} [orders] The sort orders of `iteratees`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
     * @returns {Array} Returns the new sorted array.
     * @example
     *
     * var users = [
     *   { 'user': 'fred',   'age': 48 },
     *   { 'user': 'barney', 'age': 34 },
     *   { 'user': 'fred',   'age': 42 },
     *   { 'user': 'barney', 'age': 36 }
     * ];
     *
     * // sort by `user` in ascending order and by `age` in descending order
     * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);
     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
     */
    function sortByOrder(collection, iteratees, orders, guard) {
      if (collection == null) {
        return [];
      }
      if (guard && isIterateeCall(iteratees, orders, guard)) {
        orders = undefined;
      }
      if (!isArray(iteratees)) {
        iteratees = iteratees == null ? [] : [iteratees];
      }
      if (!isArray(orders)) {
        orders = orders == null ? [] : [orders];
      }
      return baseSortByOrder(collection, iteratees, orders);
    }

    /**
     * Performs a deep comparison between each element in `collection` and the
     * source object, returning an array of all elements that have equivalent
     * property values.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Collection
     * @param {Array|Object|string} collection The collection to search.
     * @param {Object} source The object of property values to match.
     * @returns {Array} Returns the new filtered array.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },
     *   { 'user': 'fred',   'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }
     * ];
     *
     * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');
     * // => ['barney']
     *
     * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');
     * // => ['fred']
     */
    function where(collection, source) {
      return filter(collection, baseMatches(source));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Gets the number of milliseconds that have elapsed since the Unix epoch
     * (1 January 1970 00:00:00 UTC).
     *
     * @static
     * @memberOf _
     * @category Date
     * @example
     *
     * _.defer(function(stamp) {
     *   console.log(_.now() - stamp);
     * }, _.now());
     * // => logs the number of milliseconds it took for the deferred function to be invoked
     */
    var now = nativeNow || function() {
      return new Date().getTime();
    };

    /*------------------------------------------------------------------------*/

    /**
     * The opposite of `_.before`; this method creates a function that invokes
     * `func` once it is called `n` or more times.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {number} n The number of calls before `func` is invoked.
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * var saves = ['profile', 'settings'];
     *
     * var done = _.after(saves.length, function() {
     *   console.log('done saving!');
     * });
     *
     * _.forEach(saves, function(type) {
     *   asyncSave({ 'type': type, 'complete': done });
     * });
     * // => logs 'done saving!' after the two async saves have completed
     */
    function after(n, func) {
      if (typeof func != 'function') {
        if (typeof n == 'function') {
          var temp = n;
          n = func;
          func = temp;
        } else {
          throw new TypeError(FUNC_ERROR_TEXT);
        }
      }
      n = nativeIsFinite(n = +n) ? n : 0;
      return function() {
        if (--n < 1) {
          return func.apply(this, arguments);
        }
      };
    }

    /**
     * Creates a function that accepts up to `n` arguments ignoring any
     * additional arguments.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to cap arguments for.
     * @param {number} [n=func.length] The arity cap.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new function.
     * @example
     *
     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
     * // => [6, 8, 10]
     */
    function ary(func, n, guard) {
      if (guard && isIterateeCall(func, n, guard)) {
        n = undefined;
      }
      n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
    }

    /**
     * Creates a function that invokes `func`, with the `this` binding and arguments
     * of the created function, while it is called less than `n` times. Subsequent
     * calls to the created function return the result of the last `func` invocation.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {number} n The number of calls at which `func` is no longer invoked.
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * jQuery('#add').on('click', _.before(5, addContactToList));
     * // => allows adding up to 4 contacts to the list
     */
    function before(n, func) {
      var result;
      if (typeof func != 'function') {
        if (typeof n == 'function') {
          var temp = n;
          n = func;
          func = temp;
        } else {
          throw new TypeError(FUNC_ERROR_TEXT);
        }
      }
      return function() {
        if (--n > 0) {
          result = func.apply(this, arguments);
        }
        if (n <= 1) {
          func = undefined;
        }
        return result;
      };
    }

    /**
     * Creates a function that invokes `func` with the `this` binding of `thisArg`
     * and prepends any additional `_.bind` arguments to those provided to the
     * bound function.
     *
     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
     * may be used as a placeholder for partially applied arguments.
     *
     * **Note:** Unlike native `Function#bind` this method does not set the "length"
     * property of bound functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to bind.
     * @param {*} thisArg The `this` binding of `func`.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new bound function.
     * @example
     *
     * var greet = function(greeting, punctuation) {
     *   return greeting + ' ' + this.user + punctuation;
     * };
     *
     * var object = { 'user': 'fred' };
     *
     * var bound = _.bind(greet, object, 'hi');
     * bound('!');
     * // => 'hi fred!'
     *
     * // using placeholders
     * var bound = _.bind(greet, object, _, '!');
     * bound('hi');
     * // => 'hi fred!'
     */
    var bind = restParam(function(func, thisArg, partials) {
      var bitmask = BIND_FLAG;
      if (partials.length) {
        var holders = replaceHolders(partials, bind.placeholder);
        bitmask |= PARTIAL_FLAG;
      }
      return createWrapper(func, bitmask, thisArg, partials, holders);
    });

    /**
     * Binds methods of an object to the object itself, overwriting the existing
     * method. Method names may be specified as individual arguments or as arrays
     * of method names. If no method names are provided all enumerable function
     * properties, own and inherited, of `object` are bound.
     *
     * **Note:** This method does not set the "length" property of bound functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Object} object The object to bind and assign the bound methods to.
     * @param {...(string|string[])} [methodNames] The object method names to bind,
     *  specified as individual method names or arrays of method names.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var view = {
     *   'label': 'docs',
     *   'onClick': function() {
     *     console.log('clicked ' + this.label);
     *   }
     * };
     *
     * _.bindAll(view);
     * jQuery('#docs').on('click', view.onClick);
     * // => logs 'clicked docs' when the element is clicked
     */
    var bindAll = restParam(function(object, methodNames) {
      methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);

      var index = -1,
          length = methodNames.length;

      while (++index < length) {
        var key = methodNames[index];
        object[key] = createWrapper(object[key], BIND_FLAG, object);
      }
      return object;
    });

    /**
     * Creates a function that invokes the method at `object[key]` and prepends
     * any additional `_.bindKey` arguments to those provided to the bound function.
     *
     * This method differs from `_.bind` by allowing bound functions to reference
     * methods that may be redefined or don't yet exist.
     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
     * for more details.
     *
     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Object} object The object the method belongs to.
     * @param {string} key The key of the method.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new bound function.
     * @example
     *
     * var object = {
     *   'user': 'fred',
     *   'greet': function(greeting, punctuation) {
     *     return greeting + ' ' + this.user + punctuation;
     *   }
     * };
     *
     * var bound = _.bindKey(object, 'greet', 'hi');
     * bound('!');
     * // => 'hi fred!'
     *
     * object.greet = function(greeting, punctuation) {
     *   return greeting + 'ya ' + this.user + punctuation;
     * };
     *
     * bound('!');
     * // => 'hiya fred!'
     *
     * // using placeholders
     * var bound = _.bindKey(object, 'greet', _, '!');
     * bound('hi');
     * // => 'hiya fred!'
     */
    var bindKey = restParam(function(object, key, partials) {
      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
      if (partials.length) {
        var holders = replaceHolders(partials, bindKey.placeholder);
        bitmask |= PARTIAL_FLAG;
      }
      return createWrapper(key, bitmask, object, partials, holders);
    });

    /**
     * Creates a function that accepts one or more arguments of `func` that when
     * called either invokes `func` returning its result, if all `func` arguments
     * have been provided, or returns a function that accepts one or more of the
     * remaining `func` arguments, and so on. The arity of `func` may be specified
     * if `func.length` is not sufficient.
     *
     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
     * may be used as a placeholder for provided arguments.
     *
     * **Note:** This method does not set the "length" property of curried functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to curry.
     * @param {number} [arity=func.length] The arity of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new curried function.
     * @example
     *
     * var abc = function(a, b, c) {
     *   return [a, b, c];
     * };
     *
     * var curried = _.curry(abc);
     *
     * curried(1)(2)(3);
     * // => [1, 2, 3]
     *
     * curried(1, 2)(3);
     * // => [1, 2, 3]
     *
     * curried(1, 2, 3);
     * // => [1, 2, 3]
     *
     * // using placeholders
     * curried(1)(_, 3)(2);
     * // => [1, 2, 3]
     */
    var curry = createCurry(CURRY_FLAG);

    /**
     * This method is like `_.curry` except that arguments are applied to `func`
     * in the manner of `_.partialRight` instead of `_.partial`.
     *
     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for provided arguments.
     *
     * **Note:** This method does not set the "length" property of curried functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to curry.
     * @param {number} [arity=func.length] The arity of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the new curried function.
     * @example
     *
     * var abc = function(a, b, c) {
     *   return [a, b, c];
     * };
     *
     * var curried = _.curryRight(abc);
     *
     * curried(3)(2)(1);
     * // => [1, 2, 3]
     *
     * curried(2, 3)(1);
     * // => [1, 2, 3]
     *
     * curried(1, 2, 3);
     * // => [1, 2, 3]
     *
     * // using placeholders
     * curried(3)(1, _)(2);
     * // => [1, 2, 3]
     */
    var curryRight = createCurry(CURRY_RIGHT_FLAG);

    /**
     * Creates a debounced function that delays invoking `func` until after `wait`
     * milliseconds have elapsed since the last time the debounced function was
     * invoked. The debounced function comes with a `cancel` method to cancel
     * delayed invocations. Provide an options object to indicate that `func`
     * should be invoked on the leading and/or trailing edge of the `wait` timeout.
     * Subsequent calls to the debounced function return the result of the last
     * `func` invocation.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
     * on the trailing edge of the timeout only if the the debounced function is
     * invoked more than once during the `wait` timeout.
     *
     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
     * for details over the differences between `_.debounce` and `_.throttle`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to debounce.
     * @param {number} [wait=0] The number of milliseconds to delay.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.leading=false] Specify invoking on the leading
     *  edge of the timeout.
     * @param {number} [options.maxWait] The maximum time `func` is allowed to be
     *  delayed before it is invoked.
     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
     *  edge of the timeout.
     * @returns {Function} Returns the new debounced function.
     * @example
     *
     * // avoid costly calculations while the window size is in flux
     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
     *
     * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
     *   'leading': true,
     *   'trailing': false
     * }));
     *
     * // ensure `batchLog` is invoked once after 1 second of debounced calls
     * var source = new EventSource('/stream');
     * jQuery(source).on('message', _.debounce(batchLog, 250, {
     *   'maxWait': 1000
     * }));
     *
     * // cancel a debounced call
     * var todoChanges = _.debounce(batchLog, 1000);
     * Object.observe(models.todo, todoChanges);
     *
     * Object.observe(models, function(changes) {
     *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
     *     todoChanges.cancel();
     *   }
     * }, ['delete']);
     *
     * // ...at some point `models.todo` is changed
     * models.todo.completed = true;
     *
     * // ...before 1 second has passed `models.todo` is deleted
     * // which cancels the debounced `todoChanges` call
     * delete models.todo;
     */
    function debounce(func, wait, options) {
      var args,
          maxTimeoutId,
          result,
          stamp,
          thisArg,
          timeoutId,
          trailingCall,
          lastCalled = 0,
          maxWait = false,
          trailing = true;

      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      wait = wait < 0 ? 0 : (+wait || 0);
      if (options === true) {
        var leading = true;
        trailing = false;
      } else if (isObject(options)) {
        leading = !!options.leading;
        maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }

      function cancel() {
        if (timeoutId) {
          clearTimeout(timeoutId);
        }
        if (maxTimeoutId) {
          clearTimeout(maxTimeoutId);
        }
        lastCalled = 0;
        maxTimeoutId = timeoutId = trailingCall = undefined;
      }

      function complete(isCalled, id) {
        if (id) {
          clearTimeout(id);
        }
        maxTimeoutId = timeoutId = trailingCall = undefined;
        if (isCalled) {
          lastCalled = now();
          result = func.apply(thisArg, args);
          if (!timeoutId && !maxTimeoutId) {
            args = thisArg = undefined;
          }
        }
      }

      function delayed() {
        var remaining = wait - (now() - stamp);
        if (remaining <= 0 || remaining > wait) {
          complete(trailingCall, maxTimeoutId);
        } else {
          timeoutId = setTimeout(delayed, remaining);
        }
      }

      function maxDelayed() {
        complete(trailing, timeoutId);
      }

      function debounced() {
        args = arguments;
        stamp = now();
        thisArg = this;
        trailingCall = trailing && (timeoutId || !leading);

        if (maxWait === false) {
          var leadingCall = leading && !timeoutId;
        } else {
          if (!maxTimeoutId && !leading) {
            lastCalled = stamp;
          }
          var remaining = maxWait - (stamp - lastCalled),
              isCalled = remaining <= 0 || remaining > maxWait;

          if (isCalled) {
            if (maxTimeoutId) {
              maxTimeoutId = clearTimeout(maxTimeoutId);
            }
            lastCalled = stamp;
            result = func.apply(thisArg, args);
          }
          else if (!maxTimeoutId) {
            maxTimeoutId = setTimeout(maxDelayed, remaining);
          }
        }
        if (isCalled && timeoutId) {
          timeoutId = clearTimeout(timeoutId);
        }
        else if (!timeoutId && wait !== maxWait) {
          timeoutId = setTimeout(delayed, wait);
        }
        if (leadingCall) {
          isCalled = true;
          result = func.apply(thisArg, args);
        }
        if (isCalled && !timeoutId && !maxTimeoutId) {
          args = thisArg = undefined;
        }
        return result;
      }
      debounced.cancel = cancel;
      return debounced;
    }

    /**
     * Defers invoking the `func` until the current call stack has cleared. Any
     * additional arguments are provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to defer.
     * @param {...*} [args] The arguments to invoke the function with.
     * @returns {number} Returns the timer id.
     * @example
     *
     * _.defer(function(text) {
     *   console.log(text);
     * }, 'deferred');
     * // logs 'deferred' after one or more milliseconds
     */
    var defer = restParam(function(func, args) {
      return baseDelay(func, 1, args);
    });

    /**
     * Invokes `func` after `wait` milliseconds. Any additional arguments are
     * provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to delay.
     * @param {number} wait The number of milliseconds to delay invocation.
     * @param {...*} [args] The arguments to invoke the function with.
     * @returns {number} Returns the timer id.
     * @example
     *
     * _.delay(function(text) {
     *   console.log(text);
     * }, 1000, 'later');
     * // => logs 'later' after one second
     */
    var delay = restParam(function(func, wait, args) {
      return baseDelay(func, wait, args);
    });

    /**
     * Creates a function that returns the result of invoking the provided
     * functions with the `this` binding of the created function, where each
     * successive invocation is supplied the return value of the previous.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {...Function} [funcs] Functions to invoke.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var addSquare = _.flow(_.add, square);
     * addSquare(1, 2);
     * // => 9
     */
    var flow = createFlow();

    /**
     * This method is like `_.flow` except that it creates a function that
     * invokes the provided functions from right to left.
     *
     * @static
     * @memberOf _
     * @alias backflow, compose
     * @category Function
     * @param {...Function} [funcs] Functions to invoke.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var addSquare = _.flowRight(square, _.add);
     * addSquare(1, 2);
     * // => 9
     */
    var flowRight = createFlow(true);

    /**
     * Creates a function that memoizes the result of `func`. If `resolver` is
     * provided it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is coerced to a string and used as the
     * cache key. The `func` is invoked with the `this` binding of the memoized
     * function.
     *
     * **Note:** The cache is exposed as the `cache` property on the memoized
     * function. Its creation may be customized by replacing the `_.memoize.Cache`
     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
     * method interface of `get`, `has`, and `set`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to have its output memoized.
     * @param {Function} [resolver] The function to resolve the cache key.
     * @returns {Function} Returns the new memoizing function.
     * @example
     *
     * var upperCase = _.memoize(function(string) {
     *   return string.toUpperCase();
     * });
     *
     * upperCase('fred');
     * // => 'FRED'
     *
     * // modifying the result cache
     * upperCase.cache.set('fred', 'BARNEY');
     * upperCase('fred');
     * // => 'BARNEY'
     *
     * // replacing `_.memoize.Cache`
     * var object = { 'user': 'fred' };
     * var other = { 'user': 'barney' };
     * var identity = _.memoize(_.identity);
     *
     * identity(object);
     * // => { 'user': 'fred' }
     * identity(other);
     * // => { 'user': 'fred' }
     *
     * _.memoize.Cache = WeakMap;
     * var identity = _.memoize(_.identity);
     *
     * identity(object);
     * // => { 'user': 'fred' }
     * identity(other);
     * // => { 'user': 'barney' }
     */
    function memoize(func, resolver) {
      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var memoized = function() {
        var args = arguments,
            key = resolver ? resolver.apply(this, args) : args[0],
            cache = memoized.cache;

        if (cache.has(key)) {
          return cache.get(key);
        }
        var result = func.apply(this, args);
        memoized.cache = cache.set(key, result);
        return result;
      };
      memoized.cache = new memoize.Cache;
      return memoized;
    }

    /**
     * Creates a function that runs each argument through a corresponding
     * transform function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to wrap.
     * @param {...(Function|Function[])} [transforms] The functions to transform
     * arguments, specified as individual functions or arrays of functions.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function doubled(n) {
     *   return n * 2;
     * }
     *
     * function square(n) {
     *   return n * n;
     * }
     *
     * var modded = _.modArgs(function(x, y) {
     *   return [x, y];
     * }, square, doubled);
     *
     * modded(1, 2);
     * // => [1, 4]
     *
     * modded(5, 10);
     * // => [25, 20]
     */
    var modArgs = restParam(function(func, transforms) {
      transforms = baseFlatten(transforms);
      if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      var length = transforms.length;
      return restParam(function(args) {
        var index = nativeMin(args.length, length);
        while (index--) {
          args[index] = transforms[index](args[index]);
        }
        return func.apply(this, args);
      });
    });

    /**
     * Creates a function that negates the result of the predicate `func`. The
     * `func` predicate is invoked with the `this` binding and arguments of the
     * created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} predicate The predicate to negate.
     * @returns {Function} Returns the new function.
     * @example
     *
     * function isEven(n) {
     *   return n % 2 == 0;
     * }
     *
     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
     * // => [1, 3, 5]
     */
    function negate(predicate) {
      if (typeof predicate != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return function() {
        return !predicate.apply(this, arguments);
      };
    }

    /**
     * Creates a function that is restricted to invoking `func` once. Repeat calls
     * to the function return the value of the first call. The `func` is invoked
     * with the `this` binding and arguments of the created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to restrict.
     * @returns {Function} Returns the new restricted function.
     * @example
     *
     * var initialize = _.once(createApplication);
     * initialize();
     * initialize();
     * // `initialize` invokes `createApplication` once
     */
    function once(func) {
      return before(2, func);
    }

    /**
     * Creates a function that invokes `func` with `partial` arguments prepended
     * to those provided to the new function. This method is like `_.bind` except
     * it does **not** alter the `this` binding.
     *
     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * **Note:** This method does not set the "length" property of partially
     * applied functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to partially apply arguments to.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new partially applied function.
     * @example
     *
     * var greet = function(greeting, name) {
     *   return greeting + ' ' + name;
     * };
     *
     * var sayHelloTo = _.partial(greet, 'hello');
     * sayHelloTo('fred');
     * // => 'hello fred'
     *
     * // using placeholders
     * var greetFred = _.partial(greet, _, 'fred');
     * greetFred('hi');
     * // => 'hi fred'
     */
    var partial = createPartial(PARTIAL_FLAG);

    /**
     * This method is like `_.partial` except that partially applied arguments
     * are appended to those provided to the new function.
     *
     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
     * builds, may be used as a placeholder for partially applied arguments.
     *
     * **Note:** This method does not set the "length" property of partially
     * applied functions.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to partially apply arguments to.
     * @param {...*} [partials] The arguments to be partially applied.
     * @returns {Function} Returns the new partially applied function.
     * @example
     *
     * var greet = function(greeting, name) {
     *   return greeting + ' ' + name;
     * };
     *
     * var greetFred = _.partialRight(greet, 'fred');
     * greetFred('hi');
     * // => 'hi fred'
     *
     * // using placeholders
     * var sayHelloTo = _.partialRight(greet, 'hello', _);
     * sayHelloTo('fred');
     * // => 'hello fred'
     */
    var partialRight = createPartial(PARTIAL_RIGHT_FLAG);

    /**
     * Creates a function that invokes `func` with arguments arranged according
     * to the specified indexes where the argument value at the first index is
     * provided as the first argument, the argument value at the second index is
     * provided as the second argument, and so on.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to rearrange arguments for.
     * @param {...(number|number[])} indexes The arranged argument indexes,
     *  specified as individual indexes or arrays of indexes.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var rearged = _.rearg(function(a, b, c) {
     *   return [a, b, c];
     * }, 2, 0, 1);
     *
     * rearged('b', 'c', 'a')
     * // => ['a', 'b', 'c']
     *
     * var map = _.rearg(_.map, [1, 0]);
     * map(function(n) {
     *   return n * 3;
     * }, [1, 2, 3]);
     * // => [3, 6, 9]
     */
    var rearg = restParam(function(func, indexes) {
      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
    });

    /**
     * Creates a function that invokes `func` with the `this` binding of the
     * created function and arguments from `start` and beyond provided as an array.
     *
     * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to apply a rest parameter to.
     * @param {number} [start=func.length-1] The start position of the rest parameter.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var say = _.restParam(function(what, names) {
     *   return what + ' ' + _.initial(names).join(', ') +
     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
     * });
     *
     * say('hello', 'fred', 'barney', 'pebbles');
     * // => 'hello fred, barney, & pebbles'
     */
    function restParam(func, start) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
      return function() {
        var args = arguments,
            index = -1,
            length = nativeMax(args.length - start, 0),
            rest = Array(length);

        while (++index < length) {
          rest[index] = args[start + index];
        }
        switch (start) {
          case 0: return func.call(this, rest);
          case 1: return func.call(this, args[0], rest);
          case 2: return func.call(this, args[0], args[1], rest);
        }
        var otherArgs = Array(start + 1);
        index = -1;
        while (++index < start) {
          otherArgs[index] = args[index];
        }
        otherArgs[start] = rest;
        return func.apply(this, otherArgs);
      };
    }

    /**
     * Creates a function that invokes `func` with the `this` binding of the created
     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
     *
     * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator).
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to spread arguments over.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var say = _.spread(function(who, what) {
     *   return who + ' says ' + what;
     * });
     *
     * say(['fred', 'hello']);
     * // => 'fred says hello'
     *
     * // with a Promise
     * var numbers = Promise.all([
     *   Promise.resolve(40),
     *   Promise.resolve(36)
     * ]);
     *
     * numbers.then(_.spread(function(x, y) {
     *   return x + y;
     * }));
     * // => a Promise of 76
     */
    function spread(func) {
      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      return function(array) {
        return func.apply(this, array);
      };
    }

    /**
     * Creates a throttled function that only invokes `func` at most once per
     * every `wait` milliseconds. The throttled function comes with a `cancel`
     * method to cancel delayed invocations. Provide an options object to indicate
     * that `func` should be invoked on the leading and/or trailing edge of the
     * `wait` timeout. Subsequent calls to the throttled function return the
     * result of the last `func` call.
     *
     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
     * on the trailing edge of the timeout only if the the throttled function is
     * invoked more than once during the `wait` timeout.
     *
     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
     * for details over the differences between `_.throttle` and `_.debounce`.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {Function} func The function to throttle.
     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.leading=true] Specify invoking on the leading
     *  edge of the timeout.
     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
     *  edge of the timeout.
     * @returns {Function} Returns the new throttled function.
     * @example
     *
     * // avoid excessively updating the position while scrolling
     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
     *
     * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
     *   'trailing': false
     * }));
     *
     * // cancel a trailing throttled call
     * jQuery(window).on('popstate', throttled.cancel);
     */
    function throttle(func, wait, options) {
      var leading = true,
          trailing = true;

      if (typeof func != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }
      if (options === false) {
        leading = false;
      } else if (isObject(options)) {
        leading = 'leading' in options ? !!options.leading : leading;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }
      return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
    }

    /**
     * Creates a function that provides `value` to the wrapper function as its
     * first argument. Any additional arguments provided to the function are
     * appended to those provided to the wrapper function. The wrapper is invoked
     * with the `this` binding of the created function.
     *
     * @static
     * @memberOf _
     * @category Function
     * @param {*} value The value to wrap.
     * @param {Function} wrapper The wrapper function.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var p = _.wrap(_.escape, function(func, text) {
     *   return '<p>' + func(text) + '</p>';
     * });
     *
     * p('fred, barney, & pebbles');
     * // => '<p>fred, barney, &amp; pebbles</p>'
     */
    function wrap(value, wrapper) {
      wrapper = wrapper == null ? identity : wrapper;
      return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,
     * otherwise they are assigned by reference. If `customizer` is provided it is
     * invoked to produce the cloned values. If `customizer` returns `undefined`
     * cloning is handled by the method instead. The `customizer` is bound to
     * `thisArg` and invoked with two argument; (value [, index|key, object]).
     *
     * **Note:** This method is loosely based on the
     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
     * The enumerable properties of `arguments` objects and objects created by
     * constructors other than `Object` are cloned to plain `Object` objects. An
     * empty object is returned for uncloneable values such as functions, DOM nodes,
     * Maps, Sets, and WeakMaps.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to clone.
     * @param {boolean} [isDeep] Specify a deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {*} Returns the cloned value.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * var shallow = _.clone(users);
     * shallow[0] === users[0];
     * // => true
     *
     * var deep = _.clone(users, true);
     * deep[0] === users[0];
     * // => false
     *
     * // using a customizer callback
     * var el = _.clone(document.body, function(value) {
     *   if (_.isElement(value)) {
     *     return value.cloneNode(false);
     *   }
     * });
     *
     * el === document.body
     * // => false
     * el.nodeName
     * // => BODY
     * el.childNodes.length;
     * // => 0
     */
    function clone(value, isDeep, customizer, thisArg) {
      if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
        isDeep = false;
      }
      else if (typeof isDeep == 'function') {
        thisArg = customizer;
        customizer = isDeep;
        isDeep = false;
      }
      return typeof customizer == 'function'
        ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1))
        : baseClone(value, isDeep);
    }

    /**
     * Creates a deep clone of `value`. If `customizer` is provided it is invoked
     * to produce the cloned values. If `customizer` returns `undefined` cloning
     * is handled by the method instead. The `customizer` is bound to `thisArg`
     * and invoked with two argument; (value [, index|key, object]).
     *
     * **Note:** This method is loosely based on the
     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
     * The enumerable properties of `arguments` objects and objects created by
     * constructors other than `Object` are cloned to plain `Object` objects. An
     * empty object is returned for uncloneable values such as functions, DOM nodes,
     * Maps, Sets, and WeakMaps.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to deep clone.
     * @param {Function} [customizer] The function to customize cloning values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {*} Returns the deep cloned value.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * var deep = _.cloneDeep(users);
     * deep[0] === users[0];
     * // => false
     *
     * // using a customizer callback
     * var el = _.cloneDeep(document.body, function(value) {
     *   if (_.isElement(value)) {
     *     return value.cloneNode(true);
     *   }
     * });
     *
     * el === document.body
     * // => false
     * el.nodeName
     * // => BODY
     * el.childNodes.length;
     * // => 20
     */
    function cloneDeep(value, customizer, thisArg) {
      return typeof customizer == 'function'
        ? baseClone(value, true, bindCallback(customizer, thisArg, 1))
        : baseClone(value, true);
    }

    /**
     * Checks if `value` is greater than `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
     * @example
     *
     * _.gt(3, 1);
     * // => true
     *
     * _.gt(3, 3);
     * // => false
     *
     * _.gt(1, 3);
     * // => false
     */
    function gt(value, other) {
      return value > other;
    }

    /**
     * Checks if `value` is greater than or equal to `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
     * @example
     *
     * _.gte(3, 1);
     * // => true
     *
     * _.gte(3, 3);
     * // => true
     *
     * _.gte(1, 3);
     * // => false
     */
    function gte(value, other) {
      return value >= other;
    }

    /**
     * Checks if `value` is classified as an `arguments` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isArguments(function() { return arguments; }());
     * // => true
     *
     * _.isArguments([1, 2, 3]);
     * // => false
     */
    function isArguments(value) {
      return isObjectLike(value) && isArrayLike(value) &&
        hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
    }

    /**
     * Checks if `value` is classified as an `Array` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isArray([1, 2, 3]);
     * // => true
     *
     * _.isArray(function() { return arguments; }());
     * // => false
     */
    var isArray = nativeIsArray || function(value) {
      return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
    };

    /**
     * Checks if `value` is classified as a boolean primitive or object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isBoolean(false);
     * // => true
     *
     * _.isBoolean(null);
     * // => false
     */
    function isBoolean(value) {
      return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
    }

    /**
     * Checks if `value` is classified as a `Date` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isDate(new Date);
     * // => true
     *
     * _.isDate('Mon April 23 2012');
     * // => false
     */
    function isDate(value) {
      return isObjectLike(value) && objToString.call(value) == dateTag;
    }

    /**
     * Checks if `value` is a DOM element.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
     * @example
     *
     * _.isElement(document.body);
     * // => true
     *
     * _.isElement('<body>');
     * // => false
     */
    function isElement(value) {
      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
    }

    /**
     * Checks if `value` is empty. A value is considered empty unless it is an
     * `arguments` object, array, string, or jQuery-like collection with a length
     * greater than `0` or an object with own enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {Array|Object|string} value The value to inspect.
     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
     * @example
     *
     * _.isEmpty(null);
     * // => true
     *
     * _.isEmpty(true);
     * // => true
     *
     * _.isEmpty(1);
     * // => true
     *
     * _.isEmpty([1, 2, 3]);
     * // => false
     *
     * _.isEmpty({ 'a': 1 });
     * // => false
     */
    function isEmpty(value) {
      if (value == null) {
        return true;
      }
      if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
          (isObjectLike(value) && isFunction(value.splice)))) {
        return !value.length;
      }
      return !keys(value).length;
    }

    /**
     * Performs a deep comparison between two values to determine if they are
     * equivalent. If `customizer` is provided it is invoked to compare values.
     * If `customizer` returns `undefined` comparisons are handled by the method
     * instead. The `customizer` is bound to `thisArg` and invoked with three
     * arguments: (value, other [, index|key]).
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. Functions and DOM nodes
     * are **not** supported. Provide a customizer function to extend support
     * for comparing other values.
     *
     * @static
     * @memberOf _
     * @alias eq
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @param {Function} [customizer] The function to customize value comparisons.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     * @example
     *
     * var object = { 'user': 'fred' };
     * var other = { 'user': 'fred' };
     *
     * object == other;
     * // => false
     *
     * _.isEqual(object, other);
     * // => true
     *
     * // using a customizer callback
     * var array = ['hello', 'goodbye'];
     * var other = ['hi', 'goodbye'];
     *
     * _.isEqual(array, other, function(value, other) {
     *   if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {
     *     return true;
     *   }
     * });
     * // => true
     */
    function isEqual(value, other, customizer, thisArg) {
      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
      var result = customizer ? customizer(value, other) : undefined;
      return  result === undefined ? baseIsEqual(value, other, customizer) : !!result;
    }

    /**
     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
     * `SyntaxError`, `TypeError`, or `URIError` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
     * @example
     *
     * _.isError(new Error);
     * // => true
     *
     * _.isError(Error);
     * // => false
     */
    function isError(value) {
      return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
    }

    /**
     * Checks if `value` is a finite primitive number.
     *
     * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
     * @example
     *
     * _.isFinite(10);
     * // => true
     *
     * _.isFinite('10');
     * // => false
     *
     * _.isFinite(true);
     * // => false
     *
     * _.isFinite(Object(10));
     * // => false
     *
     * _.isFinite(Infinity);
     * // => false
     */
    function isFinite(value) {
      return typeof value == 'number' && nativeIsFinite(value);
    }

    /**
     * Checks if `value` is classified as a `Function` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isFunction(_);
     * // => true
     *
     * _.isFunction(/abc/);
     * // => false
     */
    function isFunction(value) {
      // The use of `Object#toString` avoids issues with the `typeof` operator
      // in older versions of Chrome and Safari which return 'function' for regexes
      // and Safari 8 equivalents which return 'object' for typed array constructors.
      return isObject(value) && objToString.call(value) == funcTag;
    }

    /**
     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(1);
     * // => false
     */
    function isObject(value) {
      // Avoid a V8 JIT bug in Chrome 19-20.
      // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
      var type = typeof value;
      return !!value && (type == 'object' || type == 'function');
    }

    /**
     * Performs a deep comparison between `object` and `source` to determine if
     * `object` contains equivalent property values. If `customizer` is provided
     * it is invoked to compare values. If `customizer` returns `undefined`
     * comparisons are handled by the method instead. The `customizer` is bound
     * to `thisArg` and invoked with three arguments: (value, other, index|key).
     *
     * **Note:** This method supports comparing properties of arrays, booleans,
     * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions
     * and DOM nodes are **not** supported. Provide a customizer function to extend
     * support for comparing other values.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {Object} object The object to inspect.
     * @param {Object} source The object of property values to match.
     * @param {Function} [customizer] The function to customize value comparisons.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.isMatch(object, { 'age': 40 });
     * // => true
     *
     * _.isMatch(object, { 'age': 36 });
     * // => false
     *
     * // using a customizer callback
     * var object = { 'greeting': 'hello' };
     * var source = { 'greeting': 'hi' };
     *
     * _.isMatch(object, source, function(value, other) {
     *   return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;
     * });
     * // => true
     */
    function isMatch(object, source, customizer, thisArg) {
      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
      return baseIsMatch(object, getMatchData(source), customizer);
    }

    /**
     * Checks if `value` is `NaN`.
     *
     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
     * which returns `true` for `undefined` and other non-numeric values.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
     * @example
     *
     * _.isNaN(NaN);
     * // => true
     *
     * _.isNaN(new Number(NaN));
     * // => true
     *
     * isNaN(undefined);
     * // => true
     *
     * _.isNaN(undefined);
     * // => false
     */
    function isNaN(value) {
      // An `NaN` primitive is the only value that is not equal to itself.
      // Perform the `toStringTag` check first to avoid errors with some host objects in IE.
      return isNumber(value) && value != +value;
    }

    /**
     * Checks if `value` is a native function.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
     * @example
     *
     * _.isNative(Array.prototype.push);
     * // => true
     *
     * _.isNative(_);
     * // => false
     */
    function isNative(value) {
      if (value == null) {
        return false;
      }
      if (isFunction(value)) {
        return reIsNative.test(fnToString.call(value));
      }
      return isObjectLike(value) && reIsHostCtor.test(value);
    }

    /**
     * Checks if `value` is `null`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
     * @example
     *
     * _.isNull(null);
     * // => true
     *
     * _.isNull(void 0);
     * // => false
     */
    function isNull(value) {
      return value === null;
    }

    /**
     * Checks if `value` is classified as a `Number` primitive or object.
     *
     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
     * as numbers, use the `_.isFinite` method.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isNumber(8.4);
     * // => true
     *
     * _.isNumber(NaN);
     * // => true
     *
     * _.isNumber('8.4');
     * // => false
     */
    function isNumber(value) {
      return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
    }

    /**
     * Checks if `value` is a plain object, that is, an object created by the
     * `Object` constructor or one with a `[[Prototype]]` of `null`.
     *
     * **Note:** This method assumes objects created by the `Object` constructor
     * have no inherited enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     * }
     *
     * _.isPlainObject(new Foo);
     * // => false
     *
     * _.isPlainObject([1, 2, 3]);
     * // => false
     *
     * _.isPlainObject({ 'x': 0, 'y': 0 });
     * // => true
     *
     * _.isPlainObject(Object.create(null));
     * // => true
     */
    function isPlainObject(value) {
      var Ctor;

      // Exit early for non `Object` objects.
      if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
          (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
        return false;
      }
      // IE < 9 iterates inherited properties before own properties. If the first
      // iterated property is an object's own property then there are no inherited
      // enumerable properties.
      var result;
      // In most environments an object's own properties are iterated before
      // its inherited properties. If the last iterated property is an object's
      // own property then there are no inherited enumerable properties.
      baseForIn(value, function(subValue, key) {
        result = key;
      });
      return result === undefined || hasOwnProperty.call(value, result);
    }

    /**
     * Checks if `value` is classified as a `RegExp` object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isRegExp(/abc/);
     * // => true
     *
     * _.isRegExp('/abc/');
     * // => false
     */
    function isRegExp(value) {
      return isObject(value) && objToString.call(value) == regexpTag;
    }

    /**
     * Checks if `value` is classified as a `String` primitive or object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isString('abc');
     * // => true
     *
     * _.isString(1);
     * // => false
     */
    function isString(value) {
      return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
    }

    /**
     * Checks if `value` is classified as a typed array.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
     * @example
     *
     * _.isTypedArray(new Uint8Array);
     * // => true
     *
     * _.isTypedArray([]);
     * // => false
     */
    function isTypedArray(value) {
      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
    }

    /**
     * Checks if `value` is `undefined`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
     * @example
     *
     * _.isUndefined(void 0);
     * // => true
     *
     * _.isUndefined(null);
     * // => false
     */
    function isUndefined(value) {
      return value === undefined;
    }

    /**
     * Checks if `value` is less than `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
     * @example
     *
     * _.lt(1, 3);
     * // => true
     *
     * _.lt(3, 3);
     * // => false
     *
     * _.lt(3, 1);
     * // => false
     */
    function lt(value, other) {
      return value < other;
    }

    /**
     * Checks if `value` is less than or equal to `other`.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
     * @example
     *
     * _.lte(1, 3);
     * // => true
     *
     * _.lte(3, 3);
     * // => true
     *
     * _.lte(3, 1);
     * // => false
     */
    function lte(value, other) {
      return value <= other;
    }

    /**
     * Converts `value` to an array.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {Array} Returns the converted array.
     * @example
     *
     * (function() {
     *   return _.toArray(arguments).slice(1);
     * }(1, 2, 3));
     * // => [2, 3]
     */
    function toArray(value) {
      var length = value ? getLength(value) : 0;
      if (!isLength(length)) {
        return values(value);
      }
      if (!length) {
        return [];
      }
      return arrayCopy(value);
    }

    /**
     * Converts `value` to a plain object flattening inherited enumerable
     * properties of `value` to own properties of the plain object.
     *
     * @static
     * @memberOf _
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {Object} Returns the converted plain object.
     * @example
     *
     * function Foo() {
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.assign({ 'a': 1 }, new Foo);
     * // => { 'a': 1, 'b': 2 }
     *
     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
     * // => { 'a': 1, 'b': 2, 'c': 3 }
     */
    function toPlainObject(value) {
      return baseCopy(value, keysIn(value));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Recursively merges own enumerable properties of the source object(s), that
     * don't resolve to `undefined` into the destination object. Subsequent sources
     * overwrite property assignments of previous sources. If `customizer` is
     * provided it is invoked to produce the merged values of the destination and
     * source properties. If `customizer` returns `undefined` merging is handled
     * by the method instead. The `customizer` is bound to `thisArg` and invoked
     * with five arguments: (objectValue, sourceValue, key, object, source).
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @param {Function} [customizer] The function to customize assigned values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var users = {
     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
     * };
     *
     * var ages = {
     *   'data': [{ 'age': 36 }, { 'age': 40 }]
     * };
     *
     * _.merge(users, ages);
     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
     *
     * // using a customizer callback
     * var object = {
     *   'fruits': ['apple'],
     *   'vegetables': ['beet']
     * };
     *
     * var other = {
     *   'fruits': ['banana'],
     *   'vegetables': ['carrot']
     * };
     *
     * _.merge(object, other, function(a, b) {
     *   if (_.isArray(a)) {
     *     return a.concat(b);
     *   }
     * });
     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
     */
    var merge = createAssigner(baseMerge);

    /**
     * Assigns own enumerable properties of source object(s) to the destination
     * object. Subsequent sources overwrite property assignments of previous sources.
     * If `customizer` is provided it is invoked to produce the assigned values.
     * The `customizer` is bound to `thisArg` and invoked with five arguments:
     * (objectValue, sourceValue, key, object, source).
     *
     * **Note:** This method mutates `object` and is based on
     * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
     *
     * @static
     * @memberOf _
     * @alias extend
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @param {Function} [customizer] The function to customize assigned values.
     * @param {*} [thisArg] The `this` binding of `customizer`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
     * // => { 'user': 'fred', 'age': 40 }
     *
     * // using a customizer callback
     * var defaults = _.partialRight(_.assign, function(value, other) {
     *   return _.isUndefined(value) ? other : value;
     * });
     *
     * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
     * // => { 'user': 'barney', 'age': 36 }
     */
    var assign = createAssigner(function(object, source, customizer) {
      return customizer
        ? assignWith(object, source, customizer)
        : baseAssign(object, source);
    });

    /**
     * Creates an object that inherits from the given `prototype` object. If a
     * `properties` object is provided its own enumerable properties are assigned
     * to the created object.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} prototype The object to inherit from.
     * @param {Object} [properties] The properties to assign to the object.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * function Shape() {
     *   this.x = 0;
     *   this.y = 0;
     * }
     *
     * function Circle() {
     *   Shape.call(this);
     * }
     *
     * Circle.prototype = _.create(Shape.prototype, {
     *   'constructor': Circle
     * });
     *
     * var circle = new Circle;
     * circle instanceof Circle;
     * // => true
     *
     * circle instanceof Shape;
     * // => true
     */
    function create(prototype, properties, guard) {
      var result = baseCreate(prototype);
      if (guard && isIterateeCall(prototype, properties, guard)) {
        properties = undefined;
      }
      return properties ? baseAssign(result, properties) : result;
    }

    /**
     * Assigns own enumerable properties of source object(s) to the destination
     * object for all destination properties that resolve to `undefined`. Once a
     * property is set, additional values of the same property are ignored.
     *
     * **Note:** This method mutates `object`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
     * // => { 'user': 'barney', 'age': 36 }
     */
    var defaults = createDefaults(assign, assignDefaults);

    /**
     * This method is like `_.defaults` except that it recursively assigns
     * default properties.
     *
     * **Note:** This method mutates `object`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @returns {Object} Returns `object`.
     * @example
     *
     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
     * // => { 'user': { 'name': 'barney', 'age': 36 } }
     *
     */
    var defaultsDeep = createDefaults(merge, mergeDefaults);

    /**
     * This method is like `_.find` except that it returns the key of the first
     * element `predicate` returns truthy for instead of the element itself.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
     * @example
     *
     * var users = {
     *   'barney':  { 'age': 36, 'active': true },
     *   'fred':    { 'age': 40, 'active': false },
     *   'pebbles': { 'age': 1,  'active': true }
     * };
     *
     * _.findKey(users, function(chr) {
     *   return chr.age < 40;
     * });
     * // => 'barney' (iteration order is not guaranteed)
     *
     * // using the `_.matches` callback shorthand
     * _.findKey(users, { 'age': 1, 'active': true });
     * // => 'pebbles'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findKey(users, 'active', false);
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.findKey(users, 'active');
     * // => 'barney'
     */
    var findKey = createFindKey(baseForOwn);

    /**
     * This method is like `_.findKey` except that it iterates over elements of
     * a collection in the opposite order.
     *
     * If a property name is provided for `predicate` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `predicate` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to search.
     * @param {Function|Object|string} [predicate=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
     * @example
     *
     * var users = {
     *   'barney':  { 'age': 36, 'active': true },
     *   'fred':    { 'age': 40, 'active': false },
     *   'pebbles': { 'age': 1,  'active': true }
     * };
     *
     * _.findLastKey(users, function(chr) {
     *   return chr.age < 40;
     * });
     * // => returns `pebbles` assuming `_.findKey` returns `barney`
     *
     * // using the `_.matches` callback shorthand
     * _.findLastKey(users, { 'age': 36, 'active': true });
     * // => 'barney'
     *
     * // using the `_.matchesProperty` callback shorthand
     * _.findLastKey(users, 'active', false);
     * // => 'fred'
     *
     * // using the `_.property` callback shorthand
     * _.findLastKey(users, 'active');
     * // => 'pebbles'
     */
    var findLastKey = createFindKey(baseForOwnRight);

    /**
     * Iterates over own and inherited enumerable properties of an object invoking
     * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked
     * with three arguments: (value, key, object). Iteratee functions may exit
     * iteration early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forIn(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
     */
    var forIn = createForIn(baseFor);

    /**
     * This method is like `_.forIn` except that it iterates over properties of
     * `object` in the opposite order.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forInRight(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
     */
    var forInRight = createForIn(baseForRight);

    /**
     * Iterates over own enumerable properties of an object invoking `iteratee`
     * for each property. The `iteratee` is bound to `thisArg` and invoked with
     * three arguments: (value, key, object). Iteratee functions may exit iteration
     * early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forOwn(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'a' and 'b' (iteration order is not guaranteed)
     */
    var forOwn = createForOwn(baseForOwn);

    /**
     * This method is like `_.forOwn` except that it iterates over properties of
     * `object` in the opposite order.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns `object`.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.forOwnRight(new Foo, function(value, key) {
     *   console.log(key);
     * });
     * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
     */
    var forOwnRight = createForOwn(baseForOwnRight);

    /**
     * Creates an array of function property names from all enumerable properties,
     * own and inherited, of `object`.
     *
     * @static
     * @memberOf _
     * @alias methods
     * @category Object
     * @param {Object} object The object to inspect.
     * @returns {Array} Returns the new array of property names.
     * @example
     *
     * _.functions(_);
     * // => ['after', 'ary', 'assign', ...]
     */
    function functions(object) {
      return baseFunctions(object, keysIn(object));
    }

    /**
     * Gets the property value at `path` of `object`. If the resolved value is
     * `undefined` the `defaultValue` is used in its place.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the property to get.
     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
     * @returns {*} Returns the resolved value.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
     *
     * _.get(object, 'a[0].b.c');
     * // => 3
     *
     * _.get(object, ['a', '0', 'b', 'c']);
     * // => 3
     *
     * _.get(object, 'a.b.c', 'default');
     * // => 'default'
     */
    function get(object, path, defaultValue) {
      var result = object == null ? undefined : baseGet(object, toPath(path), path + '');
      return result === undefined ? defaultValue : result;
    }

    /**
     * Checks if `path` is a direct property.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path to check.
     * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.
     * @example
     *
     * var object = { 'a': { 'b': { 'c': 3 } } };
     *
     * _.has(object, 'a');
     * // => true
     *
     * _.has(object, 'a.b.c');
     * // => true
     *
     * _.has(object, ['a', 'b', 'c']);
     * // => true
     */
    function has(object, path) {
      if (object == null) {
        return false;
      }
      var result = hasOwnProperty.call(object, path);
      if (!result && !isKey(path)) {
        path = toPath(path);
        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
        if (object == null) {
          return false;
        }
        path = last(path);
        result = hasOwnProperty.call(object, path);
      }
      return result || (isLength(object.length) && isIndex(path, object.length) &&
        (isArray(object) || isArguments(object)));
    }

    /**
     * Creates an object composed of the inverted keys and values of `object`.
     * If `object` contains duplicate values, subsequent values overwrite property
     * assignments of previous values unless `multiValue` is `true`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to invert.
     * @param {boolean} [multiValue] Allow multiple values per key.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invert(object);
     * // => { '1': 'c', '2': 'b' }
     *
     * // with `multiValue`
     * _.invert(object, true);
     * // => { '1': ['a', 'c'], '2': ['b'] }
     */
    function invert(object, multiValue, guard) {
      if (guard && isIterateeCall(object, multiValue, guard)) {
        multiValue = undefined;
      }
      var index = -1,
          props = keys(object),
          length = props.length,
          result = {};

      while (++index < length) {
        var key = props[index],
            value = object[key];

        if (multiValue) {
          if (hasOwnProperty.call(result, value)) {
            result[value].push(key);
          } else {
            result[value] = [key];
          }
        }
        else {
          result[value] = key;
        }
      }
      return result;
    }

    /**
     * Creates an array of the own enumerable property names of `object`.
     *
     * **Note:** Non-object values are coerced to objects. See the
     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
     * for more details.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.keys(new Foo);
     * // => ['a', 'b'] (iteration order is not guaranteed)
     *
     * _.keys('hi');
     * // => ['0', '1']
     */
    var keys = !nativeKeys ? shimKeys : function(object) {
      var Ctor = object == null ? undefined : object.constructor;
      if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
          (typeof object != 'function' && isArrayLike(object))) {
        return shimKeys(object);
      }
      return isObject(object) ? nativeKeys(object) : [];
    };

    /**
     * Creates an array of the own and inherited enumerable property names of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property names.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.keysIn(new Foo);
     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
     */
    function keysIn(object) {
      if (object == null) {
        return [];
      }
      if (!isObject(object)) {
        object = Object(object);
      }
      var length = object.length;
      length = (length && isLength(length) &&
        (isArray(object) || isArguments(object)) && length) || 0;

      var Ctor = object.constructor,
          index = -1,
          isProto = typeof Ctor == 'function' && Ctor.prototype === object,
          result = Array(length),
          skipIndexes = length > 0;

      while (++index < length) {
        result[index] = (index + '');
      }
      for (var key in object) {
        if (!(skipIndexes && isIndex(key, length)) &&
            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
          result.push(key);
        }
      }
      return result;
    }

    /**
     * The opposite of `_.mapValues`; this method creates an object with the
     * same values as `object` and keys generated by running each own enumerable
     * property of `object` through `iteratee`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the new mapped object.
     * @example
     *
     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
     *   return key + value;
     * });
     * // => { 'a1': 1, 'b2': 2 }
     */
    var mapKeys = createObjectMapper(true);

    /**
     * Creates an object with the same keys as `object` and values generated by
     * running each own enumerable property of `object` through `iteratee`. The
     * iteratee function is bound to `thisArg` and invoked with three arguments:
     * (value, key, object).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to iterate over.
     * @param {Function|Object|string} [iteratee=_.identity] The function invoked
     *  per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Object} Returns the new mapped object.
     * @example
     *
     * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {
     *   return n * 3;
     * });
     * // => { 'a': 3, 'b': 6 }
     *
     * var users = {
     *   'fred':    { 'user': 'fred',    'age': 40 },
     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
     * };
     *
     * // using the `_.property` callback shorthand
     * _.mapValues(users, 'age');
     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
     */
    var mapValues = createObjectMapper();

    /**
     * The opposite of `_.pick`; this method creates an object composed of the
     * own and inherited enumerable properties of `object` that are not omitted.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The source object.
     * @param {Function|...(string|string[])} [predicate] The function invoked per
     *  iteration or property names to omit, specified as individual property
     *  names or arrays of property names.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.omit(object, 'age');
     * // => { 'user': 'fred' }
     *
     * _.omit(object, _.isNumber);
     * // => { 'user': 'fred' }
     */
    var omit = restParam(function(object, props) {
      if (object == null) {
        return {};
      }
      if (typeof props[0] != 'function') {
        var props = arrayMap(baseFlatten(props), String);
        return pickByArray(object, baseDifference(keysIn(object), props));
      }
      var predicate = bindCallback(props[0], props[1], 3);
      return pickByCallback(object, function(value, key, object) {
        return !predicate(value, key, object);
      });
    });

    /**
     * Creates a two dimensional array of the key-value pairs for `object`,
     * e.g. `[[key1, value1], [key2, value2]]`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the new array of key-value pairs.
     * @example
     *
     * _.pairs({ 'barney': 36, 'fred': 40 });
     * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
     */
    function pairs(object) {
      object = toObject(object);

      var index = -1,
          props = keys(object),
          length = props.length,
          result = Array(length);

      while (++index < length) {
        var key = props[index];
        result[index] = [key, object[key]];
      }
      return result;
    }

    /**
     * Creates an object composed of the picked `object` properties. Property
     * names may be specified as individual arguments or as arrays of property
     * names. If `predicate` is provided it is invoked for each property of `object`
     * picking the properties `predicate` returns truthy for. The predicate is
     * bound to `thisArg` and invoked with three arguments: (value, key, object).
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The source object.
     * @param {Function|...(string|string[])} [predicate] The function invoked per
     *  iteration or property names to pick, specified as individual property
     *  names or arrays of property names.
     * @param {*} [thisArg] The `this` binding of `predicate`.
     * @returns {Object} Returns the new object.
     * @example
     *
     * var object = { 'user': 'fred', 'age': 40 };
     *
     * _.pick(object, 'user');
     * // => { 'user': 'fred' }
     *
     * _.pick(object, _.isString);
     * // => { 'user': 'fred' }
     */
    var pick = restParam(function(object, props) {
      if (object == null) {
        return {};
      }
      return typeof props[0] == 'function'
        ? pickByCallback(object, bindCallback(props[0], props[1], 3))
        : pickByArray(object, baseFlatten(props));
    });

    /**
     * This method is like `_.get` except that if the resolved value is a function
     * it is invoked with the `this` binding of its parent object and its result
     * is returned.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the property to resolve.
     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
     * @returns {*} Returns the resolved value.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
     *
     * _.result(object, 'a[0].b.c1');
     * // => 3
     *
     * _.result(object, 'a[0].b.c2');
     * // => 4
     *
     * _.result(object, 'a.b.c', 'default');
     * // => 'default'
     *
     * _.result(object, 'a.b.c', _.constant('default'));
     * // => 'default'
     */
    function result(object, path, defaultValue) {
      var result = object == null ? undefined : object[path];
      if (result === undefined) {
        if (object != null && !isKey(path, object)) {
          path = toPath(path);
          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
          result = object == null ? undefined : object[last(path)];
        }
        result = result === undefined ? defaultValue : result;
      }
      return isFunction(result) ? result.call(object) : result;
    }

    /**
     * Sets the property value of `path` on `object`. If a portion of `path`
     * does not exist it is created.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to augment.
     * @param {Array|string} path The path of the property to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
     *
     * _.set(object, 'a[0].b.c', 4);
     * console.log(object.a[0].b.c);
     * // => 4
     *
     * _.set(object, 'x[0].y.z', 5);
     * console.log(object.x[0].y.z);
     * // => 5
     */
    function set(object, path, value) {
      if (object == null) {
        return object;
      }
      var pathKey = (path + '');
      path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);

      var index = -1,
          length = path.length,
          lastIndex = length - 1,
          nested = object;

      while (nested != null && ++index < length) {
        var key = path[index];
        if (isObject(nested)) {
          if (index == lastIndex) {
            nested[key] = value;
          } else if (nested[key] == null) {
            nested[key] = isIndex(path[index + 1]) ? [] : {};
          }
        }
        nested = nested[key];
      }
      return object;
    }

    /**
     * An alternative to `_.reduce`; this method transforms `object` to a new
     * `accumulator` object which is the result of running each of its own enumerable
     * properties through `iteratee`, with each invocation potentially mutating
     * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked
     * with four arguments: (accumulator, value, key, object). Iteratee functions
     * may exit iteration early by explicitly returning `false`.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Array|Object} object The object to iterate over.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [accumulator] The custom accumulator value.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the accumulated value.
     * @example
     *
     * _.transform([2, 3, 4], function(result, n) {
     *   result.push(n *= n);
     *   return n % 2 == 0;
     * });
     * // => [4, 9]
     *
     * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {
     *   result[key] = n * 3;
     * });
     * // => { 'a': 3, 'b': 6 }
     */
    function transform(object, iteratee, accumulator, thisArg) {
      var isArr = isArray(object) || isTypedArray(object);
      iteratee = getCallback(iteratee, thisArg, 4);

      if (accumulator == null) {
        if (isArr || isObject(object)) {
          var Ctor = object.constructor;
          if (isArr) {
            accumulator = isArray(object) ? new Ctor : [];
          } else {
            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
          }
        } else {
          accumulator = {};
        }
      }
      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
        return iteratee(accumulator, value, index, object);
      });
      return accumulator;
    }

    /**
     * Creates an array of the own enumerable property values of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property values.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.values(new Foo);
     * // => [1, 2] (iteration order is not guaranteed)
     *
     * _.values('hi');
     * // => ['h', 'i']
     */
    function values(object) {
      return baseValues(object, keys(object));
    }

    /**
     * Creates an array of the own and inherited enumerable property values
     * of `object`.
     *
     * **Note:** Non-object values are coerced to objects.
     *
     * @static
     * @memberOf _
     * @category Object
     * @param {Object} object The object to query.
     * @returns {Array} Returns the array of property values.
     * @example
     *
     * function Foo() {
     *   this.a = 1;
     *   this.b = 2;
     * }
     *
     * Foo.prototype.c = 3;
     *
     * _.valuesIn(new Foo);
     * // => [1, 2, 3] (iteration order is not guaranteed)
     */
    function valuesIn(object) {
      return baseValues(object, keysIn(object));
    }

    /*------------------------------------------------------------------------*/

    /**
     * Checks if `n` is between `start` and up to but not including, `end`. If
     * `end` is not specified it is set to `start` with `start` then set to `0`.
     *
     * @static
     * @memberOf _
     * @category Number
     * @param {number} n The number to check.
     * @param {number} [start=0] The start of the range.
     * @param {number} end The end of the range.
     * @returns {boolean} Returns `true` if `n` is in the range, else `false`.
     * @example
     *
     * _.inRange(3, 2, 4);
     * // => true
     *
     * _.inRange(4, 8);
     * // => true
     *
     * _.inRange(4, 2);
     * // => false
     *
     * _.inRange(2, 2);
     * // => false
     *
     * _.inRange(1.2, 2);
     * // => true
     *
     * _.inRange(5.2, 4);
     * // => false
     */
    function inRange(value, start, end) {
      start = +start || 0;
      if (end === undefined) {
        end = start;
        start = 0;
      } else {
        end = +end || 0;
      }
      return value >= nativeMin(start, end) && value < nativeMax(start, end);
    }

    /**
     * Produces a random number between `min` and `max` (inclusive). If only one
     * argument is provided a number between `0` and the given number is returned.
     * If `floating` is `true`, or either `min` or `max` are floats, a floating-point
     * number is returned instead of an integer.
     *
     * @static
     * @memberOf _
     * @category Number
     * @param {number} [min=0] The minimum possible value.
     * @param {number} [max=1] The maximum possible value.
     * @param {boolean} [floating] Specify returning a floating-point number.
     * @returns {number} Returns the random number.
     * @example
     *
     * _.random(0, 5);
     * // => an integer between 0 and 5
     *
     * _.random(5);
     * // => also an integer between 0 and 5
     *
     * _.random(5, true);
     * // => a floating-point number between 0 and 5
     *
     * _.random(1.2, 5.2);
     * // => a floating-point number between 1.2 and 5.2
     */
    function random(min, max, floating) {
      if (floating && isIterateeCall(min, max, floating)) {
        max = floating = undefined;
      }
      var noMin = min == null,
          noMax = max == null;

      if (floating == null) {
        if (noMax && typeof min == 'boolean') {
          floating = min;
          min = 1;
        }
        else if (typeof max == 'boolean') {
          floating = max;
          noMax = true;
        }
      }
      if (noMin && noMax) {
        max = 1;
        noMax = false;
      }
      min = +min || 0;
      if (noMax) {
        max = min;
        min = 0;
      } else {
        max = +max || 0;
      }
      if (floating || min % 1 || max % 1) {
        var rand = nativeRandom();
        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
      }
      return baseRandom(min, max);
    }

    /*------------------------------------------------------------------------*/

    /**
     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the camel cased string.
     * @example
     *
     * _.camelCase('Foo Bar');
     * // => 'fooBar'
     *
     * _.camelCase('--foo-bar');
     * // => 'fooBar'
     *
     * _.camelCase('__foo_bar__');
     * // => 'fooBar'
     */
    var camelCase = createCompounder(function(result, word, index) {
      word = word.toLowerCase();
      return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
    });

    /**
     * Capitalizes the first character of `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to capitalize.
     * @returns {string} Returns the capitalized string.
     * @example
     *
     * _.capitalize('fred');
     * // => 'Fred'
     */
    function capitalize(string) {
      string = baseToString(string);
      return string && (string.charAt(0).toUpperCase() + string.slice(1));
    }

    /**
     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to deburr.
     * @returns {string} Returns the deburred string.
     * @example
     *
     * _.deburr('déjà vu');
     * // => 'deja vu'
     */
    function deburr(string) {
      string = baseToString(string);
      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
    }

    /**
     * Checks if `string` ends with the given target string.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to search.
     * @param {string} [target] The string to search for.
     * @param {number} [position=string.length] The position to search from.
     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
     * @example
     *
     * _.endsWith('abc', 'c');
     * // => true
     *
     * _.endsWith('abc', 'b');
     * // => false
     *
     * _.endsWith('abc', 'b', 2);
     * // => true
     */
    function endsWith(string, target, position) {
      string = baseToString(string);
      target = (target + '');

      var length = string.length;
      position = position === undefined
        ? length
        : nativeMin(position < 0 ? 0 : (+position || 0), length);

      position -= target.length;
      return position >= 0 && string.indexOf(target, position) == position;
    }

    /**
     * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to
     * their corresponding HTML entities.
     *
     * **Note:** No other characters are escaped. To escape additional characters
     * use a third-party library like [_he_](https://mths.be/he).
     *
     * Though the ">" character is escaped for symmetry, characters like
     * ">" and "/" don't need escaping in HTML and have no special meaning
     * unless they're part of a tag or unquoted attribute value.
     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
     * (under "semi-related fun fact") for more details.
     *
     * Backticks are escaped because in Internet Explorer < 9, they can break out
     * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),
     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
     * for more details.
     *
     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
     * to reduce XSS vectors.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to escape.
     * @returns {string} Returns the escaped string.
     * @example
     *
     * _.escape('fred, barney, & pebbles');
     * // => 'fred, barney, &amp; pebbles'
     */
    function escape(string) {
      // Reset `lastIndex` because in IE < 9 `String#replace` does not.
      string = baseToString(string);
      return (string && reHasUnescapedHtml.test(string))
        ? string.replace(reUnescapedHtml, escapeHtmlChar)
        : string;
    }

    /**
     * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
     * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to escape.
     * @returns {string} Returns the escaped string.
     * @example
     *
     * _.escapeRegExp('[lodash](https://lodash.com/)');
     * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
     */
    function escapeRegExp(string) {
      string = baseToString(string);
      return (string && reHasRegExpChars.test(string))
        ? string.replace(reRegExpChars, escapeRegExpChar)
        : (string || '(?:)');
    }

    /**
     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the kebab cased string.
     * @example
     *
     * _.kebabCase('Foo Bar');
     * // => 'foo-bar'
     *
     * _.kebabCase('fooBar');
     * // => 'foo-bar'
     *
     * _.kebabCase('__foo_bar__');
     * // => 'foo-bar'
     */
    var kebabCase = createCompounder(function(result, word, index) {
      return result + (index ? '-' : '') + word.toLowerCase();
    });

    /**
     * Pads `string` on the left and right sides if it's shorter than `length`.
     * Padding characters are truncated if they can't be evenly divided by `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.pad('abc', 8);
     * // => '  abc   '
     *
     * _.pad('abc', 8, '_-');
     * // => '_-abc_-_'
     *
     * _.pad('abc', 3);
     * // => 'abc'
     */
    function pad(string, length, chars) {
      string = baseToString(string);
      length = +length;

      var strLength = string.length;
      if (strLength >= length || !nativeIsFinite(length)) {
        return string;
      }
      var mid = (length - strLength) / 2,
          leftLength = nativeFloor(mid),
          rightLength = nativeCeil(mid);

      chars = createPadding('', rightLength, chars);
      return chars.slice(0, leftLength) + string + chars;
    }

    /**
     * Pads `string` on the left side if it's shorter than `length`. Padding
     * characters are truncated if they exceed `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.padLeft('abc', 6);
     * // => '   abc'
     *
     * _.padLeft('abc', 6, '_-');
     * // => '_-_abc'
     *
     * _.padLeft('abc', 3);
     * // => 'abc'
     */
    var padLeft = createPadDir();

    /**
     * Pads `string` on the right side if it's shorter than `length`. Padding
     * characters are truncated if they exceed `length`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to pad.
     * @param {number} [length=0] The padding length.
     * @param {string} [chars=' '] The string used as padding.
     * @returns {string} Returns the padded string.
     * @example
     *
     * _.padRight('abc', 6);
     * // => 'abc   '
     *
     * _.padRight('abc', 6, '_-');
     * // => 'abc_-_'
     *
     * _.padRight('abc', 3);
     * // => 'abc'
     */
    var padRight = createPadDir(true);

    /**
     * Converts `string` to an integer of the specified radix. If `radix` is
     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
     * in which case a `radix` of `16` is used.
     *
     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
     * of `parseInt`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} string The string to convert.
     * @param {number} [radix] The radix to interpret `value` by.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {number} Returns the converted integer.
     * @example
     *
     * _.parseInt('08');
     * // => 8
     *
     * _.map(['6', '08', '10'], _.parseInt);
     * // => [6, 8, 10]
     */
    function parseInt(string, radix, guard) {
      // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
      // Chrome fails to trim leading <BOM> whitespace characters.
      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
      if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
        radix = 0;
      } else if (radix) {
        radix = +radix;
      }
      string = trim(string);
      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
    }

    /**
     * Repeats the given string `n` times.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to repeat.
     * @param {number} [n=0] The number of times to repeat the string.
     * @returns {string} Returns the repeated string.
     * @example
     *
     * _.repeat('*', 3);
     * // => '***'
     *
     * _.repeat('abc', 2);
     * // => 'abcabc'
     *
     * _.repeat('abc', 0);
     * // => ''
     */
    function repeat(string, n) {
      var result = '';
      string = baseToString(string);
      n = +n;
      if (n < 1 || !string || !nativeIsFinite(n)) {
        return result;
      }
      // Leverage the exponentiation by squaring algorithm for a faster repeat.
      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
      do {
        if (n % 2) {
          result += string;
        }
        n = nativeFloor(n / 2);
        string += string;
      } while (n);

      return result;
    }

    /**
     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the snake cased string.
     * @example
     *
     * _.snakeCase('Foo Bar');
     * // => 'foo_bar'
     *
     * _.snakeCase('fooBar');
     * // => 'foo_bar'
     *
     * _.snakeCase('--foo-bar');
     * // => 'foo_bar'
     */
    var snakeCase = createCompounder(function(result, word, index) {
      return result + (index ? '_' : '') + word.toLowerCase();
    });

    /**
     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to convert.
     * @returns {string} Returns the start cased string.
     * @example
     *
     * _.startCase('--foo-bar');
     * // => 'Foo Bar'
     *
     * _.startCase('fooBar');
     * // => 'Foo Bar'
     *
     * _.startCase('__foo_bar__');
     * // => 'Foo Bar'
     */
    var startCase = createCompounder(function(result, word, index) {
      return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
    });

    /**
     * Checks if `string` starts with the given target string.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to search.
     * @param {string} [target] The string to search for.
     * @param {number} [position=0] The position to search from.
     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
     * @example
     *
     * _.startsWith('abc', 'a');
     * // => true
     *
     * _.startsWith('abc', 'b');
     * // => false
     *
     * _.startsWith('abc', 'b', 1);
     * // => true
     */
    function startsWith(string, target, position) {
      string = baseToString(string);
      position = position == null
        ? 0
        : nativeMin(position < 0 ? 0 : (+position || 0), string.length);

      return string.lastIndexOf(target, position) == position;
    }

    /**
     * Creates a compiled template function that can interpolate data properties
     * in "interpolate" delimiters, HTML-escape interpolated data properties in
     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
     * properties may be accessed as free variables in the template. If a setting
     * object is provided it takes precedence over `_.templateSettings` values.
     *
     * **Note:** In the development build `_.template` utilizes
     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
     * for easier debugging.
     *
     * For more information on precompiling templates see
     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
     *
     * For more information on Chrome extension sandboxes see
     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The template string.
     * @param {Object} [options] The options object.
     * @param {RegExp} [options.escape] The HTML "escape" delimiter.
     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
     * @param {Object} [options.imports] An object to import into the template as free variables.
     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
     * @param {string} [options.variable] The data object variable name.
     * @param- {Object} [otherOptions] Enables the legacy `options` param signature.
     * @returns {Function} Returns the compiled template function.
     * @example
     *
     * // using the "interpolate" delimiter to create a compiled template
     * var compiled = _.template('hello <%= user %>!');
     * compiled({ 'user': 'fred' });
     * // => 'hello fred!'
     *
     * // using the HTML "escape" delimiter to escape data property values
     * var compiled = _.template('<b><%- value %></b>');
     * compiled({ 'value': '<script>' });
     * // => '<b>&lt;script&gt;</b>'
     *
     * // using the "evaluate" delimiter to execute JavaScript and generate HTML
     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
     * compiled({ 'users': ['fred', 'barney'] });
     * // => '<li>fred</li><li>barney</li>'
     *
     * // using the internal `print` function in "evaluate" delimiters
     * var compiled = _.template('<% print("hello " + user); %>!');
     * compiled({ 'user': 'barney' });
     * // => 'hello barney!'
     *
     * // using the ES delimiter as an alternative to the default "interpolate" delimiter
     * var compiled = _.template('hello ${ user }!');
     * compiled({ 'user': 'pebbles' });
     * // => 'hello pebbles!'
     *
     * // using custom template delimiters
     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
     * var compiled = _.template('hello {{ user }}!');
     * compiled({ 'user': 'mustache' });
     * // => 'hello mustache!'
     *
     * // using backslashes to treat delimiters as plain text
     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
     * compiled({ 'value': 'ignored' });
     * // => '<%- value %>'
     *
     * // using the `imports` option to import `jQuery` as `jq`
     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
     * compiled({ 'users': ['fred', 'barney'] });
     * // => '<li>fred</li><li>barney</li>'
     *
     * // using the `sourceURL` option to specify a custom sourceURL for the template
     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
     * compiled(data);
     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
     *
     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
     * compiled.source;
     * // => function(data) {
     * //   var __t, __p = '';
     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
     * //   return __p;
     * // }
     *
     * // using the `source` property to inline compiled templates for meaningful
     * // line numbers in error messages and a stack trace
     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
     *   var JST = {\
     *     "main": ' + _.template(mainText).source + '\
     *   };\
     * ');
     */
    function template(string, options, otherOptions) {
      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
      var settings = lodash.templateSettings;

      if (otherOptions && isIterateeCall(string, options, otherOptions)) {
        options = otherOptions = undefined;
      }
      string = baseToString(string);
      options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);

      var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
          importsKeys = keys(imports),
          importsValues = baseValues(imports, importsKeys);

      var isEscaping,
          isEvaluating,
          index = 0,
          interpolate = options.interpolate || reNoMatch,
          source = "__p += '";

      // Compile the regexp to match each delimiter.
      var reDelimiters = RegExp(
        (options.escape || reNoMatch).source + '|' +
        interpolate.source + '|' +
        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
        (options.evaluate || reNoMatch).source + '|$'
      , 'g');

      // Use a sourceURL for easier debugging.
      var sourceURL = '//# sourceURL=' +
        ('sourceURL' in options
          ? options.sourceURL
          : ('lodash.templateSources[' + (++templateCounter) + ']')
        ) + '\n';

      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
        interpolateValue || (interpolateValue = esTemplateValue);

        // Escape characters that can't be included in string literals.
        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);

        // Replace delimiters with snippets.
        if (escapeValue) {
          isEscaping = true;
          source += "' +\n__e(" + escapeValue + ") +\n'";
        }
        if (evaluateValue) {
          isEvaluating = true;
          source += "';\n" + evaluateValue + ";\n__p += '";
        }
        if (interpolateValue) {
          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
        }
        index = offset + match.length;

        // The JS engine embedded in Adobe products requires returning the `match`
        // string in order to produce the correct `offset` value.
        return match;
      });

      source += "';\n";

      // If `variable` is not specified wrap a with-statement around the generated
      // code to add the data object to the top of the scope chain.
      var variable = options.variable;
      if (!variable) {
        source = 'with (obj) {\n' + source + '\n}\n';
      }
      // Cleanup code by stripping empty strings.
      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
        .replace(reEmptyStringMiddle, '$1')
        .replace(reEmptyStringTrailing, '$1;');

      // Frame code as the function body.
      source = 'function(' + (variable || 'obj') + ') {\n' +
        (variable
          ? ''
          : 'obj || (obj = {});\n'
        ) +
        "var __t, __p = ''" +
        (isEscaping
           ? ', __e = _.escape'
           : ''
        ) +
        (isEvaluating
          ? ', __j = Array.prototype.join;\n' +
            "function print() { __p += __j.call(arguments, '') }\n"
          : ';\n'
        ) +
        source +
        'return __p\n}';

      var result = attempt(function() {
        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
      });

      // Provide the compiled function's source by its `toString` method or
      // the `source` property as a convenience for inlining compiled templates.
      result.source = source;
      if (isError(result)) {
        throw result;
      }
      return result;
    }

    /**
     * Removes leading and trailing whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trim('  abc  ');
     * // => 'abc'
     *
     * _.trim('-_-abc-_-', '_-');
     * // => 'abc'
     *
     * _.map(['  foo  ', '  bar  '], _.trim);
     * // => ['foo', 'bar']
     */
    function trim(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
      }
      chars = (chars + '');
      return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
    }

    /**
     * Removes leading whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trimLeft('  abc  ');
     * // => 'abc  '
     *
     * _.trimLeft('-_-abc-_-', '_-');
     * // => 'abc-_-'
     */
    function trimLeft(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(trimmedLeftIndex(string));
      }
      return string.slice(charsLeftIndex(string, (chars + '')));
    }

    /**
     * Removes trailing whitespace or specified characters from `string`.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to trim.
     * @param {string} [chars=whitespace] The characters to trim.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the trimmed string.
     * @example
     *
     * _.trimRight('  abc  ');
     * // => '  abc'
     *
     * _.trimRight('-_-abc-_-', '_-');
     * // => '-_-abc'
     */
    function trimRight(string, chars, guard) {
      var value = string;
      string = baseToString(string);
      if (!string) {
        return string;
      }
      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
        return string.slice(0, trimmedRightIndex(string) + 1);
      }
      return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
    }

    /**
     * Truncates `string` if it's longer than the given maximum string length.
     * The last characters of the truncated string are replaced with the omission
     * string which defaults to "...".
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to truncate.
     * @param {Object|number} [options] The options object or maximum string length.
     * @param {number} [options.length=30] The maximum string length.
     * @param {string} [options.omission='...'] The string to indicate text is omitted.
     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {string} Returns the truncated string.
     * @example
     *
     * _.trunc('hi-diddly-ho there, neighborino');
     * // => 'hi-diddly-ho there, neighbo...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', 24);
     * // => 'hi-diddly-ho there, n...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'length': 24,
     *   'separator': ' '
     * });
     * // => 'hi-diddly-ho there,...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'length': 24,
     *   'separator': /,? +/
     * });
     * // => 'hi-diddly-ho there...'
     *
     * _.trunc('hi-diddly-ho there, neighborino', {
     *   'omission': ' [...]'
     * });
     * // => 'hi-diddly-ho there, neig [...]'
     */
    function trunc(string, options, guard) {
      if (guard && isIterateeCall(string, options, guard)) {
        options = undefined;
      }
      var length = DEFAULT_TRUNC_LENGTH,
          omission = DEFAULT_TRUNC_OMISSION;

      if (options != null) {
        if (isObject(options)) {
          var separator = 'separator' in options ? options.separator : separator;
          length = 'length' in options ? (+options.length || 0) : length;
          omission = 'omission' in options ? baseToString(options.omission) : omission;
        } else {
          length = +options || 0;
        }
      }
      string = baseToString(string);
      if (length >= string.length) {
        return string;
      }
      var end = length - omission.length;
      if (end < 1) {
        return omission;
      }
      var result = string.slice(0, end);
      if (separator == null) {
        return result + omission;
      }
      if (isRegExp(separator)) {
        if (string.slice(end).search(separator)) {
          var match,
              newEnd,
              substring = string.slice(0, end);

          if (!separator.global) {
            separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');
          }
          separator.lastIndex = 0;
          while ((match = separator.exec(substring))) {
            newEnd = match.index;
          }
          result = result.slice(0, newEnd == null ? end : newEnd);
        }
      } else if (string.indexOf(separator, end) != end) {
        var index = result.lastIndexOf(separator);
        if (index > -1) {
          result = result.slice(0, index);
        }
      }
      return result + omission;
    }

    /**
     * The inverse of `_.escape`; this method converts the HTML entities
     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
     * corresponding characters.
     *
     * **Note:** No other HTML entities are unescaped. To unescape additional HTML
     * entities use a third-party library like [_he_](https://mths.be/he).
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to unescape.
     * @returns {string} Returns the unescaped string.
     * @example
     *
     * _.unescape('fred, barney, &amp; pebbles');
     * // => 'fred, barney, & pebbles'
     */
    function unescape(string) {
      string = baseToString(string);
      return (string && reHasEscapedHtml.test(string))
        ? string.replace(reEscapedHtml, unescapeHtmlChar)
        : string;
    }

    /**
     * Splits `string` into an array of its words.
     *
     * @static
     * @memberOf _
     * @category String
     * @param {string} [string=''] The string to inspect.
     * @param {RegExp|string} [pattern] The pattern to match words.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Array} Returns the words of `string`.
     * @example
     *
     * _.words('fred, barney, & pebbles');
     * // => ['fred', 'barney', 'pebbles']
     *
     * _.words('fred, barney, & pebbles', /[^, ]+/g);
     * // => ['fred', 'barney', '&', 'pebbles']
     */
    function words(string, pattern, guard) {
      if (guard && isIterateeCall(string, pattern, guard)) {
        pattern = undefined;
      }
      string = baseToString(string);
      return string.match(pattern || reWords) || [];
    }

    /*------------------------------------------------------------------------*/

    /**
     * Attempts to invoke `func`, returning either the result or the caught error
     * object. Any additional arguments are provided to `func` when it is invoked.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Function} func The function to attempt.
     * @returns {*} Returns the `func` result or error object.
     * @example
     *
     * // avoid throwing errors for invalid selectors
     * var elements = _.attempt(function(selector) {
     *   return document.querySelectorAll(selector);
     * }, '>_>');
     *
     * if (_.isError(elements)) {
     *   elements = [];
     * }
     */
    var attempt = restParam(function(func, args) {
      try {
        return func.apply(undefined, args);
      } catch(e) {
        return isError(e) ? e : new Error(e);
      }
    });

    /**
     * Creates a function that invokes `func` with the `this` binding of `thisArg`
     * and arguments of the created function. If `func` is a property name the
     * created callback returns the property value for a given element. If `func`
     * is an object the created callback returns `true` for elements that contain
     * the equivalent object properties, otherwise it returns `false`.
     *
     * @static
     * @memberOf _
     * @alias iteratee
     * @category Utility
     * @param {*} [func=_.identity] The value to convert to a callback.
     * @param {*} [thisArg] The `this` binding of `func`.
     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
     * @returns {Function} Returns the callback.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * // wrap to create custom callback shorthands
     * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {
     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(func);
     *   if (!match) {
     *     return callback(func, thisArg);
     *   }
     *   return function(object) {
     *     return match[2] == 'gt'
     *       ? object[match[1]] > match[3]
     *       : object[match[1]] < match[3];
     *   };
     * });
     *
     * _.filter(users, 'age__gt36');
     * // => [{ 'user': 'fred', 'age': 40 }]
     */
    function callback(func, thisArg, guard) {
      if (guard && isIterateeCall(func, thisArg, guard)) {
        thisArg = undefined;
      }
      return isObjectLike(func)
        ? matches(func)
        : baseCallback(func, thisArg);
    }

    /**
     * Creates a function that returns `value`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {*} value The value to return from the new function.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var object = { 'user': 'fred' };
     * var getter = _.constant(object);
     *
     * getter() === object;
     * // => true
     */
    function constant(value) {
      return function() {
        return value;
      };
    }

    /**
     * This method returns the first argument provided to it.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {*} value Any value.
     * @returns {*} Returns `value`.
     * @example
     *
     * var object = { 'user': 'fred' };
     *
     * _.identity(object) === object;
     * // => true
     */
    function identity(value) {
      return value;
    }

    /**
     * Creates a function that performs a deep comparison between a given object
     * and `source`, returning `true` if the given object has equivalent property
     * values, else `false`.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties. For comparing a single
     * own or inherited property value see `_.matchesProperty`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} source The object of property values to match.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36, 'active': true },
     *   { 'user': 'fred',   'age': 40, 'active': false }
     * ];
     *
     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
     */
    function matches(source) {
      return baseMatches(baseClone(source, true));
    }

    /**
     * Creates a function that compares the property value of `path` on a given
     * object to `value`.
     *
     * **Note:** This method supports comparing arrays, booleans, `Date` objects,
     * numbers, `Object` objects, regexes, and strings. Objects are compared by
     * their own, not inherited, enumerable properties.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the property to get.
     * @param {*} srcValue The value to match.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var users = [
     *   { 'user': 'barney' },
     *   { 'user': 'fred' }
     * ];
     *
     * _.find(users, _.matchesProperty('user', 'fred'));
     * // => { 'user': 'fred' }
     */
    function matchesProperty(path, srcValue) {
      return baseMatchesProperty(path, baseClone(srcValue, true));
    }

    /**
     * Creates a function that invokes the method at `path` on a given object.
     * Any additional arguments are provided to the invoked method.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the method to invoke.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var objects = [
     *   { 'a': { 'b': { 'c': _.constant(2) } } },
     *   { 'a': { 'b': { 'c': _.constant(1) } } }
     * ];
     *
     * _.map(objects, _.method('a.b.c'));
     * // => [2, 1]
     *
     * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
     * // => [1, 2]
     */
    var method = restParam(function(path, args) {
      return function(object) {
        return invokePath(object, path, args);
      };
    });

    /**
     * The opposite of `_.method`; this method creates a function that invokes
     * the method at a given path on `object`. Any additional arguments are
     * provided to the invoked method.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} object The object to query.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var array = _.times(3, _.constant),
     *     object = { 'a': array, 'b': array, 'c': array };
     *
     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
     * // => [2, 0]
     *
     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
     * // => [2, 0]
     */
    var methodOf = restParam(function(object, args) {
      return function(path) {
        return invokePath(object, path, args);
      };
    });

    /**
     * Adds all own enumerable function properties of a source object to the
     * destination object. If `object` is a function then methods are added to
     * its prototype as well.
     *
     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
     * avoid conflicts caused by modifying the original.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Function|Object} [object=lodash] The destination object.
     * @param {Object} source The object of functions to add.
     * @param {Object} [options] The options object.
     * @param {boolean} [options.chain=true] Specify whether the functions added
     *  are chainable.
     * @returns {Function|Object} Returns `object`.
     * @example
     *
     * function vowels(string) {
     *   return _.filter(string, function(v) {
     *     return /[aeiou]/i.test(v);
     *   });
     * }
     *
     * _.mixin({ 'vowels': vowels });
     * _.vowels('fred');
     * // => ['e']
     *
     * _('fred').vowels().value();
     * // => ['e']
     *
     * _.mixin({ 'vowels': vowels }, { 'chain': false });
     * _('fred').vowels();
     * // => ['e']
     */
    function mixin(object, source, options) {
      if (options == null) {
        var isObj = isObject(source),
            props = isObj ? keys(source) : undefined,
            methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;

        if (!(methodNames ? methodNames.length : isObj)) {
          methodNames = false;
          options = source;
          source = object;
          object = this;
        }
      }
      if (!methodNames) {
        methodNames = baseFunctions(source, keys(source));
      }
      var chain = true,
          index = -1,
          isFunc = isFunction(object),
          length = methodNames.length;

      if (options === false) {
        chain = false;
      } else if (isObject(options) && 'chain' in options) {
        chain = options.chain;
      }
      while (++index < length) {
        var methodName = methodNames[index],
            func = source[methodName];

        object[methodName] = func;
        if (isFunc) {
          object.prototype[methodName] = (function(func) {
            return function() {
              var chainAll = this.__chain__;
              if (chain || chainAll) {
                var result = object(this.__wrapped__),
                    actions = result.__actions__ = arrayCopy(this.__actions__);

                actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
                result.__chain__ = chainAll;
                return result;
              }
              return func.apply(object, arrayPush([this.value()], arguments));
            };
          }(func));
        }
      }
      return object;
    }

    /**
     * Reverts the `_` variable to its previous value and returns a reference to
     * the `lodash` function.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @returns {Function} Returns the `lodash` function.
     * @example
     *
     * var lodash = _.noConflict();
     */
    function noConflict() {
      root._ = oldDash;
      return this;
    }

    /**
     * A no-operation function that returns `undefined` regardless of the
     * arguments it receives.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @example
     *
     * var object = { 'user': 'fred' };
     *
     * _.noop(object) === undefined;
     * // => true
     */
    function noop() {
      // No operation performed.
    }

    /**
     * Creates a function that returns the property value at `path` on a
     * given object.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Array|string} path The path of the property to get.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var objects = [
     *   { 'a': { 'b': { 'c': 2 } } },
     *   { 'a': { 'b': { 'c': 1 } } }
     * ];
     *
     * _.map(objects, _.property('a.b.c'));
     * // => [2, 1]
     *
     * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
     * // => [1, 2]
     */
    function property(path) {
      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
    }

    /**
     * The opposite of `_.property`; this method creates a function that returns
     * the property value at a given path on `object`.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {Object} object The object to query.
     * @returns {Function} Returns the new function.
     * @example
     *
     * var array = [0, 1, 2],
     *     object = { 'a': array, 'b': array, 'c': array };
     *
     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
     * // => [2, 0]
     *
     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
     * // => [2, 0]
     */
    function propertyOf(object) {
      return function(path) {
        return baseGet(object, toPath(path), path + '');
      };
    }

    /**
     * Creates an array of numbers (positive and/or negative) progressing from
     * `start` up to, but not including, `end`. If `end` is not specified it is
     * set to `start` with `start` then set to `0`. If `end` is less than `start`
     * a zero-length range is created unless a negative `step` is specified.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {number} [start=0] The start of the range.
     * @param {number} end The end of the range.
     * @param {number} [step=1] The value to increment or decrement by.
     * @returns {Array} Returns the new array of numbers.
     * @example
     *
     * _.range(4);
     * // => [0, 1, 2, 3]
     *
     * _.range(1, 5);
     * // => [1, 2, 3, 4]
     *
     * _.range(0, 20, 5);
     * // => [0, 5, 10, 15]
     *
     * _.range(0, -4, -1);
     * // => [0, -1, -2, -3]
     *
     * _.range(1, 4, 0);
     * // => [1, 1, 1]
     *
     * _.range(0);
     * // => []
     */
    function range(start, end, step) {
      if (step && isIterateeCall(start, end, step)) {
        end = step = undefined;
      }
      start = +start || 0;
      step = step == null ? 1 : (+step || 0);

      if (end == null) {
        end = start;
        start = 0;
      } else {
        end = +end || 0;
      }
      // Use `Array(length)` so engines like Chakra and V8 avoid slower modes.
      // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.
      var index = -1,
          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
          result = Array(length);

      while (++index < length) {
        result[index] = start;
        start += step;
      }
      return result;
    }

    /**
     * Invokes the iteratee function `n` times, returning an array of the results
     * of each invocation. The `iteratee` is bound to `thisArg` and invoked with
     * one argument; (index).
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {number} n The number of times to invoke `iteratee`.
     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {Array} Returns the array of results.
     * @example
     *
     * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));
     * // => [3, 6, 4]
     *
     * _.times(3, function(n) {
     *   mage.castSpell(n);
     * });
     * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`
     *
     * _.times(3, function(n) {
     *   this.cast(n);
     * }, mage);
     * // => also invokes `mage.castSpell(n)` three times
     */
    function times(n, iteratee, thisArg) {
      n = nativeFloor(n);

      // Exit early to avoid a JSC JIT bug in Safari 8
      // where `Array(0)` is treated as `Array(1)`.
      if (n < 1 || !nativeIsFinite(n)) {
        return [];
      }
      var index = -1,
          result = Array(nativeMin(n, MAX_ARRAY_LENGTH));

      iteratee = bindCallback(iteratee, thisArg, 1);
      while (++index < n) {
        if (index < MAX_ARRAY_LENGTH) {
          result[index] = iteratee(index);
        } else {
          iteratee(index);
        }
      }
      return result;
    }

    /**
     * Generates a unique ID. If `prefix` is provided the ID is appended to it.
     *
     * @static
     * @memberOf _
     * @category Utility
     * @param {string} [prefix] The value to prefix the ID with.
     * @returns {string} Returns the unique ID.
     * @example
     *
     * _.uniqueId('contact_');
     * // => 'contact_104'
     *
     * _.uniqueId();
     * // => '105'
     */
    function uniqueId(prefix) {
      var id = ++idCounter;
      return baseToString(prefix) + id;
    }

    /*------------------------------------------------------------------------*/

    /**
     * Adds two numbers.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} augend The first number to add.
     * @param {number} addend The second number to add.
     * @returns {number} Returns the sum.
     * @example
     *
     * _.add(6, 4);
     * // => 10
     */
    function add(augend, addend) {
      return (+augend || 0) + (+addend || 0);
    }

    /**
     * Calculates `n` rounded up to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round up.
     * @param {number} [precision=0] The precision to round up to.
     * @returns {number} Returns the rounded up number.
     * @example
     *
     * _.ceil(4.006);
     * // => 5
     *
     * _.ceil(6.004, 2);
     * // => 6.01
     *
     * _.ceil(6040, -2);
     * // => 6100
     */
    var ceil = createRound('ceil');

    /**
     * Calculates `n` rounded down to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round down.
     * @param {number} [precision=0] The precision to round down to.
     * @returns {number} Returns the rounded down number.
     * @example
     *
     * _.floor(4.006);
     * // => 4
     *
     * _.floor(0.046, 2);
     * // => 0.04
     *
     * _.floor(4060, -2);
     * // => 4000
     */
    var floor = createRound('floor');

    /**
     * Gets the maximum value of `collection`. If `collection` is empty or falsey
     * `-Infinity` is returned. If an iteratee function is provided it is invoked
     * for each value in `collection` to generate the criterion by which the value
     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the maximum value.
     * @example
     *
     * _.max([4, 2, 8, 6]);
     * // => 8
     *
     * _.max([]);
     * // => -Infinity
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.max(users, function(chr) {
     *   return chr.age;
     * });
     * // => { 'user': 'fred', 'age': 40 }
     *
     * // using the `_.property` callback shorthand
     * _.max(users, 'age');
     * // => { 'user': 'fred', 'age': 40 }
     */
    var max = createExtremum(gt, NEGATIVE_INFINITY);

    /**
     * Gets the minimum value of `collection`. If `collection` is empty or falsey
     * `Infinity` is returned. If an iteratee function is provided it is invoked
     * for each value in `collection` to generate the criterion by which the value
     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three
     * arguments: (value, index, collection).
     *
     * If a property name is provided for `iteratee` the created `_.property`
     * style callback returns the property value of the given element.
     *
     * If a value is also provided for `thisArg` the created `_.matchesProperty`
     * style callback returns `true` for elements that have a matching property
     * value, else `false`.
     *
     * If an object is provided for `iteratee` the created `_.matches` style
     * callback returns `true` for elements that have the properties of the given
     * object, else `false`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {*} Returns the minimum value.
     * @example
     *
     * _.min([4, 2, 8, 6]);
     * // => 2
     *
     * _.min([]);
     * // => Infinity
     *
     * var users = [
     *   { 'user': 'barney', 'age': 36 },
     *   { 'user': 'fred',   'age': 40 }
     * ];
     *
     * _.min(users, function(chr) {
     *   return chr.age;
     * });
     * // => { 'user': 'barney', 'age': 36 }
     *
     * // using the `_.property` callback shorthand
     * _.min(users, 'age');
     * // => { 'user': 'barney', 'age': 36 }
     */
    var min = createExtremum(lt, POSITIVE_INFINITY);

    /**
     * Calculates `n` rounded to `precision`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {number} n The number to round.
     * @param {number} [precision=0] The precision to round to.
     * @returns {number} Returns the rounded number.
     * @example
     *
     * _.round(4.006);
     * // => 4
     *
     * _.round(4.006, 2);
     * // => 4.01
     *
     * _.round(4060, -2);
     * // => 4100
     */
    var round = createRound('round');

    /**
     * Gets the sum of the values in `collection`.
     *
     * @static
     * @memberOf _
     * @category Math
     * @param {Array|Object|string} collection The collection to iterate over.
     * @param {Function|Object|string} [iteratee] The function invoked per iteration.
     * @param {*} [thisArg] The `this` binding of `iteratee`.
     * @returns {number} Returns the sum.
     * @example
     *
     * _.sum([4, 6]);
     * // => 10
     *
     * _.sum({ 'a': 4, 'b': 6 });
     * // => 10
     *
     * var objects = [
     *   { 'n': 4 },
     *   { 'n': 6 }
     * ];
     *
     * _.sum(objects, function(object) {
     *   return object.n;
     * });
     * // => 10
     *
     * // using the `_.property` callback shorthand
     * _.sum(objects, 'n');
     * // => 10
     */
    function sum(collection, iteratee, thisArg) {
      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
        iteratee = undefined;
      }
      iteratee = getCallback(iteratee, thisArg, 3);
      return iteratee.length == 1
        ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)
        : baseSum(collection, iteratee);
    }

    /*------------------------------------------------------------------------*/

    // Ensure wrappers are instances of `baseLodash`.
    lodash.prototype = baseLodash.prototype;

    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
    LodashWrapper.prototype.constructor = LodashWrapper;

    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
    LazyWrapper.prototype.constructor = LazyWrapper;

    // Add functions to the `Map` cache.
    MapCache.prototype['delete'] = mapDelete;
    MapCache.prototype.get = mapGet;
    MapCache.prototype.has = mapHas;
    MapCache.prototype.set = mapSet;

    // Add functions to the `Set` cache.
    SetCache.prototype.push = cachePush;

    // Assign cache to `_.memoize`.
    memoize.Cache = MapCache;

    // Add functions that return wrapped values when chaining.
    lodash.after = after;
    lodash.ary = ary;
    lodash.assign = assign;
    lodash.at = at;
    lodash.before = before;
    lodash.bind = bind;
    lodash.bindAll = bindAll;
    lodash.bindKey = bindKey;
    lodash.callback = callback;
    lodash.chain = chain;
    lodash.chunk = chunk;
    lodash.compact = compact;
    lodash.constant = constant;
    lodash.countBy = countBy;
    lodash.create = create;
    lodash.curry = curry;
    lodash.curryRight = curryRight;
    lodash.debounce = debounce;
    lodash.defaults = defaults;
    lodash.defaultsDeep = defaultsDeep;
    lodash.defer = defer;
    lodash.delay = delay;
    lodash.difference = difference;
    lodash.drop = drop;
    lodash.dropRight = dropRight;
    lodash.dropRightWhile = dropRightWhile;
    lodash.dropWhile = dropWhile;
    lodash.fill = fill;
    lodash.filter = filter;
    lodash.flatten = flatten;
    lodash.flattenDeep = flattenDeep;
    lodash.flow = flow;
    lodash.flowRight = flowRight;
    lodash.forEach = forEach;
    lodash.forEachRight = forEachRight;
    lodash.forIn = forIn;
    lodash.forInRight = forInRight;
    lodash.forOwn = forOwn;
    lodash.forOwnRight = forOwnRight;
    lodash.functions = functions;
    lodash.groupBy = groupBy;
    lodash.indexBy = indexBy;
    lodash.initial = initial;
    lodash.intersection = intersection;
    lodash.invert = invert;
    lodash.invoke = invoke;
    lodash.keys = keys;
    lodash.keysIn = keysIn;
    lodash.map = map;
    lodash.mapKeys = mapKeys;
    lodash.mapValues = mapValues;
    lodash.matches = matches;
    lodash.matchesProperty = matchesProperty;
    lodash.memoize = memoize;
    lodash.merge = merge;
    lodash.method = method;
    lodash.methodOf = methodOf;
    lodash.mixin = mixin;
    lodash.modArgs = modArgs;
    lodash.negate = negate;
    lodash.omit = omit;
    lodash.once = once;
    lodash.pairs = pairs;
    lodash.partial = partial;
    lodash.partialRight = partialRight;
    lodash.partition = partition;
    lodash.pick = pick;
    lodash.pluck = pluck;
    lodash.property = property;
    lodash.propertyOf = propertyOf;
    lodash.pull = pull;
    lodash.pullAt = pullAt;
    lodash.range = range;
    lodash.rearg = rearg;
    lodash.reject = reject;
    lodash.remove = remove;
    lodash.rest = rest;
    lodash.restParam = restParam;
    lodash.set = set;
    lodash.shuffle = shuffle;
    lodash.slice = slice;
    lodash.sortBy = sortBy;
    lodash.sortByAll = sortByAll;
    lodash.sortByOrder = sortByOrder;
    lodash.spread = spread;
    lodash.take = take;
    lodash.takeRight = takeRight;
    lodash.takeRightWhile = takeRightWhile;
    lodash.takeWhile = takeWhile;
    lodash.tap = tap;
    lodash.throttle = throttle;
    lodash.thru = thru;
    lodash.times = times;
    lodash.toArray = toArray;
    lodash.toPlainObject = toPlainObject;
    lodash.transform = transform;
    lodash.union = union;
    lodash.uniq = uniq;
    lodash.unzip = unzip;
    lodash.unzipWith = unzipWith;
    lodash.values = values;
    lodash.valuesIn = valuesIn;
    lodash.where = where;
    lodash.without = without;
    lodash.wrap = wrap;
    lodash.xor = xor;
    lodash.zip = zip;
    lodash.zipObject = zipObject;
    lodash.zipWith = zipWith;

    // Add aliases.
    lodash.backflow = flowRight;
    lodash.collect = map;
    lodash.compose = flowRight;
    lodash.each = forEach;
    lodash.eachRight = forEachRight;
    lodash.extend = assign;
    lodash.iteratee = callback;
    lodash.methods = functions;
    lodash.object = zipObject;
    lodash.select = filter;
    lodash.tail = rest;
    lodash.unique = uniq;

    // Add functions to `lodash.prototype`.
    mixin(lodash, lodash);

    /*------------------------------------------------------------------------*/

    // Add functions that return unwrapped values when chaining.
    lodash.add = add;
    lodash.attempt = attempt;
    lodash.camelCase = camelCase;
    lodash.capitalize = capitalize;
    lodash.ceil = ceil;
    lodash.clone = clone;
    lodash.cloneDeep = cloneDeep;
    lodash.deburr = deburr;
    lodash.endsWith = endsWith;
    lodash.escape = escape;
    lodash.escapeRegExp = escapeRegExp;
    lodash.every = every;
    lodash.find = find;
    lodash.findIndex = findIndex;
    lodash.findKey = findKey;
    lodash.findLast = findLast;
    lodash.findLastIndex = findLastIndex;
    lodash.findLastKey = findLastKey;
    lodash.findWhere = findWhere;
    lodash.first = first;
    lodash.floor = floor;
    lodash.get = get;
    lodash.gt = gt;
    lodash.gte = gte;
    lodash.has = has;
    lodash.identity = identity;
    lodash.includes = includes;
    lodash.indexOf = indexOf;
    lodash.inRange = inRange;
    lodash.isArguments = isArguments;
    lodash.isArray = isArray;
    lodash.isBoolean = isBoolean;
    lodash.isDate = isDate;
    lodash.isElement = isElement;
    lodash.isEmpty = isEmpty;
    lodash.isEqual = isEqual;
    lodash.isError = isError;
    lodash.isFinite = isFinite;
    lodash.isFunction = isFunction;
    lodash.isMatch = isMatch;
    lodash.isNaN = isNaN;
    lodash.isNative = isNative;
    lodash.isNull = isNull;
    lodash.isNumber = isNumber;
    lodash.isObject = isObject;
    lodash.isPlainObject = isPlainObject;
    lodash.isRegExp = isRegExp;
    lodash.isString = isString;
    lodash.isTypedArray = isTypedArray;
    lodash.isUndefined = isUndefined;
    lodash.kebabCase = kebabCase;
    lodash.last = last;
    lodash.lastIndexOf = lastIndexOf;
    lodash.lt = lt;
    lodash.lte = lte;
    lodash.max = max;
    lodash.min = min;
    lodash.noConflict = noConflict;
    lodash.noop = noop;
    lodash.now = now;
    lodash.pad = pad;
    lodash.padLeft = padLeft;
    lodash.padRight = padRight;
    lodash.parseInt = parseInt;
    lodash.random = random;
    lodash.reduce = reduce;
    lodash.reduceRight = reduceRight;
    lodash.repeat = repeat;
    lodash.result = result;
    lodash.round = round;
    lodash.runInContext = runInContext;
    lodash.size = size;
    lodash.snakeCase = snakeCase;
    lodash.some = some;
    lodash.sortedIndex = sortedIndex;
    lodash.sortedLastIndex = sortedLastIndex;
    lodash.startCase = startCase;
    lodash.startsWith = startsWith;
    lodash.sum = sum;
    lodash.template = template;
    lodash.trim = trim;
    lodash.trimLeft = trimLeft;
    lodash.trimRight = trimRight;
    lodash.trunc = trunc;
    lodash.unescape = unescape;
    lodash.uniqueId = uniqueId;
    lodash.words = words;

    // Add aliases.
    lodash.all = every;
    lodash.any = some;
    lodash.contains = includes;
    lodash.eq = isEqual;
    lodash.detect = find;
    lodash.foldl = reduce;
    lodash.foldr = reduceRight;
    lodash.head = first;
    lodash.include = includes;
    lodash.inject = reduce;

    mixin(lodash, (function() {
      var source = {};
      baseForOwn(lodash, function(func, methodName) {
        if (!lodash.prototype[methodName]) {
          source[methodName] = func;
        }
      });
      return source;
    }()), false);

    /*------------------------------------------------------------------------*/

    // Add functions capable of returning wrapped and unwrapped values when chaining.
    lodash.sample = sample;

    lodash.prototype.sample = function(n) {
      if (!this.__chain__ && n == null) {
        return sample(this.value());
      }
      return this.thru(function(value) {
        return sample(value, n);
      });
    };

    /*------------------------------------------------------------------------*/

    /**
     * The semantic version number.
     *
     * @static
     * @memberOf _
     * @type string
     */
    lodash.VERSION = VERSION;

    // Assign default placeholders.
    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
      lodash[methodName].placeholder = lodash;
    });

    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
    arrayEach(['drop', 'take'], function(methodName, index) {
      LazyWrapper.prototype[methodName] = function(n) {
        var filtered = this.__filtered__;
        if (filtered && !index) {
          return new LazyWrapper(this);
        }
        n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);

        var result = this.clone();
        if (filtered) {
          result.__takeCount__ = nativeMin(result.__takeCount__, n);
        } else {
          result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
        }
        return result;
      };

      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
        return this.reverse()[methodName](n).reverse();
      };
    });

    // Add `LazyWrapper` methods that accept an `iteratee` value.
    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
      var type = index + 1,
          isFilter = type != LAZY_MAP_FLAG;

      LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
        var result = this.clone();
        result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });
        result.__filtered__ = result.__filtered__ || isFilter;
        return result;
      };
    });

    // Add `LazyWrapper` methods for `_.first` and `_.last`.
    arrayEach(['first', 'last'], function(methodName, index) {
      var takeName = 'take' + (index ? 'Right' : '');

      LazyWrapper.prototype[methodName] = function() {
        return this[takeName](1).value()[0];
      };
    });

    // Add `LazyWrapper` methods for `_.initial` and `_.rest`.
    arrayEach(['initial', 'rest'], function(methodName, index) {
      var dropName = 'drop' + (index ? '' : 'Right');

      LazyWrapper.prototype[methodName] = function() {
        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
      };
    });

    // Add `LazyWrapper` methods for `_.pluck` and `_.where`.
    arrayEach(['pluck', 'where'], function(methodName, index) {
      var operationName = index ? 'filter' : 'map',
          createCallback = index ? baseMatches : property;

      LazyWrapper.prototype[methodName] = function(value) {
        return this[operationName](createCallback(value));
      };
    });

    LazyWrapper.prototype.compact = function() {
      return this.filter(identity);
    };

    LazyWrapper.prototype.reject = function(predicate, thisArg) {
      predicate = getCallback(predicate, thisArg, 1);
      return this.filter(function(value) {
        return !predicate(value);
      });
    };

    LazyWrapper.prototype.slice = function(start, end) {
      start = start == null ? 0 : (+start || 0);

      var result = this;
      if (result.__filtered__ && (start > 0 || end < 0)) {
        return new LazyWrapper(result);
      }
      if (start < 0) {
        result = result.takeRight(-start);
      } else if (start) {
        result = result.drop(start);
      }
      if (end !== undefined) {
        end = (+end || 0);
        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
      }
      return result;
    };

    LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {
      return this.reverse().takeWhile(predicate, thisArg).reverse();
    };

    LazyWrapper.prototype.toArray = function() {
      return this.take(POSITIVE_INFINITY);
    };

    // Add `LazyWrapper` methods to `lodash.prototype`.
    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
      var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
          retUnwrapped = /^(?:first|last)$/.test(methodName),
          lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];

      if (!lodashFunc) {
        return;
      }
      lodash.prototype[methodName] = function() {
        var args = retUnwrapped ? [1] : arguments,
            chainAll = this.__chain__,
            value = this.__wrapped__,
            isHybrid = !!this.__actions__.length,
            isLazy = value instanceof LazyWrapper,
            iteratee = args[0],
            useLazy = isLazy || isArray(value);

        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
          // Avoid lazy use if the iteratee has a "length" value other than `1`.
          isLazy = useLazy = false;
        }
        var interceptor = function(value) {
          return (retUnwrapped && chainAll)
            ? lodashFunc(value, 1)[0]
            : lodashFunc.apply(undefined, arrayPush([value], args));
        };

        var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },
            onlyLazy = isLazy && !isHybrid;

        if (retUnwrapped && !chainAll) {
          if (onlyLazy) {
            value = value.clone();
            value.__actions__.push(action);
            return func.call(value);
          }
          return lodashFunc.call(undefined, this.value())[0];
        }
        if (!retUnwrapped && useLazy) {
          value = onlyLazy ? value : new LazyWrapper(this);
          var result = func.apply(value, args);
          result.__actions__.push(action);
          return new LodashWrapper(result, chainAll);
        }
        return this.thru(interceptor);
      };
    });

    // Add `Array` and `String` methods to `lodash.prototype`.
    arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
      var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],
          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
          retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);

      lodash.prototype[methodName] = function() {
        var args = arguments;
        if (retUnwrapped && !this.__chain__) {
          return func.apply(this.value(), args);
        }
        return this[chainName](function(value) {
          return func.apply(value, args);
        });
      };
    });

    // Map minified function names to their real names.
    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
      var lodashFunc = lodash[methodName];
      if (lodashFunc) {
        var key = lodashFunc.name,
            names = realNames[key] || (realNames[key] = []);

        names.push({ 'name': methodName, 'func': lodashFunc });
      }
    });

    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];

    // Add functions to the lazy wrapper.
    LazyWrapper.prototype.clone = lazyClone;
    LazyWrapper.prototype.reverse = lazyReverse;
    LazyWrapper.prototype.value = lazyValue;

    // Add chaining functions to the `lodash` wrapper.
    lodash.prototype.chain = wrapperChain;
    lodash.prototype.commit = wrapperCommit;
    lodash.prototype.concat = wrapperConcat;
    lodash.prototype.plant = wrapperPlant;
    lodash.prototype.reverse = wrapperReverse;
    lodash.prototype.toString = wrapperToString;
    lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;

    // Add function aliases to the `lodash` wrapper.
    lodash.prototype.collect = lodash.prototype.map;
    lodash.prototype.head = lodash.prototype.first;
    lodash.prototype.select = lodash.prototype.filter;
    lodash.prototype.tail = lodash.prototype.rest;

    return lodash;
  }

  /*--------------------------------------------------------------------------*/

  // Export lodash.
  var _ = runInContext();

  // Some AMD build optimizers like r.js check for condition patterns like the following:
  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
    // Expose lodash to the global object when an AMD loader is present to avoid
    // errors in cases where lodash is loaded by a script tag and not intended
    // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for
    // more details.
    root._ = _;

    // Define as an anonymous module so, through path mapping, it can be
    // referenced as the "underscore" module.
    define(function() {
      return _;
    });
  }
  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
  else if (freeExports && freeModule) {
    // Export for Node.js or RingoJS.
    if (moduleExports) {
      (freeModule.exports = _)._ = _;
    }
    // Export for Rhino with CommonJS support.
    else {
      freeExports._ = _;
    }
  }
  else {
    // Export for a browser or Rhino.
    root._ = _;
  }
}.call(this));

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],334:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };

},{}],335:[function(require,module,exports){
'use strict';

module.exports = require('./lib')

},{"./lib":340}],336:[function(require,module,exports){
'use strict';

var asap = require('asap/raw');

function noop() {}

// States:
//
// 0 - pending
// 1 - fulfilled with _value
// 2 - rejected with _value
// 3 - adopted the state of another promise, _value
//
// once the state is no longer pending (0) it is immutable

// All `_` prefixed properties will be reduced to `_{random number}`
// at build time to obfuscate them and discourage their use.
// We don't use symbols or Object.defineProperty to fully hide them
// because the performance isn't good enough.


// to avoid using try/catch inside critical functions, we
// extract them to here.
var LAST_ERROR = null;
var IS_ERROR = {};
function getThen(obj) {
  try {
    return obj.then;
  } catch (ex) {
    LAST_ERROR = ex;
    return IS_ERROR;
  }
}

function tryCallOne(fn, a) {
  try {
    return fn(a);
  } catch (ex) {
    LAST_ERROR = ex;
    return IS_ERROR;
  }
}
function tryCallTwo(fn, a, b) {
  try {
    fn(a, b);
  } catch (ex) {
    LAST_ERROR = ex;
    return IS_ERROR;
  }
}

module.exports = Promise;

function Promise(fn) {
  if (typeof this !== 'object') {
    throw new TypeError('Promises must be constructed via new');
  }
  if (typeof fn !== 'function') {
    throw new TypeError('not a function');
  }
  this._45 = 0;
  this._81 = 0;
  this._65 = null;
  this._54 = null;
  if (fn === noop) return;
  doResolve(fn, this);
}
Promise._10 = null;
Promise._97 = null;
Promise._61 = noop;

Promise.prototype.then = function(onFulfilled, onRejected) {
  if (this.constructor !== Promise) {
    return safeThen(this, onFulfilled, onRejected);
  }
  var res = new Promise(noop);
  handle(this, new Handler(onFulfilled, onRejected, res));
  return res;
};

function safeThen(self, onFulfilled, onRejected) {
  return new self.constructor(function (resolve, reject) {
    var res = new Promise(noop);
    res.then(resolve, reject);
    handle(self, new Handler(onFulfilled, onRejected, res));
  });
};
function handle(self, deferred) {
  while (self._81 === 3) {
    self = self._65;
  }
  if (Promise._10) {
    Promise._10(self);
  }
  if (self._81 === 0) {
    if (self._45 === 0) {
      self._45 = 1;
      self._54 = deferred;
      return;
    }
    if (self._45 === 1) {
      self._45 = 2;
      self._54 = [self._54, deferred];
      return;
    }
    self._54.push(deferred);
    return;
  }
  handleResolved(self, deferred);
}

function handleResolved(self, deferred) {
  asap(function() {
    var cb = self._81 === 1 ? deferred.onFulfilled : deferred.onRejected;
    if (cb === null) {
      if (self._81 === 1) {
        resolve(deferred.promise, self._65);
      } else {
        reject(deferred.promise, self._65);
      }
      return;
    }
    var ret = tryCallOne(cb, self._65);
    if (ret === IS_ERROR) {
      reject(deferred.promise, LAST_ERROR);
    } else {
      resolve(deferred.promise, ret);
    }
  });
}
function resolve(self, newValue) {
  // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
  if (newValue === self) {
    return reject(
      self,
      new TypeError('A promise cannot be resolved with itself.')
    );
  }
  if (
    newValue &&
    (typeof newValue === 'object' || typeof newValue === 'function')
  ) {
    var then = getThen(newValue);
    if (then === IS_ERROR) {
      return reject(self, LAST_ERROR);
    }
    if (
      then === self.then &&
      newValue instanceof Promise
    ) {
      self._81 = 3;
      self._65 = newValue;
      finale(self);
      return;
    } else if (typeof then === 'function') {
      doResolve(then.bind(newValue), self);
      return;
    }
  }
  self._81 = 1;
  self._65 = newValue;
  finale(self);
}

function reject(self, newValue) {
  self._81 = 2;
  self._65 = newValue;
  if (Promise._97) {
    Promise._97(self, newValue);
  }
  finale(self);
}
function finale(self) {
  if (self._45 === 1) {
    handle(self, self._54);
    self._54 = null;
  }
  if (self._45 === 2) {
    for (var i = 0; i < self._54.length; i++) {
      handle(self, self._54[i]);
    }
    self._54 = null;
  }
}

function Handler(onFulfilled, onRejected, promise){
  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
  this.onRejected = typeof onRejected === 'function' ? onRejected : null;
  this.promise = promise;
}

/**
 * Take a potentially misbehaving resolver function and make sure
 * onFulfilled and onRejected are only called once.
 *
 * Makes no guarantees about asynchrony.
 */
function doResolve(fn, promise) {
  var done = false;
  var res = tryCallTwo(fn, function (value) {
    if (done) return;
    done = true;
    resolve(promise, value);
  }, function (reason) {
    if (done) return;
    done = true;
    reject(promise, reason);
  })
  if (!done && res === IS_ERROR) {
    done = true;
    reject(promise, LAST_ERROR);
  }
}

},{"asap/raw":2}],337:[function(require,module,exports){
'use strict';

var Promise = require('./core.js');

module.exports = Promise;
Promise.prototype.done = function (onFulfilled, onRejected) {
  var self = arguments.length ? this.then.apply(this, arguments) : this;
  self.then(null, function (err) {
    setTimeout(function () {
      throw err;
    }, 0);
  });
};

},{"./core.js":336}],338:[function(require,module,exports){
'use strict';

//This file contains the ES6 extensions to the core Promises/A+ API

var Promise = require('./core.js');

module.exports = Promise;

/* Static Functions */

var TRUE = valuePromise(true);
var FALSE = valuePromise(false);
var NULL = valuePromise(null);
var UNDEFINED = valuePromise(undefined);
var ZERO = valuePromise(0);
var EMPTYSTRING = valuePromise('');

function valuePromise(value) {
  var p = new Promise(Promise._61);
  p._81 = 1;
  p._65 = value;
  return p;
}
Promise.resolve = function (value) {
  if (value instanceof Promise) return value;

  if (value === null) return NULL;
  if (value === undefined) return UNDEFINED;
  if (value === true) return TRUE;
  if (value === false) return FALSE;
  if (value === 0) return ZERO;
  if (value === '') return EMPTYSTRING;

  if (typeof value === 'object' || typeof value === 'function') {
    try {
      var then = value.then;
      if (typeof then === 'function') {
        return new Promise(then.bind(value));
      }
    } catch (ex) {
      return new Promise(function (resolve, reject) {
        reject(ex);
      });
    }
  }
  return valuePromise(value);
};

Promise.all = function (arr) {
  var args = Array.prototype.slice.call(arr);

  return new Promise(function (resolve, reject) {
    if (args.length === 0) return resolve([]);
    var remaining = args.length;
    function res(i, val) {
      if (val && (typeof val === 'object' || typeof val === 'function')) {
        if (val instanceof Promise && val.then === Promise.prototype.then) {
          while (val._81 === 3) {
            val = val._65;
          }
          if (val._81 === 1) return res(i, val._65);
          if (val._81 === 2) reject(val._65);
          val.then(function (val) {
            res(i, val);
          }, reject);
          return;
        } else {
          var then = val.then;
          if (typeof then === 'function') {
            var p = new Promise(then.bind(val));
            p.then(function (val) {
              res(i, val);
            }, reject);
            return;
          }
        }
      }
      args[i] = val;
      if (--remaining === 0) {
        resolve(args);
      }
    }
    for (var i = 0; i < args.length; i++) {
      res(i, args[i]);
    }
  });
};

Promise.reject = function (value) {
  return new Promise(function (resolve, reject) {
    reject(value);
  });
};

Promise.race = function (values) {
  return new Promise(function (resolve, reject) {
    values.forEach(function(value){
      Promise.resolve(value).then(resolve, reject);
    });
  });
};

/* Prototype Methods */

Promise.prototype['catch'] = function (onRejected) {
  return this.then(null, onRejected);
};

},{"./core.js":336}],339:[function(require,module,exports){
'use strict';

var Promise = require('./core.js');

module.exports = Promise;
Promise.prototype['finally'] = function (f) {
  return this.then(function (value) {
    return Promise.resolve(f()).then(function () {
      return value;
    });
  }, function (err) {
    return Promise.resolve(f()).then(function () {
      throw err;
    });
  });
};

},{"./core.js":336}],340:[function(require,module,exports){
'use strict';

module.exports = require('./core.js');
require('./done.js');
require('./finally.js');
require('./es6-extensions.js');
require('./node-extensions.js');
require('./synchronous.js');

},{"./core.js":336,"./done.js":337,"./es6-extensions.js":338,"./finally.js":339,"./node-extensions.js":341,"./synchronous.js":342}],341:[function(require,module,exports){
'use strict';

// This file contains then/promise specific extensions that are only useful
// for node.js interop

var Promise = require('./core.js');
var asap = require('asap');

module.exports = Promise;

/* Static Functions */

Promise.denodeify = function (fn, argumentCount) {
  if (
    typeof argumentCount === 'number' && argumentCount !== Infinity
  ) {
    return denodeifyWithCount(fn, argumentCount);
  } else {
    return denodeifyWithoutCount(fn);
  }
}

var callbackFn = (
  'function (err, res) {' +
  'if (err) { rj(err); } else { rs(res); }' +
  '}'
);
function denodeifyWithCount(fn, argumentCount) {
  var args = [];
  for (var i = 0; i < argumentCount; i++) {
    args.push('a' + i);
  }
  var body = [
    'return function (' + args.join(',') + ') {',
    'var self = this;',
    'return new Promise(function (rs, rj) {',
    'var res = fn.call(',
    ['self'].concat(args).concat([callbackFn]).join(','),
    ');',
    'if (res &&',
    '(typeof res === "object" || typeof res === "function") &&',
    'typeof res.then === "function"',
    ') {rs(res);}',
    '});',
    '};'
  ].join('');
  return Function(['Promise', 'fn'], body)(Promise, fn);
}
function denodeifyWithoutCount(fn) {
  var fnLength = Math.max(fn.length - 1, 3);
  var args = [];
  for (var i = 0; i < fnLength; i++) {
    args.push('a' + i);
  }
  var body = [
    'return function (' + args.join(',') + ') {',
    'var self = this;',
    'var args;',
    'var argLength = arguments.length;',
    'if (arguments.length > ' + fnLength + ') {',
    'args = new Array(arguments.length + 1);',
    'for (var i = 0; i < arguments.length; i++) {',
    'args[i] = arguments[i];',
    '}',
    '}',
    'return new Promise(function (rs, rj) {',
    'var cb = ' + callbackFn + ';',
    'var res;',
    'switch (argLength) {',
    args.concat(['extra']).map(function (_, index) {
      return (
        'case ' + (index) + ':' +
        'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
        'break;'
      );
    }).join(''),
    'default:',
    'args[argLength] = cb;',
    'res = fn.apply(self, args);',
    '}',
    
    'if (res &&',
    '(typeof res === "object" || typeof res === "function") &&',
    'typeof res.then === "function"',
    ') {rs(res);}',
    '});',
    '};'
  ].join('');

  return Function(
    ['Promise', 'fn'],
    body
  )(Promise, fn);
}

Promise.nodeify = function (fn) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    var callback =
      typeof args[args.length - 1] === 'function' ? args.pop() : null;
    var ctx = this;
    try {
      return fn.apply(this, arguments).nodeify(callback, ctx);
    } catch (ex) {
      if (callback === null || typeof callback == 'undefined') {
        return new Promise(function (resolve, reject) {
          reject(ex);
        });
      } else {
        asap(function () {
          callback.call(ctx, ex);
        })
      }
    }
  }
}

Promise.prototype.nodeify = function (callback, ctx) {
  if (typeof callback != 'function') return this;

  this.then(function (value) {
    asap(function () {
      callback.call(ctx, null, value);
    });
  }, function (err) {
    asap(function () {
      callback.call(ctx, err);
    });
  });
}

},{"./core.js":336,"asap":1}],342:[function(require,module,exports){
'use strict';

var Promise = require('./core.js');

module.exports = Promise;
Promise.enableSynchronous = function () {
  Promise.prototype.isPending = function() {
    return this.getState() == 0;
  };

  Promise.prototype.isFulfilled = function() {
    return this.getState() == 1;
  };

  Promise.prototype.isRejected = function() {
    return this.getState() == 2;
  };

  Promise.prototype.getValue = function () {
    if (this._81 === 3) {
      return this._65.getValue();
    }

    if (!this.isFulfilled()) {
      throw new Error('Cannot get a value of an unfulfilled promise.');
    }

    return this._65;
  };

  Promise.prototype.getReason = function () {
    if (this._81 === 3) {
      return this._65.getReason();
    }

    if (!this.isRejected()) {
      throw new Error('Cannot get a rejection reason of a non-rejected promise.');
    }

    return this._65;
  };

  Promise.prototype.getState = function () {
    if (this._81 === 3) {
      return this._65.getState();
    }
    if (this._81 === -1 || this._81 === -2) {
      return 0;
    }

    return this._81;
  };
};

Promise.disableSynchronous = function() {
  Promise.prototype.isPending = undefined;
  Promise.prototype.isFulfilled = undefined;
  Promise.prototype.isRejected = undefined;
  Promise.prototype.getValue = undefined;
  Promise.prototype.getReason = undefined;
  Promise.prototype.getState = undefined;
};

},{"./core.js":336}],343:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

if (process.env.NODE_ENV !== 'production') {
  var invariant = require('fbjs/lib/invariant');
  var warning = require('fbjs/lib/warning');
  var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
  var loggedTypeFailures = {};
}

/**
 * Assert that the values match with the type specs.
 * Error messages are memorized and will only be shown once.
 *
 * @param {object} typeSpecs Map of name to a ReactPropType
 * @param {object} values Runtime values that need to be type-checked
 * @param {string} location e.g. "prop", "context", "child context"
 * @param {string} componentName Name of the component for error messages.
 * @param {?Function} getStack Returns the component stack.
 * @private
 */
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
  if (process.env.NODE_ENV !== 'production') {
    for (var typeSpecName in typeSpecs) {
      if (typeSpecs.hasOwnProperty(typeSpecName)) {
        var error;
        // Prop type validation may throw. In case they do, we don't want to
        // fail the render phase where it didn't fail before. So we log it.
        // After these have been cleaned up, we'll let them throw.
        try {
          // This is intentionally an invariant that gets caught. It's the same
          // behavior as without this statement except with a better message.
          invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', location, typeSpecName);
          error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
        } catch (ex) {
          error = ex;
        }
        warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error);
        if (error instanceof Error && !(error.message in loggedTypeFailures)) {
          // Only monitor this failure once because there tends to be a lot of the
          // same error.
          loggedTypeFailures[error.message] = true;

          var stack = getStack ? getStack() : '';

          warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
        }
      }
    }
  }
}

module.exports = checkPropTypes;

}).call(this,require('_process'))

},{"./lib/ReactPropTypesSecret":347,"_process":334,"fbjs/lib/invariant":349,"fbjs/lib/warning":350}],344:[function(require,module,exports){
/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

var emptyFunction = require('fbjs/lib/emptyFunction');
var invariant = require('fbjs/lib/invariant');

module.exports = function() {
  // Important!
  // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
  function shim() {
    invariant(
      false,
      'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
      'Use PropTypes.checkPropTypes() to call them. ' +
      'Read more at http://fb.me/use-check-prop-types'
    );
  };
  shim.isRequired = shim;
  function getShim() {
    return shim;
  };
  var ReactPropTypes = {
    array: shim,
    bool: shim,
    func: shim,
    number: shim,
    object: shim,
    string: shim,
    symbol: shim,

    any: shim,
    arrayOf: getShim,
    element: shim,
    instanceOf: getShim,
    node: shim,
    objectOf: getShim,
    oneOf: getShim,
    oneOfType: getShim,
    shape: getShim
  };

  ReactPropTypes.checkPropTypes = emptyFunction;
  ReactPropTypes.PropTypes = ReactPropTypes;

  return ReactPropTypes;
};

},{"fbjs/lib/emptyFunction":348,"fbjs/lib/invariant":349}],345:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

var emptyFunction = require('fbjs/lib/emptyFunction');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');
var checkPropTypes = require('./checkPropTypes');

module.exports = function(isValidElement, throwOnDirectAccess) {
  /* global Symbol */
  var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
  var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.

  /**
   * Returns the iterator method function contained on the iterable object.
   *
   * Be sure to invoke the function with the iterable as context:
   *
   *     var iteratorFn = getIteratorFn(myIterable);
   *     if (iteratorFn) {
   *       var iterator = iteratorFn.call(myIterable);
   *       ...
   *     }
   *
   * @param {?object} maybeIterable
   * @return {?function}
   */
  function getIteratorFn(maybeIterable) {
    var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
    if (typeof iteratorFn === 'function') {
      return iteratorFn;
    }
  }

  /**
   * Collection of methods that allow declaration and validation of props that are
   * supplied to React components. Example usage:
   *
   *   var Props = require('ReactPropTypes');
   *   var MyArticle = React.createClass({
   *     propTypes: {
   *       // An optional string prop named "description".
   *       description: Props.string,
   *
   *       // A required enum prop named "category".
   *       category: Props.oneOf(['News','Photos']).isRequired,
   *
   *       // A prop named "dialog" that requires an instance of Dialog.
   *       dialog: Props.instanceOf(Dialog).isRequired
   *     },
   *     render: function() { ... }
   *   });
   *
   * A more formal specification of how these methods are used:
   *
   *   type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
   *   decl := ReactPropTypes.{type}(.isRequired)?
   *
   * Each and every declaration produces a function with the same signature. This
   * allows the creation of custom validation functions. For example:
   *
   *  var MyLink = React.createClass({
   *    propTypes: {
   *      // An optional string or URI prop named "href".
   *      href: function(props, propName, componentName) {
   *        var propValue = props[propName];
   *        if (propValue != null && typeof propValue !== 'string' &&
   *            !(propValue instanceof URI)) {
   *          return new Error(
   *            'Expected a string or an URI for ' + propName + ' in ' +
   *            componentName
   *          );
   *        }
   *      }
   *    },
   *    render: function() {...}
   *  });
   *
   * @internal
   */

  var ANONYMOUS = '<<anonymous>>';

  // Important!
  // Keep this list in sync with production version in `./factoryWithThrowingShims.js`.
  var ReactPropTypes = {
    array: createPrimitiveTypeChecker('array'),
    bool: createPrimitiveTypeChecker('boolean'),
    func: createPrimitiveTypeChecker('function'),
    number: createPrimitiveTypeChecker('number'),
    object: createPrimitiveTypeChecker('object'),
    string: createPrimitiveTypeChecker('string'),
    symbol: createPrimitiveTypeChecker('symbol'),

    any: createAnyTypeChecker(),
    arrayOf: createArrayOfTypeChecker,
    element: createElementTypeChecker(),
    instanceOf: createInstanceTypeChecker,
    node: createNodeChecker(),
    objectOf: createObjectOfTypeChecker,
    oneOf: createEnumTypeChecker,
    oneOfType: createUnionTypeChecker,
    shape: createShapeTypeChecker
  };

  /**
   * inlined Object.is polyfill to avoid requiring consumers ship their own
   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
   */
  /*eslint-disable no-self-compare*/
  function is(x, y) {
    // SameValue algorithm
    if (x === y) {
      // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // Step 6.a: NaN == NaN
      return x !== x && y !== y;
    }
  }
  /*eslint-enable no-self-compare*/

  /**
   * We use an Error-like object for backward compatibility as people may call
   * PropTypes directly and inspect their output. However, we don't use real
   * Errors anymore. We don't inspect their stack anyway, and creating them
   * is prohibitively expensive if they are created too often, such as what
   * happens in oneOfType() for any type before the one that matched.
   */
  function PropTypeError(message) {
    this.message = message;
    this.stack = '';
  }
  // Make `instanceof Error` still work for returned errors.
  PropTypeError.prototype = Error.prototype;

  function createChainableTypeChecker(validate) {
    if (process.env.NODE_ENV !== 'production') {
      var manualPropTypeCallCache = {};
      var manualPropTypeWarningCount = 0;
    }
    function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
      componentName = componentName || ANONYMOUS;
      propFullName = propFullName || propName;

      if (secret !== ReactPropTypesSecret) {
        if (throwOnDirectAccess) {
          // New behavior only for users of `prop-types` package
          invariant(
            false,
            'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
            'Use `PropTypes.checkPropTypes()` to call them. ' +
            'Read more at http://fb.me/use-check-prop-types'
          );
        } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') {
          // Old behavior for people using React.PropTypes
          var cacheKey = componentName + ':' + propName;
          if (
            !manualPropTypeCallCache[cacheKey] &&
            // Avoid spamming the console because they are often not actionable except for lib authors
            manualPropTypeWarningCount < 3
          ) {
            warning(
              false,
              'You are manually calling a React.PropTypes validation ' +
              'function for the `%s` prop on `%s`. This is deprecated ' +
              'and will throw in the standalone `prop-types` package. ' +
              'You may be seeing this warning due to a third-party PropTypes ' +
              'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.',
              propFullName,
              componentName
            );
            manualPropTypeCallCache[cacheKey] = true;
            manualPropTypeWarningCount++;
          }
        }
      }
      if (props[propName] == null) {
        if (isRequired) {
          if (props[propName] === null) {
            return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
          }
          return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
        }
        return null;
      } else {
        return validate(props, propName, componentName, location, propFullName);
      }
    }

    var chainedCheckType = checkType.bind(null, false);
    chainedCheckType.isRequired = checkType.bind(null, true);

    return chainedCheckType;
  }

  function createPrimitiveTypeChecker(expectedType) {
    function validate(props, propName, componentName, location, propFullName, secret) {
      var propValue = props[propName];
      var propType = getPropType(propValue);
      if (propType !== expectedType) {
        // `propValue` being instance of, say, date/regexp, pass the 'object'
        // check, but we can offer a more precise error message here rather than
        // 'of type `object`'.
        var preciseType = getPreciseType(propValue);

        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createAnyTypeChecker() {
    return createChainableTypeChecker(emptyFunction.thatReturnsNull);
  }

  function createArrayOfTypeChecker(typeChecker) {
    function validate(props, propName, componentName, location, propFullName) {
      if (typeof typeChecker !== 'function') {
        return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');
      }
      var propValue = props[propName];
      if (!Array.isArray(propValue)) {
        var propType = getPropType(propValue);
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
      }
      for (var i = 0; i < propValue.length; i++) {
        var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);
        if (error instanceof Error) {
          return error;
        }
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createElementTypeChecker() {
    function validate(props, propName, componentName, location, propFullName) {
      var propValue = props[propName];
      if (!isValidElement(propValue)) {
        var propType = getPropType(propValue);
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createInstanceTypeChecker(expectedClass) {
    function validate(props, propName, componentName, location, propFullName) {
      if (!(props[propName] instanceof expectedClass)) {
        var expectedClassName = expectedClass.name || ANONYMOUS;
        var actualClassName = getClassName(props[propName]);
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createEnumTypeChecker(expectedValues) {
    if (!Array.isArray(expectedValues)) {
      process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0;
      return emptyFunction.thatReturnsNull;
    }

    function validate(props, propName, componentName, location, propFullName) {
      var propValue = props[propName];
      for (var i = 0; i < expectedValues.length; i++) {
        if (is(propValue, expectedValues[i])) {
          return null;
        }
      }

      var valuesString = JSON.stringify(expectedValues);
      return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
    }
    return createChainableTypeChecker(validate);
  }

  function createObjectOfTypeChecker(typeChecker) {
    function validate(props, propName, componentName, location, propFullName) {
      if (typeof typeChecker !== 'function') {
        return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
      }
      var propValue = props[propName];
      var propType = getPropType(propValue);
      if (propType !== 'object') {
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
      }
      for (var key in propValue) {
        if (propValue.hasOwnProperty(key)) {
          var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
          if (error instanceof Error) {
            return error;
          }
        }
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createUnionTypeChecker(arrayOfTypeCheckers) {
    if (!Array.isArray(arrayOfTypeCheckers)) {
      process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
      return emptyFunction.thatReturnsNull;
    }

    function validate(props, propName, componentName, location, propFullName) {
      for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
        var checker = arrayOfTypeCheckers[i];
        if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) {
          return null;
        }
      }

      return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
    }
    return createChainableTypeChecker(validate);
  }

  function createNodeChecker() {
    function validate(props, propName, componentName, location, propFullName) {
      if (!isNode(props[propName])) {
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function createShapeTypeChecker(shapeTypes) {
    function validate(props, propName, componentName, location, propFullName) {
      var propValue = props[propName];
      var propType = getPropType(propValue);
      if (propType !== 'object') {
        return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
      }
      for (var key in shapeTypes) {
        var checker = shapeTypes[key];
        if (!checker) {
          continue;
        }
        var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
        if (error) {
          return error;
        }
      }
      return null;
    }
    return createChainableTypeChecker(validate);
  }

  function isNode(propValue) {
    switch (typeof propValue) {
      case 'number':
      case 'string':
      case 'undefined':
        return true;
      case 'boolean':
        return !propValue;
      case 'object':
        if (Array.isArray(propValue)) {
          return propValue.every(isNode);
        }
        if (propValue === null || isValidElement(propValue)) {
          return true;
        }

        var iteratorFn = getIteratorFn(propValue);
        if (iteratorFn) {
          var iterator = iteratorFn.call(propValue);
          var step;
          if (iteratorFn !== propValue.entries) {
            while (!(step = iterator.next()).done) {
              if (!isNode(step.value)) {
                return false;
              }
            }
          } else {
            // Iterator will provide entry [k,v] tuples rather than values.
            while (!(step = iterator.next()).done) {
              var entry = step.value;
              if (entry) {
                if (!isNode(entry[1])) {
                  return false;
                }
              }
            }
          }
        } else {
          return false;
        }

        return true;
      default:
        return false;
    }
  }

  function isSymbol(propType, propValue) {
    // Native Symbol.
    if (propType === 'symbol') {
      return true;
    }

    // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
    if (propValue['@@toStringTag'] === 'Symbol') {
      return true;
    }

    // Fallback for non-spec compliant Symbols which are polyfilled.
    if (typeof Symbol === 'function' && propValue instanceof Symbol) {
      return true;
    }

    return false;
  }

  // Equivalent of `typeof` but with special handling for array and regexp.
  function getPropType(propValue) {
    var propType = typeof propValue;
    if (Array.isArray(propValue)) {
      return 'array';
    }
    if (propValue instanceof RegExp) {
      // Old webkits (at least until Android 4.0) return 'function' rather than
      // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
      // passes PropTypes.object.
      return 'object';
    }
    if (isSymbol(propType, propValue)) {
      return 'symbol';
    }
    return propType;
  }

  // This handles more types than `getPropType`. Only used for error messages.
  // See `createPrimitiveTypeChecker`.
  function getPreciseType(propValue) {
    var propType = getPropType(propValue);
    if (propType === 'object') {
      if (propValue instanceof Date) {
        return 'date';
      } else if (propValue instanceof RegExp) {
        return 'regexp';
      }
    }
    return propType;
  }

  // Returns class name of the object, if any.
  function getClassName(propValue) {
    if (!propValue.constructor || !propValue.constructor.name) {
      return ANONYMOUS;
    }
    return propValue.constructor.name;
  }

  ReactPropTypes.checkPropTypes = checkPropTypes;
  ReactPropTypes.PropTypes = ReactPropTypes;

  return ReactPropTypes;
};

}).call(this,require('_process'))

},{"./checkPropTypes":343,"./lib/ReactPropTypesSecret":347,"_process":334,"fbjs/lib/emptyFunction":348,"fbjs/lib/invariant":349,"fbjs/lib/warning":350}],346:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

if (process.env.NODE_ENV !== 'production') {
  var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&
    Symbol.for &&
    Symbol.for('react.element')) ||
    0xeac7;

  var isValidElement = function(object) {
    return typeof object === 'object' &&
      object !== null &&
      object.$$typeof === REACT_ELEMENT_TYPE;
  };

  // By explicitly using `prop-types` you are opting into new development behavior.
  // http://fb.me/prop-types-in-prod
  var throwOnDirectAccess = true;
  module.exports = require('./factoryWithTypeCheckers')(isValidElement, throwOnDirectAccess);
} else {
  // By explicitly using `prop-types` you are opting into new production behavior.
  // http://fb.me/prop-types-in-prod
  module.exports = require('./factoryWithThrowingShims')();
}

}).call(this,require('_process'))

},{"./factoryWithThrowingShims":344,"./factoryWithTypeCheckers":345,"_process":334}],347:[function(require,module,exports){
/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';

module.exports = ReactPropTypesSecret;

},{}],348:[function(require,module,exports){
"use strict";

/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * 
 */

function makeEmptyFunction(arg) {
  return function () {
    return arg;
  };
}

/**
 * This function accepts and discards inputs; it has no side effects. This is
 * primarily useful idiomatically for overridable function endpoints which
 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
 */
var emptyFunction = function emptyFunction() {};

emptyFunction.thatReturns = makeEmptyFunction;
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
emptyFunction.thatReturnsThis = function () {
  return this;
};
emptyFunction.thatReturnsArgument = function (arg) {
  return arg;
};

module.exports = emptyFunction;
},{}],349:[function(require,module,exports){
(function (process){
/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 */

'use strict';

/**
 * Use invariant() to assert state which your program assumes to be true.
 *
 * Provide sprintf-style format (only %s is supported) and arguments
 * to provide information about what broke and what you were
 * expecting.
 *
 * The invariant message will be stripped in production, but the invariant
 * will remain to ensure logic does not differ in production.
 */

var validateFormat = function validateFormat(format) {};

if (process.env.NODE_ENV !== 'production') {
  validateFormat = function validateFormat(format) {
    if (format === undefined) {
      throw new Error('invariant requires an error message argument');
    }
  };
}

function invariant(condition, format, a, b, c, d, e, f) {
  validateFormat(format);

  if (!condition) {
    var error;
    if (format === undefined) {
      error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
    } else {
      var args = [a, b, c, d, e, f];
      var argIndex = 0;
      error = new Error(format.replace(/%s/g, function () {
        return args[argIndex++];
      }));
      error.name = 'Invariant Violation';
    }

    error.framesToPop = 1; // we don't care about invariant's own frame
    throw error;
  }
}

module.exports = invariant;
}).call(this,require('_process'))

},{"_process":334}],350:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 */

'use strict';

var emptyFunction = require('./emptyFunction');

/**
 * Similar to invariant but only logs a warning if the condition is not met.
 * This can be used to log issues in development environments in critical
 * paths. Removing the logging code for production environments will keep the
 * same logic and follow the same code paths.
 */

var warning = emptyFunction;

if (process.env.NODE_ENV !== 'production') {
  (function () {
    var printWarning = function printWarning(format) {
      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      var argIndex = 0;
      var message = 'Warning: ' + format.replace(/%s/g, function () {
        return args[argIndex++];
      });
      if (typeof console !== 'undefined') {
        console.error(message);
      }
      try {
        // --- Welcome to debugging React ---
        // This error was thrown as a convenience so that you can use this stack
        // to find the callsite that caused this warning to fire.
        throw new Error(message);
      } catch (x) {}
    };

    warning = function warning(condition, format) {
      if (format === undefined) {
        throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
      }

      if (format.indexOf('Failed Composite propType: ') === 0) {
        return; // Ignore CompositeComponent proptype check.
      }

      if (!condition) {
        for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
          args[_key2 - 2] = arguments[_key2];
        }

        printWarning.apply(undefined, [format].concat(args));
      }
    };
  })();
}

module.exports = warning;
}).call(this,require('_process'))

},{"./emptyFunction":348,"_process":334}],351:[function(require,module,exports){
'use strict';

module.exports = require('react/lib/ReactDOM');

},{"react/lib/ReactDOM":431}],352:[function(require,module,exports){
'use strict';

module.exports = require('react/lib/ReactDOMServer');

},{"react/lib/ReactDOMServer":441}],353:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactDom = require('react-dom');

var _eventlistener = require('eventlistener');

var _lodash = require('lodash.debounce');

var _lodash2 = _interopRequireDefault(_lodash);

var _lodash3 = require('lodash.throttle');

var _lodash4 = _interopRequireDefault(_lodash3);

var _parentScroll = require('./utils/parentScroll');

var _parentScroll2 = _interopRequireDefault(_parentScroll);

var _inViewport = require('./utils/inViewport');

var _inViewport2 = _interopRequireDefault(_inViewport);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var LazyLoad = function (_Component) {
  _inherits(LazyLoad, _Component);

  function LazyLoad(props) {
    _classCallCheck(this, LazyLoad);

    var _this = _possibleConstructorReturn(this, (LazyLoad.__proto__ || Object.getPrototypeOf(LazyLoad)).call(this, props));

    _this.lazyLoadHandler = _this.lazyLoadHandler.bind(_this);

    if (props.throttle > 0) {
      if (props.debounce) {
        _this.lazyLoadHandler = (0, _lodash2.default)(_this.lazyLoadHandler, props.throttle);
      } else {
        _this.lazyLoadHandler = (0, _lodash4.default)(_this.lazyLoadHandler, props.throttle);
      }
    }

    _this.state = { visible: false };
    return _this;
  }

  _createClass(LazyLoad, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this._mounted = true;
      var eventNode = this.getEventNode();

      this.lazyLoadHandler();

      if (this.lazyLoadHandler.flush) {
        this.lazyLoadHandler.flush();
      }

      (0, _eventlistener.add)(window, 'resize', this.lazyLoadHandler);
      (0, _eventlistener.add)(eventNode, 'scroll', this.lazyLoadHandler);
    }
  }, {
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps() {
      if (!this.state.visible) {
        this.lazyLoadHandler();
      }
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate(_nextProps, nextState) {
      return nextState.visible;
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this._mounted = false;
      if (this.lazyLoadHandler.cancel) {
        this.lazyLoadHandler.cancel();
      }

      this.detachListeners();
    }
  }, {
    key: 'getEventNode',
    value: function getEventNode() {
      return (0, _parentScroll2.default)((0, _reactDom.findDOMNode)(this));
    }
  }, {
    key: 'getOffset',
    value: function getOffset() {
      var _props = this.props,
          offset = _props.offset,
          offsetVertical = _props.offsetVertical,
          offsetHorizontal = _props.offsetHorizontal,
          offsetTop = _props.offsetTop,
          offsetBottom = _props.offsetBottom,
          offsetLeft = _props.offsetLeft,
          offsetRight = _props.offsetRight,
          threshold = _props.threshold;


      var _offsetAll = threshold || offset;
      var _offsetVertical = offsetVertical || _offsetAll;
      var _offsetHorizontal = offsetHorizontal || _offsetAll;

      return {
        top: offsetTop || _offsetVertical,
        bottom: offsetBottom || _offsetVertical,
        left: offsetLeft || _offsetHorizontal,
        right: offsetRight || _offsetHorizontal
      };
    }
  }, {
    key: 'lazyLoadHandler',
    value: function lazyLoadHandler() {
      if (!this._mounted) {
        return;
      }
      var offset = this.getOffset();
      var node = (0, _reactDom.findDOMNode)(this);
      var eventNode = this.getEventNode();

      if ((0, _inViewport2.default)(node, eventNode, offset)) {
        var onContentVisible = this.props.onContentVisible;


        this.setState({ visible: true }, function () {
          if (onContentVisible) {
            onContentVisible();
          }
        });
        this.detachListeners();
      }
    }
  }, {
    key: 'detachListeners',
    value: function detachListeners() {
      var eventNode = this.getEventNode();

      (0, _eventlistener.remove)(window, 'resize', this.lazyLoadHandler);
      (0, _eventlistener.remove)(eventNode, 'scroll', this.lazyLoadHandler);
    }
  }, {
    key: 'render',
    value: function render() {
      var _props2 = this.props,
          children = _props2.children,
          className = _props2.className,
          height = _props2.height,
          width = _props2.width;
      var visible = this.state.visible;


      var elStyles = { height: height, width: width };
      var elClasses = 'LazyLoad' + (visible ? ' is-visible' : '') + (className ? ' ' + className : '');

      return _react2.default.createElement(this.props.elementType, {
        className: elClasses,
        style: elStyles
      }, visible && _react.Children.only(children));
    }
  }]);

  return LazyLoad;
}(_react.Component);

exports.default = LazyLoad;


LazyLoad.propTypes = {
  children: _propTypes2.default.node.isRequired,
  className: _propTypes2.default.string,
  debounce: _propTypes2.default.bool,
  elementType: _propTypes2.default.string,
  height: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  offset: _propTypes2.default.number,
  offsetBottom: _propTypes2.default.number,
  offsetHorizontal: _propTypes2.default.number,
  offsetLeft: _propTypes2.default.number,
  offsetRight: _propTypes2.default.number,
  offsetTop: _propTypes2.default.number,
  offsetVertical: _propTypes2.default.number,
  threshold: _propTypes2.default.number,
  throttle: _propTypes2.default.number,
  width: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  onContentVisible: _propTypes2.default.func
};

LazyLoad.defaultProps = {
  elementType: 'div',
  debounce: true,
  offset: 0,
  offsetBottom: 0,
  offsetHorizontal: 0,
  offsetLeft: 0,
  offsetRight: 0,
  offsetTop: 0,
  offsetVertical: 0,
  throttle: 250
};
},{"./utils/inViewport":355,"./utils/parentScroll":356,"eventlistener":302,"lodash.debounce":331,"lodash.throttle":332,"prop-types":346,"react":525,"react-dom":351}],354:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = getElementPosition;
/*
* Finds element's position relative to the whole document,
* rather than to the viewport as it is the case with .getBoundingClientRect().
*/
function getElementPosition(element) {
  var rect = element.getBoundingClientRect();

  return {
    top: rect.top + window.pageYOffset,
    left: rect.left + window.pageXOffset
  };
}
},{}],355:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = inViewport;

var _getElementPosition = require('./getElementPosition');

var _getElementPosition2 = _interopRequireDefault(_getElementPosition);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var isHidden = function isHidden(element) {
  return element.offsetParent === null;
};

function inViewport(element, container, customOffset) {
  if (isHidden(element)) {
    return false;
  }

  var top = void 0;
  var bottom = void 0;
  var left = void 0;
  var right = void 0;

  if (typeof container === 'undefined' || container === window) {
    top = window.pageYOffset;
    left = window.pageXOffset;
    bottom = top + window.innerHeight;
    right = left + window.innerWidth;
  } else {
    var containerPosition = (0, _getElementPosition2.default)(container);

    top = containerPosition.top;
    left = containerPosition.left;
    bottom = top + container.offsetHeight;
    right = left + container.offsetWidth;
  }

  var elementPosition = (0, _getElementPosition2.default)(element);

  return top <= elementPosition.top + element.offsetHeight + customOffset.top && bottom >= elementPosition.top - customOffset.bottom && left <= elementPosition.left + element.offsetWidth + customOffset.left && right >= elementPosition.left - customOffset.right;
}
},{"./getElementPosition":354}],356:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var style = function style(element, prop) {
  return typeof getComputedStyle !== 'undefined' ? getComputedStyle(element, null).getPropertyValue(prop) : element.style[prop];
};

var overflow = function overflow(element) {
  return style(element, 'overflow') + style(element, 'overflow-y') + style(element, 'overflow-x');
};

var scrollParent = function scrollParent(element) {
  if (!(element instanceof HTMLElement)) {
    return window;
  }

  var parent = element;

  while (parent) {
    if (parent === document.body || parent === document.documentElement) {
      break;
    }

    if (!parent.parentNode) {
      break;
    }

    if (/(scroll|auto)/.test(overflow(parent))) {
      return parent;
    }

    parent = parent.parentNode;
  }

  return window;
};

exports.default = scrollParent;
},{}],357:[function(require,module,exports){
/**
 * Represents a cancellation caused by navigating away
 * before the previous transition has fully resolved.
 */
"use strict";

function Cancellation() {}

module.exports = Cancellation;
},{}],358:[function(require,module,exports){
'use strict';

var invariant = require('invariant');
var canUseDOM = require('can-use-dom');

var History = {

  /**
   * The current number of entries in the history.
   *
   * Note: This property is read-only.
   */
  length: 1,

  /**
   * Sends the browser back one entry in the history.
   */
  back: function back() {
    invariant(canUseDOM, 'Cannot use History.back without a DOM');

    // Do this first so that History.length will
    // be accurate in location change listeners.
    History.length -= 1;

    window.history.back();
  }

};

module.exports = History;
},{"can-use-dom":298,"invariant":330}],359:[function(require,module,exports){
/* jshint -W084 */
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var PathUtils = require('./PathUtils');

function deepSearch(route, pathname, query) {
  // Check the subtree first to find the most deeply-nested match.
  var childRoutes = route.childRoutes;
  if (childRoutes) {
    var match, childRoute;
    for (var i = 0, len = childRoutes.length; i < len; ++i) {
      childRoute = childRoutes[i];

      if (childRoute.isDefault || childRoute.isNotFound) continue; // Check these in order later.

      if (match = deepSearch(childRoute, pathname, query)) {
        // A route in the subtree matched! Add this route and we're done.
        match.routes.unshift(route);
        return match;
      }
    }
  }

  // No child routes matched; try the default route.
  var defaultRoute = route.defaultRoute;
  if (defaultRoute && (params = PathUtils.extractParams(defaultRoute.path, pathname))) return new Match(pathname, params, query, [route, defaultRoute]);

  // Does the "not found" route match?
  var notFoundRoute = route.notFoundRoute;
  if (notFoundRoute && (params = PathUtils.extractParams(notFoundRoute.path, pathname))) return new Match(pathname, params, query, [route, notFoundRoute]);

  // Last attempt: check this route.
  var params = PathUtils.extractParams(route.path, pathname);
  if (params) return new Match(pathname, params, query, [route]);

  return null;
}

var Match = (function () {
  _createClass(Match, null, [{
    key: 'findMatch',

    /**
     * Attempts to match depth-first a route in the given route's
     * subtree against the given path and returns the match if it
     * succeeds, null if no match can be made.
     */
    value: function findMatch(routes, path) {
      var pathname = PathUtils.withoutQuery(path);
      var query = PathUtils.extractQuery(path);
      var match = null;

      for (var i = 0, len = routes.length; match == null && i < len; ++i) match = deepSearch(routes[i], pathname, query);

      return match;
    }
  }]);

  function Match(pathname, params, query, routes) {
    _classCallCheck(this, Match);

    this.pathname = pathname;
    this.params = params;
    this.query = query;
    this.routes = routes;
  }

  return Match;
})();

module.exports = Match;
},{"./PathUtils":361}],360:[function(require,module,exports){
'use strict';

var PropTypes = require('./PropTypes');

/**
 * A mixin for components that modify the URL.
 *
 * Example:
 *
 *   var MyLink = React.createClass({
 *     mixins: [ Router.Navigation ],
 *     handleClick(event) {
 *       event.preventDefault();
 *       this.transitionTo('aRoute', { the: 'params' }, { the: 'query' });
 *     },
 *     render() {
 *       return (
 *         <a onClick={this.handleClick}>Click me!</a>
 *       );
 *     }
 *   });
 */
var Navigation = {

  contextTypes: {
    router: PropTypes.router.isRequired
  },

  /**
   * Returns an absolute URL path created from the given route
   * name, URL parameters, and query values.
   */
  makePath: function makePath(to, params, query) {
    return this.context.router.makePath(to, params, query);
  },

  /**
   * Returns a string that may safely be used as the href of a
   * link to the route with the given name.
   */
  makeHref: function makeHref(to, params, query) {
    return this.context.router.makeHref(to, params, query);
  },

  /**
   * Transitions to the URL specified in the arguments by pushing
   * a new URL onto the history stack.
   */
  transitionTo: function transitionTo(to, params, query) {
    this.context.router.transitionTo(to, params, query);
  },

  /**
   * Transitions to the URL specified in the arguments by replacing
   * the current URL in the history stack.
   */
  replaceWith: function replaceWith(to, params, query) {
    this.context.router.replaceWith(to, params, query);
  },

  /**
   * Transitions to the previous URL.
   */
  goBack: function goBack() {
    return this.context.router.goBack();
  }

};

module.exports = Navigation;
},{"./PropTypes":362}],361:[function(require,module,exports){
'use strict';

var invariant = require('invariant');
var assign = require('object-assign');
var qs = require('qs');

var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g;
var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g;
var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?\/|\/\?(?![^\/=]+=.*$)/g;
var queryMatcher = /\?(.*)$/;

var _compiledPatterns = {};

function compilePattern(pattern) {
  if (!(pattern in _compiledPatterns)) {
    var paramNames = [];
    var source = pattern.replace(paramCompileMatcher, function (match, paramName) {
      if (paramName) {
        paramNames.push(paramName);
        return '([^/?#]+)';
      } else if (match === '*') {
        paramNames.push('splat');
        return '(.*?)';
      } else {
        return '\\' + match;
      }
    });

    _compiledPatterns[pattern] = {
      matcher: new RegExp('^' + source + '$', 'i'),
      paramNames: paramNames
    };
  }

  return _compiledPatterns[pattern];
}

var PathUtils = {

  /**
   * Returns true if the given path is absolute.
   */
  isAbsolute: function isAbsolute(path) {
    return path.charAt(0) === '/';
  },

  /**
   * Joins two URL paths together.
   */
  join: function join(a, b) {
    return a.replace(/\/*$/, '/') + b;
  },

  /**
   * Returns an array of the names of all parameters in the given pattern.
   */
  extractParamNames: function extractParamNames(pattern) {
    return compilePattern(pattern).paramNames;
  },

  /**
   * Extracts the portions of the given URL path that match the given pattern
   * and returns an object of param name => value pairs. Returns null if the
   * pattern does not match the given path.
   */
  extractParams: function extractParams(pattern, path) {
    var _compilePattern = compilePattern(pattern);

    var matcher = _compilePattern.matcher;
    var paramNames = _compilePattern.paramNames;

    var match = path.match(matcher);

    if (!match) return null;

    var params = {};

    paramNames.forEach(function (paramName, index) {
      params[paramName] = match[index + 1];
    });

    return params;
  },

  /**
   * Returns a version of the given route path with params interpolated. Throws
   * if there is a dynamic segment of the route path for which there is no param.
   */
  injectParams: function injectParams(pattern, params) {
    params = params || {};

    var splatIndex = 0;

    return pattern.replace(paramInjectMatcher, function (match, paramName) {
      paramName = paramName || 'splat';

      // If param is optional don't check for existence
      if (paramName.slice(-1) === '?') {
        paramName = paramName.slice(0, -1);

        if (params[paramName] == null) return '';
      } else {
        invariant(params[paramName] != null, 'Missing "%s" parameter for path "%s"', paramName, pattern);
      }

      var segment;
      if (paramName === 'splat' && Array.isArray(params[paramName])) {
        segment = params[paramName][splatIndex++];

        invariant(segment != null, 'Missing splat # %s for path "%s"', splatIndex, pattern);
      } else {
        segment = params[paramName];
      }

      return segment;
    }).replace(paramInjectTrailingSlashMatcher, '/');
  },

  /**
   * Returns an object that is the result of parsing any query string contained
   * in the given path, null if the path contains no query string.
   */
  extractQuery: function extractQuery(path) {
    var match = path.match(queryMatcher);
    return match && qs.parse(match[1]);
  },

  /**
   * Returns a version of the given path without the query string.
   */
  withoutQuery: function withoutQuery(path) {
    return path.replace(queryMatcher, '');
  },

  /**
   * Returns a version of the given path with the parameters in the given
   * query merged into the query string.
   */
  withQuery: function withQuery(path, query) {
    var existingQuery = PathUtils.extractQuery(path);

    if (existingQuery) query = query ? assign(existingQuery, query) : existingQuery;

    var queryString = qs.stringify(query, { arrayFormat: 'brackets' });

    if (queryString) return PathUtils.withoutQuery(path) + '?' + queryString;

    return PathUtils.withoutQuery(path);
  }

};

module.exports = PathUtils;
},{"invariant":330,"object-assign":391,"qs":392}],362:[function(require,module,exports){
'use strict';

var assign = require('object-assign');
var ReactPropTypes = require('react').PropTypes;
var Route = require('./Route');

var PropTypes = assign({}, ReactPropTypes, {

  /**
   * Indicates that a prop should be falsy.
   */
  falsy: function falsy(props, propName, componentName) {
    if (props[propName]) return new Error('<' + componentName + '> should not have a "' + propName + '" prop');
  },

  /**
   * Indicates that a prop should be a Route object.
   */
  route: ReactPropTypes.instanceOf(Route),

  /**
   * Indicates that a prop should be a Router object.
   */
  //router: ReactPropTypes.instanceOf(Router) // TODO
  router: ReactPropTypes.func

});

module.exports = PropTypes;
},{"./Route":364,"object-assign":391,"react":525}],363:[function(require,module,exports){
/**
 * Encapsulates a redirect to the given route.
 */
"use strict";

function Redirect(to, params, query) {
  this.to = to;
  this.params = params;
  this.query = query;
}

module.exports = Redirect;
},{}],364:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var assign = require('object-assign');
var invariant = require('invariant');
var warning = require('./warning');
var PathUtils = require('./PathUtils');

var _currentRoute;

var Route = (function () {
  _createClass(Route, null, [{
    key: 'createRoute',

    /**
     * Creates and returns a new route. Options may be a URL pathname string
     * with placeholders for named params or an object with any of the following
     * properties:
     *
     * - name                     The name of the route. This is used to lookup a
     *                            route relative to its parent route and should be
     *                            unique among all child routes of the same parent
     * - path                     A URL pathname string with optional placeholders
     *                            that specify the names of params to extract from
     *                            the URL when the path matches. Defaults to `/${name}`
     *                            when there is a name given, or the path of the parent
     *                            route, or /
     * - ignoreScrollBehavior     True to make this route (and all descendants) ignore
     *                            the scroll behavior of the router
     * - isDefault                True to make this route the default route among all
     *                            its siblings
     * - isNotFound               True to make this route the "not found" route among
     *                            all its siblings
     * - onEnter                  A transition hook that will be called when the
     *                            router is going to enter this route
     * - onLeave                  A transition hook that will be called when the
     *                            router is going to leave this route
     * - handler                  A React component that will be rendered when
     *                            this route is active
     * - parentRoute              The parent route to use for this route. This option
     *                            is automatically supplied when creating routes inside
     *                            the callback to another invocation of createRoute. You
     *                            only ever need to use this when declaring routes
     *                            independently of one another to manually piece together
     *                            the route hierarchy
     *
     * The callback may be used to structure your route hierarchy. Any call to
     * createRoute, createDefaultRoute, createNotFoundRoute, or createRedirect
     * inside the callback automatically uses this route as its parent.
     */
    value: function createRoute(options, callback) {
      options = options || {};

      if (typeof options === 'string') options = { path: options };

      var parentRoute = _currentRoute;

      if (parentRoute) {
        warning(options.parentRoute == null || options.parentRoute === parentRoute, 'You should not use parentRoute with createRoute inside another route\'s child callback; it is ignored');
      } else {
        parentRoute = options.parentRoute;
      }

      var name = options.name;
      var path = options.path || name;

      if (path && !(options.isDefault || options.isNotFound)) {
        if (PathUtils.isAbsolute(path)) {
          if (parentRoute) {
            invariant(path === parentRoute.path || parentRoute.paramNames.length === 0, 'You cannot nest path "%s" inside "%s"; the parent requires URL parameters', path, parentRoute.path);
          }
        } else if (parentRoute) {
          // Relative paths extend their parent.
          path = PathUtils.join(parentRoute.path, path);
        } else {
          path = '/' + path;
        }
      } else {
        path = parentRoute ? parentRoute.path : '/';
      }

      if (options.isNotFound && !/\*$/.test(path)) path += '*'; // Auto-append * to the path of not found routes.

      var route = new Route(name, path, options.ignoreScrollBehavior, options.isDefault, options.isNotFound, options.onEnter, options.onLeave, options.handler);

      if (parentRoute) {
        if (route.isDefault) {
          invariant(parentRoute.defaultRoute == null, '%s may not have more than one default route', parentRoute);

          parentRoute.defaultRoute = route;
        } else if (route.isNotFound) {
          invariant(parentRoute.notFoundRoute == null, '%s may not have more than one not found route', parentRoute);

          parentRoute.notFoundRoute = route;
        }

        parentRoute.appendChild(route);
      }

      // Any routes created in the callback
      // use this route as their parent.
      if (typeof callback === 'function') {
        var currentRoute = _currentRoute;
        _currentRoute = route;
        callback.call(route, route);
        _currentRoute = currentRoute;
      }

      return route;
    }

    /**
     * Creates and returns a route that is rendered when its parent matches
     * the current URL.
     */
  }, {
    key: 'createDefaultRoute',
    value: function createDefaultRoute(options) {
      return Route.createRoute(assign({}, options, { isDefault: true }));
    }

    /**
     * Creates and returns a route that is rendered when its parent matches
     * the current URL but none of its siblings do.
     */
  }, {
    key: 'createNotFoundRoute',
    value: function createNotFoundRoute(options) {
      return Route.createRoute(assign({}, options, { isNotFound: true }));
    }

    /**
     * Creates and returns a route that automatically redirects the transition
     * to another route. In addition to the normal options to createRoute, this
     * function accepts the following options:
     *
     * - from         An alias for the `path` option. Defaults to *
     * - to           The path/route/route name to redirect to
     * - params       The params to use in the redirect URL. Defaults
     *                to using the current params
     * - query        The query to use in the redirect URL. Defaults
     *                to using the current query
     */
  }, {
    key: 'createRedirect',
    value: function createRedirect(options) {
      return Route.createRoute(assign({}, options, {
        path: options.path || options.from || '*',
        onEnter: function onEnter(transition, params, query) {
          transition.redirect(options.to, options.params || params, options.query || query);
        }
      }));
    }
  }]);

  function Route(name, path, ignoreScrollBehavior, isDefault, isNotFound, onEnter, onLeave, handler) {
    _classCallCheck(this, Route);

    this.name = name;
    this.path = path;
    this.paramNames = PathUtils.extractParamNames(this.path);
    this.ignoreScrollBehavior = !!ignoreScrollBehavior;
    this.isDefault = !!isDefault;
    this.isNotFound = !!isNotFound;
    this.onEnter = onEnter;
    this.onLeave = onLeave;
    this.handler = handler;
  }

  /**
   * Appends the given route to this route's child routes.
   */

  _createClass(Route, [{
    key: 'appendChild',
    value: function appendChild(route) {
      invariant(route instanceof Route, 'route.appendChild must use a valid Route');

      if (!this.childRoutes) this.childRoutes = [];

      this.childRoutes.push(route);
    }
  }, {
    key: 'toString',
    value: function toString() {
      var string = '<Route';

      if (this.name) string += ' name="' + this.name + '"';

      string += ' path="' + this.path + '">';

      return string;
    }
  }]);

  return Route;
})();

module.exports = Route;
},{"./PathUtils":361,"./warning":390,"invariant":330,"object-assign":391}],365:[function(require,module,exports){
'use strict';

var invariant = require('invariant');
var canUseDOM = require('can-use-dom');
var getWindowScrollPosition = require('./getWindowScrollPosition');

function shouldUpdateScroll(state, prevState) {
  if (!prevState) return true;

  // Don't update scroll position when only the query has changed.
  if (state.pathname === prevState.pathname) return false;

  var routes = state.routes;
  var prevRoutes = prevState.routes;

  var sharedAncestorRoutes = routes.filter(function (route) {
    return prevRoutes.indexOf(route) !== -1;
  });

  return !sharedAncestorRoutes.some(function (route) {
    return route.ignoreScrollBehavior;
  });
}

/**
 * Provides the router with the ability to manage window scroll position
 * according to its scroll behavior.
 */
var ScrollHistory = {

  statics: {

    /**
     * Records curent scroll position as the last known position for the given URL path.
     */
    recordScrollPosition: function recordScrollPosition(path) {
      if (!this.scrollHistory) this.scrollHistory = {};

      this.scrollHistory[path] = getWindowScrollPosition();
    },

    /**
     * Returns the last known scroll position for the given URL path.
     */
    getScrollPosition: function getScrollPosition(path) {
      if (!this.scrollHistory) this.scrollHistory = {};

      return this.scrollHistory[path] || null;
    }

  },

  componentWillMount: function componentWillMount() {
    invariant(this.constructor.getScrollBehavior() == null || canUseDOM, 'Cannot use scroll behavior without a DOM');
  },

  componentDidMount: function componentDidMount() {
    this._updateScroll();
  },

  componentDidUpdate: function componentDidUpdate(prevProps, prevState) {
    this._updateScroll(prevState);
  },

  _updateScroll: function _updateScroll(prevState) {
    if (!shouldUpdateScroll(this.state, prevState)) return;

    var scrollBehavior = this.constructor.getScrollBehavior();

    if (scrollBehavior) scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path), this.state.action);
  }

};

module.exports = ScrollHistory;
},{"./getWindowScrollPosition":380,"can-use-dom":298,"invariant":330}],366:[function(require,module,exports){
'use strict';

var PropTypes = require('./PropTypes');

/**
 * A mixin for components that need to know the path, routes, URL
 * params and query that are currently active.
 *
 * Example:
 *
 *   var AboutLink = React.createClass({
 *     mixins: [ Router.State ],
 *     render() {
 *       var className = this.props.className;
 *
 *       if (this.isActive('about'))
 *         className += ' is-active';
 *
 *       return React.DOM.a({ className: className }, this.props.children);
 *     }
 *   });
 */
var State = {

  contextTypes: {
    router: PropTypes.router.isRequired
  },

  /**
   * Returns the current URL path.
   */
  getPath: function getPath() {
    return this.context.router.getCurrentPath();
  },

  /**
   * Returns the current URL path without the query string.
   */
  getPathname: function getPathname() {
    return this.context.router.getCurrentPathname();
  },

  /**
   * Returns an object of the URL params that are currently active.
   */
  getParams: function getParams() {
    return this.context.router.getCurrentParams();
  },

  /**
   * Returns an object of the query params that are currently active.
   */
  getQuery: function getQuery() {
    return this.context.router.getCurrentQuery();
  },

  /**
   * Returns an array of the routes that are currently active.
   */
  getRoutes: function getRoutes() {
    return this.context.router.getCurrentRoutes();
  },

  /**
   * A helper method to determine if a given route, params, and query
   * are active.
   */
  isActive: function isActive(to, params, query) {
    return this.context.router.isActive(to, params, query);
  }

};

module.exports = State;
},{"./PropTypes":362}],367:[function(require,module,exports){
/* jshint -W058 */

'use strict';

var Cancellation = require('./Cancellation');
var Redirect = require('./Redirect');

/**
 * Encapsulates a transition to a given path.
 *
 * The willTransitionTo and willTransitionFrom handlers receive
 * an instance of this class as their first argument.
 */
function Transition(path, retry) {
  this.path = path;
  this.abortReason = null;
  // TODO: Change this to router.retryTransition(transition)
  this.retry = retry.bind(this);
}

Transition.prototype.abort = function (reason) {
  if (this.abortReason == null) this.abortReason = reason || 'ABORT';
};

Transition.prototype.redirect = function (to, params, query) {
  this.abort(new Redirect(to, params, query));
};

Transition.prototype.cancel = function () {
  this.abort(new Cancellation());
};

Transition.from = function (transition, routes, components, callback) {
  routes.reduce(function (callback, route, index) {
    return function (error) {
      if (error || transition.abortReason) {
        callback(error);
      } else if (route.onLeave) {
        try {
          route.onLeave(transition, components[index], callback);

          // If there is no callback in the argument list, call it automatically.
          if (route.onLeave.length < 3) callback();
        } catch (e) {
          callback(e);
        }
      } else {
        callback();
      }
    };
  }, callback)();
};

Transition.to = function (transition, routes, params, query, callback) {
  routes.reduceRight(function (callback, route) {
    return function (error) {
      if (error || transition.abortReason) {
        callback(error);
      } else if (route.onEnter) {
        try {
          route.onEnter(transition, params, query, callback);

          // If there is no callback in the argument list, call it automatically.
          if (route.onEnter.length < 4) callback();
        } catch (e) {
          callback(e);
        }
      } else {
        callback();
      }
    };
  }, callback)();
};

module.exports = Transition;
},{"./Cancellation":357,"./Redirect":363}],368:[function(require,module,exports){
/**
 * Actions that modify the URL.
 */
'use strict';

var LocationActions = {

  /**
   * Indicates a new location is being pushed to the history stack.
   */
  PUSH: 'push',

  /**
   * Indicates the current location should be replaced.
   */
  REPLACE: 'replace',

  /**
   * Indicates the most recent entry should be removed from the history stack.
   */
  POP: 'pop'

};

module.exports = LocationActions;
},{}],369:[function(require,module,exports){
'use strict';

var LocationActions = require('../actions/LocationActions');

/**
 * A scroll behavior that attempts to imitate the default behavior
 * of modern browsers.
 */
var ImitateBrowserBehavior = {

  updateScrollPosition: function updateScrollPosition(position, actionType) {
    switch (actionType) {
      case LocationActions.PUSH:
      case LocationActions.REPLACE:
        window.scrollTo(0, 0);
        break;
      case LocationActions.POP:
        if (position) {
          window.scrollTo(position.x, position.y);
        } else {
          window.scrollTo(0, 0);
        }
        break;
    }
  }

};

module.exports = ImitateBrowserBehavior;
},{"../actions/LocationActions":368}],370:[function(require,module,exports){
/**
 * A scroll behavior that always scrolls to the top of the page
 * after a transition.
 */
"use strict";

var ScrollToTopBehavior = {

  updateScrollPosition: function updateScrollPosition() {
    window.scrollTo(0, 0);
  }

};

module.exports = ScrollToTopBehavior;
},{}],371:[function(require,module,exports){
/**
 * This component is necessary to get around a context warning
 * present in React 0.13.0. It sovles this by providing a separation
 * between the "owner" and "parent" contexts.
 */

'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var React = require('react');

var ContextWrapper = (function (_React$Component) {
  _inherits(ContextWrapper, _React$Component);

  function ContextWrapper() {
    _classCallCheck(this, ContextWrapper);

    _get(Object.getPrototypeOf(ContextWrapper.prototype), 'constructor', this).apply(this, arguments);
  }

  _createClass(ContextWrapper, [{
    key: 'render',
    value: function render() {
      return this.props.children;
    }
  }]);

  return ContextWrapper;
})(React.Component);

module.exports = ContextWrapper;
},{"react":525}],372:[function(require,module,exports){
'use strict';

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var PropTypes = require('../PropTypes');
var RouteHandler = require('./RouteHandler');
var Route = require('./Route');

/**
 * A <DefaultRoute> component is a special kind of <Route> that
 * renders when its parent matches but none of its siblings do.
 * Only one such route may be used at any given level in the
 * route hierarchy.
 */

var DefaultRoute = (function (_Route) {
  _inherits(DefaultRoute, _Route);

  function DefaultRoute() {
    _classCallCheck(this, DefaultRoute);

    _get(Object.getPrototypeOf(DefaultRoute.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  return DefaultRoute;
})(Route);

DefaultRoute.propTypes = {
  name: PropTypes.string,
  path: PropTypes.falsy,
  children: PropTypes.falsy,
  handler: PropTypes.func.isRequired
};

DefaultRoute.defaultProps = {
  handler: RouteHandler
};

module.exports = DefaultRoute;
},{"../PropTypes":362,"./Route":376,"./RouteHandler":377}],373:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var React = require('react');
var assign = require('object-assign');
var PropTypes = require('../PropTypes');

function isLeftClickEvent(event) {
  return event.button === 0;
}

function isModifiedEvent(event) {
  return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
}

/**
 * <Link> components are used to create an <a> element that links to a route.
 * When that route is active, the link gets an "active" class name (or the
 * value of its `activeClassName` prop).
 *
 * For example, assuming you have the following route:
 *
 *   <Route name="showPost" path="/posts/:postID" handler={Post}/>
 *
 * You could use the following component to link to that route:
 *
 *   <Link to="showPost" params={{ postID: "123" }} />
 *
 * In addition to params, links may pass along query string parameters
 * using the `query` prop.
 *
 *   <Link to="showPost" params={{ postID: "123" }} query={{ show:true }}/>
 */

var Link = (function (_React$Component) {
  _inherits(Link, _React$Component);

  function Link() {
    _classCallCheck(this, Link);

    _get(Object.getPrototypeOf(Link.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  _createClass(Link, [{
    key: 'handleClick',
    value: function handleClick(event) {
      var allowTransition = true;
      var clickResult;

      if (this.props.onClick) clickResult = this.props.onClick(event);

      if (isModifiedEvent(event) || !isLeftClickEvent(event)) return;

      if (clickResult === false || event.defaultPrevented === true) allowTransition = false;

      event.preventDefault();

      if (allowTransition) this.context.router.transitionTo(this.props.to, this.props.params, this.props.query);
    }

    /**
     * Returns the value of the "href" attribute to use on the DOM element.
     */
  }, {
    key: 'getHref',
    value: function getHref() {
      return this.context.router.makeHref(this.props.to, this.props.params, this.props.query);
    }

    /**
     * Returns the value of the "class" attribute to use on the DOM element, which contains
     * the value of the activeClassName property when this <Link> is active.
     */
  }, {
    key: 'getClassName',
    value: function getClassName() {
      var className = this.props.className;

      if (this.getActiveState()) className += ' ' + this.props.activeClassName;

      return className;
    }
  }, {
    key: 'getActiveState',
    value: function getActiveState() {
      return this.context.router.isActive(this.props.to, this.props.params, this.props.query);
    }
  }, {
    key: 'render',
    value: function render() {
      var props = assign({}, this.props, {
        href: this.getHref(),
        className: this.getClassName(),
        onClick: this.handleClick.bind(this)
      });

      if (props.activeStyle && this.getActiveState()) props.style = props.activeStyle;

      delete props.to;
      delete props.params;
      delete props.query;
      delete props.activeClassName;
      delete props.activeStyle;

      return React.DOM.a(props, this.props.children);
    }
  }]);

  return Link;
})(React.Component);

Link.contextTypes = {
  router: PropTypes.router.isRequired
};

Link.propTypes = {
  activeClassName: PropTypes.string.isRequired,
  to: PropTypes.oneOfType([PropTypes.string, PropTypes.route]).isRequired,
  params: PropTypes.object,
  query: PropTypes.object,
  activeStyle: PropTypes.object,
  onClick: PropTypes.func
};

Link.defaultProps = {
  activeClassName: 'active',
  className: ''
};

module.exports = Link;
},{"../PropTypes":362,"object-assign":391,"react":525}],374:[function(require,module,exports){
'use strict';

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var PropTypes = require('../PropTypes');
var RouteHandler = require('./RouteHandler');
var Route = require('./Route');

/**
 * A <NotFoundRoute> is a special kind of <Route> that
 * renders when the beginning of its parent's path matches
 * but none of its siblings do, including any <DefaultRoute>.
 * Only one such route may be used at any given level in the
 * route hierarchy.
 */

var NotFoundRoute = (function (_Route) {
  _inherits(NotFoundRoute, _Route);

  function NotFoundRoute() {
    _classCallCheck(this, NotFoundRoute);

    _get(Object.getPrototypeOf(NotFoundRoute.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  return NotFoundRoute;
})(Route);

NotFoundRoute.propTypes = {
  name: PropTypes.string,
  path: PropTypes.falsy,
  children: PropTypes.falsy,
  handler: PropTypes.func.isRequired
};

NotFoundRoute.defaultProps = {
  handler: RouteHandler
};

module.exports = NotFoundRoute;
},{"../PropTypes":362,"./Route":376,"./RouteHandler":377}],375:[function(require,module,exports){
'use strict';

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var PropTypes = require('../PropTypes');
var Route = require('./Route');

/**
 * A <Redirect> component is a special kind of <Route> that always
 * redirects to another route when it matches.
 */

var Redirect = (function (_Route) {
  _inherits(Redirect, _Route);

  function Redirect() {
    _classCallCheck(this, Redirect);

    _get(Object.getPrototypeOf(Redirect.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  return Redirect;
})(Route);

Redirect.propTypes = {
  path: PropTypes.string,
  from: PropTypes.string, // Alias for path.
  to: PropTypes.string,
  handler: PropTypes.falsy
};

// Redirects should not have a default handler
Redirect.defaultProps = {};

module.exports = Redirect;
},{"../PropTypes":362,"./Route":376}],376:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var React = require('react');
var invariant = require('invariant');
var PropTypes = require('../PropTypes');
var RouteHandler = require('./RouteHandler');

/**
 * <Route> components specify components that are rendered to the page when the
 * URL matches a given pattern.
 *
 * Routes are arranged in a nested tree structure. When a new URL is requested,
 * the tree is searched depth-first to find a route whose path matches the URL.
 * When one is found, all routes in the tree that lead to it are considered
 * "active" and their components are rendered into the DOM, nested in the same
 * order as they are in the tree.
 *
 * The preferred way to configure a router is using JSX. The XML-like syntax is
 * a great way to visualize how routes are laid out in an application.
 *
 *   var routes = [
 *     <Route handler={App}>
 *       <Route name="login" handler={Login}/>
 *       <Route name="logout" handler={Logout}/>
 *       <Route name="about" handler={About}/>
 *     </Route>
 *   ];
 *   
 *   Router.run(routes, function (Handler) {
 *     React.render(<Handler/>, document.body);
 *   });
 *
 * Handlers for Route components that contain children can render their active
 * child route using a <RouteHandler> element.
 *
 *   var App = React.createClass({
 *     render: function () {
 *       return (
 *         <div className="application">
 *           <RouteHandler/>
 *         </div>
 *       );
 *     }
 *   });
 *
 * If no handler is provided for the route, it will render a matched child route.
 */

var Route = (function (_React$Component) {
  _inherits(Route, _React$Component);

  function Route() {
    _classCallCheck(this, Route);

    _get(Object.getPrototypeOf(Route.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  _createClass(Route, [{
    key: 'render',
    value: function render() {
      invariant(false, '%s elements are for router configuration only and should not be rendered', this.constructor.name);
    }
  }]);

  return Route;
})(React.Component);

Route.propTypes = {
  name: PropTypes.string,
  path: PropTypes.string,
  handler: PropTypes.func,
  ignoreScrollBehavior: PropTypes.bool
};

Route.defaultProps = {
  handler: RouteHandler
};

module.exports = Route;
},{"../PropTypes":362,"./RouteHandler":377,"invariant":330,"react":525}],377:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var React = require('react');
var ContextWrapper = require('./ContextWrapper');
var assign = require('object-assign');
var PropTypes = require('../PropTypes');

var REF_NAME = '__routeHandler__';

/**
 * A <RouteHandler> component renders the active child route handler
 * when routes are nested.
 */

var RouteHandler = (function (_React$Component) {
  _inherits(RouteHandler, _React$Component);

  function RouteHandler() {
    _classCallCheck(this, RouteHandler);

    _get(Object.getPrototypeOf(RouteHandler.prototype), 'constructor', this).apply(this, arguments);
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  _createClass(RouteHandler, [{
    key: 'getChildContext',
    value: function getChildContext() {
      return {
        routeDepth: this.context.routeDepth + 1
      };
    }
  }, {
    key: 'componentDidMount',
    value: function componentDidMount() {
      this._updateRouteComponent(this.refs[REF_NAME]);
    }
  }, {
    key: 'componentDidUpdate',
    value: function componentDidUpdate() {
      this._updateRouteComponent(this.refs[REF_NAME]);
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this._updateRouteComponent(null);
    }
  }, {
    key: '_updateRouteComponent',
    value: function _updateRouteComponent(component) {
      this.context.router.setRouteComponentAtDepth(this.getRouteDepth(), component);
    }
  }, {
    key: 'getRouteDepth',
    value: function getRouteDepth() {
      return this.context.routeDepth;
    }
  }, {
    key: 'createChildRouteHandler',
    value: function createChildRouteHandler(props) {
      var route = this.context.router.getRouteAtDepth(this.getRouteDepth());

      if (route == null) return null;

      var childProps = assign({}, props || this.props, {
        ref: REF_NAME,
        params: this.context.router.getCurrentParams(),
        query: this.context.router.getCurrentQuery()
      });

      return React.createElement(route.handler, childProps);
    }
  }, {
    key: 'render',
    value: function render() {
      var handler = this.createChildRouteHandler();
      // <script/> for things like <CSSTransitionGroup/> that don't like null
      return handler ? React.createElement(
        ContextWrapper,
        null,
        handler
      ) : React.createElement('script', null);
    }
  }]);

  return RouteHandler;
})(React.Component);

RouteHandler.contextTypes = {
  routeDepth: PropTypes.number.isRequired,
  router: PropTypes.router.isRequired
};

RouteHandler.childContextTypes = {
  routeDepth: PropTypes.number.isRequired
};

module.exports = RouteHandler;
},{"../PropTypes":362,"./ContextWrapper":371,"object-assign":391,"react":525}],378:[function(require,module,exports){
(function (process){
/* jshint -W058 */
'use strict';

var React = require('react');
var warning = require('./warning');
var invariant = require('invariant');
var canUseDOM = require('can-use-dom');
var LocationActions = require('./actions/LocationActions');
var ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior');
var HashLocation = require('./locations/HashLocation');
var HistoryLocation = require('./locations/HistoryLocation');
var RefreshLocation = require('./locations/RefreshLocation');
var StaticLocation = require('./locations/StaticLocation');
var ScrollHistory = require('./ScrollHistory');
var createRoutesFromReactChildren = require('./createRoutesFromReactChildren');
var isReactChildren = require('./isReactChildren');
var Transition = require('./Transition');
var PropTypes = require('./PropTypes');
var Redirect = require('./Redirect');
var History = require('./History');
var Cancellation = require('./Cancellation');
var Match = require('./Match');
var Route = require('./Route');
var supportsHistory = require('./supportsHistory');
var PathUtils = require('./PathUtils');

/**
 * The default location for new routers.
 */
var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/';

/**
 * The default scroll behavior for new routers.
 */
var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null;

function hasProperties(object, properties) {
  for (var propertyName in properties) if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) return false;

  return true;
}

function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) {
  return routes.some(function (r) {
    if (r !== route) return false;

    var paramNames = route.paramNames;
    var paramName;

    // Ensure that all params the route cares about did not change.
    for (var i = 0, len = paramNames.length; i < len; ++i) {
      paramName = paramNames[i];

      if (nextParams[paramName] !== prevParams[paramName]) return false;
    }

    // Ensure the query hasn't changed.
    return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery);
  });
}

function addRoutesToNamedRoutes(routes, namedRoutes) {
  var route;
  for (var i = 0, len = routes.length; i < len; ++i) {
    route = routes[i];

    if (route.name) {
      invariant(namedRoutes[route.name] == null, 'You may not have more than one route named "%s"', route.name);

      namedRoutes[route.name] = route;
    }

    if (route.childRoutes) addRoutesToNamedRoutes(route.childRoutes, namedRoutes);
  }
}

function routeIsActive(activeRoutes, routeName) {
  return activeRoutes.some(function (route) {
    return route.name === routeName;
  });
}

function paramsAreActive(activeParams, params) {
  for (var property in params) if (String(activeParams[property]) !== String(params[property])) return false;

  return true;
}

function queryIsActive(activeQuery, query) {
  for (var property in query) if (String(activeQuery[property]) !== String(query[property])) return false;

  return true;
}

/**
 * Creates and returns a new router using the given options. A router
 * is a ReactComponent class that knows how to react to changes in the
 * URL and keep the contents of the page in sync.
 *
 * Options may be any of the following:
 *
 * - routes           (required) The route config
 * - location         The location to use. Defaults to HashLocation when
 *                    the DOM is available, "/" otherwise
 * - scrollBehavior   The scroll behavior to use. Defaults to ImitateBrowserBehavior
 *                    when the DOM is available, null otherwise
 * - onError          A function that is used to handle errors
 * - onAbort          A function that is used to handle aborted transitions
 *
 * When rendering in a server-side environment, the location should simply
 * be the URL path that was used in the request, including the query string.
 */
function createRouter(options) {
  options = options || {};

  if (isReactChildren(options)) options = { routes: options };

  var mountedComponents = [];
  var location = options.location || DEFAULT_LOCATION;
  var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR;
  var state = {};
  var nextState = {};
  var pendingTransition = null;
  var dispatchHandler = null;

  if (typeof location === 'string') location = new StaticLocation(location);

  if (location instanceof StaticLocation) {
    warning(!canUseDOM || process.env.NODE_ENV === 'test', 'You should not use a static location in a DOM environment because ' + 'the router will not be kept in sync with the current URL');
  } else {
    invariant(canUseDOM || location.needsDOM === false, 'You cannot use %s without a DOM', location);
  }

  // Automatically fall back to full page refreshes in
  // browsers that don't support the HTML history API.
  if (location === HistoryLocation && !supportsHistory()) location = RefreshLocation;

  var Router = React.createClass({

    displayName: 'Router',

    statics: {

      isRunning: false,

      cancelPendingTransition: function cancelPendingTransition() {
        if (pendingTransition) {
          pendingTransition.cancel();
          pendingTransition = null;
        }
      },

      clearAllRoutes: function clearAllRoutes() {
        Router.cancelPendingTransition();
        Router.namedRoutes = {};
        Router.routes = [];
      },

      /**
       * Adds routes to this router from the given children object (see ReactChildren).
       */
      addRoutes: function addRoutes(routes) {
        if (isReactChildren(routes)) routes = createRoutesFromReactChildren(routes);

        addRoutesToNamedRoutes(routes, Router.namedRoutes);

        Router.routes.push.apply(Router.routes, routes);
      },

      /**
       * Replaces routes of this router from the given children object (see ReactChildren).
       */
      replaceRoutes: function replaceRoutes(routes) {
        Router.clearAllRoutes();
        Router.addRoutes(routes);
        Router.refresh();
      },

      /**
       * Performs a match of the given path against this router and returns an object
       * with the { routes, params, pathname, query } that match. Returns null if no
       * match can be made.
       */
      match: function match(path) {
        return Match.findMatch(Router.routes, path);
      },

      /**
       * Returns an absolute URL path created from the given route
       * name, URL parameters, and query.
       */
      makePath: function makePath(to, params, query) {
        var path;
        if (PathUtils.isAbsolute(to)) {
          path = to;
        } else {
          var route = to instanceof Route ? to : Router.namedRoutes[to];

          invariant(route instanceof Route, 'Cannot find a route named "%s"', to);

          path = route.path;
        }

        return PathUtils.withQuery(PathUtils.injectParams(path, params), query);
      },

      /**
       * Returns a string that may safely be used as the href of a link
       * to the route with the given name, URL parameters, and query.
       */
      makeHref: function makeHref(to, params, query) {
        var path = Router.makePath(to, params, query);
        return location === HashLocation ? '#' + path : path;
      },

      /**
       * Transitions to the URL specified in the arguments by pushing
       * a new URL onto the history stack.
       */
      transitionTo: function transitionTo(to, params, query) {
        var path = Router.makePath(to, params, query);

        if (pendingTransition) {
          // Replace so pending location does not stay in history.
          location.replace(path);
        } else {
          location.push(path);
        }
      },

      /**
       * Transitions to the URL specified in the arguments by replacing
       * the current URL in the history stack.
       */
      replaceWith: function replaceWith(to, params, query) {
        location.replace(Router.makePath(to, params, query));
      },

      /**
       * Transitions to the previous URL if one is available. Returns true if the
       * router was able to go back, false otherwise.
       *
       * Note: The router only tracks history entries in your application, not the
       * current browser session, so you can safely call this function without guarding
       * against sending the user back to some other site. However, when using
       * RefreshLocation (which is the fallback for HistoryLocation in browsers that
       * don't support HTML5 history) this method will *always* send the client back
       * because we cannot reliably track history length.
       */
      goBack: function goBack() {
        if (History.length > 1 || location === RefreshLocation) {
          location.pop();
          return true;
        }

        warning(false, 'goBack() was ignored because there is no router history');

        return false;
      },

      handleAbort: options.onAbort || function (abortReason) {
        if (location instanceof StaticLocation) throw new Error('Unhandled aborted transition! Reason: ' + abortReason);

        if (abortReason instanceof Cancellation) {
          return;
        } else if (abortReason instanceof Redirect) {
          location.replace(Router.makePath(abortReason.to, abortReason.params, abortReason.query));
        } else {
          location.pop();
        }
      },

      handleError: options.onError || function (error) {
        // Throw so we don't silently swallow async errors.
        throw error; // This error probably originated in a transition hook.
      },

      handleLocationChange: function handleLocationChange(change) {
        Router.dispatch(change.path, change.type);
      },

      /**
       * Performs a transition to the given path and calls callback(error, abortReason)
       * when the transition is finished. If both arguments are null the router's state
       * was updated. Otherwise the transition did not complete.
       *
       * In a transition, a router first determines which routes are involved by beginning
       * with the current route, up the route tree to the first parent route that is shared
       * with the destination route, and back down the tree to the destination route. The
       * willTransitionFrom hook is invoked on all route handlers we're transitioning away
       * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on
       * all route handlers we're transitioning to.
       *
       * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the
       * transition. To resolve asynchronously, they may use the callback argument. If no
       * hooks wait, the transition is fully synchronous.
       */
      dispatch: function dispatch(path, action) {
        Router.cancelPendingTransition();

        var prevPath = state.path;
        var isRefreshing = action == null;

        if (prevPath === path && !isRefreshing) return; // Nothing to do!

        // Record the scroll position as early as possible to
        // get it before browsers try update it automatically.
        if (prevPath && action === LocationActions.PUSH) Router.recordScrollPosition(prevPath);

        var match = Router.match(path);

        warning(match != null, 'No route matches path "%s". Make sure you have <Route path="%s"> somewhere in your routes', path, path);

        if (match == null) match = {};

        var prevRoutes = state.routes || [];
        var prevParams = state.params || {};
        var prevQuery = state.query || {};

        var nextRoutes = match.routes || [];
        var nextParams = match.params || {};
        var nextQuery = match.query || {};

        var fromRoutes, toRoutes;
        if (prevRoutes.length) {
          fromRoutes = prevRoutes.filter(function (route) {
            return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery);
          });

          toRoutes = nextRoutes.filter(function (route) {
            return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery);
          });
        } else {
          fromRoutes = [];
          toRoutes = nextRoutes;
        }

        var transition = new Transition(path, Router.replaceWith.bind(Router, path));
        pendingTransition = transition;

        var fromComponents = mountedComponents.slice(prevRoutes.length - fromRoutes.length);

        Transition.from(transition, fromRoutes, fromComponents, function (error) {
          if (error || transition.abortReason) return dispatchHandler.call(Router, error, transition); // No need to continue.

          Transition.to(transition, toRoutes, nextParams, nextQuery, function (error) {
            dispatchHandler.call(Router, error, transition, {
              path: path,
              action: action,
              pathname: match.pathname,
              routes: nextRoutes,
              params: nextParams,
              query: nextQuery
            });
          });
        });
      },

      /**
       * Starts this router and calls callback(router, state) when the route changes.
       *
       * If the router's location is static (i.e. a URL path in a server environment)
       * the callback is called only once. Otherwise, the location should be one of the
       * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation).
       */
      run: function run(callback) {
        invariant(!Router.isRunning, 'Router is already running');

        dispatchHandler = function (error, transition, newState) {
          if (error) Router.handleError(error);

          if (pendingTransition !== transition) return;

          pendingTransition = null;

          if (transition.abortReason) {
            Router.handleAbort(transition.abortReason);
          } else {
            callback.call(Router, Router, nextState = newState);
          }
        };

        if (!(location instanceof StaticLocation)) {
          if (location.addChangeListener) location.addChangeListener(Router.handleLocationChange);

          Router.isRunning = true;
        }

        // Bootstrap using the current path.
        Router.refresh();
      },

      refresh: function refresh() {
        Router.dispatch(location.getCurrentPath(), null);
      },

      stop: function stop() {
        Router.cancelPendingTransition();

        if (location.removeChangeListener) location.removeChangeListener(Router.handleLocationChange);

        Router.isRunning = false;
      },

      getLocation: function getLocation() {
        return location;
      },

      getScrollBehavior: function getScrollBehavior() {
        return scrollBehavior;
      },

      getRouteAtDepth: function getRouteAtDepth(routeDepth) {
        var routes = state.routes;
        return routes && routes[routeDepth];
      },

      setRouteComponentAtDepth: function setRouteComponentAtDepth(routeDepth, component) {
        mountedComponents[routeDepth] = component;
      },

      /**
       * Returns the current URL path + query string.
       */
      getCurrentPath: function getCurrentPath() {
        return state.path;
      },

      /**
       * Returns the current URL path without the query string.
       */
      getCurrentPathname: function getCurrentPathname() {
        return state.pathname;
      },

      /**
       * Returns an object of the currently active URL parameters.
       */
      getCurrentParams: function getCurrentParams() {
        return state.params;
      },

      /**
       * Returns an object of the currently active query parameters.
       */
      getCurrentQuery: function getCurrentQuery() {
        return state.query;
      },

      /**
       * Returns an array of the currently active routes.
       */
      getCurrentRoutes: function getCurrentRoutes() {
        return state.routes;
      },

      /**
       * Returns true if the given route, params, and query are active.
       */
      isActive: function isActive(to, params, query) {
        if (PathUtils.isAbsolute(to)) return to === state.path;

        return routeIsActive(state.routes, to) && paramsAreActive(state.params, params) && (query == null || queryIsActive(state.query, query));
      }

    },

    mixins: [ScrollHistory],

    propTypes: {
      children: PropTypes.falsy
    },

    childContextTypes: {
      routeDepth: PropTypes.number.isRequired,
      router: PropTypes.router.isRequired
    },

    getChildContext: function getChildContext() {
      return {
        routeDepth: 1,
        router: Router
      };
    },

    getInitialState: function getInitialState() {
      return state = nextState;
    },

    componentWillReceiveProps: function componentWillReceiveProps() {
      this.setState(state = nextState);
    },

    componentWillUnmount: function componentWillUnmount() {
      Router.stop();
    },

    render: function render() {
      var route = Router.getRouteAtDepth(0);
      return route ? React.createElement(route.handler, this.props) : null;
    }

  });

  Router.clearAllRoutes();

  if (options.routes) Router.addRoutes(options.routes);

  return Router;
}

module.exports = createRouter;
}).call(this,require('_process'))

},{"./Cancellation":357,"./History":358,"./Match":359,"./PathUtils":361,"./PropTypes":362,"./Redirect":363,"./Route":364,"./ScrollHistory":365,"./Transition":367,"./actions/LocationActions":368,"./behaviors/ImitateBrowserBehavior":369,"./createRoutesFromReactChildren":379,"./isReactChildren":382,"./locations/HashLocation":383,"./locations/HistoryLocation":384,"./locations/RefreshLocation":385,"./locations/StaticLocation":386,"./supportsHistory":389,"./warning":390,"_process":334,"can-use-dom":298,"invariant":330,"react":525}],379:[function(require,module,exports){
/* jshint -W084 */
'use strict';

var React = require('react');
var assign = require('object-assign');
var warning = require('./warning');
var DefaultRoute = require('./components/DefaultRoute');
var NotFoundRoute = require('./components/NotFoundRoute');
var Redirect = require('./components/Redirect');
var Route = require('./Route');

function checkPropTypes(componentName, propTypes, props) {
  componentName = componentName || 'UnknownComponent';

  for (var propName in propTypes) {
    if (propTypes.hasOwnProperty(propName)) {
      var error = propTypes[propName](props, propName, componentName);

      if (error instanceof Error) warning(false, error.message);
    }
  }
}

function createRouteOptions(props) {
  var options = assign({}, props);
  var handler = options.handler;

  if (handler) {
    options.onEnter = handler.willTransitionTo;
    options.onLeave = handler.willTransitionFrom;
  }

  return options;
}

function createRouteFromReactElement(element) {
  if (!React.isValidElement(element)) return;

  var type = element.type;
  var props = assign({}, type.defaultProps, element.props);

  if (type.propTypes) checkPropTypes(type.displayName, type.propTypes, props);

  if (type === DefaultRoute) return Route.createDefaultRoute(createRouteOptions(props));

  if (type === NotFoundRoute) return Route.createNotFoundRoute(createRouteOptions(props));

  if (type === Redirect) return Route.createRedirect(createRouteOptions(props));

  return Route.createRoute(createRouteOptions(props), function () {
    if (props.children) createRoutesFromReactChildren(props.children);
  });
}

/**
 * Creates and returns an array of routes created from the given
 * ReactChildren, all of which should be one of <Route>, <DefaultRoute>,
 * <NotFoundRoute>, or <Redirect>, e.g.:
 *
 *   var { createRoutesFromReactChildren, Route, Redirect } = require('react-router');
 *
 *   var routes = createRoutesFromReactChildren(
 *     <Route path="/" handler={App}>
 *       <Route name="user" path="/user/:userId" handler={User}>
 *         <Route name="task" path="tasks/:taskId" handler={Task}/>
 *         <Redirect from="todos/:taskId" to="task"/>
 *       </Route>
 *     </Route>
 *   );
 */
function createRoutesFromReactChildren(children) {
  var routes = [];

  React.Children.forEach(children, function (child) {
    if (child = createRouteFromReactElement(child)) routes.push(child);
  });

  return routes;
}

module.exports = createRoutesFromReactChildren;
},{"./Route":364,"./components/DefaultRoute":372,"./components/NotFoundRoute":374,"./components/Redirect":375,"./warning":390,"object-assign":391,"react":525}],380:[function(require,module,exports){
'use strict';

var invariant = require('invariant');
var canUseDOM = require('can-use-dom');

/**
 * Returns the current scroll position of the window as { x, y }.
 */
function getWindowScrollPosition() {
  invariant(canUseDOM, 'Cannot get current scroll position without a DOM');

  return {
    x: window.pageXOffset || document.documentElement.scrollLeft,
    y: window.pageYOffset || document.documentElement.scrollTop
  };
}

module.exports = getWindowScrollPosition;
},{"can-use-dom":298,"invariant":330}],381:[function(require,module,exports){
'use strict';

exports.DefaultRoute = require('./components/DefaultRoute');
exports.Link = require('./components/Link');
exports.NotFoundRoute = require('./components/NotFoundRoute');
exports.Redirect = require('./components/Redirect');
exports.Route = require('./components/Route');
exports.ActiveHandler = require('./components/RouteHandler');
exports.RouteHandler = exports.ActiveHandler;

exports.HashLocation = require('./locations/HashLocation');
exports.HistoryLocation = require('./locations/HistoryLocation');
exports.RefreshLocation = require('./locations/RefreshLocation');
exports.StaticLocation = require('./locations/StaticLocation');
exports.TestLocation = require('./locations/TestLocation');

exports.ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior');
exports.ScrollToTopBehavior = require('./behaviors/ScrollToTopBehavior');

exports.History = require('./History');
exports.Navigation = require('./Navigation');
exports.State = require('./State');

exports.createRoute = require('./Route').createRoute;
exports.createDefaultRoute = require('./Route').createDefaultRoute;
exports.createNotFoundRoute = require('./Route').createNotFoundRoute;
exports.createRedirect = require('./Route').createRedirect;
exports.createRoutesFromReactChildren = require('./createRoutesFromReactChildren');

exports.create = require('./createRouter');
exports.run = require('./runRouter');
},{"./History":358,"./Navigation":360,"./Route":364,"./State":366,"./behaviors/ImitateBrowserBehavior":369,"./behaviors/ScrollToTopBehavior":370,"./components/DefaultRoute":372,"./components/Link":373,"./components/NotFoundRoute":374,"./components/Redirect":375,"./components/Route":376,"./components/RouteHandler":377,"./createRouter":378,"./createRoutesFromReactChildren":379,"./locations/HashLocation":383,"./locations/HistoryLocation":384,"./locations/RefreshLocation":385,"./locations/StaticLocation":386,"./locations/TestLocation":387,"./runRouter":388}],382:[function(require,module,exports){
'use strict';

var React = require('react');

function isValidChild(object) {
  return object == null || React.isValidElement(object);
}

function isReactChildren(object) {
  return isValidChild(object) || Array.isArray(object) && object.every(isValidChild);
}

module.exports = isReactChildren;
},{"react":525}],383:[function(require,module,exports){
'use strict';

var LocationActions = require('../actions/LocationActions');
var History = require('../History');

var _listeners = [];
var _isListening = false;
var _actionType;

function notifyChange(type) {
  if (type === LocationActions.PUSH) History.length += 1;

  var change = {
    path: HashLocation.getCurrentPath(),
    type: type
  };

  _listeners.forEach(function (listener) {
    listener.call(HashLocation, change);
  });
}

function ensureSlash() {
  var path = HashLocation.getCurrentPath();

  if (path.charAt(0) === '/') return true;

  HashLocation.replace('/' + path);

  return false;
}

function onHashChange() {
  if (ensureSlash()) {
    // If we don't have an _actionType then all we know is the hash
    // changed. It was probably caused by the user clicking the Back
    // button, but may have also been the Forward button or manual
    // manipulation. So just guess 'pop'.
    var curActionType = _actionType;
    _actionType = null;
    notifyChange(curActionType || LocationActions.POP);
  }
}

/**
 * A Location that uses `window.location.hash`.
 */
var HashLocation = {

  addChangeListener: function addChangeListener(listener) {
    _listeners.push(listener);

    // Do this BEFORE listening for hashchange.
    ensureSlash();

    if (!_isListening) {
      if (window.addEventListener) {
        window.addEventListener('hashchange', onHashChange, false);
      } else {
        window.attachEvent('onhashchange', onHashChange);
      }

      _isListening = true;
    }
  },

  removeChangeListener: function removeChangeListener(listener) {
    _listeners = _listeners.filter(function (l) {
      return l !== listener;
    });

    if (_listeners.length === 0) {
      if (window.removeEventListener) {
        window.removeEventListener('hashchange', onHashChange, false);
      } else {
        window.removeEvent('onhashchange', onHashChange);
      }

      _isListening = false;
    }
  },

  push: function push(path) {
    _actionType = LocationActions.PUSH;
    window.location.hash = path;
  },

  replace: function replace(path) {
    _actionType = LocationActions.REPLACE;
    window.location.replace(window.location.pathname + window.location.search + '#' + path);
  },

  pop: function pop() {
    _actionType = LocationActions.POP;
    History.back();
  },

  getCurrentPath: function getCurrentPath() {
    return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    window.location.href.split('#')[1] || '');
  },

  toString: function toString() {
    return '<HashLocation>';
  }

};

module.exports = HashLocation;
},{"../History":358,"../actions/LocationActions":368}],384:[function(require,module,exports){
'use strict';

var LocationActions = require('../actions/LocationActions');
var History = require('../History');

var _listeners = [];
var _isListening = false;

function notifyChange(type) {
  var change = {
    path: HistoryLocation.getCurrentPath(),
    type: type
  };

  _listeners.forEach(function (listener) {
    listener.call(HistoryLocation, change);
  });
}

function onPopState(event) {
  if (event.state === undefined) return; // Ignore extraneous popstate events in WebKit.

  notifyChange(LocationActions.POP);
}

/**
 * A Location that uses HTML5 history.
 */
var HistoryLocation = {

  addChangeListener: function addChangeListener(listener) {
    _listeners.push(listener);

    if (!_isListening) {
      if (window.addEventListener) {
        window.addEventListener('popstate', onPopState, false);
      } else {
        window.attachEvent('onpopstate', onPopState);
      }

      _isListening = true;
    }
  },

  removeChangeListener: function removeChangeListener(listener) {
    _listeners = _listeners.filter(function (l) {
      return l !== listener;
    });

    if (_listeners.length === 0) {
      if (window.addEventListener) {
        window.removeEventListener('popstate', onPopState, false);
      } else {
        window.removeEvent('onpopstate', onPopState);
      }

      _isListening = false;
    }
  },

  push: function push(path) {
    window.history.pushState({ path: path }, '', path);
    History.length += 1;
    notifyChange(LocationActions.PUSH);
  },

  replace: function replace(path) {
    window.history.replaceState({ path: path }, '', path);
    notifyChange(LocationActions.REPLACE);
  },

  pop: History.back,

  getCurrentPath: function getCurrentPath() {
    return decodeURI(window.location.pathname + window.location.search);
  },

  toString: function toString() {
    return '<HistoryLocation>';
  }

};

module.exports = HistoryLocation;
},{"../History":358,"../actions/LocationActions":368}],385:[function(require,module,exports){
'use strict';

var HistoryLocation = require('./HistoryLocation');
var History = require('../History');

/**
 * A Location that uses full page refreshes. This is used as
 * the fallback for HistoryLocation in browsers that do not
 * support the HTML5 history API.
 */
var RefreshLocation = {

  push: function push(path) {
    window.location = path;
  },

  replace: function replace(path) {
    window.location.replace(path);
  },

  pop: History.back,

  getCurrentPath: HistoryLocation.getCurrentPath,

  toString: function toString() {
    return '<RefreshLocation>';
  }

};

module.exports = RefreshLocation;
},{"../History":358,"./HistoryLocation":384}],386:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var invariant = require('invariant');

function throwCannotModify() {
  invariant(false, 'You cannot modify a static location');
}

/**
 * A location that only ever contains a single path. Useful in
 * stateless environments like servers where there is no path history,
 * only the path that was used in the request.
 */

var StaticLocation = (function () {
  function StaticLocation(path) {
    _classCallCheck(this, StaticLocation);

    this.path = path;
  }

  // TODO: Include these in the above class definition
  // once we can use ES7 property initializers.
  // https://github.com/babel/babel/issues/619

  _createClass(StaticLocation, [{
    key: 'getCurrentPath',
    value: function getCurrentPath() {
      return this.path;
    }
  }, {
    key: 'toString',
    value: function toString() {
      return '<StaticLocation path="' + this.path + '">';
    }
  }]);

  return StaticLocation;
})();

StaticLocation.prototype.push = throwCannotModify;
StaticLocation.prototype.replace = throwCannotModify;
StaticLocation.prototype.pop = throwCannotModify;

module.exports = StaticLocation;
},{"invariant":330}],387:[function(require,module,exports){
'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var invariant = require('invariant');
var LocationActions = require('../actions/LocationActions');
var History = require('../History');

/**
 * A location that is convenient for testing and does not require a DOM.
 */

var TestLocation = (function () {
  function TestLocation(history) {
    _classCallCheck(this, TestLocation);

    this.history = history || [];
    this.listeners = [];
    this.needsDOM = false;
    this._updateHistoryLength();
  }

  _createClass(TestLocation, [{
    key: '_updateHistoryLength',
    value: function _updateHistoryLength() {
      History.length = this.history.length;
    }
  }, {
    key: '_notifyChange',
    value: function _notifyChange(type) {
      var change = {
        path: this.getCurrentPath(),
        type: type
      };

      for (var i = 0, len = this.listeners.length; i < len; ++i) this.listeners[i].call(this, change);
    }
  }, {
    key: 'addChangeListener',
    value: function addChangeListener(listener) {
      this.listeners.push(listener);
    }
  }, {
    key: 'removeChangeListener',
    value: function removeChangeListener(listener) {
      this.listeners = this.listeners.filter(function (l) {
        return l !== listener;
      });
    }
  }, {
    key: 'push',
    value: function push(path) {
      this.history.push(path);
      this._updateHistoryLength();
      this._notifyChange(LocationActions.PUSH);
    }
  }, {
    key: 'replace',
    value: function replace(path) {
      invariant(this.history.length, 'You cannot replace the current path with no history');

      this.history[this.history.length - 1] = path;

      this._notifyChange(LocationActions.REPLACE);
    }
  }, {
    key: 'pop',
    value: function pop() {
      this.history.pop();
      this._updateHistoryLength();
      this._notifyChange(LocationActions.POP);
    }
  }, {
    key: 'getCurrentPath',
    value: function getCurrentPath() {
      return this.history[this.history.length - 1];
    }
  }, {
    key: 'toString',
    value: function toString() {
      return '<TestLocation>';
    }
  }]);

  return TestLocation;
})();

module.exports = TestLocation;
},{"../History":358,"../actions/LocationActions":368,"invariant":330}],388:[function(require,module,exports){
'use strict';

var createRouter = require('./createRouter');

/**
 * A high-level convenience method that creates, configures, and
 * runs a router in one shot. The method signature is:
 *
 *   Router.run(routes[, location ], callback);
 *
 * Using `window.location.hash` to manage the URL, you could do:
 *
 *   Router.run(routes, function (Handler) {
 *     React.render(<Handler/>, document.body);
 *   });
 * 
 * Using HTML5 history and a custom "cursor" prop:
 * 
 *   Router.run(routes, Router.HistoryLocation, function (Handler) {
 *     React.render(<Handler cursor={cursor}/>, document.body);
 *   });
 *
 * Returns the newly created router.
 *
 * Note: If you need to specify further options for your router such
 * as error/abort handling or custom scroll behavior, use Router.create
 * instead.
 *
 *   var router = Router.create(options);
 *   router.run(function (Handler) {
 *     // ...
 *   });
 */
function runRouter(routes, location, callback) {
  if (typeof location === 'function') {
    callback = location;
    location = null;
  }

  var router = createRouter({
    routes: routes,
    location: location
  });

  router.run(callback);

  return router;
}

module.exports = runRouter;
},{"./createRouter":378}],389:[function(require,module,exports){
'use strict';

function supportsHistory() {
  /*! taken from modernizr
   * https://github.com/Modernizr/Modernizr/blob/master/LICENSE
   * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
   * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586
   */
  var ua = navigator.userAgent;
  if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) {
    return false;
  }
  return window.history && 'pushState' in window.history;
}

module.exports = supportsHistory;
},{}],390:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of https://github.com/facebook/react/tree/0.13-stable.
 * An additional grant of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule warning
 */

"use strict";

/**
 * Similar to invariant but only logs a warning if the condition is not met.
 * This can be used to log issues in development environments in critical
 * paths. Removing the logging code for production environments will keep the
 * same logic and follow the same code paths.
 */

var __DEV__ = process.env.NODE_ENV !== 'production';

var warning = function warning() {};

if (__DEV__) {
  warning = function (condition, format) {
    for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      args[_key - 2] = arguments[_key];
    }

    if (format === undefined) {
      throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
    }

    if (format.length < 10 || /^[s\W]*$/.test(format)) {
      throw new Error('The warning format should be able to uniquely identify this ' + 'warning. Please, use a more descriptive format than: ' + format);
    }

    if (format.indexOf('Failed Composite propType: ') === 0) {
      return; // Ignore CompositeComponent proptype check.
    }

    if (!condition) {
      var argIndex = 0;
      var message = 'Warning: ' + format.replace(/%s/g, function () {
        return args[argIndex++];
      });
      console.warn(message);
      try {
        // --- Welcome to debugging React ---
        // This error was thrown as a convenience so that you can use this stack
        // to find the callsite that caused this warning to fire.
        throw new Error(message);
      } catch (x) {}
    }
  };
}

module.exports = warning;
}).call(this,require('_process'))

},{"_process":334}],391:[function(require,module,exports){
'use strict';

function ToObject(val) {
	if (val == null) {
		throw new TypeError('Object.assign cannot be called with null or undefined');
	}

	return Object(val);
}

module.exports = Object.assign || function (target, source) {
	var from;
	var keys;
	var to = ToObject(target);

	for (var s = 1; s < arguments.length; s++) {
		from = arguments[s];
		keys = Object.keys(Object(from));

		for (var i = 0; i < keys.length; i++) {
			to[keys[i]] = from[keys[i]];
		}
	}

	return to;
};

},{}],392:[function(require,module,exports){
module.exports = require('./lib/');

},{"./lib/":393}],393:[function(require,module,exports){
// Load modules

var Stringify = require('./stringify');
var Parse = require('./parse');


// Declare internals

var internals = {};


module.exports = {
    stringify: Stringify,
    parse: Parse
};

},{"./parse":394,"./stringify":395}],394:[function(require,module,exports){
// Load modules

var Utils = require('./utils');


// Declare internals

var internals = {
    delimiter: '&',
    depth: 5,
    arrayLimit: 20,
    parameterLimit: 1000
};


internals.parseValues = function (str, options) {

    var obj = {};
    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);

    for (var i = 0, il = parts.length; i < il; ++i) {
        var part = parts[i];
        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;

        if (pos === -1) {
            obj[Utils.decode(part)] = '';
        }
        else {
            var key = Utils.decode(part.slice(0, pos));
            var val = Utils.decode(part.slice(pos + 1));

            if (Object.prototype.hasOwnProperty(key)) {
                continue;
            }

            if (!obj.hasOwnProperty(key)) {
                obj[key] = val;
            }
            else {
                obj[key] = [].concat(obj[key]).concat(val);
            }
        }
    }

    return obj;
};


internals.parseObject = function (chain, val, options) {

    if (!chain.length) {
        return val;
    }

    var root = chain.shift();

    var obj = {};
    if (root === '[]') {
        obj = [];
        obj = obj.concat(internals.parseObject(chain, val, options));
    }
    else {
        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
        var index = parseInt(cleanRoot, 10);
        var indexString = '' + index;
        if (!isNaN(index) &&
            root !== cleanRoot &&
            indexString === cleanRoot &&
            index >= 0 &&
            index <= options.arrayLimit) {

            obj = [];
            obj[index] = internals.parseObject(chain, val, options);
        }
        else {
            obj[cleanRoot] = internals.parseObject(chain, val, options);
        }
    }

    return obj;
};


internals.parseKeys = function (key, val, options) {

    if (!key) {
        return;
    }

    // The regex chunks

    var parent = /^([^\[\]]*)/;
    var child = /(\[[^\[\]]*\])/g;

    // Get the parent

    var segment = parent.exec(key);

    // Don't allow them to overwrite object prototype properties

    if (Object.prototype.hasOwnProperty(segment[1])) {
        return;
    }

    // Stash the parent if it exists

    var keys = [];
    if (segment[1]) {
        keys.push(segment[1]);
    }

    // Loop through children appending to the array until we hit depth

    var i = 0;
    while ((segment = child.exec(key)) !== null && i < options.depth) {

        ++i;
        if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
            keys.push(segment[1]);
        }
    }

    // If there's a remainder, just add whatever is left

    if (segment) {
        keys.push('[' + key.slice(segment.index) + ']');
    }

    return internals.parseObject(keys, val, options);
};


module.exports = function (str, options) {

    if (str === '' ||
        str === null ||
        typeof str === 'undefined') {

        return {};
    }

    options = options || {};
    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
    options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
    options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
    options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;

    var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
    var obj = {};

    // Iterate over the keys and setup the new object

    var keys = Object.keys(tempObj);
    for (var i = 0, il = keys.length; i < il; ++i) {
        var key = keys[i];
        var newObj = internals.parseKeys(key, tempObj[key], options);
        obj = Utils.merge(obj, newObj);
    }

    return Utils.compact(obj);
};

},{"./utils":396}],395:[function(require,module,exports){
// Load modules

var Utils = require('./utils');


// Declare internals

var internals = {
    delimiter: '&',
    arrayPrefixGenerators: {
        brackets: function (prefix, key) {
            return prefix + '[]';
        },
        indices: function (prefix, key) {
            return prefix + '[' + key + ']';
        },
        repeat: function (prefix, key) {
            return prefix;
        }
    }
};


internals.stringify = function (obj, prefix, generateArrayPrefix) {

    if (Utils.isBuffer(obj)) {
        obj = obj.toString();
    }
    else if (obj instanceof Date) {
        obj = obj.toISOString();
    }
    else if (obj === null) {
        obj = '';
    }

    if (typeof obj === 'string' ||
        typeof obj === 'number' ||
        typeof obj === 'boolean') {

        return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)];
    }

    var values = [];

    if (typeof obj === 'undefined') {
        return values;
    }

    var objKeys = Object.keys(obj);
    for (var i = 0, il = objKeys.length; i < il; ++i) {
        var key = objKeys[i];
        if (Array.isArray(obj)) {
            values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
        }
        else {
            values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
        }
    }

    return values;
};


module.exports = function (obj, options) {

    options = options || {};
    var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;

    var keys = [];

    if (typeof obj !== 'object' ||
        obj === null) {

        return '';
    }

    var arrayFormat;
    if (options.arrayFormat in internals.arrayPrefixGenerators) {
        arrayFormat = options.arrayFormat;
    }
    else if ('indices' in options) {
        arrayFormat = options.indices ? 'indices' : 'repeat';
    }
    else {
        arrayFormat = 'indices';
    }

    var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];

    var objKeys = Object.keys(obj);
    for (var i = 0, il = objKeys.length; i < il; ++i) {
        var key = objKeys[i];
        keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
    }

    return keys.join(delimiter);
};

},{"./utils":396}],396:[function(require,module,exports){
// Load modules


// Declare internals

var internals = {};


exports.arrayToObject = function (source) {

    var obj = {};
    for (var i = 0, il = source.length; i < il; ++i) {
        if (typeof source[i] !== 'undefined') {

            obj[i] = source[i];
        }
    }

    return obj;
};


exports.merge = function (target, source) {

    if (!source) {
        return target;
    }

    if (typeof source !== 'object') {
        if (Array.isArray(target)) {
            target.push(source);
        }
        else {
            target[source] = true;
        }

        return target;
    }

    if (typeof target !== 'object') {
        target = [target].concat(source);
        return target;
    }

    if (Array.isArray(target) &&
        !Array.isArray(source)) {

        target = exports.arrayToObject(target);
    }

    var keys = Object.keys(source);
    for (var k = 0, kl = keys.length; k < kl; ++k) {
        var key = keys[k];
        var value = source[key];

        if (!target[key]) {
            target[key] = value;
        }
        else {
            target[key] = exports.merge(target[key], value);
        }
    }

    return target;
};


exports.decode = function (str) {

    try {
        return decodeURIComponent(str.replace(/\+/g, ' '));
    } catch (e) {
        return str;
    }
};


exports.compact = function (obj, refs) {

    if (typeof obj !== 'object' ||
        obj === null) {

        return obj;
    }

    refs = refs || [];
    var lookup = refs.indexOf(obj);
    if (lookup !== -1) {
        return refs[lookup];
    }

    refs.push(obj);

    if (Array.isArray(obj)) {
        var compacted = [];

        for (var i = 0, il = obj.length; i < il; ++i) {
            if (typeof obj[i] !== 'undefined') {
                compacted.push(obj[i]);
            }
        }

        return compacted;
    }

    var keys = Object.keys(obj);
    for (i = 0, il = keys.length; i < il; ++i) {
        var key = keys[i];
        obj[key] = exports.compact(obj[key], refs);
    }

    return obj;
};


exports.isRegExp = function (obj) {
    return Object.prototype.toString.call(obj) === '[object RegExp]';
};


exports.isBuffer = function (obj) {

    if (obj === null ||
        typeof obj === 'undefined') {

        return false;
    }

    return !!(obj.constructor &&
        obj.constructor.isBuffer &&
        obj.constructor.isBuffer(obj));
};

},{}],397:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule AutoFocusUtils
 * @typechecks static-only
 */

'use strict';

var ReactMount = require('./ReactMount');

var findDOMNode = require('./findDOMNode');
var focusNode = require('fbjs/lib/focusNode');

var Mixin = {
  componentDidMount: function () {
    if (this.props.autoFocus) {
      focusNode(findDOMNode(this));
    }
  }
};

var AutoFocusUtils = {
  Mixin: Mixin,

  focusDOMComponent: function () {
    focusNode(ReactMount.getNode(this._rootNodeID));
  }
};

module.exports = AutoFocusUtils;
},{"./ReactMount":461,"./findDOMNode":504,"fbjs/lib/focusNode":312}],398:[function(require,module,exports){
/**
 * Copyright 2013-2015 Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule BeforeInputEventPlugin
 * @typechecks static-only
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPropagators = require('./EventPropagators');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var FallbackCompositionState = require('./FallbackCompositionState');
var SyntheticCompositionEvent = require('./SyntheticCompositionEvent');
var SyntheticInputEvent = require('./SyntheticInputEvent');

var keyOf = require('fbjs/lib/keyOf');

var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
var START_KEYCODE = 229;

var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;

var documentMode = null;
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
  documentMode = document.documentMode;
}

// Webkit offers a very useful `textInput` event that can be used to
// directly represent `beforeInput`. The IE `textinput` event is not as
// useful, so we don't use it.
var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto();

// In IE9+, we have access to composition events, but the data supplied
// by the native compositionend event may be incorrect. Japanese ideographic
// spaces, for instance (\u3000) are not recorded correctly.
var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);

/**
 * Opera <= 12 includes TextEvent in window, but does not fire
 * text input events. Rely on keypress instead.
 */
function isPresto() {
  var opera = window.opera;
  return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12;
}

var SPACEBAR_CODE = 32;
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);

var topLevelTypes = EventConstants.topLevelTypes;

// Events and their corresponding property names.
var eventTypes = {
  beforeInput: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onBeforeInput: null }),
      captured: keyOf({ onBeforeInputCapture: null })
    },
    dependencies: [topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste]
  },
  compositionEnd: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCompositionEnd: null }),
      captured: keyOf({ onCompositionEndCapture: null })
    },
    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]
  },
  compositionStart: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCompositionStart: null }),
      captured: keyOf({ onCompositionStartCapture: null })
    },
    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]
  },
  compositionUpdate: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCompositionUpdate: null }),
      captured: keyOf({ onCompositionUpdateCapture: null })
    },
    dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown]
  }
};

// Track whether we've ever handled a keypress on the space key.
var hasSpaceKeypress = false;

/**
 * Return whether a native keypress event is assumed to be a command.
 * This is required because Firefox fires `keypress` events for key commands
 * (cut, copy, select-all, etc.) even though no character is inserted.
 */
function isKeypressCommand(nativeEvent) {
  return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
  // ctrlKey && altKey is equivalent to AltGr, and is not a command.
  !(nativeEvent.ctrlKey && nativeEvent.altKey);
}

/**
 * Translate native top level events into event types.
 *
 * @param {string} topLevelType
 * @return {object}
 */
function getCompositionEventType(topLevelType) {
  switch (topLevelType) {
    case topLevelTypes.topCompositionStart:
      return eventTypes.compositionStart;
    case topLevelTypes.topCompositionEnd:
      return eventTypes.compositionEnd;
    case topLevelTypes.topCompositionUpdate:
      return eventTypes.compositionUpdate;
  }
}

/**
 * Does our fallback best-guess model think this event signifies that
 * composition has begun?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionStart(topLevelType, nativeEvent) {
  return topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE;
}

/**
 * Does our fallback mode think that this event is the end of composition?
 *
 * @param {string} topLevelType
 * @param {object} nativeEvent
 * @return {boolean}
 */
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
  switch (topLevelType) {
    case topLevelTypes.topKeyUp:
      // Command keys insert or clear IME input.
      return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
    case topLevelTypes.topKeyDown:
      // Expect IME keyCode on each keydown. If we get any other
      // code we must have exited earlier.
      return nativeEvent.keyCode !== START_KEYCODE;
    case topLevelTypes.topKeyPress:
    case topLevelTypes.topMouseDown:
    case topLevelTypes.topBlur:
      // Events are not possible without cancelling IME.
      return true;
    default:
      return false;
  }
}

/**
 * Google Input Tools provides composition data via a CustomEvent,
 * with the `data` property populated in the `detail` object. If this
 * is available on the event object, use it. If not, this is a plain
 * composition event and we have nothing special to extract.
 *
 * @param {object} nativeEvent
 * @return {?string}
 */
function getDataFromCustomEvent(nativeEvent) {
  var detail = nativeEvent.detail;
  if (typeof detail === 'object' && 'data' in detail) {
    return detail.data;
  }
  return null;
}

// Track the current IME composition fallback object, if any.
var currentComposition = null;

/**
 * @param {string} topLevelType Record from `EventConstants`.
 * @param {DOMEventTarget} topLevelTarget The listening component root node.
 * @param {string} topLevelTargetID ID of `topLevelTarget`.
 * @param {object} nativeEvent Native browser event.
 * @return {?object} A SyntheticCompositionEvent.
 */
function extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
  var eventType;
  var fallbackData;

  if (canUseCompositionEvent) {
    eventType = getCompositionEventType(topLevelType);
  } else if (!currentComposition) {
    if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
      eventType = eventTypes.compositionStart;
    }
  } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
    eventType = eventTypes.compositionEnd;
  }

  if (!eventType) {
    return null;
  }

  if (useFallbackCompositionData) {
    // The current composition is stored statically and must not be
    // overwritten while composition continues.
    if (!currentComposition && eventType === eventTypes.compositionStart) {
      currentComposition = FallbackCompositionState.getPooled(topLevelTarget);
    } else if (eventType === eventTypes.compositionEnd) {
      if (currentComposition) {
        fallbackData = currentComposition.getData();
      }
    }
  }

  var event = SyntheticCompositionEvent.getPooled(eventType, topLevelTargetID, nativeEvent, nativeEventTarget);

  if (fallbackData) {
    // Inject data generated from fallback path into the synthetic event.
    // This matches the property of native CompositionEventInterface.
    event.data = fallbackData;
  } else {
    var customData = getDataFromCustomEvent(nativeEvent);
    if (customData !== null) {
      event.data = customData;
    }
  }

  EventPropagators.accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * @param {string} topLevelType Record from `EventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The string corresponding to this `beforeInput` event.
 */
function getNativeBeforeInputChars(topLevelType, nativeEvent) {
  switch (topLevelType) {
    case topLevelTypes.topCompositionEnd:
      return getDataFromCustomEvent(nativeEvent);
    case topLevelTypes.topKeyPress:
      /**
       * If native `textInput` events are available, our goal is to make
       * use of them. However, there is a special case: the spacebar key.
       * In Webkit, preventing default on a spacebar `textInput` event
       * cancels character insertion, but it *also* causes the browser
       * to fall back to its default spacebar behavior of scrolling the
       * page.
       *
       * Tracking at:
       * https://code.google.com/p/chromium/issues/detail?id=355103
       *
       * To avoid this issue, use the keypress event as if no `textInput`
       * event is available.
       */
      var which = nativeEvent.which;
      if (which !== SPACEBAR_CODE) {
        return null;
      }

      hasSpaceKeypress = true;
      return SPACEBAR_CHAR;

    case topLevelTypes.topTextInput:
      // Record the characters to be added to the DOM.
      var chars = nativeEvent.data;

      // If it's a spacebar character, assume that we have already handled
      // it at the keypress level and bail immediately. Android Chrome
      // doesn't give us keycodes, so we need to blacklist it.
      if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
        return null;
      }

      return chars;

    default:
      // For other native event types, do nothing.
      return null;
  }
}

/**
 * For browsers that do not provide the `textInput` event, extract the
 * appropriate string to use for SyntheticInputEvent.
 *
 * @param {string} topLevelType Record from `EventConstants`.
 * @param {object} nativeEvent Native browser event.
 * @return {?string} The fallback string for this `beforeInput` event.
 */
function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
  // If we are currently composing (IME) and using a fallback to do so,
  // try to extract the composed characters from the fallback object.
  if (currentComposition) {
    if (topLevelType === topLevelTypes.topCompositionEnd || isFallbackCompositionEnd(topLevelType, nativeEvent)) {
      var chars = currentComposition.getData();
      FallbackCompositionState.release(currentComposition);
      currentComposition = null;
      return chars;
    }
    return null;
  }

  switch (topLevelType) {
    case topLevelTypes.topPaste:
      // If a paste event occurs after a keypress, throw out the input
      // chars. Paste events should not lead to BeforeInput events.
      return null;
    case topLevelTypes.topKeyPress:
      /**
       * As of v27, Firefox may fire keypress events even when no character
       * will be inserted. A few possibilities:
       *
       * - `which` is `0`. Arrow keys, Esc key, etc.
       *
       * - `which` is the pressed key code, but no char is available.
       *   Ex: 'AltGr + d` in Polish. There is no modified character for
       *   this key combination and no character is inserted into the
       *   document, but FF fires the keypress for char code `100` anyway.
       *   No `input` event will occur.
       *
       * - `which` is the pressed key code, but a command combination is
       *   being used. Ex: `Cmd+C`. No character is inserted, and no
       *   `input` event will occur.
       */
      if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {
        return String.fromCharCode(nativeEvent.which);
      }
      return null;
    case topLevelTypes.topCompositionEnd:
      return useFallbackCompositionData ? null : nativeEvent.data;
    default:
      return null;
  }
}

/**
 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
 * `textInput` or fallback behavior.
 *
 * @param {string} topLevelType Record from `EventConstants`.
 * @param {DOMEventTarget} topLevelTarget The listening component root node.
 * @param {string} topLevelTargetID ID of `topLevelTarget`.
 * @param {object} nativeEvent Native browser event.
 * @return {?object} A SyntheticInputEvent.
 */
function extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
  var chars;

  if (canUseTextInputEvent) {
    chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
  } else {
    chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
  }

  // If no characters are being inserted, no BeforeInput event should
  // be fired.
  if (!chars) {
    return null;
  }

  var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, topLevelTargetID, nativeEvent, nativeEventTarget);

  event.data = chars;
  EventPropagators.accumulateTwoPhaseDispatches(event);
  return event;
}

/**
 * Create an `onBeforeInput` event to match
 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
 *
 * This event plugin is based on the native `textInput` event
 * available in Chrome, Safari, Opera, and IE. This event fires after
 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
 *
 * `beforeInput` is spec'd but not implemented in any browsers, and
 * the `input` event does not provide any useful information about what has
 * actually been added, contrary to the spec. Thus, `textInput` is the best
 * available event to identify the characters that have actually been inserted
 * into the target node.
 *
 * This plugin is also responsible for emitting `composition` events, thus
 * allowing us to share composition fallback code for both `beforeInput` and
 * `composition` event types.
 */
var BeforeInputEventPlugin = {

  eventTypes: eventTypes,

  /**
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @see {EventPluginHub.extractEvents}
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    return [extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget)];
  }
};

module.exports = BeforeInputEventPlugin;
},{"./EventConstants":410,"./EventPropagators":414,"./FallbackCompositionState":415,"./SyntheticCompositionEvent":486,"./SyntheticInputEvent":490,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/keyOf":322}],399:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule CSSProperty
 */

'use strict';

/**
 * CSS properties which accept numbers but are not in units of "px".
 */
var isUnitlessNumber = {
  animationIterationCount: true,
  boxFlex: true,
  boxFlexGroup: true,
  boxOrdinalGroup: true,
  columnCount: true,
  flex: true,
  flexGrow: true,
  flexPositive: true,
  flexShrink: true,
  flexNegative: true,
  flexOrder: true,
  fontWeight: true,
  lineClamp: true,
  lineHeight: true,
  opacity: true,
  order: true,
  orphans: true,
  tabSize: true,
  widows: true,
  zIndex: true,
  zoom: true,

  // SVG-related properties
  fillOpacity: true,
  stopOpacity: true,
  strokeDashoffset: true,
  strokeOpacity: true,
  strokeWidth: true
};

/**
 * @param {string} prefix vendor-specific prefix, eg: Webkit
 * @param {string} key style name, eg: transitionDuration
 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
 * WebkitTransitionDuration
 */
function prefixKey(prefix, key) {
  return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}

/**
 * Support style names that may come passed in prefixed by adding permutations
 * of vendor prefixes.
 */
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];

// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
Object.keys(isUnitlessNumber).forEach(function (prop) {
  prefixes.forEach(function (prefix) {
    isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
  });
});

/**
 * Most style properties can be unset by doing .style[prop] = '' but IE8
 * doesn't like doing that with shorthand properties so for the properties that
 * IE8 breaks on, which are listed here, we instead unset each of the
 * individual properties. See http://bugs.jquery.com/ticket/12385.
 * The 4-value 'clock' properties like margin, padding, border-width seem to
 * behave without any problems. Curiously, list-style works too without any
 * special prodding.
 */
var shorthandPropertyExpansions = {
  background: {
    backgroundAttachment: true,
    backgroundColor: true,
    backgroundImage: true,
    backgroundPositionX: true,
    backgroundPositionY: true,
    backgroundRepeat: true
  },
  backgroundPosition: {
    backgroundPositionX: true,
    backgroundPositionY: true
  },
  border: {
    borderWidth: true,
    borderStyle: true,
    borderColor: true
  },
  borderBottom: {
    borderBottomWidth: true,
    borderBottomStyle: true,
    borderBottomColor: true
  },
  borderLeft: {
    borderLeftWidth: true,
    borderLeftStyle: true,
    borderLeftColor: true
  },
  borderRight: {
    borderRightWidth: true,
    borderRightStyle: true,
    borderRightColor: true
  },
  borderTop: {
    borderTopWidth: true,
    borderTopStyle: true,
    borderTopColor: true
  },
  font: {
    fontStyle: true,
    fontVariant: true,
    fontWeight: true,
    fontSize: true,
    lineHeight: true,
    fontFamily: true
  },
  outline: {
    outlineWidth: true,
    outlineStyle: true,
    outlineColor: true
  }
};

var CSSProperty = {
  isUnitlessNumber: isUnitlessNumber,
  shorthandPropertyExpansions: shorthandPropertyExpansions
};

module.exports = CSSProperty;
},{}],400:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule CSSPropertyOperations
 * @typechecks static-only
 */

'use strict';

var CSSProperty = require('./CSSProperty');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var ReactPerf = require('./ReactPerf');

var camelizeStyleName = require('fbjs/lib/camelizeStyleName');
var dangerousStyleValue = require('./dangerousStyleValue');
var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');
var memoizeStringOnly = require('fbjs/lib/memoizeStringOnly');
var warning = require('fbjs/lib/warning');

var processStyleName = memoizeStringOnly(function (styleName) {
  return hyphenateStyleName(styleName);
});

var hasShorthandPropertyBug = false;
var styleFloatAccessor = 'cssFloat';
if (ExecutionEnvironment.canUseDOM) {
  var tempStyle = document.createElement('div').style;
  try {
    // IE8 throws "Invalid argument." if resetting shorthand style properties.
    tempStyle.font = '';
  } catch (e) {
    hasShorthandPropertyBug = true;
  }
  // IE8 only supports accessing cssFloat (standard) as styleFloat
  if (document.documentElement.style.cssFloat === undefined) {
    styleFloatAccessor = 'styleFloat';
  }
}

if (process.env.NODE_ENV !== 'production') {
  // 'msTransform' is correct, but the other prefixes should be capitalized
  var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;

  // style values shouldn't contain a semicolon
  var badStyleValueWithSemicolonPattern = /;\s*$/;

  var warnedStyleNames = {};
  var warnedStyleValues = {};

  var warnHyphenatedStyleName = function (name) {
    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
      return;
    }

    warnedStyleNames[name] = true;
    process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?', name, camelizeStyleName(name)) : undefined;
  };

  var warnBadVendoredStyleName = function (name) {
    if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
      return;
    }

    warnedStyleNames[name] = true;
    process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)) : undefined;
  };

  var warnStyleValueWithSemicolon = function (name, value) {
    if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
      return;
    }

    warnedStyleValues[value] = true;
    process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon. ' + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')) : undefined;
  };

  /**
   * @param {string} name
   * @param {*} value
   */
  var warnValidStyle = function (name, value) {
    if (name.indexOf('-') > -1) {
      warnHyphenatedStyleName(name);
    } else if (badVendoredStyleNamePattern.test(name)) {
      warnBadVendoredStyleName(name);
    } else if (badStyleValueWithSemicolonPattern.test(value)) {
      warnStyleValueWithSemicolon(name, value);
    }
  };
}

/**
 * Operations for dealing with CSS properties.
 */
var CSSPropertyOperations = {

  /**
   * Serializes a mapping of style properties for use as inline styles:
   *
   *   > createMarkupForStyles({width: '200px', height: 0})
   *   "width:200px;height:0;"
   *
   * Undefined values are ignored so that declarative programming is easier.
   * The result should be HTML-escaped before insertion into the DOM.
   *
   * @param {object} styles
   * @return {?string}
   */
  createMarkupForStyles: function (styles) {
    var serialized = '';
    for (var styleName in styles) {
      if (!styles.hasOwnProperty(styleName)) {
        continue;
      }
      var styleValue = styles[styleName];
      if (process.env.NODE_ENV !== 'production') {
        warnValidStyle(styleName, styleValue);
      }
      if (styleValue != null) {
        serialized += processStyleName(styleName) + ':';
        serialized += dangerousStyleValue(styleName, styleValue) + ';';
      }
    }
    return serialized || null;
  },

  /**
   * Sets the value for multiple styles on a node.  If a value is specified as
   * '' (empty string), the corresponding style property will be unset.
   *
   * @param {DOMElement} node
   * @param {object} styles
   */
  setValueForStyles: function (node, styles) {
    var style = node.style;
    for (var styleName in styles) {
      if (!styles.hasOwnProperty(styleName)) {
        continue;
      }
      if (process.env.NODE_ENV !== 'production') {
        warnValidStyle(styleName, styles[styleName]);
      }
      var styleValue = dangerousStyleValue(styleName, styles[styleName]);
      if (styleName === 'float') {
        styleName = styleFloatAccessor;
      }
      if (styleValue) {
        style[styleName] = styleValue;
      } else {
        var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName];
        if (expansion) {
          // Shorthand property that IE8 won't like unsetting, so unset each
          // component to placate it
          for (var individualStyleName in expansion) {
            style[individualStyleName] = '';
          }
        } else {
          style[styleName] = '';
        }
      }
    }
  }

};

ReactPerf.measureMethods(CSSPropertyOperations, 'CSSPropertyOperations', {
  setValueForStyles: 'setValueForStyles'
});

module.exports = CSSPropertyOperations;
}).call(this,require('_process'))

},{"./CSSProperty":399,"./ReactPerf":467,"./dangerousStyleValue":501,"_process":334,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/camelizeStyleName":306,"fbjs/lib/hyphenateStyleName":317,"fbjs/lib/memoizeStringOnly":324,"fbjs/lib/warning":329}],401:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule CallbackQueue
 */

'use strict';

var PooledClass = require('./PooledClass');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');

/**
 * A specialized pseudo-event module to help keep track of components waiting to
 * be notified when their DOM representations are available for use.
 *
 * This implements `PooledClass`, so you should never need to instantiate this.
 * Instead, use `CallbackQueue.getPooled()`.
 *
 * @class ReactMountReady
 * @implements PooledClass
 * @internal
 */
function CallbackQueue() {
  this._callbacks = null;
  this._contexts = null;
}

assign(CallbackQueue.prototype, {

  /**
   * Enqueues a callback to be invoked when `notifyAll` is invoked.
   *
   * @param {function} callback Invoked when `notifyAll` is invoked.
   * @param {?object} context Context to call `callback` with.
   * @internal
   */
  enqueue: function (callback, context) {
    this._callbacks = this._callbacks || [];
    this._contexts = this._contexts || [];
    this._callbacks.push(callback);
    this._contexts.push(context);
  },

  /**
   * Invokes all enqueued callbacks and clears the queue. This is invoked after
   * the DOM representation of a component has been created or updated.
   *
   * @internal
   */
  notifyAll: function () {
    var callbacks = this._callbacks;
    var contexts = this._contexts;
    if (callbacks) {
      !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : undefined;
      this._callbacks = null;
      this._contexts = null;
      for (var i = 0; i < callbacks.length; i++) {
        callbacks[i].call(contexts[i]);
      }
      callbacks.length = 0;
      contexts.length = 0;
    }
  },

  /**
   * Resets the internal queue.
   *
   * @internal
   */
  reset: function () {
    this._callbacks = null;
    this._contexts = null;
  },

  /**
   * `PooledClass` looks for this.
   */
  destructor: function () {
    this.reset();
  }

});

PooledClass.addPoolingTo(CallbackQueue);

module.exports = CallbackQueue;
}).call(this,require('_process'))

},{"./Object.assign":418,"./PooledClass":419,"_process":334,"fbjs/lib/invariant":318}],402:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ChangeEventPlugin
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPluginHub = require('./EventPluginHub');
var EventPropagators = require('./EventPropagators');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var ReactUpdates = require('./ReactUpdates');
var SyntheticEvent = require('./SyntheticEvent');

var getEventTarget = require('./getEventTarget');
var isEventSupported = require('./isEventSupported');
var isTextInputElement = require('./isTextInputElement');
var keyOf = require('fbjs/lib/keyOf');

var topLevelTypes = EventConstants.topLevelTypes;

var eventTypes = {
  change: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onChange: null }),
      captured: keyOf({ onChangeCapture: null })
    },
    dependencies: [topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange]
  }
};

/**
 * For IE shims
 */
var activeElement = null;
var activeElementID = null;
var activeElementValue = null;
var activeElementValueProp = null;

/**
 * SECTION: handle `change` event
 */
function shouldUseChangeEvent(elem) {
  var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
  return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
}

var doesChangeEventBubble = false;
if (ExecutionEnvironment.canUseDOM) {
  // See `handleChange` comment below
  doesChangeEventBubble = isEventSupported('change') && (!('documentMode' in document) || document.documentMode > 8);
}

function manualDispatchChangeEvent(nativeEvent) {
  var event = SyntheticEvent.getPooled(eventTypes.change, activeElementID, nativeEvent, getEventTarget(nativeEvent));
  EventPropagators.accumulateTwoPhaseDispatches(event);

  // If change and propertychange bubbled, we'd just bind to it like all the
  // other events and have it go through ReactBrowserEventEmitter. Since it
  // doesn't, we manually listen for the events and so we have to enqueue and
  // process the abstract event manually.
  //
  // Batching is necessary here in order to ensure that all event handlers run
  // before the next rerender (including event handlers attached to ancestor
  // elements instead of directly on the input). Without this, controlled
  // components don't work properly in conjunction with event bubbling because
  // the component is rerendered and the value reverted before all the event
  // handlers can run. See https://github.com/facebook/react/issues/708.
  ReactUpdates.batchedUpdates(runEventInBatch, event);
}

function runEventInBatch(event) {
  EventPluginHub.enqueueEvents(event);
  EventPluginHub.processEventQueue(false);
}

function startWatchingForChangeEventIE8(target, targetID) {
  activeElement = target;
  activeElementID = targetID;
  activeElement.attachEvent('onchange', manualDispatchChangeEvent);
}

function stopWatchingForChangeEventIE8() {
  if (!activeElement) {
    return;
  }
  activeElement.detachEvent('onchange', manualDispatchChangeEvent);
  activeElement = null;
  activeElementID = null;
}

function getTargetIDForChangeEvent(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topChange) {
    return topLevelTargetID;
  }
}
function handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topFocus) {
    // stopWatching() should be a noop here but we call it just in case we
    // missed a blur event somehow.
    stopWatchingForChangeEventIE8();
    startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
  } else if (topLevelType === topLevelTypes.topBlur) {
    stopWatchingForChangeEventIE8();
  }
}

/**
 * SECTION: handle `input` event
 */
var isInputEventSupported = false;
if (ExecutionEnvironment.canUseDOM) {
  // IE9 claims to support the input event but fails to trigger it when
  // deleting text, so we ignore its input events
  isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 9);
}

/**
 * (For old IE.) Replacement getter/setter for the `value` property that gets
 * set on the active element.
 */
var newValueProp = {
  get: function () {
    return activeElementValueProp.get.call(this);
  },
  set: function (val) {
    // Cast to a string so we can do equality checks.
    activeElementValue = '' + val;
    activeElementValueProp.set.call(this, val);
  }
};

/**
 * (For old IE.) Starts tracking propertychange events on the passed-in element
 * and override the value property so that we can distinguish user events from
 * value changes in JS.
 */
function startWatchingForValueChange(target, targetID) {
  activeElement = target;
  activeElementID = targetID;
  activeElementValue = target.value;
  activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value');

  // Not guarded in a canDefineProperty check: IE8 supports defineProperty only
  // on DOM elements
  Object.defineProperty(activeElement, 'value', newValueProp);
  activeElement.attachEvent('onpropertychange', handlePropertyChange);
}

/**
 * (For old IE.) Removes the event listeners from the currently-tracked element,
 * if any exists.
 */
function stopWatchingForValueChange() {
  if (!activeElement) {
    return;
  }

  // delete restores the original property definition
  delete activeElement.value;
  activeElement.detachEvent('onpropertychange', handlePropertyChange);

  activeElement = null;
  activeElementID = null;
  activeElementValue = null;
  activeElementValueProp = null;
}

/**
 * (For old IE.) Handles a propertychange event, sending a `change` event if
 * the value of the active element has changed.
 */
function handlePropertyChange(nativeEvent) {
  if (nativeEvent.propertyName !== 'value') {
    return;
  }
  var value = nativeEvent.srcElement.value;
  if (value === activeElementValue) {
    return;
  }
  activeElementValue = value;

  manualDispatchChangeEvent(nativeEvent);
}

/**
 * If a `change` event should be fired, returns the target's ID.
 */
function getTargetIDForInputEvent(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topInput) {
    // In modern browsers (i.e., not IE8 or IE9), the input event is exactly
    // what we want so fall through here and trigger an abstract event
    return topLevelTargetID;
  }
}

// For IE8 and IE9.
function handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topFocus) {
    // In IE8, we can capture almost all .value changes by adding a
    // propertychange handler and looking for events with propertyName
    // equal to 'value'
    // In IE9, propertychange fires for most input events but is buggy and
    // doesn't fire when text is deleted, but conveniently, selectionchange
    // appears to fire in all of the remaining cases so we catch those and
    // forward the event if the value has changed
    // In either case, we don't want to call the event handler if the value
    // is changed from JS so we redefine a setter for `.value` that updates
    // our activeElementValue variable, allowing us to ignore those changes
    //
    // stopWatching() should be a noop here but we call it just in case we
    // missed a blur event somehow.
    stopWatchingForValueChange();
    startWatchingForValueChange(topLevelTarget, topLevelTargetID);
  } else if (topLevelType === topLevelTypes.topBlur) {
    stopWatchingForValueChange();
  }
}

// For IE8 and IE9.
function getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) {
    // On the selectionchange event, the target is just document which isn't
    // helpful for us so just check activeElement instead.
    //
    // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
    // propertychange on the first input event after setting `value` from a
    // script and fires only keydown, keypress, keyup. Catching keyup usually
    // gets it and catching keydown lets us fire an event for the first
    // keystroke if user does a key repeat (it'll be a little delayed: right
    // before the second keystroke). Other input methods (e.g., paste) seem to
    // fire selectionchange normally.
    if (activeElement && activeElement.value !== activeElementValue) {
      activeElementValue = activeElement.value;
      return activeElementID;
    }
  }
}

/**
 * SECTION: handle `click` event
 */
function shouldUseClickEvent(elem) {
  // Use the `click` event to detect changes to checkbox and radio inputs.
  // This approach works across all browsers, whereas `change` does not fire
  // until `blur` in IE8.
  return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
}

function getTargetIDForClickEvent(topLevelType, topLevelTarget, topLevelTargetID) {
  if (topLevelType === topLevelTypes.topClick) {
    return topLevelTargetID;
  }
}

/**
 * This plugin creates an `onChange` event that normalizes change events
 * across form elements. This event fires at a time when it's possible to
 * change the element's value without seeing a flicker.
 *
 * Supported elements are:
 * - input (see `isTextInputElement`)
 * - textarea
 * - select
 */
var ChangeEventPlugin = {

  eventTypes: eventTypes,

  /**
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @see {EventPluginHub.extractEvents}
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {

    var getTargetIDFunc, handleEventFunc;
    if (shouldUseChangeEvent(topLevelTarget)) {
      if (doesChangeEventBubble) {
        getTargetIDFunc = getTargetIDForChangeEvent;
      } else {
        handleEventFunc = handleEventsForChangeEventIE8;
      }
    } else if (isTextInputElement(topLevelTarget)) {
      if (isInputEventSupported) {
        getTargetIDFunc = getTargetIDForInputEvent;
      } else {
        getTargetIDFunc = getTargetIDForInputEventIE;
        handleEventFunc = handleEventsForInputEventIE;
      }
    } else if (shouldUseClickEvent(topLevelTarget)) {
      getTargetIDFunc = getTargetIDForClickEvent;
    }

    if (getTargetIDFunc) {
      var targetID = getTargetIDFunc(topLevelType, topLevelTarget, topLevelTargetID);
      if (targetID) {
        var event = SyntheticEvent.getPooled(eventTypes.change, targetID, nativeEvent, nativeEventTarget);
        event.type = 'change';
        EventPropagators.accumulateTwoPhaseDispatches(event);
        return event;
      }
    }

    if (handleEventFunc) {
      handleEventFunc(topLevelType, topLevelTarget, topLevelTargetID);
    }
  }

};

module.exports = ChangeEventPlugin;
},{"./EventConstants":410,"./EventPluginHub":411,"./EventPropagators":414,"./ReactUpdates":479,"./SyntheticEvent":488,"./getEventTarget":510,"./isEventSupported":515,"./isTextInputElement":516,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/keyOf":322}],403:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ClientReactRootIndex
 * @typechecks
 */

'use strict';

var nextReactRootIndex = 0;

var ClientReactRootIndex = {
  createReactRootIndex: function () {
    return nextReactRootIndex++;
  }
};

module.exports = ClientReactRootIndex;
},{}],404:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule DOMChildrenOperations
 * @typechecks static-only
 */

'use strict';

var Danger = require('./Danger');
var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes');
var ReactPerf = require('./ReactPerf');

var setInnerHTML = require('./setInnerHTML');
var setTextContent = require('./setTextContent');
var invariant = require('fbjs/lib/invariant');

/**
 * Inserts `childNode` as a child of `parentNode` at the `index`.
 *
 * @param {DOMElement} parentNode Parent node in which to insert.
 * @param {DOMElement} childNode Child node to insert.
 * @param {number} index Index at which to insert the child.
 * @internal
 */
function insertChildAt(parentNode, childNode, index) {
  // By exploiting arrays returning `undefined` for an undefined index, we can
  // rely exclusively on `insertBefore(node, null)` instead of also using
  // `appendChild(node)`. However, using `undefined` is not allowed by all
  // browsers so we must replace it with `null`.

  // fix render order error in safari
  // IE8 will throw error when index out of list size.
  var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index);

  parentNode.insertBefore(childNode, beforeChild);
}

/**
 * Operations for updating with DOM children.
 */
var DOMChildrenOperations = {

  dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,

  updateTextContent: setTextContent,

  /**
   * Updates a component's children by processing a series of updates. The
   * update configurations are each expected to have a `parentNode` property.
   *
   * @param {array<object>} updates List of update configurations.
   * @param {array<string>} markupList List of markup strings.
   * @internal
   */
  processUpdates: function (updates, markupList) {
    var update;
    // Mapping from parent IDs to initial child orderings.
    var initialChildren = null;
    // List of children that will be moved or removed.
    var updatedChildren = null;

    for (var i = 0; i < updates.length; i++) {
      update = updates[i];
      if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
        var updatedIndex = update.fromIndex;
        var updatedChild = update.parentNode.childNodes[updatedIndex];
        var parentID = update.parentID;

        !updatedChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a <tbody> when using tables, ' + 'nesting tags like <form>, <p>, or <a>, or using non-SVG elements ' + 'in an <svg> parent. Try inspecting the child nodes of the element ' + 'with React ID `%s`.', updatedIndex, parentID) : invariant(false) : undefined;

        initialChildren = initialChildren || {};
        initialChildren[parentID] = initialChildren[parentID] || [];
        initialChildren[parentID][updatedIndex] = updatedChild;

        updatedChildren = updatedChildren || [];
        updatedChildren.push(updatedChild);
      }
    }

    var renderedMarkup;
    // markupList is either a list of markup or just a list of elements
    if (markupList.length && typeof markupList[0] === 'string') {
      renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);
    } else {
      renderedMarkup = markupList;
    }

    // Remove updated children first so that `toIndex` is consistent.
    if (updatedChildren) {
      for (var j = 0; j < updatedChildren.length; j++) {
        updatedChildren[j].parentNode.removeChild(updatedChildren[j]);
      }
    }

    for (var k = 0; k < updates.length; k++) {
      update = updates[k];
      switch (update.type) {
        case ReactMultiChildUpdateTypes.INSERT_MARKUP:
          insertChildAt(update.parentNode, renderedMarkup[update.markupIndex], update.toIndex);
          break;
        case ReactMultiChildUpdateTypes.MOVE_EXISTING:
          insertChildAt(update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex);
          break;
        case ReactMultiChildUpdateTypes.SET_MARKUP:
          setInnerHTML(update.parentNode, update.content);
          break;
        case ReactMultiChildUpdateTypes.TEXT_CONTENT:
          setTextContent(update.parentNode, update.content);
          break;
        case ReactMultiChildUpdateTypes.REMOVE_NODE:
          // Already removed by the for-loop above.
          break;
      }
    }
  }

};

ReactPerf.measureMethods(DOMChildrenOperations, 'DOMChildrenOperations', {
  updateTextContent: 'updateTextContent'
});

module.exports = DOMChildrenOperations;
}).call(this,require('_process'))

},{"./Danger":407,"./ReactMultiChildUpdateTypes":463,"./ReactPerf":467,"./setInnerHTML":520,"./setTextContent":521,"_process":334,"fbjs/lib/invariant":318}],405:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule DOMProperty
 * @typechecks static-only
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

function checkMask(value, bitmask) {
  return (value & bitmask) === bitmask;
}

var DOMPropertyInjection = {
  /**
   * Mapping from normalized, camelcased property names to a configuration that
   * specifies how the associated DOM property should be accessed or rendered.
   */
  MUST_USE_ATTRIBUTE: 0x1,
  MUST_USE_PROPERTY: 0x2,
  HAS_SIDE_EFFECTS: 0x4,
  HAS_BOOLEAN_VALUE: 0x8,
  HAS_NUMERIC_VALUE: 0x10,
  HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10,
  HAS_OVERLOADED_BOOLEAN_VALUE: 0x40,

  /**
   * Inject some specialized knowledge about the DOM. This takes a config object
   * with the following properties:
   *
   * isCustomAttribute: function that given an attribute name will return true
   * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
   * attributes where it's impossible to enumerate all of the possible
   * attribute names,
   *
   * Properties: object mapping DOM property name to one of the
   * DOMPropertyInjection constants or null. If your attribute isn't in here,
   * it won't get written to the DOM.
   *
   * DOMAttributeNames: object mapping React attribute name to the DOM
   * attribute name. Attribute names not specified use the **lowercase**
   * normalized name.
   *
   * DOMAttributeNamespaces: object mapping React attribute name to the DOM
   * attribute namespace URL. (Attribute names not specified use no namespace.)
   *
   * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
   * Property names not specified use the normalized name.
   *
   * DOMMutationMethods: Properties that require special mutation methods. If
   * `value` is undefined, the mutation method should unset the property.
   *
   * @param {object} domPropertyConfig the config as described above.
   */
  injectDOMPropertyConfig: function (domPropertyConfig) {
    var Injection = DOMPropertyInjection;
    var Properties = domPropertyConfig.Properties || {};
    var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};
    var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
    var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
    var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};

    if (domPropertyConfig.isCustomAttribute) {
      DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute);
    }

    for (var propName in Properties) {
      !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + '\'%s\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName) : invariant(false) : undefined;

      var lowerCased = propName.toLowerCase();
      var propConfig = Properties[propName];

      var propertyInfo = {
        attributeName: lowerCased,
        attributeNamespace: null,
        propertyName: propName,
        mutationMethod: null,

        mustUseAttribute: checkMask(propConfig, Injection.MUST_USE_ATTRIBUTE),
        mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),
        hasSideEffects: checkMask(propConfig, Injection.HAS_SIDE_EFFECTS),
        hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),
        hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),
        hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE),
        hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE)
      };

      !(!propertyInfo.mustUseAttribute || !propertyInfo.mustUseProperty) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Cannot require using both attribute and property: %s', propName) : invariant(false) : undefined;
      !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : undefined;
      !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : undefined;

      if (process.env.NODE_ENV !== 'production') {
        DOMProperty.getPossibleStandardName[lowerCased] = propName;
      }

      if (DOMAttributeNames.hasOwnProperty(propName)) {
        var attributeName = DOMAttributeNames[propName];
        propertyInfo.attributeName = attributeName;
        if (process.env.NODE_ENV !== 'production') {
          DOMProperty.getPossibleStandardName[attributeName] = propName;
        }
      }

      if (DOMAttributeNamespaces.hasOwnProperty(propName)) {
        propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];
      }

      if (DOMPropertyNames.hasOwnProperty(propName)) {
        propertyInfo.propertyName = DOMPropertyNames[propName];
      }

      if (DOMMutationMethods.hasOwnProperty(propName)) {
        propertyInfo.mutationMethod = DOMMutationMethods[propName];
      }

      DOMProperty.properties[propName] = propertyInfo;
    }
  }
};
var defaultValueCache = {};

/**
 * DOMProperty exports lookup objects that can be used like functions:
 *
 *   > DOMProperty.isValid['id']
 *   true
 *   > DOMProperty.isValid['foobar']
 *   undefined
 *
 * Although this may be confusing, it performs better in general.
 *
 * @see http://jsperf.com/key-exists
 * @see http://jsperf.com/key-missing
 */
var DOMProperty = {

  ID_ATTRIBUTE_NAME: 'data-reactid',

  /**
   * Map from property "standard name" to an object with info about how to set
   * the property in the DOM. Each object contains:
   *
   * attributeName:
   *   Used when rendering markup or with `*Attribute()`.
   * attributeNamespace
   * propertyName:
   *   Used on DOM node instances. (This includes properties that mutate due to
   *   external factors.)
   * mutationMethod:
   *   If non-null, used instead of the property or `setAttribute()` after
   *   initial render.
   * mustUseAttribute:
   *   Whether the property must be accessed and mutated using `*Attribute()`.
   *   (This includes anything that fails `<propName> in <element>`.)
   * mustUseProperty:
   *   Whether the property must be accessed and mutated as an object property.
   * hasSideEffects:
   *   Whether or not setting a value causes side effects such as triggering
   *   resources to be loaded or text selection changes. If true, we read from
   *   the DOM before updating to ensure that the value is only set if it has
   *   changed.
   * hasBooleanValue:
   *   Whether the property should be removed when set to a falsey value.
   * hasNumericValue:
   *   Whether the property must be numeric or parse as a numeric and should be
   *   removed when set to a falsey value.
   * hasPositiveNumericValue:
   *   Whether the property must be positive numeric or parse as a positive
   *   numeric and should be removed when set to a falsey value.
   * hasOverloadedBooleanValue:
   *   Whether the property can be used as a flag as well as with a value.
   *   Removed when strictly equal to false; present without a value when
   *   strictly equal to true; present with a value otherwise.
   */
  properties: {},

  /**
   * Mapping from lowercase property names to the properly cased version, used
   * to warn in the case of missing properties. Available only in __DEV__.
   * @type {Object}
   */
  getPossibleStandardName: process.env.NODE_ENV !== 'production' ? {} : null,

  /**
   * All of the isCustomAttribute() functions that have been injected.
   */
  _isCustomAttributeFunctions: [],

  /**
   * Checks whether a property name is a custom attribute.
   * @method
   */
  isCustomAttribute: function (attributeName) {
    for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
      var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];
      if (isCustomAttributeFn(attributeName)) {
        return true;
      }
    }
    return false;
  },

  /**
   * Returns the default property value for a DOM property (i.e., not an
   * attribute). Most default values are '' or false, but not all. Worse yet,
   * some (in particular, `type`) vary depending on the type of element.
   *
   * TODO: Is it better to grab all the possible properties when creating an
   * element to avoid having to create the same element twice?
   */
  getDefaultValueForProperty: function (nodeName, prop) {
    var nodeDefaults = defaultValueCache[nodeName];
    var testElement;
    if (!nodeDefaults) {
      defaultValueCache[nodeName] = nodeDefaults = {};
    }
    if (!(prop in nodeDefaults)) {
      testElement = document.createElement(nodeName);
      nodeDefaults[prop] = testElement[prop];
    }
    return nodeDefaults[prop];
  },

  injection: DOMPropertyInjection
};

module.exports = DOMProperty;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],406:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule DOMPropertyOperations
 * @typechecks static-only
 */

'use strict';

var DOMProperty = require('./DOMProperty');
var ReactPerf = require('./ReactPerf');

var quoteAttributeValueForBrowser = require('./quoteAttributeValueForBrowser');
var warning = require('fbjs/lib/warning');

// Simplified subset
var VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][\w\.\-]*$/;
var illegalAttributeNameCache = {};
var validatedAttributeNameCache = {};

function isAttributeNameSafe(attributeName) {
  if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
    return true;
  }
  if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
    return false;
  }
  if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
    validatedAttributeNameCache[attributeName] = true;
    return true;
  }
  illegalAttributeNameCache[attributeName] = true;
  process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : undefined;
  return false;
}

function shouldIgnoreValue(propertyInfo, value) {
  return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false;
}

if (process.env.NODE_ENV !== 'production') {
  var reactProps = {
    children: true,
    dangerouslySetInnerHTML: true,
    key: true,
    ref: true
  };
  var warnedProperties = {};

  var warnUnknownProperty = function (name) {
    if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
      return;
    }

    warnedProperties[name] = true;
    var lowerCasedName = name.toLowerCase();

    // data-* attributes should be lowercase; suggest the lowercase version
    var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;

    // For now, only warn when we have a suggested correction. This prevents
    // logging too much when using transferPropsTo.
    process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : undefined;
  };
}

/**
 * Operations for dealing with DOM properties.
 */
var DOMPropertyOperations = {

  /**
   * Creates markup for the ID property.
   *
   * @param {string} id Unescaped ID.
   * @return {string} Markup string.
   */
  createMarkupForID: function (id) {
    return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id);
  },

  setAttributeForID: function (node, id) {
    node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id);
  },

  /**
   * Creates markup for a property.
   *
   * @param {string} name
   * @param {*} value
   * @return {?string} Markup string, or null if the property was invalid.
   */
  createMarkupForProperty: function (name, value) {
    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
    if (propertyInfo) {
      if (shouldIgnoreValue(propertyInfo, value)) {
        return '';
      }
      var attributeName = propertyInfo.attributeName;
      if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {
        return attributeName + '=""';
      }
      return attributeName + '=' + quoteAttributeValueForBrowser(value);
    } else if (DOMProperty.isCustomAttribute(name)) {
      if (value == null) {
        return '';
      }
      return name + '=' + quoteAttributeValueForBrowser(value);
    } else if (process.env.NODE_ENV !== 'production') {
      warnUnknownProperty(name);
    }
    return null;
  },

  /**
   * Creates markup for a custom property.
   *
   * @param {string} name
   * @param {*} value
   * @return {string} Markup string, or empty string if the property was invalid.
   */
  createMarkupForCustomAttribute: function (name, value) {
    if (!isAttributeNameSafe(name) || value == null) {
      return '';
    }
    return name + '=' + quoteAttributeValueForBrowser(value);
  },

  /**
   * Sets the value for a property on a node.
   *
   * @param {DOMElement} node
   * @param {string} name
   * @param {*} value
   */
  setValueForProperty: function (node, name, value) {
    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
    if (propertyInfo) {
      var mutationMethod = propertyInfo.mutationMethod;
      if (mutationMethod) {
        mutationMethod(node, value);
      } else if (shouldIgnoreValue(propertyInfo, value)) {
        this.deleteValueForProperty(node, name);
      } else if (propertyInfo.mustUseAttribute) {
        var attributeName = propertyInfo.attributeName;
        var namespace = propertyInfo.attributeNamespace;
        // `setAttribute` with objects becomes only `[object]` in IE8/9,
        // ('' + value) makes it output the correct toString()-value.
        if (namespace) {
          node.setAttributeNS(namespace, attributeName, '' + value);
        } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {
          node.setAttribute(attributeName, '');
        } else {
          node.setAttribute(attributeName, '' + value);
        }
      } else {
        var propName = propertyInfo.propertyName;
        // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the
        // property type before comparing; only `value` does and is string.
        if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value) {
          // Contrary to `setAttribute`, object properties are properly
          // `toString`ed by IE8/9.
          node[propName] = value;
        }
      }
    } else if (DOMProperty.isCustomAttribute(name)) {
      DOMPropertyOperations.setValueForAttribute(node, name, value);
    } else if (process.env.NODE_ENV !== 'production') {
      warnUnknownProperty(name);
    }
  },

  setValueForAttribute: function (node, name, value) {
    if (!isAttributeNameSafe(name)) {
      return;
    }
    if (value == null) {
      node.removeAttribute(name);
    } else {
      node.setAttribute(name, '' + value);
    }
  },

  /**
   * Deletes the value for a property on a node.
   *
   * @param {DOMElement} node
   * @param {string} name
   */
  deleteValueForProperty: function (node, name) {
    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
    if (propertyInfo) {
      var mutationMethod = propertyInfo.mutationMethod;
      if (mutationMethod) {
        mutationMethod(node, undefined);
      } else if (propertyInfo.mustUseAttribute) {
        node.removeAttribute(propertyInfo.attributeName);
      } else {
        var propName = propertyInfo.propertyName;
        var defaultValue = DOMProperty.getDefaultValueForProperty(node.nodeName, propName);
        if (!propertyInfo.hasSideEffects || '' + node[propName] !== defaultValue) {
          node[propName] = defaultValue;
        }
      }
    } else if (DOMProperty.isCustomAttribute(name)) {
      node.removeAttribute(name);
    } else if (process.env.NODE_ENV !== 'production') {
      warnUnknownProperty(name);
    }
  }

};

ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', {
  setValueForProperty: 'setValueForProperty',
  setValueForAttribute: 'setValueForAttribute',
  deleteValueForProperty: 'deleteValueForProperty'
});

module.exports = DOMPropertyOperations;
}).call(this,require('_process'))

},{"./DOMProperty":405,"./ReactPerf":467,"./quoteAttributeValueForBrowser":518,"_process":334,"fbjs/lib/warning":329}],407:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule Danger
 * @typechecks static-only
 */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var createNodesFromMarkup = require('fbjs/lib/createNodesFromMarkup');
var emptyFunction = require('fbjs/lib/emptyFunction');
var getMarkupWrap = require('fbjs/lib/getMarkupWrap');
var invariant = require('fbjs/lib/invariant');

var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/;
var RESULT_INDEX_ATTR = 'data-danger-index';

/**
 * Extracts the `nodeName` from a string of markup.
 *
 * NOTE: Extracting the `nodeName` does not require a regular expression match
 * because we make assumptions about React-generated markup (i.e. there are no
 * spaces surrounding the opening tag and there is at least one attribute).
 *
 * @param {string} markup String of markup.
 * @return {string} Node name of the supplied markup.
 * @see http://jsperf.com/extract-nodename
 */
function getNodeName(markup) {
  return markup.substring(1, markup.indexOf(' '));
}

var Danger = {

  /**
   * Renders markup into an array of nodes. The markup is expected to render
   * into a list of root nodes. Also, the length of `resultList` and
   * `markupList` should be the same.
   *
   * @param {array<string>} markupList List of markup strings to render.
   * @return {array<DOMElement>} List of rendered nodes.
   * @internal
   */
  dangerouslyRenderMarkup: function (markupList) {
    !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : undefined;
    var nodeName;
    var markupByNodeName = {};
    // Group markup by `nodeName` if a wrap is necessary, else by '*'.
    for (var i = 0; i < markupList.length; i++) {
      !markupList[i] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : undefined;
      nodeName = getNodeName(markupList[i]);
      nodeName = getMarkupWrap(nodeName) ? nodeName : '*';
      markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];
      markupByNodeName[nodeName][i] = markupList[i];
    }
    var resultList = [];
    var resultListAssignmentCount = 0;
    for (nodeName in markupByNodeName) {
      if (!markupByNodeName.hasOwnProperty(nodeName)) {
        continue;
      }
      var markupListByNodeName = markupByNodeName[nodeName];

      // This for-in loop skips the holes of the sparse array. The order of
      // iteration should follow the order of assignment, which happens to match
      // numerical index order, but we don't rely on that.
      var resultIndex;
      for (resultIndex in markupListByNodeName) {
        if (markupListByNodeName.hasOwnProperty(resultIndex)) {
          var markup = markupListByNodeName[resultIndex];

          // Push the requested markup with an additional RESULT_INDEX_ATTR
          // attribute.  If the markup does not start with a < character, it
          // will be discarded below (with an appropriate console.error).
          markupListByNodeName[resultIndex] = markup.replace(OPEN_TAG_NAME_EXP,
          // This index will be parsed back out below.
          '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ');
        }
      }

      // Render each group of markup with similar wrapping `nodeName`.
      var renderNodes = createNodesFromMarkup(markupListByNodeName.join(''), emptyFunction // Do nothing special with <script> tags.
      );

      for (var j = 0; j < renderNodes.length; ++j) {
        var renderNode = renderNodes[j];
        if (renderNode.hasAttribute && renderNode.hasAttribute(RESULT_INDEX_ATTR)) {

          resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
          renderNode.removeAttribute(RESULT_INDEX_ATTR);

          !!resultList.hasOwnProperty(resultIndex) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Assigning to an already-occupied result index.') : invariant(false) : undefined;

          resultList[resultIndex] = renderNode;

          // This should match resultList.length and markupList.length when
          // we're done.
          resultListAssignmentCount += 1;
        } else if (process.env.NODE_ENV !== 'production') {
          console.error('Danger: Discarding unexpected node:', renderNode);
        }
      }
    }

    // Although resultList was populated out of order, it should now be a dense
    // array.
    !(resultListAssignmentCount === resultList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Did not assign to every index of resultList.') : invariant(false) : undefined;

    !(resultList.length === markupList.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length) : invariant(false) : undefined;

    return resultList;
  },

  /**
   * Replaces a node with a string of markup at its current position within its
   * parent. The markup must render into a single root node.
   *
   * @param {DOMElement} oldChild Child node to replace.
   * @param {string} markup Markup to render in place of the child node.
   * @internal
   */
  dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) {
    !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. Make sure `window` and `document` are available ' + 'globally before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined;
    !markup ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(false) : undefined;
    !(oldChild.tagName.toLowerCase() !== 'html') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + '<html> node. This is because browser quirks make this unreliable ' + 'and/or slow. If you want to render to the root you must use ' + 'server rendering. See ReactDOMServer.renderToString().') : invariant(false) : undefined;

    var newChild;
    if (typeof markup === 'string') {
      newChild = createNodesFromMarkup(markup, emptyFunction)[0];
    } else {
      newChild = markup;
    }
    oldChild.parentNode.replaceChild(newChild, oldChild);
  }

};

module.exports = Danger;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/createNodesFromMarkup":309,"fbjs/lib/emptyFunction":310,"fbjs/lib/getMarkupWrap":314,"fbjs/lib/invariant":318}],408:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule DefaultEventPluginOrder
 */

'use strict';

var keyOf = require('fbjs/lib/keyOf');

/**
 * Module that is injectable into `EventPluginHub`, that specifies a
 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
 * plugins, without having to package every one of them. This is better than
 * having plugins be ordered in the same order that they are injected because
 * that ordering would be influenced by the packaging order.
 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
 */
var DefaultEventPluginOrder = [keyOf({ ResponderEventPlugin: null }), keyOf({ SimpleEventPlugin: null }), keyOf({ TapEventPlugin: null }), keyOf({ EnterLeaveEventPlugin: null }), keyOf({ ChangeEventPlugin: null }), keyOf({ SelectEventPlugin: null }), keyOf({ BeforeInputEventPlugin: null })];

module.exports = DefaultEventPluginOrder;
},{"fbjs/lib/keyOf":322}],409:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EnterLeaveEventPlugin
 * @typechecks static-only
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPropagators = require('./EventPropagators');
var SyntheticMouseEvent = require('./SyntheticMouseEvent');

var ReactMount = require('./ReactMount');
var keyOf = require('fbjs/lib/keyOf');

var topLevelTypes = EventConstants.topLevelTypes;
var getFirstReactDOM = ReactMount.getFirstReactDOM;

var eventTypes = {
  mouseEnter: {
    registrationName: keyOf({ onMouseEnter: null }),
    dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver]
  },
  mouseLeave: {
    registrationName: keyOf({ onMouseLeave: null }),
    dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver]
  }
};

var extractedEvents = [null, null];

var EnterLeaveEventPlugin = {

  eventTypes: eventTypes,

  /**
   * For almost every interaction we care about, there will be both a top-level
   * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
   * we do not extract duplicate events. However, moving the mouse into the
   * browser from outside will not fire a `mouseout` event. In this case, we use
   * the `mouseover` top-level event.
   *
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @see {EventPluginHub.extractEvents}
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
      return null;
    }
    if (topLevelType !== topLevelTypes.topMouseOut && topLevelType !== topLevelTypes.topMouseOver) {
      // Must not be a mouse in or mouse out - ignoring.
      return null;
    }

    var win;
    if (topLevelTarget.window === topLevelTarget) {
      // `topLevelTarget` is probably a window object.
      win = topLevelTarget;
    } else {
      // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
      var doc = topLevelTarget.ownerDocument;
      if (doc) {
        win = doc.defaultView || doc.parentWindow;
      } else {
        win = window;
      }
    }

    var from;
    var to;
    var fromID = '';
    var toID = '';
    if (topLevelType === topLevelTypes.topMouseOut) {
      from = topLevelTarget;
      fromID = topLevelTargetID;
      to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement);
      if (to) {
        toID = ReactMount.getID(to);
      } else {
        to = win;
      }
      to = to || win;
    } else {
      from = win;
      to = topLevelTarget;
      toID = topLevelTargetID;
    }

    if (from === to) {
      // Nothing pertains to our managed components.
      return null;
    }

    var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, fromID, nativeEvent, nativeEventTarget);
    leave.type = 'mouseleave';
    leave.target = from;
    leave.relatedTarget = to;

    var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, toID, nativeEvent, nativeEventTarget);
    enter.type = 'mouseenter';
    enter.target = to;
    enter.relatedTarget = from;

    EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);

    extractedEvents[0] = leave;
    extractedEvents[1] = enter;

    return extractedEvents;
  }

};

module.exports = EnterLeaveEventPlugin;
},{"./EventConstants":410,"./EventPropagators":414,"./ReactMount":461,"./SyntheticMouseEvent":492,"fbjs/lib/keyOf":322}],410:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventConstants
 */

'use strict';

var keyMirror = require('fbjs/lib/keyMirror');

var PropagationPhases = keyMirror({ bubbled: null, captured: null });

/**
 * Types of raw signals from the browser caught at the top level.
 */
var topLevelTypes = keyMirror({
  topAbort: null,
  topBlur: null,
  topCanPlay: null,
  topCanPlayThrough: null,
  topChange: null,
  topClick: null,
  topCompositionEnd: null,
  topCompositionStart: null,
  topCompositionUpdate: null,
  topContextMenu: null,
  topCopy: null,
  topCut: null,
  topDoubleClick: null,
  topDrag: null,
  topDragEnd: null,
  topDragEnter: null,
  topDragExit: null,
  topDragLeave: null,
  topDragOver: null,
  topDragStart: null,
  topDrop: null,
  topDurationChange: null,
  topEmptied: null,
  topEncrypted: null,
  topEnded: null,
  topError: null,
  topFocus: null,
  topInput: null,
  topKeyDown: null,
  topKeyPress: null,
  topKeyUp: null,
  topLoad: null,
  topLoadedData: null,
  topLoadedMetadata: null,
  topLoadStart: null,
  topMouseDown: null,
  topMouseMove: null,
  topMouseOut: null,
  topMouseOver: null,
  topMouseUp: null,
  topPaste: null,
  topPause: null,
  topPlay: null,
  topPlaying: null,
  topProgress: null,
  topRateChange: null,
  topReset: null,
  topScroll: null,
  topSeeked: null,
  topSeeking: null,
  topSelectionChange: null,
  topStalled: null,
  topSubmit: null,
  topSuspend: null,
  topTextInput: null,
  topTimeUpdate: null,
  topTouchCancel: null,
  topTouchEnd: null,
  topTouchMove: null,
  topTouchStart: null,
  topVolumeChange: null,
  topWaiting: null,
  topWheel: null
});

var EventConstants = {
  topLevelTypes: topLevelTypes,
  PropagationPhases: PropagationPhases
};

module.exports = EventConstants;
},{"fbjs/lib/keyMirror":321}],411:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPluginHub
 */

'use strict';

var EventPluginRegistry = require('./EventPluginRegistry');
var EventPluginUtils = require('./EventPluginUtils');
var ReactErrorUtils = require('./ReactErrorUtils');

var accumulateInto = require('./accumulateInto');
var forEachAccumulated = require('./forEachAccumulated');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

/**
 * Internal store for event listeners
 */
var listenerBank = {};

/**
 * Internal queue of events that have accumulated their dispatches and are
 * waiting to have their dispatches executed.
 */
var eventQueue = null;

/**
 * Dispatches an event and releases it back into the pool, unless persistent.
 *
 * @param {?object} event Synthetic event to be dispatched.
 * @param {boolean} simulated If the event is simulated (changes exn behavior)
 * @private
 */
var executeDispatchesAndRelease = function (event, simulated) {
  if (event) {
    EventPluginUtils.executeDispatchesInOrder(event, simulated);

    if (!event.isPersistent()) {
      event.constructor.release(event);
    }
  }
};
var executeDispatchesAndReleaseSimulated = function (e) {
  return executeDispatchesAndRelease(e, true);
};
var executeDispatchesAndReleaseTopLevel = function (e) {
  return executeDispatchesAndRelease(e, false);
};

/**
 * - `InstanceHandle`: [required] Module that performs logical traversals of DOM
 *   hierarchy given ids of the logical DOM elements involved.
 */
var InstanceHandle = null;

function validateInstanceHandle() {
  var valid = InstanceHandle && InstanceHandle.traverseTwoPhase && InstanceHandle.traverseEnterLeave;
  process.env.NODE_ENV !== 'production' ? warning(valid, 'InstanceHandle not injected before use!') : undefined;
}

/**
 * This is a unified interface for event plugins to be installed and configured.
 *
 * Event plugins can implement the following properties:
 *
 *   `extractEvents` {function(string, DOMEventTarget, string, object): *}
 *     Required. When a top-level event is fired, this method is expected to
 *     extract synthetic events that will in turn be queued and dispatched.
 *
 *   `eventTypes` {object}
 *     Optional, plugins that fire events must publish a mapping of registration
 *     names that are used to register listeners. Values of this mapping must
 *     be objects that contain `registrationName` or `phasedRegistrationNames`.
 *
 *   `executeDispatch` {function(object, function, string)}
 *     Optional, allows plugins to override how an event gets dispatched. By
 *     default, the listener is simply invoked.
 *
 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
 *
 * @public
 */
var EventPluginHub = {

  /**
   * Methods for injecting dependencies.
   */
  injection: {

    /**
     * @param {object} InjectedMount
     * @public
     */
    injectMount: EventPluginUtils.injection.injectMount,

    /**
     * @param {object} InjectedInstanceHandle
     * @public
     */
    injectInstanceHandle: function (InjectedInstanceHandle) {
      InstanceHandle = InjectedInstanceHandle;
      if (process.env.NODE_ENV !== 'production') {
        validateInstanceHandle();
      }
    },

    getInstanceHandle: function () {
      if (process.env.NODE_ENV !== 'production') {
        validateInstanceHandle();
      }
      return InstanceHandle;
    },

    /**
     * @param {array} InjectedEventPluginOrder
     * @public
     */
    injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,

    /**
     * @param {object} injectedNamesToPlugins Map from names to plugin modules.
     */
    injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName

  },

  eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs,

  registrationNameModules: EventPluginRegistry.registrationNameModules,

  /**
   * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.
   *
   * @param {string} id ID of the DOM element.
   * @param {string} registrationName Name of listener (e.g. `onClick`).
   * @param {?function} listener The callback to store.
   */
  putListener: function (id, registrationName, listener) {
    !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : invariant(false) : undefined;

    var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});
    bankForRegistrationName[id] = listener;

    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
    if (PluginModule && PluginModule.didPutListener) {
      PluginModule.didPutListener(id, registrationName, listener);
    }
  },

  /**
   * @param {string} id ID of the DOM element.
   * @param {string} registrationName Name of listener (e.g. `onClick`).
   * @return {?function} The stored callback.
   */
  getListener: function (id, registrationName) {
    var bankForRegistrationName = listenerBank[registrationName];
    return bankForRegistrationName && bankForRegistrationName[id];
  },

  /**
   * Deletes a listener from the registration bank.
   *
   * @param {string} id ID of the DOM element.
   * @param {string} registrationName Name of listener (e.g. `onClick`).
   */
  deleteListener: function (id, registrationName) {
    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
    if (PluginModule && PluginModule.willDeleteListener) {
      PluginModule.willDeleteListener(id, registrationName);
    }

    var bankForRegistrationName = listenerBank[registrationName];
    // TODO: This should never be null -- when is it?
    if (bankForRegistrationName) {
      delete bankForRegistrationName[id];
    }
  },

  /**
   * Deletes all listeners for the DOM element with the supplied ID.
   *
   * @param {string} id ID of the DOM element.
   */
  deleteAllListeners: function (id) {
    for (var registrationName in listenerBank) {
      if (!listenerBank[registrationName][id]) {
        continue;
      }

      var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
      if (PluginModule && PluginModule.willDeleteListener) {
        PluginModule.willDeleteListener(id, registrationName);
      }

      delete listenerBank[registrationName][id];
    }
  },

  /**
   * Allows registered plugins an opportunity to extract events from top-level
   * native browser events.
   *
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @internal
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    var events;
    var plugins = EventPluginRegistry.plugins;
    for (var i = 0; i < plugins.length; i++) {
      // Not every plugin in the ordering may be loaded at runtime.
      var possiblePlugin = plugins[i];
      if (possiblePlugin) {
        var extractedEvents = possiblePlugin.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget);
        if (extractedEvents) {
          events = accumulateInto(events, extractedEvents);
        }
      }
    }
    return events;
  },

  /**
   * Enqueues a synthetic event that should be dispatched when
   * `processEventQueue` is invoked.
   *
   * @param {*} events An accumulation of synthetic events.
   * @internal
   */
  enqueueEvents: function (events) {
    if (events) {
      eventQueue = accumulateInto(eventQueue, events);
    }
  },

  /**
   * Dispatches all synthetic events on the event queue.
   *
   * @internal
   */
  processEventQueue: function (simulated) {
    // Set `eventQueue` to null before processing it so that we can tell if more
    // events get enqueued while processing.
    var processingEventQueue = eventQueue;
    eventQueue = null;
    if (simulated) {
      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
    } else {
      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
    }
    !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.') : invariant(false) : undefined;
    // This would be a good time to rethrow if any of the event handlers threw.
    ReactErrorUtils.rethrowCaughtError();
  },

  /**
   * These are needed for tests only. Do not use!
   */
  __purge: function () {
    listenerBank = {};
  },

  __getListenerBank: function () {
    return listenerBank;
  }

};

module.exports = EventPluginHub;
}).call(this,require('_process'))

},{"./EventPluginRegistry":412,"./EventPluginUtils":413,"./ReactErrorUtils":452,"./accumulateInto":498,"./forEachAccumulated":506,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],412:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPluginRegistry
 * @typechecks static-only
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 * Injectable ordering of event plugins.
 */
var EventPluginOrder = null;

/**
 * Injectable mapping from names to event plugin modules.
 */
var namesToPlugins = {};

/**
 * Recomputes the plugin list using the injected plugins and plugin ordering.
 *
 * @private
 */
function recomputePluginOrdering() {
  if (!EventPluginOrder) {
    // Wait until an `EventPluginOrder` is injected.
    return;
  }
  for (var pluginName in namesToPlugins) {
    var PluginModule = namesToPlugins[pluginName];
    var pluginIndex = EventPluginOrder.indexOf(pluginName);
    !(pluginIndex > -1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName) : invariant(false) : undefined;
    if (EventPluginRegistry.plugins[pluginIndex]) {
      continue;
    }
    !PluginModule.extractEvents ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName) : invariant(false) : undefined;
    EventPluginRegistry.plugins[pluginIndex] = PluginModule;
    var publishedEvents = PluginModule.eventTypes;
    for (var eventName in publishedEvents) {
      !publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : invariant(false) : undefined;
    }
  }
}

/**
 * Publishes an event so that it can be dispatched by the supplied plugin.
 *
 * @param {object} dispatchConfig Dispatch configuration for the event.
 * @param {object} PluginModule Plugin publishing the event.
 * @return {boolean} True if the event was successfully published.
 * @private
 */
function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
  !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName) : invariant(false) : undefined;
  EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;

  var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
  if (phasedRegistrationNames) {
    for (var phaseName in phasedRegistrationNames) {
      if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
        var phasedRegistrationName = phasedRegistrationNames[phaseName];
        publishRegistrationName(phasedRegistrationName, PluginModule, eventName);
      }
    }
    return true;
  } else if (dispatchConfig.registrationName) {
    publishRegistrationName(dispatchConfig.registrationName, PluginModule, eventName);
    return true;
  }
  return false;
}

/**
 * Publishes a registration name that is used to identify dispatched events and
 * can be used with `EventPluginHub.putListener` to register listeners.
 *
 * @param {string} registrationName Registration name to add.
 * @param {object} PluginModule Plugin publishing the event.
 * @private
 */
function publishRegistrationName(registrationName, PluginModule, eventName) {
  !!EventPluginRegistry.registrationNameModules[registrationName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName) : invariant(false) : undefined;
  EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
  EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies;
}

/**
 * Registers plugins so that they can extract and dispatch events.
 *
 * @see {EventPluginHub}
 */
var EventPluginRegistry = {

  /**
   * Ordered list of injected plugins.
   */
  plugins: [],

  /**
   * Mapping from event name to dispatch config
   */
  eventNameDispatchConfigs: {},

  /**
   * Mapping from registration name to plugin module
   */
  registrationNameModules: {},

  /**
   * Mapping from registration name to event name
   */
  registrationNameDependencies: {},

  /**
   * Injects an ordering of plugins (by plugin name). This allows the ordering
   * to be decoupled from injection of the actual plugins so that ordering is
   * always deterministic regardless of packaging, on-the-fly injection, etc.
   *
   * @param {array} InjectedEventPluginOrder
   * @internal
   * @see {EventPluginHub.injection.injectEventPluginOrder}
   */
  injectEventPluginOrder: function (InjectedEventPluginOrder) {
    !!EventPluginOrder ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + 'once. You are likely trying to load more than one copy of React.') : invariant(false) : undefined;
    // Clone the ordering so it cannot be dynamically mutated.
    EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
    recomputePluginOrdering();
  },

  /**
   * Injects plugins to be used by `EventPluginHub`. The plugin names must be
   * in the ordering injected by `injectEventPluginOrder`.
   *
   * Plugins can be injected as part of page initialization or on-the-fly.
   *
   * @param {object} injectedNamesToPlugins Map from names to plugin modules.
   * @internal
   * @see {EventPluginHub.injection.injectEventPluginsByName}
   */
  injectEventPluginsByName: function (injectedNamesToPlugins) {
    var isOrderingDirty = false;
    for (var pluginName in injectedNamesToPlugins) {
      if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
        continue;
      }
      var PluginModule = injectedNamesToPlugins[pluginName];
      if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== PluginModule) {
        !!namesToPlugins[pluginName] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName) : invariant(false) : undefined;
        namesToPlugins[pluginName] = PluginModule;
        isOrderingDirty = true;
      }
    }
    if (isOrderingDirty) {
      recomputePluginOrdering();
    }
  },

  /**
   * Looks up the plugin for the supplied event.
   *
   * @param {object} event A synthetic event.
   * @return {?object} The plugin that created the supplied event.
   * @internal
   */
  getPluginModuleForEvent: function (event) {
    var dispatchConfig = event.dispatchConfig;
    if (dispatchConfig.registrationName) {
      return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null;
    }
    for (var phase in dispatchConfig.phasedRegistrationNames) {
      if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
        continue;
      }
      var PluginModule = EventPluginRegistry.registrationNameModules[dispatchConfig.phasedRegistrationNames[phase]];
      if (PluginModule) {
        return PluginModule;
      }
    }
    return null;
  },

  /**
   * Exposed for unit testing.
   * @private
   */
  _resetEventPlugins: function () {
    EventPluginOrder = null;
    for (var pluginName in namesToPlugins) {
      if (namesToPlugins.hasOwnProperty(pluginName)) {
        delete namesToPlugins[pluginName];
      }
    }
    EventPluginRegistry.plugins.length = 0;

    var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
    for (var eventName in eventNameDispatchConfigs) {
      if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
        delete eventNameDispatchConfigs[eventName];
      }
    }

    var registrationNameModules = EventPluginRegistry.registrationNameModules;
    for (var registrationName in registrationNameModules) {
      if (registrationNameModules.hasOwnProperty(registrationName)) {
        delete registrationNameModules[registrationName];
      }
    }
  }

};

module.exports = EventPluginRegistry;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],413:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPluginUtils
 */

'use strict';

var EventConstants = require('./EventConstants');
var ReactErrorUtils = require('./ReactErrorUtils');

var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

/**
 * Injected dependencies:
 */

/**
 * - `Mount`: [required] Module that can convert between React dom IDs and
 *   actual node references.
 */
var injection = {
  Mount: null,
  injectMount: function (InjectedMount) {
    injection.Mount = InjectedMount;
    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(InjectedMount && InjectedMount.getNode && InjectedMount.getID, 'EventPluginUtils.injection.injectMount(...): Injected Mount ' + 'module is missing getNode or getID.') : undefined;
    }
  }
};

var topLevelTypes = EventConstants.topLevelTypes;

function isEndish(topLevelType) {
  return topLevelType === topLevelTypes.topMouseUp || topLevelType === topLevelTypes.topTouchEnd || topLevelType === topLevelTypes.topTouchCancel;
}

function isMoveish(topLevelType) {
  return topLevelType === topLevelTypes.topMouseMove || topLevelType === topLevelTypes.topTouchMove;
}
function isStartish(topLevelType) {
  return topLevelType === topLevelTypes.topMouseDown || topLevelType === topLevelTypes.topTouchStart;
}

var validateEventDispatches;
if (process.env.NODE_ENV !== 'production') {
  validateEventDispatches = function (event) {
    var dispatchListeners = event._dispatchListeners;
    var dispatchIDs = event._dispatchIDs;

    var listenersIsArr = Array.isArray(dispatchListeners);
    var idsIsArr = Array.isArray(dispatchIDs);
    var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
    var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;

    process.env.NODE_ENV !== 'production' ? warning(idsIsArr === listenersIsArr && IDsLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : undefined;
  };
}

/**
 * Dispatch the event to the listener.
 * @param {SyntheticEvent} event SyntheticEvent to handle
 * @param {boolean} simulated If the event is simulated (changes exn behavior)
 * @param {function} listener Application-level callback
 * @param {string} domID DOM id to pass to the callback.
 */
function executeDispatch(event, simulated, listener, domID) {
  var type = event.type || 'unknown-event';
  event.currentTarget = injection.Mount.getNode(domID);
  if (simulated) {
    ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event, domID);
  } else {
    ReactErrorUtils.invokeGuardedCallback(type, listener, event, domID);
  }
  event.currentTarget = null;
}

/**
 * Standard/simple iteration through an event's collected dispatches.
 */
function executeDispatchesInOrder(event, simulated) {
  var dispatchListeners = event._dispatchListeners;
  var dispatchIDs = event._dispatchIDs;
  if (process.env.NODE_ENV !== 'production') {
    validateEventDispatches(event);
  }
  if (Array.isArray(dispatchListeners)) {
    for (var i = 0; i < dispatchListeners.length; i++) {
      if (event.isPropagationStopped()) {
        break;
      }
      // Listeners and IDs are two parallel arrays that are always in sync.
      executeDispatch(event, simulated, dispatchListeners[i], dispatchIDs[i]);
    }
  } else if (dispatchListeners) {
    executeDispatch(event, simulated, dispatchListeners, dispatchIDs);
  }
  event._dispatchListeners = null;
  event._dispatchIDs = null;
}

/**
 * Standard/simple iteration through an event's collected dispatches, but stops
 * at the first dispatch execution returning true, and returns that id.
 *
 * @return {?string} id of the first dispatch execution who's listener returns
 * true, or null if no listener returned true.
 */
function executeDispatchesInOrderStopAtTrueImpl(event) {
  var dispatchListeners = event._dispatchListeners;
  var dispatchIDs = event._dispatchIDs;
  if (process.env.NODE_ENV !== 'production') {
    validateEventDispatches(event);
  }
  if (Array.isArray(dispatchListeners)) {
    for (var i = 0; i < dispatchListeners.length; i++) {
      if (event.isPropagationStopped()) {
        break;
      }
      // Listeners and IDs are two parallel arrays that are always in sync.
      if (dispatchListeners[i](event, dispatchIDs[i])) {
        return dispatchIDs[i];
      }
    }
  } else if (dispatchListeners) {
    if (dispatchListeners(event, dispatchIDs)) {
      return dispatchIDs;
    }
  }
  return null;
}

/**
 * @see executeDispatchesInOrderStopAtTrueImpl
 */
function executeDispatchesInOrderStopAtTrue(event) {
  var ret = executeDispatchesInOrderStopAtTrueImpl(event);
  event._dispatchIDs = null;
  event._dispatchListeners = null;
  return ret;
}

/**
 * Execution of a "direct" dispatch - there must be at most one dispatch
 * accumulated on the event or it is considered an error. It doesn't really make
 * sense for an event with multiple dispatches (bubbled) to keep track of the
 * return values at each dispatch execution, but it does tend to make sense when
 * dealing with "direct" dispatches.
 *
 * @return {*} The return value of executing the single dispatch.
 */
function executeDirectDispatch(event) {
  if (process.env.NODE_ENV !== 'production') {
    validateEventDispatches(event);
  }
  var dispatchListener = event._dispatchListeners;
  var dispatchID = event._dispatchIDs;
  !!Array.isArray(dispatchListener) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : invariant(false) : undefined;
  var res = dispatchListener ? dispatchListener(event, dispatchID) : null;
  event._dispatchListeners = null;
  event._dispatchIDs = null;
  return res;
}

/**
 * @param {SyntheticEvent} event
 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
 */
function hasDispatches(event) {
  return !!event._dispatchListeners;
}

/**
 * General utilities that are useful in creating custom Event Plugins.
 */
var EventPluginUtils = {
  isEndish: isEndish,
  isMoveish: isMoveish,
  isStartish: isStartish,

  executeDirectDispatch: executeDirectDispatch,
  executeDispatchesInOrder: executeDispatchesInOrder,
  executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
  hasDispatches: hasDispatches,

  getNode: function (id) {
    return injection.Mount.getNode(id);
  },
  getID: function (node) {
    return injection.Mount.getID(node);
  },

  injection: injection
};

module.exports = EventPluginUtils;
}).call(this,require('_process'))

},{"./EventConstants":410,"./ReactErrorUtils":452,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],414:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule EventPropagators
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPluginHub = require('./EventPluginHub');

var warning = require('fbjs/lib/warning');

var accumulateInto = require('./accumulateInto');
var forEachAccumulated = require('./forEachAccumulated');

var PropagationPhases = EventConstants.PropagationPhases;
var getListener = EventPluginHub.getListener;

/**
 * Some event types have a notion of different registration names for different
 * "phases" of propagation. This finds listeners by a given phase.
 */
function listenerAtPhase(id, event, propagationPhase) {
  var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
  return getListener(id, registrationName);
}

/**
 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
 * here, allows us to not have to bind or create functions for each event.
 * Mutating the event's members allows us to not have to create a wrapping
 * "dispatch" object that pairs the event with the listener.
 */
function accumulateDirectionalDispatches(domID, upwards, event) {
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(domID, 'Dispatching id must not be null') : undefined;
  }
  var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
  var listener = listenerAtPhase(domID, event, phase);
  if (listener) {
    event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
    event._dispatchIDs = accumulateInto(event._dispatchIDs, domID);
  }
}

/**
 * Collect dispatches (must be entirely collected before dispatching - see unit
 * tests). Lazily allocate the array to conserve memory.  We must loop through
 * each event and perform the traversal for each one. We cannot perform a
 * single traversal for the entire collection of events because each event may
 * have a different target.
 */
function accumulateTwoPhaseDispatchesSingle(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(event.dispatchMarker, accumulateDirectionalDispatches, event);
  }
}

/**
 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
 */
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
  if (event && event.dispatchConfig.phasedRegistrationNames) {
    EventPluginHub.injection.getInstanceHandle().traverseTwoPhaseSkipTarget(event.dispatchMarker, accumulateDirectionalDispatches, event);
  }
}

/**
 * Accumulates without regard to direction, does not look for phased
 * registration names. Same as `accumulateDirectDispatchesSingle` but without
 * requiring that the `dispatchMarker` be the same as the dispatched ID.
 */
function accumulateDispatches(id, ignoredDirection, event) {
  if (event && event.dispatchConfig.registrationName) {
    var registrationName = event.dispatchConfig.registrationName;
    var listener = getListener(id, registrationName);
    if (listener) {
      event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
      event._dispatchIDs = accumulateInto(event._dispatchIDs, id);
    }
  }
}

/**
 * Accumulates dispatches on an `SyntheticEvent`, but only for the
 * `dispatchMarker`.
 * @param {SyntheticEvent} event
 */
function accumulateDirectDispatchesSingle(event) {
  if (event && event.dispatchConfig.registrationName) {
    accumulateDispatches(event.dispatchMarker, null, event);
  }
}

function accumulateTwoPhaseDispatches(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
}

function accumulateTwoPhaseDispatchesSkipTarget(events) {
  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
}

function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
  EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(fromID, toID, accumulateDispatches, leave, enter);
}

function accumulateDirectDispatches(events) {
  forEachAccumulated(events, accumulateDirectDispatchesSingle);
}

/**
 * A small set of propagation patterns, each of which will accept a small amount
 * of information, and generate a set of "dispatch ready event objects" - which
 * are sets of events that have already been annotated with a set of dispatched
 * listener functions/ids. The API is designed this way to discourage these
 * propagation strategies from actually executing the dispatches, since we
 * always want to collect the entire set of dispatches before executing event a
 * single one.
 *
 * @constructor EventPropagators
 */
var EventPropagators = {
  accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
  accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
  accumulateDirectDispatches: accumulateDirectDispatches,
  accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
};

module.exports = EventPropagators;
}).call(this,require('_process'))

},{"./EventConstants":410,"./EventPluginHub":411,"./accumulateInto":498,"./forEachAccumulated":506,"_process":334,"fbjs/lib/warning":329}],415:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule FallbackCompositionState
 * @typechecks static-only
 */

'use strict';

var PooledClass = require('./PooledClass');

var assign = require('./Object.assign');
var getTextContentAccessor = require('./getTextContentAccessor');

/**
 * This helper class stores information about text content of a target node,
 * allowing comparison of content before and after a given event.
 *
 * Identify the node where selection currently begins, then observe
 * both its text content and its current position in the DOM. Since the
 * browser may natively replace the target node during composition, we can
 * use its position to find its replacement.
 *
 * @param {DOMEventTarget} root
 */
function FallbackCompositionState(root) {
  this._root = root;
  this._startText = this.getText();
  this._fallbackText = null;
}

assign(FallbackCompositionState.prototype, {
  destructor: function () {
    this._root = null;
    this._startText = null;
    this._fallbackText = null;
  },

  /**
   * Get current text of input.
   *
   * @return {string}
   */
  getText: function () {
    if ('value' in this._root) {
      return this._root.value;
    }
    return this._root[getTextContentAccessor()];
  },

  /**
   * Determine the differing substring between the initially stored
   * text content and the current content.
   *
   * @return {string}
   */
  getData: function () {
    if (this._fallbackText) {
      return this._fallbackText;
    }

    var start;
    var startValue = this._startText;
    var startLength = startValue.length;
    var end;
    var endValue = this.getText();
    var endLength = endValue.length;

    for (start = 0; start < startLength; start++) {
      if (startValue[start] !== endValue[start]) {
        break;
      }
    }

    var minEnd = startLength - start;
    for (end = 1; end <= minEnd; end++) {
      if (startValue[startLength - end] !== endValue[endLength - end]) {
        break;
      }
    }

    var sliceTail = end > 1 ? 1 - end : undefined;
    this._fallbackText = endValue.slice(start, sliceTail);
    return this._fallbackText;
  }
});

PooledClass.addPoolingTo(FallbackCompositionState);

module.exports = FallbackCompositionState;
},{"./Object.assign":418,"./PooledClass":419,"./getTextContentAccessor":513}],416:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule HTMLDOMPropertyConfig
 */

'use strict';

var DOMProperty = require('./DOMProperty');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;
var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;

var hasSVG;
if (ExecutionEnvironment.canUseDOM) {
  var implementation = document.implementation;
  hasSVG = implementation && implementation.hasFeature && implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1');
}

var HTMLDOMPropertyConfig = {
  isCustomAttribute: RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),
  Properties: {
    /**
     * Standard Properties
     */
    accept: null,
    acceptCharset: null,
    accessKey: null,
    action: null,
    allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    allowTransparency: MUST_USE_ATTRIBUTE,
    alt: null,
    async: HAS_BOOLEAN_VALUE,
    autoComplete: null,
    // autoFocus is polyfilled/normalized by AutoFocusUtils
    // autoFocus: HAS_BOOLEAN_VALUE,
    autoPlay: HAS_BOOLEAN_VALUE,
    capture: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    cellPadding: null,
    cellSpacing: null,
    charSet: MUST_USE_ATTRIBUTE,
    challenge: MUST_USE_ATTRIBUTE,
    checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    classID: MUST_USE_ATTRIBUTE,
    // To set className on SVG elements, it's necessary to use .setAttribute;
    // this works on HTML elements too in all browsers except IE8. Conveniently,
    // IE8 doesn't support SVG and so we can simply use the attribute in
    // browsers that support SVG and the property in browsers that don't,
    // regardless of whether the element is HTML or SVG.
    className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY,
    cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
    colSpan: null,
    content: null,
    contentEditable: null,
    contextMenu: MUST_USE_ATTRIBUTE,
    controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    coords: null,
    crossOrigin: null,
    data: null, // For `<object />` acts as `src`.
    dateTime: MUST_USE_ATTRIBUTE,
    'default': HAS_BOOLEAN_VALUE,
    defer: HAS_BOOLEAN_VALUE,
    dir: null,
    disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    download: HAS_OVERLOADED_BOOLEAN_VALUE,
    draggable: null,
    encType: null,
    form: MUST_USE_ATTRIBUTE,
    formAction: MUST_USE_ATTRIBUTE,
    formEncType: MUST_USE_ATTRIBUTE,
    formMethod: MUST_USE_ATTRIBUTE,
    formNoValidate: HAS_BOOLEAN_VALUE,
    formTarget: MUST_USE_ATTRIBUTE,
    frameBorder: MUST_USE_ATTRIBUTE,
    headers: null,
    height: MUST_USE_ATTRIBUTE,
    hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    high: null,
    href: null,
    hrefLang: null,
    htmlFor: null,
    httpEquiv: null,
    icon: null,
    id: MUST_USE_PROPERTY,
    inputMode: MUST_USE_ATTRIBUTE,
    integrity: null,
    is: MUST_USE_ATTRIBUTE,
    keyParams: MUST_USE_ATTRIBUTE,
    keyType: MUST_USE_ATTRIBUTE,
    kind: null,
    label: null,
    lang: null,
    list: MUST_USE_ATTRIBUTE,
    loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    low: null,
    manifest: MUST_USE_ATTRIBUTE,
    marginHeight: null,
    marginWidth: null,
    max: null,
    maxLength: MUST_USE_ATTRIBUTE,
    media: MUST_USE_ATTRIBUTE,
    mediaGroup: null,
    method: null,
    min: null,
    minLength: MUST_USE_ATTRIBUTE,
    multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    name: null,
    nonce: MUST_USE_ATTRIBUTE,
    noValidate: HAS_BOOLEAN_VALUE,
    open: HAS_BOOLEAN_VALUE,
    optimum: null,
    pattern: null,
    placeholder: null,
    poster: null,
    preload: null,
    radioGroup: null,
    readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    rel: null,
    required: HAS_BOOLEAN_VALUE,
    reversed: HAS_BOOLEAN_VALUE,
    role: MUST_USE_ATTRIBUTE,
    rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
    rowSpan: null,
    sandbox: null,
    scope: null,
    scoped: HAS_BOOLEAN_VALUE,
    scrolling: null,
    seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    shape: null,
    size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
    sizes: MUST_USE_ATTRIBUTE,
    span: HAS_POSITIVE_NUMERIC_VALUE,
    spellCheck: null,
    src: null,
    srcDoc: MUST_USE_PROPERTY,
    srcLang: null,
    srcSet: MUST_USE_ATTRIBUTE,
    start: HAS_NUMERIC_VALUE,
    step: null,
    style: null,
    summary: null,
    tabIndex: null,
    target: null,
    title: null,
    type: null,
    useMap: null,
    value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,
    width: MUST_USE_ATTRIBUTE,
    wmode: MUST_USE_ATTRIBUTE,
    wrap: null,

    /**
     * RDFa Properties
     */
    about: MUST_USE_ATTRIBUTE,
    datatype: MUST_USE_ATTRIBUTE,
    inlist: MUST_USE_ATTRIBUTE,
    prefix: MUST_USE_ATTRIBUTE,
    // property is also supported for OpenGraph in meta tags.
    property: MUST_USE_ATTRIBUTE,
    resource: MUST_USE_ATTRIBUTE,
    'typeof': MUST_USE_ATTRIBUTE,
    vocab: MUST_USE_ATTRIBUTE,

    /**
     * Non-standard Properties
     */
    // autoCapitalize and autoCorrect are supported in Mobile Safari for
    // keyboard hints.
    autoCapitalize: MUST_USE_ATTRIBUTE,
    autoCorrect: MUST_USE_ATTRIBUTE,
    // autoSave allows WebKit/Blink to persist values of input fields on page reloads
    autoSave: null,
    // color is for Safari mask-icon link
    color: null,
    // itemProp, itemScope, itemType are for
    // Microdata support. See http://schema.org/docs/gs.html
    itemProp: MUST_USE_ATTRIBUTE,
    itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
    itemType: MUST_USE_ATTRIBUTE,
    // itemID and itemRef are for Microdata support as well but
    // only specified in the the WHATWG spec document. See
    // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api
    itemID: MUST_USE_ATTRIBUTE,
    itemRef: MUST_USE_ATTRIBUTE,
    // results show looking glass icon and recent searches on input
    // search fields in WebKit/Blink
    results: null,
    // IE-only attribute that specifies security restrictions on an iframe
    // as an alternative to the sandbox attribute on IE<10
    security: MUST_USE_ATTRIBUTE,
    // IE-only attribute that controls focus behavior
    unselectable: MUST_USE_ATTRIBUTE
  },
  DOMAttributeNames: {
    acceptCharset: 'accept-charset',
    className: 'class',
    htmlFor: 'for',
    httpEquiv: 'http-equiv'
  },
  DOMPropertyNames: {
    autoComplete: 'autocomplete',
    autoFocus: 'autofocus',
    autoPlay: 'autoplay',
    autoSave: 'autosave',
    // `encoding` is equivalent to `enctype`, IE8 lacks an `enctype` setter.
    // http://www.w3.org/TR/html5/forms.html#dom-fs-encoding
    encType: 'encoding',
    hrefLang: 'hreflang',
    radioGroup: 'radiogroup',
    spellCheck: 'spellcheck',
    srcDoc: 'srcdoc',
    srcSet: 'srcset'
  }
};

module.exports = HTMLDOMPropertyConfig;
},{"./DOMProperty":405,"fbjs/lib/ExecutionEnvironment":304}],417:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule LinkedValueUtils
 * @typechecks static-only
 */

'use strict';

var ReactPropTypes = require('./ReactPropTypes');
var ReactPropTypeLocations = require('./ReactPropTypeLocations');

var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

var hasReadOnlyValue = {
  'button': true,
  'checkbox': true,
  'image': true,
  'hidden': true,
  'radio': true,
  'reset': true,
  'submit': true
};

function _assertSingleLink(inputProps) {
  !(inputProps.checkedLink == null || inputProps.valueLink == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use ' + 'checkedLink, you probably don\'t want to use valueLink and vice versa.') : invariant(false) : undefined;
}
function _assertValueLink(inputProps) {
  _assertSingleLink(inputProps);
  !(inputProps.value == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want ' + 'to use value or onChange, you probably don\'t want to use valueLink.') : invariant(false) : undefined;
}

function _assertCheckedLink(inputProps) {
  _assertSingleLink(inputProps);
  !(inputProps.checked == null && inputProps.onChange == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. ' + 'If you want to use checked or onChange, you probably don\'t want to ' + 'use checkedLink') : invariant(false) : undefined;
}

var propTypes = {
  value: function (props, propName, componentName) {
    if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
      return null;
    }
    return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
  },
  checked: function (props, propName, componentName) {
    if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
      return null;
    }
    return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
  },
  onChange: ReactPropTypes.func
};

var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

/**
 * Provide a linked `value` attribute for controlled forms. You should not use
 * this outside of the ReactDOM controlled form components.
 */
var LinkedValueUtils = {
  checkPropTypes: function (tagName, props, owner) {
    for (var propName in propTypes) {
      if (propTypes.hasOwnProperty(propName)) {
        var error = propTypes[propName](props, propName, tagName, ReactPropTypeLocations.prop, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
      }
      if (error instanceof Error && !(error.message in loggedTypeFailures)) {
        // Only monitor this failure once because there tends to be a lot of the
        // same error.
        loggedTypeFailures[error.message] = true;

        var addendum = getDeclarationErrorAddendum(owner);
        process.env.NODE_ENV !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : undefined;
      }
    }
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current value of the input either from value prop or link.
   */
  getValue: function (inputProps) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.value;
    }
    return inputProps.value;
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current checked status of the input either from checked prop
   *             or link.
   */
  getChecked: function (inputProps) {
    if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.value;
    }
    return inputProps.checked;
  },

  /**
   * @param {object} inputProps Props for form component
   * @param {SyntheticEvent} event change event to handle
   */
  executeOnChange: function (inputProps, event) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.requestChange(event.target.value);
    } else if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.requestChange(event.target.checked);
    } else if (inputProps.onChange) {
      return inputProps.onChange.call(undefined, event);
    }
  }
};

module.exports = LinkedValueUtils;
}).call(this,require('_process'))

},{"./ReactPropTypeLocations":469,"./ReactPropTypes":470,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],418:[function(require,module,exports){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule Object.assign
 */

// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign

'use strict';

function assign(target, sources) {
  if (target == null) {
    throw new TypeError('Object.assign target cannot be null or undefined');
  }

  var to = Object(target);
  var hasOwnProperty = Object.prototype.hasOwnProperty;

  for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) {
    var nextSource = arguments[nextIndex];
    if (nextSource == null) {
      continue;
    }

    var from = Object(nextSource);

    // We don't currently support accessors nor proxies. Therefore this
    // copy cannot throw. If we ever supported this then we must handle
    // exceptions and side-effects. We don't support symbols so they won't
    // be transferred.

    for (var key in from) {
      if (hasOwnProperty.call(from, key)) {
        to[key] = from[key];
      }
    }
  }

  return to;
}

module.exports = assign;
},{}],419:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule PooledClass
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 * Static poolers. Several custom versions for each potential number of
 * arguments. A completely generic pooler is easy to implement, but would
 * require accessing the `arguments` object. In each of these, `this` refers to
 * the Class itself, not an instance. If any others are needed, simply add them
 * here, or in their own files.
 */
var oneArgumentPooler = function (copyFieldsFrom) {
  var Klass = this;
  if (Klass.instancePool.length) {
    var instance = Klass.instancePool.pop();
    Klass.call(instance, copyFieldsFrom);
    return instance;
  } else {
    return new Klass(copyFieldsFrom);
  }
};

var twoArgumentPooler = function (a1, a2) {
  var Klass = this;
  if (Klass.instancePool.length) {
    var instance = Klass.instancePool.pop();
    Klass.call(instance, a1, a2);
    return instance;
  } else {
    return new Klass(a1, a2);
  }
};

var threeArgumentPooler = function (a1, a2, a3) {
  var Klass = this;
  if (Klass.instancePool.length) {
    var instance = Klass.instancePool.pop();
    Klass.call(instance, a1, a2, a3);
    return instance;
  } else {
    return new Klass(a1, a2, a3);
  }
};

var fourArgumentPooler = function (a1, a2, a3, a4) {
  var Klass = this;
  if (Klass.instancePool.length) {
    var instance = Klass.instancePool.pop();
    Klass.call(instance, a1, a2, a3, a4);
    return instance;
  } else {
    return new Klass(a1, a2, a3, a4);
  }
};

var fiveArgumentPooler = function (a1, a2, a3, a4, a5) {
  var Klass = this;
  if (Klass.instancePool.length) {
    var instance = Klass.instancePool.pop();
    Klass.call(instance, a1, a2, a3, a4, a5);
    return instance;
  } else {
    return new Klass(a1, a2, a3, a4, a5);
  }
};

var standardReleaser = function (instance) {
  var Klass = this;
  !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : invariant(false) : undefined;
  instance.destructor();
  if (Klass.instancePool.length < Klass.poolSize) {
    Klass.instancePool.push(instance);
  }
};

var DEFAULT_POOL_SIZE = 10;
var DEFAULT_POOLER = oneArgumentPooler;

/**
 * Augments `CopyConstructor` to be a poolable class, augmenting only the class
 * itself (statically) not adding any prototypical fields. Any CopyConstructor
 * you give this may have a `poolSize` property, and will look for a
 * prototypical `destructor` on instances (optional).
 *
 * @param {Function} CopyConstructor Constructor that can be used to reset.
 * @param {Function} pooler Customizable pooler.
 */
var addPoolingTo = function (CopyConstructor, pooler) {
  var NewKlass = CopyConstructor;
  NewKlass.instancePool = [];
  NewKlass.getPooled = pooler || DEFAULT_POOLER;
  if (!NewKlass.poolSize) {
    NewKlass.poolSize = DEFAULT_POOL_SIZE;
  }
  NewKlass.release = standardReleaser;
  return NewKlass;
};

var PooledClass = {
  addPoolingTo: addPoolingTo,
  oneArgumentPooler: oneArgumentPooler,
  twoArgumentPooler: twoArgumentPooler,
  threeArgumentPooler: threeArgumentPooler,
  fourArgumentPooler: fourArgumentPooler,
  fiveArgumentPooler: fiveArgumentPooler
};

module.exports = PooledClass;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],420:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule React
 */

'use strict';

var ReactDOM = require('./ReactDOM');
var ReactDOMServer = require('./ReactDOMServer');
var ReactIsomorphic = require('./ReactIsomorphic');

var assign = require('./Object.assign');
var deprecated = require('./deprecated');

// `version` will be added here by ReactIsomorphic.
var React = {};

assign(React, ReactIsomorphic);

assign(React, {
  // ReactDOM
  findDOMNode: deprecated('findDOMNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.findDOMNode),
  render: deprecated('render', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.render),
  unmountComponentAtNode: deprecated('unmountComponentAtNode', 'ReactDOM', 'react-dom', ReactDOM, ReactDOM.unmountComponentAtNode),

  // ReactDOMServer
  renderToString: deprecated('renderToString', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToString),
  renderToStaticMarkup: deprecated('renderToStaticMarkup', 'ReactDOMServer', 'react-dom/server', ReactDOMServer, ReactDOMServer.renderToStaticMarkup)
});

React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOM;
React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOMServer;

module.exports = React;
},{"./Object.assign":418,"./ReactDOM":431,"./ReactDOMServer":441,"./ReactIsomorphic":459,"./deprecated":502}],421:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactBrowserComponentMixin
 */

'use strict';

var ReactInstanceMap = require('./ReactInstanceMap');

var findDOMNode = require('./findDOMNode');
var warning = require('fbjs/lib/warning');

var didWarnKey = '_getDOMNodeDidWarn';

var ReactBrowserComponentMixin = {
  /**
   * Returns the DOM node rendered by this component.
   *
   * @return {DOMElement} The root node of this component.
   * @final
   * @protected
   */
  getDOMNode: function () {
    process.env.NODE_ENV !== 'production' ? warning(this.constructor[didWarnKey], '%s.getDOMNode(...) is deprecated. Please use ' + 'ReactDOM.findDOMNode(instance) instead.', ReactInstanceMap.get(this).getName() || this.tagName || 'Unknown') : undefined;
    this.constructor[didWarnKey] = true;
    return findDOMNode(this);
  }
};

module.exports = ReactBrowserComponentMixin;
}).call(this,require('_process'))

},{"./ReactInstanceMap":458,"./findDOMNode":504,"_process":334,"fbjs/lib/warning":329}],422:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactBrowserEventEmitter
 * @typechecks static-only
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPluginHub = require('./EventPluginHub');
var EventPluginRegistry = require('./EventPluginRegistry');
var ReactEventEmitterMixin = require('./ReactEventEmitterMixin');
var ReactPerf = require('./ReactPerf');
var ViewportMetrics = require('./ViewportMetrics');

var assign = require('./Object.assign');
var isEventSupported = require('./isEventSupported');

/**
 * Summary of `ReactBrowserEventEmitter` event handling:
 *
 *  - Top-level delegation is used to trap most native browser events. This
 *    may only occur in the main thread and is the responsibility of
 *    ReactEventListener, which is injected and can therefore support pluggable
 *    event sources. This is the only work that occurs in the main thread.
 *
 *  - We normalize and de-duplicate events to account for browser quirks. This
 *    may be done in the worker thread.
 *
 *  - Forward these native events (with the associated top-level type used to
 *    trap it) to `EventPluginHub`, which in turn will ask plugins if they want
 *    to extract any synthetic events.
 *
 *  - The `EventPluginHub` will then process each event by annotating them with
 *    "dispatches", a sequence of listeners and IDs that care about that event.
 *
 *  - The `EventPluginHub` then dispatches the events.
 *
 * Overview of React and the event system:
 *
 * +------------+    .
 * |    DOM     |    .
 * +------------+    .
 *       |           .
 *       v           .
 * +------------+    .
 * | ReactEvent |    .
 * |  Listener  |    .
 * +------------+    .                         +-----------+
 *       |           .               +--------+|SimpleEvent|
 *       |           .               |         |Plugin     |
 * +-----|------+    .               v         +-----------+
 * |     |      |    .    +--------------+                    +------------+
 * |     +-----------.--->|EventPluginHub|                    |    Event   |
 * |            |    .    |              |     +-----------+  | Propagators|
 * | ReactEvent |    .    |              |     |TapEvent   |  |------------|
 * |  Emitter   |    .    |              |<---+|Plugin     |  |other plugin|
 * |            |    .    |              |     +-----------+  |  utilities |
 * |     +-----------.--->|              |                    +------------+
 * |     |      |    .    +--------------+
 * +-----|------+    .                ^        +-----------+
 *       |           .                |        |Enter/Leave|
 *       +           .                +-------+|Plugin     |
 * +-------------+   .                         +-----------+
 * | application |   .
 * |-------------|   .
 * |             |   .
 * |             |   .
 * +-------------+   .
 *                   .
 *    React Core     .  General Purpose Event Plugin System
 */

var alreadyListeningTo = {};
var isMonitoringScrollValue = false;
var reactTopListenersCounter = 0;

// For events like 'submit' which don't consistently bubble (which we trap at a
// lower node than `document`), binding at `document` would cause duplicate
// events so we don't include them here
var topEventMapping = {
  topAbort: 'abort',
  topBlur: 'blur',
  topCanPlay: 'canplay',
  topCanPlayThrough: 'canplaythrough',
  topChange: 'change',
  topClick: 'click',
  topCompositionEnd: 'compositionend',
  topCompositionStart: 'compositionstart',
  topCompositionUpdate: 'compositionupdate',
  topContextMenu: 'contextmenu',
  topCopy: 'copy',
  topCut: 'cut',
  topDoubleClick: 'dblclick',
  topDrag: 'drag',
  topDragEnd: 'dragend',
  topDragEnter: 'dragenter',
  topDragExit: 'dragexit',
  topDragLeave: 'dragleave',
  topDragOver: 'dragover',
  topDragStart: 'dragstart',
  topDrop: 'drop',
  topDurationChange: 'durationchange',
  topEmptied: 'emptied',
  topEncrypted: 'encrypted',
  topEnded: 'ended',
  topError: 'error',
  topFocus: 'focus',
  topInput: 'input',
  topKeyDown: 'keydown',
  topKeyPress: 'keypress',
  topKeyUp: 'keyup',
  topLoadedData: 'loadeddata',
  topLoadedMetadata: 'loadedmetadata',
  topLoadStart: 'loadstart',
  topMouseDown: 'mousedown',
  topMouseMove: 'mousemove',
  topMouseOut: 'mouseout',
  topMouseOver: 'mouseover',
  topMouseUp: 'mouseup',
  topPaste: 'paste',
  topPause: 'pause',
  topPlay: 'play',
  topPlaying: 'playing',
  topProgress: 'progress',
  topRateChange: 'ratechange',
  topScroll: 'scroll',
  topSeeked: 'seeked',
  topSeeking: 'seeking',
  topSelectionChange: 'selectionchange',
  topStalled: 'stalled',
  topSuspend: 'suspend',
  topTextInput: 'textInput',
  topTimeUpdate: 'timeupdate',
  topTouchCancel: 'touchcancel',
  topTouchEnd: 'touchend',
  topTouchMove: 'touchmove',
  topTouchStart: 'touchstart',
  topVolumeChange: 'volumechange',
  topWaiting: 'waiting',
  topWheel: 'wheel'
};

/**
 * To ensure no conflicts with other potential React instances on the page
 */
var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2);

function getListeningForDocument(mountAt) {
  // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
  // directly.
  if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
    mountAt[topListenersIDKey] = reactTopListenersCounter++;
    alreadyListeningTo[mountAt[topListenersIDKey]] = {};
  }
  return alreadyListeningTo[mountAt[topListenersIDKey]];
}

/**
 * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For
 * example:
 *
 *   ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction);
 *
 * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
 *
 * @internal
 */
var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, {

  /**
   * Injectable event backend
   */
  ReactEventListener: null,

  injection: {
    /**
     * @param {object} ReactEventListener
     */
    injectReactEventListener: function (ReactEventListener) {
      ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel);
      ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
    }
  },

  /**
   * Sets whether or not any created callbacks should be enabled.
   *
   * @param {boolean} enabled True if callbacks should be enabled.
   */
  setEnabled: function (enabled) {
    if (ReactBrowserEventEmitter.ReactEventListener) {
      ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);
    }
  },

  /**
   * @return {boolean} True if callbacks are enabled.
   */
  isEnabled: function () {
    return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled());
  },

  /**
   * We listen for bubbled touch events on the document object.
   *
   * Firefox v8.01 (and possibly others) exhibited strange behavior when
   * mounting `onmousemove` events at some node that was not the document
   * element. The symptoms were that if your mouse is not moving over something
   * contained within that mount point (for example on the background) the
   * top-level listeners for `onmousemove` won't be called. However, if you
   * register the `mousemove` on the document object, then it will of course
   * catch all `mousemove`s. This along with iOS quirks, justifies restricting
   * top-level listeners to the document object only, at least for these
   * movement types of events and possibly all events.
   *
   * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
   *
   * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
   * they bubble to document.
   *
   * @param {string} registrationName Name of listener (e.g. `onClick`).
   * @param {object} contentDocumentHandle Document which owns the container
   */
  listenTo: function (registrationName, contentDocumentHandle) {
    var mountAt = contentDocumentHandle;
    var isListening = getListeningForDocument(mountAt);
    var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName];

    var topLevelTypes = EventConstants.topLevelTypes;
    for (var i = 0; i < dependencies.length; i++) {
      var dependency = dependencies[i];
      if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
        if (dependency === topLevelTypes.topWheel) {
          if (isEventSupported('wheel')) {
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);
          } else if (isEventSupported('mousewheel')) {
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);
          } else {
            // Firefox needs to capture a different mouse scroll event.
            // @see http://www.quirksmode.org/dom/events/tests/scroll.html
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt);
          }
        } else if (dependency === topLevelTypes.topScroll) {

          if (isEventSupported('scroll', true)) {
            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
          } else {
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topScroll, 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE);
          }
        } else if (dependency === topLevelTypes.topFocus || dependency === topLevelTypes.topBlur) {

          if (isEventSupported('focus', true)) {
            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
            ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
          } else if (isEventSupported('focusin')) {
            // IE has `focusin` and `focusout` events which bubble.
            // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
            ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
          }

          // to make sure blur and focus event listeners are only attached once
          isListening[topLevelTypes.topBlur] = true;
          isListening[topLevelTypes.topFocus] = true;
        } else if (topEventMapping.hasOwnProperty(dependency)) {
          ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt);
        }

        isListening[dependency] = true;
      }
    }
  },

  trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {
    return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle);
  },

  trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {
    return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle);
  },

  /**
   * Listens to window scroll and resize events. We cache scroll values so that
   * application code can access them without triggering reflows.
   *
   * NOTE: Scroll events do not bubble.
   *
   * @see http://www.quirksmode.org/dom/events/scroll.html
   */
  ensureScrollValueMonitoring: function () {
    if (!isMonitoringScrollValue) {
      var refresh = ViewportMetrics.refreshScrollValues;
      ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);
      isMonitoringScrollValue = true;
    }
  },

  eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,

  registrationNameModules: EventPluginHub.registrationNameModules,

  putListener: EventPluginHub.putListener,

  getListener: EventPluginHub.getListener,

  deleteListener: EventPluginHub.deleteListener,

  deleteAllListeners: EventPluginHub.deleteAllListeners

});

ReactPerf.measureMethods(ReactBrowserEventEmitter, 'ReactBrowserEventEmitter', {
  putListener: 'putListener',
  deleteListener: 'deleteListener'
});

module.exports = ReactBrowserEventEmitter;
},{"./EventConstants":410,"./EventPluginHub":411,"./EventPluginRegistry":412,"./Object.assign":418,"./ReactEventEmitterMixin":453,"./ReactPerf":467,"./ViewportMetrics":497,"./isEventSupported":515}],423:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactChildReconciler
 * @typechecks static-only
 */

'use strict';

var ReactReconciler = require('./ReactReconciler');

var instantiateReactComponent = require('./instantiateReactComponent');
var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
var traverseAllChildren = require('./traverseAllChildren');
var warning = require('fbjs/lib/warning');

function instantiateChild(childInstances, child, name) {
  // We found a component instance.
  var keyUnique = childInstances[name] === undefined;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(keyUnique, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.', name) : undefined;
  }
  if (child != null && keyUnique) {
    childInstances[name] = instantiateReactComponent(child, null);
  }
}

/**
 * ReactChildReconciler provides helpers for initializing or updating a set of
 * children. Its output is suitable for passing it onto ReactMultiChild which
 * does diffed reordering and insertion.
 */
var ReactChildReconciler = {
  /**
   * Generates a "mount image" for each of the supplied children. In the case
   * of `ReactDOMComponent`, a mount image is a string of markup.
   *
   * @param {?object} nestedChildNodes Nested child maps.
   * @return {?object} A set of child instances.
   * @internal
   */
  instantiateChildren: function (nestedChildNodes, transaction, context) {
    if (nestedChildNodes == null) {
      return null;
    }
    var childInstances = {};
    traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);
    return childInstances;
  },

  /**
   * Updates the rendered children and returns a new set of children.
   *
   * @param {?object} prevChildren Previously initialized set of children.
   * @param {?object} nextChildren Flat child element maps.
   * @param {ReactReconcileTransaction} transaction
   * @param {object} context
   * @return {?object} A new set of child instances.
   * @internal
   */
  updateChildren: function (prevChildren, nextChildren, transaction, context) {
    // We currently don't have a way to track moves here but if we use iterators
    // instead of for..in we can zip the iterators and check if an item has
    // moved.
    // TODO: If nothing has changed, return the prevChildren object so that we
    // can quickly bailout if nothing has changed.
    if (!nextChildren && !prevChildren) {
      return null;
    }
    var name;
    for (name in nextChildren) {
      if (!nextChildren.hasOwnProperty(name)) {
        continue;
      }
      var prevChild = prevChildren && prevChildren[name];
      var prevElement = prevChild && prevChild._currentElement;
      var nextElement = nextChildren[name];
      if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {
        ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);
        nextChildren[name] = prevChild;
      } else {
        if (prevChild) {
          ReactReconciler.unmountComponent(prevChild, name);
        }
        // The child must be instantiated before it's mounted.
        var nextChildInstance = instantiateReactComponent(nextElement, null);
        nextChildren[name] = nextChildInstance;
      }
    }
    // Unmount children that are no longer present.
    for (name in prevChildren) {
      if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
        ReactReconciler.unmountComponent(prevChildren[name]);
      }
    }
    return nextChildren;
  },

  /**
   * Unmounts all rendered children. This should be used to clean up children
   * when this component is unmounted.
   *
   * @param {?object} renderedChildren Previously initialized set of children.
   * @internal
   */
  unmountChildren: function (renderedChildren) {
    for (var name in renderedChildren) {
      if (renderedChildren.hasOwnProperty(name)) {
        var renderedChild = renderedChildren[name];
        ReactReconciler.unmountComponent(renderedChild);
      }
    }
  }

};

module.exports = ReactChildReconciler;
}).call(this,require('_process'))

},{"./ReactReconciler":472,"./instantiateReactComponent":514,"./shouldUpdateReactComponent":522,"./traverseAllChildren":523,"_process":334,"fbjs/lib/warning":329}],424:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactChildren
 */

'use strict';

var PooledClass = require('./PooledClass');
var ReactElement = require('./ReactElement');

var emptyFunction = require('fbjs/lib/emptyFunction');
var traverseAllChildren = require('./traverseAllChildren');

var twoArgumentPooler = PooledClass.twoArgumentPooler;
var fourArgumentPooler = PooledClass.fourArgumentPooler;

var userProvidedKeyEscapeRegex = /\/(?!\/)/g;
function escapeUserProvidedKey(text) {
  return ('' + text).replace(userProvidedKeyEscapeRegex, '//');
}

/**
 * PooledClass representing the bookkeeping associated with performing a child
 * traversal. Allows avoiding binding callbacks.
 *
 * @constructor ForEachBookKeeping
 * @param {!function} forEachFunction Function to perform traversal with.
 * @param {?*} forEachContext Context to perform context with.
 */
function ForEachBookKeeping(forEachFunction, forEachContext) {
  this.func = forEachFunction;
  this.context = forEachContext;
  this.count = 0;
}
ForEachBookKeeping.prototype.destructor = function () {
  this.func = null;
  this.context = null;
  this.count = 0;
};
PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);

function forEachSingleChild(bookKeeping, child, name) {
  var func = bookKeeping.func;
  var context = bookKeeping.context;

  func.call(context, child, bookKeeping.count++);
}

/**
 * Iterates through children that are typically specified as `props.children`.
 *
 * The provided forEachFunc(child, index) will be called for each
 * leaf child.
 *
 * @param {?*} children Children tree container.
 * @param {function(*, int)} forEachFunc
 * @param {*} forEachContext Context for forEachContext.
 */
function forEachChildren(children, forEachFunc, forEachContext) {
  if (children == null) {
    return children;
  }
  var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
  traverseAllChildren(children, forEachSingleChild, traverseContext);
  ForEachBookKeeping.release(traverseContext);
}

/**
 * PooledClass representing the bookkeeping associated with performing a child
 * mapping. Allows avoiding binding callbacks.
 *
 * @constructor MapBookKeeping
 * @param {!*} mapResult Object containing the ordered map of results.
 * @param {!function} mapFunction Function to perform mapping with.
 * @param {?*} mapContext Context to perform mapping with.
 */
function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) {
  this.result = mapResult;
  this.keyPrefix = keyPrefix;
  this.func = mapFunction;
  this.context = mapContext;
  this.count = 0;
}
MapBookKeeping.prototype.destructor = function () {
  this.result = null;
  this.keyPrefix = null;
  this.func = null;
  this.context = null;
  this.count = 0;
};
PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler);

function mapSingleChildIntoContext(bookKeeping, child, childKey) {
  var result = bookKeeping.result;
  var keyPrefix = bookKeeping.keyPrefix;
  var func = bookKeeping.func;
  var context = bookKeeping.context;

  var mappedChild = func.call(context, child, bookKeeping.count++);
  if (Array.isArray(mappedChild)) {
    mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument);
  } else if (mappedChild != null) {
    if (ReactElement.isValidElement(mappedChild)) {
      mappedChild = ReactElement.cloneAndReplaceKey(mappedChild,
      // Keep both the (mapped) and old keys if they differ, just as
      // traverseAllChildren used to do for objects as children
      keyPrefix + (mappedChild !== child ? escapeUserProvidedKey(mappedChild.key || '') + '/' : '') + childKey);
    }
    result.push(mappedChild);
  }
}

function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {
  var escapedPrefix = '';
  if (prefix != null) {
    escapedPrefix = escapeUserProvidedKey(prefix) + '/';
  }
  var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context);
  traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
  MapBookKeeping.release(traverseContext);
}

/**
 * Maps children that are typically specified as `props.children`.
 *
 * The provided mapFunction(child, key, index) will be called for each
 * leaf child.
 *
 * @param {?*} children Children tree container.
 * @param {function(*, int)} func The map function.
 * @param {*} context Context for mapFunction.
 * @return {object} Object containing the ordered map of results.
 */
function mapChildren(children, func, context) {
  if (children == null) {
    return children;
  }
  var result = [];
  mapIntoWithKeyPrefixInternal(children, result, null, func, context);
  return result;
}

function forEachSingleChildDummy(traverseContext, child, name) {
  return null;
}

/**
 * Count the number of children that are typically specified as
 * `props.children`.
 *
 * @param {?*} children Children tree container.
 * @return {number} The number of children.
 */
function countChildren(children, context) {
  return traverseAllChildren(children, forEachSingleChildDummy, null);
}

/**
 * Flatten a children object (typically specified as `props.children`) and
 * return an array with appropriately re-keyed children.
 */
function toArray(children) {
  var result = [];
  mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument);
  return result;
}

var ReactChildren = {
  forEach: forEachChildren,
  map: mapChildren,
  mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal,
  count: countChildren,
  toArray: toArray
};

module.exports = ReactChildren;
},{"./PooledClass":419,"./ReactElement":448,"./traverseAllChildren":523,"fbjs/lib/emptyFunction":310}],425:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactClass
 */

'use strict';

var ReactComponent = require('./ReactComponent');
var ReactElement = require('./ReactElement');
var ReactPropTypeLocations = require('./ReactPropTypeLocations');
var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue');

var assign = require('./Object.assign');
var emptyObject = require('fbjs/lib/emptyObject');
var invariant = require('fbjs/lib/invariant');
var keyMirror = require('fbjs/lib/keyMirror');
var keyOf = require('fbjs/lib/keyOf');
var warning = require('fbjs/lib/warning');

var MIXINS_KEY = keyOf({ mixins: null });

/**
 * Policies that describe methods in `ReactClassInterface`.
 */
var SpecPolicy = keyMirror({
  /**
   * These methods may be defined only once by the class specification or mixin.
   */
  DEFINE_ONCE: null,
  /**
   * These methods may be defined by both the class specification and mixins.
   * Subsequent definitions will be chained. These methods must return void.
   */
  DEFINE_MANY: null,
  /**
   * These methods are overriding the base class.
   */
  OVERRIDE_BASE: null,
  /**
   * These methods are similar to DEFINE_MANY, except we assume they return
   * objects. We try to merge the keys of the return values of all the mixed in
   * functions. If there is a key conflict we throw.
   */
  DEFINE_MANY_MERGED: null
});

var injectedMixins = [];

var warnedSetProps = false;
function warnSetProps() {
  if (!warnedSetProps) {
    warnedSetProps = true;
    process.env.NODE_ENV !== 'production' ? warning(false, 'setProps(...) and replaceProps(...) are deprecated. ' + 'Instead, call render again at the top level.') : undefined;
  }
}

/**
 * Composite components are higher-level components that compose other composite
 * or native components.
 *
 * To create a new type of `ReactClass`, pass a specification of
 * your new class to `React.createClass`. The only requirement of your class
 * specification is that you implement a `render` method.
 *
 *   var MyComponent = React.createClass({
 *     render: function() {
 *       return <div>Hello World</div>;
 *     }
 *   });
 *
 * The class specification supports a specific protocol of methods that have
 * special meaning (e.g. `render`). See `ReactClassInterface` for
 * more the comprehensive protocol. Any other properties and methods in the
 * class specification will be available on the prototype.
 *
 * @interface ReactClassInterface
 * @internal
 */
var ReactClassInterface = {

  /**
   * An array of Mixin objects to include when defining your component.
   *
   * @type {array}
   * @optional
   */
  mixins: SpecPolicy.DEFINE_MANY,

  /**
   * An object containing properties and methods that should be defined on
   * the component's constructor instead of its prototype (static methods).
   *
   * @type {object}
   * @optional
   */
  statics: SpecPolicy.DEFINE_MANY,

  /**
   * Definition of prop types for this component.
   *
   * @type {object}
   * @optional
   */
  propTypes: SpecPolicy.DEFINE_MANY,

  /**
   * Definition of context types for this component.
   *
   * @type {object}
   * @optional
   */
  contextTypes: SpecPolicy.DEFINE_MANY,

  /**
   * Definition of context types this component sets for its children.
   *
   * @type {object}
   * @optional
   */
  childContextTypes: SpecPolicy.DEFINE_MANY,

  // ==== Definition methods ====

  /**
   * Invoked when the component is mounted. Values in the mapping will be set on
   * `this.props` if that prop is not specified (i.e. using an `in` check).
   *
   * This method is invoked before `getInitialState` and therefore cannot rely
   * on `this.state` or use `this.setState`.
   *
   * @return {object}
   * @optional
   */
  getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,

  /**
   * Invoked once before the component is mounted. The return value will be used
   * as the initial value of `this.state`.
   *
   *   getInitialState: function() {
   *     return {
   *       isOn: false,
   *       fooBaz: new BazFoo()
   *     }
   *   }
   *
   * @return {object}
   * @optional
   */
  getInitialState: SpecPolicy.DEFINE_MANY_MERGED,

  /**
   * @return {object}
   * @optional
   */
  getChildContext: SpecPolicy.DEFINE_MANY_MERGED,

  /**
   * Uses props from `this.props` and state from `this.state` to render the
   * structure of the component.
   *
   * No guarantees are made about when or how often this method is invoked, so
   * it must not have side effects.
   *
   *   render: function() {
   *     var name = this.props.name;
   *     return <div>Hello, {name}!</div>;
   *   }
   *
   * @return {ReactComponent}
   * @nosideeffects
   * @required
   */
  render: SpecPolicy.DEFINE_ONCE,

  // ==== Delegate methods ====

  /**
   * Invoked when the component is initially created and about to be mounted.
   * This may have side effects, but any external subscriptions or data created
   * by this method must be cleaned up in `componentWillUnmount`.
   *
   * @optional
   */
  componentWillMount: SpecPolicy.DEFINE_MANY,

  /**
   * Invoked when the component has been mounted and has a DOM representation.
   * However, there is no guarantee that the DOM node is in the document.
   *
   * Use this as an opportunity to operate on the DOM when the component has
   * been mounted (initialized and rendered) for the first time.
   *
   * @param {DOMElement} rootNode DOM element representing the component.
   * @optional
   */
  componentDidMount: SpecPolicy.DEFINE_MANY,

  /**
   * Invoked before the component receives new props.
   *
   * Use this as an opportunity to react to a prop transition by updating the
   * state using `this.setState`. Current props are accessed via `this.props`.
   *
   *   componentWillReceiveProps: function(nextProps, nextContext) {
   *     this.setState({
   *       likesIncreasing: nextProps.likeCount > this.props.likeCount
   *     });
   *   }
   *
   * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
   * transition may cause a state change, but the opposite is not true. If you
   * need it, you are probably looking for `componentWillUpdate`.
   *
   * @param {object} nextProps
   * @optional
   */
  componentWillReceiveProps: SpecPolicy.DEFINE_MANY,

  /**
   * Invoked while deciding if the component should be updated as a result of
   * receiving new props, state and/or context.
   *
   * Use this as an opportunity to `return false` when you're certain that the
   * transition to the new props/state/context will not require a component
   * update.
   *
   *   shouldComponentUpdate: function(nextProps, nextState, nextContext) {
   *     return !equal(nextProps, this.props) ||
   *       !equal(nextState, this.state) ||
   *       !equal(nextContext, this.context);
   *   }
   *
   * @param {object} nextProps
   * @param {?object} nextState
   * @param {?object} nextContext
   * @return {boolean} True if the component should update.
   * @optional
   */
  shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,

  /**
   * Invoked when the component is about to update due to a transition from
   * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
   * and `nextContext`.
   *
   * Use this as an opportunity to perform preparation before an update occurs.
   *
   * NOTE: You **cannot** use `this.setState()` in this method.
   *
   * @param {object} nextProps
   * @param {?object} nextState
   * @param {?object} nextContext
   * @param {ReactReconcileTransaction} transaction
   * @optional
   */
  componentWillUpdate: SpecPolicy.DEFINE_MANY,

  /**
   * Invoked when the component's DOM representation has been updated.
   *
   * Use this as an opportunity to operate on the DOM when the component has
   * been updated.
   *
   * @param {object} prevProps
   * @param {?object} prevState
   * @param {?object} prevContext
   * @param {DOMElement} rootNode DOM element representing the component.
   * @optional
   */
  componentDidUpdate: SpecPolicy.DEFINE_MANY,

  /**
   * Invoked when the component is about to be removed from its parent and have
   * its DOM representation destroyed.
   *
   * Use this as an opportunity to deallocate any external resources.
   *
   * NOTE: There is no `componentDidUnmount` since your component will have been
   * destroyed by that point.
   *
   * @optional
   */
  componentWillUnmount: SpecPolicy.DEFINE_MANY,

  // ==== Advanced methods ====

  /**
   * Updates the component's currently mounted DOM representation.
   *
   * By default, this implements React's rendering and reconciliation algorithm.
   * Sophisticated clients may wish to override this.
   *
   * @param {ReactReconcileTransaction} transaction
   * @internal
   * @overridable
   */
  updateComponent: SpecPolicy.OVERRIDE_BASE

};

/**
 * Mapping from class specification keys to special processing functions.
 *
 * Although these are declared like instance properties in the specification
 * when defining classes using `React.createClass`, they are actually static
 * and are accessible on the constructor instead of the prototype. Despite
 * being static, they must be defined outside of the "statics" key under
 * which all other static methods are defined.
 */
var RESERVED_SPEC_KEYS = {
  displayName: function (Constructor, displayName) {
    Constructor.displayName = displayName;
  },
  mixins: function (Constructor, mixins) {
    if (mixins) {
      for (var i = 0; i < mixins.length; i++) {
        mixSpecIntoComponent(Constructor, mixins[i]);
      }
    }
  },
  childContextTypes: function (Constructor, childContextTypes) {
    if (process.env.NODE_ENV !== 'production') {
      validateTypeDef(Constructor, childContextTypes, ReactPropTypeLocations.childContext);
    }
    Constructor.childContextTypes = assign({}, Constructor.childContextTypes, childContextTypes);
  },
  contextTypes: function (Constructor, contextTypes) {
    if (process.env.NODE_ENV !== 'production') {
      validateTypeDef(Constructor, contextTypes, ReactPropTypeLocations.context);
    }
    Constructor.contextTypes = assign({}, Constructor.contextTypes, contextTypes);
  },
  /**
   * Special case getDefaultProps which should move into statics but requires
   * automatic merging.
   */
  getDefaultProps: function (Constructor, getDefaultProps) {
    if (Constructor.getDefaultProps) {
      Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps);
    } else {
      Constructor.getDefaultProps = getDefaultProps;
    }
  },
  propTypes: function (Constructor, propTypes) {
    if (process.env.NODE_ENV !== 'production') {
      validateTypeDef(Constructor, propTypes, ReactPropTypeLocations.prop);
    }
    Constructor.propTypes = assign({}, Constructor.propTypes, propTypes);
  },
  statics: function (Constructor, statics) {
    mixStaticSpecIntoComponent(Constructor, statics);
  },
  autobind: function () {} };

// noop
function validateTypeDef(Constructor, typeDef, location) {
  for (var propName in typeDef) {
    if (typeDef.hasOwnProperty(propName)) {
      // use a warning instead of an invariant so components
      // don't show up in prod but not in __DEV__
      process.env.NODE_ENV !== 'production' ? warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName) : undefined;
    }
  }
}

function validateMethodOverride(proto, name) {
  var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null;

  // Disallow overriding of base class methods unless explicitly allowed.
  if (ReactClassMixin.hasOwnProperty(name)) {
    !(specPolicy === SpecPolicy.OVERRIDE_BASE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name) : invariant(false) : undefined;
  }

  // Disallow defining methods more than once unless explicitly allowed.
  if (proto.hasOwnProperty(name)) {
    !(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name) : invariant(false) : undefined;
  }
}

/**
 * Mixin helper which handles policy validation and reserved
 * specification keys when building React classses.
 */
function mixSpecIntoComponent(Constructor, spec) {
  if (!spec) {
    return;
  }

  !(typeof spec !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.') : invariant(false) : undefined;
  !!ReactElement.isValidElement(spec) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.') : invariant(false) : undefined;

  var proto = Constructor.prototype;

  // By handling mixins before any other properties, we ensure the same
  // chaining order is applied to methods with DEFINE_MANY policy, whether
  // mixins are listed before or after these methods in the spec.
  if (spec.hasOwnProperty(MIXINS_KEY)) {
    RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
  }

  for (var name in spec) {
    if (!spec.hasOwnProperty(name)) {
      continue;
    }

    if (name === MIXINS_KEY) {
      // We have already handled mixins in a special case above.
      continue;
    }

    var property = spec[name];
    validateMethodOverride(proto, name);

    if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
      RESERVED_SPEC_KEYS[name](Constructor, property);
    } else {
      // Setup methods on prototype:
      // The following member methods should not be automatically bound:
      // 1. Expected ReactClass methods (in the "interface").
      // 2. Overridden methods (that were mixed in).
      var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
      var isAlreadyDefined = proto.hasOwnProperty(name);
      var isFunction = typeof property === 'function';
      var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false;

      if (shouldAutoBind) {
        if (!proto.__reactAutoBindMap) {
          proto.__reactAutoBindMap = {};
        }
        proto.__reactAutoBindMap[name] = property;
        proto[name] = property;
      } else {
        if (isAlreadyDefined) {
          var specPolicy = ReactClassInterface[name];

          // These cases should already be caught by validateMethodOverride.
          !(isReactClassMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name) : invariant(false) : undefined;

          // For methods which are defined more than once, call the existing
          // methods before calling the new property, merging if appropriate.
          if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
            proto[name] = createMergedResultFunction(proto[name], property);
          } else if (specPolicy === SpecPolicy.DEFINE_MANY) {
            proto[name] = createChainedFunction(proto[name], property);
          }
        } else {
          proto[name] = property;
          if (process.env.NODE_ENV !== 'production') {
            // Add verbose displayName to the function, which helps when looking
            // at profiling tools.
            if (typeof property === 'function' && spec.displayName) {
              proto[name].displayName = spec.displayName + '_' + name;
            }
          }
        }
      }
    }
  }
}

function mixStaticSpecIntoComponent(Constructor, statics) {
  if (!statics) {
    return;
  }
  for (var name in statics) {
    var property = statics[name];
    if (!statics.hasOwnProperty(name)) {
      continue;
    }

    var isReserved = (name in RESERVED_SPEC_KEYS);
    !!isReserved ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define a reserved ' + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + 'as an instance property instead; it will still be accessible on the ' + 'constructor.', name) : invariant(false) : undefined;

    var isInherited = (name in Constructor);
    !!isInherited ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name) : invariant(false) : undefined;
    Constructor[name] = property;
  }
}

/**
 * Merge two objects, but throw if both contain the same key.
 *
 * @param {object} one The first object, which is mutated.
 * @param {object} two The second object
 * @return {object} one after it has been mutated to contain everything in two.
 */
function mergeIntoWithNoDuplicateKeys(one, two) {
  !(one && two && typeof one === 'object' && typeof two === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : invariant(false) : undefined;

  for (var key in two) {
    if (two.hasOwnProperty(key)) {
      !(one[key] === undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: `%s`. This conflict ' + 'may be due to a mixin; in particular, this may be caused by two ' + 'getInitialState() or getDefaultProps() methods returning objects ' + 'with clashing keys.', key) : invariant(false) : undefined;
      one[key] = two[key];
    }
  }
  return one;
}

/**
 * Creates a function that invokes two functions and merges their return values.
 *
 * @param {function} one Function to invoke first.
 * @param {function} two Function to invoke second.
 * @return {function} Function that invokes the two argument functions.
 * @private
 */
function createMergedResultFunction(one, two) {
  return function mergedResult() {
    var a = one.apply(this, arguments);
    var b = two.apply(this, arguments);
    if (a == null) {
      return b;
    } else if (b == null) {
      return a;
    }
    var c = {};
    mergeIntoWithNoDuplicateKeys(c, a);
    mergeIntoWithNoDuplicateKeys(c, b);
    return c;
  };
}

/**
 * Creates a function that invokes two functions and ignores their return vales.
 *
 * @param {function} one Function to invoke first.
 * @param {function} two Function to invoke second.
 * @return {function} Function that invokes the two argument functions.
 * @private
 */
function createChainedFunction(one, two) {
  return function chainedFunction() {
    one.apply(this, arguments);
    two.apply(this, arguments);
  };
}

/**
 * Binds a method to the component.
 *
 * @param {object} component Component whose method is going to be bound.
 * @param {function} method Method to be bound.
 * @return {function} The bound method.
 */
function bindAutoBindMethod(component, method) {
  var boundMethod = method.bind(component);
  if (process.env.NODE_ENV !== 'production') {
    boundMethod.__reactBoundContext = component;
    boundMethod.__reactBoundMethod = method;
    boundMethod.__reactBoundArguments = null;
    var componentName = component.constructor.displayName;
    var _bind = boundMethod.bind;
    /* eslint-disable block-scoped-var, no-undef */
    boundMethod.bind = function (newThis) {
      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      // User is trying to bind() an autobound method; we effectively will
      // ignore the value of "this" that the user is trying to use, so
      // let's warn.
      if (newThis !== component && newThis !== null) {
        process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : undefined;
      } else if (!args.length) {
        process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName) : undefined;
        return boundMethod;
      }
      var reboundMethod = _bind.apply(boundMethod, arguments);
      reboundMethod.__reactBoundContext = component;
      reboundMethod.__reactBoundMethod = method;
      reboundMethod.__reactBoundArguments = args;
      return reboundMethod;
      /* eslint-enable */
    };
  }
  return boundMethod;
}

/**
 * Binds all auto-bound methods in a component.
 *
 * @param {object} component Component whose method is going to be bound.
 */
function bindAutoBindMethods(component) {
  for (var autoBindKey in component.__reactAutoBindMap) {
    if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
      var method = component.__reactAutoBindMap[autoBindKey];
      component[autoBindKey] = bindAutoBindMethod(component, method);
    }
  }
}

/**
 * Add more to the ReactClass base class. These are all legacy features and
 * therefore not already part of the modern ReactComponent.
 */
var ReactClassMixin = {

  /**
   * TODO: This will be deprecated because state should always keep a consistent
   * type signature and the only use case for this, is to avoid that.
   */
  replaceState: function (newState, callback) {
    this.updater.enqueueReplaceState(this, newState);
    if (callback) {
      this.updater.enqueueCallback(this, callback);
    }
  },

  /**
   * Checks whether or not this composite component is mounted.
   * @return {boolean} True if mounted, false otherwise.
   * @protected
   * @final
   */
  isMounted: function () {
    return this.updater.isMounted(this);
  },

  /**
   * Sets a subset of the props.
   *
   * @param {object} partialProps Subset of the next props.
   * @param {?function} callback Called after props are updated.
   * @final
   * @public
   * @deprecated
   */
  setProps: function (partialProps, callback) {
    if (process.env.NODE_ENV !== 'production') {
      warnSetProps();
    }
    this.updater.enqueueSetProps(this, partialProps);
    if (callback) {
      this.updater.enqueueCallback(this, callback);
    }
  },

  /**
   * Replace all the props.
   *
   * @param {object} newProps Subset of the next props.
   * @param {?function} callback Called after props are updated.
   * @final
   * @public
   * @deprecated
   */
  replaceProps: function (newProps, callback) {
    if (process.env.NODE_ENV !== 'production') {
      warnSetProps();
    }
    this.updater.enqueueReplaceProps(this, newProps);
    if (callback) {
      this.updater.enqueueCallback(this, callback);
    }
  }
};

var ReactClassComponent = function () {};
assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin);

/**
 * Module for creating composite components.
 *
 * @class ReactClass
 */
var ReactClass = {

  /**
   * Creates a composite component class given a class specification.
   *
   * @param {object} spec Class specification (which must define `render`).
   * @return {function} Component constructor function.
   * @public
   */
  createClass: function (spec) {
    var Constructor = function (props, context, updater) {
      // This constructor is overridden by mocks. The argument is used
      // by mocks to assert on what gets mounted.

      if (process.env.NODE_ENV !== 'production') {
        process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : undefined;
      }

      // Wire up auto-binding
      if (this.__reactAutoBindMap) {
        bindAutoBindMethods(this);
      }

      this.props = props;
      this.context = context;
      this.refs = emptyObject;
      this.updater = updater || ReactNoopUpdateQueue;

      this.state = null;

      // ReactClasses doesn't have constructors. Instead, they use the
      // getInitialState and componentWillMount methods for initialization.

      var initialState = this.getInitialState ? this.getInitialState() : null;
      if (process.env.NODE_ENV !== 'production') {
        // We allow auto-mocks to proceed as if they're returning null.
        if (typeof initialState === 'undefined' && this.getInitialState._isMockFunction) {
          // This is probably bad practice. Consider warning here and
          // deprecating this convenience.
          initialState = null;
        }
      }
      !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : invariant(false) : undefined;

      this.state = initialState;
    };
    Constructor.prototype = new ReactClassComponent();
    Constructor.prototype.constructor = Constructor;

    injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));

    mixSpecIntoComponent(Constructor, spec);

    // Initialize the defaultProps property after all mixins have been merged.
    if (Constructor.getDefaultProps) {
      Constructor.defaultProps = Constructor.getDefaultProps();
    }

    if (process.env.NODE_ENV !== 'production') {
      // This is a tag to indicate that the use of these method names is ok,
      // since it's used with createClass. If it's not, then it's likely a
      // mistake so we'll warn you to use the static property, property
      // initializer or constructor respectively.
      if (Constructor.getDefaultProps) {
        Constructor.getDefaultProps.isReactClassApproved = {};
      }
      if (Constructor.prototype.getInitialState) {
        Constructor.prototype.getInitialState.isReactClassApproved = {};
      }
    }

    !Constructor.prototype.render ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : invariant(false) : undefined;

    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : undefined;
    }

    // Reduce time spent doing lookups by setting these on the prototype.
    for (var methodName in ReactClassInterface) {
      if (!Constructor.prototype[methodName]) {
        Constructor.prototype[methodName] = null;
      }
    }

    return Constructor;
  },

  injection: {
    injectMixin: function (mixin) {
      injectedMixins.push(mixin);
    }
  }

};

module.exports = ReactClass;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactComponent":426,"./ReactElement":448,"./ReactNoopUpdateQueue":465,"./ReactPropTypeLocationNames":468,"./ReactPropTypeLocations":469,"_process":334,"fbjs/lib/emptyObject":311,"fbjs/lib/invariant":318,"fbjs/lib/keyMirror":321,"fbjs/lib/keyOf":322,"fbjs/lib/warning":329}],426:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactComponent
 */

'use strict';

var ReactNoopUpdateQueue = require('./ReactNoopUpdateQueue');

var canDefineProperty = require('./canDefineProperty');
var emptyObject = require('fbjs/lib/emptyObject');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

/**
 * Base class helpers for the updating state of a component.
 */
function ReactComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  // We initialize the default updater but the real one gets injected by the
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue;
}

ReactComponent.prototype.isReactComponent = {};

/**
 * Sets a subset of the state. Always use this to mutate
 * state. You should treat `this.state` as immutable.
 *
 * There is no guarantee that `this.state` will be immediately updated, so
 * accessing `this.state` after calling this method may return the old value.
 *
 * There is no guarantee that calls to `setState` will run synchronously,
 * as they may eventually be batched together.  You can provide an optional
 * callback that will be executed when the call to setState is actually
 * completed.
 *
 * When a function is provided to setState, it will be called at some point in
 * the future (not synchronously). It will be called with the up to date
 * component arguments (state, props, context). These values can be different
 * from this.* because your function may be called after receiveProps but before
 * shouldComponentUpdate, and this new state, props, and context will not yet be
 * assigned to this.
 *
 * @param {object|function} partialState Next partial state or function to
 *        produce next partial state to be merged with current state.
 * @param {?function} callback Called after state is updated.
 * @final
 * @protected
 */
ReactComponent.prototype.setState = function (partialState, callback) {
  !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.') : invariant(false) : undefined;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : undefined;
  }
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback);
  }
};

/**
 * Forces an update. This should only be invoked when it is known with
 * certainty that we are **not** in a DOM transaction.
 *
 * You may want to call this when you know that some deeper aspect of the
 * component's state has changed but `setState` was not called.
 *
 * This will not invoke `shouldComponentUpdate`, but it will invoke
 * `componentWillUpdate` and `componentDidUpdate`.
 *
 * @param {?function} callback Called after update is complete.
 * @final
 * @protected
 */
ReactComponent.prototype.forceUpdate = function (callback) {
  this.updater.enqueueForceUpdate(this);
  if (callback) {
    this.updater.enqueueCallback(this, callback);
  }
};

/**
 * Deprecated APIs. These APIs used to exist on classic React classes but since
 * we would like to deprecate them, we're not going to move them over to this
 * modern base class. Instead, we define a getter that warns if it's accessed.
 */
if (process.env.NODE_ENV !== 'production') {
  var deprecatedAPIs = {
    getDOMNode: ['getDOMNode', 'Use ReactDOM.findDOMNode(component) instead.'],
    isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],
    replaceProps: ['replaceProps', 'Instead, call render again at the top level.'],
    replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'],
    setProps: ['setProps', 'Instead, call render again at the top level.']
  };
  var defineDeprecationWarning = function (methodName, info) {
    if (canDefineProperty) {
      Object.defineProperty(ReactComponent.prototype, methodName, {
        get: function () {
          process.env.NODE_ENV !== 'production' ? warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]) : undefined;
          return undefined;
        }
      });
    }
  };
  for (var fnName in deprecatedAPIs) {
    if (deprecatedAPIs.hasOwnProperty(fnName)) {
      defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
    }
  }
}

module.exports = ReactComponent;
}).call(this,require('_process'))

},{"./ReactNoopUpdateQueue":465,"./canDefineProperty":500,"_process":334,"fbjs/lib/emptyObject":311,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],427:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactComponentBrowserEnvironment
 */

'use strict';

var ReactDOMIDOperations = require('./ReactDOMIDOperations');
var ReactMount = require('./ReactMount');

/**
 * Abstracts away all functionality of the reconciler that requires knowledge of
 * the browser context. TODO: These callers should be refactored to avoid the
 * need for this injection.
 */
var ReactComponentBrowserEnvironment = {

  processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,

  replaceNodeWithMarkupByID: ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,

  /**
   * If a particular environment requires that some resources be cleaned up,
   * specify this in the injected Mixin. In the DOM, we would likely want to
   * purge any cached node ID lookups.
   *
   * @private
   */
  unmountIDFromEnvironment: function (rootNodeID) {
    ReactMount.purgeID(rootNodeID);
  }

};

module.exports = ReactComponentBrowserEnvironment;
},{"./ReactDOMIDOperations":436,"./ReactMount":461}],428:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactComponentEnvironment
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

var injected = false;

var ReactComponentEnvironment = {

  /**
   * Optionally injectable environment dependent cleanup hook. (server vs.
   * browser etc). Example: A browser system caches DOM nodes based on component
   * ID and must remove that cache entry when this instance is unmounted.
   */
  unmountIDFromEnvironment: null,

  /**
   * Optionally injectable hook for swapping out mount images in the middle of
   * the tree.
   */
  replaceNodeWithMarkupByID: null,

  /**
   * Optionally injectable hook for processing a queue of child updates. Will
   * later move into MultiChildComponents.
   */
  processChildrenUpdates: null,

  injection: {
    injectEnvironment: function (environment) {
      !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : invariant(false) : undefined;
      ReactComponentEnvironment.unmountIDFromEnvironment = environment.unmountIDFromEnvironment;
      ReactComponentEnvironment.replaceNodeWithMarkupByID = environment.replaceNodeWithMarkupByID;
      ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;
      injected = true;
    }
  }

};

module.exports = ReactComponentEnvironment;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],429:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactCompositeComponent
 */

'use strict';

var ReactComponentEnvironment = require('./ReactComponentEnvironment');
var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactElement = require('./ReactElement');
var ReactInstanceMap = require('./ReactInstanceMap');
var ReactPerf = require('./ReactPerf');
var ReactPropTypeLocations = require('./ReactPropTypeLocations');
var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
var ReactReconciler = require('./ReactReconciler');
var ReactUpdateQueue = require('./ReactUpdateQueue');

var assign = require('./Object.assign');
var emptyObject = require('fbjs/lib/emptyObject');
var invariant = require('fbjs/lib/invariant');
var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
var warning = require('fbjs/lib/warning');

function getDeclarationErrorAddendum(component) {
  var owner = component._currentElement._owner || null;
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

function StatelessComponent(Component) {}
StatelessComponent.prototype.render = function () {
  var Component = ReactInstanceMap.get(this)._currentElement.type;
  return Component(this.props, this.context, this.updater);
};

/**
 * ------------------ The Life-Cycle of a Composite Component ------------------
 *
 * - constructor: Initialization of state. The instance is now retained.
 *   - componentWillMount
 *   - render
 *   - [children's constructors]
 *     - [children's componentWillMount and render]
 *     - [children's componentDidMount]
 *     - componentDidMount
 *
 *       Update Phases:
 *       - componentWillReceiveProps (only called if parent updated)
 *       - shouldComponentUpdate
 *         - componentWillUpdate
 *           - render
 *           - [children's constructors or receive props phases]
 *         - componentDidUpdate
 *
 *     - componentWillUnmount
 *     - [children's componentWillUnmount]
 *   - [children destroyed]
 * - (destroyed): The instance is now blank, released by React and ready for GC.
 *
 * -----------------------------------------------------------------------------
 */

/**
 * An incrementing ID assigned to each component when it is mounted. This is
 * used to enforce the order in which `ReactUpdates` updates dirty components.
 *
 * @private
 */
var nextMountID = 1;

/**
 * @lends {ReactCompositeComponent.prototype}
 */
var ReactCompositeComponentMixin = {

  /**
   * Base constructor for all composite component.
   *
   * @param {ReactElement} element
   * @final
   * @internal
   */
  construct: function (element) {
    this._currentElement = element;
    this._rootNodeID = null;
    this._instance = null;

    // See ReactUpdateQueue
    this._pendingElement = null;
    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;

    this._renderedComponent = null;

    this._context = null;
    this._mountOrder = 0;
    this._topLevelWrapper = null;

    // See ReactUpdates and ReactUpdateQueue.
    this._pendingCallbacks = null;
  },

  /**
   * Initializes the component, renders markup, and registers event listeners.
   *
   * @param {string} rootID DOM ID of the root node.
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @return {?string} Rendered markup to be inserted into the DOM.
   * @final
   * @internal
   */
  mountComponent: function (rootID, transaction, context) {
    this._context = context;
    this._mountOrder = nextMountID++;
    this._rootNodeID = rootID;

    var publicProps = this._processProps(this._currentElement.props);
    var publicContext = this._processContext(context);

    var Component = this._currentElement.type;

    // Initialize the public class
    var inst;
    var renderedElement;

    // This is a way to detect if Component is a stateless arrow function
    // component, which is not newable. It might not be 100% reliable but is
    // something we can do until we start detecting that Component extends
    // React.Component. We already assume that typeof Component === 'function'.
    var canInstantiate = ('prototype' in Component);

    if (canInstantiate) {
      if (process.env.NODE_ENV !== 'production') {
        ReactCurrentOwner.current = this;
        try {
          inst = new Component(publicProps, publicContext, ReactUpdateQueue);
        } finally {
          ReactCurrentOwner.current = null;
        }
      } else {
        inst = new Component(publicProps, publicContext, ReactUpdateQueue);
      }
    }

    if (!canInstantiate || inst === null || inst === false || ReactElement.isValidElement(inst)) {
      renderedElement = inst;
      inst = new StatelessComponent(Component);
    }

    if (process.env.NODE_ENV !== 'production') {
      // This will throw later in _renderValidatedComponent, but add an early
      // warning now to help debugging
      if (inst.render == null) {
        process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`, returned ' + 'null/false from a stateless component, or tried to render an ' + 'element whose type is a function that isn\'t a React component.', Component.displayName || Component.name || 'Component') : undefined;
      } else {
        // We support ES6 inheriting from React.Component, the module pattern,
        // and stateless components, but not ES6 classes that don't extend
        process.env.NODE_ENV !== 'production' ? warning(Component.prototype && Component.prototype.isReactComponent || !canInstantiate || !(inst instanceof Component), '%s(...): React component classes must extend React.Component.', Component.displayName || Component.name || 'Component') : undefined;
      }
    }

    // These should be set up in the constructor, but as a convenience for
    // simpler class abstractions, we set them up after the fact.
    inst.props = publicProps;
    inst.context = publicContext;
    inst.refs = emptyObject;
    inst.updater = ReactUpdateQueue;

    this._instance = inst;

    // Store a reference from the instance back to the internal representation
    ReactInstanceMap.set(inst, this);

    if (process.env.NODE_ENV !== 'production') {
      // Since plain JS classes are defined without any special initialization
      // logic, we can not catch common errors early. Therefore, we have to
      // catch them here, at initialization time, instead.
      process.env.NODE_ENV !== 'production' ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : undefined;
      process.env.NODE_ENV !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : undefined;
    }

    var initialState = inst.state;
    if (initialState === undefined) {
      inst.state = initialState = null;
    }
    !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;

    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;

    if (inst.componentWillMount) {
      inst.componentWillMount();
      // When mounting, calls to `setState` by `componentWillMount` will set
      // `this._pendingStateQueue` without triggering a re-render.
      if (this._pendingStateQueue) {
        inst.state = this._processPendingState(inst.props, inst.context);
      }
    }

    // If not a stateless component, we now render
    if (renderedElement === undefined) {
      renderedElement = this._renderValidatedComponent();
    }

    this._renderedComponent = this._instantiateReactComponent(renderedElement);

    var markup = ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, this._processChildContext(context));
    if (inst.componentDidMount) {
      transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
    }

    return markup;
  },

  /**
   * Releases any resources allocated by `mountComponent`.
   *
   * @final
   * @internal
   */
  unmountComponent: function () {
    var inst = this._instance;

    if (inst.componentWillUnmount) {
      inst.componentWillUnmount();
    }

    ReactReconciler.unmountComponent(this._renderedComponent);
    this._renderedComponent = null;
    this._instance = null;

    // Reset pending fields
    // Even if this component is scheduled for another update in ReactUpdates,
    // it would still be ignored because these fields are reset.
    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;
    this._pendingCallbacks = null;
    this._pendingElement = null;

    // These fields do not really need to be reset since this object is no
    // longer accessible.
    this._context = null;
    this._rootNodeID = null;
    this._topLevelWrapper = null;

    // Delete the reference from the instance to this internal representation
    // which allow the internals to be properly cleaned up even if the user
    // leaks a reference to the public instance.
    ReactInstanceMap.remove(inst);

    // Some existing components rely on inst.props even after they've been
    // destroyed (in event handlers).
    // TODO: inst.props = null;
    // TODO: inst.state = null;
    // TODO: inst.context = null;
  },

  /**
   * Filters the context object to only contain keys specified in
   * `contextTypes`
   *
   * @param {object} context
   * @return {?object}
   * @private
   */
  _maskContext: function (context) {
    var maskedContext = null;
    var Component = this._currentElement.type;
    var contextTypes = Component.contextTypes;
    if (!contextTypes) {
      return emptyObject;
    }
    maskedContext = {};
    for (var contextName in contextTypes) {
      maskedContext[contextName] = context[contextName];
    }
    return maskedContext;
  },

  /**
   * Filters the context object to only contain keys specified in
   * `contextTypes`, and asserts that they are valid.
   *
   * @param {object} context
   * @return {?object}
   * @private
   */
  _processContext: function (context) {
    var maskedContext = this._maskContext(context);
    if (process.env.NODE_ENV !== 'production') {
      var Component = this._currentElement.type;
      if (Component.contextTypes) {
        this._checkPropTypes(Component.contextTypes, maskedContext, ReactPropTypeLocations.context);
      }
    }
    return maskedContext;
  },

  /**
   * @param {object} currentContext
   * @return {object}
   * @private
   */
  _processChildContext: function (currentContext) {
    var Component = this._currentElement.type;
    var inst = this._instance;
    var childContext = inst.getChildContext && inst.getChildContext();
    if (childContext) {
      !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;
      if (process.env.NODE_ENV !== 'production') {
        this._checkPropTypes(Component.childContextTypes, childContext, ReactPropTypeLocations.childContext);
      }
      for (var name in childContext) {
        !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : invariant(false) : undefined;
      }
      return assign({}, currentContext, childContext);
    }
    return currentContext;
  },

  /**
   * Processes props by setting default values for unspecified props and
   * asserting that the props are valid. Does not mutate its argument; returns
   * a new props object with defaults merged in.
   *
   * @param {object} newProps
   * @return {object}
   * @private
   */
  _processProps: function (newProps) {
    if (process.env.NODE_ENV !== 'production') {
      var Component = this._currentElement.type;
      if (Component.propTypes) {
        this._checkPropTypes(Component.propTypes, newProps, ReactPropTypeLocations.prop);
      }
    }
    return newProps;
  },

  /**
   * Assert that the props are valid
   *
   * @param {object} propTypes Map of prop name to a ReactPropType
   * @param {object} props
   * @param {string} location e.g. "prop", "context", "child context"
   * @private
   */
  _checkPropTypes: function (propTypes, props, location) {
    // TODO: Stop validating prop types here and only use the element
    // validation.
    var componentName = this.getName();
    for (var propName in propTypes) {
      if (propTypes.hasOwnProperty(propName)) {
        var error;
        try {
          // This is intentionally an invariant that gets caught. It's the same
          // behavior as without this statement except with a better message.
          !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually ' + 'from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined;
          error = propTypes[propName](props, propName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
        } catch (ex) {
          error = ex;
        }
        if (error instanceof Error) {
          // We may want to extend this logic for similar errors in
          // top-level render calls, so I'm abstracting it away into
          // a function to minimize refactoring in the future
          var addendum = getDeclarationErrorAddendum(this);

          if (location === ReactPropTypeLocations.prop) {
            // Preface gives us something to blacklist in warning module
            process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Composite propType: %s%s', error.message, addendum) : undefined;
          } else {
            process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Context Types: %s%s', error.message, addendum) : undefined;
          }
        }
      }
    }
  },

  receiveComponent: function (nextElement, transaction, nextContext) {
    var prevElement = this._currentElement;
    var prevContext = this._context;

    this._pendingElement = null;

    this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext);
  },

  /**
   * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
   * is set, update the component.
   *
   * @param {ReactReconcileTransaction} transaction
   * @internal
   */
  performUpdateIfNecessary: function (transaction) {
    if (this._pendingElement != null) {
      ReactReconciler.receiveComponent(this, this._pendingElement || this._currentElement, transaction, this._context);
    }

    if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
      this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context);
    }
  },

  /**
   * Perform an update to a mounted component. The componentWillReceiveProps and
   * shouldComponentUpdate methods are called, then (assuming the update isn't
   * skipped) the remaining update lifecycle methods are called and the DOM
   * representation is updated.
   *
   * By default, this implements React's rendering and reconciliation algorithm.
   * Sophisticated clients may wish to override this.
   *
   * @param {ReactReconcileTransaction} transaction
   * @param {ReactElement} prevParentElement
   * @param {ReactElement} nextParentElement
   * @internal
   * @overridable
   */
  updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {
    var inst = this._instance;

    var nextContext = this._context === nextUnmaskedContext ? inst.context : this._processContext(nextUnmaskedContext);
    var nextProps;

    // Distinguish between a props update versus a simple state update
    if (prevParentElement === nextParentElement) {
      // Skip checking prop types again -- we don't read inst.props to avoid
      // warning for DOM component props in this upgrade
      nextProps = nextParentElement.props;
    } else {
      nextProps = this._processProps(nextParentElement.props);
      // An update here will schedule an update but immediately set
      // _pendingStateQueue which will ensure that any state updates gets
      // immediately reconciled instead of waiting for the next batch.

      if (inst.componentWillReceiveProps) {
        inst.componentWillReceiveProps(nextProps, nextContext);
      }
    }

    var nextState = this._processPendingState(nextProps, nextContext);

    var shouldUpdate = this._pendingForceUpdate || !inst.shouldComponentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext);

    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(typeof shouldUpdate !== 'undefined', '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : undefined;
    }

    if (shouldUpdate) {
      this._pendingForceUpdate = false;
      // Will set `this.props`, `this.state` and `this.context`.
      this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext);
    } else {
      // If it's determined that a component should not update, we still want
      // to set props and state but we shortcut the rest of the update.
      this._currentElement = nextParentElement;
      this._context = nextUnmaskedContext;
      inst.props = nextProps;
      inst.state = nextState;
      inst.context = nextContext;
    }
  },

  _processPendingState: function (props, context) {
    var inst = this._instance;
    var queue = this._pendingStateQueue;
    var replace = this._pendingReplaceState;
    this._pendingReplaceState = false;
    this._pendingStateQueue = null;

    if (!queue) {
      return inst.state;
    }

    if (replace && queue.length === 1) {
      return queue[0];
    }

    var nextState = assign({}, replace ? queue[0] : inst.state);
    for (var i = replace ? 1 : 0; i < queue.length; i++) {
      var partial = queue[i];
      assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial);
    }

    return nextState;
  },

  /**
   * Merges new props and state, notifies delegate methods of update and
   * performs update.
   *
   * @param {ReactElement} nextElement Next element
   * @param {object} nextProps Next public object to set as properties.
   * @param {?object} nextState Next object to set as state.
   * @param {?object} nextContext Next public object to set as context.
   * @param {ReactReconcileTransaction} transaction
   * @param {?object} unmaskedContext
   * @private
   */
  _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) {
    var inst = this._instance;

    var hasComponentDidUpdate = Boolean(inst.componentDidUpdate);
    var prevProps;
    var prevState;
    var prevContext;
    if (hasComponentDidUpdate) {
      prevProps = inst.props;
      prevState = inst.state;
      prevContext = inst.context;
    }

    if (inst.componentWillUpdate) {
      inst.componentWillUpdate(nextProps, nextState, nextContext);
    }

    this._currentElement = nextElement;
    this._context = unmaskedContext;
    inst.props = nextProps;
    inst.state = nextState;
    inst.context = nextContext;

    this._updateRenderedComponent(transaction, unmaskedContext);

    if (hasComponentDidUpdate) {
      transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst);
    }
  },

  /**
   * Call the component's `render` method and update the DOM accordingly.
   *
   * @param {ReactReconcileTransaction} transaction
   * @internal
   */
  _updateRenderedComponent: function (transaction, context) {
    var prevComponentInstance = this._renderedComponent;
    var prevRenderedElement = prevComponentInstance._currentElement;
    var nextRenderedElement = this._renderValidatedComponent();
    if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
      ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context));
    } else {
      // These two IDs are actually the same! But nothing should rely on that.
      var thisID = this._rootNodeID;
      var prevComponentID = prevComponentInstance._rootNodeID;
      ReactReconciler.unmountComponent(prevComponentInstance);

      this._renderedComponent = this._instantiateReactComponent(nextRenderedElement);
      var nextMarkup = ReactReconciler.mountComponent(this._renderedComponent, thisID, transaction, this._processChildContext(context));
      this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup);
    }
  },

  /**
   * @protected
   */
  _replaceNodeWithMarkupByID: function (prevComponentID, nextMarkup) {
    ReactComponentEnvironment.replaceNodeWithMarkupByID(prevComponentID, nextMarkup);
  },

  /**
   * @protected
   */
  _renderValidatedComponentWithoutOwnerOrContext: function () {
    var inst = this._instance;
    var renderedComponent = inst.render();
    if (process.env.NODE_ENV !== 'production') {
      // We allow auto-mocks to proceed as if they're returning null.
      if (typeof renderedComponent === 'undefined' && inst.render._isMockFunction) {
        // This is probably bad practice. Consider warning here and
        // deprecating this convenience.
        renderedComponent = null;
      }
    }

    return renderedComponent;
  },

  /**
   * @private
   */
  _renderValidatedComponent: function () {
    var renderedComponent;
    ReactCurrentOwner.current = this;
    try {
      renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext();
    } finally {
      ReactCurrentOwner.current = null;
    }
    !(
    // TODO: An `isValidNode` function would probably be more appropriate
    renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : invariant(false) : undefined;
    return renderedComponent;
  },

  /**
   * Lazily allocates the refs object and stores `component` as `ref`.
   *
   * @param {string} ref Reference name.
   * @param {component} component Component to store as `ref`.
   * @final
   * @private
   */
  attachRef: function (ref, component) {
    var inst = this.getPublicInstance();
    !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : invariant(false) : undefined;
    var publicComponentInstance = component.getPublicInstance();
    if (process.env.NODE_ENV !== 'production') {
      var componentName = component && component.getName ? component.getName() : 'a component';
      process.env.NODE_ENV !== 'production' ? warning(publicComponentInstance != null, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : undefined;
    }
    var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs;
    refs[ref] = publicComponentInstance;
  },

  /**
   * Detaches a reference name.
   *
   * @param {string} ref Name to dereference.
   * @final
   * @private
   */
  detachRef: function (ref) {
    var refs = this.getPublicInstance().refs;
    delete refs[ref];
  },

  /**
   * Get a text description of the component that can be used to identify it
   * in error messages.
   * @return {string} The name or null.
   * @internal
   */
  getName: function () {
    var type = this._currentElement.type;
    var constructor = this._instance && this._instance.constructor;
    return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null;
  },

  /**
   * Get the publicly accessible representation of this component - i.e. what
   * is exposed by refs and returned by render. Can be null for stateless
   * components.
   *
   * @return {ReactComponent} the public component instance.
   * @internal
   */
  getPublicInstance: function () {
    var inst = this._instance;
    if (inst instanceof StatelessComponent) {
      return null;
    }
    return inst;
  },

  // Stub
  _instantiateReactComponent: null

};

ReactPerf.measureMethods(ReactCompositeComponentMixin, 'ReactCompositeComponent', {
  mountComponent: 'mountComponent',
  updateComponent: 'updateComponent',
  _renderValidatedComponent: '_renderValidatedComponent'
});

var ReactCompositeComponent = {

  Mixin: ReactCompositeComponentMixin

};

module.exports = ReactCompositeComponent;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactComponentEnvironment":428,"./ReactCurrentOwner":430,"./ReactElement":448,"./ReactInstanceMap":458,"./ReactPerf":467,"./ReactPropTypeLocationNames":468,"./ReactPropTypeLocations":469,"./ReactReconciler":472,"./ReactUpdateQueue":478,"./shouldUpdateReactComponent":522,"_process":334,"fbjs/lib/emptyObject":311,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],430:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactCurrentOwner
 */

'use strict';

/**
 * Keeps track of the current owner.
 *
 * The current owner is the component who should own any components that are
 * currently being constructed.
 */
var ReactCurrentOwner = {

  /**
   * @internal
   * @type {ReactComponent}
   */
  current: null

};

module.exports = ReactCurrentOwner;
},{}],431:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOM
 */

/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/

'use strict';

var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactDOMTextComponent = require('./ReactDOMTextComponent');
var ReactDefaultInjection = require('./ReactDefaultInjection');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactMount = require('./ReactMount');
var ReactPerf = require('./ReactPerf');
var ReactReconciler = require('./ReactReconciler');
var ReactUpdates = require('./ReactUpdates');
var ReactVersion = require('./ReactVersion');

var findDOMNode = require('./findDOMNode');
var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
var warning = require('fbjs/lib/warning');

ReactDefaultInjection.inject();

var render = ReactPerf.measure('React', 'render', ReactMount.render);

var React = {
  findDOMNode: findDOMNode,
  render: render,
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
  version: ReactVersion,

  /* eslint-disable camelcase */
  unstable_batchedUpdates: ReactUpdates.batchedUpdates,
  unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
};

// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
/* eslint-enable camelcase */
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
  __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
    CurrentOwner: ReactCurrentOwner,
    InstanceHandles: ReactInstanceHandles,
    Mount: ReactMount,
    Reconciler: ReactReconciler,
    TextComponent: ReactDOMTextComponent
  });
}

if (process.env.NODE_ENV !== 'production') {
  var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
  if (ExecutionEnvironment.canUseDOM && window.top === window.self) {

    // First check if devtools is not installed
    if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
      // If we're in Chrome or Firefox, provide a download link if not installed.
      if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
        console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');
      }
    }

    // If we're in IE8, check to see if we are in compatibility mode and provide
    // information on preventing compatibility mode
    var ieCompatibilityMode = document.documentMode && document.documentMode < 8;

    process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : undefined;

    var expectedFeatures = [
    // shims
    Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim,

    // shams
    Object.create, Object.freeze];

    for (var i = 0; i < expectedFeatures.length; i++) {
      if (!expectedFeatures[i]) {
        console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');
        break;
      }
    }
  }
}

module.exports = React;
}).call(this,require('_process'))

},{"./ReactCurrentOwner":430,"./ReactDOMTextComponent":442,"./ReactDefaultInjection":445,"./ReactInstanceHandles":457,"./ReactMount":461,"./ReactPerf":467,"./ReactReconciler":472,"./ReactUpdates":479,"./ReactVersion":480,"./findDOMNode":504,"./renderSubtreeIntoContainer":519,"_process":334,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/warning":329}],432:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMButton
 */

'use strict';

var mouseListenerNames = {
  onClick: true,
  onDoubleClick: true,
  onMouseDown: true,
  onMouseMove: true,
  onMouseUp: true,

  onClickCapture: true,
  onDoubleClickCapture: true,
  onMouseDownCapture: true,
  onMouseMoveCapture: true,
  onMouseUpCapture: true
};

/**
 * Implements a <button> native component that does not receive mouse events
 * when `disabled` is set.
 */
var ReactDOMButton = {
  getNativeProps: function (inst, props, context) {
    if (!props.disabled) {
      return props;
    }

    // Copy the props, except the mouse listeners
    var nativeProps = {};
    for (var key in props) {
      if (props.hasOwnProperty(key) && !mouseListenerNames[key]) {
        nativeProps[key] = props[key];
      }
    }

    return nativeProps;
  }
};

module.exports = ReactDOMButton;
},{}],433:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMComponent
 * @typechecks static-only
 */

/* global hasOwnProperty:true */

'use strict';

var AutoFocusUtils = require('./AutoFocusUtils');
var CSSPropertyOperations = require('./CSSPropertyOperations');
var DOMProperty = require('./DOMProperty');
var DOMPropertyOperations = require('./DOMPropertyOperations');
var EventConstants = require('./EventConstants');
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');
var ReactDOMButton = require('./ReactDOMButton');
var ReactDOMInput = require('./ReactDOMInput');
var ReactDOMOption = require('./ReactDOMOption');
var ReactDOMSelect = require('./ReactDOMSelect');
var ReactDOMTextarea = require('./ReactDOMTextarea');
var ReactMount = require('./ReactMount');
var ReactMultiChild = require('./ReactMultiChild');
var ReactPerf = require('./ReactPerf');
var ReactUpdateQueue = require('./ReactUpdateQueue');

var assign = require('./Object.assign');
var canDefineProperty = require('./canDefineProperty');
var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
var invariant = require('fbjs/lib/invariant');
var isEventSupported = require('./isEventSupported');
var keyOf = require('fbjs/lib/keyOf');
var setInnerHTML = require('./setInnerHTML');
var setTextContent = require('./setTextContent');
var shallowEqual = require('fbjs/lib/shallowEqual');
var validateDOMNesting = require('./validateDOMNesting');
var warning = require('fbjs/lib/warning');

var deleteListener = ReactBrowserEventEmitter.deleteListener;
var listenTo = ReactBrowserEventEmitter.listenTo;
var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules;

// For quickly matching children type, to test if can be treated as content.
var CONTENT_TYPES = { 'string': true, 'number': true };

var CHILDREN = keyOf({ children: null });
var STYLE = keyOf({ style: null });
var HTML = keyOf({ __html: null });

var ELEMENT_NODE_TYPE = 1;

function getDeclarationErrorAddendum(internalInstance) {
  if (internalInstance) {
    var owner = internalInstance._currentElement._owner || null;
    if (owner) {
      var name = owner.getName();
      if (name) {
        return ' This DOM node was rendered by `' + name + '`.';
      }
    }
  }
  return '';
}

var legacyPropsDescriptor;
if (process.env.NODE_ENV !== 'production') {
  legacyPropsDescriptor = {
    props: {
      enumerable: false,
      get: function () {
        var component = this._reactInternalComponent;
        process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined;
        return component._currentElement.props;
      }
    }
  };
}

function legacyGetDOMNode() {
  if (process.env.NODE_ENV !== 'production') {
    var component = this._reactInternalComponent;
    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .getDOMNode() of a DOM node; ' + 'instead, use the node directly.%s', getDeclarationErrorAddendum(component)) : undefined;
  }
  return this;
}

function legacyIsMounted() {
  var component = this._reactInternalComponent;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined;
  }
  return !!component;
}

function legacySetStateEtc() {
  if (process.env.NODE_ENV !== 'production') {
    var component = this._reactInternalComponent;
    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setState(), .replaceState(), or ' + '.forceUpdate() of a DOM node. This is a no-op.%s', getDeclarationErrorAddendum(component)) : undefined;
  }
}

function legacySetProps(partialProps, callback) {
  var component = this._reactInternalComponent;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
  }
  if (!component) {
    return;
  }
  ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps);
  if (callback) {
    ReactUpdateQueue.enqueueCallbackInternal(component, callback);
  }
}

function legacyReplaceProps(partialProps, callback) {
  var component = this._reactInternalComponent;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
  }
  if (!component) {
    return;
  }
  ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps);
  if (callback) {
    ReactUpdateQueue.enqueueCallbackInternal(component, callback);
  }
}

function friendlyStringify(obj) {
  if (typeof obj === 'object') {
    if (Array.isArray(obj)) {
      return '[' + obj.map(friendlyStringify).join(', ') + ']';
    } else {
      var pairs = [];
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key);
          pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key]));
        }
      }
      return '{' + pairs.join(', ') + '}';
    }
  } else if (typeof obj === 'string') {
    return JSON.stringify(obj);
  } else if (typeof obj === 'function') {
    return '[function object]';
  }
  // Differs from JSON.stringify in that undefined becauses undefined and that
  // inf and nan don't become null
  return String(obj);
}

var styleMutationWarning = {};

function checkAndWarnForMutatedStyle(style1, style2, component) {
  if (style1 == null || style2 == null) {
    return;
  }
  if (shallowEqual(style1, style2)) {
    return;
  }

  var componentName = component._tag;
  var owner = component._currentElement._owner;
  var ownerName;
  if (owner) {
    ownerName = owner.getName();
  }

  var hash = ownerName + '|' + componentName;

  if (styleMutationWarning.hasOwnProperty(hash)) {
    return;
  }

  styleMutationWarning[hash] = true;

  process.env.NODE_ENV !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : undefined;
}

/**
 * @param {object} component
 * @param {?object} props
 */
function assertValidProps(component, props) {
  if (!props) {
    return;
  }
  // Note the use of `==` which checks for null or undefined.
  if (process.env.NODE_ENV !== 'production') {
    if (voidElementTags[component._tag]) {
      process.env.NODE_ENV !== 'production' ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined;
    }
  }
  if (props.dangerouslySetInnerHTML != null) {
    !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined;
    !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined;
  }
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined;
    process.env.NODE_ENV !== 'production' ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined;
  }
  !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : undefined;
}

function enqueuePutListener(id, registrationName, listener, transaction) {
  if (process.env.NODE_ENV !== 'production') {
    // IE8 has no API for event capturing and the `onScroll` event doesn't
    // bubble.
    process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined;
  }
  var container = ReactMount.findReactContainerForID(id);
  if (container) {
    var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container;
    listenTo(registrationName, doc);
  }
  transaction.getReactMountReady().enqueue(putListener, {
    id: id,
    registrationName: registrationName,
    listener: listener
  });
}

function putListener() {
  var listenerToPut = this;
  ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener);
}

// There are so many media events, it makes sense to just
// maintain a list rather than create a `trapBubbledEvent` for each
var mediaEvents = {
  topAbort: 'abort',
  topCanPlay: 'canplay',
  topCanPlayThrough: 'canplaythrough',
  topDurationChange: 'durationchange',
  topEmptied: 'emptied',
  topEncrypted: 'encrypted',
  topEnded: 'ended',
  topError: 'error',
  topLoadedData: 'loadeddata',
  topLoadedMetadata: 'loadedmetadata',
  topLoadStart: 'loadstart',
  topPause: 'pause',
  topPlay: 'play',
  topPlaying: 'playing',
  topProgress: 'progress',
  topRateChange: 'ratechange',
  topSeeked: 'seeked',
  topSeeking: 'seeking',
  topStalled: 'stalled',
  topSuspend: 'suspend',
  topTimeUpdate: 'timeupdate',
  topVolumeChange: 'volumechange',
  topWaiting: 'waiting'
};

function trapBubbledEventsLocal() {
  var inst = this;
  // If a component renders to null or if another component fatals and causes
  // the state of the tree to be corrupted, `node` here can be null.
  !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined;
  var node = ReactMount.getNode(inst._rootNodeID);
  !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined;

  switch (inst._tag) {
    case 'iframe':
      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
      break;
    case 'video':
    case 'audio':

      inst._wrapperState.listeners = [];
      // create listener for each media event
      for (var event in mediaEvents) {
        if (mediaEvents.hasOwnProperty(event)) {
          inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));
        }
      }

      break;
    case 'img':
      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
      break;
    case 'form':
      inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)];
      break;
  }
}

function mountReadyInputWrapper() {
  ReactDOMInput.mountReadyWrapper(this);
}

function postUpdateSelectWrapper() {
  ReactDOMSelect.postUpdateWrapper(this);
}

// For HTML, certain tags should omit their close tag. We keep a whitelist for
// those special cased tags.

var omittedCloseTags = {
  'area': true,
  'base': true,
  'br': true,
  'col': true,
  'embed': true,
  'hr': true,
  'img': true,
  'input': true,
  'keygen': true,
  'link': true,
  'meta': true,
  'param': true,
  'source': true,
  'track': true,
  'wbr': true
};

// NOTE: menuitem's close tag should be omitted, but that causes problems.
var newlineEatingTags = {
  'listing': true,
  'pre': true,
  'textarea': true
};

// For HTML, certain tags cannot have children. This has the same purpose as
// `omittedCloseTags` except that `menuitem` should still have its closing tag.

var voidElementTags = assign({
  'menuitem': true
}, omittedCloseTags);

// We accept any tag to be rendered but since this gets injected into arbitrary
// HTML, we want to make sure that it's a safe tag.
// http://www.w3.org/TR/REC-xml/#NT-Name

var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
var validatedTagCache = {};
var hasOwnProperty = ({}).hasOwnProperty;

function validateDangerousTag(tag) {
  if (!hasOwnProperty.call(validatedTagCache, tag)) {
    !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined;
    validatedTagCache[tag] = true;
  }
}

function processChildContextDev(context, inst) {
  // Pass down our tag name to child components for validation purposes
  context = assign({}, context);
  var info = context[validateDOMNesting.ancestorInfoContextKey];
  context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst);
  return context;
}

function isCustomComponent(tagName, props) {
  return tagName.indexOf('-') >= 0 || props.is != null;
}

/**
 * Creates a new React class that is idempotent and capable of containing other
 * React components. It accepts event listeners and DOM properties that are
 * valid according to `DOMProperty`.
 *
 *  - Event listeners: `onClick`, `onMouseDown`, etc.
 *  - DOM properties: `className`, `name`, `title`, etc.
 *
 * The `style` property functions differently from the DOM API. It accepts an
 * object mapping of style properties to values.
 *
 * @constructor ReactDOMComponent
 * @extends ReactMultiChild
 */
function ReactDOMComponent(tag) {
  validateDangerousTag(tag);
  this._tag = tag.toLowerCase();
  this._renderedChildren = null;
  this._previousStyle = null;
  this._previousStyleCopy = null;
  this._rootNodeID = null;
  this._wrapperState = null;
  this._topLevelWrapper = null;
  this._nodeWithLegacyProperties = null;
  if (process.env.NODE_ENV !== 'production') {
    this._unprocessedContextDev = null;
    this._processedContextDev = null;
  }
}

ReactDOMComponent.displayName = 'ReactDOMComponent';

ReactDOMComponent.Mixin = {

  construct: function (element) {
    this._currentElement = element;
  },

  /**
   * Generates root tag markup then recurses. This method has side effects and
   * is not idempotent.
   *
   * @internal
   * @param {string} rootID The root DOM ID for this node.
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @param {object} context
   * @return {string} The computed markup.
   */
  mountComponent: function (rootID, transaction, context) {
    this._rootNodeID = rootID;

    var props = this._currentElement.props;

    switch (this._tag) {
      case 'iframe':
      case 'img':
      case 'form':
      case 'video':
      case 'audio':
        this._wrapperState = {
          listeners: null
        };
        transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
        break;
      case 'button':
        props = ReactDOMButton.getNativeProps(this, props, context);
        break;
      case 'input':
        ReactDOMInput.mountWrapper(this, props, context);
        props = ReactDOMInput.getNativeProps(this, props, context);
        break;
      case 'option':
        ReactDOMOption.mountWrapper(this, props, context);
        props = ReactDOMOption.getNativeProps(this, props, context);
        break;
      case 'select':
        ReactDOMSelect.mountWrapper(this, props, context);
        props = ReactDOMSelect.getNativeProps(this, props, context);
        context = ReactDOMSelect.processChildContext(this, props, context);
        break;
      case 'textarea':
        ReactDOMTextarea.mountWrapper(this, props, context);
        props = ReactDOMTextarea.getNativeProps(this, props, context);
        break;
    }

    assertValidProps(this, props);
    if (process.env.NODE_ENV !== 'production') {
      if (context[validateDOMNesting.ancestorInfoContextKey]) {
        validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]);
      }
    }

    if (process.env.NODE_ENV !== 'production') {
      this._unprocessedContextDev = context;
      this._processedContextDev = processChildContextDev(context, this);
      context = this._processedContextDev;
    }

    var mountImage;
    if (transaction.useCreateElement) {
      var ownerDocument = context[ReactMount.ownerDocumentContextKey];
      var el = ownerDocument.createElement(this._currentElement.type);
      DOMPropertyOperations.setAttributeForID(el, this._rootNodeID);
      // Populate node cache
      ReactMount.getID(el);
      this._updateDOMProperties({}, props, transaction, el);
      this._createInitialChildren(transaction, props, context, el);
      mountImage = el;
    } else {
      var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);
      var tagContent = this._createContentMarkup(transaction, props, context);
      if (!tagContent && omittedCloseTags[this._tag]) {
        mountImage = tagOpen + '/>';
      } else {
        mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';
      }
    }

    switch (this._tag) {
      case 'input':
        transaction.getReactMountReady().enqueue(mountReadyInputWrapper, this);
      // falls through
      case 'button':
      case 'select':
      case 'textarea':
        if (props.autoFocus) {
          transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
        }
        break;
    }

    return mountImage;
  },

  /**
   * Creates markup for the open tag and all attributes.
   *
   * This method has side effects because events get registered.
   *
   * Iterating over object properties is faster than iterating over arrays.
   * @see http://jsperf.com/obj-vs-arr-iteration
   *
   * @private
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @param {object} props
   * @return {string} Markup of opening tag.
   */
  _createOpenTagMarkupAndPutListeners: function (transaction, props) {
    var ret = '<' + this._currentElement.type;

    for (var propKey in props) {
      if (!props.hasOwnProperty(propKey)) {
        continue;
      }
      var propValue = props[propKey];
      if (propValue == null) {
        continue;
      }
      if (registrationNameModules.hasOwnProperty(propKey)) {
        if (propValue) {
          enqueuePutListener(this._rootNodeID, propKey, propValue, transaction);
        }
      } else {
        if (propKey === STYLE) {
          if (propValue) {
            if (process.env.NODE_ENV !== 'production') {
              // See `_updateDOMProperties`. style block
              this._previousStyle = propValue;
            }
            propValue = this._previousStyleCopy = assign({}, props.style);
          }
          propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
        }
        var markup = null;
        if (this._tag != null && isCustomComponent(this._tag, props)) {
          if (propKey !== CHILDREN) {
            markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
          }
        } else {
          markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
        }
        if (markup) {
          ret += ' ' + markup;
        }
      }
    }

    // For static pages, no need to put React ID and checksum. Saves lots of
    // bytes.
    if (transaction.renderToStaticMarkup) {
      return ret;
    }

    var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
    return ret + ' ' + markupForID;
  },

  /**
   * Creates markup for the content between the tags.
   *
   * @private
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @param {object} props
   * @param {object} context
   * @return {string} Content markup.
   */
  _createContentMarkup: function (transaction, props, context) {
    var ret = '';

    // Intentional use of != to avoid catching zero/false.
    var innerHTML = props.dangerouslySetInnerHTML;
    if (innerHTML != null) {
      if (innerHTML.__html != null) {
        ret = innerHTML.__html;
      }
    } else {
      var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
      var childrenToUse = contentToUse != null ? null : props.children;
      if (contentToUse != null) {
        // TODO: Validate that text is allowed as a child of this node
        ret = escapeTextContentForBrowser(contentToUse);
      } else if (childrenToUse != null) {
        var mountImages = this.mountChildren(childrenToUse, transaction, context);
        ret = mountImages.join('');
      }
    }
    if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') {
      // text/html ignores the first character in these tags if it's a newline
      // Prefer to break application/xml over text/html (for now) by adding
      // a newline specifically to get eaten by the parser. (Alternately for
      // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first
      // \r is normalized out by HTMLTextAreaElement#value.)
      // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre>
      // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions>
      // See: <http://www.w3.org/TR/html5/syntax.html#newlines>
      // See: Parsing of "textarea" "listing" and "pre" elements
      //  from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody>
      return '\n' + ret;
    } else {
      return ret;
    }
  },

  _createInitialChildren: function (transaction, props, context, el) {
    // Intentional use of != to avoid catching zero/false.
    var innerHTML = props.dangerouslySetInnerHTML;
    if (innerHTML != null) {
      if (innerHTML.__html != null) {
        setInnerHTML(el, innerHTML.__html);
      }
    } else {
      var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
      var childrenToUse = contentToUse != null ? null : props.children;
      if (contentToUse != null) {
        // TODO: Validate that text is allowed as a child of this node
        setTextContent(el, contentToUse);
      } else if (childrenToUse != null) {
        var mountImages = this.mountChildren(childrenToUse, transaction, context);
        for (var i = 0; i < mountImages.length; i++) {
          el.appendChild(mountImages[i]);
        }
      }
    }
  },

  /**
   * Receives a next element and updates the component.
   *
   * @internal
   * @param {ReactElement} nextElement
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @param {object} context
   */
  receiveComponent: function (nextElement, transaction, context) {
    var prevElement = this._currentElement;
    this._currentElement = nextElement;
    this.updateComponent(transaction, prevElement, nextElement, context);
  },

  /**
   * Updates a native DOM component after it has already been allocated and
   * attached to the DOM. Reconciles the root DOM node, then recurses.
   *
   * @param {ReactReconcileTransaction} transaction
   * @param {ReactElement} prevElement
   * @param {ReactElement} nextElement
   * @internal
   * @overridable
   */
  updateComponent: function (transaction, prevElement, nextElement, context) {
    var lastProps = prevElement.props;
    var nextProps = this._currentElement.props;

    switch (this._tag) {
      case 'button':
        lastProps = ReactDOMButton.getNativeProps(this, lastProps);
        nextProps = ReactDOMButton.getNativeProps(this, nextProps);
        break;
      case 'input':
        ReactDOMInput.updateWrapper(this);
        lastProps = ReactDOMInput.getNativeProps(this, lastProps);
        nextProps = ReactDOMInput.getNativeProps(this, nextProps);
        break;
      case 'option':
        lastProps = ReactDOMOption.getNativeProps(this, lastProps);
        nextProps = ReactDOMOption.getNativeProps(this, nextProps);
        break;
      case 'select':
        lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
        nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
        break;
      case 'textarea':
        ReactDOMTextarea.updateWrapper(this);
        lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
        nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
        break;
    }

    if (process.env.NODE_ENV !== 'production') {
      // If the context is reference-equal to the old one, pass down the same
      // processed object so the update bailout in ReactReconciler behaves
      // correctly (and identically in dev and prod). See #5005.
      if (this._unprocessedContextDev !== context) {
        this._unprocessedContextDev = context;
        this._processedContextDev = processChildContextDev(context, this);
      }
      context = this._processedContextDev;
    }

    assertValidProps(this, nextProps);
    this._updateDOMProperties(lastProps, nextProps, transaction, null);
    this._updateDOMChildren(lastProps, nextProps, transaction, context);

    if (!canDefineProperty && this._nodeWithLegacyProperties) {
      this._nodeWithLegacyProperties.props = nextProps;
    }

    if (this._tag === 'select') {
      // <select> value update needs to occur after <option> children
      // reconciliation
      transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
    }
  },

  /**
   * Reconciles the properties by detecting differences in property values and
   * updating the DOM as necessary. This function is probably the single most
   * critical path for performance optimization.
   *
   * TODO: Benchmark whether checking for changed values in memory actually
   *       improves performance (especially statically positioned elements).
   * TODO: Benchmark the effects of putting this at the top since 99% of props
   *       do not change for a given reconciliation.
   * TODO: Benchmark areas that can be improved with caching.
   *
   * @private
   * @param {object} lastProps
   * @param {object} nextProps
   * @param {ReactReconcileTransaction} transaction
   * @param {?DOMElement} node
   */
  _updateDOMProperties: function (lastProps, nextProps, transaction, node) {
    var propKey;
    var styleName;
    var styleUpdates;
    for (propKey in lastProps) {
      if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey)) {
        continue;
      }
      if (propKey === STYLE) {
        var lastStyle = this._previousStyleCopy;
        for (styleName in lastStyle) {
          if (lastStyle.hasOwnProperty(styleName)) {
            styleUpdates = styleUpdates || {};
            styleUpdates[styleName] = '';
          }
        }
        this._previousStyleCopy = null;
      } else if (registrationNameModules.hasOwnProperty(propKey)) {
        if (lastProps[propKey]) {
          // Only call deleteListener if there was a listener previously or
          // else willDeleteListener gets called when there wasn't actually a
          // listener (e.g., onClick={null})
          deleteListener(this._rootNodeID, propKey);
        }
      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
        if (!node) {
          node = ReactMount.getNode(this._rootNodeID);
        }
        DOMPropertyOperations.deleteValueForProperty(node, propKey);
      }
    }
    for (propKey in nextProps) {
      var nextProp = nextProps[propKey];
      var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps[propKey];
      if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
        continue;
      }
      if (propKey === STYLE) {
        if (nextProp) {
          if (process.env.NODE_ENV !== 'production') {
            checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
            this._previousStyle = nextProp;
          }
          nextProp = this._previousStyleCopy = assign({}, nextProp);
        } else {
          this._previousStyleCopy = null;
        }
        if (lastProp) {
          // Unset styles on `lastProp` but not on `nextProp`.
          for (styleName in lastProp) {
            if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
              styleUpdates = styleUpdates || {};
              styleUpdates[styleName] = '';
            }
          }
          // Update styles that changed since `lastProp`.
          for (styleName in nextProp) {
            if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
              styleUpdates = styleUpdates || {};
              styleUpdates[styleName] = nextProp[styleName];
            }
          }
        } else {
          // Relies on `updateStylesByID` not mutating `styleUpdates`.
          styleUpdates = nextProp;
        }
      } else if (registrationNameModules.hasOwnProperty(propKey)) {
        if (nextProp) {
          enqueuePutListener(this._rootNodeID, propKey, nextProp, transaction);
        } else if (lastProp) {
          deleteListener(this._rootNodeID, propKey);
        }
      } else if (isCustomComponent(this._tag, nextProps)) {
        if (!node) {
          node = ReactMount.getNode(this._rootNodeID);
        }
        if (propKey === CHILDREN) {
          nextProp = null;
        }
        DOMPropertyOperations.setValueForAttribute(node, propKey, nextProp);
      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
        if (!node) {
          node = ReactMount.getNode(this._rootNodeID);
        }
        // If we're updating to null or undefined, we should remove the property
        // from the DOM node instead of inadvertantly setting to a string. This
        // brings us in line with the same behavior we have on initial render.
        if (nextProp != null) {
          DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);
        } else {
          DOMPropertyOperations.deleteValueForProperty(node, propKey);
        }
      }
    }
    if (styleUpdates) {
      if (!node) {
        node = ReactMount.getNode(this._rootNodeID);
      }
      CSSPropertyOperations.setValueForStyles(node, styleUpdates);
    }
  },

  /**
   * Reconciles the children with the various properties that affect the
   * children content.
   *
   * @param {object} lastProps
   * @param {object} nextProps
   * @param {ReactReconcileTransaction} transaction
   * @param {object} context
   */
  _updateDOMChildren: function (lastProps, nextProps, transaction, context) {
    var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
    var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;

    var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html;
    var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html;

    // Note the use of `!=` which checks for null or undefined.
    var lastChildren = lastContent != null ? null : lastProps.children;
    var nextChildren = nextContent != null ? null : nextProps.children;

    // If we're switching from children to content/html or vice versa, remove
    // the old content
    var lastHasContentOrHtml = lastContent != null || lastHtml != null;
    var nextHasContentOrHtml = nextContent != null || nextHtml != null;
    if (lastChildren != null && nextChildren == null) {
      this.updateChildren(null, transaction, context);
    } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
      this.updateTextContent('');
    }

    if (nextContent != null) {
      if (lastContent !== nextContent) {
        this.updateTextContent('' + nextContent);
      }
    } else if (nextHtml != null) {
      if (lastHtml !== nextHtml) {
        this.updateMarkup('' + nextHtml);
      }
    } else if (nextChildren != null) {
      this.updateChildren(nextChildren, transaction, context);
    }
  },

  /**
   * Destroys all event registrations for this instance. Does not remove from
   * the DOM. That must be done by the parent.
   *
   * @internal
   */
  unmountComponent: function () {
    switch (this._tag) {
      case 'iframe':
      case 'img':
      case 'form':
      case 'video':
      case 'audio':
        var listeners = this._wrapperState.listeners;
        if (listeners) {
          for (var i = 0; i < listeners.length; i++) {
            listeners[i].remove();
          }
        }
        break;
      case 'input':
        ReactDOMInput.unmountWrapper(this);
        break;
      case 'html':
      case 'head':
      case 'body':
        /**
         * Components like <html> <head> and <body> can't be removed or added
         * easily in a cross-browser way, however it's valuable to be able to
         * take advantage of React's reconciliation for styling and <title>
         * management. So we just document it and throw in dangerous cases.
         */
        !false ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is ' + 'impossible to unmount some top-level components (eg <html>, ' + '<head>, and <body>) reliably and efficiently. To fix this, have a ' + 'single top-level component that never unmounts render these ' + 'elements.', this._tag) : invariant(false) : undefined;
        break;
    }

    this.unmountChildren();
    ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
    ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
    this._rootNodeID = null;
    this._wrapperState = null;
    if (this._nodeWithLegacyProperties) {
      var node = this._nodeWithLegacyProperties;
      node._reactInternalComponent = null;
      this._nodeWithLegacyProperties = null;
    }
  },

  getPublicInstance: function () {
    if (!this._nodeWithLegacyProperties) {
      var node = ReactMount.getNode(this._rootNodeID);

      node._reactInternalComponent = this;
      node.getDOMNode = legacyGetDOMNode;
      node.isMounted = legacyIsMounted;
      node.setState = legacySetStateEtc;
      node.replaceState = legacySetStateEtc;
      node.forceUpdate = legacySetStateEtc;
      node.setProps = legacySetProps;
      node.replaceProps = legacyReplaceProps;

      if (process.env.NODE_ENV !== 'production') {
        if (canDefineProperty) {
          Object.defineProperties(node, legacyPropsDescriptor);
        } else {
          // updateComponent will update this property on subsequent renders
          node.props = this._currentElement.props;
        }
      } else {
        // updateComponent will update this property on subsequent renders
        node.props = this._currentElement.props;
      }

      this._nodeWithLegacyProperties = node;
    }
    return this._nodeWithLegacyProperties;
  }

};

ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
  mountComponent: 'mountComponent',
  updateComponent: 'updateComponent'
});

assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);

module.exports = ReactDOMComponent;
}).call(this,require('_process'))

},{"./AutoFocusUtils":397,"./CSSPropertyOperations":400,"./DOMProperty":405,"./DOMPropertyOperations":406,"./EventConstants":410,"./Object.assign":418,"./ReactBrowserEventEmitter":422,"./ReactComponentBrowserEnvironment":427,"./ReactDOMButton":432,"./ReactDOMInput":437,"./ReactDOMOption":438,"./ReactDOMSelect":439,"./ReactDOMTextarea":443,"./ReactMount":461,"./ReactMultiChild":462,"./ReactPerf":467,"./ReactUpdateQueue":478,"./canDefineProperty":500,"./escapeTextContentForBrowser":503,"./isEventSupported":515,"./setInnerHTML":520,"./setTextContent":521,"./validateDOMNesting":524,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/keyOf":322,"fbjs/lib/shallowEqual":327,"fbjs/lib/warning":329}],434:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMFactories
 * @typechecks static-only
 */

'use strict';

var ReactElement = require('./ReactElement');
var ReactElementValidator = require('./ReactElementValidator');

var mapObject = require('fbjs/lib/mapObject');

/**
 * Create a factory that creates HTML tag elements.
 *
 * @param {string} tag Tag name (e.g. `div`).
 * @private
 */
function createDOMFactory(tag) {
  if (process.env.NODE_ENV !== 'production') {
    return ReactElementValidator.createFactory(tag);
  }
  return ReactElement.createFactory(tag);
}

/**
 * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
 * This is also accessible via `React.DOM`.
 *
 * @public
 */
var ReactDOMFactories = mapObject({
  a: 'a',
  abbr: 'abbr',
  address: 'address',
  area: 'area',
  article: 'article',
  aside: 'aside',
  audio: 'audio',
  b: 'b',
  base: 'base',
  bdi: 'bdi',
  bdo: 'bdo',
  big: 'big',
  blockquote: 'blockquote',
  body: 'body',
  br: 'br',
  button: 'button',
  canvas: 'canvas',
  caption: 'caption',
  cite: 'cite',
  code: 'code',
  col: 'col',
  colgroup: 'colgroup',
  data: 'data',
  datalist: 'datalist',
  dd: 'dd',
  del: 'del',
  details: 'details',
  dfn: 'dfn',
  dialog: 'dialog',
  div: 'div',
  dl: 'dl',
  dt: 'dt',
  em: 'em',
  embed: 'embed',
  fieldset: 'fieldset',
  figcaption: 'figcaption',
  figure: 'figure',
  footer: 'footer',
  form: 'form',
  h1: 'h1',
  h2: 'h2',
  h3: 'h3',
  h4: 'h4',
  h5: 'h5',
  h6: 'h6',
  head: 'head',
  header: 'header',
  hgroup: 'hgroup',
  hr: 'hr',
  html: 'html',
  i: 'i',
  iframe: 'iframe',
  img: 'img',
  input: 'input',
  ins: 'ins',
  kbd: 'kbd',
  keygen: 'keygen',
  label: 'label',
  legend: 'legend',
  li: 'li',
  link: 'link',
  main: 'main',
  map: 'map',
  mark: 'mark',
  menu: 'menu',
  menuitem: 'menuitem',
  meta: 'meta',
  meter: 'meter',
  nav: 'nav',
  noscript: 'noscript',
  object: 'object',
  ol: 'ol',
  optgroup: 'optgroup',
  option: 'option',
  output: 'output',
  p: 'p',
  param: 'param',
  picture: 'picture',
  pre: 'pre',
  progress: 'progress',
  q: 'q',
  rp: 'rp',
  rt: 'rt',
  ruby: 'ruby',
  s: 's',
  samp: 'samp',
  script: 'script',
  section: 'section',
  select: 'select',
  small: 'small',
  source: 'source',
  span: 'span',
  strong: 'strong',
  style: 'style',
  sub: 'sub',
  summary: 'summary',
  sup: 'sup',
  table: 'table',
  tbody: 'tbody',
  td: 'td',
  textarea: 'textarea',
  tfoot: 'tfoot',
  th: 'th',
  thead: 'thead',
  time: 'time',
  title: 'title',
  tr: 'tr',
  track: 'track',
  u: 'u',
  ul: 'ul',
  'var': 'var',
  video: 'video',
  wbr: 'wbr',

  // SVG
  circle: 'circle',
  clipPath: 'clipPath',
  defs: 'defs',
  ellipse: 'ellipse',
  g: 'g',
  image: 'image',
  line: 'line',
  linearGradient: 'linearGradient',
  mask: 'mask',
  path: 'path',
  pattern: 'pattern',
  polygon: 'polygon',
  polyline: 'polyline',
  radialGradient: 'radialGradient',
  rect: 'rect',
  stop: 'stop',
  svg: 'svg',
  text: 'text',
  tspan: 'tspan'

}, createDOMFactory);

module.exports = ReactDOMFactories;
}).call(this,require('_process'))

},{"./ReactElement":448,"./ReactElementValidator":449,"_process":334,"fbjs/lib/mapObject":323}],435:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMFeatureFlags
 */

'use strict';

var ReactDOMFeatureFlags = {
  useCreateElement: false
};

module.exports = ReactDOMFeatureFlags;
},{}],436:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMIDOperations
 * @typechecks static-only
 */

'use strict';

var DOMChildrenOperations = require('./DOMChildrenOperations');
var DOMPropertyOperations = require('./DOMPropertyOperations');
var ReactMount = require('./ReactMount');
var ReactPerf = require('./ReactPerf');

var invariant = require('fbjs/lib/invariant');

/**
 * Errors for properties that should not be updated with `updatePropertyByID()`.
 *
 * @type {object}
 * @private
 */
var INVALID_PROPERTY_ERRORS = {
  dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
  style: '`style` must be set using `updateStylesByID()`.'
};

/**
 * Operations used to process updates to DOM nodes.
 */
var ReactDOMIDOperations = {

  /**
   * Updates a DOM node with new property values. This should only be used to
   * update DOM properties in `DOMProperty`.
   *
   * @param {string} id ID of the node to update.
   * @param {string} name A valid property name, see `DOMProperty`.
   * @param {*} value New value of the property.
   * @internal
   */
  updatePropertyByID: function (id, name, value) {
    var node = ReactMount.getNode(id);
    !!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;

    // If we're updating to null or undefined, we should remove the property
    // from the DOM node instead of inadvertantly setting to a string. This
    // brings us in line with the same behavior we have on initial render.
    if (value != null) {
      DOMPropertyOperations.setValueForProperty(node, name, value);
    } else {
      DOMPropertyOperations.deleteValueForProperty(node, name);
    }
  },

  /**
   * Replaces a DOM node that exists in the document with markup.
   *
   * @param {string} id ID of child to be replaced.
   * @param {string} markup Dangerous markup to inject in place of child.
   * @internal
   * @see {Danger.dangerouslyReplaceNodeWithMarkup}
   */
  dangerouslyReplaceNodeWithMarkupByID: function (id, markup) {
    var node = ReactMount.getNode(id);
    DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
  },

  /**
   * Updates a component's children by processing a series of updates.
   *
   * @param {array<object>} updates List of update configurations.
   * @param {array<string>} markup List of markup strings.
   * @internal
   */
  dangerouslyProcessChildrenUpdates: function (updates, markup) {
    for (var i = 0; i < updates.length; i++) {
      updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
    }
    DOMChildrenOperations.processUpdates(updates, markup);
  }
};

ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
  dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID',
  dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
});

module.exports = ReactDOMIDOperations;
}).call(this,require('_process'))

},{"./DOMChildrenOperations":404,"./DOMPropertyOperations":406,"./ReactMount":461,"./ReactPerf":467,"_process":334,"fbjs/lib/invariant":318}],437:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMInput
 */

'use strict';

var ReactDOMIDOperations = require('./ReactDOMIDOperations');
var LinkedValueUtils = require('./LinkedValueUtils');
var ReactMount = require('./ReactMount');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');

var instancesByReactID = {};

function forceUpdateIfMounted() {
  if (this._rootNodeID) {
    // DOM component is still mounted; update
    ReactDOMInput.updateWrapper(this);
  }
}

/**
 * Implements an <input> native component that allows setting these optional
 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
 *
 * If `checked` or `value` are not supplied (or null/undefined), user actions
 * that affect the checked state or value will trigger updates to the element.
 *
 * If they are supplied (and not null/undefined), the rendered element will not
 * trigger updates to the element. Instead, the props must change in order for
 * the rendered element to be updated.
 *
 * The rendered element will be initialized as unchecked (or `defaultChecked`)
 * with an empty value (or `defaultValue`).
 *
 * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
 */
var ReactDOMInput = {
  getNativeProps: function (inst, props, context) {
    var value = LinkedValueUtils.getValue(props);
    var checked = LinkedValueUtils.getChecked(props);

    var nativeProps = assign({}, props, {
      defaultChecked: undefined,
      defaultValue: undefined,
      value: value != null ? value : inst._wrapperState.initialValue,
      checked: checked != null ? checked : inst._wrapperState.initialChecked,
      onChange: inst._wrapperState.onChange
    });

    return nativeProps;
  },

  mountWrapper: function (inst, props) {
    if (process.env.NODE_ENV !== 'production') {
      LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);
    }

    var defaultValue = props.defaultValue;
    inst._wrapperState = {
      initialChecked: props.defaultChecked || false,
      initialValue: defaultValue != null ? defaultValue : null,
      onChange: _handleChange.bind(inst)
    };
  },

  mountReadyWrapper: function (inst) {
    // Can't be in mountWrapper or else server rendering leaks.
    instancesByReactID[inst._rootNodeID] = inst;
  },

  unmountWrapper: function (inst) {
    delete instancesByReactID[inst._rootNodeID];
  },

  updateWrapper: function (inst) {
    var props = inst._currentElement.props;

    // TODO: Shouldn't this be getChecked(props)?
    var checked = props.checked;
    if (checked != null) {
      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false);
    }

    var value = LinkedValueUtils.getValue(props);
    if (value != null) {
      // Cast `value` to a string to ensure the value is set correctly. While
      // browsers typically do this as necessary, jsdom doesn't.
      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
    }
  }
};

function _handleChange(event) {
  var props = this._currentElement.props;

  var returnValue = LinkedValueUtils.executeOnChange(props, event);

  // Here we use asap to wait until all updates have propagated, which
  // is important when using controlled components within layers:
  // https://github.com/facebook/react/issues/1698
  ReactUpdates.asap(forceUpdateIfMounted, this);

  var name = props.name;
  if (props.type === 'radio' && name != null) {
    var rootNode = ReactMount.getNode(this._rootNodeID);
    var queryRoot = rootNode;

    while (queryRoot.parentNode) {
      queryRoot = queryRoot.parentNode;
    }

    // If `rootNode.form` was non-null, then we could try `form.elements`,
    // but that sometimes behaves strangely in IE8. We could also try using
    // `form.getElementsByName`, but that will only return direct children
    // and won't include inputs that use the HTML5 `form=` attribute. Since
    // the input might not even be in a form, let's just use the global
    // `querySelectorAll` to ensure we don't miss anything.
    var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');

    for (var i = 0; i < group.length; i++) {
      var otherNode = group[i];
      if (otherNode === rootNode || otherNode.form !== rootNode.form) {
        continue;
      }
      // This will throw if radio buttons rendered by different copies of React
      // and the same name are rendered into the same form (same as #1939).
      // That's probably okay; we don't support it just as we don't support
      // mixing React with non-React.
      var otherID = ReactMount.getID(otherNode);
      !otherID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined;
      var otherInstance = instancesByReactID[otherID];
      !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined;
      // If this is a controlled radio button group, forcing the input that
      // was previously checked to update will cause it to be come re-checked
      // as appropriate.
      ReactUpdates.asap(forceUpdateIfMounted, otherInstance);
    }
  }

  return returnValue;
}

module.exports = ReactDOMInput;
}).call(this,require('_process'))

},{"./LinkedValueUtils":417,"./Object.assign":418,"./ReactDOMIDOperations":436,"./ReactMount":461,"./ReactUpdates":479,"_process":334,"fbjs/lib/invariant":318}],438:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMOption
 */

'use strict';

var ReactChildren = require('./ReactChildren');
var ReactDOMSelect = require('./ReactDOMSelect');

var assign = require('./Object.assign');
var warning = require('fbjs/lib/warning');

var valueContextKey = ReactDOMSelect.valueContextKey;

/**
 * Implements an <option> native component that warns when `selected` is set.
 */
var ReactDOMOption = {
  mountWrapper: function (inst, props, context) {
    // TODO (yungsters): Remove support for `selected` in <option>.
    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined;
    }

    // Look up whether this option is 'selected' via context
    var selectValue = context[valueContextKey];

    // If context key is null (e.g., no specified value or after initial mount)
    // or missing (e.g., for <datalist>), we don't change props.selected
    var selected = null;
    if (selectValue != null) {
      selected = false;
      if (Array.isArray(selectValue)) {
        // multiple
        for (var i = 0; i < selectValue.length; i++) {
          if ('' + selectValue[i] === '' + props.value) {
            selected = true;
            break;
          }
        }
      } else {
        selected = '' + selectValue === '' + props.value;
      }
    }

    inst._wrapperState = { selected: selected };
  },

  getNativeProps: function (inst, props, context) {
    var nativeProps = assign({ selected: undefined, children: undefined }, props);

    // Read state only from initial mount because <select> updates value
    // manually; we need the initial state only for server rendering
    if (inst._wrapperState.selected != null) {
      nativeProps.selected = inst._wrapperState.selected;
    }

    var content = '';

    // Flatten children and warn if they aren't strings or numbers;
    // invalid types are ignored.
    ReactChildren.forEach(props.children, function (child) {
      if (child == null) {
        return;
      }
      if (typeof child === 'string' || typeof child === 'number') {
        content += child;
      } else {
        process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined;
      }
    });

    if (content) {
      nativeProps.children = content;
    }

    return nativeProps;
  }

};

module.exports = ReactDOMOption;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactChildren":424,"./ReactDOMSelect":439,"_process":334,"fbjs/lib/warning":329}],439:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMSelect
 */

'use strict';

var LinkedValueUtils = require('./LinkedValueUtils');
var ReactMount = require('./ReactMount');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var warning = require('fbjs/lib/warning');

var valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);

function updateOptionsIfPendingUpdateAndMounted() {
  if (this._rootNodeID && this._wrapperState.pendingUpdate) {
    this._wrapperState.pendingUpdate = false;

    var props = this._currentElement.props;
    var value = LinkedValueUtils.getValue(props);

    if (value != null) {
      updateOptions(this, Boolean(props.multiple), value);
    }
  }
}

function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

var valuePropNames = ['value', 'defaultValue'];

/**
 * Validation function for `value` and `defaultValue`.
 * @private
 */
function checkSelectPropTypes(inst, props) {
  var owner = inst._currentElement._owner;
  LinkedValueUtils.checkPropTypes('select', props, owner);

  for (var i = 0; i < valuePropNames.length; i++) {
    var propName = valuePropNames[i];
    if (props[propName] == null) {
      continue;
    }
    if (props.multiple) {
      process.env.NODE_ENV !== 'production' ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;
    } else {
      process.env.NODE_ENV !== 'production' ? warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;
    }
  }
}

/**
 * @param {ReactDOMComponent} inst
 * @param {boolean} multiple
 * @param {*} propValue A stringable (with `multiple`, a list of stringables).
 * @private
 */
function updateOptions(inst, multiple, propValue) {
  var selectedValue, i;
  var options = ReactMount.getNode(inst._rootNodeID).options;

  if (multiple) {
    selectedValue = {};
    for (i = 0; i < propValue.length; i++) {
      selectedValue['' + propValue[i]] = true;
    }
    for (i = 0; i < options.length; i++) {
      var selected = selectedValue.hasOwnProperty(options[i].value);
      if (options[i].selected !== selected) {
        options[i].selected = selected;
      }
    }
  } else {
    // Do not set `select.value` as exact behavior isn't consistent across all
    // browsers for all cases.
    selectedValue = '' + propValue;
    for (i = 0; i < options.length; i++) {
      if (options[i].value === selectedValue) {
        options[i].selected = true;
        return;
      }
    }
    if (options.length) {
      options[0].selected = true;
    }
  }
}

/**
 * Implements a <select> native component that allows optionally setting the
 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
 * stringable. If `multiple` is true, the prop must be an array of stringables.
 *
 * If `value` is not supplied (or null/undefined), user actions that change the
 * selected option will trigger updates to the rendered options.
 *
 * If it is supplied (and not null/undefined), the rendered options will not
 * update in response to user actions. Instead, the `value` prop must change in
 * order for the rendered options to update.
 *
 * If `defaultValue` is provided, any options with the supplied values will be
 * selected.
 */
var ReactDOMSelect = {
  valueContextKey: valueContextKey,

  getNativeProps: function (inst, props, context) {
    return assign({}, props, {
      onChange: inst._wrapperState.onChange,
      value: undefined
    });
  },

  mountWrapper: function (inst, props) {
    if (process.env.NODE_ENV !== 'production') {
      checkSelectPropTypes(inst, props);
    }

    var value = LinkedValueUtils.getValue(props);
    inst._wrapperState = {
      pendingUpdate: false,
      initialValue: value != null ? value : props.defaultValue,
      onChange: _handleChange.bind(inst),
      wasMultiple: Boolean(props.multiple)
    };
  },

  processChildContext: function (inst, props, context) {
    // Pass down initial value so initial generated markup has correct
    // `selected` attributes
    var childContext = assign({}, context);
    childContext[valueContextKey] = inst._wrapperState.initialValue;
    return childContext;
  },

  postUpdateWrapper: function (inst) {
    var props = inst._currentElement.props;

    // After the initial mount, we control selected-ness manually so don't pass
    // the context value down
    inst._wrapperState.initialValue = undefined;

    var wasMultiple = inst._wrapperState.wasMultiple;
    inst._wrapperState.wasMultiple = Boolean(props.multiple);

    var value = LinkedValueUtils.getValue(props);
    if (value != null) {
      inst._wrapperState.pendingUpdate = false;
      updateOptions(inst, Boolean(props.multiple), value);
    } else if (wasMultiple !== Boolean(props.multiple)) {
      // For simplicity, reapply `defaultValue` if `multiple` is toggled.
      if (props.defaultValue != null) {
        updateOptions(inst, Boolean(props.multiple), props.defaultValue);
      } else {
        // Revert the select back to its default unselected state.
        updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : '');
      }
    }
  }
};

function _handleChange(event) {
  var props = this._currentElement.props;
  var returnValue = LinkedValueUtils.executeOnChange(props, event);

  this._wrapperState.pendingUpdate = true;
  ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
  return returnValue;
}

module.exports = ReactDOMSelect;
}).call(this,require('_process'))

},{"./LinkedValueUtils":417,"./Object.assign":418,"./ReactMount":461,"./ReactUpdates":479,"_process":334,"fbjs/lib/warning":329}],440:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMSelection
 */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var getNodeForCharacterOffset = require('./getNodeForCharacterOffset');
var getTextContentAccessor = require('./getTextContentAccessor');

/**
 * While `isCollapsed` is available on the Selection object and `collapsed`
 * is available on the Range object, IE11 sometimes gets them wrong.
 * If the anchor/focus nodes and offsets are the same, the range is collapsed.
 */
function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) {
  return anchorNode === focusNode && anchorOffset === focusOffset;
}

/**
 * Get the appropriate anchor and focus node/offset pairs for IE.
 *
 * The catch here is that IE's selection API doesn't provide information
 * about whether the selection is forward or backward, so we have to
 * behave as though it's always forward.
 *
 * IE text differs from modern selection in that it behaves as though
 * block elements end with a new line. This means character offsets will
 * differ between the two APIs.
 *
 * @param {DOMElement} node
 * @return {object}
 */
function getIEOffsets(node) {
  var selection = document.selection;
  var selectedRange = selection.createRange();
  var selectedLength = selectedRange.text.length;

  // Duplicate selection so we can move range without breaking user selection.
  var fromStart = selectedRange.duplicate();
  fromStart.moveToElementText(node);
  fromStart.setEndPoint('EndToStart', selectedRange);

  var startOffset = fromStart.text.length;
  var endOffset = startOffset + selectedLength;

  return {
    start: startOffset,
    end: endOffset
  };
}

/**
 * @param {DOMElement} node
 * @return {?object}
 */
function getModernOffsets(node) {
  var selection = window.getSelection && window.getSelection();

  if (!selection || selection.rangeCount === 0) {
    return null;
  }

  var anchorNode = selection.anchorNode;
  var anchorOffset = selection.anchorOffset;
  var focusNode = selection.focusNode;
  var focusOffset = selection.focusOffset;

  var currentRange = selection.getRangeAt(0);

  // In Firefox, range.startContainer and range.endContainer can be "anonymous
  // divs", e.g. the up/down buttons on an <input type="number">. Anonymous
  // divs do not seem to expose properties, triggering a "Permission denied
  // error" if any of its properties are accessed. The only seemingly possible
  // way to avoid erroring is to access a property that typically works for
  // non-anonymous divs and catch any error that may otherwise arise. See
  // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
  try {
    /* eslint-disable no-unused-expressions */
    currentRange.startContainer.nodeType;
    currentRange.endContainer.nodeType;
    /* eslint-enable no-unused-expressions */
  } catch (e) {
    return null;
  }

  // If the node and offset values are the same, the selection is collapsed.
  // `Selection.isCollapsed` is available natively, but IE sometimes gets
  // this value wrong.
  var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);

  var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length;

  var tempRange = currentRange.cloneRange();
  tempRange.selectNodeContents(node);
  tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);

  var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset);

  var start = isTempRangeCollapsed ? 0 : tempRange.toString().length;
  var end = start + rangeLength;

  // Detect whether the selection is backward.
  var detectionRange = document.createRange();
  detectionRange.setStart(anchorNode, anchorOffset);
  detectionRange.setEnd(focusNode, focusOffset);
  var isBackward = detectionRange.collapsed;

  return {
    start: isBackward ? end : start,
    end: isBackward ? start : end
  };
}

/**
 * @param {DOMElement|DOMTextNode} node
 * @param {object} offsets
 */
function setIEOffsets(node, offsets) {
  var range = document.selection.createRange().duplicate();
  var start, end;

  if (typeof offsets.end === 'undefined') {
    start = offsets.start;
    end = start;
  } else if (offsets.start > offsets.end) {
    start = offsets.end;
    end = offsets.start;
  } else {
    start = offsets.start;
    end = offsets.end;
  }

  range.moveToElementText(node);
  range.moveStart('character', start);
  range.setEndPoint('EndToStart', range);
  range.moveEnd('character', end - start);
  range.select();
}

/**
 * In modern non-IE browsers, we can support both forward and backward
 * selections.
 *
 * Note: IE10+ supports the Selection object, but it does not support
 * the `extend` method, which means that even in modern IE, it's not possible
 * to programatically create a backward selection. Thus, for all IE
 * versions, we use the old IE API to create our selections.
 *
 * @param {DOMElement|DOMTextNode} node
 * @param {object} offsets
 */
function setModernOffsets(node, offsets) {
  if (!window.getSelection) {
    return;
  }

  var selection = window.getSelection();
  var length = node[getTextContentAccessor()].length;
  var start = Math.min(offsets.start, length);
  var end = typeof offsets.end === 'undefined' ? start : Math.min(offsets.end, length);

  // IE 11 uses modern selection, but doesn't support the extend method.
  // Flip backward selections, so we can set with a single range.
  if (!selection.extend && start > end) {
    var temp = end;
    end = start;
    start = temp;
  }

  var startMarker = getNodeForCharacterOffset(node, start);
  var endMarker = getNodeForCharacterOffset(node, end);

  if (startMarker && endMarker) {
    var range = document.createRange();
    range.setStart(startMarker.node, startMarker.offset);
    selection.removeAllRanges();

    if (start > end) {
      selection.addRange(range);
      selection.extend(endMarker.node, endMarker.offset);
    } else {
      range.setEnd(endMarker.node, endMarker.offset);
      selection.addRange(range);
    }
  }
}

var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window);

var ReactDOMSelection = {
  /**
   * @param {DOMElement} node
   */
  getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets,

  /**
   * @param {DOMElement|DOMTextNode} node
   * @param {object} offsets
   */
  setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets
};

module.exports = ReactDOMSelection;
},{"./getNodeForCharacterOffset":512,"./getTextContentAccessor":513,"fbjs/lib/ExecutionEnvironment":304}],441:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMServer
 */

'use strict';

var ReactDefaultInjection = require('./ReactDefaultInjection');
var ReactServerRendering = require('./ReactServerRendering');
var ReactVersion = require('./ReactVersion');

ReactDefaultInjection.inject();

var ReactDOMServer = {
  renderToString: ReactServerRendering.renderToString,
  renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup,
  version: ReactVersion
};

module.exports = ReactDOMServer;
},{"./ReactDefaultInjection":445,"./ReactServerRendering":476,"./ReactVersion":480}],442:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMTextComponent
 * @typechecks static-only
 */

'use strict';

var DOMChildrenOperations = require('./DOMChildrenOperations');
var DOMPropertyOperations = require('./DOMPropertyOperations');
var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');
var ReactMount = require('./ReactMount');

var assign = require('./Object.assign');
var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
var setTextContent = require('./setTextContent');
var validateDOMNesting = require('./validateDOMNesting');

/**
 * Text nodes violate a couple assumptions that React makes about components:
 *
 *  - When mounting text into the DOM, adjacent text nodes are merged.
 *  - Text nodes cannot be assigned a React root ID.
 *
 * This component is used to wrap strings in elements so that they can undergo
 * the same reconciliation that is applied to elements.
 *
 * TODO: Investigate representing React components in the DOM with text nodes.
 *
 * @class ReactDOMTextComponent
 * @extends ReactComponent
 * @internal
 */
var ReactDOMTextComponent = function (props) {
  // This constructor and its argument is currently used by mocks.
};

assign(ReactDOMTextComponent.prototype, {

  /**
   * @param {ReactText} text
   * @internal
   */
  construct: function (text) {
    // TODO: This is really a ReactText (ReactNode), not a ReactElement
    this._currentElement = text;
    this._stringText = '' + text;

    // Properties
    this._rootNodeID = null;
    this._mountIndex = 0;
  },

  /**
   * Creates the markup for this text node. This node is not intended to have
   * any features besides containing text content.
   *
   * @param {string} rootID DOM ID of the root node.
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @return {string} Markup for this text node.
   * @internal
   */
  mountComponent: function (rootID, transaction, context) {
    if (process.env.NODE_ENV !== 'production') {
      if (context[validateDOMNesting.ancestorInfoContextKey]) {
        validateDOMNesting('span', null, context[validateDOMNesting.ancestorInfoContextKey]);
      }
    }

    this._rootNodeID = rootID;
    if (transaction.useCreateElement) {
      var ownerDocument = context[ReactMount.ownerDocumentContextKey];
      var el = ownerDocument.createElement('span');
      DOMPropertyOperations.setAttributeForID(el, rootID);
      // Populate node cache
      ReactMount.getID(el);
      setTextContent(el, this._stringText);
      return el;
    } else {
      var escapedText = escapeTextContentForBrowser(this._stringText);

      if (transaction.renderToStaticMarkup) {
        // Normally we'd wrap this in a `span` for the reasons stated above, but
        // since this is a situation where React won't take over (static pages),
        // we can simply return the text as it is.
        return escapedText;
      }

      return '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + escapedText + '</span>';
    }
  },

  /**
   * Updates this component by updating the text content.
   *
   * @param {ReactText} nextText The next text content
   * @param {ReactReconcileTransaction} transaction
   * @internal
   */
  receiveComponent: function (nextText, transaction) {
    if (nextText !== this._currentElement) {
      this._currentElement = nextText;
      var nextStringText = '' + nextText;
      if (nextStringText !== this._stringText) {
        // TODO: Save this as pending props and use performUpdateIfNecessary
        // and/or updateComponent to do the actual update for consistency with
        // other component types?
        this._stringText = nextStringText;
        var node = ReactMount.getNode(this._rootNodeID);
        DOMChildrenOperations.updateTextContent(node, nextStringText);
      }
    }
  },

  unmountComponent: function () {
    ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
  }

});

module.exports = ReactDOMTextComponent;
}).call(this,require('_process'))

},{"./DOMChildrenOperations":404,"./DOMPropertyOperations":406,"./Object.assign":418,"./ReactComponentBrowserEnvironment":427,"./ReactMount":461,"./escapeTextContentForBrowser":503,"./setTextContent":521,"./validateDOMNesting":524,"_process":334}],443:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDOMTextarea
 */

'use strict';

var LinkedValueUtils = require('./LinkedValueUtils');
var ReactDOMIDOperations = require('./ReactDOMIDOperations');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

function forceUpdateIfMounted() {
  if (this._rootNodeID) {
    // DOM component is still mounted; update
    ReactDOMTextarea.updateWrapper(this);
  }
}

/**
 * Implements a <textarea> native component that allows setting `value`, and
 * `defaultValue`. This differs from the traditional DOM API because value is
 * usually set as PCDATA children.
 *
 * If `value` is not supplied (or null/undefined), user actions that affect the
 * value will trigger updates to the element.
 *
 * If `value` is supplied (and not null/undefined), the rendered element will
 * not trigger updates to the element. Instead, the `value` prop must change in
 * order for the rendered element to be updated.
 *
 * The rendered element will be initialized with an empty value, the prop
 * `defaultValue` if specified, or the children content (deprecated).
 */
var ReactDOMTextarea = {
  getNativeProps: function (inst, props, context) {
    !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;

    // Always set children to the same thing. In IE9, the selection range will
    // get reset if `textContent` is mutated.
    var nativeProps = assign({}, props, {
      defaultValue: undefined,
      value: undefined,
      children: inst._wrapperState.initialValue,
      onChange: inst._wrapperState.onChange
    });

    return nativeProps;
  },

  mountWrapper: function (inst, props) {
    if (process.env.NODE_ENV !== 'production') {
      LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);
    }

    var defaultValue = props.defaultValue;
    // TODO (yungsters): Remove support for children content in <textarea>.
    var children = props.children;
    if (children != null) {
      if (process.env.NODE_ENV !== 'production') {
        process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : undefined;
      }
      !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : invariant(false) : undefined;
      if (Array.isArray(children)) {
        !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : invariant(false) : undefined;
        children = children[0];
      }

      defaultValue = '' + children;
    }
    if (defaultValue == null) {
      defaultValue = '';
    }
    var value = LinkedValueUtils.getValue(props);

    inst._wrapperState = {
      // We save the initial value so that `ReactDOMComponent` doesn't update
      // `textContent` (unnecessary since we update value).
      // The initial value can be a boolean or object so that's why it's
      // forced to be a string.
      initialValue: '' + (value != null ? value : defaultValue),
      onChange: _handleChange.bind(inst)
    };
  },

  updateWrapper: function (inst) {
    var props = inst._currentElement.props;
    var value = LinkedValueUtils.getValue(props);
    if (value != null) {
      // Cast `value` to a string to ensure the value is set correctly. While
      // browsers typically do this as necessary, jsdom doesn't.
      ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
    }
  }
};

function _handleChange(event) {
  var props = this._currentElement.props;
  var returnValue = LinkedValueUtils.executeOnChange(props, event);
  ReactUpdates.asap(forceUpdateIfMounted, this);
  return returnValue;
}

module.exports = ReactDOMTextarea;
}).call(this,require('_process'))

},{"./LinkedValueUtils":417,"./Object.assign":418,"./ReactDOMIDOperations":436,"./ReactUpdates":479,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],444:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDefaultBatchingStrategy
 */

'use strict';

var ReactUpdates = require('./ReactUpdates');
var Transaction = require('./Transaction');

var assign = require('./Object.assign');
var emptyFunction = require('fbjs/lib/emptyFunction');

var RESET_BATCHED_UPDATES = {
  initialize: emptyFunction,
  close: function () {
    ReactDefaultBatchingStrategy.isBatchingUpdates = false;
  }
};

var FLUSH_BATCHED_UPDATES = {
  initialize: emptyFunction,
  close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
};

var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];

function ReactDefaultBatchingStrategyTransaction() {
  this.reinitializeTransaction();
}

assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction.Mixin, {
  getTransactionWrappers: function () {
    return TRANSACTION_WRAPPERS;
  }
});

var transaction = new ReactDefaultBatchingStrategyTransaction();

var ReactDefaultBatchingStrategy = {
  isBatchingUpdates: false,

  /**
   * Call the provided function in a context within which calls to `setState`
   * and friends are batched such that components aren't updated unnecessarily.
   */
  batchedUpdates: function (callback, a, b, c, d, e) {
    var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;

    ReactDefaultBatchingStrategy.isBatchingUpdates = true;

    // The code is written this way to avoid extra allocations
    if (alreadyBatchingUpdates) {
      callback(a, b, c, d, e);
    } else {
      transaction.perform(callback, null, a, b, c, d, e);
    }
  }
};

module.exports = ReactDefaultBatchingStrategy;
},{"./Object.assign":418,"./ReactUpdates":479,"./Transaction":496,"fbjs/lib/emptyFunction":310}],445:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDefaultInjection
 */

'use strict';

var BeforeInputEventPlugin = require('./BeforeInputEventPlugin');
var ChangeEventPlugin = require('./ChangeEventPlugin');
var ClientReactRootIndex = require('./ClientReactRootIndex');
var DefaultEventPluginOrder = require('./DefaultEventPluginOrder');
var EnterLeaveEventPlugin = require('./EnterLeaveEventPlugin');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var HTMLDOMPropertyConfig = require('./HTMLDOMPropertyConfig');
var ReactBrowserComponentMixin = require('./ReactBrowserComponentMixin');
var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');
var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');
var ReactDOMComponent = require('./ReactDOMComponent');
var ReactDOMTextComponent = require('./ReactDOMTextComponent');
var ReactEventListener = require('./ReactEventListener');
var ReactInjection = require('./ReactInjection');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactMount = require('./ReactMount');
var ReactReconcileTransaction = require('./ReactReconcileTransaction');
var SelectEventPlugin = require('./SelectEventPlugin');
var ServerReactRootIndex = require('./ServerReactRootIndex');
var SimpleEventPlugin = require('./SimpleEventPlugin');
var SVGDOMPropertyConfig = require('./SVGDOMPropertyConfig');

var alreadyInjected = false;

function inject() {
  if (alreadyInjected) {
    // TODO: This is currently true because these injections are shared between
    // the client and the server package. They should be built independently
    // and not share any injection state. Then this problem will be solved.
    return;
  }
  alreadyInjected = true;

  ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener);

  /**
   * Inject modules for resolving DOM hierarchy and plugin ordering.
   */
  ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
  ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles);
  ReactInjection.EventPluginHub.injectMount(ReactMount);

  /**
   * Some important event plugins included by default (without having to require
   * them).
   */
  ReactInjection.EventPluginHub.injectEventPluginsByName({
    SimpleEventPlugin: SimpleEventPlugin,
    EnterLeaveEventPlugin: EnterLeaveEventPlugin,
    ChangeEventPlugin: ChangeEventPlugin,
    SelectEventPlugin: SelectEventPlugin,
    BeforeInputEventPlugin: BeforeInputEventPlugin
  });

  ReactInjection.NativeComponent.injectGenericComponentClass(ReactDOMComponent);

  ReactInjection.NativeComponent.injectTextComponentClass(ReactDOMTextComponent);

  ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);

  ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
  ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);

  ReactInjection.EmptyComponent.injectEmptyComponent('noscript');

  ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction);
  ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy);

  ReactInjection.RootIndex.injectCreateReactRootIndex(ExecutionEnvironment.canUseDOM ? ClientReactRootIndex.createReactRootIndex : ServerReactRootIndex.createReactRootIndex);

  ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);

  if (process.env.NODE_ENV !== 'production') {
    var url = ExecutionEnvironment.canUseDOM && window.location.href || '';
    if (/[?&]react_perf\b/.test(url)) {
      var ReactDefaultPerf = require('./ReactDefaultPerf');
      ReactDefaultPerf.start();
    }
  }
}

module.exports = {
  inject: inject
};
}).call(this,require('_process'))

},{"./BeforeInputEventPlugin":398,"./ChangeEventPlugin":402,"./ClientReactRootIndex":403,"./DefaultEventPluginOrder":408,"./EnterLeaveEventPlugin":409,"./HTMLDOMPropertyConfig":416,"./ReactBrowserComponentMixin":421,"./ReactComponentBrowserEnvironment":427,"./ReactDOMComponent":433,"./ReactDOMTextComponent":442,"./ReactDefaultBatchingStrategy":444,"./ReactDefaultPerf":446,"./ReactEventListener":454,"./ReactInjection":455,"./ReactInstanceHandles":457,"./ReactMount":461,"./ReactReconcileTransaction":471,"./SVGDOMPropertyConfig":481,"./SelectEventPlugin":482,"./ServerReactRootIndex":483,"./SimpleEventPlugin":484,"_process":334,"fbjs/lib/ExecutionEnvironment":304}],446:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDefaultPerf
 * @typechecks static-only
 */

'use strict';

var DOMProperty = require('./DOMProperty');
var ReactDefaultPerfAnalysis = require('./ReactDefaultPerfAnalysis');
var ReactMount = require('./ReactMount');
var ReactPerf = require('./ReactPerf');

var performanceNow = require('fbjs/lib/performanceNow');

function roundFloat(val) {
  return Math.floor(val * 100) / 100;
}

function addValue(obj, key, val) {
  obj[key] = (obj[key] || 0) + val;
}

var ReactDefaultPerf = {
  _allMeasurements: [], // last item in the list is the current one
  _mountStack: [0],
  _injected: false,

  start: function () {
    if (!ReactDefaultPerf._injected) {
      ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
    }

    ReactDefaultPerf._allMeasurements.length = 0;
    ReactPerf.enableMeasure = true;
  },

  stop: function () {
    ReactPerf.enableMeasure = false;
  },

  getLastMeasurements: function () {
    return ReactDefaultPerf._allMeasurements;
  },

  printExclusive: function (measurements) {
    measurements = measurements || ReactDefaultPerf._allMeasurements;
    var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements);
    console.table(summary.map(function (item) {
      return {
        'Component class name': item.componentName,
        'Total inclusive time (ms)': roundFloat(item.inclusive),
        'Exclusive mount time (ms)': roundFloat(item.exclusive),
        'Exclusive render time (ms)': roundFloat(item.render),
        'Mount time per instance (ms)': roundFloat(item.exclusive / item.count),
        'Render time per instance (ms)': roundFloat(item.render / item.count),
        'Instances': item.count
      };
    }));
    // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct
    // number.
  },

  printInclusive: function (measurements) {
    measurements = measurements || ReactDefaultPerf._allMeasurements;
    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements);
    console.table(summary.map(function (item) {
      return {
        'Owner > component': item.componentName,
        'Inclusive time (ms)': roundFloat(item.time),
        'Instances': item.count
      };
    }));
    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');
  },

  getMeasurementsSummaryMap: function (measurements) {
    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements, true);
    return summary.map(function (item) {
      return {
        'Owner > component': item.componentName,
        'Wasted time (ms)': item.time,
        'Instances': item.count
      };
    });
  },

  printWasted: function (measurements) {
    measurements = measurements || ReactDefaultPerf._allMeasurements;
    console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements));
    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');
  },

  printDOM: function (measurements) {
    measurements = measurements || ReactDefaultPerf._allMeasurements;
    var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements);
    console.table(summary.map(function (item) {
      var result = {};
      result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id;
      result.type = item.type;
      result.args = JSON.stringify(item.args);
      return result;
    }));
    console.log('Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms');
  },

  _recordWrite: function (id, fnName, totalTime, args) {
    // TODO: totalTime isn't that useful since it doesn't count paints/reflows
    var writes = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].writes;
    writes[id] = writes[id] || [];
    writes[id].push({
      type: fnName,
      time: totalTime,
      args: args
    });
  },

  measure: function (moduleName, fnName, func) {
    return function () {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      var totalTime;
      var rv;
      var start;

      if (fnName === '_renderNewRootComponent' || fnName === 'flushBatchedUpdates') {
        // A "measurement" is a set of metrics recorded for each flush. We want
        // to group the metrics for a given flush together so we can look at the
        // components that rendered and the DOM operations that actually
        // happened to determine the amount of "wasted work" performed.
        ReactDefaultPerf._allMeasurements.push({
          exclusive: {},
          inclusive: {},
          render: {},
          counts: {},
          writes: {},
          displayNames: {},
          totalTime: 0,
          created: {}
        });
        start = performanceNow();
        rv = func.apply(this, args);
        ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].totalTime = performanceNow() - start;
        return rv;
      } else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactBrowserEventEmitter' || moduleName === 'ReactDOMIDOperations' || moduleName === 'CSSPropertyOperations' || moduleName === 'DOMChildrenOperations' || moduleName === 'DOMPropertyOperations') {
        start = performanceNow();
        rv = func.apply(this, args);
        totalTime = performanceNow() - start;

        if (fnName === '_mountImageIntoNode') {
          var mountID = ReactMount.getID(args[1]);
          ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
        } else if (fnName === 'dangerouslyProcessChildrenUpdates') {
          // special format
          args[0].forEach(function (update) {
            var writeArgs = {};
            if (update.fromIndex !== null) {
              writeArgs.fromIndex = update.fromIndex;
            }
            if (update.toIndex !== null) {
              writeArgs.toIndex = update.toIndex;
            }
            if (update.textContent !== null) {
              writeArgs.textContent = update.textContent;
            }
            if (update.markupIndex !== null) {
              writeArgs.markup = args[1][update.markupIndex];
            }
            ReactDefaultPerf._recordWrite(update.parentID, update.type, totalTime, writeArgs);
          });
        } else {
          // basic format
          var id = args[0];
          if (typeof id === 'object') {
            id = ReactMount.getID(args[0]);
          }
          ReactDefaultPerf._recordWrite(id, fnName, totalTime, Array.prototype.slice.call(args, 1));
        }
        return rv;
      } else if (moduleName === 'ReactCompositeComponent' && (fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()?
      fnName === '_renderValidatedComponent')) {

        if (this._currentElement.type === ReactMount.TopLevelWrapper) {
          return func.apply(this, args);
        }

        var rootNodeID = fnName === 'mountComponent' ? args[0] : this._rootNodeID;
        var isRender = fnName === '_renderValidatedComponent';
        var isMount = fnName === 'mountComponent';

        var mountStack = ReactDefaultPerf._mountStack;
        var entry = ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1];

        if (isRender) {
          addValue(entry.counts, rootNodeID, 1);
        } else if (isMount) {
          entry.created[rootNodeID] = true;
          mountStack.push(0);
        }

        start = performanceNow();
        rv = func.apply(this, args);
        totalTime = performanceNow() - start;

        if (isRender) {
          addValue(entry.render, rootNodeID, totalTime);
        } else if (isMount) {
          var subMountTime = mountStack.pop();
          mountStack[mountStack.length - 1] += totalTime;
          addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);
          addValue(entry.inclusive, rootNodeID, totalTime);
        } else {
          addValue(entry.inclusive, rootNodeID, totalTime);
        }

        entry.displayNames[rootNodeID] = {
          current: this.getName(),
          owner: this._currentElement._owner ? this._currentElement._owner.getName() : '<root>'
        };

        return rv;
      } else {
        return func.apply(this, args);
      }
    };
  }
};

module.exports = ReactDefaultPerf;
},{"./DOMProperty":405,"./ReactDefaultPerfAnalysis":447,"./ReactMount":461,"./ReactPerf":467,"fbjs/lib/performanceNow":326}],447:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactDefaultPerfAnalysis
 */

'use strict';

var assign = require('./Object.assign');

// Don't try to save users less than 1.2ms (a number I made up)
var DONT_CARE_THRESHOLD = 1.2;
var DOM_OPERATION_TYPES = {
  '_mountImageIntoNode': 'set innerHTML',
  INSERT_MARKUP: 'set innerHTML',
  MOVE_EXISTING: 'move',
  REMOVE_NODE: 'remove',
  SET_MARKUP: 'set innerHTML',
  TEXT_CONTENT: 'set textContent',
  'setValueForProperty': 'update attribute',
  'setValueForAttribute': 'update attribute',
  'deleteValueForProperty': 'remove attribute',
  'setValueForStyles': 'update styles',
  'replaceNodeWithMarkup': 'replace',
  'updateTextContent': 'set textContent'
};

function getTotalTime(measurements) {
  // TODO: return number of DOM ops? could be misleading.
  // TODO: measure dropped frames after reconcile?
  // TODO: log total time of each reconcile and the top-level component
  // class that triggered it.
  var totalTime = 0;
  for (var i = 0; i < measurements.length; i++) {
    var measurement = measurements[i];
    totalTime += measurement.totalTime;
  }
  return totalTime;
}

function getDOMSummary(measurements) {
  var items = [];
  measurements.forEach(function (measurement) {
    Object.keys(measurement.writes).forEach(function (id) {
      measurement.writes[id].forEach(function (write) {
        items.push({
          id: id,
          type: DOM_OPERATION_TYPES[write.type] || write.type,
          args: write.args
        });
      });
    });
  });
  return items;
}

function getExclusiveSummary(measurements) {
  var candidates = {};
  var displayName;

  for (var i = 0; i < measurements.length; i++) {
    var measurement = measurements[i];
    var allIDs = assign({}, measurement.exclusive, measurement.inclusive);

    for (var id in allIDs) {
      displayName = measurement.displayNames[id].current;

      candidates[displayName] = candidates[displayName] || {
        componentName: displayName,
        inclusive: 0,
        exclusive: 0,
        render: 0,
        count: 0
      };
      if (measurement.render[id]) {
        candidates[displayName].render += measurement.render[id];
      }
      if (measurement.exclusive[id]) {
        candidates[displayName].exclusive += measurement.exclusive[id];
      }
      if (measurement.inclusive[id]) {
        candidates[displayName].inclusive += measurement.inclusive[id];
      }
      if (measurement.counts[id]) {
        candidates[displayName].count += measurement.counts[id];
      }
    }
  }

  // Now make a sorted array with the results.
  var arr = [];
  for (displayName in candidates) {
    if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
      arr.push(candidates[displayName]);
    }
  }

  arr.sort(function (a, b) {
    return b.exclusive - a.exclusive;
  });

  return arr;
}

function getInclusiveSummary(measurements, onlyClean) {
  var candidates = {};
  var inclusiveKey;

  for (var i = 0; i < measurements.length; i++) {
    var measurement = measurements[i];
    var allIDs = assign({}, measurement.exclusive, measurement.inclusive);
    var cleanComponents;

    if (onlyClean) {
      cleanComponents = getUnchangedComponents(measurement);
    }

    for (var id in allIDs) {
      if (onlyClean && !cleanComponents[id]) {
        continue;
      }

      var displayName = measurement.displayNames[id];

      // Inclusive time is not useful for many components without knowing where
      // they are instantiated. So we aggregate inclusive time with both the
      // owner and current displayName as the key.
      inclusiveKey = displayName.owner + ' > ' + displayName.current;

      candidates[inclusiveKey] = candidates[inclusiveKey] || {
        componentName: inclusiveKey,
        time: 0,
        count: 0
      };

      if (measurement.inclusive[id]) {
        candidates[inclusiveKey].time += measurement.inclusive[id];
      }
      if (measurement.counts[id]) {
        candidates[inclusiveKey].count += measurement.counts[id];
      }
    }
  }

  // Now make a sorted array with the results.
  var arr = [];
  for (inclusiveKey in candidates) {
    if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
      arr.push(candidates[inclusiveKey]);
    }
  }

  arr.sort(function (a, b) {
    return b.time - a.time;
  });

  return arr;
}

function getUnchangedComponents(measurement) {
  // For a given reconcile, look at which components did not actually
  // render anything to the DOM and return a mapping of their ID to
  // the amount of time it took to render the entire subtree.
  var cleanComponents = {};
  var dirtyLeafIDs = Object.keys(measurement.writes);
  var allIDs = assign({}, measurement.exclusive, measurement.inclusive);

  for (var id in allIDs) {
    var isDirty = false;
    // For each component that rendered, see if a component that triggered
    // a DOM op is in its subtree.
    for (var i = 0; i < dirtyLeafIDs.length; i++) {
      if (dirtyLeafIDs[i].indexOf(id) === 0) {
        isDirty = true;
        break;
      }
    }
    // check if component newly created
    if (measurement.created[id]) {
      isDirty = true;
    }
    if (!isDirty && measurement.counts[id] > 0) {
      cleanComponents[id] = true;
    }
  }
  return cleanComponents;
}

var ReactDefaultPerfAnalysis = {
  getExclusiveSummary: getExclusiveSummary,
  getInclusiveSummary: getInclusiveSummary,
  getDOMSummary: getDOMSummary,
  getTotalTime: getTotalTime
};

module.exports = ReactDefaultPerfAnalysis;
},{"./Object.assign":418}],448:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactElement
 */

'use strict';

var ReactCurrentOwner = require('./ReactCurrentOwner');

var assign = require('./Object.assign');
var canDefineProperty = require('./canDefineProperty');

// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;

var RESERVED_PROPS = {
  key: true,
  ref: true,
  __self: true,
  __source: true
};

/**
 * Base constructor for all React elements. This is only used to make this
 * work with a dynamic instanceof check. Nothing should live on this prototype.
 *
 * @param {*} type
 * @param {*} key
 * @param {string|object} ref
 * @param {*} self A *temporary* helper to detect places where `this` is
 * different from the `owner` when React.createElement is called, so that we
 * can warn. We want to get rid of owner and replace string `ref`s with arrow
 * functions, and as long as `this` and owner are the same, there will be no
 * change in behavior.
 * @param {*} source An annotation object (added by a transpiler or otherwise)
 * indicating filename, line number, and/or other information.
 * @param {*} owner
 * @param {*} props
 * @internal
 */
var ReactElement = function (type, key, ref, self, source, owner, props) {
  var element = {
    // This tag allow us to uniquely identify this as a React Element
    $$typeof: REACT_ELEMENT_TYPE,

    // Built-in properties that belong on the element
    type: type,
    key: key,
    ref: ref,
    props: props,

    // Record the component responsible for creating this element.
    _owner: owner
  };

  if (process.env.NODE_ENV !== 'production') {
    // The validation flag is currently mutative. We put it on
    // an external backing store so that we can freeze the whole object.
    // This can be replaced with a WeakMap once they are implemented in
    // commonly used development environments.
    element._store = {};

    // To make comparing ReactElements easier for testing purposes, we make
    // the validation flag non-enumerable (where possible, which should
    // include every environment we run tests in), so the test framework
    // ignores it.
    if (canDefineProperty) {
      Object.defineProperty(element._store, 'validated', {
        configurable: false,
        enumerable: false,
        writable: true,
        value: false
      });
      // self and source are DEV only properties.
      Object.defineProperty(element, '_self', {
        configurable: false,
        enumerable: false,
        writable: false,
        value: self
      });
      // Two elements created in two different places should be considered
      // equal for testing purposes and therefore we hide it from enumeration.
      Object.defineProperty(element, '_source', {
        configurable: false,
        enumerable: false,
        writable: false,
        value: source
      });
    } else {
      element._store.validated = false;
      element._self = self;
      element._source = source;
    }
    Object.freeze(element.props);
    Object.freeze(element);
  }

  return element;
};

ReactElement.createElement = function (type, config, children) {
  var propName;

  // Reserved names are extracted
  var props = {};

  var key = null;
  var ref = null;
  var self = null;
  var source = null;

  if (config != null) {
    ref = config.ref === undefined ? null : config.ref;
    key = config.key === undefined ? null : '' + config.key;
    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    // Remaining properties are added to a new props object
    for (propName in config) {
      if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      }
    }
  }

  // Children can be more than one argument, and those are transferred onto
  // the newly allocated props object.
  var childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  // Resolve default props
  if (type && type.defaultProps) {
    var defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (typeof props[propName] === 'undefined') {
        props[propName] = defaultProps[propName];
      }
    }
  }

  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
};

ReactElement.createFactory = function (type) {
  var factory = ReactElement.createElement.bind(null, type);
  // Expose the type on the factory and the prototype so that it can be
  // easily accessed on elements. E.g. `<Foo />.type === Foo`.
  // This should not be named `constructor` since this may not be the function
  // that created the element, and it may not even be a constructor.
  // Legacy hook TODO: Warn if this is accessed
  factory.type = type;
  return factory;
};

ReactElement.cloneAndReplaceKey = function (oldElement, newKey) {
  var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);

  return newElement;
};

ReactElement.cloneAndReplaceProps = function (oldElement, newProps) {
  var newElement = ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, newProps);

  if (process.env.NODE_ENV !== 'production') {
    // If the key on the original is valid, then the clone is valid
    newElement._store.validated = oldElement._store.validated;
  }

  return newElement;
};

ReactElement.cloneElement = function (element, config, children) {
  var propName;

  // Original props are copied
  var props = assign({}, element.props);

  // Reserved names are extracted
  var key = element.key;
  var ref = element.ref;
  // Self is preserved since the owner is preserved.
  var self = element._self;
  // Source is preserved since cloneElement is unlikely to be targeted by a
  // transpiler, and the original source is probably a better indicator of the
  // true owner.
  var source = element._source;

  // Owner will be preserved, unless ref is overridden
  var owner = element._owner;

  if (config != null) {
    if (config.ref !== undefined) {
      // Silently steal the ref from the parent.
      ref = config.ref;
      owner = ReactCurrentOwner.current;
    }
    if (config.key !== undefined) {
      key = '' + config.key;
    }
    // Remaining properties override existing props
    for (propName in config) {
      if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      }
    }
  }

  // Children can be more than one argument, and those are transferred onto
  // the newly allocated props object.
  var childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  return ReactElement(element.type, key, ref, self, source, owner, props);
};

/**
 * @param {?object} object
 * @return {boolean} True if `object` is a valid component.
 * @final
 */
ReactElement.isValidElement = function (object) {
  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
};

module.exports = ReactElement;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactCurrentOwner":430,"./canDefineProperty":500,"_process":334}],449:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactElementValidator
 */

/**
 * ReactElementValidator provides a wrapper around a element factory
 * which validates the props passed to the element. This is intended to be
 * used only in DEV and could be replaced by a static type checker for languages
 * that support it.
 */

'use strict';

var ReactElement = require('./ReactElement');
var ReactPropTypeLocations = require('./ReactPropTypeLocations');
var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
var ReactCurrentOwner = require('./ReactCurrentOwner');

var canDefineProperty = require('./canDefineProperty');
var getIteratorFn = require('./getIteratorFn');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

function getDeclarationErrorAddendum() {
  if (ReactCurrentOwner.current) {
    var name = ReactCurrentOwner.current.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

/**
 * Warn if there's no key explicitly set on dynamic arrays of children or
 * object keys are not valid. This allows us to keep track of children between
 * updates.
 */
var ownerHasKeyUseWarning = {};

var loggedTypeFailures = {};

/**
 * Warn if the element doesn't have an explicit key assigned to it.
 * This element is in an array. The array could grow and shrink or be
 * reordered. All children that haven't already been validated are required to
 * have a "key" property assigned to it.
 *
 * @internal
 * @param {ReactElement} element Element that requires a key.
 * @param {*} parentType element's parent's type.
 */
function validateExplicitKey(element, parentType) {
  if (!element._store || element._store.validated || element.key != null) {
    return;
  }
  element._store.validated = true;

  var addenda = getAddendaForKeyUse('uniqueKey', element, parentType);
  if (addenda === null) {
    // we already showed the warning
    return;
  }
  process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;
}

/**
 * Shared warning and monitoring code for the key warnings.
 *
 * @internal
 * @param {string} messageType A key used for de-duping warnings.
 * @param {ReactElement} element Component that requires a key.
 * @param {*} parentType element's parent's type.
 * @returns {?object} A set of addenda to use in the warning message, or null
 * if the warning has already been shown before (and shouldn't be shown again).
 */
function getAddendaForKeyUse(messageType, element, parentType) {
  var addendum = getDeclarationErrorAddendum();
  if (!addendum) {
    var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
    if (parentName) {
      addendum = ' Check the top-level render call using <' + parentName + '>.';
    }
  }

  var memoizer = ownerHasKeyUseWarning[messageType] || (ownerHasKeyUseWarning[messageType] = {});
  if (memoizer[addendum]) {
    return null;
  }
  memoizer[addendum] = true;

  var addenda = {
    parentOrOwner: addendum,
    url: ' See https://fb.me/react-warning-keys for more information.',
    childOwner: null
  };

  // Usually the current owner is the offender, but if it accepts children as a
  // property, it may be the creator of the child that's responsible for
  // assigning it a key.
  if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
    // Give the component that originally created this child.
    addenda.childOwner = ' It was passed a child from ' + element._owner.getName() + '.';
  }

  return addenda;
}

/**
 * Ensure that every element either is passed in a static location, in an
 * array with an explicit keys property defined, or in an object literal
 * with valid key property.
 *
 * @internal
 * @param {ReactNode} node Statically passed child of any type.
 * @param {*} parentType node's parent's type.
 */
function validateChildKeys(node, parentType) {
  if (typeof node !== 'object') {
    return;
  }
  if (Array.isArray(node)) {
    for (var i = 0; i < node.length; i++) {
      var child = node[i];
      if (ReactElement.isValidElement(child)) {
        validateExplicitKey(child, parentType);
      }
    }
  } else if (ReactElement.isValidElement(node)) {
    // This element was passed in a valid location.
    if (node._store) {
      node._store.validated = true;
    }
  } else if (node) {
    var iteratorFn = getIteratorFn(node);
    // Entry iterators provide implicit keys.
    if (iteratorFn) {
      if (iteratorFn !== node.entries) {
        var iterator = iteratorFn.call(node);
        var step;
        while (!(step = iterator.next()).done) {
          if (ReactElement.isValidElement(step.value)) {
            validateExplicitKey(step.value, parentType);
          }
        }
      }
    }
  }
}

/**
 * Assert that the props are valid
 *
 * @param {string} componentName Name of the component for error messages.
 * @param {object} propTypes Map of prop name to a ReactPropType
 * @param {object} props
 * @param {string} location e.g. "prop", "context", "child context"
 * @private
 */
function checkPropTypes(componentName, propTypes, props, location) {
  for (var propName in propTypes) {
    if (propTypes.hasOwnProperty(propName)) {
      var error;
      // Prop type validation may throw. In case they do, we don't want to
      // fail the render phase where it didn't fail before. So we log it.
      // After these have been cleaned up, we'll let them throw.
      try {
        // This is intentionally an invariant that gets caught. It's the same
        // behavior as without this statement except with a better message.
        !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : undefined;
        error = propTypes[propName](props, propName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
      } catch (ex) {
        error = ex;
      }
      process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], propName, typeof error) : undefined;
      if (error instanceof Error && !(error.message in loggedTypeFailures)) {
        // Only monitor this failure once because there tends to be a lot of the
        // same error.
        loggedTypeFailures[error.message] = true;

        var addendum = getDeclarationErrorAddendum();
        process.env.NODE_ENV !== 'production' ? warning(false, 'Failed propType: %s%s', error.message, addendum) : undefined;
      }
    }
  }
}

/**
 * Given an element, validate that its props follow the propTypes definition,
 * provided by the type.
 *
 * @param {ReactElement} element
 */
function validatePropTypes(element) {
  var componentClass = element.type;
  if (typeof componentClass !== 'function') {
    return;
  }
  var name = componentClass.displayName || componentClass.name;
  if (componentClass.propTypes) {
    checkPropTypes(name, componentClass.propTypes, element.props, ReactPropTypeLocations.prop);
  }
  if (typeof componentClass.getDefaultProps === 'function') {
    process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : undefined;
  }
}

var ReactElementValidator = {

  createElement: function (type, props, children) {
    var validType = typeof type === 'string' || typeof type === 'function';
    // We warn in this case but don't throw. We expect the element creation to
    // succeed and there will likely be errors in render.
    process.env.NODE_ENV !== 'production' ? warning(validType, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : undefined;

    var element = ReactElement.createElement.apply(this, arguments);

    // The result can be nullish if a mock or a custom function is used.
    // TODO: Drop this when these are no longer allowed as the type argument.
    if (element == null) {
      return element;
    }

    // Skip key warning if the type isn't valid since our key validation logic
    // doesn't expect a non-string/function type and can throw confusing errors.
    // We don't want exception behavior to differ between dev and prod.
    // (Rendering will throw with a helpful message and as soon as the type is
    // fixed, the key warnings will appear.)
    if (validType) {
      for (var i = 2; i < arguments.length; i++) {
        validateChildKeys(arguments[i], type);
      }
    }

    validatePropTypes(element);

    return element;
  },

  createFactory: function (type) {
    var validatedFactory = ReactElementValidator.createElement.bind(null, type);
    // Legacy hook TODO: Warn if this is accessed
    validatedFactory.type = type;

    if (process.env.NODE_ENV !== 'production') {
      if (canDefineProperty) {
        Object.defineProperty(validatedFactory, 'type', {
          enumerable: false,
          get: function () {
            process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : undefined;
            Object.defineProperty(this, 'type', {
              value: type
            });
            return type;
          }
        });
      }
    }

    return validatedFactory;
  },

  cloneElement: function (element, props, children) {
    var newElement = ReactElement.cloneElement.apply(this, arguments);
    for (var i = 2; i < arguments.length; i++) {
      validateChildKeys(arguments[i], newElement.type);
    }
    validatePropTypes(newElement);
    return newElement;
  }

};

module.exports = ReactElementValidator;
}).call(this,require('_process'))

},{"./ReactCurrentOwner":430,"./ReactElement":448,"./ReactPropTypeLocationNames":468,"./ReactPropTypeLocations":469,"./canDefineProperty":500,"./getIteratorFn":511,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],450:[function(require,module,exports){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactEmptyComponent
 */

'use strict';

var ReactElement = require('./ReactElement');
var ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry');
var ReactReconciler = require('./ReactReconciler');

var assign = require('./Object.assign');

var placeholderElement;

var ReactEmptyComponentInjection = {
  injectEmptyComponent: function (component) {
    placeholderElement = ReactElement.createElement(component);
  }
};

function registerNullComponentID() {
  ReactEmptyComponentRegistry.registerNullComponentID(this._rootNodeID);
}

var ReactEmptyComponent = function (instantiate) {
  this._currentElement = null;
  this._rootNodeID = null;
  this._renderedComponent = instantiate(placeholderElement);
};
assign(ReactEmptyComponent.prototype, {
  construct: function (element) {},
  mountComponent: function (rootID, transaction, context) {
    transaction.getReactMountReady().enqueue(registerNullComponentID, this);
    this._rootNodeID = rootID;
    return ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, context);
  },
  receiveComponent: function () {},
  unmountComponent: function (rootID, transaction, context) {
    ReactReconciler.unmountComponent(this._renderedComponent);
    ReactEmptyComponentRegistry.deregisterNullComponentID(this._rootNodeID);
    this._rootNodeID = null;
    this._renderedComponent = null;
  }
});

ReactEmptyComponent.injection = ReactEmptyComponentInjection;

module.exports = ReactEmptyComponent;
},{"./Object.assign":418,"./ReactElement":448,"./ReactEmptyComponentRegistry":451,"./ReactReconciler":472}],451:[function(require,module,exports){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactEmptyComponentRegistry
 */

'use strict';

// This registry keeps track of the React IDs of the components that rendered to
// `null` (in reality a placeholder such as `noscript`)
var nullComponentIDsRegistry = {};

/**
 * @param {string} id Component's `_rootNodeID`.
 * @return {boolean} True if the component is rendered to null.
 */
function isNullComponentID(id) {
  return !!nullComponentIDsRegistry[id];
}

/**
 * Mark the component as having rendered to null.
 * @param {string} id Component's `_rootNodeID`.
 */
function registerNullComponentID(id) {
  nullComponentIDsRegistry[id] = true;
}

/**
 * Unmark the component as having rendered to null: it renders to something now.
 * @param {string} id Component's `_rootNodeID`.
 */
function deregisterNullComponentID(id) {
  delete nullComponentIDsRegistry[id];
}

var ReactEmptyComponentRegistry = {
  isNullComponentID: isNullComponentID,
  registerNullComponentID: registerNullComponentID,
  deregisterNullComponentID: deregisterNullComponentID
};

module.exports = ReactEmptyComponentRegistry;
},{}],452:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 * @typechecks
 */

'use strict';

var caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 *
 * @param {?String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} a First argument
 * @param {*} b Second argument
 */
function invokeGuardedCallback(name, func, a, b) {
  try {
    return func(a, b);
  } catch (x) {
    if (caughtError === null) {
      caughtError = x;
    }
    return undefined;
  }
}

var ReactErrorUtils = {
  invokeGuardedCallback: invokeGuardedCallback,

  /**
   * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
   * handler are sure to be rethrown by rethrowCaughtError.
   */
  invokeGuardedCallbackWithCatch: invokeGuardedCallback,

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function () {
    if (caughtError) {
      var error = caughtError;
      caughtError = null;
      throw error;
    }
  }
};

if (process.env.NODE_ENV !== 'production') {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
    var fakeNode = document.createElement('react');
    ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) {
      var boundFunc = func.bind(null, a, b);
      var evtType = 'react-' + name;
      fakeNode.addEventListener(evtType, boundFunc, false);
      var evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
    };
  }
}

module.exports = ReactErrorUtils;
}).call(this,require('_process'))

},{"_process":334}],453:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactEventEmitterMixin
 */

'use strict';

var EventPluginHub = require('./EventPluginHub');

function runEventQueueInBatch(events) {
  EventPluginHub.enqueueEvents(events);
  EventPluginHub.processEventQueue(false);
}

var ReactEventEmitterMixin = {

  /**
   * Streams a fired top-level event to `EventPluginHub` where plugins have the
   * opportunity to create `ReactEvent`s to be dispatched.
   *
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {object} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native environment event.
   */
  handleTopLevel: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    var events = EventPluginHub.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget);
    runEventQueueInBatch(events);
  }
};

module.exports = ReactEventEmitterMixin;
},{"./EventPluginHub":411}],454:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactEventListener
 * @typechecks static-only
 */

'use strict';

var EventListener = require('fbjs/lib/EventListener');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var PooledClass = require('./PooledClass');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactMount = require('./ReactMount');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var getEventTarget = require('./getEventTarget');
var getUnboundedScrollPosition = require('fbjs/lib/getUnboundedScrollPosition');

var DOCUMENT_FRAGMENT_NODE_TYPE = 11;

/**
 * Finds the parent React component of `node`.
 *
 * @param {*} node
 * @return {?DOMEventTarget} Parent container, or `null` if the specified node
 *                           is not nested.
 */
function findParent(node) {
  // TODO: It may be a good idea to cache this to prevent unnecessary DOM
  // traversal, but caching is difficult to do correctly without using a
  // mutation observer to listen for all DOM changes.
  var nodeID = ReactMount.getID(node);
  var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
  var container = ReactMount.findReactContainerForID(rootID);
  var parent = ReactMount.getFirstReactDOM(container);
  return parent;
}

// Used to store ancestor hierarchy in top level callback
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
  this.topLevelType = topLevelType;
  this.nativeEvent = nativeEvent;
  this.ancestors = [];
}
assign(TopLevelCallbackBookKeeping.prototype, {
  destructor: function () {
    this.topLevelType = null;
    this.nativeEvent = null;
    this.ancestors.length = 0;
  }
});
PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler);

function handleTopLevelImpl(bookKeeping) {
  // TODO: Re-enable event.path handling
  //
  // if (bookKeeping.nativeEvent.path && bookKeeping.nativeEvent.path.length > 1) {
  //   // New browsers have a path attribute on native events
  //   handleTopLevelWithPath(bookKeeping);
  // } else {
  //   // Legacy browsers don't have a path attribute on native events
  //   handleTopLevelWithoutPath(bookKeeping);
  // }

  void handleTopLevelWithPath; // temporarily unused
  handleTopLevelWithoutPath(bookKeeping);
}

// Legacy browsers don't have a path attribute on native events
function handleTopLevelWithoutPath(bookKeeping) {
  var topLevelTarget = ReactMount.getFirstReactDOM(getEventTarget(bookKeeping.nativeEvent)) || window;

  // Loop through the hierarchy, in case there's any nested components.
  // It's important that we build the array of ancestors before calling any
  // event handlers, because event handlers can modify the DOM, leading to
  // inconsistencies with ReactMount's node cache. See #1105.
  var ancestor = topLevelTarget;
  while (ancestor) {
    bookKeeping.ancestors.push(ancestor);
    ancestor = findParent(ancestor);
  }

  for (var i = 0; i < bookKeeping.ancestors.length; i++) {
    topLevelTarget = bookKeeping.ancestors[i];
    var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
    ReactEventListener._handleTopLevel(bookKeeping.topLevelType, topLevelTarget, topLevelTargetID, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
  }
}

// New browsers have a path attribute on native events
function handleTopLevelWithPath(bookKeeping) {
  var path = bookKeeping.nativeEvent.path;
  var currentNativeTarget = path[0];
  var eventsFired = 0;
  for (var i = 0; i < path.length; i++) {
    var currentPathElement = path[i];
    if (currentPathElement.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE) {
      currentNativeTarget = path[i + 1];
    }
    // TODO: slow
    var reactParent = ReactMount.getFirstReactDOM(currentPathElement);
    if (reactParent === currentPathElement) {
      var currentPathElementID = ReactMount.getID(currentPathElement);
      var newRootID = ReactInstanceHandles.getReactRootIDFromNodeID(currentPathElementID);
      bookKeeping.ancestors.push(currentPathElement);

      var topLevelTargetID = ReactMount.getID(currentPathElement) || '';
      eventsFired++;
      ReactEventListener._handleTopLevel(bookKeeping.topLevelType, currentPathElement, topLevelTargetID, bookKeeping.nativeEvent, currentNativeTarget);

      // Jump to the root of this React render tree
      while (currentPathElementID !== newRootID) {
        i++;
        currentPathElement = path[i];
        currentPathElementID = ReactMount.getID(currentPathElement);
      }
    }
  }
  if (eventsFired === 0) {
    ReactEventListener._handleTopLevel(bookKeeping.topLevelType, window, '', bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
  }
}

function scrollValueMonitor(cb) {
  var scrollPosition = getUnboundedScrollPosition(window);
  cb(scrollPosition);
}

var ReactEventListener = {
  _enabled: true,
  _handleTopLevel: null,

  WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,

  setHandleTopLevel: function (handleTopLevel) {
    ReactEventListener._handleTopLevel = handleTopLevel;
  },

  setEnabled: function (enabled) {
    ReactEventListener._enabled = !!enabled;
  },

  isEnabled: function () {
    return ReactEventListener._enabled;
  },

  /**
   * Traps top-level events by using event bubbling.
   *
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {string} handlerBaseName Event name (e.g. "click").
   * @param {object} handle Element on which to attach listener.
   * @return {?object} An object with a remove function which will forcefully
   *                  remove the listener.
   * @internal
   */
  trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {
    var element = handle;
    if (!element) {
      return null;
    }
    return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
  },

  /**
   * Traps a top-level event by using event capturing.
   *
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {string} handlerBaseName Event name (e.g. "click").
   * @param {object} handle Element on which to attach listener.
   * @return {?object} An object with a remove function which will forcefully
   *                  remove the listener.
   * @internal
   */
  trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {
    var element = handle;
    if (!element) {
      return null;
    }
    return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
  },

  monitorScrollValue: function (refresh) {
    var callback = scrollValueMonitor.bind(null, refresh);
    EventListener.listen(window, 'scroll', callback);
  },

  dispatchEvent: function (topLevelType, nativeEvent) {
    if (!ReactEventListener._enabled) {
      return;
    }

    var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent);
    try {
      // Event queue being processed in the same cycle allows
      // `preventDefault`.
      ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
    } finally {
      TopLevelCallbackBookKeeping.release(bookKeeping);
    }
  }
};

module.exports = ReactEventListener;
},{"./Object.assign":418,"./PooledClass":419,"./ReactInstanceHandles":457,"./ReactMount":461,"./ReactUpdates":479,"./getEventTarget":510,"fbjs/lib/EventListener":303,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/getUnboundedScrollPosition":315}],455:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactInjection
 */

'use strict';

var DOMProperty = require('./DOMProperty');
var EventPluginHub = require('./EventPluginHub');
var ReactComponentEnvironment = require('./ReactComponentEnvironment');
var ReactClass = require('./ReactClass');
var ReactEmptyComponent = require('./ReactEmptyComponent');
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
var ReactNativeComponent = require('./ReactNativeComponent');
var ReactPerf = require('./ReactPerf');
var ReactRootIndex = require('./ReactRootIndex');
var ReactUpdates = require('./ReactUpdates');

var ReactInjection = {
  Component: ReactComponentEnvironment.injection,
  Class: ReactClass.injection,
  DOMProperty: DOMProperty.injection,
  EmptyComponent: ReactEmptyComponent.injection,
  EventPluginHub: EventPluginHub.injection,
  EventEmitter: ReactBrowserEventEmitter.injection,
  NativeComponent: ReactNativeComponent.injection,
  Perf: ReactPerf.injection,
  RootIndex: ReactRootIndex.injection,
  Updates: ReactUpdates.injection
};

module.exports = ReactInjection;
},{"./DOMProperty":405,"./EventPluginHub":411,"./ReactBrowserEventEmitter":422,"./ReactClass":425,"./ReactComponentEnvironment":428,"./ReactEmptyComponent":450,"./ReactNativeComponent":464,"./ReactPerf":467,"./ReactRootIndex":474,"./ReactUpdates":479}],456:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactInputSelection
 */

'use strict';

var ReactDOMSelection = require('./ReactDOMSelection');

var containsNode = require('fbjs/lib/containsNode');
var focusNode = require('fbjs/lib/focusNode');
var getActiveElement = require('fbjs/lib/getActiveElement');

function isInDocument(node) {
  return containsNode(document.documentElement, node);
}

/**
 * @ReactInputSelection: React input selection module. Based on Selection.js,
 * but modified to be suitable for react and has a couple of bug fixes (doesn't
 * assume buttons have range selections allowed).
 * Input selection module for React.
 */
var ReactInputSelection = {

  hasSelectionCapabilities: function (elem) {
    var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
    return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
  },

  getSelectionInformation: function () {
    var focusedElem = getActiveElement();
    return {
      focusedElem: focusedElem,
      selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null
    };
  },

  /**
   * @restoreSelection: If any selection information was potentially lost,
   * restore it. This is useful when performing operations that could remove dom
   * nodes and place them back in, resulting in focus being lost.
   */
  restoreSelection: function (priorSelectionInformation) {
    var curFocusedElem = getActiveElement();
    var priorFocusedElem = priorSelectionInformation.focusedElem;
    var priorSelectionRange = priorSelectionInformation.selectionRange;
    if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
      if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
        ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange);
      }
      focusNode(priorFocusedElem);
    }
  },

  /**
   * @getSelection: Gets the selection bounds of a focused textarea, input or
   * contentEditable node.
   * -@input: Look up selection bounds of this input
   * -@return {start: selectionStart, end: selectionEnd}
   */
  getSelection: function (input) {
    var selection;

    if ('selectionStart' in input) {
      // Modern browser with input or textarea.
      selection = {
        start: input.selectionStart,
        end: input.selectionEnd
      };
    } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) {
      // IE8 input.
      var range = document.selection.createRange();
      // There can only be one selection per document in IE, so it must
      // be in our element.
      if (range.parentElement() === input) {
        selection = {
          start: -range.moveStart('character', -input.value.length),
          end: -range.moveEnd('character', -input.value.length)
        };
      }
    } else {
      // Content editable or old IE textarea.
      selection = ReactDOMSelection.getOffsets(input);
    }

    return selection || { start: 0, end: 0 };
  },

  /**
   * @setSelection: Sets the selection bounds of a textarea or input and focuses
   * the input.
   * -@input     Set selection bounds of this input or textarea
   * -@offsets   Object of same form that is returned from get*
   */
  setSelection: function (input, offsets) {
    var start = offsets.start;
    var end = offsets.end;
    if (typeof end === 'undefined') {
      end = start;
    }

    if ('selectionStart' in input) {
      input.selectionStart = start;
      input.selectionEnd = Math.min(end, input.value.length);
    } else if (document.selection && (input.nodeName && input.nodeName.toLowerCase() === 'input')) {
      var range = input.createTextRange();
      range.collapse(true);
      range.moveStart('character', start);
      range.moveEnd('character', end - start);
      range.select();
    } else {
      ReactDOMSelection.setOffsets(input, offsets);
    }
  }
};

module.exports = ReactInputSelection;
},{"./ReactDOMSelection":440,"fbjs/lib/containsNode":307,"fbjs/lib/focusNode":312,"fbjs/lib/getActiveElement":313}],457:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactInstanceHandles
 * @typechecks static-only
 */

'use strict';

var ReactRootIndex = require('./ReactRootIndex');

var invariant = require('fbjs/lib/invariant');

var SEPARATOR = '.';
var SEPARATOR_LENGTH = SEPARATOR.length;

/**
 * Maximum depth of traversals before we consider the possibility of a bad ID.
 */
var MAX_TREE_DEPTH = 10000;

/**
 * Creates a DOM ID prefix to use when mounting React components.
 *
 * @param {number} index A unique integer
 * @return {string} React root ID.
 * @internal
 */
function getReactRootIDString(index) {
  return SEPARATOR + index.toString(36);
}

/**
 * Checks if a character in the supplied ID is a separator or the end.
 *
 * @param {string} id A React DOM ID.
 * @param {number} index Index of the character to check.
 * @return {boolean} True if the character is a separator or end of the ID.
 * @private
 */
function isBoundary(id, index) {
  return id.charAt(index) === SEPARATOR || index === id.length;
}

/**
 * Checks if the supplied string is a valid React DOM ID.
 *
 * @param {string} id A React DOM ID, maybe.
 * @return {boolean} True if the string is a valid React DOM ID.
 * @private
 */
function isValidID(id) {
  return id === '' || id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR;
}

/**
 * Checks if the first ID is an ancestor of or equal to the second ID.
 *
 * @param {string} ancestorID
 * @param {string} descendantID
 * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
 * @internal
 */
function isAncestorIDOf(ancestorID, descendantID) {
  return descendantID.indexOf(ancestorID) === 0 && isBoundary(descendantID, ancestorID.length);
}

/**
 * Gets the parent ID of the supplied React DOM ID, `id`.
 *
 * @param {string} id ID of a component.
 * @return {string} ID of the parent, or an empty string.
 * @private
 */
function getParentID(id) {
  return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
}

/**
 * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
 * supplied `destinationID`. If they are equal, the ID is returned.
 *
 * @param {string} ancestorID ID of an ancestor node of `destinationID`.
 * @param {string} destinationID ID of the destination node.
 * @return {string} Next ID on the path from `ancestorID` to `destinationID`.
 * @private
 */
function getNextDescendantID(ancestorID, destinationID) {
  !(isValidID(ancestorID) && isValidID(destinationID)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', ancestorID, destinationID) : invariant(false) : undefined;
  !isAncestorIDOf(ancestorID, destinationID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNextDescendantID(...): React has made an invalid assumption about ' + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', ancestorID, destinationID) : invariant(false) : undefined;
  if (ancestorID === destinationID) {
    return ancestorID;
  }
  // Skip over the ancestor and the immediate separator. Traverse until we hit
  // another separator or we reach the end of `destinationID`.
  var start = ancestorID.length + SEPARATOR_LENGTH;
  var i;
  for (i = start; i < destinationID.length; i++) {
    if (isBoundary(destinationID, i)) {
      break;
    }
  }
  return destinationID.substr(0, i);
}

/**
 * Gets the nearest common ancestor ID of two IDs.
 *
 * Using this ID scheme, the nearest common ancestor ID is the longest common
 * prefix of the two IDs that immediately preceded a "marker" in both strings.
 *
 * @param {string} oneID
 * @param {string} twoID
 * @return {string} Nearest common ancestor ID, or the empty string if none.
 * @private
 */
function getFirstCommonAncestorID(oneID, twoID) {
  var minLength = Math.min(oneID.length, twoID.length);
  if (minLength === 0) {
    return '';
  }
  var lastCommonMarkerIndex = 0;
  // Use `<=` to traverse until the "EOL" of the shorter string.
  for (var i = 0; i <= minLength; i++) {
    if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
      lastCommonMarkerIndex = i;
    } else if (oneID.charAt(i) !== twoID.charAt(i)) {
      break;
    }
  }
  var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
  !isValidID(longestCommonID) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', oneID, twoID, longestCommonID) : invariant(false) : undefined;
  return longestCommonID;
}

/**
 * Traverses the parent path between two IDs (either up or down). The IDs must
 * not be the same, and there must exist a parent path between them. If the
 * callback returns `false`, traversal is stopped.
 *
 * @param {?string} start ID at which to start traversal.
 * @param {?string} stop ID at which to end traversal.
 * @param {function} cb Callback to invoke each ID with.
 * @param {*} arg Argument to invoke the callback with.
 * @param {?boolean} skipFirst Whether or not to skip the first node.
 * @param {?boolean} skipLast Whether or not to skip the last node.
 * @private
 */
function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
  start = start || '';
  stop = stop || '';
  !(start !== stop) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', start) : invariant(false) : undefined;
  var traverseUp = isAncestorIDOf(stop, start);
  !(traverseUp || isAncestorIDOf(start, stop)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + 'not have a parent path.', start, stop) : invariant(false) : undefined;
  // Traverse from `start` to `stop` one depth at a time.
  var depth = 0;
  var traverse = traverseUp ? getParentID : getNextDescendantID;
  for (var id = start;; /* until break */id = traverse(id, stop)) {
    var ret;
    if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
      ret = cb(id, traverseUp, arg);
    }
    if (ret === false || id === stop) {
      // Only break //after// visiting `stop`.
      break;
    }
    !(depth++ < MAX_TREE_DEPTH) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', start, stop, id) : invariant(false) : undefined;
  }
}

/**
 * Manages the IDs assigned to DOM representations of React components. This
 * uses a specific scheme in order to traverse the DOM efficiently (e.g. in
 * order to simulate events).
 *
 * @internal
 */
var ReactInstanceHandles = {

  /**
   * Constructs a React root ID
   * @return {string} A React root ID.
   */
  createReactRootID: function () {
    return getReactRootIDString(ReactRootIndex.createReactRootIndex());
  },

  /**
   * Constructs a React ID by joining a root ID with a name.
   *
   * @param {string} rootID Root ID of a parent component.
   * @param {string} name A component's name (as flattened children).
   * @return {string} A React ID.
   * @internal
   */
  createReactID: function (rootID, name) {
    return rootID + name;
  },

  /**
   * Gets the DOM ID of the React component that is the root of the tree that
   * contains the React component with the supplied DOM ID.
   *
   * @param {string} id DOM ID of a React component.
   * @return {?string} DOM ID of the React component that is the root.
   * @internal
   */
  getReactRootIDFromNodeID: function (id) {
    if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
      var index = id.indexOf(SEPARATOR, 1);
      return index > -1 ? id.substr(0, index) : id;
    }
    return null;
  },

  /**
   * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
   * should would receive a `mouseEnter` or `mouseLeave` event.
   *
   * NOTE: Does not invoke the callback on the nearest common ancestor because
   * nothing "entered" or "left" that element.
   *
   * @param {string} leaveID ID being left.
   * @param {string} enterID ID being entered.
   * @param {function} cb Callback to invoke on each entered/left ID.
   * @param {*} upArg Argument to invoke the callback with on left IDs.
   * @param {*} downArg Argument to invoke the callback with on entered IDs.
   * @internal
   */
  traverseEnterLeave: function (leaveID, enterID, cb, upArg, downArg) {
    var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
    if (ancestorID !== leaveID) {
      traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
    }
    if (ancestorID !== enterID) {
      traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
    }
  },

  /**
   * Simulates the traversal of a two-phase, capture/bubble event dispatch.
   *
   * NOTE: This traversal happens on IDs without touching the DOM.
   *
   * @param {string} targetID ID of the target node.
   * @param {function} cb Callback to invoke.
   * @param {*} arg Argument to invoke the callback with.
   * @internal
   */
  traverseTwoPhase: function (targetID, cb, arg) {
    if (targetID) {
      traverseParentPath('', targetID, cb, arg, true, false);
      traverseParentPath(targetID, '', cb, arg, false, true);
    }
  },

  /**
   * Same as `traverseTwoPhase` but skips the `targetID`.
   */
  traverseTwoPhaseSkipTarget: function (targetID, cb, arg) {
    if (targetID) {
      traverseParentPath('', targetID, cb, arg, true, true);
      traverseParentPath(targetID, '', cb, arg, true, true);
    }
  },

  /**
   * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For
   * example, passing `.0.$row-0.1` would result in `cb` getting called
   * with `.0`, `.0.$row-0`, and `.0.$row-0.1`.
   *
   * NOTE: This traversal happens on IDs without touching the DOM.
   *
   * @param {string} targetID ID of the target node.
   * @param {function} cb Callback to invoke.
   * @param {*} arg Argument to invoke the callback with.
   * @internal
   */
  traverseAncestors: function (targetID, cb, arg) {
    traverseParentPath('', targetID, cb, arg, true, false);
  },

  getFirstCommonAncestorID: getFirstCommonAncestorID,

  /**
   * Exposed for unit testing.
   * @private
   */
  _getNextDescendantID: getNextDescendantID,

  isAncestorIDOf: isAncestorIDOf,

  SEPARATOR: SEPARATOR

};

module.exports = ReactInstanceHandles;
}).call(this,require('_process'))

},{"./ReactRootIndex":474,"_process":334,"fbjs/lib/invariant":318}],458:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactInstanceMap
 */

'use strict';

/**
 * `ReactInstanceMap` maintains a mapping from a public facing stateful
 * instance (key) and the internal representation (value). This allows public
 * methods to accept the user facing instance as an argument and map them back
 * to internal methods.
 */

// TODO: Replace this with ES6: var ReactInstanceMap = new Map();
var ReactInstanceMap = {

  /**
   * This API should be called `delete` but we'd have to make sure to always
   * transform these to strings for IE support. When this transform is fully
   * supported we can rename it.
   */
  remove: function (key) {
    key._reactInternalInstance = undefined;
  },

  get: function (key) {
    return key._reactInternalInstance;
  },

  has: function (key) {
    return key._reactInternalInstance !== undefined;
  },

  set: function (key, value) {
    key._reactInternalInstance = value;
  }

};

module.exports = ReactInstanceMap;
},{}],459:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactIsomorphic
 */

'use strict';

var ReactChildren = require('./ReactChildren');
var ReactComponent = require('./ReactComponent');
var ReactClass = require('./ReactClass');
var ReactDOMFactories = require('./ReactDOMFactories');
var ReactElement = require('./ReactElement');
var ReactElementValidator = require('./ReactElementValidator');
var ReactPropTypes = require('./ReactPropTypes');
var ReactVersion = require('./ReactVersion');

var assign = require('./Object.assign');
var onlyChild = require('./onlyChild');

var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
var cloneElement = ReactElement.cloneElement;

if (process.env.NODE_ENV !== 'production') {
  createElement = ReactElementValidator.createElement;
  createFactory = ReactElementValidator.createFactory;
  cloneElement = ReactElementValidator.cloneElement;
}

var React = {

  // Modern

  Children: {
    map: ReactChildren.map,
    forEach: ReactChildren.forEach,
    count: ReactChildren.count,
    toArray: ReactChildren.toArray,
    only: onlyChild
  },

  Component: ReactComponent,

  createElement: createElement,
  cloneElement: cloneElement,
  isValidElement: ReactElement.isValidElement,

  // Classic

  PropTypes: ReactPropTypes,
  createClass: ReactClass.createClass,
  createFactory: createFactory,
  createMixin: function (mixin) {
    // Currently a noop. Will be used to validate and trace mixins.
    return mixin;
  },

  // This looks DOM specific but these are actually isomorphic helpers
  // since they are just generating DOM strings.
  DOM: ReactDOMFactories,

  version: ReactVersion,

  // Hook for JSX spread, don't use this for anything else.
  __spread: assign
};

module.exports = React;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactChildren":424,"./ReactClass":425,"./ReactComponent":426,"./ReactDOMFactories":434,"./ReactElement":448,"./ReactElementValidator":449,"./ReactPropTypes":470,"./ReactVersion":480,"./onlyChild":517,"_process":334}],460:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactMarkupChecksum
 */

'use strict';

var adler32 = require('./adler32');

var TAG_END = /\/?>/;

var ReactMarkupChecksum = {
  CHECKSUM_ATTR_NAME: 'data-react-checksum',

  /**
   * @param {string} markup Markup string
   * @return {string} Markup string with checksum attribute attached
   */
  addChecksumToMarkup: function (markup) {
    var checksum = adler32(markup);

    // Add checksum (handle both parent tags and self-closing tags)
    return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '"$&');
  },

  /**
   * @param {string} markup to use
   * @param {DOMElement} element root React element
   * @returns {boolean} whether or not the markup is the same
   */
  canReuseMarkup: function (markup, element) {
    var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
    existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
    var markupChecksum = adler32(markup);
    return markupChecksum === existingChecksum;
  }
};

module.exports = ReactMarkupChecksum;
},{"./adler32":499}],461:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactMount
 */

'use strict';

var DOMProperty = require('./DOMProperty');
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags');
var ReactElement = require('./ReactElement');
var ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactInstanceMap = require('./ReactInstanceMap');
var ReactMarkupChecksum = require('./ReactMarkupChecksum');
var ReactPerf = require('./ReactPerf');
var ReactReconciler = require('./ReactReconciler');
var ReactUpdateQueue = require('./ReactUpdateQueue');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var emptyObject = require('fbjs/lib/emptyObject');
var containsNode = require('fbjs/lib/containsNode');
var instantiateReactComponent = require('./instantiateReactComponent');
var invariant = require('fbjs/lib/invariant');
var setInnerHTML = require('./setInnerHTML');
var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
var validateDOMNesting = require('./validateDOMNesting');
var warning = require('fbjs/lib/warning');

var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
var nodeCache = {};

var ELEMENT_NODE_TYPE = 1;
var DOC_NODE_TYPE = 9;
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;

var ownerDocumentContextKey = '__ReactMount_ownerDocument$' + Math.random().toString(36).slice(2);

/** Mapping from reactRootID to React component instance. */
var instancesByReactRootID = {};

/** Mapping from reactRootID to `container` nodes. */
var containersByReactRootID = {};

if (process.env.NODE_ENV !== 'production') {
  /** __DEV__-only mapping from reactRootID to root elements. */
  var rootElementsByReactRootID = {};
}

// Used to store breadth-first search state in findComponentRoot.
var findComponentRootReusableArray = [];

/**
 * Finds the index of the first character
 * that's not common between the two given strings.
 *
 * @return {number} the index of the character where the strings diverge
 */
function firstDifferenceIndex(string1, string2) {
  var minLen = Math.min(string1.length, string2.length);
  for (var i = 0; i < minLen; i++) {
    if (string1.charAt(i) !== string2.charAt(i)) {
      return i;
    }
  }
  return string1.length === string2.length ? -1 : minLen;
}

/**
 * @param {DOMElement|DOMDocument} container DOM element that may contain
 * a React component
 * @return {?*} DOM element that may have the reactRoot ID, or null.
 */
function getReactRootElementInContainer(container) {
  if (!container) {
    return null;
  }

  if (container.nodeType === DOC_NODE_TYPE) {
    return container.documentElement;
  } else {
    return container.firstChild;
  }
}

/**
 * @param {DOMElement} container DOM element that may contain a React component.
 * @return {?string} A "reactRoot" ID, if a React component is rendered.
 */
function getReactRootID(container) {
  var rootElement = getReactRootElementInContainer(container);
  return rootElement && ReactMount.getID(rootElement);
}

/**
 * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
 * element can return its control whose name or ID equals ATTR_NAME. All
 * DOM nodes support `getAttributeNode` but this can also get called on
 * other objects so just return '' if we're given something other than a
 * DOM node (such as window).
 *
 * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
 * @return {string} ID of the supplied `domNode`.
 */
function getID(node) {
  var id = internalGetID(node);
  if (id) {
    if (nodeCache.hasOwnProperty(id)) {
      var cached = nodeCache[id];
      if (cached !== node) {
        !!isValid(cached, id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', ATTR_NAME, id) : invariant(false) : undefined;

        nodeCache[id] = node;
      }
    } else {
      nodeCache[id] = node;
    }
  }

  return id;
}

function internalGetID(node) {
  // If node is something like a window, document, or text node, none of
  // which support attributes or a .getAttribute method, gracefully return
  // the empty string, as if the attribute were missing.
  return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
}

/**
 * Sets the React-specific ID of the given node.
 *
 * @param {DOMElement} node The DOM node whose ID will be set.
 * @param {string} id The value of the ID attribute.
 */
function setID(node, id) {
  var oldID = internalGetID(node);
  if (oldID !== id) {
    delete nodeCache[oldID];
  }
  node.setAttribute(ATTR_NAME, id);
  nodeCache[id] = node;
}

/**
 * Finds the node with the supplied React-generated DOM ID.
 *
 * @param {string} id A React-generated DOM ID.
 * @return {DOMElement} DOM node with the suppled `id`.
 * @internal
 */
function getNode(id) {
  if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
    nodeCache[id] = ReactMount.findReactNodeByID(id);
  }
  return nodeCache[id];
}

/**
 * Finds the node with the supplied public React instance.
 *
 * @param {*} instance A public React instance.
 * @return {?DOMElement} DOM node with the suppled `id`.
 * @internal
 */
function getNodeFromInstance(instance) {
  var id = ReactInstanceMap.get(instance)._rootNodeID;
  if (ReactEmptyComponentRegistry.isNullComponentID(id)) {
    return null;
  }
  if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
    nodeCache[id] = ReactMount.findReactNodeByID(id);
  }
  return nodeCache[id];
}

/**
 * A node is "valid" if it is contained by a currently mounted container.
 *
 * This means that the node does not have to be contained by a document in
 * order to be considered valid.
 *
 * @param {?DOMElement} node The candidate DOM node.
 * @param {string} id The expected ID of the node.
 * @return {boolean} Whether the node is contained by a mounted container.
 */
function isValid(node, id) {
  if (node) {
    !(internalGetID(node) === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactMount: Unexpected modification of `%s`', ATTR_NAME) : invariant(false) : undefined;

    var container = ReactMount.findReactContainerForID(id);
    if (container && containsNode(container, node)) {
      return true;
    }
  }

  return false;
}

/**
 * Causes the cache to forget about one React-specific ID.
 *
 * @param {string} id The ID to forget.
 */
function purgeID(id) {
  delete nodeCache[id];
}

var deepestNodeSoFar = null;
function findDeepestCachedAncestorImpl(ancestorID) {
  var ancestor = nodeCache[ancestorID];
  if (ancestor && isValid(ancestor, ancestorID)) {
    deepestNodeSoFar = ancestor;
  } else {
    // This node isn't populated in the cache, so presumably none of its
    // descendants are. Break out of the loop.
    return false;
  }
}

/**
 * Return the deepest cached node whose ID is a prefix of `targetID`.
 */
function findDeepestCachedAncestor(targetID) {
  deepestNodeSoFar = null;
  ReactInstanceHandles.traverseAncestors(targetID, findDeepestCachedAncestorImpl);

  var foundNode = deepestNodeSoFar;
  deepestNodeSoFar = null;
  return foundNode;
}

/**
 * Mounts this component and inserts it into the DOM.
 *
 * @param {ReactComponent} componentInstance The instance to mount.
 * @param {string} rootID DOM ID of the root node.
 * @param {DOMElement} container DOM element to mount into.
 * @param {ReactReconcileTransaction} transaction
 * @param {boolean} shouldReuseMarkup If true, do not insert markup
 */
function mountComponentIntoNode(componentInstance, rootID, container, transaction, shouldReuseMarkup, context) {
  if (ReactDOMFeatureFlags.useCreateElement) {
    context = assign({}, context);
    if (container.nodeType === DOC_NODE_TYPE) {
      context[ownerDocumentContextKey] = container;
    } else {
      context[ownerDocumentContextKey] = container.ownerDocument;
    }
  }
  if (process.env.NODE_ENV !== 'production') {
    if (context === emptyObject) {
      context = {};
    }
    var tag = container.nodeName.toLowerCase();
    context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(null, tag, null);
  }
  var markup = ReactReconciler.mountComponent(componentInstance, rootID, transaction, context);
  componentInstance._renderedComponent._topLevelWrapper = componentInstance;
  ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup, transaction);
}

/**
 * Batched mount.
 *
 * @param {ReactComponent} componentInstance The instance to mount.
 * @param {string} rootID DOM ID of the root node.
 * @param {DOMElement} container DOM element to mount into.
 * @param {boolean} shouldReuseMarkup If true, do not insert markup
 */
function batchedMountComponentIntoNode(componentInstance, rootID, container, shouldReuseMarkup, context) {
  var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(
  /* forceHTML */shouldReuseMarkup);
  transaction.perform(mountComponentIntoNode, null, componentInstance, rootID, container, transaction, shouldReuseMarkup, context);
  ReactUpdates.ReactReconcileTransaction.release(transaction);
}

/**
 * Unmounts a component and removes it from the DOM.
 *
 * @param {ReactComponent} instance React component instance.
 * @param {DOMElement} container DOM element to unmount from.
 * @final
 * @internal
 * @see {ReactMount.unmountComponentAtNode}
 */
function unmountComponentFromNode(instance, container) {
  ReactReconciler.unmountComponent(instance);

  if (container.nodeType === DOC_NODE_TYPE) {
    container = container.documentElement;
  }

  // http://jsperf.com/emptying-a-node
  while (container.lastChild) {
    container.removeChild(container.lastChild);
  }
}

/**
 * True if the supplied DOM node has a direct React-rendered child that is
 * not a React root element. Useful for warning in `render`,
 * `unmountComponentAtNode`, etc.
 *
 * @param {?DOMElement} node The candidate DOM node.
 * @return {boolean} True if the DOM element contains a direct child that was
 * rendered by React but is not a root element.
 * @internal
 */
function hasNonRootReactChild(node) {
  var reactRootID = getReactRootID(node);
  return reactRootID ? reactRootID !== ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) : false;
}

/**
 * Returns the first (deepest) ancestor of a node which is rendered by this copy
 * of React.
 */
function findFirstReactDOMImpl(node) {
  // This node might be from another React instance, so we make sure not to
  // examine the node cache here
  for (; node && node.parentNode !== node; node = node.parentNode) {
    if (node.nodeType !== 1) {
      // Not a DOMElement, therefore not a React component
      continue;
    }
    var nodeID = internalGetID(node);
    if (!nodeID) {
      continue;
    }
    var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);

    // If containersByReactRootID contains the container we find by crawling up
    // the tree, we know that this instance of React rendered the node.
    // nb. isValid's strategy (with containsNode) does not work because render
    // trees may be nested and we don't want a false positive in that case.
    var current = node;
    var lastID;
    do {
      lastID = internalGetID(current);
      current = current.parentNode;
      if (current == null) {
        // The passed-in node has been detached from the container it was
        // originally rendered into.
        return null;
      }
    } while (lastID !== reactRootID);

    if (current === containersByReactRootID[reactRootID]) {
      return node;
    }
  }
  return null;
}

/**
 * Temporary (?) hack so that we can store all top-level pending updates on
 * composites instead of having to worry about different types of components
 * here.
 */
var TopLevelWrapper = function () {};
TopLevelWrapper.prototype.isReactComponent = {};
if (process.env.NODE_ENV !== 'production') {
  TopLevelWrapper.displayName = 'TopLevelWrapper';
}
TopLevelWrapper.prototype.render = function () {
  // this.props is actually a ReactElement
  return this.props;
};

/**
 * Mounting is the process of initializing a React component by creating its
 * representative DOM elements and inserting them into a supplied `container`.
 * Any prior content inside `container` is destroyed in the process.
 *
 *   ReactMount.render(
 *     component,
 *     document.getElementById('container')
 *   );
 *
 *   <div id="container">                   <-- Supplied `container`.
 *     <div data-reactid=".3">              <-- Rendered reactRoot of React
 *       // ...                                 component.
 *     </div>
 *   </div>
 *
 * Inside of `container`, the first element rendered is the "reactRoot".
 */
var ReactMount = {

  TopLevelWrapper: TopLevelWrapper,

  /** Exposed for debugging purposes **/
  _instancesByReactRootID: instancesByReactRootID,

  /**
   * This is a hook provided to support rendering React components while
   * ensuring that the apparent scroll position of its `container` does not
   * change.
   *
   * @param {DOMElement} container The `container` being rendered into.
   * @param {function} renderCallback This must be called once to do the render.
   */
  scrollMonitor: function (container, renderCallback) {
    renderCallback();
  },

  /**
   * Take a component that's already mounted into the DOM and replace its props
   * @param {ReactComponent} prevComponent component instance already in the DOM
   * @param {ReactElement} nextElement component instance to render
   * @param {DOMElement} container container to render into
   * @param {?function} callback function triggered on completion
   */
  _updateRootComponent: function (prevComponent, nextElement, container, callback) {
    ReactMount.scrollMonitor(container, function () {
      ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);
      if (callback) {
        ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
      }
    });

    if (process.env.NODE_ENV !== 'production') {
      // Record the root element in case it later gets transplanted.
      rootElementsByReactRootID[getReactRootID(container)] = getReactRootElementInContainer(container);
    }

    return prevComponent;
  },

  /**
   * Register a component into the instance map and starts scroll value
   * monitoring
   * @param {ReactComponent} nextComponent component instance to render
   * @param {DOMElement} container container to render into
   * @return {string} reactRoot ID prefix
   */
  _registerComponent: function (nextComponent, container) {
    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : invariant(false) : undefined;

    ReactBrowserEventEmitter.ensureScrollValueMonitoring();

    var reactRootID = ReactMount.registerContainer(container);
    instancesByReactRootID[reactRootID] = nextComponent;
    return reactRootID;
  },

  /**
   * Render a new component into the DOM.
   * @param {ReactElement} nextElement element to render
   * @param {DOMElement} container container to render into
   * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
   * @return {ReactComponent} nextComponent
   */
  _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) {
    // Various parts of our code (such as ReactCompositeComponent's
    // _renderValidatedComponent) assume that calls to render aren't nested;
    // verify that that's the case.
    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined;

    var componentInstance = instantiateReactComponent(nextElement, null);
    var reactRootID = ReactMount._registerComponent(componentInstance, container);

    // The initial render is synchronous but any updates that happen during
    // rendering, in componentWillMount or componentDidMount, will be batched
    // according to the current batching strategy.

    ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, reactRootID, container, shouldReuseMarkup, context);

    if (process.env.NODE_ENV !== 'production') {
      // Record the root element in case it later gets transplanted.
      rootElementsByReactRootID[reactRootID] = getReactRootElementInContainer(container);
    }

    return componentInstance;
  },

  /**
   * Renders a React component into the DOM in the supplied `container`.
   *
   * If the React component was previously rendered into `container`, this will
   * perform an update on it and only mutate the DOM as necessary to reflect the
   * latest React component.
   *
   * @param {ReactComponent} parentComponent The conceptual parent of this render tree.
   * @param {ReactElement} nextElement Component element to render.
   * @param {DOMElement} container DOM element to render into.
   * @param {?function} callback function triggered on completion
   * @return {ReactComponent} Component instance rendered in `container`.
   */
  renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
    !(parentComponent != null && parentComponent._reactInternalInstance != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : invariant(false) : undefined;
    return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback);
  },

  _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
    !ReactElement.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing an element string, make sure to instantiate ' + 'it by passing it to React.createElement.' : typeof nextElement === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' :
    // Check if it quacks like an element
    nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : invariant(false) : undefined;

    process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : undefined;

    var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement);

    var prevComponent = instancesByReactRootID[getReactRootID(container)];

    if (prevComponent) {
      var prevWrappedElement = prevComponent._currentElement;
      var prevElement = prevWrappedElement.props;
      if (shouldUpdateReactComponent(prevElement, nextElement)) {
        var publicInst = prevComponent._renderedComponent.getPublicInstance();
        var updatedCallback = callback && function () {
          callback.call(publicInst);
        };
        ReactMount._updateRootComponent(prevComponent, nextWrappedElement, container, updatedCallback);
        return publicInst;
      } else {
        ReactMount.unmountComponentAtNode(container);
      }
    }

    var reactRootElement = getReactRootElementInContainer(container);
    var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);
    var containerHasNonRootReactChild = hasNonRootReactChild(container);

    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : undefined;

      if (!containerHasReactMarkup || reactRootElement.nextSibling) {
        var rootElementSibling = reactRootElement;
        while (rootElementSibling) {
          if (internalGetID(rootElementSibling)) {
            process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : undefined;
            break;
          }
          rootElementSibling = rootElementSibling.nextSibling;
        }
      }
    }

    var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;
    var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, parentComponent != null ? parentComponent._reactInternalInstance._processChildContext(parentComponent._reactInternalInstance._context) : emptyObject)._renderedComponent.getPublicInstance();
    if (callback) {
      callback.call(component);
    }
    return component;
  },

  /**
   * Renders a React component into the DOM in the supplied `container`.
   *
   * If the React component was previously rendered into `container`, this will
   * perform an update on it and only mutate the DOM as necessary to reflect the
   * latest React component.
   *
   * @param {ReactElement} nextElement Component element to render.
   * @param {DOMElement} container DOM element to render into.
   * @param {?function} callback function triggered on completion
   * @return {ReactComponent} Component instance rendered in `container`.
   */
  render: function (nextElement, container, callback) {
    return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback);
  },

  /**
   * Registers a container node into which React components will be rendered.
   * This also creates the "reactRoot" ID that will be assigned to the element
   * rendered within.
   *
   * @param {DOMElement} container DOM element to register as a container.
   * @return {string} The "reactRoot" ID of elements rendered within.
   */
  registerContainer: function (container) {
    var reactRootID = getReactRootID(container);
    if (reactRootID) {
      // If one exists, make sure it is a valid "reactRoot" ID.
      reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
    }
    if (!reactRootID) {
      // No valid "reactRoot" ID found, create one.
      reactRootID = ReactInstanceHandles.createReactRootID();
    }
    containersByReactRootID[reactRootID] = container;
    return reactRootID;
  },

  /**
   * Unmounts and destroys the React component rendered in the `container`.
   *
   * @param {DOMElement} container DOM element containing a React component.
   * @return {boolean} True if a component was found in and unmounted from
   *                   `container`
   */
  unmountComponentAtNode: function (container) {
    // Various parts of our code (such as ReactCompositeComponent's
    // _renderValidatedComponent) assume that calls to render aren't nested;
    // verify that that's the case. (Strictly speaking, unmounting won't cause a
    // render but we still don't expect to be in a render call here.)
    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : undefined;

    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : invariant(false) : undefined;

    var reactRootID = getReactRootID(container);
    var component = instancesByReactRootID[reactRootID];
    if (!component) {
      // Check if the node being unmounted was rendered by React, but isn't a
      // root node.
      var containerHasNonRootReactChild = hasNonRootReactChild(container);

      // Check if the container itself is a React root node.
      var containerID = internalGetID(container);
      var isContainerReactRoot = containerID && containerID === ReactInstanceHandles.getReactRootIDFromNodeID(containerID);

      if (process.env.NODE_ENV !== 'production') {
        process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : undefined;
      }

      return false;
    }
    ReactUpdates.batchedUpdates(unmountComponentFromNode, component, container);
    delete instancesByReactRootID[reactRootID];
    delete containersByReactRootID[reactRootID];
    if (process.env.NODE_ENV !== 'production') {
      delete rootElementsByReactRootID[reactRootID];
    }
    return true;
  },

  /**
   * Finds the container DOM element that contains React component to which the
   * supplied DOM `id` belongs.
   *
   * @param {string} id The ID of an element rendered by a React component.
   * @return {?DOMElement} DOM element that contains the `id`.
   */
  findReactContainerForID: function (id) {
    var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
    var container = containersByReactRootID[reactRootID];

    if (process.env.NODE_ENV !== 'production') {
      var rootElement = rootElementsByReactRootID[reactRootID];
      if (rootElement && rootElement.parentNode !== container) {
        process.env.NODE_ENV !== 'production' ? warning(
        // Call internalGetID here because getID calls isValid which calls
        // findReactContainerForID (this function).
        internalGetID(rootElement) === reactRootID, 'ReactMount: Root element ID differed from reactRootID.') : undefined;
        var containerChild = container.firstChild;
        if (containerChild && reactRootID === internalGetID(containerChild)) {
          // If the container has a new child with the same ID as the old
          // root element, then rootElementsByReactRootID[reactRootID] is
          // just stale and needs to be updated. The case that deserves a
          // warning is when the container is empty.
          rootElementsByReactRootID[reactRootID] = containerChild;
        } else {
          process.env.NODE_ENV !== 'production' ? warning(false, 'ReactMount: Root element has been removed from its original ' + 'container. New container: %s', rootElement.parentNode) : undefined;
        }
      }
    }

    return container;
  },

  /**
   * Finds an element rendered by React with the supplied ID.
   *
   * @param {string} id ID of a DOM node in the React component.
   * @return {DOMElement} Root DOM node of the React component.
   */
  findReactNodeByID: function (id) {
    var reactRoot = ReactMount.findReactContainerForID(id);
    return ReactMount.findComponentRoot(reactRoot, id);
  },

  /**
   * Traverses up the ancestors of the supplied node to find a node that is a
   * DOM representation of a React component rendered by this copy of React.
   *
   * @param {*} node
   * @return {?DOMEventTarget}
   * @internal
   */
  getFirstReactDOM: function (node) {
    return findFirstReactDOMImpl(node);
  },

  /**
   * Finds a node with the supplied `targetID` inside of the supplied
   * `ancestorNode`.  Exploits the ID naming scheme to perform the search
   * quickly.
   *
   * @param {DOMEventTarget} ancestorNode Search from this root.
   * @pararm {string} targetID ID of the DOM representation of the component.
   * @return {DOMEventTarget} DOM node with the supplied `targetID`.
   * @internal
   */
  findComponentRoot: function (ancestorNode, targetID) {
    var firstChildren = findComponentRootReusableArray;
    var childIndex = 0;

    var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;

    if (process.env.NODE_ENV !== 'production') {
      // This will throw on the next line; give an early warning
      process.env.NODE_ENV !== 'production' ? warning(deepestAncestor != null, 'React can\'t find the root component node for data-reactid value ' + '`%s`. If you\'re seeing this message, it probably means that ' + 'you\'ve loaded two copies of React on the page. At this time, only ' + 'a single copy of React can be loaded at a time.', targetID) : undefined;
    }

    firstChildren[0] = deepestAncestor.firstChild;
    firstChildren.length = 1;

    while (childIndex < firstChildren.length) {
      var child = firstChildren[childIndex++];
      var targetChild;

      while (child) {
        var childID = ReactMount.getID(child);
        if (childID) {
          // Even if we find the node we're looking for, we finish looping
          // through its siblings to ensure they're cached so that we don't have
          // to revisit this node again. Otherwise, we make n^2 calls to getID
          // when visiting the many children of a single node in order.

          if (targetID === childID) {
            targetChild = child;
          } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {
            // If we find a child whose ID is an ancestor of the given ID,
            // then we can be sure that we only want to search the subtree
            // rooted at this child, so we can throw out the rest of the
            // search state.
            firstChildren.length = childIndex = 0;
            firstChildren.push(child.firstChild);
          }
        } else {
          // If this child had no ID, then there's a chance that it was
          // injected automatically by the browser, as when a `<table>`
          // element sprouts an extra `<tbody>` child as a side effect of
          // `.innerHTML` parsing. Optimistically continue down this
          // branch, but not before examining the other siblings.
          firstChildren.push(child.firstChild);
        }

        child = child.nextSibling;
      }

      if (targetChild) {
        // Emptying firstChildren/findComponentRootReusableArray is
        // not necessary for correctness, but it helps the GC reclaim
        // any nodes that were left at the end of the search.
        firstChildren.length = 0;

        return targetChild;
      }
    }

    firstChildren.length = 0;

    !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findComponentRoot(..., %s): Unable to find element. This probably ' + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 'usually due to forgetting a <tbody> when using tables, nesting tags ' + 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + 'parent. ' + 'Try inspecting the child nodes of the element with React ID `%s`.', targetID, ReactMount.getID(ancestorNode)) : invariant(false) : undefined;
  },

  _mountImageIntoNode: function (markup, container, shouldReuseMarkup, transaction) {
    !(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : invariant(false) : undefined;

    if (shouldReuseMarkup) {
      var rootElement = getReactRootElementInContainer(container);
      if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
        return;
      } else {
        var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
        rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);

        var rootMarkup = rootElement.outerHTML;
        rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum);

        var normalizedMarkup = markup;
        if (process.env.NODE_ENV !== 'production') {
          // because rootMarkup is retrieved from the DOM, various normalizations
          // will have occurred which will not be present in `markup`. Here,
          // insert markup into a <div> or <iframe> depending on the container
          // type to perform the same normalizations before comparing.
          var normalizer;
          if (container.nodeType === ELEMENT_NODE_TYPE) {
            normalizer = document.createElement('div');
            normalizer.innerHTML = markup;
            normalizedMarkup = normalizer.innerHTML;
          } else {
            normalizer = document.createElement('iframe');
            document.body.appendChild(normalizer);
            normalizer.contentDocument.write(markup);
            normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML;
            document.body.removeChild(normalizer);
          }
        }

        var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup);
        var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);

        !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document using ' + 'server rendering but the checksum was invalid. This usually ' + 'means you rendered a different component type or props on ' + 'the client from the one on the server, or your render() ' + 'methods are impure. React cannot handle this case due to ' + 'cross-browser quirks by rendering at the document root. You ' + 'should look for environment dependent code in your components ' + 'and ensure the props are the same client and server side:\n%s', difference) : invariant(false) : undefined;

        if (process.env.NODE_ENV !== 'production') {
          process.env.NODE_ENV !== 'production' ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\n%s', difference) : undefined;
        }
      }
    }

    !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but ' + 'you didn\'t use server rendering. We can\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined;

    if (transaction.useCreateElement) {
      while (container.lastChild) {
        container.removeChild(container.lastChild);
      }
      container.appendChild(markup);
    } else {
      setInnerHTML(container, markup);
    }
  },

  ownerDocumentContextKey: ownerDocumentContextKey,

  /**
   * React ID utilities.
   */

  getReactRootID: getReactRootID,

  getID: getID,

  setID: setID,

  getNode: getNode,

  getNodeFromInstance: getNodeFromInstance,

  isValid: isValid,

  purgeID: purgeID
};

ReactPerf.measureMethods(ReactMount, 'ReactMount', {
  _renderNewRootComponent: '_renderNewRootComponent',
  _mountImageIntoNode: '_mountImageIntoNode'
});

module.exports = ReactMount;
}).call(this,require('_process'))

},{"./DOMProperty":405,"./Object.assign":418,"./ReactBrowserEventEmitter":422,"./ReactCurrentOwner":430,"./ReactDOMFeatureFlags":435,"./ReactElement":448,"./ReactEmptyComponentRegistry":451,"./ReactInstanceHandles":457,"./ReactInstanceMap":458,"./ReactMarkupChecksum":460,"./ReactPerf":467,"./ReactReconciler":472,"./ReactUpdateQueue":478,"./ReactUpdates":479,"./instantiateReactComponent":514,"./setInnerHTML":520,"./shouldUpdateReactComponent":522,"./validateDOMNesting":524,"_process":334,"fbjs/lib/containsNode":307,"fbjs/lib/emptyObject":311,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],462:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactMultiChild
 * @typechecks static-only
 */

'use strict';

var ReactComponentEnvironment = require('./ReactComponentEnvironment');
var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes');

var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactReconciler = require('./ReactReconciler');
var ReactChildReconciler = require('./ReactChildReconciler');

var flattenChildren = require('./flattenChildren');

/**
 * Updating children of a component may trigger recursive updates. The depth is
 * used to batch recursive updates to render markup more efficiently.
 *
 * @type {number}
 * @private
 */
var updateDepth = 0;

/**
 * Queue of update configuration objects.
 *
 * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
 *
 * @type {array<object>}
 * @private
 */
var updateQueue = [];

/**
 * Queue of markup to be rendered.
 *
 * @type {array<string>}
 * @private
 */
var markupQueue = [];

/**
 * Enqueues markup to be rendered and inserted at a supplied index.
 *
 * @param {string} parentID ID of the parent component.
 * @param {string} markup Markup that renders into an element.
 * @param {number} toIndex Destination index.
 * @private
 */
function enqueueInsertMarkup(parentID, markup, toIndex) {
  // NOTE: Null values reduce hidden classes.
  updateQueue.push({
    parentID: parentID,
    parentNode: null,
    type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
    markupIndex: markupQueue.push(markup) - 1,
    content: null,
    fromIndex: null,
    toIndex: toIndex
  });
}

/**
 * Enqueues moving an existing element to another index.
 *
 * @param {string} parentID ID of the parent component.
 * @param {number} fromIndex Source index of the existing element.
 * @param {number} toIndex Destination index of the element.
 * @private
 */
function enqueueMove(parentID, fromIndex, toIndex) {
  // NOTE: Null values reduce hidden classes.
  updateQueue.push({
    parentID: parentID,
    parentNode: null,
    type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
    markupIndex: null,
    content: null,
    fromIndex: fromIndex,
    toIndex: toIndex
  });
}

/**
 * Enqueues removing an element at an index.
 *
 * @param {string} parentID ID of the parent component.
 * @param {number} fromIndex Index of the element to remove.
 * @private
 */
function enqueueRemove(parentID, fromIndex) {
  // NOTE: Null values reduce hidden classes.
  updateQueue.push({
    parentID: parentID,
    parentNode: null,
    type: ReactMultiChildUpdateTypes.REMOVE_NODE,
    markupIndex: null,
    content: null,
    fromIndex: fromIndex,
    toIndex: null
  });
}

/**
 * Enqueues setting the markup of a node.
 *
 * @param {string} parentID ID of the parent component.
 * @param {string} markup Markup that renders into an element.
 * @private
 */
function enqueueSetMarkup(parentID, markup) {
  // NOTE: Null values reduce hidden classes.
  updateQueue.push({
    parentID: parentID,
    parentNode: null,
    type: ReactMultiChildUpdateTypes.SET_MARKUP,
    markupIndex: null,
    content: markup,
    fromIndex: null,
    toIndex: null
  });
}

/**
 * Enqueues setting the text content.
 *
 * @param {string} parentID ID of the parent component.
 * @param {string} textContent Text content to set.
 * @private
 */
function enqueueTextContent(parentID, textContent) {
  // NOTE: Null values reduce hidden classes.
  updateQueue.push({
    parentID: parentID,
    parentNode: null,
    type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
    markupIndex: null,
    content: textContent,
    fromIndex: null,
    toIndex: null
  });
}

/**
 * Processes any enqueued updates.
 *
 * @private
 */
function processQueue() {
  if (updateQueue.length) {
    ReactComponentEnvironment.processChildrenUpdates(updateQueue, markupQueue);
    clearQueue();
  }
}

/**
 * Clears any enqueued updates.
 *
 * @private
 */
function clearQueue() {
  updateQueue.length = 0;
  markupQueue.length = 0;
}

/**
 * ReactMultiChild are capable of reconciling multiple children.
 *
 * @class ReactMultiChild
 * @internal
 */
var ReactMultiChild = {

  /**
   * Provides common functionality for components that must reconcile multiple
   * children. This is used by `ReactDOMComponent` to mount, update, and
   * unmount child components.
   *
   * @lends {ReactMultiChild.prototype}
   */
  Mixin: {

    _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) {
      if (process.env.NODE_ENV !== 'production') {
        if (this._currentElement) {
          try {
            ReactCurrentOwner.current = this._currentElement._owner;
            return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);
          } finally {
            ReactCurrentOwner.current = null;
          }
        }
      }
      return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);
    },

    _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, transaction, context) {
      var nextChildren;
      if (process.env.NODE_ENV !== 'production') {
        if (this._currentElement) {
          try {
            ReactCurrentOwner.current = this._currentElement._owner;
            nextChildren = flattenChildren(nextNestedChildrenElements);
          } finally {
            ReactCurrentOwner.current = null;
          }
          return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context);
        }
      }
      nextChildren = flattenChildren(nextNestedChildrenElements);
      return ReactChildReconciler.updateChildren(prevChildren, nextChildren, transaction, context);
    },

    /**
     * Generates a "mount image" for each of the supplied children. In the case
     * of `ReactDOMComponent`, a mount image is a string of markup.
     *
     * @param {?object} nestedChildren Nested child maps.
     * @return {array} An array of mounted representations.
     * @internal
     */
    mountChildren: function (nestedChildren, transaction, context) {
      var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context);
      this._renderedChildren = children;
      var mountImages = [];
      var index = 0;
      for (var name in children) {
        if (children.hasOwnProperty(name)) {
          var child = children[name];
          // Inlined for performance, see `ReactInstanceHandles.createReactID`.
          var rootID = this._rootNodeID + name;
          var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context);
          child._mountIndex = index++;
          mountImages.push(mountImage);
        }
      }
      return mountImages;
    },

    /**
     * Replaces any rendered children with a text content string.
     *
     * @param {string} nextContent String of content.
     * @internal
     */
    updateTextContent: function (nextContent) {
      updateDepth++;
      var errorThrown = true;
      try {
        var prevChildren = this._renderedChildren;
        // Remove any rendered children.
        ReactChildReconciler.unmountChildren(prevChildren);
        // TODO: The setTextContent operation should be enough
        for (var name in prevChildren) {
          if (prevChildren.hasOwnProperty(name)) {
            this._unmountChild(prevChildren[name]);
          }
        }
        // Set new text content.
        this.setTextContent(nextContent);
        errorThrown = false;
      } finally {
        updateDepth--;
        if (!updateDepth) {
          if (errorThrown) {
            clearQueue();
          } else {
            processQueue();
          }
        }
      }
    },

    /**
     * Replaces any rendered children with a markup string.
     *
     * @param {string} nextMarkup String of markup.
     * @internal
     */
    updateMarkup: function (nextMarkup) {
      updateDepth++;
      var errorThrown = true;
      try {
        var prevChildren = this._renderedChildren;
        // Remove any rendered children.
        ReactChildReconciler.unmountChildren(prevChildren);
        for (var name in prevChildren) {
          if (prevChildren.hasOwnProperty(name)) {
            this._unmountChildByName(prevChildren[name], name);
          }
        }
        this.setMarkup(nextMarkup);
        errorThrown = false;
      } finally {
        updateDepth--;
        if (!updateDepth) {
          if (errorThrown) {
            clearQueue();
          } else {
            processQueue();
          }
        }
      }
    },

    /**
     * Updates the rendered children with new children.
     *
     * @param {?object} nextNestedChildrenElements Nested child element maps.
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    updateChildren: function (nextNestedChildrenElements, transaction, context) {
      updateDepth++;
      var errorThrown = true;
      try {
        this._updateChildren(nextNestedChildrenElements, transaction, context);
        errorThrown = false;
      } finally {
        updateDepth--;
        if (!updateDepth) {
          if (errorThrown) {
            clearQueue();
          } else {
            processQueue();
          }
        }
      }
    },

    /**
     * Improve performance by isolating this hot code path from the try/catch
     * block in `updateChildren`.
     *
     * @param {?object} nextNestedChildrenElements Nested child element maps.
     * @param {ReactReconcileTransaction} transaction
     * @final
     * @protected
     */
    _updateChildren: function (nextNestedChildrenElements, transaction, context) {
      var prevChildren = this._renderedChildren;
      var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, transaction, context);
      this._renderedChildren = nextChildren;
      if (!nextChildren && !prevChildren) {
        return;
      }
      var name;
      // `nextIndex` will increment for each child in `nextChildren`, but
      // `lastIndex` will be the last index visited in `prevChildren`.
      var lastIndex = 0;
      var nextIndex = 0;
      for (name in nextChildren) {
        if (!nextChildren.hasOwnProperty(name)) {
          continue;
        }
        var prevChild = prevChildren && prevChildren[name];
        var nextChild = nextChildren[name];
        if (prevChild === nextChild) {
          this.moveChild(prevChild, nextIndex, lastIndex);
          lastIndex = Math.max(prevChild._mountIndex, lastIndex);
          prevChild._mountIndex = nextIndex;
        } else {
          if (prevChild) {
            // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
            lastIndex = Math.max(prevChild._mountIndex, lastIndex);
            this._unmountChild(prevChild);
          }
          // The child must be instantiated before it's mounted.
          this._mountChildByNameAtIndex(nextChild, name, nextIndex, transaction, context);
        }
        nextIndex++;
      }
      // Remove children that are no longer present.
      for (name in prevChildren) {
        if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
          this._unmountChild(prevChildren[name]);
        }
      }
    },

    /**
     * Unmounts all rendered children. This should be used to clean up children
     * when this component is unmounted.
     *
     * @internal
     */
    unmountChildren: function () {
      var renderedChildren = this._renderedChildren;
      ReactChildReconciler.unmountChildren(renderedChildren);
      this._renderedChildren = null;
    },

    /**
     * Moves a child component to the supplied index.
     *
     * @param {ReactComponent} child Component to move.
     * @param {number} toIndex Destination index of the element.
     * @param {number} lastIndex Last index visited of the siblings of `child`.
     * @protected
     */
    moveChild: function (child, toIndex, lastIndex) {
      // If the index of `child` is less than `lastIndex`, then it needs to
      // be moved. Otherwise, we do not need to move it because a child will be
      // inserted or moved before `child`.
      if (child._mountIndex < lastIndex) {
        enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
      }
    },

    /**
     * Creates a child component.
     *
     * @param {ReactComponent} child Component to create.
     * @param {string} mountImage Markup to insert.
     * @protected
     */
    createChild: function (child, mountImage) {
      enqueueInsertMarkup(this._rootNodeID, mountImage, child._mountIndex);
    },

    /**
     * Removes a child component.
     *
     * @param {ReactComponent} child Child to remove.
     * @protected
     */
    removeChild: function (child) {
      enqueueRemove(this._rootNodeID, child._mountIndex);
    },

    /**
     * Sets this text content string.
     *
     * @param {string} textContent Text content to set.
     * @protected
     */
    setTextContent: function (textContent) {
      enqueueTextContent(this._rootNodeID, textContent);
    },

    /**
     * Sets this markup string.
     *
     * @param {string} markup Markup to set.
     * @protected
     */
    setMarkup: function (markup) {
      enqueueSetMarkup(this._rootNodeID, markup);
    },

    /**
     * Mounts a child with the supplied name.
     *
     * NOTE: This is part of `updateChildren` and is here for readability.
     *
     * @param {ReactComponent} child Component to mount.
     * @param {string} name Name of the child.
     * @param {number} index Index at which to insert the child.
     * @param {ReactReconcileTransaction} transaction
     * @private
     */
    _mountChildByNameAtIndex: function (child, name, index, transaction, context) {
      // Inlined for performance, see `ReactInstanceHandles.createReactID`.
      var rootID = this._rootNodeID + name;
      var mountImage = ReactReconciler.mountComponent(child, rootID, transaction, context);
      child._mountIndex = index;
      this.createChild(child, mountImage);
    },

    /**
     * Unmounts a rendered child.
     *
     * NOTE: This is part of `updateChildren` and is here for readability.
     *
     * @param {ReactComponent} child Component to unmount.
     * @private
     */
    _unmountChild: function (child) {
      this.removeChild(child);
      child._mountIndex = null;
    }

  }

};

module.exports = ReactMultiChild;
}).call(this,require('_process'))

},{"./ReactChildReconciler":423,"./ReactComponentEnvironment":428,"./ReactCurrentOwner":430,"./ReactMultiChildUpdateTypes":463,"./ReactReconciler":472,"./flattenChildren":505,"_process":334}],463:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactMultiChildUpdateTypes
 */

'use strict';

var keyMirror = require('fbjs/lib/keyMirror');

/**
 * When a component's children are updated, a series of update configuration
 * objects are created in order to batch and serialize the required changes.
 *
 * Enumerates all the possible types of update configurations.
 *
 * @internal
 */
var ReactMultiChildUpdateTypes = keyMirror({
  INSERT_MARKUP: null,
  MOVE_EXISTING: null,
  REMOVE_NODE: null,
  SET_MARKUP: null,
  TEXT_CONTENT: null
});

module.exports = ReactMultiChildUpdateTypes;
},{"fbjs/lib/keyMirror":321}],464:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactNativeComponent
 */

'use strict';

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');

var autoGenerateWrapperClass = null;
var genericComponentClass = null;
// This registry keeps track of wrapper classes around native tags.
var tagToComponentClass = {};
var textComponentClass = null;

var ReactNativeComponentInjection = {
  // This accepts a class that receives the tag string. This is a catch all
  // that can render any kind of tag.
  injectGenericComponentClass: function (componentClass) {
    genericComponentClass = componentClass;
  },
  // This accepts a text component class that takes the text string to be
  // rendered as props.
  injectTextComponentClass: function (componentClass) {
    textComponentClass = componentClass;
  },
  // This accepts a keyed object with classes as values. Each key represents a
  // tag. That particular tag will use this class instead of the generic one.
  injectComponentClasses: function (componentClasses) {
    assign(tagToComponentClass, componentClasses);
  }
};

/**
 * Get a composite component wrapper class for a specific tag.
 *
 * @param {ReactElement} element The tag for which to get the class.
 * @return {function} The React class constructor function.
 */
function getComponentClassForElement(element) {
  if (typeof element.type === 'function') {
    return element.type;
  }
  var tag = element.type;
  var componentClass = tagToComponentClass[tag];
  if (componentClass == null) {
    tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag);
  }
  return componentClass;
}

/**
 * Get a native internal component class for a specific tag.
 *
 * @param {ReactElement} element The element to create.
 * @return {function} The internal class constructor function.
 */
function createInternalComponent(element) {
  !genericComponentClass ? process.env.NODE_ENV !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : invariant(false) : undefined;
  return new genericComponentClass(element.type, element.props);
}

/**
 * @param {ReactText} text
 * @return {ReactComponent}
 */
function createInstanceForText(text) {
  return new textComponentClass(text);
}

/**
 * @param {ReactComponent} component
 * @return {boolean}
 */
function isTextComponent(component) {
  return component instanceof textComponentClass;
}

var ReactNativeComponent = {
  getComponentClassForElement: getComponentClassForElement,
  createInternalComponent: createInternalComponent,
  createInstanceForText: createInstanceForText,
  isTextComponent: isTextComponent,
  injection: ReactNativeComponentInjection
};

module.exports = ReactNativeComponent;
}).call(this,require('_process'))

},{"./Object.assign":418,"_process":334,"fbjs/lib/invariant":318}],465:[function(require,module,exports){
(function (process){
/**
 * Copyright 2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactNoopUpdateQueue
 */

'use strict';

var warning = require('fbjs/lib/warning');

function warnTDZ(publicInstance, callerName) {
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor && publicInstance.constructor.displayName || '') : undefined;
  }
}

/**
 * This is the abstract API for an update queue.
 */
var ReactNoopUpdateQueue = {

  /**
   * Checks whether or not this composite component is mounted.
   * @param {ReactClass} publicInstance The instance we want to test.
   * @return {boolean} True if mounted, false otherwise.
   * @protected
   * @final
   */
  isMounted: function (publicInstance) {
    return false;
  },

  /**
   * Enqueue a callback that will be executed after all the pending updates
   * have processed.
   *
   * @param {ReactClass} publicInstance The instance to use as `this` context.
   * @param {?function} callback Called after state is updated.
   * @internal
   */
  enqueueCallback: function (publicInstance, callback) {},

  /**
   * Forces an update. This should only be invoked when it is known with
   * certainty that we are **not** in a DOM transaction.
   *
   * You may want to call this when you know that some deeper aspect of the
   * component's state has changed but `setState` was not called.
   *
   * This will not invoke `shouldComponentUpdate`, but it will invoke
   * `componentWillUpdate` and `componentDidUpdate`.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @internal
   */
  enqueueForceUpdate: function (publicInstance) {
    warnTDZ(publicInstance, 'forceUpdate');
  },

  /**
   * Replaces all of the state. Always use this or `setState` to mutate state.
   * You should treat `this.state` as immutable.
   *
   * There is no guarantee that `this.state` will be immediately updated, so
   * accessing `this.state` after calling this method may return the old value.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} completeState Next state.
   * @internal
   */
  enqueueReplaceState: function (publicInstance, completeState) {
    warnTDZ(publicInstance, 'replaceState');
  },

  /**
   * Sets a subset of the state. This only exists because _pendingState is
   * internal. This provides a merging strategy that is not available to deep
   * properties which is confusing. TODO: Expose pendingState or don't use it
   * during the merge.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} partialState Next partial state to be merged with state.
   * @internal
   */
  enqueueSetState: function (publicInstance, partialState) {
    warnTDZ(publicInstance, 'setState');
  },

  /**
   * Sets a subset of the props.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} partialProps Subset of the next props.
   * @internal
   */
  enqueueSetProps: function (publicInstance, partialProps) {
    warnTDZ(publicInstance, 'setProps');
  },

  /**
   * Replaces all of the props.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} props New props.
   * @internal
   */
  enqueueReplaceProps: function (publicInstance, props) {
    warnTDZ(publicInstance, 'replaceProps');
  }

};

module.exports = ReactNoopUpdateQueue;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/warning":329}],466:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactOwner
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 * ReactOwners are capable of storing references to owned components.
 *
 * All components are capable of //being// referenced by owner components, but
 * only ReactOwner components are capable of //referencing// owned components.
 * The named reference is known as a "ref".
 *
 * Refs are available when mounted and updated during reconciliation.
 *
 *   var MyComponent = React.createClass({
 *     render: function() {
 *       return (
 *         <div onClick={this.handleClick}>
 *           <CustomComponent ref="custom" />
 *         </div>
 *       );
 *     },
 *     handleClick: function() {
 *       this.refs.custom.handleClick();
 *     },
 *     componentDidMount: function() {
 *       this.refs.custom.initialize();
 *     }
 *   });
 *
 * Refs should rarely be used. When refs are used, they should only be done to
 * control data that is not handled by React's data flow.
 *
 * @class ReactOwner
 */
var ReactOwner = {

  /**
   * @param {?object} object
   * @return {boolean} True if `object` is a valid owner.
   * @final
   */
  isValidOwner: function (object) {
    return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function');
  },

  /**
   * Adds a component by ref to an owner component.
   *
   * @param {ReactComponent} component Component to reference.
   * @param {string} ref Name by which to refer to the component.
   * @param {ReactOwner} owner Component on which to record the ref.
   * @final
   * @internal
   */
  addComponentAsRefTo: function (component, ref, owner) {
    !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might ' + 'be adding a ref to a component that was not created inside a component\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined;
    owner.attachRef(ref, component);
  },

  /**
   * Removes a component by ref from an owner component.
   *
   * @param {ReactComponent} component Component to dereference.
   * @param {string} ref Name of the ref to remove.
   * @param {ReactOwner} owner Component on which the ref is recorded.
   * @final
   * @internal
   */
  removeComponentAsRefFrom: function (component, ref, owner) {
    !ReactOwner.isValidOwner(owner) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might ' + 'be removing a ref to a component that was not created inside a component\'s ' + '`render` method, or you have multiple copies of React loaded ' + '(details: https://fb.me/react-refs-must-have-owner).') : invariant(false) : undefined;
    // Check that `component` is still the current ref because we do not want to
    // detach the ref if another component stole it.
    if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) {
      owner.detachRef(ref);
    }
  }

};

module.exports = ReactOwner;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],467:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactPerf
 * @typechecks static-only
 */

'use strict';

/**
 * ReactPerf is a general AOP system designed to measure performance. This
 * module only has the hooks: see ReactDefaultPerf for the analysis tool.
 */
var ReactPerf = {
  /**
   * Boolean to enable/disable measurement. Set to false by default to prevent
   * accidental logging and perf loss.
   */
  enableMeasure: false,

  /**
   * Holds onto the measure function in use. By default, don't measure
   * anything, but we'll override this if we inject a measure function.
   */
  storedMeasure: _noMeasure,

  /**
   * @param {object} object
   * @param {string} objectName
   * @param {object<string>} methodNames
   */
  measureMethods: function (object, objectName, methodNames) {
    if (process.env.NODE_ENV !== 'production') {
      for (var key in methodNames) {
        if (!methodNames.hasOwnProperty(key)) {
          continue;
        }
        object[key] = ReactPerf.measure(objectName, methodNames[key], object[key]);
      }
    }
  },

  /**
   * Use this to wrap methods you want to measure. Zero overhead in production.
   *
   * @param {string} objName
   * @param {string} fnName
   * @param {function} func
   * @return {function}
   */
  measure: function (objName, fnName, func) {
    if (process.env.NODE_ENV !== 'production') {
      var measuredFunc = null;
      var wrapper = function () {
        if (ReactPerf.enableMeasure) {
          if (!measuredFunc) {
            measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
          }
          return measuredFunc.apply(this, arguments);
        }
        return func.apply(this, arguments);
      };
      wrapper.displayName = objName + '_' + fnName;
      return wrapper;
    }
    return func;
  },

  injection: {
    /**
     * @param {function} measure
     */
    injectMeasure: function (measure) {
      ReactPerf.storedMeasure = measure;
    }
  }
};

/**
 * Simply passes through the measured function, without measuring it.
 *
 * @param {string} objName
 * @param {string} fnName
 * @param {function} func
 * @return {function}
 */
function _noMeasure(objName, fnName, func) {
  return func;
}

module.exports = ReactPerf;
}).call(this,require('_process'))

},{"_process":334}],468:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactPropTypeLocationNames
 */

'use strict';

var ReactPropTypeLocationNames = {};

if (process.env.NODE_ENV !== 'production') {
  ReactPropTypeLocationNames = {
    prop: 'prop',
    context: 'context',
    childContext: 'child context'
  };
}

module.exports = ReactPropTypeLocationNames;
}).call(this,require('_process'))

},{"_process":334}],469:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactPropTypeLocations
 */

'use strict';

var keyMirror = require('fbjs/lib/keyMirror');

var ReactPropTypeLocations = keyMirror({
  prop: null,
  context: null,
  childContext: null
});

module.exports = ReactPropTypeLocations;
},{"fbjs/lib/keyMirror":321}],470:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactPropTypes
 */

'use strict';

var ReactElement = require('./ReactElement');
var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');

var emptyFunction = require('fbjs/lib/emptyFunction');
var getIteratorFn = require('./getIteratorFn');

/**
 * Collection of methods that allow declaration and validation of props that are
 * supplied to React components. Example usage:
 *
 *   var Props = require('ReactPropTypes');
 *   var MyArticle = React.createClass({
 *     propTypes: {
 *       // An optional string prop named "description".
 *       description: Props.string,
 *
 *       // A required enum prop named "category".
 *       category: Props.oneOf(['News','Photos']).isRequired,
 *
 *       // A prop named "dialog" that requires an instance of Dialog.
 *       dialog: Props.instanceOf(Dialog).isRequired
 *     },
 *     render: function() { ... }
 *   });
 *
 * A more formal specification of how these methods are used:
 *
 *   type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
 *   decl := ReactPropTypes.{type}(.isRequired)?
 *
 * Each and every declaration produces a function with the same signature. This
 * allows the creation of custom validation functions. For example:
 *
 *  var MyLink = React.createClass({
 *    propTypes: {
 *      // An optional string or URI prop named "href".
 *      href: function(props, propName, componentName) {
 *        var propValue = props[propName];
 *        if (propValue != null && typeof propValue !== 'string' &&
 *            !(propValue instanceof URI)) {
 *          return new Error(
 *            'Expected a string or an URI for ' + propName + ' in ' +
 *            componentName
 *          );
 *        }
 *      }
 *    },
 *    render: function() {...}
 *  });
 *
 * @internal
 */

var ANONYMOUS = '<<anonymous>>';

var ReactPropTypes = {
  array: createPrimitiveTypeChecker('array'),
  bool: createPrimitiveTypeChecker('boolean'),
  func: createPrimitiveTypeChecker('function'),
  number: createPrimitiveTypeChecker('number'),
  object: createPrimitiveTypeChecker('object'),
  string: createPrimitiveTypeChecker('string'),

  any: createAnyTypeChecker(),
  arrayOf: createArrayOfTypeChecker,
  element: createElementTypeChecker(),
  instanceOf: createInstanceTypeChecker,
  node: createNodeChecker(),
  objectOf: createObjectOfTypeChecker,
  oneOf: createEnumTypeChecker,
  oneOfType: createUnionTypeChecker,
  shape: createShapeTypeChecker
};

function createChainableTypeChecker(validate) {
  function checkType(isRequired, props, propName, componentName, location, propFullName) {
    componentName = componentName || ANONYMOUS;
    propFullName = propFullName || propName;
    if (props[propName] == null) {
      var locationName = ReactPropTypeLocationNames[location];
      if (isRequired) {
        return new Error('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.'));
      }
      return null;
    } else {
      return validate(props, propName, componentName, location, propFullName);
    }
  }

  var chainedCheckType = checkType.bind(null, false);
  chainedCheckType.isRequired = checkType.bind(null, true);

  return chainedCheckType;
}

function createPrimitiveTypeChecker(expectedType) {
  function validate(props, propName, componentName, location, propFullName) {
    var propValue = props[propName];
    var propType = getPropType(propValue);
    if (propType !== expectedType) {
      var locationName = ReactPropTypeLocationNames[location];
      // `propValue` being instance of, say, date/regexp, pass the 'object'
      // check, but we can offer a more precise error message here rather than
      // 'of type `object`'.
      var preciseType = getPreciseType(propValue);

      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createAnyTypeChecker() {
  return createChainableTypeChecker(emptyFunction.thatReturns(null));
}

function createArrayOfTypeChecker(typeChecker) {
  function validate(props, propName, componentName, location, propFullName) {
    var propValue = props[propName];
    if (!Array.isArray(propValue)) {
      var locationName = ReactPropTypeLocationNames[location];
      var propType = getPropType(propValue);
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
    }
    for (var i = 0; i < propValue.length; i++) {
      var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
      if (error instanceof Error) {
        return error;
      }
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createElementTypeChecker() {
  function validate(props, propName, componentName, location, propFullName) {
    if (!ReactElement.isValidElement(props[propName])) {
      var locationName = ReactPropTypeLocationNames[location];
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a single ReactElement.'));
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createInstanceTypeChecker(expectedClass) {
  function validate(props, propName, componentName, location, propFullName) {
    if (!(props[propName] instanceof expectedClass)) {
      var locationName = ReactPropTypeLocationNames[location];
      var expectedClassName = expectedClass.name || ANONYMOUS;
      var actualClassName = getClassName(props[propName]);
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createEnumTypeChecker(expectedValues) {
  if (!Array.isArray(expectedValues)) {
    return createChainableTypeChecker(function () {
      return new Error('Invalid argument supplied to oneOf, expected an instance of array.');
    });
  }

  function validate(props, propName, componentName, location, propFullName) {
    var propValue = props[propName];
    for (var i = 0; i < expectedValues.length; i++) {
      if (propValue === expectedValues[i]) {
        return null;
      }
    }

    var locationName = ReactPropTypeLocationNames[location];
    var valuesString = JSON.stringify(expectedValues);
    return new Error('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
  }
  return createChainableTypeChecker(validate);
}

function createObjectOfTypeChecker(typeChecker) {
  function validate(props, propName, componentName, location, propFullName) {
    var propValue = props[propName];
    var propType = getPropType(propValue);
    if (propType !== 'object') {
      var locationName = ReactPropTypeLocationNames[location];
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
    }
    for (var key in propValue) {
      if (propValue.hasOwnProperty(key)) {
        var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
        if (error instanceof Error) {
          return error;
        }
      }
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createUnionTypeChecker(arrayOfTypeCheckers) {
  if (!Array.isArray(arrayOfTypeCheckers)) {
    return createChainableTypeChecker(function () {
      return new Error('Invalid argument supplied to oneOfType, expected an instance of array.');
    });
  }

  function validate(props, propName, componentName, location, propFullName) {
    for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
      var checker = arrayOfTypeCheckers[i];
      if (checker(props, propName, componentName, location, propFullName, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED') == null) {
        return null;
      }
    }

    var locationName = ReactPropTypeLocationNames[location];
    return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
  }
  return createChainableTypeChecker(validate);
}

function createNodeChecker() {
  function validate(props, propName, componentName, location, propFullName) {
    if (!isNode(props[propName])) {
      var locationName = ReactPropTypeLocationNames[location];
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function createShapeTypeChecker(shapeTypes) {
  function validate(props, propName, componentName, location, propFullName) {
    var propValue = props[propName];
    var propType = getPropType(propValue);
    if (propType !== 'object') {
      var locationName = ReactPropTypeLocationNames[location];
      return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
    }
    for (var key in shapeTypes) {
      var checker = shapeTypes[key];
      if (!checker) {
        continue;
      }
      var error = checker(propValue, key, componentName, location, propFullName + '.' + key, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
      if (error) {
        return error;
      }
    }
    return null;
  }
  return createChainableTypeChecker(validate);
}

function isNode(propValue) {
  switch (typeof propValue) {
    case 'number':
    case 'string':
    case 'undefined':
      return true;
    case 'boolean':
      return !propValue;
    case 'object':
      if (Array.isArray(propValue)) {
        return propValue.every(isNode);
      }
      if (propValue === null || ReactElement.isValidElement(propValue)) {
        return true;
      }

      var iteratorFn = getIteratorFn(propValue);
      if (iteratorFn) {
        var iterator = iteratorFn.call(propValue);
        var step;
        if (iteratorFn !== propValue.entries) {
          while (!(step = iterator.next()).done) {
            if (!isNode(step.value)) {
              return false;
            }
          }
        } else {
          // Iterator will provide entry [k,v] tuples rather than values.
          while (!(step = iterator.next()).done) {
            var entry = step.value;
            if (entry) {
              if (!isNode(entry[1])) {
                return false;
              }
            }
          }
        }
      } else {
        return false;
      }

      return true;
    default:
      return false;
  }
}

// Equivalent of `typeof` but with special handling for array and regexp.
function getPropType(propValue) {
  var propType = typeof propValue;
  if (Array.isArray(propValue)) {
    return 'array';
  }
  if (propValue instanceof RegExp) {
    // Old webkits (at least until Android 4.0) return 'function' rather than
    // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
    // passes PropTypes.object.
    return 'object';
  }
  return propType;
}

// This handles more types than `getPropType`. Only used for error messages.
// See `createPrimitiveTypeChecker`.
function getPreciseType(propValue) {
  var propType = getPropType(propValue);
  if (propType === 'object') {
    if (propValue instanceof Date) {
      return 'date';
    } else if (propValue instanceof RegExp) {
      return 'regexp';
    }
  }
  return propType;
}

// Returns class name of the object, if any.
function getClassName(propValue) {
  if (!propValue.constructor || !propValue.constructor.name) {
    return '<<anonymous>>';
  }
  return propValue.constructor.name;
}

module.exports = ReactPropTypes;
},{"./ReactElement":448,"./ReactPropTypeLocationNames":468,"./getIteratorFn":511,"fbjs/lib/emptyFunction":310}],471:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactReconcileTransaction
 * @typechecks static-only
 */

'use strict';

var CallbackQueue = require('./CallbackQueue');
var PooledClass = require('./PooledClass');
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags');
var ReactInputSelection = require('./ReactInputSelection');
var Transaction = require('./Transaction');

var assign = require('./Object.assign');

/**
 * Ensures that, when possible, the selection range (currently selected text
 * input) is not disturbed by performing the transaction.
 */
var SELECTION_RESTORATION = {
  /**
   * @return {Selection} Selection information.
   */
  initialize: ReactInputSelection.getSelectionInformation,
  /**
   * @param {Selection} sel Selection information returned from `initialize`.
   */
  close: ReactInputSelection.restoreSelection
};

/**
 * Suppresses events (blur/focus) that could be inadvertently dispatched due to
 * high level DOM manipulations (like temporarily removing a text input from the
 * DOM).
 */
var EVENT_SUPPRESSION = {
  /**
   * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
   * the reconciliation.
   */
  initialize: function () {
    var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
    ReactBrowserEventEmitter.setEnabled(false);
    return currentlyEnabled;
  },

  /**
   * @param {boolean} previouslyEnabled Enabled status of
   *   `ReactBrowserEventEmitter` before the reconciliation occurred. `close`
   *   restores the previous value.
   */
  close: function (previouslyEnabled) {
    ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
  }
};

/**
 * Provides a queue for collecting `componentDidMount` and
 * `componentDidUpdate` callbacks during the the transaction.
 */
var ON_DOM_READY_QUEUEING = {
  /**
   * Initializes the internal `onDOMReady` queue.
   */
  initialize: function () {
    this.reactMountReady.reset();
  },

  /**
   * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
   */
  close: function () {
    this.reactMountReady.notifyAll();
  }
};

/**
 * Executed within the scope of the `Transaction` instance. Consider these as
 * being member methods, but with an implied ordering while being isolated from
 * each other.
 */
var TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING];

/**
 * Currently:
 * - The order that these are listed in the transaction is critical:
 * - Suppresses events.
 * - Restores selection range.
 *
 * Future:
 * - Restore document/overflow scroll positions that were unintentionally
 *   modified via DOM insertions above the top viewport boundary.
 * - Implement/integrate with customized constraint based layout system and keep
 *   track of which dimensions must be remeasured.
 *
 * @class ReactReconcileTransaction
 */
function ReactReconcileTransaction(forceHTML) {
  this.reinitializeTransaction();
  // Only server-side rendering really needs this option (see
  // `ReactServerRendering`), but server-side uses
  // `ReactServerRenderingTransaction` instead. This option is here so that it's
  // accessible and defaults to false when `ReactDOMComponent` and
  // `ReactTextComponent` checks it in `mountComponent`.`
  this.renderToStaticMarkup = false;
  this.reactMountReady = CallbackQueue.getPooled(null);
  this.useCreateElement = !forceHTML && ReactDOMFeatureFlags.useCreateElement;
}

var Mixin = {
  /**
   * @see Transaction
   * @abstract
   * @final
   * @return {array<object>} List of operation wrap procedures.
   *   TODO: convert to array<TransactionWrapper>
   */
  getTransactionWrappers: function () {
    return TRANSACTION_WRAPPERS;
  },

  /**
   * @return {object} The queue to collect `onDOMReady` callbacks with.
   */
  getReactMountReady: function () {
    return this.reactMountReady;
  },

  /**
   * `PooledClass` looks for this, and will invoke this before allowing this
   * instance to be reused.
   */
  destructor: function () {
    CallbackQueue.release(this.reactMountReady);
    this.reactMountReady = null;
  }
};

assign(ReactReconcileTransaction.prototype, Transaction.Mixin, Mixin);

PooledClass.addPoolingTo(ReactReconcileTransaction);

module.exports = ReactReconcileTransaction;
},{"./CallbackQueue":401,"./Object.assign":418,"./PooledClass":419,"./ReactBrowserEventEmitter":422,"./ReactDOMFeatureFlags":435,"./ReactInputSelection":456,"./Transaction":496}],472:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactReconciler
 */

'use strict';

var ReactRef = require('./ReactRef');

/**
 * Helper to call ReactRef.attachRefs with this composite component, split out
 * to avoid allocations in the transaction mount-ready queue.
 */
function attachRefs() {
  ReactRef.attachRefs(this, this._currentElement);
}

var ReactReconciler = {

  /**
   * Initializes the component, renders markup, and registers event listeners.
   *
   * @param {ReactComponent} internalInstance
   * @param {string} rootID DOM ID of the root node.
   * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
   * @return {?string} Rendered markup to be inserted into the DOM.
   * @final
   * @internal
   */
  mountComponent: function (internalInstance, rootID, transaction, context) {
    var markup = internalInstance.mountComponent(rootID, transaction, context);
    if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {
      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
    }
    return markup;
  },

  /**
   * Releases any resources allocated by `mountComponent`.
   *
   * @final
   * @internal
   */
  unmountComponent: function (internalInstance) {
    ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
    internalInstance.unmountComponent();
  },

  /**
   * Update a component using a new element.
   *
   * @param {ReactComponent} internalInstance
   * @param {ReactElement} nextElement
   * @param {ReactReconcileTransaction} transaction
   * @param {object} context
   * @internal
   */
  receiveComponent: function (internalInstance, nextElement, transaction, context) {
    var prevElement = internalInstance._currentElement;

    if (nextElement === prevElement && context === internalInstance._context) {
      // Since elements are immutable after the owner is rendered,
      // we can do a cheap identity compare here to determine if this is a
      // superfluous reconcile. It's possible for state to be mutable but such
      // change should trigger an update of the owner which would recreate
      // the element. We explicitly check for the existence of an owner since
      // it's possible for an element created outside a composite to be
      // deeply mutated and reused.

      // TODO: Bailing out early is just a perf optimization right?
      // TODO: Removing the return statement should affect correctness?
      return;
    }

    var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement);

    if (refsChanged) {
      ReactRef.detachRefs(internalInstance, prevElement);
    }

    internalInstance.receiveComponent(nextElement, transaction, context);

    if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {
      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
    }
  },

  /**
   * Flush any dirty changes in a component.
   *
   * @param {ReactComponent} internalInstance
   * @param {ReactReconcileTransaction} transaction
   * @internal
   */
  performUpdateIfNecessary: function (internalInstance, transaction) {
    internalInstance.performUpdateIfNecessary(transaction);
  }

};

module.exports = ReactReconciler;
},{"./ReactRef":473}],473:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactRef
 */

'use strict';

var ReactOwner = require('./ReactOwner');

var ReactRef = {};

function attachRef(ref, component, owner) {
  if (typeof ref === 'function') {
    ref(component.getPublicInstance());
  } else {
    // Legacy ref
    ReactOwner.addComponentAsRefTo(component, ref, owner);
  }
}

function detachRef(ref, component, owner) {
  if (typeof ref === 'function') {
    ref(null);
  } else {
    // Legacy ref
    ReactOwner.removeComponentAsRefFrom(component, ref, owner);
  }
}

ReactRef.attachRefs = function (instance, element) {
  if (element === null || element === false) {
    return;
  }
  var ref = element.ref;
  if (ref != null) {
    attachRef(ref, instance, element._owner);
  }
};

ReactRef.shouldUpdateRefs = function (prevElement, nextElement) {
  // If either the owner or a `ref` has changed, make sure the newest owner
  // has stored a reference to `this`, and the previous owner (if different)
  // has forgotten the reference to `this`. We use the element instead
  // of the public this.props because the post processing cannot determine
  // a ref. The ref conceptually lives on the element.

  // TODO: Should this even be possible? The owner cannot change because
  // it's forbidden by shouldUpdateReactComponent. The ref can change
  // if you swap the keys of but not the refs. Reconsider where this check
  // is made. It probably belongs where the key checking and
  // instantiateReactComponent is done.

  var prevEmpty = prevElement === null || prevElement === false;
  var nextEmpty = nextElement === null || nextElement === false;

  return(
    // This has a few false positives w/r/t empty components.
    prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref
  );
};

ReactRef.detachRefs = function (instance, element) {
  if (element === null || element === false) {
    return;
  }
  var ref = element.ref;
  if (ref != null) {
    detachRef(ref, instance, element._owner);
  }
};

module.exports = ReactRef;
},{"./ReactOwner":466}],474:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactRootIndex
 * @typechecks
 */

'use strict';

var ReactRootIndexInjection = {
  /**
   * @param {function} _createReactRootIndex
   */
  injectCreateReactRootIndex: function (_createReactRootIndex) {
    ReactRootIndex.createReactRootIndex = _createReactRootIndex;
  }
};

var ReactRootIndex = {
  createReactRootIndex: null,
  injection: ReactRootIndexInjection
};

module.exports = ReactRootIndex;
},{}],475:[function(require,module,exports){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactServerBatchingStrategy
 * @typechecks
 */

'use strict';

var ReactServerBatchingStrategy = {
  isBatchingUpdates: false,
  batchedUpdates: function (callback) {
    // Don't do anything here. During the server rendering we don't want to
    // schedule any updates. We will simply ignore them.
  }
};

module.exports = ReactServerBatchingStrategy;
},{}],476:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @typechecks static-only
 * @providesModule ReactServerRendering
 */
'use strict';

var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');
var ReactElement = require('./ReactElement');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactMarkupChecksum = require('./ReactMarkupChecksum');
var ReactServerBatchingStrategy = require('./ReactServerBatchingStrategy');
var ReactServerRenderingTransaction = require('./ReactServerRenderingTransaction');
var ReactUpdates = require('./ReactUpdates');

var emptyObject = require('fbjs/lib/emptyObject');
var instantiateReactComponent = require('./instantiateReactComponent');
var invariant = require('fbjs/lib/invariant');

/**
 * @param {ReactElement} element
 * @return {string} the HTML markup
 */
function renderToString(element) {
  !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToString(): You must pass a valid ReactElement.') : invariant(false) : undefined;

  var transaction;
  try {
    ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);

    var id = ReactInstanceHandles.createReactRootID();
    transaction = ReactServerRenderingTransaction.getPooled(false);

    return transaction.perform(function () {
      var componentInstance = instantiateReactComponent(element, null);
      var markup = componentInstance.mountComponent(id, transaction, emptyObject);
      return ReactMarkupChecksum.addChecksumToMarkup(markup);
    }, null);
  } finally {
    ReactServerRenderingTransaction.release(transaction);
    // Revert to the DOM batching strategy since these two renderers
    // currently share these stateful modules.
    ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
  }
}

/**
 * @param {ReactElement} element
 * @return {string} the HTML markup, without the extra React ID and checksum
 * (for generating static pages)
 */
function renderToStaticMarkup(element) {
  !ReactElement.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'renderToStaticMarkup(): You must pass a valid ReactElement.') : invariant(false) : undefined;

  var transaction;
  try {
    ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);

    var id = ReactInstanceHandles.createReactRootID();
    transaction = ReactServerRenderingTransaction.getPooled(true);

    return transaction.perform(function () {
      var componentInstance = instantiateReactComponent(element, null);
      return componentInstance.mountComponent(id, transaction, emptyObject);
    }, null);
  } finally {
    ReactServerRenderingTransaction.release(transaction);
    // Revert to the DOM batching strategy since these two renderers
    // currently share these stateful modules.
    ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
  }
}

module.exports = {
  renderToString: renderToString,
  renderToStaticMarkup: renderToStaticMarkup
};
}).call(this,require('_process'))

},{"./ReactDefaultBatchingStrategy":444,"./ReactElement":448,"./ReactInstanceHandles":457,"./ReactMarkupChecksum":460,"./ReactServerBatchingStrategy":475,"./ReactServerRenderingTransaction":477,"./ReactUpdates":479,"./instantiateReactComponent":514,"_process":334,"fbjs/lib/emptyObject":311,"fbjs/lib/invariant":318}],477:[function(require,module,exports){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactServerRenderingTransaction
 * @typechecks
 */

'use strict';

var PooledClass = require('./PooledClass');
var CallbackQueue = require('./CallbackQueue');
var Transaction = require('./Transaction');

var assign = require('./Object.assign');
var emptyFunction = require('fbjs/lib/emptyFunction');

/**
 * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks
 * during the performing of the transaction.
 */
var ON_DOM_READY_QUEUEING = {
  /**
   * Initializes the internal `onDOMReady` queue.
   */
  initialize: function () {
    this.reactMountReady.reset();
  },

  close: emptyFunction
};

/**
 * Executed within the scope of the `Transaction` instance. Consider these as
 * being member methods, but with an implied ordering while being isolated from
 * each other.
 */
var TRANSACTION_WRAPPERS = [ON_DOM_READY_QUEUEING];

/**
 * @class ReactServerRenderingTransaction
 * @param {boolean} renderToStaticMarkup
 */
function ReactServerRenderingTransaction(renderToStaticMarkup) {
  this.reinitializeTransaction();
  this.renderToStaticMarkup = renderToStaticMarkup;
  this.reactMountReady = CallbackQueue.getPooled(null);
  this.useCreateElement = false;
}

var Mixin = {
  /**
   * @see Transaction
   * @abstract
   * @final
   * @return {array} Empty list of operation wrap procedures.
   */
  getTransactionWrappers: function () {
    return TRANSACTION_WRAPPERS;
  },

  /**
   * @return {object} The queue to collect `onDOMReady` callbacks with.
   */
  getReactMountReady: function () {
    return this.reactMountReady;
  },

  /**
   * `PooledClass` looks for this, and will invoke this before allowing this
   * instance to be reused.
   */
  destructor: function () {
    CallbackQueue.release(this.reactMountReady);
    this.reactMountReady = null;
  }
};

assign(ReactServerRenderingTransaction.prototype, Transaction.Mixin, Mixin);

PooledClass.addPoolingTo(ReactServerRenderingTransaction);

module.exports = ReactServerRenderingTransaction;
},{"./CallbackQueue":401,"./Object.assign":418,"./PooledClass":419,"./Transaction":496,"fbjs/lib/emptyFunction":310}],478:[function(require,module,exports){
(function (process){
/**
 * Copyright 2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactUpdateQueue
 */

'use strict';

var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactElement = require('./ReactElement');
var ReactInstanceMap = require('./ReactInstanceMap');
var ReactUpdates = require('./ReactUpdates');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

function enqueueUpdate(internalInstance) {
  ReactUpdates.enqueueUpdate(internalInstance);
}

function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
  var internalInstance = ReactInstanceMap.get(publicInstance);
  if (!internalInstance) {
    if (process.env.NODE_ENV !== 'production') {
      // Only warn when we have a callerName. Otherwise we should be silent.
      // We're probably calling from enqueueCallback. We don't want to warn
      // there because we already warned for the corresponding lifecycle method.
      process.env.NODE_ENV !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, publicInstance.constructor.displayName) : undefined;
    }
    return null;
  }

  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition ' + '(such as within `render`). Render methods should be a pure function ' + 'of props and state.', callerName) : undefined;
  }

  return internalInstance;
}

/**
 * ReactUpdateQueue allows for state updates to be scheduled into a later
 * reconciliation step.
 */
var ReactUpdateQueue = {

  /**
   * Checks whether or not this composite component is mounted.
   * @param {ReactClass} publicInstance The instance we want to test.
   * @return {boolean} True if mounted, false otherwise.
   * @protected
   * @final
   */
  isMounted: function (publicInstance) {
    if (process.env.NODE_ENV !== 'production') {
      var owner = ReactCurrentOwner.current;
      if (owner !== null) {
        process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : undefined;
        owner._warnedAboutRefsInRender = true;
      }
    }
    var internalInstance = ReactInstanceMap.get(publicInstance);
    if (internalInstance) {
      // During componentWillMount and render this will still be null but after
      // that will always render to something. At least for now. So we can use
      // this hack.
      return !!internalInstance._renderedComponent;
    } else {
      return false;
    }
  },

  /**
   * Enqueue a callback that will be executed after all the pending updates
   * have processed.
   *
   * @param {ReactClass} publicInstance The instance to use as `this` context.
   * @param {?function} callback Called after state is updated.
   * @internal
   */
  enqueueCallback: function (publicInstance, callback) {
    !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\'t callable.') : invariant(false) : undefined;
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);

    // Previously we would throw an error if we didn't have an internal
    // instance. Since we want to make it a no-op instead, we mirror the same
    // behavior we have in other enqueue* methods.
    // We also need to ignore callbacks in componentWillMount. See
    // enqueueUpdates.
    if (!internalInstance) {
      return null;
    }

    if (internalInstance._pendingCallbacks) {
      internalInstance._pendingCallbacks.push(callback);
    } else {
      internalInstance._pendingCallbacks = [callback];
    }
    // TODO: The callback here is ignored when setState is called from
    // componentWillMount. Either fix it or disallow doing so completely in
    // favor of getInitialState. Alternatively, we can disallow
    // componentWillMount during server-side rendering.
    enqueueUpdate(internalInstance);
  },

  enqueueCallbackInternal: function (internalInstance, callback) {
    !(typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\'t callable.') : invariant(false) : undefined;
    if (internalInstance._pendingCallbacks) {
      internalInstance._pendingCallbacks.push(callback);
    } else {
      internalInstance._pendingCallbacks = [callback];
    }
    enqueueUpdate(internalInstance);
  },

  /**
   * Forces an update. This should only be invoked when it is known with
   * certainty that we are **not** in a DOM transaction.
   *
   * You may want to call this when you know that some deeper aspect of the
   * component's state has changed but `setState` was not called.
   *
   * This will not invoke `shouldComponentUpdate`, but it will invoke
   * `componentWillUpdate` and `componentDidUpdate`.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @internal
   */
  enqueueForceUpdate: function (publicInstance) {
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate');

    if (!internalInstance) {
      return;
    }

    internalInstance._pendingForceUpdate = true;

    enqueueUpdate(internalInstance);
  },

  /**
   * Replaces all of the state. Always use this or `setState` to mutate state.
   * You should treat `this.state` as immutable.
   *
   * There is no guarantee that `this.state` will be immediately updated, so
   * accessing `this.state` after calling this method may return the old value.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} completeState Next state.
   * @internal
   */
  enqueueReplaceState: function (publicInstance, completeState) {
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState');

    if (!internalInstance) {
      return;
    }

    internalInstance._pendingStateQueue = [completeState];
    internalInstance._pendingReplaceState = true;

    enqueueUpdate(internalInstance);
  },

  /**
   * Sets a subset of the state. This only exists because _pendingState is
   * internal. This provides a merging strategy that is not available to deep
   * properties which is confusing. TODO: Expose pendingState or don't use it
   * during the merge.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} partialState Next partial state to be merged with state.
   * @internal
   */
  enqueueSetState: function (publicInstance, partialState) {
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');

    if (!internalInstance) {
      return;
    }

    var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);
    queue.push(partialState);

    enqueueUpdate(internalInstance);
  },

  /**
   * Sets a subset of the props.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} partialProps Subset of the next props.
   * @internal
   */
  enqueueSetProps: function (publicInstance, partialProps) {
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setProps');
    if (!internalInstance) {
      return;
    }
    ReactUpdateQueue.enqueueSetPropsInternal(internalInstance, partialProps);
  },

  enqueueSetPropsInternal: function (internalInstance, partialProps) {
    var topLevelWrapper = internalInstance._topLevelWrapper;
    !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'setProps(...): You called `setProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined;

    // Merge with the pending element if it exists, otherwise with existing
    // element props.
    var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement;
    var element = wrapElement.props;
    var props = assign({}, element.props, partialProps);
    topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props));

    enqueueUpdate(topLevelWrapper);
  },

  /**
   * Replaces all of the props.
   *
   * @param {ReactClass} publicInstance The instance that should rerender.
   * @param {object} props New props.
   * @internal
   */
  enqueueReplaceProps: function (publicInstance, props) {
    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceProps');
    if (!internalInstance) {
      return;
    }
    ReactUpdateQueue.enqueueReplacePropsInternal(internalInstance, props);
  },

  enqueueReplacePropsInternal: function (internalInstance, props) {
    var topLevelWrapper = internalInstance._topLevelWrapper;
    !topLevelWrapper ? process.env.NODE_ENV !== 'production' ? invariant(false, 'replaceProps(...): You called `replaceProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.') : invariant(false) : undefined;

    // Merge with the pending element if it exists, otherwise with existing
    // element props.
    var wrapElement = topLevelWrapper._pendingElement || topLevelWrapper._currentElement;
    var element = wrapElement.props;
    topLevelWrapper._pendingElement = ReactElement.cloneAndReplaceProps(wrapElement, ReactElement.cloneAndReplaceProps(element, props));

    enqueueUpdate(topLevelWrapper);
  },

  enqueueElementInternal: function (internalInstance, newElement) {
    internalInstance._pendingElement = newElement;
    enqueueUpdate(internalInstance);
  }

};

module.exports = ReactUpdateQueue;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactCurrentOwner":430,"./ReactElement":448,"./ReactInstanceMap":458,"./ReactUpdates":479,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],479:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactUpdates
 */

'use strict';

var CallbackQueue = require('./CallbackQueue');
var PooledClass = require('./PooledClass');
var ReactPerf = require('./ReactPerf');
var ReactReconciler = require('./ReactReconciler');
var Transaction = require('./Transaction');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');

var dirtyComponents = [];
var asapCallbackQueue = CallbackQueue.getPooled();
var asapEnqueued = false;

var batchingStrategy = null;

function ensureInjected() {
  !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching ' + 'strategy') : invariant(false) : undefined;
}

var NESTED_UPDATES = {
  initialize: function () {
    this.dirtyComponentsLength = dirtyComponents.length;
  },
  close: function () {
    if (this.dirtyComponentsLength !== dirtyComponents.length) {
      // Additional updates were enqueued by componentDidUpdate handlers or
      // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
      // these new updates so that if A's componentDidUpdate calls setState on
      // B, B will update before the callback A's updater provided when calling
      // setState.
      dirtyComponents.splice(0, this.dirtyComponentsLength);
      flushBatchedUpdates();
    } else {
      dirtyComponents.length = 0;
    }
  }
};

var UPDATE_QUEUEING = {
  initialize: function () {
    this.callbackQueue.reset();
  },
  close: function () {
    this.callbackQueue.notifyAll();
  }
};

var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];

function ReactUpdatesFlushTransaction() {
  this.reinitializeTransaction();
  this.dirtyComponentsLength = null;
  this.callbackQueue = CallbackQueue.getPooled();
  this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( /* forceHTML */false);
}

assign(ReactUpdatesFlushTransaction.prototype, Transaction.Mixin, {
  getTransactionWrappers: function () {
    return TRANSACTION_WRAPPERS;
  },

  destructor: function () {
    this.dirtyComponentsLength = null;
    CallbackQueue.release(this.callbackQueue);
    this.callbackQueue = null;
    ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
    this.reconcileTransaction = null;
  },

  perform: function (method, scope, a) {
    // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
    // with this transaction's wrappers around it.
    return Transaction.Mixin.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);
  }
});

PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);

function batchedUpdates(callback, a, b, c, d, e) {
  ensureInjected();
  batchingStrategy.batchedUpdates(callback, a, b, c, d, e);
}

/**
 * Array comparator for ReactComponents by mount ordering.
 *
 * @param {ReactComponent} c1 first component you're comparing
 * @param {ReactComponent} c2 second component you're comparing
 * @return {number} Return value usable by Array.prototype.sort().
 */
function mountOrderComparator(c1, c2) {
  return c1._mountOrder - c2._mountOrder;
}

function runBatchedUpdates(transaction) {
  var len = transaction.dirtyComponentsLength;
  !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to ' + 'match dirty-components array length (%s).', len, dirtyComponents.length) : invariant(false) : undefined;

  // Since reconciling a component higher in the owner hierarchy usually (not
  // always -- see shouldComponentUpdate()) will reconcile children, reconcile
  // them before their children by sorting the array.
  dirtyComponents.sort(mountOrderComparator);

  for (var i = 0; i < len; i++) {
    // If a component is unmounted before pending changes apply, it will still
    // be here, but we assume that it has cleared its _pendingCallbacks and
    // that performUpdateIfNecessary is a noop.
    var component = dirtyComponents[i];

    // If performUpdateIfNecessary happens to enqueue any new updates, we
    // shouldn't execute the callbacks until the next render happens, so
    // stash the callbacks first
    var callbacks = component._pendingCallbacks;
    component._pendingCallbacks = null;

    ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction);

    if (callbacks) {
      for (var j = 0; j < callbacks.length; j++) {
        transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());
      }
    }
  }
}

var flushBatchedUpdates = function () {
  // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
  // array and perform any updates enqueued by mount-ready handlers (i.e.,
  // componentDidUpdate) but we need to check here too in order to catch
  // updates enqueued by setState callbacks and asap calls.
  while (dirtyComponents.length || asapEnqueued) {
    if (dirtyComponents.length) {
      var transaction = ReactUpdatesFlushTransaction.getPooled();
      transaction.perform(runBatchedUpdates, null, transaction);
      ReactUpdatesFlushTransaction.release(transaction);
    }

    if (asapEnqueued) {
      asapEnqueued = false;
      var queue = asapCallbackQueue;
      asapCallbackQueue = CallbackQueue.getPooled();
      queue.notifyAll();
      CallbackQueue.release(queue);
    }
  }
};
flushBatchedUpdates = ReactPerf.measure('ReactUpdates', 'flushBatchedUpdates', flushBatchedUpdates);

/**
 * Mark a component as needing a rerender, adding an optional callback to a
 * list of functions which will be executed once the rerender occurs.
 */
function enqueueUpdate(component) {
  ensureInjected();

  // Various parts of our code (such as ReactCompositeComponent's
  // _renderValidatedComponent) assume that calls to render aren't nested;
  // verify that that's the case. (This is called by each top-level update
  // function, like setProps, setState, forceUpdate, etc.; creation and
  // destruction of top-level components is guarded in ReactMount.)

  if (!batchingStrategy.isBatchingUpdates) {
    batchingStrategy.batchedUpdates(enqueueUpdate, component);
    return;
  }

  dirtyComponents.push(component);
}

/**
 * Enqueue a callback to be run at the end of the current batching cycle. Throws
 * if no updates are currently being performed.
 */
function asap(callback, context) {
  !batchingStrategy.isBatchingUpdates ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + 'updates are not being batched.') : invariant(false) : undefined;
  asapCallbackQueue.enqueue(callback, context);
  asapEnqueued = true;
}

var ReactUpdatesInjection = {
  injectReconcileTransaction: function (ReconcileTransaction) {
    !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : invariant(false) : undefined;
    ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
  },

  injectBatchingStrategy: function (_batchingStrategy) {
    !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : invariant(false) : undefined;
    !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : invariant(false) : undefined;
    !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : invariant(false) : undefined;
    batchingStrategy = _batchingStrategy;
  }
};

var ReactUpdates = {
  /**
   * React references `ReactReconcileTransaction` using this property in order
   * to allow dependency injection.
   *
   * @internal
   */
  ReactReconcileTransaction: null,

  batchedUpdates: batchedUpdates,
  enqueueUpdate: enqueueUpdate,
  flushBatchedUpdates: flushBatchedUpdates,
  injection: ReactUpdatesInjection,
  asap: asap
};

module.exports = ReactUpdates;
}).call(this,require('_process'))

},{"./CallbackQueue":401,"./Object.assign":418,"./PooledClass":419,"./ReactPerf":467,"./ReactReconciler":472,"./Transaction":496,"_process":334,"fbjs/lib/invariant":318}],480:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactVersion
 */

'use strict';

module.exports = '0.14.9';
},{}],481:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SVGDOMPropertyConfig
 */

'use strict';

var DOMProperty = require('./DOMProperty');

var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;

var NS = {
  xlink: 'http://www.w3.org/1999/xlink',
  xml: 'http://www.w3.org/XML/1998/namespace'
};

var SVGDOMPropertyConfig = {
  Properties: {
    clipPath: MUST_USE_ATTRIBUTE,
    cx: MUST_USE_ATTRIBUTE,
    cy: MUST_USE_ATTRIBUTE,
    d: MUST_USE_ATTRIBUTE,
    dx: MUST_USE_ATTRIBUTE,
    dy: MUST_USE_ATTRIBUTE,
    fill: MUST_USE_ATTRIBUTE,
    fillOpacity: MUST_USE_ATTRIBUTE,
    fontFamily: MUST_USE_ATTRIBUTE,
    fontSize: MUST_USE_ATTRIBUTE,
    fx: MUST_USE_ATTRIBUTE,
    fy: MUST_USE_ATTRIBUTE,
    gradientTransform: MUST_USE_ATTRIBUTE,
    gradientUnits: MUST_USE_ATTRIBUTE,
    markerEnd: MUST_USE_ATTRIBUTE,
    markerMid: MUST_USE_ATTRIBUTE,
    markerStart: MUST_USE_ATTRIBUTE,
    offset: MUST_USE_ATTRIBUTE,
    opacity: MUST_USE_ATTRIBUTE,
    patternContentUnits: MUST_USE_ATTRIBUTE,
    patternUnits: MUST_USE_ATTRIBUTE,
    points: MUST_USE_ATTRIBUTE,
    preserveAspectRatio: MUST_USE_ATTRIBUTE,
    r: MUST_USE_ATTRIBUTE,
    rx: MUST_USE_ATTRIBUTE,
    ry: MUST_USE_ATTRIBUTE,
    spreadMethod: MUST_USE_ATTRIBUTE,
    stopColor: MUST_USE_ATTRIBUTE,
    stopOpacity: MUST_USE_ATTRIBUTE,
    stroke: MUST_USE_ATTRIBUTE,
    strokeDasharray: MUST_USE_ATTRIBUTE,
    strokeLinecap: MUST_USE_ATTRIBUTE,
    strokeOpacity: MUST_USE_ATTRIBUTE,
    strokeWidth: MUST_USE_ATTRIBUTE,
    textAnchor: MUST_USE_ATTRIBUTE,
    transform: MUST_USE_ATTRIBUTE,
    version: MUST_USE_ATTRIBUTE,
    viewBox: MUST_USE_ATTRIBUTE,
    x1: MUST_USE_ATTRIBUTE,
    x2: MUST_USE_ATTRIBUTE,
    x: MUST_USE_ATTRIBUTE,
    xlinkActuate: MUST_USE_ATTRIBUTE,
    xlinkArcrole: MUST_USE_ATTRIBUTE,
    xlinkHref: MUST_USE_ATTRIBUTE,
    xlinkRole: MUST_USE_ATTRIBUTE,
    xlinkShow: MUST_USE_ATTRIBUTE,
    xlinkTitle: MUST_USE_ATTRIBUTE,
    xlinkType: MUST_USE_ATTRIBUTE,
    xmlBase: MUST_USE_ATTRIBUTE,
    xmlLang: MUST_USE_ATTRIBUTE,
    xmlSpace: MUST_USE_ATTRIBUTE,
    y1: MUST_USE_ATTRIBUTE,
    y2: MUST_USE_ATTRIBUTE,
    y: MUST_USE_ATTRIBUTE
  },
  DOMAttributeNamespaces: {
    xlinkActuate: NS.xlink,
    xlinkArcrole: NS.xlink,
    xlinkHref: NS.xlink,
    xlinkRole: NS.xlink,
    xlinkShow: NS.xlink,
    xlinkTitle: NS.xlink,
    xlinkType: NS.xlink,
    xmlBase: NS.xml,
    xmlLang: NS.xml,
    xmlSpace: NS.xml
  },
  DOMAttributeNames: {
    clipPath: 'clip-path',
    fillOpacity: 'fill-opacity',
    fontFamily: 'font-family',
    fontSize: 'font-size',
    gradientTransform: 'gradientTransform',
    gradientUnits: 'gradientUnits',
    markerEnd: 'marker-end',
    markerMid: 'marker-mid',
    markerStart: 'marker-start',
    patternContentUnits: 'patternContentUnits',
    patternUnits: 'patternUnits',
    preserveAspectRatio: 'preserveAspectRatio',
    spreadMethod: 'spreadMethod',
    stopColor: 'stop-color',
    stopOpacity: 'stop-opacity',
    strokeDasharray: 'stroke-dasharray',
    strokeLinecap: 'stroke-linecap',
    strokeOpacity: 'stroke-opacity',
    strokeWidth: 'stroke-width',
    textAnchor: 'text-anchor',
    viewBox: 'viewBox',
    xlinkActuate: 'xlink:actuate',
    xlinkArcrole: 'xlink:arcrole',
    xlinkHref: 'xlink:href',
    xlinkRole: 'xlink:role',
    xlinkShow: 'xlink:show',
    xlinkTitle: 'xlink:title',
    xlinkType: 'xlink:type',
    xmlBase: 'xml:base',
    xmlLang: 'xml:lang',
    xmlSpace: 'xml:space'
  }
};

module.exports = SVGDOMPropertyConfig;
},{"./DOMProperty":405}],482:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SelectEventPlugin
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventPropagators = require('./EventPropagators');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var ReactInputSelection = require('./ReactInputSelection');
var SyntheticEvent = require('./SyntheticEvent');

var getActiveElement = require('fbjs/lib/getActiveElement');
var isTextInputElement = require('./isTextInputElement');
var keyOf = require('fbjs/lib/keyOf');
var shallowEqual = require('fbjs/lib/shallowEqual');

var topLevelTypes = EventConstants.topLevelTypes;

var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11;

var eventTypes = {
  select: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onSelect: null }),
      captured: keyOf({ onSelectCapture: null })
    },
    dependencies: [topLevelTypes.topBlur, topLevelTypes.topContextMenu, topLevelTypes.topFocus, topLevelTypes.topKeyDown, topLevelTypes.topMouseDown, topLevelTypes.topMouseUp, topLevelTypes.topSelectionChange]
  }
};

var activeElement = null;
var activeElementID = null;
var lastSelection = null;
var mouseDown = false;

// Track whether a listener exists for this plugin. If none exist, we do
// not extract events.
var hasListener = false;
var ON_SELECT_KEY = keyOf({ onSelect: null });

/**
 * Get an object which is a unique representation of the current selection.
 *
 * The return value will not be consistent across nodes or browsers, but
 * two identical selections on the same node will return identical objects.
 *
 * @param {DOMElement} node
 * @return {object}
 */
function getSelection(node) {
  if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) {
    return {
      start: node.selectionStart,
      end: node.selectionEnd
    };
  } else if (window.getSelection) {
    var selection = window.getSelection();
    return {
      anchorNode: selection.anchorNode,
      anchorOffset: selection.anchorOffset,
      focusNode: selection.focusNode,
      focusOffset: selection.focusOffset
    };
  } else if (document.selection) {
    var range = document.selection.createRange();
    return {
      parentElement: range.parentElement(),
      text: range.text,
      top: range.boundingTop,
      left: range.boundingLeft
    };
  }
}

/**
 * Poll selection to see whether it's changed.
 *
 * @param {object} nativeEvent
 * @return {?SyntheticEvent}
 */
function constructSelectEvent(nativeEvent, nativeEventTarget) {
  // Ensure we have the right element, and that the user is not dragging a
  // selection (this matches native `select` event behavior). In HTML5, select
  // fires only on input and textarea thus if there's no focused element we
  // won't dispatch.
  if (mouseDown || activeElement == null || activeElement !== getActiveElement()) {
    return null;
  }

  // Only fire when selection has actually changed.
  var currentSelection = getSelection(activeElement);
  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
    lastSelection = currentSelection;

    var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementID, nativeEvent, nativeEventTarget);

    syntheticEvent.type = 'select';
    syntheticEvent.target = activeElement;

    EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);

    return syntheticEvent;
  }

  return null;
}

/**
 * This plugin creates an `onSelect` event that normalizes select events
 * across form elements.
 *
 * Supported elements are:
 * - input (see `isTextInputElement`)
 * - textarea
 * - contentEditable
 *
 * This differs from native browser implementations in the following ways:
 * - Fires on contentEditable fields as well as inputs.
 * - Fires for collapsed selection.
 * - Fires after user input.
 */
var SelectEventPlugin = {

  eventTypes: eventTypes,

  /**
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @see {EventPluginHub.extractEvents}
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    if (!hasListener) {
      return null;
    }

    switch (topLevelType) {
      // Track the input node that has focus.
      case topLevelTypes.topFocus:
        if (isTextInputElement(topLevelTarget) || topLevelTarget.contentEditable === 'true') {
          activeElement = topLevelTarget;
          activeElementID = topLevelTargetID;
          lastSelection = null;
        }
        break;
      case topLevelTypes.topBlur:
        activeElement = null;
        activeElementID = null;
        lastSelection = null;
        break;

      // Don't fire the event while the user is dragging. This matches the
      // semantics of the native select event.
      case topLevelTypes.topMouseDown:
        mouseDown = true;
        break;
      case topLevelTypes.topContextMenu:
      case topLevelTypes.topMouseUp:
        mouseDown = false;
        return constructSelectEvent(nativeEvent, nativeEventTarget);

      // Chrome and IE fire non-standard event when selection is changed (and
      // sometimes when it hasn't). IE's event fires out of order with respect
      // to key and input events on deletion, so we discard it.
      //
      // Firefox doesn't support selectionchange, so check selection status
      // after each key entry. The selection changes after keydown and before
      // keyup, but we check on keydown as well in the case of holding down a
      // key, when multiple keydown events are fired but only one keyup is.
      // This is also our approach for IE handling, for the reason above.
      case topLevelTypes.topSelectionChange:
        if (skipSelectionChangeEvent) {
          break;
        }
      // falls through
      case topLevelTypes.topKeyDown:
      case topLevelTypes.topKeyUp:
        return constructSelectEvent(nativeEvent, nativeEventTarget);
    }

    return null;
  },

  didPutListener: function (id, registrationName, listener) {
    if (registrationName === ON_SELECT_KEY) {
      hasListener = true;
    }
  }
};

module.exports = SelectEventPlugin;
},{"./EventConstants":410,"./EventPropagators":414,"./ReactInputSelection":456,"./SyntheticEvent":488,"./isTextInputElement":516,"fbjs/lib/ExecutionEnvironment":304,"fbjs/lib/getActiveElement":313,"fbjs/lib/keyOf":322,"fbjs/lib/shallowEqual":327}],483:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ServerReactRootIndex
 * @typechecks
 */

'use strict';

/**
 * Size of the reactRoot ID space. We generate random numbers for React root
 * IDs and if there's a collision the events and DOM update system will
 * get confused. In the future we need a way to generate GUIDs but for
 * now this will work on a smaller scale.
 */
var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);

var ServerReactRootIndex = {
  createReactRootIndex: function () {
    return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
  }
};

module.exports = ServerReactRootIndex;
},{}],484:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SimpleEventPlugin
 */

'use strict';

var EventConstants = require('./EventConstants');
var EventListener = require('fbjs/lib/EventListener');
var EventPropagators = require('./EventPropagators');
var ReactMount = require('./ReactMount');
var SyntheticClipboardEvent = require('./SyntheticClipboardEvent');
var SyntheticEvent = require('./SyntheticEvent');
var SyntheticFocusEvent = require('./SyntheticFocusEvent');
var SyntheticKeyboardEvent = require('./SyntheticKeyboardEvent');
var SyntheticMouseEvent = require('./SyntheticMouseEvent');
var SyntheticDragEvent = require('./SyntheticDragEvent');
var SyntheticTouchEvent = require('./SyntheticTouchEvent');
var SyntheticUIEvent = require('./SyntheticUIEvent');
var SyntheticWheelEvent = require('./SyntheticWheelEvent');

var emptyFunction = require('fbjs/lib/emptyFunction');
var getEventCharCode = require('./getEventCharCode');
var invariant = require('fbjs/lib/invariant');
var keyOf = require('fbjs/lib/keyOf');

var topLevelTypes = EventConstants.topLevelTypes;

var eventTypes = {
  abort: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onAbort: true }),
      captured: keyOf({ onAbortCapture: true })
    }
  },
  blur: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onBlur: true }),
      captured: keyOf({ onBlurCapture: true })
    }
  },
  canPlay: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCanPlay: true }),
      captured: keyOf({ onCanPlayCapture: true })
    }
  },
  canPlayThrough: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCanPlayThrough: true }),
      captured: keyOf({ onCanPlayThroughCapture: true })
    }
  },
  click: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onClick: true }),
      captured: keyOf({ onClickCapture: true })
    }
  },
  contextMenu: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onContextMenu: true }),
      captured: keyOf({ onContextMenuCapture: true })
    }
  },
  copy: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCopy: true }),
      captured: keyOf({ onCopyCapture: true })
    }
  },
  cut: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onCut: true }),
      captured: keyOf({ onCutCapture: true })
    }
  },
  doubleClick: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDoubleClick: true }),
      captured: keyOf({ onDoubleClickCapture: true })
    }
  },
  drag: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDrag: true }),
      captured: keyOf({ onDragCapture: true })
    }
  },
  dragEnd: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragEnd: true }),
      captured: keyOf({ onDragEndCapture: true })
    }
  },
  dragEnter: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragEnter: true }),
      captured: keyOf({ onDragEnterCapture: true })
    }
  },
  dragExit: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragExit: true }),
      captured: keyOf({ onDragExitCapture: true })
    }
  },
  dragLeave: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragLeave: true }),
      captured: keyOf({ onDragLeaveCapture: true })
    }
  },
  dragOver: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragOver: true }),
      captured: keyOf({ onDragOverCapture: true })
    }
  },
  dragStart: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDragStart: true }),
      captured: keyOf({ onDragStartCapture: true })
    }
  },
  drop: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDrop: true }),
      captured: keyOf({ onDropCapture: true })
    }
  },
  durationChange: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onDurationChange: true }),
      captured: keyOf({ onDurationChangeCapture: true })
    }
  },
  emptied: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onEmptied: true }),
      captured: keyOf({ onEmptiedCapture: true })
    }
  },
  encrypted: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onEncrypted: true }),
      captured: keyOf({ onEncryptedCapture: true })
    }
  },
  ended: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onEnded: true }),
      captured: keyOf({ onEndedCapture: true })
    }
  },
  error: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onError: true }),
      captured: keyOf({ onErrorCapture: true })
    }
  },
  focus: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onFocus: true }),
      captured: keyOf({ onFocusCapture: true })
    }
  },
  input: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onInput: true }),
      captured: keyOf({ onInputCapture: true })
    }
  },
  keyDown: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onKeyDown: true }),
      captured: keyOf({ onKeyDownCapture: true })
    }
  },
  keyPress: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onKeyPress: true }),
      captured: keyOf({ onKeyPressCapture: true })
    }
  },
  keyUp: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onKeyUp: true }),
      captured: keyOf({ onKeyUpCapture: true })
    }
  },
  load: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onLoad: true }),
      captured: keyOf({ onLoadCapture: true })
    }
  },
  loadedData: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onLoadedData: true }),
      captured: keyOf({ onLoadedDataCapture: true })
    }
  },
  loadedMetadata: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onLoadedMetadata: true }),
      captured: keyOf({ onLoadedMetadataCapture: true })
    }
  },
  loadStart: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onLoadStart: true }),
      captured: keyOf({ onLoadStartCapture: true })
    }
  },
  // Note: We do not allow listening to mouseOver events. Instead, use the
  // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
  mouseDown: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onMouseDown: true }),
      captured: keyOf({ onMouseDownCapture: true })
    }
  },
  mouseMove: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onMouseMove: true }),
      captured: keyOf({ onMouseMoveCapture: true })
    }
  },
  mouseOut: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onMouseOut: true }),
      captured: keyOf({ onMouseOutCapture: true })
    }
  },
  mouseOver: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onMouseOver: true }),
      captured: keyOf({ onMouseOverCapture: true })
    }
  },
  mouseUp: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onMouseUp: true }),
      captured: keyOf({ onMouseUpCapture: true })
    }
  },
  paste: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onPaste: true }),
      captured: keyOf({ onPasteCapture: true })
    }
  },
  pause: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onPause: true }),
      captured: keyOf({ onPauseCapture: true })
    }
  },
  play: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onPlay: true }),
      captured: keyOf({ onPlayCapture: true })
    }
  },
  playing: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onPlaying: true }),
      captured: keyOf({ onPlayingCapture: true })
    }
  },
  progress: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onProgress: true }),
      captured: keyOf({ onProgressCapture: true })
    }
  },
  rateChange: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onRateChange: true }),
      captured: keyOf({ onRateChangeCapture: true })
    }
  },
  reset: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onReset: true }),
      captured: keyOf({ onResetCapture: true })
    }
  },
  scroll: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onScroll: true }),
      captured: keyOf({ onScrollCapture: true })
    }
  },
  seeked: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onSeeked: true }),
      captured: keyOf({ onSeekedCapture: true })
    }
  },
  seeking: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onSeeking: true }),
      captured: keyOf({ onSeekingCapture: true })
    }
  },
  stalled: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onStalled: true }),
      captured: keyOf({ onStalledCapture: true })
    }
  },
  submit: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onSubmit: true }),
      captured: keyOf({ onSubmitCapture: true })
    }
  },
  suspend: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onSuspend: true }),
      captured: keyOf({ onSuspendCapture: true })
    }
  },
  timeUpdate: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onTimeUpdate: true }),
      captured: keyOf({ onTimeUpdateCapture: true })
    }
  },
  touchCancel: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onTouchCancel: true }),
      captured: keyOf({ onTouchCancelCapture: true })
    }
  },
  touchEnd: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onTouchEnd: true }),
      captured: keyOf({ onTouchEndCapture: true })
    }
  },
  touchMove: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onTouchMove: true }),
      captured: keyOf({ onTouchMoveCapture: true })
    }
  },
  touchStart: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onTouchStart: true }),
      captured: keyOf({ onTouchStartCapture: true })
    }
  },
  volumeChange: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onVolumeChange: true }),
      captured: keyOf({ onVolumeChangeCapture: true })
    }
  },
  waiting: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onWaiting: true }),
      captured: keyOf({ onWaitingCapture: true })
    }
  },
  wheel: {
    phasedRegistrationNames: {
      bubbled: keyOf({ onWheel: true }),
      captured: keyOf({ onWheelCapture: true })
    }
  }
};

var topLevelEventsToDispatchConfig = {
  topAbort: eventTypes.abort,
  topBlur: eventTypes.blur,
  topCanPlay: eventTypes.canPlay,
  topCanPlayThrough: eventTypes.canPlayThrough,
  topClick: eventTypes.click,
  topContextMenu: eventTypes.contextMenu,
  topCopy: eventTypes.copy,
  topCut: eventTypes.cut,
  topDoubleClick: eventTypes.doubleClick,
  topDrag: eventTypes.drag,
  topDragEnd: eventTypes.dragEnd,
  topDragEnter: eventTypes.dragEnter,
  topDragExit: eventTypes.dragExit,
  topDragLeave: eventTypes.dragLeave,
  topDragOver: eventTypes.dragOver,
  topDragStart: eventTypes.dragStart,
  topDrop: eventTypes.drop,
  topDurationChange: eventTypes.durationChange,
  topEmptied: eventTypes.emptied,
  topEncrypted: eventTypes.encrypted,
  topEnded: eventTypes.ended,
  topError: eventTypes.error,
  topFocus: eventTypes.focus,
  topInput: eventTypes.input,
  topKeyDown: eventTypes.keyDown,
  topKeyPress: eventTypes.keyPress,
  topKeyUp: eventTypes.keyUp,
  topLoad: eventTypes.load,
  topLoadedData: eventTypes.loadedData,
  topLoadedMetadata: eventTypes.loadedMetadata,
  topLoadStart: eventTypes.loadStart,
  topMouseDown: eventTypes.mouseDown,
  topMouseMove: eventTypes.mouseMove,
  topMouseOut: eventTypes.mouseOut,
  topMouseOver: eventTypes.mouseOver,
  topMouseUp: eventTypes.mouseUp,
  topPaste: eventTypes.paste,
  topPause: eventTypes.pause,
  topPlay: eventTypes.play,
  topPlaying: eventTypes.playing,
  topProgress: eventTypes.progress,
  topRateChange: eventTypes.rateChange,
  topReset: eventTypes.reset,
  topScroll: eventTypes.scroll,
  topSeeked: eventTypes.seeked,
  topSeeking: eventTypes.seeking,
  topStalled: eventTypes.stalled,
  topSubmit: eventTypes.submit,
  topSuspend: eventTypes.suspend,
  topTimeUpdate: eventTypes.timeUpdate,
  topTouchCancel: eventTypes.touchCancel,
  topTouchEnd: eventTypes.touchEnd,
  topTouchMove: eventTypes.touchMove,
  topTouchStart: eventTypes.touchStart,
  topVolumeChange: eventTypes.volumeChange,
  topWaiting: eventTypes.waiting,
  topWheel: eventTypes.wheel
};

for (var type in topLevelEventsToDispatchConfig) {
  topLevelEventsToDispatchConfig[type].dependencies = [type];
}

var ON_CLICK_KEY = keyOf({ onClick: null });
var onClickListeners = {};

var SimpleEventPlugin = {

  eventTypes: eventTypes,

  /**
   * @param {string} topLevelType Record from `EventConstants`.
   * @param {DOMEventTarget} topLevelTarget The listening component root node.
   * @param {string} topLevelTargetID ID of `topLevelTarget`.
   * @param {object} nativeEvent Native browser event.
   * @return {*} An accumulation of synthetic events.
   * @see {EventPluginHub.extractEvents}
   */
  extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) {
    var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
    if (!dispatchConfig) {
      return null;
    }
    var EventConstructor;
    switch (topLevelType) {
      case topLevelTypes.topAbort:
      case topLevelTypes.topCanPlay:
      case topLevelTypes.topCanPlayThrough:
      case topLevelTypes.topDurationChange:
      case topLevelTypes.topEmptied:
      case topLevelTypes.topEncrypted:
      case topLevelTypes.topEnded:
      case topLevelTypes.topError:
      case topLevelTypes.topInput:
      case topLevelTypes.topLoad:
      case topLevelTypes.topLoadedData:
      case topLevelTypes.topLoadedMetadata:
      case topLevelTypes.topLoadStart:
      case topLevelTypes.topPause:
      case topLevelTypes.topPlay:
      case topLevelTypes.topPlaying:
      case topLevelTypes.topProgress:
      case topLevelTypes.topRateChange:
      case topLevelTypes.topReset:
      case topLevelTypes.topSeeked:
      case topLevelTypes.topSeeking:
      case topLevelTypes.topStalled:
      case topLevelTypes.topSubmit:
      case topLevelTypes.topSuspend:
      case topLevelTypes.topTimeUpdate:
      case topLevelTypes.topVolumeChange:
      case topLevelTypes.topWaiting:
        // HTML Events
        // @see http://www.w3.org/TR/html5/index.html#events-0
        EventConstructor = SyntheticEvent;
        break;
      case topLevelTypes.topKeyPress:
        // FireFox creates a keypress event for function keys too. This removes
        // the unwanted keypress events. Enter is however both printable and
        // non-printable. One would expect Tab to be as well (but it isn't).
        if (getEventCharCode(nativeEvent) === 0) {
          return null;
        }
      /* falls through */
      case topLevelTypes.topKeyDown:
      case topLevelTypes.topKeyUp:
        EventConstructor = SyntheticKeyboardEvent;
        break;
      case topLevelTypes.topBlur:
      case topLevelTypes.topFocus:
        EventConstructor = SyntheticFocusEvent;
        break;
      case topLevelTypes.topClick:
        // Firefox creates a click event on right mouse clicks. This removes the
        // unwanted click events.
        if (nativeEvent.button === 2) {
          return null;
        }
      /* falls through */
      case topLevelTypes.topContextMenu:
      case topLevelTypes.topDoubleClick:
      case topLevelTypes.topMouseDown:
      case topLevelTypes.topMouseMove:
      case topLevelTypes.topMouseOut:
      case topLevelTypes.topMouseOver:
      case topLevelTypes.topMouseUp:
        EventConstructor = SyntheticMouseEvent;
        break;
      case topLevelTypes.topDrag:
      case topLevelTypes.topDragEnd:
      case topLevelTypes.topDragEnter:
      case topLevelTypes.topDragExit:
      case topLevelTypes.topDragLeave:
      case topLevelTypes.topDragOver:
      case topLevelTypes.topDragStart:
      case topLevelTypes.topDrop:
        EventConstructor = SyntheticDragEvent;
        break;
      case topLevelTypes.topTouchCancel:
      case topLevelTypes.topTouchEnd:
      case topLevelTypes.topTouchMove:
      case topLevelTypes.topTouchStart:
        EventConstructor = SyntheticTouchEvent;
        break;
      case topLevelTypes.topScroll:
        EventConstructor = SyntheticUIEvent;
        break;
      case topLevelTypes.topWheel:
        EventConstructor = SyntheticWheelEvent;
        break;
      case topLevelTypes.topCopy:
      case topLevelTypes.topCut:
      case topLevelTypes.topPaste:
        EventConstructor = SyntheticClipboardEvent;
        break;
    }
    !EventConstructor ? process.env.NODE_ENV !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : invariant(false) : undefined;
    var event = EventConstructor.getPooled(dispatchConfig, topLevelTargetID, nativeEvent, nativeEventTarget);
    EventPropagators.accumulateTwoPhaseDispatches(event);
    return event;
  },

  didPutListener: function (id, registrationName, listener) {
    // Mobile Safari does not fire properly bubble click events on
    // non-interactive elements, which means delegated click listeners do not
    // fire. The workaround for this bug involves attaching an empty click
    // listener on the target node.
    if (registrationName === ON_CLICK_KEY) {
      var node = ReactMount.getNode(id);
      if (!onClickListeners[id]) {
        onClickListeners[id] = EventListener.listen(node, 'click', emptyFunction);
      }
    }
  },

  willDeleteListener: function (id, registrationName) {
    if (registrationName === ON_CLICK_KEY) {
      onClickListeners[id].remove();
      delete onClickListeners[id];
    }
  }

};

module.exports = SimpleEventPlugin;
}).call(this,require('_process'))

},{"./EventConstants":410,"./EventPropagators":414,"./ReactMount":461,"./SyntheticClipboardEvent":485,"./SyntheticDragEvent":487,"./SyntheticEvent":488,"./SyntheticFocusEvent":489,"./SyntheticKeyboardEvent":491,"./SyntheticMouseEvent":492,"./SyntheticTouchEvent":493,"./SyntheticUIEvent":494,"./SyntheticWheelEvent":495,"./getEventCharCode":507,"_process":334,"fbjs/lib/EventListener":303,"fbjs/lib/emptyFunction":310,"fbjs/lib/invariant":318,"fbjs/lib/keyOf":322}],485:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticClipboardEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticEvent = require('./SyntheticEvent');

/**
 * @interface Event
 * @see http://www.w3.org/TR/clipboard-apis/
 */
var ClipboardEventInterface = {
  clipboardData: function (event) {
    return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
  }
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);

module.exports = SyntheticClipboardEvent;
},{"./SyntheticEvent":488}],486:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticCompositionEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticEvent = require('./SyntheticEvent');

/**
 * @interface Event
 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
 */
var CompositionEventInterface = {
  data: null
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface);

module.exports = SyntheticCompositionEvent;
},{"./SyntheticEvent":488}],487:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticDragEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticMouseEvent = require('./SyntheticMouseEvent');

/**
 * @interface DragEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var DragEventInterface = {
  dataTransfer: null
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);

module.exports = SyntheticDragEvent;
},{"./SyntheticMouseEvent":492}],488:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticEvent
 * @typechecks static-only
 */

'use strict';

var PooledClass = require('./PooledClass');

var assign = require('./Object.assign');
var emptyFunction = require('fbjs/lib/emptyFunction');
var warning = require('fbjs/lib/warning');

/**
 * @interface Event
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var EventInterface = {
  type: null,
  target: null,
  // currentTarget is set when dispatching; no use in copying it here
  currentTarget: emptyFunction.thatReturnsNull,
  eventPhase: null,
  bubbles: null,
  cancelable: null,
  timeStamp: function (event) {
    return event.timeStamp || Date.now();
  },
  defaultPrevented: null,
  isTrusted: null
};

/**
 * Synthetic events are dispatched by event plugins, typically in response to a
 * top-level event delegation handler.
 *
 * These systems should generally use pooling to reduce the frequency of garbage
 * collection. The system should check `isPersistent` to determine whether the
 * event should be released into the pool after being dispatched. Users that
 * need a persisted event should invoke `persist`.
 *
 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
 * normalizing browser quirks. Subclasses do not necessarily have to implement a
 * DOM interface; custom application-specific events can also subclass this.
 *
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 */
function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  this.dispatchConfig = dispatchConfig;
  this.dispatchMarker = dispatchMarker;
  this.nativeEvent = nativeEvent;

  var Interface = this.constructor.Interface;
  for (var propName in Interface) {
    if (!Interface.hasOwnProperty(propName)) {
      continue;
    }
    var normalize = Interface[propName];
    if (normalize) {
      this[propName] = normalize(nativeEvent);
    } else {
      if (propName === 'target') {
        this.target = nativeEventTarget;
      } else {
        this[propName] = nativeEvent[propName];
      }
    }
  }

  var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
  if (defaultPrevented) {
    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
  } else {
    this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
  }
  this.isPropagationStopped = emptyFunction.thatReturnsFalse;
}

assign(SyntheticEvent.prototype, {

  preventDefault: function () {
    this.defaultPrevented = true;
    var event = this.nativeEvent;
    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re calling `preventDefault` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined;
    }
    if (!event) {
      return;
    }

    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
  },

  stopPropagation: function () {
    var event = this.nativeEvent;
    if (process.env.NODE_ENV !== 'production') {
      process.env.NODE_ENV !== 'production' ? warning(event, 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re calling `stopPropagation` on a ' + 'released/nullified synthetic event. This is a no-op. See ' + 'https://fb.me/react-event-pooling for more information.') : undefined;
    }
    if (!event) {
      return;
    }

    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
    this.isPropagationStopped = emptyFunction.thatReturnsTrue;
  },

  /**
   * We release all dispatched `SyntheticEvent`s after each event loop, adding
   * them back into the pool. This allows a way to hold onto a reference that
   * won't be added back into the pool.
   */
  persist: function () {
    this.isPersistent = emptyFunction.thatReturnsTrue;
  },

  /**
   * Checks if this event should be released back into the pool.
   *
   * @return {boolean} True if this should not be released, false otherwise.
   */
  isPersistent: emptyFunction.thatReturnsFalse,

  /**
   * `PooledClass` looks for `destructor` on each instance it releases.
   */
  destructor: function () {
    var Interface = this.constructor.Interface;
    for (var propName in Interface) {
      this[propName] = null;
    }
    this.dispatchConfig = null;
    this.dispatchMarker = null;
    this.nativeEvent = null;
  }

});

SyntheticEvent.Interface = EventInterface;

/**
 * Helper to reduce boilerplate when creating subclasses.
 *
 * @param {function} Class
 * @param {?object} Interface
 */
SyntheticEvent.augmentClass = function (Class, Interface) {
  var Super = this;

  var prototype = Object.create(Super.prototype);
  assign(prototype, Class.prototype);
  Class.prototype = prototype;
  Class.prototype.constructor = Class;

  Class.Interface = assign({}, Super.Interface, Interface);
  Class.augmentClass = Super.augmentClass;

  PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);
};

PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);

module.exports = SyntheticEvent;
}).call(this,require('_process'))

},{"./Object.assign":418,"./PooledClass":419,"_process":334,"fbjs/lib/emptyFunction":310,"fbjs/lib/warning":329}],489:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticFocusEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticUIEvent = require('./SyntheticUIEvent');

/**
 * @interface FocusEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var FocusEventInterface = {
  relatedTarget: null
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);

module.exports = SyntheticFocusEvent;
},{"./SyntheticUIEvent":494}],490:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticInputEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticEvent = require('./SyntheticEvent');

/**
 * @interface Event
 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
 *      /#events-inputevents
 */
var InputEventInterface = {
  data: null
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface);

module.exports = SyntheticInputEvent;
},{"./SyntheticEvent":488}],491:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticKeyboardEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticUIEvent = require('./SyntheticUIEvent');

var getEventCharCode = require('./getEventCharCode');
var getEventKey = require('./getEventKey');
var getEventModifierState = require('./getEventModifierState');

/**
 * @interface KeyboardEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var KeyboardEventInterface = {
  key: getEventKey,
  location: null,
  ctrlKey: null,
  shiftKey: null,
  altKey: null,
  metaKey: null,
  repeat: null,
  locale: null,
  getModifierState: getEventModifierState,
  // Legacy Interface
  charCode: function (event) {
    // `charCode` is the result of a KeyPress event and represents the value of
    // the actual printable character.

    // KeyPress is deprecated, but its replacement is not yet final and not
    // implemented in any major browser. Only KeyPress has charCode.
    if (event.type === 'keypress') {
      return getEventCharCode(event);
    }
    return 0;
  },
  keyCode: function (event) {
    // `keyCode` is the result of a KeyDown/Up event and represents the value of
    // physical keyboard key.

    // The actual meaning of the value depends on the users' keyboard layout
    // which cannot be detected. Assuming that it is a US keyboard layout
    // provides a surprisingly accurate mapping for US and European users.
    // Due to this, it is left to the user to implement at this time.
    if (event.type === 'keydown' || event.type === 'keyup') {
      return event.keyCode;
    }
    return 0;
  },
  which: function (event) {
    // `which` is an alias for either `keyCode` or `charCode` depending on the
    // type of the event.
    if (event.type === 'keypress') {
      return getEventCharCode(event);
    }
    if (event.type === 'keydown' || event.type === 'keyup') {
      return event.keyCode;
    }
    return 0;
  }
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);

module.exports = SyntheticKeyboardEvent;
},{"./SyntheticUIEvent":494,"./getEventCharCode":507,"./getEventKey":508,"./getEventModifierState":509}],492:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticMouseEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticUIEvent = require('./SyntheticUIEvent');
var ViewportMetrics = require('./ViewportMetrics');

var getEventModifierState = require('./getEventModifierState');

/**
 * @interface MouseEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var MouseEventInterface = {
  screenX: null,
  screenY: null,
  clientX: null,
  clientY: null,
  ctrlKey: null,
  shiftKey: null,
  altKey: null,
  metaKey: null,
  getModifierState: getEventModifierState,
  button: function (event) {
    // Webkit, Firefox, IE9+
    // which:  1 2 3
    // button: 0 1 2 (standard)
    var button = event.button;
    if ('which' in event) {
      return button;
    }
    // IE<9
    // which:  undefined
    // button: 0 0 0
    // button: 1 4 2 (onmouseup)
    return button === 2 ? 2 : button === 4 ? 1 : 0;
  },
  buttons: null,
  relatedTarget: function (event) {
    return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
  },
  // "Proprietary" Interface.
  pageX: function (event) {
    return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft;
  },
  pageY: function (event) {
    return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop;
  }
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);

module.exports = SyntheticMouseEvent;
},{"./SyntheticUIEvent":494,"./ViewportMetrics":497,"./getEventModifierState":509}],493:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticTouchEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticUIEvent = require('./SyntheticUIEvent');

var getEventModifierState = require('./getEventModifierState');

/**
 * @interface TouchEvent
 * @see http://www.w3.org/TR/touch-events/
 */
var TouchEventInterface = {
  touches: null,
  targetTouches: null,
  changedTouches: null,
  altKey: null,
  metaKey: null,
  ctrlKey: null,
  shiftKey: null,
  getModifierState: getEventModifierState
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticUIEvent}
 */
function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);

module.exports = SyntheticTouchEvent;
},{"./SyntheticUIEvent":494,"./getEventModifierState":509}],494:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticUIEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticEvent = require('./SyntheticEvent');

var getEventTarget = require('./getEventTarget');

/**
 * @interface UIEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var UIEventInterface = {
  view: function (event) {
    if (event.view) {
      return event.view;
    }

    var target = getEventTarget(event);
    if (target != null && target.window === target) {
      // target is a window object
      return target;
    }

    var doc = target.ownerDocument;
    // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
    if (doc) {
      return doc.defaultView || doc.parentWindow;
    } else {
      return window;
    }
  },
  detail: function (event) {
    return event.detail || 0;
  }
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticEvent}
 */
function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);

module.exports = SyntheticUIEvent;
},{"./SyntheticEvent":488,"./getEventTarget":510}],495:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SyntheticWheelEvent
 * @typechecks static-only
 */

'use strict';

var SyntheticMouseEvent = require('./SyntheticMouseEvent');

/**
 * @interface WheelEvent
 * @see http://www.w3.org/TR/DOM-Level-3-Events/
 */
var WheelEventInterface = {
  deltaX: function (event) {
    return 'deltaX' in event ? event.deltaX :
    // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
    'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
  },
  deltaY: function (event) {
    return 'deltaY' in event ? event.deltaY :
    // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
    'wheelDeltaY' in event ? -event.wheelDeltaY :
    // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
    'wheelDelta' in event ? -event.wheelDelta : 0;
  },
  deltaZ: null,

  // Browsers without "deltaMode" is reporting in raw wheel delta where one
  // notch on the scroll is always +/- 120, roughly equivalent to pixels.
  // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
  // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
  deltaMode: null
};

/**
 * @param {object} dispatchConfig Configuration used to dispatch this event.
 * @param {string} dispatchMarker Marker identifying the event target.
 * @param {object} nativeEvent Native browser event.
 * @extends {SyntheticMouseEvent}
 */
function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}

SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);

module.exports = SyntheticWheelEvent;
},{"./SyntheticMouseEvent":492}],496:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule Transaction
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 * `Transaction` creates a black box that is able to wrap any method such that
 * certain invariants are maintained before and after the method is invoked
 * (Even if an exception is thrown while invoking the wrapped method). Whoever
 * instantiates a transaction can provide enforcers of the invariants at
 * creation time. The `Transaction` class itself will supply one additional
 * automatic invariant for you - the invariant that any transaction instance
 * should not be run while it is already being run. You would typically create a
 * single instance of a `Transaction` for reuse multiple times, that potentially
 * is used to wrap several different methods. Wrappers are extremely simple -
 * they only require implementing two methods.
 *
 * <pre>
 *                       wrappers (injected at creation time)
 *                                      +        +
 *                                      |        |
 *                    +-----------------|--------|--------------+
 *                    |                 v        |              |
 *                    |      +---------------+   |              |
 *                    |   +--|    wrapper1   |---|----+         |
 *                    |   |  +---------------+   v    |         |
 *                    |   |          +-------------+  |         |
 *                    |   |     +----|   wrapper2  |--------+   |
 *                    |   |     |    +-------------+  |     |   |
 *                    |   |     |                     |     |   |
 *                    |   v     v                     v     v   | wrapper
 *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
 * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | |   | |   |   |         |   |   | |   | |
 *                    | +---+ +---+   +---------+   +---+ +---+ |
 *                    |  initialize                    close    |
 *                    +-----------------------------------------+
 * </pre>
 *
 * Use cases:
 * - Preserving the input selection ranges before/after reconciliation.
 *   Restoring selection even in the event of an unexpected error.
 * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
 *   while guaranteeing that afterwards, the event system is reactivated.
 * - Flushing a queue of collected DOM mutations to the main UI thread after a
 *   reconciliation takes place in a worker thread.
 * - Invoking any collected `componentDidUpdate` callbacks after rendering new
 *   content.
 * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
 *   to preserve the `scrollTop` (an automatic scroll aware DOM).
 * - (Future use case): Layout calculations before and after DOM updates.
 *
 * Transactional plugin API:
 * - A module that has an `initialize` method that returns any precomputation.
 * - and a `close` method that accepts the precomputation. `close` is invoked
 *   when the wrapped process is completed, or has failed.
 *
 * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
 * that implement `initialize` and `close`.
 * @return {Transaction} Single transaction for reuse in thread.
 *
 * @class Transaction
 */
var Mixin = {
  /**
   * Sets up this instance so that it is prepared for collecting metrics. Does
   * so such that this setup method may be used on an instance that is already
   * initialized, in a way that does not consume additional memory upon reuse.
   * That can be useful if you decide to make your subclass of this mixin a
   * "PooledClass".
   */
  reinitializeTransaction: function () {
    this.transactionWrappers = this.getTransactionWrappers();
    if (this.wrapperInitData) {
      this.wrapperInitData.length = 0;
    } else {
      this.wrapperInitData = [];
    }
    this._isInTransaction = false;
  },

  _isInTransaction: false,

  /**
   * @abstract
   * @return {Array<TransactionWrapper>} Array of transaction wrappers.
   */
  getTransactionWrappers: null,

  isInTransaction: function () {
    return !!this._isInTransaction;
  },

  /**
   * Executes the function within a safety window. Use this for the top level
   * methods that result in large amounts of computation/mutations that would
   * need to be safety checked. The optional arguments helps prevent the need
   * to bind in many cases.
   *
   * @param {function} method Member of scope to call.
   * @param {Object} scope Scope to invoke from.
   * @param {Object?=} a Argument to pass to the method.
   * @param {Object?=} b Argument to pass to the method.
   * @param {Object?=} c Argument to pass to the method.
   * @param {Object?=} d Argument to pass to the method.
   * @param {Object?=} e Argument to pass to the method.
   * @param {Object?=} f Argument to pass to the method.
   *
   * @return {*} Return value from `method`.
   */
  perform: function (method, scope, a, b, c, d, e, f) {
    !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there ' + 'is already an outstanding transaction.') : invariant(false) : undefined;
    var errorThrown;
    var ret;
    try {
      this._isInTransaction = true;
      // Catching errors makes debugging more difficult, so we start with
      // errorThrown set to true before setting it to false after calling
      // close -- if it's still set to true in the finally block, it means
      // one of these calls threw.
      errorThrown = true;
      this.initializeAll(0);
      ret = method.call(scope, a, b, c, d, e, f);
      errorThrown = false;
    } finally {
      try {
        if (errorThrown) {
          // If `method` throws, prefer to show that stack trace over any thrown
          // by invoking `closeAll`.
          try {
            this.closeAll(0);
          } catch (err) {}
        } else {
          // Since `method` didn't throw, we don't want to silence the exception
          // here.
          this.closeAll(0);
        }
      } finally {
        this._isInTransaction = false;
      }
    }
    return ret;
  },

  initializeAll: function (startIndex) {
    var transactionWrappers = this.transactionWrappers;
    for (var i = startIndex; i < transactionWrappers.length; i++) {
      var wrapper = transactionWrappers[i];
      try {
        // Catching errors makes debugging more difficult, so we start with the
        // OBSERVED_ERROR state before overwriting it with the real return value
        // of initialize -- if it's still set to OBSERVED_ERROR in the finally
        // block, it means wrapper.initialize threw.
        this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
        this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;
      } finally {
        if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {
          // The initializer for wrapper i threw an error; initialize the
          // remaining wrappers but silence any exceptions from them to ensure
          // that the first error is the one to bubble up.
          try {
            this.initializeAll(i + 1);
          } catch (err) {}
        }
      }
    }
  },

  /**
   * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
   * them the respective return values of `this.transactionWrappers.init[i]`
   * (`close`rs that correspond to initializers that failed will not be
   * invoked).
   */
  closeAll: function (startIndex) {
    !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : invariant(false) : undefined;
    var transactionWrappers = this.transactionWrappers;
    for (var i = startIndex; i < transactionWrappers.length; i++) {
      var wrapper = transactionWrappers[i];
      var initData = this.wrapperInitData[i];
      var errorThrown;
      try {
        // Catching errors makes debugging more difficult, so we start with
        // errorThrown set to true before setting it to false after calling
        // close -- if it's still set to true in the finally block, it means
        // wrapper.close threw.
        errorThrown = true;
        if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) {
          wrapper.close.call(this, initData);
        }
        errorThrown = false;
      } finally {
        if (errorThrown) {
          // The closer for wrapper i threw an error; close the remaining
          // wrappers but silence any exceptions from them to ensure that the
          // first error is the one to bubble up.
          try {
            this.closeAll(i + 1);
          } catch (e) {}
        }
      }
    }
    this.wrapperInitData.length = 0;
  }
};

var Transaction = {

  Mixin: Mixin,

  /**
   * Token to look for to determine if an error occurred.
   */
  OBSERVED_ERROR: {}

};

module.exports = Transaction;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],497:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ViewportMetrics
 */

'use strict';

var ViewportMetrics = {

  currentScrollLeft: 0,

  currentScrollTop: 0,

  refreshScrollValues: function (scrollPosition) {
    ViewportMetrics.currentScrollLeft = scrollPosition.x;
    ViewportMetrics.currentScrollTop = scrollPosition.y;
  }

};

module.exports = ViewportMetrics;
},{}],498:[function(require,module,exports){
(function (process){
/**
 * Copyright 2014-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule accumulateInto
 */

'use strict';

var invariant = require('fbjs/lib/invariant');

/**
 *
 * Accumulates items that must not be null or undefined into the first one. This
 * is used to conserve memory by avoiding array allocations, and thus sacrifices
 * API cleanness. Since `current` can be null before being passed in and not
 * null after this function, make sure to assign it back to `current`:
 *
 * `a = accumulateInto(a, b);`
 *
 * This API should be sparingly used. Try `accumulate` for something cleaner.
 *
 * @return {*|array<*>} An accumulation of items.
 */

function accumulateInto(current, next) {
  !(next != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : invariant(false) : undefined;
  if (current == null) {
    return next;
  }

  // Both are not empty. Warning: Never call x.concat(y) when you are not
  // certain that x is an Array (x could be a string with concat method).
  var currentIsArray = Array.isArray(current);
  var nextIsArray = Array.isArray(next);

  if (currentIsArray && nextIsArray) {
    current.push.apply(current, next);
    return current;
  }

  if (currentIsArray) {
    current.push(next);
    return current;
  }

  if (nextIsArray) {
    // A bit too dangerous to mutate `next`.
    return [current].concat(next);
  }

  return [current, next];
}

module.exports = accumulateInto;
}).call(this,require('_process'))

},{"_process":334,"fbjs/lib/invariant":318}],499:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule adler32
 */

'use strict';

var MOD = 65521;

// adler32 is not cryptographically strong, and is only used to sanity check that
// markup generated on the server matches the markup generated on the client.
// This implementation (a modified version of the SheetJS version) has been optimized
// for our use case, at the expense of conforming to the adler32 specification
// for non-ascii inputs.
function adler32(data) {
  var a = 1;
  var b = 0;
  var i = 0;
  var l = data.length;
  var m = l & ~0x3;
  while (i < m) {
    for (; i < Math.min(i + 4096, m); i += 4) {
      b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3));
    }
    a %= MOD;
    b %= MOD;
  }
  for (; i < l; i++) {
    b += a += data.charCodeAt(i);
  }
  a %= MOD;
  b %= MOD;
  return a | b << 16;
}

module.exports = adler32;
},{}],500:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule canDefineProperty
 */

'use strict';

var canDefineProperty = false;
if (process.env.NODE_ENV !== 'production') {
  try {
    Object.defineProperty({}, 'x', { get: function () {} });
    canDefineProperty = true;
  } catch (x) {
    // IE will fail on defineProperty
  }
}

module.exports = canDefineProperty;
}).call(this,require('_process'))

},{"_process":334}],501:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule dangerousStyleValue
 * @typechecks static-only
 */

'use strict';

var CSSProperty = require('./CSSProperty');

var isUnitlessNumber = CSSProperty.isUnitlessNumber;

/**
 * Convert a value into the proper css writable value. The style name `name`
 * should be logical (no hyphens), as specified
 * in `CSSProperty.isUnitlessNumber`.
 *
 * @param {string} name CSS property name such as `topMargin`.
 * @param {*} value CSS property value such as `10px`.
 * @return {string} Normalized style value with dimensions applied.
 */
function dangerousStyleValue(name, value) {
  // Note that we've removed escapeTextForBrowser() calls here since the
  // whole string will be escaped when the attribute is injected into
  // the markup. If you provide unsafe user data here they can inject
  // arbitrary CSS which may be problematic (I couldn't repro this):
  // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
  // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
  // This is not an XSS hole but instead a potential CSS injection issue
  // which has lead to a greater discussion about how we're going to
  // trust URLs moving forward. See #2115901

  var isEmpty = value == null || typeof value === 'boolean' || value === '';
  if (isEmpty) {
    return '';
  }

  var isNonNumeric = isNaN(value);
  if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) {
    return '' + value; // cast to string
  }

  if (typeof value === 'string') {
    value = value.trim();
  }
  return value + 'px';
}

module.exports = dangerousStyleValue;
},{"./CSSProperty":399}],502:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule deprecated
 */

'use strict';

var assign = require('./Object.assign');
var warning = require('fbjs/lib/warning');

/**
 * This will log a single deprecation notice per function and forward the call
 * on to the new API.
 *
 * @param {string} fnName The name of the function
 * @param {string} newModule The module that fn will exist in
 * @param {string} newPackage The module that fn will exist in
 * @param {*} ctx The context this forwarded call should run in
 * @param {function} fn The function to forward on to
 * @return {function} The function that will warn once and then call fn
 */
function deprecated(fnName, newModule, newPackage, ctx, fn) {
  var warned = false;
  if (process.env.NODE_ENV !== 'production') {
    var newFn = function () {
      process.env.NODE_ENV !== 'production' ? warning(warned,
      // Require examples in this string must be split to prevent React's
      // build tools from mistaking them for real requires.
      // Otherwise the build tools will attempt to build a '%s' module.
      'React.%s is deprecated. Please use %s.%s from require' + '(\'%s\') ' + 'instead.', fnName, newModule, fnName, newPackage) : undefined;
      warned = true;
      return fn.apply(ctx, arguments);
    };
    // We need to make sure all properties of the original fn are copied over.
    // In particular, this is needed to support PropTypes
    return assign(newFn, fn);
  }

  return fn;
}

module.exports = deprecated;
}).call(this,require('_process'))

},{"./Object.assign":418,"_process":334,"fbjs/lib/warning":329}],503:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule escapeTextContentForBrowser
 */

'use strict';

var ESCAPE_LOOKUP = {
  '&': '&amp;',
  '>': '&gt;',
  '<': '&lt;',
  '"': '&quot;',
  '\'': '&#x27;'
};

var ESCAPE_REGEX = /[&><"']/g;

function escaper(match) {
  return ESCAPE_LOOKUP[match];
}

/**
 * Escapes text to prevent scripting attacks.
 *
 * @param {*} text Text value to escape.
 * @return {string} An escaped string.
 */
function escapeTextContentForBrowser(text) {
  return ('' + text).replace(ESCAPE_REGEX, escaper);
}

module.exports = escapeTextContentForBrowser;
},{}],504:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule findDOMNode
 * @typechecks static-only
 */

'use strict';

var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactInstanceMap = require('./ReactInstanceMap');
var ReactMount = require('./ReactMount');

var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

/**
 * Returns the DOM node rendered by this element.
 *
 * @param {ReactComponent|DOMElement} componentOrElement
 * @return {?DOMElement} The root node of this element.
 */
function findDOMNode(componentOrElement) {
  if (process.env.NODE_ENV !== 'production') {
    var owner = ReactCurrentOwner.current;
    if (owner !== null) {
      process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing getDOMNode or findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : undefined;
      owner._warnedAboutRefsInRender = true;
    }
  }
  if (componentOrElement == null) {
    return null;
  }
  if (componentOrElement.nodeType === 1) {
    return componentOrElement;
  }
  if (ReactInstanceMap.has(componentOrElement)) {
    return ReactMount.getNodeFromInstance(componentOrElement);
  }
  !(componentOrElement.render == null || typeof componentOrElement.render !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : invariant(false) : undefined;
  !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : invariant(false) : undefined;
}

module.exports = findDOMNode;
}).call(this,require('_process'))

},{"./ReactCurrentOwner":430,"./ReactInstanceMap":458,"./ReactMount":461,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],505:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule flattenChildren
 */

'use strict';

var traverseAllChildren = require('./traverseAllChildren');
var warning = require('fbjs/lib/warning');

/**
 * @param {function} traverseContext Context passed through traversal.
 * @param {?ReactComponent} child React child component.
 * @param {!string} name String name of key path to child.
 */
function flattenSingleChildIntoContext(traverseContext, child, name) {
  // We found a component instance.
  var result = traverseContext;
  var keyUnique = result[name] === undefined;
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(keyUnique, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.', name) : undefined;
  }
  if (keyUnique && child != null) {
    result[name] = child;
  }
}

/**
 * Flattens children that are typically specified as `props.children`. Any null
 * children will not be included in the resulting object.
 * @return {!object} flattened children keyed by name.
 */
function flattenChildren(children) {
  if (children == null) {
    return children;
  }
  var result = {};
  traverseAllChildren(children, flattenSingleChildIntoContext, result);
  return result;
}

module.exports = flattenChildren;
}).call(this,require('_process'))

},{"./traverseAllChildren":523,"_process":334,"fbjs/lib/warning":329}],506:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule forEachAccumulated
 */

'use strict';

/**
 * @param {array} arr an "accumulation" of items which is either an Array or
 * a single item. Useful when paired with the `accumulate` module. This is a
 * simple utility that allows us to reason about a collection of items, but
 * handling the case when there is exactly one item (and we do not need to
 * allocate an array).
 */
var forEachAccumulated = function (arr, cb, scope) {
  if (Array.isArray(arr)) {
    arr.forEach(cb, scope);
  } else if (arr) {
    cb.call(scope, arr);
  }
};

module.exports = forEachAccumulated;
},{}],507:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getEventCharCode
 * @typechecks static-only
 */

'use strict';

/**
 * `charCode` represents the actual "character code" and is safe to use with
 * `String.fromCharCode`. As such, only keys that correspond to printable
 * characters produce a valid `charCode`, the only exception to this is Enter.
 * The Tab-key is considered non-printable and does not have a `charCode`,
 * presumably because it does not produce a tab-character in browsers.
 *
 * @param {object} nativeEvent Native browser event.
 * @return {number} Normalized `charCode` property.
 */
function getEventCharCode(nativeEvent) {
  var charCode;
  var keyCode = nativeEvent.keyCode;

  if ('charCode' in nativeEvent) {
    charCode = nativeEvent.charCode;

    // FF does not set `charCode` for the Enter-key, check against `keyCode`.
    if (charCode === 0 && keyCode === 13) {
      charCode = 13;
    }
  } else {
    // IE8 does not implement `charCode`, but `keyCode` has the correct value.
    charCode = keyCode;
  }

  // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
  // Must not discard the (non-)printable Enter-key.
  if (charCode >= 32 || charCode === 13) {
    return charCode;
  }

  return 0;
}

module.exports = getEventCharCode;
},{}],508:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getEventKey
 * @typechecks static-only
 */

'use strict';

var getEventCharCode = require('./getEventCharCode');

/**
 * Normalization of deprecated HTML5 `key` values
 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
 */
var normalizeKey = {
  'Esc': 'Escape',
  'Spacebar': ' ',
  'Left': 'ArrowLeft',
  'Up': 'ArrowUp',
  'Right': 'ArrowRight',
  'Down': 'ArrowDown',
  'Del': 'Delete',
  'Win': 'OS',
  'Menu': 'ContextMenu',
  'Apps': 'ContextMenu',
  'Scroll': 'ScrollLock',
  'MozPrintableKey': 'Unidentified'
};

/**
 * Translation from legacy `keyCode` to HTML5 `key`
 * Only special keys supported, all others depend on keyboard layout or browser
 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
 */
var translateToKey = {
  8: 'Backspace',
  9: 'Tab',
  12: 'Clear',
  13: 'Enter',
  16: 'Shift',
  17: 'Control',
  18: 'Alt',
  19: 'Pause',
  20: 'CapsLock',
  27: 'Escape',
  32: ' ',
  33: 'PageUp',
  34: 'PageDown',
  35: 'End',
  36: 'Home',
  37: 'ArrowLeft',
  38: 'ArrowUp',
  39: 'ArrowRight',
  40: 'ArrowDown',
  45: 'Insert',
  46: 'Delete',
  112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6',
  118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',
  144: 'NumLock',
  145: 'ScrollLock',
  224: 'Meta'
};

/**
 * @param {object} nativeEvent Native browser event.
 * @return {string} Normalized `key` property.
 */
function getEventKey(nativeEvent) {
  if (nativeEvent.key) {
    // Normalize inconsistent values reported by browsers due to
    // implementations of a working draft specification.

    // FireFox implements `key` but returns `MozPrintableKey` for all
    // printable characters (normalized to `Unidentified`), ignore it.
    var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
    if (key !== 'Unidentified') {
      return key;
    }
  }

  // Browser does not implement `key`, polyfill as much of it as we can.
  if (nativeEvent.type === 'keypress') {
    var charCode = getEventCharCode(nativeEvent);

    // The enter-key is technically both printable and non-printable and can
    // thus be captured by `keypress`, no other non-printable key should.
    return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
  }
  if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
    // While user keyboard layout determines the actual meaning of each
    // `keyCode` value, almost all function keys have a universal value.
    return translateToKey[nativeEvent.keyCode] || 'Unidentified';
  }
  return '';
}

module.exports = getEventKey;
},{"./getEventCharCode":507}],509:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getEventModifierState
 * @typechecks static-only
 */

'use strict';

/**
 * Translation from modifier key to the associated property in the event.
 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
 */

var modifierKeyToProp = {
  'Alt': 'altKey',
  'Control': 'ctrlKey',
  'Meta': 'metaKey',
  'Shift': 'shiftKey'
};

// IE8 does not implement getModifierState so we simply map it to the only
// modifier keys exposed by the event itself, does not support Lock-keys.
// Currently, all major browsers except Chrome seems to support Lock-keys.
function modifierStateGetter(keyArg) {
  var syntheticEvent = this;
  var nativeEvent = syntheticEvent.nativeEvent;
  if (nativeEvent.getModifierState) {
    return nativeEvent.getModifierState(keyArg);
  }
  var keyProp = modifierKeyToProp[keyArg];
  return keyProp ? !!nativeEvent[keyProp] : false;
}

function getEventModifierState(nativeEvent) {
  return modifierStateGetter;
}

module.exports = getEventModifierState;
},{}],510:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getEventTarget
 * @typechecks static-only
 */

'use strict';

/**
 * Gets the target node from a native browser event by accounting for
 * inconsistencies in browser DOM APIs.
 *
 * @param {object} nativeEvent Native browser event.
 * @return {DOMEventTarget} Target node.
 */
function getEventTarget(nativeEvent) {
  var target = nativeEvent.target || nativeEvent.srcElement || window;
  // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
  // @see http://www.quirksmode.org/js/events_properties.html
  return target.nodeType === 3 ? target.parentNode : target;
}

module.exports = getEventTarget;
},{}],511:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getIteratorFn
 * @typechecks static-only
 */

'use strict';

/* global Symbol */
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.

/**
 * Returns the iterator method function contained on the iterable object.
 *
 * Be sure to invoke the function with the iterable as context:
 *
 *     var iteratorFn = getIteratorFn(myIterable);
 *     if (iteratorFn) {
 *       var iterator = iteratorFn.call(myIterable);
 *       ...
 *     }
 *
 * @param {?object} maybeIterable
 * @return {?function}
 */
function getIteratorFn(maybeIterable) {
  var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
  if (typeof iteratorFn === 'function') {
    return iteratorFn;
  }
}

module.exports = getIteratorFn;
},{}],512:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getNodeForCharacterOffset
 */

'use strict';

/**
 * Given any node return the first leaf node without children.
 *
 * @param {DOMElement|DOMTextNode} node
 * @return {DOMElement|DOMTextNode}
 */
function getLeafNode(node) {
  while (node && node.firstChild) {
    node = node.firstChild;
  }
  return node;
}

/**
 * Get the next sibling within a container. This will walk up the
 * DOM if a node's siblings have been exhausted.
 *
 * @param {DOMElement|DOMTextNode} node
 * @return {?DOMElement|DOMTextNode}
 */
function getSiblingNode(node) {
  while (node) {
    if (node.nextSibling) {
      return node.nextSibling;
    }
    node = node.parentNode;
  }
}

/**
 * Get object describing the nodes which contain characters at offset.
 *
 * @param {DOMElement|DOMTextNode} root
 * @param {number} offset
 * @return {?object}
 */
function getNodeForCharacterOffset(root, offset) {
  var node = getLeafNode(root);
  var nodeStart = 0;
  var nodeEnd = 0;

  while (node) {
    if (node.nodeType === 3) {
      nodeEnd = nodeStart + node.textContent.length;

      if (nodeStart <= offset && nodeEnd >= offset) {
        return {
          node: node,
          offset: offset - nodeStart
        };
      }

      nodeStart = nodeEnd;
    }

    node = getLeafNode(getSiblingNode(node));
  }
}

module.exports = getNodeForCharacterOffset;
},{}],513:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule getTextContentAccessor
 */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var contentKey = null;

/**
 * Gets the key used to access text content on a DOM node.
 *
 * @return {?string} Key used to access text content.
 * @internal
 */
function getTextContentAccessor() {
  if (!contentKey && ExecutionEnvironment.canUseDOM) {
    // Prefer textContent to innerText because many browsers support both but
    // SVG <text> elements don't support innerText even when <div> does.
    contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
  }
  return contentKey;
}

module.exports = getTextContentAccessor;
},{"fbjs/lib/ExecutionEnvironment":304}],514:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule instantiateReactComponent
 * @typechecks static-only
 */

'use strict';

var ReactCompositeComponent = require('./ReactCompositeComponent');
var ReactEmptyComponent = require('./ReactEmptyComponent');
var ReactNativeComponent = require('./ReactNativeComponent');

var assign = require('./Object.assign');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

// To avoid a cyclic dependency, we create the final class in this module
var ReactCompositeComponentWrapper = function () {};
assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent.Mixin, {
  _instantiateReactComponent: instantiateReactComponent
});

function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

/**
 * Check if the type reference is a known internal type. I.e. not a user
 * provided composite type.
 *
 * @param {function} type
 * @return {boolean} Returns true if this is a valid internal type.
 */
function isInternalComponentType(type) {
  return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function';
}

/**
 * Given a ReactNode, create an instance that will actually be mounted.
 *
 * @param {ReactNode} node
 * @return {object} A new instance of the element's constructor.
 * @protected
 */
function instantiateReactComponent(node) {
  var instance;

  if (node === null || node === false) {
    instance = new ReactEmptyComponent(instantiateReactComponent);
  } else if (typeof node === 'object') {
    var element = node;
    !(element && (typeof element.type === 'function' || typeof element.type === 'string')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) ' + 'or a class/function (for composite components) but got: %s.%s', element.type == null ? element.type : typeof element.type, getDeclarationErrorAddendum(element._owner)) : invariant(false) : undefined;

    // Special case string values
    if (typeof element.type === 'string') {
      instance = ReactNativeComponent.createInternalComponent(element);
    } else if (isInternalComponentType(element.type)) {
      // This is temporarily available for custom components that are not string
      // representations. I.e. ART. Once those are updated to use the string
      // representation, we can drop this code path.
      instance = new element.type(element);
    } else {
      instance = new ReactCompositeComponentWrapper();
    }
  } else if (typeof node === 'string' || typeof node === 'number') {
    instance = ReactNativeComponent.createInstanceForText(node);
  } else {
    !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : invariant(false) : undefined;
  }

  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(typeof instance.construct === 'function' && typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : undefined;
  }

  // Sets up the instance. This can probably just move into the constructor now.
  instance.construct(node);

  // These two fields are used by the DOM and ART diffing algorithms
  // respectively. Instead of using expandos on components, we should be
  // storing the state needed by the diffing algorithms elsewhere.
  instance._mountIndex = 0;
  instance._mountImage = null;

  if (process.env.NODE_ENV !== 'production') {
    instance._isOwnerNecessary = false;
    instance._warnedAboutRefsInRender = false;
  }

  // Internal instances should fully constructed at this point, so they should
  // not get any new fields added to them at this point.
  if (process.env.NODE_ENV !== 'production') {
    if (Object.preventExtensions) {
      Object.preventExtensions(instance);
    }
  }

  return instance;
}

module.exports = instantiateReactComponent;
}).call(this,require('_process'))

},{"./Object.assign":418,"./ReactCompositeComponent":429,"./ReactEmptyComponent":450,"./ReactNativeComponent":464,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],515:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule isEventSupported
 */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var useHasFeature;
if (ExecutionEnvironment.canUseDOM) {
  useHasFeature = document.implementation && document.implementation.hasFeature &&
  // always returns true in newer browsers as per the standard.
  // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
  document.implementation.hasFeature('', '') !== true;
}

/**
 * Checks if an event is supported in the current execution environment.
 *
 * NOTE: This will not work correctly for non-generic events such as `change`,
 * `reset`, `load`, `error`, and `select`.
 *
 * Borrows from Modernizr.
 *
 * @param {string} eventNameSuffix Event name, e.g. "click".
 * @param {?boolean} capture Check if the capture phase is supported.
 * @return {boolean} True if the event is supported.
 * @internal
 * @license Modernizr 3.0.0pre (Custom Build) | MIT
 */
function isEventSupported(eventNameSuffix, capture) {
  if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) {
    return false;
  }

  var eventName = 'on' + eventNameSuffix;
  var isSupported = (eventName in document);

  if (!isSupported) {
    var element = document.createElement('div');
    element.setAttribute(eventName, 'return;');
    isSupported = typeof element[eventName] === 'function';
  }

  if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
    // This is the only way to test support for the `wheel` event in IE9+.
    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
  }

  return isSupported;
}

module.exports = isEventSupported;
},{"fbjs/lib/ExecutionEnvironment":304}],516:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule isTextInputElement
 */

'use strict';

/**
 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
 */
var supportedInputTypes = {
  'color': true,
  'date': true,
  'datetime': true,
  'datetime-local': true,
  'email': true,
  'month': true,
  'number': true,
  'password': true,
  'range': true,
  'search': true,
  'tel': true,
  'text': true,
  'time': true,
  'url': true,
  'week': true
};

function isTextInputElement(elem) {
  var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
  return nodeName && (nodeName === 'input' && supportedInputTypes[elem.type] || nodeName === 'textarea');
}

module.exports = isTextInputElement;
},{}],517:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule onlyChild
 */
'use strict';

var ReactElement = require('./ReactElement');

var invariant = require('fbjs/lib/invariant');

/**
 * Returns the first child in a collection of children and verifies that there
 * is only one child in the collection. The current implementation of this
 * function assumes that a single child gets passed without a wrapper, but the
 * purpose of this helper function is to abstract away the particular structure
 * of children.
 *
 * @param {?object} children Child collection structure.
 * @return {ReactComponent} The first and only `ReactComponent` contained in the
 * structure.
 */
function onlyChild(children) {
  !ReactElement.isValidElement(children) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'onlyChild must be passed a children with exactly one child.') : invariant(false) : undefined;
  return children;
}

module.exports = onlyChild;
}).call(this,require('_process'))

},{"./ReactElement":448,"_process":334,"fbjs/lib/invariant":318}],518:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule quoteAttributeValueForBrowser
 */

'use strict';

var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');

/**
 * Escapes attribute value to prevent scripting attacks.
 *
 * @param {*} value Value to escape.
 * @return {string} An escaped string.
 */
function quoteAttributeValueForBrowser(value) {
  return '"' + escapeTextContentForBrowser(value) + '"';
}

module.exports = quoteAttributeValueForBrowser;
},{"./escapeTextContentForBrowser":503}],519:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
* @providesModule renderSubtreeIntoContainer
*/

'use strict';

var ReactMount = require('./ReactMount');

module.exports = ReactMount.renderSubtreeIntoContainer;
},{"./ReactMount":461}],520:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule setInnerHTML
 */

/* globals MSApp */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');

var WHITESPACE_TEST = /^[ \r\n\t\f]/;
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/;

/**
 * Set the innerHTML property of a node, ensuring that whitespace is preserved
 * even in IE8.
 *
 * @param {DOMElement} node
 * @param {string} html
 * @internal
 */
var setInnerHTML = function (node, html) {
  node.innerHTML = html;
};

// Win8 apps: Allow all html to be inserted
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
  setInnerHTML = function (node, html) {
    MSApp.execUnsafeLocalFunction(function () {
      node.innerHTML = html;
    });
  };
}

if (ExecutionEnvironment.canUseDOM) {
  // IE8: When updating a just created node with innerHTML only leading
  // whitespace is removed. When updating an existing node with innerHTML
  // whitespace in root TextNodes is also collapsed.
  // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html

  // Feature detection; only IE8 is known to behave improperly like this.
  var testElement = document.createElement('div');
  testElement.innerHTML = ' ';
  if (testElement.innerHTML === '') {
    setInnerHTML = function (node, html) {
      // Magic theory: IE8 supposedly differentiates between added and updated
      // nodes when processing innerHTML, innerHTML on updated nodes suffers
      // from worse whitespace behavior. Re-adding a node like this triggers
      // the initial and more favorable whitespace behavior.
      // TODO: What to do on a detached node?
      if (node.parentNode) {
        node.parentNode.replaceChild(node, node);
      }

      // We also implement a workaround for non-visible tags disappearing into
      // thin air on IE8, this only happens if there is no visible text
      // in-front of the non-visible tags. Piggyback on the whitespace fix
      // and simply check if any non-visible tags appear in the source.
      if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) {
        // Recover leading whitespace by temporarily prepending any character.
        // \uFEFF has the potential advantage of being zero-width/invisible.
        // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode
        // in hopes that this is preserved even if "\uFEFF" is transformed to
        // the actual Unicode character (by Babel, for example).
        // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216
        node.innerHTML = String.fromCharCode(0xFEFF) + html;

        // deleteData leaves an empty `TextNode` which offsets the index of all
        // children. Definitely want to avoid this.
        var textNode = node.firstChild;
        if (textNode.data.length === 1) {
          node.removeChild(textNode);
        } else {
          textNode.deleteData(0, 1);
        }
      } else {
        node.innerHTML = html;
      }
    };
  }
}

module.exports = setInnerHTML;
},{"fbjs/lib/ExecutionEnvironment":304}],521:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule setTextContent
 */

'use strict';

var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
var setInnerHTML = require('./setInnerHTML');

/**
 * Set the textContent property of a node, ensuring that whitespace is preserved
 * even in IE8. innerText is a poor substitute for textContent and, among many
 * issues, inserts <br> instead of the literal newline chars. innerHTML behaves
 * as it should.
 *
 * @param {DOMElement} node
 * @param {string} text
 * @internal
 */
var setTextContent = function (node, text) {
  node.textContent = text;
};

if (ExecutionEnvironment.canUseDOM) {
  if (!('textContent' in document.documentElement)) {
    setTextContent = function (node, text) {
      setInnerHTML(node, escapeTextContentForBrowser(text));
    };
  }
}

module.exports = setTextContent;
},{"./escapeTextContentForBrowser":503,"./setInnerHTML":520,"fbjs/lib/ExecutionEnvironment":304}],522:[function(require,module,exports){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule shouldUpdateReactComponent
 * @typechecks static-only
 */

'use strict';

/**
 * Given a `prevElement` and `nextElement`, determines if the existing
 * instance should be updated as opposed to being destroyed or replaced by a new
 * instance. Both arguments are elements. This ensures that this logic can
 * operate on stateless trees without any backing instance.
 *
 * @param {?object} prevElement
 * @param {?object} nextElement
 * @return {boolean} True if the existing instance should be updated.
 * @protected
 */
function shouldUpdateReactComponent(prevElement, nextElement) {
  var prevEmpty = prevElement === null || prevElement === false;
  var nextEmpty = nextElement === null || nextElement === false;
  if (prevEmpty || nextEmpty) {
    return prevEmpty === nextEmpty;
  }

  var prevType = typeof prevElement;
  var nextType = typeof nextElement;
  if (prevType === 'string' || prevType === 'number') {
    return nextType === 'string' || nextType === 'number';
  } else {
    return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key;
  }
  return false;
}

module.exports = shouldUpdateReactComponent;
},{}],523:[function(require,module,exports){
(function (process){
/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule traverseAllChildren
 */

'use strict';

var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactElement = require('./ReactElement');
var ReactInstanceHandles = require('./ReactInstanceHandles');

var getIteratorFn = require('./getIteratorFn');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

var SEPARATOR = ReactInstanceHandles.SEPARATOR;
var SUBSEPARATOR = ':';

/**
 * TODO: Test that a single child and an array with one item have the same key
 * pattern.
 */

var userProvidedKeyEscaperLookup = {
  '=': '=0',
  '.': '=1',
  ':': '=2'
};

var userProvidedKeyEscapeRegex = /[=.:]/g;

var didWarnAboutMaps = false;

function userProvidedKeyEscaper(match) {
  return userProvidedKeyEscaperLookup[match];
}

/**
 * Generate a key string that identifies a component within a set.
 *
 * @param {*} component A component that could contain a manual key.
 * @param {number} index Index that is used if a manual key is not provided.
 * @return {string}
 */
function getComponentKey(component, index) {
  if (component && component.key != null) {
    // Explicit key
    return wrapUserProvidedKey(component.key);
  }
  // Implicit key determined by the index in the set
  return index.toString(36);
}

/**
 * Escape a component key so that it is safe to use in a reactid.
 *
 * @param {*} text Component key to be escaped.
 * @return {string} An escaped string.
 */
function escapeUserProvidedKey(text) {
  return ('' + text).replace(userProvidedKeyEscapeRegex, userProvidedKeyEscaper);
}

/**
 * Wrap a `key` value explicitly provided by the user to distinguish it from
 * implicitly-generated keys generated by a component's index in its parent.
 *
 * @param {string} key Value of a user-provided `key` attribute
 * @return {string}
 */
function wrapUserProvidedKey(key) {
  return '$' + escapeUserProvidedKey(key);
}

/**
 * @param {?*} children Children tree container.
 * @param {!string} nameSoFar Name of the key path so far.
 * @param {!function} callback Callback to invoke with each child found.
 * @param {?*} traverseContext Used to pass information throughout the traversal
 * process.
 * @return {!number} The number of children in this subtree.
 */
function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
  var type = typeof children;

  if (type === 'undefined' || type === 'boolean') {
    // All of the above are perceived as null.
    children = null;
  }

  if (children === null || type === 'string' || type === 'number' || ReactElement.isValidElement(children)) {
    callback(traverseContext, children,
    // If it's the only child, treat the name as if it was wrapped in an array
    // so that it's consistent if the number of children grows.
    nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
    return 1;
  }

  var child;
  var nextName;
  var subtreeCount = 0; // Count of children found in the current subtree.
  var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;

  if (Array.isArray(children)) {
    for (var i = 0; i < children.length; i++) {
      child = children[i];
      nextName = nextNamePrefix + getComponentKey(child, i);
      subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
    }
  } else {
    var iteratorFn = getIteratorFn(children);
    if (iteratorFn) {
      var iterator = iteratorFn.call(children);
      var step;
      if (iteratorFn !== children.entries) {
        var ii = 0;
        while (!(step = iterator.next()).done) {
          child = step.value;
          nextName = nextNamePrefix + getComponentKey(child, ii++);
          subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
        }
      } else {
        if (process.env.NODE_ENV !== 'production') {
          process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.') : undefined;
          didWarnAboutMaps = true;
        }
        // Iterator will provide entry [k,v] tuples rather than values.
        while (!(step = iterator.next()).done) {
          var entry = step.value;
          if (entry) {
            child = entry[1];
            nextName = nextNamePrefix + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);
            subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
          }
        }
      }
    } else if (type === 'object') {
      var addendum = '';
      if (process.env.NODE_ENV !== 'production') {
        addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.';
        if (children._isReactElement) {
          addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.';
        }
        if (ReactCurrentOwner.current) {
          var name = ReactCurrentOwner.current.getName();
          if (name) {
            addendum += ' Check the render method of `' + name + '`.';
          }
        }
      }
      var childrenString = String(children);
      !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : invariant(false) : undefined;
    }
  }

  return subtreeCount;
}

/**
 * Traverses children that are typically specified as `props.children`, but
 * might also be specified through attributes:
 *
 * - `traverseAllChildren(this.props.children, ...)`
 * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
 *
 * The `traverseContext` is an optional argument that is passed through the
 * entire traversal. It can be used to store accumulations or anything else that
 * the callback might find relevant.
 *
 * @param {?*} children Children tree object.
 * @param {!function} callback To invoke upon traversing each child.
 * @param {?*} traverseContext Context for traversal.
 * @return {!number} The number of children in this subtree.
 */
function traverseAllChildren(children, callback, traverseContext) {
  if (children == null) {
    return 0;
  }

  return traverseAllChildrenImpl(children, '', callback, traverseContext);
}

module.exports = traverseAllChildren;
}).call(this,require('_process'))

},{"./ReactCurrentOwner":430,"./ReactElement":448,"./ReactInstanceHandles":457,"./getIteratorFn":511,"_process":334,"fbjs/lib/invariant":318,"fbjs/lib/warning":329}],524:[function(require,module,exports){
(function (process){
/**
 * Copyright 2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule validateDOMNesting
 */

'use strict';

var assign = require('./Object.assign');
var emptyFunction = require('fbjs/lib/emptyFunction');
var warning = require('fbjs/lib/warning');

var validateDOMNesting = emptyFunction;

if (process.env.NODE_ENV !== 'production') {
  // This validation code was written based on the HTML5 parsing spec:
  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
  //
  // Note: this does not catch all invalid nesting, nor does it try to (as it's
  // not clear what practical benefit doing so provides); instead, we warn only
  // for cases where the parser will give a parse tree differing from what React
  // intended. For example, <b><div></div></b> is invalid but we don't warn
  // because it still parses correctly; we do warn for other cases like nested
  // <p> tags where the beginning of the second element implicitly closes the
  // first, causing a confusing mess.

  // https://html.spec.whatwg.org/multipage/syntax.html#special
  var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];

  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
  var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',

  // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
  // TODO: Distinguish by namespace here -- for <title>, including it here
  // errs on the side of fewer warnings
  'foreignObject', 'desc', 'title'];

  // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
  var buttonScopeTags = inScopeTags.concat(['button']);

  // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
  var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];

  var emptyAncestorInfo = {
    parentTag: null,

    formTag: null,
    aTagInScope: null,
    buttonTagInScope: null,
    nobrTagInScope: null,
    pTagInButtonScope: null,

    listItemTagAutoclosing: null,
    dlItemTagAutoclosing: null
  };

  var updatedAncestorInfo = function (oldInfo, tag, instance) {
    var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
    var info = { tag: tag, instance: instance };

    if (inScopeTags.indexOf(tag) !== -1) {
      ancestorInfo.aTagInScope = null;
      ancestorInfo.buttonTagInScope = null;
      ancestorInfo.nobrTagInScope = null;
    }
    if (buttonScopeTags.indexOf(tag) !== -1) {
      ancestorInfo.pTagInButtonScope = null;
    }

    // See rules for 'li', 'dd', 'dt' start tags in
    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
    if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
      ancestorInfo.listItemTagAutoclosing = null;
      ancestorInfo.dlItemTagAutoclosing = null;
    }

    ancestorInfo.parentTag = info;

    if (tag === 'form') {
      ancestorInfo.formTag = info;
    }
    if (tag === 'a') {
      ancestorInfo.aTagInScope = info;
    }
    if (tag === 'button') {
      ancestorInfo.buttonTagInScope = info;
    }
    if (tag === 'nobr') {
      ancestorInfo.nobrTagInScope = info;
    }
    if (tag === 'p') {
      ancestorInfo.pTagInButtonScope = info;
    }
    if (tag === 'li') {
      ancestorInfo.listItemTagAutoclosing = info;
    }
    if (tag === 'dd' || tag === 'dt') {
      ancestorInfo.dlItemTagAutoclosing = info;
    }

    return ancestorInfo;
  };

  /**
   * Returns whether
   */
  var isTagValidWithParent = function (tag, parentTag) {
    // First, let's check if we're in an unusual parsing mode...
    switch (parentTag) {
      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
      case 'select':
        return tag === 'option' || tag === 'optgroup' || tag === '#text';
      case 'optgroup':
        return tag === 'option' || tag === '#text';
      // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
      // but
      case 'option':
        return tag === '#text';

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
      // No special behavior since these rules fall back to "in body" mode for
      // all except special table nodes which cause bad parsing behavior anyway.

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
      case 'tr':
        return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
      case 'tbody':
      case 'thead':
      case 'tfoot':
        return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
      case 'colgroup':
        return tag === 'col' || tag === 'template';

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
      case 'table':
        return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';

      // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
      case 'head':
        return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';

      // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
      case 'html':
        return tag === 'head' || tag === 'body';
    }

    // Probably in the "in body" parsing mode, so we outlaw only tag combos
    // where the parsing rules cause implicit opens or closes to be added.
    // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
    switch (tag) {
      case 'h1':
      case 'h2':
      case 'h3':
      case 'h4':
      case 'h5':
      case 'h6':
        return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';

      case 'rp':
      case 'rt':
        return impliedEndTags.indexOf(parentTag) === -1;

      case 'caption':
      case 'col':
      case 'colgroup':
      case 'frame':
      case 'head':
      case 'tbody':
      case 'td':
      case 'tfoot':
      case 'th':
      case 'thead':
      case 'tr':
        // These tags are only valid with a few parents that have special child
        // parsing rules -- if we're down here, then none of those matched and
        // so we allow it only if we don't know what the parent is, as all other
        // cases are invalid.
        return parentTag == null;
    }

    return true;
  };

  /**
   * Returns whether
   */
  var findInvalidAncestorForTag = function (tag, ancestorInfo) {
    switch (tag) {
      case 'address':
      case 'article':
      case 'aside':
      case 'blockquote':
      case 'center':
      case 'details':
      case 'dialog':
      case 'dir':
      case 'div':
      case 'dl':
      case 'fieldset':
      case 'figcaption':
      case 'figure':
      case 'footer':
      case 'header':
      case 'hgroup':
      case 'main':
      case 'menu':
      case 'nav':
      case 'ol':
      case 'p':
      case 'section':
      case 'summary':
      case 'ul':

      case 'pre':
      case 'listing':

      case 'table':

      case 'hr':

      case 'xmp':

      case 'h1':
      case 'h2':
      case 'h3':
      case 'h4':
      case 'h5':
      case 'h6':
        return ancestorInfo.pTagInButtonScope;

      case 'form':
        return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;

      case 'li':
        return ancestorInfo.listItemTagAutoclosing;

      case 'dd':
      case 'dt':
        return ancestorInfo.dlItemTagAutoclosing;

      case 'button':
        return ancestorInfo.buttonTagInScope;

      case 'a':
        // Spec says something about storing a list of markers, but it sounds
        // equivalent to this check.
        return ancestorInfo.aTagInScope;

      case 'nobr':
        return ancestorInfo.nobrTagInScope;
    }

    return null;
  };

  /**
   * Given a ReactCompositeComponent instance, return a list of its recursive
   * owners, starting at the root and ending with the instance itself.
   */
  var findOwnerStack = function (instance) {
    if (!instance) {
      return [];
    }

    var stack = [];
    /*eslint-disable space-after-keywords */
    do {
      /*eslint-enable space-after-keywords */
      stack.push(instance);
    } while (instance = instance._currentElement._owner);
    stack.reverse();
    return stack;
  };

  var didWarn = {};

  validateDOMNesting = function (childTag, childInstance, ancestorInfo) {
    ancestorInfo = ancestorInfo || emptyAncestorInfo;
    var parentInfo = ancestorInfo.parentTag;
    var parentTag = parentInfo && parentInfo.tag;

    var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
    var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
    var problematic = invalidParent || invalidAncestor;

    if (problematic) {
      var ancestorTag = problematic.tag;
      var ancestorInstance = problematic.instance;

      var childOwner = childInstance && childInstance._currentElement._owner;
      var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner;

      var childOwners = findOwnerStack(childOwner);
      var ancestorOwners = findOwnerStack(ancestorOwner);

      var minStackLen = Math.min(childOwners.length, ancestorOwners.length);
      var i;

      var deepestCommon = -1;
      for (i = 0; i < minStackLen; i++) {
        if (childOwners[i] === ancestorOwners[i]) {
          deepestCommon = i;
        } else {
          break;
        }
      }

      var UNKNOWN = '(unknown)';
      var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) {
        return inst.getName() || UNKNOWN;
      });
      var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {
        return inst.getName() || UNKNOWN;
      });
      var ownerInfo = [].concat(
      // If the parent and child instances have a common owner ancestor, start
      // with that -- otherwise we just start with the parent's owners.
      deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag,
      // If we're warning about an invalid (non-parent) ancestry, add '...'
      invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > ');

      var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo;
      if (didWarn[warnKey]) {
        return;
      }
      didWarn[warnKey] = true;

      if (invalidParent) {
        var info = '';
        if (ancestorTag === 'table' && childTag === 'tr') {
          info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
        }
        process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a child of <%s>. ' + 'See %s.%s', childTag, ancestorTag, ownerInfo, info) : undefined;
      } else {
        process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a descendant of ' + '<%s>. See %s.', childTag, ancestorTag, ownerInfo) : undefined;
      }
    }
  };

  validateDOMNesting.ancestorInfoContextKey = '__validateDOMNesting_ancestorInfo$' + Math.random().toString(36).slice(2);

  validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;

  // For testing
  validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) {
    ancestorInfo = ancestorInfo || emptyAncestorInfo;
    var parentInfo = ancestorInfo.parentTag;
    var parentTag = parentInfo && parentInfo.tag;
    return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo);
  };
}

module.exports = validateDOMNesting;
}).call(this,require('_process'))

},{"./Object.assign":418,"_process":334,"fbjs/lib/emptyFunction":310,"fbjs/lib/warning":329}],525:[function(require,module,exports){
'use strict';

module.exports = require('./lib/React');

},{"./lib/React":420}],526:[function(require,module,exports){

/**
 * Reduce `arr` with `fn`.
 *
 * @param {Array} arr
 * @param {Function} fn
 * @param {Mixed} initial
 *
 * TODO: combatible error handling?
 */

module.exports = function(arr, fn, initial){  
  var idx = 0;
  var len = arr.length;
  var curr = arguments.length == 3
    ? initial
    : arr[idx++];

  while (idx < len) {
    curr = fn.call(null, curr, arr[idx], ++idx, arr);
  }
  
  return curr;
};
},{}],527:[function(require,module,exports){
/**
 * A module of methods that you want to include in all actions.
 * This module is consumed by `createAction`.
 */
"use strict";

module.exports = {};
},{}],528:[function(require,module,exports){
"use strict";

exports.createdStores = [];

exports.createdActions = [];

exports.reset = function () {
    while (exports.createdStores.length) {
        exports.createdStores.pop();
    }
    while (exports.createdActions.length) {
        exports.createdActions.pop();
    }
};
},{}],529:[function(require,module,exports){
"use strict";

var _ = require("./utils"),
    maker = require("./joins").instanceJoinCreator;

/**
 * Extract child listenables from a parent from their
 * children property and return them in a keyed Object
 *
 * @param {Object} listenable The parent listenable
 */
var mapChildListenables = function mapChildListenables(listenable) {
    var i = 0,
        children = {},
        childName;
    for (; i < (listenable.children || []).length; ++i) {
        childName = listenable.children[i];
        if (listenable[childName]) {
            children[childName] = listenable[childName];
        }
    }
    return children;
};

/**
 * Make a flat dictionary of all listenables including their
 * possible children (recursively), concatenating names in camelCase.
 *
 * @param {Object} listenables The top-level listenables
 */
var flattenListenables = function flattenListenables(listenables) {
    var flattened = {};
    for (var key in listenables) {
        var listenable = listenables[key];
        var childMap = mapChildListenables(listenable);

        // recursively flatten children
        var children = flattenListenables(childMap);

        // add the primary listenable and chilren
        flattened[key] = listenable;
        for (var childKey in children) {
            var childListenable = children[childKey];
            flattened[key + _.capitalize(childKey)] = childListenable;
        }
    }

    return flattened;
};

/**
 * A module of methods related to listening.
 */
module.exports = {

    /**
     * An internal utility function used by `validateListening`
     *
     * @param {Action|Store} listenable The listenable we want to search for
     * @returns {Boolean} The result of a recursive search among `this.subscriptions`
     */
    hasListener: function hasListener(listenable) {
        var i = 0,
            j,
            listener,
            listenables;
        for (; i < (this.subscriptions || []).length; ++i) {
            listenables = [].concat(this.subscriptions[i].listenable);
            for (j = 0; j < listenables.length; j++) {
                listener = listenables[j];
                if (listener === listenable || listener.hasListener && listener.hasListener(listenable)) {
                    return true;
                }
            }
        }
        return false;
    },

    /**
     * A convenience method that listens to all listenables in the given object.
     *
     * @param {Object} listenables An object of listenables. Keys will be used as callback method names.
     */
    listenToMany: function listenToMany(listenables) {
        var allListenables = flattenListenables(listenables);
        for (var key in allListenables) {
            var cbname = _.callbackName(key),
                localname = this[cbname] ? cbname : this[key] ? key : undefined;
            if (localname) {
                this.listenTo(allListenables[key], localname, this[cbname + "Default"] || this[localname + "Default"] || localname);
            }
        }
    },

    /**
     * Checks if the current context can listen to the supplied listenable
     *
     * @param {Action|Store} listenable An Action or Store that should be
     *  listened to.
     * @returns {String|Undefined} An error message, or undefined if there was no problem.
     */
    validateListening: function validateListening(listenable) {
        if (listenable === this) {
            return "Listener is not able to listen to itself";
        }
        if (!_.isFunction(listenable.listen)) {
            return listenable + " is missing a listen method";
        }
        if (listenable.hasListener && listenable.hasListener(this)) {
            return "Listener cannot listen to this listenable because of circular loop";
        }
    },

    /**
     * Sets up a subscription to the given listenable for the context object
     *
     * @param {Action|Store} listenable An Action or Store that should be
     *  listened to.
     * @param {Function|String} callback The callback to register as event handler
     * @param {Function|String} defaultCallback The callback to register as default handler
     * @returns {Object} A subscription obj where `stop` is an unsub function and `listenable` is the object being listened to
     */
    listenTo: function listenTo(listenable, callback, defaultCallback) {
        var desub,
            unsubscriber,
            subscriptionobj,
            subs = this.subscriptions = this.subscriptions || [];
        _.throwIf(this.validateListening(listenable));
        this.fetchInitialState(listenable, defaultCallback);
        desub = listenable.listen(this[callback] || callback, this);
        unsubscriber = function () {
            var index = subs.indexOf(subscriptionobj);
            _.throwIf(index === -1, "Tried to remove listen already gone from subscriptions list!");
            subs.splice(index, 1);
            desub();
        };
        subscriptionobj = {
            stop: unsubscriber,
            listenable: listenable
        };
        subs.push(subscriptionobj);
        return subscriptionobj;
    },

    /**
     * Stops listening to a single listenable
     *
     * @param {Action|Store} listenable The action or store we no longer want to listen to
     * @returns {Boolean} True if a subscription was found and removed, otherwise false.
     */
    stopListeningTo: function stopListeningTo(listenable) {
        var sub,
            i = 0,
            subs = this.subscriptions || [];
        for (; i < subs.length; i++) {
            sub = subs[i];
            if (sub.listenable === listenable) {
                sub.stop();
                _.throwIf(subs.indexOf(sub) !== -1, "Failed to remove listen from subscriptions list!");
                return true;
            }
        }
        return false;
    },

    /**
     * Stops all subscriptions and empties subscriptions array
     */
    stopListeningToAll: function stopListeningToAll() {
        var remaining,
            subs = this.subscriptions || [];
        while (remaining = subs.length) {
            subs[0].stop();
            _.throwIf(subs.length !== remaining - 1, "Failed to remove listen from subscriptions list!");
        }
    },

    /**
     * Used in `listenTo`. Fetches initial data from a publisher if it has a `getInitialState` method.
     * @param {Action|Store} listenable The publisher we want to get initial state from
     * @param {Function|String} defaultCallback The method to receive the data
     */
    fetchInitialState: function fetchInitialState(listenable, defaultCallback) {
        defaultCallback = defaultCallback && this[defaultCallback] || defaultCallback;
        var me = this;
        if (_.isFunction(defaultCallback) && _.isFunction(listenable.getInitialState)) {
            var data = listenable.getInitialState();
            if (data && _.isFunction(data.then)) {
                data.then(function () {
                    defaultCallback.apply(me, arguments);
                });
            } else {
                defaultCallback.call(this, data);
            }
        }
    },

    /**
     * The callback will be called once all listenables have triggered at least once.
     * It will be invoked with the last emission from each listenable.
     * @param {...Publishers} publishers Publishers that should be tracked.
     * @param {Function|String} callback The method to call when all publishers have emitted
     * @returns {Object} A subscription obj where `stop` is an unsub function and `listenable` is an array of listenables
     */
    joinTrailing: maker("last"),

    /**
     * The callback will be called once all listenables have triggered at least once.
     * It will be invoked with the first emission from each listenable.
     * @param {...Publishers} publishers Publishers that should be tracked.
     * @param {Function|String} callback The method to call when all publishers have emitted
     * @returns {Object} A subscription obj where `stop` is an unsub function and `listenable` is an array of listenables
     */
    joinLeading: maker("first"),

    /**
     * The callback will be called once all listenables have triggered at least once.
     * It will be invoked with all emission from each listenable.
     * @param {...Publishers} publishers Publishers that should be tracked.
     * @param {Function|String} callback The method to call when all publishers have emitted
     * @returns {Object} A subscription obj where `stop` is an unsub function and `listenable` is an array of listenables
     */
    joinConcat: maker("all"),

    /**
     * The callback will be called once all listenables have triggered.
     * If a callback triggers twice before that happens, an error is thrown.
     * @param {...Publishers} publishers Publishers that should be tracked.
     * @param {Function|String} callback The method to call when all publishers have emitted
     * @returns {Object} A subscription obj where `stop` is an unsub function and `listenable` is an array of listenables
     */
    joinStrict: maker("strict")
};
},{"./joins":536,"./utils":538}],530:[function(require,module,exports){
"use strict";

var _ = require("./utils");

/**
 * A module of methods for object that you want to be able to listen to.
 * This module is consumed by `createStore` and `createAction`
 */
module.exports = {

    /**
     * Hook used by the publisher that is invoked before emitting
     * and before `shouldEmit`. The arguments are the ones that the action
     * is invoked with. If this function returns something other than
     * undefined, that will be passed on as arguments for shouldEmit and
     * emission.
     */
    preEmit: function preEmit() {},

    /**
     * Hook used by the publisher after `preEmit` to determine if the
     * event should be emitted with given arguments. This may be overridden
     * in your application, default implementation always returns true.
     *
     * @returns {Boolean} true if event should be emitted
     */
    shouldEmit: function shouldEmit() {
        return true;
    },

    /**
     * Subscribes the given callback for action triggered
     *
     * @param {Function} callback The callback to register as event handler
     * @param {Mixed} [optional] bindContext The context to bind the callback with
     * @returns {Function} Callback that unsubscribes the registered event handler
     */
    listen: function listen(callback, bindContext) {
        bindContext = bindContext || this;
        var eventHandler = function eventHandler(args) {
            if (aborted) {
                return;
            }
            callback.apply(bindContext, args);
        },
            me = this,
            aborted = false;
        this.emitter.addListener(this.eventLabel, eventHandler);
        return function () {
            aborted = true;
            me.emitter.removeListener(me.eventLabel, eventHandler);
        };
    },

    /**
     * Publishes an event using `this.emitter` (if `shouldEmit` agrees)
     */
    trigger: function trigger() {
        var args = arguments,
            pre = this.preEmit.apply(this, args);
        args = pre === undefined ? args : _.isArguments(pre) ? pre : [].concat(pre);
        if (this.shouldEmit.apply(this, args)) {
            this.emitter.emit(this.eventLabel, args);
        }
    },

    /**
     * Tries to publish the event on the next tick
     */
    triggerAsync: function triggerAsync() {
        var args = arguments,
            me = this;
        _.nextTick(function () {
            me.trigger.apply(me, args);
        });
    },

    /**
     * Wraps the trigger mechanism with a deferral function.
     *
     * @param {Function} callback the deferral function,
     *        first argument is the resolving function and the
     *        rest are the arguments provided from the previous
     *        trigger invocation
     */
    deferWith: function deferWith(callback) {
        var oldTrigger = this.trigger,
            ctx = this,
            resolver = function resolver() {
            oldTrigger.apply(ctx, arguments);
        };
        this.trigger = function () {
            callback.apply(ctx, [resolver].concat([].splice.call(arguments, 0)));
        };
    }

};
},{"./utils":538}],531:[function(require,module,exports){
/**
 * A module of methods that you want to include in all stores.
 * This module is consumed by `createStore`.
 */
"use strict";

module.exports = {};
},{}],532:[function(require,module,exports){
"use strict";

module.exports = function (store, definition) {
    for (var name in definition) {
        if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
            var propertyDescriptor = Object.getOwnPropertyDescriptor(definition, name);

            if (!propertyDescriptor.value || typeof propertyDescriptor.value !== "function" || !definition.hasOwnProperty(name)) {
                continue;
            }

            store[name] = definition[name].bind(store);
        } else {
            var property = definition[name];

            if (typeof property !== "function" || !definition.hasOwnProperty(name)) {
                continue;
            }

            store[name] = property.bind(store);
        }
    }

    return store;
};
},{}],533:[function(require,module,exports){
"use strict";

var _ = require("./utils"),
    ActionMethods = require("./ActionMethods"),
    PublisherMethods = require("./PublisherMethods"),
    Keep = require("./Keep");

var allowed = { preEmit: 1, shouldEmit: 1 };

/**
 * Creates an action functor object. It is mixed in with functions
 * from the `PublisherMethods` mixin. `preEmit` and `shouldEmit` may
 * be overridden in the definition object.
 *
 * @param {Object} definition The action object definition
 */
var createAction = function createAction(definition) {

    definition = definition || {};
    if (!_.isObject(definition)) {
        definition = { actionName: definition };
    }

    for (var a in ActionMethods) {
        if (!allowed[a] && PublisherMethods[a]) {
            throw new Error("Cannot override API method " + a + " in Reflux.ActionMethods. Use another method name or override it on Reflux.PublisherMethods instead.");
        }
    }

    for (var d in definition) {
        if (!allowed[d] && PublisherMethods[d]) {
            throw new Error("Cannot override API method " + d + " in action creation. Use another method name or override it on Reflux.PublisherMethods instead.");
        }
    }

    definition.children = definition.children || [];
    if (definition.asyncResult) {
        definition.children = definition.children.concat(["completed", "failed"]);
    }

    var i = 0,
        childActions = {};
    for (; i < definition.children.length; i++) {
        var name = definition.children[i];
        childActions[name] = createAction(name);
    }

    var context = _.extend({
        eventLabel: "action",
        emitter: new _.EventEmitter(),
        _isAction: true
    }, PublisherMethods, ActionMethods, definition);

    var functor = function functor() {
        var triggerType = functor.sync ? "trigger" : "triggerAsync";
        return functor[triggerType].apply(functor, arguments);
    };

    _.extend(functor, childActions, context);

    Keep.createdActions.push(functor);

    return functor;
};

module.exports = createAction;
},{"./ActionMethods":527,"./Keep":528,"./PublisherMethods":530,"./utils":538}],534:[function(require,module,exports){
"use strict";

var _ = require("./utils"),
    Keep = require("./Keep"),
    mixer = require("./mixer"),
    bindMethods = require("./bindMethods");

var allowed = { preEmit: 1, shouldEmit: 1 };

/**
 * Creates an event emitting Data Store. It is mixed in with functions
 * from the `ListenerMethods` and `PublisherMethods` mixins. `preEmit`
 * and `shouldEmit` may be overridden in the definition object.
 *
 * @param {Object} definition The data store object definition
 * @returns {Store} A data store instance
 */
module.exports = function (definition) {

    var StoreMethods = require("./StoreMethods"),
        PublisherMethods = require("./PublisherMethods"),
        ListenerMethods = require("./ListenerMethods");

    definition = definition || {};

    for (var a in StoreMethods) {
        if (!allowed[a] && (PublisherMethods[a] || ListenerMethods[a])) {
            throw new Error("Cannot override API method " + a + " in Reflux.StoreMethods. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead.");
        }
    }

    for (var d in definition) {
        if (!allowed[d] && (PublisherMethods[d] || ListenerMethods[d])) {
            throw new Error("Cannot override API method " + d + " in store creation. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead.");
        }
    }

    definition = mixer(definition);

    function Store() {
        var i = 0,
            arr;
        this.subscriptions = [];
        this.emitter = new _.EventEmitter();
        this.eventLabel = "change";
        bindMethods(this, definition);
        if (this.init && _.isFunction(this.init)) {
            this.init();
        }
        if (this.listenables) {
            arr = [].concat(this.listenables);
            for (; i < arr.length; i++) {
                this.listenToMany(arr[i]);
            }
        }
    }

    _.extend(Store.prototype, ListenerMethods, PublisherMethods, StoreMethods, definition);

    var store = new Store();
    Keep.createdStores.push(store);

    return store;
};
},{"./Keep":528,"./ListenerMethods":529,"./PublisherMethods":530,"./StoreMethods":531,"./bindMethods":532,"./mixer":537,"./utils":538}],535:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});
var Reflux = {
    version: {
        "reflux-core": "0.3.0"
    }
};

Reflux.ActionMethods = require("./ActionMethods");

Reflux.ListenerMethods = require("./ListenerMethods");

Reflux.PublisherMethods = require("./PublisherMethods");

Reflux.StoreMethods = require("./StoreMethods");

Reflux.createAction = require("./createAction");

Reflux.createStore = require("./createStore");

var maker = require("./joins").staticJoinCreator;

Reflux.joinTrailing = Reflux.all = maker("last"); // Reflux.all alias for backward compatibility

Reflux.joinLeading = maker("first");

Reflux.joinStrict = maker("strict");

Reflux.joinConcat = maker("all");

var _ = Reflux.utils = require("./utils");

Reflux.EventEmitter = _.EventEmitter;

Reflux.Promise = _.Promise;

/**
 * Convenience function for creating a set of actions
 *
 * @param definitions the definitions for the actions to be created
 * @returns an object with actions of corresponding action names
 */
Reflux.createActions = (function () {
    var reducer = function reducer(definitions, actions) {
        Object.keys(definitions).forEach(function (actionName) {
            var val = definitions[actionName];
            actions[actionName] = Reflux.createAction(val);
        });
    };

    return function (definitions) {
        var actions = {};
        if (definitions instanceof Array) {
            definitions.forEach(function (val) {
                if (_.isObject(val)) {
                    reducer(val, actions);
                } else {
                    actions[val] = Reflux.createAction(val);
                }
            });
        } else {
            reducer(definitions, actions);
        }
        return actions;
    };
})();

/**
 * Sets the eventmitter that Reflux uses
 */
Reflux.setEventEmitter = function (ctx) {
    Reflux.EventEmitter = _.EventEmitter = ctx;
};

/**
 * Sets the method used for deferring actions and stores
 */
Reflux.nextTick = function (nextTick) {
    _.nextTick = nextTick;
};

Reflux.use = function (pluginCb) {
    pluginCb(Reflux);
};

/**
 * Provides the set of created actions and stores for introspection
 */
/*eslint-disable no-underscore-dangle*/
Reflux.__keep = require("./Keep");
/*eslint-enable no-underscore-dangle*/

/**
 * Warn if Function.prototype.bind not available
 */
if (!Function.prototype.bind) {
    console.error("Function.prototype.bind not available. " + "ES5 shim required. " + "https://github.com/spoike/refluxjs#es5");
}

exports["default"] = Reflux;
module.exports = exports["default"];
},{"./ActionMethods":527,"./Keep":528,"./ListenerMethods":529,"./PublisherMethods":530,"./StoreMethods":531,"./createAction":533,"./createStore":534,"./joins":536,"./utils":538}],536:[function(require,module,exports){
/**
 * Internal module used to create static and instance join methods
 */

"use strict";

var createStore = require("./createStore"),
    _ = require("./utils");

var slice = Array.prototype.slice,
    strategyMethodNames = {
    strict: "joinStrict",
    first: "joinLeading",
    last: "joinTrailing",
    all: "joinConcat"
};

/**
 * Used in `index.js` to create the static join methods
 * @param {String} strategy Which strategy to use when tracking listenable trigger arguments
 * @returns {Function} A static function which returns a store with a join listen on the given listenables using the given strategy
 */
exports.staticJoinCreator = function (strategy) {
    return function () /* listenables... */{
        var listenables = slice.call(arguments);
        return createStore({
            init: function init() {
                this[strategyMethodNames[strategy]].apply(this, listenables.concat("triggerAsync"));
            }
        });
    };
};

/**
 * Used in `ListenerMethods.js` to create the instance join methods
 * @param {String} strategy Which strategy to use when tracking listenable trigger arguments
 * @returns {Function} An instance method which sets up a join listen on the given listenables using the given strategy
 */
exports.instanceJoinCreator = function (strategy) {
    return function () /* listenables..., callback*/{
        _.throwIf(arguments.length < 2, "Cannot create a join with less than 2 listenables!");
        var listenables = slice.call(arguments),
            callback = listenables.pop(),
            numberOfListenables = listenables.length,
            join = {
            numberOfListenables: numberOfListenables,
            callback: this[callback] || callback,
            listener: this,
            strategy: strategy
        },
            i,
            cancels = [],
            subobj;
        for (i = 0; i < numberOfListenables; i++) {
            _.throwIf(this.validateListening(listenables[i]));
        }
        for (i = 0; i < numberOfListenables; i++) {
            cancels.push(listenables[i].listen(newListener(i, join), this));
        }
        reset(join);
        subobj = { listenable: listenables };
        subobj.stop = makeStopper(subobj, cancels, this);
        this.subscriptions = (this.subscriptions || []).concat(subobj);
        return subobj;
    };
};

// ---- internal join functions ----

function makeStopper(subobj, cancels, context) {
    return function () {
        var i,
            subs = context.subscriptions,
            index = subs ? subs.indexOf(subobj) : -1;
        _.throwIf(index === -1, "Tried to remove join already gone from subscriptions list!");
        for (i = 0; i < cancels.length; i++) {
            cancels[i]();
        }
        subs.splice(index, 1);
    };
}

function reset(join) {
    join.listenablesEmitted = new Array(join.numberOfListenables);
    join.args = new Array(join.numberOfListenables);
}

function newListener(i, join) {
    return function () {
        var callargs = slice.call(arguments);
        if (join.listenablesEmitted[i]) {
            switch (join.strategy) {
                case "strict":
                    throw new Error("Strict join failed because listener triggered twice.");
                case "last":
                    join.args[i] = callargs;break;
                case "all":
                    join.args[i].push(callargs);
            }
        } else {
            join.listenablesEmitted[i] = true;
            join.args[i] = join.strategy === "all" ? [callargs] : callargs;
        }
        emitIfAllListenablesEmitted(join);
    };
}

function emitIfAllListenablesEmitted(join) {
    for (var i = 0; i < join.numberOfListenables; i++) {
        if (!join.listenablesEmitted[i]) {
            return;
        }
    }
    join.callback.apply(join.listener, join.args);
    reset(join);
}
},{"./createStore":534,"./utils":538}],537:[function(require,module,exports){
"use strict";

var _ = require("./utils");

module.exports = function mix(def) {
    var composed = {
        init: [],
        preEmit: [],
        shouldEmit: []
    };

    var updated = (function mixDef(mixin) {
        var mixed = {};
        if (mixin.mixins) {
            mixin.mixins.forEach(function (subMixin) {
                _.extend(mixed, mixDef(subMixin));
            });
        }
        _.extend(mixed, mixin);
        Object.keys(composed).forEach(function (composable) {
            if (mixin.hasOwnProperty(composable)) {
                composed[composable].push(mixin[composable]);
            }
        });
        return mixed;
    })(def);

    if (composed.init.length > 1) {
        updated.init = function () {
            var args = arguments;
            composed.init.forEach(function (init) {
                init.apply(this, args);
            }, this);
        };
    }
    if (composed.preEmit.length > 1) {
        updated.preEmit = function () {
            return composed.preEmit.reduce((function (args, preEmit) {
                var newValue = preEmit.apply(this, args);
                return newValue === undefined ? args : [newValue];
            }).bind(this), arguments);
        };
    }
    if (composed.shouldEmit.length > 1) {
        updated.shouldEmit = function () {
            var args = arguments;
            return !composed.shouldEmit.some(function (shouldEmit) {
                return !shouldEmit.apply(this, args);
            }, this);
        };
    }
    Object.keys(composed).forEach(function (composable) {
        if (composed[composable].length === 1) {
            updated[composable] = composed[composable][0];
        }
    });

    return updated;
};
},{"./utils":538}],538:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.capitalize = capitalize;
exports.callbackName = callbackName;
exports.isObject = isObject;
exports.extend = extend;
exports.isFunction = isFunction;
exports.object = object;
exports.isArguments = isArguments;
exports.throwIf = throwIf;

function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function callbackName(string, prefix) {
    prefix = prefix || "on";
    return prefix + exports.capitalize(string);
}

/*
 * isObject, extend, isFunction, isArguments are taken from undescore/lodash in
 * order to remove the dependency
 */

function isObject(obj) {
    var type = typeof obj;
    return type === "function" || type === "object" && !!obj;
}

function extend(obj) {
    if (!isObject(obj)) {
        return obj;
    }
    var source, prop;
    for (var i = 1, length = arguments.length; i < length; i++) {
        source = arguments[i];
        for (prop in source) {
            if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
                var propertyDescriptor = Object.getOwnPropertyDescriptor(source, prop);
                Object.defineProperty(obj, prop, propertyDescriptor);
            } else {
                obj[prop] = source[prop];
            }
        }
    }
    return obj;
}

function isFunction(value) {
    return typeof value === "function";
}

exports.EventEmitter = require("eventemitter3");

exports.nextTick = function (callback) {
    setTimeout(callback, 0);
};

function object(keys, vals) {
    var o = {},
        i = 0;
    for (; i < keys.length; i++) {
        o[keys[i]] = vals[i];
    }
    return o;
}

function isArguments(value) {
    return typeof value === "object" && "callee" in value && typeof value.length === "number";
}

function throwIf(val, msg) {
    if (val) {
        throw Error(msg || val);
    }
}
},{"eventemitter3":301}],539:[function(require,module,exports){
var _ = require('reflux-core/lib/utils'),
    ListenerMethods = require('reflux-core/lib/ListenerMethods');

/**
 * A module meant to be consumed as a mixin by a React component. Supplies the methods from
 * `ListenerMethods` mixin and takes care of teardown of subscriptions.
 * Note that if you're using the `connect` mixin you don't need this mixin, as connect will
 * import everything this mixin contains!
 */
module.exports = _.extend({

    /**
     * Cleans up all listener previously registered.
     */
    componentWillUnmount: ListenerMethods.stopListeningToAll

}, ListenerMethods);

},{"reflux-core/lib/ListenerMethods":529,"reflux-core/lib/utils":538}],540:[function(require,module,exports){
var ListenerMethods = require('reflux-core/lib/ListenerMethods'),
    ListenerMixin = require('./ListenerMixin'),
    _ = require('reflux-core/lib/utils');

module.exports = function(listenable,key){
    return {
        getInitialState: function(){
            if (!_.isFunction(listenable.getInitialState)) {
                return {};
            } else if (key === undefined) {
                return listenable.getInitialState();
            } else {
                return _.object([key],[listenable.getInitialState()]);
            }
        },
        componentDidMount: function(){
            _.extend(this,ListenerMethods);
            var me = this, cb = (key === undefined ? this.setState : function(v){
                if (typeof me.isMounted === "undefined" || me.isMounted() === true) {
                    me.setState(_.object([key],[v]));
                }
            });
            this.listenTo(listenable,cb);
        },
        componentWillUnmount: ListenerMixin.componentWillUnmount
    };
};

},{"./ListenerMixin":539,"reflux-core/lib/ListenerMethods":529,"reflux-core/lib/utils":538}],541:[function(require,module,exports){
var ListenerMethods = require('reflux-core/lib/ListenerMethods'),
    ListenerMixin = require('./ListenerMixin'),
    _ = require('reflux-core/lib/utils');

module.exports = function(listenable, key, filterFunc) {
    filterFunc = _.isFunction(key) ? key : filterFunc;
    return {
        getInitialState: function() {
            if (!_.isFunction(listenable.getInitialState)) {
                return {};
            } else if (_.isFunction(key)) {
                return filterFunc.call(this, listenable.getInitialState());
            } else {
                // Filter initial payload from store.
                var result = filterFunc.call(this, listenable.getInitialState());
                if (typeof(result) !== "undefined") {
                    return _.object([key], [result]);
                } else {
                    return {};
                }
            }
        },
        componentDidMount: function() {
            _.extend(this, ListenerMethods);
            var me = this;
            var cb = function(value) {
                if (_.isFunction(key)) {
                    me.setState(filterFunc.call(me, value));
                } else {
                    var result = filterFunc.call(me, value);
                    me.setState(_.object([key], [result]));
                }
            };

            this.listenTo(listenable, cb);
        },
        componentWillUnmount: ListenerMixin.componentWillUnmount
    };
};


},{"./ListenerMixin":539,"reflux-core/lib/ListenerMethods":529,"reflux-core/lib/utils":538}],542:[function(require,module,exports){
var Reflux = require('reflux-core');

Reflux.connect = require('./connect');

Reflux.connectFilter = require('./connectFilter');

Reflux.ListenerMixin = require('./ListenerMixin');

Reflux.listenTo = require('./listenTo');

Reflux.listenToMany = require('./listenToMany');

module.exports = Reflux;

},{"./ListenerMixin":539,"./connect":540,"./connectFilter":541,"./listenTo":543,"./listenToMany":544,"reflux-core":535}],543:[function(require,module,exports){
var ListenerMethods = require('reflux-core/lib/ListenerMethods');

/**
 * A mixin factory for a React component. Meant as a more convenient way of using the `ListenerMixin`,
 * without having to manually set listeners in the `componentDidMount` method.
 *
 * @param {Action|Store} listenable An Action or Store that should be
 *  listened to.
 * @param {Function|String} callback The callback to register as event handler
 * @param {Function|String} defaultCallback The callback to register as default handler
 * @returns {Object} An object to be used as a mixin, which sets up the listener for the given listenable.
 */
module.exports = function(listenable,callback,initial){
    return {
        /**
         * Set up the mixin before the initial rendering occurs. Import methods from `ListenerMethods`
         * and then make the call to `listenTo` with the arguments provided to the factory function
         */
        componentDidMount: function() {
            for(var m in ListenerMethods){
                if (this[m] !== ListenerMethods[m]){
                    if (this[m]){
                        throw "Can't have other property '"+m+"' when using Reflux.listenTo!";
                    }
                    this[m] = ListenerMethods[m];
                }
            }
            this.listenTo(listenable,callback,initial);
        },
        /**
         * Cleans up all listener previously registered.
         */
        componentWillUnmount: ListenerMethods.stopListeningToAll
    };
};

},{"reflux-core/lib/ListenerMethods":529}],544:[function(require,module,exports){
var ListenerMethods = require('reflux-core/lib/ListenerMethods');

/**
 * A mixin factory for a React component. Meant as a more convenient way of using the `listenerMixin`,
 * without having to manually set listeners in the `componentDidMount` method. This version is used
 * to automatically set up a `listenToMany` call.
 *
 * @param {Object} listenables An object of listenables
 * @returns {Object} An object to be used as a mixin, which sets up the listeners for the given listenables.
 */
module.exports = function(listenables){
    return {
        /**
         * Set up the mixin before the initial rendering occurs. Import methods from `ListenerMethods`
         * and then make the call to `listenTo` with the arguments provided to the factory function
         */
        componentDidMount: function() {
            for(var m in ListenerMethods){
                if (this[m] !== ListenerMethods[m]){
                    if (this[m]){
                        throw "Can't have other property '"+m+"' when using Reflux.listenToMany!";
                    }
                    this[m] = ListenerMethods[m];
                }
            }
            this.listenToMany(listenables);
        },
        /**
         * Cleans up all listener previously registered.
         */
        componentWillUnmount: ListenerMethods.stopListeningToAll
    };
};

},{"reflux-core/lib/ListenerMethods":529}],545:[function(require,module,exports){
(function (process,global){
/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
 * additional grant of patent rights can be found in the PATENTS file in
 * the same directory.
 */

!(function(global) {
  "use strict";

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      // If regeneratorRuntime is defined globally and we're in a module,
      // make the exports object identical to regeneratorRuntime.
      module.exports = runtime;
    }
    // Don't bother evaluating the rest of this file if the runtime was
    // already defined globally.
    return;
  }

  // Define the runtime globally (as expected by generated code) as either
  // module.exports (if we're in a module) or a new, empty object.
  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  // This is a polyfill for %IteratorPrototype% for environments that
  // don't natively support it.
  var IteratorPrototype = {};
  IteratorPrototype[iteratorSymbol] = function () {
    return this;
  };

  var getProto = Object.getPrototypeOf;
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype &&
      NativeIteratorPrototype !== Op &&
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    // This environment has a native %IteratorPrototype%; use it instead
    // of the polyfill.
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype =
    Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunctionPrototype[toStringTagSymbol] =
    GeneratorFunction.displayName = "GeneratorFunction";

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      if (!(toStringTagSymbol in genFun)) {
        genFun[toStringTagSymbol] = "GeneratorFunction";
      }
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `hasOwn.call(value, "__await")` to determine if the yielded value is
  // meant to be awaited.
  runtime.awrap = function(arg) {
    return { __await: arg };
  };

  function AsyncIterator(generator) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        if (value &&
            typeof value === "object" &&
            hasOwn.call(value, "__await")) {
          return Promise.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        return Promise.resolve(value).then(function(unwrapped) {
          // When a yielded Promise is resolved, its final value becomes
          // the .value of the Promise<{value,done}> result for the
          // current iteration. If the Promise is rejected, however, the
          // result for this iteration will be rejected with the same
          // reason. Note that rejections of yielded Promises are not
          // thrown back into the generator function, as is the case
          // when an awaited Promise is rejected. This difference in
          // behavior between yield and await is important, because it
          // allows the consumer to decide what to do with the yielded
          // rejection (swallow it and continue, manually .throw it back
          // into the generator, abandon iteration, whatever). With
          // await, by contrast, there is no opportunity to examine the
          // rejection reason outside the generator function, so the
          // only option is to throw it from the await expression, and
          // let the generator function handle the exception.
          result.value = unwrapped;
          resolve(result);
        }, reject);
      }
    }

    if (typeof process === "object" && process.domain) {
      invoke = process.domain.bind(invoke);
    }

    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new Promise(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : callInvokeWithMethodAndArg();
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  AsyncIterator.prototype[asyncIteratorSymbol] = function () {
    return this;
  };
  runtime.AsyncIterator = AsyncIterator;

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList)
    );

    return runtime.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      context.method = method;
      context.arg = arg;

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }

        if (context.method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = context.arg;

        } else if (context.method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw context.arg;
          }

          context.dispatchException(context.arg);

        } else if (context.method === "return") {
          context.abrupt("return", context.arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          if (record.arg === ContinueSentinel) {
            continue;
          }

          return {
            value: record.arg,
            done: context.done
          };

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(context.arg) call above.
          context.method = "throw";
          context.arg = record.arg;
        }
      }
    };
  }

  // Call delegate.iterator[context.method](context.arg) and handle the
  // result, either by returning a { value, done } result from the
  // delegate iterator, or by modifying context.method and context.arg,
  // setting context.delegate to null, and returning the ContinueSentinel.
  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];
    if (method === undefined) {
      // A .throw or .return when the delegate iterator has no .throw
      // method always terminates the yield* loop.
      context.delegate = null;

      if (context.method === "throw") {
        if (delegate.iterator.return) {
          // If the delegate iterator has a return method, give it a
          // chance to clean up.
          context.method = "return";
          context.arg = undefined;
          maybeInvokeDelegate(delegate, context);

          if (context.method === "throw") {
            // If maybeInvokeDelegate(context) changed context.method from
            // "return" to "throw", let that override the TypeError below.
            return ContinueSentinel;
          }
        }

        context.method = "throw";
        context.arg = new TypeError(
          "The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    var record = tryCatch(method, delegate.iterator, context.arg);

    if (record.type === "throw") {
      context.method = "throw";
      context.arg = record.arg;
      context.delegate = null;
      return ContinueSentinel;
    }

    var info = record.arg;

    if (! info) {
      context.method = "throw";
      context.arg = new TypeError("iterator result is not an object");
      context.delegate = null;
      return ContinueSentinel;
    }

    if (info.done) {
      // Assign the result of the finished delegate to the temporary
      // variable specified by delegate.resultName (see delegateYield).
      context[delegate.resultName] = info.value;

      // Resume execution at the desired location (see delegateYield).
      context.next = delegate.nextLoc;

      // If context.method was "throw" but the delegate handled the
      // exception, let the outer generator proceed normally. If
      // context.method was "next", forget context.arg since it has been
      // "consumed" by the delegate iterator. If context.method was
      // "return", allow the original .return call to continue in the
      // outer generator.
      if (context.method !== "return") {
        context.method = "next";
        context.arg = undefined;
      }

    } else {
      // Re-yield the result returned by the delegate method.
      return info;
    }

    // The delegate iterator is finished, so forget it and continue with
    // the outer generator.
    context.delegate = null;
    return ContinueSentinel;
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  Gp[toStringTagSymbol] = "Generator";

  Gp.toString = function() {
    return "[object Generator]";
  };

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  runtime.values = values;

  function doneResult() {
    return { value: undefined, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined;
      this.done = false;
      this.delegate = null;

      this.method = "next";
      this.arg = undefined;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;

        if (caught) {
          // If the dispatched exception was caught by a catch block,
          // then let that catch block handle the exception normally.
          context.method = "next";
          context.arg = undefined;
        }

        return !! caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.method = "next";
        this.next = finallyEntry.finallyLoc;
        return ContinueSentinel;
      }

      return this.complete(record);
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = this.arg = record.arg;
        this.method = "return";
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }

      return ContinueSentinel;
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      if (this.method === "next") {
        // Deliberately forget the last sent value so that we don't
        // accidentally pass it on to the delegate.
        this.arg = undefined;
      }

      return ContinueSentinel;
    }
  };
})(
  // Among the various tricks for obtaining a reference to the global
  // object, this seems to be the most reliable technique that does not
  // use indirect eval (which violates Content Security Policy).
  typeof global === "object" ? global :
  typeof window === "object" ? window :
  typeof self === "object" ? self : this
);

}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"_process":334}],546:[function(require,module,exports){
(function(g) {
	var FORMAT_RE = /({+)([^:{\|}]+)(\|([^:}]+))?(:(-?\d*)([ij]?))?(}+)/g,
		defined = function(x) { return typeof x !== 'undefined' },
		format = function() {
			var args = arguments,
				str = this

			return this.replace(FORMAT_RE, function() {
				var m = arguments,
					match = m[0],
					braces_in = m[1],
					id = m[2],
					// id not an int? named!
					named = (id % 1 !== 0),
					// if no property chain exist, get the name instead
					property_chain = m[4] || (named && id),
					padding = m[6],
					modifier = m[7],
					braces_out = m[8],
					property,
					obj = {},
					arg = named ? args[0] : args[id],
					res = []

				// escaped?
				if (braces_in.length > 1 && braces_out.length > 1)
					return match.slice(1, match.length - 1)

				// visit the properties
				property_chain = property_chain && property_chain.split('.') || []
				while (defined(property = property_chain.shift()) && defined(arg)) {
					// evaluate any intermediate function
					if (typeof arg === 'function') arg = arg.apply(obj, [])

					obj = arg
					arg = arg[property]
				}

				// Evaluate the leaf function
				if (typeof arg === 'function') arg = arg.apply(obj, [])

				// Integer modifier
				if ('i' === modifier) arg = Math.round(arg)

				// JSON modifier
				else if ('j' === modifier) arg = JSON.stringify(arg)

				// Nothing found :-(
				if (!defined(arg)) return match

				// Apply padding and return
				arg = String(arg)
				if (padding < 0) {
					res.push(arg)
					padding = 1 - padding
				}
				if (padding > arg.length) res.length = padding - arg.length
				if (!defined(res[0])) res[res.length] = arg
				return res.join(" ")
			})
		},
		main = function() {
			// Call as a method
			return format.apply(arguments[0], Array.prototype.slice.call(arguments, 1))
		}

	// Install as a method
	main.extendString = function(methodName) {
		String.prototype[methodName || 'format'] = format
	}

	// Export as window.stringformat (browser) or as a module (Node)
	g.top ? g.stringformat = main : module.exports = main
})(this)

},{}],547:[function(require,module,exports){
/**
 * Module dependencies.
 */

var Emitter = require('emitter');
var reduce = require('reduce');
var requestBase = require('./request-base');
var isObject = require('./is-object');

/**
 * Root reference for iframes.
 */

var root;
if (typeof window !== 'undefined') { // Browser window
  root = window;
} else if (typeof self !== 'undefined') { // Web Worker
  root = self;
} else { // Other environments
  root = this;
}

/**
 * Noop.
 */

function noop(){};

/**
 * Check if `obj` is a host object,
 * we don't want to serialize these :)
 *
 * TODO: future proof, move to compoent land
 *
 * @param {Object} obj
 * @return {Boolean}
 * @api private
 */

function isHost(obj) {
  var str = {}.toString.call(obj);

  switch (str) {
    case '[object File]':
    case '[object Blob]':
    case '[object FormData]':
      return true;
    default:
      return false;
  }
}

/**
 * Expose `request`.
 */

var request = module.exports = require('./request').bind(null, Request);

/**
 * Determine XHR.
 */

request.getXHR = function () {
  if (root.XMLHttpRequest
      && (!root.location || 'file:' != root.location.protocol
          || !root.ActiveXObject)) {
    return new XMLHttpRequest;
  } else {
    try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
    try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
    try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
    try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
  }
  return false;
};

/**
 * Removes leading and trailing whitespace, added to support IE.
 *
 * @param {String} s
 * @return {String}
 * @api private
 */

var trim = ''.trim
  ? function(s) { return s.trim(); }
  : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };

/**
 * Serialize the given `obj`.
 *
 * @param {Object} obj
 * @return {String}
 * @api private
 */

function serialize(obj) {
  if (!isObject(obj)) return obj;
  var pairs = [];
  for (var key in obj) {
    if (null != obj[key]) {
      pushEncodedKeyValuePair(pairs, key, obj[key]);
        }
      }
  return pairs.join('&');
}

/**
 * Helps 'serialize' with serializing arrays.
 * Mutates the pairs array.
 *
 * @param {Array} pairs
 * @param {String} key
 * @param {Mixed} val
 */

function pushEncodedKeyValuePair(pairs, key, val) {
  if (Array.isArray(val)) {
    return val.forEach(function(v) {
      pushEncodedKeyValuePair(pairs, key, v);
    });
  }
  pairs.push(encodeURIComponent(key)
    + '=' + encodeURIComponent(val));
}

/**
 * Expose serialization method.
 */

 request.serializeObject = serialize;

 /**
  * Parse the given x-www-form-urlencoded `str`.
  *
  * @param {String} str
  * @return {Object}
  * @api private
  */

function parseString(str) {
  var obj = {};
  var pairs = str.split('&');
  var parts;
  var pair;

  for (var i = 0, len = pairs.length; i < len; ++i) {
    pair = pairs[i];
    parts = pair.split('=');
    obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
  }

  return obj;
}

/**
 * Expose parser.
 */

request.parseString = parseString;

/**
 * Default MIME type map.
 *
 *     superagent.types.xml = 'application/xml';
 *
 */

request.types = {
  html: 'text/html',
  json: 'application/json',
  xml: 'application/xml',
  urlencoded: 'application/x-www-form-urlencoded',
  'form': 'application/x-www-form-urlencoded',
  'form-data': 'application/x-www-form-urlencoded'
};

/**
 * Default serialization map.
 *
 *     superagent.serialize['application/xml'] = function(obj){
 *       return 'generated xml here';
 *     };
 *
 */

 request.serialize = {
   'application/x-www-form-urlencoded': serialize,
   'application/json': JSON.stringify
 };

 /**
  * Default parsers.
  *
  *     superagent.parse['application/xml'] = function(str){
  *       return { object parsed from str };
  *     };
  *
  */

request.parse = {
  'application/x-www-form-urlencoded': parseString,
  'application/json': JSON.parse
};

/**
 * Parse the given header `str` into
 * an object containing the mapped fields.
 *
 * @param {String} str
 * @return {Object}
 * @api private
 */

function parseHeader(str) {
  var lines = str.split(/\r?\n/);
  var fields = {};
  var index;
  var line;
  var field;
  var val;

  lines.pop(); // trailing CRLF

  for (var i = 0, len = lines.length; i < len; ++i) {
    line = lines[i];
    index = line.indexOf(':');
    field = line.slice(0, index).toLowerCase();
    val = trim(line.slice(index + 1));
    fields[field] = val;
  }

  return fields;
}

/**
 * Check if `mime` is json or has +json structured syntax suffix.
 *
 * @param {String} mime
 * @return {Boolean}
 * @api private
 */

function isJSON(mime) {
  return /[\/+]json\b/.test(mime);
}

/**
 * Return the mime type for the given `str`.
 *
 * @param {String} str
 * @return {String}
 * @api private
 */

function type(str){
  return str.split(/ *; */).shift();
};

/**
 * Return header field parameters.
 *
 * @param {String} str
 * @return {Object}
 * @api private
 */

function params(str){
  return reduce(str.split(/ *; */), function(obj, str){
    var parts = str.split(/ *= */)
      , key = parts.shift()
      , val = parts.shift();

    if (key && val) obj[key] = val;
    return obj;
  }, {});
};

/**
 * Initialize a new `Response` with the given `xhr`.
 *
 *  - set flags (.ok, .error, etc)
 *  - parse header
 *
 * Examples:
 *
 *  Aliasing `superagent` as `request` is nice:
 *
 *      request = superagent;
 *
 *  We can use the promise-like API, or pass callbacks:
 *
 *      request.get('/').end(function(res){});
 *      request.get('/', function(res){});
 *
 *  Sending data can be chained:
 *
 *      request
 *        .post('/user')
 *        .send({ name: 'tj' })
 *        .end(function(res){});
 *
 *  Or passed to `.send()`:
 *
 *      request
 *        .post('/user')
 *        .send({ name: 'tj' }, function(res){});
 *
 *  Or passed to `.post()`:
 *
 *      request
 *        .post('/user', { name: 'tj' })
 *        .end(function(res){});
 *
 * Or further reduced to a single call for simple cases:
 *
 *      request
 *        .post('/user', { name: 'tj' }, function(res){});
 *
 * @param {XMLHTTPRequest} xhr
 * @param {Object} options
 * @api private
 */

function Response(req, options) {
  options = options || {};
  this.req = req;
  this.xhr = this.req.xhr;
  // responseText is accessible only if responseType is '' or 'text' and on older browsers
  this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
     ? this.xhr.responseText
     : null;
  this.statusText = this.req.xhr.statusText;
  this.setStatusProperties(this.xhr.status);
  this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
  // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
  // getResponseHeader still works. so we get content-type even if getting
  // other headers fails.
  this.header['content-type'] = this.xhr.getResponseHeader('content-type');
  this.setHeaderProperties(this.header);
  this.body = this.req.method != 'HEAD'
    ? this.parseBody(this.text ? this.text : this.xhr.response)
    : null;
}

/**
 * Get case-insensitive `field` value.
 *
 * @param {String} field
 * @return {String}
 * @api public
 */

Response.prototype.get = function(field){
  return this.header[field.toLowerCase()];
};

/**
 * Set header related properties:
 *
 *   - `.type` the content type without params
 *
 * A response of "Content-Type: text/plain; charset=utf-8"
 * will provide you with a `.type` of "text/plain".
 *
 * @param {Object} header
 * @api private
 */

Response.prototype.setHeaderProperties = function(header){
  // content-type
  var ct = this.header['content-type'] || '';
  this.type = type(ct);

  // params
  var obj = params(ct);
  for (var key in obj) this[key] = obj[key];
};

/**
 * Parse the given body `str`.
 *
 * Used for auto-parsing of bodies. Parsers
 * are defined on the `superagent.parse` object.
 *
 * @param {String} str
 * @return {Mixed}
 * @api private
 */

Response.prototype.parseBody = function(str){
  var parse = request.parse[this.type];
  if (!parse && isJSON(this.type)) {
    parse = request.parse['application/json'];
  }
  return parse && str && (str.length || str instanceof Object)
    ? parse(str)
    : null;
};

/**
 * Set flags such as `.ok` based on `status`.
 *
 * For example a 2xx response will give you a `.ok` of __true__
 * whereas 5xx will be __false__ and `.error` will be __true__. The
 * `.clientError` and `.serverError` are also available to be more
 * specific, and `.statusType` is the class of error ranging from 1..5
 * sometimes useful for mapping respond colors etc.
 *
 * "sugar" properties are also defined for common cases. Currently providing:
 *
 *   - .noContent
 *   - .badRequest
 *   - .unauthorized
 *   - .notAcceptable
 *   - .notFound
 *
 * @param {Number} status
 * @api private
 */

Response.prototype.setStatusProperties = function(status){
  // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
  if (status === 1223) {
    status = 204;
  }

  var type = status / 100 | 0;

  // status / class
  this.status = this.statusCode = status;
  this.statusType = type;

  // basics
  this.info = 1 == type;
  this.ok = 2 == type;
  this.clientError = 4 == type;
  this.serverError = 5 == type;
  this.error = (4 == type || 5 == type)
    ? this.toError()
    : false;

  // sugar
  this.accepted = 202 == status;
  this.noContent = 204 == status;
  this.badRequest = 400 == status;
  this.unauthorized = 401 == status;
  this.notAcceptable = 406 == status;
  this.notFound = 404 == status;
  this.forbidden = 403 == status;
};

/**
 * Return an `Error` representative of this response.
 *
 * @return {Error}
 * @api public
 */

Response.prototype.toError = function(){
  var req = this.req;
  var method = req.method;
  var url = req.url;

  var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
  var err = new Error(msg);
  err.status = this.status;
  err.method = method;
  err.url = url;

  return err;
};

/**
 * Expose `Response`.
 */

request.Response = Response;

/**
 * Initialize a new `Request` with the given `method` and `url`.
 *
 * @param {String} method
 * @param {String} url
 * @api public
 */

function Request(method, url) {
  var self = this;
  this._query = this._query || [];
  this.method = method;
  this.url = url;
  this.header = {}; // preserves header name case
  this._header = {}; // coerces header names to lowercase
  this.on('end', function(){
    var err = null;
    var res = null;

    try {
      res = new Response(self);
    } catch(e) {
      err = new Error('Parser is unable to parse the response');
      err.parse = true;
      err.original = e;
      // issue #675: return the raw response if the response parsing fails
      err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;
      // issue #876: return the http status code if the response parsing fails
      err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null;
      return self.callback(err);
    }

    self.emit('response', res);

    if (err) {
      return self.callback(err, res);
    }

    if (res.status >= 200 && res.status < 300) {
      return self.callback(err, res);
    }

    var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
    new_err.original = err;
    new_err.response = res;
    new_err.status = res.status;

    self.callback(new_err, res);
  });
}

/**
 * Mixin `Emitter` and `requestBase`.
 */

Emitter(Request.prototype);
for (var key in requestBase) {
  Request.prototype[key] = requestBase[key];
}

/**
 * Abort the request, and clear potential timeout.
 *
 * @return {Request}
 * @api public
 */

Request.prototype.abort = function(){
  if (this.aborted) return;
  this.aborted = true;
  this.xhr && this.xhr.abort();
  this.clearTimeout();
  this.emit('abort');
  return this;
};

/**
 * Set Content-Type to `type`, mapping values from `request.types`.
 *
 * Examples:
 *
 *      superagent.types.xml = 'application/xml';
 *
 *      request.post('/')
 *        .type('xml')
 *        .send(xmlstring)
 *        .end(callback);
 *
 *      request.post('/')
 *        .type('application/xml')
 *        .send(xmlstring)
 *        .end(callback);
 *
 * @param {String} type
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.type = function(type){
  this.set('Content-Type', request.types[type] || type);
  return this;
};

/**
 * Set responseType to `val`. Presently valid responseTypes are 'blob' and 
 * 'arraybuffer'.
 *
 * Examples:
 *
 *      req.get('/')
 *        .responseType('blob')
 *        .end(callback);
 *
 * @param {String} val
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.responseType = function(val){
  this._responseType = val;
  return this;
};

/**
 * Set Accept to `type`, mapping values from `request.types`.
 *
 * Examples:
 *
 *      superagent.types.json = 'application/json';
 *
 *      request.get('/agent')
 *        .accept('json')
 *        .end(callback);
 *
 *      request.get('/agent')
 *        .accept('application/json')
 *        .end(callback);
 *
 * @param {String} accept
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.accept = function(type){
  this.set('Accept', request.types[type] || type);
  return this;
};

/**
 * Set Authorization field value with `user` and `pass`.
 *
 * @param {String} user
 * @param {String} pass
 * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.auth = function(user, pass, options){
  if (!options) {
    options = {
      type: 'basic'
    }
  }

  switch (options.type) {
    case 'basic':
      var str = btoa(user + ':' + pass);
      this.set('Authorization', 'Basic ' + str);
    break;

    case 'auto':
      this.username = user;
      this.password = pass;
    break;
  }
  return this;
};

/**
* Add query-string `val`.
*
* Examples:
*
*   request.get('/shoes')
*     .query('size=10')
*     .query({ color: 'blue' })
*
* @param {Object|String} val
* @return {Request} for chaining
* @api public
*/

Request.prototype.query = function(val){
  if ('string' != typeof val) val = serialize(val);
  if (val) this._query.push(val);
  return this;
};

/**
 * Queue the given `file` as an attachment to the specified `field`,
 * with optional `filename`.
 *
 * ``` js
 * request.post('/upload')
 *   .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
 *   .end(callback);
 * ```
 *
 * @param {String} field
 * @param {Blob|File} file
 * @param {String} filename
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.attach = function(field, file, filename){
  this._getFormData().append(field, file, filename || file.name);
  return this;
};

Request.prototype._getFormData = function(){
  if (!this._formData) {
    this._formData = new root.FormData();
  }
  return this._formData;
};

/**
 * Send `data` as the request body, defaulting the `.type()` to "json" when
 * an object is given.
 *
 * Examples:
 *
 *       // manual json
 *       request.post('/user')
 *         .type('json')
 *         .send('{"name":"tj"}')
 *         .end(callback)
 *
 *       // auto json
 *       request.post('/user')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // manual x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send('name=tj')
 *         .end(callback)
 *
 *       // auto x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // defaults to x-www-form-urlencoded
  *      request.post('/user')
  *        .send('name=tobi')
  *        .send('species=ferret')
  *        .end(callback)
 *
 * @param {String|Object} data
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.send = function(data){
  var obj = isObject(data);
  var type = this._header['content-type'];

  // merge
  if (obj && isObject(this._data)) {
    for (var key in data) {
      this._data[key] = data[key];
    }
  } else if ('string' == typeof data) {
    if (!type) this.type('form');
    type = this._header['content-type'];
    if ('application/x-www-form-urlencoded' == type) {
      this._data = this._data
        ? this._data + '&' + data
        : data;
    } else {
      this._data = (this._data || '') + data;
    }
  } else {
    this._data = data;
  }

  if (!obj || isHost(data)) return this;
  if (!type) this.type('json');
  return this;
};

/**
 * @deprecated
 */
Response.prototype.parse = function serialize(fn){
  if (root.console) {
    console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0");
  }
  this.serialize(fn);
  return this;
};

Response.prototype.serialize = function serialize(fn){
  this._parser = fn;
  return this;
};

/**
 * Invoke the callback with `err` and `res`
 * and handle arity check.
 *
 * @param {Error} err
 * @param {Response} res
 * @api private
 */

Request.prototype.callback = function(err, res){
  var fn = this._callback;
  this.clearTimeout();
  fn(err, res);
};

/**
 * Invoke callback with x-domain error.
 *
 * @api private
 */

Request.prototype.crossDomainError = function(){
  var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
  err.crossDomain = true;

  err.status = this.status;
  err.method = this.method;
  err.url = this.url;

  this.callback(err);
};

/**
 * Invoke callback with timeout error.
 *
 * @api private
 */

Request.prototype.timeoutError = function(){
  var timeout = this._timeout;
  var err = new Error('timeout of ' + timeout + 'ms exceeded');
  err.timeout = timeout;
  this.callback(err);
};

/**
 * Enable transmission of cookies with x-domain requests.
 *
 * Note that for this to work the origin must not be
 * using "Access-Control-Allow-Origin" with a wildcard,
 * and also must set "Access-Control-Allow-Credentials"
 * to "true".
 *
 * @api public
 */

Request.prototype.withCredentials = function(){
  this._withCredentials = true;
  return this;
};

/**
 * Initiate request, invoking callback `fn(res)`
 * with an instanceof `Response`.
 *
 * @param {Function} fn
 * @return {Request} for chaining
 * @api public
 */

Request.prototype.end = function(fn){
  var self = this;
  var xhr = this.xhr = request.getXHR();
  var query = this._query.join('&');
  var timeout = this._timeout;
  var data = this._formData || this._data;

  // store callback
  this._callback = fn || noop;

  // state change
  xhr.onreadystatechange = function(){
    if (4 != xhr.readyState) return;

    // In IE9, reads to any property (e.g. status) off of an aborted XHR will
    // result in the error "Could not complete the operation due to error c00c023f"
    var status;
    try { status = xhr.status } catch(e) { status = 0; }

    if (0 == status) {
      if (self.timedout) return self.timeoutError();
      if (self.aborted) return;
      return self.crossDomainError();
    }
    self.emit('end');
  };

  // progress
  var handleProgress = function(e){
    if (e.total > 0) {
      e.percent = e.loaded / e.total * 100;
    }
    e.direction = 'download';
    self.emit('progress', e);
  };
  if (this.hasListeners('progress')) {
    xhr.onprogress = handleProgress;
  }
  try {
    if (xhr.upload && this.hasListeners('progress')) {
      xhr.upload.onprogress = handleProgress;
    }
  } catch(e) {
    // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
    // Reported here:
    // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
  }

  // timeout
  if (timeout && !this._timer) {
    this._timer = setTimeout(function(){
      self.timedout = true;
      self.abort();
    }, timeout);
  }

  // querystring
  if (query) {
    query = request.serializeObject(query);
    this.url += ~this.url.indexOf('?')
      ? '&' + query
      : '?' + query;
  }

  // initiate request
  if (this.username && this.password) {
    xhr.open(this.method, this.url, true, this.username, this.password);
  } else {
    xhr.open(this.method, this.url, true);
  }

  // CORS
  if (this._withCredentials) xhr.withCredentials = true;

  // body
  if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
    // serialize stuff
    var contentType = this._header['content-type'];
    var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : ''];
    if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
    if (serialize) data = serialize(data);
  }

  // set header fields
  for (var field in this.header) {
    if (null == this.header[field]) continue;
    xhr.setRequestHeader(field, this.header[field]);
  }

  if (this._responseType) {
    xhr.responseType = this._responseType;
  }

  // send stuff
  this.emit('request', this);

  // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
  // We need null here if data is undefined
  xhr.send(typeof data !== 'undefined' ? data : null);
  return this;
};


/**
 * Expose `Request`.
 */

request.Request = Request;

/**
 * GET `url` with optional callback `fn(res)`.
 *
 * @param {String} url
 * @param {Mixed|Function} data or fn
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

request.get = function(url, data, fn){
  var req = request('GET', url);
  if ('function' == typeof data) fn = data, data = null;
  if (data) req.query(data);
  if (fn) req.end(fn);
  return req;
};

/**
 * HEAD `url` with optional callback `fn(res)`.
 *
 * @param {String} url
 * @param {Mixed|Function} data or fn
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

request.head = function(url, data, fn){
  var req = request('HEAD', url);
  if ('function' == typeof data) fn = data, data = null;
  if (data) req.send(data);
  if (fn) req.end(fn);
  return req;
};

/**
 * DELETE `url` with optional callback `fn(res)`.
 *
 * @param {String} url
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

function del(url, fn){
  var req = request('DELETE', url);
  if (fn) req.end(fn);
  return req;
};

request['del'] = del;
request['delete'] = del;

/**
 * PATCH `url` with optional `data` and callback `fn(res)`.
 *
 * @param {String} url
 * @param {Mixed} data
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

request.patch = function(url, data, fn){
  var req = request('PATCH', url);
  if ('function' == typeof data) fn = data, data = null;
  if (data) req.send(data);
  if (fn) req.end(fn);
  return req;
};

/**
 * POST `url` with optional `data` and callback `fn(res)`.
 *
 * @param {String} url
 * @param {Mixed} data
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

request.post = function(url, data, fn){
  var req = request('POST', url);
  if ('function' == typeof data) fn = data, data = null;
  if (data) req.send(data);
  if (fn) req.end(fn);
  return req;
};

/**
 * PUT `url` with optional `data` and callback `fn(res)`.
 *
 * @param {String} url
 * @param {Mixed|Function} data or fn
 * @param {Function} fn
 * @return {Request}
 * @api public
 */

request.put = function(url, data, fn){
  var req = request('PUT', url);
  if ('function' == typeof data) fn = data, data = null;
  if (data) req.send(data);
  if (fn) req.end(fn);
  return req;
};

},{"./is-object":548,"./request":550,"./request-base":549,"emitter":300,"reduce":526}],548:[function(require,module,exports){
/**
 * Check if `obj` is an object.
 *
 * @param {Object} obj
 * @return {Boolean}
 * @api private
 */

function isObject(obj) {
  return null != obj && 'object' == typeof obj;
}

module.exports = isObject;

},{}],549:[function(require,module,exports){
/**
 * Module of mixed-in functions shared between node and client code
 */
var isObject = require('./is-object');

/**
 * Clear previous timeout.
 *
 * @return {Request} for chaining
 * @api public
 */

exports.clearTimeout = function _clearTimeout(){
  this._timeout = 0;
  clearTimeout(this._timer);
  return this;
};

/**
 * Force given parser
 *
 * Sets the body parser no matter type.
 *
 * @param {Function}
 * @api public
 */

exports.parse = function parse(fn){
  this._parser = fn;
  return this;
};

/**
 * Set timeout to `ms`.
 *
 * @param {Number} ms
 * @return {Request} for chaining
 * @api public
 */

exports.timeout = function timeout(ms){
  this._timeout = ms;
  return this;
};

/**
 * Faux promise support
 *
 * @param {Function} fulfill
 * @param {Function} reject
 * @return {Request}
 */

exports.then = function then(fulfill, reject) {
  return this.end(function(err, res) {
    err ? reject(err) : fulfill(res);
  });
}

/**
 * Allow for extension
 */

exports.use = function use(fn) {
  fn(this);
  return this;
}


/**
 * Get request header `field`.
 * Case-insensitive.
 *
 * @param {String} field
 * @return {String}
 * @api public
 */

exports.get = function(field){
  return this._header[field.toLowerCase()];
};

/**
 * Get case-insensitive header `field` value.
 * This is a deprecated internal API. Use `.get(field)` instead.
 *
 * (getHeader is no longer used internally by the superagent code base)
 *
 * @param {String} field
 * @return {String}
 * @api private
 * @deprecated
 */

exports.getHeader = exports.get;

/**
 * Set header `field` to `val`, or multiple fields with one object.
 * Case-insensitive.
 *
 * Examples:
 *
 *      req.get('/')
 *        .set('Accept', 'application/json')
 *        .set('X-API-Key', 'foobar')
 *        .end(callback);
 *
 *      req.get('/')
 *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
 *        .end(callback);
 *
 * @param {String|Object} field
 * @param {String} val
 * @return {Request} for chaining
 * @api public
 */

exports.set = function(field, val){
  if (isObject(field)) {
    for (var key in field) {
      this.set(key, field[key]);
    }
    return this;
  }
  this._header[field.toLowerCase()] = val;
  this.header[field] = val;
  return this;
};

/**
 * Remove header `field`.
 * Case-insensitive.
 *
 * Example:
 *
 *      req.get('/')
 *        .unset('User-Agent')
 *        .end(callback);
 *
 * @param {String} field
 */
exports.unset = function(field){
  delete this._header[field.toLowerCase()];
  delete this.header[field];
  return this;
};

/**
 * Write the field `name` and `val` for "multipart/form-data"
 * request bodies.
 *
 * ``` js
 * request.post('/upload')
 *   .field('foo', 'bar')
 *   .end(callback);
 * ```
 *
 * @param {String} name
 * @param {String|Blob|File|Buffer|fs.ReadStream} val
 * @return {Request} for chaining
 * @api public
 */
exports.field = function(name, val) {
  this._getFormData().append(name, val);
  return this;
};

},{"./is-object":548}],550:[function(require,module,exports){
// The node and browser modules expose versions of this with the
// appropriate constructor function bound as first argument
/**
 * Issue a request:
 *
 * Examples:
 *
 *    request('GET', '/users').end(callback)
 *    request('/users').end(callback)
 *    request('/users', callback)
 *
 * @param {String} method
 * @param {String|Function} url or callback
 * @return {Request}
 * @api public
 */

function request(RequestConstructor, method, url) {
  // callback
  if ('function' == typeof url) {
    return new RequestConstructor('GET', method).end(url);
  }

  // url first
  if (2 == arguments.length) {
    return new RequestConstructor('GET', method);
  }

  return new RequestConstructor(method, url);
}

module.exports = request;

},{}],551:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _toDate = require('./lib/toDate');

var _toDate2 = _interopRequireDefault(_toDate);

var _toFloat = require('./lib/toFloat');

var _toFloat2 = _interopRequireDefault(_toFloat);

var _toInt = require('./lib/toInt');

var _toInt2 = _interopRequireDefault(_toInt);

var _toBoolean = require('./lib/toBoolean');

var _toBoolean2 = _interopRequireDefault(_toBoolean);

var _equals = require('./lib/equals');

var _equals2 = _interopRequireDefault(_equals);

var _contains = require('./lib/contains');

var _contains2 = _interopRequireDefault(_contains);

var _matches = require('./lib/matches');

var _matches2 = _interopRequireDefault(_matches);

var _isEmail = require('./lib/isEmail');

var _isEmail2 = _interopRequireDefault(_isEmail);

var _isURL = require('./lib/isURL');

var _isURL2 = _interopRequireDefault(_isURL);

var _isMACAddress = require('./lib/isMACAddress');

var _isMACAddress2 = _interopRequireDefault(_isMACAddress);

var _isIP = require('./lib/isIP');

var _isIP2 = _interopRequireDefault(_isIP);

var _isFQDN = require('./lib/isFQDN');

var _isFQDN2 = _interopRequireDefault(_isFQDN);

var _isBoolean = require('./lib/isBoolean');

var _isBoolean2 = _interopRequireDefault(_isBoolean);

var _isAlpha = require('./lib/isAlpha');

var _isAlpha2 = _interopRequireDefault(_isAlpha);

var _isAlphanumeric = require('./lib/isAlphanumeric');

var _isAlphanumeric2 = _interopRequireDefault(_isAlphanumeric);

var _isNumeric = require('./lib/isNumeric');

var _isNumeric2 = _interopRequireDefault(_isNumeric);

var _isLowercase = require('./lib/isLowercase');

var _isLowercase2 = _interopRequireDefault(_isLowercase);

var _isUppercase = require('./lib/isUppercase');

var _isUppercase2 = _interopRequireDefault(_isUppercase);

var _isAscii = require('./lib/isAscii');

var _isAscii2 = _interopRequireDefault(_isAscii);

var _isFullWidth = require('./lib/isFullWidth');

var _isFullWidth2 = _interopRequireDefault(_isFullWidth);

var _isHalfWidth = require('./lib/isHalfWidth');

var _isHalfWidth2 = _interopRequireDefault(_isHalfWidth);

var _isVariableWidth = require('./lib/isVariableWidth');

var _isVariableWidth2 = _interopRequireDefault(_isVariableWidth);

var _isMultibyte = require('./lib/isMultibyte');

var _isMultibyte2 = _interopRequireDefault(_isMultibyte);

var _isSurrogatePair = require('./lib/isSurrogatePair');

var _isSurrogatePair2 = _interopRequireDefault(_isSurrogatePair);

var _isInt = require('./lib/isInt');

var _isInt2 = _interopRequireDefault(_isInt);

var _isFloat = require('./lib/isFloat');

var _isFloat2 = _interopRequireDefault(_isFloat);

var _isDecimal = require('./lib/isDecimal');

var _isDecimal2 = _interopRequireDefault(_isDecimal);

var _isHexadecimal = require('./lib/isHexadecimal');

var _isHexadecimal2 = _interopRequireDefault(_isHexadecimal);

var _isDivisibleBy = require('./lib/isDivisibleBy');

var _isDivisibleBy2 = _interopRequireDefault(_isDivisibleBy);

var _isHexColor = require('./lib/isHexColor');

var _isHexColor2 = _interopRequireDefault(_isHexColor);

var _isMD = require('./lib/isMD5');

var _isMD2 = _interopRequireDefault(_isMD);

var _isJSON = require('./lib/isJSON');

var _isJSON2 = _interopRequireDefault(_isJSON);

var _isEmpty = require('./lib/isEmpty');

var _isEmpty2 = _interopRequireDefault(_isEmpty);

var _isLength = require('./lib/isLength');

var _isLength2 = _interopRequireDefault(_isLength);

var _isByteLength = require('./lib/isByteLength');

var _isByteLength2 = _interopRequireDefault(_isByteLength);

var _isUUID = require('./lib/isUUID');

var _isUUID2 = _interopRequireDefault(_isUUID);

var _isMongoId = require('./lib/isMongoId');

var _isMongoId2 = _interopRequireDefault(_isMongoId);

var _isDate = require('./lib/isDate');

var _isDate2 = _interopRequireDefault(_isDate);

var _isAfter = require('./lib/isAfter');

var _isAfter2 = _interopRequireDefault(_isAfter);

var _isBefore = require('./lib/isBefore');

var _isBefore2 = _interopRequireDefault(_isBefore);

var _isIn = require('./lib/isIn');

var _isIn2 = _interopRequireDefault(_isIn);

var _isCreditCard = require('./lib/isCreditCard');

var _isCreditCard2 = _interopRequireDefault(_isCreditCard);

var _isISIN = require('./lib/isISIN');

var _isISIN2 = _interopRequireDefault(_isISIN);

var _isISBN = require('./lib/isISBN');

var _isISBN2 = _interopRequireDefault(_isISBN);

var _isISSN = require('./lib/isISSN');

var _isISSN2 = _interopRequireDefault(_isISSN);

var _isMobilePhone = require('./lib/isMobilePhone');

var _isMobilePhone2 = _interopRequireDefault(_isMobilePhone);

var _isCurrency = require('./lib/isCurrency');

var _isCurrency2 = _interopRequireDefault(_isCurrency);

var _isISO = require('./lib/isISO8601');

var _isISO2 = _interopRequireDefault(_isISO);

var _isBase = require('./lib/isBase64');

var _isBase2 = _interopRequireDefault(_isBase);

var _isDataURI = require('./lib/isDataURI');

var _isDataURI2 = _interopRequireDefault(_isDataURI);

var _ltrim = require('./lib/ltrim');

var _ltrim2 = _interopRequireDefault(_ltrim);

var _rtrim = require('./lib/rtrim');

var _rtrim2 = _interopRequireDefault(_rtrim);

var _trim = require('./lib/trim');

var _trim2 = _interopRequireDefault(_trim);

var _escape = require('./lib/escape');

var _escape2 = _interopRequireDefault(_escape);

var _unescape = require('./lib/unescape');

var _unescape2 = _interopRequireDefault(_unescape);

var _stripLow = require('./lib/stripLow');

var _stripLow2 = _interopRequireDefault(_stripLow);

var _whitelist = require('./lib/whitelist');

var _whitelist2 = _interopRequireDefault(_whitelist);

var _blacklist = require('./lib/blacklist');

var _blacklist2 = _interopRequireDefault(_blacklist);

var _isWhitelisted = require('./lib/isWhitelisted');

var _isWhitelisted2 = _interopRequireDefault(_isWhitelisted);

var _normalizeEmail = require('./lib/normalizeEmail');

var _normalizeEmail2 = _interopRequireDefault(_normalizeEmail);

var _toString = require('./lib/util/toString');

var _toString2 = _interopRequireDefault(_toString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var version = '6.3.0';

var validator = {
  version: version,
  toDate: _toDate2.default,
  toFloat: _toFloat2.default,
  toInt: _toInt2.default,
  toBoolean: _toBoolean2.default,
  equals: _equals2.default,
  contains: _contains2.default,
  matches: _matches2.default,
  isEmail: _isEmail2.default,
  isURL: _isURL2.default,
  isMACAddress: _isMACAddress2.default,
  isIP: _isIP2.default,
  isFQDN: _isFQDN2.default,
  isBoolean: _isBoolean2.default,
  isAlpha: _isAlpha2.default,
  isAlphanumeric: _isAlphanumeric2.default,
  isNumeric: _isNumeric2.default,
  isLowercase: _isLowercase2.default,
  isUppercase: _isUppercase2.default,
  isAscii: _isAscii2.default,
  isFullWidth: _isFullWidth2.default,
  isHalfWidth: _isHalfWidth2.default,
  isVariableWidth: _isVariableWidth2.default,
  isMultibyte: _isMultibyte2.default,
  isSurrogatePair: _isSurrogatePair2.default,
  isInt: _isInt2.default,
  isFloat: _isFloat2.default,
  isDecimal: _isDecimal2.default,
  isHexadecimal: _isHexadecimal2.default,
  isDivisibleBy: _isDivisibleBy2.default,
  isHexColor: _isHexColor2.default,
  isMD5: _isMD2.default,
  isJSON: _isJSON2.default,
  isEmpty: _isEmpty2.default,
  isLength: _isLength2.default,
  isByteLength: _isByteLength2.default,
  isUUID: _isUUID2.default,
  isMongoId: _isMongoId2.default,
  isDate: _isDate2.default,
  isAfter: _isAfter2.default,
  isBefore: _isBefore2.default,
  isIn: _isIn2.default,
  isCreditCard: _isCreditCard2.default,
  isISIN: _isISIN2.default,
  isISBN: _isISBN2.default,
  isISSN: _isISSN2.default,
  isMobilePhone: _isMobilePhone2.default,
  isCurrency: _isCurrency2.default,
  isISO8601: _isISO2.default,
  isBase64: _isBase2.default,
  isDataURI: _isDataURI2.default,
  ltrim: _ltrim2.default,
  rtrim: _rtrim2.default,
  trim: _trim2.default,
  escape: _escape2.default,
  unescape: _unescape2.default,
  stripLow: _stripLow2.default,
  whitelist: _whitelist2.default,
  blacklist: _blacklist2.default,
  isWhitelisted: _isWhitelisted2.default,
  normalizeEmail: _normalizeEmail2.default,
  toString: _toString2.default
};

exports.default = validator;
module.exports = exports['default'];
},{"./lib/blacklist":553,"./lib/contains":554,"./lib/equals":555,"./lib/escape":556,"./lib/isAfter":557,"./lib/isAlpha":558,"./lib/isAlphanumeric":559,"./lib/isAscii":560,"./lib/isBase64":561,"./lib/isBefore":562,"./lib/isBoolean":563,"./lib/isByteLength":564,"./lib/isCreditCard":565,"./lib/isCurrency":566,"./lib/isDataURI":567,"./lib/isDate":568,"./lib/isDecimal":569,"./lib/isDivisibleBy":570,"./lib/isEmail":571,"./lib/isEmpty":572,"./lib/isFQDN":573,"./lib/isFloat":574,"./lib/isFullWidth":575,"./lib/isHalfWidth":576,"./lib/isHexColor":577,"./lib/isHexadecimal":578,"./lib/isIP":579,"./lib/isISBN":580,"./lib/isISIN":581,"./lib/isISO8601":582,"./lib/isISSN":583,"./lib/isIn":584,"./lib/isInt":585,"./lib/isJSON":586,"./lib/isLength":587,"./lib/isLowercase":588,"./lib/isMACAddress":589,"./lib/isMD5":590,"./lib/isMobilePhone":591,"./lib/isMongoId":592,"./lib/isMultibyte":593,"./lib/isNumeric":594,"./lib/isSurrogatePair":595,"./lib/isURL":596,"./lib/isUUID":597,"./lib/isUppercase":598,"./lib/isVariableWidth":599,"./lib/isWhitelisted":600,"./lib/ltrim":601,"./lib/matches":602,"./lib/normalizeEmail":603,"./lib/rtrim":604,"./lib/stripLow":605,"./lib/toBoolean":606,"./lib/toDate":607,"./lib/toFloat":608,"./lib/toInt":609,"./lib/trim":610,"./lib/unescape":611,"./lib/util/toString":614,"./lib/whitelist":615}],552:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var alpha = exports.alpha = {
  'en-US': /^[A-Z]+$/i,
  'cs-CZ': /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
  'da-DK': /^[A-ZÆØÅ]+$/i,
  'de-DE': /^[A-ZÄÖÜß]+$/i,
  'es-ES': /^[A-ZÁÉÍÑÓÚÜ]+$/i,
  'fr-FR': /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
  'nl-NL': /^[A-ZÉËÏÓÖÜ]+$/i,
  'hu-HU': /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
  'pl-PL': /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
  'pt-PT': /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i,
  'ru-RU': /^[А-ЯЁ]+$/i,
  'sr-RS@latin': /^[A-ZČĆŽŠĐ]+$/i,
  'sr-RS': /^[А-ЯЂЈЉЊЋЏ]+$/i,
  'tr-TR': /^[A-ZÇĞİıÖŞÜ]+$/i,
  'uk-UA': /^[А-ЯЄIЇҐ]+$/i,
  ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/
};

var alphanumeric = exports.alphanumeric = {
  'en-US': /^[0-9A-Z]+$/i,
  'cs-CZ': /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
  'da-DK': /^[0-9A-ZÆØÅ]$/i,
  'de-DE': /^[0-9A-ZÄÖÜß]+$/i,
  'es-ES': /^[0-9A-ZÁÉÍÑÓÚÜ]+$/i,
  'fr-FR': /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
  'hu-HU': /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
  'nl-NL': /^[0-9A-ZÉËÏÓÖÜ]+$/i,
  'pl-PL': /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
  'pt-PT': /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i,
  'ru-RU': /^[0-9А-ЯЁ]+$/i,
  'sr-RS@latin': /^[0-9A-ZČĆŽŠĐ]+$/i,
  'sr-RS': /^[0-9А-ЯЂЈЉЊЋЏ]+$/i,
  'tr-TR': /^[0-9A-ZÇĞİıÖŞÜ]+$/i,
  'uk-UA': /^[0-9А-ЯЄIЇҐ]+$/i,
  ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/
};

var englishLocales = exports.englishLocales = ['AU', 'GB', 'HK', 'IN', 'NZ', 'ZA', 'ZM'];

for (var locale, i = 0; i < englishLocales.length; i++) {
  locale = 'en-' + englishLocales[i];
  alpha[locale] = alpha['en-US'];
  alphanumeric[locale] = alphanumeric['en-US'];
}

alpha['pt-BR'] = alpha['pt-PT'];
alphanumeric['pt-BR'] = alphanumeric['pt-PT'];

// Source: http://www.localeplanet.com/java/
var arabicLocales = exports.arabicLocales = ['AE', 'BH', 'DZ', 'EG', 'IQ', 'JO', 'KW', 'LB', 'LY', 'MA', 'QM', 'QA', 'SA', 'SD', 'SY', 'TN', 'YE'];

for (var _locale, _i = 0; _i < arabicLocales.length; _i++) {
  _locale = 'ar-' + arabicLocales[_i];
  alpha[_locale] = alpha.ar;
  alphanumeric[_locale] = alphanumeric.ar;
}
},{}],553:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = blacklist;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function blacklist(str, chars) {
  (0, _assertString2.default)(str);
  return str.replace(new RegExp('[' + chars + ']+', 'g'), '');
}
module.exports = exports['default'];
},{"./util/assertString":612}],554:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = contains;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _toString = require('./util/toString');

var _toString2 = _interopRequireDefault(_toString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function contains(str, elem) {
  (0, _assertString2.default)(str);
  return str.indexOf((0, _toString2.default)(elem)) >= 0;
}
module.exports = exports['default'];
},{"./util/assertString":612,"./util/toString":614}],555:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = equals;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function equals(str, comparison) {
  (0, _assertString2.default)(str);
  return str === comparison;
}
module.exports = exports['default'];
},{"./util/assertString":612}],556:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
      value: true
});
exports.default = escape;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function escape(str) {
      (0, _assertString2.default)(str);
      return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\//g, '&#x2F;').replace(/\\/g, '&#x5C;').replace(/`/g, '&#96;');
}
module.exports = exports['default'];
},{"./util/assertString":612}],557:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isAfter;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _toDate = require('./toDate');

var _toDate2 = _interopRequireDefault(_toDate);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isAfter(str) {
  var date = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(new Date());

  (0, _assertString2.default)(str);
  var comparison = (0, _toDate2.default)(date);
  var original = (0, _toDate2.default)(str);
  return !!(original && comparison && original > comparison);
}
module.exports = exports['default'];
},{"./toDate":607,"./util/assertString":612}],558:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isAlpha;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _alpha = require('./alpha');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isAlpha(str) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';

  (0, _assertString2.default)(str);
  if (locale in _alpha.alpha) {
    return _alpha.alpha[locale].test(str);
  }
  throw new Error('Invalid locale \'' + locale + '\'');
}
module.exports = exports['default'];
},{"./alpha":552,"./util/assertString":612}],559:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isAlphanumeric;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _alpha = require('./alpha');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isAlphanumeric(str) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';

  (0, _assertString2.default)(str);
  if (locale in _alpha.alphanumeric) {
    return _alpha.alphanumeric[locale].test(str);
  }
  throw new Error('Invalid locale \'' + locale + '\'');
}
module.exports = exports['default'];
},{"./alpha":552,"./util/assertString":612}],560:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isAscii;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable no-control-regex */
var ascii = /^[\x00-\x7F]+$/;
/* eslint-enable no-control-regex */

function isAscii(str) {
  (0, _assertString2.default)(str);
  return ascii.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],561:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isBase64;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var notBase64 = /[^A-Z0-9+\/=]/i;

function isBase64(str) {
  (0, _assertString2.default)(str);
  var len = str.length;
  if (!len || len % 4 !== 0 || notBase64.test(str)) {
    return false;
  }
  var firstPaddingChar = str.indexOf('=');
  return firstPaddingChar === -1 || firstPaddingChar === len - 1 || firstPaddingChar === len - 2 && str[len - 1] === '=';
}
module.exports = exports['default'];
},{"./util/assertString":612}],562:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isBefore;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _toDate = require('./toDate');

var _toDate2 = _interopRequireDefault(_toDate);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isBefore(str) {
  var date = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(new Date());

  (0, _assertString2.default)(str);
  var comparison = (0, _toDate2.default)(date);
  var original = (0, _toDate2.default)(str);
  return !!(original && comparison && original < comparison);
}
module.exports = exports['default'];
},{"./toDate":607,"./util/assertString":612}],563:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isBoolean;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isBoolean(str) {
  (0, _assertString2.default)(str);
  return ['true', 'false', '1', '0'].indexOf(str) >= 0;
}
module.exports = exports['default'];
},{"./util/assertString":612}],564:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = isByteLength;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable prefer-rest-params */
function isByteLength(str, options) {
  (0, _assertString2.default)(str);
  var min = void 0;
  var max = void 0;
  if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
    min = options.min || 0;
    max = options.max;
  } else {
    // backwards compatibility: isByteLength(str, min [, max])
    min = arguments[1];
    max = arguments[2];
  }
  var len = encodeURI(str).split(/%..|./).length - 1;
  return len >= min && (typeof max === 'undefined' || len <= max);
}
module.exports = exports['default'];
},{"./util/assertString":612}],565:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isCreditCard;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable max-len */
var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})|62[0-9]{14}$/;
/* eslint-enable max-len */

function isCreditCard(str) {
  (0, _assertString2.default)(str);
  var sanitized = str.replace(/[^0-9]+/g, '');
  if (!creditCard.test(sanitized)) {
    return false;
  }
  var sum = 0;
  var digit = void 0;
  var tmpNum = void 0;
  var shouldDouble = void 0;
  for (var i = sanitized.length - 1; i >= 0; i--) {
    digit = sanitized.substring(i, i + 1);
    tmpNum = parseInt(digit, 10);
    if (shouldDouble) {
      tmpNum *= 2;
      if (tmpNum >= 10) {
        sum += tmpNum % 10 + 1;
      } else {
        sum += tmpNum;
      }
    } else {
      sum += tmpNum;
    }
    shouldDouble = !shouldDouble;
  }
  return !!(sum % 10 === 0 ? sanitized : false);
}
module.exports = exports['default'];
},{"./util/assertString":612}],566:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isCurrency;

var _merge = require('./util/merge');

var _merge2 = _interopRequireDefault(_merge);

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function currencyRegex(options) {
  var symbol = '(\\' + options.symbol.replace(/\./g, '\\.') + ')' + (options.require_symbol ? '' : '?'),
      negative = '-?',
      whole_dollar_amount_without_sep = '[1-9]\\d*',
      whole_dollar_amount_with_sep = '[1-9]\\d{0,2}(\\' + options.thousands_separator + '\\d{3})*',
      valid_whole_dollar_amounts = ['0', whole_dollar_amount_without_sep, whole_dollar_amount_with_sep],
      whole_dollar_amount = '(' + valid_whole_dollar_amounts.join('|') + ')?',
      decimal_amount = '(\\' + options.decimal_separator + '\\d{2})?';
  var pattern = whole_dollar_amount + decimal_amount;

  // default is negative sign before symbol, but there are two other options (besides parens)
  if (options.allow_negatives && !options.parens_for_negatives) {
    if (options.negative_sign_after_digits) {
      pattern += negative;
    } else if (options.negative_sign_before_digits) {
      pattern = negative + pattern;
    }
  }

  // South African Rand, for example, uses R 123 (space) and R-123 (no space)
  if (options.allow_negative_sign_placeholder) {
    pattern = '( (?!\\-))?' + pattern;
  } else if (options.allow_space_after_symbol) {
    pattern = ' ?' + pattern;
  } else if (options.allow_space_after_digits) {
    pattern += '( (?!$))?';
  }

  if (options.symbol_after_digits) {
    pattern += symbol;
  } else {
    pattern = symbol + pattern;
  }

  if (options.allow_negatives) {
    if (options.parens_for_negatives) {
      pattern = '(\\(' + pattern + '\\)|' + pattern + ')';
    } else if (!(options.negative_sign_before_digits || options.negative_sign_after_digits)) {
      pattern = negative + pattern;
    }
  }

  /* eslint-disable prefer-template */
  return new RegExp('^' +
  // ensure there's a dollar and/or decimal amount, and that
  // it doesn't start with a space or a negative sign followed by a space
  '(?!-? )(?=.*\\d)' + pattern + '$');
  /* eslint-enable prefer-template */
}

var default_currency_options = {
  symbol: '$',
  require_symbol: false,
  allow_space_after_symbol: false,
  symbol_after_digits: false,
  allow_negatives: true,
  parens_for_negatives: false,
  negative_sign_before_digits: false,
  negative_sign_after_digits: false,
  allow_negative_sign_placeholder: false,
  thousands_separator: ',',
  decimal_separator: '.',
  allow_space_after_digits: false
};

function isCurrency(str, options) {
  (0, _assertString2.default)(str);
  options = (0, _merge2.default)(options, default_currency_options);
  return currencyRegex(options).test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612,"./util/merge":613}],567:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isDataURI;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var dataURI = /^\s*data:([a-z]+\/[a-z0-9\-\+]+(;[a-z\-]+=[a-z0-9\-]+)?)?(;base64)?,[a-z0-9!\$&',\(\)\*\+,;=\-\._~:@\/\?%\s]*\s*$/i; // eslint-disable-line max-len

function isDataURI(str) {
  (0, _assertString2.default)(str);
  return dataURI.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],568:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isDate;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _isISO = require('./isISO8601');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function getTimezoneOffset(str) {
  var iso8601Parts = str.match(_isISO.iso8601);
  var timezone = void 0,
      sign = void 0,
      hours = void 0,
      minutes = void 0;
  if (!iso8601Parts) {
    str = str.toLowerCase();
    timezone = str.match(/(?:\s|gmt\s*)(-|\+)(\d{1,4})(\s|$)/);
    if (!timezone) {
      return str.indexOf('gmt') !== -1 ? 0 : null;
    }
    sign = timezone[1];
    var offset = timezone[2];
    if (offset.length === 3) {
      offset = '0' + offset;
    }
    if (offset.length <= 2) {
      hours = 0;
      minutes = parseInt(offset, 10);
    } else {
      hours = parseInt(offset.slice(0, 2), 10);
      minutes = parseInt(offset.slice(2, 4), 10);
    }
  } else {
    timezone = iso8601Parts[21];
    if (!timezone) {
      // if no hour/minute was provided, the date is GMT
      return !iso8601Parts[12] ? 0 : null;
    }
    if (timezone === 'z' || timezone === 'Z') {
      return 0;
    }
    sign = iso8601Parts[22];
    if (timezone.indexOf(':') !== -1) {
      hours = parseInt(iso8601Parts[23], 10);
      minutes = parseInt(iso8601Parts[24], 10);
    } else {
      hours = 0;
      minutes = parseInt(iso8601Parts[23], 10);
    }
  }
  return (hours * 60 + minutes) * (sign === '-' ? 1 : -1);
}

function isDate(str) {
  (0, _assertString2.default)(str);
  var normalizedDate = new Date(Date.parse(str));
  if (isNaN(normalizedDate)) {
    return false;
  }

  // normalizedDate is in the user's timezone. Apply the input
  // timezone offset to the date so that the year and day match
  // the input
  var timezoneOffset = getTimezoneOffset(str);
  if (timezoneOffset !== null) {
    var timezoneDifference = normalizedDate.getTimezoneOffset() - timezoneOffset;
    normalizedDate = new Date(normalizedDate.getTime() + 60000 * timezoneDifference);
  }

  var day = String(normalizedDate.getDate());
  var dayOrYear = void 0,
      dayOrYearMatches = void 0,
      year = void 0;
  // check for valid double digits that could be late days
  // check for all matches since a string like '12/23' is a valid date
  // ignore everything with nearby colons
  dayOrYearMatches = str.match(/(^|[^:\d])[23]\d([^T:\d]|$)/g);
  if (!dayOrYearMatches) {
    return true;
  }
  dayOrYear = dayOrYearMatches.map(function (digitString) {
    return digitString.match(/\d+/g)[0];
  }).join('/');

  year = String(normalizedDate.getFullYear()).slice(-2);
  if (dayOrYear === day || dayOrYear === year) {
    return true;
  } else if (dayOrYear === '' + day / year || dayOrYear === '' + year / day) {
    return true;
  }
  return false;
}
module.exports = exports['default'];
},{"./isISO8601":582,"./util/assertString":612}],569:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isDecimal;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var decimal = /^[-+]?([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/;

function isDecimal(str) {
  (0, _assertString2.default)(str);
  return str !== '' && decimal.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],570:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isDivisibleBy;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _toFloat = require('./toFloat');

var _toFloat2 = _interopRequireDefault(_toFloat);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isDivisibleBy(str, num) {
  (0, _assertString2.default)(str);
  return (0, _toFloat2.default)(str) % parseInt(num, 10) === 0;
}
module.exports = exports['default'];
},{"./toFloat":608,"./util/assertString":612}],571:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isEmail;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _merge = require('./util/merge');

var _merge2 = _interopRequireDefault(_merge);

var _isByteLength = require('./isByteLength');

var _isByteLength2 = _interopRequireDefault(_isByteLength);

var _isFQDN = require('./isFQDN');

var _isFQDN2 = _interopRequireDefault(_isFQDN);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var default_email_options = {
  allow_display_name: false,
  require_display_name: false,
  allow_utf8_local_part: true,
  require_tld: true
};

/* eslint-disable max-len */
/* eslint-disable no-control-regex */
var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;
var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
/* eslint-enable max-len */
/* eslint-enable no-control-regex */

function isEmail(str, options) {
  (0, _assertString2.default)(str);
  options = (0, _merge2.default)(options, default_email_options);

  if (options.require_display_name || options.allow_display_name) {
    var display_email = str.match(displayName);
    if (display_email) {
      str = display_email[1];
    } else if (options.require_display_name) {
      return false;
    }
  }

  var parts = str.split('@');
  var domain = parts.pop();
  var user = parts.join('@');

  var lower_domain = domain.toLowerCase();
  if (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com') {
    user = user.replace(/\./g, '').toLowerCase();
  }

  if (!(0, _isByteLength2.default)(user, { max: 64 }) || !(0, _isByteLength2.default)(domain, { max: 256 })) {
    return false;
  }

  if (!(0, _isFQDN2.default)(domain, { require_tld: options.require_tld })) {
    return false;
  }

  if (user[0] === '"') {
    user = user.slice(1, user.length - 1);
    return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user);
  }

  var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart;

  var user_parts = user.split('.');
  for (var i = 0; i < user_parts.length; i++) {
    if (!pattern.test(user_parts[i])) {
      return false;
    }
  }

  return true;
}
module.exports = exports['default'];
},{"./isByteLength":564,"./isFQDN":573,"./util/assertString":612,"./util/merge":613}],572:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isEmpty;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isEmpty(str) {
  (0, _assertString2.default)(str);
  return str.length === 0;
}
module.exports = exports['default'];
},{"./util/assertString":612}],573:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isFDQN;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _merge = require('./util/merge');

var _merge2 = _interopRequireDefault(_merge);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var default_fqdn_options = {
  require_tld: true,
  allow_underscores: false,
  allow_trailing_dot: false
};

function isFDQN(str, options) {
  (0, _assertString2.default)(str);
  options = (0, _merge2.default)(options, default_fqdn_options);

  /* Remove the optional trailing dot before checking validity */
  if (options.allow_trailing_dot && str[str.length - 1] === '.') {
    str = str.substring(0, str.length - 1);
  }
  var parts = str.split('.');
  if (options.require_tld) {
    var tld = parts.pop();
    if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) {
      return false;
    }
  }
  for (var part, i = 0; i < parts.length; i++) {
    part = parts[i];
    if (options.allow_underscores) {
      part = part.replace(/_/g, '');
    }
    if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) {
      return false;
    }
    if (/[\uff01-\uff5e]/.test(part)) {
      // disallow full-width chars
      return false;
    }
    if (part[0] === '-' || part[part.length - 1] === '-') {
      return false;
    }
  }
  return true;
}
module.exports = exports['default'];
},{"./util/assertString":612,"./util/merge":613}],574:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isFloat;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var float = /^(?:[-+])?(?:[0-9]+)?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$/;

function isFloat(str, options) {
  (0, _assertString2.default)(str);
  options = options || {};
  if (str === '' || str === '.') {
    return false;
  }
  return float.test(str) && (!options.hasOwnProperty('min') || str >= options.min) && (!options.hasOwnProperty('max') || str <= options.max) && (!options.hasOwnProperty('lt') || str < options.lt) && (!options.hasOwnProperty('gt') || str > options.gt);
}
module.exports = exports['default'];
},{"./util/assertString":612}],575:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.fullWidth = undefined;
exports.default = isFullWidth;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var fullWidth = exports.fullWidth = /[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;

function isFullWidth(str) {
  (0, _assertString2.default)(str);
  return fullWidth.test(str);
}
},{"./util/assertString":612}],576:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.halfWidth = undefined;
exports.default = isHalfWidth;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var halfWidth = exports.halfWidth = /[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;

function isHalfWidth(str) {
  (0, _assertString2.default)(str);
  return halfWidth.test(str);
}
},{"./util/assertString":612}],577:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isHexColor;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var hexcolor = /^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;

function isHexColor(str) {
  (0, _assertString2.default)(str);
  return hexcolor.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],578:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isHexadecimal;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var hexadecimal = /^[0-9A-F]+$/i;

function isHexadecimal(str) {
  (0, _assertString2.default)(str);
  return hexadecimal.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],579:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isIP;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
var ipv6Block = /^[0-9A-F]{1,4}$/i;

function isIP(str) {
  var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';

  (0, _assertString2.default)(str);
  version = String(version);
  if (!version) {
    return isIP(str, 4) || isIP(str, 6);
  } else if (version === '4') {
    if (!ipv4Maybe.test(str)) {
      return false;
    }
    var parts = str.split('.').sort(function (a, b) {
      return a - b;
    });
    return parts[3] <= 255;
  } else if (version === '6') {
    var blocks = str.split(':');
    var foundOmissionBlock = false; // marker to indicate ::

    // At least some OS accept the last 32 bits of an IPv6 address
    // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says
    // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses,
    // and '::a.b.c.d' is deprecated, but also valid.
    var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4);
    var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8;

    if (blocks.length > expectedNumberOfBlocks) {
      return false;
    }
    // initial or final ::
    if (str === '::') {
      return true;
    } else if (str.substr(0, 2) === '::') {
      blocks.shift();
      blocks.shift();
      foundOmissionBlock = true;
    } else if (str.substr(str.length - 2) === '::') {
      blocks.pop();
      blocks.pop();
      foundOmissionBlock = true;
    }

    for (var i = 0; i < blocks.length; ++i) {
      // test for a :: which can not be at the string start/end
      // since those cases have been handled above
      if (blocks[i] === '' && i > 0 && i < blocks.length - 1) {
        if (foundOmissionBlock) {
          return false; // multiple :: in address
        }
        foundOmissionBlock = true;
      } else if (foundIPv4TransitionBlock && i === blocks.length - 1) {
        // it has been checked before that the last
        // block is a valid IPv4 address
      } else if (!ipv6Block.test(blocks[i])) {
        return false;
      }
    }
    if (foundOmissionBlock) {
      return blocks.length >= 1;
    }
    return blocks.length === expectedNumberOfBlocks;
  }
  return false;
}
module.exports = exports['default'];
},{"./util/assertString":612}],580:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isISBN;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var isbn10Maybe = /^(?:[0-9]{9}X|[0-9]{10})$/;
var isbn13Maybe = /^(?:[0-9]{13})$/;
var factor = [1, 3];

function isISBN(str) {
  var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';

  (0, _assertString2.default)(str);
  version = String(version);
  if (!version) {
    return isISBN(str, 10) || isISBN(str, 13);
  }
  var sanitized = str.replace(/[\s-]+/g, '');
  var checksum = 0;
  var i = void 0;
  if (version === '10') {
    if (!isbn10Maybe.test(sanitized)) {
      return false;
    }
    for (i = 0; i < 9; i++) {
      checksum += (i + 1) * sanitized.charAt(i);
    }
    if (sanitized.charAt(9) === 'X') {
      checksum += 10 * 10;
    } else {
      checksum += 10 * sanitized.charAt(9);
    }
    if (checksum % 11 === 0) {
      return !!sanitized;
    }
  } else if (version === '13') {
    if (!isbn13Maybe.test(sanitized)) {
      return false;
    }
    for (i = 0; i < 12; i++) {
      checksum += factor[i % 2] * sanitized.charAt(i);
    }
    if (sanitized.charAt(12) - (10 - checksum % 10) % 10 === 0) {
      return !!sanitized;
    }
  }
  return false;
}
module.exports = exports['default'];
},{"./util/assertString":612}],581:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isISIN;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var isin = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;

function isISIN(str) {
  (0, _assertString2.default)(str);
  if (!isin.test(str)) {
    return false;
  }

  var checksumStr = str.replace(/[A-Z]/g, function (character) {
    return parseInt(character, 36);
  });

  var sum = 0;
  var digit = void 0;
  var tmpNum = void 0;
  var shouldDouble = true;
  for (var i = checksumStr.length - 2; i >= 0; i--) {
    digit = checksumStr.substring(i, i + 1);
    tmpNum = parseInt(digit, 10);
    if (shouldDouble) {
      tmpNum *= 2;
      if (tmpNum >= 10) {
        sum += tmpNum + 1;
      } else {
        sum += tmpNum;
      }
    } else {
      sum += tmpNum;
    }
    shouldDouble = !shouldDouble;
  }

  return parseInt(str.substr(str.length - 1), 10) === (10000 - sum) % 10;
}
module.exports = exports['default'];
},{"./util/assertString":612}],582:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.iso8601 = undefined;

exports.default = function (str) {
  (0, _assertString2.default)(str);
  return iso8601.test(str);
};

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable max-len */
// from http://goo.gl/0ejHHW
var iso8601 = exports.iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
/* eslint-enable max-len */
},{"./util/assertString":612}],583:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isISSN;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var issn = '^\\d{4}-?\\d{3}[\\dX]$';

function isISSN(str) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  (0, _assertString2.default)(str);
  var testIssn = issn;
  testIssn = options.require_hyphen ? testIssn.replace('?', '') : testIssn;
  testIssn = options.case_sensitive ? new RegExp(testIssn) : new RegExp(testIssn, 'i');
  if (!testIssn.test(str)) {
    return false;
  }
  var issnDigits = str.replace('-', '');
  var position = 8;
  var checksum = 0;
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = issnDigits[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var digit = _step.value;

      var digitValue = digit.toUpperCase() === 'X' ? 10 : +digit;
      checksum += digitValue * position;
      --position;
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  return checksum % 11 === 0;
}
module.exports = exports['default'];
},{"./util/assertString":612}],584:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = isIn;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _toString = require('./util/toString');

var _toString2 = _interopRequireDefault(_toString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isIn(str, options) {
  (0, _assertString2.default)(str);
  var i = void 0;
  if (Object.prototype.toString.call(options) === '[object Array]') {
    var array = [];
    for (i in options) {
      if ({}.hasOwnProperty.call(options, i)) {
        array[i] = (0, _toString2.default)(options[i]);
      }
    }
    return array.indexOf(str) >= 0;
  } else if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
    return options.hasOwnProperty(str);
  } else if (options && typeof options.indexOf === 'function') {
    return options.indexOf(str) >= 0;
  }
  return false;
}
module.exports = exports['default'];
},{"./util/assertString":612,"./util/toString":614}],585:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isInt;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/;
var intLeadingZeroes = /^[-+]?[0-9]+$/;

function isInt(str, options) {
  (0, _assertString2.default)(str);
  options = options || {};

  // Get the regex to use for testing, based on whether
  // leading zeroes are allowed or not.
  var regex = options.hasOwnProperty('allow_leading_zeroes') && !options.allow_leading_zeroes ? int : intLeadingZeroes;

  // Check min/max/lt/gt
  var minCheckPassed = !options.hasOwnProperty('min') || str >= options.min;
  var maxCheckPassed = !options.hasOwnProperty('max') || str <= options.max;
  var ltCheckPassed = !options.hasOwnProperty('lt') || str < options.lt;
  var gtCheckPassed = !options.hasOwnProperty('gt') || str > options.gt;

  return regex.test(str) && minCheckPassed && maxCheckPassed && ltCheckPassed && gtCheckPassed;
}
module.exports = exports['default'];
},{"./util/assertString":612}],586:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = isJSON;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isJSON(str) {
  (0, _assertString2.default)(str);
  try {
    var obj = JSON.parse(str);
    return !!obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object';
  } catch (e) {/* ignore */}
  return false;
}
module.exports = exports['default'];
},{"./util/assertString":612}],587:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = isLength;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable prefer-rest-params */
function isLength(str, options) {
  (0, _assertString2.default)(str);
  var min = void 0;
  var max = void 0;
  if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
    min = options.min || 0;
    max = options.max;
  } else {
    // backwards compatibility: isLength(str, min [, max])
    min = arguments[1];
    max = arguments[2];
  }
  var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
  var len = str.length - surrogatePairs.length;
  return len >= min && (typeof max === 'undefined' || len <= max);
}
module.exports = exports['default'];
},{"./util/assertString":612}],588:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isLowercase;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isLowercase(str) {
  (0, _assertString2.default)(str);
  return str === str.toLowerCase();
}
module.exports = exports['default'];
},{"./util/assertString":612}],589:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isMACAddress;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var macAddress = /^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$/;

function isMACAddress(str) {
  (0, _assertString2.default)(str);
  return macAddress.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],590:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isMD5;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var md5 = /^[a-f0-9]{32}$/;

function isMD5(str) {
  (0, _assertString2.default)(str);
  return md5.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],591:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isMobilePhone;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable max-len */
var phones = {
  'ar-DZ': /^(\+?213|0)(5|6|7)\d{8}$/,
  'ar-SY': /^(!?(\+?963)|0)?9\d{8}$/,
  'ar-SA': /^(!?(\+?966)|0)?5\d{8}$/,
  'en-US': /^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$/,
  'cs-CZ': /^(\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/,
  'de-DE': /^(\+?49[ \.\-])?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\/]{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$/,
  'da-DK': /^(\+?45)?(\d{8})$/,
  'el-GR': /^(\+?30)?(69\d{8})$/,
  'en-AU': /^(\+?61|0)4\d{8}$/,
  'en-GB': /^(\+?44|0)7\d{9}$/,
  'en-HK': /^(\+?852\-?)?[569]\d{3}\-?\d{4}$/,
  'en-IN': /^(\+?91|0)?[789]\d{9}$/,
  'en-NG': /^(\+?234|0)?[789]\d{9}$/,
  'en-NZ': /^(\+?64|0)2\d{7,9}$/,
  'en-ZA': /^(\+?27|0)\d{9}$/,
  'en-ZM': /^(\+?26)?09[567]\d{7}$/,
  'es-ES': /^(\+?34)?(6\d{1}|7[1234])\d{7}$/,
  'fi-FI': /^(\+?358|0)\s?(4(0|1|2|4|5)?|50)\s?(\d\s?){4,8}\d$/,
  'fr-FR': /^(\+?33|0)[67]\d{8}$/,
  'he-IL': /^(\+972|0)([23489]|5[0248]|77)[1-9]\d{6}/,
  'hu-HU': /^(\+?36)(20|30|70)\d{7}$/,
  'it-IT': /^(\+?39)?\s?3\d{2} ?\d{6,7}$/,
  'ja-JP': /^(\+?81|0)\d{1,4}[ \-]?\d{1,4}[ \-]?\d{4}$/,
  'ms-MY': /^(\+?6?01){1}(([145]{1}(\-|\s)?\d{7,8})|([236789]{1}(\s|\-)?\d{7}))$/,
  'nb-NO': /^(\+?47)?[49]\d{7}$/,
  'nl-BE': /^(\+?32|0)4?\d{8}$/,
  'nn-NO': /^(\+?47)?[49]\d{7}$/,
  'pl-PL': /^(\+?48)? ?[5-8]\d ?\d{3} ?\d{2} ?\d{2}$/,
  'pt-BR': /^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$/,
  'pt-PT': /^(\+?351)?9[1236]\d{7}$/,
  'ro-RO': /^(\+?4?0)\s?7\d{2}(\/|\s|\.|\-)?\d{3}(\s|\.|\-)?\d{3}$/,
  'en-PK': /^((\+92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$/,
  'ru-RU': /^(\+?7|8)?9\d{9}$/,
  'sr-RS': /^(\+3816|06)[- \d]{5,9}$/,
  'tr-TR': /^(\+?90|0)?5\d{9}$/,
  'vi-VN': /^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$/,
  'zh-CN': /^(\+?0?86\-?)?1[345789]\d{9}$/,
  'zh-TW': /^(\+?886\-?|0)?9\d{8}$/
};
/* eslint-enable max-len */

// aliases
phones['en-CA'] = phones['en-US'];
phones['fr-BE'] = phones['nl-BE'];
phones['zh-HK'] = phones['en-HK'];

function isMobilePhone(str, locale) {
  (0, _assertString2.default)(str);
  if (locale in phones) {
    return phones[locale].test(str);
  }
  return false;
}
module.exports = exports['default'];
},{"./util/assertString":612}],592:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isMongoId;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _isHexadecimal = require('./isHexadecimal');

var _isHexadecimal2 = _interopRequireDefault(_isHexadecimal);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isMongoId(str) {
  (0, _assertString2.default)(str);
  return (0, _isHexadecimal2.default)(str) && str.length === 24;
}
module.exports = exports['default'];
},{"./isHexadecimal":578,"./util/assertString":612}],593:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isMultibyte;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable no-control-regex */
var multibyte = /[^\x00-\x7F]/;
/* eslint-enable no-control-regex */

function isMultibyte(str) {
  (0, _assertString2.default)(str);
  return multibyte.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],594:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isNumeric;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var numeric = /^[-+]?[0-9]+$/;

function isNumeric(str) {
  (0, _assertString2.default)(str);
  return numeric.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],595:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isSurrogatePair;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;

function isSurrogatePair(str) {
  (0, _assertString2.default)(str);
  return surrogatePair.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],596:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isURL;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _isFQDN = require('./isFQDN');

var _isFQDN2 = _interopRequireDefault(_isFQDN);

var _isIP = require('./isIP');

var _isIP2 = _interopRequireDefault(_isIP);

var _merge = require('./util/merge');

var _merge2 = _interopRequireDefault(_merge);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var default_url_options = {
  protocols: ['http', 'https', 'ftp'],
  require_tld: true,
  require_protocol: false,
  require_host: true,
  require_valid_protocol: true,
  allow_underscores: false,
  allow_trailing_dot: false,
  allow_protocol_relative_urls: false
};

var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;

function isRegExp(obj) {
  return Object.prototype.toString.call(obj) === '[object RegExp]';
}

function checkHost(host, matches) {
  for (var i = 0; i < matches.length; i++) {
    var match = matches[i];
    if (host === match || isRegExp(match) && match.test(host)) {
      return true;
    }
  }
  return false;
}

function isURL(url, options) {
  (0, _assertString2.default)(url);
  if (!url || url.length >= 2083 || /[\s<>]/.test(url)) {
    return false;
  }
  if (url.indexOf('mailto:') === 0) {
    return false;
  }
  options = (0, _merge2.default)(options, default_url_options);
  var protocol = void 0,
      auth = void 0,
      host = void 0,
      hostname = void 0,
      port = void 0,
      port_str = void 0,
      split = void 0,
      ipv6 = void 0;

  split = url.split('#');
  url = split.shift();

  split = url.split('?');
  url = split.shift();

  split = url.split('://');
  if (split.length > 1) {
    protocol = split.shift();
    if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
      return false;
    }
  } else if (options.require_protocol) {
    return false;
  } else if (options.allow_protocol_relative_urls && url.substr(0, 2) === '//') {
    split[0] = url.substr(2);
  }
  url = split.join('://');

  split = url.split('/');
  url = split.shift();

  if (url === '' && !options.require_host) {
    return true;
  }

  split = url.split('@');
  if (split.length > 1) {
    auth = split.shift();
    if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
      return false;
    }
  }
  hostname = split.join('@');

  port_str = ipv6 = null;
  var ipv6_match = hostname.match(wrapped_ipv6);
  if (ipv6_match) {
    host = '';
    ipv6 = ipv6_match[1];
    port_str = ipv6_match[2] || null;
  } else {
    split = hostname.split(':');
    host = split.shift();
    if (split.length) {
      port_str = split.join(':');
    }
  }

  if (port_str !== null) {
    port = parseInt(port_str, 10);
    if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
      return false;
    }
  }

  if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6)) && host !== 'localhost') {
    return false;
  }

  host = host || ipv6;

  if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
    return false;
  }
  if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
    return false;
  }

  return true;
}
module.exports = exports['default'];
},{"./isFQDN":573,"./isIP":579,"./util/assertString":612,"./util/merge":613}],597:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isUUID;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var uuid = {
  3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
  4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
  5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
  all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
};

function isUUID(str) {
  var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'all';

  (0, _assertString2.default)(str);
  var pattern = uuid[version];
  return pattern && pattern.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],598:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isUppercase;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isUppercase(str) {
  (0, _assertString2.default)(str);
  return str === str.toUpperCase();
}
module.exports = exports['default'];
},{"./util/assertString":612}],599:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isVariableWidth;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _isFullWidth = require('./isFullWidth');

var _isHalfWidth = require('./isHalfWidth');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isVariableWidth(str) {
  (0, _assertString2.default)(str);
  return _isFullWidth.fullWidth.test(str) && _isHalfWidth.halfWidth.test(str);
}
module.exports = exports['default'];
},{"./isFullWidth":575,"./isHalfWidth":576,"./util/assertString":612}],600:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = isWhitelisted;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function isWhitelisted(str, chars) {
  (0, _assertString2.default)(str);
  for (var i = str.length - 1; i >= 0; i--) {
    if (chars.indexOf(str[i]) === -1) {
      return false;
    }
  }
  return true;
}
module.exports = exports['default'];
},{"./util/assertString":612}],601:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ltrim;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ltrim(str, chars) {
  (0, _assertString2.default)(str);
  var pattern = chars ? new RegExp('^[' + chars + ']+', 'g') : /^\s+/g;
  return str.replace(pattern, '');
}
module.exports = exports['default'];
},{"./util/assertString":612}],602:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = matches;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function matches(str, pattern, modifiers) {
  (0, _assertString2.default)(str);
  if (Object.prototype.toString.call(pattern) !== '[object RegExp]') {
    pattern = new RegExp(pattern, modifiers);
  }
  return pattern.test(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],603:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = normalizeEmail;

var _isEmail = require('./isEmail');

var _isEmail2 = _interopRequireDefault(_isEmail);

var _merge = require('./util/merge');

var _merge2 = _interopRequireDefault(_merge);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var default_normalize_email_options = {
  // The following options apply to all email addresses
  // Lowercases the local part of the email address.
  // Please note this may violate RFC 5321 as per http://stackoverflow.com/a/9808332/192024).
  // The domain is always lowercased, as per RFC 1035
  all_lowercase: true,

  // The following conversions are specific to GMail
  // Lowercases the local part of the GMail address (known to be case-insensitive)
  gmail_lowercase: true,
  // Removes dots from the local part of the email address, as that's ignored by GMail
  gmail_remove_dots: true,
  // Removes the subaddress (e.g. "+foo") from the email address
  gmail_remove_subaddress: true,
  // Conversts the googlemail.com domain to gmail.com
  gmail_convert_googlemaildotcom: true,

  // The following conversions are specific to Outlook.com / Windows Live / Hotmail
  // Lowercases the local part of the Outlook.com address (known to be case-insensitive)
  outlookdotcom_lowercase: true,
  // Removes the subaddress (e.g. "+foo") from the email address
  outlookdotcom_remove_subaddress: true,

  // The following conversions are specific to Yahoo
  // Lowercases the local part of the Yahoo address (known to be case-insensitive)
  yahoo_lowercase: true,
  // Removes the subaddress (e.g. "-foo") from the email address
  yahoo_remove_subaddress: true,

  // The following conversions are specific to iCloud
  // Lowercases the local part of the iCloud address (known to be case-insensitive)
  icloud_lowercase: true,
  // Removes the subaddress (e.g. "+foo") from the email address
  icloud_remove_subaddress: true
};

// List of domains used by iCloud
var icloud_domains = ['icloud.com', 'me.com'];

// List of domains used by Outlook.com and its predecessors
// This list is likely incomplete.
// Partial reference:
// https://blogs.office.com/2013/04/17/outlook-com-gets-two-step-verification-sign-in-by-alias-and-new-international-domains/
var outlookdotcom_domains = ['hotmail.at', 'hotmail.be', 'hotmail.ca', 'hotmail.cl', 'hotmail.co.il', 'hotmail.co.nz', 'hotmail.co.th', 'hotmail.co.uk', 'hotmail.com', 'hotmail.com.ar', 'hotmail.com.au', 'hotmail.com.br', 'hotmail.com.gr', 'hotmail.com.mx', 'hotmail.com.pe', 'hotmail.com.tr', 'hotmail.com.vn', 'hotmail.cz', 'hotmail.de', 'hotmail.dk', 'hotmail.es', 'hotmail.fr', 'hotmail.hu', 'hotmail.id', 'hotmail.ie', 'hotmail.in', 'hotmail.it', 'hotmail.jp', 'hotmail.kr', 'hotmail.lv', 'hotmail.my', 'hotmail.ph', 'hotmail.pt', 'hotmail.sa', 'hotmail.sg', 'hotmail.sk', 'live.be', 'live.co.uk', 'live.com', 'live.com.ar', 'live.com.mx', 'live.de', 'live.es', 'live.eu', 'live.fr', 'live.it', 'live.nl', 'msn.com', 'outlook.at', 'outlook.be', 'outlook.cl', 'outlook.co.il', 'outlook.co.nz', 'outlook.co.th', 'outlook.com', 'outlook.com.ar', 'outlook.com.au', 'outlook.com.br', 'outlook.com.gr', 'outlook.com.pe', 'outlook.com.tr', 'outlook.com.vn', 'outlook.cz', 'outlook.de', 'outlook.dk', 'outlook.es', 'outlook.fr', 'outlook.hu', 'outlook.id', 'outlook.ie', 'outlook.in', 'outlook.it', 'outlook.jp', 'outlook.kr', 'outlook.lv', 'outlook.my', 'outlook.ph', 'outlook.pt', 'outlook.sa', 'outlook.sg', 'outlook.sk', 'passport.com'];

// List of domains used by Yahoo Mail
// This list is likely incomplete
var yahoo_domains = ['rocketmail.com', 'yahoo.ca', 'yahoo.co.uk', 'yahoo.com', 'yahoo.de', 'yahoo.fr', 'yahoo.in', 'yahoo.it', 'ymail.com'];

function normalizeEmail(email, options) {
  options = (0, _merge2.default)(options, default_normalize_email_options);

  if (!(0, _isEmail2.default)(email)) {
    return false;
  }

  var raw_parts = email.split('@');
  var domain = raw_parts.pop();
  var user = raw_parts.join('@');
  var parts = [user, domain];

  // The domain is always lowercased, as it's case-insensitive per RFC 1035
  parts[1] = parts[1].toLowerCase();

  if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
    // Address is GMail
    if (options.gmail_remove_subaddress) {
      parts[0] = parts[0].split('+')[0];
    }
    if (options.gmail_remove_dots) {
      parts[0] = parts[0].replace(/\./g, '');
    }
    if (!parts[0].length) {
      return false;
    }
    if (options.all_lowercase || options.gmail_lowercase) {
      parts[0] = parts[0].toLowerCase();
    }
    parts[1] = options.gmail_convert_googlemaildotcom ? 'gmail.com' : parts[1];
  } else if (~icloud_domains.indexOf(parts[1])) {
    // Address is iCloud
    if (options.icloud_remove_subaddress) {
      parts[0] = parts[0].split('+')[0];
    }
    if (!parts[0].length) {
      return false;
    }
    if (options.all_lowercase || options.icloud_lowercase) {
      parts[0] = parts[0].toLowerCase();
    }
  } else if (~outlookdotcom_domains.indexOf(parts[1])) {
    // Address is Outlook.com
    if (options.outlookdotcom_remove_subaddress) {
      parts[0] = parts[0].split('+')[0];
    }
    if (!parts[0].length) {
      return false;
    }
    if (options.all_lowercase || options.outlookdotcom_lowercase) {
      parts[0] = parts[0].toLowerCase();
    }
  } else if (~yahoo_domains.indexOf(parts[1])) {
    // Address is Yahoo
    if (options.yahoo_remove_subaddress) {
      var components = parts[0].split('-');
      parts[0] = components.length > 1 ? components.slice(0, -1).join('-') : components[0];
    }
    if (!parts[0].length) {
      return false;
    }
    if (options.all_lowercase || options.yahoo_lowercase) {
      parts[0] = parts[0].toLowerCase();
    }
  } else if (options.all_lowercase) {
    // Any other address
    parts[0] = parts[0].toLowerCase();
  }
  return parts.join('@');
}
module.exports = exports['default'];
},{"./isEmail":571,"./util/merge":613}],604:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = rtrim;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function rtrim(str, chars) {
  (0, _assertString2.default)(str);
  var pattern = chars ? new RegExp('[' + chars + ']') : /\s/;

  var idx = str.length - 1;
  while (idx >= 0 && pattern.test(str[idx])) {
    idx--;
  }

  return idx < str.length ? str.substr(0, idx + 1) : str;
}
module.exports = exports['default'];
},{"./util/assertString":612}],605:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = stripLow;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

var _blacklist = require('./blacklist');

var _blacklist2 = _interopRequireDefault(_blacklist);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function stripLow(str, keep_new_lines) {
  (0, _assertString2.default)(str);
  var chars = keep_new_lines ? '\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F' : '\\x00-\\x1F\\x7F';
  return (0, _blacklist2.default)(str, chars);
}
module.exports = exports['default'];
},{"./blacklist":553,"./util/assertString":612}],606:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = toBoolean;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function toBoolean(str, strict) {
  (0, _assertString2.default)(str);
  if (strict) {
    return str === '1' || str === 'true';
  }
  return str !== '0' && str !== 'false' && str !== '';
}
module.exports = exports['default'];
},{"./util/assertString":612}],607:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = toDate;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function toDate(date) {
  (0, _assertString2.default)(date);
  date = Date.parse(date);
  return !isNaN(date) ? new Date(date) : null;
}
module.exports = exports['default'];
},{"./util/assertString":612}],608:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = toFloat;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function toFloat(str) {
  (0, _assertString2.default)(str);
  return parseFloat(str);
}
module.exports = exports['default'];
},{"./util/assertString":612}],609:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = toInt;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function toInt(str, radix) {
  (0, _assertString2.default)(str);
  return parseInt(str, radix || 10);
}
module.exports = exports['default'];
},{"./util/assertString":612}],610:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = trim;

var _rtrim = require('./rtrim');

var _rtrim2 = _interopRequireDefault(_rtrim);

var _ltrim = require('./ltrim');

var _ltrim2 = _interopRequireDefault(_ltrim);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function trim(str, chars) {
  return (0, _rtrim2.default)((0, _ltrim2.default)(str, chars), chars);
}
module.exports = exports['default'];
},{"./ltrim":601,"./rtrim":604}],611:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
      value: true
});
exports.default = unescape;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function unescape(str) {
      (0, _assertString2.default)(str);
      return str.replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#x2F;/g, '/').replace(/&#96;/g, '`');
}
module.exports = exports['default'];
},{"./util/assertString":612}],612:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = assertString;
function assertString(input) {
  if (typeof input !== 'string') {
    throw new TypeError('This library (validator.js) validates strings only');
  }
}
module.exports = exports['default'];
},{}],613:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = merge;
function merge() {
  var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var defaults = arguments[1];

  for (var key in defaults) {
    if (typeof obj[key] === 'undefined') {
      obj[key] = defaults[key];
    }
  }
  return obj;
}
module.exports = exports['default'];
},{}],614:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.default = toString;
function toString(input) {
  if ((typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && input !== null) {
    if (typeof input.toString === 'function') {
      input = input.toString();
    } else {
      input = '[object Object]';
    }
  } else if (input === null || typeof input === 'undefined' || isNaN(input) && !input.length) {
    input = '';
  }
  return String(input);
}
module.exports = exports['default'];
},{}],615:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = whitelist;

var _assertString = require('./util/assertString');

var _assertString2 = _interopRequireDefault(_assertString);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function whitelist(str, chars) {
  (0, _assertString2.default)(str);
  return str.replace(new RegExp('[^' + chars + ']+', 'g'), '');
}
module.exports = exports['default'];
},{"./util/assertString":612}],616:[function(require,module,exports){
(function (global){
!function(t,e){"use strict";"function"==typeof define&&define.amd?define([],function(){return t.Waves=e.call(t),t.Waves}):"object"==typeof exports?module.exports=e.call(t):t.Waves=e.call(t)}("object"==typeof global?global:this,function(){"use strict";function t(t){return null!==t&&t===t.window}function e(e){return t(e)?e:9===e.nodeType&&e.defaultView}function n(t){var e=typeof t;return"function"===e||"object"===e&&!!t}function o(t){return n(t)&&t.nodeType>0}function a(t){var e=f.call(t);return"[object String]"===e?d(t):n(t)&&/^\[object (Array|HTMLCollection|NodeList|Object)\]$/.test(e)&&t.hasOwnProperty("length")?t:o(t)?[t]:[]}function i(t){var n,o,a={top:0,left:0},i=t&&t.ownerDocument;return n=i.documentElement,void 0!==t.getBoundingClientRect&&(a=t.getBoundingClientRect()),o=e(i),{top:a.top+o.pageYOffset-n.clientTop,left:a.left+o.pageXOffset-n.clientLeft}}function r(t){var e="";for(var n in t)t.hasOwnProperty(n)&&(e+=n+":"+t[n]+";");return e}function s(t,e,n){if(n){n.classList.remove("waves-rippling");var o=n.getAttribute("data-x"),a=n.getAttribute("data-y"),i=n.getAttribute("data-scale"),s=n.getAttribute("data-translate"),u=350-(Date.now()-Number(n.getAttribute("data-hold")));u<0&&(u=0),"mousemove"===t.type&&(u=150);var c="mousemove"===t.type?2500:v.duration;setTimeout(function(){var t={top:a+"px",left:o+"px",opacity:"0","-webkit-transition-duration":c+"ms","-moz-transition-duration":c+"ms","-o-transition-duration":c+"ms","transition-duration":c+"ms","-webkit-transform":i+" "+s,"-moz-transform":i+" "+s,"-ms-transform":i+" "+s,"-o-transform":i+" "+s,transform:i+" "+s};n.setAttribute("style",r(t)),setTimeout(function(){try{e.removeChild(n)}catch(t){return!1}},c)},u)}}function u(t){if(!1===h.allowEvent(t))return null;for(var e=null,n=t.target||t.srcElement;n.parentElement;){if(!(n instanceof SVGElement)&&n.classList.contains("waves-effect")){e=n;break}n=n.parentElement}return e}function c(t){var e=u(t);if(null!==e){if(e.disabled||e.getAttribute("disabled")||e.classList.contains("disabled"))return;if(h.registerEvent(t),"touchstart"===t.type&&v.delay){var n=!1,o=setTimeout(function(){o=null,v.show(t,e)},v.delay),a=function(a){o&&(clearTimeout(o),o=null,v.show(t,e)),n||(n=!0,v.hide(a,e)),r()},i=function(t){o&&(clearTimeout(o),o=null),a(t),r()};e.addEventListener("touchmove",i,!1),e.addEventListener("touchend",a,!1),e.addEventListener("touchcancel",a,!1);var r=function(){e.removeEventListener("touchmove",i),e.removeEventListener("touchend",a),e.removeEventListener("touchcancel",a)}}else v.show(t,e),m&&(e.addEventListener("touchend",v.hide,!1),e.addEventListener("touchcancel",v.hide,!1)),e.addEventListener("mouseup",v.hide,!1),e.addEventListener("mouseleave",v.hide,!1)}}var l=l||{},d=document.querySelectorAll.bind(document),f=Object.prototype.toString,m="ontouchstart"in window,v={duration:750,delay:200,show:function(t,e,n){if(2===t.button)return!1;e=e||this;var o=document.createElement("div");o.className="waves-ripple waves-rippling",e.appendChild(o);var a=i(e),s=0,u=0;"touches"in t&&t.touches.length?(s=t.touches[0].pageY-a.top,u=t.touches[0].pageX-a.left):(s=t.pageY-a.top,u=t.pageX-a.left),u=u>=0?u:0,s=s>=0?s:0;var c="scale("+e.clientWidth/100*3+")",l="translate(0,0)";n&&(l="translate("+n.x+"px, "+n.y+"px)"),o.setAttribute("data-hold",Date.now()),o.setAttribute("data-x",u),o.setAttribute("data-y",s),o.setAttribute("data-scale",c),o.setAttribute("data-translate",l);var d={top:s+"px",left:u+"px"};o.classList.add("waves-notransition"),o.setAttribute("style",r(d)),o.classList.remove("waves-notransition"),d["-webkit-transform"]=c+" "+l,d["-moz-transform"]=c+" "+l,d["-ms-transform"]=c+" "+l,d["-o-transform"]=c+" "+l,d.transform=c+" "+l,d.opacity="1";var f="mousemove"===t.type?2500:v.duration;d["-webkit-transition-duration"]=f+"ms",d["-moz-transition-duration"]=f+"ms",d["-o-transition-duration"]=f+"ms",d["transition-duration"]=f+"ms",o.setAttribute("style",r(d))},hide:function(t,e){for(var n=(e=e||this).getElementsByClassName("waves-rippling"),o=0,a=n.length;o<a;o++)s(t,e,n[o]);m&&(e.removeEventListener("touchend",v.hide),e.removeEventListener("touchcancel",v.hide)),e.removeEventListener("mouseup",v.hide),e.removeEventListener("mouseleave",v.hide)}},p={input:function(t){var e=t.parentNode;if("i"!==e.tagName.toLowerCase()||!e.classList.contains("waves-effect")){var n=document.createElement("i");n.className=t.className+" waves-input-wrapper",t.className="waves-button-input",e.replaceChild(n,t),n.appendChild(t);var o=window.getComputedStyle(t,null),a=o.color,i=o.backgroundColor;n.setAttribute("style","color:"+a+";background:"+i),t.setAttribute("style","background-color:rgba(0,0,0,0);")}},img:function(t){var e=t.parentNode;if("i"!==e.tagName.toLowerCase()||!e.classList.contains("waves-effect")){var n=document.createElement("i");e.replaceChild(n,t),n.appendChild(t)}}},h={touches:0,allowEvent:function(t){var e=!0;return/^(mousedown|mousemove)$/.test(t.type)&&h.touches&&(e=!1),e},registerEvent:function(t){var e=t.type;"touchstart"===e?h.touches+=1:/^(touchend|touchcancel)$/.test(e)&&setTimeout(function(){h.touches&&(h.touches-=1)},500)}};return l.init=function(t){var e=document.body;"duration"in(t=t||{})&&(v.duration=t.duration),"delay"in t&&(v.delay=t.delay),m&&(e.addEventListener("touchstart",c,!1),e.addEventListener("touchcancel",h.registerEvent,!1),e.addEventListener("touchend",h.registerEvent,!1)),e.addEventListener("mousedown",c,!1)},l.attach=function(t,e){t=a(t),"[object Array]"===f.call(e)&&(e=e.join(" ")),e=e?" "+e:"";for(var n,o,i=0,r=t.length;i<r;i++)o=(n=t[i]).tagName.toLowerCase(),-1!==["input","img"].indexOf(o)&&(p[o](n),n=n.parentElement),-1===n.className.indexOf("waves-effect")&&(n.className+=" waves-effect"+e)},l.ripple=function(t,e){var n=(t=a(t)).length;if(e=e||{},e.wait=e.wait||0,e.position=e.position||null,n)for(var o,r,s,u={},c=0,l={type:"mousedown",button:1};c<n;c++)if(o=t[c],r=e.position||{x:o.clientWidth/2,y:o.clientHeight/2},s=i(o),u.x=s.left+r.x,u.y=s.top+r.y,l.pageX=u.x,l.pageY=u.y,v.show(l,o),e.wait>=0&&null!==e.wait){var d={type:"mouseup",button:1};setTimeout(function(t,e){return function(){v.hide(t,e)}}(d,o),e.wait)}},l.calm=function(t){for(var e={type:"mouseup",button:1},n=0,o=(t=a(t)).length;n<o;n++)v.hide(e,t[n])},l.displayEffect=function(t){l.init(t)},l});

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],617:[function(require,module,exports){
/*
 * jQuery File Upload Plugin
 * https://github.com/blueimp/jQuery-File-Upload
 *
 * Copyright 2010, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

/* jshint nomen:false */
/* global define, require, window, document, location, Blob, FormData */

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Register as an anonymous AMD module:
        define([
            'jquery',
            'jquery.ui.widget'
        ], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS:
        factory(
            require('jquery'),
            require('./vendor/jquery.ui.widget')
        );
    } else {
        // Browser globals:
        factory(window.jQuery);
    }
}(function ($) {
    'use strict';

    // Detect file input support, based on
    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
    $.support.fileInput = !(new RegExp(
        // Handle devices which give false positives for the feature detection:
        '(Android (1\\.[0156]|2\\.[01]))' +
            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
            '|(w(eb)?OSBrowser)|(webOS)' +
            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
    ).test(window.navigator.userAgent) ||
        // Feature detection for all other devices:
        $('<input type="file">').prop('disabled'));

    // The FileReader API is not actually used, but works as feature detection,
    // as some Safari versions (5?) support XHR file uploads via the FormData API,
    // but not non-multipart XHR file uploads.
    // window.XMLHttpRequestUpload is not available on IE10, so we check for
    // window.ProgressEvent instead to detect XHR2 file upload capability:
    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
    $.support.xhrFormDataFileUpload = !!window.FormData;

    // Detect support for Blob slicing (required for chunked uploads):
    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);

    // Helper function to create drag handlers for dragover/dragenter/dragleave:
    function getDragHandler(type) {
        var isDragOver = type === 'dragover';
        return function (e) {
            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
            var dataTransfer = e.dataTransfer;
            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
                    this._trigger(
                        type,
                        $.Event(type, {delegatedEvent: e})
                    ) !== false) {
                e.preventDefault();
                if (isDragOver) {
                    dataTransfer.dropEffect = 'copy';
                }
            }
        };
    }

    // The fileupload widget listens for change events on file input fields defined
    // via fileInput setting and paste or drop events of the given dropZone.
    // In addition to the default jQuery Widget methods, the fileupload widget
    // exposes the "add" and "send" methods, to add or directly send files using
    // the fileupload API.
    // By default, files added via file input selection, paste, drag & drop or
    // "add" method are uploaded immediately, but it is possible to override
    // the "add" callback option to queue file uploads.
    $.widget('blueimp.fileupload', {

        options: {
            // The drop target element(s), by the default the complete document.
            // Set to null to disable drag & drop support:
            dropZone: $(document),
            // The paste target element(s), by the default undefined.
            // Set to a DOM node or jQuery object to enable file pasting:
            pasteZone: undefined,
            // The file input field(s), that are listened to for change events.
            // If undefined, it is set to the file input fields inside
            // of the widget element on plugin initialization.
            // Set to null to disable the change listener.
            fileInput: undefined,
            // By default, the file input field is replaced with a clone after
            // each input field change event. This is required for iframe transport
            // queues and allows change events to be fired for the same file
            // selection, but can be disabled by setting the following option to false:
            replaceFileInput: true,
            // The parameter name for the file form data (the request argument name).
            // If undefined or empty, the name property of the file input field is
            // used, or "files[]" if the file input name property is also empty,
            // can be a string or an array of strings:
            paramName: undefined,
            // By default, each file of a selection is uploaded using an individual
            // request for XHR type uploads. Set to false to upload file
            // selections in one request each:
            singleFileUploads: true,
            // To limit the number of files uploaded with one XHR request,
            // set the following option to an integer greater than 0:
            limitMultiFileUploads: undefined,
            // The following option limits the number of files uploaded with one
            // XHR request to keep the request size under or equal to the defined
            // limit in bytes:
            limitMultiFileUploadSize: undefined,
            // Multipart file uploads add a number of bytes to each uploaded file,
            // therefore the following option adds an overhead for each file used
            // in the limitMultiFileUploadSize configuration:
            limitMultiFileUploadSizeOverhead: 512,
            // Set the following option to true to issue all file upload requests
            // in a sequential order:
            sequentialUploads: false,
            // To limit the number of concurrent uploads,
            // set the following option to an integer greater than 0:
            limitConcurrentUploads: undefined,
            // Set the following option to true to force iframe transport uploads:
            forceIframeTransport: false,
            // Set the following option to the location of a redirect url on the
            // origin server, for cross-domain iframe transport uploads:
            redirect: undefined,
            // The parameter name for the redirect url, sent as part of the form
            // data and set to 'redirect' if this option is empty:
            redirectParamName: undefined,
            // Set the following option to the location of a postMessage window,
            // to enable postMessage transport uploads:
            postMessage: undefined,
            // By default, XHR file uploads are sent as multipart/form-data.
            // The iframe transport is always using multipart/form-data.
            // Set to false to enable non-multipart XHR uploads:
            multipart: true,
            // To upload large files in smaller chunks, set the following option
            // to a preferred maximum chunk size. If set to 0, null or undefined,
            // or the browser does not support the required Blob API, files will
            // be uploaded as a whole.
            maxChunkSize: undefined,
            // When a non-multipart upload or a chunked multipart upload has been
            // aborted, this option can be used to resume the upload by setting
            // it to the size of the already uploaded bytes. This option is most
            // useful when modifying the options object inside of the "add" or
            // "send" callbacks, as the options are cloned for each file upload.
            uploadedBytes: undefined,
            // By default, failed (abort or error) file uploads are removed from the
            // global progress calculation. Set the following option to false to
            // prevent recalculating the global progress data:
            recalculateProgress: true,
            // Interval in milliseconds to calculate and trigger progress events:
            progressInterval: 100,
            // Interval in milliseconds to calculate progress bitrate:
            bitrateInterval: 500,
            // By default, uploads are started automatically when adding files:
            autoUpload: true,

            // Error and info messages:
            messages: {
                uploadedBytes: 'Uploaded bytes exceed file size'
            },

            // Translation function, gets the message key to be translated
            // and an object with context specific data as arguments:
            i18n: function (message, context) {
                message = this.messages[message] || message.toString();
                if (context) {
                    $.each(context, function (key, value) {
                        message = message.replace('{' + key + '}', value);
                    });
                }
                return message;
            },

            // Additional form data to be sent along with the file uploads can be set
            // using this option, which accepts an array of objects with name and
            // value properties, a function returning such an array, a FormData
            // object (for XHR file uploads), or a simple object.
            // The form of the first fileInput is given as parameter to the function:
            formData: function (form) {
                return form.serializeArray();
            },

            // The add callback is invoked as soon as files are added to the fileupload
            // widget (via file input selection, drag & drop, paste or add API call).
            // If the singleFileUploads option is enabled, this callback will be
            // called once for each file in the selection for XHR file uploads, else
            // once for each file selection.
            //
            // The upload starts when the submit method is invoked on the data parameter.
            // The data object contains a files property holding the added files
            // and allows you to override plugin options as well as define ajax settings.
            //
            // Listeners for this callback can also be bound the following way:
            // .bind('fileuploadadd', func);
            //
            // data.submit() returns a Promise object and allows to attach additional
            // handlers using jQuery's Deferred callbacks:
            // data.submit().done(func).fail(func).always(func);
            add: function (e, data) {
                if (e.isDefaultPrevented()) {
                    return false;
                }
                if (data.autoUpload || (data.autoUpload !== false &&
                        $(this).fileupload('option', 'autoUpload'))) {
                    data.process().done(function () {
                        data.submit();
                    });
                }
            },

            // Other callbacks:

            // Callback for the submit event of each file upload:
            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);

            // Callback for the start of each file upload request:
            // send: function (e, data) {}, // .bind('fileuploadsend', func);

            // Callback for successful uploads:
            // done: function (e, data) {}, // .bind('fileuploaddone', func);

            // Callback for failed (abort or error) uploads:
            // fail: function (e, data) {}, // .bind('fileuploadfail', func);

            // Callback for completed (success, abort or error) requests:
            // always: function (e, data) {}, // .bind('fileuploadalways', func);

            // Callback for upload progress events:
            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);

            // Callback for global upload progress events:
            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);

            // Callback for uploads start, equivalent to the global ajaxStart event:
            // start: function (e) {}, // .bind('fileuploadstart', func);

            // Callback for uploads stop, equivalent to the global ajaxStop event:
            // stop: function (e) {}, // .bind('fileuploadstop', func);

            // Callback for change events of the fileInput(s):
            // change: function (e, data) {}, // .bind('fileuploadchange', func);

            // Callback for paste events to the pasteZone(s):
            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);

            // Callback for drop events of the dropZone(s):
            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);

            // Callback for dragover events of the dropZone(s):
            // dragover: function (e) {}, // .bind('fileuploaddragover', func);

            // Callback for the start of each chunk upload request:
            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);

            // Callback for successful chunk uploads:
            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);

            // Callback for failed (abort or error) chunk uploads:
            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);

            // Callback for completed (success, abort or error) chunk upload requests:
            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);

            // The plugin options are used as settings object for the ajax calls.
            // The following are jQuery ajax settings required for the file uploads:
            processData: false,
            contentType: false,
            cache: false,
            timeout: 0
        },

        // A list of options that require reinitializing event listeners and/or
        // special initialization code:
        _specialOptions: [
            'fileInput',
            'dropZone',
            'pasteZone',
            'multipart',
            'forceIframeTransport'
        ],

        _blobSlice: $.support.blobSlice && function () {
            var slice = this.slice || this.webkitSlice || this.mozSlice;
            return slice.apply(this, arguments);
        },

        _BitrateTimer: function () {
            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
            this.loaded = 0;
            this.bitrate = 0;
            this.getBitrate = function (now, loaded, interval) {
                var timeDiff = now - this.timestamp;
                if (!this.bitrate || !interval || timeDiff > interval) {
                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
                    this.loaded = loaded;
                    this.timestamp = now;
                }
                return this.bitrate;
            };
        },

        _isXHRUpload: function (options) {
            return !options.forceIframeTransport &&
                ((!options.multipart && $.support.xhrFileUpload) ||
                $.support.xhrFormDataFileUpload);
        },

        _getFormData: function (options) {
            var formData;
            if ($.type(options.formData) === 'function') {
                return options.formData(options.form);
            }
            if ($.isArray(options.formData)) {
                return options.formData;
            }
            if ($.type(options.formData) === 'object') {
                formData = [];
                $.each(options.formData, function (name, value) {
                    formData.push({name: name, value: value});
                });
                return formData;
            }
            return [];
        },

        _getTotal: function (files) {
            var total = 0;
            $.each(files, function (index, file) {
                total += file.size || 1;
            });
            return total;
        },

        _initProgressObject: function (obj) {
            var progress = {
                loaded: 0,
                total: 0,
                bitrate: 0
            };
            if (obj._progress) {
                $.extend(obj._progress, progress);
            } else {
                obj._progress = progress;
            }
        },

        _initResponseObject: function (obj) {
            var prop;
            if (obj._response) {
                for (prop in obj._response) {
                    if (obj._response.hasOwnProperty(prop)) {
                        delete obj._response[prop];
                    }
                }
            } else {
                obj._response = {};
            }
        },

        _onProgress: function (e, data) {
            if (e.lengthComputable) {
                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
                    loaded;
                if (data._time && data.progressInterval &&
                        (now - data._time < data.progressInterval) &&
                        e.loaded !== e.total) {
                    return;
                }
                data._time = now;
                loaded = Math.floor(
                    e.loaded / e.total * (data.chunkSize || data._progress.total)
                ) + (data.uploadedBytes || 0);
                // Add the difference from the previously loaded state
                // to the global loaded counter:
                this._progress.loaded += (loaded - data._progress.loaded);
                this._progress.bitrate = this._bitrateTimer.getBitrate(
                    now,
                    this._progress.loaded,
                    data.bitrateInterval
                );
                data._progress.loaded = data.loaded = loaded;
                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
                    now,
                    loaded,
                    data.bitrateInterval
                );
                // Trigger a custom progress event with a total data property set
                // to the file size(s) of the current upload and a loaded data
                // property calculated accordingly:
                this._trigger(
                    'progress',
                    $.Event('progress', {delegatedEvent: e}),
                    data
                );
                // Trigger a global progress event for all current file uploads,
                // including ajax calls queued for sequential file uploads:
                this._trigger(
                    'progressall',
                    $.Event('progressall', {delegatedEvent: e}),
                    this._progress
                );
            }
        },

        _initProgressListener: function (options) {
            var that = this,
                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
            // Accesss to the native XHR object is required to add event listeners
            // for the upload progress event:
            if (xhr.upload) {
                $(xhr.upload).bind('progress', function (e) {
                    var oe = e.originalEvent;
                    // Make sure the progress event properties get copied over:
                    e.lengthComputable = oe.lengthComputable;
                    e.loaded = oe.loaded;
                    e.total = oe.total;
                    that._onProgress(e, options);
                });
                options.xhr = function () {
                    return xhr;
                };
            }
        },

        _isInstanceOf: function (type, obj) {
            // Cross-frame instanceof check
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        },

        _initXHRData: function (options) {
            var that = this,
                formData,
                file = options.files[0],
                // Ignore non-multipart setting if not supported:
                multipart = options.multipart || !$.support.xhrFileUpload,
                paramName = $.type(options.paramName) === 'array' ?
                    options.paramName[0] : options.paramName;
            options.headers = $.extend({}, options.headers);
            if (options.contentRange) {
                options.headers['Content-Range'] = options.contentRange;
            }
            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
                options.headers['Content-Disposition'] = 'attachment; filename="' +
                    encodeURI(file.name) + '"';
            }
            if (!multipart) {
                options.contentType = file.type || 'application/octet-stream';
                options.data = options.blob || file;
            } else if ($.support.xhrFormDataFileUpload) {
                if (options.postMessage) {
                    // window.postMessage does not allow sending FormData
                    // objects, so we just add the File/Blob objects to
                    // the formData array and let the postMessage window
                    // create the FormData object out of this array:
                    formData = this._getFormData(options);
                    if (options.blob) {
                        formData.push({
                            name: paramName,
                            value: options.blob
                        });
                    } else {
                        $.each(options.files, function (index, file) {
                            formData.push({
                                name: ($.type(options.paramName) === 'array' &&
                                    options.paramName[index]) || paramName,
                                value: file
                            });
                        });
                    }
                } else {
                    if (that._isInstanceOf('FormData', options.formData)) {
                        formData = options.formData;
                    } else {
                        formData = new FormData();
                        $.each(this._getFormData(options), function (index, field) {
                            formData.append(field.name, field.value);
                        });
                    }
                    if (options.blob) {
                        formData.append(paramName, options.blob, file.name);
                    } else {
                        $.each(options.files, function (index, file) {
                            // This check allows the tests to run with
                            // dummy objects:
                            if (that._isInstanceOf('File', file) ||
                                    that._isInstanceOf('Blob', file)) {
                                formData.append(
                                    ($.type(options.paramName) === 'array' &&
                                        options.paramName[index]) || paramName,
                                    file,
                                    file.uploadName || file.name
                                );
                            }
                        });
                    }
                }
                options.data = formData;
            }
            // Blob reference is not needed anymore, free memory:
            options.blob = null;
        },

        _initIframeSettings: function (options) {
            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
            // Setting the dataType to iframe enables the iframe transport:
            options.dataType = 'iframe ' + (options.dataType || '');
            // The iframe transport accepts a serialized array as form data:
            options.formData = this._getFormData(options);
            // Add redirect url to form data on cross-domain uploads:
            if (options.redirect && targetHost && targetHost !== location.host) {
                options.formData.push({
                    name: options.redirectParamName || 'redirect',
                    value: options.redirect
                });
            }
        },

        _initDataSettings: function (options) {
            if (this._isXHRUpload(options)) {
                if (!this._chunkedUpload(options, true)) {
                    if (!options.data) {
                        this._initXHRData(options);
                    }
                    this._initProgressListener(options);
                }
                if (options.postMessage) {
                    // Setting the dataType to postmessage enables the
                    // postMessage transport:
                    options.dataType = 'postmessage ' + (options.dataType || '');
                }
            } else {
                this._initIframeSettings(options);
            }
        },

        _getParamName: function (options) {
            var fileInput = $(options.fileInput),
                paramName = options.paramName;
            if (!paramName) {
                paramName = [];
                fileInput.each(function () {
                    var input = $(this),
                        name = input.prop('name') || 'files[]',
                        i = (input.prop('files') || [1]).length;
                    while (i) {
                        paramName.push(name);
                        i -= 1;
                    }
                });
                if (!paramName.length) {
                    paramName = [fileInput.prop('name') || 'files[]'];
                }
            } else if (!$.isArray(paramName)) {
                paramName = [paramName];
            }
            return paramName;
        },

        _initFormSettings: function (options) {
            // Retrieve missing options from the input field and the
            // associated form, if available:
            if (!options.form || !options.form.length) {
                options.form = $(options.fileInput.prop('form'));
                // If the given file input doesn't have an associated form,
                // use the default widget file input's form:
                if (!options.form.length) {
                    options.form = $(this.options.fileInput.prop('form'));
                }
            }
            options.paramName = this._getParamName(options);
            if (!options.url) {
                options.url = options.form.prop('action') || location.href;
            }
            // The HTTP request method must be "POST" or "PUT":
            options.type = (options.type ||
                ($.type(options.form.prop('method')) === 'string' &&
                    options.form.prop('method')) || ''
                ).toUpperCase();
            if (options.type !== 'POST' && options.type !== 'PUT' &&
                    options.type !== 'PATCH') {
                options.type = 'POST';
            }
            if (!options.formAcceptCharset) {
                options.formAcceptCharset = options.form.attr('accept-charset');
            }
        },

        _getAJAXSettings: function (data) {
            var options = $.extend({}, this.options, data);
            this._initFormSettings(options);
            this._initDataSettings(options);
            return options;
        },

        // jQuery 1.6 doesn't provide .state(),
        // while jQuery 1.8+ removed .isRejected() and .isResolved():
        _getDeferredState: function (deferred) {
            if (deferred.state) {
                return deferred.state();
            }
            if (deferred.isResolved()) {
                return 'resolved';
            }
            if (deferred.isRejected()) {
                return 'rejected';
            }
            return 'pending';
        },

        // Maps jqXHR callbacks to the equivalent
        // methods of the given Promise object:
        _enhancePromise: function (promise) {
            promise.success = promise.done;
            promise.error = promise.fail;
            promise.complete = promise.always;
            return promise;
        },

        // Creates and returns a Promise object enhanced with
        // the jqXHR methods abort, success, error and complete:
        _getXHRPromise: function (resolveOrReject, context, args) {
            var dfd = $.Deferred(),
                promise = dfd.promise();
            context = context || this.options.context || promise;
            if (resolveOrReject === true) {
                dfd.resolveWith(context, args);
            } else if (resolveOrReject === false) {
                dfd.rejectWith(context, args);
            }
            promise.abort = dfd.promise;
            return this._enhancePromise(promise);
        },

        // Adds convenience methods to the data callback argument:
        _addConvenienceMethods: function (e, data) {
            var that = this,
                getPromise = function (args) {
                    return $.Deferred().resolveWith(that, args).promise();
                };
            data.process = function (resolveFunc, rejectFunc) {
                if (resolveFunc || rejectFunc) {
                    data._processQueue = this._processQueue =
                        (this._processQueue || getPromise([this])).pipe(
                            function () {
                                if (data.errorThrown) {
                                    return $.Deferred()
                                        .rejectWith(that, [data]).promise();
                                }
                                return getPromise(arguments);
                            }
                        ).pipe(resolveFunc, rejectFunc);
                }
                return this._processQueue || getPromise([this]);
            };
            data.submit = function () {
                if (this.state() !== 'pending') {
                    data.jqXHR = this.jqXHR =
                        (that._trigger(
                            'submit',
                            $.Event('submit', {delegatedEvent: e}),
                            this
                        ) !== false) && that._onSend(e, this);
                }
                return this.jqXHR || that._getXHRPromise();
            };
            data.abort = function () {
                if (this.jqXHR) {
                    return this.jqXHR.abort();
                }
                this.errorThrown = 'abort';
                that._trigger('fail', null, this);
                return that._getXHRPromise(false);
            };
            data.state = function () {
                if (this.jqXHR) {
                    return that._getDeferredState(this.jqXHR);
                }
                if (this._processQueue) {
                    return that._getDeferredState(this._processQueue);
                }
            };
            data.processing = function () {
                return !this.jqXHR && this._processQueue && that
                    ._getDeferredState(this._processQueue) === 'pending';
            };
            data.progress = function () {
                return this._progress;
            };
            data.response = function () {
                return this._response;
            };
        },

        // Parses the Range header from the server response
        // and returns the uploaded bytes:
        _getUploadedBytes: function (jqXHR) {
            var range = jqXHR.getResponseHeader('Range'),
                parts = range && range.split('-'),
                upperBytesPos = parts && parts.length > 1 &&
                    parseInt(parts[1], 10);
            return upperBytesPos && upperBytesPos + 1;
        },

        // Uploads a file in multiple, sequential requests
        // by splitting the file up in multiple blob chunks.
        // If the second parameter is true, only tests if the file
        // should be uploaded in chunks, but does not invoke any
        // upload requests:
        _chunkedUpload: function (options, testOnly) {
            options.uploadedBytes = options.uploadedBytes || 0;
            var that = this,
                file = options.files[0],
                fs = file.size,
                ub = options.uploadedBytes,
                mcs = options.maxChunkSize || fs,
                slice = this._blobSlice,
                dfd = $.Deferred(),
                promise = dfd.promise(),
                jqXHR,
                upload;
            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
                    options.data) {
                return false;
            }
            if (testOnly) {
                return true;
            }
            if (ub >= fs) {
                file.error = options.i18n('uploadedBytes');
                return this._getXHRPromise(
                    false,
                    options.context,
                    [null, 'error', file.error]
                );
            }
            // The chunk upload method:
            upload = function () {
                // Clone the options object for each chunk upload:
                var o = $.extend({}, options),
                    currentLoaded = o._progress.loaded;
                o.blob = slice.call(
                    file,
                    ub,
                    ub + mcs,
                    file.type
                );
                // Store the current chunk size, as the blob itself
                // will be dereferenced after data processing:
                o.chunkSize = o.blob.size;
                // Expose the chunk bytes position range:
                o.contentRange = 'bytes ' + ub + '-' +
                    (ub + o.chunkSize - 1) + '/' + fs;
                // Process the upload data (the blob and potential form data):
                that._initXHRData(o);
                // Add progress listeners for this chunk upload:
                that._initProgressListener(o);
                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
                        that._getXHRPromise(false, o.context))
                    .done(function (result, textStatus, jqXHR) {
                        ub = that._getUploadedBytes(jqXHR) ||
                            (ub + o.chunkSize);
                        // Create a progress event if no final progress event
                        // with loaded equaling total has been triggered
                        // for this chunk:
                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
                            that._onProgress($.Event('progress', {
                                lengthComputable: true,
                                loaded: ub - o.uploadedBytes,
                                total: ub - o.uploadedBytes
                            }), o);
                        }
                        options.uploadedBytes = o.uploadedBytes = ub;
                        o.result = result;
                        o.textStatus = textStatus;
                        o.jqXHR = jqXHR;
                        that._trigger('chunkdone', null, o);
                        that._trigger('chunkalways', null, o);
                        if (ub < fs) {
                            // File upload not yet complete,
                            // continue with the next chunk:
                            upload();
                        } else {
                            dfd.resolveWith(
                                o.context,
                                [result, textStatus, jqXHR]
                            );
                        }
                    })
                    .fail(function (jqXHR, textStatus, errorThrown) {
                        o.jqXHR = jqXHR;
                        o.textStatus = textStatus;
                        o.errorThrown = errorThrown;
                        that._trigger('chunkfail', null, o);
                        that._trigger('chunkalways', null, o);
                        dfd.rejectWith(
                            o.context,
                            [jqXHR, textStatus, errorThrown]
                        );
                    });
            };
            this._enhancePromise(promise);
            promise.abort = function () {
                return jqXHR.abort();
            };
            upload();
            return promise;
        },

        _beforeSend: function (e, data) {
            if (this._active === 0) {
                // the start callback is triggered when an upload starts
                // and no other uploads are currently running,
                // equivalent to the global ajaxStart event:
                this._trigger('start');
                // Set timer for global bitrate progress calculation:
                this._bitrateTimer = new this._BitrateTimer();
                // Reset the global progress values:
                this._progress.loaded = this._progress.total = 0;
                this._progress.bitrate = 0;
            }
            // Make sure the container objects for the .response() and
            // .progress() methods on the data object are available
            // and reset to their initial state:
            this._initResponseObject(data);
            this._initProgressObject(data);
            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
            data._progress.total = data.total = this._getTotal(data.files) || 1;
            data._progress.bitrate = data.bitrate = 0;
            this._active += 1;
            // Initialize the global progress values:
            this._progress.loaded += data.loaded;
            this._progress.total += data.total;
        },

        _onDone: function (result, textStatus, jqXHR, options) {
            var total = options._progress.total,
                response = options._response;
            if (options._progress.loaded < total) {
                // Create a progress event if no final progress event
                // with loaded equaling total has been triggered:
                this._onProgress($.Event('progress', {
                    lengthComputable: true,
                    loaded: total,
                    total: total
                }), options);
            }
            response.result = options.result = result;
            response.textStatus = options.textStatus = textStatus;
            response.jqXHR = options.jqXHR = jqXHR;
            this._trigger('done', null, options);
        },

        _onFail: function (jqXHR, textStatus, errorThrown, options) {
            var response = options._response;
            if (options.recalculateProgress) {
                // Remove the failed (error or abort) file upload from
                // the global progress calculation:
                this._progress.loaded -= options._progress.loaded;
                this._progress.total -= options._progress.total;
            }
            response.jqXHR = options.jqXHR = jqXHR;
            response.textStatus = options.textStatus = textStatus;
            response.errorThrown = options.errorThrown = errorThrown;
            this._trigger('fail', null, options);
        },

        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
            // jqXHRorResult, textStatus and jqXHRorError are added to the
            // options object via done and fail callbacks
            this._trigger('always', null, options);
        },

        _onSend: function (e, data) {
            if (!data.submit) {
                this._addConvenienceMethods(e, data);
            }
            var that = this,
                jqXHR,
                aborted,
                slot,
                pipe,
                options = that._getAJAXSettings(data),
                send = function () {
                    that._sending += 1;
                    // Set timer for bitrate progress calculation:
                    options._bitrateTimer = new that._BitrateTimer();
                    jqXHR = jqXHR || (
                        ((aborted || that._trigger(
                            'send',
                            $.Event('send', {delegatedEvent: e}),
                            options
                        ) === false) &&
                        that._getXHRPromise(false, options.context, aborted)) ||
                        that._chunkedUpload(options) || $.ajax(options)
                    ).done(function (result, textStatus, jqXHR) {
                        that._onDone(result, textStatus, jqXHR, options);
                    }).fail(function (jqXHR, textStatus, errorThrown) {
                        that._onFail(jqXHR, textStatus, errorThrown, options);
                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
                        that._onAlways(
                            jqXHRorResult,
                            textStatus,
                            jqXHRorError,
                            options
                        );
                        that._sending -= 1;
                        that._active -= 1;
                        if (options.limitConcurrentUploads &&
                                options.limitConcurrentUploads > that._sending) {
                            // Start the next queued upload,
                            // that has not been aborted:
                            var nextSlot = that._slots.shift();
                            while (nextSlot) {
                                if (that._getDeferredState(nextSlot) === 'pending') {
                                    nextSlot.resolve();
                                    break;
                                }
                                nextSlot = that._slots.shift();
                            }
                        }
                        if (that._active === 0) {
                            // The stop callback is triggered when all uploads have
                            // been completed, equivalent to the global ajaxStop event:
                            that._trigger('stop');
                        }
                    });
                    return jqXHR;
                };
            this._beforeSend(e, options);
            if (this.options.sequentialUploads ||
                    (this.options.limitConcurrentUploads &&
                    this.options.limitConcurrentUploads <= this._sending)) {
                if (this.options.limitConcurrentUploads > 1) {
                    slot = $.Deferred();
                    this._slots.push(slot);
                    pipe = slot.pipe(send);
                } else {
                    this._sequence = this._sequence.pipe(send, send);
                    pipe = this._sequence;
                }
                // Return the piped Promise object, enhanced with an abort method,
                // which is delegated to the jqXHR object of the current upload,
                // and jqXHR callbacks mapped to the equivalent Promise methods:
                pipe.abort = function () {
                    aborted = [undefined, 'abort', 'abort'];
                    if (!jqXHR) {
                        if (slot) {
                            slot.rejectWith(options.context, aborted);
                        }
                        return send();
                    }
                    return jqXHR.abort();
                };
                return this._enhancePromise(pipe);
            }
            return send();
        },

        _onAdd: function (e, data) {
            var that = this,
                result = true,
                options = $.extend({}, this.options, data),
                files = data.files,
                filesLength = files.length,
                limit = options.limitMultiFileUploads,
                limitSize = options.limitMultiFileUploadSize,
                overhead = options.limitMultiFileUploadSizeOverhead,
                batchSize = 0,
                paramName = this._getParamName(options),
                paramNameSet,
                paramNameSlice,
                fileSet,
                i,
                j = 0;
            if (!filesLength) {
                return false;
            }
            if (limitSize && files[0].size === undefined) {
                limitSize = undefined;
            }
            if (!(options.singleFileUploads || limit || limitSize) ||
                    !this._isXHRUpload(options)) {
                fileSet = [files];
                paramNameSet = [paramName];
            } else if (!(options.singleFileUploads || limitSize) && limit) {
                fileSet = [];
                paramNameSet = [];
                for (i = 0; i < filesLength; i += limit) {
                    fileSet.push(files.slice(i, i + limit));
                    paramNameSlice = paramName.slice(i, i + limit);
                    if (!paramNameSlice.length) {
                        paramNameSlice = paramName;
                    }
                    paramNameSet.push(paramNameSlice);
                }
            } else if (!options.singleFileUploads && limitSize) {
                fileSet = [];
                paramNameSet = [];
                for (i = 0; i < filesLength; i = i + 1) {
                    batchSize += files[i].size + overhead;
                    if (i + 1 === filesLength ||
                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
                            (limit && i + 1 - j >= limit)) {
                        fileSet.push(files.slice(j, i + 1));
                        paramNameSlice = paramName.slice(j, i + 1);
                        if (!paramNameSlice.length) {
                            paramNameSlice = paramName;
                        }
                        paramNameSet.push(paramNameSlice);
                        j = i + 1;
                        batchSize = 0;
                    }
                }
            } else {
                paramNameSet = paramName;
            }
            data.originalFiles = files;
            $.each(fileSet || files, function (index, element) {
                var newData = $.extend({}, data);
                newData.files = fileSet ? element : [element];
                newData.paramName = paramNameSet[index];
                that._initResponseObject(newData);
                that._initProgressObject(newData);
                that._addConvenienceMethods(e, newData);
                result = that._trigger(
                    'add',
                    $.Event('add', {delegatedEvent: e}),
                    newData
                );
                return result;
            });
            return result;
        },

        _replaceFileInput: function (data) {
            var input = data.fileInput,
                inputClone = input.clone(true),
                restoreFocus = input.is(document.activeElement);
            // Add a reference for the new cloned file input to the data argument:
            data.fileInputClone = inputClone;
            $('<form></form>').append(inputClone)[0].reset();
            // Detaching allows to insert the fileInput on another form
            // without loosing the file input value:
            input.after(inputClone).detach();
            // If the fileInput had focus before it was detached,
            // restore focus to the inputClone.
            if (restoreFocus) {
                inputClone.focus();
            }
            // Avoid memory leaks with the detached file input:
            $.cleanData(input.unbind('remove'));
            // Replace the original file input element in the fileInput
            // elements set with the clone, which has been copied including
            // event handlers:
            this.options.fileInput = this.options.fileInput.map(function (i, el) {
                if (el === input[0]) {
                    return inputClone[0];
                }
                return el;
            });
            // If the widget has been initialized on the file input itself,
            // override this.element with the file input clone:
            if (input[0] === this.element[0]) {
                this.element = inputClone;
            }
        },

        _handleFileTreeEntry: function (entry, path) {
            var that = this,
                dfd = $.Deferred(),
                errorHandler = function (e) {
                    if (e && !e.entry) {
                        e.entry = entry;
                    }
                    // Since $.when returns immediately if one
                    // Deferred is rejected, we use resolve instead.
                    // This allows valid files and invalid items
                    // to be returned together in one set:
                    dfd.resolve([e]);
                },
                successHandler = function (entries) {
                    that._handleFileTreeEntries(
                        entries,
                        path + entry.name + '/'
                    ).done(function (files) {
                        dfd.resolve(files);
                    }).fail(errorHandler);
                },
                readEntries = function () {
                    dirReader.readEntries(function (results) {
                        if (!results.length) {
                            successHandler(entries);
                        } else {
                            entries = entries.concat(results);
                            readEntries();
                        }
                    }, errorHandler);
                },
                dirReader, entries = [];
            path = path || '';
            if (entry.isFile) {
                if (entry._file) {
                    // Workaround for Chrome bug #149735
                    entry._file.relativePath = path;
                    dfd.resolve(entry._file);
                } else {
                    entry.file(function (file) {
                        file.relativePath = path;
                        dfd.resolve(file);
                    }, errorHandler);
                }
            } else if (entry.isDirectory) {
                dirReader = entry.createReader();
                readEntries();
            } else {
                // Return an empy list for file system items
                // other than files or directories:
                dfd.resolve([]);
            }
            return dfd.promise();
        },

        _handleFileTreeEntries: function (entries, path) {
            var that = this;
            return $.when.apply(
                $,
                $.map(entries, function (entry) {
                    return that._handleFileTreeEntry(entry, path);
                })
            ).pipe(function () {
                return Array.prototype.concat.apply(
                    [],
                    arguments
                );
            });
        },

        _getDroppedFiles: function (dataTransfer) {
            dataTransfer = dataTransfer || {};
            var items = dataTransfer.items;
            if (items && items.length && (items[0].webkitGetAsEntry ||
                    items[0].getAsEntry)) {
                return this._handleFileTreeEntries(
                    $.map(items, function (item) {
                        var entry;
                        if (item.webkitGetAsEntry) {
                            entry = item.webkitGetAsEntry();
                            if (entry) {
                                // Workaround for Chrome bug #149735:
                                entry._file = item.getAsFile();
                            }
                            return entry;
                        }
                        return item.getAsEntry();
                    })
                );
            }
            return $.Deferred().resolve(
                $.makeArray(dataTransfer.files)
            ).promise();
        },

        _getSingleFileInputFiles: function (fileInput) {
            fileInput = $(fileInput);
            var entries = fileInput.prop('webkitEntries') ||
                    fileInput.prop('entries'),
                files,
                value;
            if (entries && entries.length) {
                return this._handleFileTreeEntries(entries);
            }
            files = $.makeArray(fileInput.prop('files'));
            if (!files.length) {
                value = fileInput.prop('value');
                if (!value) {
                    return $.Deferred().resolve([]).promise();
                }
                // If the files property is not available, the browser does not
                // support the File API and we add a pseudo File object with
                // the input value as name with path information removed:
                files = [{name: value.replace(/^.*\\/, '')}];
            } else if (files[0].name === undefined && files[0].fileName) {
                // File normalization for Safari 4 and Firefox 3:
                $.each(files, function (index, file) {
                    file.name = file.fileName;
                    file.size = file.fileSize;
                });
            }
            return $.Deferred().resolve(files).promise();
        },

        _getFileInputFiles: function (fileInput) {
            if (!(fileInput instanceof $) || fileInput.length === 1) {
                return this._getSingleFileInputFiles(fileInput);
            }
            return $.when.apply(
                $,
                $.map(fileInput, this._getSingleFileInputFiles)
            ).pipe(function () {
                return Array.prototype.concat.apply(
                    [],
                    arguments
                );
            });
        },

        _onChange: function (e) {
            var that = this,
                data = {
                    fileInput: $(e.target),
                    form: $(e.target.form)
                };
            this._getFileInputFiles(data.fileInput).always(function (files) {
                data.files = files;
                if (that.options.replaceFileInput) {
                    that._replaceFileInput(data);
                }
                if (that._trigger(
                        'change',
                        $.Event('change', {delegatedEvent: e}),
                        data
                    ) !== false) {
                    that._onAdd(e, data);
                }
            });
        },

        _onPaste: function (e) {
            var items = e.originalEvent && e.originalEvent.clipboardData &&
                    e.originalEvent.clipboardData.items,
                data = {files: []};
            if (items && items.length) {
                $.each(items, function (index, item) {
                    var file = item.getAsFile && item.getAsFile();
                    if (file) {
                        data.files.push(file);
                    }
                });
                if (this._trigger(
                        'paste',
                        $.Event('paste', {delegatedEvent: e}),
                        data
                    ) !== false) {
                    this._onAdd(e, data);
                }
            }
        },

        _onDrop: function (e) {
            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
            var that = this,
                dataTransfer = e.dataTransfer,
                data = {};
            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
                e.preventDefault();
                this._getDroppedFiles(dataTransfer).always(function (files) {
                    data.files = files;
                    if (that._trigger(
                            'drop',
                            $.Event('drop', {delegatedEvent: e}),
                            data
                        ) !== false) {
                        that._onAdd(e, data);
                    }
                });
            }
        },

        _onDragOver: getDragHandler('dragover'),

        _onDragEnter: getDragHandler('dragenter'),

        _onDragLeave: getDragHandler('dragleave'),

        _initEventHandlers: function () {
            if (this._isXHRUpload(this.options)) {
                this._on(this.options.dropZone, {
                    dragover: this._onDragOver,
                    drop: this._onDrop,
                    // event.preventDefault() on dragenter is required for IE10+:
                    dragenter: this._onDragEnter,
                    // dragleave is not required, but added for completeness:
                    dragleave: this._onDragLeave
                });
                this._on(this.options.pasteZone, {
                    paste: this._onPaste
                });
            }
            if ($.support.fileInput) {
                this._on(this.options.fileInput, {
                    change: this._onChange
                });
            }
        },

        _destroyEventHandlers: function () {
            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
            this._off(this.options.pasteZone, 'paste');
            this._off(this.options.fileInput, 'change');
        },

        _setOption: function (key, value) {
            var reinit = $.inArray(key, this._specialOptions) !== -1;
            if (reinit) {
                this._destroyEventHandlers();
            }
            this._super(key, value);
            if (reinit) {
                this._initSpecialOptions();
                this._initEventHandlers();
            }
        },

        _initSpecialOptions: function () {
            var options = this.options;
            if (options.fileInput === undefined) {
                options.fileInput = this.element.is('input[type="file"]') ?
                        this.element : this.element.find('input[type="file"]');
            } else if (!(options.fileInput instanceof $)) {
                options.fileInput = $(options.fileInput);
            }
            if (!(options.dropZone instanceof $)) {
                options.dropZone = $(options.dropZone);
            }
            if (!(options.pasteZone instanceof $)) {
                options.pasteZone = $(options.pasteZone);
            }
        },

        _getRegExp: function (str) {
            var parts = str.split('/'),
                modifiers = parts.pop();
            parts.shift();
            return new RegExp(parts.join('/'), modifiers);
        },

        _isRegExpOption: function (key, value) {
            return key !== 'url' && $.type(value) === 'string' &&
                /^\/.*\/[igm]{0,3}$/.test(value);
        },

        _initDataAttributes: function () {
            var that = this,
                options = this.options,
                data = this.element.data();
            // Initialize options set via HTML5 data-attributes:
            $.each(
                this.element[0].attributes,
                function (index, attr) {
                    var key = attr.name.toLowerCase(),
                        value;
                    if (/^data-/.test(key)) {
                        // Convert hyphen-ated key to camelCase:
                        key = key.slice(5).replace(/-[a-z]/g, function (str) {
                            return str.charAt(1).toUpperCase();
                        });
                        value = data[key];
                        if (that._isRegExpOption(key, value)) {
                            value = that._getRegExp(value);
                        }
                        options[key] = value;
                    }
                }
            );
        },

        _create: function () {
            this._initDataAttributes();
            this._initSpecialOptions();
            this._slots = [];
            this._sequence = this._getXHRPromise(true);
            this._sending = this._active = 0;
            this._initProgressObject(this);
            this._initEventHandlers();
        },

        // This method is exposed to the widget API and allows to query
        // the number of active uploads:
        active: function () {
            return this._active;
        },

        // This method is exposed to the widget API and allows to query
        // the widget upload progress.
        // It returns an object with loaded, total and bitrate properties
        // for the running uploads:
        progress: function () {
            return this._progress;
        },

        // This method is exposed to the widget API and allows adding files
        // using the fileupload API. The data parameter accepts an object which
        // must have a files property and can contain additional options:
        // .fileupload('add', {files: filesList});
        add: function (data) {
            var that = this;
            if (!data || this.options.disabled) {
                return;
            }
            if (data.fileInput && !data.files) {
                this._getFileInputFiles(data.fileInput).always(function (files) {
                    data.files = files;
                    that._onAdd(null, data);
                });
            } else {
                data.files = $.makeArray(data.files);
                this._onAdd(null, data);
            }
        },

        // This method is exposed to the widget API and allows sending files
        // using the fileupload API. The data parameter accepts an object which
        // must have a files or fileInput property and can contain additional options:
        // .fileupload('send', {files: filesList});
        // The method returns a Promise object for the file upload call.
        send: function (data) {
            if (data && !this.options.disabled) {
                if (data.fileInput && !data.files) {
                    var that = this,
                        dfd = $.Deferred(),
                        promise = dfd.promise(),
                        jqXHR,
                        aborted;
                    promise.abort = function () {
                        aborted = true;
                        if (jqXHR) {
                            return jqXHR.abort();
                        }
                        dfd.reject(null, 'abort', 'abort');
                        return promise;
                    };
                    this._getFileInputFiles(data.fileInput).always(
                        function (files) {
                            if (aborted) {
                                return;
                            }
                            if (!files.length) {
                                dfd.reject();
                                return;
                            }
                            data.files = files;
                            jqXHR = that._onSend(null, data);
                            jqXHR.then(
                                function (result, textStatus, jqXHR) {
                                    dfd.resolve(result, textStatus, jqXHR);
                                },
                                function (jqXHR, textStatus, errorThrown) {
                                    dfd.reject(jqXHR, textStatus, errorThrown);
                                }
                            );
                        }
                    );
                    return this._enhancePromise(promise);
                }
                data.files = $.makeArray(data.files);
                if (data.files.length) {
                    return this._onSend(null, data);
                }
            }
            return this._getXHRPromise(false, data && data.context);
        }

    });

}));

},{"./vendor/jquery.ui.widget":618,"jquery":628}],618:[function(require,module,exports){
/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28
* http://jqueryui.com
* Includes: widget.js
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */

(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([ "jquery" ], factory );

	} else if ( typeof exports === "object" ) {

		// Node/CommonJS
		factory( require( "jquery" ) );

	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {
/*!
 * jQuery UI Widget 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/jQuery.widget/
 */


var widget_uuid = 0,
	widget_slice = Array.prototype.slice;

$.cleanData = (function( orig ) {
	return function( elems ) {
		var events, elem, i;
		for ( i = 0; (elem = elems[i]) != null; i++ ) {
			try {

				// Only trigger remove when necessary to save time
				events = $._data( elem, "events" );
				if ( events && events.remove ) {
					$( elem ).triggerHandler( "remove" );
				}

			// http://bugs.jquery.com/ticket/8235
			} catch ( e ) {}
		}
		orig( elems );
	};
})( $.cleanData );

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		// proxiedPrototype allows the provided prototype to remain unmodified
		// so that it can be used as a mixin for multiple widgets (#8876)
		proxiedPrototype = {},
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( !$.isFunction( value ) ) {
			proxiedPrototype[ prop ] = value;
			return;
		}
		proxiedPrototype[ prop ] = (function() {
			var _super = function() {
					return base.prototype[ prop ].apply( this, arguments );
				},
				_superApply = function( args ) {
					return base.prototype[ prop ].apply( this, args );
				};
			return function() {
				var __super = this._super,
					__superApply = this._superApply,
					returnValue;

				this._super = _super;
				this._superApply = _superApply;

				returnValue = value.apply( this, arguments );

				this._super = __super;
				this._superApply = __superApply;

				return returnValue;
			};
		})();
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
	}, proxiedPrototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );

	return constructor;
};

$.widget.extend = function( target ) {
	var input = widget_slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = widget_slice.call( arguments, 1 ),
			returnValue = this;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( options === "instance" ) {
					returnValue = instance;
					return false;
				}
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {

			// Allow multiple hashes to be passed on init
			if ( args.length ) {
				options = $.widget.extend.apply( null, [ options ].concat(args) );
			}

			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} );
					if ( instance._init ) {
						instance._init();
					}
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = widget_uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( arguments.length === 1 ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( arguments.length === 1 ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled", !!value );

			// If the widget is becoming disabled, then nothing is interactive
			if ( value ) {
				this.hoverable.removeClass( "ui-state-hover" );
				this.focusable.removeClass( "ui-state-focus" );
			}
		}

		return this;
	},

	enable: function() {
		return this._setOptions({ disabled: false });
	},
	disable: function() {
		return this._setOptions({ disabled: true });
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
			this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );

		// Clear the stack to avoid memory leaks (#10056)
		this.bindings = $( this.bindings.not( element ).get() );
		this.focusable = $( this.focusable.not( element ).get() );
		this.hoverable = $( this.hoverable.not( element ).get() );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

var widget = $.widget;



}));

},{"jquery":628}],619:[function(require,module,exports){
(function (global){
/*!
 * clipboard.js v1.7.1
 * https://zenorocha.github.io/clipboard.js
 *
 * Licensed MIT © Zeno Rocha
 */
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n||t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(t,e,n){function o(t,e){for(;t&&t.nodeType!==i;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var i=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}e.exports=o},{}],2:[function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function i(t,e,n,o){return function(n){n.delegateTarget=r(n.target,e),n.delegateTarget&&o.call(t,n)}}var r=t("./closest");e.exports=o},{"./closest":1}],3:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},{}],4:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return i(t,e,n);if(c.nodeList(t))return r(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function r(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return l(document.body,t,e,n)}var c=t("./is"),l=t("delegate");e.exports=o},{"./is":3,delegate:2}],5:[function(t,e,n){function o(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),i=document.createRange();i.selectNodeContents(t),o.removeAllRanges(),o.addRange(i),e=o.toString()}return e}e.exports=o},{}],6:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){i.off(t,o),e.apply(n,arguments)}var i=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;for(o;o<i;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;r<a;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],7:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if(void 0!==o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),c=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return a(t,[{key:"resolveOptions",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function t(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function t(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function t(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:"copyText",value:function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function t(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function t(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function t(){this.removeFake()}},{key:"action",set:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:5}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if(void 0!==o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function l(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var s=i(e),u=i(n),f=i(o),d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),p=function(t){function e(t,n){r(this,e);var o=a(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return o.resolveOptions(n),o.listenClick(t),o}return c(e,t),h(e,[{key:"resolveOptions",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===d(e.container)?e.container:document.body}},{key:"listenClick",value:function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})}},{key:"onClick",value:function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),container:this.container,trigger:n,emitter:this})}},{key:"defaultAction",value:function t(e){return l("action",e)}},{key:"defaultTarget",value:function t(e){var n=l("target",e);if(n)return document.querySelector(n)}},{key:"defaultText",value:function t(e){return l("text",e)}},{key:"destroy",value:function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],n="string"==typeof e?[e]:e,o=!!document.queryCommandSupported;return n.forEach(function(t){o=o&&!!document.queryCommandSupported(t)}),o}}]),e}(u.default);t.exports=p})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)});
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],620:[function(require,module,exports){
/* jshint -W071, -W074 */
/* global jQuery:false */

/* Disabled options are:
 * W071: This function has too many statements
 * W074: This function's cyclomatic complexity is too high
 */

/*
 *	jQuery ezPlus 1.1.11
 *	Demo's and documentation:
 *	http://igorlino.github.io/elevatezoom-plus/
 *
 *	licensed under MIT license.
 *	http://en.wikipedia.org/wiki/MIT_License
 *
 */

if (typeof Object.create !== 'function') {
    Object.create = function (obj) {
        function F() {
        }

        F.prototype = obj;
        return new F();
    };
}

(function ($, window, document, undefined) {
    var EZP = {
        init: function (options, elem) {
            var self = this;
            var $galleries;

            self.elem = elem;
            self.$elem = $(elem);

            self.imageSrc = self.$elem.data('zoom-image') ? self.$elem.data('zoom-image') : self.$elem.attr('src');

            self.options = $.extend({}, $.fn.ezPlus.options, self.responsiveConfig(options || {}));

            if (!self.options.enabled) {
                return;
            }

            //TINT OVERRIDE SETTINGS
            if (self.options.tint) {
                self.options.lensColour = 'none'; //colour of the lens background
                self.options.lensOpacity = '1'; //opacity of the lens
            }
            //INNER OVERRIDE SETTINGS
            if (self.options.zoomType === 'inner') {
                self.options.showLens = false;
            }

            //UUID WHEN MISSING IDENTIFIER
            if (self.options.zoomId === -1) {
                self.options.zoomId = generateUUID();
            }


            //Remove alt on hover

            self.$elem.parent().removeAttr('title').removeAttr('alt');

            self.zoomImage = self.imageSrc;

            self.refresh(1);

            //Create the image swap from the gallery
            $galleries = $(self.options.gallery ? ('#' + self.options.gallery) : self.options.gallerySelector);
            $galleries.on('click.zoom', self.options.galleryItem, function (e) {

                //Set a class on the currently active gallery image
                if (self.options.galleryActiveClass) {
                    $(self.options.galleryItem, $galleries).removeClass(self.options.galleryActiveClass);
                    $(this).addClass(self.options.galleryActiveClass);
                }
                //stop any link on the a tag from working
                if (this.tagName === 'A') {
                    e.preventDefault();
                }

                //call the swap image function
                if ($(this).data('zoom-image')) {
                    self.zoomImagePre = $(this).data('zoom-image');
                }
                else {
                    self.zoomImagePre = $(this).data('image');
                }
                self.swaptheimage($(this).data('image'), self.zoomImagePre);
                if (this.tagName === 'A') {
                    return false;
                }
            });

            function generateUUID() {
                var d = new Date().getTime();
                var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                    var r = (d + Math.random() * 16) % 16 | 0;
                    d = Math.floor(d / 16);
                    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
                });
                return uuid;
            }
        },
        refresh: function (length) {
            var self = this;

            setTimeout(function () {
                self.fetch(self.imageSrc);

            }, length || self.options.refresh);
        },
        fetch: function (imgsrc) {
            //get the image
            var self = this;
            var newImg = new Image();
            newImg.onload = function () {
                //set the large image dimensions - used to calculte ratio's
                self.largeWidth = newImg.width;
                self.largeHeight = newImg.height;
                //once image is loaded start the calls
                self.startZoom();
                self.currentImage = self.imageSrc;
                //let caller know image has been loaded
                self.options.onZoomedImageLoaded(self.$elem);
            };
            self.setImageSource(newImg, imgsrc); // this must be done AFTER setting onload

            return;
        },
        setImageSource: function (image, src) {
            //sets an image's source.
            image.src = src;
        },
        startZoom: function () {
            var self = this;
            //get dimensions of the non zoomed image
            self.nzWidth = self.$elem.width();
            self.nzHeight = self.$elem.height();

            //activated elements
            self.isWindowActive = false;
            self.isLensActive = false;
            self.isTintActive = false;
            self.overWindow = false;

            //CrossFade Wrapper
            if (self.options.imageCrossfade) {
                self.zoomWrap = self.$elem.wrap('<div style="height:' + self.nzHeight + 'px;width:' + self.nzWidth + 'px;" class="zoomWrapper" />');
                self.$elem.css('position', 'absolute');
            }

            self.zoomLock = 1;
            self.scrollingLock = false;
            self.changeBgSize = false;
            self.currentZoomLevel = self.options.zoomLevel;

            //get offset of the non zoomed image
            self.nzOffset = self.$elem.offset();
            //calculate the width ratio of the large/small image
            self.widthRatio = (self.largeWidth / self.currentZoomLevel) / self.nzWidth;
            self.heightRatio = (self.largeHeight / self.currentZoomLevel) / self.nzHeight;

            function getWindowZoomStyle() {
                return 'overflow: hidden;' +
                    'background-position: 0px 0px;text-align:center;' +
                    'background-color: ' + String(self.options.zoomWindowBgColour) + ';' +
                    'width: ' + String(self.options.zoomWindowWidth) + 'px;' +
                    'height: ' + String(self.options.zoomWindowHeight) + 'px;' +
                    'float: left;' +
                    'background-size: ' + self.largeWidth / self.currentZoomLevel + 'px ' + self.largeHeight / self.currentZoomLevel + 'px;' +
                    'display: none;z-index:100;' +
                    'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' +
                    'background-repeat: no-repeat;' +
                    'position: absolute;';
            }

            //if window zoom
            if (self.options.zoomType === 'window') {
                self.zoomWindowStyle = getWindowZoomStyle();
            }

            function getInnerZoomStyle() {
                //has a border been put on the image? Lets cater for this
                var borderWidth = self.$elem.css('border-left-width');

                return 'overflow: hidden;' +
                    'margin-left: ' + String(borderWidth) + ';' +
                    'margin-top: ' + String(borderWidth) + ';' +
                    'background-position: 0px 0px;' +
                    'width: ' + String(self.nzWidth) + 'px;' +
                    'height: ' + String(self.nzHeight) + 'px;' +
                    'float: left;' +
                    'display: none;' +
                    'cursor:' + (self.options.cursor) + ';' +
                    'px solid ' + self.options.borderColour + ';' +
                    'background-repeat: no-repeat;' +
                    'position: absolute;';
            }

            //if inner  zoom
            if (self.options.zoomType === 'inner') {
                self.zoomWindowStyle = getInnerZoomStyle();
            }

            function getWindowLensStyle() {
                var lensHeight, lensWidth;
                // adjust images less than the window height

                if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) {
                    lensHeight = self.nzHeight;
                }
                else {
                    lensHeight = String(self.options.zoomWindowHeight / self.heightRatio);
                }
                if (self.largeWidth < self.options.zoomWindowWidth) {
                    lensWidth = self.nzWidth;
                }
                else {
                    lensWidth = String(self.options.zoomWindowWidth / self.widthRatio);
                }

                return 'background-position: 0px 0px;width: ' + String((self.options.zoomWindowWidth) / self.widthRatio) + 'px;' +
                    'height: ' + String((self.options.zoomWindowHeight) / self.heightRatio) +
                    'px;float: right;display: none;' +
                    'overflow: hidden;' +
                    'z-index: 999;' +
                    'opacity:' + (self.options.lensOpacity) + ';filter: alpha(opacity = ' + (self.options.lensOpacity * 100) + '); zoom:1;' +
                    'width:' + lensWidth + 'px;' +
                    'height:' + lensHeight + 'px;' +
                    'background-color:' + (self.options.lensColour) + ';' +
                    'cursor:' + (self.options.cursor) + ';' +
                    'border: ' + (self.options.lensBorderSize) + 'px' +
                    ' solid ' + (self.options.lensBorderColour) + ';background-repeat: no-repeat;position: absolute;';
            }

            //lens style for window zoom
            if (self.options.zoomType === 'window') {
                self.lensStyle = getWindowLensStyle();
            }

            //tint style
            self.tintStyle = 'display: block;' +
                'position: absolute;' +
                'background-color: ' + self.options.tintColour + ';' +
                'filter:alpha(opacity=0);' +
                'opacity: 0;' +
                'width: ' + self.nzWidth + 'px;' +
                'height: ' + self.nzHeight + 'px;';

            //lens style for lens zoom with optional round for modern browsers
            self.lensRound = '';

            if (self.options.zoomType === 'lens') {
                self.lensStyle = 'background-position: 0px 0px;' +
                    'float: left;display: none;' +
                    'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' +
                    'width:' + String(self.options.lensSize) + 'px;' +
                    'height:' + String(self.options.lensSize) + 'px;' +
                    'background-repeat: no-repeat;position: absolute;';
            }

            //does not round in all browsers
            if (self.options.lensShape === 'round') {
                self.lensRound = 'border-top-left-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' +
                    'border-top-right-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' +
                    'border-bottom-left-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' +
                    'border-bottom-right-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;';
            }

            //create the div's                                                + ""
            //self.zoomContainer = $('<div/>').addClass('zoomContainer').css({"position":"relative", "height":self.nzHeight, "width":self.nzWidth});

            self.zoomContainer =
                $('<div class="zoomContainer" ' +
                    'uuid="' + self.options.zoomId + '"' +
                    'style="' +
                    'position:absolute;' +
                    'left:' + self.nzOffset.left + 'px;' +
                    'top:' + self.nzOffset.top + 'px;' +
                    'height:' + self.nzHeight + 'px;' + '' +
                    'width:' + self.nzWidth + 'px;' +
                    'z-index:' + self.options.zIndex + '"></div>');
            $(self.options.zoomContainerAppendTo).append(self.zoomContainer);

            //this will add overflow hidden and contrain the lens on lens mode
            if (self.options.containLensZoom && self.options.zoomType === 'lens') {
                self.zoomContainer.css('overflow', 'hidden');
            }
            if (self.options.zoomType !== 'inner') {
                self.zoomLens = $('<div class="zoomLens" style="' + self.lensStyle + self.lensRound + '">&nbsp;</div>')
                    .appendTo(self.zoomContainer)
                    .click(function () {
                        self.$elem.trigger('click');
                    });

                if (self.options.tint) {
                    self.tintContainer = $('<div/>').addClass('tintContainer');
                    self.zoomTint = $('<div class="zoomTint" style="' + self.tintStyle + '"></div>');

                    self.zoomLens.wrap(self.tintContainer);

                    self.zoomTintcss = self.zoomLens.after(self.zoomTint);

                    //if tint enabled - set an image to show over the tint

                    self.zoomTintImage = $('<img style="' +
                        'position: absolute; left: 0px; top: 0px; max-width: none; ' +
                        'width: ' + self.nzWidth + 'px; ' +
                        'height: ' + self.nzHeight + 'px;" ' +
                        'src="' + self.imageSrc + '">')
                        .appendTo(self.zoomLens)
                        .click(function () {

                            self.$elem.trigger('click');
                        });
                }
            }

            var targetZoomContainer = isNaN(self.options.zoomWindowPosition) ? 'body' : self.zoomContainer;
            //create zoom window
            self.zoomWindow = $('<div style="z-index:999;' +
                'left:' + (self.windowOffsetLeft) + 'px;' +
                'top:' + (self.windowOffsetTop) + 'px;' + self.zoomWindowStyle + '" class="zoomWindow">&nbsp;</div>')
                .appendTo(targetZoomContainer).click(function () {
                    self.$elem.trigger('click');
                });
            self.zoomWindowContainer = $('<div/>').addClass('zoomWindowContainer').css('width', self.options.zoomWindowWidth);
            self.zoomWindow.wrap(self.zoomWindowContainer);

            //  self.captionStyle = "text-align: left;background-color: black;'+
            // 'color: white;font-weight: bold;padding: 10px;font-family: sans-serif;font-size: 11px";
            // self.zoomCaption = $('<div class="ezplus-caption" '+
            // 'style="'+self.captionStyle+'display: block; width: 280px;">INSERT ALT TAG</div>').appendTo(self.zoomWindow.parent());

            if (self.options.zoomType === 'lens') {
                self.zoomLens.css('background-image', 'url("' + self.imageSrc + '")');
            }
            if (self.options.zoomType === 'window') {
                self.zoomWindow.css('background-image', 'url("' + self.imageSrc + '")');
            }
            if (self.options.zoomType === 'inner') {
                self.zoomWindow.css('background-image', 'url("' + self.imageSrc + '")');
            }

            /*-------------------END THE ZOOM WINDOW AND LENS----------------------------------*/
            if (self.options.touchEnabled) {
                //touch events
                self.$elem.bind('touchmove.ezpspace', function (e) {
                    e.preventDefault();
                    var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
                    self.setPosition(touch);
                });
                self.zoomContainer.bind('touchmove.ezpspace', function (e) {
                    if (self.options.zoomType === 'inner') {
                        self.showHideWindow('show');

                    }
                    e.preventDefault();
                    var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
                    self.setPosition(touch);

                });
                self.zoomContainer.bind('touchend.ezpspace', function (e) {
                    self.showHideWindow('hide');
                    if (self.options.showLens) {
                        self.showHideLens('hide');
                    }
                    if (self.options.tint && self.options.zoomType !== 'inner') {
                        self.showHideTint('hide');
                    }
                });

                self.$elem.bind('touchend.ezpspace', function (e) {
                    self.showHideWindow('hide');
                    if (self.options.showLens) {
                        self.showHideLens('hide');
                    }
                    if (self.options.tint && self.options.zoomType !== 'inner') {
                        self.showHideTint('hide');
                    }
                });
                if (self.options.showLens) {
                    self.zoomLens.bind('touchmove.ezpspace', function (e) {

                        e.preventDefault();
                        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
                        self.setPosition(touch);
                    });

                    self.zoomLens.bind('touchend.ezpspace', function (e) {
                        self.showHideWindow('hide');
                        if (self.options.showLens) {
                            self.showHideLens('hide');
                        }
                        if (self.options.tint && self.options.zoomType !== 'inner') {
                            self.showHideTint('hide');
                        }
                    });
                }
            }
            //Needed to work in IE
            self.$elem.bind('mousemove.ezpspace', function (e) {
                if (self.overWindow === false) {
                    self.setElements('show');
                }
                //make sure on orientation change the setposition is not fired
                if (self.lastX !== e.clientX || self.lastY !== e.clientY) {
                    self.setPosition(e);
                    self.currentLoc = e;
                }
                self.lastX = e.clientX;
                self.lastY = e.clientY;

            });

            self.zoomContainer.bind('click.ezpspace', self.options.onImageClick);

            self.zoomContainer.bind('mousemove.ezpspace', function (e) {
                if (self.overWindow === false) {
                    self.setElements('show');
                }
                mouseMoveZoomHandler(e);
            });

            function mouseMoveZoomHandler(e) {
                //self.overWindow = true;
                //make sure on orientation change the setposition is not fired
                if (self.lastX !== e.clientX || self.lastY !== e.clientY) {
                    self.setPosition(e);
                    self.currentLoc = e;
                }
                self.lastX = e.clientX;
                self.lastY = e.clientY;
            }

            var elementToTrack = null;
            if (self.options.zoomType !== 'inner') {
                elementToTrack = self.zoomLens;
            }
            if (self.options.tint && self.options.zoomType !== 'inner') {
                elementToTrack = self.zoomTint;
            }
            if (self.options.zoomType === 'inner') {
                elementToTrack = self.zoomWindow;
            }

            //register the mouse tracking
            if (elementToTrack) {
                elementToTrack.bind('mousemove.ezpspace', mouseMoveZoomHandler);
            }

            //  lensFadeOut: 500,  zoomTintFadeIn
            self.zoomContainer.add(self.$elem).mouseenter(function () {
                if (self.overWindow === false) {
                    self.setElements('show');
                }
            }).mouseleave(function () {
                if (!self.scrollLock) {
                    self.setElements('hide');
                    self.options.onDestroy(self.$elem);
                }
            });
            //end ove image

            if (self.options.zoomType !== 'inner') {
                self.zoomWindow.mouseenter(function () {
                    self.overWindow = true;
                    self.setElements('hide');
                }).mouseleave(function () {
                    self.overWindow = false;
                });
            }
            //end ove image

            // var delta = parseInt(e.originalEvent.wheelDelta || -e.originalEvent.detail);

            //      $(this).empty();
            //    return false;

            //fix for initial zoom setting
            //if (self.options.zoomLevel !== 1) {
            //    	self.changeZoomLevel(self.currentZoomLevel);
            //}
            //set the min zoomlevel
            if (self.options.minZoomLevel) {
                self.minZoomLevel = self.options.minZoomLevel;
            }
            else {
                self.minZoomLevel = self.options.scrollZoomIncrement * 2;
            }

            if (self.options.scrollZoom) {
                self.zoomContainer.add(self.$elem).bind('wheel DOMMouseScroll MozMousePixelScroll', function (e) {
                    // in IE there is issue with firing of mouseleave - So check whether still scrolling
                    // and on mouseleave check if scrolllock
                    self.scrollLock = true;
                    clearTimeout($.data(this, 'timer'));
                    $.data(this, 'timer', setTimeout(function () {
                        self.scrollLock = false;
                        //do something
                    }, 250));

                    var theEvent = e.originalEvent.deltaY || e.originalEvent.detail * -1;

                    //this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
                    //   e.preventDefault();

                    e.stopImmediatePropagation();
                    e.stopPropagation();
                    e.preventDefault();

                    if (theEvent / 120 > 0) {
                        //scrolling up
                        if (self.currentZoomLevel >= self.minZoomLevel) {
                            self.changeZoomLevel(self.currentZoomLevel - self.options.scrollZoomIncrement);
                        }
                    }
                    else {
                        //scrolling down

                        //Check if it has to maintain original zoom window aspect ratio or not
                        if ((!self.fullheight && !self.fullwidth) || !self.options.mantainZoomAspectRatio) {
                            if (self.options.maxZoomLevel) {
                                if (self.currentZoomLevel <= self.options.maxZoomLevel) {
                                    self.changeZoomLevel(parseFloat(self.currentZoomLevel) + self.options.scrollZoomIncrement);
                                }
                            }
                            else {
                                //andy
                                self.changeZoomLevel(parseFloat(self.currentZoomLevel) + self.options.scrollZoomIncrement);
                            }
                        }
                    }
                    return false;
                });
            }
        },
        destroy: function () {
            var self = this;
            self.$elem.unbind('ezpspace');
            $(self.zoomContainer).remove();
            self.delete;
        },
        getIdentifier: function () {
            var self = this;
            return self.options.zoomId;
        },
        setElements: function (type) {
            var self = this;
            if (!self.options.zoomEnabled) {
                return false;
            }
            if (type === 'show') {
                if (self.isWindowSet) {
                    if (self.options.zoomType === 'inner') {
                        self.showHideWindow('show');
                    }
                    if (self.options.zoomType === 'window') {
                        self.showHideWindow('show');
                    }
                    if (self.options.showLens) {
                        self.showHideLens('show');
                    }
                    if (self.options.tint && self.options.zoomType !== 'inner') {
                        self.showHideTint('show');
                    }
                }
            }

            if (type === 'hide') {
                if (self.options.zoomType === 'window') {
                    self.showHideWindow('hide');
                }
                if (!self.options.tint) {
                    self.showHideWindow('hide');
                }
                if (self.options.showLens) {
                    self.showHideLens('hide');
                }
                if (self.options.tint) {
                    self.showHideTint('hide');
                }
            }
        },
        setPosition: function (e) {

            var self = this;

            if (!self.options.zoomEnabled) {
                return false;
            }

            //recaclc offset each time in case the image moves
            //this can be caused by other on page elements
            self.nzHeight = self.$elem.height();
            self.nzWidth = self.$elem.width();
            self.nzOffset = self.$elem.offset();

            if (self.options.tint && self.options.zoomType !== 'inner') {
                self.zoomTint.css({
                    top: 0,
                    left: 0
                });
            }
            //set responsive
            //will checking if the image needs changing before running this code work faster?
            if (self.options.responsive && !self.options.scrollZoom) {
                if (self.options.showLens) {
                    var lensHeight, lensWidth;
                    if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) {
                        lensHeight = self.nzHeight;
                    }
                    else {
                        lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));
                    }
                    if (self.largeWidth < self.options.zoomWindowWidth) {
                        lensWidth = self.nzWidth;
                    }
                    else {
                        lensWidth = (self.options.zoomWindowWidth / self.widthRatio);
                    }
                    self.widthRatio = self.largeWidth / self.nzWidth;
                    self.heightRatio = self.largeHeight / self.nzHeight;
                    if (self.options.zoomType !== 'lens') {
                        //possibly dont need to keep recalcalculating
                        //if the lens is heigher than the image, then set lens size to image size
                        if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) {
                            lensHeight = self.nzHeight;

                        }
                        else {
                            lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));
                        }

                        if (self.nzWidth < self.options.zoomWindowHeight / self.heightRatio) {
                            lensWidth = self.nzWidth;
                        }
                        else {
                            lensWidth = String((self.options.zoomWindowWidth / self.widthRatio));
                        }

                        self.zoomLens.css({
                            'width': lensWidth,
                            'height': lensHeight
                        });

                        if (self.options.tint) {
                            self.zoomTintImage.css({
                                'width': self.nzWidth,
                                'height': self.nzHeight
                            });
                        }

                    }
                    if (self.options.zoomType === 'lens') {
                        self.zoomLens.css({
                            width: String(self.options.lensSize) + 'px',
                            height: String(self.options.lensSize) + 'px'
                        });
                    }
                    //end responsive image change
                }
            }

            //container fix
            self.zoomContainer.css({
                top: self.nzOffset.top,
                left: self.nzOffset.left
            });
            self.mouseLeft = parseInt(e.pageX - self.nzOffset.left);
            self.mouseTop = parseInt(e.pageY - self.nzOffset.top);
            //calculate the Location of the Lens

            //calculate the bound regions - but only if zoom window
            if (self.options.zoomType === 'window') {
                var zoomLensHeight = self.zoomLens.height() / 2;
                var zoomLensWidth = self.zoomLens.width() / 2;
                self.Etoppos = (self.mouseTop < 0 + zoomLensHeight);
                self.Eboppos = (self.mouseTop > self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2));
                self.Eloppos = (self.mouseLeft < 0 + zoomLensWidth);
                self.Eroppos = (self.mouseLeft > (self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2)));
            }
            //calculate the bound regions - but only for inner zoom
            if (self.options.zoomType === 'inner') {
                self.Etoppos = (self.mouseTop < ((self.nzHeight / 2) / self.heightRatio));
                self.Eboppos = (self.mouseTop > (self.nzHeight - ((self.nzHeight / 2) / self.heightRatio)));
                self.Eloppos = (self.mouseLeft < 0 + (((self.nzWidth / 2) / self.widthRatio)));
                self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.nzWidth / 2) / self.widthRatio - (self.options.lensBorderSize * 2)));
            }

            // if the mouse position of the slider is one of the outerbounds, then hide  window and lens
            if (self.mouseLeft < 0 || self.mouseTop < 0 || self.mouseLeft > self.nzWidth || self.mouseTop > self.nzHeight) {
                self.setElements('hide');
                return;
            }
            //else continue with operations
            else {
                //lens options
                if (self.options.showLens) {
                    //		self.showHideLens('show');
                    //set background position of lens
                    self.lensLeftPos = String(Math.floor(self.mouseLeft - self.zoomLens.width() / 2));
                    self.lensTopPos = String(Math.floor(self.mouseTop - self.zoomLens.height() / 2));
                }
                //adjust the background position if the mouse is in one of the outer regions

                //Top region
                if (self.Etoppos) {
                    self.lensTopPos = 0;
                }
                //Left Region
                if (self.Eloppos) {
                    self.windowLeftPos = 0;
                    self.lensLeftPos = 0;
                    self.tintpos = 0;
                }
                //Set bottom and right region for window mode
                if (self.options.zoomType === 'window') {
                    if (self.Eboppos) {
                        self.lensTopPos = Math.max((self.nzHeight) - self.zoomLens.height() - (self.options.lensBorderSize * 2), 0);
                    }
                    if (self.Eroppos) {
                        self.lensLeftPos = (self.nzWidth - (self.zoomLens.width()) - (self.options.lensBorderSize * 2));
                    }
                }
                //Set bottom and right region for inner mode
                if (self.options.zoomType === 'inner') {
                    if (self.Eboppos) {
                        self.lensTopPos = Math.max(((self.nzHeight) - (self.options.lensBorderSize * 2)), 0);
                    }
                    if (self.Eroppos) {
                        self.lensLeftPos = (self.nzWidth - (self.nzWidth) - (self.options.lensBorderSize * 2));
                    }
                }
                //if lens zoom
                if (self.options.zoomType === 'lens') {

                    self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomLens.width() / 2) * (-1));
                    self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomLens.height() / 2) * (-1));
                    self.zoomLens.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');

                    if (self.changeBgSize) {
                        if (self.nzHeight > self.nzWidth) {
                            if (self.options.zoomType === 'lens') {
                                self.zoomLens.css('background-size',
                                    self.largeWidth / self.newvalueheight + 'px ' +
                                    self.largeHeight / self.newvalueheight + 'px');
                            }

                            self.zoomWindow.css('background-size',
                                self.largeWidth / self.newvalueheight + 'px ' +
                                self.largeHeight / self.newvalueheight + 'px');
                        }
                        else {
                            if (self.options.zoomType === 'lens') {
                                self.zoomLens.css('background-size',
                                    self.largeWidth / self.newvaluewidth + 'px ' +
                                    self.largeHeight / self.newvaluewidth + 'px');
                            }
                            self.zoomWindow.css('background-size',
                                self.largeWidth / self.newvaluewidth + 'px ' +
                                self.largeHeight / self.newvaluewidth + 'px');
                        }
                        self.changeBgSize = false;
                    }

                    self.setWindowPosition(e);
                }
                //if tint zoom
                if (self.options.tint && self.options.zoomType !== 'inner') {
                    self.setTintPosition(e);
                }
                //set the css background position
                if (self.options.zoomType === 'window') {
                    self.setWindowPosition(e);
                }
                if (self.options.zoomType === 'inner') {
                    self.setWindowPosition(e);
                }
                if (self.options.showLens) {
                    if (self.fullwidth && self.options.zoomType !== 'lens') {
                        self.lensLeftPos = 0;
                    }
                    self.zoomLens.css({
                        left: self.lensLeftPos + 'px',
                        top: self.lensTopPos + 'px'
                    });
                }

            } //end else
        },
        showHideZoomContainer: function (change) {
            var self = this;
            if (change === 'show') {
                if (self.zoomContainer) {
                    self.zoomContainer.show();
                }
            }
            if (change === 'hide') {
                if (self.zoomContainer) {
                    self.zoomContainer.hide();
                }
            }
        },
        showHideWindow: function (change) {
            var self = this;
            if (change === 'show') {
                if (!self.isWindowActive && self.zoomWindow) {
                    self.options.onShow(self);
                    if (self.options.zoomWindowFadeIn) {
                        self.zoomWindow.stop(true, true, false).fadeIn(self.options.zoomWindowFadeIn);
                    }
                    else {
                        self.zoomWindow.show();
                    }
                    self.isWindowActive = true;
                }
            }
            if (change === 'hide') {
                if (self.isWindowActive) {
                    if (self.options.zoomWindowFadeOut) {
                        self.zoomWindow.stop(true, true).fadeOut(self.options.zoomWindowFadeOut, function () {
                            if (self.loop) {
                                //stop moving the zoom window when zoom window is faded out
                                clearInterval(self.loop);
                                self.loop = false;
                            }
                        });
                    }
                    else {
                        self.zoomWindow.hide();
                    }
                    self.isWindowActive = false;
                }
            }
        },
        showHideLens: function (change) {
            var self = this;
            if (change === 'show') {
                if (!self.isLensActive) {
                    if (self.options.lensFadeIn && self.zoomLens) {
                        self.zoomLens.stop(true, true, false).fadeIn(self.options.lensFadeIn);
                    }
                    else {
                        self.zoomLens.show();
                    }
                    self.isLensActive = true;
                }
            }
            if (change === 'hide') {
                if (self.isLensActive) {
                    if (self.options.lensFadeOut) {
                        self.zoomLens.stop(true, true).fadeOut(self.options.lensFadeOut);
                    }
                    else {
                        self.zoomLens.hide();
                    }
                    self.isLensActive = false;
                }
            }
        },
        showHideTint: function (change) {
            var self = this;
            if (change === 'show') {
                if (!self.isTintActive && self.zoomTint) {

                    if (self.options.zoomTintFadeIn) {
                        self.zoomTint.css('opacity', self.options.tintOpacity).animate().stop(true, true).fadeIn('slow');
                    }
                    else {
                        self.zoomTint.css('opacity', self.options.tintOpacity).animate();
                        self.zoomTint.show();
                    }
                    self.isTintActive = true;
                }
            }
            if (change === 'hide') {
                if (self.isTintActive) {

                    if (self.options.zoomTintFadeOut) {
                        self.zoomTint.stop(true, true).fadeOut(self.options.zoomTintFadeOut);
                    }
                    else {
                        self.zoomTint.hide();
                    }
                    self.isTintActive = false;
                }
            }
        },

        setLensPosition: function (e) {
        },

        setWindowPosition: function (e) {
            //return obj.slice( 0, count );
            var self = this;

            if (!isNaN(self.options.zoomWindowPosition)) {

                switch (self.options.zoomWindowPosition) {
                    case 1: //done
                        self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1
                        self.windowOffsetLeft = (+self.nzWidth); //DONE 1, 2, 3, 4, 16
                        break;
                    case 2:
                        if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin

                            self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1);
                            self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16
                        }
                        else { //negative margin
                            $.noop();
                        }
                        break;
                    case 3: //done
                        self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9
                        self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16
                        break;
                    case 4: //done
                        self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8
                        self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16
                        break;
                    case 5: //done
                        self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8
                        self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15
                        break;
                    case 6:
                        if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin
                            self.windowOffsetTop = (self.nzHeight);  //DONE - 4,5,6,7,8

                            self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1);
                        }
                        else { //negative margin
                            $.noop();
                        }

                        break;
                    case 7: //done
                        self.windowOffsetTop = (self.nzHeight);  //DONE - 4,5,6,7,8
                        self.windowOffsetLeft = 0; //DONE 7, 13
                        break;
                    case 8: //done
                        self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8
                        self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1);  //DONE 8,9,10,11,12
                        break;
                    case 9:  //done
                        self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9
                        self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1);  //DONE 8,9,10,11,12
                        break;
                    case 10:
                        if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin

                            self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1);
                            self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1);  //DONE 8,9,10,11,12
                        }
                        else { //negative margin
                            $.noop();
                        }
                        break;
                    case 11:
                        self.windowOffsetTop = (self.options.zoomWindowOffsetY);
                        self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1);  //DONE 8,9,10,11,12
                        break;
                    case 12: //done
                        self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16
                        self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1);  //DONE 8,9,10,11,12
                        break;
                    case 13: //done
                        self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16
                        self.windowOffsetLeft = (0); //DONE 7, 13
                        break;
                    case 14:
                        if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin
                            self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16

                            self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1);
                        }
                        else { //negative margin
                            $.noop();
                        }
                        break;
                    case 15://done
                        self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16
                        self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15
                        break;
                    case 16:  //done
                        self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16
                        self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16
                        break;
                    default: //done
                        self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1
                        self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16
                }
            } //end isNAN
            else {
                // For BC purposes, treat passed element as ID if element not found
                self.externalContainer = $(self.options.zoomWindowPosition);
                if (!self.externalContainer.length) {
                    self.externalContainer = $('#' + self.options.zoomWindowPosition);
                }

                self.externalContainerWidth = self.externalContainer.width();
                self.externalContainerHeight = self.externalContainer.height();
                self.externalContainerOffset = self.externalContainer.offset();

                self.windowOffsetTop = self.externalContainerOffset.top;//DONE - 1
                self.windowOffsetLeft = self.externalContainerOffset.left; //DONE 1, 2, 3, 4, 16

            }
            self.isWindowSet = true;
            self.windowOffsetTop = self.windowOffsetTop + self.options.zoomWindowOffsetY;
            self.windowOffsetLeft = self.windowOffsetLeft + self.options.zoomWindowOffsetX;

            self.zoomWindow.css({
                top: self.windowOffsetTop,
                left: self.windowOffsetLeft
            });

            if (self.options.zoomType === 'inner') {
                self.zoomWindow.css({
                    top: 0,
                    left: 0
                });

            }

            self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1));
            self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));
            if (self.Etoppos) {
                self.windowTopPos = 0;
            }
            if (self.Eloppos) {
                self.windowLeftPos = 0;
            }
            if (self.Eboppos) {
                self.windowTopPos = (self.largeHeight / self.currentZoomLevel - self.zoomWindow.height()) * (-1);
            }
            if (self.Eroppos) {
                self.windowLeftPos = ((self.largeWidth / self.currentZoomLevel - self.zoomWindow.width()) * (-1));
            }

            //stops micro movements
            if (self.fullheight) {
                self.windowTopPos = 0;
            }
            if (self.fullwidth) {
                self.windowLeftPos = 0;
            }

            //set the css background position
            if (self.options.zoomType === 'window' || self.options.zoomType === 'inner') {

                if (self.zoomLock === 1) {
                    //overrides for images not zoomable
                    if (self.widthRatio <= 1) {
                        self.windowLeftPos = 0;
                    }
                    if (self.heightRatio <= 1) {
                        self.windowTopPos = 0;
                    }
                }
                // adjust images less than the window height

                if (self.options.zoomType === 'window') {
                    if (self.largeHeight < self.options.zoomWindowHeight) {
                        self.windowTopPos = 0;
                    }
                    if (self.largeWidth < self.options.zoomWindowWidth) {
                        self.windowLeftPos = 0;
                    }
                }
                //set the zoomwindow background position
                if (self.options.easing) {

                    //     if(self.changeZoom){
                    //           clearInterval(self.loop);
                    //           self.changeZoom = false;
                    //           self.loop = false;

                    //            }
                    //set the pos to 0 if not set
                    if (!self.xp) {
                        self.xp = 0;
                    }
                    if (!self.yp) {
                        self.yp = 0;
                    }
                    //if loop not already started, then run it
                    if (!self.loop) {
                        self.loop = setInterval(function () {
                            //using zeno's paradox

                            self.xp += (self.windowLeftPos - self.xp) / self.options.easingAmount;
                            self.yp += (self.windowTopPos - self.yp) / self.options.easingAmount;
                            if (self.scrollingLock) {

                                clearInterval(self.loop);
                                self.xp = self.windowLeftPos;
                                self.yp = self.windowTopPos;

                                self.xp = ((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1);
                                self.yp = (((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));

                                if (self.changeBgSize) {
                                    if (self.nzHeight > self.nzWidth) {
                                        if (self.options.zoomType === 'lens') {
                                            self.zoomLens.css('background-size',
                                                self.largeWidth / self.newvalueheight + 'px ' +
                                                self.largeHeight / self.newvalueheight + 'px');
                                        }
                                        self.zoomWindow.css('background-size',
                                            self.largeWidth / self.newvalueheight + 'px ' +
                                            self.largeHeight / self.newvalueheight + 'px');
                                    }
                                    else {
                                        if (self.options.zoomType !== 'lens') {
                                            self.zoomLens.css('background-size',
                                                self.largeWidth / self.newvaluewidth + 'px ' +
                                                self.largeHeight / self.newvalueheight + 'px');
                                        }
                                        self.zoomWindow.css('background-size',
                                            self.largeWidth / self.newvaluewidth + 'px ' +
                                            self.largeHeight / self.newvaluewidth + 'px');
                                    }

                                    /*
                                     if(!self.bgxp){self.bgxp = self.largeWidth/self.newvalue;}
                                     if(!self.bgyp){self.bgyp = self.largeHeight/self.newvalue ;}
                                     if (!self.bgloop){
                                     self.bgloop = setInterval(function(){

                                     self.bgxp += (self.largeWidth/self.newvalue  - self.bgxp) / self.options.easingAmount;
                                     self.bgyp += (self.largeHeight/self.newvalue  - self.bgyp) / self.options.easingAmount;

                                     self.zoomWindow.css('background-size', self.bgxp + 'px ' + self.bgyp + 'px' );


                                     }, 16);

                                     }
                                     */
                                    self.changeBgSize = false;
                                }

                                self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');
                                self.scrollingLock = false;
                                self.loop = false;

                            }
                            else if (Math.round(Math.abs(self.xp - self.windowLeftPos) + Math.abs(self.yp - self.windowTopPos)) < 1) {
                                //stops micro movements
                                clearInterval(self.loop);
                                self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px');
                                self.loop = false;
                            }
                            else {
                                if (self.changeBgSize) {
                                    if (self.nzHeight > self.nzWidth) {
                                        if (self.options.zoomType === 'lens') {
                                            self.zoomLens.css('background-size',
                                                self.largeWidth / self.newvalueheight + 'px ' +
                                                self.largeHeight / self.newvalueheight + 'px');
                                        }
                                        self.zoomWindow.css('background-size',
                                            self.largeWidth / self.newvalueheight + 'px ' +
                                            self.largeHeight / self.newvalueheight + 'px');
                                    }
                                    else {
                                        if (self.options.zoomType !== 'lens') {
                                            self.zoomLens.css('background-size',
                                                self.largeWidth / self.newvaluewidth + 'px ' +
                                                self.largeHeight / self.newvaluewidth + 'px');
                                        }
                                        self.zoomWindow.css('background-size',
                                            self.largeWidth / self.newvaluewidth + 'px ' +
                                            self.largeHeight / self.newvaluewidth + 'px');
                                    }
                                    self.changeBgSize = false;
                                }

                                self.zoomWindow.css('background-position', self.xp + 'px ' + self.yp + 'px');
                            }
                        }, 16);
                    }
                }
                else {
                    if (self.changeBgSize) {
                        if (self.nzHeight > self.nzWidth) {
                            if (self.options.zoomType === 'lens') {
                                self.zoomLens.css('background-size',
                                    self.largeWidth / self.newvalueheight + 'px ' +
                                    self.largeHeight / self.newvalueheight + 'px');
                            }

                            self.zoomWindow.css('background-size',
                                self.largeWidth / self.newvalueheight + 'px ' +
                                self.largeHeight / self.newvalueheight + 'px');
                        }
                        else {
                            if (self.options.zoomType === 'lens') {
                                self.zoomLens.css('background-size',
                                    self.largeWidth / self.newvaluewidth + 'px ' +
                                    self.largeHeight / self.newvaluewidth + 'px');
                            }
                            if ((self.largeHeight / self.newvaluewidth) < self.options.zoomWindowHeight) {

                                self.zoomWindow.css('background-size',
                                    self.largeWidth / self.newvaluewidth + 'px ' +
                                    self.largeHeight / self.newvaluewidth + 'px');
                            }
                            else {

                                self.zoomWindow.css('background-size',
                                    self.largeWidth / self.newvalueheight + 'px ' +
                                    self.largeHeight / self.newvalueheight + 'px');
                            }

                        }
                        self.changeBgSize = false;
                    }

                    self.zoomWindow.css('background-position',
                        self.windowLeftPos + 'px ' +
                        self.windowTopPos + 'px');
                }
            }
        },

        setTintPosition: function (e) {
            var self = this;
            var zoomLensWidth = self.zoomLens.width();
            var zoomLensHeight = self.zoomLens.height();
            self.nzOffset = self.$elem.offset();
            self.tintpos = String(((e.pageX - self.nzOffset.left) - (zoomLensWidth / 2)) * (-1));
            self.tintposy = String(((e.pageY - self.nzOffset.top) - zoomLensHeight / 2) * (-1));
            if (self.Etoppos) {
                self.tintposy = 0;
            }
            if (self.Eloppos) {
                self.tintpos = 0;
            }
            if (self.Eboppos) {
                self.tintposy = (self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2)) * (-1);
            }
            if (self.Eroppos) {
                self.tintpos = ((self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2)) * (-1));
            }
            if (self.options.tint) {
                //stops micro movements
                if (self.fullheight) {
                    self.tintposy = 0;

                }
                if (self.fullwidth) {
                    self.tintpos = 0;

                }
                self.zoomTintImage.css({
                    'left': self.tintpos + 'px',
                    'top': self.tintposy + 'px'
                });
            }
        },

        swaptheimage: function (smallimage, largeimage) {
            var self = this;
            var newImg = new Image();

            if (self.options.loadingIcon) {
                self.spinner = $('<div style="' +
                    'background: url(\'' + self.options.loadingIcon + '\') no-repeat center;' +
                    'height:' + self.nzHeight + 'px;' +
                    'width:' + self.nzWidth + 'px;' +
                    'z-index: 2000;position: absolute; ' +
                    'background-position: center center;"></div>');
                self.$elem.after(self.spinner);
            }

            self.options.onImageSwap(self.$elem);

            newImg.onload = function () {
                self.largeWidth = newImg.width;
                self.largeHeight = newImg.height;
                self.zoomImage = largeimage;
                self.zoomWindow.css('background-size', self.largeWidth + 'px ' + self.largeHeight + 'px');

                self.swapAction(smallimage, largeimage);
                return;
            };
            self.setImageSource(newImg, largeimage);  // this must be done AFTER setting onload
        },

        swapAction: function (smallimage, largeimage) {
            var self = this;
            var elemWidth = self.$elem.width();
            var elemHeight = self.$elem.height();
            var newImg2 = new Image();
            newImg2.onload = function () {
                //re-calculate values
                self.nzHeight = newImg2.height;
                self.nzWidth = newImg2.width;
                self.options.onImageSwapComplete(self.$elem);

                self.doneCallback();
                return;
            };
            self.setImageSource(newImg2, smallimage);

            //reset the zoomlevel to that initially set in options
            self.currentZoomLevel = self.options.zoomLevel;
            self.options.maxZoomLevel = false;

            //swaps the main image
            //self.$elem.attr('src',smallimage);
            //swaps the zoom image
            if (self.options.zoomType === 'lens') {
                self.zoomLens.css('background-image', 'url("' + largeimage + '")');
            }
            if (self.options.zoomType === 'window') {
                self.zoomWindow.css('background-image', 'url("' + largeimage + '")');
            }
            if (self.options.zoomType === 'inner') {
                self.zoomWindow.css('background-image', 'url("' + largeimage + '")');
            }

            self.currentImage = largeimage;

            if (self.options.imageCrossfade) {
                var oldImg = self.$elem;
                var newImg = oldImg.clone();
                self.$elem.attr('src', smallimage);
                self.$elem.after(newImg);
                newImg.stop(true).fadeOut(self.options.imageCrossfade, function () {
                    $(this).remove();
                });

                // if(self.options.zoomType === 'inner'){
                //remove any attributes on the cloned image so we can resize later
                self.$elem.width('auto').removeAttr('width');
                self.$elem.height('auto').removeAttr('height');
                //   }

                oldImg.fadeIn(self.options.imageCrossfade);

                if (self.options.tint && self.options.zoomType !== 'inner') {

                    var oldImgTint = self.zoomTintImage;
                    var newImgTint = oldImgTint.clone();
                    self.zoomTintImage.attr('src', largeimage);
                    self.zoomTintImage.after(newImgTint);
                    newImgTint.stop(true).fadeOut(self.options.imageCrossfade, function () {
                        $(this).remove();
                    });

                    oldImgTint.fadeIn(self.options.imageCrossfade);

                    //self.zoomTintImage.attr('width',elem.data('image'));

                    //resize the tint window
                    self.zoomTint.css({
                        height: elemHeight,
                        width: elemWidth
                    });
                }

                self.zoomContainer.css({
                    'height': elemHeight,
                    'width': elemWidth
                });

                if (self.options.zoomType === 'inner') {
                    if (!self.options.constrainType) {
                        self.zoomWrap.parent().css({
                            'height': elemHeight,
                            'width': elemWidth
                        });

                        self.zoomWindow.css({
                            'height': elemHeight,
                            'width': elemWidth
                        });
                    }
                }

                if (self.options.imageCrossfade) {
                    self.zoomWrap.css({
                        'height': elemHeight,
                        'width': elemWidth
                    });
                }
            }
            else {
                self.$elem.attr('src', smallimage);
                if (self.options.tint) {
                    self.zoomTintImage.attr('src', largeimage);
                    //self.zoomTintImage.attr('width',elem.data('image'));
                    self.zoomTintImage.attr('height', elemHeight);
                    //self.zoomTintImage.attr('src') = elem.data('image');
                    self.zoomTintImage.css('height', elemHeight);
                    self.zoomTint.css('height', elemHeight);

                }
                self.zoomContainer.css({
                    'height': elemHeight,
                    'width': elemWidth
                });

                if (self.options.imageCrossfade) {
                    self.zoomWrap.css({
                        'height': elemHeight,
                        'width': elemWidth
                    });
                }
            }
            if (self.options.constrainType) {

                //This will contrain the image proportions
                if (self.options.constrainType === 'height') {

                    var autoWDimension = {
                        'height': self.options.constrainSize,
                        'width': 'auto'
                    };
                    self.zoomContainer.css(autoWDimension);

                    if (self.options.imageCrossfade) {
                        self.zoomWrap.css(autoWDimension);
                        self.constwidth = self.zoomWrap.width();
                    }
                    else {
                        self.$elem.css(autoWDimension);
                        self.constwidth = elemWidth;
                    }

                    var constWDim = {
                        'height': self.options.constrainSize,
                        'width': self.constwidth
                    };
                    if (self.options.zoomType === 'inner') {

                        self.zoomWrap.parent().css(constWDim);
                        self.zoomWindow.css(constWDim);
                    }
                    if (self.options.tint) {
                        self.tintContainer.css(constWDim);
                        self.zoomTint.css(constWDim);
                        self.zoomTintImage.css(constWDim);
                    }

                }
                if (self.options.constrainType === 'width') {
                    var autoHDimension = {
                        'height': 'auto',
                        'width': self.options.constrainSize
                    };
                    self.zoomContainer.css(autoHDimension);

                    if (self.options.imageCrossfade) {
                        self.zoomWrap.css(autoHDimension);
                        self.constheight = self.zoomWrap.height();
                    }
                    else {
                        self.$elem.css(autoHDimension);
                        self.constheight = elemHeight;
                    }

                    var constHDim = {
                        'height': self.constheight,
                        'width': self.options.constrainSize
                    };
                    if (self.options.zoomType === 'inner') {
                        self.zoomWrap.parent().css(constHDim);
                        self.zoomWindow.css(constHDim);
                    }
                    if (self.options.tint) {
                        self.tintContainer.css(constHDim);
                        self.zoomTint.css(constHDim);
                        self.zoomTintImage.css(constHDim);
                    }
                }
            }
        },

        doneCallback: function () {
            var self = this;
            if (self.options.loadingIcon) {
                self.spinner.hide();
            }

            self.nzOffset = self.$elem.offset();
            self.nzWidth = self.$elem.width();
            self.nzHeight = self.$elem.height();

            // reset the zoomlevel back to default
            self.currentZoomLevel = self.options.zoomLevel;

            //ratio of the large to small image
            self.widthRatio = self.largeWidth / self.nzWidth;
            self.heightRatio = self.largeHeight / self.nzHeight;

            //NEED TO ADD THE LENS SIZE FOR ROUND
            // adjust images less than the window height
            if (self.options.zoomType === 'window') {
                var lensHeight, lensWidth;

                if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) {
                    lensHeight = self.nzHeight;

                }
                else {
                    lensHeight = String((self.options.zoomWindowHeight / self.heightRatio));
                }

                if (self.nzWidth < self.options.zoomWindowWidth) {
                    lensWidth = self.nzWidth;
                }
                else {
                    lensWidth = (self.options.zoomWindowWidth / self.widthRatio);
                }

                if (self.zoomLens) {
                    self.zoomLens.css({
                        'width': lensWidth,
                        'height': lensHeight
                    });
                }
            }
        },

        getCurrentImage: function () {
            var self = this;
            return self.zoomImage;
        },

        getGalleryList: function () {
            var self = this;
            //loop through the gallery options and set them in list for fancybox
            self.gallerylist = [];
            if (self.options.gallery) {
                $('#' + self.options.gallery + ' a').each(function () {

                    var imgSrc = '';
                    if ($(this).data('zoom-image')) {
                        imgSrc = $(this).data('zoom-image');
                    }
                    else if ($(this).data('image')) {
                        imgSrc = $(this).data('image');
                    }
                    //put the current image at the start
                    if (imgSrc === self.zoomImage) {
                        self.gallerylist.unshift({
                            href: '' + imgSrc + '',
                            title: $(this).find('img').attr('title')
                        });
                    }
                    else {
                        self.gallerylist.push({
                            href: '' + imgSrc + '',
                            title: $(this).find('img').attr('title')
                        });
                    }
                });
            }
            //if no gallery - return current image
            else {
                self.gallerylist.push({
                    href: '' + self.zoomImage + '',
                    title: $(this).find('img').attr('title')
                });
            }
            return self.gallerylist;
        },

        changeZoomLevel: function (value) {
            var self = this;

            //flag a zoom, so can adjust the easing during setPosition
            self.scrollingLock = true;

            //round to two decimal places
            self.newvalue = parseFloat(value).toFixed(2);
            var newvalue = self.newvalue;

            //maxwidth & Maxheight of the image
            var maxheightnewvalue = self.largeHeight / ((self.options.zoomWindowHeight / self.nzHeight) * self.nzHeight);
            var maxwidthtnewvalue = self.largeWidth / ((self.options.zoomWindowWidth / self.nzWidth) * self.nzWidth);

            //calculate new heightratio
            if (self.options.zoomType !== 'inner') {
                if (maxheightnewvalue <= newvalue) {
                    self.heightRatio = (self.largeHeight / maxheightnewvalue) / self.nzHeight;
                    self.newvalueheight = maxheightnewvalue;
                    self.fullheight = true;
                }
                else {
                    self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;
                    self.newvalueheight = newvalue;
                    self.fullheight = false;
                }

                // calculate new width ratio

                if (maxwidthtnewvalue <= newvalue) {
                    self.widthRatio = (self.largeWidth / maxwidthtnewvalue) / self.nzWidth;
                    self.newvaluewidth = maxwidthtnewvalue;
                    self.fullwidth = true;
                }
                else {
                    self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;
                    self.newvaluewidth = newvalue;
                    self.fullwidth = false;
                }
                if (self.options.zoomType === 'lens') {
                    if (maxheightnewvalue <= newvalue) {
                        self.fullwidth = true;
                        self.newvaluewidth = maxheightnewvalue;
                    } else {
                        self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;
                        self.newvaluewidth = newvalue;

                        self.fullwidth = false;
                    }
                }
            }

            if (self.options.zoomType === 'inner') {
                maxheightnewvalue = parseFloat(self.largeHeight / self.nzHeight).toFixed(2);
                maxwidthtnewvalue = parseFloat(self.largeWidth / self.nzWidth).toFixed(2);
                if (newvalue > maxheightnewvalue) {
                    newvalue = maxheightnewvalue;
                }
                if (newvalue > maxwidthtnewvalue) {
                    newvalue = maxwidthtnewvalue;
                }

                if (maxheightnewvalue <= newvalue) {
                    self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;
                    if (newvalue > maxheightnewvalue) {
                        self.newvalueheight = maxheightnewvalue;
                    } else {
                        self.newvalueheight = newvalue;
                    }
                    self.fullheight = true;
                }
                else {
                    self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight;

                    if (newvalue > maxheightnewvalue) {

                        self.newvalueheight = maxheightnewvalue;
                    } else {
                        self.newvalueheight = newvalue;
                    }
                    self.fullheight = false;
                }

                if (maxwidthtnewvalue <= newvalue) {

                    self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;
                    if (newvalue > maxwidthtnewvalue) {

                        self.newvaluewidth = maxwidthtnewvalue;
                    } else {
                        self.newvaluewidth = newvalue;
                    }

                    self.fullwidth = true;
                }
                else {
                    self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth;
                    self.newvaluewidth = newvalue;
                    self.fullwidth = false;
                }
            } //end inner
            var scrcontinue = false;

            if (self.options.zoomType === 'inner') {
                if (self.nzWidth >= self.nzHeight) {
                    if (self.newvaluewidth <= maxwidthtnewvalue) {
                        scrcontinue = true;
                    }
                    else {
                        scrcontinue = false;
                        self.fullheight = true;
                        self.fullwidth = true;
                    }
                }
                if (self.nzHeight > self.nzWidth) {
                    if (self.newvaluewidth <= maxwidthtnewvalue) {
                        scrcontinue = true;
                    }
                    else {
                        scrcontinue = false;
                        self.fullheight = true;
                        self.fullwidth = true;
                    }
                }
            }

            if (self.options.zoomType !== 'inner') {
                scrcontinue = true;
            }

            if (scrcontinue) {
                self.zoomLock = 0;
                self.changeZoom = true;

                //if lens height is less than image height
                if (((self.options.zoomWindowHeight) / self.heightRatio) <= self.nzHeight) {
                    self.currentZoomLevel = self.newvalueheight;
                    if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') {
                        self.changeBgSize = true;
                        self.zoomLens.css('height', String(self.options.zoomWindowHeight / self.heightRatio) + 'px');
                    }
                    if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') {
                        self.changeBgSize = true;
                    }
                }

                if ((self.options.zoomWindowWidth / self.widthRatio) <= self.nzWidth) {
                    if (self.options.zoomType !== 'inner') {
                        if (self.newvaluewidth > self.newvalueheight) {
                            self.currentZoomLevel = self.newvaluewidth;
                        }
                    }

                    if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') {
                        self.changeBgSize = true;

                        self.zoomLens.css('width', String(self.options.zoomWindowWidth / self.widthRatio) + 'px');
                    }
                    if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') {
                        self.changeBgSize = true;
                    }

                }
                if (self.options.zoomType === 'inner') {
                    self.changeBgSize = true;

                    if (self.nzWidth > self.nzHeight) {
                        self.currentZoomLevel = self.newvaluewidth;
                    }
                    if (self.nzHeight > self.nzWidth) {
                        self.currentZoomLevel = self.newvaluewidth;
                    }
                }
            }      //under

            //sets the boundry change, called in setWindowPos
            self.setPosition(self.currentLoc);
            //
        },

        closeAll: function () {
            var self = this;
            if (self.zoomWindow) {
                self.zoomWindow.hide();
            }
            if (self.zoomLens) {
                self.zoomLens.hide();
            }
            if (self.zoomTint) {
                self.zoomTint.hide();
            }
        },

        changeState: function (value) {
            var self = this;
            if (value === 'enable') {
                self.options.zoomEnabled = true;
            }
            if (value === 'disable') {
                self.options.zoomEnabled = false;
            }
        },

        responsiveConfig: function (options) {
            if (options.respond && options.respond.length > 0) {
                return $.extend({}, options, this.configByScreenWidth(options));
            }
            return options;
        },

        configByScreenWidth: function (options) {
            var screenWidth = $(window).width();

            var config = $.grep(options.respond, function (item) {
                var range = item.range.split('-');
                return (screenWidth >= range[0]) && (screenWidth <= range[1]);
            });

            if (config.length > 0) {
                return config[0];
            } else {
                return options;
            }
        }
    };

    $.fn.ezPlus = function (options) {
        return this.each(function () {
            var elevate = Object.create(EZP);

            elevate.init(options, this);

            $.data(this, 'ezPlus', elevate);

        });
    };

    $.fn.ezPlus.options = {
        borderColour: '#888',
        borderSize: 4,
        constrainSize: false,  //in pixels the dimensions you want to constrain on
        constrainType: false,  //width or height
        containLensZoom: false,
        cursor: 'inherit', // user should set to what they want the cursor as, if they have set a click function
        debug: false,
        easing: false,
        easingAmount: 12,
        enabled: true,

        gallery: false,
        galleryActiveClass: 'zoomGalleryActive',
        gallerySelector: false,
        galleryItem: 'a',

        imageCrossfade: false,

        lensBorderColour: '#000',
        lensBorderSize: 1,
        lensColour: 'white', //colour of the lens background
        lensFadeIn: false,
        lensFadeOut: false,
        lensOpacity: 0.4, //opacity of the lens
        lensShape: 'square', //can be 'round'
        lensSize: 200,
        lenszoom: false,

        loadingIcon: false, //http://www.example.com/spinner.gif

        // This change will allow to decide if you want to decrease
        // zoom of one of the dimensions once the other reached it's top value,
        // or keep the aspect ratio, default behaviour still being as always,
        // allow to continue zooming out, so it keeps retrocompatibility.
        mantainZoomAspectRatio: false,
        maxZoomLevel: false,
        minZoomLevel: false,

        onComplete: $.noop,
        onDestroy: $.noop,
        onImageClick: $.noop,
        onImageSwap: $.noop,
        onImageSwapComplete: $.noop,
        onShow: $.noop,
        onZoomedImageLoaded: $.noop,

        preloading: 1, //by default, load all the images, if 0, then only load images after activated (PLACEHOLDER FOR NEXT VERSION)
        respond: [],
        responsive: true,
        scrollZoom: false, //allow zoom on mousewheel, true to activate
        scrollZoomIncrement: 0.1,  //steps of the scrollzoom
        showLens: true,
        tint: false, //enable the tinting
        tintColour: '#333', //default tint color, can be anything, red, #ccc, rgb(0,0,0)
        tintOpacity: 0.4, //opacity of the tint
        touchEnabled: true,


        zoomActivation: 'hover', // Can also be click (PLACEHOLDER FOR NEXT VERSION)
        zoomContainerAppendTo: 'body', //zoom container parent selector
        zoomId: -1, // identifier for the zoom container
        zoomLevel: 1, //default zoom level of image
        zoomTintFadeIn: false,
        zoomTintFadeOut: false,
        zoomType: 'window', //window is default,  also 'lens' available -
        zoomWindowAlwaysShow: false,
        zoomWindowBgColour: '#fff',
        zoomWindowFadeIn: false,
        zoomWindowFadeOut: false,
        zoomWindowHeight: 400,
        zoomWindowOffsetX: 0,
        zoomWindowOffsetY: 0,
        zoomWindowPosition: 1, //Possible values: 1-16, but we can also position with a selector string.
        zoomWindowWidth: 400,
        zoomEnabled: true, //false disables zoomwindow from showing
        zIndex: 999
    };

})(jQuery, window, document);

},{}],621:[function(require,module,exports){
!function(a){function b(){return new Date(Date.UTC.apply(Date,arguments))}var c=function(b,c){var f=this;this.element=a(b),this.autoShow=void 0==c.autoShow||c.autoShow,this.appendTo=c.appendTo||"body",this.closeButton=c.closeButton,this.language=c.language||this.element.data("date-language")||"en",this.language=this.language in d?this.language:this.language.split("-")[0],this.language=this.language in d?this.language:"en",this.isRTL=d[this.language].rtl||!1,this.format=e.parseFormat(c.format||this.element.data("date-format")||d[this.language].format||"mm/dd/yyyy"),this.formatText=c.format||this.element.data("date-format")||d[this.language].format||"mm/dd/yyyy",this.isInline=!1,this.isInput=this.element.is("input"),this.component=!!this.element.is(".date")&&this.element.find(".prefix, .postfix"),this.hasInput=this.component&&this.element.find("input").length,this.disableDblClickSelection=c.disableDblClickSelection,this.onRender=c.onRender||function(){},this.component&&0===this.component.length&&(this.component=!1),this.linkField=c.linkField||this.element.data("link-field")||!1,this.linkFormat=e.parseFormat(c.linkFormat||this.element.data("link-format")||"yyyy-mm-dd hh:ii:ss"),this.minuteStep=c.minuteStep||this.element.data("minute-step")||5,this.pickerPosition=c.pickerPosition||this.element.data("picker-position")||"bottom-right",this.initialDate=c.initialDate||null,this.faCSSprefix=c.faCSSprefix||"fa",this.leftArrow=c.leftArrow||'<i class="'+this.faCSSprefix+" "+this.faCSSprefix+'-chevron-left fi-arrow-left"/>',this.rightArrow=c.rightArrow||'<i class="'+this.faCSSprefix+" "+this.faCSSprefix+'-chevron-right fi-arrow-right"/>',this.closeIcon=c.closeIcon||'<i class="'+this.faCSSprefix+" "+this.faCSSprefix+"-remove "+this.faCSSprefix+'-times fi-x"></i>',this.minView=0,"minView"in c?this.minView=c.minView:"minView"in this.element.data()&&(this.minView=this.element.data("min-view")),this.minView=e.convertViewMode(this.minView),this.maxView=e.modes.length-1,"maxView"in c?this.maxView=c.maxView:"maxView"in this.element.data()&&(this.maxView=this.element.data("max-view")),this.maxView=e.convertViewMode(this.maxView),this.startViewMode="month","startView"in c?this.startViewMode=c.startView:"startView"in this.element.data()&&(this.startViewMode=this.element.data("start-view")),this.startViewMode=e.convertViewMode(this.startViewMode),this.viewMode=this.startViewMode,"minView"in c||"maxView"in c||this.element.data("min-view")&&!this.element.data("max-view")||(this.pickTime=!1,"pickTime"in c&&(this.pickTime=c.pickTime),1==this.pickTime?(this.minView=0,this.maxView=4):(this.minView=2,this.maxView=4)),this.forceParse=!0,"forceParse"in c?this.forceParse=c.forceParse:"dateForceParse"in this.element.data()&&(this.forceParse=this.element.data("date-force-parse")),this.picker=a(e.template(this.leftArrow,this.rightArrow,this.closeIcon)).appendTo(this.isInline?this.element:this.appendTo).on({click:a.proxy(this.click,this),mousedown:a.proxy(this.mousedown,this)}),this.closeButton?this.picker.find("a.datepicker-close").show():this.picker.find("a.datepicker-close").hide(),this.isInline?this.picker.addClass("datepicker-inline"):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.isRTL&&(this.picker.addClass("datepicker-rtl"),this.picker.find(".date-switch").each(function(){a(this).parent().prepend(a(this).siblings(".next")),a(this).parent().append(a(this).siblings(".prev"))}),this.picker.find(".prev, .next").toggleClass("prev next")),a(document).on("mousedown",function(b){0===a(b.target).closest(".datepicker.datepicker-inline, .datepicker.datepicker-dropdown").length&&f.hide()}),this.autoclose=!0,"autoclose"in c?this.autoclose=c.autoclose:"dateAutoclose"in this.element.data()&&(this.autoclose=this.element.data("date-autoclose")),this.keyboardNavigation=!0,"keyboardNavigation"in c?this.keyboardNavigation=c.keyboardNavigation:"dateKeyboardNavigation"in this.element.data()&&(this.keyboardNavigation=this.element.data("date-keyboard-navigation")),this.todayBtn=c.todayBtn||this.element.data("date-today-btn")||!1,this.todayHighlight=c.todayHighlight||this.element.data("date-today-highlight")||!1,this.calendarWeeks=!1,"calendarWeeks"in c?this.calendarWeeks=c.calendarWeeks:"dateCalendarWeeks"in this.element.data()&&(this.calendarWeeks=this.element.data("date-calendar-weeks")),this.calendarWeeks&&this.picker.find("tfoot th.today").attr("colspan",function(a,b){return parseInt(b)+1}),this.weekStart=(c.weekStart||this.element.data("date-weekstart")||d[this.language].weekStart||0)%7,this.weekEnd=(this.weekStart+6)%7,this.startDate=-(1/0),this.endDate=1/0,this.daysOfWeekDisabled=[],this.datesDisabled=[],this.setStartDate(c.startDate||this.element.data("date-startdate")),this.setEndDate(c.endDate||this.element.data("date-enddate")),this.setDaysOfWeekDisabled(c.daysOfWeekDisabled||this.element.data("date-days-of-week-disabled")),this.setDatesDisabled(c.datesDisabled||this.element.data("dates-disabled")),this.fillDow(),this.fillMonths(),this.update(),this.showMode(),this.isInline&&this.show(),this._attachEvents()};c.prototype={constructor:c,_events:[],_attachEvents:function(){this._detachEvents(),this.isInput?this.keyboardNavigation?this._events=[[this.element,{focus:this.autoShow?a.proxy(this.show,this):function(){},keyup:a.proxy(this.update,this),keydown:a.proxy(this.keydown,this),click:this.element.attr("readonly")?a.proxy(this.show,this):function(){}}]]:this._events=[[this.element,{focus:this.autoShow?a.proxy(this.show,this):function(){}}]]:this.component&&this.hasInput?this._events=[[this.element.find("input"),{focus:this.autoShow?a.proxy(this.show,this):function(){},keyup:a.proxy(this.update,this),keydown:a.proxy(this.keydown,this)}],[this.component,{click:a.proxy(this.show,this)}]]:this.element.is("div")?this.isInline=!0:this._events=[[this.element,{click:a.proxy(this.show,this)}]],this.disableDblClickSelection&&(this._events[this._events.length]=[this.element,{dblclick:function(b){b.preventDefault(),b.stopPropagation(),a(this).blur()}}]);for(var b,c,d=0;d<this._events.length;d++)b=this._events[d][0],c=this._events[d][1],b.on(c)},_detachEvents:function(){for(var a,b,c=0;c<this._events.length;c++)a=this._events[c][0],b=this._events[c][1],a.off(b);this._events=[]},show:function(b){this.picker.show(),this.height=this.component?this.component.outerHeight():this.element.outerHeight(),this.update(),this.place(),a(window).on("resize",a.proxy(this.place,this)),b&&(b.stopPropagation(),b.preventDefault()),this.element.trigger({type:"show",date:this.date})},hide:function(b){this.isInline||this.picker.is(":visible")&&(this.picker.hide(),a(window).off("resize",this.place),this.viewMode=this.startViewMode,this.showMode(),this.isInput||a(document).off("mousedown",this.hide),this.forceParse&&(this.isInput&&this.element.val()||this.hasInput&&this.element.find("input").val())&&this.setValue(),this.element.trigger({type:"hide",date:this.date}))},remove:function(){this._detachEvents(),this.picker.remove(),delete this.element.data().datepicker},getDate:function(){var a=this.getUTCDate();return new Date(a.getTime()+6e4*a.getTimezoneOffset())},getUTCDate:function(){return this.date},setDate:function(a){this.setUTCDate(new Date(a.getTime()-6e4*a.getTimezoneOffset()))},setUTCDate:function(a){this.date=a,this.setValue()},setValue:function(){var a=this.getFormattedDate();this.isInput?this.element.val(a):(this.component&&this.element.find("input").val(a),this.element.data("date",a))},getFormattedDate:function(a){return void 0===a&&(a=this.format),e.formatDate(this.date,a,this.language)},setStartDate:function(a){this.startDate=a||-(1/0),this.startDate!==-(1/0)&&(this.startDate=e.parseDate(this.startDate,this.format,this.language)),this.update(),this.updateNavArrows()},setEndDate:function(a){this.endDate=a||1/0,this.endDate!==1/0&&(this.endDate=e.parseDate(this.endDate,this.format,this.language)),this.update(),this.updateNavArrows()},setDaysOfWeekDisabled:function(b){this.daysOfWeekDisabled=b||[],a.isArray(this.daysOfWeekDisabled)||(this.daysOfWeekDisabled=this.daysOfWeekDisabled.split(/,\s*/)),this.daysOfWeekDisabled=a.map(this.daysOfWeekDisabled,function(a){return parseInt(a,10)}),this.update(),this.updateNavArrows()},setDatesDisabled:function(b){this.datesDisabled=b||[],a.isArray(this.datesDisabled)||(this.datesDisabled=this.datesDisabled.split(/,\s*/)),this.datesDisabled=a.map(this.datesDisabled,function(a){return e.parseDate(a,this.format,this.language).valueOf()}),this.update(),this.updateNavArrows()},place:function(){if(!this.isInline){var b=parseInt(this.element.parents().filter(function(){return"auto"!=a(this).css("z-index")}).first().css("z-index"))+10,c=this.component?this.component:this.element,d=c.offset(),e=c.outerHeight()+parseInt(c.css("margin-top")),f=c.outerWidth()+parseInt(c.css("margin-left")),g=d.top+e,h=d.left;this.picker.removeClass("datepicker-top datepicker-bottom"),g+this.picker.outerHeight()>=a(window).scrollTop()+a(window).height()?(g=d.top-this.picker.outerHeight(),this.picker.addClass("datepicker-top")):this.picker.addClass("datepicker-bottom"),d.left+this.picker.width()>=a(window).width()&&(h=d.left+f-this.picker.width()),this.picker.css({top:g,left:h,zIndex:b})}},update:function(){var b,c=!1,d=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val();return arguments&&arguments.length&&("string"==typeof arguments[0]||arguments[0]instanceof Date)?(b=arguments[0],c=!0):b=d||null==this.initialDate?this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val():this.initialDate,b.length>this.formatText.length?(a(this.picker).addClass("is-invalid"),void a(this.element).addClass("is-invalid-input")):(a(this.picker).removeClass("is-invalid"),a(this.element).removeClass("is-invalid-input"),this.date=e.parseDate(b,this.format,this.language),(c||null!=this.initialDate)&&this.setValue(),this.date<this.startDate?this.viewDate=new Date(this.startDate.valueOf()):this.date>this.endDate?this.viewDate=new Date(this.endDate.valueOf()):this.viewDate=new Date(this.date.valueOf()),void this.fill())},fillDow:function(){var a=this.weekStart,b="<tr>";if(this.calendarWeeks){var c='<th class="cw">&nbsp;</th>';b+=c,this.picker.find(".datepicker-days thead tr:first-child").prepend(c)}for(;a<this.weekStart+7;)b+='<th class="dow">'+d[this.language].daysMin[a++%7]+"</th>";b+="</tr>",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;b<12;)a+='<span class="month">'+d[this.language].monthsShort[b++]+"</span>";this.picker.find(".datepicker-months td").html(a)},fill:function(){if(null!=this.date&&null!=this.viewDate){var c=new Date(this.viewDate.valueOf()),f=c.getUTCFullYear(),g=c.getUTCMonth(),h=c.getUTCDate(),i=c.getUTCHours(),j=c.getUTCMinutes(),k=this.startDate!==-(1/0)?this.startDate.getUTCFullYear():-(1/0),l=this.startDate!==-(1/0)?this.startDate.getUTCMonth():-(1/0),m=this.endDate!==1/0?this.endDate.getUTCFullYear():1/0,n=this.endDate!==1/0?this.endDate.getUTCMonth():1/0,o=this.date&&b(this.date.getUTCFullYear(),this.date.getUTCMonth(),this.date.getUTCDate()).valueOf(),p=new Date;d[this.language].titleFormat||d.en.titleFormat;this.picker.find(".datepicker-days thead th:eq(1)").text(d[this.language].months[g]+" "+f),this.picker.find(".datepicker-hours thead th:eq(1)").text(h+" "+d[this.language].months[g]+" "+f),this.picker.find(".datepicker-minutes thead th:eq(1)").text(h+" "+d[this.language].months[g]+" "+f),this.picker.find("tfoot th.today").text(d[this.language].today).toggle(this.todayBtn!==!1),this.updateNavArrows(),this.fillMonths();var q=b(f,g-1,28,0,0,0,0),r=e.getDaysInMonth(q.getUTCFullYear(),q.getUTCMonth());q.setUTCDate(r),q.setUTCDate(r-(q.getUTCDay()-this.weekStart+7)%7);var s=new Date(q.valueOf());s.setUTCDate(s.getUTCDate()+42),s=s.valueOf();for(var t,u=[];q.valueOf()<s;){if(q.getUTCDay()==this.weekStart&&(u.push("<tr>"),this.calendarWeeks)){var v=new Date(q.getUTCFullYear(),q.getUTCMonth(),q.getUTCDate()-q.getDay()+10-(this.weekStart&&this.weekStart%7<5&&7)),w=new Date(v.getFullYear(),0,4),x=~~((v-w)/864e5/7+1.5);u.push('<td class="cw">'+x+"</td>")}t=" "+this.onRender(q)+" ",q.getUTCFullYear()<f||q.getUTCFullYear()==f&&q.getUTCMonth()<g?t+=" old":(q.getUTCFullYear()>f||q.getUTCFullYear()==f&&q.getUTCMonth()>g)&&(t+=" new"),this.todayHighlight&&q.getUTCFullYear()==p.getFullYear()&&q.getUTCMonth()==p.getMonth()&&q.getUTCDate()==p.getDate()&&(t+=" today"),o&&q.valueOf()==o&&(t+=" active"),(q.valueOf()<this.startDate||q.valueOf()>this.endDate||a.inArray(q.getUTCDay(),this.daysOfWeekDisabled)!==-1||a.inArray(q.valueOf(),this.datesDisabled)!==-1)&&(t+=" disabled"),u.push('<td class="day'+t+'">'+q.getUTCDate()+"</td>"),q.getUTCDay()==this.weekEnd&&u.push("</tr>"),q.setUTCDate(q.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(u.join("")),u=[];for(var y=0;y<24;y++){var z=b(f,g,h,y);t="",z.valueOf()+36e5<this.startDate||z.valueOf()>this.endDate?t+=" disabled":i==y&&(t+=" active"),u.push('<span class="hour'+t+'">'+y+":00</span>")}this.picker.find(".datepicker-hours td").html(u.join("")),u=[];for(var y=0;y<60;y+=this.minuteStep){var z=b(f,g,h,i,y);t="",z.valueOf()<this.startDate||z.valueOf()>this.endDate?t+=" disabled":Math.floor(j/this.minuteStep)==Math.floor(y/this.minuteStep)&&(t+=" active"),u.push('<span class="minute'+t+'">'+i+":"+(y<10?"0"+y:y)+"</span>")}this.picker.find(".datepicker-minutes td").html(u.join(""));var A=this.date&&this.date.getUTCFullYear(),B=this.picker.find(".datepicker-months").find("th:eq(1)").text(f).end().find("span").removeClass("active");A&&A==f&&B.eq(this.date.getUTCMonth()).addClass("active"),(f<k||f>m)&&B.addClass("disabled"),f==k&&B.slice(0,l).addClass("disabled"),f==m&&B.slice(n+1).addClass("disabled"),u="",f=10*parseInt(f/10,10);var C=this.picker.find(".datepicker-years").find("th:eq(1)").text(f+"-"+(f+9)).end().find("td");f-=1;for(var y=-1;y<11;y++)u+='<span class="year'+(y==-1||10==y?" old":"")+(A==f?" active":"")+(f<k||f>m?" disabled":"")+'">'+f+"</span>",f+=1;C.html(u)}},updateNavArrows:function(){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth(),d=a.getUTCDate(),e=a.getUTCHours();switch(this.viewMode){case 0:this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()&&d<=this.startDate.getUTCDate()&&e<=this.startDate.getUTCHours()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()&&d>=this.endDate.getUTCDate()&&e>=this.endDate.getUTCHours()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()&&d<=this.startDate.getUTCDate()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()&&d>=this.endDate.getUTCDate()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 2:this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 3:case 4:this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}},click:function(c){c.stopPropagation(),c.preventDefault(),(a(c.target).hasClass("datepicker-close")||a(c.target).parent().hasClass("datepicker-close"))&&this.hide();var d=a(c.target).closest("span, td, th");if(1==d.length){if(d.is(".disabled"))return void this.element.trigger({type:"outOfRange",date:this.viewDate,startDate:this.startDate,endDate:this.endDate});switch(d[0].nodeName.toLowerCase()){case"th":switch(d[0].className){case"date-switch":this.showMode(1);break;case"prev":case"next":var f=e.modes[this.viewMode].navStep*("prev"==d[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveHour(this.viewDate,f);break;case 1:this.viewDate=this.moveDate(this.viewDate,f);break;case 2:this.viewDate=this.moveMonth(this.viewDate,f);break;case 3:case 4:this.viewDate=this.moveYear(this.viewDate,f)}this.fill();break;case"today":var g=new Date;g=b(g.getFullYear(),g.getMonth(),g.getDate(),g.getHours(),g.getMinutes(),g.getSeconds()),this.viewMode=this.startViewMode,this.showMode(0),this._setDate(g)}break;case"span":if(!d.is(".disabled")){if(d.is(".month"))if(3===this.minView){var h=d.parent().find("span").index(d)||0,i=this.viewDate.getUTCFullYear(),j=1,k=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();this._setDate(b(i,h,j,k,l,m,0))}else{this.viewDate.setUTCDate(1);var h=d.parent().find("span").index(d);this.viewDate.setUTCMonth(h),this.element.trigger({type:"changeMonth",date:this.viewDate})}else if(d.is(".year"))if(4===this.minView){var i=parseInt(d.text(),10)||0,h=0,j=1,k=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();this._setDate(b(i,h,j,k,l,m,0))}else{this.viewDate.setUTCDate(1);var i=parseInt(d.text(),10)||0;this.viewDate.setUTCFullYear(i),this.element.trigger({type:"changeYear",date:this.viewDate})}else if(d.is(".hour")){var k=parseInt(d.text(),10)||0,i=this.viewDate.getUTCFullYear(),h=this.viewDate.getUTCMonth(),j=this.viewDate.getUTCDate(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();this._setDate(b(i,h,j,k,l,m,0))}else if(d.is(".minute")){var l=parseInt(d.text().substr(d.text().indexOf(":")+1),10)||0,i=this.viewDate.getUTCFullYear(),h=this.viewDate.getUTCMonth(),j=this.viewDate.getUTCDate(),k=this.viewDate.getUTCHours(),m=this.viewDate.getUTCSeconds();this._setDate(b(i,h,j,k,l,m,0))}if(0!=this.viewMode){var n=this.viewMode;this.showMode(-1),this.fill(),n==this.viewMode&&this.autoclose&&this.hide()}else this.fill(),this.autoclose&&this.hide()}break;case"td":if(d.is(".day")&&!d.is(".disabled")){var j=parseInt(d.text(),10)||1,i=this.viewDate.getUTCFullYear(),h=this.viewDate.getUTCMonth(),k=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();d.is(".old")?0===h?(h=11,i-=1):h-=1:d.is(".new")&&(11==h?(h=0,i+=1):h+=1),this._setDate(b(i,h,j,k,l,m,0))}var n=this.viewMode;this.showMode(-1),this.fill(),n==this.viewMode&&this.autoclose&&this.hide()}}},_setDate:function(a,b){b&&"date"!=b||(this.date=a),b&&"view"!=b||(this.viewDate=a),this.fill(),this.setValue(),this.element.trigger({type:"changeDate",date:this.date});var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&(c.change(),this.autoclose&&(!b||"date"==b))},moveHour:function(a,b){if(!b)return a;var c=new Date(a.valueOf());return b=b>0?1:-1,c.setUTCHours(c.getUTCHours()+b),c},moveDate:function(a,b){if(!b)return a;var c=new Date(a.valueOf());return b=b>0?1:-1,c.setUTCDate(c.getUTCDate()+b),c},moveMonth:function(a,b){if(!b)return a;var c,d,e=new Date(a.valueOf()),f=e.getUTCDate(),g=e.getUTCMonth(),h=Math.abs(b);if(b=b>0?1:-1,1==h)d=b==-1?function(){return e.getUTCMonth()==g}:function(){return e.getUTCMonth()!=c},c=g+b,e.setUTCMonth(c),(c<0||c>11)&&(c=(c+12)%12);else{for(var i=0;i<h;i++)e=this.moveMonth(e,b);c=e.getUTCMonth(),e.setUTCDate(f),d=function(){return c!=e.getUTCMonth()}}for(;d();)e.setUTCDate(--f),e.setUTCMonth(c);return e},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.startDate&&a<=this.endDate},keydown:function(a){if(!this.keyboardNavigation)return!0;if(this.picker.is(":not(:visible)"))return void(27==a.keyCode&&this.show());var b,c,d,e=!1;switch(a.keyCode){case 27:this.hide(),a.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;b=37==a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):a.shiftKey?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):(c=new Date(this.date.valueOf()),c.setUTCDate(this.date.getUTCDate()+b),d=new Date(this.viewDate.valueOf()),d.setUTCDate(this.viewDate.getUTCDate()+b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 38:case 40:if(!this.keyboardNavigation)break;b=38==a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):a.shiftKey?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):(c=new Date(this.date.valueOf()),c.setUTCDate(this.date.getUTCDate()+7*b),d=new Date(this.viewDate.valueOf()),d.setUTCDate(this.viewDate.getUTCDate()+7*b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 13:this.hide(),a.preventDefault();break;case 9:this.hide()}if(e){this.element.trigger({type:"changeDate",date:this.date});var f;this.isInput?f=this.element:this.component&&(f=this.element.find("input")),f&&f.change()}},showMode:function(a){if(a){var b=Math.max(0,Math.min(e.modes.length-1,this.viewMode+a));b>=this.minView&&b<=this.maxView&&(this.viewMode=b)}this.picker.find(">div").hide().filter(".datepicker-"+e.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()},reset:function(a){this._setDate(null,"date")}},a.fn.fdatepicker=function(b){var d=Array.apply(null,arguments);return d.shift(),this.each(function(){var e=a(this),f=e.data("datepicker"),g="object"==typeof b&&b;f||e.data("datepicker",f=new c(this,a.extend({},a.fn.fdatepicker.defaults,g))),"string"==typeof b&&"function"==typeof f[b]&&f[b].apply(f,d)})},a.fn.fdatepicker.defaults={onRender:function(a){return""}},a.fn.fdatepicker.Constructor=c;var d=a.fn.fdatepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",titleFormat:"MM yyyy"}},e={modes:[{clsName:"minutes",navFnc:"Hours",navStep:1},{clsName:"hours",navFnc:"Date",navStep:1},{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,e.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/hh?|ii?|ss?|dd?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){var b=a.replace(this.validParts,"\0").split("\0"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return this.formatText=a,{separators:b,parts:c}},parseDate:function(c,e,f){if(c instanceof Date)return new Date(c.valueOf()-6e4*c.getTimezoneOffset());if(/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(c)&&(e=this.parseFormat("yyyy-mm-dd")),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(c)&&(e=this.parseFormat("yyyy-mm-dd hh:ii")),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(c)&&(e=this.parseFormat("yyyy-mm-dd hh:ii:ss")),/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(c)){var g,h,i=/([-+]\d+)([dmwy])/,j=c.match(/([-+]\d+)([dmwy])/g);c=new Date;for(var k=0;k<j.length;k++)switch(g=i.exec(j[k]),h=parseInt(g[1]),g[2]){case"d":c.setUTCDate(c.getUTCDate()+h);break;case"m":c=Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype,c,h);break;case"w":c.setUTCDate(c.getUTCDate()+7*h);break;case"y":c=Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype,c,h)}return b(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate(),c.getUTCHours(),c.getUTCMinutes(),c.getUTCSeconds())}var l,m,g,j=c&&c.match(this.nonpunctuation)||[],c=new Date,n={},o=["hh","h","ii","i","ss","s","yyyy","yy","M","MM","m","mm","d","dd"],p={hh:function(a,b){return a.setUTCHours(b)},h:function(a,b){return a.setUTCHours(b)},ii:function(a,b){return a.setUTCMinutes(b)},i:function(a,b){return a.setUTCMinutes(b)},ss:function(a,b){return a.setUTCSeconds(b)},s:function(a,b){return a.setUTCSeconds(b)},yyyy:function(a,b){return a.setUTCFullYear(b)},yy:function(a,b){return a.setUTCFullYear(2e3+b)},m:function(a,b){for(b-=1;b<0;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!=b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};if(p.M=p.MM=p.mm=p.m,p.dd=p.d,c=b(c.getFullYear(),c.getMonth(),c.getDate(),0,0,0),j.length==e.parts.length){for(var k=0,q=e.parts.length;k<q;k++){if(l=parseInt(j[k],10),g=e.parts[k],isNaN(l))switch(g){case"MM":m=a(d[f].months).filter(function(){var a=this.slice(0,j[k].length),b=j[k].slice(0,a.length);return a==b}),l=a.inArray(m[0],d[f].months)+1;break;case"M":m=a(d[f].monthsShort).filter(function(){var a=this.slice(0,j[k].length),b=j[k].slice(0,a.length);return a==b}),l=a.inArray(m[0],d[f].monthsShort)+1}n[g]=l}for(var r,k=0;k<o.length;k++)r=o[k],r in n&&!isNaN(n[r])&&p[r](c,n[r])}return c},formatDate:function(b,c,e){if(null==b)return"";var f={h:b.getUTCHours(),i:b.getUTCMinutes(),s:b.getUTCSeconds(),d:b.getUTCDate(),m:b.getUTCMonth()+1,M:d[e].monthsShort[b.getUTCMonth()],MM:d[e].months[b.getUTCMonth()],yy:b.getUTCFullYear().toString().substring(2),yyyy:b.getUTCFullYear()};f.hh=(f.h<10?"0":"")+f.h,f.ii=(f.i<10?"0":"")+f.i,f.ss=(f.s<10?"0":"")+f.s,f.dd=(f.d<10?"0":"")+f.d,f.mm=(f.m<10?"0":"")+f.m;for(var b=[],g=a.extend([],c.separators),h=0,i=c.parts.length;h<i;h++)g.length&&b.push(g.shift()),b.push(f[c.parts[h]]);return b.join("")},convertViewMode:function(a){switch(a){case 4:case"decade":a=4;break;case 3:case"year":a=3;break;case 2:case"month":a=2;break;case 1:case"day":a=1;break;case 0:case"hour":a=0}return a},headTemplate:function(a,b){return'<thead><tr><th class="prev">'+a+'</th><th colspan="5" class="date-switch"></th><th class="next">'+b+"</th></tr></thead>"},contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>',footTemplate:'<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'};e.template=function(a,b,c){return'<div class="datepicker"><div class="datepicker-minutes"><table class=" table-condensed">'+e.headTemplate(a,b)+e.contTemplate+e.footTemplate+'</table></div><div class="datepicker-hours"><table class=" table-condensed">'+e.headTemplate(a,b)+e.contTemplate+e.footTemplate+'</table></div><div class="datepicker-days"><table class=" table-condensed">'+e.headTemplate(a,b)+"<tbody></tbody>"+e.footTemplate+'</table></div><div class="datepicker-months"><table class="table-condensed">'+e.headTemplate(a,b)+e.contTemplate+e.footTemplate+'</table></div><div class="datepicker-years"><table class="table-condensed">'+e.headTemplate(a,b)+e.contTemplate+e.footTemplate+'</table></div><a class="button datepicker-close tiny alert right" style="width:auto;">'+c+"</a></div>"},a.fn.fdatepicker.DPGlobal=e}(window.jQuery);
},{}],622:[function(require,module,exports){
/*
 * Foundation Responsive Library
 * http://foundation.zurb.com
 * Copyright 2015, ZURB
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
*/

(function ($, window, document, undefined) {
  'use strict';

  var header_helpers = function (class_array) {
    var head = $('head');
    head.prepend($.map(class_array, function (class_name) {
      if (head.has('.' + class_name).length === 0) {
        return '<meta class="' + class_name + '" />';
      }
    }));
  };

  header_helpers([
    'foundation-mq-small',
    'foundation-mq-small-only',
    'foundation-mq-medium',
    'foundation-mq-medium-only',
    'foundation-mq-large',
    'foundation-mq-large-only',
    'foundation-mq-xlarge',
    'foundation-mq-xlarge-only',
    'foundation-mq-xxlarge',
    'foundation-data-attribute-namespace']);

  // Enable FastClick if present

  $(function () {
    if (typeof FastClick !== 'undefined') {
      // Don't attach to body if undefined
      if (typeof document.body !== 'undefined') {
        FastClick.attach(document.body);
      }
    }
  });

  // private Fast Selector wrapper,
  // returns jQuery object. Only use where
  // getElementById is not available.
  var S = function (selector, context) {
    if (typeof selector === 'string') {
      if (context) {
        var cont;
        if (context.jquery) {
          cont = context[0];
          if (!cont) {
            return context;
          }
        } else {
          cont = context;
        }
        return $(cont.querySelectorAll(selector));
      }

      return $(document.querySelectorAll(selector));
    }

    return $(selector, context);
  };

  // Namespace functions.

  var attr_name = function (init) {
    var arr = [];
    if (!init) {
      arr.push('data');
    }
    if (this.namespace.length > 0) {
      arr.push(this.namespace);
    }
    arr.push(this.name);

    return arr.join('-');
  };

  var add_namespace = function (str) {
    var parts = str.split('-'),
        i = parts.length,
        arr = [];

    while (i--) {
      if (i !== 0) {
        arr.push(parts[i]);
      } else {
        if (this.namespace.length > 0) {
          arr.push(this.namespace, parts[i]);
        } else {
          arr.push(parts[i]);
        }
      }
    }

    return arr.reverse().join('-');
  };

  // Event binding and data-options updating.

  var bindings = function (method, options) {
    var self = this,
        bind = function(){
          var $this = S(this),
              should_bind_events = !$this.data(self.attr_name(true) + '-init');
          $this.data(self.attr_name(true) + '-init', $.extend({}, self.settings, (options || method), self.data_options($this)));

          if (should_bind_events) {
            self.events(this);
          }
        };

    if (S(this.scope).is('[' + this.attr_name() +']')) {
      bind.call(this.scope);
    } else {
      S('[' + this.attr_name() +']', this.scope).each(bind);
    }
    // # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating.
    if (typeof method === 'string') {
      return this[method].call(this, options);
    }

  };

  var single_image_loaded = function (image, callback) {
    function loaded () {
      callback(image[0]);
    }

    function bindLoad () {
      this.one('load', loaded);

      if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
        var src = this.attr( 'src' ),
            param = src.match( /\?/ ) ? '&' : '?';

        param += 'random=' + (new Date()).getTime();
        this.attr('src', src + param);
      }
    }

    if (!image.attr('src')) {
      loaded();
      return;
    }

    if (image[0].complete || image[0].readyState === 4) {
      loaded();
    } else {
      bindLoad.call(image);
    }
  };

  /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */

  window.matchMedia || (window.matchMedia = function() {
      "use strict";

      // For browsers that support matchMedium api such as IE 9 and webkit
      var styleMedia = (window.styleMedia || window.media);

      // For those that don't support matchMedium
      if (!styleMedia) {
          var style       = document.createElement('style'),
              script      = document.getElementsByTagName('script')[0],
              info        = null;

          style.type  = 'text/css';
          style.id    = 'matchmediajs-test';

          script.parentNode.insertBefore(style, script);

          // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
          info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;

          styleMedia = {
              matchMedium: function(media) {
                  var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';

                  // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
                  if (style.styleSheet) {
                      style.styleSheet.cssText = text;
                  } else {
                      style.textContent = text;
                  }

                  // Test if media query is true or false
                  return info.width === '1px';
              }
          };
      }

      return function(media) {
          return {
              matches: styleMedia.matchMedium(media || 'all'),
              media: media || 'all'
          };
      };
  }());

  /*
   * jquery.requestAnimationFrame
   * https://github.com/gnarf37/jquery-requestAnimationFrame
   * Requires jQuery 1.8+
   *
   * Copyright (c) 2012 Corey Frang
   * Licensed under the MIT license.
   */

  (function(jQuery) {


  // requestAnimationFrame polyfill adapted from Erik Möller
  // fixes from Paul Irish and Tino Zijdel
  // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

  var animating,
      lastTime = 0,
      vendors = ['webkit', 'moz'],
      requestAnimationFrame = window.requestAnimationFrame,
      cancelAnimationFrame = window.cancelAnimationFrame,
      jqueryFxAvailable = 'undefined' !== typeof jQuery.fx;

  for (; lastTime < vendors.length && !requestAnimationFrame; lastTime++) {
    requestAnimationFrame = window[ vendors[lastTime] + 'RequestAnimationFrame' ];
    cancelAnimationFrame = cancelAnimationFrame ||
      window[ vendors[lastTime] + 'CancelAnimationFrame' ] ||
      window[ vendors[lastTime] + 'CancelRequestAnimationFrame' ];
  }

  function raf() {
    if (animating) {
      requestAnimationFrame(raf);

      if (jqueryFxAvailable) {
        jQuery.fx.tick();
      }
    }
  }

  if (requestAnimationFrame) {
    // use rAF
    window.requestAnimationFrame = requestAnimationFrame;
    window.cancelAnimationFrame = cancelAnimationFrame;

    if (jqueryFxAvailable) {
      jQuery.fx.timer = function (timer) {
        if (timer() && jQuery.timers.push(timer) && !animating) {
          animating = true;
          raf();
        }
      };

      jQuery.fx.stop = function () {
        animating = false;
      };
    }
  } else {
    // polyfill
    window.requestAnimationFrame = function (callback) {
      var currTime = new Date().getTime(),
        timeToCall = Math.max(0, 16 - (currTime - lastTime)),
        id = window.setTimeout(function () {
          callback(currTime + timeToCall);
        }, timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };

    window.cancelAnimationFrame = function (id) {
      clearTimeout(id);
    };

  }

  }( $ ));

  function removeQuotes (string) {
    if (typeof string === 'string' || string instanceof String) {
      string = string.replace(/^['\\/"]+|(;\s?})+|['\\/"]+$/g, '');
    }

    return string;
  }

  function MediaQuery(selector) {
    this.selector = selector;
    this.query = '';
  }

  MediaQuery.prototype.toString = function () {
    return this.query || (this.query = S(this.selector).css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''));
  };

  window.Foundation = {
    name : 'Foundation',

    version : '5.5.3',

    media_queries : {
      'small'       : new MediaQuery('.foundation-mq-small'),
      'small-only'  : new MediaQuery('.foundation-mq-small-only'),
      'medium'      : new MediaQuery('.foundation-mq-medium'),
      'medium-only' : new MediaQuery('.foundation-mq-medium-only'),
      'large'       : new MediaQuery('.foundation-mq-large'),
      'large-only'  : new MediaQuery('.foundation-mq-large-only'),
      'xlarge'      : new MediaQuery('.foundation-mq-xlarge'),
      'xlarge-only' : new MediaQuery('.foundation-mq-xlarge-only'),
      'xxlarge'     : new MediaQuery('.foundation-mq-xxlarge')
    },

    stylesheet : $('<style></style>').appendTo('head')[0].sheet,

    global : {
      namespace : undefined
    },

    init : function (scope, libraries, method, options, response) {
      var args = [scope, method, options, response],
          responses = [];

      // check RTL
      this.rtl = /rtl/i.test(S('html').attr('dir'));

      // set foundation global scope
      this.scope = scope || this.scope;

      this.set_namespace();

      if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) {
        if (this.libs.hasOwnProperty(libraries)) {
          responses.push(this.init_lib(libraries, args));
        }
      } else {
        for (var lib in this.libs) {
          responses.push(this.init_lib(lib, libraries));
        }
      }

      S(window).load(function () {
        S(window)
          .trigger('resize.fndtn.clearing')
          .trigger('resize.fndtn.dropdown')
          .trigger('resize.fndtn.equalizer')
          .trigger('resize.fndtn.interchange')
          .trigger('resize.fndtn.joyride')
          .trigger('resize.fndtn.magellan')
          .trigger('resize.fndtn.topbar')
          .trigger('resize.fndtn.slider');
      });

      return scope;
    },

    init_lib : function (lib, args) {
      if (this.libs.hasOwnProperty(lib)) {
        this.patch(this.libs[lib]);

        if (args && args.hasOwnProperty(lib)) {
            if (typeof this.libs[lib].settings !== 'undefined') {
              $.extend(true, this.libs[lib].settings, args[lib]);
            } else if (typeof this.libs[lib].defaults !== 'undefined') {
              $.extend(true, this.libs[lib].defaults, args[lib]);
            }
          return this.libs[lib].init.apply(this.libs[lib], [this.scope, args[lib]]);
        }

        args = args instanceof Array ? args : new Array(args);
        return this.libs[lib].init.apply(this.libs[lib], args);
      }

      return function () {};
    },

    patch : function (lib) {
      lib.scope = this.scope;
      lib.namespace = this.global.namespace;
      lib.rtl = this.rtl;
      lib['data_options'] = this.utils.data_options;
      lib['attr_name'] = attr_name;
      lib['add_namespace'] = add_namespace;
      lib['bindings'] = bindings;
      lib['S'] = this.utils.S;
    },

    inherit : function (scope, methods) {
      var methods_arr = methods.split(' '),
          i = methods_arr.length;

      while (i--) {
        if (this.utils.hasOwnProperty(methods_arr[i])) {
          scope[methods_arr[i]] = this.utils[methods_arr[i]];
        }
      }
    },

    set_namespace : function () {

      // Description:
      //    Don't bother reading the namespace out of the meta tag
      //    if the namespace has been set globally in javascript
      //
      // Example:
      //    Foundation.global.namespace = 'my-namespace';
      // or make it an empty string:
      //    Foundation.global.namespace = '';
      //
      //

      // If the namespace has not been set (is undefined), try to read it out of the meta element.
      // Otherwise use the globally defined namespace, even if it's empty ('')
      var namespace = ( this.global.namespace === undefined ) ? $('.foundation-data-attribute-namespace').css('font-family') : this.global.namespace;

      // Finally, if the namsepace is either undefined or false, set it to an empty string.
      // Otherwise use the namespace value.
      this.global.namespace = ( namespace === undefined || /false/i.test(namespace) ) ? '' : namespace;
    },

    libs : {},

    // methods that can be inherited in libraries
    utils : {

      // Description:
      //    Fast Selector wrapper returns jQuery object. Only use where getElementById
      //    is not available.
      //
      // Arguments:
      //    Selector (String): CSS selector describing the element(s) to be
      //    returned as a jQuery object.
      //
      //    Scope (String): CSS selector describing the area to be searched. Default
      //    is document.
      //
      // Returns:
      //    Element (jQuery Object): jQuery object containing elements matching the
      //    selector within the scope.
      S : S,

      // Description:
      //    Executes a function a max of once every n milliseconds
      //
      // Arguments:
      //    Func (Function): Function to be throttled.
      //
      //    Delay (Integer): Function execution threshold in milliseconds.
      //
      // Returns:
      //    Lazy_function (Function): Function with throttling applied.
      throttle : function (func, delay) {
        var timer = null;

        return function () {
          var context = this, args = arguments;

          if (timer == null) {
            timer = setTimeout(function () {
              func.apply(context, args);
              timer = null;
            }, delay);
          }
        };
      },

      // Description:
      //    Executes a function when it stops being invoked for n seconds
      //    Modified version of _.debounce() http://underscorejs.org
      //
      // Arguments:
      //    Func (Function): Function to be debounced.
      //
      //    Delay (Integer): Function execution threshold in milliseconds.
      //
      //    Immediate (Bool): Whether the function should be called at the beginning
      //    of the delay instead of the end. Default is false.
      //
      // Returns:
      //    Lazy_function (Function): Function with debouncing applied.
      debounce : function (func, delay, immediate) {
        var timeout, result;
        return function () {
          var context = this, args = arguments;
          var later = function () {
            timeout = null;
            if (!immediate) {
              result = func.apply(context, args);
            }
          };
          var callNow = immediate && !timeout;
          clearTimeout(timeout);
          timeout = setTimeout(later, delay);
          if (callNow) {
            result = func.apply(context, args);
          }
          return result;
        };
      },

      // Description:
      //    Parses data-options attribute
      //
      // Arguments:
      //    El (jQuery Object): Element to be parsed.
      //
      // Returns:
      //    Options (Javascript Object): Contents of the element's data-options
      //    attribute.
      data_options : function (el, data_attr_name) {
        data_attr_name = data_attr_name || 'options';
        var opts = {}, ii, p, opts_arr,
            data_options = function (el) {
              var namespace = Foundation.global.namespace;

              if (namespace.length > 0) {
                return el.data(namespace + '-' + data_attr_name);
              }

              return el.data(data_attr_name);
            };

        var cached_options = data_options(el);

        if (typeof cached_options === 'object') {
          return cached_options;
        }

        opts_arr = (cached_options || ':').split(';');
        ii = opts_arr.length;

        function isNumber (o) {
          return !isNaN (o - 0) && o !== null && o !== '' && o !== false && o !== true;
        }

        function trim (str) {
          if (typeof str === 'string') {
            return $.trim(str);
          }
          return str;
        }

        while (ii--) {
          p = opts_arr[ii].split(':');
          p = [p[0], p.slice(1).join(':')];

          if (/true/i.test(p[1])) {
            p[1] = true;
          }
          if (/false/i.test(p[1])) {
            p[1] = false;
          }
          if (isNumber(p[1])) {
            if (p[1].indexOf('.') === -1) {
              p[1] = parseInt(p[1], 10);
            } else {
              p[1] = parseFloat(p[1]);
            }
          }

          if (p.length === 2 && p[0].length > 0) {
            opts[trim(p[0])] = trim(p[1]);
          }
        }

        return opts;
      },

      // Description:
      //    Adds JS-recognizable media queries
      //
      // Arguments:
      //    Media (String): Key string for the media query to be stored as in
      //    Foundation.media_queries
      //
      //    Class (String): Class name for the generated <meta> tag
      register_media : function (media, media_class) {
        if (Foundation.media_queries[media] === undefined) {
          $('head').append('<meta class="' + media_class + '"/>');
          Foundation.media_queries[media] = removeQuotes($('.' + media_class).css('font-family'));
        }
      },

      // Description:
      //    Add custom CSS within a JS-defined media query
      //
      // Arguments:
      //    Rule (String): CSS rule to be appended to the document.
      //
      //    Media (String): Optional media query string for the CSS rule to be
      //    nested under.
      add_custom_rule : function (rule, media) {
        if (media === undefined && Foundation.stylesheet) {
          Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length);
        } else {
          var query = Foundation.media_queries[media];

          if (query !== undefined) {
            Foundation.stylesheet.insertRule('@media ' +
              Foundation.media_queries[media] + '{ ' + rule + ' }', Foundation.stylesheet.cssRules.length);
          }
        }
      },

      // Description:
      //    Performs a callback function when an image is fully loaded
      //
      // Arguments:
      //    Image (jQuery Object): Image(s) to check if loaded.
      //
      //    Callback (Function): Function to execute when image is fully loaded.
      image_loaded : function (images, callback) {
        var self = this,
            unloaded = images.length;

        function pictures_has_height(images) {
          var pictures_number = images.length;

          for (var i = pictures_number - 1; i >= 0; i--) {
            if(images.attr('height') === undefined) {
              return false;
            };
          };

          return true;
        }

        if (unloaded === 0 || pictures_has_height(images)) {
          callback(images);
        }

        images.each(function () {
          single_image_loaded(self.S(this), function () {
            unloaded -= 1;
            if (unloaded === 0) {
              callback(images);
            }
          });
        });
      },

      // Description:
      //    Returns a random, alphanumeric string
      //
      // Arguments:
      //    Length (Integer): Length of string to be generated. Defaults to random
      //    integer.
      //
      // Returns:
      //    Rand (String): Pseudo-random, alphanumeric string.
      random_str : function () {
        if (!this.fidx) {
          this.fidx = 0;
        }
        this.prefix = this.prefix || [(this.name || 'F'), (+new Date).toString(36)].join('-');

        return this.prefix + (this.fidx++).toString(36);
      },

      // Description:
      //    Helper for window.matchMedia
      //
      // Arguments:
      //    mq (String): Media query
      //
      // Returns:
      //    (Boolean): Whether the media query passes or not
      match : function (mq) {
        return window.matchMedia(mq).matches;
      },

      // Description:
      //    Helpers for checking Foundation default media queries with JS
      //
      // Returns:
      //    (Boolean): Whether the media query passes or not

      is_small_up : function () {
        return this.match(Foundation.media_queries.small);
      },

      is_medium_up : function () {
        return this.match(Foundation.media_queries.medium);
      },

      is_large_up : function () {
        return this.match(Foundation.media_queries.large);
      },

      is_xlarge_up : function () {
        return this.match(Foundation.media_queries.xlarge);
      },

      is_xxlarge_up : function () {
        return this.match(Foundation.media_queries.xxlarge);
      },

      is_small_only : function () {
        return !this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up();
      },

      is_medium_only : function () {
        return this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up();
      },

      is_large_only : function () {
        return this.is_medium_up() && this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up();
      },

      is_xlarge_only : function () {
        return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && !this.is_xxlarge_up();
      },

      is_xxlarge_only : function () {
        return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && this.is_xxlarge_up();
      }
    }
  };

  $.fn.foundation = function () {
    var args = Array.prototype.slice.call(arguments, 0);

    return this.each(function () {
      Foundation.init.apply(Foundation, [this].concat(args));
      return this;
    });
  };

}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.abide = {
    name : 'abide',

    version : '5.5.3',

    settings : {
      live_validate : true, // validate the form as you go
      validate_on_blur : true, // validate whenever you focus/blur on an input field
      // validate_on: 'tab', // tab (when user tabs between fields), change (input changes), manual (call custom events)

      focus_on_invalid : true, // automatically bring the focus to an invalid input field
      error_labels : true, // labels with a for="inputId" will receive an `error` class
      error_class : 'error', // labels with a for="inputId" will receive an `error` class
      // the amount of time Abide will take before it validates the form (in ms).
      // smaller time will result in faster validation
      timeout : 1000,
      patterns : {
        alpha : /^[a-zA-Z]+$/,
        alpha_numeric : /^[a-zA-Z0-9]+$/,
        integer : /^[-+]?\d+$/,
        number : /^[-+]?\d*(?:[\.\,]\d+)?$/,

        // amex, visa, diners
        card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
        cvv : /^([0-9]){3,4}$/,

        // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
        email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,

        // http://blogs.lse.ac.uk/lti/2008/04/23/a-regular-expression-to-match-any-url/
        url: /^(https?|ftp|file|ssh):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+~%\/\.\w]+)?\??([-\+=&;%@\.\w]+)?#?([\w]+)?)?/,
        // abc.de
        domain : /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,

        datetime : /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,
        // YYYY-MM-DD
        date : /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,
        // HH:MM:SS
        time : /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,
        dateISO : /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,
        // MM/DD/YYYY
        month_day_year : /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,
        // DD/MM/YYYY
        day_month_year : /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,

        // #FFF or #FFFFFF
        color : /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
      },
      validators : {
        equalTo : function (el, required, parent) {
          var from  = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value,
              to    = el.value,
              valid = (from === to);

          return valid;
        }
      }
    },

    timer : null,

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function (scope) {
      var self = this,
          form = self.S(scope).attr('novalidate', 'novalidate'),
          settings = form.data(this.attr_name(true) + '-init') || {};

      this.invalid_attr = this.add_namespace('data-invalid');

      function validate(originalSelf, e) {
        clearTimeout(self.timer);
        self.timer = setTimeout(function () {
          self.validate([originalSelf], e);
        }.bind(originalSelf), settings.timeout);
      }

      form
        .off('.abide')
        .on('submit.fndtn.abide', function (e) {
          var is_ajax = /ajax/i.test(self.S(this).attr(self.attr_name()));
          return self.validate(self.S(this).find('input, textarea, select').not(":hidden, [data-abide-ignore]").get(), e, is_ajax);
        })
        .on('validate.fndtn.abide', function (e) {
          if (settings.validate_on === 'manual') {
            self.validate([e.target], e);
          }
        })
        .on('reset', function (e) {
          return self.reset($(this), e);
        })
        .find('input, textarea, select').not(":hidden, [data-abide-ignore]")
          .off('.abide')
          .on('blur.fndtn.abide change.fndtn.abide', function (e) {
              var id = this.getAttribute('id'),
                  eqTo = form.find('[data-equalto="'+ id +'"]');
            // old settings fallback
            // will be deprecated with F6 release
            if (settings.validate_on_blur && settings.validate_on_blur === true) {
              validate(this, e);
            }
            // checks if there is an equalTo equivalent related by id
            if(typeof eqTo.get(0) !== "undefined" && eqTo.val().length){
              validate(eqTo.get(0),e);
            }
            // new settings combining validate options into one setting
            if (settings.validate_on === 'change') {
              validate(this, e);
            }
          })
          .on('keydown.fndtn.abide', function (e) {
            var id = this.getAttribute('id'),
                eqTo = form.find('[data-equalto="'+ id +'"]');
            // old settings fallback
            // will be deprecated with F6 release
            if (settings.live_validate && settings.live_validate === true && e.which != 9) {
              validate(this, e);
            }
            // checks if there is an equalTo equivalent related by id
            if(typeof eqTo.get(0) !== "undefined" && eqTo.val().length){
              validate(eqTo.get(0),e);
            }
            // new settings combining validate options into one setting
            if (settings.validate_on === 'tab' && e.which === 9) {
              validate(this, e);
            }
            else if (settings.validate_on === 'change') {
              validate(this, e);
            }
          })
          .on('focus', function (e) {
            if (navigator.userAgent.match(/iPad|iPhone|Android|BlackBerry|Windows Phone|webOS/i)) {
              $('html, body').animate({
                  scrollTop: $(e.target).offset().top
              }, 100);
            }
          });
    },

    reset : function (form, e) {
      var self = this;
      form.removeAttr(self.invalid_attr);

      $('[' + self.invalid_attr + ']', form).removeAttr(self.invalid_attr);
      $('.' + self.settings.error_class, form).not('small').removeClass(self.settings.error_class);
      $(':input', form).not(':button, :submit, :reset, :hidden, [data-abide-ignore]').val('').removeAttr(self.invalid_attr);
    },

    validate : function (els, e, is_ajax) {
      var validations = this.parse_patterns(els),
          validation_count = validations.length,
          form = this.S(els[0]).closest('form'),
          submit_event = /submit/.test(e.type);

      // Has to count up to make sure the focus gets applied to the top error
      for (var i = 0; i < validation_count; i++) {
        if (!validations[i] && (submit_event || is_ajax)) {
          if (this.settings.focus_on_invalid) {
            els[i].focus();
          }
          form.trigger('invalid.fndtn.abide');
          this.S(els[i]).closest('form').attr(this.invalid_attr, '');
          return false;
        }
      }

      if (submit_event || is_ajax) {
        form.trigger('valid.fndtn.abide');
      }

      form.removeAttr(this.invalid_attr);

      if (is_ajax) {
        return false;
      }

      return true;
    },

    parse_patterns : function (els) {
      var i = els.length,
          el_patterns = [];

      while (i--) {
        el_patterns.push(this.pattern(els[i]));
      }

      return this.check_validation_and_apply_styles(el_patterns);
    },

    pattern : function (el) {
      var type = el.getAttribute('type'),
          required = typeof el.getAttribute('required') === 'string';

      var pattern = el.getAttribute('pattern') || '';

      if (this.settings.patterns.hasOwnProperty(pattern) && pattern.length > 0) {
        return [el, this.settings.patterns[pattern], required];
      } else if (pattern.length > 0) {
        return [el, new RegExp(pattern), required];
      }

      if (this.settings.patterns.hasOwnProperty(type)) {
        return [el, this.settings.patterns[type], required];
      }

      pattern = /.*/;

      return [el, pattern, required];
    },

    // TODO: Break this up into smaller methods, getting hard to read.
    check_validation_and_apply_styles : function (el_patterns) {
      var i = el_patterns.length,
          validations = [];
      if (i == 0) {
        return validations;
      }
      var form = this.S(el_patterns[0][0]).closest('[data-' + this.attr_name(true) + ']'),
          settings = form.data(this.attr_name(true) + '-init') || {};
      while (i--) {
        var el = el_patterns[i][0],
            required = el_patterns[i][2],
            value = el.value.trim(),
            direct_parent = this.S(el).parent(),
            validator = el.getAttribute(this.add_namespace('data-abide-validator')),
            is_radio = el.type === 'radio',
            is_checkbox = el.type === 'checkbox',
            label = this.S('label[for="' + el.getAttribute('id') + '"]'),
            valid_length = (required) ? (el.value.length > 0) : true,
            el_validations = [];

        var parent, valid;

        // support old way to do equalTo validations
        if (el.getAttribute(this.add_namespace('data-equalto'))) { validator = 'equalTo' }

        if (!direct_parent.is('label')) {
          parent = direct_parent;
        } else {
          parent = direct_parent.parent();
        }

        if (is_radio && required) {
          el_validations.push(this.valid_radio(el, required));
        } else if (is_checkbox && required) {
          el_validations.push(this.valid_checkbox(el, required));

        } else if (validator) {
          // Validate using each of the specified (space-delimited) validators.
          var validators = validator.split(' ');
          var last_valid = true, all_valid = true;
          for (var iv = 0; iv < validators.length; iv++) {
              valid = this.settings.validators[validators[iv]].apply(this, [el, required, parent])
              el_validations.push(valid);
              all_valid = valid && last_valid;
              last_valid = valid;
          }
          if (all_valid) {
              this.S(el).removeAttr(this.invalid_attr);
              parent.removeClass('error');
              if (label.length > 0 && this.settings.error_labels) {
                label.removeClass(this.settings.error_class).removeAttr('role');
              }
              $(el).triggerHandler('valid');
          } else {
              this.S(el).attr(this.invalid_attr, '');
              parent.addClass('error');
              if (label.length > 0 && this.settings.error_labels) {
                label.addClass(this.settings.error_class).attr('role', 'alert');
              }
              $(el).triggerHandler('invalid');
          }
        } else {

          if (el_patterns[i][1].test(value) && valid_length ||
            !required && el.value.length < 1 || $(el).attr('disabled')) {
            el_validations.push(true);
          } else {
            el_validations.push(false);
          }

          el_validations = [el_validations.every(function (valid) {return valid;})];
          if (el_validations[0]) {
            this.S(el).removeAttr(this.invalid_attr);
            el.setAttribute('aria-invalid', 'false');
            el.removeAttribute('aria-describedby');
            parent.removeClass(this.settings.error_class);
            if (label.length > 0 && this.settings.error_labels) {
              label.removeClass(this.settings.error_class).removeAttr('role');
            }
            $(el).triggerHandler('valid');
          } else {
            this.S(el).attr(this.invalid_attr, '');
            el.setAttribute('aria-invalid', 'true');

            // Try to find the error associated with the input
            var errorElem = parent.find('small.' + this.settings.error_class, 'span.' + this.settings.error_class);
            var errorID = errorElem.length > 0 ? errorElem[0].id : '';
            if (errorID.length > 0) {
              el.setAttribute('aria-describedby', errorID);
            }

            // el.setAttribute('aria-describedby', $(el).find('.error')[0].id);
            parent.addClass(this.settings.error_class);
            if (label.length > 0 && this.settings.error_labels) {
              label.addClass(this.settings.error_class).attr('role', 'alert');
            }
            $(el).triggerHandler('invalid');
          }
        }
        validations = validations.concat(el_validations);
      }

      return validations;
    },

    valid_checkbox : function (el, required) {
      var el = this.S(el),
          valid = (el.is(':checked') || !required || el.get(0).getAttribute('disabled'));

      if (valid) {
        el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
        $(el).triggerHandler('valid');
      } else {
        el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
        $(el).triggerHandler('invalid');
      }

      return valid;
    },

    valid_radio : function (el, required) {
      var name = el.getAttribute('name'),
          group = this.S(el).closest('[data-' + this.attr_name(true) + ']').find("[name='" + name + "']"),
          count = group.length,
          valid = false,
          disabled = false;

      // Has to count up to make sure the focus gets applied to the top error
      for (var i=0; i < count; i++) {
        if( group[i].getAttribute('disabled') ){
          disabled=true;
          valid=true;
        } else {
          if (group[i].checked){
            valid = true;
          } else {
            if( disabled ){
              valid = false;
            }
          }
        }
      }

      // Has to count up to make sure the focus gets applied to the top error
      for (var i = 0; i < count; i++) {
        if (valid) {
          this.S(group[i]).removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
          $(group[i]).triggerHandler('valid');
        } else {
          this.S(group[i]).attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
          $(group[i]).triggerHandler('invalid');
        }
      }

      return valid;
    },

    valid_equal : function (el, required, parent) {
      var from  = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value,
          to    = el.value,
          valid = (from === to);

      if (valid) {
        this.S(el).removeAttr(this.invalid_attr);
        parent.removeClass(this.settings.error_class);
        if (label.length > 0 && settings.error_labels) {
          label.removeClass(this.settings.error_class);
        }
      } else {
        this.S(el).attr(this.invalid_attr, '');
        parent.addClass(this.settings.error_class);
        if (label.length > 0 && settings.error_labels) {
          label.addClass(this.settings.error_class);
        }
      }

      return valid;
    },

    valid_oneof : function (el, required, parent, doNotValidateOthers) {
      var el = this.S(el),
        others = this.S('[' + this.add_namespace('data-oneof') + ']'),
        valid = others.filter(':checked').length > 0;

      if (valid) {
        el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
      } else {
        el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
      }

      if (!doNotValidateOthers) {
        var _this = this;
        others.each(function () {
          _this.valid_oneof.call(_this, this, null, null, true);
        });
      }

      return valid;
    },

    reflow : function(scope, options) {
      var self = this,
          form = self.S('[' + this.attr_name() + ']').attr('novalidate', 'novalidate');
          self.S(form).each(function (idx, el) {
            self.events(el);
          });
    }
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.accordion = {
    name : 'accordion',

    version : '5.5.3',

    settings : {
      content_class : 'content',
      active_class : 'active',
      multi_expand : false,
      toggleable : true,
      callback : function () {}
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function (instance) {
      var self = this;
      var S = this.S;
      self.create(this.S(instance));

      S(this.scope)
      .off('.fndtn.accordion')
      .on('click.fndtn.accordion', '[' + this.attr_name() + '] > dd > a, [' + this.attr_name() + '] > li > a', function (e) {
        var accordion = S(this).closest('[' + self.attr_name() + ']'),
            groupSelector = self.attr_name() + '=' + accordion.attr(self.attr_name()),
            settings = accordion.data(self.attr_name(true) + '-init') || self.settings,
            target = S('#' + this.href.split('#')[1]),
            aunts = $('> dd, > li', accordion),
            siblings = aunts.children('.' + settings.content_class),
            active_content = siblings.filter('.' + settings.active_class);

        e.preventDefault();

        if (accordion.attr(self.attr_name())) {
          siblings = siblings.add('[' + groupSelector + '] dd > ' + '.' + settings.content_class + ', [' + groupSelector + '] li > ' + '.' + settings.content_class);
          aunts = aunts.add('[' + groupSelector + '] dd, [' + groupSelector + '] li');
        }

        if (settings.toggleable && target.is(active_content)) {
          target.parent('dd, li').toggleClass(settings.active_class, false);
          target.toggleClass(settings.active_class, false);
          S(this).attr('aria-expanded', function(i, attr){
              return attr === 'true' ? 'false' : 'true';
          });
          settings.callback(target);
          target.triggerHandler('toggled', [accordion]);
          accordion.triggerHandler('toggled', [target]);
          return;
        }

        if (!settings.multi_expand) {
          siblings.removeClass(settings.active_class);
          aunts.removeClass(settings.active_class);
          aunts.children('a').attr('aria-expanded','false');
        }

        target.addClass(settings.active_class).parent().addClass(settings.active_class);
        settings.callback(target);
        target.triggerHandler('toggled', [accordion]);
        accordion.triggerHandler('toggled', [target]);
        S(this).attr('aria-expanded','true');
      });
    },

    create: function($instance) {
      var self = this,
          accordion = $instance,
          aunts = $('> .accordion-navigation', accordion),
          settings = accordion.data(self.attr_name(true) + '-init') || self.settings;

      aunts.children('a').attr('aria-expanded','false');
      aunts.has('.' + settings.content_class + '.' + settings.active_class).addClass(settings.active_class).children('a').attr('aria-expanded','true');

      if (settings.multi_expand) {
        $instance.attr('aria-multiselectable','true');
      }
    },
	
  	toggle : function(options) {
  		var options = typeof options !== 'undefined' ? options : {};
  		var selector = typeof options.selector !== 'undefined' ? options.selector : '';
  		var toggle_state = typeof options.toggle_state !== 'undefined' ? options.toggle_state : '';
  		var $accordion = typeof options.$accordion !== 'undefined' ? options.$accordion : this.S(this.scope).closest('[' + this.attr_name() + ']');
  
  		var $items = $accordion.find('> dd' + selector + ', > li' + selector);
  		if ( $items.length < 1 ) {
  			if ( window.console ) {
  				console.error('Selection not found.', selector);
  			}
  			return false;
  		}
  
  		var S = this.S;
  		var active_class = this.settings.active_class;
  		$items.each(function() {
  			var $item = S(this);
  			var is_active = $item.hasClass(active_class);
  			if ( ( is_active && toggle_state === 'close' ) || ( !is_active && toggle_state === 'open' ) || toggle_state === '' ) {
  				$item.find('> a').trigger('click.fndtn.accordion');
  			}
  		});
  	},
  
  	open : function(options) {
  		var options = typeof options !== 'undefined' ? options : {};
  		options.toggle_state = 'open';
  		this.toggle(options);
  	},
  
  	close : function(options) {
  		var options = typeof options !== 'undefined' ? options : {};
  		options.toggle_state = 'close';
  		this.toggle(options);
  	},	

    off : function () {},

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.alert = {
    name : 'alert',

    version : '5.5.3',

    settings : {
      callback : function () {}
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = this.S;

      $(this.scope).off('.alert').on('click.fndtn.alert', '[' + this.attr_name() + '] .close', function (e) {
        var alertBox = S(this).closest('[' + self.attr_name() + ']'),
            settings = alertBox.data(self.attr_name(true) + '-init') || self.settings;

        e.preventDefault();
        if (Modernizr.csstransitions) {
          alertBox.addClass('alert-close');
          alertBox.on('transitionend webkitTransitionEnd oTransitionEnd', function (e) {
            S(this).trigger('close.fndtn.alert').remove();
            settings.callback();
          });
        } else {
          alertBox.fadeOut(300, function () {
            S(this).trigger('close.fndtn.alert').remove();
            settings.callback();
          });
        }
      });
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.clearing = {
    name : 'clearing',

    version : '5.5.3',

    settings : {
      templates : {
        viewing : '<a href="#" class="clearing-close">&times;</a>' +
          '<div class="visible-img" style="display: none"><div class="clearing-touch-label"></div><img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' +
          '<p class="clearing-caption"></p><a href="#" class="clearing-main-prev"><span></span></a>' +
          '<a href="#" class="clearing-main-next"><span></span></a></div>' +
          '<img class="clearing-preload-next" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' +
          '<img class="clearing-preload-prev" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />'
      },

      // comma delimited list of selectors that, on click, will close clearing,
      // add 'div.clearing-blackout, div.visible-img' to close on background click
      close_selectors : '.clearing-close, div.clearing-blackout',

      // Default to the entire li element.
      open_selectors : '',

      // Image will be skipped in carousel.
      skip_selector : '',

      touch_label : '',

      // event initializer and locks
      init : false,
      locked : false
    },

    init : function (scope, method, options) {
      var self = this;
      Foundation.inherit(this, 'throttle image_loaded');

      this.bindings(method, options);

      if (self.S(this.scope).is('[' + this.attr_name() + ']')) {
        this.assemble(self.S('li', this.scope));
      } else {
        self.S('[' + this.attr_name() + ']', this.scope).each(function () {
          self.assemble(self.S('li', this));
        });
      }
    },

    events : function (scope) {
      var self = this,
          S = self.S,
          $scroll_container = $('.scroll-container');

      if ($scroll_container.length > 0) {
        this.scope = $scroll_container;
      }

      S(this.scope)
        .off('.clearing')
        .on('click.fndtn.clearing', 'ul[' + this.attr_name() + '] li ' + this.settings.open_selectors,
          function (e, current, target) {
            var current = current || S(this),
                target = target || current,
                next = current.next('li'),
                settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'),
                image = S(e.target);

            e.preventDefault();

            if (!settings) {
              self.init();
              settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
            }

            // if clearing is open and the current image is
            // clicked, go to the next image in sequence
            if (target.hasClass('visible') &&
              current[0] === target[0] &&
              next.length > 0 && self.is_open(current)) {
              target = next;
              image = S('img', target);
            }

            // set current and target to the clicked li if not otherwise defined.
            self.open(image, current, target);
            self.update_paddles(target);
          })

        .on('click.fndtn.clearing', '.clearing-main-next',
          function (e) { self.nav(e, 'next') })
        .on('click.fndtn.clearing', '.clearing-main-prev',
          function (e) { self.nav(e, 'prev') })
        .on('click.fndtn.clearing', this.settings.close_selectors,
          function (e) { Foundation.libs.clearing.close(e, this) });

      $(document).on('keydown.fndtn.clearing',
          function (e) { self.keydown(e) });

      S(window).off('.clearing').on('resize.fndtn.clearing',
        function () { self.resize() });

      this.swipe_events(scope);
    },

    swipe_events : function (scope) {
      var self = this,
      S = self.S;

      S(this.scope)
        .on('touchstart.fndtn.clearing', '.visible-img', function (e) {
          if (!e.touches) { e = e.originalEvent; }
          var data = {
                start_page_x : e.touches[0].pageX,
                start_page_y : e.touches[0].pageY,
                start_time : (new Date()).getTime(),
                delta_x : 0,
                is_scrolling : undefined
              };

          S(this).data('swipe-transition', data);
          e.stopPropagation();
        })
        .on('touchmove.fndtn.clearing', '.visible-img', function (e) {
          if (!e.touches) {
            e = e.originalEvent;
          }
          // Ignore pinch/zoom events
          if (e.touches.length > 1 || e.scale && e.scale !== 1) {
            return;
          }

          var data = S(this).data('swipe-transition');

          if (typeof data === 'undefined') {
            data = {};
          }

          data.delta_x = e.touches[0].pageX - data.start_page_x;

          if (Foundation.rtl) {
            data.delta_x = -data.delta_x;
          }

          if (typeof data.is_scrolling === 'undefined') {
            data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
          }

          if (!data.is_scrolling && !data.active) {
            e.preventDefault();
            var direction = (data.delta_x < 0) ? 'next' : 'prev';
            data.active = true;
            self.nav(e, direction);
          }
        })
        .on('touchend.fndtn.clearing', '.visible-img', function (e) {
          S(this).data('swipe-transition', {});
          e.stopPropagation();
        });
    },

    assemble : function ($li) {
      var $el = $li.parent();

      if ($el.parent().hasClass('carousel')) {
        return;
      }

      $el.after('<div id="foundationClearingHolder"></div>');

      var grid = $el.detach(),
          grid_outerHTML = '';

      if (grid[0] == null) {
        return;
      } else {
        grid_outerHTML = grid[0].outerHTML;
      }

      var holder = this.S('#foundationClearingHolder'),
          settings = $el.data(this.attr_name(true) + '-init'),
          data = {
            grid : '<div class="carousel">' + grid_outerHTML + '</div>',
            viewing : settings.templates.viewing
          },
          wrapper = '<div class="clearing-assembled"><div>' + data.viewing +
            data.grid + '</div></div>',
          touch_label = this.settings.touch_label;

      if (Modernizr.touch) {
        wrapper = $(wrapper).find('.clearing-touch-label').html(touch_label).end();
      }

      holder.after(wrapper).remove();
    },

    open : function ($image, current, target) {
      var self = this,
          body = $(document.body),
          root = target.closest('.clearing-assembled'),
          container = self.S('div', root).first(),
          visible_image = self.S('.visible-img', container),
          image = self.S('img', visible_image).not($image),
          label = self.S('.clearing-touch-label', container),
          error = false,
          loaded = {};

      // Event to disable scrolling on touch devices when Clearing is activated
      $('body').on('touchmove', function (e) {
        e.preventDefault();
      });

      image.error(function () {
        error = true;
      });

      function startLoad() {
        setTimeout(function () {
          this.image_loaded(image, function () {
            if (image.outerWidth() === 1 && !error) {
              startLoad.call(this);
            } else {
              cb.call(this, image);
            }
          }.bind(this));
        }.bind(this), 100);
      }

      function cb (image) {
        var $image = $(image);
        $image.css('visibility', 'visible');
        $image.trigger('imageVisible');
        // toggle the gallery
        body.css('overflow', 'hidden');
        root.addClass('clearing-blackout');
        container.addClass('clearing-container');
        visible_image.show();
        this.fix_height(target)
          .caption(self.S('.clearing-caption', visible_image), self.S('img', target))
          .center_and_label(image, label)
          .shift(current, target, function () {
            target.closest('li').siblings().removeClass('visible');
            target.closest('li').addClass('visible');
          });
        visible_image.trigger('opened.fndtn.clearing')
      }

      if (!this.locked()) {
        visible_image.trigger('open.fndtn.clearing');
        // set the image to the selected thumbnail
        loaded = this.load($image);
        if (loaded.interchange) {
          image
            .attr('data-interchange', loaded.interchange)
            .foundation('interchange', 'reflow');
        } else {
          image
            .attr('src', loaded.src)
            .attr('data-interchange', '');
        }
        image.css('visibility', 'hidden');

        startLoad.call(this);
      }
    },

    close : function (e, el) {
      e.preventDefault();

      var root = (function (target) {
            if (/blackout/.test(target.selector)) {
              return target;
            } else {
              return target.closest('.clearing-blackout');
            }
          }($(el))),
          body = $(document.body), container, visible_image;

      if (el === e.target && root) {
        body.css('overflow', '');
        container = $('div', root).first();
        visible_image = $('.visible-img', container);
        visible_image.trigger('close.fndtn.clearing');
        this.settings.prev_index = 0;
        $('ul[' + this.attr_name() + ']', root)
          .attr('style', '').closest('.clearing-blackout')
          .removeClass('clearing-blackout');
        container.removeClass('clearing-container');
        visible_image.hide();
        visible_image.trigger('closed.fndtn.clearing');
      }

      // Event to re-enable scrolling on touch devices
      $('body').off('touchmove');

      return false;
    },

    is_open : function (current) {
      return current.parent().prop('style').length > 0;
    },

    keydown : function (e) {
      var clearing = $('.clearing-blackout ul[' + this.attr_name() + ']'),
          NEXT_KEY = this.rtl ? 37 : 39,
          PREV_KEY = this.rtl ? 39 : 37,
          ESC_KEY = 27;

      if (e.which === NEXT_KEY) {
        this.go(clearing, 'next');
      }
      if (e.which === PREV_KEY) {
        this.go(clearing, 'prev');
      }
      if (e.which === ESC_KEY) {
        this.S('a.clearing-close').trigger('click.fndtn.clearing');
      }
    },

    nav : function (e, direction) {
      var clearing = $('ul[' + this.attr_name() + ']', '.clearing-blackout');

      e.preventDefault();
      this.go(clearing, direction);
    },

    resize : function () {
      var image = $('img', '.clearing-blackout .visible-img'),
          label = $('.clearing-touch-label', '.clearing-blackout');

      if (image.length) {
        this.center_and_label(image, label);
        image.trigger('resized.fndtn.clearing')
      }
    },

    // visual adjustments
    fix_height : function (target) {
      var lis = target.parent().children(),
          self = this;

      lis.each(function () {
        var li = self.S(this),
            image = li.find('img');

        if (li.height() > image.outerHeight()) {
          li.addClass('fix-height');
        }
      })
      .closest('ul')
      .width(lis.length * 100 + '%');

      return this;
    },

    update_paddles : function (target) {
      target = target.closest('li');
      var visible_image = target
        .closest('.carousel')
        .siblings('.visible-img');

      if (target.next().length > 0) {
        this.S('.clearing-main-next', visible_image).removeClass('disabled');
      } else {
        this.S('.clearing-main-next', visible_image).addClass('disabled');
      }

      if (target.prev().length > 0) {
        this.S('.clearing-main-prev', visible_image).removeClass('disabled');
      } else {
        this.S('.clearing-main-prev', visible_image).addClass('disabled');
      }
    },

    center_and_label : function (target, label) {
      if (!this.rtl && label.length > 0) {
        label.css({
          marginLeft : -(label.outerWidth() / 2),
          marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10
        });
      } else {
        label.css({
          marginRight : -(label.outerWidth() / 2),
          marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10,
          left: 'auto',
          right: '50%'
        });
      }
      return this;
    },

    // image loading and preloading

    load : function ($image) {
      var href,
          interchange,
          closest_a;

      if ($image[0].nodeName === 'A') {
        href = $image.attr('href');
        interchange = $image.data('clearing-interchange');
      } else {
        closest_a = $image.closest('a');
        href = closest_a.attr('href');
        interchange = closest_a.data('clearing-interchange');
      }

      this.preload($image);

      return {
        'src': href ? href : $image.attr('src'),
        'interchange': href ? interchange : $image.data('clearing-interchange')
      }
    },

    preload : function ($image) {
      this
        .img($image.closest('li').next(), 'next')
        .img($image.closest('li').prev(), 'prev');
    },

    img : function (img, sibling_type) {
      if (img.length) {
        var preload_img = $('.clearing-preload-' + sibling_type),
            new_a = this.S('a', img),
            src,
            interchange,
            image;

        if (new_a.length) {
          src = new_a.attr('href');
          interchange = new_a.data('clearing-interchange');
        } else {
          image = this.S('img', img);
          src = image.attr('src');
          interchange = image.data('clearing-interchange');
        }

        if (interchange) {
          preload_img.attr('data-interchange', interchange);
        } else {
          preload_img.attr('src', src);
          preload_img.attr('data-interchange', '');
        }
      }
      return this;
    },

    // image caption

    caption : function (container, $image) {
      var caption = $image.attr('data-caption');

      if (caption) {
      	var containerPlain = container.get(0);
      	containerPlain.innerHTML = caption;
        container.show();
      } else {
        container
          .text('')
          .hide();
      }
      return this;
    },

    // directional methods

    go : function ($ul, direction) {
      var current = this.S('.visible', $ul),
          target = current[direction]();

      // Check for skip selector.
      if (this.settings.skip_selector && target.find(this.settings.skip_selector).length != 0) {
        target = target[direction]();
      }

      if (target.length) {
        this.S('img', target)
          .trigger('click.fndtn.clearing', [current, target])
          .trigger('change.fndtn.clearing');
      }
    },

    shift : function (current, target, callback) {
      var clearing = target.parent(),
          old_index = this.settings.prev_index || target.index(),
          direction = this.direction(clearing, current, target),
          dir = this.rtl ? 'right' : 'left',
          left = parseInt(clearing.css('left'), 10),
          width = target.outerWidth(),
          skip_shift;

      var dir_obj = {};

      // we use jQuery animate instead of CSS transitions because we
      // need a callback to unlock the next animation
      // needs support for RTL **
      if (target.index() !== old_index && !/skip/.test(direction)) {
        if (/left/.test(direction)) {
          this.lock();
          dir_obj[dir] = left + width;
          clearing.animate(dir_obj, 300, this.unlock());
        } else if (/right/.test(direction)) {
          this.lock();
          dir_obj[dir] = left - width;
          clearing.animate(dir_obj, 300, this.unlock());
        }
      } else if (/skip/.test(direction)) {
        // the target image is not adjacent to the current image, so
        // do we scroll right or not
        skip_shift = target.index() - this.settings.up_count;
        this.lock();

        if (skip_shift > 0) {
          dir_obj[dir] = -(skip_shift * width);
          clearing.animate(dir_obj, 300, this.unlock());
        } else {
          dir_obj[dir] = 0;
          clearing.animate(dir_obj, 300, this.unlock());
        }
      }

      callback();
    },

    direction : function ($el, current, target) {
      var lis = this.S('li', $el),
          li_width = lis.outerWidth() + (lis.outerWidth() / 4),
          up_count = Math.floor(this.S('.clearing-container').outerWidth() / li_width) - 1,
          target_index = lis.index(target),
          response;

      this.settings.up_count = up_count;

      if (this.adjacent(this.settings.prev_index, target_index)) {
        if ((target_index > up_count) && target_index > this.settings.prev_index) {
          response = 'right';
        } else if ((target_index > up_count - 1) && target_index <= this.settings.prev_index) {
          response = 'left';
        } else {
          response = false;
        }
      } else {
        response = 'skip';
      }

      this.settings.prev_index = target_index;

      return response;
    },

    adjacent : function (current_index, target_index) {
      for (var i = target_index + 1; i >= target_index - 1; i--) {
        if (i === current_index) {
          return true;
        }
      }
      return false;
    },

    // lock management

    lock : function () {
      this.settings.locked = true;
    },

    unlock : function () {
      this.settings.locked = false;
    },

    locked : function () {
      return this.settings.locked;
    },

    off : function () {
      this.S(this.scope).off('.fndtn.clearing');
      this.S(window).off('.fndtn.clearing');
    },

    reflow : function () {
      this.init();
    }
  };

}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.dropdown = {
    name : 'dropdown',

    version : '5.5.3',

    settings : {
      active_class : 'open',
      disabled_class : 'disabled',
      mega_class : 'mega',
      align : 'bottom',
      is_hover : false,
      hover_timeout : 150,
      opened : function () {},
      closed : function () {}
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');

      $.extend(true, this.settings, method, options);
      this.bindings(method, options);
    },

    events : function (scope) {
      var self = this,
          S = self.S;

      S(this.scope)
        .off('.dropdown')
        .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) {
          var settings = S(this).data(self.attr_name(true) + '-init') || self.settings;
          if (!settings.is_hover || Modernizr.touch) {
            e.preventDefault();
            if (S(this).parent('[data-reveal-id]').length) {
              e.stopPropagation();
            }
            self.toggle($(this));
          }
        })
        .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this),
              dropdown,
              target;

          clearTimeout(self.timeout);

          if ($this.data(self.data_attr())) {
            dropdown = S('#' + $this.data(self.data_attr()));
            target = $this;
          } else {
            dropdown = $this;
            target = S('[' + self.attr_name() + '="' + dropdown.attr('id') + '"]');
          }

          var settings = target.data(self.attr_name(true) + '-init') || self.settings;

          if (S(e.currentTarget).data(self.data_attr()) && settings.is_hover) {
            self.closeall.call(self);
          }

          if (settings.is_hover) {
            self.open.apply(self, [dropdown, target]);
          }
        })
        .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this);
          var settings;

          if ($this.data(self.data_attr())) {
              settings = $this.data(self.data_attr(true) + '-init') || self.settings;
          } else {
              var target   = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'),
                  settings = target.data(self.attr_name(true) + '-init') || self.settings;
          }

          self.timeout = setTimeout(function () {
            if ($this.data(self.data_attr())) {
              if (settings.is_hover) {
                self.close.call(self, S('#' + $this.data(self.data_attr())));
              }
            } else {
              if (settings.is_hover) {
                self.close.call(self, $this);
              }
            }
          }.bind(this), settings.hover_timeout);
        })
        .on('click.fndtn.dropdown', function (e) {
          var parent = S(e.target).closest('[' + self.attr_name() + '-content]');
          var links  = parent.find('a');

          if (links.length > 0 && parent.attr('aria-autoclose') !== 'false') {
              self.close.call(self, S('[' + self.attr_name() + '-content]'));
          }

          if (e.target !== document && !$.contains(document.documentElement, e.target)) {
            return;
          }

          if (S(e.target).closest('[' + self.attr_name() + ']').length > 0) {
            return;
          }

          if (!(S(e.target).data('revealId')) &&
            (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') ||
              $.contains(parent.first()[0], e.target)))) {
            e.stopPropagation();
            return;
          }

          self.close.call(self, S('[' + self.attr_name() + '-content]'));
        })
        .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
          self.settings.opened.call(this);
        })
        .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
          self.settings.closed.call(this);
        });

      S(window)
        .off('.dropdown')
        .on('resize.fndtn.dropdown', self.throttle(function () {
          self.resize.call(self);
        }, 50));

      this.resize();
    },

    close : function (dropdown) {
      var self = this;
      dropdown.each(function (idx) {
        var original_target = $('[' + self.attr_name() + '=' + dropdown[idx].id + ']') || $('aria-controls=' + dropdown[idx].id + ']');
        original_target.attr('aria-expanded', 'false');
        if (self.S(this).hasClass(self.settings.active_class)) {
          self.S(this)
            .css(Foundation.rtl ? 'right' : 'left', '-99999px')
            .attr('aria-hidden', 'true')
            .removeClass(self.settings.active_class)
            .prev('[' + self.attr_name() + ']')
            .removeClass(self.settings.active_class)
            .removeData('target');

          self.S(this).trigger('closed.fndtn.dropdown', [dropdown]);
        }
      });
      dropdown.removeClass('f-open-' + this.attr_name(true));
    },

    closeall : function () {
      var self = this;
      $.each(self.S('.f-open-' + this.attr_name(true)), function () {
        self.close.call(self, self.S(this));
      });
    },

    open : function (dropdown, target) {
      this
        .css(dropdown
        .addClass(this.settings.active_class), target);
      dropdown.prev('[' + this.attr_name() + ']').addClass(this.settings.active_class);
      dropdown.data('target', target.get(0)).trigger('opened.fndtn.dropdown', [dropdown, target]);
      dropdown.attr('aria-hidden', 'false');
      target.attr('aria-expanded', 'true');
      dropdown.focus();
      dropdown.addClass('f-open-' + this.attr_name(true));
    },

    data_attr : function () {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + this.name;
      }

      return this.name;
    },

    toggle : function (target) {
      if (target.hasClass(this.settings.disabled_class)) {
        return;
      }
      var dropdown = this.S('#' + target.data(this.data_attr()));
      if (dropdown.length === 0) {
        // No dropdown found, not continuing
        return;
      }

      this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown));

      if (dropdown.hasClass(this.settings.active_class)) {
        this.close.call(this, dropdown);
        if (dropdown.data('target') !== target.get(0)) {
          this.open.call(this, dropdown, target);
        }
      } else {
        this.open.call(this, dropdown, target);
      }
    },

    resize : function () {
      var dropdown = this.S('[' + this.attr_name() + '-content].open');
      var target = $(dropdown.data("target"));

      if (dropdown.length && target.length) {
        this.css(dropdown, target);
      }
    },

    css : function (dropdown, target) {
      var left_offset = Math.max((target.width() - dropdown.width()) / 2, 8),
          settings = target.data(this.attr_name(true) + '-init') || this.settings,
          parentOverflow = dropdown.parent().css('overflow-y') || dropdown.parent().css('overflow');

      this.clear_idx();



      if (this.small()) {
        var p = this.dirs.bottom.call(dropdown, target, settings);

        dropdown.attr('style', '').removeClass('drop-left drop-right drop-top').css({
          position : 'absolute',
          width : '95%',
          'max-width' : 'none',
          top : p.top
        });

        dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset);
      }
      // detect if dropdown is in an overflow container
      else if (parentOverflow !== 'visible') {
        var offset = target[0].offsetTop + target[0].offsetHeight;

        dropdown.attr('style', '').css({
          position : 'absolute',
          top : offset
        });

        dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset);
      }
      else {

        this.style(dropdown, target, settings);
      }

      return dropdown;
    },

    style : function (dropdown, target, settings) {
      var css = $.extend({position : 'absolute'},
        this.dirs[settings.align].call(dropdown, target, settings));

      dropdown.attr('style', '').css(css);
    },

    // return CSS property object
    // `this` is the dropdown
    dirs : {
      // Calculate target offset
      _base : function (t, s) {
        var o_p = this.offsetParent(),
            o = o_p.offset(),
            p = t.offset();

        p.top -= o.top;
        p.left -= o.left;

        //set some flags on the p object to pass along
        p.missRight = false;
        p.missTop = false;
        p.missLeft = false;
        p.leftRightFlag = false;

        //lets see if the panel will be off the screen
        //get the actual width of the page and store it
        var actualBodyWidth;
        var windowWidth = window.innerWidth;
        
        if (document.getElementsByClassName('row')[0]) {
          actualBodyWidth = document.getElementsByClassName('row')[0].clientWidth;
        } else {
          actualBodyWidth = windowWidth;
        }

        var actualMarginWidth = (windowWidth - actualBodyWidth) / 2;
        var actualBoundary = actualBodyWidth;

        if (!this.hasClass('mega') && !s.ignore_repositioning) {
          var outerWidth = this.outerWidth();
          var o_left = t.offset().left;
		  
          //miss top
          if (t.offset().top <= this.outerHeight()) {
            p.missTop = true;
            actualBoundary = windowWidth - actualMarginWidth;
            p.leftRightFlag = true;
          }

          //miss right
          if (o_left + outerWidth > o_left + actualMarginWidth && o_left - actualMarginWidth > outerWidth) {
            p.missRight = true;
            p.missLeft = false;
          }

          //miss left
          if (o_left - outerWidth <= 0) {
            p.missLeft = true;
            p.missRight = false;
          }
        }

        return p;
      },

      top : function (t, s) {
        var self = Foundation.libs.dropdown,
            p = self.dirs._base.call(this, t, s);

        this.addClass('drop-top');

        if (p.missTop == true) {
          p.top = p.top + t.outerHeight() + this.outerHeight();
          this.removeClass('drop-top');
        }

        if (p.missRight == true) {
          p.left = p.left - this.outerWidth() + t.outerWidth();
        }

        if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
          self.adjust_pip(this, t, s, p);
        }

        if (Foundation.rtl) {
          return {left : p.left - this.outerWidth() + t.outerWidth(),
            top : p.top - this.outerHeight()};
        }

        return {left : p.left, top : p.top - this.outerHeight()};
      },

      bottom : function (t, s) {
        var self = Foundation.libs.dropdown,
            p = self.dirs._base.call(this, t, s);

        if (p.missRight == true) {
          p.left = p.left - this.outerWidth() + t.outerWidth();
        }

        if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
          self.adjust_pip(this, t, s, p);
        }

        if (self.rtl) {
          return {left : p.left - this.outerWidth() + t.outerWidth(), top : p.top + t.outerHeight()};
        }

        return {left : p.left, top : p.top + t.outerHeight()};
      },

      left : function (t, s) {
        var p = Foundation.libs.dropdown.dirs._base.call(this, t, s);

        this.addClass('drop-left');

        if (p.missLeft == true) {
          p.left =  p.left + this.outerWidth();
          p.top = p.top + t.outerHeight();
          this.removeClass('drop-left');
        }

        return {left : p.left - this.outerWidth(), top : p.top};
      },

      right : function (t, s) {
        var p = Foundation.libs.dropdown.dirs._base.call(this, t, s);

        this.addClass('drop-right');

        if (p.missRight == true) {
          p.left = p.left - this.outerWidth();
          p.top = p.top + t.outerHeight();
          this.removeClass('drop-right');
        } else {
          p.triggeredRight = true;
        }

        var self = Foundation.libs.dropdown;

        if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
          self.adjust_pip(this, t, s, p);
        }

        return {left : p.left + t.outerWidth(), top : p.top};
      }
    },

    // Insert rule to style psuedo elements
    adjust_pip : function (dropdown, target, settings, position) {
      var sheet = Foundation.stylesheet,
          pip_offset_base = 8;

      if (dropdown.hasClass(settings.mega_class)) {
        pip_offset_base = position.left + (target.outerWidth() / 2) - 8;
      } else if (this.small()) {
        pip_offset_base += position.left - 8;
      }

      this.rule_idx = sheet.cssRules.length;

      //default
      var sel_before = '.f-dropdown.open:before',
          sel_after  = '.f-dropdown.open:after',
          css_before = 'left: ' + pip_offset_base + 'px;',
          css_after  = 'left: ' + (pip_offset_base - 1) + 'px;';

      if (position.missRight == true) {
        pip_offset_base = dropdown.outerWidth() - 23;
        sel_before = '.f-dropdown.open:before',
        sel_after  = '.f-dropdown.open:after',
        css_before = 'left: ' + pip_offset_base + 'px;',
        css_after  = 'left: ' + (pip_offset_base - 1) + 'px;';
      }

      //just a case where right is fired, but its not missing right
      if (position.triggeredRight == true) {
        sel_before = '.f-dropdown.open:before',
        sel_after  = '.f-dropdown.open:after',
        css_before = 'left:-12px;',
        css_after  = 'left:-14px;';
      }

      if (sheet.insertRule) {
        sheet.insertRule([sel_before, '{', css_before, '}'].join(' '), this.rule_idx);
        sheet.insertRule([sel_after, '{', css_after, '}'].join(' '), this.rule_idx + 1);
      } else {
        sheet.addRule(sel_before, css_before, this.rule_idx);
        sheet.addRule(sel_after, css_after, this.rule_idx + 1);
      }
    },

    // Remove old dropdown rule index
    clear_idx : function () {
      var sheet = Foundation.stylesheet;

      if (typeof this.rule_idx !== 'undefined') {
        sheet.deleteRule(this.rule_idx);
        sheet.deleteRule(this.rule_idx);
        delete this.rule_idx;
      }
    },

    small : function () {
      return matchMedia(Foundation.media_queries.small).matches &&
        !matchMedia(Foundation.media_queries.medium).matches;
    },

    off : function () {
      this.S(this.scope).off('.fndtn.dropdown');
      this.S('html, body').off('.fndtn.dropdown');
      this.S(window).off('.fndtn.dropdown');
      this.S('[data-dropdown-content]').off('.fndtn.dropdown');
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.equalizer = {
    name : 'equalizer',

    version : '5.5.3',

    settings : {
      use_tallest : true,
      before_height_change : $.noop,
      after_height_change : $.noop,
      equalize_on_stack : false,
      act_on_hidden_el: false
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'image_loaded');
      this.bindings(method, options);
      this.reflow();
    },

    events : function () {
      this.S(window).off('.equalizer').on('resize.fndtn.equalizer', function (e) {
        this.reflow();
      }.bind(this));
    },

    equalize : function (equalizer) {
      var isStacked = false,
          group = equalizer.data('equalizer'),
          settings = equalizer.data(this.attr_name(true)+'-init') || this.settings,
          vals,
          firstTopOffset;

      if (settings.act_on_hidden_el) {
        vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]') : equalizer.find('['+this.attr_name()+'-watch]');
      }
      else {
        vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]:visible') : equalizer.find('['+this.attr_name()+'-watch]:visible');
      }
      
      if (vals.length === 0) {
        return;
      }

      settings.before_height_change();
      equalizer.trigger('before-height-change.fndth.equalizer');
      vals.height('inherit');

      if (settings.equalize_on_stack === false) {
        firstTopOffset = vals.first().offset().top;
        vals.each(function () {
          if ($(this).offset().top !== firstTopOffset) {
            isStacked = true;
            return false;
          }
        });
        if (isStacked) {
          return;
        }
      }

      var heights = vals.map(function () { return $(this).outerHeight(false) }).get();

      if (settings.use_tallest) {
        var max = Math.max.apply(null, heights);
        vals.css('height', max);
      } else {
        var min = Math.min.apply(null, heights);
        vals.css('height', min);
      }

      settings.after_height_change();
      equalizer.trigger('after-height-change.fndtn.equalizer');
    },

    reflow : function () {
      var self = this;

      this.S('[' + this.attr_name() + ']', this.scope).each(function () {
        var $eq_target = $(this),
            media_query = $eq_target.data('equalizer-mq'),
            ignore_media_query = true;

        if (media_query) {
          media_query = 'is_' + media_query.replace(/-/g, '_');
          if (Foundation.utils.hasOwnProperty(media_query)) {
            ignore_media_query = false;
          }
        }

        self.image_loaded(self.S('img', this), function () {
          if (ignore_media_query || Foundation.utils[media_query]()) {
            self.equalize($eq_target)
          } else {
            var vals = $eq_target.find('[' + self.attr_name() + '-watch]:visible');
            vals.css('height', 'auto');
          }
        });
      });
    }
  };
})(jQuery, window, window.document);

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.interchange = {
    name : 'interchange',

    version : '5.5.3',

    cache : {},

    images_loaded : false,
    nodes_loaded : false,

    settings : {
      load_attr : 'interchange',

      named_queries : {
        'default'     : 'only screen',
        'small'       : Foundation.media_queries['small'],
        'small-only'  : Foundation.media_queries['small-only'],
        'medium'      : Foundation.media_queries['medium'],
        'medium-only' : Foundation.media_queries['medium-only'],
        'large'       : Foundation.media_queries['large'],
        'large-only'  : Foundation.media_queries['large-only'],
        'xlarge'      : Foundation.media_queries['xlarge'],
        'xlarge-only' : Foundation.media_queries['xlarge-only'],
        'xxlarge'     : Foundation.media_queries['xxlarge'],
        'landscape'   : 'only screen and (orientation: landscape)',
        'portrait'    : 'only screen and (orientation: portrait)',
        'retina'      : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
          'only screen and (min--moz-device-pixel-ratio: 2),' +
          'only screen and (-o-min-device-pixel-ratio: 2/1),' +
          'only screen and (min-device-pixel-ratio: 2),' +
          'only screen and (min-resolution: 192dpi),' +
          'only screen and (min-resolution: 2dppx)'
      },

      directives : {
        replace : function (el, path, trigger) {
          // The trigger argument, if called within the directive, fires
          // an event named after the directive on the element, passing
          // any parameters along to the event that you pass to trigger.
          //
          // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c)
          //
          // This allows you to bind a callback like so:
          // $('#interchangeContainer').on('replace', function (e, a, b, c) {
          //   console.log($(this).html(), a, b, c);
          // });

          if (el !== null && /IMG/.test(el[0].nodeName)) {
            var orig_path = $.each(el, function(){this.src = path;});
            // var orig_path = el[0].src;

            if (new RegExp(path, 'i').test(orig_path)) {
              return;
            }

            el.attr("src", path);

            return trigger(el[0].src);
          }
          var last_path = el.data(this.data_attr + '-last-path'),
              self = this;

          if (last_path == path) {
            return;
          }

          if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) {
            $(el).css('background-image', 'url(' + path + ')');
            el.data('interchange-last-path', path);
            return trigger(path);
          }

          return $.get(path, function (response) {
            el.html(response);
            el.data(self.data_attr + '-last-path', path);
            trigger();
          });

        }
      }
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle random_str');

      this.data_attr = this.set_data_attr();
      $.extend(true, this.settings, method, options);
      this.bindings(method, options);
      this.reflow();
    },

    get_media_hash : function () {
        var mediaHash = '';
        for (var queryName in this.settings.named_queries ) {
            mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString();
        }
        return mediaHash;
    },

    events : function () {
      var self = this, prevMediaHash;

      $(window)
        .off('.interchange')
        .on('resize.fndtn.interchange', self.throttle(function () {
            var currMediaHash = self.get_media_hash();
            if (currMediaHash !== prevMediaHash) {
                self.resize();
            }
            prevMediaHash = currMediaHash;
        }, 50));

      return this;
    },

    resize : function () {
      var cache = this.cache;

      if (!this.images_loaded || !this.nodes_loaded) {
        setTimeout($.proxy(this.resize, this), 50);
        return;
      }

      for (var uuid in cache) {
        if (cache.hasOwnProperty(uuid)) {
          var passed = this.results(uuid, cache[uuid]);
          if (passed) {
            this.settings.directives[passed
              .scenario[1]].call(this, passed.el, passed.scenario[0], (function (passed) {
                if (arguments[0] instanceof Array) {
                  var args = arguments[0];
                } else {
                  var args = Array.prototype.slice.call(arguments, 0);
                }

                return function() {
                  passed.el.trigger(passed.scenario[1], args);
                }
              }(passed)));
          }
        }
      }

    },

    results : function (uuid, scenarios) {
      var count = scenarios.length;

      if (count > 0) {
        var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]');

        while (count--) {
          var mq, rule = scenarios[count][2];
          if (this.settings.named_queries.hasOwnProperty(rule)) {
            mq = matchMedia(this.settings.named_queries[rule]);
          } else {
            mq = matchMedia(rule);
          }
          if (mq.matches) {
            return {el : el, scenario : scenarios[count]};
          }
        }
      }

      return false;
    },

    load : function (type, force_update) {
      if (typeof this['cached_' + type] === 'undefined' || force_update) {
        this['update_' + type]();
      }

      return this['cached_' + type];
    },

    update_images : function () {
      var images = this.S('img[' + this.data_attr + ']'),
          count = images.length,
          i = count,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cache = {};
      this.cached_images = [];
      this.images_loaded = (count === 0);

      while (i--) {
        loaded_count++;
        if (images[i]) {
          var str = images[i].getAttribute(data_attr) || '';

          if (str.length > 0) {
            this.cached_images.push(images[i]);
          }
        }

        if (loaded_count === count) {
          this.images_loaded = true;
          this.enhance('images');
        }
      }

      return this;
    },

    update_nodes : function () {
      var nodes = this.S('[' + this.data_attr + ']').not('img'),
          count = nodes.length,
          i = count,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cached_nodes = [];
      this.nodes_loaded = (count === 0);

      while (i--) {
        loaded_count++;
        var str = nodes[i].getAttribute(data_attr) || '';

        if (str.length > 0) {
          this.cached_nodes.push(nodes[i]);
        }

        if (loaded_count === count) {
          this.nodes_loaded = true;
          this.enhance('nodes');
        }
      }

      return this;
    },

    enhance : function (type) {
      var i = this['cached_' + type].length;

      while (i--) {
        this.object($(this['cached_' + type][i]));
      }

      return $(window).trigger('resize.fndtn.interchange');
    },

    convert_directive : function (directive) {

      var trimmed = this.trim(directive);

      if (trimmed.length > 0) {
        return trimmed;
      }

      return 'replace';
    },

    parse_scenario : function (scenario) {
      // This logic had to be made more complex since some users were using commas in the url path
      // So we cannot simply just split on a comma

      var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/),
      // getting the mq has gotten a bit complicated since we started accounting for several use cases
      // of URLs. For now we'll continue to match these scenarios, but we may consider having these scenarios
      // as nested objects or arrays in F6.
      // regex: match everything before close parenthesis for mq
      media_query         = scenario[1].match(/(.*)\)/);

      if (directive_match) {
        var path  = directive_match[1],
        directive = directive_match[2];

      } else {
        var cached_split = scenario[0].split(/,\s*$/),
        path             = cached_split[0],
        directive        = '';
      }

      return [this.trim(path), this.convert_directive(directive), this.trim(media_query[1])];
    },

    object : function (el) {
      var raw_arr = this.parse_data_attr(el),
          scenarios = [],
          i = raw_arr.length;

      if (i > 0) {
        while (i--) {
          // split array between comma delimited content and mq
          // regex: comma, optional space, open parenthesis
          var scenario = raw_arr[i].split(/,\s?\(/);

          if (scenario.length > 1) {
            var params = this.parse_scenario(scenario);
            scenarios.push(params);
          }
        }
      }

      return this.store(el, scenarios);
    },

    store : function (el, scenarios) {
      var uuid = this.random_str(),
          current_uuid = el.data(this.add_namespace('uuid', true));

      if (this.cache[current_uuid]) {
        return this.cache[current_uuid];
      }

      el.attr(this.add_namespace('data-uuid'), uuid);
      return this.cache[uuid] = scenarios;
    },

    trim : function (str) {

      if (typeof str === 'string') {
        return $.trim(str);
      }

      return str;
    },

    set_data_attr : function (init) {
      if (init) {
        if (this.namespace.length > 0) {
          return this.namespace + '-' + this.settings.load_attr;
        }

        return this.settings.load_attr;
      }

      if (this.namespace.length > 0) {
        return 'data-' + this.namespace + '-' + this.settings.load_attr;
      }

      return 'data-' + this.settings.load_attr;
    },

    parse_data_attr : function (el) {
      var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/),
          i = raw.length,
          output = [];

      while (i--) {
        if (raw[i].replace(/[\W\d]+/, '').length > 4) {
          output.push(raw[i]);
        }
      }

      return output;
    },

    reflow : function () {
      this.load('images', true);
      this.load('nodes', true);
    }

  };

}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  var Modernizr = Modernizr || false;

  Foundation.libs.joyride = {
    name : 'joyride',

    version : '5.5.3',

    defaults : {
      expose                   : false,     // turn on or off the expose feature
      modal                    : true,      // Whether to cover page with modal during the tour
      keyboard                 : true,      // enable left, right and esc keystrokes
      tip_location             : 'bottom',  // 'top', 'bottom', 'left' or 'right' in relation to parent
      nub_position             : 'auto',    // override on a per tooltip bases
      scroll_speed             : 1500,      // Page scrolling speed in milliseconds, 0 = no scroll animation
      scroll_animation         : 'linear',  // supports 'swing' and 'linear', extend with jQuery UI.
      timer                    : 0,         // 0 = no timer , all other numbers = timer in milliseconds
      start_timer_on_click     : true,      // true or false - true requires clicking the first button start the timer
      start_offset             : 0,         // the index of the tooltip you want to start on (index of the li)
      next_button              : true,      // true or false to control whether a next button is used
      prev_button              : true,      // true or false to control whether a prev button is used
      tip_animation            : 'fade',    // 'pop' or 'fade' in each tip
      pause_after              : [],        // array of indexes where to pause the tour after
      exposed                  : [],        // array of expose elements
      tip_animation_fade_speed : 300,       // when tipAnimation = 'fade' this is speed in milliseconds for the transition
      cookie_monster           : false,     // true or false to control whether cookies are used
      cookie_name              : 'joyride', // Name the cookie you'll use
      cookie_domain            : false,     // Will this cookie be attached to a domain, ie. '.notableapp.com'
      cookie_expires           : 365,       // set when you would like the cookie to expire.
      tip_container            : 'body',    // Where will the tip be attached
      abort_on_close           : true,      // When true, the close event will not fire any callback
      tip_location_patterns    : {
        top : ['bottom'],
        bottom : [], // bottom should not need to be repositioned
        left : ['right', 'top', 'bottom'],
        right : ['left', 'top', 'bottom']
      },
      post_ride_callback     : function () {},    // A method to call once the tour closes (canceled or complete)
      post_step_callback     : function () {},    // A method to call after each step
      pre_step_callback      : function () {},    // A method to call before each step
      pre_ride_callback      : function () {},    // A method to call before the tour starts (passed index, tip, and cloned exposed element)
      post_expose_callback   : function () {},    // A method to call after an element has been exposed
      template : { // HTML segments for tip layout
        link          : '<a href="#close" class="joyride-close-tip">&times;</a>',
        timer         : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',
        tip           : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',
        wrapper       : '<div class="joyride-content-wrapper"></div>',
        button        : '<a href="#" class="small button joyride-next-tip"></a>',
        prev_button   : '<a href="#" class="small button joyride-prev-tip"></a>',
        modal         : '<div class="joyride-modal-bg"></div>',
        expose        : '<div class="joyride-expose-wrapper"></div>',
        expose_cover  : '<div class="joyride-expose-cover"></div>'
      },
      expose_add_class : '' // One or more space-separated class names to be added to exposed element
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle random_str');

      this.settings = this.settings || $.extend({}, this.defaults, (options || method));

      this.bindings(method, options)
    },

    go_next : function () {
      if (this.settings.$li.next().length < 1) {
        this.end();
      } else if (this.settings.timer > 0) {
        clearTimeout(this.settings.automate);
        this.hide();
        this.show();
        this.startTimer();
      } else {
        this.hide();
        this.show();
      }
    },

    go_prev : function () {
      if (this.settings.$li.prev().length < 1) {
        // Do nothing if there are no prev element
      } else if (this.settings.timer > 0) {
        clearTimeout(this.settings.automate);
        this.hide();
        this.show(null, true);
        this.startTimer();
      } else {
        this.hide();
        this.show(null, true);
      }
    },

    events : function () {
      var self = this;

      $(this.scope)
        .off('.joyride')
        .on('click.fndtn.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) {
          e.preventDefault();
          this.go_next()
        }.bind(this))
        .on('click.fndtn.joyride', '.joyride-prev-tip', function (e) {
          e.preventDefault();
          this.go_prev();
        }.bind(this))

        .on('click.fndtn.joyride', '.joyride-close-tip', function (e) {
          e.preventDefault();
          this.end(this.settings.abort_on_close);
        }.bind(this))

        .on('keyup.fndtn.joyride', function (e) {
          // Don't do anything if keystrokes are disabled
          // or if the joyride is not being shown
          if (!this.settings.keyboard || !this.settings.riding) {
            return;
          }

          switch (e.which) {
            case 39: // right arrow
              e.preventDefault();
              this.go_next();
              break;
            case 37: // left arrow
              e.preventDefault();
              this.go_prev();
              break;
            case 27: // escape
              e.preventDefault();
              this.end(this.settings.abort_on_close);
          }
        }.bind(this));

      $(window)
        .off('.joyride')
        .on('resize.fndtn.joyride', self.throttle(function () {
          if ($('[' + self.attr_name() + ']').length > 0 && self.settings.$next_tip && self.settings.riding) {
            if (self.settings.exposed.length > 0) {
              var $els = $(self.settings.exposed);

              $els.each(function () {
                var $this = $(this);
                self.un_expose($this);
                self.expose($this);
              });
            }

            if (self.is_phone()) {
              self.pos_phone();
            } else {
              self.pos_default(false);
            }
          }
        }, 100));
    },

    start : function () {
      var self = this,
          $this = $('[' + this.attr_name() + ']', this.scope),
          integer_settings = ['timer', 'scrollSpeed', 'startOffset', 'tipAnimationFadeSpeed', 'cookieExpires'],
          int_settings_count = integer_settings.length;

      if (!$this.length > 0) {
        return;
      }

      if (!this.settings.init) {
        this.events();
      }

      this.settings = $this.data(this.attr_name(true) + '-init');

      // non configureable settings
      this.settings.$content_el = $this;
      this.settings.$body = $(this.settings.tip_container);
      this.settings.body_offset = $(this.settings.tip_container).position();
      this.settings.$tip_content = this.settings.$content_el.find('> li');
      this.settings.paused = false;
      this.settings.attempts = 0;
      this.settings.riding = true;

      // can we create cookies?
      if (typeof $.cookie !== 'function') {
        this.settings.cookie_monster = false;
      }

      // generate the tips and insert into dom.
      if (!this.settings.cookie_monster || this.settings.cookie_monster && !$.cookie(this.settings.cookie_name)) {
        this.settings.$tip_content.each(function (index) {
          var $this = $(this);
          this.settings = $.extend({}, self.defaults, self.data_options($this));

          // Make sure that settings parsed from data_options are integers where necessary
          var i = int_settings_count;
          while (i--) {
            self.settings[integer_settings[i]] = parseInt(self.settings[integer_settings[i]], 10);
          }
          self.create({$li : $this, index : index});
        });

        // show first tip
        if (!this.settings.start_timer_on_click && this.settings.timer > 0) {
          this.show('init');
          this.startTimer();
        } else {
          this.show('init');
        }

      }
    },

    resume : function () {
      this.set_li();
      this.show();
    },

    tip_template : function (opts) {
      var $blank, content;

      opts.tip_class = opts.tip_class || '';

      $blank = $(this.settings.template.tip).addClass(opts.tip_class);
      content = $.trim($(opts.li).html()) +
        this.prev_button_text(opts.prev_button_text, opts.index) +
        this.button_text(opts.button_text) +
        this.settings.template.link +
        this.timer_instance(opts.index);

      $blank.append($(this.settings.template.wrapper));
      $blank.first().attr(this.add_namespace('data-index'), opts.index);
      $('.joyride-content-wrapper', $blank).append(content);

      return $blank[0];
    },

    timer_instance : function (index) {
      var txt;

      if ((index === 0 && this.settings.start_timer_on_click && this.settings.timer > 0) || this.settings.timer === 0) {
        txt = '';
      } else {
        txt = $(this.settings.template.timer)[0].outerHTML;
      }
      return txt;
    },

    button_text : function (txt) {
      if (this.settings.tip_settings.next_button) {
        txt = $.trim(txt) || 'Next';
        txt = $(this.settings.template.button).append(txt)[0].outerHTML;
      } else {
        txt = '';
      }
      return txt;
    },

    prev_button_text : function (txt, idx) {
      if (this.settings.tip_settings.prev_button) {
        txt = $.trim(txt) || 'Previous';

        // Add the disabled class to the button if it's the first element
        if (idx == 0) {
          txt = $(this.settings.template.prev_button).append(txt).addClass('disabled')[0].outerHTML;
        } else {
          txt = $(this.settings.template.prev_button).append(txt)[0].outerHTML;
        }
      } else {
        txt = '';
      }
      return txt;
    },

    create : function (opts) {
      this.settings.tip_settings = $.extend({}, this.settings, this.data_options(opts.$li));
      var buttonText = opts.$li.attr(this.add_namespace('data-button')) || opts.$li.attr(this.add_namespace('data-text')),
          prevButtonText = opts.$li.attr(this.add_namespace('data-button-prev')) || opts.$li.attr(this.add_namespace('data-prev-text')),
        tipClass = opts.$li.attr('class'),
        $tip_content = $(this.tip_template({
          tip_class : tipClass,
          index : opts.index,
          button_text : buttonText,
          prev_button_text : prevButtonText,
          li : opts.$li
        }));

      $(this.settings.tip_container).append($tip_content);
    },

    show : function (init, is_prev) {
      var $timer = null;

      // are we paused?
      if (this.settings.$li === undefined || ($.inArray(this.settings.$li.index(), this.settings.pause_after) === -1)) {

        // don't go to the next li if the tour was paused
        if (this.settings.paused) {
          this.settings.paused = false;
        } else {
          this.set_li(init, is_prev);
        }

        this.settings.attempts = 0;

        if (this.settings.$li.length && this.settings.$target.length > 0) {
          if (init) { //run when we first start
            this.settings.pre_ride_callback(this.settings.$li.index(), this.settings.$next_tip);
            if (this.settings.modal) {
              this.show_modal();
            }
          }

          this.settings.pre_step_callback(this.settings.$li.index(), this.settings.$next_tip);

          if (this.settings.modal && this.settings.expose) {
            this.expose();
          }

          this.settings.tip_settings = $.extend({}, this.settings, this.data_options(this.settings.$li));

          this.settings.timer = parseInt(this.settings.timer, 10);

          this.settings.tip_settings.tip_location_pattern = this.settings.tip_location_patterns[this.settings.tip_settings.tip_location];

          // scroll and hide bg if not modal and not expose
          if (!/body/i.test(this.settings.$target.selector) && !this.settings.expose) {
            var joyridemodalbg = $('.joyride-modal-bg');
            if (/pop/i.test(this.settings.tipAnimation)) {
                joyridemodalbg.hide();
            } else {
                joyridemodalbg.fadeOut(this.settings.tipAnimationFadeSpeed);
            }
            this.scroll_to();
          }

          if (this.is_phone()) {
            this.pos_phone(true);
          } else {
            this.pos_default(true);
          }

          $timer = this.settings.$next_tip.find('.joyride-timer-indicator');

          if (/pop/i.test(this.settings.tip_animation)) {

            $timer.width(0);

            if (this.settings.timer > 0) {

              this.settings.$next_tip.show();

              setTimeout(function () {
                $timer.animate({
                  width : $timer.parent().width()
                }, this.settings.timer, 'linear');
              }.bind(this), this.settings.tip_animation_fade_speed);

            } else {
              this.settings.$next_tip.show();

            }

          } else if (/fade/i.test(this.settings.tip_animation)) {

            $timer.width(0);

            if (this.settings.timer > 0) {

              this.settings.$next_tip
                .fadeIn(this.settings.tip_animation_fade_speed)
                .show();

              setTimeout(function () {
                $timer.animate({
                  width : $timer.parent().width()
                }, this.settings.timer, 'linear');
              }.bind(this), this.settings.tip_animation_fade_speed);

            } else {
              this.settings.$next_tip.fadeIn(this.settings.tip_animation_fade_speed);
            }
          }

          this.settings.$current_tip = this.settings.$next_tip;

        // skip non-existant targets
        } else if (this.settings.$li && this.settings.$target.length < 1) {

          this.show(init, is_prev);

        } else {

          this.end();

        }
      } else {

        this.settings.paused = true;

      }

    },

    is_phone : function () {
      return matchMedia(Foundation.media_queries.small).matches &&
        !matchMedia(Foundation.media_queries.medium).matches;
    },

    hide : function () {
      if (this.settings.modal && this.settings.expose) {
        this.un_expose();
      }

      if (!this.settings.modal) {
        $('.joyride-modal-bg').hide();
      }

      // Prevent scroll bouncing...wait to remove from layout
      this.settings.$current_tip.css('visibility', 'hidden');
      setTimeout($.proxy(function () {
        this.hide();
        this.css('visibility', 'visible');
      }, this.settings.$current_tip), 0);
      this.settings.post_step_callback(this.settings.$li.index(),
        this.settings.$current_tip);
    },

    set_li : function (init, is_prev) {
      if (init) {
        this.settings.$li = this.settings.$tip_content.eq(this.settings.start_offset);
        this.set_next_tip();
        this.settings.$current_tip = this.settings.$next_tip;
      } else {
        if (is_prev) {
          this.settings.$li = this.settings.$li.prev();
        } else {
          this.settings.$li = this.settings.$li.next();
        }
        this.set_next_tip();
      }

      this.set_target();
    },

    set_next_tip : function () {
      this.settings.$next_tip = $('.joyride-tip-guide').eq(this.settings.$li.index());
      this.settings.$next_tip.data('closed', '');
    },

    set_target : function () {
      var cl = this.settings.$li.attr(this.add_namespace('data-class')),
          id = this.settings.$li.attr(this.add_namespace('data-id')),
          $sel = function () {
            if (id) {
              return $(document.getElementById(id));
            } else if (cl) {
              return $('.' + cl).first();
            } else {
              return $('body');
            }
          };

      this.settings.$target = $sel();
    },

    scroll_to : function () {
      var window_half, tipOffset;

      window_half = $(window).height() / 2;
      tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight());

      if (tipOffset != 0) {
        $('html, body').stop().animate({
          scrollTop : tipOffset
        }, this.settings.scroll_speed, 'swing');
      }
    },

    paused : function () {
      return ($.inArray((this.settings.$li.index() + 1), this.settings.pause_after) === -1);
    },

    restart : function () {
      this.hide();
      this.settings.$li = undefined;
      this.show('init');
    },

    pos_default : function (init) {
      var $nub = this.settings.$next_tip.find('.joyride-nub'),
          nub_width = Math.ceil($nub.outerWidth() / 2),
          nub_height = Math.ceil($nub.outerHeight() / 2),
          toggle = init || false;

      // tip must not be "display: none" to calculate position
      if (toggle) {
        this.settings.$next_tip.css('visibility', 'hidden');
        this.settings.$next_tip.show();
      }

      if (!/body/i.test(this.settings.$target.selector)) {
        var topAdjustment = this.settings.tip_settings.tipAdjustmentY ? parseInt(this.settings.tip_settings.tipAdjustmentY) : 0,
            leftAdjustment = this.settings.tip_settings.tipAdjustmentX ? parseInt(this.settings.tip_settings.tipAdjustmentX) : 0;

        if (this.bottom()) {
          if (this.rtl) {
            this.settings.$next_tip.css({
              top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
              left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth() + leftAdjustment});
          } else {
            this.settings.$next_tip.css({
              top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
              left : this.settings.$target.offset().left + leftAdjustment});
          }

          this.nub_position($nub, this.settings.tip_settings.nub_position, 'top');

        } else if (this.top()) {
          if (this.rtl) {
            this.settings.$next_tip.css({
              top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
              left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth()});
          } else {
            this.settings.$next_tip.css({
              top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
              left : this.settings.$target.offset().left + leftAdjustment});
          }

          this.nub_position($nub, this.settings.tip_settings.nub_position, 'bottom');

        } else if (this.right()) {

          this.settings.$next_tip.css({
            top : this.settings.$target.offset().top + topAdjustment,
            left : (this.settings.$target.outerWidth() + this.settings.$target.offset().left + nub_width + leftAdjustment)});

          this.nub_position($nub, this.settings.tip_settings.nub_position, 'left');

        } else if (this.left()) {

          this.settings.$next_tip.css({
            top : this.settings.$target.offset().top + topAdjustment,
            left : (this.settings.$target.offset().left - this.settings.$next_tip.outerWidth() - nub_width + leftAdjustment)});

          this.nub_position($nub, this.settings.tip_settings.nub_position, 'right');

        }

        if (!this.visible(this.corners(this.settings.$next_tip)) && this.settings.attempts < this.settings.tip_settings.tip_location_pattern.length) {

          $nub.removeClass('bottom')
            .removeClass('top')
            .removeClass('right')
            .removeClass('left');

          this.settings.tip_settings.tip_location = this.settings.tip_settings.tip_location_pattern[this.settings.attempts];

          this.settings.attempts++;

          this.pos_default();

        }

      } else if (this.settings.$li.length) {

        this.pos_modal($nub);

      }

      if (toggle) {
        this.settings.$next_tip.hide();
        this.settings.$next_tip.css('visibility', 'visible');
      }

    },

    pos_phone : function (init) {
      var tip_height = this.settings.$next_tip.outerHeight(),
          tip_offset = this.settings.$next_tip.offset(),
          target_height = this.settings.$target.outerHeight(),
          $nub = $('.joyride-nub', this.settings.$next_tip),
          nub_height = Math.ceil($nub.outerHeight() / 2),
          toggle = init || false;

      $nub.removeClass('bottom')
        .removeClass('top')
        .removeClass('right')
        .removeClass('left');

      if (toggle) {
        this.settings.$next_tip.css('visibility', 'hidden');
        this.settings.$next_tip.show();
      }

      if (!/body/i.test(this.settings.$target.selector)) {

        if (this.top()) {

            this.settings.$next_tip.offset({top : this.settings.$target.offset().top - tip_height - nub_height});
            $nub.addClass('bottom');

        } else {

          this.settings.$next_tip.offset({top : this.settings.$target.offset().top + target_height + nub_height});
          $nub.addClass('top');

        }

      } else if (this.settings.$li.length) {
        this.pos_modal($nub);
      }

      if (toggle) {
        this.settings.$next_tip.hide();
        this.settings.$next_tip.css('visibility', 'visible');
      }
    },

    pos_modal : function ($nub) {
      this.center();
      $nub.hide();

      this.show_modal();
    },

    show_modal : function () {
      if (!this.settings.$next_tip.data('closed')) {
        var joyridemodalbg =  $('.joyride-modal-bg');
        if (joyridemodalbg.length < 1) {
          var joyridemodalbg = $(this.settings.template.modal);
          joyridemodalbg.appendTo('body');
        }

        if (/pop/i.test(this.settings.tip_animation)) {
            joyridemodalbg.show();
        } else {
            joyridemodalbg.fadeIn(this.settings.tip_animation_fade_speed);
        }
      }
    },

    expose : function () {
      var expose,
          exposeCover,
          el,
          origCSS,
          origClasses,
          randId = 'expose-' + this.random_str(6);

      if (arguments.length > 0 && arguments[0] instanceof $) {
        el = arguments[0];
      } else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) {
        el = this.settings.$target;
      } else {
        return false;
      }

      if (el.length < 1) {
        if (window.console) {
          console.error('element not valid', el);
        }
        return false;
      }

      expose = $(this.settings.template.expose);
      this.settings.$body.append(expose);
      expose.css({
        top : el.offset().top,
        left : el.offset().left,
        width : el.outerWidth(true),
        height : el.outerHeight(true)
      });

      exposeCover = $(this.settings.template.expose_cover);

      origCSS = {
        zIndex : el.css('z-index'),
        position : el.css('position')
      };

      origClasses = el.attr('class') == null ? '' : el.attr('class');

      el.css('z-index', parseInt(expose.css('z-index')) + 1);

      if (origCSS.position == 'static') {
        el.css('position', 'relative');
      }

      el.data('expose-css', origCSS);
      el.data('orig-class', origClasses);
      el.attr('class', origClasses + ' ' + this.settings.expose_add_class);

      exposeCover.css({
        top : el.offset().top,
        left : el.offset().left,
        width : el.outerWidth(true),
        height : el.outerHeight(true)
      });

      if (this.settings.modal) {
        this.show_modal();
      }

      this.settings.$body.append(exposeCover);
      expose.addClass(randId);
      exposeCover.addClass(randId);
      el.data('expose', randId);
      this.settings.post_expose_callback(this.settings.$li.index(), this.settings.$next_tip, el);
      this.add_exposed(el);
    },

    un_expose : function () {
      var exposeId,
          el,
          expose,
          origCSS,
          origClasses,
          clearAll = false;

      if (arguments.length > 0 && arguments[0] instanceof $) {
        el = arguments[0];
      } else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) {
        el = this.settings.$target;
      } else {
        return false;
      }

      if (el.length < 1) {
        if (window.console) {
          console.error('element not valid', el);
        }
        return false;
      }

      exposeId = el.data('expose');
      expose = $('.' + exposeId);

      if (arguments.length > 1) {
        clearAll = arguments[1];
      }

      if (clearAll === true) {
        $('.joyride-expose-wrapper,.joyride-expose-cover').remove();
      } else {
        expose.remove();
      }

      origCSS = el.data('expose-css');

      if (origCSS.zIndex == 'auto') {
        el.css('z-index', '');
      } else {
        el.css('z-index', origCSS.zIndex);
      }

      if (origCSS.position != el.css('position')) {
        if (origCSS.position == 'static') {// this is default, no need to set it.
          el.css('position', '');
        } else {
          el.css('position', origCSS.position);
        }
      }

      origClasses = el.data('orig-class');
      el.attr('class', origClasses);
      el.removeData('orig-classes');

      el.removeData('expose');
      el.removeData('expose-z-index');
      this.remove_exposed(el);
    },

    add_exposed : function (el) {
      this.settings.exposed = this.settings.exposed || [];
      if (el instanceof $ || typeof el === 'object') {
        this.settings.exposed.push(el[0]);
      } else if (typeof el == 'string') {
        this.settings.exposed.push(el);
      }
    },

    remove_exposed : function (el) {
      var search, i;
      if (el instanceof $) {
        search = el[0]
      } else if (typeof el == 'string') {
        search = el;
      }

      this.settings.exposed = this.settings.exposed || [];
      i = this.settings.exposed.length;

      while (i--) {
        if (this.settings.exposed[i] == search) {
          this.settings.exposed.splice(i, 1);
          return;
        }
      }
    },

    center : function () {
      var $w = $(window);

      this.settings.$next_tip.css({
        top : ((($w.height() - this.settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()),
        left : ((($w.width() - this.settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft())
      });

      return true;
    },

    bottom : function () {
      return /bottom/i.test(this.settings.tip_settings.tip_location);
    },

    top : function () {
      return /top/i.test(this.settings.tip_settings.tip_location);
    },

    right : function () {
      return /right/i.test(this.settings.tip_settings.tip_location);
    },

    left : function () {
      return /left/i.test(this.settings.tip_settings.tip_location);
    },

    corners : function (el) {
      if (el.length === 0) {
         return [false, false, false, false];   
      }
      
      var w = $(window),
          window_half = w.height() / 2,
          //using this to calculate since scroll may not have finished yet.
          tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight()),
          right = w.width() + w.scrollLeft(),
          offsetBottom =  w.height() + tipOffset,
          bottom = w.height() + w.scrollTop(),
          top = w.scrollTop();

      if (tipOffset < top) {
        if (tipOffset < 0) {
          top = 0;
        } else {
          top = tipOffset;
        }
      }

      if (offsetBottom > bottom) {
        bottom = offsetBottom;
      }

      return [
        el.offset().top < top,
        right < el.offset().left + el.outerWidth(),
        bottom < el.offset().top + el.outerHeight(),
        w.scrollLeft() > el.offset().left
      ];
    },

    visible : function (hidden_corners) {
      var i = hidden_corners.length;

      while (i--) {
        if (hidden_corners[i]) {
          return false;
        }
      }

      return true;
    },

    nub_position : function (nub, pos, def) {
      if (pos === 'auto') {
        nub.addClass(def);
      } else {
        nub.addClass(pos);
      }
    },

    startTimer : function () {
      if (this.settings.$li.length) {
        this.settings.automate = setTimeout(function () {
          this.hide();
          this.show();
          this.startTimer();
        }.bind(this), this.settings.timer);
      } else {
        clearTimeout(this.settings.automate);
      }
    },

    end : function (abort) {
      if (this.settings.cookie_monster) {
        $.cookie(this.settings.cookie_name, 'ridden', {expires : this.settings.cookie_expires, domain : this.settings.cookie_domain});
      }

      if (this.settings.timer > 0) {
        clearTimeout(this.settings.automate);
      }

      if (this.settings.modal && this.settings.expose) {
        this.un_expose();
      }

      // Unplug keystrokes listener
      $(this.scope).off('keyup.joyride')

      this.settings.$next_tip.data('closed', true);
      this.settings.riding = false;

      $('.joyride-modal-bg').hide();
      this.settings.$current_tip.hide();

      if (typeof abort === 'undefined' || abort === false) {
        this.settings.post_step_callback(this.settings.$li.index(), this.settings.$current_tip);
        this.settings.post_ride_callback(this.settings.$li.index(), this.settings.$current_tip);
      }

      $('.joyride-tip-guide').remove();
    },

    off : function () {
      $(this.scope).off('.joyride');
      $(window).off('.joyride');
      $('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride');
      $('.joyride-tip-guide, .joyride-modal-bg').remove();
      clearTimeout(this.settings.automate);
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs['magellan-expedition'] = {
    name : 'magellan-expedition',

    version : '5.5.3',

    settings : {
      active_class : 'active',
      threshold : 0, // pixels from the top of the expedition for it to become fixes
      destination_threshold : 20, // pixels from the top of destination for it to be considered active
      throttle_delay : 30, // calculation throttling to increase framerate
      fixed_top : 0, // top distance in pixels assigend to the fixed element on scroll
      offset_by_height : true,  // whether to offset the destination by the expedition height. Usually you want this to be true, unless your expedition is on the side.
      duration : 700, // animation duration time
      easing : 'swing' // animation easing
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = self.S,
          settings = self.settings;

      // initialize expedition offset
      self.set_expedition_position();

      S(self.scope)
        .off('.magellan')
        .on('click.fndtn.magellan', '[' + self.add_namespace('data-magellan-arrival') + '] a[href*=#]', function (e) {
          var sameHost = ((this.hostname === location.hostname) || !this.hostname),
              samePath = self.filterPathname(location.pathname) === self.filterPathname(this.pathname),
              testHash = this.hash.replace(/(:|\.|\/)/g, '\\$1'),
              anchor = this;

          if (sameHost && samePath && testHash) {
            e.preventDefault();
            var expedition = $(this).closest('[' + self.attr_name() + ']'),
                settings = expedition.data('magellan-expedition-init'),
                hash = this.hash.split('#').join(''),
                target = $('a[name="' + hash + '"]');

            if (target.length === 0) {
              target = $('#' + hash);

            }

            // Account for expedition height if fixed position
            var scroll_top = target.offset().top - settings.destination_threshold + 1;
            if (settings.offset_by_height) {
              scroll_top = scroll_top - expedition.outerHeight();
            }
            $('html, body').stop().animate({
              'scrollTop' : scroll_top
            }, settings.duration, settings.easing, function () {
              if (history.pushState) {
                history.pushState(null, null, anchor.pathname + anchor.search + '#' + hash);
              } else {
                location.hash = anchor.pathname + anchor.search + '#' + hash;
              }
            });
          }
        })
        .on('scroll.fndtn.magellan', self.throttle(this.check_for_arrivals.bind(this), settings.throttle_delay));
    },

    check_for_arrivals : function () {
      var self = this;
      self.update_arrivals();
      self.update_expedition_positions();
    },

    set_expedition_position : function () {
      var self = this;
      $('[' + this.attr_name() + '=fixed]', self.scope).each(function (idx, el) {
        var expedition = $(this),
            settings = expedition.data('magellan-expedition-init'),
            styles = expedition.attr('styles'), // save styles
            top_offset, fixed_top;

        expedition.attr('style', '');
        top_offset = expedition.offset().top + settings.threshold;

        //set fixed-top by attribute
        fixed_top = parseInt(expedition.data('magellan-fixed-top'));
        if (!isNaN(fixed_top)) {
          self.settings.fixed_top = fixed_top;
        }

        expedition.data(self.data_attr('magellan-top-offset'), top_offset);
        expedition.attr('style', styles);
      });
    },

    update_expedition_positions : function () {
      var self = this,
          window_top_offset = $(window).scrollTop();

      $('[' + this.attr_name() + '=fixed]', self.scope).each(function () {
        var expedition = $(this),
            settings = expedition.data('magellan-expedition-init'),
            styles = expedition.attr('style'), // save styles
            top_offset = expedition.data('magellan-top-offset');

        //scroll to the top distance
        if (window_top_offset + self.settings.fixed_top >= top_offset) {
          // Placeholder allows height calculations to be consistent even when
          // appearing to switch between fixed/non-fixed placement
          var placeholder = expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']');
          if (placeholder.length === 0) {
            placeholder = expedition.clone();
            placeholder.removeAttr(self.attr_name());
            placeholder.attr(self.add_namespace('data-magellan-expedition-clone'), '');
            expedition.before(placeholder);
          }
          expedition.css({position :'fixed', top : settings.fixed_top}).addClass('fixed');
        } else {
          expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']').remove();
          expedition.attr('style', styles).css('position', '').css('top', '').removeClass('fixed');
        }
      });
    },

    update_arrivals : function () {
      var self = this,
          window_top_offset = $(window).scrollTop();

      $('[' + this.attr_name() + ']', self.scope).each(function () {
        var expedition = $(this),
            settings = expedition.data(self.attr_name(true) + '-init'),
            offsets = self.offsets(expedition, window_top_offset),
            arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'),
            active_item = false;
        offsets.each(function (idx, item) {
          if (item.viewport_offset >= item.top_offset) {
            var arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']');
            arrivals.not(item.arrival).removeClass(settings.active_class);
            item.arrival.addClass(settings.active_class);
            active_item = true;
            return true;
          }
        });

        if (!active_item) {
          arrivals.removeClass(settings.active_class);
        }
      });
    },

    offsets : function (expedition, window_offset) {
      var self = this,
          settings = expedition.data(self.attr_name(true) + '-init'),
          viewport_offset = window_offset;

      return expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']').map(function (idx, el) {
        var name = $(this).data(self.data_attr('magellan-arrival')),
            dest = $('[' + self.add_namespace('data-magellan-destination') + '=' + name + ']');
        if (dest.length > 0) {
          var top_offset = dest.offset().top - settings.destination_threshold;
          if (settings.offset_by_height) {
            top_offset = top_offset - expedition.outerHeight();
          }
          top_offset = Math.floor(top_offset);
          return {
            destination : dest,
            arrival : $(this),
            top_offset : top_offset,
            viewport_offset : viewport_offset
          }
        }
      }).sort(function (a, b) {
        if (a.top_offset < b.top_offset) {
          return -1;
        }
        if (a.top_offset > b.top_offset) {
          return 1;
        }
        return 0;
      });
    },

    data_attr : function (str) {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + str;
      }

      return str;
    },

    off : function () {
      this.S(this.scope).off('.magellan');
      this.S(window).off('.magellan');
    },

    filterPathname : function (pathname) {
      pathname = pathname || '';
      return pathname
          .replace(/^\//,'')
          .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'')
          .replace(/\/$/,'');
    },

    reflow : function () {
      var self = this;
      // remove placeholder expeditions used for height calculation purposes
      $('[' + self.add_namespace('data-magellan-expedition-clone') + ']', self.scope).remove();
    }
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.offcanvas = {
    name : 'offcanvas',

    version : '5.5.3',

    settings : {
      open_method : 'move',
      close_on_click : false
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = self.S,
          move_class = '',
          right_postfix = '',
          left_postfix = '',
          top_postfix = '',
          bottom_postfix = '';

      if (this.settings.open_method === 'move') {
        move_class = 'move-';
        right_postfix = 'right';
        left_postfix = 'left';
        top_postfix = 'top';
        bottom_postfix = 'bottom';
      } else if (this.settings.open_method === 'overlap_single') {
        move_class = 'offcanvas-overlap-';
        right_postfix = 'right';
        left_postfix = 'left';
        top_postfix = 'top';
        bottom_postfix = 'bottom';
      } else if (this.settings.open_method === 'overlap') {
        move_class = 'offcanvas-overlap';
      }

      S(this.scope).off('.offcanvas')
        .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + right_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.left-submenu').removeClass(move_class + right_postfix);
          }
          $('.left-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + right_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + right_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.left-submenu').toggleClass(move_class + right_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + right_postfix);
          }
          $('.left-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of left canvas
        .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + left_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.right-submenu').removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + left_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + left_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.right-submenu').toggleClass(move_class + left_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of right canvas
        .on('click.fndtn.offcanvas', '.top-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + bottom_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.top-submenu').removeClass(move_class + bottom_postfix);
          }
          $('.top-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.top-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + bottom_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + bottom_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.top-submenu').toggleClass(move_class + bottom_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + bottom_postfix);
          }
          $('.top-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of top canvas
        .on('click.fndtn.offcanvas', '.bottom-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + top_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.bottom-submenu').removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.bottom-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + top_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + top_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.bottom-submenu').toggleClass(move_class + top_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of bottom
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + left_postfix);
          S('.right-submenu').removeClass(move_class + left_postfix);
          if (right_postfix) {
            self.click_remove_class(e, move_class + right_postfix);
            S('.left-submenu').removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + left_postfix);
          $('.left-off-canvas-toggle').attr('aria-expanded', 'false');
          if (right_postfix) {
            self.click_remove_class(e, move_class + right_postfix);
            $('.right-off-canvas-toggle').attr('aria-expanded', 'false');
          }
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + top_postfix);
          S('.bottom-submenu').removeClass(move_class + top_postfix);
          if (bottom_postfix) {
            self.click_remove_class(e, move_class + bottom_postfix);
            S('.top-submenu').removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + top_postfix);
          $('.top-off-canvas-toggle').attr('aria-expanded', 'false');
          if (bottom_postfix) {
            self.click_remove_class(e, move_class + bottom_postfix);
            $('.bottom-off-canvas-toggle').attr('aria-expanded', 'false');
          }
        });
    },

    toggle : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      if ($off_canvas.is('.' + class_name)) {
        this.hide(class_name, $off_canvas);
      } else {
        this.show(class_name, $off_canvas);
      }
    },

    show : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      $off_canvas.trigger('open.fndtn.offcanvas');
      $off_canvas.addClass(class_name);
    },

    hide : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      $off_canvas.trigger('close.fndtn.offcanvas');
      $off_canvas.removeClass(class_name);
    },

    click_toggle_class : function (e, class_name) {
      e.preventDefault();
      var $off_canvas = this.get_wrapper(e);
      this.toggle(class_name, $off_canvas);
    },

    click_remove_class : function (e, class_name) {
      e.preventDefault();
      var $off_canvas = this.get_wrapper(e);
      this.hide(class_name, $off_canvas);
    },

    get_settings : function (e) {
      var offcanvas  = this.S(e.target).closest('[' + this.attr_name() + ']');
      return offcanvas.data(this.attr_name(true) + '-init') || this.settings;
    },

    get_wrapper : function (e) {
      var $off_canvas = this.S(e ? e.target : this.scope).closest('.off-canvas-wrap');

      if ($off_canvas.length === 0) {
        $off_canvas = this.S('.off-canvas-wrap');
      }
      return $off_canvas;
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  var noop = function () {};

  var Orbit = function (el, settings) {
    // Don't reinitialize plugin
    if (el.hasClass(settings.slides_container_class)) {
      return this;
    }

    var self = this,
        container,
        slides_container = el,
        number_container,
        bullets_container,
        timer_container,
        idx = 0,
        animate,
        timer,
        locked = false,
        adjust_height_after = false;

    self.slides = function () {
      return slides_container.children(settings.slide_selector);
    };

    self.slides().first().addClass(settings.active_slide_class);

    self.update_slide_number = function (index) {
      if (settings.slide_number) {
        number_container.find('span:first').text(parseInt(index) + 1);
        number_container.find('span:last').text(self.slides().length);
      }
      if (settings.bullets) {
        bullets_container.children().removeClass(settings.bullets_active_class);
        $(bullets_container.children().get(index)).addClass(settings.bullets_active_class);
      }
    };

    self.update_active_link = function (index) {
      var link = $('[data-orbit-link="' + self.slides().eq(index).attr('data-orbit-slide') + '"]');
      link.siblings().removeClass(settings.bullets_active_class);
      link.addClass(settings.bullets_active_class);
    };

    self.build_markup = function () {
      slides_container.wrap('<div class="' + settings.container_class + '"></div>');
      container = slides_container.parent();
      slides_container.addClass(settings.slides_container_class);

      if (settings.stack_on_small) {
        container.addClass(settings.stack_on_small_class);
      }

      if (settings.navigation_arrows) {
        container.append($('<a href="#"><span></span></a>').addClass(settings.prev_class));
        container.append($('<a href="#"><span></span></a>').addClass(settings.next_class));
      }

      if (settings.timer) {
        timer_container = $('<div>').addClass(settings.timer_container_class);
        timer_container.append('<span>');
        timer_container.append($('<div>').addClass(settings.timer_progress_class));
        timer_container.addClass(settings.timer_paused_class);
        container.append(timer_container);
      }

      if (settings.slide_number) {
        number_container = $('<div>').addClass(settings.slide_number_class);
        number_container.append('<span></span> ' + settings.slide_number_text + ' <span></span>');
        container.append(number_container);
      }

      if (settings.bullets) {
        bullets_container = $('<ol>').addClass(settings.bullets_container_class);
        container.append(bullets_container);
        bullets_container.wrap('<div class="orbit-bullets-container"></div>');
        self.slides().each(function (idx, el) {
          var bullet = $('<li>').attr('data-orbit-slide', idx).on('click', self.link_bullet);;
          bullets_container.append(bullet);
        });
      }

    };

    self._goto = function (next_idx, start_timer) {
      // if (locked) {return false;}
      if (next_idx === idx) {return false;}
      if (typeof timer === 'object') {timer.restart();}
      var slides = self.slides();

      var dir = 'next';
      locked = true;
      if (next_idx < idx) {dir = 'prev';}
      if (next_idx >= slides.length) {
        if (!settings.circular) {
          return false;
        }
        next_idx = 0;
      } else if (next_idx < 0) {
        if (!settings.circular) {
          return false;
        }
        next_idx = slides.length - 1;
      }

      var current = $(slides.get(idx));
      var next = $(slides.get(next_idx));

      current.css('zIndex', 2);
      current.removeClass(settings.active_slide_class);
      next.css('zIndex', 4).addClass(settings.active_slide_class);

      slides_container.trigger('before-slide-change.fndtn.orbit');
      settings.before_slide_change();
      self.update_active_link(next_idx);

      var callback = function () {
        var unlock = function () {
          idx = next_idx;
          locked = false;
          if (start_timer === true) {timer = self.create_timer(); timer.start();}
          self.update_slide_number(idx);
          slides_container.trigger('after-slide-change.fndtn.orbit', [{slide_number : idx, total_slides : slides.length}]);
          settings.after_slide_change(idx, slides.length);
        };
        if (slides_container.outerHeight() != next.outerHeight() && settings.variable_height) {
          slides_container.animate({'height': next.outerHeight()}, 250, 'linear', unlock);
        } else {
          unlock();
        }
      };

      if (slides.length === 1) {callback(); return false;}

      var start_animation = function () {
        if (dir === 'next') {animate.next(current, next, callback);}
        if (dir === 'prev') {animate.prev(current, next, callback);}
      };

      if (next.outerHeight() > slides_container.outerHeight() && settings.variable_height) {
        slides_container.animate({'height': next.outerHeight()}, 250, 'linear', start_animation);
      } else {
        start_animation();
      }
    };

    self.next = function (e) {
      e.stopImmediatePropagation();
      e.preventDefault();
      self._goto(idx + 1);
    };

    self.prev = function (e) {
      e.stopImmediatePropagation();
      e.preventDefault();
      self._goto(idx - 1);
    };

    self.link_custom = function (e) {
      e.preventDefault();
      var link = $(this).attr('data-orbit-link');
      if ((typeof link === 'string') && (link = $.trim(link)) != '') {
        var slide = container.find('[data-orbit-slide=' + link + ']');
        if (slide.index() != -1) {self._goto(slide.index());}
      }
    };

    self.link_bullet = function (e) {
      var index = $(this).attr('data-orbit-slide');
      if ((typeof index === 'string') && (index = $.trim(index)) != '') {
        if (isNaN(parseInt(index))) {
          var slide = container.find('[data-orbit-slide=' + index + ']');
          if (slide.index() != -1) {self._goto(slide.index() + 1);}
        } else {
          self._goto(parseInt(index));
        }
      }

    }

    self.timer_callback = function () {
      self._goto(idx + 1, true);
    }

    self.compute_dimensions = function () {
      var current = $(self.slides().get(idx));
      var h = current.outerHeight();
      if (!settings.variable_height) {
        self.slides().each(function(){
          if ($(this).outerHeight() > h) { h = $(this).outerHeight(); }
        });
      }
      slides_container.height(h);
    };

    self.create_timer = function () {
      var t = new Timer(
        container.find('.' + settings.timer_container_class),
        settings,
        self.timer_callback
      );
      return t;
    };

    self.stop_timer = function () {
      if (typeof timer === 'object') {
        timer.stop();
      }
    };

    self.toggle_timer = function () {
      var t = container.find('.' + settings.timer_container_class);
      if (t.hasClass(settings.timer_paused_class)) {
        if (typeof timer === 'undefined') {timer = self.create_timer();}
        timer.start();
      } else {
        if (typeof timer === 'object') {timer.stop();}
      }
    };

    self.init = function () {
      self.build_markup();
      if (settings.timer) {
        timer = self.create_timer();
        Foundation.utils.image_loaded(this.slides().children('img'), timer.start);
      }
      animate = new FadeAnimation(settings, slides_container);
      if (settings.animation === 'slide') {
        animate = new SlideAnimation(settings, slides_container);
      }

      container.on('click', '.' + settings.next_class, self.next);
      container.on('click', '.' + settings.prev_class, self.prev);

      if (settings.next_on_click) {
        container.on('click', '.' + settings.slides_container_class + ' [data-orbit-slide]', self.link_bullet);
      }

      container.on('click', self.toggle_timer);
      if (settings.swipe) {
        container.on('touchstart.fndtn.orbit', function (e) {
          if (!e.touches) {e = e.originalEvent;}
          var data = {
            start_page_x : e.touches[0].pageX,
            start_page_y : e.touches[0].pageY,
            start_time : (new Date()).getTime(),
            delta_x : 0,
            is_scrolling : undefined
          };
          container.data('swipe-transition', data);
          e.stopPropagation();
        })
        .on('touchmove.fndtn.orbit', function (e) {
          if (!e.touches) {
            e = e.originalEvent;
          }
          // Ignore pinch/zoom events
          if (e.touches.length > 1 || e.scale && e.scale !== 1) {
            return;
          }

          var data = container.data('swipe-transition');
          if (typeof data === 'undefined') {data = {};}

          data.delta_x = e.touches[0].pageX - data.start_page_x;

          if ( typeof data.is_scrolling === 'undefined') {
            data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
          }

          if (!data.is_scrolling && !data.active) {
            e.preventDefault();
            var direction = (data.delta_x < 0) ? (idx + 1) : (idx - 1);
            data.active = true;
            self._goto(direction);
          }
        })
        .on('touchend.fndtn.orbit', function (e) {
          container.data('swipe-transition', {});
          e.stopPropagation();
        })
      }
      container.on('mouseenter.fndtn.orbit', function (e) {
        if (settings.timer && settings.pause_on_hover) {
          self.stop_timer();
        }
      })
      .on('mouseleave.fndtn.orbit', function (e) {
        if (settings.timer && settings.resume_on_mouseout) {
          timer.start();
        }
      });

      $(document).on('click', '[data-orbit-link]', self.link_custom);
      $(window).on('load resize', self.compute_dimensions);
      Foundation.utils.image_loaded(this.slides().children('img'), self.compute_dimensions);
      Foundation.utils.image_loaded(this.slides().children('img'), function () {
        container.prev('.' + settings.preloader_class).css('display', 'none');
        self.update_slide_number(0);
        self.update_active_link(0);
        slides_container.trigger('ready.fndtn.orbit');
      });
    };

    self.init();
  };

  var Timer = function (el, settings, callback) {
    var self = this,
        duration = settings.timer_speed,
        progress = el.find('.' + settings.timer_progress_class),
        start,
        timeout,
        left = -1;

    this.update_progress = function (w) {
      var new_progress = progress.clone();
      new_progress.attr('style', '');
      new_progress.css('width', w + '%');
      progress.replaceWith(new_progress);
      progress = new_progress;
    };

    this.restart = function () {
      clearTimeout(timeout);
      el.addClass(settings.timer_paused_class);
      left = -1;
      self.update_progress(0);
    };

    this.start = function () {
      if (!el.hasClass(settings.timer_paused_class)) {return true;}
      left = (left === -1) ? duration : left;
      el.removeClass(settings.timer_paused_class);
      start = new Date().getTime();
      progress.animate({'width' : '100%'}, left, 'linear');
      timeout = setTimeout(function () {
        self.restart();
        callback();
      }, left);
      el.trigger('timer-started.fndtn.orbit')
    };

    this.stop = function () {
      if (el.hasClass(settings.timer_paused_class)) {return true;}
      clearTimeout(timeout);
      el.addClass(settings.timer_paused_class);
      var end = new Date().getTime();
      left = left - (end - start);
      var w = 100 - ((left / duration) * 100);
      self.update_progress(w);
      el.trigger('timer-stopped.fndtn.orbit');
    };
  };

  var SlideAnimation = function (settings, container) {
    var duration = settings.animation_speed;
    var is_rtl = ($('html[dir=rtl]').length === 1);
    var margin = is_rtl ? 'marginRight' : 'marginLeft';
    var animMargin = {};
    animMargin[margin] = '0%';

    this.next = function (current, next, callback) {
      current.animate({marginLeft : '-100%'}, duration);
      next.animate(animMargin, duration, function () {
        current.css(margin, '100%');
        callback();
      });
    };

    this.prev = function (current, prev, callback) {
      current.animate({marginLeft : '100%'}, duration);
      prev.css(margin, '-100%');
      prev.animate(animMargin, duration, function () {
        current.css(margin, '100%');
        callback();
      });
    };
  };

  var FadeAnimation = function (settings, container) {
    var duration = settings.animation_speed;
    var is_rtl = ($('html[dir=rtl]').length === 1);
    var margin = is_rtl ? 'marginRight' : 'marginLeft';

    this.next = function (current, next, callback) {
      next.css({'margin' : '0%', 'opacity' : '0.01'});
      next.animate({'opacity' :'1'}, duration, 'linear', function () {
        current.css('margin', '100%');
        callback();
      });
    };

    this.prev = function (current, prev, callback) {
      prev.css({'margin' : '0%', 'opacity' : '0.01'});
      prev.animate({'opacity' : '1'}, duration, 'linear', function () {
        current.css('margin', '100%');
        callback();
      });
    };
  };

  Foundation.libs = Foundation.libs || {};

  Foundation.libs.orbit = {
    name : 'orbit',

    version : '5.5.3',

    settings : {
      animation : 'slide',
      timer_speed : 10000,
      pause_on_hover : true,
      resume_on_mouseout : false,
      next_on_click : true,
      animation_speed : 500,
      stack_on_small : false,
      navigation_arrows : true,
      slide_number : true,
      slide_number_text : 'of',
      container_class : 'orbit-container',
      stack_on_small_class : 'orbit-stack-on-small',
      next_class : 'orbit-next',
      prev_class : 'orbit-prev',
      timer_container_class : 'orbit-timer',
      timer_paused_class : 'paused',
      timer_progress_class : 'orbit-progress',
      slides_container_class : 'orbit-slides-container',
      preloader_class : 'preloader',
      slide_selector : '*',
      bullets_container_class : 'orbit-bullets',
      bullets_active_class : 'active',
      slide_number_class : 'orbit-slide-number',
      caption_class : 'orbit-caption',
      active_slide_class : 'active',
      orbit_transition_class : 'orbit-transitioning',
      bullets : true,
      circular : true,
      timer : true,
      variable_height : false,
      swipe : true,
      before_slide_change : noop,
      after_slide_change : noop
    },

    init : function (scope, method, options) {
      var self = this;
      this.bindings(method, options);
    },

    events : function (instance) {
      var orbit_instance = new Orbit(this.S(instance), this.S(instance).data('orbit-init'));
      this.S(instance).data(this.name + '-instance', orbit_instance);
    },

    reflow : function () {
      var self = this;

      if (self.S(self.scope).is('[data-orbit]')) {
        var $el = self.S(self.scope);
        var instance = $el.data(self.name + '-instance');
        instance.compute_dimensions();
      } else {
        self.S('[data-orbit]', self.scope).each(function (idx, el) {
          var $el = self.S(el);
          var opts = self.data_options($el);
          var instance = $el.data(self.name + '-instance');
          instance.compute_dimensions();
        });
      }
    }
  };

}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  var openModals = [];

  Foundation.libs.reveal = {
    name : 'reveal',

    version : '5.5.3',

    locked : false,

    settings : {
      animation : 'fadeAndPop',
      animation_speed : 250,
      close_on_background_click : true,
      close_on_esc : true,
      dismiss_modal_class : 'close-reveal-modal',
      multiple_opened : false,
      bg_class : 'reveal-modal-bg',
      root_element : 'body',
      open : function(){},
      opened : function(){},
      close : function(){},
      closed : function(){},
      on_ajax_error: $.noop,
      bg : $('.reveal-modal-bg'),
      css : {
        open : {
          'opacity' : 0,
          'visibility' : 'visible',
          'display' : 'block'
        },
        close : {
          'opacity' : 1,
          'visibility' : 'hidden',
          'display' : 'none'
        }
      }
    },

    init : function (scope, method, options) {
      $.extend(true, this.settings, method, options);
      this.bindings(method, options);
    },

    events : function (scope) {
      var self = this,
          S = self.S;

      S(this.scope)
        .off('.reveal')
        .on('click.fndtn.reveal', '[' + this.add_namespace('data-reveal-id') + ']:not([disabled])', function (e) {
          e.preventDefault();

          if (!self.locked) {
            var element = S(this),
                ajax = element.data(self.data_attr('reveal-ajax')),
                replaceContentSel = element.data(self.data_attr('reveal-replace-content'));

            self.locked = true;

            if (typeof ajax === 'undefined') {
              self.open.call(self, element);
            } else {
              var url = ajax === true ? element.attr('href') : ajax;
              self.open.call(self, element, {url : url}, { replaceContentSel : replaceContentSel });
            }
          }
        });

      S(document)
        .on('click.fndtn.reveal', this.close_targets(), function (e) {
          e.preventDefault();
          if (!self.locked) {
            var settings = S('[' + self.attr_name() + '].open').data(self.attr_name(true) + '-init') || self.settings,
                bg_clicked = S(e.target)[0] === S('.' + settings.bg_class)[0];

            if (bg_clicked) {
              if (settings.close_on_background_click) {
                e.stopPropagation();
              } else {
                return;
              }
            }

            self.locked = true;
            self.close.call(self, bg_clicked ? S('[' + self.attr_name() + '].open:not(.toback)') : S(this).closest('[' + self.attr_name() + ']'));
          }
        });

      if (S('[' + self.attr_name() + ']', this.scope).length > 0) {
        S(this.scope)
          // .off('.reveal')
          .on('open.fndtn.reveal', this.settings.open)
          .on('opened.fndtn.reveal', this.settings.opened)
          .on('opened.fndtn.reveal', this.open_video)
          .on('close.fndtn.reveal', this.settings.close)
          .on('closed.fndtn.reveal', this.settings.closed)
          .on('closed.fndtn.reveal', this.close_video);
      } else {
        S(this.scope)
          // .off('.reveal')
          .on('open.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.open)
          .on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.opened)
          .on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.open_video)
          .on('close.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.close)
          .on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.closed)
          .on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.close_video);
      }

      return true;
    },

    // PATCH #3: turning on key up capture only when a reveal window is open
    key_up_on : function (scope) {
      var self = this;

      // PATCH #1: fixing multiple keyup event trigger from single key press
      self.S('body').off('keyup.fndtn.reveal').on('keyup.fndtn.reveal', function ( event ) {
        var open_modal = self.S('[' + self.attr_name() + '].open'),
            settings = open_modal.data(self.attr_name(true) + '-init') || self.settings ;
        // PATCH #2: making sure that the close event can be called only while unlocked,
        //           so that multiple keyup.fndtn.reveal events don't prevent clean closing of the reveal window.
        if ( settings && event.which === 27  && settings.close_on_esc && !self.locked) { // 27 is the keycode for the Escape key
          self.close.call(self, open_modal);
        }
      });

      return true;
    },

    // PATCH #3: turning on key up capture only when a reveal window is open
    key_up_off : function (scope) {
      this.S('body').off('keyup.fndtn.reveal');
      return true;
    },

    open : function (target, ajax_settings) {
      var self = this,
          modal;

      if (target) {
        if (typeof target.selector !== 'undefined') {
          // Find the named node; only use the first one found, since the rest of the code assumes there's only one node
          modal = self.S('#' + target.data(self.data_attr('reveal-id'))).first();
        } else {
          modal = self.S(this.scope);

          ajax_settings = target;
        }
      } else {
        modal = self.S(this.scope);
      }

      var settings = modal.data(self.attr_name(true) + '-init');
      settings = settings || this.settings;


      if (modal.hasClass('open') && target !== undefined && target.attr('data-reveal-id') == modal.attr('id')) {
        return self.close(modal);
      }

      if (!modal.hasClass('open')) {
        var open_modal = self.S('[' + self.attr_name() + '].open');

        if (typeof modal.data('css-top') === 'undefined') {
          modal.data('css-top', parseInt(modal.css('top'), 10))
            .data('offset', this.cache_offset(modal));
        }

        modal.attr('tabindex','0').attr('aria-hidden','false');

        this.key_up_on(modal);    // PATCH #3: turning on key up capture only when a reveal window is open

        // Prevent namespace event from triggering twice
        modal.on('open.fndtn.reveal', function(e) {
          if (e.namespace !== 'fndtn.reveal') return;
        });

        modal.on('open.fndtn.reveal').trigger('open.fndtn.reveal');

        if (open_modal.length < 1) {
          this.toggle_bg(modal, true);
        }

        if (typeof ajax_settings === 'string') {
          ajax_settings = {
            url : ajax_settings
          };
        }

        var openModal = function() {
          if(open_modal.length > 0) {
            if(settings.multiple_opened) {
              self.to_back(open_modal);
            } else {
              self.hide(open_modal, settings.css.close);
            }
          }

          // bl: add the open_modal that isn't already in the background to the openModals array
          if(settings.multiple_opened) {
            openModals.push(modal);
          }

          self.show(modal, settings.css.open);
        };

        if (typeof ajax_settings === 'undefined' || !ajax_settings.url) {
          openModal();
        } else {
          var old_success = typeof ajax_settings.success !== 'undefined' ? ajax_settings.success : null;
          $.extend(ajax_settings, {
            success : function (data, textStatus, jqXHR) {
              if ( $.isFunction(old_success) ) {
                var result = old_success(data, textStatus, jqXHR);
                if (typeof result == 'string') {
                  data = result;
                }
              }

              if (typeof options !== 'undefined' && typeof options.replaceContentSel !== 'undefined') {
                modal.find(options.replaceContentSel).html(data);
              } else {
                modal.html(data);
              }

              self.S(modal).foundation('section', 'reflow');
              self.S(modal).children().foundation();

              openModal();
            }
          });

          // check for if user initalized with error callback
          if (settings.on_ajax_error !== $.noop) {
            $.extend(ajax_settings, {
              error : settings.on_ajax_error
            });
          }

          $.ajax(ajax_settings);
        }
      }
      self.S(window).trigger('resize');
    },

    close : function (modal) {
      var modal = modal && modal.length ? modal : this.S(this.scope),
          open_modals = this.S('[' + this.attr_name() + '].open'),
          settings = modal.data(this.attr_name(true) + '-init') || this.settings,
          self = this;

      if (open_modals.length > 0) {

        modal.removeAttr('tabindex','0').attr('aria-hidden','true');

        this.locked = true;
        this.key_up_off(modal);   // PATCH #3: turning on key up capture only when a reveal window is open

        modal.trigger('close.fndtn.reveal');

        if ((settings.multiple_opened && open_modals.length === 1) || !settings.multiple_opened || modal.length > 1) {
          self.toggle_bg(modal, false);
          self.to_front(modal);
        }

        if (settings.multiple_opened) {
          var isCurrent = modal.is(':not(.toback)');
          self.hide(modal, settings.css.close, settings);
          if(isCurrent) {
            // remove the last modal since it is now closed
            openModals.pop();
          } else {
            // if this isn't the current modal, then find it in the array and remove it
            openModals = $.grep(openModals, function(elt) {
              var isThis = elt[0]===modal[0];
              if(isThis) {
                // since it's not currently in the front, put it in the front now that it is hidden
                // so that if it's re-opened, it won't be .toback
                self.to_front(modal);
              }
              return !isThis;
            });
          }
          // finally, show the next modal in the stack, if there is one
          if(openModals.length>0) {
            self.to_front(openModals[openModals.length - 1]);
          }
        } else {
          self.hide(open_modals, settings.css.close, settings);
        }
      }
    },

    close_targets : function () {
      var base = '.' + this.settings.dismiss_modal_class;

      if (this.settings.close_on_background_click) {
        return base + ', .' + this.settings.bg_class;
      }

      return base;
    },

    toggle_bg : function (modal, state) {
      if (this.S('.' + this.settings.bg_class).length === 0) {
        this.settings.bg = $('<div />', {'class': this.settings.bg_class})
          .appendTo('body').hide();
      }

      var visible = this.settings.bg.filter(':visible').length > 0;
      if ( state != visible ) {
        if ( state == undefined ? visible : !state ) {
          this.hide(this.settings.bg);
        } else {
          this.show(this.settings.bg);
        }
      }
    },

    show : function (el, css) {
      // is modal
      if (css) {
        var settings = el.data(this.attr_name(true) + '-init') || this.settings,
            root_element = settings.root_element,
            context = this;

        if (el.parent(root_element).length === 0) {
          var placeholder = el.wrap('<div style="display: none;" />').parent();

          el.on('closed.fndtn.reveal.wrapped', function () {
            el.detach().appendTo(placeholder);
            el.unwrap().unbind('closed.fndtn.reveal.wrapped');
          });

          el.detach().appendTo(root_element);
        }

        var animData = getAnimationData(settings.animation);
        if (!animData.animate) {
          this.locked = false;
        }
        if (animData.pop) {
          css.top = $(window).scrollTop() - el.data('offset') + 'px';
          var end_css = {
            top: $(window).scrollTop() + el.data('css-top') + 'px',
            opacity: 1
          };

          return setTimeout(function () {
            return el
              .css(css)
              .animate(end_css, settings.animation_speed, 'linear', function () {
                context.locked = false;
                el.trigger('opened.fndtn.reveal');
              })
              .addClass('open');
          }, settings.animation_speed / 2);
        }

        css.top = $(window).scrollTop() + el.data('css-top') + 'px';

        if (animData.fade) {
          var end_css = {opacity: 1};

          return setTimeout(function () {
            return el
              .css(css)
              .animate(end_css, settings.animation_speed, 'linear', function () {
                context.locked = false;
                el.trigger('opened.fndtn.reveal');
              })
              .addClass('open');
          }, settings.animation_speed / 2);
        }

        return el.css(css).show().css({opacity : 1}).addClass('open').trigger('opened.fndtn.reveal');
      }

      var settings = this.settings;

      // should we animate the background?
      if (getAnimationData(settings.animation).fade) {
        return el.fadeIn(settings.animation_speed / 2);
      }

      this.locked = false;

      return el.show();
    },

    to_back : function(el) {
      el.addClass('toback');
    },

    to_front : function(el) {
      el.removeClass('toback');
    },

    hide : function (el, css) {
      // is modal
      if (css) {
        var settings = el.data(this.attr_name(true) + '-init'),
            context = this;
        settings = settings || this.settings;

        var animData = getAnimationData(settings.animation);
        if (!animData.animate) {
          this.locked = false;
        }
        if (animData.pop) {
          var end_css = {
            top: - $(window).scrollTop() - el.data('offset') + 'px',
            opacity: 0
          };

          return setTimeout(function () {
            return el
              .animate(end_css, settings.animation_speed, 'linear', function () {
                context.locked = false;
                el.css(css).trigger('closed.fndtn.reveal');
              })
              .removeClass('open');
          }, settings.animation_speed / 2);
        }

        if (animData.fade) {
          var end_css = {opacity : 0};

          return setTimeout(function () {
            return el
              .animate(end_css, settings.animation_speed, 'linear', function () {
                context.locked = false;
                el.css(css).trigger('closed.fndtn.reveal');
              })
              .removeClass('open');
          }, settings.animation_speed / 2);
        }

        return el.hide().css(css).removeClass('open').trigger('closed.fndtn.reveal');
      }

      var settings = this.settings;

      // should we animate the background?
      if (getAnimationData(settings.animation).fade) {
        return el.fadeOut(settings.animation_speed / 2);
      }

      return el.hide();
    },

    close_video : function (e) {
      var video = $('.flex-video', e.target),
          iframe = $('iframe', video);

      if (iframe.length > 0) {
        iframe.attr('data-src', iframe[0].src);
        iframe.attr('src', iframe.attr('src'));
        video.hide();
      }
    },

    open_video : function (e) {
      var video = $('.flex-video', e.target),
          iframe = video.find('iframe');

      if (iframe.length > 0) {
        var data_src = iframe.attr('data-src');
        if (typeof data_src === 'string') {
          iframe[0].src = iframe.attr('data-src');
        } else {
          var src = iframe[0].src;
          iframe[0].src = undefined;
          iframe[0].src = src;
        }
        video.show();
      }
    },

    data_attr : function (str) {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + str;
      }

      return str;
    },

    cache_offset : function (modal) {
      var offset = modal.show().height() + parseInt(modal.css('top'), 10) + modal.scrollY;

      modal.hide();

      return offset;
    },

    off : function () {
      $(this.scope).off('.fndtn.reveal');
    },

    reflow : function () {}
  };

  /*
   * getAnimationData('popAndFade') // {animate: true,  pop: true,  fade: true}
   * getAnimationData('fade')       // {animate: true,  pop: false, fade: true}
   * getAnimationData('pop')        // {animate: true,  pop: true,  fade: false}
   * getAnimationData('foo')        // {animate: false, pop: false, fade: false}
   * getAnimationData(null)         // {animate: false, pop: false, fade: false}
   */
  function getAnimationData(str) {
    var fade = /fade/i.test(str);
    var pop = /pop/i.test(str);
    return {
      animate : fade || pop,
      pop : pop,
      fade : fade
    };
  }
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.slider = {
    name : 'slider',

    version : '5.5.3',

    settings : {
      start : 0,
      end : 100,
      step : 1,
      precision : 2,
      initial : null,
      display_selector : '',
      vertical : false,
      trigger_input_change : false,
      on_change : function () {}
    },

    cache : {},

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');
      this.bindings(method, options);
      this.reflow();
    },

    events : function () {
      var self = this;
      $(this.scope)
        .off('.slider')
        .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider',
        '[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) {
          if (!self.cache.active) {
            e.preventDefault();
            self.set_active_slider($(e.target));
          }
        })
        .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) {
          if (!!self.cache.active) {
            e.preventDefault();
            if ($.data(self.cache.active[0], 'settings').vertical) {
              var scroll_offset = 0;
              if (!e.pageY) {
                scroll_offset = window.scrollY;
              }
              self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
            } else {
              self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
            }
          }
        })
        .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) {
          if(!self.cache.active) {
            // if the user has just clicked into the slider without starting to drag the handle
            var slider = $(e.target).attr('role') === 'slider' ? $(e.target) : $(e.target).closest('.range-slider').find("[role='slider']");

            if (slider.length && (!slider.parent().hasClass('disabled') && !slider.parent().attr('disabled'))) {
              self.set_active_slider(slider);
              if ($.data(self.cache.active[0], 'settings').vertical) {
                var scroll_offset = 0;
                if (!e.pageY) {
                  scroll_offset = window.scrollY;
                }
                self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
              } else {
                self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
              }
            }
          }
          self.remove_active_slider();
        })
        .on('change.fndtn.slider', function (e) {
          self.settings.on_change();
        });

      self.S(window)
        .on('resize.fndtn.slider', self.throttle(function (e) {
          self.reflow();
        }, 300));

      // update slider value as users change input value
      this.S('[' + this.attr_name() + ']').each(function () {
        var slider = $(this),
            handle = slider.children('.range-slider-handle')[0],
            settings = self.initialize_settings(handle);

        if (settings.display_selector != '') {
          $(settings.display_selector).each(function(){
            if ($(this).attr('value')) {
              $(this).off('change').on('change', function () {
                slider.foundation("slider", "set_value", $(this).val());
              });
            }
          });
        }
      });
    },

    get_cursor_position : function (e, xy) {
      var pageXY = 'page' + xy.toUpperCase(),
          clientXY = 'client' + xy.toUpperCase(),
          position;

      if (typeof e[pageXY] !== 'undefined') {
        position = e[pageXY];
      } else if (typeof e.originalEvent[clientXY] !== 'undefined') {
        position = e.originalEvent[clientXY];
      } else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') {
        position = e.originalEvent.touches[0][clientXY];
      } else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') {
        position = e.currentPoint[xy];
      }

      return position;
    },

    set_active_slider : function ($handle) {
      this.cache.active = $handle;
    },

    remove_active_slider : function () {
      this.cache.active = null;
    },

    calculate_position : function ($handle, cursor_x) {
      var self = this,
          settings = $.data($handle[0], 'settings'),
          handle_l = $.data($handle[0], 'handle_l'),
          handle_o = $.data($handle[0], 'handle_o'),
          bar_l = $.data($handle[0], 'bar_l'),
          bar_o = $.data($handle[0], 'bar_o');

      requestAnimationFrame(function () {
        var pct;

        if (Foundation.rtl && !settings.vertical) {
          pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1);
        } else {
          pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1);
        }

        pct = settings.vertical ? 1 - pct : pct;

        var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision);

        self.set_ui($handle, norm);
      });
    },

    set_ui : function ($handle, value) {
      var settings = $.data($handle[0], 'settings'),
          handle_l = $.data($handle[0], 'handle_l'),
          bar_l = $.data($handle[0], 'bar_l'),
          norm_pct = this.normalized_percentage(value, settings.start, settings.end),
          handle_offset = norm_pct * (bar_l - handle_l) - 1,
          progress_bar_length = norm_pct * 100,
          $handle_parent = $handle.parent(),
          $hidden_inputs = $handle.parent().children('input[type=hidden]');

      if (Foundation.rtl && !settings.vertical) {
        handle_offset = -handle_offset;
      }

      handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset;
      this.set_translate($handle, handle_offset, settings.vertical);

      if (settings.vertical) {
        $handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%');
      } else {
        $handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%');
      }

      $handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider');

      $hidden_inputs.val(value);
      if (settings.trigger_input_change) {
          $hidden_inputs.trigger('change.fndtn.slider');
      }

      if (!$handle[0].hasAttribute('aria-valuemin')) {
        $handle.attr({
          'aria-valuemin' : settings.start,
          'aria-valuemax' : settings.end
        });
      }
      $handle.attr('aria-valuenow', value);

      if (settings.display_selector != '') {
        $(settings.display_selector).each(function () {
          if (this.hasAttribute('value')) {
            $(this).val(value);
          } else {
            $(this).text(value);
          }
        });
      }

    },

    normalized_percentage : function (val, start, end) {
      return Math.min(1, (val - start) / (end - start));
    },

    normalized_value : function (val, start, end, step, precision) {
      var range = end - start,
          point = val * range,
          mod = (point - (point % step)) / step,
          rem = point % step,
          round = ( rem >= step * 0.5 ? step : 0);
      return ((mod * step + round) + start).toFixed(precision);
    },

    set_translate : function (ele, offset, vertical) {
      if (vertical) {
        $(ele)
          .css('-webkit-transform', 'translateY(' + offset + 'px)')
          .css('-moz-transform', 'translateY(' + offset + 'px)')
          .css('-ms-transform', 'translateY(' + offset + 'px)')
          .css('-o-transform', 'translateY(' + offset + 'px)')
          .css('transform', 'translateY(' + offset + 'px)');
      } else {
        $(ele)
          .css('-webkit-transform', 'translateX(' + offset + 'px)')
          .css('-moz-transform', 'translateX(' + offset + 'px)')
          .css('-ms-transform', 'translateX(' + offset + 'px)')
          .css('-o-transform', 'translateX(' + offset + 'px)')
          .css('transform', 'translateX(' + offset + 'px)');
      }
    },

    limit_to : function (val, min, max) {
      return Math.min(Math.max(val, min), max);
    },

    initialize_settings : function (handle) {
      var settings = $.extend({}, this.settings, this.data_options($(handle).parent())),
          decimal_places_match_result;

      if (settings.precision === null) {
        decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/);
        settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0;
      }

      if (settings.vertical) {
        $.data(handle, 'bar_o', $(handle).parent().offset().top);
        $.data(handle, 'bar_l', $(handle).parent().outerHeight());
        $.data(handle, 'handle_o', $(handle).offset().top);
        $.data(handle, 'handle_l', $(handle).outerHeight());
      } else {
        $.data(handle, 'bar_o', $(handle).parent().offset().left);
        $.data(handle, 'bar_l', $(handle).parent().outerWidth());
        $.data(handle, 'handle_o', $(handle).offset().left);
        $.data(handle, 'handle_l', $(handle).outerWidth());
      }

      $.data(handle, 'bar', $(handle).parent());
      return $.data(handle, 'settings', settings);
    },

    set_initial_position : function ($ele) {
      var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'),
          initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start),
          $handle = $ele.children('.range-slider-handle');
      this.set_ui($handle, initial);
    },

    set_value : function (value) {
      var self = this;
      $('[' + self.attr_name() + ']', this.scope).each(function () {
        $(this).attr(self.attr_name(), value);
      });
      if (!!$(this.scope).attr(self.attr_name())) {
        $(this.scope).attr(self.attr_name(), value);
      }
      self.reflow();
    },

    reflow : function () {
      var self = this;
      self.S('[' + this.attr_name() + ']').each(function () {
        var handle = $(this).children('.range-slider-handle')[0],
            val = $(this).attr(self.attr_name());
        self.initialize_settings(handle);

        if (val) {
          self.set_ui($(handle), parseFloat(val));
        } else {
          self.set_initial_position($(this));
        }
      });
    }
  };

}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tab = {
    name : 'tab',

    version : '5.5.3',

    settings : {
      active_class : 'active',
      callback : function () {},
      deep_linking : false,
      scroll_to_content : true,
      is_hover : false
    },

    default_tab_hashes : [],

    init : function (scope, method, options) {
      var self = this,
          S = this.S;

  	  // Store the default active tabs which will be referenced when the
  	  // location hash is absent, as in the case of navigating the tabs and
  	  // returning to the first viewing via the browser Back button.
  	  S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () {
  	    self.default_tab_hashes.push(this.hash);
  	  });

      this.bindings(method, options);
      this.handle_location_hash_change();
    },

    events : function () {
      var self = this,
          S = this.S;

      var usual_tab_behavior =  function (e, target) {
        var settings = S(target).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
        if (!settings.is_hover || Modernizr.touch) {
          // if user did not pressed tab key, prevent default action
          var keyCode = e.keyCode || e.which;
          if (keyCode !== 9) { 
            e.preventDefault();
            e.stopPropagation();
          }
          self.toggle_active_tab(S(target).parent());
          
        }
      };

      S(this.scope)
        .off('.tab')
        // Key event: focus/tab key
        .on('keydown.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) {
          var keyCode = e.keyCode || e.which;
          // if user pressed tab key
          if (keyCode === 13 || keyCode === 32) { // enter or space
            var el = this;
            usual_tab_behavior(e, el);
          } 
        })
        // Click event: tab title
        .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) {
          var el = this;
          usual_tab_behavior(e, el);
        })
        // Hover event: tab title
        .on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) {
          var settings = S(this).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
          if (settings.is_hover) {
            self.toggle_active_tab(S(this).parent());
          }
        });

      // Location hash change event
      S(window).on('hashchange.fndtn.tab', function (e) {
        e.preventDefault();
        self.handle_location_hash_change();
      });
    },

    handle_location_hash_change : function () {

      var self = this,
          S = this.S;

      S('[' + this.attr_name() + ']', this.scope).each(function () {
        var settings = S(this).data(self.attr_name(true) + '-init');
        if (settings.deep_linking) {
          // Match the location hash to a label
          var hash;
          if (settings.scroll_to_content) {
            hash = self.scope.location.hash;
          } else {
            // prefix the hash to prevent anchor scrolling
            hash = self.scope.location.hash.replace('fndtn-', '');
          }
          if (hash != '') {
            // Check whether the location hash references a tab content div or
            // another element on the page (inside or outside the tab content div)
            var hash_element = S(hash);
            if (hash_element.hasClass('content') && hash_element.parent().hasClass('tabs-content')) {
              // Tab content div
              self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + hash + ']').parent());
            } else {
              // Not the tab content div. If inside the tab content, find the
              // containing tab and toggle it as active.
              var hash_tab_container_id = hash_element.closest('.content').attr('id');
              if (hash_tab_container_id != undefined) {
                self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=#' + hash_tab_container_id + ']').parent(), hash);
              }
            }
          } else {
            // Reference the default tab hashes which were initialized in the init function
            for (var ind = 0; ind < self.default_tab_hashes.length; ind++) {
              self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + self.default_tab_hashes[ind] + ']').parent());
            }
          }
        }
       });
     },

    toggle_active_tab : function (tab, location_hash) {
      var self = this,
          S = self.S,
          tabs = tab.closest('[' + this.attr_name() + ']'),
          tab_link = tab.find('a'),
          anchor = tab.children('a').first(),
          target_hash = '#' + anchor.attr('href').split('#')[1],
          target = S(target_hash),
          siblings = tab.siblings(),
          settings = tabs.data(this.attr_name(true) + '-init'),
          interpret_keyup_action = function (e) {
            // Light modification of Heydon Pickering's Practical ARIA Examples: http://heydonworks.com/practical_aria_examples/js/a11y.js

            // define current, previous and next (possible) tabs

            var $original = $(this);
            var $prev = $(this).parents('li').prev().children('[role="tab"]');
            var $next = $(this).parents('li').next().children('[role="tab"]');
            var $target;

            // find the direction (prev or next)

            switch (e.keyCode) {
              case 37:
                $target = $prev;
                break;
              case 39:
                $target = $next;
                break;
              default:
                $target = false
                  break;
            }

            if ($target.length) {
              $original.attr({
                'tabindex' : '-1',
                'aria-selected' : null
              });
              $target.attr({
                'tabindex' : '0',
                'aria-selected' : true
              }).focus();
            }

            // Hide panels

            $('[role="tabpanel"]')
              .attr('aria-hidden', 'true');

            // Show panel which corresponds to target

            $('#' + $(document.activeElement).attr('href').substring(1))
              .attr('aria-hidden', null);

          },
          go_to_hash = function(hash) {
            // This function allows correct behaviour of the browser's back button when deep linking is enabled. Without it
            // the user would get continually redirected to the default hash.
            var default_hash = settings.scroll_to_content ? self.default_tab_hashes[0] : 'fndtn-' + self.default_tab_hashes[0].replace('#', '');

            if (hash !== default_hash || window.location.hash) {
              window.location.hash = hash;
            }
          };

      // allow usage of data-tab-content attribute instead of href
      if (anchor.data('tab-content')) {
        target_hash = '#' + anchor.data('tab-content').split('#')[1];
        target = S(target_hash);
      }

      if (settings.deep_linking) {

        if (settings.scroll_to_content) {

          // retain current hash to scroll to content
          go_to_hash(location_hash || target_hash);

          if (location_hash == undefined || location_hash == target_hash) {
            tab.parent()[0].scrollIntoView();
          } else {
            S(target_hash)[0].scrollIntoView();
          }
        } else {
          // prefix the hashes so that the browser doesn't scroll down
          if (location_hash != undefined) {
            go_to_hash('fndtn-' + location_hash.replace('#', ''));
          } else {
            go_to_hash('fndtn-' + target_hash.replace('#', ''));
          }
        }
      }

      // WARNING: The activation and deactivation of the tab content must
      // occur after the deep linking in order to properly refresh the browser
      // window (notably in Chrome).
      // Clean up multiple attr instances to done once
      tab.addClass(settings.active_class).triggerHandler('opened');
      tab_link.attr({'aria-selected' : 'true',  tabindex : 0});
      siblings.removeClass(settings.active_class)
      siblings.find('a').attr({'aria-selected' : 'false'/*,  tabindex : -1*/});
      target.siblings().removeClass(settings.active_class).attr({'aria-hidden' : 'true'/*,  tabindex : -1*/});
      target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr('tabindex');
      settings.callback(tab);
      target.triggerHandler('toggled', [target]);
      tabs.triggerHandler('toggled', [tab]);

      tab_link.off('keydown').on('keydown', interpret_keyup_action );
    },

    data_attr : function (str) {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + str;
      }

      return str;
    },

    off : function () {},

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tooltip = {
    name : 'tooltip',

    version : '5.5.3',

    settings : {
      additional_inheritable_classes : [],
      tooltip_class : '.tooltip',
      append_to : 'body',
      touch_close_text : 'Tap To Close',
      disable_for_touch : false,
      hover_delay : 200,
      fade_in_duration : 150,
      fade_out_duration : 150,
      show_on : 'all',
      tip_template : function (selector, content) {
        return '<span data-selector="' + selector + '" id="' + selector + '" class="'
          + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
          + '" role="tooltip">' + content + '<span class="nub"></span></span>';
      }
    },

    cache : {},

    init : function (scope, method, options) {
      Foundation.inherit(this, 'random_str');
      this.bindings(method, options);
    },

    should_show : function (target, tip) {
      var settings = $.extend({}, this.settings, this.data_options(target));

      if (settings.show_on === 'all') {
        return true;
      } else if (this.small() && settings.show_on === 'small') {
        return true;
      } else if (this.medium() && settings.show_on === 'medium') {
        return true;
      } else if (this.large() && settings.show_on === 'large') {
        return true;
      }
      return false;
    },

    medium : function () {
      return matchMedia(Foundation.media_queries['medium']).matches;
    },

    large : function () {
      return matchMedia(Foundation.media_queries['large']).matches;
    },

    events : function (instance) {
      var self = this,
          S = self.S;

      self.create(this.S(instance));

      function _startShow(elt, $this, immediate) {
        if (elt.timer) {
          return;
        }

        if (immediate) {
          elt.timer = null;
          self.showTip($this);
        } else {
          elt.timer = setTimeout(function () {
            elt.timer = null;
            self.showTip($this);
          }.bind(elt), self.settings.hover_delay);
        }
      }

      function _startHide(elt, $this) {
        if (elt.timer) {
          clearTimeout(elt.timer);
          elt.timer = null;
        }

        self.hide($this);
      }

      $(this.scope)
        .off('.tooltip')
        .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip',
          '[' + this.attr_name() + ']', function (e) {
          var $this = S(this),
              settings = $.extend({}, self.settings, self.data_options($this)),
              is_touch = false;

          if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) {
            return false;
          }

          if (/mouse/i.test(e.type) && self.ie_touch(e)) {
            return false;
          }
          
          if ($this.hasClass('open')) {
            if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
              e.preventDefault();
            }
            self.hide($this);
          } else {
            if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
              return;
            } else if (!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
              e.preventDefault();
              S(settings.tooltip_class + '.open').hide();
              is_touch = true;
              // close other open tooltips on touch
              if ($('.open[' + self.attr_name() + ']').length > 0) {
               var prevOpen = S($('.open[' + self.attr_name() + ']')[0]);
               self.hide(prevOpen);
              }
            }

            if (/enter|over/i.test(e.type)) {
              _startShow(this, $this);

            } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
              _startHide(this, $this);
            } else {
              _startShow(this, $this, true);
            }
          }
        })
        .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) {
          if (/mouse/i.test(e.type) && self.ie_touch(e)) {
            return false;
          }

          if ($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') {
            return;
          } else if ($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) {
            self.convert_to_touch($(this));
          } else {
            _startHide(this, $(this));
          }
        })
        .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) {
          _startHide(this, S(this));
        });
    },

    ie_touch : function (e) {
      // How do I distinguish between IE11 and Windows Phone 8?????
      return false;
    },

    showTip : function ($target) {
      var $tip = this.getTip($target);
      if (this.should_show($target, $tip)) {
        return this.show($target);
      }
      return;
    },

    getTip : function ($target) {
      var selector = this.selector($target),
          settings = $.extend({}, this.settings, this.data_options($target)),
          tip = null;

      if (selector) {
        tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class);
      }

      return (typeof tip === 'object') ? tip : false;
    },

    selector : function ($target) {
      var dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector');

      if (typeof dataSelector != 'string') {
        dataSelector = this.random_str(6);
        $target
          .attr('data-selector', dataSelector)
          .attr('aria-describedby', dataSelector);
      }

      return dataSelector;
    },

    create : function ($target) {
      var self = this,
          settings = $.extend({}, this.settings, this.data_options($target)),
          tip_template = this.settings.tip_template;

      if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) {
        tip_template = window[settings.tip_template];
      }

      var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
          classes = this.inheritable_classes($target);

      $tip.addClass(classes).appendTo(settings.append_to);

      if (Modernizr.touch) {
        $tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>');
        $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function (e) {
          self.hide($target);
        });
      }

      $target.removeAttr('title').attr('title', '');
    },

    reposition : function (target, tip, classes) {
      var width, nub, nubHeight, nubWidth, objPos;

      tip.css('visibility', 'hidden').show();

      width = target.data('width');
      nub = tip.children('.nub');
      nubHeight = nub.outerHeight();
      nubWidth = nub.outerWidth();

      if (this.small()) {
        tip.css({'width' : '100%'});
      } else {
        tip.css({'width' : (width) ? width : 'auto'});
      }

      objPos = function (obj, top, right, bottom, left, width) {
        return obj.css({
          'top' : (top) ? top : 'auto',
          'bottom' : (bottom) ? bottom : 'auto',
          'left' : (left) ? left : 'auto',
          'right' : (right) ? right : 'auto'
        }).end();
      };
      
      var o_top = target.offset().top;
      var o_left = target.offset().left;
      var outerHeight = target.outerHeight();

      objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left);

      if (this.small()) {
        objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', 12.5, $(this.scope).width());
        tip.addClass('tip-override');
        objPos(nub, -nubHeight, 'auto', 'auto', o_left);
      } else {
        
        if (Foundation.rtl) {
          nub.addClass('rtl');
          o_left = o_left + target.outerWidth() - tip.outerWidth();
        }

        objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left);
        // reset nub from small styles, if they've been applied
        if (nub.attr('style')) {
          nub.removeAttr('style');
        }
        
        tip.removeClass('tip-override');
        
        var tip_outerHeight = tip.outerHeight();
        
        if (classes && classes.indexOf('tip-top') > -1) {
          if (Foundation.rtl) {
            nub.addClass('rtl');
          }
          objPos(tip, (o_top - tip_outerHeight), 'auto', 'auto', o_left)
            .removeClass('tip-override');
        } else if (classes && classes.indexOf('tip-left') > -1) {
          objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left - tip.outerWidth() - nubHeight))
            .removeClass('tip-override');
          nub.removeClass('rtl');
        } else if (classes && classes.indexOf('tip-right') > -1) {
          objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left + target.outerWidth() + nubHeight))
            .removeClass('tip-override');
          nub.removeClass('rtl');
        }
      }

      tip.css('visibility', 'visible').hide();
    },

    small : function () {
      return matchMedia(Foundation.media_queries.small).matches &&
        !matchMedia(Foundation.media_queries.medium).matches;
    },

    inheritable_classes : function ($target) {
      var settings = $.extend({}, this.settings, this.data_options($target)),
          inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes),
          classes = $target.attr('class'),
          filtered = classes ? $.map(classes.split(' '), function (el, i) {
            if ($.inArray(el, inheritables) !== -1) {
              return el;
            }
          }).join(' ') : '';

      return $.trim(filtered);
    },

    convert_to_touch : function ($target) {
      var self = this,
          $tip = self.getTip($target),
          settings = $.extend({}, self.settings, self.data_options($target));

      if ($tip.find('.tap-to-close').length === 0) {
        $tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>');
        $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function (e) {
          self.hide($target);
        });
      }

      $target.data('tooltip-open-event-type', 'touch');
    },

    show : function ($target) {
      var $tip = this.getTip($target);
      if ($target.data('tooltip-open-event-type') == 'touch') {
        this.convert_to_touch($target);
      }

      this.reposition($target, $tip, $target.attr('class'));
      $target.addClass('open');
      $tip.fadeIn(this.settings.fade_in_duration);
    },

    hide : function ($target) {
      var $tip = this.getTip($target);

      $tip.fadeOut(this.settings.fade_out_duration, function () {
        $tip.find('.tap-to-close').remove();
        $tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose');
        $target.removeClass('open');
      });
    },

    off : function () {
      var self = this;
      this.S(this.scope).off('.fndtn.tooltip');
      this.S(this.settings.tooltip_class).each(function (i) {
        $('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text());
      }).remove();
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.topbar = {
    name : 'topbar',

    version : '5.5.3',

    settings : {
      index : 0,
      start_offset : 0,
      sticky_class : 'sticky',
      custom_back_text : true,
      back_text : 'Back',
      mobile_show_parent_link : true,
      is_hover : true,
      scrolltop : true, // jump to top when sticky nav menu toggle is clicked
      sticky_on : 'all',
      dropdown_autoclose: true
    },

    init : function (section, method, options) {
      Foundation.inherit(this, 'add_custom_rule register_media throttle');
      var self = this;

      self.register_media('topbar', 'foundation-mq-topbar');

      this.bindings(method, options);

      self.S('[' + this.attr_name() + ']', this.scope).each(function () {
        var topbar = $(this),
            settings = topbar.data(self.attr_name(true) + '-init'),
            section = self.S('section, .top-bar-section', this);
        topbar.data('index', 0);
        var topbarContainer = topbar.parent();
        if (topbarContainer.hasClass('fixed') || self.is_sticky(topbar, topbarContainer, settings) ) {
          self.settings.sticky_class = settings.sticky_class;
          self.settings.sticky_topbar = topbar;
          topbar.data('height', topbarContainer.outerHeight());
          topbar.data('stickyoffset', topbarContainer.offset().top);
        } else {
          topbar.data('height', topbar.outerHeight());
        }

        if (!settings.assembled) {
          self.assemble(topbar);
        }

        if (settings.is_hover) {
          self.S('.has-dropdown', topbar).addClass('not-click');
        } else {
          self.S('.has-dropdown', topbar).removeClass('not-click');
        }

        // Pad body when sticky (scrolled) or fixed.
        self.add_custom_rule('.f-topbar-fixed { padding-top: ' + topbar.data('height') + 'px }');

        if (topbarContainer.hasClass('fixed')) {
          self.S('body').addClass('f-topbar-fixed');
        }
      });

    },

    is_sticky : function (topbar, topbarContainer, settings) {
      var sticky     = topbarContainer.hasClass(settings.sticky_class);
      var smallMatch = matchMedia(Foundation.media_queries.small).matches;
      var medMatch   = matchMedia(Foundation.media_queries.medium).matches;
      var lrgMatch   = matchMedia(Foundation.media_queries.large).matches;

      if (sticky && settings.sticky_on === 'all') {
        return true;
      }
      if (sticky && this.small() && settings.sticky_on.indexOf('small') !== -1) {
        if (smallMatch && !medMatch && !lrgMatch) { return true; }
      }
      if (sticky && this.medium() && settings.sticky_on.indexOf('medium') !== -1) {
        if (smallMatch && medMatch && !lrgMatch) { return true; }
      }
      if (sticky && this.large() && settings.sticky_on.indexOf('large') !== -1) {
        if (smallMatch && medMatch && lrgMatch) { return true; }
      }

       return false;
    },

    toggle : function (toggleEl) {
      var self = this,
          topbar;

      if (toggleEl) {
        topbar = self.S(toggleEl).closest('[' + this.attr_name() + ']');
      } else {
        topbar = self.S('[' + this.attr_name() + ']');
      }

      var settings = topbar.data(this.attr_name(true) + '-init');

      var section = self.S('section, .top-bar-section', topbar);

      if (self.breakpoint()) {
        if (!self.rtl) {
          section.css({left : '0%'});
          $('>.name', section).css({left : '100%'});
        } else {
          section.css({right : '0%'});
          $('>.name', section).css({right : '100%'});
        }

        self.S('li.moved', section).removeClass('moved');
        topbar.data('index', 0);

        topbar
          .toggleClass('expanded')
          .css('height', '');
      }

      if (settings.scrolltop) {
        if (!topbar.hasClass('expanded')) {
          if (topbar.hasClass('fixed')) {
            topbar.parent().addClass('fixed');
            topbar.removeClass('fixed');
            self.S('body').addClass('f-topbar-fixed');
          }
        } else if (topbar.parent().hasClass('fixed')) {
          if (settings.scrolltop) {
            topbar.parent().removeClass('fixed');
            topbar.addClass('fixed');
            self.S('body').removeClass('f-topbar-fixed');

            window.scrollTo(0, 0);
          } else {
            topbar.parent().removeClass('expanded');
          }
        }
      } else {
        if (self.is_sticky(topbar, topbar.parent(), settings)) {
          topbar.parent().addClass('fixed');
        }

        if (topbar.parent().hasClass('fixed')) {
          if (!topbar.hasClass('expanded')) {
            topbar.removeClass('fixed');
            topbar.parent().removeClass('expanded');
            self.update_sticky_positioning();
          } else {
            topbar.addClass('fixed');
            topbar.parent().addClass('expanded');
            self.S('body').addClass('f-topbar-fixed');
          }
        }
      }
    },

    timer : null,

    events : function (bar) {
      var self = this,
          S = this.S;

      S(this.scope)
        .off('.topbar')
        .on('click.fndtn.topbar', '[' + this.attr_name() + '] .toggle-topbar', function (e) {
          e.preventDefault();
          self.toggle(this);
        })
        .on('click.fndtn.topbar contextmenu.fndtn.topbar', '.top-bar .top-bar-section li a[href^="#"],[' + this.attr_name() + '] .top-bar-section li a[href^="#"]', function (e) {
          var li = $(this).closest('li'),
              topbar = li.closest('[' + self.attr_name() + ']'),
              settings = topbar.data(self.attr_name(true) + '-init');

          if (settings.dropdown_autoclose && settings.is_hover) {
            var hoverLi = $(this).closest('.hover');
            hoverLi.removeClass('hover');
          }
          if (self.breakpoint() && !li.hasClass('back') && !li.hasClass('has-dropdown')) {
            self.toggle();
          }

        })
        .on('click.fndtn.topbar', '[' + this.attr_name() + '] li.has-dropdown', function (e) {
          var li = S(this),
              target = S(e.target),
              topbar = li.closest('[' + self.attr_name() + ']'),
              settings = topbar.data(self.attr_name(true) + '-init');

          if (target.data('revealId')) {
            self.toggle();
            return;
          }

          if (self.breakpoint()) {
            return;
          }

          if (settings.is_hover && !Modernizr.touch) {
            return;
          }

          e.stopImmediatePropagation();

          if (li.hasClass('hover')) {
            li
              .removeClass('hover')
              .find('li')
              .removeClass('hover');

            li.parents('li.hover')
              .removeClass('hover');
          } else {
            li.addClass('hover');

            $(li).siblings().removeClass('hover');

            if (target[0].nodeName === 'A' && target.parent().hasClass('has-dropdown')) {
              e.preventDefault();
            }
          }
        })
        .on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown>a', function (e) {
          if (self.breakpoint()) {

            e.preventDefault();

            var $this = S(this),
                topbar = $this.closest('[' + self.attr_name() + ']'),
                section = topbar.find('section, .top-bar-section'),
                dropdownHeight = $this.next('.dropdown').outerHeight(),
                $selectedLi = $this.closest('li');

            topbar.data('index', topbar.data('index') + 1);
            $selectedLi.addClass('moved');

            if (!self.rtl) {
              section.css({left : -(100 * topbar.data('index')) + '%'});
              section.find('>.name').css({left : 100 * topbar.data('index') + '%'});
            } else {
              section.css({right : -(100 * topbar.data('index')) + '%'});
              section.find('>.name').css({right : 100 * topbar.data('index') + '%'});
            }

            topbar.css('height', $this.siblings('ul').outerHeight(true) + topbar.data('height'));
          }
        });

      S(window).off('.topbar').on('resize.fndtn.topbar', self.throttle(function () {
          self.resize.call(self);
      }, 50)).trigger('resize.fndtn.topbar').load(function () {
          // Ensure that the offset is calculated after all of the pages resources have loaded
          S(this).trigger('resize.fndtn.topbar');
      });

      S('body').off('.topbar').on('click.fndtn.topbar', function (e) {
        var parent = S(e.target).closest('li').closest('li.hover');

        if (parent.length > 0) {
          return;
        }

        S('[' + self.attr_name() + '] li.hover').removeClass('hover');
      });

      // Go up a level on Click
      S(this.scope).on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown .back', function (e) {
        e.preventDefault();

        var $this = S(this),
            topbar = $this.closest('[' + self.attr_name() + ']'),
            section = topbar.find('section, .top-bar-section'),
            settings = topbar.data(self.attr_name(true) + '-init'),
            $movedLi = $this.closest('li.moved'),
            $previousLevelUl = $movedLi.parent();

        topbar.data('index', topbar.data('index') - 1);

        if (!self.rtl) {
          section.css({left : -(100 * topbar.data('index')) + '%'});
          section.find('>.name').css({left : 100 * topbar.data('index') + '%'});
        } else {
          section.css({right : -(100 * topbar.data('index')) + '%'});
          section.find('>.name').css({right : 100 * topbar.data('index') + '%'});
        }

        if (topbar.data('index') === 0) {
          topbar.css('height', '');
        } else {
          topbar.css('height', $previousLevelUl.outerHeight(true) + topbar.data('height'));
        }

        setTimeout(function () {
          $movedLi.removeClass('moved');
        }, 300);
      });

      // Show dropdown menus when their items are focused
      S(this.scope).find('.dropdown a')
        .focus(function () {
          $(this).parents('.has-dropdown').addClass('hover');
        })
        .blur(function () {
          $(this).parents('.has-dropdown').removeClass('hover');
        });
    },

    resize : function () {
      var self = this;
      self.S('[' + this.attr_name() + ']').each(function () {
        var topbar = self.S(this),
            settings = topbar.data(self.attr_name(true) + '-init');

        var stickyContainer = topbar.parent('.' + self.settings.sticky_class);
        var stickyOffset;

        if (!self.breakpoint()) {
          var doToggle = topbar.hasClass('expanded');
          topbar
            .css('height', '')
            .removeClass('expanded')
            .find('li')
            .removeClass('hover');

            if (doToggle) {
              self.toggle(topbar);
            }
        }

        if (self.is_sticky(topbar, stickyContainer, settings)) {
          if (stickyContainer.hasClass('fixed')) {
            // Remove the fixed to allow for correct calculation of the offset.
            stickyContainer.removeClass('fixed');

            stickyOffset = stickyContainer.offset().top;
            if (self.S(document.body).hasClass('f-topbar-fixed')) {
              stickyOffset -= topbar.data('height');
            }

            topbar.data('stickyoffset', stickyOffset);
            stickyContainer.addClass('fixed');
          } else {
            stickyOffset = stickyContainer.offset().top;
            topbar.data('stickyoffset', stickyOffset);
          }
        }

      });
    },

    breakpoint : function () {
      return !matchMedia(Foundation.media_queries['topbar']).matches;
    },

    small : function () {
      return matchMedia(Foundation.media_queries['small']).matches;
    },

    medium : function () {
      return matchMedia(Foundation.media_queries['medium']).matches;
    },

    large : function () {
      return matchMedia(Foundation.media_queries['large']).matches;
    },

    assemble : function (topbar) {
      var self = this,
          settings = topbar.data(this.attr_name(true) + '-init'),
          section = self.S('section, .top-bar-section', topbar);

      // Pull element out of the DOM for manipulation
      section.detach();

      self.S('.has-dropdown>a', section).each(function () {
        var $link = self.S(this),
            $dropdown = $link.siblings('.dropdown'),
            url = $link.attr('href'),
            $titleLi;

        if (!$dropdown.find('.title.back').length) {

          if (settings.mobile_show_parent_link == true && url) {
            $titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5></li><li class="parent-link hide-for-medium-up"><a class="parent-link js-generated" href="' + url + '">' + $link.html() +'</a></li>');
          } else {
            $titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5>');
          }

          // Copy link to subnav
          if (settings.custom_back_text == true) {
            $('h5>a', $titleLi).html(settings.back_text);
          } else {
            $('h5>a', $titleLi).html('&laquo; ' + $link.html());
          }
          $dropdown.prepend($titleLi);
        }
      });

      // Put element back in the DOM
      section.appendTo(topbar);

      // check for sticky
      this.sticky();

      this.assembled(topbar);
    },

    assembled : function (topbar) {
      topbar.data(this.attr_name(true), $.extend({}, topbar.data(this.attr_name(true)), {assembled : true}));
    },

    height : function (ul) {
      var total = 0,
          self = this;

      $('> li', ul).each(function () {
        total += self.S(this).outerHeight(true);
      });

      return total;
    },

    sticky : function () {
      var self = this;

      this.S(window).on('scroll', function () {
        self.update_sticky_positioning();
      });
    },

    update_sticky_positioning : function () {
      var klass = '.' + this.settings.sticky_class,
          $window = this.S(window),
          self = this;

      if (self.settings.sticky_topbar && self.is_sticky(this.settings.sticky_topbar,this.settings.sticky_topbar.parent(), this.settings)) {
        var distance = this.settings.sticky_topbar.data('stickyoffset') + this.settings.start_offset;
        if (!self.S(klass).hasClass('expanded')) {
          if ($window.scrollTop() > (distance)) {
            if (!self.S(klass).hasClass('fixed')) {
              self.S(klass).addClass('fixed');
              self.S('body').addClass('f-topbar-fixed');
            }
          } else if ($window.scrollTop() <= distance) {
            if (self.S(klass).hasClass('fixed')) {
              self.S(klass).removeClass('fixed');
              self.S('body').removeClass('f-topbar-fixed');
            }
          }
        }
      }
    },

    off : function () {
      this.S(this.scope).off('.fndtn.topbar');
      this.S(window).off('.fndtn.topbar');
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

},{}],623:[function(require,module,exports){
;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.offcanvas = {
    name : 'offcanvas',

    version : '5.5.3',

    settings : {
      open_method : 'move',
      close_on_click : false
    },

    init : function (scope, method, options) {
      this.bindings(method, options);
    },

    events : function () {
      var self = this,
          S = self.S,
          move_class = '',
          right_postfix = '',
          left_postfix = '',
          top_postfix = '',
          bottom_postfix = '';

      if (this.settings.open_method === 'move') {
        move_class = 'move-';
        right_postfix = 'right';
        left_postfix = 'left';
        top_postfix = 'top';
        bottom_postfix = 'bottom';
      } else if (this.settings.open_method === 'overlap_single') {
        move_class = 'offcanvas-overlap-';
        right_postfix = 'right';
        left_postfix = 'left';
        top_postfix = 'top';
        bottom_postfix = 'bottom';
      } else if (this.settings.open_method === 'overlap') {
        move_class = 'offcanvas-overlap';
      }

      S(this.scope).off('.offcanvas')
        .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + right_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.left-submenu').removeClass(move_class + right_postfix);
          }
          $('.left-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + right_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + right_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.left-submenu').toggleClass(move_class + right_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + right_postfix);
          }
          $('.left-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of left canvas
        .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + left_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.right-submenu').removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + left_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + left_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.right-submenu').toggleClass(move_class + left_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of right canvas
        .on('click.fndtn.offcanvas', '.top-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + bottom_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.top-submenu').removeClass(move_class + bottom_postfix);
          }
          $('.top-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.top-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + bottom_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + bottom_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.top-submenu').toggleClass(move_class + bottom_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + bottom_postfix);
          }
          $('.top-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of top canvas
        .on('click.fndtn.offcanvas', '.bottom-off-canvas-toggle', function (e) {
          self.click_toggle_class(e, move_class + top_postfix);
          if (self.settings.open_method !== 'overlap') {
            S('.bottom-submenu').removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.bottom-off-canvas-menu a', function (e) {
          var settings = self.get_settings(e);
          var parent = S(this).parent();

          if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
            self.hide.call(self, move_class + top_postfix, self.get_wrapper(e));
            parent.parent().removeClass(move_class + top_postfix);
          } else if (S(this).parent().hasClass('has-submenu')) {
            e.preventDefault();
            S(this).siblings('.bottom-submenu').toggleClass(move_class + top_postfix);
          } else if (parent.hasClass('back')) {
            e.preventDefault();
            parent.parent().removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        //end of bottom
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + left_postfix);
          S('.right-submenu').removeClass(move_class + left_postfix);
          if (right_postfix) {
            self.click_remove_class(e, move_class + right_postfix);
            S('.left-submenu').removeClass(move_class + left_postfix);
          }
          $('.right-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + left_postfix);
          $('.left-off-canvas-toggle').attr('aria-expanded', 'false');
          if (right_postfix) {
            self.click_remove_class(e, move_class + right_postfix);
            $('.right-off-canvas-toggle').attr('aria-expanded', 'false');
          }
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + top_postfix);
          S('.bottom-submenu').removeClass(move_class + top_postfix);
          if (bottom_postfix) {
            self.click_remove_class(e, move_class + bottom_postfix);
            S('.top-submenu').removeClass(move_class + top_postfix);
          }
          $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true');
        })
        .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
          self.click_remove_class(e, move_class + top_postfix);
          $('.top-off-canvas-toggle').attr('aria-expanded', 'false');
          if (bottom_postfix) {
            self.click_remove_class(e, move_class + bottom_postfix);
            $('.bottom-off-canvas-toggle').attr('aria-expanded', 'false');
          }
        });
    },

    toggle : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      if ($off_canvas.is('.' + class_name)) {
        this.hide(class_name, $off_canvas);
      } else {
        this.show(class_name, $off_canvas);
      }
    },

    show : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      $off_canvas.trigger('open.fndtn.offcanvas');
      $off_canvas.addClass(class_name);
    },

    hide : function (class_name, $off_canvas) {
      $off_canvas = $off_canvas || this.get_wrapper();
      $off_canvas.trigger('close.fndtn.offcanvas');
      $off_canvas.removeClass(class_name);
    },

    click_toggle_class : function (e, class_name) {
      e.preventDefault();
      var $off_canvas = this.get_wrapper(e);
      this.toggle(class_name, $off_canvas);
    },

    click_remove_class : function (e, class_name) {
      e.preventDefault();
      var $off_canvas = this.get_wrapper(e);
      this.hide(class_name, $off_canvas);
    },

    get_settings : function (e) {
      var offcanvas  = this.S(e.target).closest('[' + this.attr_name() + ']');
      return offcanvas.data(this.attr_name(true) + '-init') || this.settings;
    },

    get_wrapper : function (e) {
      var $off_canvas = this.S(e ? e.target : this.scope).closest('.off-canvas-wrap');

      if ($off_canvas.length === 0) {
        $off_canvas = this.S('.off-canvas-wrap');
      }
      return $off_canvas;
    },

    reflow : function () {}
  };
}(jQuery, window, window.document));

},{}],624:[function(require,module,exports){
/*! jQuery UI - v1.11.4 - 2015-03-11
* http://jqueryui.com
* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */

(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}function s(e){for(var t,i;e.length&&e[0]!==document;){if(t=e.css("position"),("absolute"===t||"relative"===t||"fixed"===t)&&(i=parseInt(e.css("zIndex"),10),!isNaN(i)&&0!==i))return i;e=e.parent()}return 0}function n(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.regional.en=e.extend(!0,{},this.regional[""]),this.regional["en-US"]=e.extend(!0,{},this.regional.en),this.dpDiv=a(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",o)}function o(){e.datepicker._isDisabledDatepicker(v.inline?v.dpDiv.parent()[0]:v.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))}function r(t,i){e.extend(t,i);for(var s in i)null==i[s]&&(t[s]=i[s]);return t}function h(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var l=0,u=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,n=u.call(arguments,1),a=0,o=n.length;o>a;a++)for(i in n[a])s=n[a][i],n[a].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(n){var a="string"==typeof n,o=u.call(arguments,1),r=this;return a?this.each(function(){var i,a=e.data(this,s);return"instance"===n?(r=a,!1):a?e.isFunction(a[n])&&"_"!==n.charAt(0)?(i=a[n].apply(a,o),i!==a&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+n+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+n+"'")}):(o.length&&(n=e.widget.extend.apply(null,[n].concat(o))),this.each(function(){var t=e.data(this,s);t?(t.option(n||{}),t._init&&t._init()):e.data(this,s,new i(n,this))})),r}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=l++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var d=!1;e(document).mouseup(function(){d=!1}),e.widget("ui.mouse",{version:"1.11.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!d){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),d=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),d=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,i,s=e("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=s.children()[0];return e("body").append(s),t=a.offsetWidth,s.css("overflow","scroll"),i=a.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),n=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),n="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,a="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:a?e.position.scrollbarWidth():0,height:n?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:n,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s||n?i.width():i.outerWidth(),height:s||n?i.height():i.outerHeight()}}},e.fn.position=function(n){if(!n||!n.of)return f.apply(this,arguments);n=e.extend({},n);var p,m,g,v,y,b,_=e(n.of),x=e.position.getWithinInfo(n.within),w=e.position.getScrollInfo(x),k=(n.collision||"flip").split(" "),T={};return b=s(_),_[0].preventDefault&&(n.at="left top"),m=b.width,g=b.height,v=b.offset,y=e.extend({},v),e.each(["my","at"],function(){var e,t,i=(n[this]||"").split(" ");1===i.length&&(i=l.test(i[0])?i.concat(["center"]):u.test(i[0])?["center"].concat(i):["center","center"]),i[0]=l.test(i[0])?i[0]:"center",i[1]=u.test(i[1])?i[1]:"center",e=d.exec(i[0]),t=d.exec(i[1]),T[this]=[e?e[0]:0,t?t[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===n.at[0]?y.left+=m:"center"===n.at[0]&&(y.left+=m/2),"bottom"===n.at[1]?y.top+=g:"center"===n.at[1]&&(y.top+=g/2),p=t(T.at,m,g),y.left+=p[0],y.top+=p[1],this.each(function(){var s,l,u=e(this),d=u.outerWidth(),c=u.outerHeight(),f=i(this,"marginLeft"),b=i(this,"marginTop"),D=d+f+i(this,"marginRight")+w.width,S=c+b+i(this,"marginBottom")+w.height,M=e.extend({},y),C=t(T.my,u.outerWidth(),u.outerHeight());"right"===n.my[0]?M.left-=d:"center"===n.my[0]&&(M.left-=d/2),"bottom"===n.my[1]?M.top-=c:"center"===n.my[1]&&(M.top-=c/2),M.left+=C[0],M.top+=C[1],a||(M.left=h(M.left),M.top=h(M.top)),s={marginLeft:f,marginTop:b},e.each(["left","top"],function(t,i){e.ui.position[k[t]]&&e.ui.position[k[t]][i](M,{targetWidth:m,targetHeight:g,elemWidth:d,elemHeight:c,collisionPosition:s,collisionWidth:D,collisionHeight:S,offset:[p[0]+C[0],p[1]+C[1]],my:n.my,at:n.at,within:x,elem:u})}),n.using&&(l=function(e){var t=v.left-M.left,i=t+m-d,s=v.top-M.top,a=s+g-c,h={target:{element:_,left:v.left,top:v.top,width:m,height:g},element:{element:u,left:M.left,top:M.top,width:d,height:c},horizontal:0>i?"left":t>0?"right":"center",vertical:0>a?"top":s>0?"bottom":"middle"};d>m&&m>r(t+i)&&(h.horizontal="center"),c>g&&g>r(s+a)&&(h.vertical="middle"),h.important=o(r(t),r(i))>o(r(s),r(a))?"horizontal":"vertical",n.using.call(this,e,h)}),u.offset(e.extend(M,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=e.left-t.collisionPosition.marginLeft,h=n-r,l=r+t.collisionWidth-a-n;t.collisionWidth>a?h>0&&0>=l?(i=e.left+h+t.collisionWidth-a-n,e.left+=h-i):e.left=l>0&&0>=h?n:h>l?n+a-t.collisionWidth:n:h>0?e.left+=h:l>0?e.left-=l:e.left=o(e.left-r,e.left)},top:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollTop:s.offset.top,a=t.within.height,r=e.top-t.collisionPosition.marginTop,h=n-r,l=r+t.collisionHeight-a-n;t.collisionHeight>a?h>0&&0>=l?(i=e.top+h+t.collisionHeight-a-n,e.top+=h-i):e.top=l>0&&0>=h?n:h>l?n+a-t.collisionHeight:n:h>0?e.top+=h:l>0?e.top-=l:e.top=o(e.top-r,e.top)}},flip:{left:function(e,t){var i,s,n=t.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-o-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-o-a,(0>i||r(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>r(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,n=t.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-o-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-o-a,(0>s||r(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,(i>0||d>r(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,n,o,r=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)t.style[o]=s[o];t.appendChild(h),i=r||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",n=e(h).offset().left,a=n>10&&11>n,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.accordion",{version:"1.11.4",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),e=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&(this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)),void 0)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,s=this.headers.length,n=this.headers.index(t.target),a=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(e(t.target).attr("tabIndex",-1),e(a).attr("tabIndex",0),a.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var e=this.headers,t=this.panels;this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.panels=this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide(),t&&(this._off(e.not(this.headers)),this._off(t.not(this.panels)))},_refresh:function(){var t,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var t=e(this),i=t.uniqueId().attr("id"),s=t.next(),n=s.uniqueId().attr("id");t.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(t=n.height(),this.element.siblings(":visible").each(function(){var i=e(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(t-=i.outerHeight(!0))}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n[0]===s[0],o=a&&i.collapsible,r=o?e():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:o?e():n,newPanel:r};t.preventDefault(),a&&!i.collapsible||this._trigger("beforeActivate",t,l)===!1||(i.active=o?!1:this.headers.index(n),this.active=a?e():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),a||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,s=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,t):(s.hide(),i.show(),this._toggleComplete(t)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(e(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(e,t,i){var s,n,a,o=this,r=0,h=e.css("box-sizing"),l=e.length&&(!t.length||e.index()<t.index()),u=this.options.animate||{},d=l&&u.down||u,c=function(){o._toggleComplete(i)};return"number"==typeof d&&(a=d),"string"==typeof d&&(n=d),n=n||d.easing||u.easing,a=a||d.duration||u.duration,t.length?e.length?(s=e.show().outerHeight(),t.animate(this.hideProps,{duration:a,easing:n,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(this.showProps,{duration:a,easing:n,complete:c,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?"content-box"===h&&(r+=i.now):"content"!==o.options.heightStyle&&(i.now=Math.round(s-t.outerHeight()-r),r=0)}}),void 0):t.animate(this.hideProps,a,n,c):e.animate(this.showProps,a,n,c)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.widget("ui.menu",{version:"1.11.4",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(e){e.preventDefault()},"click .ui-menu-item":function(t){var i=e(t.target);!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&e(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){if(!this.previousFilter){var i=e(t.currentTarget);
i.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(t,i)}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.find(this.options.items).eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){this._closeOnDocumentClick(e)&&this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){var i,s,n,a,o=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:o=!1,s=this.previousFilter||"",n=String.fromCharCode(t.keyCode),a=!1,clearTimeout(this.filterTimer),n===s?a=!0:n=s+n,i=this._filterMenuItems(n),i=a&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(t.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(t,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}o&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(e):this.select(e))},refresh:function(){var t,i,s=this,n=this.options.icons.submenu,a=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),a.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),i=t.parent(),s=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);i.attr("aria-haspopup","true").prepend(s),t.attr("aria-labelledby",i.attr("id"))}),t=a.add(this.element),i=t.find(this.options.items),i.not(".ui-menu-item").each(function(){var t=e(this);s._isDivider(t)&&t.addClass("ui-widget-content ui-menu-divider")}),i.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){"icons"===e&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},focus:function(e,t){var i,s;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&e&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,n=t.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=t.outerHeight(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active}))},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(t){return!e(t.target).closest(".ui-menu").length},_isDivider:function(e){return!/[^\-\u2014\u2013\s]/.test(e.text())},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[t]()),this.focus(i,s)},nextPage:function(t){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-n}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(t),void 0)},previousPage:function(t){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+n>0}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items).first())),void 0):(this.next(t),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,i)},_filterMenuItems:function(t){var i=t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(e.trim(e(this).text()))})}}),e.widget("ui.autocomplete",{version:"1.11.4",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,void 0;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),void 0):(this._searchTimeout(e),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(e),this._change(e),void 0)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:n})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&e.trim(s).length&&(this.liveRegion.children().hide(),e("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,n){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){n(e)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),i=this.menu.element.is(":visible"),s=e.altKey||e.ctrlKey||e.metaKey||e.shiftKey;(!t||t&&!i&&!s)&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):void 0},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var t=++this.requestIndex;return e.proxy(function(e){t===this.requestIndex&&this.__response(e),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").text(i.label).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[e](t),void 0):(this.search(null,t),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.children().hide(),e("<div>").text(i).appendTo(this.liveRegion))}}),e.ui.autocomplete;var c,p="ui-button ui-widget ui-state-default ui-corner-all",f="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",m=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},g=function(t){var i=t.name,s=t.form,n=e([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?e(s).find("[name='"+i+"'][type=radio]"):e("[name='"+i+"'][type=radio]",t.ownerDocument).filter(function(){return!this.form})),n};e.widget("ui.button",{version:"1.11.4",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,m),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,i=this.options,s="checkbox"===this.type||"radio"===this.type,n=s?"":"ui-state-active";null===i.label&&(i.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(p).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){i.disabled||this===c&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){i.disabled||e(this).removeClass(n)}).bind("click"+this.eventNamespace,function(e){i.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),s&&this.element.bind("change"+this.eventNamespace,function(){t.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return i.disabled?!1:void 0}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(i.disabled)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var s=t.element[0];g(s).not(s).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return i.disabled?!1:(e(this).addClass("ui-state-active"),c=this,t.document.one("mouseup",function(){c=null}),void 0)}).bind("mouseup"+this.eventNamespace,function(){return i.disabled?!1:(e(this).removeClass("ui-state-active"),void 0)}).bind("keydown"+this.eventNamespace,function(t){return i.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),void 0)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",i.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(p+" ui-state-active "+f).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),t&&("checkbox"===this.type||"radio"===this.type?this.buttonElement.removeClass("ui-state-focus"):this.buttonElement.removeClass("ui-state-focus ui-state-active")),void 0):(this._resetButton(),void 0)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?g(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),void 0;var t=this.buttonElement.removeClass(f),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,a=[];s.primary||s.secondary?(this.options.text&&a.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(a.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):a.push("ui-button-text-only"),t.addClass(a.join(" "))}}),e.widget("ui.buttonset",{version:"1.11.4",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction"),i=this.element.find(this.options.items),s=i.filter(":ui-button");i.not(":ui-button").button(),s.button("refresh"),this.buttons=i.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}}),e.ui.button,e.extend(e.ui,{datepicker:{version:"1.11.4"}});var v;e.extend(n.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return r(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var s,n,a;s=t.nodeName.toLowerCase(),n="div"===s||"span"===s,t.id||(this.uuid+=1,t.id="dp"+this.uuid),a=this._newInst(e(t),n),a.settings=e.extend({},i||{}),"input"===s?this._connectDatepicker(t,a):n&&this._inlineDatepicker(t,a)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?a(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var s=e(t);i.append=e([]),i.trigger=e([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,"datepicker",i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var s,n,a,o=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),o&&(i.append=e("<span class='"+this._appendClass+"'>"+o+"</span>"),t[r?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&t.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),a=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:a,alt:n,title:n}):e("<button type='button'></button>").addClass(this._triggerClass).html(a?e("<img/>").attr({src:a,alt:n,title:n}):n)),t[r?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,s,n,a=new Date(2009,11,20),o=this._get(e,"dateFormat");o.match(/[DM]/)&&(t=function(e){for(i=0,s=0,n=0;e.length>n;n++)e[n].length>i&&(i=e[n].length,s=n);return s},a.setMonth(t(this._get(e,o.match(/MM/)?"monthNames":"monthNamesShort"))),a.setDate(t(this._get(e,o.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())),e.input.attr("size",this._formatDate(e,a).length)}},_inlineDatepicker:function(t,i){var s=e(t);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),e.data(t,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,s,n,a){var o,h,l,u,d,c=this._dialogInst;return c||(this.uuid+=1,o="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+o+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),c=this._dialogInst=this._newInst(this._dialogInput,!1),c.settings={},e.data(this._dialogInput[0],"datepicker",c)),r(c.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(c,i):i,this._dialogInput.val(i),this._pos=a?a.length?a:[a.pageX,a.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+u,l/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),c.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],"datepicker",c),this},_destroyDatepicker:function(t){var i,s=e(t),n=e.data(t,"datepicker");s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),v===n&&(v=null))},_enableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,a.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,a.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(t,i,s){var n,a,o,h,l=this._getInst(t);return 2===arguments.length&&"string"==typeof i?"defaults"===i?e.extend({},e.datepicker._defaults):l?"all"===i?e.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),a=this._getDateDatepicker(t,!0),o=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),r(l.settings,n),null!==o&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,o)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(t):this._enableDatepicker(t)),this._attachments(e(t),l),this._autoSize(l),this._setDate(l,a),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,s,n,a=e.datepicker._getInst(t.target),o=!0,r=a.dpDiv.is(".ui-datepicker-rtl");if(a._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),o=!1;break;case 13:return n=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",a.dpDiv),n[0]&&e.datepicker._selectDay(t.target,a.selectedMonth,a.selectedYear,n[0]),i=e.datepicker._get(a,"onSelect"),i?(s=e.datepicker._formatDate(a),i.apply(a.input?a.input[0]:null,[s,a])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),o=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),o=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?1:-1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),o=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?-1:1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),o=t.ctrlKey||t.metaKey;break;default:o=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):o=!1;o&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(t){var i,s,n=e.datepicker._getInst(t.target);
return e.datepicker._get(n,"constrainInput")?(i=e.datepicker._possibleChars(e.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==t.charCode?t.keyCode:t.charCode),t.ctrlKey||t.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(t){var i,s=e.datepicker._getInst(t.target);if(s.input.val()!==s.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,e.datepicker._getFormatConfig(s)),i&&(e.datepicker._setDateFromField(s),e.datepicker._updateAlternate(s),e.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,n,a,o,h,l,u;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),n=e.datepicker._get(i,"beforeShow"),a=n?n.apply(t,[t,i]):{},a!==!1&&(r(i.settings,a),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),o=!1,e(t).parents().each(function(){return o|="fixed"===e(this).css("position"),!o}),h={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),h=e.datepicker._checkOffset(i,h,o),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":o?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),i.inline||(l=e.datepicker._get(i,"showAnim"),u=e.datepicker._get(i,"duration"),i.dpDiv.css("z-index",s(e(t))+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[l]?i.dpDiv.show(l,e.datepicker._get(i,"showOptions"),u):i.dpDiv[l||"show"](l?u:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,v=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t);var i,s=this._getNumberOfMonths(t),n=s[1],a=17,r=t.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&t.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),t.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,s){var n=t.dpDiv.outerWidth(),a=t.dpDiv.outerHeight(),o=t.input?t.input.outerWidth():0,r=t.input?t.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:e(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?n-o:0,i.left-=s&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=s&&i.top===t.input.offset().top+r?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+a>l&&l>a?Math.abs(a+r):0),i},_findPos:function(t){for(var i,s=this._getInst(t),n=this._get(s,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[n?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,s,n,a,o=this._curInst;!o||t&&o!==e.data(t,"datepicker")||this._datepickerShowing&&(i=this._get(o,"showAnim"),s=this._get(o,"duration"),n=function(){e.datepicker._tidyDialog(o)},e.effects&&(e.effects.effect[i]||e.effects[i])?o.dpDiv.hide(i,e.datepicker._get(o,"showOptions"),s,n):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,a=this._get(o,"onClose"),a&&a.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),s=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==s)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,s){var n=e(t),a=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(a,i+("M"===s?this._get(a,"showCurrentAtPos"):0),s),this._updateDatepicker(a))},_gotoToday:function(t){var i,s=e(t),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(t,i,s){var n=e(t),a=this._getInst(n[0]);a["selected"+("M"===s?"Month":"Year")]=a["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(a),this._adjustDate(n)},_selectDay:function(t,i,s,n){var a,o=e(t);e(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0])||(a=this._getInst(o[0]),a.selectedDay=a.currentDay=e("a",n).html(),a.selectedMonth=a.currentMonth=i,a.selectedYear=a.currentYear=s,this._selectDate(t,this._formatDate(a,a.currentDay,a.currentMonth,a.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var s,n=e(t),a=this._getInst(n[0]);i=null!=i?i:this._formatDate(a),a.input&&a.input.val(i),this._updateAlternate(a),s=this._get(a,"onSelect"),s?s.apply(a.input?a.input[0]:null,[i,a]):a.input&&a.input.trigger("change"),a.inline?this._updateDatepicker(a):(this._hideDatepicker(),this._lastInput=a.input[0],"object"!=typeof a.input[0]&&a.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,s,n,a=this._get(t,"altField");a&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),s=this._getDate(t),n=this.formatDate(i,s,this._getFormatConfig(t)),e(a).each(function(){e(this).val(n)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(t,i,s){if(null==t||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,a,o,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),d=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,c=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,m=-1,g=-1,v=-1,y=-1,b=!1,_=function(e){var i=t.length>n+1&&t.charAt(n+1)===e;return i&&n++,i},x=function(e){var t=_(e),s="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,n="y"===e?s:1,a=RegExp("^\\d{"+n+","+s+"}"),o=i.substring(h).match(a);if(!o)throw"Missing number at position "+h;return h+=o[0].length,parseInt(o[0],10)},w=function(t,s,n){var a=-1,o=e.map(_(t)?n:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(o,function(e,t){var s=t[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(a=t[0],h+=s.length,!1):void 0}),-1!==a)return a+1;throw"Unknown name at position "+h},k=function(){if(i.charAt(h)!==t.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;t.length>n;n++)if(b)"'"!==t.charAt(n)||_("'")?k():b=!1;else switch(t.charAt(n)){case"d":v=x("d");break;case"D":w("D",d,c);break;case"o":y=x("o");break;case"m":g=x("m");break;case"M":g=w("M",p,f);break;case"y":m=x("y");break;case"@":r=new Date(x("@")),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"!":r=new Date((x("!")-this._ticksTo1970)/1e4),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"'":_("'")?k():b=!0;break;default:k()}if(i.length>h&&(o=i.substr(h),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),y>-1)for(g=1,v=y;;){if(a=this._getDaysInMonth(m,g-1),a>=v)break;g++,v-=a}if(r=this._daylightSavingAdjust(new Date(m,g-1,v)),r.getFullYear()!==m||r.getMonth()+1!==g||r.getDate()!==v)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,a=(i?i.dayNames:null)||this._defaults.dayNames,o=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(t){var i=e.length>s+1&&e.charAt(s+1)===t;return i&&s++,i},l=function(e,t,i){var s=""+t;if(h(e))for(;i>s.length;)s="0"+s;return s},u=function(e,t,i,s){return h(e)?s[t]:i[t]},d="",c=!1;if(t)for(s=0;e.length>s;s++)if(c)"'"!==e.charAt(s)||h("'")?d+=e.charAt(s):c=!1;else switch(e.charAt(s)){case"d":d+=l("d",t.getDate(),2);break;case"D":d+=u("D",t.getDay(),n,a);break;case"o":d+=l("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":d+=l("m",t.getMonth()+1,2);break;case"M":d+=u("M",t.getMonth(),o,r);break;case"y":d+=h("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":d+=t.getTime();break;case"!":d+=1e4*t.getTime()+this._ticksTo1970;break;case"'":h("'")?d+="'":c=!0;break;default:d+=e.charAt(s)}return d},_possibleChars:function(e){var t,i="",s=!1,n=function(i){var s=e.length>t+1&&e.charAt(t+1)===i;return s&&t++,s};for(t=0;e.length>t;t++)if(s)"'"!==e.charAt(t)||n("'")?i+=e.charAt(t):s=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,t){return void 0!==e.settings[t]?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),s=e.lastVal=e.input?e.input.val():null,n=this._getDefaultDate(e),a=n,o=this._getFormatConfig(e);try{a=this.parseDate(i,s,o)||n}catch(r){s=t?"":s}e.selectedDay=a.getDate(),e.drawMonth=e.selectedMonth=a.getMonth(),e.drawYear=e.selectedYear=a.getFullYear(),e.currentDay=s?a.getDate():0,e.currentMonth=s?a.getMonth():0,e.currentYear=s?a.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,s){var n=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},a=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,a=n.getFullYear(),o=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":o+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o));break;case"y":case"Y":a+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o))}l=h.exec(i)}return new Date(a,o,r)},o=null==i||""===i?s:"string"==typeof i?a(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return o=o&&"Invalid Date"==""+o?s:o,o&&(o.setHours(0),o.setMinutes(0),o.setSeconds(0),o.setMilliseconds(0)),this._daylightSavingAdjust(o)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var s=!t,n=e.selectedMonth,a=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),n===e.selectedMonth&&a===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(s?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),s="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(s,-i,"M")},next:function(){e.datepicker._adjustDate(s,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(s)},selectDay:function(){return e.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(s,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,s,n,a,o,r,h,l,u,d,c,p,f,m,g,v,y,b,_,x,w,k,T,D,S,M,C,N,A,P,I,H,z,F,E,O,j,W,L=new Date,R=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(e,"isRTL"),B=this._get(e,"showButtonPanel"),J=this._get(e,"hideIfNoPrevNext"),q=this._get(e,"navigationAsDateFormat"),K=this._getNumberOfMonths(e),V=this._get(e,"showCurrentAtPos"),U=this._get(e,"stepMonths"),Q=1!==K[0]||1!==K[1],G=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),X=this._getMinMaxDate(e,"min"),$=this._getMinMaxDate(e,"max"),Z=e.drawMonth-V,et=e.drawYear;if(0>Z&&(Z+=12,et--),$)for(t=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-K[0]*K[1]+1,$.getDate())),t=X&&X>t?X:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=q?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-U,1)),this._getFormatConfig(e)):i,s=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":J?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(e,"nextText"),n=q?this.formatDate(n,this._daylightSavingAdjust(new Date(et,Z+U,1)),this._getFormatConfig(e)):n,a=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":J?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",o=this._get(e,"currentText"),r=this._get(e,"gotoCurrent")&&e.currentDay?G:R,o=q?this.formatDate(o,r,this._getFormatConfig(e)):o,h=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(e,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+o+"</button>":"")+(Y?"":h)+"</div>":"",u=parseInt(this._get(e,"firstDay"),10),u=isNaN(u)?0:u,d=this._get(e,"showWeek"),c=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),f=this._get(e,"monthNames"),m=this._get(e,"monthNamesShort"),g=this._get(e,"beforeShowDay"),v=this._get(e,"showOtherMonths"),y=this._get(e,"selectOtherMonths"),b=this._getDefaultDate(e),_="",w=0;K[0]>w;w++){for(k="",this.maxRows=4,T=0;K[1]>T;T++){if(D=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),S=" ui-corner-all",M="",Q){if(M+="<div class='ui-datepicker-group",K[1]>1)switch(T){case 0:M+=" ui-datepicker-group-first",S=" ui-corner-"+(Y?"right":"left");break;case K[1]-1:M+=" ui-datepicker-group-last",S=" ui-corner-"+(Y?"left":"right");break;default:M+=" ui-datepicker-group-middle",S=""}M+="'>"}for(M+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+S+"'>"+(/all|left/.test(S)&&0===w?Y?a:s:"")+(/all|right/.test(S)&&0===w?Y?s:a:"")+this._generateMonthYearHeader(e,Z,et,X,$,w>0||T>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",C=d?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",x=0;7>x;x++)N=(x+u)%7,C+="<th scope='col'"+((x+u+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+c[N]+"'>"+p[N]+"</span></th>";for(M+=C+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),P=(this._getFirstDayOfMonth(et,Z)-u+7)%7,I=Math.ceil((P+A)/7),H=Q?this.maxRows>I?this.maxRows:I:I,this.maxRows=H,z=this._daylightSavingAdjust(new Date(et,Z,1-P)),F=0;H>F;F++){for(M+="<tr>",E=d?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(z)+"</td>":"",x=0;7>x;x++)O=g?g.apply(e.input?e.input[0]:null,[z]):[!0,""],j=z.getMonth()!==Z,W=j&&!y||!O[0]||X&&X>z||$&&z>$,E+="<td class='"+((x+u+6)%7>=5?" ui-datepicker-week-end":"")+(j?" ui-datepicker-other-month":"")+(z.getTime()===D.getTime()&&Z===e.selectedMonth&&e._keyEvent||b.getTime()===z.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(W?" "+this._unselectableClass+" ui-state-disabled":"")+(j&&!v?"":" "+O[1]+(z.getTime()===G.getTime()?" "+this._currentClass:"")+(z.getTime()===R.getTime()?" ui-datepicker-today":""))+"'"+(j&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(W?"":" data-handler='selectDay' data-event='click' data-month='"+z.getMonth()+"' data-year='"+z.getFullYear()+"'")+">"+(j&&!v?"&#xa0;":W?"<span class='ui-state-default'>"+z.getDate()+"</span>":"<a class='ui-state-default"+(z.getTime()===R.getTime()?" ui-state-highlight":"")+(z.getTime()===G.getTime()?" ui-state-active":"")+(j?" ui-priority-secondary":"")+"' href='#'>"+z.getDate()+"</a>")+"</td>",z.setDate(z.getDate()+1),z=this._daylightSavingAdjust(z);M+=E+"</tr>"}Z++,Z>11&&(Z=0,et++),M+="</tbody></table>"+(Q?"</div>"+(K[0]>0&&T===K[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),k+=M}_+=k}return _+=l,e._keyEvent=!1,_},_generateMonthYearHeader:function(e,t,i,s,n,a,o,r){var h,l,u,d,c,p,f,m,g=this._get(e,"changeMonth"),v=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",_="";if(a||!g)_+="<span class='ui-datepicker-month'>"+o[t]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,_+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",u=0;12>u;u++)(!h||u>=s.getMonth())&&(!l||n.getMonth()>=u)&&(_+="<option value='"+u+"'"+(u===t?" selected='selected'":"")+">"+r[u]+"</option>");_+="</select>"}if(y||(b+=_+(!a&&g&&v?"":"&#xa0;")),!e.yearshtml)if(e.yearshtml="",a||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(d=this._get(e,"yearRange").split(":"),c=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?c+parseInt(e,10):parseInt(e,10);return isNaN(t)?c:t},f=p(d[0]),m=Math.max(f,p(d[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=n?Math.min(m,n.getFullYear()):m,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)e.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";e.yearshtml+="</select>",b+=e.yearshtml,e.yearshtml=null}return b+=this._get(e,"yearSuffix"),y&&(b+=(!a&&g&&v?"":"&#xa0;")+_),b+="</div>"},_adjustInstDate:function(e,t,i){var s=e.drawYear+("Y"===i?t:0),n=e.drawMonth+("M"===i?t:0),a=Math.min(e.selectedDay,this._getDaysInMonth(s,n))+("D"===i?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(s,n,a)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),s=this._getMinMaxDate(e,"max"),n=i&&i>t?i:t;return s&&n>s?s:n},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,s){var n=this._getNumberOfMonths(e),a=this._daylightSavingAdjust(new Date(i,s+(0>t?t:n[0]*n[1]),1));return 0>t&&a.setDate(this._getDaysInMonth(a.getFullYear(),a.getMonth())),this._isInRange(e,a)},_isInRange:function(e,t){var i,s,n=this._getMinMaxDate(e,"min"),a=this._getMinMaxDate(e,"max"),o=null,r=null,h=this._get(e,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),o=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(o+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||t.getTime()>=n.getTime())&&(!a||t.getTime()<=a.getTime())&&(!o||t.getFullYear()>=o)&&(!r||r>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,s){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var n=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(s,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),n,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new n,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.11.4",e.datepicker,e.widget("ui.draggable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(t){var i=this.options;return this._blurActiveElement(t),this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=e(this);return e("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var i=this.document[0];if(this.handleElement.is(t.target))try{i.activeElement&&"body"!==i.activeElement.nodeName.toLowerCase()&&e(i.activeElement).blur()}catch(s){}},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===e(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._normalizeRightBottom(),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(e){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:e.pageX-this.offset.left,top:e.pageY-this.offset.top}},_mouseDrag:function(t,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper),n=s?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options,a=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,e(a).width()-this.helperProportions.width-this.margins.left,(e(a).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=e(n.containment),s=i[0],s&&(t=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)
},_convertPositionTo:function(e,t){t||(t=this.position);var i="absolute"===e?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:t.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(e,t){var i,s,n,a,o=this.options,r=this._isRootNode(this.scrollParent[0]),h=e.pageX,l=e.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,h=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a),"y"===o.axis&&(h=this.originalPageX),"x"===o.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i,s){var n=e.extend({},i,{item:s.element});s.sortables=[],e(s.options.connectToSortable).each(function(){var i=e(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i,s){var n=e.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,e.each(s.sortables,function(){var e=this;e.isOver?(e.isOver=0,s.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,n))})},drag:function(t,i,s){e.each(s.sortables,function(){var n=!1,a=this;a.positionAbs=s.positionAbs,a.helperProportions=s.helperProportions,a.offset.click=s.offset.click,a._intersectsWith(a.containerCache)&&(n=!0,e.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==a&&this._intersectsWith(this.containerCache)&&e.contains(a.element[0],this.element[0])&&(n=!1),n})),n?(a.isOver||(a.isOver=1,s._parent=i.helper.parent(),a.currentItem=i.helper.appendTo(a.element).data("ui-sortable-item",!0),a.options._helper=a.options.helper,a.options.helper=function(){return i.helper[0]},t.target=a.currentItem[0],a._mouseCapture(t,!0),a._mouseStart(t,!0,!0),a.offset.click.top=s.offset.click.top,a.offset.click.left=s.offset.click.left,a.offset.parent.left-=s.offset.parent.left-a.offset.parent.left,a.offset.parent.top-=s.offset.parent.top-a.offset.parent.top,s._trigger("toSortable",t),s.dropped=a.element,e.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,a.fromOutside=s),a.currentItem&&(a._mouseDrag(t),i.position=a.position)):a.isOver&&(a.isOver=0,a.cancelHelperRemoval=!0,a.options._revert=a.options.revert,a.options.revert=!1,a._trigger("out",t,a._uiHash(a)),a._mouseStop(t,!0),a.options.revert=a.options._revert,a.options.helper=a.options._helper,a.placeholder&&a.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(t),i.position=s._generatePosition(t,!0),s._trigger("fromSortable",t),s.dropped=!1,e.each(s.sortables,function(){this.refreshPositions()}))})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,i,s){var n=e("body"),a=s.options;n.css("cursor")&&(a._cursor=n.css("cursor")),n.css("cursor",a.cursor)},stop:function(t,i,s){var n=s.options;n._cursor&&e("body").css("cursor",n._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("opacity")&&(a._opacity=n.css("opacity")),n.css("opacity",a.opacity)},stop:function(t,i,s){var n=s.options;n._opacity&&e(i.helper).css("opacity",n._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,i,s){var n=s.options,a=!1,o=s.scrollParentNotHidden[0],r=s.document[0];o!==r&&"HTML"!==o.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+o.offsetHeight-t.pageY<n.scrollSensitivity?o.scrollTop=a=o.scrollTop+n.scrollSpeed:t.pageY-s.overflowOffset.top<n.scrollSensitivity&&(o.scrollTop=a=o.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+o.offsetWidth-t.pageX<n.scrollSensitivity?o.scrollLeft=a=o.scrollLeft+n.scrollSpeed:t.pageX-s.overflowOffset.left<n.scrollSensitivity&&(o.scrollLeft=a=o.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(t.pageY-e(r).scrollTop()<n.scrollSensitivity?a=e(r).scrollTop(e(r).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(r).scrollTop())<n.scrollSensitivity&&(a=e(r).scrollTop(e(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(t.pageX-e(r).scrollLeft()<n.scrollSensitivity?a=e(r).scrollLeft(e(r).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(r).scrollLeft())<n.scrollSensitivity&&(a=e(r).scrollLeft(e(r).scrollLeft()+n.scrollSpeed)))),a!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(s,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,i,s){var n=s.options;s.snapElements=[],e(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var t=e(this),i=t.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:i.top,left:i.left})})},drag:function(t,i,s){var n,a,o,r,h,l,u,d,c,p,f=s.options,m=f.snapTolerance,g=i.offset.left,v=g+s.helperProportions.width,y=i.offset.top,b=y+s.helperProportions.height;for(c=s.snapElements.length-1;c>=0;c--)h=s.snapElements[c].left-s.margins.left,l=h+s.snapElements[c].width,u=s.snapElements[c].top-s.margins.top,d=u+s.snapElements[c].height,h-m>v||g>l+m||u-m>b||y>d+m||!e.contains(s.snapElements[c].item.ownerDocument,s.snapElements[c].item)?(s.snapElements[c].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(n=m>=Math.abs(u-b),a=m>=Math.abs(d-y),o=m>=Math.abs(h-v),r=m>=Math.abs(l-g),n&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||a||o||r,"outer"!==f.snapMode&&(n=m>=Math.abs(u-y),a=m>=Math.abs(d-b),o=m>=Math.abs(h-g),r=m>=Math.abs(l-v),n&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d-s.helperProportions.height,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[c].snapping&&(n||a||o||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=n||a||o||r||p)}}),e.ui.plugin.add("draggable","stack",{start:function(t,i,s){var n,a=s.options,o=e.makeArray(e(a.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});o.length&&(n=parseInt(e(o[0]).css("zIndex"),10)||0,e(o).each(function(t){e(this).css("zIndex",n+t)}),this.css("zIndex",n+o.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("zIndex")&&(a._zIndex=n.css("zIndex")),n.css("zIndex",a.zIndex)},stop:function(t,i,s){var n=s.options;n._zIndex&&e(i.helper).css("zIndex",n._zIndex)}}),e.ui.draggable,e.widget("ui.resizable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(e){return parseInt(e,10)||0},_isNumber:function(e){return!isNaN(parseInt(e,10))},_hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return t[s]>0?!0:(t[s]=1,n=t[s]>0,t[s]=0,n)},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=e(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("<div class='ui-resizable-handle "+a+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=e(this.handles[i]),this._on(this.handles[i],{mousedown:o._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var i,s,n,a=this.options,o=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),a.containment&&(i+=e(a.containment).scrollLeft()||0,s+=e(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:o.width(),height:o.height()},this.originalSize=this._helper?{width:o.outerWidth(),height:o.outerHeight()}:{width:o.width(),height:o.height()},this.sizeDiff={width:o.outerWidth()-o.width(),height:o.outerHeight()-o.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===n?this.axis+"-resize":n),o.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var i,s,n=this.originalMousePosition,a=this.axis,o=t.pageX-n.left||0,r=t.pageY-n.top||0,h=this._change[a];return this._updatePrevProperties(),h?(i=h.apply(this,[t,o,r]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var e={};return this.position.top!==this.prevPosition.top&&(e.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(e.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(e.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(e.height=this.size.height+"px"),this.helper.css(e),e},_updateVirtualBoundaries:function(e){var t,i,s,n,a,o=this.options;a={minWidth:this._isNumber(o.minWidth)?o.minWidth:0,maxWidth:this._isNumber(o.maxWidth)?o.maxWidth:1/0,minHeight:this._isNumber(o.minHeight)?o.minHeight:0,maxHeight:this._isNumber(o.maxHeight)?o.maxHeight:1/0},(this._aspectRatio||e)&&(t=a.minHeight*this.aspectRatio,s=a.minWidth/this.aspectRatio,i=a.maxHeight*this.aspectRatio,n=a.maxWidth/this.aspectRatio,t>a.minWidth&&(a.minWidth=t),s>a.minHeight&&(a.minHeight=s),a.maxWidth>i&&(a.maxWidth=i),a.maxHeight>n&&(a.maxHeight=n)),this._vBoundaries=a},_updateCache:function(e){this.offset=this.helper.offset(),this._isNumber(e.left)&&(this.position.left=e.left),this._isNumber(e.top)&&(this.position.top=e.top),this._isNumber(e.height)&&(this.size.height=e.height),this._isNumber(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,i=this.size,s=this.axis;return this._isNumber(e.height)?e.width=e.height*this.aspectRatio:this._isNumber(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===s&&(e.left=t.left+(i.width-e.width),e.top=null),"nw"===s&&(e.top=t.top+(i.height-e.height),e.left=t.left+(i.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,i=this.axis,s=this._isNumber(e.width)&&t.maxWidth&&t.maxWidth<e.width,n=this._isNumber(e.height)&&t.maxHeight&&t.maxHeight<e.height,a=this._isNumber(e.width)&&t.minWidth&&t.minWidth>e.width,o=this._isNumber(e.height)&&t.minHeight&&t.minHeight>e.height,r=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,l=/sw|nw|w/.test(i),u=/nw|ne|n/.test(i);return a&&(e.width=t.minWidth),o&&(e.height=t.minHeight),s&&(e.width=t.maxWidth),n&&(e.height=t.maxHeight),a&&l&&(e.left=r-t.minWidth),s&&l&&(e.left=r-t.maxWidth),o&&u&&(e.top=h-t.minHeight),n&&u&&(e.top=h-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_getPaddingPlusBorderDimensions:function(e){for(var t=0,i=[],s=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],n=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];4>t;t++)i[t]=parseInt(s[t],10)||0,i[t]+=parseInt(n[t],10)||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e,t=0,i=this.helper||this.element;this._proportionallyResizeElements.length>t;t++)e=this._proportionallyResizeElements[t],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(e)),e.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,i,s,n,a,o,r,h=e(this).resizable("instance"),l=h.options,u=h.element,d=l.containment,c=d instanceof e?d.get(0):/parent/.test(d)?u.parent().get(0):d;c&&(h.containerElement=e(c),/document/.test(d)||d===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(c),i=[],e(["Top","Right","Left","Bottom"]).each(function(e,s){i[e]=h._num(t.css("padding"+s))}),h.containerOffset=t.offset(),h.containerPosition=t.position(),h.containerSize={height:t.innerHeight()-i[3],width:t.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,a=h.containerSize.width,o=h._hasScroll(c,"left")?c.scrollWidth:a,r=h._hasScroll(c)?c.scrollHeight:n,h.parentData={element:c,left:s.left,top:s.top,width:o,height:r}))},resize:function(t){var i,s,n,a,o=e(this).resizable("instance"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,d={top:0,left:0},c=o.containerElement,p=!0;c[0]!==document&&/static/.test(c.css("position"))&&(d=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-d.left),u&&(o.size.height=o.size.width/o.aspectRatio,p=!1),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio,p=!1),o.position.top=o._helper?h.top:0),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a?(o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top):(o.offset.left=o.element.offset().left,o.offset.top=o.element.offset().top),i=Math.abs(o.sizeDiff.width+(o._helper?o.offset.left-d.left:o.offset.left-h.left)),s=Math.abs(o.sizeDiff.height+(o._helper?o.offset.top-d.top:o.offset.top-h.top)),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio,p=!1)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio,p=!1)),p||(o.position.left=o.prevPosition.left,o.position.top=o.prevPosition.top,o.size.width=o.prevSize.width,o.size.height=o.prevSize.height)},stop:function(){var t=e(this).resizable("instance"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).resizable("instance"),i=t.options;e(i.alsoResize).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})},resize:function(t,i){var s=e(this).resizable("instance"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0};e(n.alsoResize).each(function(){var t=e(this),s=e(this).data("ui-resizable-alsoresize"),n={},a=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(a,function(e,t){var i=(s[t]||0)+(r[t]||0);i&&i>=0&&(n[t]=i||null)}),t.css(n)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t,i=e(this).resizable("instance"),s=i.options,n=i.size,a=i.originalSize,o=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,u=h[1]||1,d=Math.round((n.width-a.width)/l)*l,c=Math.round((n.height-a.height)/u)*u,p=a.width+d,f=a.height+c,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,v=s.minWidth&&s.minWidth>p,y=s.minHeight&&s.minHeight>f;s.grid=h,v&&(p+=l),y&&(f+=u),m&&(p-=l),g&&(f-=u),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=o.top-c):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=o.left-d):((0>=f-u||0>=p-l)&&(t=i._getPaddingPlusBorderDimensions(this)),f-u>0?(i.size.height=f,i.position.top=o.top-c):(f=u-t.height,i.size.height=f,i.position.top=o.top+a.height-f),p-l>0?(i.size.width=p,i.position.left=o.left-d):(p=l-t.width,i.size.width=p,i.position.left=o.left+a.width-p))}}),e.ui.resizable,e.widget("ui.dialog",{version:"1.11.4",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i,s=this;if(this._isOpen&&this._trigger("beforeClose",t)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&e(i).blur()}catch(n){}this._hide(this.uiDialog,this.options.hide,function(){s._trigger("close",t)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+e(this).css("z-index")}).get(),a=Math.max.apply(null,n);return a>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",a+1),s=!0),s&&!i&&this._trigger("focus",t),s},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var e=this._focusedElement;e||(e=this.element.find("[autofocus]")),e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),void 0;
if(t.keyCode===e.ui.keyCode.TAB&&!t.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");t.target!==n[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==s[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){n.focus()}),t.preventDefault()):(this._delay(function(){s.focus()}),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html("&#160;"),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),void 0):(e.each(i,function(i,s){var n,a;s=e.isFunction(s)?{click:s,text:i}:s,s=e.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(t.element[0],arguments)},a={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,e("<button></button>",s).button(a).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,t(n))},drag:function(e,s){i._trigger("drag",e,t(s))},stop:function(n,a){var o=a.offset.left-i.document.scrollLeft(),r=a.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(o>=0?"+":"")+o+" "+"top"+(r>=0?"+":"")+r,of:i.window},e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,t(a))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,s=this.options,n=s.resizable,a=this.uiDialog.css("position"),o="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:o,start:function(s,n){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,t(n))},resize:function(e,s){i._trigger("resize",e,t(s))},stop:function(n,a){var o=i.uiDialog.offset(),r=o.left-i.document.scrollLeft(),h=o.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,t(a))}}).css("position",a)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=e(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),i=e.inArray(this,t);-1!==i&&t.splice(i,1)},_trackingInstances:function(){var e=this.document.data("ui-dialog-instances");return e||(e=[],this.document.data("ui-dialog-instances",e)),e},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};e.each(t,function(e,t){i._setOption(e,t),e in i.sizeRelatedOptions&&(s=!0),e in i.resizableRelatedOptions&&(n[e]=t)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,t){var i,s,n=this.uiDialog;"dialogClass"===e&&n.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=n.is(":data(ui-draggable)"),i&&!t&&n.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(s=n.is(":data(ui-resizable)"),s&&!t&&n.resizable("destroy"),s&&"string"==typeof t&&n.resizable("option","handles",t),s||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),e=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),t=Math.max(0,s.minHeight-e),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-e):"none","auto"===s.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=!0;this._delay(function(){t=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(e){t||this._allowInteraction(e)||(e.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var e=this.document.data("ui-dialog-overlays")-1;e?this.document.data("ui-dialog-overlays",e):this.document.unbind("focusin").removeData("ui-dialog-overlays"),this.overlay.remove(),this.overlay=null}}}),e.widget("ui.droppable",{version:"1.11.4",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(s)?s:function(e){return e.is(s)},this.proportions=function(){return arguments.length?(t=arguments[0],void 0):t?t:t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(t){e.ui.ddmanager.droppables[t]=e.ui.ddmanager.droppables[t]||[],e.ui.ddmanager.droppables[t].push(this)},_splice:function(e){for(var t=0;e.length>t;t++)e[t]===this&&e.splice(t,1)},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];this._splice(t),this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){if("accept"===t)this.accept=e.isFunction(i)?i:function(e){return e.is(i)};else if("scope"===t){var s=e.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(t,i)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=e(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(i,{offset:i.element.offset()}),i.options.tolerance,t)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(){function e(e,t,i){return e>=t&&t+i>e}return function(t,i,s,n){if(!i.offset)return!1;var a=(t.positionAbs||t.position.absolute).left+t.margins.left,o=(t.positionAbs||t.position.absolute).top+t.margins.top,r=a+t.helperProportions.width,h=o+t.helperProportions.height,l=i.offset.left,u=i.offset.top,d=l+i.proportions().width,c=u+i.proportions().height;switch(s){case"fit":return a>=l&&d>=r&&o>=u&&c>=h;case"intersect":return a+t.helperProportions.width/2>l&&d>r-t.helperProportions.width/2&&o+t.helperProportions.height/2>u&&c>h-t.helperProportions.height/2;case"pointer":return e(n.pageY,u,i.proportions().height)&&e(n.pageX,l,i.proportions().width);case"touch":return(o>=u&&c>=o||h>=u&&c>=h||u>o&&h>c)&&(a>=l&&d>=a||r>=l&&d>=r||l>a&&r>d);default:return!1}}}(),e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,n,a=e.ui.ddmanager.droppables[t.options.scope]||[],o=i?i.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||t&&!a[s].accept.call(a[s].element[0],t.currentItem||t.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions().height=0;continue e}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions({width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight}))}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=e.ui.intersect(t,this,this.options.tolerance,i),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return e(this).droppable("instance").options.scope===n}),a.length&&(s=e(a[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}},e.ui.droppable;var y="ui-effects-",b=e;e.effects={effect:{}},function(e,t){function i(e,t,i){var s=d[t.type]||{};return null==e?i||!t.def?null:t.def:(e=s.floor?~~e:parseFloat(e),isNaN(e)?t.def:s.mod?(e+s.mod)%s.mod:0>e?0:e>s.max?s.max:e)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(e,a){var o,r=a.re.exec(i),h=r&&a.parse(r),l=a.space||"rgba";return h?(o=s[l](h),s[u[l].cache]=o[u[l].cache],n=s._rgba=o._rgba,!1):t}),n.length?("0,0,0,0"===n.join()&&e.extend(n,a.transparent),s):a[i]}function n(e,t,i){return i=(i+1)%1,1>6*i?e+6*(t-e)*i:1>2*i?t:2>3*i?e+6*(t-e)*(2/3-i):e}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[2.55*e[1],2.55*e[2],2.55*e[3],e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],l=e.Color=function(t,i,s,n){return new e.Color.fn.parse(t,i,s,n)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},d={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},c=l.support={},p=e("<p>")[0],f=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",c.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(n,o,r,h){if(n===t)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=e(n).css(o),o=t);var d=this,c=e.type(n),p=this._rgba=[];return o!==t&&(n=[n,o,r,h],c="array"),"string"===c?this.parse(s(n)||a._default):"array"===c?(f(u.rgba.props,function(e,t){p[t.idx]=i(n[t.idx],t)}),this):"object"===c?(n instanceof l?f(u,function(e,t){n[t.cache]&&(d[t.cache]=n[t.cache].slice())}):f(u,function(t,s){var a=s.cache;f(s.props,function(e,t){if(!d[a]&&s.to){if("alpha"===e||null==n[e])return;d[a]=s.to(d._rgba)}d[a][t.idx]=i(n[e],t,!0)}),d[a]&&0>e.inArray(null,d[a].slice(0,3))&&(d[a][3]=1,s.from&&(d._rgba=s.from(d[a])))}),this):t},is:function(e){var i=l(e),s=!0,n=this;return f(u,function(e,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(e,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:t})),s}),s},_space:function(){var e=[],t=this;return f(u,function(i,s){t[s.cache]&&e.push(i)}),e.pop()},transition:function(e,t){var s=l(e),n=s._space(),a=u[n],o=0===this.alpha()?l("transparent"):this,r=o[a.cache]||a.to(o._rgba),h=r.slice();return s=s[a.cache],f(a.props,function(e,n){var a=n.idx,o=r[a],l=s[a],u=d[n.type]||{};null!==l&&(null===o?h[a]=l:(u.mod&&(l-o>u.mod/2?o+=u.mod:o-l>u.mod/2&&(o-=u.mod)),h[a]=i((l-o)*t+o,n)))}),this[n](h)},blend:function(t){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(t)._rgba;return l(e.map(i,function(e,t){return(1-s)*n[t]+s*e}))},toRgbaString:function(){var t="rgba(",i=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===i[3]&&(i.pop(),t="rgb("),t+i.join()+")"},toHslaString:function(){var t="hsla(",i=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&3>t&&(e=Math.round(100*e)+"%"),e});return 1===i[3]&&(i.pop(),t="hsl("),t+i.join()+")"},toHexString:function(t){var i=this._rgba.slice(),s=i.pop();return t&&i.push(~~(255*s)),"#"+e.map(i,function(e){return e=(e||0).toString(16),1===e.length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,i,s=e[0]/255,n=e[1]/255,a=e[2]/255,o=e[3],r=Math.max(s,n,a),h=Math.min(s,n,a),l=r-h,u=r+h,d=.5*u;return t=h===r?0:s===r?60*(n-a)/l+360:n===r?60*(a-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=d?l/u:l/(2-u),[Math.round(t)%360,i,d,null==o?1:o]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,i=e[1],s=e[2],a=e[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,t+1/3)),Math.round(255*n(r,o,t)),Math.round(255*n(r,o,t-1/3)),a]},f(u,function(s,n){var a=n.props,o=n.cache,h=n.to,u=n.from;l.fn[s]=function(s){if(h&&!this[o]&&(this[o]=h(this._rgba)),s===t)return this[o].slice();var n,r=e.type(s),d="array"===r||"object"===r?s:arguments,c=this[o].slice();return f(a,function(e,t){var s=d["object"===r?e:t.idx];null==s&&(s=c[t.idx]),c[t.idx]=i(s,t)}),u?(n=l(u(c)),n[o]=c,n):l(c)},f(a,function(t,i){l.fn[t]||(l.fn[t]=function(n){var a,o=e.type(n),h="alpha"===t?this._hsla?"hsla":"rgba":s,l=this[h](),u=l[i.idx];return"undefined"===o?u:("function"===o&&(n=n.call(this,u),o=e.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=u+parseFloat(a[2])*("+"===a[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(t){var i=t.split(" ");f(i,function(t,i){e.cssHooks[i]={set:function(t,n){var a,o,r="";if("transparent"!==n&&("string"!==e.type(n)||(a=s(n)))){if(n=l(a||n),!c.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?t.parentNode:t;(""===r||"transparent"===r)&&o&&o.style;)try{r=e.css(o,"backgroundColor"),o=o.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{t.style[i]=n}catch(h){}}},e.fx.step[i]=function(t){t.colorInit||(t.start=l(t.elem,i),t.end=l(t.end),t.colorInit=!0),e.cssHooks[i].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook(o),e.cssHooks.borderColor={expand:function(e){var t={};return f(["Top","Right","Bottom","Left"],function(i,s){t["border"+s+"Color"]=e}),t}},a=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(b),function(){function t(t){var i,s,n=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[e.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function i(t,i){var s,a,o={};for(s in i)a=i[s],t[s]!==a&&(n[s]||(e.fx.step[s]||!isNaN(parseFloat(a)))&&(o[s]=a));return o}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,i){e.fx.step[i]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(b.style(e.elem,i,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(n,a,o,r){var h=e.speed(a,o,r);return this.queue(function(){var a,o=e(this),r=o.attr("class")||"",l=h.children?o.find("*").addBack():o;l=l.map(function(){var i=e(this);return{el:i,start:t(this)}}),a=function(){e.each(s,function(e,t){n[t]&&o[t+"Class"](n[t])})},a(),l=l.map(function(){return this.end=t(this.el[0]),this.diff=i(this.start,this.end),this}),o.attr("class",r),l=l.map(function(){var t=this,i=e.Deferred(),s=e.extend({},h,{queue:!1,complete:function(){i.resolve(t)}});return this.el.animate(this.diff,s),i.promise()}),e.when.apply(e,l.get()).done(function(){a(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),h.complete.call(o[0])})})},e.fn.extend({addClass:function(t){return function(i,s,n,a){return s?e.effects.animateClass.call(this,{add:i},s,n,a):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(i,s,n,a){return arguments.length>1?e.effects.animateClass.call(this,{remove:i},s,n,a):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(t){return function(i,s,n,a,o){return"boolean"==typeof s||void 0===s?n?e.effects.animateClass.call(this,s?{add:i}:{remove:i},n,a,o):t.apply(this,arguments):e.effects.animateClass.call(this,{toggle:i},s,n,a)}}(e.fn.toggleClass),switchClass:function(t,i,s,n,a){return e.effects.animateClass.call(this,{add:i,remove:t},s,n,a)}})}(),function(){function t(t,i,s,n){return e.isPlainObject(t)&&(i=t,t=t.effect),t={effect:t},null==i&&(i={}),e.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||e.fx.speeds[i])&&(n=s,s=i,i={}),e.isFunction(s)&&(n=s,s=null),i&&e.extend(t,i),s=s||i.duration,t.duration=e.fx.off?0:"number"==typeof s?s:s in e.fx.speeds?e.fx.speeds[s]:e.fx.speeds._default,t.complete=n||i.complete,t}function i(t){return!t||"number"==typeof t||e.fx.speeds[t]?!0:"string"!=typeof t||e.effects.effect[t]?e.isFunction(t)?!0:"object"!=typeof t||t.effect?!1:!0:!0}e.extend(e.effects,{version:"1.11.4",save:function(e,t){for(var i=0;t.length>i;i++)null!==t[i]&&e.data(y+t[i],e[0].style[t[i]])},restore:function(e,t){var i,s;for(s=0;t.length>s;s++)null!==t[s]&&(i=e.data(y+t[s]),void 0===i&&(i=""),e.css(t[s],i))},setMode:function(e,t){return"toggle"===t&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var i,s;switch(e[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=e[0]/t.height}switch(e[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=e[1]/t.width}return{x:s,y:i}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var i={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},s=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:t.width(),height:t.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return t.wrap(s),(t[0]===a||e.contains(t[0],a))&&e(a).focus(),s=t.parent(),"static"===t.css("position")?(s.css({position:"relative"}),t.css({position:"relative"})):(e.extend(i,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,s){i[s]=t.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(n),s.css(i).show()},removeWrapper:function(t){var i=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===i||e.contains(t[0],i))&&e(i).focus()),t},setTransition:function(t,i,s,n){return n=n||{},e.each(i,function(e,i){var a=t.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),e.fn.extend({effect:function(){function i(t){function i(){e.isFunction(a)&&a.call(n[0]),e.isFunction(t)&&t()}var n=e(this),a=s.complete,r=s.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),i()):o.call(n[0],s,i)}var s=t.apply(this,arguments),n=s.mode,a=s.queue,o=e.effects.effect[s.effect];return e.fx.off||!o?n?this[n](s.duration,s.complete):this.each(function(){s.complete&&s.complete.call(this)}):a===!1?this.each(i):this.queue(a||"fx",i)},show:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(e.fn.show),hide:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(e.fn.hide),toggle:function(e){return function(s){if(i(s)||"boolean"==typeof s)return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(e.fn.toggle),cssUnit:function(t){var i=this.css(t),s=[];return e.each(["em","px","%","pt"],function(e,t){i.indexOf(t)>0&&(s=[parseFloat(i),t])}),s}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,i){t[i]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,i=4;((t=Math.pow(2,--i))-1)/11>e;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,i){e.easing["easeIn"+t]=i,e.easing["easeOut"+t]=function(e){return 1-i(1-e)},e.easing["easeInOut"+t]=function(e){return.5>e?i(2*e)/2:1-i(-2*e+2)/2}})}(),e.effects,e.effects.effect.blind=function(t,i){var s,n,a,o=e(this),r=/up|down|vertical/,h=/up|left|vertical|horizontal/,l=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(o,t.mode||"hide"),d=t.direction||"up",c=r.test(d),p=c?"height":"width",f=c?"top":"left",m=h.test(d),g={},v="show"===u;o.parent().is(".ui-effects-wrapper")?e.effects.save(o.parent(),l):e.effects.save(o,l),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n=s[p](),a=parseFloat(s.css(f))||0,g[p]=v?n:0,m||(o.css(c?"bottom":"right",0).css(c?"top":"left","auto").css({position:"absolute"}),g[f]=v?a:n+a),v&&(s.css(p,0),m||s.css(f,a+n)),s.animate(g,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){"hide"===u&&o.hide(),e.effects.restore(o,l),e.effects.removeWrapper(o),i()}})},e.effects.effect.bounce=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"effect"),l="hide"===h,u="show"===h,d=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(u||l?1:0),m=t.duration/f,g=t.easing,v="up"===d||"down"===d?"top":"left",y="up"===d||"left"===d,b=o.queue(),_=b.length;for((u||l)&&r.push("opacity"),e.effects.save(o,r),o.show(),e.effects.createWrapper(o),c||(c=o["top"===v?"outerHeight":"outerWidth"]()/3),u&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,y?2*-c:2*c).animate(a,m,g)),l&&(c/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g).animate(a,m,g),c=l?2*c:c/2;l&&(n={opacity:0},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g)),o.queue(function(){l&&o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}),_>1&&b.splice.apply(b,[1,0].concat(b.splice(_,f+1))),o.dequeue()},e.effects.effect.clip=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"hide"),l="show"===h,u=t.direction||"vertical",d="vertical"===u,c=d?"height":"width",p=d?"top":"left",f={};e.effects.save(o,r),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[c](),l&&(n.css(c,0),n.css(p,a/2)),f[c]=l?a:0,f[p]=l?0:a/2,n.animate(f,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){l||o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}})},e.effects.effect.drop=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","opacity","height","width"],o=e.effects.setMode(n,t.mode||"hide"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h?"pos":"neg",d={opacity:r?1:0};e.effects.save(n,a),n.show(),e.effects.createWrapper(n),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===u?-s:s),d[l]=(r?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.explode=function(t,i){function s(){b.push(this),b.length===d*c&&n()}function n(){p.css({visibility:"visible"}),e(b).remove(),m||p.hide(),i()}var a,o,r,h,l,u,d=t.pieces?Math.round(Math.sqrt(t.pieces)):3,c=d,p=e(this),f=e.effects.setMode(p,t.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/c),y=Math.ceil(p.outerHeight()/d),b=[];for(a=0;d>a;a++)for(h=g.top+a*y,u=a-(d-1)/2,o=0;c>o;o++)r=g.left+o*v,l=o-(c-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*y}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:y,left:r+(m?l*v:0),top:h+(m?u*y:0),opacity:m?0:1}).animate({left:r+(m?0:l*v),top:h+(m?0:u*y),opacity:m?1:0},t.duration||500,t.easing,s)},e.effects.effect.fade=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:t.duration,easing:t.easing,complete:i})},e.effects.effect.fold=function(t,i){var s,n,a=e(this),o=["position","top","bottom","left","right","height","width"],r=e.effects.setMode(a,t.mode||"hide"),h="show"===r,l="hide"===r,u=t.size||15,d=/([0-9]+)%/.exec(u),c=!!t.horizFirst,p=h!==c,f=p?["width","height"]:["height","width"],m=t.duration/2,g={},v={};e.effects.save(a,o),a.show(),s=e.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],d&&(u=parseInt(d[1],10)/100*n[l?0:1]),h&&s.css(c?{height:0,width:u}:{height:u,width:0}),g[f[0]]=h?n[0]:u,v[f[1]]=h?n[1]:0,s.animate(g,m,t.easing).animate(v,m,t.easing,function(){l&&a.hide(),e.effects.restore(a,o),e.effects.removeWrapper(a),i()})},e.effects.effect.highlight=function(t,i){var s=e(this),n=["backgroundImage","backgroundColor","opacity"],a=e.effects.setMode(s,t.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),e.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===a&&s.hide(),e.effects.restore(s,n),i()}})},e.effects.effect.size=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],u=["fontSize"],d=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],c=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),f=t.restore||"effect"!==p,m=t.scale||"both",g=t.origin||["middle","center"],v=o.css("position"),y=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===t.mode&&"show"===p?(o.from=t.to||b,o.to=t.from||s):(o.from=t.from||("show"===p?b:s),o.to=t.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===m||"both"===m)&&(a.from.y!==a.to.y&&(y=y.concat(d),o.from=e.effects.setTransition(o,d,a.from.y,o.from),o.to=e.effects.setTransition(o,d,a.to.y,o.to)),a.from.x!==a.to.x&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,a.from.x,o.from),o.to=e.effects.setTransition(o,c,a.to.x,o.to))),("content"===m||"both"===m)&&a.from.y!==a.to.y&&(y=y.concat(u).concat(l),o.from=e.effects.setTransition(o,u,a.from.y,o.from),o.to=e.effects.setTransition(o,u,a.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),g&&(n=e.effects.getBaseline(g,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===m||"both"===m)&&(d=d.concat(["marginTop","marginBottom"]).concat(u),c=c.concat(["marginLeft","marginRight"]),l=r.concat(d).concat(c),o.find("*[width]").each(function(){var i=e(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};
f&&e.effects.save(i,l),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=e.effects.setTransition(i,d,a.from.y,i.from),i.to=e.effects.setTransition(i,d,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=e.effects.setTransition(i,c,a.from.x,i.from),i.to=e.effects.setTransition(i,c,a.to.x,i.to)),i.css(i.from),i.animate(i.to,t.duration,t.easing,function(){f&&e.effects.restore(i,l)})})),o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),e.effects.restore(o,y),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,i){var s=parseInt(i,10),n=e?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),e.effects.removeWrapper(o),i()}})},e.effects.effect.scale=function(t,i){var s=e(this),n=e.extend(!0,{},t),a=e.effects.setMode(s,t.mode||"effect"),o=parseInt(t.percent,10)||(0===parseInt(t.percent,10)?0:"hide"===a?0:100),r=t.direction||"both",h=t.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},u={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=h||["middle","center"],n.restore=!0),n.from=t.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*u.y,width:l.width*u.x,outerHeight:l.outerHeight*u.y,outerWidth:l.outerWidth*u.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},e.effects.effect.puff=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"hide"),a="hide"===n,o=parseInt(t.percent,10)||150,r=o/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(t)},e.effects.effect.pulsate=function(t,i){var s,n=e(this),a=e.effects.setMode(n,t.mode||"show"),o="show"===a,r="hide"===a,h=o||"hide"===a,l=2*(t.times||5)+(h?1:0),u=t.duration/l,d=0,c=n.queue(),p=c.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),d=1),s=1;l>s;s++)n.animate({opacity:d},u,t.easing),d=1-d;n.animate({opacity:d},u,t.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&c.splice.apply(c,[1,0].concat(c.splice(p,l+1))),n.dequeue()},e.effects.effect.shake=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","height","width"],o=e.effects.setMode(n,t.mode||"effect"),r=t.direction||"left",h=t.distance||20,l=t.times||3,u=2*l+1,d=Math.round(t.duration/u),c="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},m={},g={},v=n.queue(),y=v.length;for(e.effects.save(n,a),n.show(),e.effects.createWrapper(n),f[c]=(p?"-=":"+=")+h,m[c]=(p?"+=":"-=")+2*h,g[c]=(p?"-=":"+=")+2*h,n.animate(f,d,t.easing),s=1;l>s;s++)n.animate(m,d,t.easing).animate(g,d,t.easing);n.animate(m,d,t.easing).animate(f,d/2,t.easing).queue(function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}),y>1&&v.splice.apply(v,[1,0].concat(v.splice(y,u+1))),n.dequeue()},e.effects.effect.slide=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","width","height"],o=e.effects.setMode(n,t.mode||"show"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h,d={};e.effects.save(n,a),n.show(),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,u?isNaN(s)?"-"+s:-s:s),d[l]=(r?u?"+=":"-=":u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.transfer=function(t,i){var s=e(this),n=e(t.to),a="fixed"===n.css("position"),o=e("body"),r=a?o.scrollTop():0,h=a?o.scrollLeft():0,l=n.offset(),u={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},d=s.offset(),c=e("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(t.className).css({top:d.top-r,left:d.left-h,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(u,t.duration,t.easing,function(){c.remove(),i()})},e.widget("ui.progressbar",{version:"1.11.4",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return void 0===e?this.options.value:(this.options.value=this._constrainedValue(e),this._refreshValue(),void 0)},_constrainedValue:function(e){return void 0===e&&(e=this.options.value),this.indeterminate=e===!1,"number"!=typeof e&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){"max"===e&&(t=Math.max(this.min,t)),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),e.widget("ui.selectable",e.ui.mouse,{version:"1.11.4",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,n=e.data(this,"selectable-item");return n?(s=!t.metaKey&&!t.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",t,{selecting:n.element}):i._trigger("unselecting",t,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=t.pageX,h=t.pageY;return a>r&&(i=r,r=a,a=i),o>h&&(i=h,h=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:h-o}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||a>i.right||i.top>h||o>i.bottom):"fit"===n.tolerance&&(l=i.left>a&&r>i.right&&i.top>o&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}}),e.widget("ui.selectmenu",{version:"1.11.4",defaultElement:"<select>",options:{appendTo:null,disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:null,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this.options.disabled&&this.disable()},_drawButton:function(){var t=this;this.label=e("label[for='"+this.ids.element+"']").attr("for",this.ids.button),this._on(this.label,{click:function(e){this.button.focus(),e.preventDefault()}}),this.element.hide(),this.button=e("<span>",{"class":"ui-selectmenu-button ui-widget ui-state-default ui-corner-all",tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true"}).insertAfter(this.element),e("<span>",{"class":"ui-icon "+this.options.icons.button}).prependTo(this.button),this.buttonText=e("<span>",{"class":"ui-selectmenu-text"}).appendTo(this.button),this._setText(this.buttonText,this.element.find("option:selected").text()),this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){t.menuItems||t._refreshMenu()}),this._hoverable(this.button),this._focusable(this.button)},_drawMenu:function(){var t=this;this.menu=e("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=e("<div>",{"class":"ui-selectmenu-menu ui-front"}).append(this.menu).appendTo(this._appendTo()),this.menuInstance=this.menu.menu({role:"listbox",select:function(e,i){e.preventDefault(),t._setSelection(),t._select(i.item.data("ui-selectmenu-item"),e)},focus:function(e,i){var s=i.item.data("ui-selectmenu-item");null!=t.focusIndex&&s.index!==t.focusIndex&&(t._trigger("focus",e,{item:s}),t.isOpen||t._select(s,e)),t.focusIndex=s.index,t.button.attr("aria-activedescendant",t.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menu.addClass("ui-corner-bottom").removeClass("ui-corner-all"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this._setText(this.buttonText,this._getSelectedItem().text()),this.options.width||this._resizeButton()},_refreshMenu:function(){this.menu.empty();var e,t=this.element.find("option");t.length&&(this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup"),e=this._getSelectedItem(),this.menuInstance.focus(null,e),this._setAria(e.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(e){this.options.disabled||(this.menuItems?(this.menu.find(".ui-state-focus").removeClass("ui-state-focus"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",e))},_position:function(){this.menuWrap.position(e.extend({of:this.button},this.options.position))},close:function(e){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",e))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderMenu:function(t,i){var s=this,n="";e.each(i,function(i,a){a.optgroup!==n&&(e("<li>",{"class":"ui-selectmenu-optgroup ui-menu-divider"+(a.element.parent("optgroup").prop("disabled")?" ui-state-disabled":""),text:a.optgroup}).appendTo(t),n=a.optgroup),s._renderItemData(t,a)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-selectmenu-item",t)},_renderItem:function(t,i){var s=e("<li>");return i.disabled&&s.addClass("ui-state-disabled"),this._setText(s,i.label),s.appendTo(t)},_setText:function(e,t){t?e.text(t):e.html("&#160;")},_move:function(e,t){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex):(i=this.menuItems.eq(this.element[0].selectedIndex),n+=":not(.ui-state-disabled)"),s="first"===e||"last"===e?i["first"===e?"prevAll":"nextAll"](n).eq(-1):i[e+"All"](n).eq(0),s.length&&this.menuInstance.focus(t,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex)},_toggle:function(e){this[this.isOpen?"close":"open"](e)},_setSelection:function(){var e;this.range&&(window.getSelection?(e=window.getSelection(),e.removeAllRanges(),e.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(t){this.isOpen&&(e(t.target).closest(".ui-selectmenu-menu, #"+this.ids.button).length||this.close(t))}},_buttonEvents:{mousedown:function(){var e;window.getSelection?(e=window.getSelection(),e.rangeCount&&(this.range=e.getRangeAt(0))):this.range=document.selection.createRange()},click:function(e){this._setSelection(),this._toggle(e)},keydown:function(t){var i=!0;switch(t.keyCode){case e.ui.keyCode.TAB:case e.ui.keyCode.ESCAPE:this.close(t),i=!1;break;case e.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case e.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case e.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case e.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case e.ui.keyCode.LEFT:this._move("prev",t);break;case e.ui.keyCode.RIGHT:this._move("next",t);break;case e.ui.keyCode.HOME:case e.ui.keyCode.PAGE_UP:this._move("first",t);break;case e.ui.keyCode.END:case e.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),i=!1}i&&t.preventDefault()}},_selectFocusedItem:function(e){var t=this.menuItems.eq(this.focusIndex);t.hasClass("ui-state-disabled")||this._select(t.data("ui-selectmenu-item"),e)},_select:function(e,t){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=e.index,this._setText(this.buttonText,e.label),this._setAria(e),this._trigger("select",t,{item:e}),e.index!==i&&this._trigger("change",t,{item:e}),this.close(t)},_setAria:function(e){var t=this.menuItems.eq(e.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(e,t){"icons"===e&&this.button.find("span.ui-icon").removeClass(this.options.icons.button).addClass(t.button),this._super(e,t),"appendTo"===e&&this.menuWrap.appendTo(this._appendTo()),"disabled"===e&&(this.menuInstance.option("disabled",t),this.button.toggleClass("ui-state-disabled",t).attr("aria-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)),"width"===e&&this._resizeButton()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_toggleAttr:function(){this.button.toggleClass("ui-corner-top",this.isOpen).toggleClass("ui-corner-all",!this.isOpen).attr("aria-expanded",this.isOpen),this.menuWrap.toggleClass("ui-selectmenu-open",this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var e=this.options.width;e||(e=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(e)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){return{disabled:this.element.prop("disabled")}},_parseOptions:function(t){var i=[];t.each(function(t,s){var n=e(s),a=n.parent("optgroup");i.push({element:n,index:t,value:n.val(),label:n.text(),optgroup:a.attr("label")||"",disabled:a.prop("disabled")||n.prop("disabled")})}),this.items=i},_destroy:function(){this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.label.attr("for",this.ids.element)}}),e.widget("ui.slider",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),a="<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",o=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),t=n.length;i>t;t++)o.push(a);this.handles=n.add(e(o.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)})},_createRange:function(){var t=this.options,i="";t.range?(t.range===!0&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:e.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=e("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===t.range||"max"===t.range?" ui-slider-range-"+t.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var i,s,n,a,o,r,h,l,u=this,d=this.options;return d.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:t.pageX,y:t.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var i=Math.abs(s-u.values(t));(n>i||n===i&&(t===u._lastChangedValue||u.values(t)===d.min))&&(n=i,a=e(this),o=t)}),r=this._start(t,o),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,a.addClass("ui-state-active").focus(),h=a.offset(),l=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:t.pageX-h.left-a.width()/2,top:t.pageY-h.top-a.height()/2-(parseInt(a.css("borderTopWidth"),10)||0)-(parseInt(a.css("borderBottomWidth"),10)||0)+(parseInt(a.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},i=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,i),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,i,s,n,a;return"horizontal"===this.orientation?(t=this.elementSize.width,i=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,i=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/t,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),a=this._valueMin()+s*n,this._trimAlignValue(a)},_start:function(e,t){var i={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("start",e,i)},_slide:function(e,t,i){var s,n,a;this.options.values&&this.options.values.length?(s=this.values(t?0:1),2===this.options.values.length&&this.options.range===!0&&(0===t&&i>s||1===t&&s>i)&&(i=s),i!==this.values(t)&&(n=this.values(),n[t]=i,a=this._trigger("slide",e,{handle:this.handles[t],value:i,values:n}),s=this.values(t?0:1),a!==!1&&this.values(t,i))):i!==this.value()&&(a=this._trigger("slide",e,{handle:this.handles[t],value:i}),a!==!1&&this.value(i))},_stop:function(e,t){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("stop",e,i)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._lastChangedValue=t,this._trigger("change",e,i)}},value:function(e){return arguments.length?(this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(t,i){var s,n,a;if(arguments.length>1)return this.options.values[t]=this._trimAlignValue(i),this._refreshValue(),this._change(null,t),void 0;if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();for(s=this.options.values,n=arguments[0],a=0;s.length>a;a+=1)s[a]=this._trimAlignValue(n[a]),this._change(null,a);this._refreshValue()},_setOption:function(t,i){var s,n=0;switch("range"===t&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),e.isArray(this.options.values)&&(n=this.options.values.length),"disabled"===t&&this.element.toggleClass("ui-state-disabled",!!i),this._super(t,i),t){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue(),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e)},_values:function(e){var t,i,s;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(e){if(this._valueMin()>=e)return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,i=(e-this._valueMin())%t,s=e-i;return 2*Math.abs(i)>=t&&(s+=i>0?t:-t),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var e=this.options.max,t=this._valueMin(),i=this.options.step,s=Math.floor(+(e-t).toFixed(this._precision())/i)*i;e=s+t,this.max=parseFloat(e.toFixed(this._precision()))},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshValue:function(){var t,i,s,n,a,o=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",e(this).stop(1,1)[l?"animate":"css"](u,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-t+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-t+"%"},{queue:!1,duration:r.animate}))),t=i}):(s=this.value(),n=this._valueMin(),a=this._valueMax(),i=a!==n?100*((s-n)/(a-n)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,r.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===o&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===o&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(t){var i,s,n,a,o=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,e(t.target).addClass("ui-state-active"),i=this._start(t,o),i===!1))return}switch(a=this.options.step,s=n=this.options.values&&this.options.values.length?this.values(o):this.value(),t.keyCode){case e.ui.keyCode.HOME:n=this._valueMin();break;case e.ui.keyCode.END:n=this._valueMax();break;case e.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+a);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-a)}this._slide(t,o,n)},keyup:function(t){var i=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,i),this._change(t,i),e(t.target).removeClass("ui-state-active"))}}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,a.widgetName+"-item")===a?(s=e(this),!1):void 0}),e.data(t.target,a.widgetName+"-item")===a&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=e("<style>*{ cursor: "+o.cursor+" !important; }</style>").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));
return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<o.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+o.scrollSpeed:t.pageY-this.overflowOffset.top<o.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-o.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<o.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+o.scrollSpeed:t.pageX-this.overflowOffset.left<o.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-o.scrollSpeed)):(t.pageY-this.document.scrollTop()<o.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-o.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<o.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+o.scrollSpeed)),t.pageX-this.document.scrollLeft()<o.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-o.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<o.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+o.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>r&&h>s+l,c="y"===this.options.axis||t+u>a&&o>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return s?this.floating?a&&"right"===a||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(n=e(c[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(d.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=d.length-1;i>=0;i--)for(o=d[i][1],r=d[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tbody"===s?t._createTrPlaceholder(t.currentItem.find("tr").eq(0),e("<tr>",t.document[0]).appendTo(n)):"tr"===s?t._createTrPlaceholder(t.currentItem,n):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_createTrPlaceholder:function(t,i){var s=this;t.children().each(function(){e("<td>&#160;</td>",s.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,d,c=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(c&&e.contains(this.containers[i].element[0],c.element[0]))continue;c=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=c.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",d=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[d]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[d]-h)&&(n=Math.abs(t[d]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.width():this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(a=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}}),e.widget("ui.spinner",{version:"1.11.4",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},i=this.element;return e.each(["min","max","step"],function(e,s){var n=i.attr(s);void 0!==n&&n.length&&(t[s]=n)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e),void 0)},mousewheel:function(e,t){if(t){if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()}},"mousedown .ui-spinner-button":function(t){function i(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(t)!==!1&&this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){return e(t.currentTarget).hasClass("ui-state-active")?this._start(t)===!1?!1:(this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*e.height())&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var i=this.options,s=e.ui.keyCode;switch(t.keyCode){case s.UP:return this._repeat(null,1,t),!0;case s.DOWN:return this._repeat(null,-1,t),!0;case s.PAGE_UP:return this._repeat(null,i.page,t),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return this.spinning||this._trigger("start",e)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(e,t,i){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,i)},e),this._spin(t*this.options.step,i)},_spin:function(e,t){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+e*this._increment(this.counter)),this.spinning&&this._trigger("spin",t,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(t){var i=this.options.incremental;return i?e.isFunction(i)?i(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_adjustValue:function(e){var t,i,s=this.options;return t=null!==s.min?s.min:0,i=e-t,i=Math.round(i/s.step)*s.step,e=t+i,e=parseFloat(e.toFixed(this._precision())),null!==s.max&&e>s.max?s.max:null!==s.min&&s.min>e?s.min:e},_stop:function(e){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e))},_setOption:function(e,t){if("culture"===e||"numberFormat"===e){var i=this._parse(this.element.val());return this.options[e]=t,this.element.val(this._format(i)),void 0}("max"===e||"min"===e||"step"===e)&&"string"==typeof t&&(t=this._parse(t)),"icons"===e&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(t.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(t.down)),this._super(e,t),"disabled"===e&&(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable"))},_setOptions:h(function(e){this._super(e)}),_parse:function(e){return"string"==typeof e&&""!==e&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),""===e||isNaN(e)?null:e},_format:function(e){return""===e?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var e=this.value();return null===e?!1:e===this._adjustValue(e)},_value:function(e,t){var i;""!==e&&(i=this._parse(e),null!==i&&(t||(i=this._adjustValue(i)),e=this._format(i))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:h(function(e){this._stepUp(e)}),_stepUp:function(e){this._start()&&(this._spin((e||1)*this.options.step),this._stop())},stepDown:h(function(e){this._stepDown(e)}),_stepDown:function(e){this._start()&&(this._spin((e||1)*-this.options.step),this._stop())},pageUp:h(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:h(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){return arguments.length?(h(this._value).call(this,e),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),e.widget("ui.tabs",{version:"1.11.4",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,n){return e(n).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),t.ctrlKey||t.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>n&&(t=0),0>t&&(t=n),t}for(var n=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this,i=this.tabs,s=this.anchors,n=this.panels;
this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var n,a,o,r=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(n=s.hash,o=n.substring(1),a=t.element.find(t._sanitizeSelector(n))):(o=h.attr("aria-controls")||e({}).uniqueId()[0].id,n="#"+o,a=t.element.find(n),a.length||(a=t._createPanel(o),a.insertAfter(t.panels[i-1]||t.tablist)),a.attr("aria-live","polite")),a.length&&(t.panels=t.panels.add(a)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":o,"aria-labelledby":r}),a.attr("aria-labelledby",r)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?e():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:r?e():a,newPanel:h};t.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?e():a,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),t),this._toggle(t,u))},_toggle:function(t,i){function s(){a.running=!1,a._trigger("activate",t,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,n=this.tabs.eq(t),a=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),r={tab:n,panel:o},h=function(e,t){"abort"===t&&s.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr};this._isLocal(a[0])||(this.xhr=e.ajax(this._ajaxSettings(a,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.done(function(e,t,n){setTimeout(function(){o.html(e),s._trigger("load",i,r),h(n,t)},1)}).fail(function(e,t){setTimeout(function(){h(e,t)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,a){return n._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:a},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),e.widget("ui.tooltip",{version:"1.11.4",options:{content:function(){var t=e(this).attr("title")||"";return e("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_addDescribedBy:function(t,i){var s=(t.attr("aria-describedby")||"").split(/\s+/);s.push(i),t.data("ui-tooltip-id",i).attr("aria-describedby",e.trim(s.join(" ")))},_removeDescribedBy:function(t){var i=t.data("ui-tooltip-id"),s=(t.attr("aria-describedby")||"").split(/\s+/),n=e.inArray(i,s);-1!==n&&s.splice(n,1),t.removeData("ui-tooltip-id"),s=e.trim(s.join(" ")),s?t.attr("aria-describedby",s):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable(),this.liveRegion=e("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body)},_setOption:function(t,i){var s=this;return"disabled"===t?(this[i?"_disable":"_enable"](),this.options[t]=i,void 0):(this._super(t,i),"content"===t&&e.each(this.tooltips,function(e,t){s._updateContent(t.element)}),void 0)},_disable:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur");n.target=n.currentTarget=s.element[0],t.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var i=this,s=e(t?t.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&s.parents().each(function(){var t,s=e(this);s.data("ui-tooltip-open")&&(t=e.Event("blur"),t.target=t.currentTarget=this,i.close(t,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(t,s),this._updateContent(s,t))},_updateContent:function(e,t){var i,s=this.options.content,n=this,a=t?t.type:null;return"string"==typeof s?this._open(t,e,s):(i=s.call(e[0],function(i){n._delay(function(){e.data("ui-tooltip-open")&&(t&&(t.type=a),this._open(t,e,i))})}),i&&this._open(t,e,i),void 0)},_open:function(t,i,s){function n(e){l.of=e,o.is(":hidden")||o.position(l)}var a,o,r,h,l=e.extend({},this.options.position);if(s){if(a=this._find(i))return a.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(t&&"mouseover"===t.type?i.attr("title",""):i.removeAttr("title")),a=this._tooltip(i),o=a.tooltip,this._addDescribedBy(i,o.attr("id")),o.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),s.clone?(h=s.clone(),h.removeAttr("id").find("[id]").removeAttr("id")):h=s,e("<div>").html(h).appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:n}),n(t)):o.position(e.extend({of:i},this.options.position)),o.hide(),this._show(o,this.options.show),this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){o.is(":visible")&&(n(l.of),clearInterval(r))},e.fx.interval)),this._trigger("open",t,{tooltip:o})}},_registerCloseHandlers:function(t,i){var s={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var s=e.Event(t);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),t&&"mouseover"!==t.type||(s.mouseleave="close"),t&&"focusin"!==t.type||(s.focusout="close"),this._on(!0,i,s)},close:function(t){var i,s=this,n=e(t?t.currentTarget:this.element),a=this._find(n);return a?(i=a.tooltip,a.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),a.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(e(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&e.each(this.parents,function(t,i){e(i.element).attr("title",i.title),delete s.parents[t]}),a.closing=!0,this._trigger("close",t,{tooltip:i}),a.hiding||(a.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(t){var i=e("<div>").attr("role","tooltip").addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||"")),s=i.uniqueId().attr("id");return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),this.tooltips[s]={element:t,tooltip:i}},_find:function(e){var t=e.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur"),a=s.element;n.target=n.currentTarget=a[0],t.close(n,!0),e("#"+i).remove(),a.data("ui-tooltip-title")&&(a.attr("title")||a.attr("title",a.data("ui-tooltip-title")),a.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}})});
},{}],625:[function(require,module,exports){
/*!
 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2013 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		// CommonJS
		factory(require('jquery'));
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {

	var pluses = /\+/g;

	function encode(s) {
		return config.raw ? s : encodeURIComponent(s);
	}

	function decode(s) {
		return config.raw ? s : decodeURIComponent(s);
	}

	function stringifyCookieValue(value) {
		return encode(config.json ? JSON.stringify(value) : String(value));
	}

	function parseCookieValue(s) {
		if (s.indexOf('"') === 0) {
			// This is a quoted cookie as according to RFC2068, unescape...
			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
		}

		try {
			// Replace server-side written pluses with spaces.
			// If we can't decode the cookie, ignore it, it's unusable.
			// If we can't parse the cookie, ignore it, it's unusable.
			s = decodeURIComponent(s.replace(pluses, ' '));
			return config.json ? JSON.parse(s) : s;
		} catch(e) {}
	}

	function read(s, converter) {
		var value = config.raw ? s : parseCookieValue(s);
		return $.isFunction(converter) ? converter(value) : value;
	}

	var config = $.cookie = function (key, value, options) {

		// Write

		if (value !== undefined && !$.isFunction(value)) {
			options = $.extend({}, config.defaults, options);

			if (typeof options.expires === 'number') {
				var days = options.expires, t = options.expires = new Date();
				t.setTime(+t + days * 864e+5);
			}

			return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path    ? '; path=' + options.path : '',
				options.domain  ? '; domain=' + options.domain : '',
				options.secure  ? '; secure' : ''
			].join(''));
		}

		// Read

		var result = key ? undefined : {};

		// To prevent the for loop in the first place assign an empty array
		// in case there are no cookies at all. Also prevents odd result when
		// calling $.cookie().
		var cookies = document.cookie ? document.cookie.split('; ') : [];

		for (var i = 0, l = cookies.length; i < l; i++) {
			var parts = cookies[i].split('=');
			var name = decode(parts.shift());
			var cookie = parts.join('=');

			if (key && key === name) {
				// If second argument (value) is a function it's a converter...
				result = read(cookie, value);
				break;
			}

			// Prevent storing a cookie that we couldn't decode.
			if (!key && (cookie = read(cookie)) !== undefined) {
				result[name] = cookie;
			}
		}

		return result;
	};

	config.defaults = {};

	$.removeCookie = function (key, options) {
		if ($.cookie(key) === undefined) {
			return false;
		}

		// Must not alter options, thus extending a fresh object...
		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
		return !$.cookie(key);
	};

}));

},{"jquery":628}],626:[function(require,module,exports){
(function(d){var p={},e,a,h=document,i=window,f=h.documentElement,j=d.expando;d.event.special.inview={add:function(a){p[a.guid+"-"+this[j]]={data:a,$element:d(this)}},remove:function(a){try{delete p[a.guid+"-"+this[j]]}catch(d){}}};d(i).bind("scroll resize",function(){e=a=null});!f.addEventListener&&f.attachEvent&&f.attachEvent("onfocusin",function(){a=null});setInterval(function(){var k=d(),j,n=0;d.each(p,function(a,b){var c=b.data.selector,d=b.$element;k=k.add(c?d.find(c):d)});if(j=k.length){var b;
if(!(b=e)){var g={height:i.innerHeight,width:i.innerWidth};if(!g.height&&((b=h.compatMode)||!d.support.boxModel))b="CSS1Compat"===b?f:h.body,g={height:b.clientHeight,width:b.clientWidth};b=g}e=b;for(a=a||{top:i.pageYOffset||f.scrollTop||h.body.scrollTop,left:i.pageXOffset||f.scrollLeft||h.body.scrollLeft};n<j;n++)if(d.contains(f,k[n])){b=d(k[n]);var l=b.height(),m=b.width(),c=b.offset(),g=b.data("inview");if(!a||!e)break;c.top+l>a.top&&c.top<a.top+e.height&&c.left+m>a.left&&c.left<a.left+e.width?
(m=a.left>c.left?"right":a.left+e.width<c.left+m?"left":"both",l=a.top>c.top?"bottom":a.top+e.height<c.top+l?"top":"both",c=m+"-"+l,(!g||g!==c)&&b.data("inview",c).trigger("inview",[!0,m,l])):g&&b.data("inview",!1).trigger("inview",[!1])}}},250)})(jQuery);
},{}],627:[function(require,module,exports){
/**
 * @license jquery.panzoom.js v2.0.5
 * Updated: Thu Apr 03 2014
 * Add pan and zoom functionality to any element
 * Copyright (c) 2014 timmy willison
 * Released under the MIT license
 * https://github.com/timmywil/jquery.panzoom/blob/master/MIT-License.txt
 */

(function(global, factory) {
	// AMD
	if (typeof define === 'function' && define.amd) {
		define([ 'jquery' ], function(jQuery) {
			return factory(global, jQuery);
		});
	// CommonJS/Browserify
	} else if (typeof exports === 'object') {
		factory(global, require('jquery'));
	// Global
	} else {
		factory(global, global.jQuery);
	}
}(typeof window !== 'undefined' ? window : this, function(window, $) {
	'use strict';

	// Common properties to lift for touch or pointer events
	var list = 'over out down up move enter leave cancel'.split(' ');
	var hook = $.extend({}, $.event.mouseHooks);
	var events = {};

	// Support pointer events in IE11+ if available
	if ( window.PointerEvent ) {
		$.each(list, function( i, name ) {
			// Add event name to events property and add fixHook
			$.event.fixHooks[
				(events[name] = 'pointer' + name)
			] = hook;
		});
	} else {
		var mouseProps = hook.props;
		// Add touch properties for the touch hook
		hook.props = mouseProps.concat(['touches', 'changedTouches', 'targetTouches', 'altKey', 'ctrlKey', 'metaKey', 'shiftKey']);

		/**
		 * Support: Android
		 * Android sets pageX/Y to 0 for any touch event
		 * Attach first touch's pageX/pageY and clientX/clientY if not set correctly
		 */
		hook.filter = function( event, originalEvent ) {
			var touch;
			var i = mouseProps.length;
			if ( !originalEvent.pageX && originalEvent.touches && (touch = originalEvent.touches[0]) ) {
				// Copy over all mouse properties
				while(i--) {
					event[mouseProps[i]] = touch[mouseProps[i]];
				}
			}
			return event;
		};

		$.each(list, function( i, name ) {
			// No equivalent touch events for over and out
			if (i < 2) {
				events[ name ] = 'mouse' + name;
			} else {
				var touch = 'touch' +
					(name === 'down' ? 'start' : name === 'up' ? 'end' : name);
				// Add fixHook
				$.event.fixHooks[ touch ] = hook;
				// Add event names to events property
				events[ name ] = touch + ' mouse' + name;
			}
		});
	}

	$.pointertouch = events;

	var datakey = '__pz__';
	var slice = Array.prototype.slice;
	var pointerEvents = !!window.PointerEvent;

	// Regex
	var rupper = /([A-Z])/g;
	var rsvg = /^http:[\w\.\/]+svg$/;
	var rinline = /^inline/;

	var floating = '(\\-?[\\d\\.e]+)';
	var commaSpace = '\\,?\\s*';
	var rmatrix = new RegExp(
		'^matrix\\(' +
		floating + commaSpace +
		floating + commaSpace +
		floating + commaSpace +
		floating + commaSpace +
		floating + commaSpace +
		floating + '\\)$'
	);

	/**
	 * Utility for determing transform matrix equality
	 * Checks backwards to test translation first
	 * @param {Array} first
	 * @param {Array} second
	 */
	function matrixEquals(first, second) {
		var i = first.length;
		while(--i) {
			if (+first[i] !== +second[i]) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Creates the options object for reset functions
	 * @param {Boolean|Object} opts See reset methods
	 * @returns {Object} Returns the newly-created options object
	 */
	function createResetOptions(opts) {
		var options = { range: true, animate: true };
		if (typeof opts === 'boolean') {
			options.animate = opts;
		} else {
			$.extend(options, opts);
		}
		return options;
	}

	/**
	 * Represent a transformation matrix with a 3x3 matrix for calculations
	 * Matrix functions adapted from Louis Remi's jQuery.transform (https://github.com/louisremi/jquery.transform.js)
	 * @param {Array|Number} a An array of six values representing a 2d transformation matrix
	 */
	function Matrix(a, b, c, d, e, f, g, h, i) {
		if ($.type(a) === 'array') {
			this.elements = [
				+a[0], +a[2], +a[4],
				+a[1], +a[3], +a[5],
				    0,     0,     1
			];
		} else {
			this.elements = [
				a, b, c,
				d, e, f,
				g || 0, h || 0, i || 1
			];
		}
	}

	Matrix.prototype = {
		/**
		 * Multiply a 3x3 matrix by a similar matrix or a vector
		 * @param {Matrix|Vector} matrix
		 * @return {Matrix|Vector} Returns a vector if multiplying by a vector
		 */
		x: function(matrix) {
			var isVector = matrix instanceof Vector;

			var a = this.elements,
				b = matrix.elements;

			if (isVector && b.length === 3) {
				// b is actually a vector
				return new Vector(
					a[0] * b[0] + a[1] * b[1] + a[2] * b[2],
					a[3] * b[0] + a[4] * b[1] + a[5] * b[2],
					a[6] * b[0] + a[7] * b[1] + a[8] * b[2]
				);
			} else if (b.length === a.length) {
				// b is a 3x3 matrix
				return new Matrix(
					a[0] * b[0] + a[1] * b[3] + a[2] * b[6],
					a[0] * b[1] + a[1] * b[4] + a[2] * b[7],
					a[0] * b[2] + a[1] * b[5] + a[2] * b[8],

					a[3] * b[0] + a[4] * b[3] + a[5] * b[6],
					a[3] * b[1] + a[4] * b[4] + a[5] * b[7],
					a[3] * b[2] + a[4] * b[5] + a[5] * b[8],

					a[6] * b[0] + a[7] * b[3] + a[8] * b[6],
					a[6] * b[1] + a[7] * b[4] + a[8] * b[7],
					a[6] * b[2] + a[7] * b[5] + a[8] * b[8]
				);
			}
			return false; // fail
		},
		/**
		 * Generates an inverse of the current matrix
		 * @returns {Matrix}
		 */
		inverse: function() {
			var d = 1 / this.determinant(),
				a = this.elements;
			return new Matrix(
				d * ( a[8] * a[4] - a[7] * a[5]),
				d * (-(a[8] * a[1] - a[7] * a[2])),
				d * ( a[5] * a[1] - a[4] * a[2]),

				d * (-(a[8] * a[3] - a[6] * a[5])),
				d * ( a[8] * a[0] - a[6] * a[2]),
				d * (-(a[5] * a[0] - a[3] * a[2])),

				d * ( a[7] * a[3] - a[6] * a[4]),
				d * (-(a[7] * a[0] - a[6] * a[1])),
				d * ( a[4] * a[0] - a[3] * a[1])
			);
		},
		/**
		 * Calculates the determinant of the current matrix
		 * @returns {Number}
		 */
		determinant: function() {
			var a = this.elements;
			return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]);
		}
	};

	/**
	 * Create a vector containing three values
	 */
	function Vector(x, y, z) {
		this.elements = [ x, y, z ];
	}

	/**
	 * Get the element at zero-indexed index i
	 * @param {Number} i
	 */
	Vector.prototype.e = Matrix.prototype.e = function(i) {
		return this.elements[ i ];
	};

	/**
	 * Create a Panzoom object for a given element
	 * @constructor
	 * @param {Element} elem - Element to use pan and zoom
	 * @param {Object} [options] - An object literal containing options to override default options
	 *  (See Panzoom.defaults for ones not listed below)
	 * @param {jQuery} [options.$zoomIn] - zoom in buttons/links collection (you can also bind these yourself
	 *  e.g. $button.on('click', function(e) { e.preventDefault(); $elem.panzooom('zoomIn'); });)
	 * @param {jQuery} [options.$zoomOut] - zoom out buttons/links collection on which to bind zoomOut
	 * @param {jQuery} [options.$zoomRange] - zoom in/out with this range control
	 * @param {jQuery} [options.$reset] - Reset buttons/links collection on which to bind the reset method
	 * @param {Function} [options.on[Start|Change|Zoom|Pan|End|Reset] - Optional callbacks for panzoom events
	 */
	function Panzoom(elem, options) {

		// Allow instantiation without `new` keyword
		if (!(this instanceof Panzoom)) {
			return new Panzoom(elem, options);
		}

		// Sanity checks
		if (elem.nodeType !== 1) {
			$.error('Panzoom called on non-Element node');
		}
		if (!$.contains(document, elem)) {
			$.error('Panzoom element must be attached to the document');
		}

		// Don't remake
		var d = $.data(elem, datakey);
		if (d) {
			return d;
		}

		// Extend default with given object literal
		// Each instance gets its own options
		this.options = options = $.extend({}, Panzoom.defaults, options);
		this.elem = elem;
		var $elem = this.$elem = $(elem);
		this.$set = options.$set && options.$set.length ? options.$set : $elem;
		this.$doc = $(elem.ownerDocument || document);
		this.$parent = $elem.parent();

		// This is SVG if the namespace is SVG
		// However, while <svg> elements are SVG, we want to treat those like other elements
		this.isSVG = rsvg.test(elem.namespaceURI) && elem.nodeName.toLowerCase() !== 'svg';

		this.panning = false;

		// Save the original transform value
		// Save the prefixed transform style key
		// Set the starting transform
		this._buildTransform();

		// Build the appropriately-prefixed transform style property name
		// De-camelcase
		this._transform = !this.isSVG && $.cssProps.transform.replace(rupper, '-$1').toLowerCase();

		// Build the transition value
		this._buildTransition();

		// Build containment dimensions
		this.resetDimensions();

		// Add zoom and reset buttons to `this`
		var $empty = $();
		var self = this;
		$.each([ '$zoomIn', '$zoomOut', '$zoomRange', '$reset' ], function(i, name) {
			self[ name ] = options[ name ] || $empty;
		});

		this.enable();

		// Save the instance
		$.data(elem, datakey, this);
	}

	// Attach regex for possible use (immutable)
	Panzoom.rmatrix = rmatrix;

	// Container for event names
	Panzoom.events = $.pointertouch;

	Panzoom.defaults = {
		// Should always be non-empty
		// Used to bind jQuery events without collisions
		// A guid is not added here as different instantiations/versions of panzoom
		// on the same element is not supported, so don't do it.
		eventNamespace: '.panzoom',

		// Whether or not to transition the scale
		transition: true,

		// Default cursor style for the element
		cursor: 'move',

		// There may be some use cases for zooming without panning or vice versa
		disablePan: false,
		disableZoom: false,

		// The increment at which to zoom
		// adds/subtracts to the scale each time zoomIn/Out is called
		increment: 0.3,

		minScale: 0.4,
		maxScale: 5,

		// The default step for the range input
		// Precendence: default < HTML attribute < option setting
		rangeStep: 0.05,

		// Animation duration (ms)
		duration: 200,
		// CSS easing used for scale transition
		easing: 'ease-in-out',

		// Indicate that the element should be contained within it's parent when panning
		// Note: this does not affect zooming outside of the parent
		// Set this value to 'invert' to only allow panning outside of the parent element (basically the opposite of the normal use of contain)
		// 'invert' is useful for a large panzoom element where you don't want to show anything behind it
		contain: false
	};

	Panzoom.prototype = {
		constructor: Panzoom,

		/**
		 * @returns {Panzoom} Returns the instance
		 */
		instance: function() {
			return this;
		},

		/**
		 * Enable or re-enable the panzoom instance
		 */
		enable: function() {
			// Unbind first
			this._initStyle();
			this._bind();
			this.disabled = false;
		},

		/**
		 * Disable panzoom
		 */
		disable: function() {
			this.disabled = true;
			this._resetStyle();
			this._unbind();
		},

		/**
		 * @returns {Boolean} Returns whether the current panzoom instance is disabled
		 */
		isDisabled: function() {
			return this.disabled;
		},

		/**
		 * Destroy the panzoom instance
		 */
		destroy: function() {
			this.disable();
			$.removeData(this.elem, datakey);
		},

		/**
		 * Builds the restricing dimensions from the containment element
		 * Also used with focal points
		 * Call this method whenever the dimensions of the element or parent are changed
		 */
		resetDimensions: function() {
			// Reset container properties
			var $parent = this.$parent;
			this.container = {
				width: $parent.innerWidth(),
				height: $parent.innerHeight()
			};
			var po = $parent.offset();
			var elem = this.elem;
			var $elem = this.$elem;
			var dims;
			if (this.isSVG) {
				dims = elem.getBoundingClientRect();
				dims = {
					left: dims.left - po.left,
					top: dims.top - po.top,
					width: dims.width,
					height: dims.height,
					margin: { left: 0, top: 0 }
				};
			} else {
				dims = {
					left: $.css(elem, 'left', true) || 0,
					top: $.css(elem, 'top', true) || 0,
					width: $elem.innerWidth(),
					height: $elem.innerHeight(),
					margin: {
						top: $.css(elem, 'marginTop', true) || 0,
						left: $.css(elem, 'marginLeft', true) || 0
					}
				};
			}
			dims.widthBorder = ($.css(elem, 'borderLeftWidth', true) + $.css(elem, 'borderRightWidth', true)) || 0;
			dims.heightBorder = ($.css(elem, 'borderTopWidth', true) + $.css(elem, 'borderBottomWidth', true)) || 0;
			this.dimensions = dims;
		},

		/**
		 * Return the element to it's original transform matrix
		 * @param {Boolean} [options] If a boolean is passed, animate the reset (default: true). If an options object is passed, simply pass that along to setMatrix.
		 * @param {Boolean} [options.silent] Silence the reset event
		 */
		reset: function(options) {
			options = createResetOptions(options);
			// Reset the transform to its original value
			var matrix = this.setMatrix(this._origTransform, options);
			if (!options.silent) {
				this._trigger('reset', matrix);
			}
		},

		/**
		 * Only resets zoom level
		 * @param {Boolean|Object} [options] Whether to animate the reset (default: true) or an object of options to pass to zoom()
		 */
		resetZoom: function(options) {
			options = createResetOptions(options);
			var origMatrix = this.getMatrix(this._origTransform);
			options.dValue = origMatrix[ 3 ];
			this.zoom(origMatrix[0], options);
		},

		/**
		 * Only reset panning
		 * @param {Boolean|Object} [options] Whether to animate the reset (default: true) or an object of options to pass to pan()
		 */
		resetPan: function(options) {
			var origMatrix = this.getMatrix(this._origTransform);
			this.pan(origMatrix[4], origMatrix[5], createResetOptions(options));
		},

		/**
		 * Sets a transform on the $set
		 * @param {String} transform
		 */
		setTransform: function(transform) {
			var method = this.isSVG ? 'attr' : 'style';
			var $set = this.$set;
			var i = $set.length;
			while(i--) {
				$[method]($set[i], 'transform', transform);
			}
		},

		/**
		 * Retrieving the transform is different for SVG
		 *  (unless a style transform is already present)
		 * Uses the $set collection for retrieving the transform
		 * @param {String} [transform] Pass in an transform value (like 'scale(1.1)')
		 *  to have it formatted into matrix format for use by Panzoom
		 * @returns {String} Returns the current transform value of the element
		 */
		getTransform: function(transform) {
			var $set = this.$set;
			var transformElem = $set[0];
			if (transform) {
				this.setTransform(transform);
			} else {
				// Retrieve the transform
				transform = $[this.isSVG ? 'attr' : 'style'](transformElem, 'transform');
			}

			// Convert any transforms set by the user to matrix format
			// by setting to computed
			if (transform !== 'none' && !rmatrix.test(transform)) {
				// Get computed and set for next time
				this.setTransform(transform = $.css(transformElem, 'transform'));
			}

			return transform || 'none';
		},

		/**
		 * Retrieve the current transform matrix for $elem (or turn a transform into it's array values)
		 * @param {String} [transform] matrix-formatted transform value
		 * @returns {Array} Returns the current transform matrix split up into it's parts, or a default matrix
		 */
		getMatrix: function(transform) {
			var matrix = rmatrix.exec(transform || this.getTransform());
			if (matrix) {
				matrix.shift();
			}
			return matrix || [ 1, 0, 0, 1, 0, 0 ];
		},

		/**
		 * Given a matrix object, quickly set the current matrix of the element
		 * @param {Array|String} matrix
		 * @param {Boolean} [animate] Whether to animate the transform change
		 * @param {Object} [options]
		 * @param {Boolean|String} [options.animate] Whether to animate the transform change, or 'skip' indicating that it is unnecessary to set
		 * @param {Boolean} [options.contain] Override the global contain option
		 * @param {Boolean} [options.range] If true, $zoomRange's value will be updated.
		 * @param {Boolean} [options.silent] If true, the change event will not be triggered
		 * @returns {Array} Returns the newly-set matrix
		 */
		setMatrix: function(matrix, options) {
			if (this.disabled) { return; }
			if (!options) { options = {}; }
			// Convert to array
			if (typeof matrix === 'string') {
				matrix = this.getMatrix(matrix);
			}
			var dims, container, marginW, marginH, diffW, diffH, left, top, width, height;
			var scale = +matrix[0];
			var $parent = this.$parent;
			var contain = typeof options.contain !== 'undefined' ? options.contain : this.options.contain;

			// Apply containment
			if (contain) {
				dims = this._checkDims();
				container = this.container;
				width = dims.width + dims.widthBorder;
				height = dims.height + dims.heightBorder;
				// Use absolute value of scale here as negative scale doesn't mean even smaller
				marginW = ((width * Math.abs(scale)) - container.width) / 2;
				marginH = ((height * Math.abs(scale)) - container.height) / 2;
				left = dims.left + dims.margin.left;
				top = dims.top + dims.margin.top;
				if (contain === 'invert') {
					diffW = width > container.width ? width - container.width : 0;
					diffH = height > container.height ? height - container.height : 0;
					marginW += (container.width - width) / 2;
					marginH += (container.height - height) / 2;
					matrix[4] = Math.max(Math.min(matrix[4], marginW - left), -marginW - left - diffW);
					matrix[5] = Math.max(Math.min(matrix[5], marginH - top), -marginH - top - diffH + dims.heightBorder);
				} else {
					// marginW += dims.widthBorder / 2;
					marginH += dims.heightBorder / 2;
					diffW = container.width > width ? container.width - width : 0;
					diffH = container.height > height ? container.height - height : 0;
					// If the element is not naturally centered, assume full margin right
					if ($parent.css('textAlign') !== 'center' || !rinline.test($.css(this.elem, 'display'))) {
						marginW = marginH = 0;
					} else {
						diffW = 0;
					}
					matrix[4] = Math.min(
						Math.max(matrix[4], marginW - left),
						-marginW - left + diffW
					);
					matrix[5] = Math.min(
						Math.max(matrix[5], marginH - top),
						-marginH - top + diffH
					);
				}
			}
			if (options.animate !== 'skip') {
				// Set transition
				this.transition(!options.animate);
			}
			// Update range
			if (options.range) {
				this.$zoomRange.val(scale);
			}

			// Set the matrix on this.$set
			this.setTransform('matrix(' + matrix.join(',') + ')');

			if (!options.silent) {
				this._trigger('change', matrix);
			}

			return matrix;
		},

		/**
		 * @returns {Boolean} Returns whether the panzoom element is currently being dragged
		 */
		isPanning: function() {
			return this.panning;
		},

		/**
		 * Apply the current transition to the element, if allowed
		 * @param {Boolean} [off] Indicates that the transition should be turned off
		 */
		transition: function(off) {
			if (!this._transition) { return; }
			var transition = off || !this.options.transition ? 'none' : this._transition;
			var $set = this.$set;
			var i = $set.length;
			while(i--) {
				// Avoid reflows when zooming
				if ($.style($set[i], 'transition') !== transition) {
					$.style($set[i], 'transition', transition);
				}
			}
		},

		/**
		 * Pan the element to the specified translation X and Y
		 * Note: this is not the same as setting jQuery#offset() or jQuery#position()
		 * @param {Number} x
		 * @param {Number} y
		 * @param {Object} [options] These options are passed along to setMatrix
		 * @param {Array} [options.matrix] The matrix being manipulated (if already known so it doesn't have to be retrieved again)
		 * @param {Boolean} [options.silent] Silence the pan event. Note that this will also silence the setMatrix change event.
		 * @param {Boolean} [options.relative] Make the x and y values relative to the existing matrix
		 */
		pan: function(x, y, options) {
			if (this.options.disablePan) { return; }
			if (!options) { options = {}; }
			var matrix = options.matrix;
			if (!matrix) {
				matrix = this.getMatrix();
			}
			// Cast existing matrix values to numbers
			if (options.relative) {
				x += +matrix[4];
				y += +matrix[5];
			}
			matrix[4] = x;
			matrix[5] = y;
			this.setMatrix(matrix, options);
			if (!options.silent) {
				this._trigger('pan', matrix[4], matrix[5]);
			}
		},

		/**
		 * Zoom in/out the element using the scale properties of a transform matrix
		 * @param {Number|Boolean} [scale] The scale to which to zoom or a boolean indicating to transition a zoom out
		 * @param {Object} [opts] All global options can be overwritten by this options object. For example, override the default increment.
		 * @param {Boolean} [opts.noSetRange] Specify that the method should not set the $zoomRange value (as is the case when $zoomRange is calling zoom on change)
		 * @param {jQuery.Event|Object} [opts.focal] A focal point on the panzoom element on which to zoom.
		 *  If an object, set the clientX and clientY properties to the position relative to the parent
		 * @param {Boolean} [opts.animate] Whether to animate the zoom (defaults to true if scale is not a number, false otherwise)
		 * @param {Boolean} [opts.silent] Silence the zoom event
		 * @param {Array} [opts.matrix] Optionally pass the current matrix so it doesn't need to be retrieved
		 * @param {Number} [opts.dValue] Think of a transform matrix as four values a, b, c, d
		 *  where a/d are the horizontal/vertical scale values and b/c are the skew values
		 *  (5 and 6 of matrix array are the tx/ty transform values).
		 *  Normally, the scale is set to both the a and d values of the matrix.
		 *  This option allows you to specify a different d value for the zoom.
		 *  For instance, to flip vertically, you could set -1 as the dValue.
		 */
		zoom: function(scale, opts) {
			// Shuffle arguments
			if (typeof scale === 'object') {
				opts = scale;
				scale = null;
			} else if (!opts) {
				opts = {};
			}
			var options = $.extend({}, this.options, opts);
			// Check if disabled
			if (options.disableZoom) { return; }
			var animate = false;
			var matrix = options.matrix || this.getMatrix();

			// Calculate zoom based on increment
			if (typeof scale !== 'number') {
				scale = +matrix[0] + (options.increment * (scale ? -1 : 1));
				animate = true;
			}

			// Constrain scale
			if (scale > options.maxScale) {
				scale = options.maxScale;
			} else if (scale < options.minScale) {
				scale = options.minScale;
			}

			// Calculate focal point based on scale
			var focal = options.focal;
			if (focal && !options.disablePan) {
				// Adapted from code by Florian Günther
				// https://github.com/florianguenther/zui53
				var dims = this._checkDims();
				var clientX = focal.clientX;
				var clientY = focal.clientY;
				// Adjust the focal point for default transform-origin => 50% 50%
				if (!this.isSVG) {
					clientX -= (dims.width + dims.widthBorder) / 2;
					clientY -= (dims.height + dims.heightBorder) / 2;
				}
				var clientV = new Vector(clientX, clientY, 1);
				var surfaceM = new Matrix(matrix);
				// Supply an offset manually if necessary
				var o = this.parentOffset || this.$parent.offset();
				var offsetM = new Matrix(1, 0, o.left - this.$doc.scrollLeft(), 0, 1, o.top - this.$doc.scrollTop());
				var surfaceV = surfaceM.inverse().x(offsetM.inverse().x(clientV));
				var scaleBy = scale / matrix[0];
				surfaceM = surfaceM.x(new Matrix([ scaleBy, 0, 0, scaleBy, 0, 0 ]));
				clientV = offsetM.x(surfaceM.x(surfaceV));
				matrix[4] = +matrix[4] + (clientX - clientV.e(0));
				matrix[5] = +matrix[5] + (clientY - clientV.e(1));
			}

			// Set the scale
			matrix[0] = scale;
			matrix[3] = typeof options.dValue === 'number' ? options.dValue : scale;

			// Calling zoom may still pan the element
			this.setMatrix(matrix, {
				animate: typeof options.animate === 'boolean' ? options.animate : animate,
				// Set the zoomRange value
				range: !options.noSetRange
			});

			// Trigger zoom event
			if (!options.silent) {
				this._trigger('zoom', matrix[0], options);
			}
		},

		/**
		 * Get/set option on an existing instance
		 * @returns {Array|undefined} If getting, returns an array of all values
		 *   on each instance for a given key. If setting, continue chaining by returning undefined.
		 */
		option: function(key, value) {
			var options;
			if (!key) {
				// Avoids returning direct reference
				return $.extend({}, this.options);
			}

			if (typeof key === 'string') {
				if (arguments.length === 1) {
					return this.options[ key ] !== undefined ?
						this.options[ key ] :
						null;
				}
				options = {};
				options[ key ] = value;
			} else {
				options = key;
			}

			this._setOptions(options);
		},

		/**
		 * Internally sets options
		 * @param {Object} options - An object literal of options to set
		 */
		_setOptions: function(options) {
			$.each(options, $.proxy(function(key, value) {
				switch(key) {
					case 'disablePan':
						this._resetStyle();
						/* falls through */
					case '$zoomIn':
					case '$zoomOut':
					case '$zoomRange':
					case '$reset':
					case 'disableZoom':
					case 'onStart':
					case 'onChange':
					case 'onZoom':
					case 'onPan':
					case 'onEnd':
					case 'onReset':
					case 'eventNamespace':
						this._unbind();
				}
				this.options[ key ] = value;
				switch(key) {
					case 'disablePan':
						this._initStyle();
						/* falls through */
					case '$zoomIn':
					case '$zoomOut':
					case '$zoomRange':
					case '$reset':
						// Set these on the instance
						this[ key ] = value;
						/* falls through */
					case 'disableZoom':
					case 'onStart':
					case 'onChange':
					case 'onZoom':
					case 'onPan':
					case 'onEnd':
					case 'onReset':
					case 'eventNamespace':
						this._bind();
						break;
					case 'cursor':
						$.style(this.elem, 'cursor', value);
						break;
					case 'minScale':
						this.$zoomRange.attr('min', value);
						break;
					case 'maxScale':
						this.$zoomRange.attr('max', value);
						break;
					case 'rangeStep':
						this.$zoomRange.attr('step', value);
						break;
					case 'startTransform':
						this._buildTransform();
						break;
					case 'duration':
					case 'easing':
						this._buildTransition();
						/* falls through */
					case 'transition':
						this.transition();
						break;
					case '$set':
						if (value instanceof $ && value.length) {
							this.$set = value;
							// Reset styles
							this._initStyle();
							this._buildTransform();
						}
				}
			}, this));
		},

		/**
		 * Initialize base styles for the element and its parent
		 */
		_initStyle: function() {
			var styles = {
				// Promote the element to it's own compositor layer
				'backface-visibility': 'hidden',
				// Set to defaults for the namespace
				'transform-origin': this.isSVG ? '0 0' : '50% 50%'
			};
			// Set elem styles
			if (!this.options.disablePan) {
				styles.cursor = this.options.cursor;
			}
			this.$set.css(styles);

			// Set parent to relative if set to static
			var $parent = this.$parent;
			// No need to add styles to the body
			if ($parent.length && !$.nodeName($parent[0], 'body')) {
				styles = {
					overflow: 'hidden'
				};
				if ($parent.css('position') === 'static') {
					styles.position = 'relative';
				}
				$parent.css(styles);
			}
		},

		/**
		 * Undo any styles attached in this plugin
		 */
		_resetStyle: function() {
			this.$elem.css({
				'cursor': '',
				'transition': ''
			});
			this.$parent.css({
				'overflow': '',
				'position': ''
			});
		},

		/**
		 * Binds all necessary events
		 */
		_bind: function() {
			var self = this;
			var options = this.options;
			var ns = options.eventNamespace;
			var str_start = pointerEvents ? 'pointerdown' + ns : ('touchstart' + ns + ' mousedown' + ns);
			var str_click = pointerEvents ? 'pointerup' + ns : ('touchend' + ns + ' click' + ns);
			var events = {};
			var $reset = this.$reset;
			var $zoomRange = this.$zoomRange;

			// Bind panzoom events from options
			$.each([ 'Start', 'Change', 'Zoom', 'Pan', 'End', 'Reset' ], function() {
				var m = options[ 'on' + this ];
				if ($.isFunction(m)) {
					events[ 'panzoom' + this.toLowerCase() + ns ] = m;
				}
			});

			// Bind $elem drag and click/touchdown events
			// Bind touchstart if either panning or zooming is enabled
			if (!options.disablePan || !options.disableZoom) {
				events[ str_start ] = function(e) {
					var touches;
					if (e.type === 'touchstart' ?
						// Touch
						(touches = e.touches) &&
							((touches.length === 1 && !options.disablePan) || touches.length === 2) :
						// Mouse/Pointer: Ignore right click
						!options.disablePan && e.which === 1) {

						e.preventDefault();
						e.stopPropagation();
						self._startMove(e, touches);
					}
				};
			}
			this.$elem.on(events);

			// Bind reset
			if ($reset.length) {
				$reset.on(str_click, function(e) {
					e.preventDefault();
					self.reset();
				});
			}

			// Set default attributes for the range input
			if ($zoomRange.length) {
				$zoomRange.attr({
					// Only set the range step if explicit or
					// set the default if there is no attribute present
					step: options.rangeStep === Panzoom.defaults.rangeStep &&
						$zoomRange.attr('step') ||
						options.rangeStep,
					min: options.minScale,
					max: options.maxScale
				}).prop({
					value: this.getMatrix()[0]
				});
			}

			// No bindings if zooming is disabled
			if (options.disableZoom) {
				return;
			}

			var $zoomIn = this.$zoomIn;
			var $zoomOut = this.$zoomOut;

			// Bind zoom in/out
			// Don't bind one without the other
			if ($zoomIn.length && $zoomOut.length) {
				// preventDefault cancels future mouse events on touch events
				$zoomIn.on(str_click, function(e) {
					e.preventDefault();
					self.zoom();
				});
				$zoomOut.on(str_click, function(e) {
					e.preventDefault();
					self.zoom(true);
				});
			}

			if ($zoomRange.length) {
				events = {};
				// Cannot prevent default action here, just use pointerdown/mousedown
				events[ (pointerEvents ? 'pointerdown' : 'mousedown') + ns ] = function() {
					self.transition(true);
				};
				events[ 'change' + ns ] = function() {
					self.zoom(+this.value, { noSetRange: true });
				};
				$zoomRange.on(events);
			}
		},

		/**
		 * Unbind all events
		 */
		_unbind: function() {
			this.$elem
				.add(this.$zoomIn)
				.add(this.$zoomOut)
				.add(this.$reset)
				.off(this.options.eventNamespace);
		},

		/**
		 * Builds the original transform value
		 */
		_buildTransform: function() {
			// Save the original transform
			// Retrieving this also adds the correct prefixed style name
			// to jQuery's internal $.cssProps
			return this._origTransform = this.getTransform(this.options.startTransform);
		},

		/**
		 * Set transition property for later use when zooming
		 * If SVG, create necessary animations elements for translations and scaling
		 */
		_buildTransition: function() {
			if (this._transform) {
				var options = this.options;
				this._transition = this._transform + ' ' + options.duration + 'ms ' + options.easing;
			}
		},

		/**
		 * Checks dimensions to make sure they don't need to be re-calculated
		 */
		_checkDims: function() {
			var dims = this.dimensions;
			// Rebuild if width or height is still 0
			if (!dims.width || !dims.height) {
				this.resetDimensions();
			}
			return this.dimensions;
		},

		/**
		 * Calculates the distance between two touch points
		 * Remember pythagorean?
		 * @param {Array} touches
		 * @returns {Number} Returns the distance
		 */
		_getDistance: function(touches) {
			var touch1 = touches[0];
			var touch2 = touches[1];
			return Math.sqrt(Math.pow(Math.abs(touch2.clientX - touch1.clientX), 2) + Math.pow(Math.abs(touch2.clientY - touch1.clientY), 2));
		},

		/**
		 * Constructs an approximated point in the middle of two touch points
		 * @returns {Object} Returns an object containing pageX and pageY
		 */
		_getMiddle: function(touches) {
			var touch1 = touches[0];
			var touch2 = touches[1];
			return {
				clientX: ((touch2.clientX - touch1.clientX) / 2) + touch1.clientX,
				clientY: ((touch2.clientY - touch1.clientY) / 2) + touch1.clientY
			};
		},

		/**
		 * Trigger a panzoom event on our element
		 * The event is passed the Panzoom instance
		 * @param {String|jQuery.Event} event
		 * @param {Mixed} arg1[, arg2, arg3, ...] Arguments to append to the trigger
		 */
		_trigger: function (event) {
			if (typeof event === 'string') {
				event = 'panzoom' + event;
			}
			this.$elem.triggerHandler(event, [this].concat(slice.call(arguments, 1)));
		},

		/**
		 * Starts the pan
		 * This is bound to mouse/touchmove on the element
		 * @param {jQuery.Event} event An event with pageX, pageY, and possibly the touches list
		 * @param {TouchList} [touches] The touches list if present
		 */
		_startMove: function(event, touches) {
			var move, moveEvent, endEvent,
				startDistance, startScale, startMiddle,
				startPageX, startPageY;
			var self = this;
			var options = this.options;
			var ns = options.eventNamespace;
			var matrix = this.getMatrix();
			var original = matrix.slice(0);
			var origPageX = +original[4];
			var origPageY = +original[5];
			var panOptions = { matrix: matrix, animate: 'skip' };

			// Use proper events
			if (pointerEvents) {
				moveEvent = 'pointermove';
				endEvent = 'pointerup';
			} else if (event.type === 'touchstart') {
				moveEvent = 'touchmove';
				endEvent = 'touchend';
			} else {
				moveEvent = 'mousemove';
				endEvent = 'mouseup';
			}

			// Add namespace
			moveEvent += ns;
			endEvent += ns;

			// Remove any transitions happening
			this.transition(true);

			// Indicate that we are currently panning
			this.panning = true;

			// Trigger start event
			this._trigger('start', event, touches);

			if (touches && touches.length === 2) {
				startDistance = this._getDistance(touches);
				startScale = +matrix[0];
				startMiddle = this._getMiddle(touches);
				move = function(e) {
					e.preventDefault();

					// Calculate move on middle point
					var middle = self._getMiddle(touches = e.touches);
					var diff = self._getDistance(touches) - startDistance;

					// Set zoom
					self.zoom(diff * (options.increment / 100) + startScale, {
						focal: middle,
						matrix: matrix,
						animate: false
					});

					// Set pan
					self.pan(
						+matrix[4] + middle.clientX - startMiddle.clientX,
						+matrix[5] + middle.clientY - startMiddle.clientY,
						panOptions
					);
					startMiddle = middle;
				};
			} else {
				startPageX = event.pageX;
				startPageY = event.pageY;

				/**
				 * Mousemove/touchmove function to pan the element
				 * @param {Object} e Event object
				 */
				move = function(e) {
					e.preventDefault();
					self.pan(
						origPageX + e.pageX - startPageX,
						origPageY + e.pageY - startPageY,
						panOptions
					);
				};
			}

			// Bind the handlers
			$(document)
				.off(ns)
				.on(moveEvent, move)
				.on(endEvent, function(e) {
					e.preventDefault();
					// Unbind all document events
					$(this).off(ns);
					self.panning = false;
					// Trigger our end event
					// Simply set the type to "panzoomend" to pass through all end properties
					// jQuery's `not` is used here to compare Array equality
					e.type = 'panzoomend';
					self._trigger(e, matrix, !matrixEquals(matrix, original));
				});
		}
	};

	// Add Panzoom as a static property
	$.Panzoom = Panzoom;

	/**
	 * Extend jQuery
	 * @param {Object|String} options - The name of a method to call on the prototype
	 *  or an object literal of options
	 * @returns {jQuery|Mixed} jQuery instance for regular chaining or the return value(s) of a panzoom method call
	 */
	$.fn.panzoom = function(options) {
		var instance, args, m, ret;

		// Call methods widget-style
		if (typeof options === 'string') {
			ret = [];
			args = slice.call(arguments, 1);
			this.each(function() {
				instance = $.data(this, datakey);

				if (!instance) {
					ret.push(undefined);

				// Ignore methods beginning with `_`
				} else if (options.charAt(0) !== '_' &&
					typeof (m = instance[ options ]) === 'function' &&
					// If nothing is returned, do not add to return values
					(m = m.apply(instance, args)) !== undefined) {

					ret.push(m);
				}
			});

			// Return an array of values for the jQuery instances
			// Or the value itself if there is only one
			// Or keep chaining
			return ret.length ?
				(ret.length === 1 ? ret[0] : ret) :
				this;
		}

		return this.each(function() { new Panzoom(this, options); });
	};

	return Panzoom;
}));

},{"jquery":628}],628:[function(require,module,exports){
(function (global){
; var __browserify_shim_require__=require;(function browserifyShim(module, exports, require, define, browserify_shim__define__module__export__) {
/*!
 * jQuery JavaScript Library v2.2.4
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2016-05-20T17:23Z
 */

(function( global, factory ) {

	if ( typeof module === "object" && typeof module.exports === "object" ) {
		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

// Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
//"use strict";
var arr = [];

var document = window.document;

var slice = arr.slice;

var concat = arr.concat;

var push = arr.push;

var indexOf = arr.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var support = {};



var
	version = "2.2.4",

	// Define a local copy of jQuery
	jQuery = function( selector, context ) {

		// The jQuery object is actually just the init constructor 'enhanced'
		// Need init if jQuery is called (just allow error to be thrown if not included)
		return new jQuery.fn.init( selector, context );
	},

	// Support: Android<4.1
	// Make sure we trim BOM and NBSP
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,

	// Matches dashed string for camelizing
	rmsPrefix = /^-ms-/,
	rdashAlpha = /-([\da-z])/gi,

	// Used by jQuery.camelCase as callback to replace()
	fcamelCase = function( all, letter ) {
		return letter.toUpperCase();
	};

jQuery.fn = jQuery.prototype = {

	// The current version of jQuery being used
	jquery: version,

	constructor: jQuery,

	// Start with an empty selector
	selector: "",

	// The default length of a jQuery object is 0
	length: 0,

	toArray: function() {
		return slice.call( this );
	},

	// Get the Nth element in the matched element set OR
	// Get the whole matched element set as a clean array
	get: function( num ) {
		return num != null ?

			// Return just the one element from the set
			( num < 0 ? this[ num + this.length ] : this[ num ] ) :

			// Return all the elements in a clean array
			slice.call( this );
	},

	// Take an array of elements and push it onto the stack
	// (returning the new matched element set)
	pushStack: function( elems ) {

		// Build a new jQuery matched element set
		var ret = jQuery.merge( this.constructor(), elems );

		// Add the old object onto the stack (as a reference)
		ret.prevObject = this;
		ret.context = this.context;

		// Return the newly-formed element set
		return ret;
	},

	// Execute a callback for every element in the matched set.
	each: function( callback ) {
		return jQuery.each( this, callback );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map( this, function( elem, i ) {
			return callback.call( elem, i, elem );
		} ) );
	},

	slice: function() {
		return this.pushStack( slice.apply( this, arguments ) );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	eq: function( i ) {
		var len = this.length,
			j = +i + ( i < 0 ? len : 0 );
		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
	},

	end: function() {
		return this.prevObject || this.constructor();
	},

	// For internal use only.
	// Behaves like an Array's method, not like a jQuery method.
	push: push,
	sort: arr.sort,
	splice: arr.splice
};

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[ 0 ] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;

		// Skip the boolean and the target
		target = arguments[ i ] || {};
		i++;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
		target = {};
	}

	// Extend jQuery itself if only one argument is passed
	if ( i === length ) {
		target = this;
		i--;
	}

	for ( ; i < length; i++ ) {

		// Only deal with non-null/undefined values
		if ( ( options = arguments[ i ] ) != null ) {

			// Extend the base object
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				// Prevent never-ending loop
				if ( target === copy ) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
					( copyIsArray = jQuery.isArray( copy ) ) ) ) {

					if ( copyIsArray ) {
						copyIsArray = false;
						clone = src && jQuery.isArray( src ) ? src : [];

					} else {
						clone = src && jQuery.isPlainObject( src ) ? src : {};
					}

					// Never move original objects, clone them
					target[ name ] = jQuery.extend( deep, clone, copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

jQuery.extend( {

	// Unique for each copy of jQuery on the page
	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),

	// Assume jQuery is ready without the ready module
	isReady: true,

	error: function( msg ) {
		throw new Error( msg );
	},

	noop: function() {},

	isFunction: function( obj ) {
		return jQuery.type( obj ) === "function";
	},

	isArray: Array.isArray,

	isWindow: function( obj ) {
		return obj != null && obj === obj.window;
	},

	isNumeric: function( obj ) {

		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
		// subtraction forces infinities to NaN
		// adding 1 corrects loss of precision from parseFloat (#15100)
		var realStringObj = obj && obj.toString();
		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
	},

	isPlainObject: function( obj ) {
		var key;

		// Not plain objects:
		// - Any object or value whose internal [[Class]] property is not "[object Object]"
		// - DOM nodes
		// - window
		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
			return false;
		}

		// Not own constructor property must be Object
		if ( obj.constructor &&
				!hasOwn.call( obj, "constructor" ) &&
				!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
			return false;
		}

		// Own properties are enumerated firstly, so to speed up,
		// if last one is own, then all properties are own
		for ( key in obj ) {}

		return key === undefined || hasOwn.call( obj, key );
	},

	isEmptyObject: function( obj ) {
		var name;
		for ( name in obj ) {
			return false;
		}
		return true;
	},

	type: function( obj ) {
		if ( obj == null ) {
			return obj + "";
		}

		// Support: Android<4.0, iOS<6 (functionish RegExp)
		return typeof obj === "object" || typeof obj === "function" ?
			class2type[ toString.call( obj ) ] || "object" :
			typeof obj;
	},

	// Evaluates a script in a global context
	globalEval: function( code ) {
		var script,
			indirect = eval;

		code = jQuery.trim( code );

		if ( code ) {

			// If the code includes a valid, prologue position
			// strict mode pragma, execute code by injecting a
			// script tag into the document.
			if ( code.indexOf( "use strict" ) === 1 ) {
				script = document.createElement( "script" );
				script.text = code;
				document.head.appendChild( script ).parentNode.removeChild( script );
			} else {

				// Otherwise, avoid the DOM node creation, insertion
				// and removal by using an indirect global eval

				indirect( code );
			}
		}
	},

	// Convert dashed to camelCase; used by the css and data modules
	// Support: IE9-11+
	// Microsoft forgot to hump their vendor prefix (#9572)
	camelCase: function( string ) {
		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
	},

	nodeName: function( elem, name ) {
		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	},

	each: function( obj, callback ) {
		var length, i = 0;

		if ( isArrayLike( obj ) ) {
			length = obj.length;
			for ( ; i < length; i++ ) {
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		} else {
			for ( i in obj ) {
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		}

		return obj;
	},

	// Support: Android<4.1
	trim: function( text ) {
		return text == null ?
			"" :
			( text + "" ).replace( rtrim, "" );
	},

	// results is for internal usage only
	makeArray: function( arr, results ) {
		var ret = results || [];

		if ( arr != null ) {
			if ( isArrayLike( Object( arr ) ) ) {
				jQuery.merge( ret,
					typeof arr === "string" ?
					[ arr ] : arr
				);
			} else {
				push.call( ret, arr );
			}
		}

		return ret;
	},

	inArray: function( elem, arr, i ) {
		return arr == null ? -1 : indexOf.call( arr, elem, i );
	},

	merge: function( first, second ) {
		var len = +second.length,
			j = 0,
			i = first.length;

		for ( ; j < len; j++ ) {
			first[ i++ ] = second[ j ];
		}

		first.length = i;

		return first;
	},

	grep: function( elems, callback, invert ) {
		var callbackInverse,
			matches = [],
			i = 0,
			length = elems.length,
			callbackExpect = !invert;

		// Go through the array, only saving the items
		// that pass the validator function
		for ( ; i < length; i++ ) {
			callbackInverse = !callback( elems[ i ], i );
			if ( callbackInverse !== callbackExpect ) {
				matches.push( elems[ i ] );
			}
		}

		return matches;
	},

	// arg is for internal usage only
	map: function( elems, callback, arg ) {
		var length, value,
			i = 0,
			ret = [];

		// Go through the array, translating each of the items to their new values
		if ( isArrayLike( elems ) ) {
			length = elems.length;
			for ( ; i < length; i++ ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}

		// Go through every key on the object,
		} else {
			for ( i in elems ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}
		}

		// Flatten any nested arrays
		return concat.apply( [], ret );
	},

	// A global GUID counter for objects
	guid: 1,

	// Bind a function to a context, optionally partially applying any
	// arguments.
	proxy: function( fn, context ) {
		var tmp, args, proxy;

		if ( typeof context === "string" ) {
			tmp = fn[ context ];
			context = fn;
			fn = tmp;
		}

		// Quick check to determine if target is callable, in the spec
		// this throws a TypeError, but we will just return undefined.
		if ( !jQuery.isFunction( fn ) ) {
			return undefined;
		}

		// Simulated bind
		args = slice.call( arguments, 2 );
		proxy = function() {
			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
		};

		// Set the guid of unique handler to the same of original handler, so it can be removed
		proxy.guid = fn.guid = fn.guid || jQuery.guid++;

		return proxy;
	},

	now: Date.now,

	// jQuery.support is not used in Core but other projects attach their
	// properties to it so it needs to exist.
	support: support
} );

// JSHint would error on this code due to the Symbol not being defined in ES5.
// Defining this global in .jshintrc would create a danger of using the global
// unguarded in another place, it seems safer to just disable JSHint for these
// three lines.
/* jshint ignore: start */
if ( typeof Symbol === "function" ) {
	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}
/* jshint ignore: end */

// Populate the class2type map
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
function( i, name ) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
} );

function isArrayLike( obj ) {

	// Support: iOS 8.2 (not reproducible in simulator)
	// `in` check used to prevent JIT error (gh-2145)
	// hasOwn isn't used here due to false negatives
	// regarding Nodelist length in IE
	var length = !!obj && "length" in obj && obj.length,
		type = jQuery.type( obj );

	if ( type === "function" || jQuery.isWindow( obj ) ) {
		return false;
	}

	return type === "array" || length === 0 ||
		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
var Sizzle =
/*!
 * Sizzle CSS Selector Engine v2.2.1
 * http://sizzlejs.com/
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2015-10-17
 */
(function( window ) {

var i,
	support,
	Expr,
	getText,
	isXML,
	tokenize,
	compile,
	select,
	outermostContext,
	sortInput,
	hasDuplicate,

	// Local document vars
	setDocument,
	document,
	docElem,
	documentIsHTML,
	rbuggyQSA,
	rbuggyMatches,
	matches,
	contains,

	// Instance-specific data
	expando = "sizzle" + 1 * new Date(),
	preferredDoc = window.document,
	dirruns = 0,
	done = 0,
	classCache = createCache(),
	tokenCache = createCache(),
	compilerCache = createCache(),
	sortOrder = function( a, b ) {
		if ( a === b ) {
			hasDuplicate = true;
		}
		return 0;
	},

	// General-purpose constants
	MAX_NEGATIVE = 1 << 31,

	// Instance methods
	hasOwn = ({}).hasOwnProperty,
	arr = [],
	pop = arr.pop,
	push_native = arr.push,
	push = arr.push,
	slice = arr.slice,
	// Use a stripped-down indexOf as it's faster than native
	// http://jsperf.com/thor-indexof-vs-for/5
	indexOf = function( list, elem ) {
		var i = 0,
			len = list.length;
		for ( ; i < len; i++ ) {
			if ( list[i] === elem ) {
				return i;
			}
		}
		return -1;
	},

	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",

	// Regular expressions

	// http://www.w3.org/TR/css3-selectors/#whitespace
	whitespace = "[\\x20\\t\\r\\n\\f]",

	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
		// Operator (capture 2)
		"*([*^$|!~]?=)" + whitespace +
		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
		"*\\]",

	pseudos = ":(" + identifier + ")(?:\\((" +
		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
		// 1. quoted (capture 3; capture 4 or capture 5)
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
		// 2. simple (capture 6)
		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
		// 3. anything else (capture 2)
		".*" +
		")\\)|)",

	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
	rwhitespace = new RegExp( whitespace + "+", "g" ),
	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),

	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),

	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),

	rpseudo = new RegExp( pseudos ),
	ridentifier = new RegExp( "^" + identifier + "$" ),

	matchExpr = {
		"ID": new RegExp( "^#(" + identifier + ")" ),
		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
		"ATTR": new RegExp( "^" + attributes ),
		"PSEUDO": new RegExp( "^" + pseudos ),
		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
		// For use in libraries implementing .is()
		// We use this for POS matching in `select`
		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
	},

	rinputs = /^(?:input|select|textarea|button)$/i,
	rheader = /^h\d$/i,

	rnative = /^[^{]+\{\s*\[native \w/,

	// Easily-parseable/retrievable ID or TAG or CLASS selectors
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

	rsibling = /[+~]/,
	rescape = /'|\\/g,

	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
	funescape = function( _, escaped, escapedWhitespace ) {
		var high = "0x" + escaped - 0x10000;
		// NaN means non-codepoint
		// Support: Firefox<24
		// Workaround erroneous numeric interpretation of +"0x"
		return high !== high || escapedWhitespace ?
			escaped :
			high < 0 ?
				// BMP codepoint
				String.fromCharCode( high + 0x10000 ) :
				// Supplemental Plane codepoint (surrogate pair)
				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
	},

	// Used for iframes
	// See setDocument()
	// Removing the function wrapper causes a "Permission Denied"
	// error in IE
	unloadHandler = function() {
		setDocument();
	};

// Optimize for push.apply( _, NodeList )
try {
	push.apply(
		(arr = slice.call( preferredDoc.childNodes )),
		preferredDoc.childNodes
	);
	// Support: Android<4.0
	// Detect silently failing push.apply
	arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
	push = { apply: arr.length ?

		// Leverage slice if possible
		function( target, els ) {
			push_native.apply( target, slice.call(els) );
		} :

		// Support: IE<9
		// Otherwise append directly
		function( target, els ) {
			var j = target.length,
				i = 0;
			// Can't trust NodeList.length
			while ( (target[j++] = els[i++]) ) {}
			target.length = j - 1;
		}
	};
}

function Sizzle( selector, context, results, seed ) {
	var m, i, elem, nid, nidselect, match, groups, newSelector,
		newContext = context && context.ownerDocument,

		// nodeType defaults to 9, since context defaults to document
		nodeType = context ? context.nodeType : 9;

	results = results || [];

	// Return early from calls with invalid selector or context
	if ( typeof selector !== "string" || !selector ||
		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

		return results;
	}

	// Try to shortcut find operations (as opposed to filters) in HTML documents
	if ( !seed ) {

		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
			setDocument( context );
		}
		context = context || document;

		if ( documentIsHTML ) {

			// If the selector is sufficiently simple, try using a "get*By*" DOM method
			// (excepting DocumentFragment context, where the methods don't exist)
			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {

				// ID selector
				if ( (m = match[1]) ) {

					// Document context
					if ( nodeType === 9 ) {
						if ( (elem = context.getElementById( m )) ) {

							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( elem.id === m ) {
								results.push( elem );
								return results;
							}
						} else {
							return results;
						}

					// Element context
					} else {

						// Support: IE, Opera, Webkit
						// TODO: identify versions
						// getElementById can match elements by name instead of ID
						if ( newContext && (elem = newContext.getElementById( m )) &&
							contains( context, elem ) &&
							elem.id === m ) {

							results.push( elem );
							return results;
						}
					}

				// Type selector
				} else if ( match[2] ) {
					push.apply( results, context.getElementsByTagName( selector ) );
					return results;

				// Class selector
				} else if ( (m = match[3]) && support.getElementsByClassName &&
					context.getElementsByClassName ) {

					push.apply( results, context.getElementsByClassName( m ) );
					return results;
				}
			}

			// Take advantage of querySelectorAll
			if ( support.qsa &&
				!compilerCache[ selector + " " ] &&
				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {

				if ( nodeType !== 1 ) {
					newContext = context;
					newSelector = selector;

				// qSA looks outside Element context, which is not what we want
				// Thanks to Andrew Dupont for this workaround technique
				// Support: IE <=8
				// Exclude object elements
				} else if ( context.nodeName.toLowerCase() !== "object" ) {

					// Capture the context ID, setting it first if necessary
					if ( (nid = context.getAttribute( "id" )) ) {
						nid = nid.replace( rescape, "\\$&" );
					} else {
						context.setAttribute( "id", (nid = expando) );
					}

					// Prefix every selector in the list
					groups = tokenize( selector );
					i = groups.length;
					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
					while ( i-- ) {
						groups[i] = nidselect + " " + toSelector( groups[i] );
					}
					newSelector = groups.join( "," );

					// Expand context for sibling selectors
					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
						context;
				}

				if ( newSelector ) {
					try {
						push.apply( results,
							newContext.querySelectorAll( newSelector )
						);
						return results;
					} catch ( qsaError ) {
					} finally {
						if ( nid === expando ) {
							context.removeAttribute( "id" );
						}
					}
				}
			}
		}
	}

	// All others
	return select( selector.replace( rtrim, "$1" ), context, results, seed );
}

/**
 * Create key-value caches of limited size
 * @returns {function(string, object)} Returns the Object data after storing it on itself with
 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
 *	deleting the oldest entry
 */
function createCache() {
	var keys = [];

	function cache( key, value ) {
		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
		if ( keys.push( key + " " ) > Expr.cacheLength ) {
			// Only keep the most recent entries
			delete cache[ keys.shift() ];
		}
		return (cache[ key + " " ] = value);
	}
	return cache;
}

/**
 * Mark a function for special use by Sizzle
 * @param {Function} fn The function to mark
 */
function markFunction( fn ) {
	fn[ expando ] = true;
	return fn;
}

/**
 * Support testing using an element
 * @param {Function} fn Passed the created div and expects a boolean result
 */
function assert( fn ) {
	var div = document.createElement("div");

	try {
		return !!fn( div );
	} catch (e) {
		return false;
	} finally {
		// Remove from its parent by default
		if ( div.parentNode ) {
			div.parentNode.removeChild( div );
		}
		// release memory in IE
		div = null;
	}
}

/**
 * Adds the same handler for all of the specified attrs
 * @param {String} attrs Pipe-separated list of attributes
 * @param {Function} handler The method that will be applied
 */
function addHandle( attrs, handler ) {
	var arr = attrs.split("|"),
		i = arr.length;

	while ( i-- ) {
		Expr.attrHandle[ arr[i] ] = handler;
	}
}

/**
 * Checks document order of two siblings
 * @param {Element} a
 * @param {Element} b
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
 */
function siblingCheck( a, b ) {
	var cur = b && a,
		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
			( ~b.sourceIndex || MAX_NEGATIVE ) -
			( ~a.sourceIndex || MAX_NEGATIVE );

	// Use IE sourceIndex if available on both nodes
	if ( diff ) {
		return diff;
	}

	// Check if b follows a
	if ( cur ) {
		while ( (cur = cur.nextSibling) ) {
			if ( cur === b ) {
				return -1;
			}
		}
	}

	return a ? 1 : -1;
}

/**
 * Returns a function to use in pseudos for input types
 * @param {String} type
 */
function createInputPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return name === "input" && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for buttons
 * @param {String} type
 */
function createButtonPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return (name === "input" || name === "button") && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for positionals
 * @param {Function} fn
 */
function createPositionalPseudo( fn ) {
	return markFunction(function( argument ) {
		argument = +argument;
		return markFunction(function( seed, matches ) {
			var j,
				matchIndexes = fn( [], seed.length, argument ),
				i = matchIndexes.length;

			// Match elements found at the specified indexes
			while ( i-- ) {
				if ( seed[ (j = matchIndexes[i]) ] ) {
					seed[j] = !(matches[j] = seed[j]);
				}
			}
		});
	});
}

/**
 * Checks a node for validity as a Sizzle context
 * @param {Element|Object=} context
 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
 */
function testContext( context ) {
	return context && typeof context.getElementsByTagName !== "undefined" && context;
}

// Expose support vars for convenience
support = Sizzle.support = {};

/**
 * Detects XML nodes
 * @param {Element|Object} elem An element or a document
 * @returns {Boolean} True iff elem is a non-HTML XML node
 */
isXML = Sizzle.isXML = function( elem ) {
	// documentElement is verified for cases where it doesn't yet exist
	// (such as loading iframes in IE - #4833)
	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
	return documentElement ? documentElement.nodeName !== "HTML" : false;
};

/**
 * Sets document-related variables once based on the current document
 * @param {Element|Object} [doc] An element or document object to use to set the document
 * @returns {Object} Returns the current document
 */
setDocument = Sizzle.setDocument = function( node ) {
	var hasCompare, parent,
		doc = node ? node.ownerDocument || node : preferredDoc;

	// Return early if doc is invalid or already selected
	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
		return document;
	}

	// Update global variables
	document = doc;
	docElem = document.documentElement;
	documentIsHTML = !isXML( document );

	// Support: IE 9-11, Edge
	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
	if ( (parent = document.defaultView) && parent.top !== parent ) {
		// Support: IE 11
		if ( parent.addEventListener ) {
			parent.addEventListener( "unload", unloadHandler, false );

		// Support: IE 9 - 10 only
		} else if ( parent.attachEvent ) {
			parent.attachEvent( "onunload", unloadHandler );
		}
	}

	/* Attributes
	---------------------------------------------------------------------- */

	// Support: IE<8
	// Verify that getAttribute really returns attributes and not properties
	// (excepting IE8 booleans)
	support.attributes = assert(function( div ) {
		div.className = "i";
		return !div.getAttribute("className");
	});

	/* getElement(s)By*
	---------------------------------------------------------------------- */

	// Check if getElementsByTagName("*") returns only elements
	support.getElementsByTagName = assert(function( div ) {
		div.appendChild( document.createComment("") );
		return !div.getElementsByTagName("*").length;
	});

	// Support: IE<9
	support.getElementsByClassName = rnative.test( document.getElementsByClassName );

	// Support: IE<10
	// Check if getElementById returns elements by name
	// The broken getElementById methods don't pick up programatically-set names,
	// so use a roundabout getElementsByName test
	support.getById = assert(function( div ) {
		docElem.appendChild( div ).id = expando;
		return !document.getElementsByName || !document.getElementsByName( expando ).length;
	});

	// ID find and filter
	if ( support.getById ) {
		Expr.find["ID"] = function( id, context ) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				var m = context.getElementById( id );
				return m ? [ m ] : [];
			}
		};
		Expr.filter["ID"] = function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				return elem.getAttribute("id") === attrId;
			};
		};
	} else {
		// Support: IE6/7
		// getElementById is not reliable as a find shortcut
		delete Expr.find["ID"];

		Expr.filter["ID"] =  function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				var node = typeof elem.getAttributeNode !== "undefined" &&
					elem.getAttributeNode("id");
				return node && node.value === attrId;
			};
		};
	}

	// Tag
	Expr.find["TAG"] = support.getElementsByTagName ?
		function( tag, context ) {
			if ( typeof context.getElementsByTagName !== "undefined" ) {
				return context.getElementsByTagName( tag );

			// DocumentFragment nodes don't have gEBTN
			} else if ( support.qsa ) {
				return context.querySelectorAll( tag );
			}
		} :

		function( tag, context ) {
			var elem,
				tmp = [],
				i = 0,
				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
				results = context.getElementsByTagName( tag );

			// Filter out possible comments
			if ( tag === "*" ) {
				while ( (elem = results[i++]) ) {
					if ( elem.nodeType === 1 ) {
						tmp.push( elem );
					}
				}

				return tmp;
			}
			return results;
		};

	// Class
	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
			return context.getElementsByClassName( className );
		}
	};

	/* QSA/matchesSelector
	---------------------------------------------------------------------- */

	// QSA and matchesSelector support

	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
	rbuggyMatches = [];

	// qSa(:focus) reports false when true (Chrome 21)
	// We allow this because of a bug in IE8/9 that throws an error
	// whenever `document.activeElement` is accessed on an iframe
	// So, we allow :focus to pass through QSA all the time to avoid the IE error
	// See http://bugs.jquery.com/ticket/13378
	rbuggyQSA = [];

	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
		// Build QSA regex
		// Regex strategy adopted from Diego Perini
		assert(function( div ) {
			// Select is set to empty string on purpose
			// This is to test IE's treatment of not explicitly
			// setting a boolean content attribute,
			// since its presence should be enough
			// http://bugs.jquery.com/ticket/12359
			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
				"<option selected=''></option></select>";

			// Support: IE8, Opera 11-12.16
			// Nothing should be selected when empty strings follow ^= or $= or *=
			// The test attribute must be unknown in Opera but "safe" for WinRT
			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
			}

			// Support: IE8
			// Boolean attributes and "value" are not treated correctly
			if ( !div.querySelectorAll("[selected]").length ) {
				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
			}

			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
				rbuggyQSA.push("~=");
			}

			// Webkit/Opera - :checked should return selected option elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			// IE8 throws error here and will not see later tests
			if ( !div.querySelectorAll(":checked").length ) {
				rbuggyQSA.push(":checked");
			}

			// Support: Safari 8+, iOS 8+
			// https://bugs.webkit.org/show_bug.cgi?id=136851
			// In-page `selector#id sibing-combinator selector` fails
			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
				rbuggyQSA.push(".#.+[+~]");
			}
		});

		assert(function( div ) {
			// Support: Windows 8 Native Apps
			// The type and name attributes are restricted during .innerHTML assignment
			var input = document.createElement("input");
			input.setAttribute( "type", "hidden" );
			div.appendChild( input ).setAttribute( "name", "D" );

			// Support: IE8
			// Enforce case-sensitivity of name attribute
			if ( div.querySelectorAll("[name=d]").length ) {
				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
			}

			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
			// IE8 throws error here and will not see later tests
			if ( !div.querySelectorAll(":enabled").length ) {
				rbuggyQSA.push( ":enabled", ":disabled" );
			}

			// Opera 10-11 does not throw on post-comma invalid pseudos
			div.querySelectorAll("*,:x");
			rbuggyQSA.push(",.*:");
		});
	}

	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
		docElem.webkitMatchesSelector ||
		docElem.mozMatchesSelector ||
		docElem.oMatchesSelector ||
		docElem.msMatchesSelector) )) ) {

		assert(function( div ) {
			// Check to see if it's possible to do matchesSelector
			// on a disconnected node (IE 9)
			support.disconnectedMatch = matches.call( div, "div" );

			// This should fail with an exception
			// Gecko does not error, returns false instead
			matches.call( div, "[s!='']:x" );
			rbuggyMatches.push( "!=", pseudos );
		});
	}

	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );

	/* Contains
	---------------------------------------------------------------------- */
	hasCompare = rnative.test( docElem.compareDocumentPosition );

	// Element contains another
	// Purposefully self-exclusive
	// As in, an element does not contain itself
	contains = hasCompare || rnative.test( docElem.contains ) ?
		function( a, b ) {
			var adown = a.nodeType === 9 ? a.documentElement : a,
				bup = b && b.parentNode;
			return a === bup || !!( bup && bup.nodeType === 1 && (
				adown.contains ?
					adown.contains( bup ) :
					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
			));
		} :
		function( a, b ) {
			if ( b ) {
				while ( (b = b.parentNode) ) {
					if ( b === a ) {
						return true;
					}
				}
			}
			return false;
		};

	/* Sorting
	---------------------------------------------------------------------- */

	// Document order sorting
	sortOrder = hasCompare ?
	function( a, b ) {

		// Flag for duplicate removal
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		// Sort on method existence if only one input has compareDocumentPosition
		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
		if ( compare ) {
			return compare;
		}

		// Calculate position if both inputs belong to the same document
		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
			a.compareDocumentPosition( b ) :

			// Otherwise we know they are disconnected
			1;

		// Disconnected nodes
		if ( compare & 1 ||
			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {

			// Choose the first element that is related to our preferred document
			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
				return -1;
			}
			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
				return 1;
			}

			// Maintain original order
			return sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;
		}

		return compare & 4 ? -1 : 1;
	} :
	function( a, b ) {
		// Exit early if the nodes are identical
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		var cur,
			i = 0,
			aup = a.parentNode,
			bup = b.parentNode,
			ap = [ a ],
			bp = [ b ];

		// Parentless nodes are either documents or disconnected
		if ( !aup || !bup ) {
			return a === document ? -1 :
				b === document ? 1 :
				aup ? -1 :
				bup ? 1 :
				sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;

		// If the nodes are siblings, we can do a quick check
		} else if ( aup === bup ) {
			return siblingCheck( a, b );
		}

		// Otherwise we need full lists of their ancestors for comparison
		cur = a;
		while ( (cur = cur.parentNode) ) {
			ap.unshift( cur );
		}
		cur = b;
		while ( (cur = cur.parentNode) ) {
			bp.unshift( cur );
		}

		// Walk down the tree looking for a discrepancy
		while ( ap[i] === bp[i] ) {
			i++;
		}

		return i ?
			// Do a sibling check if the nodes have a common ancestor
			siblingCheck( ap[i], bp[i] ) :

			// Otherwise nodes in our document sort first
			ap[i] === preferredDoc ? -1 :
			bp[i] === preferredDoc ? 1 :
			0;
	};

	return document;
};

Sizzle.matches = function( expr, elements ) {
	return Sizzle( expr, null, null, elements );
};

Sizzle.matchesSelector = function( elem, expr ) {
	// Set document vars if needed
	if ( ( elem.ownerDocument || elem ) !== document ) {
		setDocument( elem );
	}

	// Make sure that attribute selectors are quoted
	expr = expr.replace( rattributeQuotes, "='$1']" );

	if ( support.matchesSelector && documentIsHTML &&
		!compilerCache[ expr + " " ] &&
		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

		try {
			var ret = matches.call( elem, expr );

			// IE 9's matchesSelector returns false on disconnected nodes
			if ( ret || support.disconnectedMatch ||
					// As well, disconnected nodes are said to be in a document
					// fragment in IE 9
					elem.document && elem.document.nodeType !== 11 ) {
				return ret;
			}
		} catch (e) {}
	}

	return Sizzle( expr, document, null, [ elem ] ).length > 0;
};

Sizzle.contains = function( context, elem ) {
	// Set document vars if needed
	if ( ( context.ownerDocument || context ) !== document ) {
		setDocument( context );
	}
	return contains( context, elem );
};

Sizzle.attr = function( elem, name ) {
	// Set document vars if needed
	if ( ( elem.ownerDocument || elem ) !== document ) {
		setDocument( elem );
	}

	var fn = Expr.attrHandle[ name.toLowerCase() ],
		// Don't get fooled by Object.prototype properties (jQuery #13807)
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
			fn( elem, name, !documentIsHTML ) :
			undefined;

	return val !== undefined ?
		val :
		support.attributes || !documentIsHTML ?
			elem.getAttribute( name ) :
			(val = elem.getAttributeNode(name)) && val.specified ?
				val.value :
				null;
};

Sizzle.error = function( msg ) {
	throw new Error( "Syntax error, unrecognized expression: " + msg );
};

/**
 * Document sorting and removing duplicates
 * @param {ArrayLike} results
 */
Sizzle.uniqueSort = function( results ) {
	var elem,
		duplicates = [],
		j = 0,
		i = 0;

	// Unless we *know* we can detect duplicates, assume their presence
	hasDuplicate = !support.detectDuplicates;
	sortInput = !support.sortStable && results.slice( 0 );
	results.sort( sortOrder );

	if ( hasDuplicate ) {
		while ( (elem = results[i++]) ) {
			if ( elem === results[ i ] ) {
				j = duplicates.push( i );
			}
		}
		while ( j-- ) {
			results.splice( duplicates[ j ], 1 );
		}
	}

	// Clear input after sorting to release objects
	// See https://github.com/jquery/sizzle/pull/225
	sortInput = null;

	return results;
};

/**
 * Utility function for retrieving the text value of an array of DOM nodes
 * @param {Array|Element} elem
 */
getText = Sizzle.getText = function( elem ) {
	var node,
		ret = "",
		i = 0,
		nodeType = elem.nodeType;

	if ( !nodeType ) {
		// If no nodeType, this is expected to be an array
		while ( (node = elem[i++]) ) {
			// Do not traverse comment nodes
			ret += getText( node );
		}
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
		// Use textContent for elements
		// innerText usage removed for consistency of new lines (jQuery #11153)
		if ( typeof elem.textContent === "string" ) {
			return elem.textContent;
		} else {
			// Traverse its children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				ret += getText( elem );
			}
		}
	} else if ( nodeType === 3 || nodeType === 4 ) {
		return elem.nodeValue;
	}
	// Do not include comment or processing instruction nodes

	return ret;
};

Expr = Sizzle.selectors = {

	// Can be adjusted by the user
	cacheLength: 50,

	createPseudo: markFunction,

	match: matchExpr,

	attrHandle: {},

	find: {},

	relative: {
		">": { dir: "parentNode", first: true },
		" ": { dir: "parentNode" },
		"+": { dir: "previousSibling", first: true },
		"~": { dir: "previousSibling" }
	},

	preFilter: {
		"ATTR": function( match ) {
			match[1] = match[1].replace( runescape, funescape );

			// Move the given value to match[3] whether quoted or unquoted
			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );

			if ( match[2] === "~=" ) {
				match[3] = " " + match[3] + " ";
			}

			return match.slice( 0, 4 );
		},

		"CHILD": function( match ) {
			/* matches from matchExpr["CHILD"]
				1 type (only|nth|...)
				2 what (child|of-type)
				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
				4 xn-component of xn+y argument ([+-]?\d*n|)
				5 sign of xn-component
				6 x of xn-component
				7 sign of y-component
				8 y of y-component
			*/
			match[1] = match[1].toLowerCase();

			if ( match[1].slice( 0, 3 ) === "nth" ) {
				// nth-* requires argument
				if ( !match[3] ) {
					Sizzle.error( match[0] );
				}

				// numeric x and y parameters for Expr.filter.CHILD
				// remember that false/true cast respectively to 0/1
				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );

			// other types prohibit arguments
			} else if ( match[3] ) {
				Sizzle.error( match[0] );
			}

			return match;
		},

		"PSEUDO": function( match ) {
			var excess,
				unquoted = !match[6] && match[2];

			if ( matchExpr["CHILD"].test( match[0] ) ) {
				return null;
			}

			// Accept quoted arguments as-is
			if ( match[3] ) {
				match[2] = match[4] || match[5] || "";

			// Strip excess characters from unquoted arguments
			} else if ( unquoted && rpseudo.test( unquoted ) &&
				// Get excess from tokenize (recursively)
				(excess = tokenize( unquoted, true )) &&
				// advance to the next closing parenthesis
				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {

				// excess is a negative index
				match[0] = match[0].slice( 0, excess );
				match[2] = unquoted.slice( 0, excess );
			}

			// Return only captures needed by the pseudo filter method (type and argument)
			return match.slice( 0, 3 );
		}
	},

	filter: {

		"TAG": function( nodeNameSelector ) {
			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
			return nodeNameSelector === "*" ?
				function() { return true; } :
				function( elem ) {
					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
				};
		},

		"CLASS": function( className ) {
			var pattern = classCache[ className + " " ];

			return pattern ||
				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
				classCache( className, function( elem ) {
					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
				});
		},

		"ATTR": function( name, operator, check ) {
			return function( elem ) {
				var result = Sizzle.attr( elem, name );

				if ( result == null ) {
					return operator === "!=";
				}
				if ( !operator ) {
					return true;
				}

				result += "";

				return operator === "=" ? result === check :
					operator === "!=" ? result !== check :
					operator === "^=" ? check && result.indexOf( check ) === 0 :
					operator === "*=" ? check && result.indexOf( check ) > -1 :
					operator === "$=" ? check && result.slice( -check.length ) === check :
					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
					false;
			};
		},

		"CHILD": function( type, what, argument, first, last ) {
			var simple = type.slice( 0, 3 ) !== "nth",
				forward = type.slice( -4 ) !== "last",
				ofType = what === "of-type";

			return first === 1 && last === 0 ?

				// Shortcut for :nth-*(n)
				function( elem ) {
					return !!elem.parentNode;
				} :

				function( elem, context, xml ) {
					var cache, uniqueCache, outerCache, node, nodeIndex, start,
						dir = simple !== forward ? "nextSibling" : "previousSibling",
						parent = elem.parentNode,
						name = ofType && elem.nodeName.toLowerCase(),
						useCache = !xml && !ofType,
						diff = false;

					if ( parent ) {

						// :(first|last|only)-(child|of-type)
						if ( simple ) {
							while ( dir ) {
								node = elem;
								while ( (node = node[ dir ]) ) {
									if ( ofType ?
										node.nodeName.toLowerCase() === name :
										node.nodeType === 1 ) {

										return false;
									}
								}
								// Reverse direction for :only-* (if we haven't yet done so)
								start = dir = type === "only" && !start && "nextSibling";
							}
							return true;
						}

						start = [ forward ? parent.firstChild : parent.lastChild ];

						// non-xml :nth-child(...) stores cache data on `parent`
						if ( forward && useCache ) {

							// Seek `elem` from a previously-cached index

							// ...in a gzip-friendly way
							node = parent;
							outerCache = node[ expando ] || (node[ expando ] = {});

							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ node.uniqueID ] ||
								(outerCache[ node.uniqueID ] = {});

							cache = uniqueCache[ type ] || [];
							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
							diff = nodeIndex && cache[ 2 ];
							node = nodeIndex && parent.childNodes[ nodeIndex ];

							while ( (node = ++nodeIndex && node && node[ dir ] ||

								// Fallback to seeking `elem` from the start
								(diff = nodeIndex = 0) || start.pop()) ) {

								// When found, cache indexes on `parent` and break
								if ( node.nodeType === 1 && ++diff && node === elem ) {
									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
									break;
								}
							}

						} else {
							// Use previously-cached element index if available
							if ( useCache ) {
								// ...in a gzip-friendly way
								node = elem;
								outerCache = node[ expando ] || (node[ expando ] = {});

								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									(outerCache[ node.uniqueID ] = {});

								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex;
							}

							// xml :nth-child(...)
							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
							if ( diff === false ) {
								// Use the same loop as above to seek `elem` from the start
								while ( (node = ++nodeIndex && node && node[ dir ] ||
									(diff = nodeIndex = 0) || start.pop()) ) {

									if ( ( ofType ?
										node.nodeName.toLowerCase() === name :
										node.nodeType === 1 ) &&
										++diff ) {

										// Cache the index of each encountered element
										if ( useCache ) {
											outerCache = node[ expando ] || (node[ expando ] = {});

											// Support: IE <9 only
											// Defend against cloned attroperties (jQuery gh-1709)
											uniqueCache = outerCache[ node.uniqueID ] ||
												(outerCache[ node.uniqueID ] = {});

											uniqueCache[ type ] = [ dirruns, diff ];
										}

										if ( node === elem ) {
											break;
										}
									}
								}
							}
						}

						// Incorporate the offset, then check against cycle size
						diff -= last;
						return diff === first || ( diff % first === 0 && diff / first >= 0 );
					}
				};
		},

		"PSEUDO": function( pseudo, argument ) {
			// pseudo-class names are case-insensitive
			// http://www.w3.org/TR/selectors/#pseudo-classes
			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
			// Remember that setFilters inherits from pseudos
			var args,
				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
					Sizzle.error( "unsupported pseudo: " + pseudo );

			// The user may use createPseudo to indicate that
			// arguments are needed to create the filter function
			// just as Sizzle does
			if ( fn[ expando ] ) {
				return fn( argument );
			}

			// But maintain support for old signatures
			if ( fn.length > 1 ) {
				args = [ pseudo, pseudo, "", argument ];
				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
					markFunction(function( seed, matches ) {
						var idx,
							matched = fn( seed, argument ),
							i = matched.length;
						while ( i-- ) {
							idx = indexOf( seed, matched[i] );
							seed[ idx ] = !( matches[ idx ] = matched[i] );
						}
					}) :
					function( elem ) {
						return fn( elem, 0, args );
					};
			}

			return fn;
		}
	},

	pseudos: {
		// Potentially complex pseudos
		"not": markFunction(function( selector ) {
			// Trim the selector passed to compile
			// to avoid treating leading and trailing
			// spaces as combinators
			var input = [],
				results = [],
				matcher = compile( selector.replace( rtrim, "$1" ) );

			return matcher[ expando ] ?
				markFunction(function( seed, matches, context, xml ) {
					var elem,
						unmatched = matcher( seed, null, xml, [] ),
						i = seed.length;

					// Match elements unmatched by `matcher`
					while ( i-- ) {
						if ( (elem = unmatched[i]) ) {
							seed[i] = !(matches[i] = elem);
						}
					}
				}) :
				function( elem, context, xml ) {
					input[0] = elem;
					matcher( input, null, xml, results );
					// Don't keep the element (issue #299)
					input[0] = null;
					return !results.pop();
				};
		}),

		"has": markFunction(function( selector ) {
			return function( elem ) {
				return Sizzle( selector, elem ).length > 0;
			};
		}),

		"contains": markFunction(function( text ) {
			text = text.replace( runescape, funescape );
			return function( elem ) {
				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
			};
		}),

		// "Whether an element is represented by a :lang() selector
		// is based solely on the element's language value
		// being equal to the identifier C,
		// or beginning with the identifier C immediately followed by "-".
		// The matching of C against the element's language value is performed case-insensitively.
		// The identifier C does not have to be a valid language name."
		// http://www.w3.org/TR/selectors/#lang-pseudo
		"lang": markFunction( function( lang ) {
			// lang value must be a valid identifier
			if ( !ridentifier.test(lang || "") ) {
				Sizzle.error( "unsupported lang: " + lang );
			}
			lang = lang.replace( runescape, funescape ).toLowerCase();
			return function( elem ) {
				var elemLang;
				do {
					if ( (elemLang = documentIsHTML ?
						elem.lang :
						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {

						elemLang = elemLang.toLowerCase();
						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
					}
				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
				return false;
			};
		}),

		// Miscellaneous
		"target": function( elem ) {
			var hash = window.location && window.location.hash;
			return hash && hash.slice( 1 ) === elem.id;
		},

		"root": function( elem ) {
			return elem === docElem;
		},

		"focus": function( elem ) {
			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
		},

		// Boolean properties
		"enabled": function( elem ) {
			return elem.disabled === false;
		},

		"disabled": function( elem ) {
			return elem.disabled === true;
		},

		"checked": function( elem ) {
			// In CSS3, :checked should return both checked and selected elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			var nodeName = elem.nodeName.toLowerCase();
			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
		},

		"selected": function( elem ) {
			// Accessing this property makes selected-by-default
			// options in Safari work properly
			if ( elem.parentNode ) {
				elem.parentNode.selectedIndex;
			}

			return elem.selected === true;
		},

		// Contents
		"empty": function( elem ) {
			// http://www.w3.org/TR/selectors/#empty-pseudo
			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
			//   but not by others (comment: 8; processing instruction: 7; etc.)
			// nodeType < 6 works because attributes (2) do not appear as children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				if ( elem.nodeType < 6 ) {
					return false;
				}
			}
			return true;
		},

		"parent": function( elem ) {
			return !Expr.pseudos["empty"]( elem );
		},

		// Element/input types
		"header": function( elem ) {
			return rheader.test( elem.nodeName );
		},

		"input": function( elem ) {
			return rinputs.test( elem.nodeName );
		},

		"button": function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === "button" || name === "button";
		},

		"text": function( elem ) {
			var attr;
			return elem.nodeName.toLowerCase() === "input" &&
				elem.type === "text" &&

				// Support: IE<8
				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
		},

		// Position-in-collection
		"first": createPositionalPseudo(function() {
			return [ 0 ];
		}),

		"last": createPositionalPseudo(function( matchIndexes, length ) {
			return [ length - 1 ];
		}),

		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
			return [ argument < 0 ? argument + length : argument ];
		}),

		"even": createPositionalPseudo(function( matchIndexes, length ) {
			var i = 0;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"odd": createPositionalPseudo(function( matchIndexes, length ) {
			var i = 1;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
			var i = argument < 0 ? argument + length : argument;
			for ( ; --i >= 0; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		}),

		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
			var i = argument < 0 ? argument + length : argument;
			for ( ; ++i < length; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		})
	}
};

Expr.pseudos["nth"] = Expr.pseudos["eq"];

// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
	Expr.pseudos[ i ] = createInputPseudo( i );
}
for ( i in { submit: true, reset: true } ) {
	Expr.pseudos[ i ] = createButtonPseudo( i );
}

// Easy API for creating new setFilters
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
	var matched, match, tokens, type,
		soFar, groups, preFilters,
		cached = tokenCache[ selector + " " ];

	if ( cached ) {
		return parseOnly ? 0 : cached.slice( 0 );
	}

	soFar = selector;
	groups = [];
	preFilters = Expr.preFilter;

	while ( soFar ) {

		// Comma and first run
		if ( !matched || (match = rcomma.exec( soFar )) ) {
			if ( match ) {
				// Don't consume trailing commas as valid
				soFar = soFar.slice( match[0].length ) || soFar;
			}
			groups.push( (tokens = []) );
		}

		matched = false;

		// Combinators
		if ( (match = rcombinators.exec( soFar )) ) {
			matched = match.shift();
			tokens.push({
				value: matched,
				// Cast descendant combinators to space
				type: match[0].replace( rtrim, " " )
			});
			soFar = soFar.slice( matched.length );
		}

		// Filters
		for ( type in Expr.filter ) {
			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
				(match = preFilters[ type ]( match ))) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					type: type,
					matches: match
				});
				soFar = soFar.slice( matched.length );
			}
		}

		if ( !matched ) {
			break;
		}
	}

	// Return the length of the invalid excess
	// if we're just parsing
	// Otherwise, throw an error or return tokens
	return parseOnly ?
		soFar.length :
		soFar ?
			Sizzle.error( selector ) :
			// Cache the tokens
			tokenCache( selector, groups ).slice( 0 );
};

function toSelector( tokens ) {
	var i = 0,
		len = tokens.length,
		selector = "";
	for ( ; i < len; i++ ) {
		selector += tokens[i].value;
	}
	return selector;
}

function addCombinator( matcher, combinator, base ) {
	var dir = combinator.dir,
		checkNonElements = base && dir === "parentNode",
		doneName = done++;

	return combinator.first ?
		// Check against closest ancestor/preceding element
		function( elem, context, xml ) {
			while ( (elem = elem[ dir ]) ) {
				if ( elem.nodeType === 1 || checkNonElements ) {
					return matcher( elem, context, xml );
				}
			}
		} :

		// Check against all ancestor/preceding elements
		function( elem, context, xml ) {
			var oldCache, uniqueCache, outerCache,
				newCache = [ dirruns, doneName ];

			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
			if ( xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						if ( matcher( elem, context, xml ) ) {
							return true;
						}
					}
				}
			} else {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						outerCache = elem[ expando ] || (elem[ expando ] = {});

						// Support: IE <9 only
						// Defend against cloned attroperties (jQuery gh-1709)
						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});

						if ( (oldCache = uniqueCache[ dir ]) &&
							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

							// Assign to newCache so results back-propagate to previous elements
							return (newCache[ 2 ] = oldCache[ 2 ]);
						} else {
							// Reuse newcache so results back-propagate to previous elements
							uniqueCache[ dir ] = newCache;

							// A match means we're done; a fail means we have to keep checking
							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
								return true;
							}
						}
					}
				}
			}
		};
}

function elementMatcher( matchers ) {
	return matchers.length > 1 ?
		function( elem, context, xml ) {
			var i = matchers.length;
			while ( i-- ) {
				if ( !matchers[i]( elem, context, xml ) ) {
					return false;
				}
			}
			return true;
		} :
		matchers[0];
}

function multipleContexts( selector, contexts, results ) {
	var i = 0,
		len = contexts.length;
	for ( ; i < len; i++ ) {
		Sizzle( selector, contexts[i], results );
	}
	return results;
}

function condense( unmatched, map, filter, context, xml ) {
	var elem,
		newUnmatched = [],
		i = 0,
		len = unmatched.length,
		mapped = map != null;

	for ( ; i < len; i++ ) {
		if ( (elem = unmatched[i]) ) {
			if ( !filter || filter( elem, context, xml ) ) {
				newUnmatched.push( elem );
				if ( mapped ) {
					map.push( i );
				}
			}
		}
	}

	return newUnmatched;
}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
	if ( postFilter && !postFilter[ expando ] ) {
		postFilter = setMatcher( postFilter );
	}
	if ( postFinder && !postFinder[ expando ] ) {
		postFinder = setMatcher( postFinder, postSelector );
	}
	return markFunction(function( seed, results, context, xml ) {
		var temp, i, elem,
			preMap = [],
			postMap = [],
			preexisting = results.length,

			// Get initial elements from seed or context
			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),

			// Prefilter to get matcher input, preserving a map for seed-results synchronization
			matcherIn = preFilter && ( seed || !selector ) ?
				condense( elems, preMap, preFilter, context, xml ) :
				elems,

			matcherOut = matcher ?
				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

					// ...intermediate processing is necessary
					[] :

					// ...otherwise use results directly
					results :
				matcherIn;

		// Find primary matches
		if ( matcher ) {
			matcher( matcherIn, matcherOut, context, xml );
		}

		// Apply postFilter
		if ( postFilter ) {
			temp = condense( matcherOut, postMap );
			postFilter( temp, [], context, xml );

			// Un-match failing elements by moving them back to matcherIn
			i = temp.length;
			while ( i-- ) {
				if ( (elem = temp[i]) ) {
					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
				}
			}
		}

		if ( seed ) {
			if ( postFinder || preFilter ) {
				if ( postFinder ) {
					// Get the final matcherOut by condensing this intermediate into postFinder contexts
					temp = [];
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) ) {
							// Restore matcherIn since elem is not yet a final match
							temp.push( (matcherIn[i] = elem) );
						}
					}
					postFinder( null, (matcherOut = []), temp, xml );
				}

				// Move matched elements from seed to results to keep them synchronized
				i = matcherOut.length;
				while ( i-- ) {
					if ( (elem = matcherOut[i]) &&
						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {

						seed[temp] = !(results[temp] = elem);
					}
				}
			}

		// Add elements to results, through postFinder if defined
		} else {
			matcherOut = condense(
				matcherOut === results ?
					matcherOut.splice( preexisting, matcherOut.length ) :
					matcherOut
			);
			if ( postFinder ) {
				postFinder( null, results, matcherOut, xml );
			} else {
				push.apply( results, matcherOut );
			}
		}
	});
}

function matcherFromTokens( tokens ) {
	var checkContext, matcher, j,
		len = tokens.length,
		leadingRelative = Expr.relative[ tokens[0].type ],
		implicitRelative = leadingRelative || Expr.relative[" "],
		i = leadingRelative ? 1 : 0,

		// The foundational matcher ensures that elements are reachable from top-level context(s)
		matchContext = addCombinator( function( elem ) {
			return elem === checkContext;
		}, implicitRelative, true ),
		matchAnyContext = addCombinator( function( elem ) {
			return indexOf( checkContext, elem ) > -1;
		}, implicitRelative, true ),
		matchers = [ function( elem, context, xml ) {
			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
				(checkContext = context).nodeType ?
					matchContext( elem, context, xml ) :
					matchAnyContext( elem, context, xml ) );
			// Avoid hanging onto element (issue #299)
			checkContext = null;
			return ret;
		} ];

	for ( ; i < len; i++ ) {
		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
		} else {
			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );

			// Return special upon seeing a positional matcher
			if ( matcher[ expando ] ) {
				// Find the next relative operator (if any) for proper handling
				j = ++i;
				for ( ; j < len; j++ ) {
					if ( Expr.relative[ tokens[j].type ] ) {
						break;
					}
				}
				return setMatcher(
					i > 1 && elementMatcher( matchers ),
					i > 1 && toSelector(
						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
					).replace( rtrim, "$1" ),
					matcher,
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
					j < len && toSelector( tokens )
				);
			}
			matchers.push( matcher );
		}
	}

	return elementMatcher( matchers );
}

function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
	var bySet = setMatchers.length > 0,
		byElement = elementMatchers.length > 0,
		superMatcher = function( seed, context, xml, results, outermost ) {
			var elem, j, matcher,
				matchedCount = 0,
				i = "0",
				unmatched = seed && [],
				setMatched = [],
				contextBackup = outermostContext,
				// We must always have either seed elements or outermost context
				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
				// Use integer dirruns iff this is the outermost matcher
				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
				len = elems.length;

			if ( outermost ) {
				outermostContext = context === document || context || outermost;
			}

			// Add elements passing elementMatchers directly to results
			// Support: IE<9, Safari
			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
				if ( byElement && elem ) {
					j = 0;
					if ( !context && elem.ownerDocument !== document ) {
						setDocument( elem );
						xml = !documentIsHTML;
					}
					while ( (matcher = elementMatchers[j++]) ) {
						if ( matcher( elem, context || document, xml) ) {
							results.push( elem );
							break;
						}
					}
					if ( outermost ) {
						dirruns = dirrunsUnique;
					}
				}

				// Track unmatched elements for set filters
				if ( bySet ) {
					// They will have gone through all possible matchers
					if ( (elem = !matcher && elem) ) {
						matchedCount--;
					}

					// Lengthen the array for every element, matched or not
					if ( seed ) {
						unmatched.push( elem );
					}
				}
			}

			// `i` is now the count of elements visited above, and adding it to `matchedCount`
			// makes the latter nonnegative.
			matchedCount += i;

			// Apply set filters to unmatched elements
			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
			// no element matchers and no seed.
			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
			// numerically zero.
			if ( bySet && i !== matchedCount ) {
				j = 0;
				while ( (matcher = setMatchers[j++]) ) {
					matcher( unmatched, setMatched, context, xml );
				}

				if ( seed ) {
					// Reintegrate element matches to eliminate the need for sorting
					if ( matchedCount > 0 ) {
						while ( i-- ) {
							if ( !(unmatched[i] || setMatched[i]) ) {
								setMatched[i] = pop.call( results );
							}
						}
					}

					// Discard index placeholder values to get only actual matches
					setMatched = condense( setMatched );
				}

				// Add matches to results
				push.apply( results, setMatched );

				// Seedless set matches succeeding multiple successful matchers stipulate sorting
				if ( outermost && !seed && setMatched.length > 0 &&
					( matchedCount + setMatchers.length ) > 1 ) {

					Sizzle.uniqueSort( results );
				}
			}

			// Override manipulation of globals by nested matchers
			if ( outermost ) {
				dirruns = dirrunsUnique;
				outermostContext = contextBackup;
			}

			return unmatched;
		};

	return bySet ?
		markFunction( superMatcher ) :
		superMatcher;
}

compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
	var i,
		setMatchers = [],
		elementMatchers = [],
		cached = compilerCache[ selector + " " ];

	if ( !cached ) {
		// Generate a function of recursive functions that can be used to check each element
		if ( !match ) {
			match = tokenize( selector );
		}
		i = match.length;
		while ( i-- ) {
			cached = matcherFromTokens( match[i] );
			if ( cached[ expando ] ) {
				setMatchers.push( cached );
			} else {
				elementMatchers.push( cached );
			}
		}

		// Cache the compiled function
		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );

		// Save selector and tokenization
		cached.selector = selector;
	}
	return cached;
};

/**
 * A low-level selection function that works with Sizzle's compiled
 *  selector functions
 * @param {String|Function} selector A selector or a pre-compiled
 *  selector function built with Sizzle.compile
 * @param {Element} context
 * @param {Array} [results]
 * @param {Array} [seed] A set of elements to match against
 */
select = Sizzle.select = function( selector, context, results, seed ) {
	var i, tokens, token, type, find,
		compiled = typeof selector === "function" && selector,
		match = !seed && tokenize( (selector = compiled.selector || selector) );

	results = results || [];

	// Try to minimize operations if there is only one selector in the list and no seed
	// (the latter of which guarantees us context)
	if ( match.length === 1 ) {

		// Reduce context if the leading compound selector is an ID
		tokens = match[0] = match[0].slice( 0 );
		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
				support.getById && context.nodeType === 9 && documentIsHTML &&
				Expr.relative[ tokens[1].type ] ) {

			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
			if ( !context ) {
				return results;

			// Precompiled matchers will still verify ancestry, so step up a level
			} else if ( compiled ) {
				context = context.parentNode;
			}

			selector = selector.slice( tokens.shift().value.length );
		}

		// Fetch a seed set for right-to-left matching
		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
		while ( i-- ) {
			token = tokens[i];

			// Abort if we hit a combinator
			if ( Expr.relative[ (type = token.type) ] ) {
				break;
			}
			if ( (find = Expr.find[ type ]) ) {
				// Search, expanding context for leading sibling combinators
				if ( (seed = find(
					token.matches[0].replace( runescape, funescape ),
					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
				)) ) {

					// If seed is empty or no tokens remain, we can return early
					tokens.splice( i, 1 );
					selector = seed.length && toSelector( tokens );
					if ( !selector ) {
						push.apply( results, seed );
						return results;
					}

					break;
				}
			}
		}
	}

	// Compile and execute a filtering function if one is not provided
	// Provide `match` to avoid retokenization if we modified the selector above
	( compiled || compile( selector, match ) )(
		seed,
		context,
		!documentIsHTML,
		results,
		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
	);
	return results;
};

// One-time assignments

// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;

// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate;

// Initialize against the default document
setDocument();

// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow *each other*
support.sortDetached = assert(function( div1 ) {
	// Should return 1, but returns 4 (following)
	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
});

// Support: IE<8
// Prevent attribute/property "interpolation"
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert(function( div ) {
	div.innerHTML = "<a href='#'></a>";
	return div.firstChild.getAttribute("href") === "#" ;
}) ) {
	addHandle( "type|href|height|width", function( elem, name, isXML ) {
		if ( !isXML ) {
			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
		}
	});
}

// Support: IE<9
// Use defaultValue in place of getAttribute("value")
if ( !support.attributes || !assert(function( div ) {
	div.innerHTML = "<input/>";
	div.firstChild.setAttribute( "value", "" );
	return div.firstChild.getAttribute( "value" ) === "";
}) ) {
	addHandle( "value", function( elem, name, isXML ) {
		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
			return elem.defaultValue;
		}
	});
}

// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
if ( !assert(function( div ) {
	return div.getAttribute("disabled") == null;
}) ) {
	addHandle( booleans, function( elem, name, isXML ) {
		var val;
		if ( !isXML ) {
			return elem[ name ] === true ? name.toLowerCase() :
					(val = elem.getAttributeNode( name )) && val.specified ?
					val.value :
				null;
		}
	});
}

return Sizzle;

})( window );



jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;



var dir = function( elem, dir, until ) {
	var matched = [],
		truncate = until !== undefined;

	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
		if ( elem.nodeType === 1 ) {
			if ( truncate && jQuery( elem ).is( until ) ) {
				break;
			}
			matched.push( elem );
		}
	}
	return matched;
};


var siblings = function( n, elem ) {
	var matched = [];

	for ( ; n; n = n.nextSibling ) {
		if ( n.nodeType === 1 && n !== elem ) {
			matched.push( n );
		}
	}

	return matched;
};


var rneedsContext = jQuery.expr.match.needsContext;

var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );



var risSimple = /^.[^:#\[\.,]*$/;

// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
	if ( jQuery.isFunction( qualifier ) ) {
		return jQuery.grep( elements, function( elem, i ) {
			/* jshint -W018 */
			return !!qualifier.call( elem, i, elem ) !== not;
		} );

	}

	if ( qualifier.nodeType ) {
		return jQuery.grep( elements, function( elem ) {
			return ( elem === qualifier ) !== not;
		} );

	}

	if ( typeof qualifier === "string" ) {
		if ( risSimple.test( qualifier ) ) {
			return jQuery.filter( qualifier, elements, not );
		}

		qualifier = jQuery.filter( qualifier, elements );
	}

	return jQuery.grep( elements, function( elem ) {
		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
	} );
}

jQuery.filter = function( expr, elems, not ) {
	var elem = elems[ 0 ];

	if ( not ) {
		expr = ":not(" + expr + ")";
	}

	return elems.length === 1 && elem.nodeType === 1 ?
		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
			return elem.nodeType === 1;
		} ) );
};

jQuery.fn.extend( {
	find: function( selector ) {
		var i,
			len = this.length,
			ret = [],
			self = this;

		if ( typeof selector !== "string" ) {
			return this.pushStack( jQuery( selector ).filter( function() {
				for ( i = 0; i < len; i++ ) {
					if ( jQuery.contains( self[ i ], this ) ) {
						return true;
					}
				}
			} ) );
		}

		for ( i = 0; i < len; i++ ) {
			jQuery.find( selector, self[ i ], ret );
		}

		// Needed because $( selector, context ) becomes $( context ).find( selector )
		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
		ret.selector = this.selector ? this.selector + " " + selector : selector;
		return ret;
	},
	filter: function( selector ) {
		return this.pushStack( winnow( this, selector || [], false ) );
	},
	not: function( selector ) {
		return this.pushStack( winnow( this, selector || [], true ) );
	},
	is: function( selector ) {
		return !!winnow(
			this,

			// If this is a positional/relative selector, check membership in the returned set
			// so $("p:first").is("p:last") won't return true for a doc with two "p".
			typeof selector === "string" && rneedsContext.test( selector ) ?
				jQuery( selector ) :
				selector || [],
			false
		).length;
	}
} );


// Initialize a jQuery object


// A central reference to the root jQuery(document)
var rootjQuery,

	// A simple way to check for HTML strings
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
	// Strict HTML recognition (#11290: must start with <)
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

	init = jQuery.fn.init = function( selector, context, root ) {
		var match, elem;

		// HANDLE: $(""), $(null), $(undefined), $(false)
		if ( !selector ) {
			return this;
		}

		// Method init() accepts an alternate rootjQuery
		// so migrate can support jQuery.sub (gh-2101)
		root = root || rootjQuery;

		// Handle HTML strings
		if ( typeof selector === "string" ) {
			if ( selector[ 0 ] === "<" &&
				selector[ selector.length - 1 ] === ">" &&
				selector.length >= 3 ) {

				// Assume that strings that start and end with <> are HTML and skip the regex check
				match = [ null, selector, null ];

			} else {
				match = rquickExpr.exec( selector );
			}

			// Match html or make sure no context is specified for #id
			if ( match && ( match[ 1 ] || !context ) ) {

				// HANDLE: $(html) -> $(array)
				if ( match[ 1 ] ) {
					context = context instanceof jQuery ? context[ 0 ] : context;

					// Option to run scripts is true for back-compat
					// Intentionally let the error be thrown if parseHTML is not present
					jQuery.merge( this, jQuery.parseHTML(
						match[ 1 ],
						context && context.nodeType ? context.ownerDocument || context : document,
						true
					) );

					// HANDLE: $(html, props)
					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
						for ( match in context ) {

							// Properties of context are called as methods if possible
							if ( jQuery.isFunction( this[ match ] ) ) {
								this[ match ]( context[ match ] );

							// ...and otherwise set as attributes
							} else {
								this.attr( match, context[ match ] );
							}
						}
					}

					return this;

				// HANDLE: $(#id)
				} else {
					elem = document.getElementById( match[ 2 ] );

					// Support: Blackberry 4.6
					// gEBID returns nodes no longer in the document (#6963)
					if ( elem && elem.parentNode ) {

						// Inject the element directly into the jQuery object
						this.length = 1;
						this[ 0 ] = elem;
					}

					this.context = document;
					this.selector = selector;
					return this;
				}

			// HANDLE: $(expr, $(...))
			} else if ( !context || context.jquery ) {
				return ( context || root ).find( selector );

			// HANDLE: $(expr, context)
			// (which is just equivalent to: $(context).find(expr)
			} else {
				return this.constructor( context ).find( selector );
			}

		// HANDLE: $(DOMElement)
		} else if ( selector.nodeType ) {
			this.context = this[ 0 ] = selector;
			this.length = 1;
			return this;

		// HANDLE: $(function)
		// Shortcut for document ready
		} else if ( jQuery.isFunction( selector ) ) {
			return root.ready !== undefined ?
				root.ready( selector ) :

				// Execute immediately if ready is not present
				selector( jQuery );
		}

		if ( selector.selector !== undefined ) {
			this.selector = selector.selector;
			this.context = selector.context;
		}

		return jQuery.makeArray( selector, this );
	};

// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

// Initialize central reference
rootjQuery = jQuery( document );


var rparentsprev = /^(?:parents|prev(?:Until|All))/,

	// Methods guaranteed to produce a unique set when starting from a unique set
	guaranteedUnique = {
		children: true,
		contents: true,
		next: true,
		prev: true
	};

jQuery.fn.extend( {
	has: function( target ) {
		var targets = jQuery( target, this ),
			l = targets.length;

		return this.filter( function() {
			var i = 0;
			for ( ; i < l; i++ ) {
				if ( jQuery.contains( this, targets[ i ] ) ) {
					return true;
				}
			}
		} );
	},

	closest: function( selectors, context ) {
		var cur,
			i = 0,
			l = this.length,
			matched = [],
			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
				jQuery( selectors, context || this.context ) :
				0;

		for ( ; i < l; i++ ) {
			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {

				// Always skip document fragments
				if ( cur.nodeType < 11 && ( pos ?
					pos.index( cur ) > -1 :

					// Don't pass non-elements to Sizzle
					cur.nodeType === 1 &&
						jQuery.find.matchesSelector( cur, selectors ) ) ) {

					matched.push( cur );
					break;
				}
			}
		}

		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
	},

	// Determine the position of an element within the set
	index: function( elem ) {

		// No argument, return index in parent
		if ( !elem ) {
			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
		}

		// Index in selector
		if ( typeof elem === "string" ) {
			return indexOf.call( jQuery( elem ), this[ 0 ] );
		}

		// Locate the position of the desired element
		return indexOf.call( this,

			// If it receives a jQuery object, the first element is used
			elem.jquery ? elem[ 0 ] : elem
		);
	},

	add: function( selector, context ) {
		return this.pushStack(
			jQuery.uniqueSort(
				jQuery.merge( this.get(), jQuery( selector, context ) )
			)
		);
	},

	addBack: function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	}
} );

function sibling( cur, dir ) {
	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
	return cur;
}

jQuery.each( {
	parent: function( elem ) {
		var parent = elem.parentNode;
		return parent && parent.nodeType !== 11 ? parent : null;
	},
	parents: function( elem ) {
		return dir( elem, "parentNode" );
	},
	parentsUntil: function( elem, i, until ) {
		return dir( elem, "parentNode", until );
	},
	next: function( elem ) {
		return sibling( elem, "nextSibling" );
	},
	prev: function( elem ) {
		return sibling( elem, "previousSibling" );
	},
	nextAll: function( elem ) {
		return dir( elem, "nextSibling" );
	},
	prevAll: function( elem ) {
		return dir( elem, "previousSibling" );
	},
	nextUntil: function( elem, i, until ) {
		return dir( elem, "nextSibling", until );
	},
	prevUntil: function( elem, i, until ) {
		return dir( elem, "previousSibling", until );
	},
	siblings: function( elem ) {
		return siblings( ( elem.parentNode || {} ).firstChild, elem );
	},
	children: function( elem ) {
		return siblings( elem.firstChild );
	},
	contents: function( elem ) {
		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
	}
}, function( name, fn ) {
	jQuery.fn[ name ] = function( until, selector ) {
		var matched = jQuery.map( this, fn, until );

		if ( name.slice( -5 ) !== "Until" ) {
			selector = until;
		}

		if ( selector && typeof selector === "string" ) {
			matched = jQuery.filter( selector, matched );
		}

		if ( this.length > 1 ) {

			// Remove duplicates
			if ( !guaranteedUnique[ name ] ) {
				jQuery.uniqueSort( matched );
			}

			// Reverse order for parents* and prev-derivatives
			if ( rparentsprev.test( name ) ) {
				matched.reverse();
			}
		}

		return this.pushStack( matched );
	};
} );
var rnotwhite = ( /\S+/g );



// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
	var object = {};
	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
		object[ flag ] = true;
	} );
	return object;
}

/*
 * Create a callback list using the following parameters:
 *
 *	options: an optional list of space-separated options that will change how
 *			the callback list behaves or a more traditional option object
 *
 * By default a callback list will act like an event callback list and can be
 * "fired" multiple times.
 *
 * Possible options:
 *
 *	once:			will ensure the callback list can only be fired once (like a Deferred)
 *
 *	memory:			will keep track of previous values and will call any callback added
 *					after the list has been fired right away with the latest "memorized"
 *					values (like a Deferred)
 *
 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
 *
 *	stopOnFalse:	interrupt callings when a callback returns false
 *
 */
jQuery.Callbacks = function( options ) {

	// Convert options from String-formatted to Object-formatted if needed
	// (we check in cache first)
	options = typeof options === "string" ?
		createOptions( options ) :
		jQuery.extend( {}, options );

	var // Flag to know if list is currently firing
		firing,

		// Last fire value for non-forgettable lists
		memory,

		// Flag to know if list was already fired
		fired,

		// Flag to prevent firing
		locked,

		// Actual callback list
		list = [],

		// Queue of execution data for repeatable lists
		queue = [],

		// Index of currently firing callback (modified by add/remove as needed)
		firingIndex = -1,

		// Fire callbacks
		fire = function() {

			// Enforce single-firing
			locked = options.once;

			// Execute callbacks for all pending executions,
			// respecting firingIndex overrides and runtime changes
			fired = firing = true;
			for ( ; queue.length; firingIndex = -1 ) {
				memory = queue.shift();
				while ( ++firingIndex < list.length ) {

					// Run callback and check for early termination
					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
						options.stopOnFalse ) {

						// Jump to end and forget the data so .add doesn't re-fire
						firingIndex = list.length;
						memory = false;
					}
				}
			}

			// Forget the data if we're done with it
			if ( !options.memory ) {
				memory = false;
			}

			firing = false;

			// Clean up if we're done firing for good
			if ( locked ) {

				// Keep an empty list if we have data for future add calls
				if ( memory ) {
					list = [];

				// Otherwise, this object is spent
				} else {
					list = "";
				}
			}
		},

		// Actual Callbacks object
		self = {

			// Add a callback or a collection of callbacks to the list
			add: function() {
				if ( list ) {

					// If we have memory from a past run, we should fire after adding
					if ( memory && !firing ) {
						firingIndex = list.length - 1;
						queue.push( memory );
					}

					( function add( args ) {
						jQuery.each( args, function( _, arg ) {
							if ( jQuery.isFunction( arg ) ) {
								if ( !options.unique || !self.has( arg ) ) {
									list.push( arg );
								}
							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {

								// Inspect recursively
								add( arg );
							}
						} );
					} )( arguments );

					if ( memory && !firing ) {
						fire();
					}
				}
				return this;
			},

			// Remove a callback from the list
			remove: function() {
				jQuery.each( arguments, function( _, arg ) {
					var index;
					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
						list.splice( index, 1 );

						// Handle firing indexes
						if ( index <= firingIndex ) {
							firingIndex--;
						}
					}
				} );
				return this;
			},

			// Check if a given callback is in the list.
			// If no argument is given, return whether or not list has callbacks attached.
			has: function( fn ) {
				return fn ?
					jQuery.inArray( fn, list ) > -1 :
					list.length > 0;
			},

			// Remove all callbacks from the list
			empty: function() {
				if ( list ) {
					list = [];
				}
				return this;
			},

			// Disable .fire and .add
			// Abort any current/pending executions
			// Clear all callbacks and values
			disable: function() {
				locked = queue = [];
				list = memory = "";
				return this;
			},
			disabled: function() {
				return !list;
			},

			// Disable .fire
			// Also disable .add unless we have memory (since it would have no effect)
			// Abort any pending executions
			lock: function() {
				locked = queue = [];
				if ( !memory ) {
					list = memory = "";
				}
				return this;
			},
			locked: function() {
				return !!locked;
			},

			// Call all callbacks with the given context and arguments
			fireWith: function( context, args ) {
				if ( !locked ) {
					args = args || [];
					args = [ context, args.slice ? args.slice() : args ];
					queue.push( args );
					if ( !firing ) {
						fire();
					}
				}
				return this;
			},

			// Call all the callbacks with the given arguments
			fire: function() {
				self.fireWith( this, arguments );
				return this;
			},

			// To know if the callbacks have already been called at least once
			fired: function() {
				return !!fired;
			}
		};

	return self;
};


jQuery.extend( {

	Deferred: function( func ) {
		var tuples = [

				// action, add listener, listener list, final state
				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
			],
			state = "pending",
			promise = {
				state: function() {
					return state;
				},
				always: function() {
					deferred.done( arguments ).fail( arguments );
					return this;
				},
				then: function( /* fnDone, fnFail, fnProgress */ ) {
					var fns = arguments;
					return jQuery.Deferred( function( newDefer ) {
						jQuery.each( tuples, function( i, tuple ) {
							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];

							// deferred[ done | fail | progress ] for forwarding actions to newDefer
							deferred[ tuple[ 1 ] ]( function() {
								var returned = fn && fn.apply( this, arguments );
								if ( returned && jQuery.isFunction( returned.promise ) ) {
									returned.promise()
										.progress( newDefer.notify )
										.done( newDefer.resolve )
										.fail( newDefer.reject );
								} else {
									newDefer[ tuple[ 0 ] + "With" ](
										this === promise ? newDefer.promise() : this,
										fn ? [ returned ] : arguments
									);
								}
							} );
						} );
						fns = null;
					} ).promise();
				},

				// Get a promise for this deferred
				// If obj is provided, the promise aspect is added to the object
				promise: function( obj ) {
					return obj != null ? jQuery.extend( obj, promise ) : promise;
				}
			},
			deferred = {};

		// Keep pipe for back-compat
		promise.pipe = promise.then;

		// Add list-specific methods
		jQuery.each( tuples, function( i, tuple ) {
			var list = tuple[ 2 ],
				stateString = tuple[ 3 ];

			// promise[ done | fail | progress ] = list.add
			promise[ tuple[ 1 ] ] = list.add;

			// Handle state
			if ( stateString ) {
				list.add( function() {

					// state = [ resolved | rejected ]
					state = stateString;

				// [ reject_list | resolve_list ].disable; progress_list.lock
				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
			}

			// deferred[ resolve | reject | notify ]
			deferred[ tuple[ 0 ] ] = function() {
				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
				return this;
			};
			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
		} );

		// Make the deferred a promise
		promise.promise( deferred );

		// Call given func if any
		if ( func ) {
			func.call( deferred, deferred );
		}

		// All done!
		return deferred;
	},

	// Deferred helper
	when: function( subordinate /* , ..., subordinateN */ ) {
		var i = 0,
			resolveValues = slice.call( arguments ),
			length = resolveValues.length,

			// the count of uncompleted subordinates
			remaining = length !== 1 ||
				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

			// the master Deferred.
			// If resolveValues consist of only a single Deferred, just use that.
			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

			// Update function for both resolve and progress values
			updateFunc = function( i, contexts, values ) {
				return function( value ) {
					contexts[ i ] = this;
					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
					if ( values === progressValues ) {
						deferred.notifyWith( contexts, values );
					} else if ( !( --remaining ) ) {
						deferred.resolveWith( contexts, values );
					}
				};
			},

			progressValues, progressContexts, resolveContexts;

		// Add listeners to Deferred subordinates; treat others as resolved
		if ( length > 1 ) {
			progressValues = new Array( length );
			progressContexts = new Array( length );
			resolveContexts = new Array( length );
			for ( ; i < length; i++ ) {
				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
					resolveValues[ i ].promise()
						.progress( updateFunc( i, progressContexts, progressValues ) )
						.done( updateFunc( i, resolveContexts, resolveValues ) )
						.fail( deferred.reject );
				} else {
					--remaining;
				}
			}
		}

		// If we're not waiting on anything, resolve the master
		if ( !remaining ) {
			deferred.resolveWith( resolveContexts, resolveValues );
		}

		return deferred.promise();
	}
} );


// The deferred used on DOM ready
var readyList;

jQuery.fn.ready = function( fn ) {

	// Add the callback
	jQuery.ready.promise().done( fn );

	return this;
};

jQuery.extend( {

	// Is the DOM ready to be used? Set to true once it occurs.
	isReady: false,

	// A counter to track how many items to wait for before
	// the ready event fires. See #6781
	readyWait: 1,

	// Hold (or release) the ready event
	holdReady: function( hold ) {
		if ( hold ) {
			jQuery.readyWait++;
		} else {
			jQuery.ready( true );
		}
	},

	// Handle when the DOM is ready
	ready: function( wait ) {

		// Abort if there are pending holds or we're already ready
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
			return;
		}

		// Remember that the DOM is ready
		jQuery.isReady = true;

		// If a normal DOM Ready event fired, decrement, and wait if need be
		if ( wait !== true && --jQuery.readyWait > 0 ) {
			return;
		}

		// If there are functions bound, to execute
		readyList.resolveWith( document, [ jQuery ] );

		// Trigger any bound ready events
		if ( jQuery.fn.triggerHandler ) {
			jQuery( document ).triggerHandler( "ready" );
			jQuery( document ).off( "ready" );
		}
	}
} );

/**
 * The ready event handler and self cleanup method
 */
function completed() {
	document.removeEventListener( "DOMContentLoaded", completed );
	window.removeEventListener( "load", completed );
	jQuery.ready();
}

jQuery.ready.promise = function( obj ) {
	if ( !readyList ) {

		readyList = jQuery.Deferred();

		// Catch cases where $(document).ready() is called
		// after the browser event has already occurred.
		// Support: IE9-10 only
		// Older IE sometimes signals "interactive" too soon
		if ( document.readyState === "complete" ||
			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

			// Handle it asynchronously to allow scripts the opportunity to delay ready
			window.setTimeout( jQuery.ready );

		} else {

			// Use the handy event callback
			document.addEventListener( "DOMContentLoaded", completed );

			// A fallback to window.onload, that will always work
			window.addEventListener( "load", completed );
		}
	}
	return readyList.promise( obj );
};

// Kick off the DOM ready check even if the user does not
jQuery.ready.promise();




// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
	var i = 0,
		len = elems.length,
		bulk = key == null;

	// Sets many values
	if ( jQuery.type( key ) === "object" ) {
		chainable = true;
		for ( i in key ) {
			access( elems, fn, i, key[ i ], true, emptyGet, raw );
		}

	// Sets one value
	} else if ( value !== undefined ) {
		chainable = true;

		if ( !jQuery.isFunction( value ) ) {
			raw = true;
		}

		if ( bulk ) {

			// Bulk operations run against the entire set
			if ( raw ) {
				fn.call( elems, value );
				fn = null;

			// ...except when executing function values
			} else {
				bulk = fn;
				fn = function( elem, key, value ) {
					return bulk.call( jQuery( elem ), value );
				};
			}
		}

		if ( fn ) {
			for ( ; i < len; i++ ) {
				fn(
					elems[ i ], key, raw ?
					value :
					value.call( elems[ i ], i, fn( elems[ i ], key ) )
				);
			}
		}
	}

	return chainable ?
		elems :

		// Gets
		bulk ?
			fn.call( elems ) :
			len ? fn( elems[ 0 ], key ) : emptyGet;
};
var acceptData = function( owner ) {

	// Accepts only:
	//  - Node
	//    - Node.ELEMENT_NODE
	//    - Node.DOCUMENT_NODE
	//  - Object
	//    - Any
	/* jshint -W018 */
	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};




function Data() {
	this.expando = jQuery.expando + Data.uid++;
}

Data.uid = 1;

Data.prototype = {

	register: function( owner, initial ) {
		var value = initial || {};

		// If it is a node unlikely to be stringify-ed or looped over
		// use plain assignment
		if ( owner.nodeType ) {
			owner[ this.expando ] = value;

		// Otherwise secure it in a non-enumerable, non-writable property
		// configurability must be true to allow the property to be
		// deleted with the delete operator
		} else {
			Object.defineProperty( owner, this.expando, {
				value: value,
				writable: true,
				configurable: true
			} );
		}
		return owner[ this.expando ];
	},
	cache: function( owner ) {

		// We can accept data for non-element nodes in modern browsers,
		// but we should not, see #8335.
		// Always return an empty object.
		if ( !acceptData( owner ) ) {
			return {};
		}

		// Check if the owner object already has a cache
		var value = owner[ this.expando ];

		// If not, create one
		if ( !value ) {
			value = {};

			// We can accept data for non-element nodes in modern browsers,
			// but we should not, see #8335.
			// Always return an empty object.
			if ( acceptData( owner ) ) {

				// If it is a node unlikely to be stringify-ed or looped over
				// use plain assignment
				if ( owner.nodeType ) {
					owner[ this.expando ] = value;

				// Otherwise secure it in a non-enumerable property
				// configurable must be true to allow the property to be
				// deleted when data is removed
				} else {
					Object.defineProperty( owner, this.expando, {
						value: value,
						configurable: true
					} );
				}
			}
		}

		return value;
	},
	set: function( owner, data, value ) {
		var prop,
			cache = this.cache( owner );

		// Handle: [ owner, key, value ] args
		if ( typeof data === "string" ) {
			cache[ data ] = value;

		// Handle: [ owner, { properties } ] args
		} else {

			// Copy the properties one-by-one to the cache object
			for ( prop in data ) {
				cache[ prop ] = data[ prop ];
			}
		}
		return cache;
	},
	get: function( owner, key ) {
		return key === undefined ?
			this.cache( owner ) :
			owner[ this.expando ] && owner[ this.expando ][ key ];
	},
	access: function( owner, key, value ) {
		var stored;

		// In cases where either:
		//
		//   1. No key was specified
		//   2. A string key was specified, but no value provided
		//
		// Take the "read" path and allow the get method to determine
		// which value to return, respectively either:
		//
		//   1. The entire cache object
		//   2. The data stored at the key
		//
		if ( key === undefined ||
				( ( key && typeof key === "string" ) && value === undefined ) ) {

			stored = this.get( owner, key );

			return stored !== undefined ?
				stored : this.get( owner, jQuery.camelCase( key ) );
		}

		// When the key is not a string, or both a key and value
		// are specified, set or extend (existing objects) with either:
		//
		//   1. An object of properties
		//   2. A key and value
		//
		this.set( owner, key, value );

		// Since the "set" path can have two possible entry points
		// return the expected data based on which path was taken[*]
		return value !== undefined ? value : key;
	},
	remove: function( owner, key ) {
		var i, name, camel,
			cache = owner[ this.expando ];

		if ( cache === undefined ) {
			return;
		}

		if ( key === undefined ) {
			this.register( owner );

		} else {

			// Support array or space separated string of keys
			if ( jQuery.isArray( key ) ) {

				// If "name" is an array of keys...
				// When data is initially created, via ("key", "val") signature,
				// keys will be converted to camelCase.
				// Since there is no way to tell _how_ a key was added, remove
				// both plain key and camelCase key. #12786
				// This will only penalize the array argument path.
				name = key.concat( key.map( jQuery.camelCase ) );
			} else {
				camel = jQuery.camelCase( key );

				// Try the string as a key before any manipulation
				if ( key in cache ) {
					name = [ key, camel ];
				} else {

					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					name = camel;
					name = name in cache ?
						[ name ] : ( name.match( rnotwhite ) || [] );
				}
			}

			i = name.length;

			while ( i-- ) {
				delete cache[ name[ i ] ];
			}
		}

		// Remove the expando if there's no more data
		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {

			// Support: Chrome <= 35-45+
			// Webkit & Blink performance suffers when deleting properties
			// from DOM nodes, so set to undefined instead
			// https://code.google.com/p/chromium/issues/detail?id=378607
			if ( owner.nodeType ) {
				owner[ this.expando ] = undefined;
			} else {
				delete owner[ this.expando ];
			}
		}
	},
	hasData: function( owner ) {
		var cache = owner[ this.expando ];
		return cache !== undefined && !jQuery.isEmptyObject( cache );
	}
};
var dataPriv = new Data();

var dataUser = new Data();



//	Implementation Summary
//
//	1. Enforce API surface and semantic compatibility with 1.9.x branch
//	2. Improve the module's maintainability by reducing the storage
//		paths to a single mechanism.
//	3. Use the same single mechanism to support "private" and "user" data.
//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
//	5. Avoid exposing implementation details on user objects (eg. expando properties)
//	6. Provide a clear path for implementation upgrade to WeakMap in 2014

var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	rmultiDash = /[A-Z]/g;

function dataAttr( elem, key, data ) {
	var name;

	// If nothing was found internally, try to fetch any
	// data from the HTML5 data-* attribute
	if ( data === undefined && elem.nodeType === 1 ) {
		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
		data = elem.getAttribute( name );

		if ( typeof data === "string" ) {
			try {
				data = data === "true" ? true :
					data === "false" ? false :
					data === "null" ? null :

					// Only convert to a number if it doesn't change the string
					+data + "" === data ? +data :
					rbrace.test( data ) ? jQuery.parseJSON( data ) :
					data;
			} catch ( e ) {}

			// Make sure we set the data so it isn't changed later
			dataUser.set( elem, key, data );
		} else {
			data = undefined;
		}
	}
	return data;
}

jQuery.extend( {
	hasData: function( elem ) {
		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
	},

	data: function( elem, name, data ) {
		return dataUser.access( elem, name, data );
	},

	removeData: function( elem, name ) {
		dataUser.remove( elem, name );
	},

	// TODO: Now that all calls to _data and _removeData have been replaced
	// with direct calls to dataPriv methods, these can be deprecated.
	_data: function( elem, name, data ) {
		return dataPriv.access( elem, name, data );
	},

	_removeData: function( elem, name ) {
		dataPriv.remove( elem, name );
	}
} );

jQuery.fn.extend( {
	data: function( key, value ) {
		var i, name, data,
			elem = this[ 0 ],
			attrs = elem && elem.attributes;

		// Gets all values
		if ( key === undefined ) {
			if ( this.length ) {
				data = dataUser.get( elem );

				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
					i = attrs.length;
					while ( i-- ) {

						// Support: IE11+
						// The attrs elements can be null (#14894)
						if ( attrs[ i ] ) {
							name = attrs[ i ].name;
							if ( name.indexOf( "data-" ) === 0 ) {
								name = jQuery.camelCase( name.slice( 5 ) );
								dataAttr( elem, name, data[ name ] );
							}
						}
					}
					dataPriv.set( elem, "hasDataAttrs", true );
				}
			}

			return data;
		}

		// Sets multiple values
		if ( typeof key === "object" ) {
			return this.each( function() {
				dataUser.set( this, key );
			} );
		}

		return access( this, function( value ) {
			var data, camelKey;

			// The calling jQuery object (element matches) is not empty
			// (and therefore has an element appears at this[ 0 ]) and the
			// `value` parameter was not undefined. An empty jQuery object
			// will result in `undefined` for elem = this[ 0 ] which will
			// throw an exception if an attempt to read a data cache is made.
			if ( elem && value === undefined ) {

				// Attempt to get data from the cache
				// with the key as-is
				data = dataUser.get( elem, key ) ||

					// Try to find dashed key if it exists (gh-2779)
					// This is for 2.2.x only
					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );

				if ( data !== undefined ) {
					return data;
				}

				camelKey = jQuery.camelCase( key );

				// Attempt to get data from the cache
				// with the key camelized
				data = dataUser.get( elem, camelKey );
				if ( data !== undefined ) {
					return data;
				}

				// Attempt to "discover" the data in
				// HTML5 custom data-* attrs
				data = dataAttr( elem, camelKey, undefined );
				if ( data !== undefined ) {
					return data;
				}

				// We tried really hard, but the data doesn't exist.
				return;
			}

			// Set the data...
			camelKey = jQuery.camelCase( key );
			this.each( function() {

				// First, attempt to store a copy or reference of any
				// data that might've been store with a camelCased key.
				var data = dataUser.get( this, camelKey );

				// For HTML5 data-* attribute interop, we have to
				// store property names with dashes in a camelCase form.
				// This might not apply to all properties...*
				dataUser.set( this, camelKey, value );

				// *... In the case of properties that might _actually_
				// have dashes, we need to also store a copy of that
				// unchanged property.
				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
					dataUser.set( this, key, value );
				}
			} );
		}, null, value, arguments.length > 1, null, true );
	},

	removeData: function( key ) {
		return this.each( function() {
			dataUser.remove( this, key );
		} );
	}
} );


jQuery.extend( {
	queue: function( elem, type, data ) {
		var queue;

		if ( elem ) {
			type = ( type || "fx" ) + "queue";
			queue = dataPriv.get( elem, type );

			// Speed up dequeue by getting out quickly if this is just a lookup
			if ( data ) {
				if ( !queue || jQuery.isArray( data ) ) {
					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
				} else {
					queue.push( data );
				}
			}
			return queue || [];
		}
	},

	dequeue: function( elem, type ) {
		type = type || "fx";

		var queue = jQuery.queue( elem, type ),
			startLength = queue.length,
			fn = queue.shift(),
			hooks = jQuery._queueHooks( elem, type ),
			next = function() {
				jQuery.dequeue( elem, type );
			};

		// If the fx queue is dequeued, always remove the progress sentinel
		if ( fn === "inprogress" ) {
			fn = queue.shift();
			startLength--;
		}

		if ( fn ) {

			// Add a progress sentinel to prevent the fx queue from being
			// automatically dequeued
			if ( type === "fx" ) {
				queue.unshift( "inprogress" );
			}

			// Clear up the last queue stop function
			delete hooks.stop;
			fn.call( elem, next, hooks );
		}

		if ( !startLength && hooks ) {
			hooks.empty.fire();
		}
	},

	// Not public - generate a queueHooks object, or return the current one
	_queueHooks: function( elem, type ) {
		var key = type + "queueHooks";
		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
			empty: jQuery.Callbacks( "once memory" ).add( function() {
				dataPriv.remove( elem, [ type + "queue", key ] );
			} )
		} );
	}
} );

jQuery.fn.extend( {
	queue: function( type, data ) {
		var setter = 2;

		if ( typeof type !== "string" ) {
			data = type;
			type = "fx";
			setter--;
		}

		if ( arguments.length < setter ) {
			return jQuery.queue( this[ 0 ], type );
		}

		return data === undefined ?
			this :
			this.each( function() {
				var queue = jQuery.queue( this, type, data );

				// Ensure a hooks for this queue
				jQuery._queueHooks( this, type );

				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
					jQuery.dequeue( this, type );
				}
			} );
	},
	dequeue: function( type ) {
		return this.each( function() {
			jQuery.dequeue( this, type );
		} );
	},
	clearQueue: function( type ) {
		return this.queue( type || "fx", [] );
	},

	// Get a promise resolved when queues of a certain type
	// are emptied (fx is the type by default)
	promise: function( type, obj ) {
		var tmp,
			count = 1,
			defer = jQuery.Deferred(),
			elements = this,
			i = this.length,
			resolve = function() {
				if ( !( --count ) ) {
					defer.resolveWith( elements, [ elements ] );
				}
			};

		if ( typeof type !== "string" ) {
			obj = type;
			type = undefined;
		}
		type = type || "fx";

		while ( i-- ) {
			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
			if ( tmp && tmp.empty ) {
				count++;
				tmp.empty.add( resolve );
			}
		}
		resolve();
		return defer.promise( obj );
	}
} );
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;

var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );


var cssExpand = [ "Top", "Right", "Bottom", "Left" ];

var isHidden = function( elem, el ) {

		// isHidden might be called from jQuery#filter function;
		// in that case, element will be second argument
		elem = el || elem;
		return jQuery.css( elem, "display" ) === "none" ||
			!jQuery.contains( elem.ownerDocument, elem );
	};



function adjustCSS( elem, prop, valueParts, tween ) {
	var adjusted,
		scale = 1,
		maxIterations = 20,
		currentValue = tween ?
			function() { return tween.cur(); } :
			function() { return jQuery.css( elem, prop, "" ); },
		initial = currentValue(),
		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

		// Starting value computation is required for potential unit mismatches
		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
			rcssNum.exec( jQuery.css( elem, prop ) );

	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {

		// Trust units reported by jQuery.css
		unit = unit || initialInUnit[ 3 ];

		// Make sure we update the tween properties later on
		valueParts = valueParts || [];

		// Iteratively approximate from a nonzero starting point
		initialInUnit = +initial || 1;

		do {

			// If previous iteration zeroed out, double until we get *something*.
			// Use string for doubling so we don't accidentally see scale as unchanged below
			scale = scale || ".5";

			// Adjust and apply
			initialInUnit = initialInUnit / scale;
			jQuery.style( elem, prop, initialInUnit + unit );

		// Update scale, tolerating zero or NaN from tween.cur()
		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
		} while (
			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
		);
	}

	if ( valueParts ) {
		initialInUnit = +initialInUnit || +initial || 0;

		// Apply relative offset (+=/-=) if specified
		adjusted = valueParts[ 1 ] ?
			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
			+valueParts[ 2 ];
		if ( tween ) {
			tween.unit = unit;
			tween.start = initialInUnit;
			tween.end = adjusted;
		}
	}
	return adjusted;
}
var rcheckableType = ( /^(?:checkbox|radio)$/i );

var rtagName = ( /<([\w:-]+)/ );

var rscriptType = ( /^$|\/(?:java|ecma)script/i );



// We have to close these tags to support XHTML (#13200)
var wrapMap = {

	// Support: IE9
	option: [ 1, "<select multiple='multiple'>", "</select>" ],

	// XHTML parsers do not magically insert elements in the
	// same way that tag soup parsers do. So we cannot shorten
	// this by omitting <tbody> or other required elements.
	thead: [ 1, "<table>", "</table>" ],
	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

	_default: [ 0, "", "" ]
};

// Support: IE9
wrapMap.optgroup = wrapMap.option;

wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;


function getAll( context, tag ) {

	// Support: IE9-11+
	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
	var ret = typeof context.getElementsByTagName !== "undefined" ?
			context.getElementsByTagName( tag || "*" ) :
			typeof context.querySelectorAll !== "undefined" ?
				context.querySelectorAll( tag || "*" ) :
			[];

	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
		jQuery.merge( [ context ], ret ) :
		ret;
}


// Mark scripts as having already been evaluated
function setGlobalEval( elems, refElements ) {
	var i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		dataPriv.set(
			elems[ i ],
			"globalEval",
			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
		);
	}
}


var rhtml = /<|&#?\w+;/;

function buildFragment( elems, context, scripts, selection, ignored ) {
	var elem, tmp, tag, wrap, contains, j,
		fragment = context.createDocumentFragment(),
		nodes = [],
		i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		elem = elems[ i ];

		if ( elem || elem === 0 ) {

			// Add nodes directly
			if ( jQuery.type( elem ) === "object" ) {

				// Support: Android<4.1, PhantomJS<2
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );

			// Convert non-html into a text node
			} else if ( !rhtml.test( elem ) ) {
				nodes.push( context.createTextNode( elem ) );

			// Convert html into DOM nodes
			} else {
				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );

				// Deserialize a standard representation
				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
				wrap = wrapMap[ tag ] || wrapMap._default;
				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];

				// Descend through wrappers to the right content
				j = wrap[ 0 ];
				while ( j-- ) {
					tmp = tmp.lastChild;
				}

				// Support: Android<4.1, PhantomJS<2
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, tmp.childNodes );

				// Remember the top-level container
				tmp = fragment.firstChild;

				// Ensure the created nodes are orphaned (#12392)
				tmp.textContent = "";
			}
		}
	}

	// Remove wrapper from fragment
	fragment.textContent = "";

	i = 0;
	while ( ( elem = nodes[ i++ ] ) ) {

		// Skip elements already in the context collection (trac-4087)
		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
			if ( ignored ) {
				ignored.push( elem );
			}
			continue;
		}

		contains = jQuery.contains( elem.ownerDocument, elem );

		// Append to fragment
		tmp = getAll( fragment.appendChild( elem ), "script" );

		// Preserve script evaluation history
		if ( contains ) {
			setGlobalEval( tmp );
		}

		// Capture executables
		if ( scripts ) {
			j = 0;
			while ( ( elem = tmp[ j++ ] ) ) {
				if ( rscriptType.test( elem.type || "" ) ) {
					scripts.push( elem );
				}
			}
		}
	}

	return fragment;
}


( function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Android 4.0-4.3, Safari<=5.1
	// Check state lost if the name is set (#11217)
	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );
	input.setAttribute( "name", "t" );

	div.appendChild( input );

	// Support: Safari<=5.1, Android<4.2
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE<=11+
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
} )();


var
	rkeyEvent = /^key/,
	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;

function returnTrue() {
	return true;
}

function returnFalse() {
	return false;
}

// Support: IE9
// See #13393 for more info
function safeActiveElement() {
	try {
		return document.activeElement;
	} catch ( err ) { }
}

function on( elem, types, selector, data, fn, one ) {
	var origFn, type;

	// Types can be a map of types/handlers
	if ( typeof types === "object" ) {

		// ( types-Object, selector, data )
		if ( typeof selector !== "string" ) {

			// ( types-Object, data )
			data = data || selector;
			selector = undefined;
		}
		for ( type in types ) {
			on( elem, type, selector, data, types[ type ], one );
		}
		return elem;
	}

	if ( data == null && fn == null ) {

		// ( types, fn )
		fn = selector;
		data = selector = undefined;
	} else if ( fn == null ) {
		if ( typeof selector === "string" ) {

			// ( types, selector, fn )
			fn = data;
			data = undefined;
		} else {

			// ( types, data, fn )
			fn = data;
			data = selector;
			selector = undefined;
		}
	}
	if ( fn === false ) {
		fn = returnFalse;
	} else if ( !fn ) {
		return elem;
	}

	if ( one === 1 ) {
		origFn = fn;
		fn = function( event ) {

			// Can use an empty set, since event contains the info
			jQuery().off( event );
			return origFn.apply( this, arguments );
		};

		// Use same guid so caller can remove using origFn
		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
	}
	return elem.each( function() {
		jQuery.event.add( this, types, fn, data, selector );
	} );
}

/*
 * Helper functions for managing events -- not part of the public interface.
 * Props to Dean Edwards' addEvent library for many of the ideas.
 */
jQuery.event = {

	global: {},

	add: function( elem, types, handler, data, selector ) {

		var handleObjIn, eventHandle, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = dataPriv.get( elem );

		// Don't attach events to noData or text/comment nodes (but allow plain objects)
		if ( !elemData ) {
			return;
		}

		// Caller can pass in an object of custom data in lieu of the handler
		if ( handler.handler ) {
			handleObjIn = handler;
			handler = handleObjIn.handler;
			selector = handleObjIn.selector;
		}

		// Make sure that the handler has a unique ID, used to find/remove it later
		if ( !handler.guid ) {
			handler.guid = jQuery.guid++;
		}

		// Init the element's event structure and main handler, if this is the first
		if ( !( events = elemData.events ) ) {
			events = elemData.events = {};
		}
		if ( !( eventHandle = elemData.handle ) ) {
			eventHandle = elemData.handle = function( e ) {

				// Discard the second event of a jQuery.event.trigger() and
				// when an event is called after a page has unloaded
				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
			};
		}

		// Handle multiple events separated by a space
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[ t ] ) || [];
			type = origType = tmp[ 1 ];
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// There *must* be a type, no attaching namespace-only handlers
			if ( !type ) {
				continue;
			}

			// If event changes its type, use the special event handlers for the changed type
			special = jQuery.event.special[ type ] || {};

			// If selector defined, determine special event api type, otherwise given type
			type = ( selector ? special.delegateType : special.bindType ) || type;

			// Update special based on newly reset type
			special = jQuery.event.special[ type ] || {};

			// handleObj is passed to all event handlers
			handleObj = jQuery.extend( {
				type: type,
				origType: origType,
				data: data,
				handler: handler,
				guid: handler.guid,
				selector: selector,
				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
				namespace: namespaces.join( "." )
			}, handleObjIn );

			// Init the event handler queue if we're the first
			if ( !( handlers = events[ type ] ) ) {
				handlers = events[ type ] = [];
				handlers.delegateCount = 0;

				// Only use addEventListener if the special events handler returns false
				if ( !special.setup ||
					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {

					if ( elem.addEventListener ) {
						elem.addEventListener( type, eventHandle );
					}
				}
			}

			if ( special.add ) {
				special.add.call( elem, handleObj );

				if ( !handleObj.handler.guid ) {
					handleObj.handler.guid = handler.guid;
				}
			}

			// Add to the element's handler list, delegates in front
			if ( selector ) {
				handlers.splice( handlers.delegateCount++, 0, handleObj );
			} else {
				handlers.push( handleObj );
			}

			// Keep track of which events have ever been used, for event optimization
			jQuery.event.global[ type ] = true;
		}

	},

	// Detach an event or set of events from an element
	remove: function( elem, types, handler, selector, mappedTypes ) {

		var j, origCount, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );

		if ( !elemData || !( events = elemData.events ) ) {
			return;
		}

		// Once for each type.namespace in types; type may be omitted
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[ t ] ) || [];
			type = origType = tmp[ 1 ];
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// Unbind all events (on this namespace, if provided) for the element
			if ( !type ) {
				for ( type in events ) {
					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
				}
				continue;
			}

			special = jQuery.event.special[ type ] || {};
			type = ( selector ? special.delegateType : special.bindType ) || type;
			handlers = events[ type ] || [];
			tmp = tmp[ 2 ] &&
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );

			// Remove matching events
			origCount = j = handlers.length;
			while ( j-- ) {
				handleObj = handlers[ j ];

				if ( ( mappedTypes || origType === handleObj.origType ) &&
					( !handler || handler.guid === handleObj.guid ) &&
					( !tmp || tmp.test( handleObj.namespace ) ) &&
					( !selector || selector === handleObj.selector ||
						selector === "**" && handleObj.selector ) ) {
					handlers.splice( j, 1 );

					if ( handleObj.selector ) {
						handlers.delegateCount--;
					}
					if ( special.remove ) {
						special.remove.call( elem, handleObj );
					}
				}
			}

			// Remove generic event handler if we removed something and no more handlers exist
			// (avoids potential for endless recursion during removal of special event handlers)
			if ( origCount && !handlers.length ) {
				if ( !special.teardown ||
					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {

					jQuery.removeEvent( elem, type, elemData.handle );
				}

				delete events[ type ];
			}
		}

		// Remove data and the expando if it's no longer used
		if ( jQuery.isEmptyObject( events ) ) {
			dataPriv.remove( elem, "handle events" );
		}
	},

	dispatch: function( event ) {

		// Make a writable jQuery.Event from the native event object
		event = jQuery.event.fix( event );

		var i, j, ret, matched, handleObj,
			handlerQueue = [],
			args = slice.call( arguments ),
			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
			special = jQuery.event.special[ event.type ] || {};

		// Use the fix-ed jQuery.Event rather than the (read-only) native event
		args[ 0 ] = event;
		event.delegateTarget = this;

		// Call the preDispatch hook for the mapped type, and let it bail if desired
		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
			return;
		}

		// Determine handlers
		handlerQueue = jQuery.event.handlers.call( this, event, handlers );

		// Run delegates first; they may want to stop propagation beneath us
		i = 0;
		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
			event.currentTarget = matched.elem;

			j = 0;
			while ( ( handleObj = matched.handlers[ j++ ] ) &&
				!event.isImmediatePropagationStopped() ) {

				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
				// a subset or equal to those in the bound event (both can have no namespace).
				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {

					event.handleObj = handleObj;
					event.data = handleObj.data;

					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
						handleObj.handler ).apply( matched.elem, args );

					if ( ret !== undefined ) {
						if ( ( event.result = ret ) === false ) {
							event.preventDefault();
							event.stopPropagation();
						}
					}
				}
			}
		}

		// Call the postDispatch hook for the mapped type
		if ( special.postDispatch ) {
			special.postDispatch.call( this, event );
		}

		return event.result;
	},

	handlers: function( event, handlers ) {
		var i, matches, sel, handleObj,
			handlerQueue = [],
			delegateCount = handlers.delegateCount,
			cur = event.target;

		// Support (at least): Chrome, IE9
		// Find delegate handlers
		// Black-hole SVG <use> instance trees (#13180)
		//
		// Support: Firefox<=42+
		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
		if ( delegateCount && cur.nodeType &&
			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {

			for ( ; cur !== this; cur = cur.parentNode || this ) {

				// Don't check non-elements (#13208)
				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
					matches = [];
					for ( i = 0; i < delegateCount; i++ ) {
						handleObj = handlers[ i ];

						// Don't conflict with Object.prototype properties (#13203)
						sel = handleObj.selector + " ";

						if ( matches[ sel ] === undefined ) {
							matches[ sel ] = handleObj.needsContext ?
								jQuery( sel, this ).index( cur ) > -1 :
								jQuery.find( sel, this, null, [ cur ] ).length;
						}
						if ( matches[ sel ] ) {
							matches.push( handleObj );
						}
					}
					if ( matches.length ) {
						handlerQueue.push( { elem: cur, handlers: matches } );
					}
				}
			}
		}

		// Add the remaining (directly-bound) handlers
		if ( delegateCount < handlers.length ) {
			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
		}

		return handlerQueue;
	},

	// Includes some event props shared by KeyEvent and MouseEvent
	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),

	fixHooks: {},

	keyHooks: {
		props: "char charCode key keyCode".split( " " ),
		filter: function( event, original ) {

			// Add which for key events
			if ( event.which == null ) {
				event.which = original.charCode != null ? original.charCode : original.keyCode;
			}

			return event;
		}
	},

	mouseHooks: {
		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
			"screenX screenY toElement" ).split( " " ),
		filter: function( event, original ) {
			var eventDoc, doc, body,
				button = original.button;

			// Calculate pageX/Y if missing and clientX/Y available
			if ( event.pageX == null && original.clientX != null ) {
				eventDoc = event.target.ownerDocument || document;
				doc = eventDoc.documentElement;
				body = eventDoc.body;

				event.pageX = original.clientX +
					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
					( doc && doc.clientLeft || body && body.clientLeft || 0 );
				event.pageY = original.clientY +
					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
					( doc && doc.clientTop  || body && body.clientTop  || 0 );
			}

			// Add which for click: 1 === left; 2 === middle; 3 === right
			// Note: button is not normalized, so don't use it
			if ( !event.which && button !== undefined ) {
				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
			}

			return event;
		}
	},

	fix: function( event ) {
		if ( event[ jQuery.expando ] ) {
			return event;
		}

		// Create a writable copy of the event object and normalize some properties
		var i, prop, copy,
			type = event.type,
			originalEvent = event,
			fixHook = this.fixHooks[ type ];

		if ( !fixHook ) {
			this.fixHooks[ type ] = fixHook =
				rmouseEvent.test( type ) ? this.mouseHooks :
				rkeyEvent.test( type ) ? this.keyHooks :
				{};
		}
		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;

		event = new jQuery.Event( originalEvent );

		i = copy.length;
		while ( i-- ) {
			prop = copy[ i ];
			event[ prop ] = originalEvent[ prop ];
		}

		// Support: Cordova 2.5 (WebKit) (#13255)
		// All events should have a target; Cordova deviceready doesn't
		if ( !event.target ) {
			event.target = document;
		}

		// Support: Safari 6.0+, Chrome<28
		// Target should not be a text node (#504, #13143)
		if ( event.target.nodeType === 3 ) {
			event.target = event.target.parentNode;
		}

		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
	},

	special: {
		load: {

			// Prevent triggered image.load events from bubbling to window.load
			noBubble: true
		},
		focus: {

			// Fire native event if possible so blur/focus sequence is correct
			trigger: function() {
				if ( this !== safeActiveElement() && this.focus ) {
					this.focus();
					return false;
				}
			},
			delegateType: "focusin"
		},
		blur: {
			trigger: function() {
				if ( this === safeActiveElement() && this.blur ) {
					this.blur();
					return false;
				}
			},
			delegateType: "focusout"
		},
		click: {

			// For checkbox, fire native event so checked state will be right
			trigger: function() {
				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
					this.click();
					return false;
				}
			},

			// For cross-browser consistency, don't fire native .click() on links
			_default: function( event ) {
				return jQuery.nodeName( event.target, "a" );
			}
		},

		beforeunload: {
			postDispatch: function( event ) {

				// Support: Firefox 20+
				// Firefox doesn't alert if the returnValue field is not set.
				if ( event.result !== undefined && event.originalEvent ) {
					event.originalEvent.returnValue = event.result;
				}
			}
		}
	}
};

jQuery.removeEvent = function( elem, type, handle ) {

	// This "if" is needed for plain objects
	if ( elem.removeEventListener ) {
		elem.removeEventListener( type, handle );
	}
};

jQuery.Event = function( src, props ) {

	// Allow instantiation without the 'new' keyword
	if ( !( this instanceof jQuery.Event ) ) {
		return new jQuery.Event( src, props );
	}

	// Event object
	if ( src && src.type ) {
		this.originalEvent = src;
		this.type = src.type;

		// Events bubbling up the document may have been marked as prevented
		// by a handler lower down the tree; reflect the correct value.
		this.isDefaultPrevented = src.defaultPrevented ||
				src.defaultPrevented === undefined &&

				// Support: Android<4.0
				src.returnValue === false ?
			returnTrue :
			returnFalse;

	// Event type
	} else {
		this.type = src;
	}

	// Put explicitly provided properties onto the event object
	if ( props ) {
		jQuery.extend( this, props );
	}

	// Create a timestamp if incoming event doesn't have one
	this.timeStamp = src && src.timeStamp || jQuery.now();

	// Mark it as fixed
	this[ jQuery.expando ] = true;
};

// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
	constructor: jQuery.Event,
	isDefaultPrevented: returnFalse,
	isPropagationStopped: returnFalse,
	isImmediatePropagationStopped: returnFalse,
	isSimulated: false,

	preventDefault: function() {
		var e = this.originalEvent;

		this.isDefaultPrevented = returnTrue;

		if ( e && !this.isSimulated ) {
			e.preventDefault();
		}
	},
	stopPropagation: function() {
		var e = this.originalEvent;

		this.isPropagationStopped = returnTrue;

		if ( e && !this.isSimulated ) {
			e.stopPropagation();
		}
	},
	stopImmediatePropagation: function() {
		var e = this.originalEvent;

		this.isImmediatePropagationStopped = returnTrue;

		if ( e && !this.isSimulated ) {
			e.stopImmediatePropagation();
		}

		this.stopPropagation();
	}
};

// Create mouseenter/leave events using mouseover/out and event-time checks
// so that event delegation works in jQuery.
// Do the same for pointerenter/pointerleave and pointerover/pointerout
//
// Support: Safari 7 only
// Safari sends mouseenter too often; see:
// https://code.google.com/p/chromium/issues/detail?id=470258
// for the description of the bug (it existed in older Chrome versions as well).
jQuery.each( {
	mouseenter: "mouseover",
	mouseleave: "mouseout",
	pointerenter: "pointerover",
	pointerleave: "pointerout"
}, function( orig, fix ) {
	jQuery.event.special[ orig ] = {
		delegateType: fix,
		bindType: fix,

		handle: function( event ) {
			var ret,
				target = this,
				related = event.relatedTarget,
				handleObj = event.handleObj;

			// For mouseenter/leave call the handler if related is outside the target.
			// NB: No relatedTarget if the mouse left/entered the browser window
			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
				event.type = handleObj.origType;
				ret = handleObj.handler.apply( this, arguments );
				event.type = fix;
			}
			return ret;
		}
	};
} );

jQuery.fn.extend( {
	on: function( types, selector, data, fn ) {
		return on( this, types, selector, data, fn );
	},
	one: function( types, selector, data, fn ) {
		return on( this, types, selector, data, fn, 1 );
	},
	off: function( types, selector, fn ) {
		var handleObj, type;
		if ( types && types.preventDefault && types.handleObj ) {

			// ( event )  dispatched jQuery.Event
			handleObj = types.handleObj;
			jQuery( types.delegateTarget ).off(
				handleObj.namespace ?
					handleObj.origType + "." + handleObj.namespace :
					handleObj.origType,
				handleObj.selector,
				handleObj.handler
			);
			return this;
		}
		if ( typeof types === "object" ) {

			// ( types-object [, selector] )
			for ( type in types ) {
				this.off( type, selector, types[ type ] );
			}
			return this;
		}
		if ( selector === false || typeof selector === "function" ) {

			// ( types [, fn] )
			fn = selector;
			selector = undefined;
		}
		if ( fn === false ) {
			fn = returnFalse;
		}
		return this.each( function() {
			jQuery.event.remove( this, types, fn, selector );
		} );
	}
} );


var
	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,

	// Support: IE 10-11, Edge 10240+
	// In IE/Edge using regex groups here causes severe slowdowns.
	// See https://connect.microsoft.com/IE/feedback/details/1736512/
	rnoInnerhtml = /<script|<style|<link/i,

	// checked="checked" or checked
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
	rscriptTypeMasked = /^true\/(.*)/,
	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;

// Manipulating tables requires a tbody
function manipulationTarget( elem, content ) {
	return jQuery.nodeName( elem, "table" ) &&
		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?

		elem.getElementsByTagName( "tbody" )[ 0 ] ||
			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
		elem;
}

// Replace/restore the type attribute of script elements for safe DOM manipulation
function disableScript( elem ) {
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
	return elem;
}
function restoreScript( elem ) {
	var match = rscriptTypeMasked.exec( elem.type );

	if ( match ) {
		elem.type = match[ 1 ];
	} else {
		elem.removeAttribute( "type" );
	}

	return elem;
}

function cloneCopyEvent( src, dest ) {
	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;

	if ( dest.nodeType !== 1 ) {
		return;
	}

	// 1. Copy private data: events, handlers, etc.
	if ( dataPriv.hasData( src ) ) {
		pdataOld = dataPriv.access( src );
		pdataCur = dataPriv.set( dest, pdataOld );
		events = pdataOld.events;

		if ( events ) {
			delete pdataCur.handle;
			pdataCur.events = {};

			for ( type in events ) {
				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
					jQuery.event.add( dest, type, events[ type ][ i ] );
				}
			}
		}
	}

	// 2. Copy user data
	if ( dataUser.hasData( src ) ) {
		udataOld = dataUser.access( src );
		udataCur = jQuery.extend( {}, udataOld );

		dataUser.set( dest, udataCur );
	}
}

// Fix IE bugs, see support tests
function fixInput( src, dest ) {
	var nodeName = dest.nodeName.toLowerCase();

	// Fails to persist the checked state of a cloned checkbox or radio button.
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
		dest.checked = src.checked;

	// Fails to return the selected option to the default selected state when cloning options
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
		dest.defaultValue = src.defaultValue;
	}
}

function domManip( collection, args, callback, ignored ) {

	// Flatten any nested arrays
	args = concat.apply( [], args );

	var fragment, first, scripts, hasScripts, node, doc,
		i = 0,
		l = collection.length,
		iNoClone = l - 1,
		value = args[ 0 ],
		isFunction = jQuery.isFunction( value );

	// We can't cloneNode fragments that contain checked, in WebKit
	if ( isFunction ||
			( l > 1 && typeof value === "string" &&
				!support.checkClone && rchecked.test( value ) ) ) {
		return collection.each( function( index ) {
			var self = collection.eq( index );
			if ( isFunction ) {
				args[ 0 ] = value.call( this, index, self.html() );
			}
			domManip( self, args, callback, ignored );
		} );
	}

	if ( l ) {
		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
		first = fragment.firstChild;

		if ( fragment.childNodes.length === 1 ) {
			fragment = first;
		}

		// Require either new content or an interest in ignored elements to invoke the callback
		if ( first || ignored ) {
			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
			hasScripts = scripts.length;

			// Use the original fragment for the last item
			// instead of the first because it can end up
			// being emptied incorrectly in certain situations (#8070).
			for ( ; i < l; i++ ) {
				node = fragment;

				if ( i !== iNoClone ) {
					node = jQuery.clone( node, true, true );

					// Keep references to cloned scripts for later restoration
					if ( hasScripts ) {

						// Support: Android<4.1, PhantomJS<2
						// push.apply(_, arraylike) throws on ancient WebKit
						jQuery.merge( scripts, getAll( node, "script" ) );
					}
				}

				callback.call( collection[ i ], node, i );
			}

			if ( hasScripts ) {
				doc = scripts[ scripts.length - 1 ].ownerDocument;

				// Reenable scripts
				jQuery.map( scripts, restoreScript );

				// Evaluate executable scripts on first document insertion
				for ( i = 0; i < hasScripts; i++ ) {
					node = scripts[ i ];
					if ( rscriptType.test( node.type || "" ) &&
						!dataPriv.access( node, "globalEval" ) &&
						jQuery.contains( doc, node ) ) {

						if ( node.src ) {

							// Optional AJAX dependency, but won't run scripts if not present
							if ( jQuery._evalUrl ) {
								jQuery._evalUrl( node.src );
							}
						} else {
							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
						}
					}
				}
			}
		}
	}

	return collection;
}

function remove( elem, selector, keepData ) {
	var node,
		nodes = selector ? jQuery.filter( selector, elem ) : elem,
		i = 0;

	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
		if ( !keepData && node.nodeType === 1 ) {
			jQuery.cleanData( getAll( node ) );
		}

		if ( node.parentNode ) {
			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
				setGlobalEval( getAll( node, "script" ) );
			}
			node.parentNode.removeChild( node );
		}
	}

	return elem;
}

jQuery.extend( {
	htmlPrefilter: function( html ) {
		return html.replace( rxhtmlTag, "<$1></$2>" );
	},

	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
		var i, l, srcElements, destElements,
			clone = elem.cloneNode( true ),
			inPage = jQuery.contains( elem.ownerDocument, elem );

		// Fix IE cloning issues
		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
				!jQuery.isXMLDoc( elem ) ) {

			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
			destElements = getAll( clone );
			srcElements = getAll( elem );

			for ( i = 0, l = srcElements.length; i < l; i++ ) {
				fixInput( srcElements[ i ], destElements[ i ] );
			}
		}

		// Copy the events from the original to the clone
		if ( dataAndEvents ) {
			if ( deepDataAndEvents ) {
				srcElements = srcElements || getAll( elem );
				destElements = destElements || getAll( clone );

				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
				}
			} else {
				cloneCopyEvent( elem, clone );
			}
		}

		// Preserve script evaluation history
		destElements = getAll( clone, "script" );
		if ( destElements.length > 0 ) {
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
		}

		// Return the cloned set
		return clone;
	},

	cleanData: function( elems ) {
		var data, elem, type,
			special = jQuery.event.special,
			i = 0;

		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
			if ( acceptData( elem ) ) {
				if ( ( data = elem[ dataPriv.expando ] ) ) {
					if ( data.events ) {
						for ( type in data.events ) {
							if ( special[ type ] ) {
								jQuery.event.remove( elem, type );

							// This is a shortcut to avoid jQuery.event.remove's overhead
							} else {
								jQuery.removeEvent( elem, type, data.handle );
							}
						}
					}

					// Support: Chrome <= 35-45+
					// Assign undefined instead of using delete, see Data#remove
					elem[ dataPriv.expando ] = undefined;
				}
				if ( elem[ dataUser.expando ] ) {

					// Support: Chrome <= 35-45+
					// Assign undefined instead of using delete, see Data#remove
					elem[ dataUser.expando ] = undefined;
				}
			}
		}
	}
} );

jQuery.fn.extend( {

	// Keep domManip exposed until 3.0 (gh-2225)
	domManip: domManip,

	detach: function( selector ) {
		return remove( this, selector, true );
	},

	remove: function( selector ) {
		return remove( this, selector );
	},

	text: function( value ) {
		return access( this, function( value ) {
			return value === undefined ?
				jQuery.text( this ) :
				this.empty().each( function() {
					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
						this.textContent = value;
					}
				} );
		}, null, value, arguments.length );
	},

	append: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.appendChild( elem );
			}
		} );
	},

	prepend: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.insertBefore( elem, target.firstChild );
			}
		} );
	},

	before: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this );
			}
		} );
	},

	after: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this.nextSibling );
			}
		} );
	},

	empty: function() {
		var elem,
			i = 0;

		for ( ; ( elem = this[ i ] ) != null; i++ ) {
			if ( elem.nodeType === 1 ) {

				// Prevent memory leaks
				jQuery.cleanData( getAll( elem, false ) );

				// Remove any remaining nodes
				elem.textContent = "";
			}
		}

		return this;
	},

	clone: function( dataAndEvents, deepDataAndEvents ) {
		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

		return this.map( function() {
			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
		} );
	},

	html: function( value ) {
		return access( this, function( value ) {
			var elem = this[ 0 ] || {},
				i = 0,
				l = this.length;

			if ( value === undefined && elem.nodeType === 1 ) {
				return elem.innerHTML;
			}

			// See if we can take a shortcut and just use innerHTML
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

				value = jQuery.htmlPrefilter( value );

				try {
					for ( ; i < l; i++ ) {
						elem = this[ i ] || {};

						// Remove element nodes and prevent memory leaks
						if ( elem.nodeType === 1 ) {
							jQuery.cleanData( getAll( elem, false ) );
							elem.innerHTML = value;
						}
					}

					elem = 0;

				// If using innerHTML throws an exception, use the fallback method
				} catch ( e ) {}
			}

			if ( elem ) {
				this.empty().append( value );
			}
		}, null, value, arguments.length );
	},

	replaceWith: function() {
		var ignored = [];

		// Make the changes, replacing each non-ignored context element with the new content
		return domManip( this, arguments, function( elem ) {
			var parent = this.parentNode;

			if ( jQuery.inArray( this, ignored ) < 0 ) {
				jQuery.cleanData( getAll( this ) );
				if ( parent ) {
					parent.replaceChild( elem, this );
				}
			}

		// Force callback invocation
		}, ignored );
	}
} );

jQuery.each( {
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function( name, original ) {
	jQuery.fn[ name ] = function( selector ) {
		var elems,
			ret = [],
			insert = jQuery( selector ),
			last = insert.length - 1,
			i = 0;

		for ( ; i <= last; i++ ) {
			elems = i === last ? this : this.clone( true );
			jQuery( insert[ i ] )[ original ]( elems );

			// Support: QtWebKit
			// .get() because push.apply(_, arraylike) throws
			push.apply( ret, elems.get() );
		}

		return this.pushStack( ret );
	};
} );


var iframe,
	elemdisplay = {

		// Support: Firefox
		// We have to pre-define these values for FF (#10227)
		HTML: "block",
		BODY: "block"
	};

/**
 * Retrieve the actual display of a element
 * @param {String} name nodeName of the element
 * @param {Object} doc Document object
 */

// Called only from within defaultDisplay
function actualDisplay( name, doc ) {
	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),

		display = jQuery.css( elem[ 0 ], "display" );

	// We don't have any data stored on the element,
	// so use "detach" method as fast way to get rid of the element
	elem.detach();

	return display;
}

/**
 * Try to determine the default display value of an element
 * @param {String} nodeName
 */
function defaultDisplay( nodeName ) {
	var doc = document,
		display = elemdisplay[ nodeName ];

	if ( !display ) {
		display = actualDisplay( nodeName, doc );

		// If the simple way fails, read from inside an iframe
		if ( display === "none" || !display ) {

			// Use the already-created iframe if possible
			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
				.appendTo( doc.documentElement );

			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
			doc = iframe[ 0 ].contentDocument;

			// Support: IE
			doc.write();
			doc.close();

			display = actualDisplay( nodeName, doc );
			iframe.detach();
		}

		// Store the correct default display
		elemdisplay[ nodeName ] = display;
	}

	return display;
}
var rmargin = ( /^margin/ );

var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );

var getStyles = function( elem ) {

		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		var view = elem.ownerDocument.defaultView;

		if ( !view || !view.opener ) {
			view = window;
		}

		return view.getComputedStyle( elem );
	};

var swap = function( elem, options, callback, args ) {
	var ret, name,
		old = {};

	// Remember the old values, and insert the new ones
	for ( name in options ) {
		old[ name ] = elem.style[ name ];
		elem.style[ name ] = options[ name ];
	}

	ret = callback.apply( elem, args || [] );

	// Revert the old values
	for ( name in options ) {
		elem.style[ name ] = old[ name ];
	}

	return ret;
};


var documentElement = document.documentElement;



( function() {
	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
		container = document.createElement( "div" ),
		div = document.createElement( "div" );

	// Finish early in limited (non-browser) environments
	if ( !div.style ) {
		return;
	}

	// Support: IE9-11+
	// Style of cloned element affects source element cloned (#8908)
	div.style.backgroundClip = "content-box";
	div.cloneNode( true ).style.backgroundClip = "";
	support.clearCloneStyle = div.style.backgroundClip === "content-box";

	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
		"padding:0;margin-top:1px;position:absolute";
	container.appendChild( div );

	// Executing both pixelPosition & boxSizingReliable tests require only one layout
	// so they're executed at the same time to save the second computation.
	function computeStyleTests() {
		div.style.cssText =

			// Support: Firefox<29, Android 2.3
			// Vendor-prefix box-sizing
			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
			"position:relative;display:block;" +
			"margin:auto;border:1px;padding:1px;" +
			"top:1%;width:50%";
		div.innerHTML = "";
		documentElement.appendChild( container );

		var divStyle = window.getComputedStyle( div );
		pixelPositionVal = divStyle.top !== "1%";
		reliableMarginLeftVal = divStyle.marginLeft === "2px";
		boxSizingReliableVal = divStyle.width === "4px";

		// Support: Android 4.0 - 4.3 only
		// Some styles come back with percentage values, even though they shouldn't
		div.style.marginRight = "50%";
		pixelMarginRightVal = divStyle.marginRight === "4px";

		documentElement.removeChild( container );
	}

	jQuery.extend( support, {
		pixelPosition: function() {

			// This test is executed only once but we still do memoizing
			// since we can use the boxSizingReliable pre-computing.
			// No need to check if the test was already performed, though.
			computeStyleTests();
			return pixelPositionVal;
		},
		boxSizingReliable: function() {
			if ( boxSizingReliableVal == null ) {
				computeStyleTests();
			}
			return boxSizingReliableVal;
		},
		pixelMarginRight: function() {

			// Support: Android 4.0-4.3
			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
			// since that compresses better and they're computed together anyway.
			if ( boxSizingReliableVal == null ) {
				computeStyleTests();
			}
			return pixelMarginRightVal;
		},
		reliableMarginLeft: function() {

			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
			if ( boxSizingReliableVal == null ) {
				computeStyleTests();
			}
			return reliableMarginLeftVal;
		},
		reliableMarginRight: function() {

			// Support: Android 2.3
			// Check if div with explicit width and no margin-right incorrectly
			// gets computed margin-right based on width of container. (#3333)
			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
			// This support function is only executed once so no memoizing is needed.
			var ret,
				marginDiv = div.appendChild( document.createElement( "div" ) );

			// Reset CSS: box-sizing; display; margin; border; padding
			marginDiv.style.cssText = div.style.cssText =

				// Support: Android 2.3
				// Vendor-prefix box-sizing
				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
				"display:block;margin:0;border:0;padding:0";
			marginDiv.style.marginRight = marginDiv.style.width = "0";
			div.style.width = "1px";
			documentElement.appendChild( container );

			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );

			documentElement.removeChild( container );
			div.removeChild( marginDiv );

			return ret;
		}
	} );
} )();


function curCSS( elem, name, computed ) {
	var width, minWidth, maxWidth, ret,
		style = elem.style;

	computed = computed || getStyles( elem );
	ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;

	// Support: Opera 12.1x only
	// Fall back to style even without computed
	// computed is undefined for elems on document fragments
	if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
		ret = jQuery.style( elem, name );
	}

	// Support: IE9
	// getPropertyValue is only needed for .css('filter') (#12537)
	if ( computed ) {

		// A tribute to the "awesome hack by Dean Edwards"
		// Android Browser returns percentage for some values,
		// but width seems to be reliably pixels.
		// This is against the CSSOM draft spec:
		// http://dev.w3.org/csswg/cssom/#resolved-values
		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {

			// Remember the original values
			width = style.width;
			minWidth = style.minWidth;
			maxWidth = style.maxWidth;

			// Put in the new values to get a computed value out
			style.minWidth = style.maxWidth = style.width = ret;
			ret = computed.width;

			// Revert the changed values
			style.width = width;
			style.minWidth = minWidth;
			style.maxWidth = maxWidth;
		}
	}

	return ret !== undefined ?

		// Support: IE9-11+
		// IE returns zIndex value as an integer.
		ret + "" :
		ret;
}


function addGetHookIf( conditionFn, hookFn ) {

	// Define the hook, we'll check on the first run if it's really needed.
	return {
		get: function() {
			if ( conditionFn() ) {

				// Hook not needed (or it's not possible to use it due
				// to missing dependency), remove it.
				delete this.get;
				return;
			}

			// Hook needed; redefine it so that the support test is not executed again.
			return ( this.get = hookFn ).apply( this, arguments );
		}
	};
}


var

	// Swappable if display is none or starts with table
	// except "table", "table-cell", or "table-caption"
	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(none|table(?!-c[ea]).+)/,

	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
	cssNormalTransform = {
		letterSpacing: "0",
		fontWeight: "400"
	},

	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
	emptyStyle = document.createElement( "div" ).style;

// Return a css property mapped to a potentially vendor prefixed property
function vendorPropName( name ) {

	// Shortcut for names that are not vendor prefixed
	if ( name in emptyStyle ) {
		return name;
	}

	// Check for vendor prefixed names
	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
		i = cssPrefixes.length;

	while ( i-- ) {
		name = cssPrefixes[ i ] + capName;
		if ( name in emptyStyle ) {
			return name;
		}
	}
}

function setPositiveNumber( elem, value, subtract ) {

	// Any relative (+/-) values have already been
	// normalized at this point
	var matches = rcssNum.exec( value );
	return matches ?

		// Guard against undefined "subtract", e.g., when used as in cssHooks
		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
		value;
}

function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
	var i = extra === ( isBorderBox ? "border" : "content" ) ?

		// If we already have the right measurement, avoid augmentation
		4 :

		// Otherwise initialize for horizontal or vertical properties
		name === "width" ? 1 : 0,

		val = 0;

	for ( ; i < 4; i += 2 ) {

		// Both box models exclude margin, so add it if we want it
		if ( extra === "margin" ) {
			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
		}

		if ( isBorderBox ) {

			// border-box includes padding, so remove it if we want content
			if ( extra === "content" ) {
				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
			}

			// At this point, extra isn't border nor margin, so remove border
			if ( extra !== "margin" ) {
				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		} else {

			// At this point, extra isn't content, so add padding
			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

			// At this point, extra isn't content nor padding, so add border
			if ( extra !== "padding" ) {
				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		}
	}

	return val;
}

function getWidthOrHeight( elem, name, extra ) {

	// Start with offset property, which is equivalent to the border-box value
	var valueIsBorderBox = true,
		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
		styles = getStyles( elem ),
		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";

	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
	if ( val <= 0 || val == null ) {

		// Fall back to computed then uncomputed css if necessary
		val = curCSS( elem, name, styles );
		if ( val < 0 || val == null ) {
			val = elem.style[ name ];
		}

		// Computed unit is not pixels. Stop here and return.
		if ( rnumnonpx.test( val ) ) {
			return val;
		}

		// Check for style in case a browser which returns unreliable values
		// for getComputedStyle silently falls back to the reliable elem.style
		valueIsBorderBox = isBorderBox &&
			( support.boxSizingReliable() || val === elem.style[ name ] );

		// Normalize "", auto, and prepare for extra
		val = parseFloat( val ) || 0;
	}

	// Use the active box-sizing model to add/subtract irrelevant styles
	return ( val +
		augmentWidthOrHeight(
			elem,
			name,
			extra || ( isBorderBox ? "border" : "content" ),
			valueIsBorderBox,
			styles
		)
	) + "px";
}

function showHide( elements, show ) {
	var display, elem, hidden,
		values = [],
		index = 0,
		length = elements.length;

	for ( ; index < length; index++ ) {
		elem = elements[ index ];
		if ( !elem.style ) {
			continue;
		}

		values[ index ] = dataPriv.get( elem, "olddisplay" );
		display = elem.style.display;
		if ( show ) {

			// Reset the inline display of this element to learn if it is
			// being hidden by cascaded rules or not
			if ( !values[ index ] && display === "none" ) {
				elem.style.display = "";
			}

			// Set elements which have been overridden with display: none
			// in a stylesheet to whatever the default browser style is
			// for such an element
			if ( elem.style.display === "" && isHidden( elem ) ) {
				values[ index ] = dataPriv.access(
					elem,
					"olddisplay",
					defaultDisplay( elem.nodeName )
				);
			}
		} else {
			hidden = isHidden( elem );

			if ( display !== "none" || !hidden ) {
				dataPriv.set(
					elem,
					"olddisplay",
					hidden ? display : jQuery.css( elem, "display" )
				);
			}
		}
	}

	// Set the display of most of the elements in a second loop
	// to avoid the constant reflow
	for ( index = 0; index < length; index++ ) {
		elem = elements[ index ];
		if ( !elem.style ) {
			continue;
		}
		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
			elem.style.display = show ? values[ index ] || "" : "none";
		}
	}

	return elements;
}

jQuery.extend( {

	// Add in style property hooks for overriding the default
	// behavior of getting and setting a style property
	cssHooks: {
		opacity: {
			get: function( elem, computed ) {
				if ( computed ) {

					// We should always get a number back from opacity
					var ret = curCSS( elem, "opacity" );
					return ret === "" ? "1" : ret;
				}
			}
		}
	},

	// Don't automatically add "px" to these possibly-unitless properties
	cssNumber: {
		"animationIterationCount": true,
		"columnCount": true,
		"fillOpacity": true,
		"flexGrow": true,
		"flexShrink": true,
		"fontWeight": true,
		"lineHeight": true,
		"opacity": true,
		"order": true,
		"orphans": true,
		"widows": true,
		"zIndex": true,
		"zoom": true
	},

	// Add in properties whose names you wish to fix before
	// setting or getting the value
	cssProps: {
		"float": "cssFloat"
	},

	// Get and set the style property on a DOM Node
	style: function( elem, name, value, extra ) {

		// Don't set styles on text and comment nodes
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
			return;
		}

		// Make sure that we're working with the right name
		var ret, type, hooks,
			origName = jQuery.camelCase( name ),
			style = elem.style;

		name = jQuery.cssProps[ origName ] ||
			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );

		// Gets hook for the prefixed version, then unprefixed version
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// Check if we're setting a value
		if ( value !== undefined ) {
			type = typeof value;

			// Convert "+=" or "-=" to relative numbers (#7345)
			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
				value = adjustCSS( elem, name, ret );

				// Fixes bug #9237
				type = "number";
			}

			// Make sure that null and NaN values aren't set (#7116)
			if ( value == null || value !== value ) {
				return;
			}

			// If a number was passed in, add the unit (except for certain CSS properties)
			if ( type === "number" ) {
				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
			}

			// Support: IE9-11+
			// background-* props affect original clone's values
			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
				style[ name ] = "inherit";
			}

			// If a hook was provided, use that value, otherwise just set the specified value
			if ( !hooks || !( "set" in hooks ) ||
				( value = hooks.set( elem, value, extra ) ) !== undefined ) {

				style[ name ] = value;
			}

		} else {

			// If a hook was provided get the non-computed value from there
			if ( hooks && "get" in hooks &&
				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {

				return ret;
			}

			// Otherwise just get the value from the style object
			return style[ name ];
		}
	},

	css: function( elem, name, extra, styles ) {
		var val, num, hooks,
			origName = jQuery.camelCase( name );

		// Make sure that we're working with the right name
		name = jQuery.cssProps[ origName ] ||
			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );

		// Try prefixed name followed by the unprefixed name
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// If a hook was provided get the computed value from there
		if ( hooks && "get" in hooks ) {
			val = hooks.get( elem, true, extra );
		}

		// Otherwise, if a way to get the computed value exists, use that
		if ( val === undefined ) {
			val = curCSS( elem, name, styles );
		}

		// Convert "normal" to computed value
		if ( val === "normal" && name in cssNormalTransform ) {
			val = cssNormalTransform[ name ];
		}

		// Make numeric if forced or a qualifier was provided and val looks numeric
		if ( extra === "" || extra ) {
			num = parseFloat( val );
			return extra === true || isFinite( num ) ? num || 0 : val;
		}
		return val;
	}
} );

jQuery.each( [ "height", "width" ], function( i, name ) {
	jQuery.cssHooks[ name ] = {
		get: function( elem, computed, extra ) {
			if ( computed ) {

				// Certain elements can have dimension info if we invisibly show them
				// but it must have a current display style that would benefit
				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
					elem.offsetWidth === 0 ?
						swap( elem, cssShow, function() {
							return getWidthOrHeight( elem, name, extra );
						} ) :
						getWidthOrHeight( elem, name, extra );
			}
		},

		set: function( elem, value, extra ) {
			var matches,
				styles = extra && getStyles( elem ),
				subtract = extra && augmentWidthOrHeight(
					elem,
					name,
					extra,
					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
					styles
				);

			// Convert to pixels if value adjustment is needed
			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
				( matches[ 3 ] || "px" ) !== "px" ) {

				elem.style[ name ] = value;
				value = jQuery.css( elem, name );
			}

			return setPositiveNumber( elem, value, subtract );
		}
	};
} );

jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
	function( elem, computed ) {
		if ( computed ) {
			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
				elem.getBoundingClientRect().left -
					swap( elem, { marginLeft: 0 }, function() {
						return elem.getBoundingClientRect().left;
					} )
				) + "px";
		}
	}
);

// Support: Android 2.3
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
	function( elem, computed ) {
		if ( computed ) {
			return swap( elem, { "display": "inline-block" },
				curCSS, [ elem, "marginRight" ] );
		}
	}
);

// These hooks are used by animate to expand properties
jQuery.each( {
	margin: "",
	padding: "",
	border: "Width"
}, function( prefix, suffix ) {
	jQuery.cssHooks[ prefix + suffix ] = {
		expand: function( value ) {
			var i = 0,
				expanded = {},

				// Assumes a single number if not a string
				parts = typeof value === "string" ? value.split( " " ) : [ value ];

			for ( ; i < 4; i++ ) {
				expanded[ prefix + cssExpand[ i ] + suffix ] =
					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
			}

			return expanded;
		}
	};

	if ( !rmargin.test( prefix ) ) {
		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
	}
} );

jQuery.fn.extend( {
	css: function( name, value ) {
		return access( this, function( elem, name, value ) {
			var styles, len,
				map = {},
				i = 0;

			if ( jQuery.isArray( name ) ) {
				styles = getStyles( elem );
				len = name.length;

				for ( ; i < len; i++ ) {
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
				}

				return map;
			}

			return value !== undefined ?
				jQuery.style( elem, name, value ) :
				jQuery.css( elem, name );
		}, name, value, arguments.length > 1 );
	},
	show: function() {
		return showHide( this, true );
	},
	hide: function() {
		return showHide( this );
	},
	toggle: function( state ) {
		if ( typeof state === "boolean" ) {
			return state ? this.show() : this.hide();
		}

		return this.each( function() {
			if ( isHidden( this ) ) {
				jQuery( this ).show();
			} else {
				jQuery( this ).hide();
			}
		} );
	}
} );


function Tween( elem, options, prop, end, easing ) {
	return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;

Tween.prototype = {
	constructor: Tween,
	init: function( elem, options, prop, end, easing, unit ) {
		this.elem = elem;
		this.prop = prop;
		this.easing = easing || jQuery.easing._default;
		this.options = options;
		this.start = this.now = this.cur();
		this.end = end;
		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
	},
	cur: function() {
		var hooks = Tween.propHooks[ this.prop ];

		return hooks && hooks.get ?
			hooks.get( this ) :
			Tween.propHooks._default.get( this );
	},
	run: function( percent ) {
		var eased,
			hooks = Tween.propHooks[ this.prop ];

		if ( this.options.duration ) {
			this.pos = eased = jQuery.easing[ this.easing ](
				percent, this.options.duration * percent, 0, 1, this.options.duration
			);
		} else {
			this.pos = eased = percent;
		}
		this.now = ( this.end - this.start ) * eased + this.start;

		if ( this.options.step ) {
			this.options.step.call( this.elem, this.now, this );
		}

		if ( hooks && hooks.set ) {
			hooks.set( this );
		} else {
			Tween.propHooks._default.set( this );
		}
		return this;
	}
};

Tween.prototype.init.prototype = Tween.prototype;

Tween.propHooks = {
	_default: {
		get: function( tween ) {
			var result;

			// Use a property on the element directly when it is not a DOM element,
			// or when there is no matching style property that exists.
			if ( tween.elem.nodeType !== 1 ||
				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
				return tween.elem[ tween.prop ];
			}

			// Passing an empty string as a 3rd parameter to .css will automatically
			// attempt a parseFloat and fallback to a string if the parse fails.
			// Simple values such as "10px" are parsed to Float;
			// complex values such as "rotate(1rad)" are returned as-is.
			result = jQuery.css( tween.elem, tween.prop, "" );

			// Empty strings, null, undefined and "auto" are converted to 0.
			return !result || result === "auto" ? 0 : result;
		},
		set: function( tween ) {

			// Use step hook for back compat.
			// Use cssHook if its there.
			// Use .style if available and use plain properties where available.
			if ( jQuery.fx.step[ tween.prop ] ) {
				jQuery.fx.step[ tween.prop ]( tween );
			} else if ( tween.elem.nodeType === 1 &&
				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
					jQuery.cssHooks[ tween.prop ] ) ) {
				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
			} else {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	}
};

// Support: IE9
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
	set: function( tween ) {
		if ( tween.elem.nodeType && tween.elem.parentNode ) {
			tween.elem[ tween.prop ] = tween.now;
		}
	}
};

jQuery.easing = {
	linear: function( p ) {
		return p;
	},
	swing: function( p ) {
		return 0.5 - Math.cos( p * Math.PI ) / 2;
	},
	_default: "swing"
};

jQuery.fx = Tween.prototype.init;

// Back Compat <1.8 extension point
jQuery.fx.step = {};




var
	fxNow, timerId,
	rfxtypes = /^(?:toggle|show|hide)$/,
	rrun = /queueHooks$/;

// Animations created synchronously will run synchronously
function createFxNow() {
	window.setTimeout( function() {
		fxNow = undefined;
	} );
	return ( fxNow = jQuery.now() );
}

// Generate parameters to create a standard animation
function genFx( type, includeWidth ) {
	var which,
		i = 0,
		attrs = { height: type };

	// If we include width, step value is 1 to do all cssExpand values,
	// otherwise step value is 2 to skip over Left and Right
	includeWidth = includeWidth ? 1 : 0;
	for ( ; i < 4 ; i += 2 - includeWidth ) {
		which = cssExpand[ i ];
		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
	}

	if ( includeWidth ) {
		attrs.opacity = attrs.width = type;
	}

	return attrs;
}

function createTween( value, prop, animation ) {
	var tween,
		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
		index = 0,
		length = collection.length;
	for ( ; index < length; index++ ) {
		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {

			// We're done with this property
			return tween;
		}
	}
}

function defaultPrefilter( elem, props, opts ) {
	/* jshint validthis: true */
	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
		anim = this,
		orig = {},
		style = elem.style,
		hidden = elem.nodeType && isHidden( elem ),
		dataShow = dataPriv.get( elem, "fxshow" );

	// Handle queue: false promises
	if ( !opts.queue ) {
		hooks = jQuery._queueHooks( elem, "fx" );
		if ( hooks.unqueued == null ) {
			hooks.unqueued = 0;
			oldfire = hooks.empty.fire;
			hooks.empty.fire = function() {
				if ( !hooks.unqueued ) {
					oldfire();
				}
			};
		}
		hooks.unqueued++;

		anim.always( function() {

			// Ensure the complete handler is called before this completes
			anim.always( function() {
				hooks.unqueued--;
				if ( !jQuery.queue( elem, "fx" ).length ) {
					hooks.empty.fire();
				}
			} );
		} );
	}

	// Height/width overflow pass
	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {

		// Make sure that nothing sneaks out
		// Record all 3 overflow attributes because IE9-10 do not
		// change the overflow attribute when overflowX and
		// overflowY are set to the same value
		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

		// Set display property to inline-block for height/width
		// animations on inline elements that are having width/height animated
		display = jQuery.css( elem, "display" );

		// Test default display if display is currently "none"
		checkDisplay = display === "none" ?
			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;

		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
			style.display = "inline-block";
		}
	}

	if ( opts.overflow ) {
		style.overflow = "hidden";
		anim.always( function() {
			style.overflow = opts.overflow[ 0 ];
			style.overflowX = opts.overflow[ 1 ];
			style.overflowY = opts.overflow[ 2 ];
		} );
	}

	// show/hide pass
	for ( prop in props ) {
		value = props[ prop ];
		if ( rfxtypes.exec( value ) ) {
			delete props[ prop ];
			toggle = toggle || value === "toggle";
			if ( value === ( hidden ? "hide" : "show" ) ) {

				// If there is dataShow left over from a stopped hide or show
				// and we are going to proceed with show, we should pretend to be hidden
				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
					hidden = true;
				} else {
					continue;
				}
			}
			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );

		// Any non-fx value stops us from restoring the original display value
		} else {
			display = undefined;
		}
	}

	if ( !jQuery.isEmptyObject( orig ) ) {
		if ( dataShow ) {
			if ( "hidden" in dataShow ) {
				hidden = dataShow.hidden;
			}
		} else {
			dataShow = dataPriv.access( elem, "fxshow", {} );
		}

		// Store state if its toggle - enables .stop().toggle() to "reverse"
		if ( toggle ) {
			dataShow.hidden = !hidden;
		}
		if ( hidden ) {
			jQuery( elem ).show();
		} else {
			anim.done( function() {
				jQuery( elem ).hide();
			} );
		}
		anim.done( function() {
			var prop;

			dataPriv.remove( elem, "fxshow" );
			for ( prop in orig ) {
				jQuery.style( elem, prop, orig[ prop ] );
			}
		} );
		for ( prop in orig ) {
			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );

			if ( !( prop in dataShow ) ) {
				dataShow[ prop ] = tween.start;
				if ( hidden ) {
					tween.end = tween.start;
					tween.start = prop === "width" || prop === "height" ? 1 : 0;
				}
			}
		}

	// If this is a noop like .hide().hide(), restore an overwritten display value
	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
		style.display = display;
	}
}

function propFilter( props, specialEasing ) {
	var index, name, easing, value, hooks;

	// camelCase, specialEasing and expand cssHook pass
	for ( index in props ) {
		name = jQuery.camelCase( index );
		easing = specialEasing[ name ];
		value = props[ index ];
		if ( jQuery.isArray( value ) ) {
			easing = value[ 1 ];
			value = props[ index ] = value[ 0 ];
		}

		if ( index !== name ) {
			props[ name ] = value;
			delete props[ index ];
		}

		hooks = jQuery.cssHooks[ name ];
		if ( hooks && "expand" in hooks ) {
			value = hooks.expand( value );
			delete props[ name ];

			// Not quite $.extend, this won't overwrite existing keys.
			// Reusing 'index' because we have the correct "name"
			for ( index in value ) {
				if ( !( index in props ) ) {
					props[ index ] = value[ index ];
					specialEasing[ index ] = easing;
				}
			}
		} else {
			specialEasing[ name ] = easing;
		}
	}
}

function Animation( elem, properties, options ) {
	var result,
		stopped,
		index = 0,
		length = Animation.prefilters.length,
		deferred = jQuery.Deferred().always( function() {

			// Don't match elem in the :animated selector
			delete tick.elem;
		} ),
		tick = function() {
			if ( stopped ) {
				return false;
			}
			var currentTime = fxNow || createFxNow(),
				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),

				// Support: Android 2.3
				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
				temp = remaining / animation.duration || 0,
				percent = 1 - temp,
				index = 0,
				length = animation.tweens.length;

			for ( ; index < length ; index++ ) {
				animation.tweens[ index ].run( percent );
			}

			deferred.notifyWith( elem, [ animation, percent, remaining ] );

			if ( percent < 1 && length ) {
				return remaining;
			} else {
				deferred.resolveWith( elem, [ animation ] );
				return false;
			}
		},
		animation = deferred.promise( {
			elem: elem,
			props: jQuery.extend( {}, properties ),
			opts: jQuery.extend( true, {
				specialEasing: {},
				easing: jQuery.easing._default
			}, options ),
			originalProperties: properties,
			originalOptions: options,
			startTime: fxNow || createFxNow(),
			duration: options.duration,
			tweens: [],
			createTween: function( prop, end ) {
				var tween = jQuery.Tween( elem, animation.opts, prop, end,
						animation.opts.specialEasing[ prop ] || animation.opts.easing );
				animation.tweens.push( tween );
				return tween;
			},
			stop: function( gotoEnd ) {
				var index = 0,

					// If we are going to the end, we want to run all the tweens
					// otherwise we skip this part
					length = gotoEnd ? animation.tweens.length : 0;
				if ( stopped ) {
					return this;
				}
				stopped = true;
				for ( ; index < length ; index++ ) {
					animation.tweens[ index ].run( 1 );
				}

				// Resolve when we played the last frame; otherwise, reject
				if ( gotoEnd ) {
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
					deferred.resolveWith( elem, [ animation, gotoEnd ] );
				} else {
					deferred.rejectWith( elem, [ animation, gotoEnd ] );
				}
				return this;
			}
		} ),
		props = animation.props;

	propFilter( props, animation.opts.specialEasing );

	for ( ; index < length ; index++ ) {
		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
		if ( result ) {
			if ( jQuery.isFunction( result.stop ) ) {
				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
					jQuery.proxy( result.stop, result );
			}
			return result;
		}
	}

	jQuery.map( props, createTween, animation );

	if ( jQuery.isFunction( animation.opts.start ) ) {
		animation.opts.start.call( elem, animation );
	}

	jQuery.fx.timer(
		jQuery.extend( tick, {
			elem: elem,
			anim: animation,
			queue: animation.opts.queue
		} )
	);

	// attach callbacks from options
	return animation.progress( animation.opts.progress )
		.done( animation.opts.done, animation.opts.complete )
		.fail( animation.opts.fail )
		.always( animation.opts.always );
}

jQuery.Animation = jQuery.extend( Animation, {
	tweeners: {
		"*": [ function( prop, value ) {
			var tween = this.createTween( prop, value );
			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
			return tween;
		} ]
	},

	tweener: function( props, callback ) {
		if ( jQuery.isFunction( props ) ) {
			callback = props;
			props = [ "*" ];
		} else {
			props = props.match( rnotwhite );
		}

		var prop,
			index = 0,
			length = props.length;

		for ( ; index < length ; index++ ) {
			prop = props[ index ];
			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
			Animation.tweeners[ prop ].unshift( callback );
		}
	},

	prefilters: [ defaultPrefilter ],

	prefilter: function( callback, prepend ) {
		if ( prepend ) {
			Animation.prefilters.unshift( callback );
		} else {
			Animation.prefilters.push( callback );
		}
	}
} );

jQuery.speed = function( speed, easing, fn ) {
	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
		complete: fn || !fn && easing ||
			jQuery.isFunction( speed ) && speed,
		duration: speed,
		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
	};

	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
		opt.duration : opt.duration in jQuery.fx.speeds ?
			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;

	// Normalize opt.queue - true/undefined/null -> "fx"
	if ( opt.queue == null || opt.queue === true ) {
		opt.queue = "fx";
	}

	// Queueing
	opt.old = opt.complete;

	opt.complete = function() {
		if ( jQuery.isFunction( opt.old ) ) {
			opt.old.call( this );
		}

		if ( opt.queue ) {
			jQuery.dequeue( this, opt.queue );
		}
	};

	return opt;
};

jQuery.fn.extend( {
	fadeTo: function( speed, to, easing, callback ) {

		// Show any hidden elements after setting opacity to 0
		return this.filter( isHidden ).css( "opacity", 0 ).show()

			// Animate to the value specified
			.end().animate( { opacity: to }, speed, easing, callback );
	},
	animate: function( prop, speed, easing, callback ) {
		var empty = jQuery.isEmptyObject( prop ),
			optall = jQuery.speed( speed, easing, callback ),
			doAnimation = function() {

				// Operate on a copy of prop so per-property easing won't be lost
				var anim = Animation( this, jQuery.extend( {}, prop ), optall );

				// Empty animations, or finishing resolves immediately
				if ( empty || dataPriv.get( this, "finish" ) ) {
					anim.stop( true );
				}
			};
			doAnimation.finish = doAnimation;

		return empty || optall.queue === false ?
			this.each( doAnimation ) :
			this.queue( optall.queue, doAnimation );
	},
	stop: function( type, clearQueue, gotoEnd ) {
		var stopQueue = function( hooks ) {
			var stop = hooks.stop;
			delete hooks.stop;
			stop( gotoEnd );
		};

		if ( typeof type !== "string" ) {
			gotoEnd = clearQueue;
			clearQueue = type;
			type = undefined;
		}
		if ( clearQueue && type !== false ) {
			this.queue( type || "fx", [] );
		}

		return this.each( function() {
			var dequeue = true,
				index = type != null && type + "queueHooks",
				timers = jQuery.timers,
				data = dataPriv.get( this );

			if ( index ) {
				if ( data[ index ] && data[ index ].stop ) {
					stopQueue( data[ index ] );
				}
			} else {
				for ( index in data ) {
					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
						stopQueue( data[ index ] );
					}
				}
			}

			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this &&
					( type == null || timers[ index ].queue === type ) ) {

					timers[ index ].anim.stop( gotoEnd );
					dequeue = false;
					timers.splice( index, 1 );
				}
			}

			// Start the next in the queue if the last step wasn't forced.
			// Timers currently will call their complete callbacks, which
			// will dequeue but only if they were gotoEnd.
			if ( dequeue || !gotoEnd ) {
				jQuery.dequeue( this, type );
			}
		} );
	},
	finish: function( type ) {
		if ( type !== false ) {
			type = type || "fx";
		}
		return this.each( function() {
			var index,
				data = dataPriv.get( this ),
				queue = data[ type + "queue" ],
				hooks = data[ type + "queueHooks" ],
				timers = jQuery.timers,
				length = queue ? queue.length : 0;

			// Enable finishing flag on private data
			data.finish = true;

			// Empty the queue first
			jQuery.queue( this, type, [] );

			if ( hooks && hooks.stop ) {
				hooks.stop.call( this, true );
			}

			// Look for any active animations, and finish them
			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
					timers[ index ].anim.stop( true );
					timers.splice( index, 1 );
				}
			}

			// Look for any animations in the old queue and finish them
			for ( index = 0; index < length; index++ ) {
				if ( queue[ index ] && queue[ index ].finish ) {
					queue[ index ].finish.call( this );
				}
			}

			// Turn off finishing flag
			delete data.finish;
		} );
	}
} );

jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
	var cssFn = jQuery.fn[ name ];
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return speed == null || typeof speed === "boolean" ?
			cssFn.apply( this, arguments ) :
			this.animate( genFx( name, true ), speed, easing, callback );
	};
} );

// Generate shortcuts for custom animations
jQuery.each( {
	slideDown: genFx( "show" ),
	slideUp: genFx( "hide" ),
	slideToggle: genFx( "toggle" ),
	fadeIn: { opacity: "show" },
	fadeOut: { opacity: "hide" },
	fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return this.animate( props, speed, easing, callback );
	};
} );

jQuery.timers = [];
jQuery.fx.tick = function() {
	var timer,
		i = 0,
		timers = jQuery.timers;

	fxNow = jQuery.now();

	for ( ; i < timers.length; i++ ) {
		timer = timers[ i ];

		// Checks the timer has not already been removed
		if ( !timer() && timers[ i ] === timer ) {
			timers.splice( i--, 1 );
		}
	}

	if ( !timers.length ) {
		jQuery.fx.stop();
	}
	fxNow = undefined;
};

jQuery.fx.timer = function( timer ) {
	jQuery.timers.push( timer );
	if ( timer() ) {
		jQuery.fx.start();
	} else {
		jQuery.timers.pop();
	}
};

jQuery.fx.interval = 13;
jQuery.fx.start = function() {
	if ( !timerId ) {
		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
	}
};

jQuery.fx.stop = function() {
	window.clearInterval( timerId );

	timerId = null;
};

jQuery.fx.speeds = {
	slow: 600,
	fast: 200,

	// Default speed
	_default: 400
};


// Based off of the plugin by Clint Helfers, with permission.
// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
jQuery.fn.delay = function( time, type ) {
	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
	type = type || "fx";

	return this.queue( type, function( next, hooks ) {
		var timeout = window.setTimeout( next, time );
		hooks.stop = function() {
			window.clearTimeout( timeout );
		};
	} );
};


( function() {
	var input = document.createElement( "input" ),
		select = document.createElement( "select" ),
		opt = select.appendChild( document.createElement( "option" ) );

	input.type = "checkbox";

	// Support: iOS<=5.1, Android<=4.2+
	// Default value for a checkbox should be "on"
	support.checkOn = input.value !== "";

	// Support: IE<=11+
	// Must access selectedIndex to make default options select
	support.optSelected = opt.selected;

	// Support: Android<=2.3
	// Options inside disabled selects are incorrectly marked as disabled
	select.disabled = true;
	support.optDisabled = !opt.disabled;

	// Support: IE<=11+
	// An input loses its value after becoming a radio
	input = document.createElement( "input" );
	input.value = "t";
	input.type = "radio";
	support.radioValue = input.value === "t";
} )();


var boolHook,
	attrHandle = jQuery.expr.attrHandle;

jQuery.fn.extend( {
	attr: function( name, value ) {
		return access( this, jQuery.attr, name, value, arguments.length > 1 );
	},

	removeAttr: function( name ) {
		return this.each( function() {
			jQuery.removeAttr( this, name );
		} );
	}
} );

jQuery.extend( {
	attr: function( elem, name, value ) {
		var ret, hooks,
			nType = elem.nodeType;

		// Don't get/set attributes on text, comment and attribute nodes
		if ( nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		// Fallback to prop when attributes are not supported
		if ( typeof elem.getAttribute === "undefined" ) {
			return jQuery.prop( elem, name, value );
		}

		// All attributes are lowercase
		// Grab necessary hook if one is defined
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
			name = name.toLowerCase();
			hooks = jQuery.attrHooks[ name ] ||
				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
		}

		if ( value !== undefined ) {
			if ( value === null ) {
				jQuery.removeAttr( elem, name );
				return;
			}

			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				return ret;
			}

			elem.setAttribute( name, value + "" );
			return value;
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			return ret;
		}

		ret = jQuery.find.attr( elem, name );

		// Non-existent attributes return null, we normalize to undefined
		return ret == null ? undefined : ret;
	},

	attrHooks: {
		type: {
			set: function( elem, value ) {
				if ( !support.radioValue && value === "radio" &&
					jQuery.nodeName( elem, "input" ) ) {
					var val = elem.value;
					elem.setAttribute( "type", value );
					if ( val ) {
						elem.value = val;
					}
					return value;
				}
			}
		}
	},

	removeAttr: function( elem, value ) {
		var name, propName,
			i = 0,
			attrNames = value && value.match( rnotwhite );

		if ( attrNames && elem.nodeType === 1 ) {
			while ( ( name = attrNames[ i++ ] ) ) {
				propName = jQuery.propFix[ name ] || name;

				// Boolean attributes get special treatment (#10870)
				if ( jQuery.expr.match.bool.test( name ) ) {

					// Set corresponding property to false
					elem[ propName ] = false;
				}

				elem.removeAttribute( name );
			}
		}
	}
} );

// Hooks for boolean attributes
boolHook = {
	set: function( elem, value, name ) {
		if ( value === false ) {

			// Remove boolean attributes when set to false
			jQuery.removeAttr( elem, name );
		} else {
			elem.setAttribute( name, name );
		}
		return name;
	}
};
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
	var getter = attrHandle[ name ] || jQuery.find.attr;

	attrHandle[ name ] = function( elem, name, isXML ) {
		var ret, handle;
		if ( !isXML ) {

			// Avoid an infinite loop by temporarily removing this function from the getter
			handle = attrHandle[ name ];
			attrHandle[ name ] = ret;
			ret = getter( elem, name, isXML ) != null ?
				name.toLowerCase() :
				null;
			attrHandle[ name ] = handle;
		}
		return ret;
	};
} );




var rfocusable = /^(?:input|select|textarea|button)$/i,
	rclickable = /^(?:a|area)$/i;

jQuery.fn.extend( {
	prop: function( name, value ) {
		return access( this, jQuery.prop, name, value, arguments.length > 1 );
	},

	removeProp: function( name ) {
		return this.each( function() {
			delete this[ jQuery.propFix[ name ] || name ];
		} );
	}
} );

jQuery.extend( {
	prop: function( elem, name, value ) {
		var ret, hooks,
			nType = elem.nodeType;

		// Don't get/set properties on text, comment and attribute nodes
		if ( nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {

			// Fix name and attach hooks
			name = jQuery.propFix[ name ] || name;
			hooks = jQuery.propHooks[ name ];
		}

		if ( value !== undefined ) {
			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				return ret;
			}

			return ( elem[ name ] = value );
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			return ret;
		}

		return elem[ name ];
	},

	propHooks: {
		tabIndex: {
			get: function( elem ) {

				// elem.tabIndex doesn't always return the
				// correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				// Use proper attribute retrieval(#12072)
				var tabindex = jQuery.find.attr( elem, "tabindex" );

				return tabindex ?
					parseInt( tabindex, 10 ) :
					rfocusable.test( elem.nodeName ) ||
						rclickable.test( elem.nodeName ) && elem.href ?
							0 :
							-1;
			}
		}
	},

	propFix: {
		"for": "htmlFor",
		"class": "className"
	}
} );

// Support: IE <=11 only
// Accessing the selectedIndex property
// forces the browser to respect setting selected
// on the option
// The getter ensures a default option is selected
// when in an optgroup
if ( !support.optSelected ) {
	jQuery.propHooks.selected = {
		get: function( elem ) {
			var parent = elem.parentNode;
			if ( parent && parent.parentNode ) {
				parent.parentNode.selectedIndex;
			}
			return null;
		},
		set: function( elem ) {
			var parent = elem.parentNode;
			if ( parent ) {
				parent.selectedIndex;

				if ( parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
			}
		}
	};
}

jQuery.each( [
	"tabIndex",
	"readOnly",
	"maxLength",
	"cellSpacing",
	"cellPadding",
	"rowSpan",
	"colSpan",
	"useMap",
	"frameBorder",
	"contentEditable"
], function() {
	jQuery.propFix[ this.toLowerCase() ] = this;
} );




var rclass = /[\t\r\n\f]/g;

function getClass( elem ) {
	return elem.getAttribute && elem.getAttribute( "class" ) || "";
}

jQuery.fn.extend( {
	addClass: function( value ) {
		var classes, elem, cur, curValue, clazz, j, finalValue,
			i = 0;

		if ( jQuery.isFunction( value ) ) {
			return this.each( function( j ) {
				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
			} );
		}

		if ( typeof value === "string" && value ) {
			classes = value.match( rnotwhite ) || [];

			while ( ( elem = this[ i++ ] ) ) {
				curValue = getClass( elem );
				cur = elem.nodeType === 1 &&
					( " " + curValue + " " ).replace( rclass, " " );

				if ( cur ) {
					j = 0;
					while ( ( clazz = classes[ j++ ] ) ) {
						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
							cur += clazz + " ";
						}
					}

					// Only assign if different to avoid unneeded rendering.
					finalValue = jQuery.trim( cur );
					if ( curValue !== finalValue ) {
						elem.setAttribute( "class", finalValue );
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		var classes, elem, cur, curValue, clazz, j, finalValue,
			i = 0;

		if ( jQuery.isFunction( value ) ) {
			return this.each( function( j ) {
				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
			} );
		}

		if ( !arguments.length ) {
			return this.attr( "class", "" );
		}

		if ( typeof value === "string" && value ) {
			classes = value.match( rnotwhite ) || [];

			while ( ( elem = this[ i++ ] ) ) {
				curValue = getClass( elem );

				// This expression is here for better compressibility (see addClass)
				cur = elem.nodeType === 1 &&
					( " " + curValue + " " ).replace( rclass, " " );

				if ( cur ) {
					j = 0;
					while ( ( clazz = classes[ j++ ] ) ) {

						// Remove *all* instances
						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
							cur = cur.replace( " " + clazz + " ", " " );
						}
					}

					// Only assign if different to avoid unneeded rendering.
					finalValue = jQuery.trim( cur );
					if ( curValue !== finalValue ) {
						elem.setAttribute( "class", finalValue );
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value;

		if ( typeof stateVal === "boolean" && type === "string" ) {
			return stateVal ? this.addClass( value ) : this.removeClass( value );
		}

		if ( jQuery.isFunction( value ) ) {
			return this.each( function( i ) {
				jQuery( this ).toggleClass(
					value.call( this, i, getClass( this ), stateVal ),
					stateVal
				);
			} );
		}

		return this.each( function() {
			var className, i, self, classNames;

			if ( type === "string" ) {

				// Toggle individual class names
				i = 0;
				self = jQuery( this );
				classNames = value.match( rnotwhite ) || [];

				while ( ( className = classNames[ i++ ] ) ) {

					// Check each className given, space separated list
					if ( self.hasClass( className ) ) {
						self.removeClass( className );
					} else {
						self.addClass( className );
					}
				}

			// Toggle whole class name
			} else if ( value === undefined || type === "boolean" ) {
				className = getClass( this );
				if ( className ) {

					// Store className if set
					dataPriv.set( this, "__className__", className );
				}

				// If the element has a class name or if we're passed `false`,
				// then remove the whole classname (if there was one, the above saved it).
				// Otherwise bring back whatever was previously saved (if anything),
				// falling back to the empty string if nothing was stored.
				if ( this.setAttribute ) {
					this.setAttribute( "class",
						className || value === false ?
						"" :
						dataPriv.get( this, "__className__" ) || ""
					);
				}
			}
		} );
	},

	hasClass: function( selector ) {
		var className, elem,
			i = 0;

		className = " " + selector + " ";
		while ( ( elem = this[ i++ ] ) ) {
			if ( elem.nodeType === 1 &&
				( " " + getClass( elem ) + " " ).replace( rclass, " " )
					.indexOf( className ) > -1
			) {
				return true;
			}
		}

		return false;
	}
} );




var rreturn = /\r/g,
	rspaces = /[\x20\t\r\n\f]+/g;

jQuery.fn.extend( {
	val: function( value ) {
		var hooks, ret, isFunction,
			elem = this[ 0 ];

		if ( !arguments.length ) {
			if ( elem ) {
				hooks = jQuery.valHooks[ elem.type ] ||
					jQuery.valHooks[ elem.nodeName.toLowerCase() ];

				if ( hooks &&
					"get" in hooks &&
					( ret = hooks.get( elem, "value" ) ) !== undefined
				) {
					return ret;
				}

				ret = elem.value;

				return typeof ret === "string" ?

					// Handle most common string cases
					ret.replace( rreturn, "" ) :

					// Handle cases where value is null/undef or number
					ret == null ? "" : ret;
			}

			return;
		}

		isFunction = jQuery.isFunction( value );

		return this.each( function( i ) {
			var val;

			if ( this.nodeType !== 1 ) {
				return;
			}

			if ( isFunction ) {
				val = value.call( this, i, jQuery( this ).val() );
			} else {
				val = value;
			}

			// Treat null/undefined as ""; convert numbers to string
			if ( val == null ) {
				val = "";

			} else if ( typeof val === "number" ) {
				val += "";

			} else if ( jQuery.isArray( val ) ) {
				val = jQuery.map( val, function( value ) {
					return value == null ? "" : value + "";
				} );
			}

			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

			// If set returns undefined, fall back to normal setting
			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
				this.value = val;
			}
		} );
	}
} );

jQuery.extend( {
	valHooks: {
		option: {
			get: function( elem ) {

				var val = jQuery.find.attr( elem, "value" );
				return val != null ?
					val :

					// Support: IE10-11+
					// option.text throws exceptions (#14686, #14858)
					// Strip and collapse whitespace
					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
			}
		},
		select: {
			get: function( elem ) {
				var value, option,
					options = elem.options,
					index = elem.selectedIndex,
					one = elem.type === "select-one" || index < 0,
					values = one ? null : [],
					max = one ? index + 1 : options.length,
					i = index < 0 ?
						max :
						one ? index : 0;

				// Loop through all the selected options
				for ( ; i < max; i++ ) {
					option = options[ i ];

					// IE8-9 doesn't update selected after form reset (#2551)
					if ( ( option.selected || i === index ) &&

							// Don't return options that are disabled or in a disabled optgroup
							( support.optDisabled ?
								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
							( !option.parentNode.disabled ||
								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {

						// Get the specific value for the option
						value = jQuery( option ).val();

						// We don't need an array for one selects
						if ( one ) {
							return value;
						}

						// Multi-Selects return an array
						values.push( value );
					}
				}

				return values;
			},

			set: function( elem, value ) {
				var optionSet, option,
					options = elem.options,
					values = jQuery.makeArray( value ),
					i = options.length;

				while ( i-- ) {
					option = options[ i ];
					if ( option.selected =
						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
					) {
						optionSet = true;
					}
				}

				// Force browsers to behave consistently when non-matching value is set
				if ( !optionSet ) {
					elem.selectedIndex = -1;
				}
				return values;
			}
		}
	}
} );

// Radios and checkboxes getter/setter
jQuery.each( [ "radio", "checkbox" ], function() {
	jQuery.valHooks[ this ] = {
		set: function( elem, value ) {
			if ( jQuery.isArray( value ) ) {
				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
			}
		}
	};
	if ( !support.checkOn ) {
		jQuery.valHooks[ this ].get = function( elem ) {
			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
		};
	}
} );




// Return jQuery for attributes-only inclusion


var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;

jQuery.extend( jQuery.event, {

	trigger: function( event, data, elem, onlyHandlers ) {

		var i, cur, tmp, bubbleType, ontype, handle, special,
			eventPath = [ elem || document ],
			type = hasOwn.call( event, "type" ) ? event.type : event,
			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];

		cur = tmp = elem = elem || document;

		// Don't do events on text and comment nodes
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
			return;
		}

		// focus/blur morphs to focusin/out; ensure we're not firing them right now
		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
			return;
		}

		if ( type.indexOf( "." ) > -1 ) {

			// Namespaced trigger; create a regexp to match event type in handle()
			namespaces = type.split( "." );
			type = namespaces.shift();
			namespaces.sort();
		}
		ontype = type.indexOf( ":" ) < 0 && "on" + type;

		// Caller can pass in a jQuery.Event object, Object, or just an event type string
		event = event[ jQuery.expando ] ?
			event :
			new jQuery.Event( type, typeof event === "object" && event );

		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
		event.isTrigger = onlyHandlers ? 2 : 3;
		event.namespace = namespaces.join( "." );
		event.rnamespace = event.namespace ?
			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
			null;

		// Clean up the event in case it is being reused
		event.result = undefined;
		if ( !event.target ) {
			event.target = elem;
		}

		// Clone any incoming data and prepend the event, creating the handler arg list
		data = data == null ?
			[ event ] :
			jQuery.makeArray( data, [ event ] );

		// Allow special events to draw outside the lines
		special = jQuery.event.special[ type ] || {};
		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
			return;
		}

		// Determine event propagation path in advance, per W3C events spec (#9951)
		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {

			bubbleType = special.delegateType || type;
			if ( !rfocusMorph.test( bubbleType + type ) ) {
				cur = cur.parentNode;
			}
			for ( ; cur; cur = cur.parentNode ) {
				eventPath.push( cur );
				tmp = cur;
			}

			// Only add window if we got to document (e.g., not plain obj or detached DOM)
			if ( tmp === ( elem.ownerDocument || document ) ) {
				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
			}
		}

		// Fire handlers on the event path
		i = 0;
		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {

			event.type = i > 1 ?
				bubbleType :
				special.bindType || type;

			// jQuery handler
			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
				dataPriv.get( cur, "handle" );
			if ( handle ) {
				handle.apply( cur, data );
			}

			// Native handler
			handle = ontype && cur[ ontype ];
			if ( handle && handle.apply && acceptData( cur ) ) {
				event.result = handle.apply( cur, data );
				if ( event.result === false ) {
					event.preventDefault();
				}
			}
		}
		event.type = type;

		// If nobody prevented the default action, do it now
		if ( !onlyHandlers && !event.isDefaultPrevented() ) {

			if ( ( !special._default ||
				special._default.apply( eventPath.pop(), data ) === false ) &&
				acceptData( elem ) ) {

				// Call a native DOM method on the target with the same name name as the event.
				// Don't do default actions on window, that's where global variables be (#6170)
				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {

					// Don't re-trigger an onFOO event when we call its FOO() method
					tmp = elem[ ontype ];

					if ( tmp ) {
						elem[ ontype ] = null;
					}

					// Prevent re-triggering of the same event, since we already bubbled it above
					jQuery.event.triggered = type;
					elem[ type ]();
					jQuery.event.triggered = undefined;

					if ( tmp ) {
						elem[ ontype ] = tmp;
					}
				}
			}
		}

		return event.result;
	},

	// Piggyback on a donor event to simulate a different one
	// Used only for `focus(in | out)` events
	simulate: function( type, elem, event ) {
		var e = jQuery.extend(
			new jQuery.Event(),
			event,
			{
				type: type,
				isSimulated: true
			}
		);

		jQuery.event.trigger( e, null, elem );
	}

} );

jQuery.fn.extend( {

	trigger: function( type, data ) {
		return this.each( function() {
			jQuery.event.trigger( type, data, this );
		} );
	},
	triggerHandler: function( type, data ) {
		var elem = this[ 0 ];
		if ( elem ) {
			return jQuery.event.trigger( type, data, elem, true );
		}
	}
} );


jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
	function( i, name ) {

	// Handle event binding
	jQuery.fn[ name ] = function( data, fn ) {
		return arguments.length > 0 ?
			this.on( name, null, data, fn ) :
			this.trigger( name );
	};
} );

jQuery.fn.extend( {
	hover: function( fnOver, fnOut ) {
		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
	}
} );




support.focusin = "onfocusin" in window;


// Support: Firefox
// Firefox doesn't have focus(in | out) events
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
//
// Support: Chrome, Safari
// focus(in | out) events fire after focus & blur events,
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
if ( !support.focusin ) {
	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {

		// Attach a single capturing handler on the document while someone wants focusin/focusout
		var handler = function( event ) {
			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
		};

		jQuery.event.special[ fix ] = {
			setup: function() {
				var doc = this.ownerDocument || this,
					attaches = dataPriv.access( doc, fix );

				if ( !attaches ) {
					doc.addEventListener( orig, handler, true );
				}
				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
			},
			teardown: function() {
				var doc = this.ownerDocument || this,
					attaches = dataPriv.access( doc, fix ) - 1;

				if ( !attaches ) {
					doc.removeEventListener( orig, handler, true );
					dataPriv.remove( doc, fix );

				} else {
					dataPriv.access( doc, fix, attaches );
				}
			}
		};
	} );
}
var location = window.location;

var nonce = jQuery.now();

var rquery = ( /\?/ );



// Support: Android 2.3
// Workaround failure to string-cast null input
jQuery.parseJSON = function( data ) {
	return JSON.parse( data + "" );
};


// Cross-browser xml parsing
jQuery.parseXML = function( data ) {
	var xml;
	if ( !data || typeof data !== "string" ) {
		return null;
	}

	// Support: IE9
	try {
		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
	} catch ( e ) {
		xml = undefined;
	}

	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
		jQuery.error( "Invalid XML: " + data );
	}
	return xml;
};


var
	rhash = /#.*$/,
	rts = /([?&])_=[^&]*/,
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,

	// #7653, #8125, #8152: local protocol detection
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	rnoContent = /^(?:GET|HEAD)$/,
	rprotocol = /^\/\//,

	/* Prefilters
	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
	 * 2) These are called:
	 *    - BEFORE asking for a transport
	 *    - AFTER param serialization (s.data is a string if s.processData is true)
	 * 3) key is the dataType
	 * 4) the catchall symbol "*" can be used
	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
	 */
	prefilters = {},

	/* Transports bindings
	 * 1) key is the dataType
	 * 2) the catchall symbol "*" can be used
	 * 3) selection will start with transport dataType and THEN go to "*" if needed
	 */
	transports = {},

	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
	allTypes = "*/".concat( "*" ),

	// Anchor tag for parsing the document origin
	originAnchor = document.createElement( "a" );
	originAnchor.href = location.href;

// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {

	// dataTypeExpression is optional and defaults to "*"
	return function( dataTypeExpression, func ) {

		if ( typeof dataTypeExpression !== "string" ) {
			func = dataTypeExpression;
			dataTypeExpression = "*";
		}

		var dataType,
			i = 0,
			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];

		if ( jQuery.isFunction( func ) ) {

			// For each dataType in the dataTypeExpression
			while ( ( dataType = dataTypes[ i++ ] ) ) {

				// Prepend if requested
				if ( dataType[ 0 ] === "+" ) {
					dataType = dataType.slice( 1 ) || "*";
					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );

				// Otherwise append
				} else {
					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
				}
			}
		}
	};
}

// Base inspection function for prefilters and transports
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {

	var inspected = {},
		seekingTransport = ( structure === transports );

	function inspect( dataType ) {
		var selected;
		inspected[ dataType ] = true;
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
			if ( typeof dataTypeOrTransport === "string" &&
				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {

				options.dataTypes.unshift( dataTypeOrTransport );
				inspect( dataTypeOrTransport );
				return false;
			} else if ( seekingTransport ) {
				return !( selected = dataTypeOrTransport );
			}
		} );
		return selected;
	}

	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
}

// A special extend for ajax options
// that takes "flat" options (not to be deep extended)
// Fixes #9887
function ajaxExtend( target, src ) {
	var key, deep,
		flatOptions = jQuery.ajaxSettings.flatOptions || {};

	for ( key in src ) {
		if ( src[ key ] !== undefined ) {
			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
		}
	}
	if ( deep ) {
		jQuery.extend( true, target, deep );
	}

	return target;
}

/* Handles responses to an ajax request:
 * - finds the right dataType (mediates between content-type and expected dataType)
 * - returns the corresponding response
 */
function ajaxHandleResponses( s, jqXHR, responses ) {

	var ct, type, finalDataType, firstDataType,
		contents = s.contents,
		dataTypes = s.dataTypes;

	// Remove auto dataType and get content-type in the process
	while ( dataTypes[ 0 ] === "*" ) {
		dataTypes.shift();
		if ( ct === undefined ) {
			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
		}
	}

	// Check if we're dealing with a known content-type
	if ( ct ) {
		for ( type in contents ) {
			if ( contents[ type ] && contents[ type ].test( ct ) ) {
				dataTypes.unshift( type );
				break;
			}
		}
	}

	// Check to see if we have a response for the expected dataType
	if ( dataTypes[ 0 ] in responses ) {
		finalDataType = dataTypes[ 0 ];
	} else {

		// Try convertible dataTypes
		for ( type in responses ) {
			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
				finalDataType = type;
				break;
			}
			if ( !firstDataType ) {
				firstDataType = type;
			}
		}

		// Or just use first one
		finalDataType = finalDataType || firstDataType;
	}

	// If we found a dataType
	// We add the dataType to the list if needed
	// and return the corresponding response
	if ( finalDataType ) {
		if ( finalDataType !== dataTypes[ 0 ] ) {
			dataTypes.unshift( finalDataType );
		}
		return responses[ finalDataType ];
	}
}

/* Chain conversions given the request and the original response
 * Also sets the responseXXX fields on the jqXHR instance
 */
function ajaxConvert( s, response, jqXHR, isSuccess ) {
	var conv2, current, conv, tmp, prev,
		converters = {},

		// Work with a copy of dataTypes in case we need to modify it for conversion
		dataTypes = s.dataTypes.slice();

	// Create converters map with lowercased keys
	if ( dataTypes[ 1 ] ) {
		for ( conv in s.converters ) {
			converters[ conv.toLowerCase() ] = s.converters[ conv ];
		}
	}

	current = dataTypes.shift();

	// Convert to each sequential dataType
	while ( current ) {

		if ( s.responseFields[ current ] ) {
			jqXHR[ s.responseFields[ current ] ] = response;
		}

		// Apply the dataFilter if provided
		if ( !prev && isSuccess && s.dataFilter ) {
			response = s.dataFilter( response, s.dataType );
		}

		prev = current;
		current = dataTypes.shift();

		if ( current ) {

		// There's only work to do if current dataType is non-auto
			if ( current === "*" ) {

				current = prev;

			// Convert response if prev dataType is non-auto and differs from current
			} else if ( prev !== "*" && prev !== current ) {

				// Seek a direct converter
				conv = converters[ prev + " " + current ] || converters[ "* " + current ];

				// If none found, seek a pair
				if ( !conv ) {
					for ( conv2 in converters ) {

						// If conv2 outputs current
						tmp = conv2.split( " " );
						if ( tmp[ 1 ] === current ) {

							// If prev can be converted to accepted input
							conv = converters[ prev + " " + tmp[ 0 ] ] ||
								converters[ "* " + tmp[ 0 ] ];
							if ( conv ) {

								// Condense equivalence converters
								if ( conv === true ) {
									conv = converters[ conv2 ];

								// Otherwise, insert the intermediate dataType
								} else if ( converters[ conv2 ] !== true ) {
									current = tmp[ 0 ];
									dataTypes.unshift( tmp[ 1 ] );
								}
								break;
							}
						}
					}
				}

				// Apply converter (if not an equivalence)
				if ( conv !== true ) {

					// Unless errors are allowed to bubble, catch and return them
					if ( conv && s.throws ) {
						response = conv( response );
					} else {
						try {
							response = conv( response );
						} catch ( e ) {
							return {
								state: "parsererror",
								error: conv ? e : "No conversion from " + prev + " to " + current
							};
						}
					}
				}
			}
		}
	}

	return { state: "success", data: response };
}

jQuery.extend( {

	// Counter for holding the number of active queries
	active: 0,

	// Last-Modified header cache for next request
	lastModified: {},
	etag: {},

	ajaxSettings: {
		url: location.href,
		type: "GET",
		isLocal: rlocalProtocol.test( location.protocol ),
		global: true,
		processData: true,
		async: true,
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
		/*
		timeout: 0,
		data: null,
		dataType: null,
		username: null,
		password: null,
		cache: null,
		throws: false,
		traditional: false,
		headers: {},
		*/

		accepts: {
			"*": allTypes,
			text: "text/plain",
			html: "text/html",
			xml: "application/xml, text/xml",
			json: "application/json, text/javascript"
		},

		contents: {
			xml: /\bxml\b/,
			html: /\bhtml/,
			json: /\bjson\b/
		},

		responseFields: {
			xml: "responseXML",
			text: "responseText",
			json: "responseJSON"
		},

		// Data converters
		// Keys separate source (or catchall "*") and destination types with a single space
		converters: {

			// Convert anything to text
			"* text": String,

			// Text to html (true = no transformation)
			"text html": true,

			// Evaluate text as a json expression
			"text json": jQuery.parseJSON,

			// Parse text as xml
			"text xml": jQuery.parseXML
		},

		// For options that shouldn't be deep extended:
		// you can add your own custom options here if
		// and when you create one that shouldn't be
		// deep extended (see ajaxExtend)
		flatOptions: {
			url: true,
			context: true
		}
	},

	// Creates a full fledged settings object into target
	// with both ajaxSettings and settings fields.
	// If target is omitted, writes into ajaxSettings.
	ajaxSetup: function( target, settings ) {
		return settings ?

			// Building a settings object
			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :

			// Extending ajaxSettings
			ajaxExtend( jQuery.ajaxSettings, target );
	},

	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
	ajaxTransport: addToPrefiltersOrTransports( transports ),

	// Main method
	ajax: function( url, options ) {

		// If url is an object, simulate pre-1.5 signature
		if ( typeof url === "object" ) {
			options = url;
			url = undefined;
		}

		// Force options to be an object
		options = options || {};

		var transport,

			// URL without anti-cache param
			cacheURL,

			// Response headers
			responseHeadersString,
			responseHeaders,

			// timeout handle
			timeoutTimer,

			// Url cleanup var
			urlAnchor,

			// To know if global events are to be dispatched
			fireGlobals,

			// Loop variable
			i,

			// Create the final options object
			s = jQuery.ajaxSetup( {}, options ),

			// Callbacks context
			callbackContext = s.context || s,

			// Context for global events is callbackContext if it is a DOM node or jQuery collection
			globalEventContext = s.context &&
				( callbackContext.nodeType || callbackContext.jquery ) ?
					jQuery( callbackContext ) :
					jQuery.event,

			// Deferreds
			deferred = jQuery.Deferred(),
			completeDeferred = jQuery.Callbacks( "once memory" ),

			// Status-dependent callbacks
			statusCode = s.statusCode || {},

			// Headers (they are sent all at once)
			requestHeaders = {},
			requestHeadersNames = {},

			// The jqXHR state
			state = 0,

			// Default abort message
			strAbort = "canceled",

			// Fake xhr
			jqXHR = {
				readyState: 0,

				// Builds headers hashtable if needed
				getResponseHeader: function( key ) {
					var match;
					if ( state === 2 ) {
						if ( !responseHeaders ) {
							responseHeaders = {};
							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
							}
						}
						match = responseHeaders[ key.toLowerCase() ];
					}
					return match == null ? null : match;
				},

				// Raw string
				getAllResponseHeaders: function() {
					return state === 2 ? responseHeadersString : null;
				},

				// Caches the header
				setRequestHeader: function( name, value ) {
					var lname = name.toLowerCase();
					if ( !state ) {
						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
						requestHeaders[ name ] = value;
					}
					return this;
				},

				// Overrides response content-type header
				overrideMimeType: function( type ) {
					if ( !state ) {
						s.mimeType = type;
					}
					return this;
				},

				// Status-dependent callbacks
				statusCode: function( map ) {
					var code;
					if ( map ) {
						if ( state < 2 ) {
							for ( code in map ) {

								// Lazy-add the new callback in a way that preserves old ones
								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
							}
						} else {

							// Execute the appropriate callbacks
							jqXHR.always( map[ jqXHR.status ] );
						}
					}
					return this;
				},

				// Cancel the request
				abort: function( statusText ) {
					var finalText = statusText || strAbort;
					if ( transport ) {
						transport.abort( finalText );
					}
					done( 0, finalText );
					return this;
				}
			};

		// Attach deferreds
		deferred.promise( jqXHR ).complete = completeDeferred.add;
		jqXHR.success = jqXHR.done;
		jqXHR.error = jqXHR.fail;

		// Remove hash character (#7531: and string promotion)
		// Add protocol if not provided (prefilters might expect it)
		// Handle falsy url in the settings object (#10093: consistency with old signature)
		// We also use the url parameter if available
		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
			.replace( rprotocol, location.protocol + "//" );

		// Alias method option to type as per ticket #12004
		s.type = options.method || options.type || s.method || s.type;

		// Extract dataTypes list
		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];

		// A cross-domain request is in order when the origin doesn't match the current origin.
		if ( s.crossDomain == null ) {
			urlAnchor = document.createElement( "a" );

			// Support: IE8-11+
			// IE throws exception if url is malformed, e.g. http://example.com:80x/
			try {
				urlAnchor.href = s.url;

				// Support: IE8-11+
				// Anchor's host property isn't correctly set when s.url is relative
				urlAnchor.href = urlAnchor.href;
				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
					urlAnchor.protocol + "//" + urlAnchor.host;
			} catch ( e ) {

				// If there is an error parsing the URL, assume it is crossDomain,
				// it can be rejected by the transport if it is invalid
				s.crossDomain = true;
			}
		}

		// Convert data if not already a string
		if ( s.data && s.processData && typeof s.data !== "string" ) {
			s.data = jQuery.param( s.data, s.traditional );
		}

		// Apply prefilters
		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );

		// If request was aborted inside a prefilter, stop there
		if ( state === 2 ) {
			return jqXHR;
		}

		// We can fire global events as of now if asked to
		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
		fireGlobals = jQuery.event && s.global;

		// Watch for a new set of requests
		if ( fireGlobals && jQuery.active++ === 0 ) {
			jQuery.event.trigger( "ajaxStart" );
		}

		// Uppercase the type
		s.type = s.type.toUpperCase();

		// Determine if request has content
		s.hasContent = !rnoContent.test( s.type );

		// Save the URL in case we're toying with the If-Modified-Since
		// and/or If-None-Match header later on
		cacheURL = s.url;

		// More options handling for requests with no content
		if ( !s.hasContent ) {

			// If data is available, append data to url
			if ( s.data ) {
				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );

				// #9682: remove data so that it's not used in an eventual retry
				delete s.data;
			}

			// Add anti-cache in url if needed
			if ( s.cache === false ) {
				s.url = rts.test( cacheURL ) ?

					// If there is already a '_' parameter, set its value
					cacheURL.replace( rts, "$1_=" + nonce++ ) :

					// Otherwise add one to the end
					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
			}
		}

		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
		if ( s.ifModified ) {
			if ( jQuery.lastModified[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
			}
			if ( jQuery.etag[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
			}
		}

		// Set the correct header, if data is being sent
		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
		}

		// Set the Accepts header for the server, depending on the dataType
		jqXHR.setRequestHeader(
			"Accept",
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
				s.accepts[ s.dataTypes[ 0 ] ] +
					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
				s.accepts[ "*" ]
		);

		// Check for headers option
		for ( i in s.headers ) {
			jqXHR.setRequestHeader( i, s.headers[ i ] );
		}

		// Allow custom headers/mimetypes and early abort
		if ( s.beforeSend &&
			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {

			// Abort if not done already and return
			return jqXHR.abort();
		}

		// Aborting is no longer a cancellation
		strAbort = "abort";

		// Install callbacks on deferreds
		for ( i in { success: 1, error: 1, complete: 1 } ) {
			jqXHR[ i ]( s[ i ] );
		}

		// Get transport
		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );

		// If no transport, we auto-abort
		if ( !transport ) {
			done( -1, "No Transport" );
		} else {
			jqXHR.readyState = 1;

			// Send global event
			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
			}

			// If request was aborted inside ajaxSend, stop there
			if ( state === 2 ) {
				return jqXHR;
			}

			// Timeout
			if ( s.async && s.timeout > 0 ) {
				timeoutTimer = window.setTimeout( function() {
					jqXHR.abort( "timeout" );
				}, s.timeout );
			}

			try {
				state = 1;
				transport.send( requestHeaders, done );
			} catch ( e ) {

				// Propagate exception as error if not done
				if ( state < 2 ) {
					done( -1, e );

				// Simply rethrow otherwise
				} else {
					throw e;
				}
			}
		}

		// Callback for when everything is done
		function done( status, nativeStatusText, responses, headers ) {
			var isSuccess, success, error, response, modified,
				statusText = nativeStatusText;

			// Called once
			if ( state === 2 ) {
				return;
			}

			// State is "done" now
			state = 2;

			// Clear timeout if it exists
			if ( timeoutTimer ) {
				window.clearTimeout( timeoutTimer );
			}

			// Dereference transport for early garbage collection
			// (no matter how long the jqXHR object will be used)
			transport = undefined;

			// Cache response headers
			responseHeadersString = headers || "";

			// Set readyState
			jqXHR.readyState = status > 0 ? 4 : 0;

			// Determine if successful
			isSuccess = status >= 200 && status < 300 || status === 304;

			// Get response data
			if ( responses ) {
				response = ajaxHandleResponses( s, jqXHR, responses );
			}

			// Convert no matter what (that way responseXXX fields are always set)
			response = ajaxConvert( s, response, jqXHR, isSuccess );

			// If successful, handle type chaining
			if ( isSuccess ) {

				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
				if ( s.ifModified ) {
					modified = jqXHR.getResponseHeader( "Last-Modified" );
					if ( modified ) {
						jQuery.lastModified[ cacheURL ] = modified;
					}
					modified = jqXHR.getResponseHeader( "etag" );
					if ( modified ) {
						jQuery.etag[ cacheURL ] = modified;
					}
				}

				// if no content
				if ( status === 204 || s.type === "HEAD" ) {
					statusText = "nocontent";

				// if not modified
				} else if ( status === 304 ) {
					statusText = "notmodified";

				// If we have data, let's convert it
				} else {
					statusText = response.state;
					success = response.data;
					error = response.error;
					isSuccess = !error;
				}
			} else {

				// Extract error from statusText and normalize for non-aborts
				error = statusText;
				if ( status || !statusText ) {
					statusText = "error";
					if ( status < 0 ) {
						status = 0;
					}
				}
			}

			// Set data for the fake xhr object
			jqXHR.status = status;
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";

			// Success/Error
			if ( isSuccess ) {
				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
			} else {
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
			}

			// Status-dependent callbacks
			jqXHR.statusCode( statusCode );
			statusCode = undefined;

			if ( fireGlobals ) {
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
					[ jqXHR, s, isSuccess ? success : error ] );
			}

			// Complete
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );

			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );

				// Handle the global AJAX counter
				if ( !( --jQuery.active ) ) {
					jQuery.event.trigger( "ajaxStop" );
				}
			}
		}

		return jqXHR;
	},

	getJSON: function( url, data, callback ) {
		return jQuery.get( url, data, callback, "json" );
	},

	getScript: function( url, callback ) {
		return jQuery.get( url, undefined, callback, "script" );
	}
} );

jQuery.each( [ "get", "post" ], function( i, method ) {
	jQuery[ method ] = function( url, data, callback, type ) {

		// Shift arguments if data argument was omitted
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = undefined;
		}

		// The url can be an options object (which then must have .url)
		return jQuery.ajax( jQuery.extend( {
			url: url,
			type: method,
			dataType: type,
			data: data,
			success: callback
		}, jQuery.isPlainObject( url ) && url ) );
	};
} );


jQuery._evalUrl = function( url ) {
	return jQuery.ajax( {
		url: url,

		// Make this explicit, since user can override this through ajaxSetup (#11264)
		type: "GET",
		dataType: "script",
		async: false,
		global: false,
		"throws": true
	} );
};


jQuery.fn.extend( {
	wrapAll: function( html ) {
		var wrap;

		if ( jQuery.isFunction( html ) ) {
			return this.each( function( i ) {
				jQuery( this ).wrapAll( html.call( this, i ) );
			} );
		}

		if ( this[ 0 ] ) {

			// The elements to wrap the target around
			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );

			if ( this[ 0 ].parentNode ) {
				wrap.insertBefore( this[ 0 ] );
			}

			wrap.map( function() {
				var elem = this;

				while ( elem.firstElementChild ) {
					elem = elem.firstElementChild;
				}

				return elem;
			} ).append( this );
		}

		return this;
	},

	wrapInner: function( html ) {
		if ( jQuery.isFunction( html ) ) {
			return this.each( function( i ) {
				jQuery( this ).wrapInner( html.call( this, i ) );
			} );
		}

		return this.each( function() {
			var self = jQuery( this ),
				contents = self.contents();

			if ( contents.length ) {
				contents.wrapAll( html );

			} else {
				self.append( html );
			}
		} );
	},

	wrap: function( html ) {
		var isFunction = jQuery.isFunction( html );

		return this.each( function( i ) {
			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
		} );
	},

	unwrap: function() {
		return this.parent().each( function() {
			if ( !jQuery.nodeName( this, "body" ) ) {
				jQuery( this ).replaceWith( this.childNodes );
			}
		} ).end();
	}
} );


jQuery.expr.filters.hidden = function( elem ) {
	return !jQuery.expr.filters.visible( elem );
};
jQuery.expr.filters.visible = function( elem ) {

	// Support: Opera <= 12.12
	// Opera reports offsetWidths and offsetHeights less than zero on some elements
	// Use OR instead of AND as the element is not visible if either is true
	// See tickets #10406 and #13132
	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
};




var r20 = /%20/g,
	rbracket = /\[\]$/,
	rCRLF = /\r?\n/g,
	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	rsubmittable = /^(?:input|select|textarea|keygen)/i;

function buildParams( prefix, obj, traditional, add ) {
	var name;

	if ( jQuery.isArray( obj ) ) {

		// Serialize array item.
		jQuery.each( obj, function( i, v ) {
			if ( traditional || rbracket.test( prefix ) ) {

				// Treat each array item as a scalar.
				add( prefix, v );

			} else {

				// Item is non-scalar (array or object), encode its numeric index.
				buildParams(
					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
					v,
					traditional,
					add
				);
			}
		} );

	} else if ( !traditional && jQuery.type( obj ) === "object" ) {

		// Serialize object item.
		for ( name in obj ) {
			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
		}

	} else {

		// Serialize scalar item.
		add( prefix, obj );
	}
}

// Serialize an array of form elements or a set of
// key/values into a query string
jQuery.param = function( a, traditional ) {
	var prefix,
		s = [],
		add = function( key, value ) {

			// If value is a function, invoke it and return its value
			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
		};

	// Set traditional to true for jQuery <= 1.3.2 behavior.
	if ( traditional === undefined ) {
		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
	}

	// If an array was passed in, assume that it is an array of form elements.
	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {

		// Serialize the form elements
		jQuery.each( a, function() {
			add( this.name, this.value );
		} );

	} else {

		// If traditional, encode the "old" way (the way 1.3.2 or older
		// did it), otherwise encode params recursively.
		for ( prefix in a ) {
			buildParams( prefix, a[ prefix ], traditional, add );
		}
	}

	// Return the resulting serialization
	return s.join( "&" ).replace( r20, "+" );
};

jQuery.fn.extend( {
	serialize: function() {
		return jQuery.param( this.serializeArray() );
	},
	serializeArray: function() {
		return this.map( function() {

			// Can add propHook for "elements" to filter or add form elements
			var elements = jQuery.prop( this, "elements" );
			return elements ? jQuery.makeArray( elements ) : this;
		} )
		.filter( function() {
			var type = this.type;

			// Use .is( ":disabled" ) so that fieldset[disabled] works
			return this.name && !jQuery( this ).is( ":disabled" ) &&
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
				( this.checked || !rcheckableType.test( type ) );
		} )
		.map( function( i, elem ) {
			var val = jQuery( this ).val();

			return val == null ?
				null :
				jQuery.isArray( val ) ?
					jQuery.map( val, function( val ) {
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
					} ) :
					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
		} ).get();
	}
} );


jQuery.ajaxSettings.xhr = function() {
	try {
		return new window.XMLHttpRequest();
	} catch ( e ) {}
};

var xhrSuccessStatus = {

		// File protocol always yields status code 0, assume 200
		0: 200,

		// Support: IE9
		// #1450: sometimes IE returns 1223 when it should be 204
		1223: 204
	},
	xhrSupported = jQuery.ajaxSettings.xhr();

support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
support.ajax = xhrSupported = !!xhrSupported;

jQuery.ajaxTransport( function( options ) {
	var callback, errorCallback;

	// Cross domain only allowed if supported through XMLHttpRequest
	if ( support.cors || xhrSupported && !options.crossDomain ) {
		return {
			send: function( headers, complete ) {
				var i,
					xhr = options.xhr();

				xhr.open(
					options.type,
					options.url,
					options.async,
					options.username,
					options.password
				);

				// Apply custom fields if provided
				if ( options.xhrFields ) {
					for ( i in options.xhrFields ) {
						xhr[ i ] = options.xhrFields[ i ];
					}
				}

				// Override mime type if needed
				if ( options.mimeType && xhr.overrideMimeType ) {
					xhr.overrideMimeType( options.mimeType );
				}

				// X-Requested-With header
				// For cross-domain requests, seeing as conditions for a preflight are
				// akin to a jigsaw puzzle, we simply never set it to be sure.
				// (it can always be set on a per-request basis or even using ajaxSetup)
				// For same-domain requests, won't change header if already provided.
				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
					headers[ "X-Requested-With" ] = "XMLHttpRequest";
				}

				// Set headers
				for ( i in headers ) {
					xhr.setRequestHeader( i, headers[ i ] );
				}

				// Callback
				callback = function( type ) {
					return function() {
						if ( callback ) {
							callback = errorCallback = xhr.onload =
								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;

							if ( type === "abort" ) {
								xhr.abort();
							} else if ( type === "error" ) {

								// Support: IE9
								// On a manual native abort, IE9 throws
								// errors on any property access that is not readyState
								if ( typeof xhr.status !== "number" ) {
									complete( 0, "error" );
								} else {
									complete(

										// File: protocol always yields status 0; see #8605, #14207
										xhr.status,
										xhr.statusText
									);
								}
							} else {
								complete(
									xhrSuccessStatus[ xhr.status ] || xhr.status,
									xhr.statusText,

									// Support: IE9 only
									// IE9 has no XHR2 but throws on binary (trac-11426)
									// For XHR2 non-text, let the caller handle it (gh-2498)
									( xhr.responseType || "text" ) !== "text"  ||
									typeof xhr.responseText !== "string" ?
										{ binary: xhr.response } :
										{ text: xhr.responseText },
									xhr.getAllResponseHeaders()
								);
							}
						}
					};
				};

				// Listen to events
				xhr.onload = callback();
				errorCallback = xhr.onerror = callback( "error" );

				// Support: IE9
				// Use onreadystatechange to replace onabort
				// to handle uncaught aborts
				if ( xhr.onabort !== undefined ) {
					xhr.onabort = errorCallback;
				} else {
					xhr.onreadystatechange = function() {

						// Check readyState before timeout as it changes
						if ( xhr.readyState === 4 ) {

							// Allow onerror to be called first,
							// but that will not handle a native abort
							// Also, save errorCallback to a variable
							// as xhr.onerror cannot be accessed
							window.setTimeout( function() {
								if ( callback ) {
									errorCallback();
								}
							} );
						}
					};
				}

				// Create the abort callback
				callback = callback( "abort" );

				try {

					// Do send the request (this may raise an exception)
					xhr.send( options.hasContent && options.data || null );
				} catch ( e ) {

					// #14683: Only rethrow if this hasn't been notified as an error yet
					if ( callback ) {
						throw e;
					}
				}
			},

			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
} );




// Install script dataType
jQuery.ajaxSetup( {
	accepts: {
		script: "text/javascript, application/javascript, " +
			"application/ecmascript, application/x-ecmascript"
	},
	contents: {
		script: /\b(?:java|ecma)script\b/
	},
	converters: {
		"text script": function( text ) {
			jQuery.globalEval( text );
			return text;
		}
	}
} );

// Handle cache's special case and crossDomain
jQuery.ajaxPrefilter( "script", function( s ) {
	if ( s.cache === undefined ) {
		s.cache = false;
	}
	if ( s.crossDomain ) {
		s.type = "GET";
	}
} );

// Bind script tag hack transport
jQuery.ajaxTransport( "script", function( s ) {

	// This transport only deals with cross domain requests
	if ( s.crossDomain ) {
		var script, callback;
		return {
			send: function( _, complete ) {
				script = jQuery( "<script>" ).prop( {
					charset: s.scriptCharset,
					src: s.url
				} ).on(
					"load error",
					callback = function( evt ) {
						script.remove();
						callback = null;
						if ( evt ) {
							complete( evt.type === "error" ? 404 : 200, evt.type );
						}
					}
				);

				// Use native DOM manipulation to avoid our domManip AJAX trickery
				document.head.appendChild( script[ 0 ] );
			},
			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
} );




var oldCallbacks = [],
	rjsonp = /(=)\?(?=&|$)|\?\?/;

// Default jsonp settings
jQuery.ajaxSetup( {
	jsonp: "callback",
	jsonpCallback: function() {
		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
		this[ callback ] = true;
		return callback;
	}
} );

// Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {

	var callbackName, overwritten, responseContainer,
		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
			"url" :
			typeof s.data === "string" &&
				( s.contentType || "" )
					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
				rjsonp.test( s.data ) && "data"
		);

	// Handle iff the expected data type is "jsonp" or we have a parameter to set
	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {

		// Get callback name, remembering preexisting value associated with it
		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
			s.jsonpCallback() :
			s.jsonpCallback;

		// Insert callback into url or form data
		if ( jsonProp ) {
			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
		} else if ( s.jsonp !== false ) {
			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
		}

		// Use data converter to retrieve json after script execution
		s.converters[ "script json" ] = function() {
			if ( !responseContainer ) {
				jQuery.error( callbackName + " was not called" );
			}
			return responseContainer[ 0 ];
		};

		// Force json dataType
		s.dataTypes[ 0 ] = "json";

		// Install callback
		overwritten = window[ callbackName ];
		window[ callbackName ] = function() {
			responseContainer = arguments;
		};

		// Clean-up function (fires after converters)
		jqXHR.always( function() {

			// If previous value didn't exist - remove it
			if ( overwritten === undefined ) {
				jQuery( window ).removeProp( callbackName );

			// Otherwise restore preexisting value
			} else {
				window[ callbackName ] = overwritten;
			}

			// Save back as free
			if ( s[ callbackName ] ) {

				// Make sure that re-using the options doesn't screw things around
				s.jsonpCallback = originalSettings.jsonpCallback;

				// Save the callback name for future use
				oldCallbacks.push( callbackName );
			}

			// Call if it was a function and we have a response
			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
				overwritten( responseContainer[ 0 ] );
			}

			responseContainer = overwritten = undefined;
		} );

		// Delegate to script
		return "script";
	}
} );




// Argument "data" should be string of html
// context (optional): If specified, the fragment will be created in this context,
// defaults to document
// keepScripts (optional): If true, will include scripts passed in the html string
jQuery.parseHTML = function( data, context, keepScripts ) {
	if ( !data || typeof data !== "string" ) {
		return null;
	}
	if ( typeof context === "boolean" ) {
		keepScripts = context;
		context = false;
	}
	context = context || document;

	var parsed = rsingleTag.exec( data ),
		scripts = !keepScripts && [];

	// Single tag
	if ( parsed ) {
		return [ context.createElement( parsed[ 1 ] ) ];
	}

	parsed = buildFragment( [ data ], context, scripts );

	if ( scripts && scripts.length ) {
		jQuery( scripts ).remove();
	}

	return jQuery.merge( [], parsed.childNodes );
};


// Keep a copy of the old load method
var _load = jQuery.fn.load;

/**
 * Load a url into a page
 */
jQuery.fn.load = function( url, params, callback ) {
	if ( typeof url !== "string" && _load ) {
		return _load.apply( this, arguments );
	}

	var selector, type, response,
		self = this,
		off = url.indexOf( " " );

	if ( off > -1 ) {
		selector = jQuery.trim( url.slice( off ) );
		url = url.slice( 0, off );
	}

	// If it's a function
	if ( jQuery.isFunction( params ) ) {

		// We assume that it's the callback
		callback = params;
		params = undefined;

	// Otherwise, build a param string
	} else if ( params && typeof params === "object" ) {
		type = "POST";
	}

	// If we have elements to modify, make the request
	if ( self.length > 0 ) {
		jQuery.ajax( {
			url: url,

			// If "type" variable is undefined, then "GET" method will be used.
			// Make value of this field explicit since
			// user can override it through ajaxSetup method
			type: type || "GET",
			dataType: "html",
			data: params
		} ).done( function( responseText ) {

			// Save response for use in complete callback
			response = arguments;

			self.html( selector ?

				// If a selector was specified, locate the right elements in a dummy div
				// Exclude scripts to avoid IE 'Permission Denied' errors
				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :

				// Otherwise use the full result
				responseText );

		// If the request succeeds, this function gets "data", "status", "jqXHR"
		// but they are ignored because response was set above.
		// If it fails, this function gets "jqXHR", "status", "error"
		} ).always( callback && function( jqXHR, status ) {
			self.each( function() {
				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
			} );
		} );
	}

	return this;
};




// Attach a bunch of functions for handling common AJAX events
jQuery.each( [
	"ajaxStart",
	"ajaxStop",
	"ajaxComplete",
	"ajaxError",
	"ajaxSuccess",
	"ajaxSend"
], function( i, type ) {
	jQuery.fn[ type ] = function( fn ) {
		return this.on( type, fn );
	};
} );




jQuery.expr.filters.animated = function( elem ) {
	return jQuery.grep( jQuery.timers, function( fn ) {
		return elem === fn.elem;
	} ).length;
};




/**
 * Gets a window from an element
 */
function getWindow( elem ) {
	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}

jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery( elem ),
			props = {};

		// Set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css( elem, "top" );
		curCSSLeft = jQuery.css( elem, "left" );
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;

		// Need to be able to calculate position if either
		// top or left is auto and position is either absolute or fixed
		if ( calculatePosition ) {
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} else {
			curTop = parseFloat( curCSSTop ) || 0;
			curLeft = parseFloat( curCSSLeft ) || 0;
		}

		if ( jQuery.isFunction( options ) ) {

			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
		}

		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );

		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend( {
	offset: function( options ) {
		if ( arguments.length ) {
			return options === undefined ?
				this :
				this.each( function( i ) {
					jQuery.offset.setOffset( this, options, i );
				} );
		}

		var docElem, win,
			elem = this[ 0 ],
			box = { top: 0, left: 0 },
			doc = elem && elem.ownerDocument;

		if ( !doc ) {
			return;
		}

		docElem = doc.documentElement;

		// Make sure it's not a disconnected DOM node
		if ( !jQuery.contains( docElem, elem ) ) {
			return box;
		}

		box = elem.getBoundingClientRect();
		win = getWindow( doc );
		return {
			top: box.top + win.pageYOffset - docElem.clientTop,
			left: box.left + win.pageXOffset - docElem.clientLeft
		};
	},

	position: function() {
		if ( !this[ 0 ] ) {
			return;
		}

		var offsetParent, offset,
			elem = this[ 0 ],
			parentOffset = { top: 0, left: 0 };

		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
		// because it is its only offset parent
		if ( jQuery.css( elem, "position" ) === "fixed" ) {

			// Assume getBoundingClientRect is there when computed position is fixed
			offset = elem.getBoundingClientRect();

		} else {

			// Get *real* offsetParent
			offsetParent = this.offsetParent();

			// Get correct offsets
			offset = this.offset();
			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
				parentOffset = offsetParent.offset();
			}

			// Add offsetParent borders
			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
		}

		// Subtract parent offsets and element margins
		return {
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	// This method will return documentElement in the following cases:
	// 1) For the element inside the iframe without offsetParent, this method will return
	//    documentElement of the parent window
	// 2) For the hidden or detached element
	// 3) For body or html element, i.e. in case of the html node - it will return itself
	//
	// but those exceptions were never presented as a real life use-cases
	// and might be considered as more preferable results.
	//
	// This logic, however, is not guaranteed and can change at any point in the future
	offsetParent: function() {
		return this.map( function() {
			var offsetParent = this.offsetParent;

			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
				offsetParent = offsetParent.offsetParent;
			}

			return offsetParent || documentElement;
		} );
	}
} );

// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ method ] = function( val ) {
		return access( this, function( elem, method, val ) {
			var win = getWindow( elem );

			if ( val === undefined ) {
				return win ? win[ prop ] : elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : win.pageXOffset,
					top ? val : win.pageYOffset
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length );
	};
} );

// Support: Safari<7-8+, Chrome<37-44+
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		function( elem, computed ) {
			if ( computed ) {
				computed = curCSS( elem, prop );

				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test( computed ) ?
					jQuery( elem ).position()[ prop ] + "px" :
					computed;
			}
		}
	);
} );


// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
		function( defaultExtra, funcName ) {

		// Margin is only for outerHeight, outerWidth
		jQuery.fn[ funcName ] = function( margin, value ) {
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );

			return access( this, function( elem, type, value ) {
				var doc;

				if ( jQuery.isWindow( elem ) ) {

					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
					// isn't a whole lot we can do. See pull request at this URL for discussion:
					// https://github.com/jquery/jquery/pull/764
					return elem.document.documentElement[ "client" + name ];
				}

				// Get document width or height
				if ( elem.nodeType === 9 ) {
					doc = elem.documentElement;

					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
					// whichever is greatest
					return Math.max(
						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
						elem.body[ "offset" + name ], doc[ "offset" + name ],
						doc[ "client" + name ]
					);
				}

				return value === undefined ?

					// Get width or height on the element, requesting but not forcing parseFloat
					jQuery.css( elem, type, extra ) :

					// Set width or height on the element
					jQuery.style( elem, type, value, extra );
			}, type, chainable ? margin : undefined, chainable, null );
		};
	} );
} );


jQuery.fn.extend( {

	bind: function( types, data, fn ) {
		return this.on( types, null, data, fn );
	},
	unbind: function( types, fn ) {
		return this.off( types, null, fn );
	},

	delegate: function( selector, types, data, fn ) {
		return this.on( types, selector, data, fn );
	},
	undelegate: function( selector, types, fn ) {

		// ( namespace ) or ( selector, types [, fn] )
		return arguments.length === 1 ?
			this.off( selector, "**" ) :
			this.off( types, selector || "**", fn );
	},
	size: function() {
		return this.length;
	}
} );

jQuery.fn.andSelf = jQuery.fn.addBack;




// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.

// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if ( typeof define === "function" && define.amd ) {
	define( "jquery", [], function() {
		return jQuery;
	} );
}



var

	// Map over jQuery in case of overwrite
	_jQuery = window.jQuery,

	// Map over the $ in case of overwrite
	_$ = window.$;

jQuery.noConflict = function( deep ) {
	if ( window.$ === jQuery ) {
		window.$ = _$;
	}

	if ( deep && window.jQuery === jQuery ) {
		window.jQuery = _jQuery;
	}

	return jQuery;
};

// Expose jQuery and $ identifiers, even in AMD
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( !noGlobal ) {
	window.jQuery = window.$ = jQuery;
}

return jQuery;
}));

; browserify_shim__define__module__export__(typeof $ != "undefined" ? $ : window.$);

}).call(global, undefined, undefined, undefined, undefined, function defineExport(ex) { module.exports = ex; });

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],629:[function(require,module,exports){
/*! lightslider - v1.1.6 - 2016-10-25
* https://github.com/sachinchoolur/lightslider
* Copyright (c) 2016 Sachin N; Licensed MIT */
!function(a,b){"use strict";var c={item:3,autoWidth:!1,slideMove:1,slideMargin:10,addClass:"",mode:"slide",useCSS:!0,cssEasing:"ease",easing:"linear",speed:400,auto:!1,pauseOnHover:!1,loop:!1,slideEndAnimation:!0,pause:2e3,keyPress:!1,controls:!0,prevHtml:"",nextHtml:"",rtl:!1,adaptiveHeight:!1,vertical:!1,verticalHeight:500,vThumbWidth:100,thumbItem:10,pager:!0,gallery:!1,galleryMargin:5,thumbMargin:5,currentPagerPosition:"middle",enableTouch:!0,enableDrag:!0,freeMove:!0,swipeThreshold:40,responsive:[],onBeforeStart:function(a){},onSliderLoad:function(a){},onBeforeSlide:function(a,b){},onAfterSlide:function(a,b){},onBeforeNextSlide:function(a,b){},onBeforePrevSlide:function(a,b){}};a.fn.lightSlider=function(b){if(0===this.length)return this;if(this.length>1)return this.each(function(){a(this).lightSlider(b)}),this;var d={},e=a.extend(!0,{},c,b),f={},g=this;d.$el=this,"fade"===e.mode&&(e.vertical=!1);var h=g.children(),i=a(window).width(),j=null,k=null,l=0,m=0,n=!1,o=0,p="",q=0,r=e.vertical===!0?"height":"width",s=e.vertical===!0?"margin-bottom":"margin-right",t=0,u=0,v=0,w=0,x=null,y="ontouchstart"in document.documentElement,z={};return z.chbreakpoint=function(){if(i=a(window).width(),e.responsive.length){var b;if(e.autoWidth===!1&&(b=e.item),i<e.responsive[0].breakpoint)for(var c=0;c<e.responsive.length;c++)i<e.responsive[c].breakpoint&&(j=e.responsive[c].breakpoint,k=e.responsive[c]);if("undefined"!=typeof k&&null!==k)for(var d in k.settings)k.settings.hasOwnProperty(d)&&(("undefined"==typeof f[d]||null===f[d])&&(f[d]=e[d]),e[d]=k.settings[d]);if(!a.isEmptyObject(f)&&i>e.responsive[0].breakpoint)for(var g in f)f.hasOwnProperty(g)&&(e[g]=f[g]);e.autoWidth===!1&&t>0&&v>0&&b!==e.item&&(q=Math.round(t/((v+e.slideMargin)*e.slideMove)))}},z.calSW=function(){e.autoWidth===!1&&(v=(o-(e.item*e.slideMargin-e.slideMargin))/e.item)},z.calWidth=function(a){var b=a===!0?p.find(".lslide").length:h.length;if(e.autoWidth===!1)m=b*(v+e.slideMargin);else{m=0;for(var c=0;b>c;c++)m+=parseInt(h.eq(c).width())+e.slideMargin}return m},d={doCss:function(){var a=function(){for(var a=["transition","MozTransition","WebkitTransition","OTransition","msTransition","KhtmlTransition"],b=document.documentElement,c=0;c<a.length;c++)if(a[c]in b.style)return!0};return e.useCSS&&a()?!0:!1},keyPress:function(){e.keyPress&&a(document).on("keyup.lightslider",function(b){a(":focus").is("input, textarea")||(b.preventDefault?b.preventDefault():b.returnValue=!1,37===b.keyCode?g.goToPrevSlide():39===b.keyCode&&g.goToNextSlide())})},controls:function(){e.controls&&(g.after('<div class="lSAction"><a class="lSPrev">'+e.prevHtml+'</a><a class="lSNext">'+e.nextHtml+"</a></div>"),e.autoWidth?z.calWidth(!1)<o&&p.find(".lSAction").hide():l<=e.item&&p.find(".lSAction").hide(),p.find(".lSAction a").on("click",function(b){return b.preventDefault?b.preventDefault():b.returnValue=!1,"lSPrev"===a(this).attr("class")?g.goToPrevSlide():g.goToNextSlide(),!1}))},initialStyle:function(){var a=this;"fade"===e.mode&&(e.autoWidth=!1,e.slideEndAnimation=!1),e.auto&&(e.slideEndAnimation=!1),e.autoWidth&&(e.slideMove=1,e.item=1),e.loop&&(e.slideMove=1,e.freeMove=!1),e.onBeforeStart.call(this,g),z.chbreakpoint(),g.addClass("lightSlider").wrap('<div class="lSSlideOuter '+e.addClass+'"><div class="lSSlideWrapper"></div></div>'),p=g.parent(".lSSlideWrapper"),e.rtl===!0&&p.parent().addClass("lSrtl"),e.vertical?(p.parent().addClass("vertical"),o=e.verticalHeight,p.css("height",o+"px")):o=g.outerWidth(),h.addClass("lslide"),e.loop===!0&&"slide"===e.mode&&(z.calSW(),z.clone=function(){if(z.calWidth(!0)>o){for(var b=0,c=0,d=0;d<h.length&&(b+=parseInt(g.find(".lslide").eq(d).width())+e.slideMargin,c++,!(b>=o+e.slideMargin));d++);var f=e.autoWidth===!0?c:e.item;if(f<g.find(".clone.left").length)for(var i=0;i<g.find(".clone.left").length-f;i++)h.eq(i).remove();if(f<g.find(".clone.right").length)for(var j=h.length-1;j>h.length-1-g.find(".clone.right").length;j--)q--,h.eq(j).remove();for(var k=g.find(".clone.right").length;f>k;k++)g.find(".lslide").eq(k).clone().removeClass("lslide").addClass("clone right").appendTo(g),q++;for(var l=g.find(".lslide").length-g.find(".clone.left").length;l>g.find(".lslide").length-f;l--)g.find(".lslide").eq(l-1).clone().removeClass("lslide").addClass("clone left").prependTo(g);h=g.children()}else h.hasClass("clone")&&(g.find(".clone").remove(),a.move(g,0))},z.clone()),z.sSW=function(){l=h.length,e.rtl===!0&&e.vertical===!1&&(s="margin-left"),e.autoWidth===!1&&h.css(r,v+"px"),h.css(s,e.slideMargin+"px"),m=z.calWidth(!1),g.css(r,m+"px"),e.loop===!0&&"slide"===e.mode&&n===!1&&(q=g.find(".clone.left").length)},z.calL=function(){h=g.children(),l=h.length},this.doCss()&&p.addClass("usingCss"),z.calL(),"slide"===e.mode?(z.calSW(),z.sSW(),e.loop===!0&&(t=a.slideValue(),this.move(g,t)),e.vertical===!1&&this.setHeight(g,!1)):(this.setHeight(g,!0),g.addClass("lSFade"),this.doCss()||(h.fadeOut(0),h.eq(q).fadeIn(0))),e.loop===!0&&"slide"===e.mode?h.eq(q).addClass("active"):h.first().addClass("active")},pager:function(){var a=this;if(z.createPager=function(){w=(o-(e.thumbItem*e.thumbMargin-e.thumbMargin))/e.thumbItem;var b=p.find(".lslide"),c=p.find(".lslide").length,d=0,f="",h=0;for(d=0;c>d;d++){"slide"===e.mode&&(e.autoWidth?h+=(parseInt(b.eq(d).width())+e.slideMargin)*e.slideMove:h=d*(v+e.slideMargin)*e.slideMove);var i=b.eq(d*e.slideMove).attr("data-thumb");if(f+=e.gallery===!0?'<li style="width:100%;'+r+":"+w+"px;"+s+":"+e.thumbMargin+'px"><a href="#"><img src="'+i+'" /></a></li>':'<li><a href="#">'+(d+1)+"</a></li>","slide"===e.mode&&h>=m-o-e.slideMargin){d+=1;var j=2;e.autoWidth&&(f+='<li><a href="#">'+(d+1)+"</a></li>",j=1),j>d?(f=null,p.parent().addClass("noPager")):p.parent().removeClass("noPager");break}}var k=p.parent();k.find(".lSPager").html(f),e.gallery===!0&&(e.vertical===!0&&k.find(".lSPager").css("width",e.vThumbWidth+"px"),u=d*(e.thumbMargin+w)+.5,k.find(".lSPager").css({property:u+"px","transition-duration":e.speed+"ms"}),e.vertical===!0&&p.parent().css("padding-right",e.vThumbWidth+e.galleryMargin+"px"),k.find(".lSPager").css(r,u+"px"));var l=k.find(".lSPager").find("li");l.first().addClass("active"),l.on("click",function(){return e.loop===!0&&"slide"===e.mode?q+=l.index(this)-k.find(".lSPager").find("li.active").index():q=l.index(this),g.mode(!1),e.gallery===!0&&a.slideThumb(),!1})},e.pager){var b="lSpg";e.gallery&&(b="lSGallery"),p.after('<ul class="lSPager '+b+'"></ul>');var c=e.vertical?"margin-left":"margin-top";p.parent().find(".lSPager").css(c,e.galleryMargin+"px"),z.createPager()}setTimeout(function(){z.init()},0)},setHeight:function(a,b){var c=null,d=this;c=e.loop?a.children(".lslide ").first():a.children().first();var f=function(){var d=c.outerHeight(),e=0,f=d;b&&(d=0,e=100*f/o),a.css({height:d+"px","padding-bottom":e+"%"})};f(),c.find("img").length?c.find("img")[0].complete?(f(),x||d.auto()):c.find("img").on("load",function(){setTimeout(function(){f(),x||d.auto()},100)}):x||d.auto()},active:function(a,b){this.doCss()&&"fade"===e.mode&&p.addClass("on");var c=0;if(q*e.slideMove<l){a.removeClass("active"),this.doCss()||"fade"!==e.mode||b!==!1||a.fadeOut(e.speed),c=b===!0?q:q*e.slideMove;var d,f;b===!0&&(d=a.length,f=d-1,c+1>=d&&(c=f)),e.loop===!0&&"slide"===e.mode&&(c=b===!0?q-g.find(".clone.left").length:q*e.slideMove,b===!0&&(d=a.length,f=d-1,c+1===d?c=f:c+1>d&&(c=0))),this.doCss()||"fade"!==e.mode||b!==!1||a.eq(c).fadeIn(e.speed),a.eq(c).addClass("active")}else a.removeClass("active"),a.eq(a.length-1).addClass("active"),this.doCss()||"fade"!==e.mode||b!==!1||(a.fadeOut(e.speed),a.eq(c).fadeIn(e.speed))},move:function(a,b){e.rtl===!0&&(b=-b),this.doCss()?a.css(e.vertical===!0?{transform:"translate3d(0px, "+-b+"px, 0px)","-webkit-transform":"translate3d(0px, "+-b+"px, 0px)"}:{transform:"translate3d("+-b+"px, 0px, 0px)","-webkit-transform":"translate3d("+-b+"px, 0px, 0px)"}):e.vertical===!0?a.css("position","relative").animate({top:-b+"px"},e.speed,e.easing):a.css("position","relative").animate({left:-b+"px"},e.speed,e.easing);var c=p.parent().find(".lSPager").find("li");this.active(c,!0)},fade:function(){this.active(h,!1);var a=p.parent().find(".lSPager").find("li");this.active(a,!0)},slide:function(){var a=this;z.calSlide=function(){m>o&&(t=a.slideValue(),a.active(h,!1),t>m-o-e.slideMargin?t=m-o-e.slideMargin:0>t&&(t=0),a.move(g,t),e.loop===!0&&"slide"===e.mode&&(q>=l-g.find(".clone.left").length/e.slideMove&&a.resetSlide(g.find(".clone.left").length),0===q&&a.resetSlide(p.find(".lslide").length)))},z.calSlide()},resetSlide:function(a){var b=this;p.find(".lSAction a").addClass("disabled"),setTimeout(function(){q=a,p.css("transition-duration","0ms"),t=b.slideValue(),b.active(h,!1),d.move(g,t),setTimeout(function(){p.css("transition-duration",e.speed+"ms"),p.find(".lSAction a").removeClass("disabled")},50)},e.speed+100)},slideValue:function(){var a=0;if(e.autoWidth===!1)a=q*(v+e.slideMargin)*e.slideMove;else{a=0;for(var b=0;q>b;b++)a+=parseInt(h.eq(b).width())+e.slideMargin}return a},slideThumb:function(){var a;switch(e.currentPagerPosition){case"left":a=0;break;case"middle":a=o/2-w/2;break;case"right":a=o-w}var b=q-g.find(".clone.left").length,c=p.parent().find(".lSPager");"slide"===e.mode&&e.loop===!0&&(b>=c.children().length?b=0:0>b&&(b=c.children().length));var d=b*(w+e.thumbMargin)-a;d+o>u&&(d=u-o-e.thumbMargin),0>d&&(d=0),this.move(c,d)},auto:function(){e.auto&&(clearInterval(x),x=setInterval(function(){g.goToNextSlide()},e.pause))},pauseOnHover:function(){var b=this;e.auto&&e.pauseOnHover&&(p.on("mouseenter",function(){a(this).addClass("ls-hover"),g.pause(),e.auto=!0}),p.on("mouseleave",function(){a(this).removeClass("ls-hover"),p.find(".lightSlider").hasClass("lsGrabbing")||b.auto()}))},touchMove:function(a,b){if(p.css("transition-duration","0ms"),"slide"===e.mode){var c=a-b,d=t-c;if(d>=m-o-e.slideMargin)if(e.freeMove===!1)d=m-o-e.slideMargin;else{var f=m-o-e.slideMargin;d=f+(d-f)/5}else 0>d&&(e.freeMove===!1?d=0:d/=5);this.move(g,d)}},touchEnd:function(a){if(p.css("transition-duration",e.speed+"ms"),"slide"===e.mode){var b=!1,c=!0;t-=a,t>m-o-e.slideMargin?(t=m-o-e.slideMargin,e.autoWidth===!1&&(b=!0)):0>t&&(t=0);var d=function(a){var c=0;if(b||a&&(c=1),e.autoWidth)for(var d=0,f=0;f<h.length&&(d+=parseInt(h.eq(f).width())+e.slideMargin,q=f+c,!(d>=t));f++);else{var g=t/((v+e.slideMargin)*e.slideMove);q=parseInt(g)+c,t>=m-o-e.slideMargin&&g%1!==0&&q++}};a>=e.swipeThreshold?(d(!1),c=!1):a<=-e.swipeThreshold&&(d(!0),c=!1),g.mode(c),this.slideThumb()}else a>=e.swipeThreshold?g.goToPrevSlide():a<=-e.swipeThreshold&&g.goToNextSlide()},enableDrag:function(){var b=this;if(!y){var c=0,d=0,f=!1;p.find(".lightSlider").addClass("lsGrab"),p.on("mousedown",function(b){return o>m&&0!==m?!1:void("lSPrev"!==a(b.target).attr("class")&&"lSNext"!==a(b.target).attr("class")&&(c=e.vertical===!0?b.pageY:b.pageX,f=!0,b.preventDefault?b.preventDefault():b.returnValue=!1,p.scrollLeft+=1,p.scrollLeft-=1,p.find(".lightSlider").removeClass("lsGrab").addClass("lsGrabbing"),clearInterval(x)))}),a(window).on("mousemove",function(a){f&&(d=e.vertical===!0?a.pageY:a.pageX,b.touchMove(d,c))}),a(window).on("mouseup",function(g){if(f){p.find(".lightSlider").removeClass("lsGrabbing").addClass("lsGrab"),f=!1,d=e.vertical===!0?g.pageY:g.pageX;var h=d-c;Math.abs(h)>=e.swipeThreshold&&a(window).on("click.ls",function(b){b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopImmediatePropagation(),b.stopPropagation(),a(window).off("click.ls")}),b.touchEnd(h)}})}},enableTouch:function(){var a=this;if(y){var b={},c={};p.on("touchstart",function(a){c=a.originalEvent.targetTouches[0],b.pageX=a.originalEvent.targetTouches[0].pageX,b.pageY=a.originalEvent.targetTouches[0].pageY,clearInterval(x)}),p.on("touchmove",function(d){if(o>m&&0!==m)return!1;var f=d.originalEvent;c=f.targetTouches[0];var g=Math.abs(c.pageX-b.pageX),h=Math.abs(c.pageY-b.pageY);e.vertical===!0?(3*h>g&&d.preventDefault(),a.touchMove(c.pageY,b.pageY)):(3*g>h&&d.preventDefault(),a.touchMove(c.pageX,b.pageX))}),p.on("touchend",function(){if(o>m&&0!==m)return!1;var d;d=e.vertical===!0?c.pageY-b.pageY:c.pageX-b.pageX,a.touchEnd(d)})}},build:function(){var b=this;b.initialStyle(),this.doCss()&&(e.enableTouch===!0&&b.enableTouch(),e.enableDrag===!0&&b.enableDrag()),a(window).on("focus",function(){b.auto()}),a(window).on("blur",function(){clearInterval(x)}),b.pager(),b.pauseOnHover(),b.controls(),b.keyPress()}},d.build(),z.init=function(){z.chbreakpoint(),e.vertical===!0?(o=e.item>1?e.verticalHeight:h.outerHeight(),p.css("height",o+"px")):o=p.outerWidth(),e.loop===!0&&"slide"===e.mode&&z.clone(),z.calL(),"slide"===e.mode&&g.removeClass("lSSlide"),"slide"===e.mode&&(z.calSW(),z.sSW()),setTimeout(function(){"slide"===e.mode&&g.addClass("lSSlide")},1e3),e.pager&&z.createPager(),e.adaptiveHeight===!0&&e.vertical===!1&&g.css("height",h.eq(q).outerHeight(!0)),e.adaptiveHeight===!1&&("slide"===e.mode?e.vertical===!1?d.setHeight(g,!1):d.auto():d.setHeight(g,!0)),e.gallery===!0&&d.slideThumb(),"slide"===e.mode&&d.slide(),e.autoWidth===!1?h.length<=e.item?p.find(".lSAction").hide():p.find(".lSAction").show():z.calWidth(!1)<o&&0!==m?p.find(".lSAction").hide():p.find(".lSAction").show()},g.goToPrevSlide=function(){if(q>0)e.onBeforePrevSlide.call(this,g,q),q--,g.mode(!1),e.gallery===!0&&d.slideThumb();else if(e.loop===!0){if(e.onBeforePrevSlide.call(this,g,q),"fade"===e.mode){var a=l-1;q=parseInt(a/e.slideMove)}g.mode(!1),e.gallery===!0&&d.slideThumb()}else e.slideEndAnimation===!0&&(g.addClass("leftEnd"),setTimeout(function(){g.removeClass("leftEnd")},400))},g.goToNextSlide=function(){var a=!0;if("slide"===e.mode){var b=d.slideValue();a=b<m-o-e.slideMargin}q*e.slideMove<l-e.slideMove&&a?(e.onBeforeNextSlide.call(this,g,q),q++,g.mode(!1),e.gallery===!0&&d.slideThumb()):e.loop===!0?(e.onBeforeNextSlide.call(this,g,q),q=0,g.mode(!1),e.gallery===!0&&d.slideThumb()):e.slideEndAnimation===!0&&(g.addClass("rightEnd"),setTimeout(function(){g.removeClass("rightEnd")},400))},g.mode=function(a){e.adaptiveHeight===!0&&e.vertical===!1&&g.css("height",h.eq(q).outerHeight(!0)),n===!1&&("slide"===e.mode?d.doCss()&&(g.addClass("lSSlide"),""!==e.speed&&p.css("transition-duration",e.speed+"ms"),""!==e.cssEasing&&p.css("transition-timing-function",e.cssEasing)):d.doCss()&&(""!==e.speed&&g.css("transition-duration",e.speed+"ms"),""!==e.cssEasing&&g.css("transition-timing-function",e.cssEasing))),a||e.onBeforeSlide.call(this,g,q),"slide"===e.mode?d.slide():d.fade(),p.hasClass("ls-hover")||d.auto(),setTimeout(function(){a||e.onAfterSlide.call(this,g,q)},e.speed),n=!0},g.play=function(){g.goToNextSlide(),e.auto=!0,d.auto()},g.pause=function(){e.auto=!1,clearInterval(x)},g.refresh=function(){z.init()},g.getCurrentSlideCount=function(){var a=q;if(e.loop){var b=p.find(".lslide").length,c=g.find(".clone.left").length;a=c-1>=q?b+(q-c):q>=b+c?q-b-c:q-c}return a+1},g.getTotalSlideCount=function(){return p.find(".lslide").length},g.goToSlide=function(a){q=e.loop?a+g.find(".clone.left").length-1:a,g.mode(!1),e.gallery===!0&&d.slideThumb()},g.destroy=function(){g.lightSlider&&(g.goToPrevSlide=function(){},g.goToNextSlide=function(){},g.mode=function(){},g.play=function(){},g.pause=function(){},g.refresh=function(){},g.getCurrentSlideCount=function(){},g.getTotalSlideCount=function(){},g.goToSlide=function(){},g.lightSlider=null,z={init:function(){}},g.parent().parent().find(".lSAction, .lSPager").remove(),g.removeClass("lightSlider lSFade lSSlide lsGrab lsGrabbing leftEnd right").removeAttr("style").unwrap().unwrap(),g.children().removeAttr("style"),h.removeClass("lslide active"),g.find(".clone").remove(),h=null,x=null,n=!1,q=0)},setTimeout(function(){e.onSliderLoad.call(this,g)},10),a(window).on("resize orientationchange",function(a){setTimeout(function(){a.preventDefault?a.preventDefault():a.returnValue=!1,z.init()},200)}),this}}(jQuery);
},{}],630:[function(require,module,exports){
!function(e,t,n,i){"use strict";t=void 0!==t&&t.Math==Math?t:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.dropdown=function(i){var a,o=e(this),s=e(n),r=o.selector||"",l="ontouchstart"in n.documentElement,c=(new Date).getTime(),u=[],d=arguments[0],v="string"==typeof d,f=[].slice.call(arguments,1);return o.each(function(m){var h,g,p,b,w,x,C,S,y=e.isPlainObject(i)?e.extend(!0,{},e.fn.dropdown.settings,i):e.extend({},e.fn.dropdown.settings),A=y.className,T=y.message,k=y.fields,L=y.keys,I=y.metadata,D=y.namespace,q=y.regExp,R=y.selector,O=y.error,V=y.templates,E="."+D,F="module-"+D,M=e(this),z=e(y.context),P=M.find(R.text),H=M.find(R.search),j=M.find(R.sizer),N=M.find(R.input),U=M.find(R.icon),K=M.prev().find(R.text).length>0?M.prev().find(R.text):M.prev(),W=M.children(R.menu),B=W.find(R.item),$=!1,Q=!1,X=!1,Y=this,G=M.data(F);S={initialize:function(){S.debug("Initializing dropdown",y),S.is.alreadySetup()?S.setup.reference():(S.setup.layout(),y.values&&S.change.values(y.values),S.refreshData(),S.save.defaults(),S.restore.selected(),S.create.id(),S.bind.events(),S.observeChanges(),S.instantiate())},instantiate:function(){S.verbose("Storing instance of dropdown",S),G=S,M.data(F,S)},destroy:function(){S.verbose("Destroying previous dropdown",M),S.remove.tabbable(),M.off(E).removeData(F),W.off(E),s.off(b),S.disconnect.menuObserver(),S.disconnect.selectObserver()},observeChanges:function(){"MutationObserver"in t&&(x=new MutationObserver(S.event.select.mutation),C=new MutationObserver(S.event.menu.mutation),S.debug("Setting up mutation observer",x,C),S.observe.select(),S.observe.menu())},disconnect:{menuObserver:function(){C&&C.disconnect()},selectObserver:function(){x&&x.disconnect()}},observe:{select:function(){S.has.input()&&x.observe(M[0],{childList:!0,subtree:!0})},menu:function(){S.has.menu()&&C.observe(W[0],{childList:!0,subtree:!0})}},create:{id:function(){w=(Math.random().toString(16)+"000000000").substr(2,8),b="."+w,S.verbose("Creating unique id for element",w)},userChoice:function(t){var n,i,a;return!!(t=t||S.get.userValues())&&(t=e.isArray(t)?t:[t],e.each(t,function(t,o){!1===S.get.item(o)&&(a=y.templates.addition(S.add.variables(T.addResult,o)),i=e("<div />").html(a).attr("data-"+I.value,o).attr("data-"+I.text,o).addClass(A.addition).addClass(A.item),y.hideAdditions&&i.addClass(A.hidden),n=void 0===n?i:n.add(i),S.verbose("Creating user choices for value",o,i))}),n)},userLabels:function(t){var n=S.get.userValues();n&&(S.debug("Adding user labels",n),e.each(n,function(e,t){S.verbose("Adding custom user value"),S.add.label(t,t)}))},menu:function(){W=e("<div />").addClass(A.menu).appendTo(M)},sizer:function(){j=e("<span />").addClass(A.sizer).insertAfter(H)}},search:function(e){e=void 0!==e?e:S.get.query(),S.verbose("Searching for query",e),S.has.minCharacters(e)?S.filter(e):S.hide()},select:{firstUnfiltered:function(){S.verbose("Selecting first non-filtered element"),S.remove.selectedItem(),B.not(R.unselectable).not(R.addition+R.hidden).eq(0).addClass(A.selected)},nextAvailable:function(e){e=e.eq(0);var t=e.nextAll(R.item).not(R.unselectable).eq(0),n=e.prevAll(R.item).not(R.unselectable).eq(0);t.length>0?(S.verbose("Moving selection to",t),t.addClass(A.selected)):(S.verbose("Moving selection to",n),n.addClass(A.selected))}},setup:{api:function(){var e={debug:y.debug,urlData:{value:S.get.value(),query:S.get.query()},on:!1};S.verbose("First request, initializing API"),M.api(e)},layout:function(){M.is("select")&&(S.setup.select(),S.setup.returnedObject()),S.has.menu()||S.create.menu(),S.is.search()&&!S.has.search()&&(S.verbose("Adding search input"),H=e("<input />").addClass(A.search).prop("autocomplete","off").insertBefore(P)),S.is.multiple()&&S.is.searchSelection()&&!S.has.sizer()&&S.create.sizer(),y.allowTab&&S.set.tabbable()},select:function(){var t=S.get.selectValues();S.debug("Dropdown initialized on a select",t),M.is("select")&&(N=M),N.parent(R.dropdown).length>0?(S.debug("UI dropdown already exists. Creating dropdown menu only"),M=N.closest(R.dropdown),S.has.menu()||S.create.menu(),W=M.children(R.menu),S.setup.menu(t)):(S.debug("Creating entire dropdown from select"),M=e("<div />").attr("class",N.attr("class")).addClass(A.selection).addClass(A.dropdown).html(V.dropdown(t)).insertBefore(N),N.hasClass(A.multiple)&&!1===N.prop("multiple")&&(S.error(O.missingMultiple),N.prop("multiple",!0)),N.is("[multiple]")&&S.set.multiple(),N.prop("disabled")&&(S.debug("Disabling dropdown"),M.addClass(A.disabled)),N.removeAttr("class").detach().prependTo(M)),S.refresh()},menu:function(e){W.html(V.menu(e,k)),B=W.find(R.item)},reference:function(){S.debug("Dropdown behavior was called on select, replacing with closest dropdown"),M=M.parent(R.dropdown),G=M.data(F),Y=M.get(0),S.refresh(),S.setup.returnedObject()},returnedObject:function(){var e=o.slice(0,m),t=o.slice(m+1);o=e.add(M).add(t)}},refresh:function(){S.refreshSelectors(),S.refreshData()},refreshItems:function(){B=W.find(R.item)},refreshSelectors:function(){S.verbose("Refreshing selector cache"),P=M.find(R.text),H=M.find(R.search),N=M.find(R.input),U=M.find(R.icon),K=M.prev().find(R.text).length>0?M.prev().find(R.text):M.prev(),W=M.children(R.menu),B=W.find(R.item)},refreshData:function(){S.verbose("Refreshing cached metadata"),B.removeData(I.text).removeData(I.value)},clearData:function(){S.verbose("Clearing metadata"),B.removeData(I.text).removeData(I.value),M.removeData(I.defaultText).removeData(I.defaultValue).removeData(I.placeholderText)},toggle:function(){S.verbose("Toggling menu visibility"),S.is.active()?S.hide():S.show()},show:function(t){if(t=e.isFunction(t)?t:function(){},!S.can.show()&&S.is.remote()&&(S.debug("No API results retrieved, searching before show"),S.queryRemote(S.get.query(),S.show)),S.can.show()&&!S.is.active()){if(S.debug("Showing dropdown"),!S.has.message()||S.has.maxSelections()||S.has.allResultsFiltered()||S.remove.message(),S.is.allFiltered())return!0;!1!==y.onShow.call(Y)&&S.animate.show(function(){S.can.click()&&S.bind.intent(),S.has.menuSearch()&&S.focusSearch(),S.set.visible(),t.call(Y)})}},hide:function(t){t=e.isFunction(t)?t:function(){},S.is.active()&&(S.debug("Hiding dropdown"),!1!==y.onHide.call(Y)&&S.animate.hide(function(){S.remove.visible(),t.call(Y)}))},hideOthers:function(){S.verbose("Finding other dropdowns to hide"),o.not(M).has(R.menu+"."+A.visible).dropdown("hide")},hideMenu:function(){S.verbose("Hiding menu  instantaneously"),S.remove.active(),S.remove.visible(),W.transition("hide")},hideSubMenus:function(){var e=W.children(R.item).find(R.menu);S.verbose("Hiding sub menus",e),e.transition("hide")},bind:{events:function(){l&&S.bind.touchEvents(),S.bind.keyboardEvents(),S.bind.inputEvents(),S.bind.mouseEvents()},touchEvents:function(){S.debug("Touch device detected binding additional touch events"),S.is.searchSelection()||S.is.single()&&M.on("touchstart"+E,S.event.test.toggle),W.on("touchstart"+E,R.item,S.event.item.mouseenter)},keyboardEvents:function(){S.verbose("Binding keyboard events"),M.on("keydown"+E,S.event.keydown),S.has.search()&&M.on(S.get.inputEvent()+E,R.search,S.event.input),S.is.multiple()&&s.on("keydown"+b,S.event.document.keydown)},inputEvents:function(){S.verbose("Binding input change events"),M.on("change"+E,R.input,S.event.change)},mouseEvents:function(){S.verbose("Binding mouse events"),S.is.multiple()&&M.on("click"+E,R.label,S.event.label.click).on("click"+E,R.remove,S.event.remove.click),S.is.searchSelection()?(M.on("mousedown"+E,S.event.mousedown).on("mouseup"+E,S.event.mouseup).on("mousedown"+E,R.menu,S.event.menu.mousedown).on("mouseup"+E,R.menu,S.event.menu.mouseup).on("click"+E,R.icon,S.event.icon.click).on("focus"+E,R.search,S.event.search.focus).on("click"+E,R.search,S.event.search.focus).on("blur"+E,R.search,S.event.search.blur).on("click"+E,R.text,S.event.text.focus),S.is.multiple()&&M.on("click"+E,S.event.click)):("click"==y.on?M.on("click"+E,R.icon,S.event.icon.click).on("click"+E,S.event.test.toggle):"hover"==y.on?M.on("mouseenter"+E,S.delay.show).on("mouseleave"+E,S.delay.hide):M.on(y.on+E,S.toggle),M.on("mousedown"+E,S.event.mousedown).on("mouseup"+E,S.event.mouseup).on("focus"+E,S.event.focus),S.has.menuSearch()?M.on("blur"+E,R.search,S.event.search.blur):M.on("blur"+E,S.event.blur)),W.on("mouseenter"+E,R.item,S.event.item.mouseenter).on("mouseleave"+E,R.item,S.event.item.mouseleave).on("click"+E,R.item,S.event.item.click)},intent:function(){S.verbose("Binding hide intent event to document"),l&&s.on("touchstart"+b,S.event.test.touch).on("touchmove"+b,S.event.test.touch),s.on("click"+b,S.event.test.hide)}},unbind:{intent:function(){S.verbose("Removing hide intent event from document"),l&&s.off("touchstart"+b).off("touchmove"+b),s.off("click"+b)}},filter:function(e){var t=void 0!==e?e:S.get.query(),n=function(){S.is.multiple()&&S.filterActive(),(e||!e&&0==S.get.activeItem().length)&&S.select.firstUnfiltered(),S.has.allResultsFiltered()?y.onNoResults.call(Y,t)?y.allowAdditions?y.hideAdditions&&(S.verbose("User addition with no menu, setting empty style"),S.set.empty(),S.hideMenu()):(S.verbose("All items filtered, showing message",t),S.add.message(T.noResults)):(S.verbose("All items filtered, hiding dropdown",t),S.hideMenu()):(S.remove.empty(),S.remove.message()),y.allowAdditions&&S.add.userSuggestion(e),S.is.searchSelection()&&S.can.show()&&S.is.focusedOnSearch()&&S.show()};y.useLabels&&S.has.maxSelections()||(y.apiSettings?S.can.useAPI()?S.queryRemote(t,function(){y.filterRemoteData&&S.filterItems(t),n()}):S.error(O.noAPI):(S.filterItems(t),n()))},queryRemote:function(t,n){var i={errorDuration:!1,cache:"local",throttle:y.throttle,urlData:{query:t},onError:function(){S.add.message(T.serverError),n()},onFailure:function(){S.add.message(T.serverError),n()},onSuccess:function(e){S.remove.message(),S.setup.menu({values:e[k.remoteValues]}),n()}};M.api("get request")||S.setup.api(),i=e.extend(!0,{},i,y.apiSettings),M.api("setting",i).api("query")},filterItems:function(t){var n=void 0!==t?t:S.get.query(),i=null,a=S.escape.string(n),o=new RegExp("^"+a,"igm");S.has.query()&&(i=[],S.verbose("Searching for matching values",n),B.each(function(){var t,a,s=e(this);if("both"==y.match||"text"==y.match){if(t=String(S.get.choiceText(s,!1)),-1!==t.search(o))return i.push(this),!0;if("exact"===y.fullTextSearch&&S.exactSearch(n,t))return i.push(this),!0;if(!0===y.fullTextSearch&&S.fuzzySearch(n,t))return i.push(this),!0}if("both"==y.match||"value"==y.match){if(a=String(S.get.choiceValue(s,t)),-1!==a.search(o))return i.push(this),!0;if("exact"===y.fullTextSearch&&S.exactSearch(n,a))return i.push(this),!0;if(!0===y.fullTextSearch&&S.fuzzySearch(n,a))return i.push(this),!0}})),S.debug("Showing only matched items",n),S.remove.filteredItem(),i&&B.not(i).addClass(A.filtered)},fuzzySearch:function(e,t){var n=t.length,i=e.length;if(e=e.toLowerCase(),t=t.toLowerCase(),i>n)return!1;if(i===n)return e===t;e:for(var a=0,o=0;a<i;a++){for(var s=e.charCodeAt(a);o<n;)if(t.charCodeAt(o++)===s)continue e;return!1}return!0},exactSearch:function(e,t){return e=e.toLowerCase(),t=t.toLowerCase(),t.indexOf(e)>-1},filterActive:function(){y.useLabels&&B.filter("."+A.active).addClass(A.filtered)},focusSearch:function(e){S.has.search()&&!S.is.focusedOnSearch()&&(e?(M.off("focus"+E,R.search),H.focus(),M.on("focus"+E,R.search,S.event.search.focus)):H.focus())},forceSelection:function(){var e=B.not(A.filtered).filter("."+A.selected).eq(0),t=B.not(A.filtered).filter("."+A.active).eq(0),n=e.length>0?e:t;if(n.length>0&&!S.is.multiple())return S.debug("Forcing partial selection to selected item",n),void S.event.item.click.call(n,{},!0);y.allowAdditions?(S.set.selected(S.get.query()),S.remove.searchTerm()):S.remove.searchTerm()},change:{values:function(t){y.allowAdditions||S.clear(),S.debug("Creating dropdown with specified values",t),S.setup.menu({values:t}),e.each(t,function(e,t){if(1==t.selected)return S.debug("Setting initial selection to",t.value),S.set.selected(t.value),!0})}},event:{change:function(){X||(S.debug("Input changed, updating selection"),S.set.selected())},focus:function(){y.showOnFocus&&!$&&S.is.hidden()&&!g&&S.show()},blur:function(e){g=n.activeElement===this,$||g||(S.remove.activeLabel(),S.hide())},mousedown:function(){S.is.searchSelection()?p=!0:$=!0},mouseup:function(){S.is.searchSelection()?p=!1:$=!1},click:function(t){e(t.target).is(M)&&(S.is.focusedOnSearch()?S.show():S.focusSearch())},search:{focus:function(){$=!0,S.is.multiple()&&S.remove.activeLabel(),y.showOnFocus&&S.search()},blur:function(e){g=n.activeElement===this,S.is.searchSelection()&&!p&&(Q||g||(y.forceSelection&&S.forceSelection(),S.hide())),p=!1}},icon:{click:function(e){S.toggle()}},text:{focus:function(e){$=!0,S.focusSearch()}},input:function(e){(S.is.multiple()||S.is.searchSelection())&&S.set.filtered(),clearTimeout(S.timer),S.timer=setTimeout(S.search,y.delay.search)},label:{click:function(t){var n=e(this),i=M.find(R.label),a=i.filter("."+A.active),o=n.nextAll("."+A.active),s=n.prevAll("."+A.active),r=o.length>0?n.nextUntil(o).add(a).add(n):n.prevUntil(s).add(a).add(n);t.shiftKey?(a.removeClass(A.active),r.addClass(A.active)):t.ctrlKey?n.toggleClass(A.active):(a.removeClass(A.active),n.addClass(A.active)),y.onLabelSelect.apply(this,i.filter("."+A.active))}},remove:{click:function(){var t=e(this).parent();t.hasClass(A.active)?S.remove.activeLabels():S.remove.activeLabels(t)}},test:{toggle:function(e){var t=S.is.multiple()?S.show:S.toggle;S.is.bubbledLabelClick(e)||S.is.bubbledIconClick(e)||S.determine.eventOnElement(e,t)&&e.preventDefault()},touch:function(e){S.determine.eventOnElement(e,function(){"touchstart"==e.type?S.timer=setTimeout(function(){S.hide()},y.delay.touch):"touchmove"==e.type&&clearTimeout(S.timer)}),e.stopPropagation()},hide:function(e){S.determine.eventInModule(e,S.hide)}},select:{mutation:function(t){S.debug("<select> modified, recreating menu");var n=!1;e.each(t,function(t,i){if(e(i.target).is("select")||e(i.addedNodes).is("select"))return n=!0,!0}),n&&(S.disconnect.selectObserver(),S.refresh(),S.setup.select(),S.set.selected(),S.observe.select())}},menu:{mutation:function(t){var n=t[0],i=e(n.addedNodes?n.addedNodes[0]:!1),a=e(n.removedNodes?n.removedNodes[0]:!1),o=i.add(a),s=o.is(R.addition)||o.closest(R.addition).length>0,r=o.is(R.message)||o.closest(R.message).length>0;s||r?(S.debug("Updating item selector cache"),S.refreshItems()):(S.debug("Menu modified, updating selector cache"),S.refresh())},mousedown:function(){Q=!0},mouseup:function(){Q=!1}},item:{mouseenter:function(t){var n=e(t.target),i=e(this),a=i.children(R.menu),o=i.siblings(R.item).children(R.menu),s=a.length>0;!(a.find(n).length>0)&&s&&(clearTimeout(S.itemTimer),S.itemTimer=setTimeout(function(){S.verbose("Showing sub-menu",a),e.each(o,function(){S.animate.hide(!1,e(this))}),S.animate.show(!1,a)},y.delay.show),t.preventDefault())},mouseleave:function(t){var n=e(this).children(R.menu);n.length>0&&(clearTimeout(S.itemTimer),S.itemTimer=setTimeout(function(){S.verbose("Hiding sub-menu",n),S.animate.hide(!1,n)},y.delay.hide))},click:function(t,i){var a=e(this),o=e(t?t.target:""),s=a.find(R.menu),r=S.get.choiceText(a),l=S.get.choiceValue(a,r),c=s.length>0,u=s.find(o).length>0;S.has.menuSearch()&&e(n.activeElement).blur(),u||c&&!y.allowCategorySelection||(S.is.searchSelection()&&(y.allowAdditions&&S.remove.userAddition(),S.remove.searchTerm(),S.is.focusedOnSearch()||1==i||S.focusSearch(!0)),y.useLabels||(S.remove.filteredItem(),S.set.scrollPosition(a)),S.determine.selectAction.call(this,r,l))}},document:{keydown:function(e){var t=e.which;if(S.is.inObject(t,L)){var n=M.find(R.label),i=n.filter("."+A.active),a=(i.data(I.value),n.index(i)),o=n.length,s=i.length>0,r=i.length>1,l=0===a,c=a+1==o,u=S.is.searchSelection(),d=S.is.focusedOnSearch(),v=S.is.focused(),f=d&&0===S.get.caretPosition();if(u&&!s&&!d)return;t==L.leftArrow?!v&&!f||s?s&&(e.shiftKey?S.verbose("Adding previous label to selection"):(S.verbose("Selecting previous label"),n.removeClass(A.active)),l&&!r?i.addClass(A.active):i.prev(R.siblingLabel).addClass(A.active).end(),e.preventDefault()):(S.verbose("Selecting previous label"),n.last().addClass(A.active)):t==L.rightArrow?(v&&!s&&n.first().addClass(A.active),s&&(e.shiftKey?S.verbose("Adding next label to selection"):(S.verbose("Selecting next label"),n.removeClass(A.active)),c?u?d?n.removeClass(A.active):S.focusSearch():r?i.next(R.siblingLabel).addClass(A.active):i.addClass(A.active):i.next(R.siblingLabel).addClass(A.active),e.preventDefault())):t==L.deleteKey||t==L.backspace?s?(S.verbose("Removing active labels"),c&&u&&!d&&S.focusSearch(),i.last().next(R.siblingLabel).addClass(A.active),S.remove.activeLabels(i),e.preventDefault()):f&&!s&&t==L.backspace&&(S.verbose("Removing last label on input backspace"),i=n.last().addClass(A.active),S.remove.activeLabels(i)):i.removeClass(A.active)}}},keydown:function(e){var t=e.which;if(S.is.inObject(t,L)){var n,i=B.not(R.unselectable).filter("."+A.selected).eq(0),a=W.children("."+A.active).eq(0),o=i.length>0?i:a,s=o.length>0?o.siblings(":not(."+A.filtered+")").addBack():W.children(":not(."+A.filtered+")"),r=o.children(R.menu),l=o.closest(R.menu),c=l.hasClass(A.visible)||l.hasClass(A.animating)||l.parent(R.menu).length>0,u=r.length>0,d=o.length>0,v=o.not(R.unselectable).length>0,f=t==L.delimiter&&y.allowAdditions&&S.is.multiple(),m=y.allowAdditions&&y.hideAdditions&&(t==L.enter||f)&&v;if(m&&(S.verbose("Selecting item from keyboard shortcut",o),S.event.item.click.call(o,e),S.is.searchSelection()&&S.remove.searchTerm()),S.is.visible()){if((t==L.enter||f)&&(t==L.enter&&d&&u&&!y.allowCategorySelection?(S.verbose("Pressed enter on unselectable category, opening sub menu"),t=L.rightArrow):v&&(S.verbose("Selecting item from keyboard shortcut",o),S.event.item.click.call(o,e),S.is.searchSelection()&&S.remove.searchTerm()),e.preventDefault()),d&&(t==L.leftArrow&&l[0]!==W[0]&&(S.verbose("Left key pressed, closing sub-menu"),S.animate.hide(!1,l),o.removeClass(A.selected),l.closest(R.item).addClass(A.selected),e.preventDefault()),t==L.rightArrow&&u&&(S.verbose("Right key pressed, opening sub-menu"),S.animate.show(!1,r),o.removeClass(A.selected),r.find(R.item).eq(0).addClass(A.selected),e.preventDefault())),t==L.upArrow){if(n=d&&c?o.prevAll(R.item+":not("+R.unselectable+")").eq(0):B.eq(0),s.index(n)<0)return S.verbose("Up key pressed but reached top of current menu"),void e.preventDefault();S.verbose("Up key pressed, changing active item"),o.removeClass(A.selected),n.addClass(A.selected),S.set.scrollPosition(n),y.selectOnKeydown&&S.is.single()&&S.set.selectedItem(n),e.preventDefault()}if(t==L.downArrow){if(n=d&&c?n=o.nextAll(R.item+":not("+R.unselectable+")").eq(0):B.eq(0),0===n.length)return S.verbose("Down key pressed but reached bottom of current menu"),void e.preventDefault();S.verbose("Down key pressed, changing active item"),B.removeClass(A.selected),n.addClass(A.selected),S.set.scrollPosition(n),y.selectOnKeydown&&S.is.single()&&S.set.selectedItem(n),e.preventDefault()}t==L.pageUp&&(S.scrollPage("up"),e.preventDefault()),t==L.pageDown&&(S.scrollPage("down"),e.preventDefault()),t==L.escape&&(S.verbose("Escape key pressed, closing dropdown"),S.hide())}else f&&e.preventDefault(),t!=L.downArrow||S.is.visible()||(S.verbose("Down key pressed, showing dropdown"),S.show(),e.preventDefault())}else S.has.search()||S.set.selectedLetter(String.fromCharCode(t))}},trigger:{change:function(){var e=n.createEvent("HTMLEvents"),t=N[0];t&&(S.verbose("Triggering native change event"),e.initEvent("change",!0,!1),t.dispatchEvent(e))}},determine:{selectAction:function(t,n){S.verbose("Determining action",y.action),e.isFunction(S.action[y.action])?(S.verbose("Triggering preset action",y.action,t,n),S.action[y.action].call(Y,t,n,this)):e.isFunction(y.action)?(S.verbose("Triggering user action",y.action,t,n),y.action.call(Y,t,n,this)):S.error(O.action,y.action)},eventInModule:function(t,i){var a=e(t.target),o=a.closest(n.documentElement).length>0,s=a.closest(M).length>0;return i=e.isFunction(i)?i:function(){},o&&!s?(S.verbose("Triggering event",i),i(),!0):(S.verbose("Event occurred in dropdown, canceling callback"),!1)},eventOnElement:function(t,i){var a=e(t.target),o=a.closest(R.siblingLabel),s=n.body.contains(t.target),r=0===M.find(o).length,l=0===a.closest(W).length;return i=e.isFunction(i)?i:function(){},s&&r&&l?(S.verbose("Triggering event",i),i(),!0):(S.verbose("Event occurred in dropdown menu, canceling callback"),!1)}},action:{nothing:function(){},activate:function(t,n,i){if(n=void 0!==n?n:t,S.can.activate(e(i))){if(S.set.selected(n,e(i)),S.is.multiple()&&!S.is.allFiltered())return;S.hideAndClear()}},select:function(t,n,i){if(n=void 0!==n?n:t,S.can.activate(e(i))){if(S.set.value(n,e(i)),S.is.multiple()&&!S.is.allFiltered())return;S.hideAndClear()}},combo:function(t,n,i){n=void 0!==n?n:t,S.set.selected(n,e(i)),S.hideAndClear()},hide:function(e,t,n){S.set.value(t,e),S.hideAndClear()}},get:{id:function(){return w},defaultText:function(){return M.data(I.defaultText)},defaultValue:function(){return M.data(I.defaultValue)},placeholderText:function(){return"auto"!=y.placeholder&&"string"==typeof y.placeholder?y.placeholder:M.data(I.placeholderText)||""},text:function(){return P.text()},query:function(){return e.trim(H.val())},searchWidth:function(e){return e=void 0!==e?e:H.val(),j.text(e),Math.ceil(j.width()+1)},selectionCount:function(){var t=S.get.values();return S.is.multiple()?e.isArray(t)?t.length:0:""!==S.get.value()?1:0},transition:function(e){return"auto"==y.transition?S.is.upward(e)?"slide up":"slide down":y.transition},userValues:function(){var t=S.get.values();return!!t&&(t=e.isArray(t)?t:[t],e.grep(t,function(e){return!1===S.get.item(e)}))},uniqueArray:function(t){return e.grep(t,function(n,i){return e.inArray(n,t)===i})},caretPosition:function(){var e,t,i=H.get(0);return"selectionStart"in i?i.selectionStart:n.selection?(i.focus(),e=n.selection.createRange(),t=e.text.length,e.moveStart("character",-i.value.length),e.text.length-t):void 0},value:function(){var t=N.length>0?N.val():M.data(I.value),n=e.isArray(t)&&1===t.length&&""===t[0];return void 0===t||n?"":t},values:function(){var e=S.get.value();return""===e?"":!S.has.selectInput()&&S.is.multiple()?"string"==typeof e?e.split(y.delimiter):"":e},remoteValues:function(){var t=S.get.values(),n=!1;return t&&("string"==typeof t&&(t=[t]),e.each(t,function(e,t){var i=S.read.remoteData(t);S.verbose("Restoring value from session data",i,t),i&&(n||(n={}),n[t]=i)})),n},choiceText:function(t,n){if(n=void 0!==n?n:y.preserveHTML,t)return t.find(R.menu).length>0&&(S.verbose("Retrieving text of element with sub-menu"),t=t.clone(),t.find(R.menu).remove(),t.find(R.menuIcon).remove()),void 0!==t.data(I.text)?t.data(I.text):n?e.trim(t.html()):e.trim(t.text())},choiceValue:function(t,n){return n=n||S.get.choiceText(t),!!t&&(void 0!==t.data(I.value)?String(t.data(I.value)):"string"==typeof n?e.trim(n.toLowerCase()):String(n))},inputEvent:function(){var e=H[0];return!!e&&(void 0!==e.oninput?"input":void 0!==e.onpropertychange?"propertychange":"keyup")},selectValues:function(){var t={};return t.values=[],M.find("option").each(function(){var n=e(this),i=n.html(),a=n.attr("disabled"),o=void 0!==n.attr("value")?n.attr("value"):i;"auto"===y.placeholder&&""===o?t.placeholder=i:t.values.push({name:i,value:o,disabled:a})}),y.placeholder&&"auto"!==y.placeholder&&(S.debug("Setting placeholder value to",y.placeholder),t.placeholder=y.placeholder),y.sortSelect?(t.values.sort(function(e,t){return e.name>t.name?1:-1}),S.debug("Retrieved and sorted values from select",t)):S.debug("Retrieved values from select",t),t},activeItem:function(){return B.filter("."+A.active)},selectedItem:function(){var e=B.not(R.unselectable).filter("."+A.selected);return e.length>0?e:B.eq(0)},itemWithAdditions:function(e){var t=S.get.item(e),n=S.create.userChoice(e);return n&&n.length>0&&(t=t.length>0?t.add(n):n),t},item:function(t,n){var i,a,o=!1;return t=void 0!==t?t:void 0!==S.get.values()?S.get.values():S.get.text(),i=a?t.length>0:void 0!==t&&null!==t,a=S.is.multiple()&&e.isArray(t),n=""===t||0===t||(n||!1),i&&B.each(function(){var i=e(this),s=S.get.choiceText(i),r=S.get.choiceValue(i,s);if(null!==r&&void 0!==r)if(a)-1===e.inArray(String(r),t)&&-1===e.inArray(s,t)||(o=o?o.add(i):i);else if(n){if(S.verbose("Ambiguous dropdown value using strict type check",i,t),r===t||s===t)return o=i,!0}else if(String(r)==String(t)||s==t)return S.verbose("Found select item by value",r,t),o=i,!0}),o}},check:{maxSelections:function(e){return!y.maxSelections||(e=void 0!==e?e:S.get.selectionCount(),e>=y.maxSelections?(S.debug("Maximum selection count reached"),y.useLabels&&(B.addClass(A.filtered),S.add.message(T.maxSelections)),!0):(S.verbose("No longer at maximum selection count"),S.remove.message(),S.remove.filteredItem(),S.is.searchSelection()&&S.filterItems(),!1))}},restore:{defaults:function(){S.clear(),S.restore.defaultText(),S.restore.defaultValue()},defaultText:function(){var e=S.get.defaultText();e===S.get.placeholderText?(S.debug("Restoring default placeholder text",e),S.set.placeholderText(e)):(S.debug("Restoring default text",e),S.set.text(e))},placeholderText:function(){S.set.placeholderText()},defaultValue:function(){var e=S.get.defaultValue();void 0!==e&&(S.debug("Restoring default value",e),""!==e?(S.set.value(e),S.set.selected()):(S.remove.activeItem(),S.remove.selectedItem()))},labels:function(){y.allowAdditions&&(y.useLabels||(S.error(O.labels),y.useLabels=!0),S.debug("Restoring selected values"),S.create.userLabels()),S.check.maxSelections()},selected:function(){S.restore.values(),S.is.multiple()?(S.debug("Restoring previously selected values and labels"),S.restore.labels()):S.debug("Restoring previously selected values")},values:function(){S.set.initialLoad(),y.apiSettings&&y.saveRemoteData&&S.get.remoteValues()?S.restore.remoteValues():S.set.selected(),S.remove.initialLoad()},remoteValues:function(){var t=S.get.remoteValues();S.debug("Recreating selected from session data",t),t&&(S.is.single()?e.each(t,function(e,t){S.set.text(t)}):e.each(t,function(e,t){S.add.label(e,t)}))}},read:{remoteData:function(e){var n;return void 0===t.Storage?void S.error(O.noStorage):void 0!==(n=sessionStorage.getItem(e))&&n}},save:{defaults:function(){S.save.defaultText(),S.save.placeholderText(),S.save.defaultValue()},defaultValue:function(){var e=S.get.value();S.verbose("Saving default value as",e),M.data(I.defaultValue,e)},defaultText:function(){var e=S.get.text();S.verbose("Saving default text as",e),M.data(I.defaultText,e)},placeholderText:function(){var e;!1!==y.placeholder&&P.hasClass(A.placeholder)&&(e=S.get.text(),S.verbose("Saving placeholder text as",e),M.data(I.placeholderText,e))},remoteData:function(e,n){if(void 0===t.Storage)return void S.error(O.noStorage);S.verbose("Saving remote data to session storage",n,e),sessionStorage.setItem(n,e)}},clear:function(){S.is.multiple()&&y.useLabels?S.remove.labels():(S.remove.activeItem(),S.remove.selectedItem()),S.set.placeholderText(),S.clearValue()},clearValue:function(){S.set.value("")},scrollPage:function(e,t){var n,i,a,o=t||S.get.selectedItem(),s=o.closest(R.menu),r=s.outerHeight(),l=s.scrollTop(),c=B.eq(0).outerHeight(),u=Math.floor(r/c),d=(s.prop("scrollHeight"),"up"==e?l-c*u:l+c*u),v=B.not(R.unselectable);a="up"==e?v.index(o)-u:v.index(o)+u,n="up"==e?a>=0:a<v.length,i=n?v.eq(a):"up"==e?v.first():v.last(),i.length>0&&(S.debug("Scrolling page",e,i),o.removeClass(A.selected),i.addClass(A.selected),y.selectOnKeydown&&S.is.single()&&S.set.selectedItem(i),s.scrollTop(d))},set:{filtered:function(){var e=S.is.multiple(),t=S.is.searchSelection(),n=e&&t,i=t?S.get.query():"",a="string"==typeof i&&i.length>0,o=S.get.searchWidth(),s=""!==i;e&&a&&(S.verbose("Adjusting input width",o,y.glyphWidth),H.css("width",o)),a||n&&s?(S.verbose("Hiding placeholder text"),P.addClass(A.filtered)):(!e||n&&!s)&&(S.verbose("Showing placeholder text"),P.removeClass(A.filtered))},empty:function(){M.addClass(A.empty)},loading:function(){M.addClass(A.loading)},placeholderText:function(e){e=e||S.get.placeholderText(),S.debug("Setting placeholder text",e),S.set.text(e),P.addClass(A.placeholder)},tabbable:function(){S.is.searchSelection()?(S.debug("Added tabindex to searchable dropdown"),H.val("").attr("tabindex",0),W.attr("tabindex",-1)):(S.debug("Added tabindex to dropdown"),void 0===M.attr("tabindex")&&(M.attr("tabindex",0),W.attr("tabindex",-1)))},initialLoad:function(){S.verbose("Setting initial load"),h=!0},activeItem:function(e){y.allowAdditions&&e.filter(R.addition).length>0?e.addClass(A.filtered):e.addClass(A.active)},partialSearch:function(e){var t=S.get.query().length;H.val(e.substr(0,t))},scrollPosition:function(e,t){var n,i,a,o,s,r,l,c,u;e=e||S.get.selectedItem(),n=e.closest(R.menu),i=e&&e.length>0,t=void 0!==t&&t,e&&n.length>0&&i&&(o=e.position().top,n.addClass(A.loading),r=n.scrollTop(),s=n.offset().top,o=e.offset().top,a=r-s+o,t||(l=n.height(),u=r+l<a+5,c=a-5<r),S.debug("Scrolling to active item",a),(t||c||u)&&n.scrollTop(a),n.removeClass(A.loading))},text:function(e){"select"!==y.action&&("combo"==y.action?(S.debug("Changing combo button text",e,K),y.preserveHTML?K.html(e):K.text(e)):(e!==S.get.placeholderText()&&P.removeClass(A.placeholder),S.debug("Changing text",e,P),P.removeClass(A.filtered),y.preserveHTML?P.html(e):P.text(e)))},selectedItem:function(e){var t=S.get.choiceValue(e),n=S.get.choiceText(e,!1),i=S.get.choiceText(e,!0);S.debug("Setting user selection to item",e),S.remove.activeItem(),S.set.partialSearch(n),S.set.activeItem(e),S.set.selected(t,e),S.set.text(i)},selectedLetter:function(t){var n,i=B.filter("."+A.selected),a=i.length>0&&S.has.firstLetter(i,t),o=!1;a&&(n=i.nextAll(B).eq(0),S.has.firstLetter(n,t)&&(o=n)),o||B.each(function(){if(S.has.firstLetter(e(this),t))return o=e(this),!1}),o&&(S.verbose("Scrolling to next value with letter",t),S.set.scrollPosition(o),i.removeClass(A.selected),o.addClass(A.selected),y.selectOnKeydown&&S.is.single()&&S.set.selectedItem(o))},direction:function(e){"auto"==y.direction?(S.remove.upward(),S.can.openDownward(e)?S.remove.upward(e):S.set.upward(e),S.is.leftward(e)||S.can.openRightward(e)||S.set.leftward(e)):"upward"==y.direction&&S.set.upward(e)},upward:function(e){(e||M).addClass(A.upward)},leftward:function(e){(e||W).addClass(A.leftward)},value:function(e,t,n){var i=S.escape.value(e),a=N.length>0,o=(S.has.value(e),S.get.values()),s=void 0!==e?String(e):e;if(a){if(!y.allowReselection&&s==o&&(S.verbose("Skipping value update already same value",e,o),!S.is.initialLoad()))return;S.is.single()&&S.has.selectInput()&&S.can.extendSelect()&&(S.debug("Adding user option",e),S.add.optionValue(e)),S.debug("Updating input value",i,o),X=!0,N.val(i),!1===y.fireOnInit&&S.is.initialLoad()?S.debug("Input native change event ignored on initial load"):S.trigger.change(),X=!1}else S.verbose("Storing value in metadata",i,N),i!==o&&M.data(I.value,s);!1===y.fireOnInit&&S.is.initialLoad()?S.verbose("No callback on initial load",y.onChange):y.onChange.call(Y,e,t,n)},active:function(){M.addClass(A.active)},multiple:function(){M.addClass(A.multiple)},visible:function(){M.addClass(A.visible)},exactly:function(e,t){S.debug("Setting selected to exact values"),S.clear(),S.set.selected(e,t)},selected:function(t,n){var i=S.is.multiple();(n=y.allowAdditions?n||S.get.itemWithAdditions(t):n||S.get.item(t))&&(S.debug("Setting selected menu item to",n),S.is.multiple()&&S.remove.searchWidth(),S.is.single()?(S.remove.activeItem(),S.remove.selectedItem()):y.useLabels&&S.remove.selectedItem(),n.each(function(){var t=e(this),a=S.get.choiceText(t),o=S.get.choiceValue(t,a),s=t.hasClass(A.filtered),r=t.hasClass(A.active),l=t.hasClass(A.addition),c=i&&1==n.length;i?!r||l?(y.apiSettings&&y.saveRemoteData&&S.save.remoteData(a,o),y.useLabels?(S.add.value(o,a,t),S.add.label(o,a,c),S.set.activeItem(t),S.filterActive(),
S.select.nextAvailable(n)):(S.add.value(o,a,t),S.set.text(S.add.variables(T.count)),S.set.activeItem(t))):s||(S.debug("Selected active value, removing label"),S.remove.selected(o)):(y.apiSettings&&y.saveRemoteData&&S.save.remoteData(a,o),S.set.text(a),S.set.value(o,a,t),t.addClass(A.active).addClass(A.selected))}))}},add:{label:function(t,n,i){var a,o=S.is.searchSelection()?H:P,s=S.escape.value(t);if(a=e("<a />").addClass(A.label).attr("data-"+I.value,s).html(V.label(s,n)),a=y.onLabelCreate.call(a,s,n),S.has.label(t))return void S.debug("Label already exists, skipping",s);y.label.variation&&a.addClass(y.label.variation),!0===i?(S.debug("Animating in label",a),a.addClass(A.hidden).insertBefore(o).transition(y.label.transition,y.label.duration)):(S.debug("Adding selection label",a),a.insertBefore(o))},message:function(t){var n=W.children(R.message),i=y.templates.message(S.add.variables(t));n.length>0?n.html(i):n=e("<div/>").html(i).addClass(A.message).appendTo(W)},optionValue:function(t){var n=S.escape.value(t);N.find('option[value="'+S.escape.string(n)+'"]').length>0||(S.disconnect.selectObserver(),S.is.single()&&(S.verbose("Removing previous user addition"),N.find("option."+A.addition).remove()),e("<option/>").prop("value",n).addClass(A.addition).html(t).appendTo(N),S.verbose("Adding user addition as an <option>",t),S.observe.select())},userSuggestion:function(e){var t,n=W.children(R.addition),i=S.get.item(e),a=i&&i.not(R.addition).length,o=n.length>0;if(!y.useLabels||!S.has.maxSelections()){if(""===e||a)return void n.remove();o?(n.data(I.value,e).data(I.text,e).attr("data-"+I.value,e).attr("data-"+I.text,e).removeClass(A.filtered),y.hideAdditions||(t=y.templates.addition(S.add.variables(T.addResult,e)),n.html(t)),S.verbose("Replacing user suggestion with new value",n)):(n=S.create.userChoice(e),n.prependTo(W),S.verbose("Adding item choice to menu corresponding with user choice addition",n)),y.hideAdditions&&!S.is.allFiltered()||n.addClass(A.selected).siblings().removeClass(A.selected),S.refreshItems()}},variables:function(e,t){var n,i,a=-1!==e.search("{count}"),o=-1!==e.search("{maxCount}"),s=-1!==e.search("{term}");return S.verbose("Adding templated variables to message",e),a&&(n=S.get.selectionCount(),e=e.replace("{count}",n)),o&&(n=S.get.selectionCount(),e=e.replace("{maxCount}",y.maxSelections)),s&&(i=t||S.get.query(),e=e.replace("{term}",i)),e},value:function(t,n,i){var a,o=S.get.values();if(""===t)return void S.debug("Cannot select blank values from multiselect");e.isArray(o)?(a=o.concat([t]),a=S.get.uniqueArray(a)):a=[t],S.has.selectInput()?S.can.extendSelect()&&(S.debug("Adding value to select",t,a,N),S.add.optionValue(t)):(a=a.join(y.delimiter),S.debug("Setting hidden input to delimited value",a,N)),!1===y.fireOnInit&&S.is.initialLoad()?S.verbose("Skipping onadd callback on initial load",y.onAdd):y.onAdd.call(Y,t,n,i),S.set.value(a,t,n,i),S.check.maxSelections()}},remove:{active:function(){M.removeClass(A.active)},activeLabel:function(){M.find(R.label).removeClass(A.active)},empty:function(){M.removeClass(A.empty)},loading:function(){M.removeClass(A.loading)},initialLoad:function(){h=!1},upward:function(e){(e||M).removeClass(A.upward)},leftward:function(e){(e||W).removeClass(A.leftward)},visible:function(){M.removeClass(A.visible)},activeItem:function(){B.removeClass(A.active)},filteredItem:function(){y.useLabels&&S.has.maxSelections()||(y.useLabels&&S.is.multiple()?B.not("."+A.active).removeClass(A.filtered):B.removeClass(A.filtered),S.remove.empty())},optionValue:function(e){var t=S.escape.value(e),n=N.find('option[value="'+S.escape.string(t)+'"]');n.length>0&&n.hasClass(A.addition)&&(x&&(x.disconnect(),S.verbose("Temporarily disconnecting mutation observer")),n.remove(),S.verbose("Removing user addition as an <option>",t),x&&x.observe(N[0],{childList:!0,subtree:!0}))},message:function(){W.children(R.message).remove()},searchWidth:function(){H.css("width","")},searchTerm:function(){S.verbose("Cleared search term"),H.val(""),S.set.filtered()},userAddition:function(){B.filter(R.addition).remove()},selected:function(t,n){if(!(n=y.allowAdditions?n||S.get.itemWithAdditions(t):n||S.get.item(t)))return!1;n.each(function(){var t=e(this),n=S.get.choiceText(t),i=S.get.choiceValue(t,n);S.is.multiple()?y.useLabels?(S.remove.value(i,n,t),S.remove.label(i)):(S.remove.value(i,n,t),0===S.get.selectionCount()?S.set.placeholderText():S.set.text(S.add.variables(T.count))):S.remove.value(i,n,t),t.removeClass(A.filtered).removeClass(A.active),y.useLabels&&t.removeClass(A.selected)})},selectedItem:function(){B.removeClass(A.selected)},value:function(e,t,n){var i,a=S.get.values();S.has.selectInput()?(S.verbose("Input is <select> removing selected option",e),i=S.remove.arrayValue(e,a),S.remove.optionValue(e)):(S.verbose("Removing from delimited values",e),i=S.remove.arrayValue(e,a),i=i.join(y.delimiter)),!1===y.fireOnInit&&S.is.initialLoad()?S.verbose("No callback on initial load",y.onRemove):y.onRemove.call(Y,e,t,n),S.set.value(i,t,n),S.check.maxSelections()},arrayValue:function(t,n){return e.isArray(n)||(n=[n]),n=e.grep(n,function(e){return t!=e}),S.verbose("Removed value from delimited string",t,n),n},label:function(e,t){var n=M.find(R.label),i=n.filter("[data-"+I.value+'="'+S.escape.string(e)+'"]');S.verbose("Removing label",i),i.remove()},activeLabels:function(e){e=e||M.find(R.label).filter("."+A.active),S.verbose("Removing active label selections",e),S.remove.labels(e)},labels:function(t){t=t||M.find(R.label),S.verbose("Removing labels",t),t.each(function(){var t=e(this),n=t.data(I.value),i=void 0!==n?String(n):n,a=S.is.userValue(i);if(!1===y.onLabelRemove.call(t,n))return void S.debug("Label remove callback cancelled removal");S.remove.message(),a?(S.remove.value(i),S.remove.label(i)):S.remove.selected(i)})},tabbable:function(){S.is.searchSelection()?(S.debug("Searchable dropdown initialized"),H.removeAttr("tabindex"),W.removeAttr("tabindex")):(S.debug("Simple selection dropdown initialized"),M.removeAttr("tabindex"),W.removeAttr("tabindex"))}},has:{menuSearch:function(){return S.has.search()&&H.closest(W).length>0},search:function(){return H.length>0},sizer:function(){return j.length>0},selectInput:function(){return N.is("select")},minCharacters:function(e){return!y.minCharacters||(e=void 0!==e?String(e):String(S.get.query()),e.length>=y.minCharacters)},firstLetter:function(e,t){var n,i;return!(!e||0===e.length||"string"!=typeof t)&&(n=S.get.choiceText(e,!1),t=t.toLowerCase(),i=String(n).charAt(0).toLowerCase(),t==i)},input:function(){return N.length>0},items:function(){return B.length>0},menu:function(){return W.length>0},message:function(){return 0!==W.children(R.message).length},label:function(e){var t=S.escape.value(e);return M.find(R.label).filter("[data-"+I.value+'="'+S.escape.string(t)+'"]').length>0},maxSelections:function(){return y.maxSelections&&S.get.selectionCount()>=y.maxSelections},allResultsFiltered:function(){var e=B.not(R.addition);return e.filter(R.unselectable).length===e.length},userSuggestion:function(){return W.children(R.addition).length>0},query:function(){return""!==S.get.query()},value:function(t){var n=S.get.values();return!!(e.isArray(n)?n&&-1!==e.inArray(t,n):n==t)}},is:{active:function(){return M.hasClass(A.active)},bubbledLabelClick:function(t){return e(t.target).is("select, input")&&M.closest("label").length>0},bubbledIconClick:function(t){return e(t.target).closest(U).length>0},alreadySetup:function(){return M.is("select")&&void 0!==M.parent(R.dropdown).data(F)&&0===M.prev().length},animating:function(e){return e?e.transition&&e.transition("is animating"):W.transition&&W.transition("is animating")},leftward:function(e){return(e||W).hasClass(A.leftward)},disabled:function(){return M.hasClass(A.disabled)},focused:function(){return n.activeElement===M[0]},focusedOnSearch:function(){return n.activeElement===H[0]},allFiltered:function(){return(S.is.multiple()||S.has.search())&&!(0==y.hideAdditions&&S.has.userSuggestion())&&!S.has.message()&&S.has.allResultsFiltered()},hidden:function(e){return!S.is.visible(e)},initialLoad:function(){return h},inObject:function(t,n){var i=!1;return e.each(n,function(e,n){if(n==t)return i=!0,!0}),i},multiple:function(){return M.hasClass(A.multiple)},remote:function(){return y.apiSettings&&S.can.useAPI()},single:function(){return!S.is.multiple()},selectMutation:function(t){var n=!1;return e.each(t,function(t,i){if(i.target&&e(i.target).is("select"))return n=!0,!0}),n},search:function(){return M.hasClass(A.search)},searchSelection:function(){return S.has.search()&&1===H.parent(R.dropdown).length},selection:function(){return M.hasClass(A.selection)},userValue:function(t){return-1!==e.inArray(t,S.get.userValues())},upward:function(e){return(e||M).hasClass(A.upward)},visible:function(e){return e?e.hasClass(A.visible):W.hasClass(A.visible)},verticallyScrollableContext:function(){var e=z.get(0)!==t&&z.css("overflow-y");return"auto"==e||"scroll"==e},horizontallyScrollableContext:function(){var e=z.get(0)!==t&&z.css("overflow-X");return"auto"==e||"scroll"==e}},can:{activate:function(e){return!!y.useLabels||(!S.has.maxSelections()||!(!S.has.maxSelections()||!e.hasClass(A.active)))},openDownward:function(e){var t,n=e||W,i=!0,a={};return n.addClass(A.loading),t={context:{scrollTop:z.scrollTop(),height:z.outerHeight()},menu:{offset:n.offset(),height:n.outerHeight()}},S.is.verticallyScrollableContext()&&(t.menu.offset.top+=t.context.scrollTop),a={above:t.context.scrollTop<=t.menu.offset.top-t.menu.height,below:t.context.scrollTop+t.context.height>=t.menu.offset.top+t.menu.height},a.below?(S.verbose("Dropdown can fit in context downward",a),i=!0):a.below||a.above?(S.verbose("Dropdown cannot fit below, opening upward",a),i=!1):(S.verbose("Dropdown cannot fit in either direction, favoring downward",a),i=!0),n.removeClass(A.loading),i},openRightward:function(e){var t,n=e||W,i=!0,a=!1;return n.addClass(A.loading),t={context:{scrollLeft:z.scrollLeft(),width:z.outerWidth()},menu:{offset:n.offset(),width:n.outerWidth()}},S.is.horizontallyScrollableContext()&&(t.menu.offset.left+=t.context.scrollLeft),a=t.menu.offset.left+t.menu.width>=t.context.scrollLeft+t.context.width,a&&(S.verbose("Dropdown cannot fit in context rightward",a),i=!1),n.removeClass(A.loading),i},click:function(){return l||"click"==y.on},extendSelect:function(){return y.allowAdditions||y.apiSettings},show:function(){return!S.is.disabled()&&(S.has.items()||S.has.message())},useAPI:function(){return void 0!==e.fn.api}},animate:{show:function(t,n){var i,a=n||W,o=n?function(){}:function(){S.hideSubMenus(),S.hideOthers(),S.set.active()};t=e.isFunction(t)?t:function(){},S.verbose("Doing menu show animation",a),S.set.direction(n),i=S.get.transition(n),S.is.selection()&&S.set.scrollPosition(S.get.selectedItem(),!0),(S.is.hidden(a)||S.is.animating(a))&&("none"==i?(o(),a.transition("show"),t.call(Y)):void 0!==e.fn.transition&&M.transition("is supported")?a.transition({animation:i+" in",debug:y.debug,verbose:y.verbose,duration:y.duration,queue:!0,onStart:o,onComplete:function(){t.call(Y)}}):S.error(O.noTransition,i))},hide:function(t,n){var i=n||W,a=(n?y.duration:y.duration,n?function(){}:function(){S.can.click()&&S.unbind.intent(),S.remove.active()}),o=S.get.transition(n);t=e.isFunction(t)?t:function(){},(S.is.visible(i)||S.is.animating(i))&&(S.verbose("Doing menu hide animation",i),"none"==o?(a(),i.transition("hide"),t.call(Y)):void 0!==e.fn.transition&&M.transition("is supported")?i.transition({animation:o+" out",duration:y.duration,debug:y.debug,verbose:y.verbose,queue:!0,onStart:a,onComplete:function(){t.call(Y)}}):S.error(O.transition))}},hideAndClear:function(){S.remove.searchTerm(),S.has.maxSelections()||(S.has.search()?S.hide(function(){S.remove.filteredItem()}):S.hide())},delay:{show:function(){S.verbose("Delaying show event to ensure user intent"),clearTimeout(S.timer),S.timer=setTimeout(S.show,y.delay.show)},hide:function(){S.verbose("Delaying hide event to ensure user intent"),clearTimeout(S.timer),S.timer=setTimeout(S.hide,y.delay.hide)}},escape:{value:function(t){var n=e.isArray(t),i="string"==typeof t,a=!i&&!n,o=i&&-1!==t.search(q.quote),s=[];return a||!o?t:(S.debug("Encoding quote values for use in select",t),n?(e.each(t,function(e,t){s.push(t.replace(q.quote,"&quot;"))}),s):t.replace(q.quote,"&quot;"))},string:function(e){return e=String(e),e.replace(q.escape,"\\$&")}},setting:function(t,n){if(S.debug("Changing setting",t,n),e.isPlainObject(t))e.extend(!0,y,t);else{if(void 0===n)return y[t];e.isPlainObject(y[t])?e.extend(!0,y[t],n):y[t]=n}},internal:function(t,n){if(e.isPlainObject(t))e.extend(!0,S,t);else{if(void 0===n)return S[t];S[t]=n}},debug:function(){!y.silent&&y.debug&&(y.performance?S.performance.log(arguments):(S.debug=Function.prototype.bind.call(console.info,console,y.name+":"),S.debug.apply(console,arguments)))},verbose:function(){!y.silent&&y.verbose&&y.debug&&(y.performance?S.performance.log(arguments):(S.verbose=Function.prototype.bind.call(console.info,console,y.name+":"),S.verbose.apply(console,arguments)))},error:function(){y.silent||(S.error=Function.prototype.bind.call(console.error,console,y.name+":"),S.error.apply(console,arguments))},performance:{log:function(e){var t,n,i;y.performance&&(t=(new Date).getTime(),i=c||t,n=t-i,c=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:Y,"Execution Time":n})),clearTimeout(S.performance.timer),S.performance.timer=setTimeout(S.performance.display,500)},display:function(){var t=y.name+":",n=0;c=!1,clearTimeout(S.performance.timer),e.each(u,function(e,t){n+=t["Execution Time"]}),t+=" "+n+"ms",r&&(t+=" '"+r+"'"),(void 0!==console.group||void 0!==console.table)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,n,i){var o,s,r,l=G;return n=n||f,i=Y||i,"string"==typeof t&&void 0!==l&&(t=t.split(/[\. ]/),o=t.length-1,e.each(t,function(n,i){var a=n!=o?i+t[n+1].charAt(0).toUpperCase()+t[n+1].slice(1):t;if(e.isPlainObject(l[a])&&n!=o)l=l[a];else{if(void 0!==l[a])return s=l[a],!1;if(!e.isPlainObject(l[i])||n==o)return void 0!==l[i]?(s=l[i],!1):(S.error(O.method,t),!1);l=l[i]}})),e.isFunction(s)?r=s.apply(i,n):void 0!==s&&(r=s),e.isArray(a)?a.push(r):void 0!==a?a=[a,r]:void 0!==r&&(a=r),s}},v?(void 0===G&&S.initialize(),S.invoke(d)):(void 0!==G&&G.invoke("destroy"),S.initialize())}),void 0!==a?a:o},e.fn.dropdown.settings={silent:!1,debug:!1,verbose:!1,performance:!0,on:"click",action:"activate",values:!1,apiSettings:!1,selectOnKeydown:!0,minCharacters:0,filterRemoteData:!1,saveRemoteData:!0,throttle:200,context:t,direction:"auto",keepOnScreen:!0,match:"both",fullTextSearch:!1,placeholder:"auto",preserveHTML:!0,sortSelect:!1,forceSelection:!0,allowAdditions:!1,hideAdditions:!0,maxSelections:!1,useLabels:!0,delimiter:",",showOnFocus:!0,allowReselection:!1,allowTab:!0,allowCategorySelection:!1,fireOnInit:!1,transition:"auto",duration:200,glyphWidth:1.037,label:{transition:"scale",duration:200,variation:!1},delay:{hide:300,show:200,search:20,touch:50},onChange:function(e,t,n){},onAdd:function(e,t,n){},onRemove:function(e,t,n){},onLabelSelect:function(e){},onLabelCreate:function(t,n){return e(this)},onLabelRemove:function(e){return!0},onNoResults:function(e){return!0},onShow:function(){},onHide:function(){},name:"Dropdown",namespace:"dropdown",message:{addResult:"Add <b>{term}</b>",count:"{count} selected",maxSelections:"Max {maxCount} selections",noResults:"No results found.",serverError:"There was an error contacting the server"},error:{action:"You called a dropdown action that was not defined",alreadySetup:"Once a select has been initialized behaviors must be called on the created ui dropdown",labels:"Allowing user additions currently requires the use of labels.",missingMultiple:"<select> requires multiple property to be set to correctly preserve multiple values",method:"The method you called is not defined.",noAPI:"The API module is required to load resources remotely",noStorage:"Saving remote data requires session storage",noTransition:"This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>"},regExp:{escape:/[-[\]{}()*+?.,\\^$|#\s]/g,quote:/"/g},metadata:{defaultText:"defaultText",defaultValue:"defaultValue",placeholderText:"placeholder",text:"text",value:"value"},fields:{remoteValues:"results",values:"values",disabled:"disabled",name:"name",value:"value",text:"text"},keys:{backspace:8,delimiter:188,deleteKey:46,enter:13,escape:27,pageUp:33,pageDown:34,leftArrow:37,upArrow:38,rightArrow:39,downArrow:40},selector:{addition:".addition",dropdown:".ui.dropdown",hidden:".hidden",icon:"> .dropdown.icon",input:'> input[type="hidden"], > select',item:".item",label:"> .label",remove:"> .label > .delete.icon",siblingLabel:".label",menu:".menu",message:".message",menuIcon:".dropdown.icon",search:"input.search, .menu > .search > input, .menu input.search",sizer:"> input.sizer",text:"> .text:not(.icon)",unselectable:".disabled, .filtered"},className:{active:"active",addition:"addition",animating:"animating",disabled:"disabled",empty:"empty",dropdown:"ui dropdown",filtered:"filtered",hidden:"hidden transition",item:"item",label:"ui label",loading:"loading",menu:"menu",message:"message",multiple:"multiple",placeholder:"default",sizer:"sizer",search:"search",selected:"selected",selection:"selection",upward:"upward",leftward:"left",visible:"visible"}},e.fn.dropdown.settings.templates={dropdown:function(t){var n=t.placeholder||!1,i=(t.values,"");return i+='<i class="dropdown icon"></i>',t.placeholder?i+='<div class="default text">'+n+"</div>":i+='<div class="text"></div>',i+='<div class="menu">',e.each(t.values,function(e,t){i+=t.disabled?'<div class="disabled item" data-value="'+t.value+'">'+t.name+"</div>":'<div class="item" data-value="'+t.value+'">'+t.name+"</div>"}),i+="</div>"},menu:function(t,n){var i=t[n.values]||{},a="";return e.each(i,function(e,t){var i=t[n.text]?'data-text="'+t[n.text]+'"':"",o=t[n.disabled]?"disabled ":"";a+='<div class="'+o+'item" data-value="'+t[n.value]+'"'+i+">",a+=t[n.name],a+="</div>"}),a},label:function(e,t){return t+'<i class="delete icon"></i>'},message:function(e){return e},addition:function(e){return e}}}(jQuery,window,document);
},{}],631:[function(require,module,exports){
/*!
 * # Semantic UI 2.1.7 - Transition
 * http://github.com/semantic-org/semantic-ui/
 *
 *
 * Copyright 2015 Contributors
 * Released under the MIT license
 * http://opensource.org/licenses/MIT
 *
 */
!function(n,e,i,t){"use strict";n.fn.transition=function(){var a,o=n(this),r=o.selector||"",s=(new Date).getTime(),l=[],u=arguments,c=u[0],d=[].slice.call(arguments,1),m="string"==typeof c;e.requestAnimationFrame||e.mozRequestAnimationFrame||e.webkitRequestAnimationFrame||e.msRequestAnimationFrame||function(n){setTimeout(n,0)};return o.each(function(e){var f,p,g,v,b,y,h,w,C,A=n(this),S=this;C={initialize:function(){f=C.get.settings.apply(S,u),v=f.className,g=f.error,b=f.metadata,w="."+f.namespace,h="module-"+f.namespace,p=A.data(h)||C,y=C.get.animationEndEvent(),m&&(m=C.invoke(c)),m===!1&&(C.verbose("Converted arguments into settings object",f),f.interval?C.delay(f.animate):C.animate(),C.instantiate())},instantiate:function(){C.verbose("Storing instance of module",C),p=C,A.data(h,p)},destroy:function(){C.verbose("Destroying previous module for",S),A.removeData(h)},refresh:function(){C.verbose("Refreshing display type on next animation"),delete C.displayType},forceRepaint:function(){C.verbose("Forcing element repaint");var n=A.parent(),e=A.next();0===e.length?A.detach().appendTo(n):A.detach().insertBefore(e)},repaint:function(){C.verbose("Repainting element");S.offsetWidth},delay:function(n){var i,a,r=C.get.animationDirection();r||(r=C.can.transition()?C.get.direction():"static"),n=n!==t?n:f.interval,i="auto"==f.reverse&&r==v.outward,a=i||1==f.reverse?(o.length-e)*f.interval:e*f.interval,C.debug("Delaying animation by",a),setTimeout(C.animate,a)},animate:function(n){if(f=n||f,!C.is.supported())return C.error(g.support),!1;if(C.debug("Preparing animation",f.animation),C.is.animating()){if(f.queue)return!f.allowRepeats&&C.has.direction()&&C.is.occurring()&&C.queuing!==!0?C.debug("Animation is currently occurring, preventing queueing same animation",f.animation):C.queue(f.animation),!1;if(!f.allowRepeats&&C.is.occurring())return C.debug("Animation is already occurring, will not execute repeated animation",f.animation),!1;C.debug("New animation started, completing previous early",f.animation),p.complete()}C.can.animate()?C.set.animating(f.animation):C.error(g.noAnimation,f.animation,S)},reset:function(){C.debug("Resetting animation to beginning conditions"),C.remove.animationCallbacks(),C.restore.conditions(),C.remove.animating()},queue:function(n){C.debug("Queueing animation of",n),C.queuing=!0,A.one(y+".queue"+w,function(){C.queuing=!1,C.repaint(),C.animate.apply(this,f)})},complete:function(n){C.debug("Animation complete",f.animation),C.remove.completeCallback(),C.remove.failSafe(),C.is.looping()||(C.is.outward()?(C.verbose("Animation is outward, hiding element"),C.restore.conditions(),C.hide()):C.is.inward()?(C.verbose("Animation is outward, showing element"),C.restore.conditions(),C.show()):(C.verbose("Static animation completed"),C.restore.conditions(),f.onComplete.call(S)))},force:{visible:function(){var n=A.attr("style"),e=C.get.userStyle(),i=C.get.displayType(),a=e+"display: "+i+" !important;",o=A.css("display"),r=n===t||""===n;o!==i?(C.verbose("Overriding default display to show element",i),A.attr("style",a)):r&&A.removeAttr("style")},hidden:function(){var n=A.attr("style"),e=A.css("display"),i=n===t||""===n;"none"===e||C.is.hidden()?i&&A.removeAttr("style"):(C.verbose("Overriding default display to hide element"),A.css("display","none"))}},has:{direction:function(e){var i=!1;return e=e||f.animation,"string"==typeof e&&(e=e.split(" "),n.each(e,function(n,e){(e===v.inward||e===v.outward)&&(i=!0)})),i},inlineDisplay:function(){var e=A.attr("style")||"";return n.isArray(e.match(/display.*?;/,""))}},set:{animating:function(n){var e;C.remove.completeCallback(),n=n||f.animation,e=C.get.animationClass(n),C.save.animation(e),C.force.visible(),C.remove.hidden(),C.remove.direction(),C.start.animation(e)},duration:function(n,e){e=e||f.duration,e="number"==typeof e?e+"ms":e,(e||0===e)&&(C.verbose("Setting animation duration",e),A.css({"animation-duration":e}))},direction:function(n){n=n||C.get.direction(),n==v.inward?C.set.inward():C.set.outward()},looping:function(){C.debug("Transition set to loop"),A.addClass(v.looping)},hidden:function(){A.addClass(v.transition).addClass(v.hidden)},inward:function(){C.debug("Setting direction to inward"),A.removeClass(v.outward).addClass(v.inward)},outward:function(){C.debug("Setting direction to outward"),A.removeClass(v.inward).addClass(v.outward)},visible:function(){A.addClass(v.transition).addClass(v.visible)}},start:{animation:function(n){n=n||C.get.animationClass(),C.debug("Starting tween",n),A.addClass(n).one(y+".complete"+w,C.complete),f.useFailSafe&&C.add.failSafe(),C.set.duration(f.duration),f.onStart.call(S)}},save:{animation:function(n){C.cache||(C.cache={}),C.cache.animation=n},displayType:function(n){"none"!==n&&A.data(b.displayType,n)},transitionExists:function(e,i){n.fn.transition.exists[e]=i,C.verbose("Saving existence of transition",e,i)}},restore:{conditions:function(){var n=C.get.currentAnimation();n&&(A.removeClass(n),C.verbose("Removing animation class",C.cache)),C.remove.duration()}},add:{failSafe:function(){var n=C.get.duration();C.timer=setTimeout(function(){A.triggerHandler(y)},n+f.failSafeDelay),C.verbose("Adding fail safe timer",C.timer)}},remove:{animating:function(){A.removeClass(v.animating)},animationCallbacks:function(){C.remove.queueCallback(),C.remove.completeCallback()},queueCallback:function(){A.off(".queue"+w)},completeCallback:function(){A.off(".complete"+w)},display:function(){A.css("display","")},direction:function(){A.removeClass(v.inward).removeClass(v.outward)},duration:function(){A.css("animation-duration","")},failSafe:function(){C.verbose("Removing fail safe timer",C.timer),C.timer&&clearTimeout(C.timer)},hidden:function(){A.removeClass(v.hidden)},visible:function(){A.removeClass(v.visible)},looping:function(){C.debug("Transitions are no longer looping"),C.is.looping()&&(C.reset(),A.removeClass(v.looping))},transition:function(){A.removeClass(v.visible).removeClass(v.hidden)}},get:{settings:function(e,i,t){return"object"==typeof e?n.extend(!0,{},n.fn.transition.settings,e):"function"==typeof t?n.extend({},n.fn.transition.settings,{animation:e,onComplete:t,duration:i}):"string"==typeof i||"number"==typeof i?n.extend({},n.fn.transition.settings,{animation:e,duration:i}):"object"==typeof i?n.extend({},n.fn.transition.settings,i,{animation:e}):"function"==typeof i?n.extend({},n.fn.transition.settings,{animation:e,onComplete:i}):n.extend({},n.fn.transition.settings,{animation:e})},animationClass:function(n){var e=n||f.animation,i=C.can.transition()&&!C.has.direction()?C.get.direction()+" ":"";return v.animating+" "+v.transition+" "+i+e},currentAnimation:function(){return C.cache&&C.cache.animation!==t?C.cache.animation:!1},currentDirection:function(){return C.is.inward()?v.inward:v.outward},direction:function(){return C.is.hidden()||!C.is.visible()?v.inward:v.outward},animationDirection:function(e){var i;return e=e||f.animation,"string"==typeof e&&(e=e.split(" "),n.each(e,function(n,e){e===v.inward?i=v.inward:e===v.outward&&(i=v.outward)})),i?i:!1},duration:function(n){return n=n||f.duration,n===!1&&(n=A.css("animation-duration")||0),"string"==typeof n?n.indexOf("ms")>-1?parseFloat(n):1e3*parseFloat(n):n},displayType:function(){return f.displayType?f.displayType:(A.data(b.displayType)===t&&C.can.transition(!0),A.data(b.displayType))},userStyle:function(n){return n=n||A.attr("style")||"",n.replace(/display.*?;/,"")},transitionExists:function(e){return n.fn.transition.exists[e]},animationStartEvent:function(){var n,e=i.createElement("div"),a={animation:"animationstart",OAnimation:"oAnimationStart",MozAnimation:"mozAnimationStart",WebkitAnimation:"webkitAnimationStart"};for(n in a)if(e.style[n]!==t)return a[n];return!1},animationEndEvent:function(){var n,e=i.createElement("div"),a={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"mozAnimationEnd",WebkitAnimation:"webkitAnimationEnd"};for(n in a)if(e.style[n]!==t)return a[n];return!1}},can:{transition:function(e){var i,a,o,r,s,l,u,c=f.animation,d=C.get.transitionExists(c);if(d===t||e){if(C.verbose("Determining whether animation exists"),i=A.attr("class"),a=A.prop("tagName"),o=n("<"+a+" />").addClass(i).insertAfter(A),r=o.addClass(c).removeClass(v.inward).removeClass(v.outward).addClass(v.animating).addClass(v.transition).css("animationName"),s=o.addClass(v.inward).css("animationName"),u=o.attr("class",i).removeAttr("style").removeClass(v.hidden).removeClass(v.visible).show().css("display"),C.verbose("Determining final display state",u),C.save.displayType(u),o.remove(),r!=s)C.debug("Direction exists for animation",c),l=!0;else{if("none"==r||!r)return void C.debug("No animation defined in css",c);C.debug("Static animation found",c,u),l=!1}C.save.transitionExists(c,l)}return d!==t?d:l},animate:function(){return C.can.transition()!==t}},is:{animating:function(){return A.hasClass(v.animating)},inward:function(){return A.hasClass(v.inward)},outward:function(){return A.hasClass(v.outward)},looping:function(){return A.hasClass(v.looping)},occurring:function(n){return n=n||f.animation,n="."+n.replace(" ","."),A.filter(n).length>0},visible:function(){return A.is(":visible")},hidden:function(){return"hidden"===A.css("visibility")},supported:function(){return y!==!1}},hide:function(){C.verbose("Hiding element"),C.is.animating()&&C.reset(),S.blur(),C.remove.display(),C.remove.visible(),C.set.hidden(),C.force.hidden(),f.onHide.call(S),f.onComplete.call(S)},show:function(n){C.verbose("Showing element",n),C.remove.hidden(),C.set.visible(),C.force.visible(),f.onShow.call(S),f.onComplete.call(S)},toggle:function(){C.is.visible()?C.hide():C.show()},stop:function(){C.debug("Stopping current animation"),A.triggerHandler(y)},stopAll:function(){C.debug("Stopping all animation"),C.remove.queueCallback(),A.triggerHandler(y)},clear:{queue:function(){C.debug("Clearing animation queue"),C.remove.queueCallback()}},enable:function(){C.verbose("Starting animation"),A.removeClass(v.disabled)},disable:function(){C.debug("Stopping animation"),A.addClass(v.disabled)},setting:function(e,i){if(C.debug("Changing setting",e,i),n.isPlainObject(e))n.extend(!0,f,e);else{if(i===t)return f[e];f[e]=i}},internal:function(e,i){if(n.isPlainObject(e))n.extend(!0,C,e);else{if(i===t)return C[e];C[e]=i}},debug:function(){f.debug&&(f.performance?C.performance.log(arguments):(C.debug=Function.prototype.bind.call(console.info,console,f.name+":"),C.debug.apply(console,arguments)))},verbose:function(){f.verbose&&f.debug&&(f.performance?C.performance.log(arguments):(C.verbose=Function.prototype.bind.call(console.info,console,f.name+":"),C.verbose.apply(console,arguments)))},error:function(){C.error=Function.prototype.bind.call(console.error,console,f.name+":"),C.error.apply(console,arguments)},performance:{log:function(n){var e,i,t;f.performance&&(e=(new Date).getTime(),t=s||e,i=e-t,s=e,l.push({Name:n[0],Arguments:[].slice.call(n,1)||"",Element:S,"Execution Time":i})),clearTimeout(C.performance.timer),C.performance.timer=setTimeout(C.performance.display,500)},display:function(){var e=f.name+":",i=0;s=!1,clearTimeout(C.performance.timer),n.each(l,function(n,e){i+=e["Execution Time"]}),e+=" "+i+"ms",r&&(e+=" '"+r+"'"),o.length>1&&(e+=" ("+o.length+")"),(console.group!==t||console.table!==t)&&l.length>0&&(console.groupCollapsed(e),console.table?console.table(l):n.each(l,function(n,e){console.log(e.Name+": "+e["Execution Time"]+"ms")}),console.groupEnd()),l=[]}},invoke:function(e,i,o){var r,s,l,u=p;return i=i||d,o=S||o,"string"==typeof e&&u!==t&&(e=e.split(/[\. ]/),r=e.length-1,n.each(e,function(i,a){var o=i!=r?a+e[i+1].charAt(0).toUpperCase()+e[i+1].slice(1):e;if(n.isPlainObject(u[o])&&i!=r)u=u[o];else{if(u[o]!==t)return s=u[o],!1;if(!n.isPlainObject(u[a])||i==r)return u[a]!==t?(s=u[a],!1):!1;u=u[a]}})),n.isFunction(s)?l=s.apply(o,i):s!==t&&(l=s),n.isArray(a)?a.push(l):a!==t?a=[a,l]:l!==t&&(a=l),s!==t?s:!1}},C.initialize()}),a!==t?a:this},n.fn.transition.exists={},n.fn.transition.settings={name:"Transition",debug:!1,verbose:!1,performance:!0,namespace:"transition",interval:0,reverse:"auto",onStart:function(){},onComplete:function(){},onShow:function(){},onHide:function(){},useFailSafe:!0,failSafeDelay:100,allowRepeats:!1,displayType:!1,animation:"fade",duration:!1,queue:!0,metadata:{displayType:"display"},className:{animating:"animating",disabled:"disabled",hidden:"hidden",inward:"in",loading:"loading",looping:"looping",outward:"out",transition:"transition",visible:"visible"},error:{noAnimation:"Element is no longer attached to DOM. Unable to animate.",repeated:"That animation is already occurring, cancelling repeated animation",method:"The method you called is not defined",support:"This browser does not support CSS animations"}}}(jQuery,window,document);
},{}],632:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['toggleFilter', 'clearFilters', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],633:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiCart_api = require('../_api/cart_api');

var _apiCart_api2 = _interopRequireDefault(_apiCart_api);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var CartActions = _reflux2['default'].createActions({
  'loadCart': {
    children: ['completed', 'failed']
  },
  'updateCartItem': {},
  'deleteCartItem': {},
  'clearCart': {},
  'addCartItem': {},
  'addCartItems': {},
  'quickBuy': {},
  'quickBuyItems': {}
});

CartActions.loadCart.listen(function (onMount) {
  _apiCart_api2['default'].cartitems().then(function (response) {
    CartActions.loadCart.completed(response);
    if (onMount) {
      var cart = JSON.parse(JSON.stringify(response));
      _libCustomEvents2['default'].loadCartEvent(cart);
    }
  })['catch'](CartActions.loadCart.failed);
});

CartActions.updateCartItem.listen(function (skuId, quantity) {
  _apiCart_api2['default'].updatecartitem(skuId, quantity).then(function (response) {
    CartActions.loadCart.completed(response, skuId);
    var cart = JSON.parse(JSON.stringify(response));
    _libCustomEvents2['default'].modifyCartEvent(cart);
  })
  // .then(CartActions.loadCart.completed)
  ['catch'](function (response) {
    CartActions.loadCart.failed(skuId);
  });
});

CartActions.deleteCartItem.listen(function (args) {
  _apiCart_api2['default'].deletecartitem(args).then(function (response) {
    CartActions.loadCart.completed(response);
    var deleteItem = JSON.parse(JSON.stringify(response));
    _libCustomEvents2['default'].deleteCartEvent(deleteItem);
  })['catch'](CartActions.loadCart.failed);
});

CartActions.clearCart.listen(function () {
  _apiCart_api2['default'].clearcart().then(CartActions.loadCart.completed)['catch'](function (response) {
    _apiCart_api2['default'].cartitems().then(CartActions.loadCart.completed)['catch'](CartActions.loadCart.failed);
  });
});

CartActions.addCartItem.listen(function (skuId, quantity, productContext) {
  _apiCart_api2['default'].addCartItem(skuId, quantity).then(function (response) {
    CartActions.loadCart.completed(response);
    var added = JSON.parse(JSON.stringify(response.Added));
    var cart = JSON.parse(JSON.stringify(response.Cart));
    triggerAddToCartEvent(added, cart, productContext);
  })['catch'](function (response) {
    CartActions.loadCart.failed(response, skuId);
  });
  // .catch(CartActions.loadCart.failed);
});

CartActions.addCartItems.listen(function (items) {
  _apiCart_api2['default'].addCartItems(items).then(function (response) {
    CartActions.loadCart.completed(response);
    var added = JSON.parse(JSON.stringify(response.Added));
    var cart = JSON.parse(JSON.stringify(response.Cart));
    _libCustomEvents2['default'].triggerAddToCartBatchEvent(added, cart);
  })['catch'](function () {
    CartActions.loadCart.failed();
  });
});
CartActions.quickBuy.listen(function (skuId, quantity, productContext) {
  _apiCart_api2['default'].addCartItem(skuId, quantity).then(function (response) {
    window.location.href = hiabconfig.quickbuy.url;
    var added = JSON.parse(JSON.stringify(response.Added));
    var cart = JSON.parse(JSON.stringify(response.Cart));
    triggerAddToCartEvent(added, cart, productContext);
  })['catch'](function (response) {
    CartActions.loadCart.failed(response, skuId);
  });
});
CartActions.quickBuyItems.listen(function (items) {
  _apiCart_api2['default'].addCartItems(items, true).then(function (response) {
    window.location.href = hiabconfig.quickbuy.url;
    var added = JSON.parse(JSON.stringify(response.Added));
    var cart = JSON.parse(JSON.stringify(response.Cart));
    _libCustomEvents2['default'].triggerQuickBuyBatchEvent(added, cart);
  })['catch'](CartActions.loadCart.failed);
});

// The list of added products that is returned when adding to cart does not contain
// any product information. Get details from the list of all cart items, but retain
// the quantity from `addedItems`
function getAddedProducts(addedItems, allItems) {
  return addedItems.map(function (addedItem) {
    var sameItemFromAllItems = allItems.filter(function (x) {
      return x.Code == addedItem.Code;
    }).pop();
    sameItemFromAllItems.Quantity = addedItem.Quantity;
    sameItemFromAllItems.OldQuantity = addedItem.OldQuantity;
    sameItemFromAllItems.Updated = addedItem.Updated;

    return sameItemFromAllItems;
  });
}

function formatProductsForDataLayer(products) {
  return products.map(function (p) {
    return {
      'name': p.DisplayName,
      'id': p.Code,
      'price': p.RawPrice,
      'quantity': p.Quantity
    };
  });
}

function triggerAddToCartEvent(addedItems, cart, productContext) {
  if (typeof window.dataLayer === 'undefined' && !hiabconfig.EnableGoogleTagManager) return false;
  var products = getAddedProducts(addedItems, cart.CartItems);
  window.dataLayer.push({
    'event': 'addToCart',
    'ecommerce': {
      'currencyCode': cart.CurrencyCode,
      'add': formatProductsForDataLayer(products)
    }
  });

  _libCustomEvents2['default'].addToCartEvent(products, cart, productContext);
}

exports['default'] = CartActions;
module.exports = exports['default'];

},{"../_api/cart_api":652,"../_lib/custom-events":671,"reflux":542}],634:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['toggleFilter', 'clearFilters', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],635:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiCheckout_api = require('../_api/checkout_api');

var _apiCheckout_api2 = _interopRequireDefault(_apiCheckout_api);

var _cart_actions = require('./cart_actions');

var _cart_actions2 = _interopRequireDefault(_cart_actions);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var CheckoutActions = _reflux2['default'].createActions({
  'loadCheckout': {
    children: ['completed', 'failed']
  },
  'updateCheckoutCartItem': {},
  'deleteCheckoutCartItem': {},
  'updateCheckoutCartItemCustomerComment': {},
  'updateShippingOptionOrPriority': {},
  // 'updateShippingOption': {},
  'updateCountryCode': {}
});

CheckoutActions.loadCheckout.listen(function (args) {
  _apiCheckout_api2['default'].getCheckout(args).then(CheckoutActions.loadCheckout.completed)['catch'](CheckoutActions.loadCheckout.failed);
});

CheckoutActions.updateCheckoutCartItem.listen(function (skuId, quantity) {
  _apiCheckout_api2['default'].updateCartItemQuantity(skuId, quantity).then(function (res) {
    //Load checkout
    CheckoutActions.loadCheckout.completed(res);

    //Trigger load cart
    _cart_actions2['default'].loadCart();
    var checkout = JSON.parse(JSON.stringify(res));
    _libCustomEvents2['default'].modifyCartEventFromCheckout(checkout);
  })['catch'](CheckoutActions.loadCheckout.failed);
});

CheckoutActions.deleteCheckoutCartItem.listen(function (args) {
  _apiCheckout_api2['default'].deleteCartItem(args).then(function (res) {
    //Load checkout
    CheckoutActions.loadCheckout.completed(res);

    //Trigger load cart
    _cart_actions2['default'].loadCart();
    var checkout = JSON.parse(JSON.stringify(res));
    _libCustomEvents2['default'].modifyCartEventFromCheckout(checkout);
  })['catch'](CheckoutActions.loadCheckout.failed);
});

CheckoutActions.updateCheckoutCartItemCustomerComment.listen(function (id, comment) {
  _apiCheckout_api2['default'].updateCartItemCustomerComment(id, comment).then(CheckoutActions.loadCheckout.completed)['catch'](CheckoutActions.loadCheckout.failed);
});

CheckoutActions.updateShippingOptionOrPriority.listen(function (data) {
  _apiCheckout_api2['default'].updateShippingOptionOrPriority(data).then(function (res) {
    //Load checkout
    CheckoutActions.loadCheckout.completed(res);

    //Trigger load cart
    _cart_actions2['default'].loadCart();
  })['catch'](CheckoutActions.loadCheckout.failed);
});

CheckoutActions.updateCountryCode.listen(function (code) {
  _apiCheckout_api2['default'].updateCountryCode(code).then(function (res) {
    //Load checkout
    CheckoutActions.loadCheckout.completed(res);

    //Trigger load cart
    _cart_actions2['default'].loadCart();
  })['catch'](CheckoutActions.loadCheckout.failed);
});

exports['default'] = CheckoutActions;
module.exports = exports['default'];

},{"../_api/checkout_api":654,"../_lib/custom-events":671,"./cart_actions":633,"reflux":542}],636:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiCheckout_apiNew = require('../_api/checkout_api-new');

var _apiCheckout_apiNew2 = _interopRequireDefault(_apiCheckout_apiNew);

var _cart_actions = require('./cart_actions');

var _cart_actions2 = _interopRequireDefault(_cart_actions);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var _storesCheckout_cart_store = require('../_stores/checkout_cart_store');

var _storesCheckout_cart_store2 = _interopRequireDefault(_storesCheckout_cart_store);

var _storesCheckout_cart_total_store = require('../_stores/checkout_cart_total_store');

var _storesCheckout_cart_total_store2 = _interopRequireDefault(_storesCheckout_cart_total_store);

var _storesCheckout_cart_alert_store = require('../_stores/checkout_cart_alert_store');

var _storesCheckout_cart_alert_store2 = _interopRequireDefault(_storesCheckout_cart_alert_store);

var _storesCheckout_cart_warning_store = require('../_stores/checkout_cart_warning_store');

var _storesCheckout_cart_warning_store2 = _interopRequireDefault(_storesCheckout_cart_warning_store);

var _storesCheckout_dangerous_goods_alert_store = require('../_stores/checkout_dangerous_goods_alert_store');

var _storesCheckout_dangerous_goods_alert_store2 = _interopRequireDefault(_storesCheckout_dangerous_goods_alert_store);

var _storesCheckout_shipping_store = require('../_stores/checkout_shipping_store');

var _storesCheckout_shipping_store2 = _interopRequireDefault(_storesCheckout_shipping_store);

var _storesCheckout_addresses_store = require('../_stores/checkout_addresses_store');

var _storesCheckout_addresses_store2 = _interopRequireDefault(_storesCheckout_addresses_store);

var _storesCheckout_billing_store = require('../_stores/checkout_billing_store');

var _storesCheckout_billing_store2 = _interopRequireDefault(_storesCheckout_billing_store);

var _storesCheckout_addresses_alert_store = require('../_stores/checkout_addresses_alert_store');

var _storesCheckout_addresses_alert_store2 = _interopRequireDefault(_storesCheckout_addresses_alert_store);

var _storesCheckout_summary_store = require('../_stores/checkout_summary_store');

var _storesCheckout_summary_store2 = _interopRequireDefault(_storesCheckout_summary_store);

var _storesCheckout_tracking_data_store = require('../_stores/checkout_tracking_data_store');

var _storesCheckout_tracking_data_store2 = _interopRequireDefault(_storesCheckout_tracking_data_store);

var _storesCheckout_loading_store = require('../_stores/checkout_loading_store');

var _storesCheckout_loading_store2 = _interopRequireDefault(_storesCheckout_loading_store);

var _storesCheckout_order_simulation_store = require('../_stores/checkout_order_simulation_store');

var _storesCheckout_order_simulation_store2 = _interopRequireDefault(_storesCheckout_order_simulation_store);

var CheckoutActions = _reflux2['default'].createActions({
	'loadCheckout': {
		children: ['completed', 'failed']
	},
	'setCheckout': {},
	'updateCheckoutCartItem': {},
	'deleteCheckoutCartItem': {},
	'updateCheckoutCartItemCustomerComment': {},
	'updateShippingOptionOrPriority': {},
	// 'updateShippingOption': {},
	'changeShippingAddress': {},
	'changeBillingAddress': {},
	'updateCountryCode': {},
	'simulateOrder': {}

});

CheckoutActions.loadCheckout.listen(function (args) {
	_apiCheckout_apiNew2['default'].getCheckout(args).then(function (res) {})['catch'](function (res) {
		//console.log(res);
	});
});

CheckoutActions.setCheckout.listen(function (res) {
	//console.log(res);
	if (res.Success) {
		_storesCheckout_loading_store2['default'].setStore(false);
	} else {
		//has error
		_storesCheckout_loading_store2['default'].setStore(false);
		// console.log("error");
		location.reload(true); // reload page from server
	}
	if (res.ok) {
		//Has error
		_storesCheckout_loading_store2['default'].setStore(false);
	}
	if (res.CheckoutHtml) {
		var CheckoutHtmlRes = res.CheckoutHtml;
		//CART
		if (CheckoutHtmlRes.CartLineItems) {
			_storesCheckout_cart_store2['default'].setStore(CheckoutHtmlRes.CartLineItems);
		}
		if (CheckoutHtmlRes.CartTotal) {
			_storesCheckout_cart_total_store2['default'].setStore(CheckoutHtmlRes.CartTotal);
		}

		if (CheckoutHtmlRes.CartAlert) {
			_storesCheckout_cart_alert_store2['default'].setStore(CheckoutHtmlRes.CartAlert);
		} else {
			_storesCheckout_cart_alert_store2['default'].setStore('');
		}

		if (CheckoutHtmlRes.CartWarnings) {
			_storesCheckout_cart_warning_store2['default'].setStore(CheckoutHtmlRes.CartWarnings);
		} else {
			_storesCheckout_cart_warning_store2['default'].setStore('');
		}

		//DANGEROUS GODS
		if (CheckoutHtmlRes.SpecialShippingHandling) {
			_storesCheckout_dangerous_goods_alert_store2['default'].setStore(CheckoutHtmlRes.SpecialShippingHandling);
		} else {
			_storesCheckout_dangerous_goods_alert_store2['default'].setStore('');
		}
		//SHIPPING
		if (CheckoutHtmlRes.ShippingAddresses) {
			_storesCheckout_addresses_store2['default'].setStore(CheckoutHtmlRes.ShippingAddresses);
		}
		if (CheckoutHtmlRes.BillingInformation) {
			_storesCheckout_billing_store2['default'].setStore(CheckoutHtmlRes.BillingInformation);
		}
		if (CheckoutHtmlRes.ShippingAddressesAlert) {
			_storesCheckout_addresses_alert_store2['default'].setStore(CheckoutHtmlRes.ShippingAddressesAlert);
		} else {
			_storesCheckout_addresses_alert_store2['default'].setStore("");
		}
		if (CheckoutHtmlRes.ShippingOptions) {
			_storesCheckout_shipping_store2['default'].setStore(CheckoutHtmlRes.ShippingOptions);
		}
		if (CheckoutHtmlRes.CheckoutSummary) {
			_storesCheckout_summary_store2['default'].setStore(CheckoutHtmlRes.CheckoutSummary);
		}
		if (CheckoutHtmlRes.TrackingData) {
			_storesCheckout_tracking_data_store2['default'].setStore(CheckoutHtmlRes.TrackingData);
		}
	}
});
//New
CheckoutActions.updateCheckoutCartItem.listen(function (skuId, quantity, upgraded) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].updateCartItem(skuId, quantity, upgraded).then(function (res) {
		CheckoutActions.setCheckout(res);
		_libCustomEvents2['default'].modifyCartEventFromCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});

CheckoutActions.deleteCheckoutCartItem.listen(function (skuId) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].deleteCartItem(skuId).then(function (res) {
		CheckoutActions.setCheckout(res);
		_libCustomEvents2['default'].modifyCartEventFromCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});

CheckoutActions.updateShippingOptionOrPriority.listen(function (data) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].updateShippingOptionOrPriority(data).then(function (res) {
		CheckoutActions.setCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});

//NEW
CheckoutActions.changeShippingAddress.listen(function (id) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].loadShippingAddress(id).then(function (res) {
		CheckoutActions.setCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});
CheckoutActions.changeBillingAddress.listen(function (id) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].loadBillingAddress(id).then(function (res) {
		CheckoutActions.setCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});

CheckoutActions.updateCountryCode.listen(function (shippingAddress) {
	_storesCheckout_loading_store2['default'].setStore(true);
	_apiCheckout_apiNew2['default'].updateCountryCode(shippingAddress).then(function (res) {
		CheckoutActions.setCheckout(res);
	})['catch'](function (res) {
		CheckoutActions.setCheckout(res);
	});
});

CheckoutActions.simulateOrder.listen(function (token, addresses, cost) {
	_storesCheckout_loading_store2['default'].setStore(true);

	_apiCheckout_apiNew2['default'].orderSimulation(token, addresses, cost).then(function (res) {
		_storesCheckout_order_simulation_store2['default'].setStore(res);
		_storesCheckout_loading_store2['default'].setStore(false);
	})['catch'](function (res) {
		_storesCheckout_order_simulation_store2['default'].setStore(res);
		_storesCheckout_loading_store2['default'].setStore(false);
	});
});

exports['default'] = CheckoutActions;
module.exports = exports['default'];

},{"../_api/checkout_api-new":653,"../_lib/custom-events":671,"../_stores/checkout_addresses_alert_store":701,"../_stores/checkout_addresses_store":702,"../_stores/checkout_billing_store":703,"../_stores/checkout_cart_alert_store":704,"../_stores/checkout_cart_store":705,"../_stores/checkout_cart_total_store":706,"../_stores/checkout_cart_warning_store":707,"../_stores/checkout_dangerous_goods_alert_store":708,"../_stores/checkout_loading_store":709,"../_stores/checkout_order_simulation_store":710,"../_stores/checkout_shipping_store":711,"../_stores/checkout_summary_store":713,"../_stores/checkout_tracking_data_store":714,"./cart_actions":633,"reflux":542}],637:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var HistoryActions = _reflux2['default'].createActions({
  'storeUpdated': {}
});

HistoryActions.storeUpdated.listen(function (args) {});

exports['default'] = HistoryActions;
module.exports = exports['default'];

},{"reflux":542}],638:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiIllustration_api = require('../_api/illustration_api');

var _apiIllustration_api2 = _interopRequireDefault(_apiIllustration_api);

var _apiIllustrationForOverlay_api = require('../_api/illustrationForOverlay_api');

var _apiIllustrationForOverlay_api2 = _interopRequireDefault(_apiIllustrationForOverlay_api);

var IllustrationActions = _reflux2['default'].createActions({
  'loadIllustration': {
    children: ['completed', 'failed']
  },
  'loadIllustrationForOverlay': {
    children: ['completed', 'failed']
  }
});

IllustrationActions.loadIllustration.listen(function (illustrationId, modelId) {
  // console.log(illustrationId+' '+modelId);
  _apiIllustration_api2['default'].getIllustration(illustrationId, modelId).then(IllustrationActions.loadIllustration.completed)['catch'](IllustrationActions.loadIllustration.failed);
});

IllustrationActions.loadIllustrationForOverlay.listen(function (args, nodeType) {
  _apiIllustrationForOverlay_api2['default'].getIllustration(args, nodeType).then(IllustrationActions.loadIllustrationForOverlay.completed)['catch'](IllustrationActions.loadIllustrationForOverlay.failed);
});

exports['default'] = IllustrationActions;
module.exports = exports['default'];

},{"../_api/illustrationForOverlay_api":655,"../_api/illustration_api":656,"reflux":542}],639:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiModelsearch_api = require('../_api/modelsearch_api');

var _apiModelsearch_api2 = _interopRequireDefault(_apiModelsearch_api);

var ModelSearchActions = _reflux2['default'].createActions({
  'loadModel': {
    children: ['completed', 'failed']
  }
});

ModelSearchActions.loadModel.listen(function (args) {
  _apiModelsearch_api2['default'].search(args).then(ModelSearchActions.loadModel.completed)['catch'](ModelSearchActions.loadModel.failed);
});

exports['default'] = ModelSearchActions;
module.exports = exports['default'];

},{"../_api/modelsearch_api":658,"reflux":542}],640:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _storesOrderlines_store = require('../_stores/orderlines_store');

var _storesOrderlines_store2 = _interopRequireDefault(_storesOrderlines_store);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var OrderLinesActions = _reflux2['default'].createActions({
	'add': {},
	'clear': {},
	'removeOrderLine': {}
});

OrderLinesActions.add.listen(function (id, orderline) {
	_storesOrderlines_store2['default'].add(id, orderline);
	_libCustomEvents2['default'].batchAddRow(orderline);
});

OrderLinesActions.clear.listen(function () {
	_storesOrderlines_store2['default'].clear();
});

OrderLinesActions.removeOrderLine.listen(function (id) {
	_storesOrderlines_store2['default'].removeOrderLine(id);
	_libCustomEvents2['default'].batchRemoveRow(id);
});

exports['default'] = OrderLinesActions;
module.exports = exports['default'];

},{"../_lib/custom-events":671,"../_stores/orderlines_store":722,"reflux":542}],641:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

var _storesPrice_service_storeJs = require('../_stores/price_service_store.js');

var _storesPrice_service_storeJs2 = _interopRequireDefault(_storesPrice_service_storeJs);

var PriceServiceActions = _reflux2['default'].createActions({
	'addMaterials': {},
	'abortFetchPrices': {},
	'fetchPrices': {}
});

var materialToRequest = [];
var currentRequest = null;

PriceServiceActions.addMaterials.listen(function (material) {
	materialToRequest.push(material);
});

function loopVariants(allMaterials, batchSize) {
	if (allMaterials.length > batchSize * 5) batchSize = Math.ceil(allMaterials.length / 5);

	var materialBatch = [];
	for (var i = 0; i < batchSize; i++) {
		materialBatch.push(allMaterials.shift());
		if (materialBatch.length == batchSize || allMaterials.length === 0) {
			makeAjaxCall(materialBatch);
			if (allMaterials.length > 0) {
				loopVariants(allMaterials, batchSize);
			}
		}
		if (allMaterials.length <= 0) {
			break;
		}
	}
}

function makeAjaxCall(materials) {

	if (materials.length <= 0) {
		return;
	}
	return new _promise2['default'](function (resolve, reject) {
		var url = '/api/productinformation/productinfo?codes=' + materials.join("&codes=") + '';
		currentRequest = _superagent2['default'].get(url).set('Accept', 'application/json').set('credentials', 'same-origin').end(function (error, response) {
			if (response.body) {
				resolve(response.body);
				_storesPrice_service_storeJs2['default'].addPrices(response.body);
			} else {
				reject('Error');
				_storesPrice_service_storeJs2['default'].handleError(materials);
			}
		});
	});
}

PriceServiceActions.fetchPrices.listen(function (batchSize) {
	// console.log('fetchPrices');
	if (materialToRequest.length > 0) {
		loopVariants(materialToRequest, batchSize);
		// console.log('fetchPrices-3');
	}
});

PriceServiceActions.abortFetchPrices.listen(function () {
	currentRequest.abort();
});
exports['default'] = PriceServiceActions;
module.exports = exports['default'];

},{"../_stores/price_service_store.js":723,"promise":335,"reflux":542,"superagent":547}],642:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['toggleFilter', 'onClearFilters', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],643:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var _apiSalesforce_recommendations_api = require('../_api/salesforce_recommendations_api');

var _apiSalesforce_recommendations_api2 = _interopRequireDefault(_apiSalesforce_recommendations_api);

var _salesforcerecommendationsList = require('../salesforcerecommendations/list');

var _salesforcerecommendationsList2 = _interopRequireDefault(_salesforcerecommendationsList);

var _salesforcerecommendationsSlider = require('../salesforcerecommendations/slider');

var _salesforcerecommendationsSlider2 = _interopRequireDefault(_salesforcerecommendationsSlider);

var RecommendationsActions = _reflux2['default'].createActions({
  'loadRecommendations': {
    children: ['completed', 'failed']
  },
  'renderRecommendations': {}
});

RecommendationsActions.loadRecommendations.listen(function (recommendationRequest) {
  _apiSalesforce_recommendations_api2['default'].fetchRecommendations(recommendationRequest).then(function (response) {
    RecommendationsActions.renderRecommendations(response);
    RecommendationsActions.loadRecommendations.completed(response);
  })['catch'](RecommendationsActions.loadRecommendations.failed);
});

RecommendationsActions.renderRecommendations.listen(function (response) {
  if (response == null) {
    return;
  }
  if (response.Recommendations == null) {
    $(".product-recommendations." + response.Id).hide();
    return;
  }
  if (response.BlockStyle == 'list' || response.BlockStyle == 'list-collapsed') {
    $("#" + response.Id).each(function () {
      ReactDOM.render(React.createElement(_salesforcerecommendationsList2['default'], { response: response }), this);
      if (response.BlockStyle == 'list-collapsed' && response.Recommendations.length === 1) {
        $(".product-recommendations." + response.Id + " .collapse-wrapper.row").hide();
      }
    });
  } else if (response.BlockStyle == 'slider' || response.BlockStyle == 'condensed-slider') {
    $("#" + response.Id).each(function () {
      $('#' + response.Id).removeClass('load-skeleton-slider');
      ReactDOM.render(React.createElement(_salesforcerecommendationsSlider2['default'], { response: response }), this);
    });
  }
});

exports['default'] = RecommendationsActions;
module.exports = exports['default'];

},{"../_api/salesforce_recommendations_api":660,"../_lib/custom-events":671,"../salesforcerecommendations/list":810,"../salesforcerecommendations/slider":814,"reflux":542}],644:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _actionsBrand_filter_actions = require('../_actions/brand_filter_actions');

var _actionsBrand_filter_actions2 = _interopRequireDefault(_actionsBrand_filter_actions);

var _actionsUsage_type_filter_actions = require('../_actions/usage_type_filter_actions');

var _actionsUsage_type_filter_actions2 = _interopRequireDefault(_actionsUsage_type_filter_actions);

var _actionsCategory_filter_actions = require('../_actions/category_filter_actions');

var _actionsCategory_filter_actions2 = _interopRequireDefault(_actionsCategory_filter_actions);

var _actionsTop_category_filter_actions = require('../_actions/top_category_filter_actions');

var _actionsTop_category_filter_actions2 = _interopRequireDefault(_actionsTop_category_filter_actions);

var _actionsProduct_line_filter_actions = require('../_actions/product_line_filter_actions');

var _actionsProduct_line_filter_actions2 = _interopRequireDefault(_actionsProduct_line_filter_actions);

var _actionsSerial_number_filter_actions = require('../_actions/serial_number_filter_actions');

var _actionsSerial_number_filter_actions2 = _interopRequireDefault(_actionsSerial_number_filter_actions);

var _storesBrand_filter_store = require('../_stores/brand_filter_store');

var _storesBrand_filter_store2 = _interopRequireDefault(_storesBrand_filter_store);

var _storesUsage_type_filter_store = require('../_stores/usage_type_filter_store');

var _storesUsage_type_filter_store2 = _interopRequireDefault(_storesUsage_type_filter_store);

var _storesCategory_filter_store = require('../_stores/category_filter_store');

var _storesCategory_filter_store2 = _interopRequireDefault(_storesCategory_filter_store);

var _libCustomSearchEvents = require('../_lib/custom-search-events');

var _libCustomSearchEvents2 = _interopRequireDefault(_libCustomSearchEvents);

var _storesTop_category_filter_store = require('../_stores/top_category_filter_store');

var _storesTop_category_filter_store2 = _interopRequireDefault(_storesTop_category_filter_store);

var _storesProduct_line_filter_store = require('../_stores/product_line_filter_store');

var _storesProduct_line_filter_store2 = _interopRequireDefault(_storesProduct_line_filter_store);

var _storesSerial_number_filter_store = require('../_stores/serial_number_filter_store');

var _storesSerial_number_filter_store2 = _interopRequireDefault(_storesSerial_number_filter_store);

var waitingForAnotherCheck = 1000;
var filterTimer = null;
var currentRequest = null;

var SearchActions = _reflux2['default'].createActions({
  invalidate: { children: ['completed', 'failed'] },
  invalidateSpareParts: { children: ['completed', 'failed'] },
  loadNextPage: { children: ['completed', 'failed'] },
  setQuery: {},
  setQueryToUrl: {}
});

var fetchSearchResults = function fetchSearchResults(baseUrl, searchOptions) {
  return new Promise(function (resolve, reject) {
    if (currentRequest != null) {
      currentRequest.abort();
    }
    // console.log(searchOptions);
    searchOptions['epsLanguage'] = hiabconfig.preferredCulture;
    currentRequest = _superagent2['default'].get(baseUrl).set('X-Requested-With', 'XMLHttpRequest').query(searchOptions).end(function (err, res) {
      currentRequest = null;
      if (!err && res.body) {
        resolve(res.body);
        setQueryToUrl(searchOptions);
        if (typeof document.getElementById("search-page") != 'undefined') {
          _libCustomSearchEvents2['default'].trackFullSearch(searchOptions.query, res.body);
        }
      } else {
        reject(err);
      }
    });
  });
};

var getSearchOptionsFromStores = function getSearchOptionsFromStores() {
  var options = {
    categories: _storesCategory_filter_store2['default'].filters,
    brands: _storesBrand_filter_store2['default'].selectedFilters().map(function (x) {
      return x.name;
    }),
    usageTypes: _storesUsage_type_filter_store2['default'].selectedFilters().map(function (x) {
      return x.name;
    }),
    productLines: _storesProduct_line_filter_store2['default'].selectedFilters().map(function (x) {
      return x.name;
    }),
    topLevelCategories: _storesTop_category_filter_store2['default'].selectedFilters().map(function (x) {
      return x.name;
    }),
    serialNumber: _storesSerial_number_filter_store2['default'].serialNumber
  };
  if (SearchStore.state.query != '') {
    options.query = SearchStore.state.query;
  }
  if (SortStore.state.field) {
    options.sortField = SortStore.state.field;
  }
  if (SortStore.state.order) {
    options.sortOrder = SortStore.state.order;
  }
  return options;
};

SearchActions.invalidate.listen(function () {
  var _this = this;

  var options = getSearchOptionsFromStores();
  options.page = 1;
  fetchSearchResults(SearchStore.state.searchUrl + 'everything', options).then(function (response) {
    _actionsBrand_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.brandFacets);
    _actionsUsage_type_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.usageTypeFacets);
    _actionsCategory_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.categoryFacets);
    _actionsProduct_line_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.productLineFacets);
    _actionsTop_category_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.topCategoryFacets);
    _actionsSerial_number_filter_actions2['default'].updateFilters(response.lightSparePartViewModel.serialNumber);
    _this.completed(response);
  }, function (error) {
    return _this.failed(error);
  });
});

var doFilter = function doFilter(self) {
  var options = getSearchOptionsFromStores();
  options.page = 1;
  fetchSearchResults(SearchStore.state.searchUrl + 'lightSpareParts', options).then(function (response) {
    _actionsBrand_filter_actions2['default'].updateFilters(response.brandFacets);
    _actionsUsage_type_filter_actions2['default'].updateFilters(response.usageTypeFacets);
    _actionsCategory_filter_actions2['default'].updateFilters(response.categoryFacets);
    _actionsProduct_line_filter_actions2['default'].updateFilters(response.productLineFacets);
    _actionsTop_category_filter_actions2['default'].updateFilters(response.topCategoryFacets);
    if (response.serialNoInvalid === true) {
      _actionsSerial_number_filter_actions2['default'].updateFilters(response.serialNoInvalid);
    } else {
      _actionsSerial_number_filter_actions2['default'].updateFilters();
    }
    self.completed(response);
  }, function (error) {
    return self.failed(error);
  });
};

SearchActions.invalidateSpareParts.listen(function () {
  var _this2 = this;

  if (filterTimer) clearTimeout(filterTimer);

  filterTimer = setTimeout(function () {
    doFilter(_this2);
  }, waitingForAnotherCheck);
});

SearchActions.loadNextPage.listen(function (group) {
  var _this3 = this;

  var options = getSearchOptionsFromStores();
  if (getUrlVars()['page'] && parseInt(getUrlVars()['page'], 10) !== NaN) {
    options.page = parseInt(getUrlVars()['page']) + 1;
  } else {
    options.page = (SearchStore.state.pagesLoadedByGroup[group] || 1) + 1;
  }

  var actionMethodName = "";
  switch (group) {
    case "lightSparePartViewModel":
      actionMethodName = "LightSpareParts";
      break;
    case "spareParts":
      actionMethodName = "SpareParts";
      break;
    case "pages":
      actionMethodName = "Pages";
      break;
    default:
      actionMethodName = group;
  }

  fetchSearchResults(SearchStore.state.searchUrl + actionMethodName, options).then(function (response) {
    return _this3.completed(group, response.items, response.moreResultsAvailable);
  }, function (error) {
    return _this3.failed(error);
  });
});

var setQueryToUrl = function setQueryToUrl(options) {
  var url = window.location.href.split('?');
  var query = '?';

  Object.keys(options).forEach(function (key) {
    if (options[key] && options[key].constructor === Array) {
      if (options[key].length > 0) {
        options[key].forEach(function (value) {
          query += key + (options[key].length === 1 ? '' : '[]') + '=' + encodeURI(value) + '&';
        });
      }
    } else {
      if (key !== 'sortField' && key !== 'sortOrder' && options[key] !== undefined) {
        query += key + '=' + options[key] + '&';
      }
    }
  });

  if (query.substring(query.length - 1) === '&') {
    query = query.substring(0, query.length - 1);
  }

  history.pushState({ SearchHiab: 'Hiab product search' }, 'Search', query);
};

var getUrlVars = function getUrlVars() {
  var vars = {};
  var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
    vars[key] = value;
  });
  return vars;
};

exports['default'] = SearchActions;
module.exports = exports['default'];

},{"../_actions/brand_filter_actions":632,"../_actions/category_filter_actions":634,"../_actions/product_line_filter_actions":642,"../_actions/serial_number_filter_actions":645,"../_actions/top_category_filter_actions":647,"../_actions/usage_type_filter_actions":649,"../_lib/custom-search-events":672,"../_stores/brand_filter_store":697,"../_stores/category_filter_store":700,"../_stores/product_line_filter_store":724,"../_stores/serial_number_filter_store":727,"../_stores/top_category_filter_store":730,"../_stores/usage_type_filter_store":732,"reflux":542,"superagent":547}],645:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['applyFilter', 'clearFilter', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],646:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var SortActions = _reflux2['default'].createActions(['setOrder', 'setField']);

exports['default'] = SortActions;
module.exports = exports['default'];

},{"reflux":542}],647:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['toggleFilter', 'onClearFilters', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],648:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiTreeview_api = require('../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var TreeViewActions = _reflux2['default'].createActions({
  'loadNodes': {
    children: ['completed', 'failed']
  },
  'searchNodesInModel': {
    children: ['completed', 'failed']
  }
});

TreeViewActions.loadNodes.listen(function (args) {
  _apiTreeview_api2['default'].getNodes(args).then(TreeViewActions.loadNodes.completed)['catch'](TreeViewActions.loadNodes.failed);
});

TreeViewActions.searchNodesInModel.listen(function (query, modelId, isMachine) {
  _apiTreeview_api2['default'].searchNodesInModel(query, modelId, isMachine).then(TreeViewActions.searchNodesInModel.completed)['catch'](TreeViewActions.searchNodesInModel.failed);
});

exports['default'] = TreeViewActions;
module.exports = exports['default'];

},{"../_api/treeview_api":661,"reflux":542}],649:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

exports['default'] = _reflux2['default'].createActions(['toggleFilter', 'onClearFilters', 'updateFilters']);
module.exports = exports['default'];

},{"reflux":542}],650:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _apiUser_addresses_api = require('../_api/user_addresses_api');

var _apiUser_addresses_api2 = _interopRequireDefault(_apiUser_addresses_api);

var _storesUser_default_addresses_store = require('../_stores/user_default_addresses_store');

var _storesUser_default_addresses_store2 = _interopRequireDefault(_storesUser_default_addresses_store);

var _storesUser_country_options_store = require('../_stores/user_country_options_store');

var _storesUser_country_options_store2 = _interopRequireDefault(_storesUser_country_options_store);

var _storesAddress_field_store = require('../_stores/address_field_store');

var _storesAddress_field_store2 = _interopRequireDefault(_storesAddress_field_store);

var AddressActions = _reflux2['default'].createActions({
  'loadAddresses': {
    children: ['completed', 'failed']
  },
  'deleteAddress': {},
  'updateAddress': {},
  'createAddress': {},
  'checkPostalCode': {},
  'setDefaultAddress': {},
  'setCountries': {},
  'getCountries': {}
});

AddressActions.loadAddresses.listen(function (args) {
  _apiUser_addresses_api2['default'].addresses(args).then(AddressActions.loadAddresses.completed)['catch'](AddressActions.loadAddresses.failed);
});

AddressActions.setDefaultAddress.listen(function (defaultAddress) {
  _storesUser_default_addresses_store2['default'].setDefaultAddress(defaultAddress);
});

AddressActions.setCountries.listen(function (countries) {
  _storesUser_country_options_store2['default'].setCountries(countries);
});
AddressActions.getCountries.listen(function (countries) {
  _storesUser_country_options_store2['default'].getCountries(countries);
});

AddressActions.deleteAddress.listen(function (addresses) {
  _apiUser_addresses_api2['default'].deleteaddress(addresses).then(AddressActions.loadAddresses.completed)['catch'](AddressActions.loadAddresses.failed);
});

AddressActions.updateAddress.listen(function (addresses) {
  _apiUser_addresses_api2['default'].updateaddress(addresses).then(AddressActions.loadAddresses.completed)['catch'](AddressActions.loadAddresses.failed);
});

AddressActions.createAddress.listen(function (addresses) {
  _apiUser_addresses_api2['default'].createaddress(addresses).then(AddressActions.loadAddresses.completed)['catch'](AddressActions.loadAddresses.failed);
});

AddressActions.checkPostalCode.listen(function (countryCode, value) {
  _apiUser_addresses_api2['default'].checkPostalCode(countryCode, value).then(_storesAddress_field_store2['default'].checkPostalCodeCompleted)['catch'](_storesAddress_field_store2['default'].checkPostalCodeFailed);
});

exports['default'] = AddressActions;
module.exports = exports['default'];

},{"../_api/user_addresses_api":662,"../_stores/address_field_store":696,"../_stores/user_country_options_store":734,"../_stores/user_default_addresses_store":735,"reflux":542}],651:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _storesBreadcrumb_store = require('../_stores/breadcrumb_store');

var _storesBreadcrumb_store2 = _interopRequireDefault(_storesBreadcrumb_store);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	getBreadcrumb: function getBreadcrumb(modelId) {
		return new _promise2['default'](function (resolve, reject) {
			//let url = '/dummy/json/Breadcrumbs/' + modelId + '.json';
			var url = hiabconfig.explodedViews.apiBaseUrl + 'Breadcrumbs/' + modelId;

			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					_storesBreadcrumb_store2['default'].init();
					_storesBreadcrumb_store2['default'].set(modelId, response.body);
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},
	getMachineBreadcrumb: function getMachineBreadcrumb(modelId) {
		return new _promise2['default'](function (resolve, reject) {
			//let url = '/dummy/json/Breadcrumbs/' + modelId + '.json';
			var url = hiabconfig.explodedViews.apiBaseUrl + 'MachineBreadcrumbs/' + modelId;

			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					_storesBreadcrumb_store2['default'].init();
					_storesBreadcrumb_store2['default'].set(modelId, response.body);
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},
	getModelBreadcrumb: function getModelBreadcrumb(modelId) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.explodedViews.apiBaseUrl + 'ModelBreadcrumbs/' + modelId;

			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					_storesBreadcrumb_store2['default'].init();
					_storesBreadcrumb_store2['default'].set(modelId, response.body);
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	}
};
module.exports = exports['default'];

},{"../_stores/breadcrumb_store":698,"promise":335,"superagent":547}],652:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	cartitems: function cartitems() {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.cart.apiBaseUrl + 'getcart';
			// url = 'dummy/json/cart/cartitems.json';
			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	clearcart: function clearcart() {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.cart.apiBaseUrl + 'clearcart';

			_superagent2['default'].post(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	addcartitem: function addcartitem(skuId, quantity) {
		// console.log('CartApi#addcartitem is deprecated. Use CartApi#addCartItem or CartApi#addCartItems instead.')
		var cartItems = [{ Code: skuId, Quantity: quantity }];
		// Account for backend changes since deprecation
		return this.addCartItems(cartItems).then(function (response) {
			return _promise2['default'].resolve(response.Cart);
		});
	},

	addCartItem: function addCartItem(code, quantity) {
		return this.addCartItems([{ code: code, quantity: quantity }]);
	},
	// /**
	//  * @param {Object[]} cartItems
	//  * @param {string} cartItems[].code - skuId
	//  * @param {integer} cartItems[].quantity - interpreted as decimal by backend (?)
	//  */
	addCartItems: function addCartItems(cartItems) {
		var isQuickBuyBatch = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];

		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.cart.apiBaseUrl + 'addcartitems?qbcontext=' + isQuickBuyBatch + '&language=' + hiabconfig.preferredCulture;

			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(cartItems).end(function (error, response) {
				if (error || !response.body) {
					reject(error || "no response body");
				} else {
					resolve(response.body);
				}
			});
		});
	},

	updatecartitem: function updatecartitem(skuId, quantity) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.cart.apiBaseUrl + 'updatecartitemquantity?language=' + hiabconfig.preferredCulture,
			    cartItem = { code: skuId, quantity: quantity };

			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(cartItem).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	deletecartitem: function deletecartitem(skuId) {
		return new _promise2['default'](function (resolve, reject) {

			var url = hiabconfig.cart.apiBaseUrl + 'deletecartitem/' + skuId;
			//	url = '/dummy/json/cart/deleteitem.json';
			_superagent2['default'].post(url)
			//.get(url)
			.set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	}

};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],653:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {

	currentRequestShippingOptionOrPriority: null,
	currentRequestOrderSimulation: null,
	currentRequestCountryCode: null,

	getCheckout: function getCheckout() {
		return new _promise2['default'](function (resolve, reject) {
			//let url = '/dummy/json/Checkout/checkout.json';
			var url = hiabconfig.checkout.apiBaseUrl + 'getcheckout';
			url = 'dummy/json/Checkout/checkout-2.json';
			_superagent2['default']
			//.get(url)

			//.get(url)

			//.get(url)
			.get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	orderSimulation: function orderSimulation(data) {
		var _this = this;

		return new _promise2['default'](function (resolve, reject) {

			if (_this.currentRequestOrderSimulation !== null) {
				_this.currentRequestOrderSimulation.abort();
			}
			var url = hiabconfig.checkout.apiBaseUrl + 'OrderSimulationJson';
			_this.currentRequestOrderSimulation = _superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send(data).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},
	updateShippingOptionOrPriority: function updateShippingOptionOrPriority(option) {
		var _this2 = this;

		return new _promise2['default'](function (resolve, reject) {

			if (_this2.currentRequestShippingOptionOrPriority !== null) {
				_this2.currentRequestShippingOptionOrPriority.abort();
			}

			var url = hiabconfig.checkout.apiBaseUrl + 'updateShippingOptionJson';

			_this2.currentRequestShippingOptionOrPriority = _superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send(option).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	updateCountryCode: function updateCountryCode(shippingAddress) {
		var _this3 = this;

		return new _promise2['default'](function (resolve, reject) {
			if (_this3.currentRequestCountryCode !== null) {
				_this3.currentRequestCountryCode.abort();
			}

			var url = hiabconfig.checkout.apiBaseUrl + 'UpdateShippingCountryJson';

			_this3.currentRequestCountryCode = _superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send({ shippingAddresses: shippingAddress }).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	updateCartItem: function updateCartItem(skuId, quantity, upgraded) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'updateCartItemJson',
			   
			//let url = '/dummy/json/checkout/checkout.html',
			cartItem = { code: skuId, quantity: quantity, upgraded: upgraded };

			_superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send(cartItem).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	deleteCartItem: function deleteCartItem(skuId) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'deletecartitemJson';
			//let url = '/dummy/json/checkout/checkout.html';
			var id = { "id": skuId };
			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(id).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	updateCartItemCustomerComment: function updateCartItemCustomerComment(id, comment) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'updatecartitemcustomercommentJson';
			//let url = '/dummy/json/checkout/checkout.html',
			var cartItem = { id: id, comment: comment };
			//Will send succes or false
			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(cartItem).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},

	loadShippingAddress: function loadShippingAddress(id) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'setShippingAddressByIdJson',
			   
			//let url = '/dummy/json/checkout/checkout.html',
			addressId = { id: id };

			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(addressId).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	},
	loadBillingAddress: function loadBillingAddress(id) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'setBillingAddressByIdJson',
			   
			//let url = '/dummy/json/checkout/checkout.html',
			addressId = { id: id };

			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(addressId).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject(response);
				}
			});
		});
	}

};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],654:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {

	currentRequestShippingOptionOrPriority: null,
	currentRequestCountryCode: null,

	getCheckout: function getCheckout() {
		return new _promise2['default'](function (resolve, reject) {
			//let url = '/dummy/json/Checkout/checkout.json';
			var url = hiabconfig.checkout.apiBaseUrl + 'getcheckout';
			_superagent2['default']
			//.get(url)

			//.get(url)

			//.get(url)
			.get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	updateShippingOptionOrPriority: function updateShippingOptionOrPriority(option) {
		var _this = this;

		return new _promise2['default'](function (resolve, reject) {

			if (_this.currentRequestShippingOptionOrPriority !== null) {
				_this.currentRequestShippingOptionOrPriority.abort();
			}

			var url = hiabconfig.checkout.apiBaseUrl + 'updateShippingOption';

			_this.currentRequestShippingOptionOrPriority = _superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send(option).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	},

	updateCountryCode: function updateCountryCode(code) {
		var _this2 = this;

		return new _promise2['default'](function (resolve, reject) {
			if (_this2.currentRequestCountryCode !== null) {
				_this2.currentRequestCountryCode.abort();
			}

			var url = hiabconfig.checkout.apiBaseUrl + 'UpdateShippingCountry';

			_this2.currentRequestCountryCode = _superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send({ countryCode: code }).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	},

	updateCartItemQuantity: function updateCartItemQuantity(skuId, quantity) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'updatecartitemquantity',
			   
			//let url = '/dummy/json/checkout/checkout.html',
			cartItem = { code: skuId, quantity: quantity };

			_superagent2['default'].post(url).set('X-Requested-With', 'XMLHttpRequest').send(cartItem).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	},

	deleteCartItem: function deleteCartItem(skuId) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'deletecartitem';
			//let url = '/dummy/json/checkout/checkout.html';
			var id = { "id": skuId };

			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(id).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	},

	updateCartItemCustomerComment: function updateCartItemCustomerComment(id, comment) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'updatecartitemcustomercomment';
			//let url = '/dummy/json/checkout/checkout.html',
			var cartItem = { id: id, comment: comment };

			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').send(cartItem).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	},

	loadShippingAddress: function loadShippingAddress(id) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.checkout.apiBaseUrl + 'GetShippingAddressById/' + id,
			   
			//let url = '/dummy/json/checkout/checkout.html',
			addressId = { id: id };

			_superagent2['default'].post(url)
			//.get(url)
			.set('X-Requested-With', 'XMLHttpRequest').query(addressId).end(function (error, response) {
				if (response.text) {
					resolve(response.text);
				} else {
					reject('Error');
				}
			});
		});
	}

};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],655:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

/**
 * Illustration api module
 * @module _api/illustration_api
 */
exports['default'] = {
  /**
  * Get illustration by guid
  * @param {guid} guid - parent node guid
  */
  getIllustration: function getIllustration(guid, nodeType) {
    return new _promise2['default'](function (resolve, reject) {
      if (!guid) {
        return reject();
      }
      var url = hiabconfig.explodedViews.apiBaseUrl + 'GetIllustration/' + guid + '?nodetype=' + nodeType + '&modelId=';

      _superagent2['default'].get(url).end(function (error, response) {
        if (response.body) {
          resolve(response.body);
        } else {
          reject('Error');
        }
      });
    });
  }
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],656:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

/**
 * Illustration api module
 * @module _api/illustration_api
 */
exports['default'] = {
  /**
  * Get illustration by guid
  * @param {guid} guid - parent node guid
  */
  getIllustration: function getIllustration(guid, modelId) {
    return new _promise2['default'](function (resolve, reject) {
      if (!guid) {
        return reject();
      }

      var url = hiabconfig.explodedViews.apiBaseUrl + 'GetIllustration/' + guid + '?modelid=' + modelId;
      _superagent2['default'].get(url).end(function (error, response) {
        if (response.body) {
          resolve(response.body);
        } else {
          reject('Error');
        }
      });
    });
  }
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],657:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	impersonatedUser: function impersonatedUser() {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.impersonator.apiBaseUrl + 'get';
			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	impersonatedSignin: function impersonatedSignin(id) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.impersonator.apiBaseUrl + 'SignIn/' + id;
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Language', hiabconfig.preferredCulture).end(function (error, response) {
				if (response.status === 200) {
					resolve(response);
				} else {
					reject(response);
				}
			});
		});
	},

	impersonatedSignout: function impersonatedSignout() {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.impersonator.apiBaseUrl + 'SignOut';
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Language', hiabconfig.preferredCulture).end(function (error, response) {
				if (response.status === 200) {
					resolve(response);
				} else {
					reject('Error');
				}
			});
		});
	}
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],658:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {

	currentRequest: null,

	fetchModelTypes: function fetchModelTypes(serialNumber) {
		var _this = this;

		return new _promise2['default'](function (resolve, reject) {
			if (_this.currentRequest !== null) {
				_this.currentRequest.abort();
			}
			var url = hiabconfig.explodedViews.apiBaseUrl + 'modelsearch/' + modelQuery; //Api/SalesforceRecommendations/GetRecommendations;
			_this.currentRequest = _superagent2['default'].get(url).set('Accept', 'application/json').send(serialNumber).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	search: function search(modelQuery) {
		var _this2 = this;

		return new _promise2['default'](function (resolve, reject) {
			if (_this2.currentRequest !== null) {
				_this2.currentRequest.abort();
			}
			var url = hiabconfig.explodedViews.apiBaseUrl + 'modelsearch/' + modelQuery;
			_this2.currentRequest = _superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	abortSearch: function abortSearch() {
		if (this.currentRequest !== null) {
			this.currentRequest.abort();
		}
	}
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],659:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	isbuyable: function isbuyable(productId) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.batchOrder.apiBaseUrl + 'isbuyable';
			_superagent2['default'].get(url).query({ id: productId }).set('Accept', 'application/json').end(function (error, response) {
				if (error || !response.body) {
					reject(error || 'No response body');
				} else {
					resolve(response.body);
				}
			});
		});
	}
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],660:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	fetchRecommendations: function fetchRecommendations(recommendationRequest) {
		return new _promise2['default'](function (resolve, reject) {
			var url = '/Api/SalesforceRecommendations/GetRecommendations';
			var data = JSON.stringify(recommendationRequest);
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(data).end(function (error, response) {
				if (response || response.body) {
					resolve(response.body);
				} else {
					reject(error || "no response body");
				}
			});
		});
	}
};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],661:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _storesTreeview_store = require('../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	getNodes: function getNodes(parent) {
		return new _promise2['default'](function (resolve, reject) {
			var apiType = 'GetNodes/';

			if (!parent) {
				parent = 0;
			} else {
				var isMachine = parent.substring(0, 8) == 'machine-';
				var isModel = parent.substring(0, 6) == 'model-';
				if (isMachine) {
					apiType = 'GetMachineNodes/';
					parent = parent.replace('machine-', '');
				} else if (isModel) {
					parent = parent.replace('model-', '');
				}
			}

			var cacheKey = parent;
			var findInCache = _storesTreeview_store2['default'].get(cacheKey);

			if (!_lodash2['default'].isUndefined(findInCache)) {
				return resolve(findInCache.data);
			}

			var url = hiabconfig.explodedViews.apiBaseUrl + apiType + parent;
			_superagent2['default'].get(url).end(function (error, response) {
				if (response.body) {
					_storesTreeview_store2['default'].set(cacheKey, response.body);
					resolve(response.body);
				} else {
					_storesTreeview_store2['default'].setLoadingState(false);
					var _error = response.statusCode === 204 ? response.statusCode : 'Error';
					reject(_error);
				}
			});
		});
	},
	getAscendantNodes: function getAscendantNodes(modelId, illustrationId, nodeId) {
		var isMachine = modelId.substring(0, 8) == 'machine-';
		var apiType = illustrationId ? 'AncestorsForIllustration' : 'AncestorsForSection';
		var id = illustrationId ? illustrationId : nodeId;

		if (isMachine && illustrationId) {
			apiType = 'GetMachineNodes';
			modelId = modelId.replace('machine-', '');
			id = modelId;
		}

		return new _promise2['default'](function (resolve, reject) {

			var url = hiabconfig.explodedViews.apiBaseUrl + apiType + '/' + id;
			var params = {
				baseModelId: modelId
			};

			if (illustrationId && !isMachine) {
				_superagent2['default'].get(url).query(params).end(function (error, response) {
					if (response.body) {
						resolve(response.body);
					} else {
						_storesTreeview_store2['default'].setLoadingState(false);
						reject('Error');
					}
				});
			} else {
				_superagent2['default'].get(url).end(function (error, response) {
					if (response.body) {
						resolve(response.body);
					} else {
						_storesTreeview_store2['default'].setLoadingState(false);
						reject('Error');
					}
				});
			}
		});
	},

	currentRequest: null,

	searchNodesInModel: function searchNodesInModel(query, modelId, isMachine) {
		var _this = this;

		var endPoint = 'SearchInModel';
		if (isMachine) {
			modelId = modelId.replace('machine-', '');
			endPoint = 'SearchInMachine';
		}
		return new _promise2['default'](function (resolve, reject) {
			if (_this.currentRequest !== null) {
				_this.currentRequest.abort();
			}
			var url = hiabconfig.explodedViews.apiBaseUrl + endPoint + '/?query=' + query + '&modelid=' + modelId;
			_this.currentRequest = _superagent2['default'].get(url).end(function (error, response) {
				if (response.body) {
					resolve(response.body);
				} else {
					_storesTreeview_store2['default'].setLoadingState(false);
					reject('Error');
				}
			});
		});
	}
};
module.exports = exports['default'];

},{"../_stores/treeview_store":731,"lodash":333,"promise":335,"superagent":547}],662:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

exports['default'] = {
	addresses: function addresses() {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.addresses.apiBaseUrl + 'Index';
			_superagent2['default'].get(url).set('Accept', 'application/json').end(function (error, response) {
				if (response && response.body) {
					resolve(response.body);
				} else {
					reject('Error');
				}
			});
		});
	},

	deleteaddress: function deleteaddress(address) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.addresses.apiBaseUrl + 'Delete';
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(address).end(function (error, response) {
				if (error || !response.body) {
					reject(error || "no response body");
				} else {
					resolve(response.body);
				}
			});
		});
	},

	updateaddress: function updateaddress(address) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.addresses.apiBaseUrl + 'Update';
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(address).end(function (error, response) {
				if (error || !response.body) {
					reject(error || "no response body");
				} else {
					resolve(response.body);
				}
			});
		});
	},

	createaddress: function createaddress(address) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.addresses.apiBaseUrl + 'Create';
			_superagent2['default'].post(url).set('Accept', 'application/json').set('Content-Type', 'application/json').send(address).end(function (error, response) {
				if (error || !response.body) {
					reject(error || "no response body");
				} else {
					resolve(response.body);
				}
			});
		});
	},

	checkPostalCode: function checkPostalCode(countryCode, value) {
		return new _promise2['default'](function (resolve, reject) {
			var url = hiabconfig.addresses.apiBaseUrl + 'ValidatePostalCode?countryCode=' + countryCode + '&postalcode=' + value;
			_superagent2['default'].get(url).set('Accept', 'application/json').set('Content-Type', 'application/json')
			// .send(data)
			.end(function (error, response) {
				// console.log('API');
				// console.log(response);
				if (error) {
					reject(error || "no response body");
				} else {
					resolve(response.body);
				}
			});
		});
	}

};
module.exports = exports['default'];

},{"promise":335,"superagent":547}],663:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var addclass = {
	init: function init() {
		var isOnExplodedViewPage = _jquery2['default']('#illustration').length > 0 ? true : false;
		var urlParts = window.location.href.split('/');
		var explodedViewUrl = hiabconfig.explodedViews.explodedViewsNameInUrl;
		// console.log(isOnExplodedViewPage);
		// console.log(urlParts);
		// console.log(urlParts.indexOf('exploded-view'));
		// console.log(urlParts[urlParts.indexOf('exploded-view') + 1]);

		_jquery2['default']('body').on('click', '[data-add-class]', function (e) {
			if (isOnExplodedViewPage) {
				e.preventDefault();
				if (_jquery2['default'](this).attr('data-brandtree-close') === '' && urlParts.indexOf(explodedViewUrl) !== -1 && urlParts[urlParts.indexOf(explodedViewUrl) + 1] === '') {
					if (document.referrer.split('/')[2] != location.hostname) {
						window.location.href = window.location.origin;
					} else {
						history.back();
					}
				} else {
					_jquery2['default'](_jquery2['default'](this).data('add-class')).toggleClass(_jquery2['default'](this).data('added-class'));
				}
			} else {
				_jquery2['default'](_jquery2['default'](this).data('add-class')).toggleClass(_jquery2['default'](this).data('added-class'));
			}
		});
	}
};

exports['default'] = addclass;
module.exports = exports['default'];

},{"jquery":628}],664:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var addtocart = {
	init: function init() {

		var changeQuantity = undefined;
		var productsNbr = [];

		function CartIsWorking() {
			return _jquery2['default']('#controll-cart').hasClass('adding');
		}

		_jquery2['default']('.amount').change(function () {
			var newQuantity = _jquery2['default'](this).val();
			var code = _jquery2['default'](this).attr('data-product-sku');
			var amountElements = _jquery2['default'](".amount[data-product-sku='" + code + "']");

			amountElements.each(function () {
				_jquery2['default'](this).val(newQuantity);
			});
		});

		_jquery2['default']('.product-detailpage .amount').unbind('keyup').bind('keyup', function (event) {
			event.preventDefault();

			if (event.which == 13) {
				var skuID = _jquery2['default'](this).data('product-sku');

				if (CartIsWorking() || _jquery2['default']('button.add-to-cart[data-product-sku="' + skuID + '"]').hasClass('loading')) {
					return;
				}

				_jquery2['default'](this).animate({
					lineHeight: "60px",
					opacity: "0.1"
				}, {
					duration: 300,
					specialEasing: {
						lineHeight: "linear"
					},
					complete: function complete() {
						_jquery2['default'](this).animate({
							lineHeight: "18px",
							opacity: "1"
						}, 200);
					}
				});
				var quantity = _jquery2['default'](this).val();
				_jquery2['default']('#controll-cart')[0].className += ' adding';
				_jquery2['default']('.uc-headercart')[0].className += ' adding';
				_jquery2['default']('button.add-to-cart[data-product-sku="' + skuID + '"]').addClass('loading');
				_jquery2['default']('.uc-headercart').removeClass('right-off-canvas-toggle');
				productsNbr.push(skuID.toString());
				_actionsCart_actions2['default'].addCartItem(skuID, quantity);
			}
		});
		_jquery2['default']('body').on('click', 'button.not-buyable', function (e) {
			if (CartIsWorking()) {
				return false;
			} else {
				return true;
			}
		});
		_jquery2['default']('body').on('click', 'button.add-to-cart', function (e) {
			e.stopImmediatePropagation();
			e.preventDefault();

			if (_jquery2['default'](this).hasClass('loading') || _jquery2['default']('button.quick-buy').hasClass('loading')) {
				return;
			}

			_jquery2['default']('#controll-cart')[0].className += ' adding';
			_jquery2['default']('.uc-headercart')[0].className += ' adding';
			_jquery2['default'](this)[0].className += ' loading';
			var skuID = _jquery2['default'](this).data('product-sku');
			var quantity = _jquery2['default'](".amount[data-product-sku='" + skuID + "']").val();
			if (!quantity) {
				quantity = 1;
			}

			var productContext = _jquery2['default'](this).parent().data('product-context');

			_jquery2['default']('.uc-headercart').removeClass('right-off-canvas-toggle');
			productsNbr.push(skuID.toString());
			_actionsCart_actions2['default'].addCartItem(skuID, quantity, productContext);
		});

		_jquery2['default']('body').on('click', 'button.quick-buy', function (e) {
			e.preventDefault();
			e.stopImmediatePropagation();

			if (CartIsWorking()) {
				return;
			}

			_jquery2['default']('#controll-cart').addClass('adding');
			_jquery2['default']('.uc-headercart').addClass('adding');
			_jquery2['default'](this).addClass('loading');
			var skuID = _jquery2['default'](this).data('product-sku');
			var quantity = _jquery2['default'](".amount[data-product-sku='" + skuID + "']").val();
			if (!quantity) {
				quantity = 1;
			}

			var productContext = _jquery2['default'](this).parent().data('product-context');

			_jquery2['default']('.uc-headercart').removeClass('right-off-canvas-toggle');
			_actionsCart_actions2['default'].quickBuy(skuID, quantity, productContext);
		});

		_storesCart_store2['default'].listen(function (res) {
			var numberOfItemsCompleted = 0;
			if (_jquery2['default']('[data-product-sku]').length > 0 /*&& !$('.drawer-main').hasClass('move-left')*/) {

					for (var item in res.Added) {
						if (res.Added.hasOwnProperty(item)) {
							var index = productsNbr.indexOf(res.Added[item].Code);
							if (index !== -1) {
								var button = _jquery2['default']('button[data-product-sku="' + res.Added[item].Code + '"]')[0];
								button.className = button.className.replace(' loading', '');
								productsNbr.splice(index, 1);
								numberOfItemsCompleted++;
							}
						}
					}

					for (var item in res.Failed) {
						if (res.Failed.hasOwnProperty(item)) {
							var index = productsNbr.indexOf(res.Failed[item].Code);
							if (index !== -1) {
								var button = _jquery2['default']('button[data-product-sku="' + res.Failed[item].Code + '"]')[0];
								button.className = button.className.replace(' loading', '');
								productsNbr.splice(index, 1);
								numberOfItemsCompleted++;
							}
						}
					}

					var headerCart = _jquery2['default']('.uc-headercart')[0];
					var controllCart = _jquery2['default']('#controll-cart')[0];
					for (var i = 0; i < numberOfItemsCompleted; i++) {
						headerCart.className = headerCart.className.replace(' adding', '');
						controllCart.className = controllCart.className.replace(' adding', '');
					}
				}
		});
	}
};

exports['default'] = addtocart;
module.exports = exports['default'];

},{"../_actions/cart_actions":633,"../_stores/cart_store":699,"jquery":628}],665:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var autosubmit = {
	init: function init() {
		_jquery2['default']('[data-autosubmit]').on('change', function () {
			_jquery2['default'](this).parents('form').submit();
		});
	}
};

exports['default'] = autosubmit;
module.exports = exports['default'];

},{"jquery":628}],666:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _componentsBrandnavigationBrandnavigation = require('../components/brandnavigation/brandnavigation');

var _componentsBrandnavigationBrandnavigation2 = _interopRequireDefault(_componentsBrandnavigationBrandnavigation);

var _storesHistory_store = require('../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var _componentsBrandnavigationModelsearch = require('../components/brandnavigation/modelsearch');

var _componentsBrandnavigationModelsearch2 = _interopRequireDefault(_componentsBrandnavigationModelsearch);

var _componentsBrandnavigationModelsearchResult = require('../components/brandnavigation/modelsearch-result');

var _componentsBrandnavigationModelsearchResult2 = _interopRequireDefault(_componentsBrandnavigationModelsearchResult);

var brandtree = {
	init: function init() {
		_jquery2['default']('[data-brandtree-close]').on('click', this.onClose);
		if (_jquery2['default']('#brandtree-listview').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_componentsBrandnavigationBrandnavigation2['default'], null), _jquery2['default']('#brandtree-listview')[0]);
		if (_jquery2['default']('#model-search').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_componentsBrandnavigationModelsearch2['default'], null), _jquery2['default']('#model-search')[0]);
		if (_jquery2['default']('#model-search-result').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_componentsBrandnavigationModelsearchResult2['default'], null), _jquery2['default']('#model-search-result')[0]);
	},

	onClose: function onClose() {
		//Reset history
		_storesHistory_store2['default'].init();
		_actionsHistory_actions2['default'].storeUpdated();
	}
};

exports['default'] = brandtree;
module.exports = exports['default'];

},{"../_actions/history_actions":637,"../_stores/history_store":716,"../components/brandnavigation/brandnavigation":746,"../components/brandnavigation/modelsearch":754,"../components/brandnavigation/modelsearch-result":753,"jquery":628,"react":525,"react-dom":351}],667:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var clearcart = {
	init: function init() {
		var element;

		_jquery2['default']('.inner-wrap').on('click', '.do-clear-cart', function (e) {
			e.preventDefault();
			_jquery2['default'](this).addClass('loading');
			_jquery2['default']('#checkout-button').prop("disabled", true);
			_jquery2['default']('.clear-cart .close').prop("disabled", true);
			element = _jquery2['default'](this);

			var cart = JSON.parse(JSON.stringify(_storesCart_store2['default'].getStore()));
			_libCustomEvents2['default'].clearCartEvent(cart.Cart.CartItems, cart.Cart.CartId);

			_actionsCart_actions2['default'].clearCart();
		});

		_storesCart_store2['default'].listen(function (res) {
			if (res.Cart.CartItems && res.Cart.CartItems.length === 0) {
				var pathNameParts = window.location.pathname.split('/').filter(function (n) {
					return n !== '';
				});
				if (pathNameParts[pathNameParts.length - 1] === 'checkout') {
					window.location.href = window.location.origin;
				} else {
					if (element) {
						element.removeClass('loading');
						_jquery2['default']('.clear-cart').removeClass('is-open');
						_jquery2['default']('#checkout-button').prop("disabled", false);
						_jquery2['default']('.clear-cart .close').prop("disabled", false);
					}
				}
			}
		});
	}
};

exports['default'] = clearcart;
module.exports = exports['default'];

},{"../_actions/cart_actions":633,"../_lib/custom-events":671,"../_stores/cart_store":699,"jquery":628}],668:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var complaintview = {
	init: function init() {
		_jquery2['default']('body').on('click', '[data-product-id]', function (e) {
			e.preventDefault();
			var count = 0;
			_jquery2['default']('#complaint ul.tabs li.tab-title').each(function () {
				if (count === 0) {
					_jquery2['default'](this).addClass('active');
					_jquery2['default']('a', _jquery2['default'](this)).attr('aria-selected', true);
				} else {
					_jquery2['default'](this).removeClass('active');
					_jquery2['default']('a', _jquery2['default'](this)).attr('aria-selected', false);
				}
				count++;
			});

			var netPrice = _jquery2['default'](this).attr('data-net-price');
			if (netPrice) {
				_jquery2['default']('#complaint-price-netprice').val(netPrice.split(' ')[0].replace(',', '.'));
			}
			var endCustomerPrice = _jquery2['default'](this).attr('data-end-customer-price');
			if (endCustomerPrice) {
				_jquery2['default']('#complaint-price-end-costumer').val(endCustomerPrice.split(' ')[0].replace(',', '.'));
			}

			var d = new Date();
			var month = d.getMonth() + 1;
			var day = d.getDate();
			var date = d.getFullYear() + ' - ' + (('' + month).length < 2 ? '0' : '') + month + ' - ' + (('' + day).length < 2 ? '0' : '') + day;

			if (!_jquery2['default'](this).data("data-is-buyable")) {
				_jquery2['default']('#complaint ul li').hide();
				_jquery2['default']('#complaint .tabs-content .content').removeClass('active');

				_jquery2['default']('#complaint ul li a[href="#other"]').parent().show().addClass('active');
				_jquery2['default']('#other').show().addClass('active');
			} else {
				_jquery2['default']('#' + _jquery2['default'](this).data("active-tab")).addClass('active');
			}

			_jquery2['default']('#complaint').foundation('reveal', 'open');

			_jquery2['default']('.complaint-productid').val(_jquery2['default'](this).data('product-id'));
			_jquery2['default']('.complaint-date').val(date);

			// $('#complaint .tabs li').removeClass('active');
			// $('a[href=#' + $(this).data("active-tab") + ']').parent().addClass('active');
		});

		_jquery2['default']('#complaint-availability-status').on('change', function () {
			if (_jquery2['default'](this).val() == hiabconfig.complaintView.lang.availabilityStatusOther) {
				_jquery2['default']('.availability-status-other').css('display', 'block');
			} else {
				_jquery2['default']('.availability-status-other').css('display', 'none');
			}
		});

		_jquery2['default']('body').on('valid.fndtn.abide', '#complaint .tabs-content .content.active .row form', function (e) {

			// data-net-price="20" data-end-customer-price="25"

			var formData = _jquery2['default']('#complaint .tabs-content .content.active .row form').serializeArray();
			var formDataNice = {};
			for (var variable in formData) {
				if (formData.hasOwnProperty(variable)) {
					if (formData[variable].name === 'Date') {
						var d = new Date();
						formDataNice[formData[variable].name] = d.toUTCString();
					} else {
						formDataNice[formData[variable].name] = formData[variable].value;
					}
				}
			}
			formDataNice.MarketId = hiabconfig.marketId;
			// console.log(formDataNice);
			var fromId = _jquery2['default']('#complaint .tabs-content .content.active form').attr('id');
			var url;

			switch (fromId) {
				case 'complaint-price':
					url = '/api/' + hiabconfig.preferredCulture + '/CustomerFeedback/Price';
					break;
				case 'complaint-availability':
					url = '/api/' + hiabconfig.preferredCulture + '/CustomerFeedback/Availability';
					break;
				case 'complaint-other':
					url = '/api/' + hiabconfig.preferredCulture + '/CustomerFeedback/Other';
					break;
				default:
			}

			_jquery2['default']('#complaint .tabs-content .content.active form button.send-complaint').addClass('loading');
			_jquery2['default']('#complaint .tabs-content .content.active form .errorMsg').hide();
			_jquery2['default']('#complaint .tabs-content .content.active form .successMsg').hide();
			// $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
			//
			// });
			_jquery2['default'].ajax({
				type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
				url: url, // the url where we want to POST
				data: formDataNice, // our data object
				headers: { 'X-XSRF-Token': formDataNice['__RequestVerificationToken'] }
			})
			// using the done promise callback
			.done(function (data) {
				// log data to the console so we can see
				console.log(data);
				_jquery2['default']('#complaint .tabs-content .content.active form .successMsg').show();
				// here we will handle errors and validation messages
				_jquery2['default']('#complaint .tabs-content .content.active form button.send-complaint').removeClass('loading');
			}).error(function (jqXHR, textStatus, errorThrown) {
				// TODO: Handle error
				// console.log( 'Request failed: jqXHR ' + textStatus + ' textStatus ' + textStatus + ' errorThrown ' + errorThrown);

			});
			// stop the form from submitting the normal way and refreshing the page
			e.preventDefault();
		});

		_jquery2['default']('#complaint .tabs-content .content .row form').each(function (e) {
			_jquery2['default'](this).on('submit', function (e) {
				e.preventDefault();
				//console.log('stanna');
			});
		});

		_jquery2['default']('body').on('change', '#complaint-availability-status', function (e) {
			//console.log($('#complaint-availability-status option:last-of-type').text().trim());
			//console.log($(this).val());
			if (_jquery2['default'](this).val() === _jquery2['default']('#complaint-availability-status option:last-of-type').text().trim()) {
				_jquery2['default']('#complaint-availability-other').parent().show();
			} else {
				_jquery2['default']('#complaint-availability-other').parent().hide();
			}
			// $('#' +$('#complaint .tabs-content .content.active form').attr('id') ).foundation();
		});
	}
};

exports['default'] = complaintview;
module.exports = exports['default'];

},{"jquery":628}],669:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _customEvents = require('./custom-events');

var _customEvents2 = _interopRequireDefault(_customEvents);

var confirmationPage = {
  init: function init() {
    if ($('.uc-checkout-cart-confirmation').length > 0) {
      if (performance.navigation.type != 1) {
        //USE THIS LATER
      } else {
          //console.log('reload');
        }
      var orders = confirmationData.orders;
      if (orders.length > 0) {
        for (var i = 0; i < orders.length; i++) {
          var order = orders[i];
          _customEvents2['default'].confirmationPageAddTrans(order);
        }
      }
    }
  }
};

exports['default'] = confirmationPage;
module.exports = exports['default'];

},{"./custom-events":671}],670:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryCookie = require('jquery.cookie');

var _jqueryCookie2 = _interopRequireDefault(_jqueryCookie);

var cookie = {

  init: function init() {
    this.closeCookie();

    if (_jquery2['default']('.jsCookies').length > 0) {
      if (!_jquery2['default'].cookie('hiabecom-cookie')) {
        _jquery2['default']('.jsCookies').show();
        _jquery2['default'].cookie('hiabecom-cookie', '{}', { expires: 31, path: '/' });
      } else {
        var res = JSON.parse(_jquery2['default'].cookie('hiabecom-cookie'));
        if (res.approved) {
          _jquery2['default']('.jsCookies').hide();
        } else {
          _jquery2['default']('.jsCookies').show();
        }
      }
    }

    if (_jquery2['default']('#maintenance-banner').length > 0) {
      var maintenanceId = _jquery2['default']('#maintenance-banner').data('maintenance-id');
      if (!_jquery2['default'].cookie('hiabecom-maintenance' + maintenanceId)) {
        _jquery2['default']('#maintenance-banner').show();
        _jquery2['default'].cookie('hiabecom-maintenance' + maintenanceId, '{}', { expires: 31, path: '/' });
      } else {
        var res = JSON.parse(_jquery2['default'].cookie('hiabecom-maintenance' + maintenanceId));
        if (res.approved) {
          _jquery2['default']('#maintenance-banner').hide();
        } else {
          _jquery2['default']('#maintenance-banner').show();
        }
      }
    }

    if (_jquery2['default']('#maintenance-takeover.active').length > 0) {
      var maintenanceId = _jquery2['default']('#maintenance-takeover.active').data('maintenance-id');
      if (!_jquery2['default'].cookie('hiabecom-maintenance-takeover' + maintenanceId)) {
        _jquery2['default']('#maintenance-takeover').css('display', 'table');
        _jquery2['default']('body').addClass('has-maintenance-takeover');
        _jquery2['default'].cookie('hiabecom-maintenance-takeover' + maintenanceId, '{}', { expires: 31, path: '/' });
      } else {
        var res = JSON.parse(_jquery2['default'].cookie('hiabecom-maintenance-takeover' + maintenanceId));
        if (res.approved) {
          _jquery2['default']('#maintenance-takeover').hide();
        } else {
          _jquery2['default']('#maintenance-takeover').css('display', 'table');
          // console.log('add class to body!');
          _jquery2['default']('body').addClass('has-maintenance-takeover');
        }
      }
    }
  },

  closeCookie: function closeCookie() {

    var okButton = document.querySelector('.jsCookiesBtn');
    var maintenanceBannerButton = document.querySelector('.maintenance-banner-btn');
    var maintenanceTakeoverButton = document.querySelector('.maintenance-takeover-btn');

    if (okButton) {
      'click touchmove touchend touchleave touchcancel'.split(' ').forEach(function (event) {
        okButton.addEventListener(event, function (e) {
          e.preventDefault();
          var res = JSON.parse(_jquery2['default'].cookie('hiabecom-cookie'));
          _jquery2['default'].removeCookie('hiabecom-cookie', { path: '/' });
          res.approved = true;
          _jquery2['default'].cookie('hiabecom-cookie', JSON.stringify(res), { expires: 31, path: '/' });
          _jquery2['default']('.jsCookies').hide();
        });
      });
    }

    if (maintenanceBannerButton) {
      (function () {
        var maintenanceId = _jquery2['default']('#maintenance-banner').data('maintenance-id');

        'click touchmove touchend touchleave touchcancel'.split(' ').forEach(function (event) {
          maintenanceBannerButton.addEventListener(event, function (e) {
            e.preventDefault();
            var res = JSON.parse(_jquery2['default'].cookie('hiabecom-maintenance' + maintenanceId));
            _jquery2['default'].removeCookie('hiabecom-maintenance' + maintenanceId, { path: '/' });
            res.approved = true;
            _jquery2['default'].cookie('hiabecom-maintenance' + maintenanceId, JSON.stringify(res), { expires: 31, path: '/' });
            _jquery2['default']('#maintenance-banner').hide();
          });
        });
      })();
    }

    if (maintenanceTakeoverButton) {
      (function () {
        var maintenanceId = _jquery2['default']('#maintenance-takeover.active').data('maintenance-id');

        'click touchmove touchend touchleave touchcancel'.split(' ').forEach(function (event) {
          maintenanceTakeoverButton.addEventListener(event, function (e) {
            e.preventDefault();
            var res = JSON.parse(_jquery2['default'].cookie('hiabecom-maintenance-takeover' + maintenanceId));
            _jquery2['default'].removeCookie('hiabecom-maintenance-takeover' + maintenanceId, { path: '/' });
            res.approved = true;
            _jquery2['default'].cookie('hiabecom-maintenance-takeover' + maintenanceId, JSON.stringify(res), { expires: 31, path: '/' });
            _jquery2['default']('#maintenance-takeover').hide();
            _jquery2['default']('body').removeClass('has-maintenance-takeover');
          });
        });
      })();
    }
  }

};

exports['default'] = cookie;
module.exports = exports['default'];

},{"jquery":628,"jquery.cookie":625}],671:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var CustomEvents = {
  init: function init() {

    _jquery2['default'](document).ready(function () {
      initEvents();
    });
  },
  triggerDataLayerPush: function triggerDataLayerPush(object) {
    if (hiabconfig.EnableGoogleTagManager) {
      dataLayer.push(object);
    }
  },
  triggerWindowDataLayerPush: function triggerWindowDataLayerPush(object) {
    if (hiabconfig.EnableGoogleTagManager) {
      window.dataLayer.push(object);
    }
  },
  triggerLoginEvent: function triggerLoginEvent(body) {
    if (!window.dataLayer) return false;

    var commonContext = JSON.parse(body.CommonContext);

    CustomEvents.triggerDataLayerPush({
      'event': 'trackLoginEvent',
      'commonContext': commonContext
    });
  },
  triggerLogoutEvent: function triggerLogoutEvent(body) {
    if (!window.dataLayer) return false;

    CustomEvents.triggerDataLayerPush({
      'event': 'trackLogoutEvent',
      'commonContext': body.CommonContext
    });
  },
  triggerSliderAdImpressionEvent: function triggerSliderAdImpressionEvent(el) {
    var slideImg = _jquery2['default'](el).find('.active').find('.slide-img'),
        bannerId = slideImg.data('banner-id'),
        zoneId = slideImg.data('zone-id'),
        bannerName = slideImg.data('banner-name'),
        bannerType = slideImg.data('banner-type'),
        bannerInstance = slideImg.data('banner-instance');

    CustomEvents.triggerDataLayerPush({
      'event': 'trackAdImpression',
      'adContext': {
        "banner_name": bannerName,
        "banner_type": bannerType,
        "banner_instance": bannerInstance },
      'bannerId': bannerId,
      'zoneId': zoneId
    });
  },
  triggerSliderAdClickEvent: function triggerSliderAdClickEvent(e) {
    var el = _jquery2['default'](e.target),
        sliderImg = el.parents('.slide-img'),
        bannerId = sliderImg.data('banner-id'),
        zoneId = sliderImg.data('zone-id'),
        bannerName = sliderImg.data('banner-name'),
        bannerType = sliderImg.data('banner-type'),
        bannerInstance = sliderImg.data('banner-instance');

    CustomEvents.triggerDataLayerPush({
      'event': 'trackAdClick',
      'adContext': { "banner_name": bannerName, "banner_type": bannerType, "banner_instance": bannerInstance },
      'bannerId': bannerId,
      'zoneId': zoneId
    });
  },
  triggerImpersonationStartEvent: function triggerImpersonationStartEvent(body) {
    CustomEvents.triggerDataLayerPush({
      'event': 'impersonationStart',
      'category': 'admin',
      'action': 'impersonate',
      'label': body.CustomerName,
      'value': body.CustomerId
    });
  },
  addToCartEvent: function addToCartEvent(products, cart, productContext) {
    for (var i = 0; i < products.length; i++) {
      var product = products[i];

      var trackingEvent = product.Updated ? 'modifyCart' : 'addToCartEvent';
      CustomEvents.triggerWindowDataLayerPush({
        'event': trackingEvent,
        'cartContext': {
          sku: product.Code,
          name: product.DisplayName,
          category: hiabconfig.tracking.category,
          netPrice: product.PlacedPrice,
          old_quantity: product.OldQuantity,
          quantity: product.Quantity + product.OldQuantity,
          currency: cart.Currency,
          cartContent: cart.CartItems,
          cartId: cart.CartId
        },
        'productContext': productContext
      });
    }
  },
  triggerAddToCartBatchEvent: function triggerAddToCartBatchEvent(products, cart) {
    batchCartEvent(cart, 'batchAddToCart', 'addtocart');
  },
  triggerQuickBuyBatchEvent: function triggerQuickBuyBatchEvent(products, cart) {
    batchCartEvent(cart, 'batchQuickbuy', 'quickbuy');
  },
  loadCartEvent: function loadCartEvent(response) {
    CustomEvents.triggerWindowDataLayerPush({
      'event': 'loadCart',
      'cartContext': {
        cartContent: response.Cart.CartItems,
        cartId: response.Cart.CartId
      },
      'category': 'minicart'
    });
  },
  loadCartEventCheckout: function loadCartEventCheckout(cartContent, cartId) {

    CustomEvents.triggerWindowDataLayerPush({
      'event': 'loadCart',
      'cartContext': {
        cartContent: cartContent,
        cartId: cartId
      },
      'category': 'checkout'
    });
  },
  clearCartEvent: function clearCartEvent(cartContent, cartId) {
    CustomEvents.triggerWindowDataLayerPush({
      'event': 'clearCart',
      'cartContext': {
        cartContent: cartContent,
        cartId: cartId
      },
      'category': 'minicart'
    });
  },
  modifyCartEvent: function modifyCartEvent(response) {
    var line = getLine(response.Cart.CartItems, response.ProductContext.PartNumber);
    CustomEvents.triggerWindowDataLayerPush({
      'event': 'modifyCart',
      'cartContext': {
        sku: line.Code,
        name: line.DisplayName,
        category: 'minicart',
        netPrice: line.PlacedPrice,
        old_quantity: response.OldQuantity,
        quantity: line.Quantity,
        currency: response.Cart.Currency,
        cartContent: response.Cart.CartItems,
        cartId: response.Cart.CartId
      },
      'productContext': response.ProductContext,
      'category': 'minicart'
    });
  },
  deleteCartEvent: function deleteCartEvent(response) {
    var line = response.DeletedLine;
    CustomEvents.triggerWindowDataLayerPush({
      'event': 'modifyCart',
      'cartContext': {
        sku: line.Code,
        name: line.DisplayName,
        category: 'minicart',
        netPrice: line.PlacedPrice,
        old_quantity: line.Quantity,
        quantity: 0,
        currency: response.Cart.Currency,
        cartContent: response.Cart.CartItems,
        cartId: response.Cart.CartId
      },
      'productContext': response.ProductContext,
      'category': 'minicart'
    });
  },
  modifyCartEventFromCheckout: function modifyCartEventFromCheckout(res) {
    var trackingData = res.TrackingData;
    var cartContext = JSON.parse(trackingData.CartContext);

    cartContext.cartId = trackingData.CartId;
    cartContext.cartContent = trackingData.CartContent;

    CustomEvents.triggerWindowDataLayerPush({
      'event': 'modifyCart',
      'cartContext': cartContext,
      'productContext': trackingData.ProductContext,
      'category': 'checkout'
    });
  },
  batchUpload: function batchUpload(data) {
    var materials = [];
    _jquery2['default'].each(data.result.Buyables, function (index, value) {
      materials.push(value.MaterialId);
    });
    CustomEvents.triggerWindowDataLayerPush({
      'batchImportContext': {
        'row_count': data.result.Buyables.length + data.result.Errors.length,
        'fail_count': data.result.Errors.length,
        'import_count': data.result.Buyables.length,
        'file_type': data.files[0].name.includes('.xls') ? 'Excel' : 'CSV',
        'materials': materials
      },
      'customStructuredEvent': {
        'category': 'batch',
        'action': 'import'
      }
    });
  },
  batchAddRow: function batchAddRow(orderline) {
    CustomEvents.triggerWindowDataLayerPush({
      'customStructuredEvent': {
        'Category': 'batch',
        'Action': 'add',
        'Label': orderline.material,
        'Value': orderline.quantity
      }
    });
  },
  batchRemoveRow: function batchRemoveRow(id) {
    CustomEvents.triggerWindowDataLayerPush({
      'customStructuredEvent': {
        'Category': 'batch',
        'Action': 'remove',
        'Label': id
      }
    });
  },
  confirmationPageAddTrans: function confirmationPageAddTrans(order) {
    var transactionProducts = [];
    for (var i = 0; i < order.items.length; i++) {
      var item = order.items[i];
      transactionProducts.push(confirmationPageAddItem(item));
    }

    CustomEvents.triggerWindowDataLayerPush({
      'event': 'orderConfirmation',
      'transactionId': order.orderId,
      'transactionAffiliation': '',
      'transactionTotal': order.total,
      'transactionTax': '',
      'transactionShipping': order.shipping,
      'transactionCity': order.city,
      'transactionCountry': order.country,
      'transactionState': order.state,
      'currency': order.currency,
      'orderContext': {
        'shipping_option': order.shipping_option,
        'priority': order.priority,
        'delivery_date': order.delivery_date,
        'order_promotion': order.order_promotion,
        'plant': order.plant
      },
      'transactionProducts': transactionProducts
    });
  }
};
function getLine(lines, code) {
  for (var i = 0; i < lines.length; i++) {
    if (lines[i].Code === code) {
      return lines[i];
    }
  }
  return null;
}
function getSearchParam() {
  var sPageURL = decodeURIComponent(window.location.search.substring(1)),
      sURLVariables = sPageURL.split('&'),
      sParameterName,
      i;

  for (i = 0; i < sURLVariables.length; i++) {
    sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] === 'query') {
      return sParameterName[1];
    }
  }
}
function batchCartEvent(cart, eventName, actionName) {
  var batchQuickBuyContexts = cart.BatchQuickBuyContexts;

  for (var i = 0; i < batchQuickBuyContexts.length; i++) {

    var item = batchQuickBuyContexts[i];

    var batchQuickbuyContext = {
      price_gross: item.PriceGross,
      price_net: item.PriceNet,
      part_business_area: item.PartBusinessArea,
      part_description: item.PartDescription,
      part_number: item.PartNumber,
      part_product_line: item.PartProductLine,
      has_price: item.HasPrice,
      is_buyable: item.IsBuyable,
      quantity: item.Quantity,
      available_quantity: item.AvailableQuantity,
      cartContent: cart.CartItems,
      cartId: cart.CartId
    };

    var batchEvent = {
      'event': eventName,
      'batchQuickbuyContext': batchQuickbuyContext
    };

    CustomEvents.triggerWindowDataLayerPush(batchEvent);
  }
}
function confirmationPageAddItem(order) {
  return {
    'orderId': order.order,
    'sku': order.sku,
    'name': order.name,
    'price': order.price,
    'quantity': order.quantity,
    'orderLineContext': {
      'line_promotion': order.line_promotion,
      'available_quantity': order.available_quantity,
      'price_gross': order.price_gross,
      'price_net': order.price_net,
      'part_business_area': order.part_business_area,
      'part_product_line': order.part_business_area
    }
  };
}
function initEvents() {

  if (_jquery2['default']('.jsImageTextBlock').length !== 0) {
    _jquery2['default']('.jsTrackImageTextBlockAdClick').on('click', function (e) {
      var el = _jquery2['default'](e.target),
          parent = el.parents('.jsImageTextBlock'),
          bannerId = parent.data('banner-id'),
          zoneId = parent.data('zone-id'),
          bannerName = parent.data('banner-name'),
          bannerType = parent.data('banner-type'),
          bannerInstance = parent.data('banner-instance');

      CustomEvents.triggerDataLayerPush({
        'event': 'trackAdClick',
        'adContext': {
          'banner_name': bannerName,
          'banner_type': bannerType,
          'banner_instance': bannerInstance
        },
        'bannerId': bannerId,
        'zoneId': zoneId
      });

      return true;
    });
  }

  if (_jquery2['default']('.product-detailpage').length !== 0 && window.location.href.indexOf("query") > -1) {
    CustomEvents.triggerDataLayerPush({
      'event': 'SearchLinkClick',
      'elementUrl': window.location.href,
      'elementContent': getSearchParam()
    });
  }
}
exports['default'] = CustomEvents;
module.exports = exports['default'];

},{"jquery":628}],672:[function(require,module,exports){
'use strict';

exports.__esModule = true;
var CustomSearchEvents = {
	init: function init() {},
	triggerDataLayerPush: function triggerDataLayerPush(object) {
		if (hiabconfig.EnableGoogleTagManager) {
			dataLayer.push({ object: object });
		}
	},
	trackFullSearch: function trackFullSearch(searchTerm, responseBody) {
		var searchResult = "";
		if (typeof responseBody.lightSparePartViewModel != 'undefined') {
			searchResult = responseBody.lightSparePartViewModel.matching;
		} else {
			searchResult = responseBody.matching;
		}
		CustomSearchEvents.triggerDataLayerPush({
			'event': 'trackSearchEvent',
			'SearchTerms': [searchTerm],
			'SearchFilters': { 'searchType': 'full' },
			'SearchResult': searchResult,
			'SearchResultOnFirstPage': typeof responseBody.lightSparePartViewModel != 'undefined' ? responseBody.lightSparePartViewModel.items.length : responseBody.items.length
		});
	},
	trackQuickSearch: function trackQuickSearch(searchTerm, searchResult, results) {
		var searchResultOnFirstPage = 0;
		for (var i = 0; i < results.length; i++) {
			searchResultOnFirstPage = searchResultOnFirstPage + results[i].results.length;
		}

		CustomSearchEvents.triggerDataLayerPush({
			'event': 'trackSearchEvent',
			'SearchTerms': [searchTerm],
			'SearchFilters': { 'searchType': 'quick' },
			'SearchResult': searchResult,
			'SearchResultOnFirstPage': searchResultOnFirstPage
		});
	},
	trackFullSearchPageLoad: function trackFullSearchPageLoad() {
		if (document.getElementById('jsSearchPageTrackingData')) {
			var dataElement = document.getElementById('jsSearchPageTrackingData'),
			    trackingData = JSON.parse(dataElement.dataset.searchTrackingData);

			window.dataLayer.push({
				'event': 'trackSearchEvent',
				'SearchTerms': trackingData.searchTerms,
				'SearchFilters': { 'searchType': 'full' },
				'SearchResult': trackingData.searchResult,
				'SearchResultOnFirstPage': trackingData.searchResultOnFirstPage
			});
		}
	}

};

exports['default'] = CustomSearchEvents;
module.exports = exports['default'];

},{}],673:[function(require,module,exports){
'use strict';

;(function ($) {
	$.fn.fdatepicker.dates['hiab'] = {
		days: hiabconfig.datepicker.lang.days,
		daysShort: hiabconfig.datepicker.lang.daysMin,
		daysMin: hiabconfig.datepicker.lang.daysMin,
		months: hiabconfig.datepicker.lang.months,
		monthsShort: hiabconfig.datepicker.lang.monthsShort,
		today: hiabconfig.datepicker.lang.today,
		clear: hiabconfig.datepicker.lang.clear,
		weekStart: hiabconfig.datepicker.lang.weekStart,
		format: hiabconfig.datepicker.lang.format
	};
})(jQuery);

},{}],674:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _foundationDatepicker = require('foundation-datepicker');

var _foundationDatepicker2 = _interopRequireDefault(_foundationDatepicker);

var format = hiabconfig.datepicker.lang.format;

var foundationdatepicker = {

	init: function init() {

		if (format.replace(/[^m]/g, "").length < 2) {
			var string = format.replace('m', 'mm');
			format = string;
		}

		if (format.replace(/[^d]/g, "").length < 2) {
			var string = format.replace('d', 'dd');
			format = string;
		}

		var checkin = _jquery2['default']('#datefrom').fdatepicker({
			language: 'hiab',
			format: format
		}).on('changeDate', function (ev) {
			_jquery2['default']('#dateto')[0].focus();
		}).data('datepicker');

		var checkout = _jquery2['default']('#dateto').fdatepicker({
			language: 'hiab',
			format: format
		}).on('changeDate', function (ev) {
			checkout.hide();
		}).data('datepicker');
	}
};

exports['default'] = foundationdatepicker;
module.exports = exports['default'];

},{"foundation-datepicker":621,"jquery":628}],675:[function(require,module,exports){
'use strict';

exports.__esModule = true;
var detectVendor = {

	init: function init() {
		if (navigator.appVersion.indexOf('MSIE') != -1 || detectVendor.isIE10() || detectVendor.isIE6() || detectVendor.isIE11()) {
			document.documentElement.className += ' ie';
		}
		// if (window.navigator.msPointerEnabled && navigator.msMaxTouchPoints > 0) {
		// 	document.documentElement.className += ' surface';
		// }

		if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
			document.documentElement.className += ' iOS';
		}
		var version = detectVendor.getBrowser();
		document.documentElement.className += ' ' + version[0] + ' ' + version[0] + '-' + version[1];
	},
	getBrowser: function getBrowser() {
		var ua = navigator.userAgent,
		    tem,
		    M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
		if (/trident/i.test(M[1])) {
			tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
			return 'IE ' + (tem[1] || '');
		}
		if (M[1] === 'Chrome') {
			tem = ua.match(/\b(OPR|Edge)\/(\d+)/);
			if (tem != null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
		}
		M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
		if ((tem = ua.match(/version\/(\d+)/i)) != null) M.splice(1, 1, tem[1]);
		return M;
	},

	isIE6: function isIE6() {
		if (/\bMSIE 6/.test(navigator.userAgent) && !window.opera) {
			return true;
		} else {
			return false;
		}
	},

	isIE7: function isIE7() {
		if (navigator.appVersion.indexOf('MSIE 7.') != -1) {
			return true;
		} else {
			return false;
		}
	},

	isIE8: function isIE8() {
		if (navigator.appVersion.indexOf('MSIE 8.') != -1) {
			return true;
		} else {
			return false;
		}
	},

	isIE9: function isIE9() {
		if (navigator.appVersion.indexOf('MSIE 9.') != -1) {
			return true;
		} else {
			return false;
		}
	},

	isIE10: function isIE10() {
		if ( /*@cc_on!@*/false && document.documentMode === 10) {
			return true;
		} else {
			return false;
		}
	},

	isIE11: function isIE11() {
		if (!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)) {
			return true;
		} else {
			return false;
		}
	},
	isEdge: function isEdge() {
		if (!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)) {
			return true;
		} else {
			return false;
		}
	}
};

exports['default'] = detectVendor;
module.exports = exports['default'];

},{}],676:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryCookie = require('jquery.cookie');

var _jqueryCookie2 = _interopRequireDefault(_jqueryCookie);

var _customEvents = require('./custom-events');

var _customEvents2 = _interopRequireDefault(_customEvents);

var model = {};
var serialNo = "";
var data = {};

var fitsMyMachine = {
    init: function init() {
        this.howToFindSerialNoTrigger = _jquery2['default']('.how-to-find-serial-no');
        this.serialNoSearchTrigger = _jquery2['default']('#serialNoSearch');
        this.serialNumberInputTrigger = _jquery2['default']('#serialNo');
        this.enableClearButtonTrigger = _jquery2['default']('#clear');

        this.serialNoSearchTrigger.click(function () {
            fitsMyMachine.CreateMatchMachineModel();
        });
        //Open configure text dialog
        this.howToFindSerialNoTrigger.on('click', function () {
            _jquery2['default']('#how-to-find-serial-no-modal').foundation('reveal', 'open');
        });

        this.serialNumberInputTrigger.on('keyup', function (e) {
            var value = _jquery2['default'](this).val();
            _jquery2['default']('#clear').show();
            if (value != '' && value.length > 3 && value.length < 25) {
                _jquery2['default']('#serialNoSearch').prop('disabled', false);
            } else if (value == '') {
                _jquery2['default']('#clear').hide();
                _jquery2['default']('#serialNoSearch').prop('disabled', true);
            } else {
                _jquery2['default']('#serialNoSearch').prop('disabled', true);
            }

            if (e.which === 13 && value != '' && value.length > 3 && value.length < 25) {
                e.preventDefault();
                fitsMyMachine.CreateMatchMachineModel();
            }
        });

        _jquery2['default']('#clear').on('click', function () {
            _jquery2['default']('#serialNo').val('');
            _jquery2['default']('#clear').hide();
            fitsMyMachine.HideStatus();
            _jquery2['default']('.does-this-fit-my-machine .info').show();
            _jquery2['default']('#serialNoSearch').prop('disabled', true);
            _jquery2['default'].removeCookie('match-machine', { path: '/' });
            data = { inputClear: true };
            _customEvents2['default'].triggerWindowDataLayerPush(data);
        });

        if (this.serialNumberInputTrigger.length > 0) {
            var cookie = _jquery2['default'].cookie('match-machine');
            if (cookie != null && cookie.length > 0) {
                fitsMyMachine.CreateMatchMachineModel(cookie);
                fitsMyMachine.AddCookieValueToInput(cookie);
                data = { valueFromCookie: true };
                _customEvents2['default'].triggerWindowDataLayerPush(data);
            }
        }
    },

    AddCookieValueToInput: function AddCookieValueToInput(cookie) {
        if (cookie.length > 0) {
            _jquery2['default']('#serialNo').val(cookie);
            _jquery2['default']('#clear').show();
            _jquery2['default']('#serialNoSearch').prop('disabled', false);
        }
    },

    HideStatus: function HideStatus() {
        _jquery2['default']('.does-this-fit-my-machine .info').hide();
        _jquery2['default']('.does-this-fit-my-machine .unable-to-verify').hide();
        _jquery2['default']('.does-this-fit-my-machine .too-many-searches').hide();
        _jquery2['default']('.does-this-fit-my-machine .not-authenticated').hide();
        _jquery2['default']('.does-this-fit-my-machine .not-found').hide();
        _jquery2['default']('.does-this-fit-my-machine .verified').hide();
        _jquery2['default']('.does-this-fit-my-machine .validation-error').hide();
        _jquery2['default']('.does-this-fit-my-machine .error').hide();
        _jquery2['default']('.does-this-fit-my-machine .search').hide();
    },

    CreateMatchMachineModel: function CreateMatchMachineModel() {
        var serialNo = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0];

        var currentSerialNo = serialNo;

        if (currentSerialNo === "") {
            data = { valueFromCookie: false };
            _customEvents2['default'].triggerWindowDataLayerPush(data);
        }
        fitsMyMachine.HideStatus();
        _jquery2['default']('.does-this-fit-my-machine .search').show();

        model = {
            Code: _jquery2['default']("input[name=code]").val(),
            SerialNumber: currentSerialNo === "" ? _jquery2['default']("input[name=serialNo]").val() : currentSerialNo,
            Status: ""
        };
        if (model.SerialNumber === "") {
            _jquery2['default']('.does-this-fit-my-machine .search').hide();
            _jquery2['default']('.does-this-fit-my-machine .validation-error').show();
            return;
        }
        fitsMyMachine.MatchMachine(model);
    },

    MatchMachine: function MatchMachine(model) {
        _jquery2['default'].ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: '/api/serialnumbersearch/fitsmymachine',
            data: JSON.stringify(model),
            dataType: "json",
            success: function success(response) {
                if (response == null) {
                    _jquery2['default']('.does-this-fit-my-machine .search').hide();
                    _jquery2['default']('.does-this-fit-my-machine .error').show();
                } else {
                    _jquery2['default']('.does-this-fit-my-machine .search').hide();
                    var statusText = "";
                    if (response.Status === 1) {
                        _jquery2['default']('.does-this-fit-my-machine .not-found').show();
                        statusText = "Not found.";
                    } else if (response.Status === 2) {
                        _jquery2['default']('.does-this-fit-my-machine .verified').show();
                        statusText = "Verified.";
                    } else if (response.Status === 3) {
                        _jquery2['default']('.does-this-fit-my-machine .unable-to-verify').show();
                        statusText = "Unable to verify.";
                    } else if (response.Status === 4) {
                        _jquery2['default']('.does-this-fit-my-machine .validation-error').show();
                        statusText = "Validation error.";
                    } else if (response.Status === 5) {
                        _jquery2['default']('.does-this-fit-my-machine .too-many-searches').show();
                        statusText = "Too many searches.";
                    } else if (response.Status === 6) {
                        _jquery2['default']('.does-this-fit-my-machine .not-authenticated').show();
                        statusText = "Not authenticated.";
                    }
                    _jquery2['default'].cookie('match-machine', response.SerialNumber, { path: '/' });
                }
                data = { Status: response.Status, SerialNumber: response.SerialNumber, Code: response.Code, StatusText: statusText };
                console.log(statusText);
                _customEvents2['default'].triggerWindowDataLayerPush(data);
            },
            error: function error() {
                _jquery2['default']('.does-this-fit-my-machine .search').hide();
                _jquery2['default']('.does-this-fit-my-machine .error').show();
                data = { Status: null, SerialNumber: null, Code: null, StatusText: "Unexprexted error." };
                _customEvents2['default'].triggerWindowDataLayerPush(data);
            }
        });
    }
};

exports['default'] = fitsMyMachine;
module.exports = exports['default'];

},{"./custom-events":671,"jquery":628,"jquery.cookie":625}],677:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var IEequalizerFix = {

  init: function init() {
    var ua = window.navigator.userAgent;
    var trident = ua.indexOf('Trident/');
    var msie = ua.indexOf('MSIE ');

    if (msie > 0 || trident > 0) {
      (function () {
        var resultSpareParts = _jquery2['default']('.result-spare-parts').length > 0 ? true : false;
        var ucProductlist = _jquery2['default']('.uc-productlist').length > 0 ? true : false;
        var ucProductlistUl = _jquery2['default']('.uc-productlist ul').length > 0 ? true : false;
        var itemNameWatch = _jquery2['default']('.item-name-watch').length > 0 ? true : false;
        var amountpPriceStock = _jquery2['default']('.amount-price-stock-watch').length > 0 ? true : false;

        if (ucProductlistUl || ucProductlist) {
          Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist ul'));
          Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist'));
          Foundation.libs.equalizer.equalize(_jquery2['default']('.amount-price-stock-watch'));
        }

        _jquery2['default'](window).on('resize', function () {
          // console.log('resize');
          if (resultSpareParts) {
            // console.log('result-spare-parts');
            Foundation.libs.equalizer.equalize(_jquery2['default']('.result-spare-parts'));
          }

          if (ucProductlistUl) {
            // console.log('uc-campaing-block ul');
            Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist ul'));
          }

          if (ucProductlist) {
            // console.log('uc-productlist');
            Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist'));
          }

          if (amountpPriceStock) {
            // console.log('amountpPriceStock');
            Foundation.libs.equalizer.equalize(_jquery2['default']('.amount-price-stock-watch'));
          }
          if (itemNameWatch) {
            // console.log('itemNameWatch');
            Foundation.libs.equalizer.equalize(_jquery2['default']('.item-name-watch'));
          }
        });
      })();
    }
  }

};

// equalHeight: function(group) {
//   var tallest = 0;
//   group.each(function() {
//     $(this).css('height', 'auto');
//     var thisHeight = $(this).height();
//     console.log(thisHeight);
//     if (thisHeight > tallest) {
//       tallest = thisHeight;
//     }
//   });
//
//   group.height(tallest);
// }

exports['default'] = IEequalizerFix;
module.exports = exports['default'];

},{"jquery":628}],678:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var listviewtoggle = {
	init: function init() {
		//toggle listview layout
		_jquery2['default']('body').on('click', '.uc-layout-toggle button', function (e) {
			e.preventDefault();
			if (!_jquery2['default'](this).hasClass('active')) {
				_jquery2['default']('.uc-layout-toggle button').removeClass('active');
				_jquery2['default'](this).addClass('active');
			}
			if (_jquery2['default'](this).is("#grid")) {
				_jquery2['default']('.uc-productlist ul').removeClass('list');
				var ua = window.navigator.userAgent;
				var trident = ua.indexOf('Trident/');
				var msie = ua.indexOf('MSIE ');

				if (msie > 0 || trident > 0) {
					Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist ul'));
					Foundation.libs.equalizer.equalize(_jquery2['default']('.uc-productlist'));
					Foundation.libs.equalizer.equalize(_jquery2['default']('.amount-price-stock-watch'));
				} else {
					_jquery2['default'](document).foundation('equalizer', 'reflow');
				}
			} else {
				_jquery2['default']('.uc-productlist ul').addClass('list');
				_jquery2['default']('.item-name').css('height', 'auto');
				_jquery2['default']('.amount-price-stock').css('height', 'auto');
			}
		});

		//toggle uc-treemenu parents
		_jquery2['default']('body').on('click', '#categorylist .expand', function (e) {
			e.preventDefault();
			if (_jquery2['default'](this).parent().parent().hasClass('is-open')) {
				_jquery2['default'](this).parent().parent().removeClass('is-open');
			} else {
				_jquery2['default'](this).parent().parent().addClass('is-open');
			}
		});
	}
};

exports['default'] = listviewtoggle;
module.exports = exports['default'];

},{"jquery":628}],679:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryPanzoom = require('jquery.panzoom');

var _jqueryPanzoom2 = _interopRequireDefault(_jqueryPanzoom);

var panzoom = {

	panzoom: null,

	options: {
		minScale: 1,
		maxScale: 4,
		rangeStep: 0.1,
		contain: 'invert',
		easing: "ease-in-out"
	},

	init: function init(elm) {

		//$(".explodedview-zoom-container").panzoom('destroy');
		if (_jquery2['default']('.explodedview-zoom-container .aspect-ratio', elm).length > 0) {
			this.panzoom = _jquery2['default']('.explodedview-zoom-container .aspect-ratio', elm).panzoom(this.options);
			_jquery2['default']('.explodedview-zoom-container .aspect-ratio').panzoom('reset', false);

			_jquery2['default']('img').bind('contextmenu', function (e) {
				e.preventDefault();
				return false;
			});

			this.zoomControls();
			this.scrollWheelZoom();
			this.doublicklickZoom();
			this.resetDimensions();
		}
	},

	scrollWheelZoom: function scrollWheelZoom() {
		var _this = this;

		this.panzoom.on('mousewheel.focal', function (e) {
			e.preventDefault();
			var delta = e.delta || e.originalEvent.wheelDelta;

			var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
			_this.zoom(zoomOut, e, 0.01, false);
		});
	},

	zoomControls: function zoomControls() {
		var _this2 = this;

		_jquery2['default']('.zoom-in').on('click', function (e) {
			e.stopPropagation();
			e.preventDefault();
			_this2.zoom(false, null, 0.08, true);
		});
		_jquery2['default']('.zoom-out').on('click', function (e) {
			e.stopPropagation();
			e.preventDefault();
			_this2.zoom(true, null, 0.08, true);
		});
		_jquery2['default']('.zoom-reset').on('click', function (e) {
			e.stopPropagation();
			e.preventDefault();
			_this2.zoom("resetZoom", false);
			_this2.zoom("resetPan", false);
		});
	},

	doublicklickZoom: function doublicklickZoom() {
		var _this3 = this;

		this.panzoom.parent().on('dblclick', function (e) {
			e.preventDefault();
			e.stopPropagation();

			if (_jquery2['default'](e.target).is('.zoom')) return;

			_this3.zoom(false, e, 1, true);
		});
	},

	zoom: function zoom(zoomOut, focal, increment, animate) {
		this.panzoom.panzoom('zoom', zoomOut, {
			increment: increment,
			animate: animate,
			focal: focal
		});
	},

	resetDimensions: function resetDimensions() {
		var _this4 = this;

		_jquery2['default'](window).on('resize', function () {

			if (_this4.panzoom) {
				_this4.panzoom.panzoom('resetDimensions');
			}
		});
	}
};

exports['default'] = panzoom;
module.exports = exports['default'];

},{"jquery":628,"jquery.panzoom":627}],680:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var print = {
	init: function init() {
		_jquery2['default']('.print').on('click', function () {
			window.print();
			return false;
		});
	}
};
exports['default'] = print;
module.exports = exports['default'];

},{"jquery":628}],681:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _componentsSearchSpare_part_footer = require('../components/search/spare_part_footer');

var _componentsSearchSpare_part_footer2 = _interopRequireDefault(_componentsSearchSpare_part_footer);

var _actionsPrice_service_actions = require('../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesPrice_service_store = require('../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var ProductCardFooter = {
	init: function init() {
		var materials = [];
		_jquery2['default']('[data-footer-element]').each(function () {

			var materialNumber = _jquery2['default'](this).data('footer-element');
			var detailsUrl = _jquery2['default'](this).data('part-url');
			var gotScaledPrices = _jquery2['default'](this).data('got-scaled-prices').toLowerCase() == "true";
			var userIsDealer = _jquery2['default']('body.is-dealer').length > 0;
			var translations = hiabconfig.SparePartFooter.lang;
			_reactDom2['default'].render(_react2['default'].createElement(_componentsSearchSpare_part_footer2['default'], { isDealer: userIsDealer, materialNumber: materialNumber, gotScaledPrices: gotScaledPrices, url: detailsUrl, translations: translations }), _jquery2['default'](this)[0]);
			materials.push(materialNumber);
		});
		ProductCardFooter.fetchPrice(materials);
	},
	fetchPrice: function fetchPrice(materials) {
		var pricesInStore = _storesPrice_service_store2['default'].getPrices();
		var pricesInStoreCodes = pricesInStore.map(function (priceInStore) {
			return priceInStore.Code;
		});

		var resultItemsNotInPriceStore = materials.filter(function (resultItem) {
			return pricesInStoreCodes.indexOf(resultItem) < 0;
		});

		resultItemsNotInPriceStore.forEach(function (item) {
			_actionsPrice_service_actions2['default'].addMaterials(item);
		});
		_actionsPrice_service_actions2['default'].fetchPrices(hiabconfig.jsPriceBatchAmount);
	}
};

exports['default'] = ProductCardFooter;
module.exports = exports['default'];

},{"../_actions/price_service_actions":641,"../_stores/price_service_store":723,"../components/search/spare_part_footer":783,"jquery":628,"react":525,"react-dom":351}],682:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var productContains = {
	init: function init() {
		_jquery2['default']('.uc-product-contains:not(.kit)').each(function () {
			if (_jquery2['default'](this).find('ul').children().length > 11) {
				_jquery2['default'](this).addClass('has-more');
			}
		});
	}
};
exports['default'] = productContains;
module.exports = exports['default'];

},{"jquery":628}],683:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _ezPlus = require('ez-plus');

var _ezPlus2 = _interopRequireDefault(_ezPlus);

var _lightslider = require('lightslider');

var _lightslider2 = _interopRequireDefault(_lightslider);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesPrice_service_store = require('../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var setHeight = 0;
var nameHeight = 0;
var amtHeight = 0;
var productImages = null;

var productimagezoom = {
	init: function init() {
		_jquery2['default'](window).on("resize", function () {
			_jquery2['default']('.zoomContainer').remove();
			_jquery2['default']('#productImages .lslide.active img').ezPlus({
				responsive: true,
				zoomWindowPosition: 11,
				respond: [{
					range: '0-800',
					enabled: false
				}]
			});
			var width = _jquery2['default'](document).width();
			if (width <= 800) {
				productImages.refresh();
			}
		});

		productImages = _jquery2['default']('#productImages').lightSlider({
			repsonsive: true,
			gallery: true,
			item: 1,
			loop: false,
			slideMargin: 2,
			enableDrag: false,
			currentPagerPosition: 'left',
			vertical: true,
			verticalHeight: 261,
			vThumbWidth: 60,
			thumbMargin: 10,
			thumbItem: 4,
			adaptiveHeight: false,
			controls: false,
			responsive: [{
				breakpoint: 800,
				settings: {
					gallery: false,
					vertical: false,
					verticalHeight: 0,
					vThumbWidth: 0,
					thumbMargin: 10,
					thumbItem: 4,
					adaptiveHeight: true,
					enableDrag: true,
					currentPagerPosition: 'middle',
					mode: 'fade'
				}
			}],
			onSliderLoad: function onSliderLoad(el) {
				_jquery2['default']('img').bind('contextmenu', function (e) {
					e.preventDefault();
					return false;
				});
				_jquery2['default']('#productImages .lslide.active img').ezPlus({
					responsive: true,
					zoomWindowPosition: 11,
					respond: [{
						range: '0-800',
						enabled: false
					}]
				});
			},
			onBeforeSlide: function onBeforeSlide(el) {
				_jquery2['default']('img').bind('contextmenu', function (e) {
					e.preventDefault();
					return false;
				});
				_jquery2['default']('.zoomContainer').remove();
			},
			onAfterSlide: function onAfterSlide(el) {
				_jquery2['default']('img').bind('contextmenu', function (e) {
					e.preventDefault();
					return false;
				});
				_jquery2['default']('#productImages .lslide.active img').ezPlus({
					responsive: true,
					zoomWindowPosition: 11,
					respond: [{
						range: '0-800',
						enabled: false
					}]
				});
			}
		});

		// var productSlider = $('.productdetail-slider').lightSlider({
		// 	item:3,
		// 	loop:false,
		// 	slideMove:3,
		// 	slideMargin: 0,
		// 	speed: 700, //ms'
		//   auto: false,
		//   slideEndAnimation: true,
		// 	enableDrag: false,
		// 	adaptiveHeight: true,
		// 	responsive : [
		// 		{
		// 			breakpoint:1420,
		// 			settings: {
		// 				item:2,
		// 				slideMove:2,
		// 			}
		// 		},
		// 		{
		// 			breakpoint:970,
		// 			settings: {
		// 				item:1,
		// 				slideMove:1,
		// 			}
		// 		},
		// 		{
		// 			breakpoint:800,
		// 			settings: {
		// 				item:3,
		// 				slideMove:3,
		// 			}
		// 		},
		// 		{
		// 			breakpoint:700,
		// 			settings: {
		// 				item:2,
		// 				slideMove:2,
		// 			}
		// 		},
		// 		{
		// 			breakpoint:500,
		// 			settings: {
		// 				item:1,
		// 				slideMove:1,
		// 			}
		// 		}
		// 	],
		// 	onSliderLoad(el){
		// 		productimagezoom.reflow();
		// 	}
		// });

		// this.unsubscribe = PriceServiceStore.listen( () => {
		// 	setHeight = 0;
		// 	nameHeight = 0;
		// 	amtHeight = 0;
		// 	productimagezoom.reflow();
		// });
	}
};

// reflow(){
//
// 	var ua = window.navigator.userAgent;
// 	var trident = ua.indexOf('Trident/');
// 	var msie = ua.indexOf('MSIE ');
// 	if (msie > 0 || trident > 0) {
// 		Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
// 		Foundation.libs.equalizer.equalize($('.item-name-watch'));
// 	}else{
// 		$(document).foundation('equalizer','reflow');
// 	}
// 	$('.productdetail-slider li').each(function( index ) {
// 		if($(this).height() > setHeight){
// 			setHeight = $(this).height();
// 		}
// 		let itemName = $(this).children().find('.item-name');
// 		let amtItem = $(this).children().find('.footer').children('.amount-price-stock');
// 		if(itemName.height() > nameHeight){
// 			nameHeight = itemName.height();
// 		}
// 		if(amtItem.height() > amtHeight){
// 			amtHeight = amtItem.height();
// 		}
// 	});
//
// 	$('.productdetail-slider .item-name').height(nameHeight);
// 	$('.productdetail-slider .amount-price-stock').height(amtHeight);
// 	$('.productdetail-slider').height(setHeight);
// 	$('.uc-product-upsell .lSSlideWrapper').height(setHeight);
// }
exports['default'] = productimagezoom;
module.exports = exports['default'];

},{"../_stores/price_service_store":723,"ez-plus":620,"jquery":628,"lightslider":629,"react":525}],684:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var typingTimer = null;
var doneTypingInterval = 750;

var scaledPrices = {
	init: function init() {

		var scaledPrices = [];

		var $productInfoAmount = _jquery2['default']('.inner.uc-product-information .mainAmount');
		var $productInfoPrice = _jquery2['default']('.inner.uc-product-information .mainPrice');

		var $stickyInfoAmount = _jquery2['default']('.product-summary-sticky .mainAmount');
		var $stickyInfoPrice = _jquery2['default']('.product-summary-sticky .mainPrice');

		_jquery2['default']('.scaled-prices select option').each(function (index) {
			var rangeMin = _jquery2['default'](this).data('range-min');
			var rangeMax = _jquery2['default'](this).data('range-max');
			var price = _jquery2['default'](this).data('price');
			scaledPrices.push({ min: rangeMin, max: rangeMax, price: price, value: rangeMin });
		});

		_jquery2['default'](document).on('change', '.scaled-prices select', function () {
			var rangeMin = _jquery2['default'](this).find('option:selected').data('range-min');
			var price = _jquery2['default'](this).find('option:selected').data('price');

			$productInfoAmount[0].value = rangeMin;
			$productInfoAmount[0].defaultValue = rangeMin;
			$productInfoPrice[0].innerHTML = price;

			$stickyInfoAmount[0].value = rangeMin;
			$stickyInfoAmount[0].defaultValue = rangeMin;
			$stickyInfoPrice[0].innerHTML = price;

			animate();
		});

		_jquery2['default'](document).on('input', '.inner.uc-product-information .mainAmount', function () {
			var _this = this;

			if (typingTimer) clearTimeout(typingTimer);
			typingTimer = setTimeout(function () {
				updateInput(_this);
			}, doneTypingInterval);
		});

		_jquery2['default'](document).on('input', '.product-summary-sticky .mainAmount', function () {
			var _this2 = this;

			if (typingTimer) clearTimeout(typingTimer);
			typingTimer = setTimeout(function () {
				updateInput(_this2);
			}, doneTypingInterval);
		});

		function updateInput(el) {
			if (el.value !== el.defaultValue) {

				$stickyInfoAmount[0].value = el.value;
				$stickyInfoAmount[0].defaultValue = el.value;
				$productInfoAmount[0].value = el.value;
				$productInfoAmount[0].defaultValue = el.value;

				var prevValue = _jquery2['default']('.scaled-prices select').val();
				for (var i = 0; i < scaledPrices.length; i++) {
					if (el.value > scaledPrices[i].min || el.value == scaledPrices[i].min || el.value == scaledPrices[i].max) {
						$productInfoPrice[0].innerHTML = scaledPrices[i].price;
						$stickyInfoPrice[0].innerHTML = scaledPrices[i].price;
						_jquery2['default']('.scaled-prices select').val(scaledPrices[i].value);
					}
				}
				animate(prevValue);
			}
		}

		function animate(prevValue) {
			if (_jquery2['default']('.scaled-prices select').val() !== prevValue) {
				$productInfoPrice.removeClass().addClass('bounceIn' + ' animated' + ' mainPrice').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
					_jquery2['default'](this).removeClass();
					_jquery2['default'](this).addClass('mainPrice');
				});
				$stickyInfoPrice.removeClass().addClass('bounceIn' + ' animated' + ' mainPrice').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
					_jquery2['default'](this).removeClass();
					_jquery2['default'](this).addClass('mainPrice');
				});
			}
		}
	}
};

exports['default'] = scaledPrices;
module.exports = exports['default'];

},{"jquery":628}],685:[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var productAddToCart = "";
var productAddToCartOffset = 0;
var additionalNav = "";
var additionalNavOffset = 0;

var scrollcontrolsProductDetail = {
	init: function init() {
		productAddToCart = document.querySelector('section.uc-product-information .input-buttons');
		if (_jquery2["default"](productAddToCart).length > 0) {
			productAddToCartOffset = _jquery2["default"]('.uc-scrollcontrols-sticky').height();
			if (!scrollcontrolsProductDetail.isInViewport(productAddToCart, productAddToCartOffset)) {
				_jquery2["default"]('.product-summary-sticky .product-content').addClass('onscreen');
			}
		}

		additionalNav = document.querySelector('.additional-navigation-wrapper .additional-nav');
		if (_jquery2["default"](additionalNav).length > 0) {
			additionalNavOffset = _jquery2["default"]('.uc-scrollcontrols-sticky').height() + _jquery2["default"]('.product-summary-sticky .product-content').height() - _jquery2["default"]('.additional-navigation-wrapper .additional-nav').height();
			if (!scrollcontrolsProductDetail.isInViewport(additionalNav, additionalNavOffset)) {
				_jquery2["default"]('.product-summary-sticky nav').addClass('onscreen');
			}
		}
	},
	isInViewport: function isInViewport(elem, offset) {
		if (elem === 0 || elem === null || elem === "") {
			return;
		}
		var bounding = elem.getBoundingClientRect();
		return bounding.top >= offset;
	}
};
var scrollStop = function scrollStop(callback) {
	if (!callback || typeof callback !== 'function') return;
	var isScrolling;
	window.addEventListener('scroll', function (event) {
		window.clearTimeout(isScrolling);
		isScrolling = setTimeout(function () {
			callback();
		}, 33);
	}, false);
};
scrollStop(function () {
	if (!scrollcontrolsProductDetail.isInViewport(productAddToCart, productAddToCartOffset)) {
		_jquery2["default"]('.product-summary-sticky .product-content').addClass('onscreen');
	} else {
		_jquery2["default"]('.product-summary-sticky .product-content').removeClass('onscreen');
		_jquery2["default"]('.product-summary-sticky nav').removeClass('onscreen');
	}

	if (!scrollcontrolsProductDetail.isInViewport(additionalNav, additionalNavOffset)) {
		_jquery2["default"]('.product-summary-sticky nav').addClass('onscreen');
	} else {
		_jquery2["default"]('.product-summary-sticky nav').removeClass('onscreen');
	}
});

exports["default"] = scrollcontrolsProductDetail;
module.exports = exports["default"];

},{"jquery":628}],686:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryInview = require('jquery.inview');

var _jqueryInview2 = _interopRequireDefault(_jqueryInview);

var scrollcontrols = {
	init: function init() {

		var header = document.querySelector('.uc-siteheader');
		if (!scrollcontrols.isInViewport(header, 0)) {
			_jquery2['default']('.uc-scrollcontrols-sticky').addClass('onscreen');
			_jquery2['default']('body').addClass('onscreen');
		}
		_jquery2['default'](header).bind('inview', function (event, isInView) {
			if (isInView) {
				_jquery2['default']('.uc-scrollcontrols-sticky').removeClass('onscreen');
				_jquery2['default']('body').removeClass('onscreen');
				_jquery2['default']('.product-summary-sticky .product-content').removeClass('onscreen');
				_jquery2['default']('.product-summary-sticky nav').removeClass('onscreen');
			} else {
				_jquery2['default']('.uc-scrollcontrols-sticky').addClass('onscreen');
				_jquery2['default']('body').addClass('onscreen');
			}
		});
	},
	isInViewport: function isInViewport(elem, offset) {
		var bounding = elem.getBoundingClientRect();
		return bounding.top >= offset;
	}
};

exports['default'] = scrollcontrols;
module.exports = exports['default'];

},{"jquery":628,"jquery.inview":626}],687:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesSearch_result_store = require('../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var isProductPage = _jquery2['default']('.product-detailpage').length > 0;

var scrollto = {
	init: function init() {

		var offsetHeader = _jquery2['default']('.uc-scrollcontrols-sticky').height();
		var offsetProductSummary = _jquery2['default']('.product-summary-sticky').height();
		var additionalOffset = isProductPage ? -1 : 0;

		var offsetHeight = offsetHeader + offsetProductSummary + additionalOffset;

		_jquery2['default']('body').on('click', '[data-scroll-to]', function (e) {
			e.preventDefault();

			if (_jquery2['default']('.uc-order-detail').length > 0) {
				_jquery2['default']('.order-invoice').removeClass('invoice-selected');
				_jquery2['default'](_jquery2['default'](this).data('scroll-to')).addClass('invoice-selected');
			}

			_jquery2['default']('html, body').animate({
				scrollTop: _jquery2['default'](_jquery2['default'](this).data("scroll-to")).offset().top - offsetHeight
			});
		});

		var findserviceIsDown = _storesSearch_result_store2['default'].checkFindserviceIsDown();
		if (findserviceIsDown.pages || findserviceIsDown.spareParts) {
			_jquery2['default']('.price-manage-info').show();
			if (_jquery2['default'](window).scrollTop() > _jquery2['default']('.price-manage-info').offset().top) {
				_jquery2['default']('html, body').animate({
					scrollTop: _jquery2['default']('.price-manage-info').offset().top - offsetHeight
				}, 1000);
			}
		}

		_storesSearch_result_store2['default'].listen(function (searchStoreState) {
			var res = _storesSearch_result_store2['default'].checkFindserviceIsDown();
			if (res.pages || res.spareParts) {
				_jquery2['default']('.price-manage-info').show();
				if (_jquery2['default'](window).scrollTop() > _jquery2['default']('.price-manage-info').offset().top) {
					_jquery2['default']('html, body').animate({
						scrollTop: _jquery2['default']('.price-manage-info').offset().top - offsetHeight
					}, 1000);
				}
			} else {
				_jquery2['default']('.price-manage-info').hide();
			}
		});
	}
};

exports['default'] = scrollto;
module.exports = exports['default'];

},{"../_stores/search_result_store":725,"jquery":628}],688:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _componentsSearchSearch_field = require('../components/search/search_field');

var _componentsSearchSearch_field2 = _interopRequireDefault(_componentsSearchSearch_field);

var searchresult = {
	init: function init() {
		if (_jquery2['default']('#search-field').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_componentsSearchSearch_field2['default'], null), _jquery2['default']('#search-field')[0]);
		if (_jquery2['default']('#search-field-modal').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_componentsSearchSearch_field2['default'], null), _jquery2['default']('#search-field-modal')[0]);
	}

};

exports['default'] = searchresult;
module.exports = exports['default'];

},{"../components/search/search_field":781,"jquery":628,"react":525,"react-dom":351}],689:[function(require,module,exports){
"use strict";

exports.__esModule = true;
var selfregistration = {
	init: function init() {
		$('#jsRecaptchaError').hide();
		$("form").submit(function (event) {
			var recaptcha = $("#g-recaptcha-response").val();
			if (recaptcha === "") {
				event.preventDefault();
				$('#jsRecaptchaError').show();
			} else {
				$('#jsRecaptchaError').hide();
			}
			$("div[class^='sr-custom-error']").hide();
		});

		window.recaptchaChecked = function () {
			$('#jsRecaptchaError').hide();
		};

		$("input").focusout(function () {
			$(this).parent().nextAll('.sr-custom-error:first').hide();
		});

		$("#country").change(function () {
			$(this).parent().nextAll('.sr-custom-error:first').hide();
		});

		$('#btnAddSerialNumber').on('click', function () {
			addSerialNumber();
		});

		$('input#jsSerialNumber').on('input', function () {
			if ($(this).val() !== '') {
				$("#btnAddSerialNumber").removeAttr("disabled");
			} else {
				$("#btnAddSerialNumber").attr("disabled", "true");
			}
		});

		function addSerialNumber() {
			$('.sr-custom-error__serialnumbers').hide();
			var serialNumbers = $('input#jsSerialNumber').val();
			var serialNumber = $('input#jsSerialNumber').val();
			var regExp = new RegExp("^(?!.*--)[a-zA-Z0-9,-\\s]+$");
			if (!regExp.test(serialNumber)) {
				return;
			}

			if (!validateSerialNumbersLength(serialNumbers)) {
				return;
			}

			var serialNumbersArr = serialNumbers.split(",");
			serialNumbersArr.forEach(function (serialNumber) {
				serialNumber = serialNumber.trim();
				if (serialNumber === '') {
					return;
				}
				addSerialModel();
				var index = $("#jsSerialNumberList").children("li").length;
				var indexField = "<input type='hidden' name='SerialNumbers.Index' value='" + index + "' />";
				var hiddenValueField = "<input type='hidden' id='SerialNumbers_" + index + "__Name' name='FormModel.SerialNumbers[" + index + "].Value' value='" + serialNumber + "' />";
				var visibleValue = "<span class='sr-serial-number__remove-button-wrap'>" + serialNumber + "<input id='btnRemoveSerialNumber' class='sr-serial-number__remove-button' type='button' onclick='removeSerialNumber(" + index + ");' /></span>";
				var listItem = "<li id='jsSerialNumber" + index + "' class='sr-serial-number__item'>" + indexField + hiddenValueField + visibleValue + "</li>";
				$('#jsSerialNumberList').append(listItem);
			});
			$('input#jsSerialNumber').val("");
		}

		function validateSerialNumbersLength(serialNumbers) {
			$('#jsSerialModelError').hide();
			var serialNumbersFormatted = serialNumbers.replace(/\s/g, '');
			serialNumbers.replace(',', '');
			if (serialNumbersFormatted.length > 1000) {
				$('.sr-custom-error__serialnumbers').show();
				return false;
			}

			var existingSerialsLength = 0;
			$("li.sr-serial-number__item").each(function () {
				existingSerialsLength += $(this).text() !== undefined ? $(this).text().trim().length : 0;
			});

			if (existingSerialsLength + serialNumbersFormatted.length > 1000) {
				$('.sr-custom-error__serialnumbers').show();
				return false;
			}
			return true;
		}

		window.removeSerialNumber = function (index) {
			var serialToBeRemoved = "li#jsSerialNumber" + index;
			$(serialToBeRemoved).remove();
			var serialNumbers = $('input#jsSerialNumber').val();
			validateSerialNumbersLength(serialNumbers);
		};
	}
};

exports["default"] = selfregistration;
module.exports = exports["default"];

},{}],690:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _semanticUiTransition = require('semantic-ui-transition');

var _semanticUiTransition2 = _interopRequireDefault(_semanticUiTransition);

var _semanticUiDropdown = require('semantic-ui-dropdown');

var _semanticUiDropdown2 = _interopRequireDefault(_semanticUiDropdown);

var semanticdropdown = {
	init: function init() {
		if (_jquery2['default']('.ui.dropdown.selectbox').length > 0) {
			_jquery2['default']('.ui.dropdown').dropdown();
		}
	}
};

exports['default'] = semanticdropdown;
module.exports = exports['default'];

},{"jquery":628,"semantic-ui-dropdown":630,"semantic-ui-transition":631}],691:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _clipboard = require('clipboard');

var _clipboard2 = _interopRequireDefault(_clipboard);

// import dropdown from 'dropdown';

var share = {
	init: function init() {
		if (_jquery2['default']('.share-modal .email-container').length > 0) {
			share.renderEmailSearch();
		}
		var clip = new _clipboard2['default']('.copy-url');
		clip.on('success', function (e) {
			share.animateShareButton(e.trigger, true);
		});

		clip.on('error', function (e) {
			share.animateShareButton(e.trigger, false);
		});

		_jquery2['default']('body').on('click', '[data-share-type="email"]', function (e) {
			_jquery2['default']('.share-modal').addClass('email-share-open');
		});
		_jquery2['default']('body').on('click', '.email-container .back', function (e) {
			_jquery2['default']('.share-modal').removeClass('email-share-open');
		});
		_jquery2['default']('body').on('click', '.email-container .send', function (e) {
			_jquery2['default']('.email-container').addClass('is-loading');
			_jquery2['default'](this).addClass('is-loading');
		});
	},
	animateShareButton: function animateShareButton(el, didSucceed) {
		if (didSucceed) {
			_jquery2['default'](el).addClass('share-success');
			setTimeout(function () {
				_jquery2['default'](el).removeClass('share-success');
				_jquery2['default'](el).addClass('share-done');
			}, 1500);
			setTimeout(function () {
				_jquery2['default'](el).removeClass('share-done');
			}, 7500);
		} else {
			// TODO: do something for the error
		}
	},
	renderEmailSearch: function renderEmailSearch() {
		_jquery2['default']('.email-container .ui.dropdown').dropdown({
			fullTextSearch: true,
			allowAdditions: true,
			message: {
				addResult: '#!Send to: <b>{term}</b>'
			},
			onChange: function onChange(value, text, $choice) {
				var btn = _jquery2['default'](this).parent().find('button');
				btn.prop('disabled', share.validateAsEmail(value));
			},
			onAdd: function onAdd(addedValue, addedText, $addedChoice) {
				var btn = _jquery2['default'](this).parent().find('button');
				btn.prop('disabled', share.validateAsEmail(addedValue));
			}
		});
	},
	validateAsEmail: function validateAsEmail(value) {
		var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
		return !re.test(value);
	}

};

exports['default'] = share;
module.exports = exports['default'];

},{"clipboard":619,"jquery":628}],692:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _lightslider = require('lightslider');

var _lightslider2 = _interopRequireDefault(_lightslider);

var _customEvents = require('./custom-events');

var _customEvents2 = _interopRequireDefault(_customEvents);

var startpageslider = {
	init: function init() {
		var slider = _jquery2['default']("#startpage-slider").lightSlider({
			item: 1,
			slideMove: 1,
			slideMargin: 0,
			speed: 700, //ms'
			auto: true,
			loop: true,
			pauseOnHover: true,
			pause: 5000,
			controls: false,
			repsonsive: true,
			onSliderLoad: function onSliderLoad(el) {
				_customEvents2['default'].triggerSliderAdImpressionEvent(el);
			},
			onAfterSlide: function onAfterSlide(el) {
				_customEvents2['default'].triggerSliderAdImpressionEvent(el);
			}
		});

		_jquery2['default']('.jsTrackAdClick').on('click', function (e) {
			_customEvents2['default'].triggerSliderAdClickEvent(e);
			return true;
		});

		_jquery2['default']('body').on('click', '#slider-play', function (e) {
			slider.play();
			_jquery2['default'](this).hide();
			_jquery2['default']('#slider-pause').show();
		});
		_jquery2['default']('body').on('click', '#slider-pause', function (e) {
			slider.pause();
			_jquery2['default'](this).hide();
			_jquery2['default']('#slider-play').show();
		});
	}
};

exports['default'] = startpageslider;
module.exports = exports['default'];

},{"./custom-events":671,"jquery":628,"lightslider":629}],693:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var toggler = {
	init: function init() {
		this.bindEvents();
		_jquery2['default']('html').click(function (e) {
			if (_jquery2['default']('.uc-language-selector').hasClass('is-open')) {
				if (_jquery2['default'](e.target).data('toggle') != '.uc-language-selector') {
					_jquery2['default']('.uc-language-selector').removeClass('is-open');
				}
			}
		});
	},

	// bindEvents(i, togglerElm) {
	bindEvents: function bindEvents() {
		var self = this;
		_jquery2['default']('body').on('click', '[data-toggle]', function (e) {
			e.preventDefault();
			var slideElm = _jquery2['default'](this).attr('data-toggle-slide');

			if (slideElm) {
				self.slideToggle(slideElm);
			}

			self.setStates(this, _jquery2['default'](this).attr('data-toggle'));

			//Set focus element
			self.setFocus(_jquery2['default'](this).attr('data-toggle-setfocusto'));
		});
	},

	setStates: function setStates(el, obj) {
		var $el = _jquery2['default'](el);
		var $spanShow = $el.find("span.show");
		var $spanHide = $el.find("span.hide");

		var $obj = undefined;
		if (obj.length > 0) {
			$obj = obj == 'parent' ? $el.parent() : _jquery2['default'](obj);
		}
		if ($obj.is('.is-open')) {
			$el.removeClass('is-open');
			$obj.removeClass('is-open');
			if ($spanHide.is(":visible")) {
				$spanHide.hide();
				$spanShow.show();
			}
		} else {
			$el.addClass('is-open');
			$obj.addClass('is-open');
			if ($spanShow.is(":visible")) {
				$spanShow.hide();
				$spanHide.show();
			}
		}
	},

	setFocus: function setFocus(el) {
		var $el = _jquery2['default'](el);
		if ($el.length > 0) $el.focus();
	},

	slideToggle: function slideToggle(el) {
		var $el = _jquery2['default'](el);
		if ($el.is('.is-open')) {
			$el.slideUp();
		} else {
			$el.slideDown();
		}
	}

};

exports['default'] = toggler;
module.exports = exports['default'];

},{"jquery":628}],694:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var togglerHeader = {
	init: function init() {
		this.bindEvents();
		_jquery2['default']('html').click(function (e) {
			if (_jquery2['default']('.uc-language-selector').hasClass('is-open')) {
				if (_jquery2['default'](e.target).data('toggle') != '.uc-language-selector') {
					_jquery2['default']('.uc-language-selector').removeClass('is-open');
				}
			}
		});
	},

	bindEvents: function bindEvents() {
		var self = this;
		_jquery2['default']('body').on('click', '[data-toggle-header]', function (e) {
			e.preventDefault();

			var $el = _jquery2['default'](_jquery2['default'](this).data('toggle-header'));
			var $elBtn = _jquery2['default'](_jquery2['default'](this));

			if ($el.is('.is-open')) {
				_jquery2['default']('.header-dialog').removeClass('is-open');
				_jquery2['default']('[data-toggle-header]').removeClass('is-open');
			} else {
				_jquery2['default']('.header-dialog').removeClass('is-open');
				_jquery2['default']('[data-toggle-header]').removeClass('is-open');
				$el.addClass('is-open');
				$elBtn.addClass('is-open');
			}
		});
	}

};

exports['default'] = togglerHeader;
module.exports = exports['default'];

},{"jquery":628}],695:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _user_addressesUser_addresses_default = require('../user_addresses/user_addresses_default');

var _user_addressesUser_addresses_default2 = _interopRequireDefault(_user_addressesUser_addresses_default);

var _user_addressesUser_addresses_item = require('../user_addresses/user_addresses_item');

var _user_addressesUser_addresses_item2 = _interopRequireDefault(_user_addressesUser_addresses_item);

var _user_addressesAddress_add_item = require('../user_addresses/address_add_item');

var _user_addressesAddress_add_item2 = _interopRequireDefault(_user_addressesAddress_add_item);

var useraddresses = {
	init: function init() {
		if (_jquery2['default']('#userDefaultAddress').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_user_addressesUser_addresses_default2['default'], null), _jquery2['default']('#userDefaultAddress')[0]);
		if (_jquery2['default']('#userAddresses').length > 0) _reactDom2['default'].render(_react2['default'].createElement(_user_addressesUser_addresses_item2['default'], null), _jquery2['default']('#userAddresses')[0]);

		_jquery2['default']('body').on('click', '.add-address button', function (e) {
			e.preventDefault();
			_jquery2['default']('.user-address.add-new').addClass('adding');
		});

		_jquery2['default']('body').on('click', '.add-address button', function (e) {
			e.preventDefault();
			_jquery2['default']('.user-address.add-new').addClass('adding');
		});
		_jquery2['default']('body').on('click', '#toggle-shipping-address', function (e) {
			var $el = _jquery2['default']('#user-shipping-address');
			var $spanShow = _jquery2['default'](this).find("span.show");
			var $spanHide = _jquery2['default'](this).find("span.hide");

			if ($el.hasClass('is-open')) {
				$el.removeClass('is-open');
				$spanShow.hide();
				$spanHide.show();
			} else {
				$el.addClass('is-open');
				$spanHide.hide();
				$spanShow.show();
			}
		});
		_jquery2['default']('body').on('click', '#toggle-billing-address', function (e) {
			var $el = _jquery2['default']('#user-billing-address');
			var $spanShow = _jquery2['default'](this).find("span.show");
			var $spanHide = _jquery2['default'](this).find("span.hide");

			if ($el.hasClass('is-open')) {
				$el.removeClass('is-open');
				$spanShow.hide();
				$spanHide.show();
			} else {
				$el.addClass('is-open');

				$spanHide.hide();
				$spanShow.show();
			}
		});
	}
};

exports['default'] = useraddresses;
module.exports = exports['default'];

},{"../user_addresses/address_add_item":819,"../user_addresses/user_addresses_default":827,"../user_addresses/user_addresses_item":828,"jquery":628,"react":525,"react-dom":351}],696:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var AddressFieldStore = _reflux2['default'].createStore({

  listenables: _actionsUser_addresses_actions2['default'],

  init: function init() {
    this.postalCodeIsValid = false;
  },

  checkPostalCodeCompleted: function checkPostalCodeCompleted(result) {
    this.postalCodeIsValid = result;
    this.trigger(this.postalCodeIsValid);
  },

  // checkPostalCodeFailed(result){
  //   this.postalCodeIsValid = result;
  // 	this.trigger(this.postalCodeIsValid);
  // },

  isPostalCorrect: function isPostalCorrect() {
    return this.postalCodeIsValid;
  },

  resetPostalCode: function resetPostalCode() {
    this.postalCodeIsValid = false;
  }

});

exports['default'] = AddressFieldStore;
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"lodash":333,"reflux":542}],697:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsBrand_filter_actions = require('../_actions/brand_filter_actions');

var _actionsBrand_filter_actions2 = _interopRequireDefault(_actionsBrand_filter_actions);

var _toggle_filter_store_mixin = require('./toggle_filter_store_mixin');

var _toggle_filter_store_mixin2 = _interopRequireDefault(_toggle_filter_store_mixin);

var BrandFilterStore = _reflux2['default'].createStore({
  listenables: _actionsBrand_filter_actions2['default'],
  mixins: [_toggle_filter_store_mixin2['default']]
});

exports['default'] = BrandFilterStore;
module.exports = exports['default'];

},{"../_actions/brand_filter_actions":632,"./toggle_filter_store_mixin":729,"reflux":542}],698:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var BreadcrumbStore = _reflux2['default'].createStore({

  init: function init() {
    this.breadcumb = [];
  },

  getStore: function getStore() {
    return this.breadcumb;
  },

  get: function get(cacheKey) {
    return _lodash2['default'].findWhere(this.breadcumb, { key: cacheKey });
  },

  set: function set(key, data) {
    this.breadcumb.push({ key: key, data: data });
  }

});

exports['default'] = BreadcrumbStore;
module.exports = exports['default'];

},{"lodash":333,"reflux":542}],699:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var CartStore = _reflux2['default'].createStore({

  listenables: _actionsCart_actions2['default'],

  init: function init() {
    this.cart = [];
    this.error = {};
  },

  getStore: function getStore() {
    return this.cart;
  },

  onLoadCart: function onLoadCart() {
    this.cart = [];
    this.loadError = null;
  },

  onLoadCartCompleted: function onLoadCartCompleted(res, updatedQuantity) {
    this.cart = res;
    this.loadError = '';
    if (res.error) {
      this.error = res.error;
    }
    if (updatedQuantity) {
      this.cart.UpdatedItem = updatedQuantity;
    }
    this.trigger(this.cart);
  },

  onLoadCartFailed: function onLoadCartFailed(response, skuId) {
    // this.loadError = "Could not load cart.";
    this.cart.error = {};
    this.cart.error.Failed = [];
    this.cart.error.Failed.push({ Code: skuId, WarningMessage: 'Could not load cart.', Response: response });
    this.trigger(this.cart);
  }

});

exports['default'] = CartStore;
module.exports = exports['default'];

},{"../_actions/cart_actions":633,"lodash":333,"reflux":542}],700:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var CategoryFilterStore = _reflux2['default'].createStore({
  init: function init() {
    this.filters = this.filters || [];
  },

  getInitialState: function getInitialState() {
    return this.filters;
  },

  hydrate: function hydrate(state) {
    this.filters = state.filters;
  },

  dehydrate: function dehydrate() {
    return JSON.stringify({ filters: this.filters });
  }
});

exports['default'] = CategoryFilterStore;
module.exports = exports['default'];

},{"reflux":542}],701:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutAddressesAlertStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutAddressesAlert = {};
	},

	getStore: function getStore() {
		return this.checkoutAddressesAlert;
	},
	setStore: function setStore(store) {
		this.checkoutAddressesAlert = store;
		this.trigger(this.checkoutAddressesAlert);
	}
	// ,
	//
	// onLoadcheckoutAddressesAlert: function() {
	// 	this.checkoutAddressesAlert = null;
	// 	this.loadError = null;
	// },
	// onLoadcheckoutAddressesAlertCompleted(res) {
	// 	this.checkoutAddressesAlert = res;
	//   this.loadError = '';
	// 	// $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddressesAlert);
	// },
	//
	// onLoadcheckoutAddressesAlertFailed() {
	//   this.loadError = "Could not load cart.";
	// 	$('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddressesAlert);
	// }

});

exports['default'] = CheckoutAddressesAlertStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],702:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutAddressesStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutAddresses = {};
	},

	getStore: function getStore() {
		return this.checkoutAddresses;
	},
	setStore: function setStore(store) {
		this.checkoutAddresses = store;
		this.trigger(this.checkoutAddresses);
	}
	// ,
	//
	// onLoadcheckoutAddresses: function() {
	// 	this.checkoutAddresses = null;
	// 	this.loadError = null;
	// },
	// onLoadcheckoutAddressesCompleted(res) {
	// 	this.checkoutAddresses = res;
	//   this.loadError = '';
	// 	// $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddresses);
	// },
	//
	// onLoadcheckoutAddressesFailed() {
	//   this.loadError = "Could not load cart.";
	// 	$('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddresses);
	// }

});

exports['default'] = CheckoutAddressesStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],703:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutBillingStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutBilling = {};
	},

	getStore: function getStore() {
		return this.checkoutBilling;
	},
	setStore: function setStore(store) {
		this.checkoutBilling = store;
		this.trigger(this.checkoutBilling);
	}
	// ,
	//
	// onLoadcheckoutAddresses: function() {
	// 	this.checkoutAddresses = null;
	// 	this.loadError = null;
	// },
	// onLoadcheckoutAddressesCompleted(res) {
	// 	this.checkoutAddresses = res;
	//   this.loadError = '';
	// 	// $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddresses);
	// },
	//
	// onLoadcheckoutAddressesFailed() {
	//   this.loadError = "Could not load cart.";
	// 	$('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutAddresses);
	// }

});

exports['default'] = CheckoutBillingStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],704:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutCartAlertStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutCartAlert = {};
	},

	getStore: function getStore() {
		return this.checkoutCartAlert;
	},
	setStore: function setStore(store) {
		this.checkoutCartAlert = store;
		this.trigger(this.checkoutCartAlert);
	}

});

exports['default'] = CheckoutCartAlertStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],705:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutCartStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutCart = {};
	},

	getStore: function getStore() {
		return this.checkoutCart;
	},
	setStore: function setStore(store) {
		this.checkoutCart = store;
		this.trigger(this.checkoutCart);
	}

});

exports['default'] = CheckoutCartStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],706:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutCartTotalStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutCartTotal = {};
	},

	getStore: function getStore() {
		return this.checkoutCartTotal;
	},
	setStore: function setStore(store) {
		this.checkoutCartTotal = store;
		this.trigger(this.checkoutCartTotal);
	}

});

exports['default'] = CheckoutCartTotalStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],707:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutCartWarningStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutCartWarning = {};
	},

	getStore: function getStore() {
		return this.checkoutCartWarning;
	},
	setStore: function setStore(store) {
		this.checkoutCartWarning = store;
		this.trigger(this.checkoutCartWarning);
	}

});

exports['default'] = CheckoutCartWarningStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],708:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutDangerousGoodsAlertStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutDangerousGoodsAlert = {};
	},

	getStore: function getStore() {
		return this.checkoutDangerousGoodsAlert;
	},
	setStore: function setStore(store) {
		this.checkoutDangerousGoodsAlert = store;
		this.trigger(this.checkoutDangerousGoodsAlert);
	}

});

exports['default'] = CheckoutDangerousGoodsAlertStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],709:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutLoadingStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutLoading = false;
	},

	getStore: function getStore() {
		return this.checkoutLoading;
	},
	setStore: function setStore(store) {
		this.checkoutLoading = store;
		this.trigger(this.checkoutLoading);
	}

});

exports['default'] = CheckoutLoadingStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],710:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutOrderSimulationStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.simulatedOrder = {};
	},

	getStore: function getStore() {
		return this.simulatedOrder;
	},
	setStore: function setStore(store) {
		this.simulatedOrder = store;
		this.trigger(this.simulatedOrder);
	}

});

exports['default'] = CheckoutOrderSimulationStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],711:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutShippingStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutShipping = {};
	},

	getStore: function getStore() {
		return this.checkoutShipping;
	},
	setStore: function setStore(store) {
		this.checkoutShipping = store;
		this.trigger(this.checkoutShipping);
	}

});

exports['default'] = CheckoutShippingStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],712:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutStore = _reflux2['default'].createStore({

  listenables: _actionsCheckout_actions2['default'],

  init: function init() {
    this.checkout = {};
  },

  getStore: function getStore() {
    return this.checkout;
  },

  onLoadCheckout: function onLoadCheckout() {
    this.checkout = null;
    this.loadError = null;
  },

  onLoadCheckoutCompleted: function onLoadCheckoutCompleted(res) {
    this.checkout = res;
    this.loadError = '';
    $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
    this.trigger(this.checkout);
  },

  onLoadCheckoutFailed: function onLoadCheckoutFailed() {
    this.loadError = "Could not load cart.";
    $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
    this.trigger(this.checkout);
  }

});

exports['default'] = CheckoutStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],713:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutSummaryStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutSummary = {};
	},

	getStore: function getStore() {
		return this.checkoutSummary;
	},
	setStore: function setStore(store) {
		this.checkoutSummary = store;
		this.trigger(this.checkoutSummary);
	}
	// ,
	//
	// onLoadcheckoutSummary: function() {
	// 	this.checkoutSummary = null;
	// 	this.loadError = null;
	// },
	// onLoadcheckoutSummaryCompleted(res) {
	// 	this.checkoutSummary = res;
	//   this.loadError = '';
	// 	// $('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutSummary);
	// },
	//
	// onLoadcheckoutSummaryFailed() {
	//   this.loadError = "Could not load cart.";
	// 	$('#shipping-address, .uc-checkout-summary, .uc-checkout-shipping-options').removeClass('loading');
	//   this.trigger(this.checkoutSummary);
	// }

});

exports['default'] = CheckoutSummaryStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],714:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutTrackingDataStore = _reflux2['default'].createStore({

	listenables: _actionsCheckout_actions2['default'],

	init: function init() {
		this.checkoutTrackingData = {};
	},

	getStore: function getStore() {
		return this.checkoutTrackingData;
	},
	setStore: function setStore(store) {
		this.checkoutTrackingData = store;
		this.trigger(this.checkoutTrackingData);
	}

});

exports['default'] = CheckoutTrackingDataStore;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"lodash":333,"reflux":542}],715:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _brand_filter_store = require('./brand_filter_store');

var _brand_filter_store2 = _interopRequireDefault(_brand_filter_store);

var _usage_type_filter_store = require('./usage_type_filter_store');

var _usage_type_filter_store2 = _interopRequireDefault(_usage_type_filter_store);

var state = {
  brandFilterCount: 0,
  usageTypeFilterCount: 0
};

var FilterCountStore = _reflux2['default'].createStore(Object.defineProperties({
  init: function init() {
    this.listenTo(_brand_filter_store2['default'], this.onBrandFiltersChange);
    this.listenTo(_usage_type_filter_store2['default'], this.onUsageTypeFilterChange);
  },

  getInitialState: function getInitialState() {
    state.brandFilterCount = _brand_filter_store2['default'].selectedFilters.length;
    state.usageTypeFilterCount = _usage_type_filter_store2['default'].selectedFilters.length;
    return this.count;
  },

  onBrandFiltersChange: function onBrandFiltersChange(filters) {
    state.brandFilterCount = filters.filter(function (x) {
      return x.selected;
    }).length;
    this.trigger(this.count);
  },

  onUsageTypeFilterChange: function onUsageTypeFilterChange(filters) {
    state.usageTypeFilterCount = filters.filter(function (x) {
      return x.selected;
    }).length;
    this.trigger(this.count);
  }

}, {
  count: {
    get: function get() {
      return state.brandFilterCount + state.usageTypeFilterCount;
    },
    configurable: true,
    enumerable: true
  }
}));

exports['default'] = FilterCountStore;
module.exports = exports['default'];

},{"./brand_filter_store":697,"./usage_type_filter_store":732,"reflux":542}],716:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsHistory_actions = require('../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var HistoryStore = _reflux2['default'].createStore({

	listenables: _actionsHistory_actions2['default'],

	init: function init() {
		this.history = [];
		this.currentNav = hiabconfig.explodedViews.rootModel;
	},

	getStore: function getStore() {
		return this.history;
	},

	get: function get(cacheKey) {
		return _lodash2['default'].findWhere(this.history, { key: cacheKey });
	},

	removeHistoryAfter: function removeHistoryAfter(cacheKey) {
		var index = _lodash2['default'].indexOf(this.history, _lodash2['default'].find(this.history, { key: cacheKey }));
		this.history.splice(index, this.history.length);
	},

	set: function set(key, data) {
		var find = this.get(key);
		if (!_lodash2['default'].isUndefined(find)) {
			var index = _lodash2['default'].indexOf(this.history, _lodash2['default'].find(this.history, { key: key }));
			this.history.splice(index, 1);
		}
		this.history.push({ key: key, data: data });
	},

	getCurrentNav: function getCurrentNav() {
		return this.currentNav;
	},

	setCurrentNav: function setCurrentNav(node) {
		this.currentNav = node;
	},

	onStoreUpdated: function onStoreUpdated() {
		this.trigger();
	}

});

exports['default'] = HistoryStore;
module.exports = exports['default'];

},{"../_actions/history_actions":637,"lodash":333,"reflux":542}],717:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsIllustration_actions = require('../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var IllustrationForOverlayStore = _reflux2['default'].createStore({

	listenables: _actionsIllustration_actions2['default'],

	init: function init() {
		this.data = {};
		this.loadingState = false;
	},

	onLoadIllustrationForOverlayCompleted: function onLoadIllustrationForOverlayCompleted(res) {
		this.data.illustration = res;
		this.data.loadError = '';
		this.trigger(this.data);
	},

	onLoadIllustrationForOverlayFailed: function onLoadIllustrationForOverlayFailed() {
		this.data.illustration = {};
		this.data.loadError = "Could not load illustration.";
		this.trigger(this.data);
	}

});

exports['default'] = IllustrationForOverlayStore;
module.exports = exports['default'];

},{"../_actions/illustration_actions":638,"reflux":542}],718:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsIllustration_actions = require('../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var IllustrationStore = _reflux2['default'].createStore({

	listenables: _actionsIllustration_actions2['default'],

	init: function init() {
		this.data = {};
		this.loadingState = false;
	},

	getIllustration: function getIllustration() {
		return this.data;
	},
	setLoadingState: function setLoadingState(state) {
		this.loadingState = state;
		this.trigger(this.loadingState);
	},
	getLoadingState: function getLoadingState() {
		return this.loadingState;
	},
	onLoadIllustration: function onLoadIllustration() {
		this.data.illustration = {};
		this.data.loadError = null;
	},

	onLoadIllustrationCompleted: function onLoadIllustrationCompleted(res) {
		this.data.illustration = res;
		this.data.loadError = '';
		this.trigger(this.data);
	},

	onLoadIllustrationFailed: function onLoadIllustrationFailed() {
		this.data.illustration = {};
		this.data.loadError = "Could not load illustration.";
		this.trigger(this.data);
	}

});

exports['default'] = IllustrationStore;
module.exports = exports['default'];

},{"../_actions/illustration_actions":638,"reflux":542}],719:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var LocalizationStore = _reflux2['default'].createStore({
  init: function init() {
    this.state = {
      translations: {}
    };
  },

  getTranslation: function getTranslation(key) {
    return this.state.translations[key];
  },

  hydrate: function hydrate(state) {
    _extends(this.state, state);
  },

  dehydrate: function dehydrate() {
    return JSON.stringify(this.state);
  }
});

exports['default'] = LocalizationStore;
module.exports = exports['default'];

},{"reflux":542}],720:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsTreeview_actions = require('../_actions/treeview_actions');

var _actionsTreeview_actions2 = _interopRequireDefault(_actionsTreeview_actions);

var ModelTreeSearchStore = _reflux2['default'].createStore({

	listenables: _actionsTreeview_actions2['default'],

	init: function init() {
		this.searchValue = '';
	},

	searchNodesInModelCompleted: function searchNodesInModelCompleted(res) {
		this.trigger(res);
	},

	searchNodesInModelFailed: function searchNodesInModelFailed() {
		this.trigger('Could not load model.');
	},

	setSearchValue: function setSearchValue(value) {
		this.searchValue = value;
	},

	getSearchValue: function getSearchValue() {
		return this.searchValue;
	}

});

exports['default'] = ModelTreeSearchStore;
module.exports = exports['default'];

},{"../_actions/treeview_actions":648,"lodash":333,"reflux":542}],721:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsModelsearch_action = require('../_actions/modelsearch_action');

var _actionsModelsearch_action2 = _interopRequireDefault(_actionsModelsearch_action);

var ModelStore = _reflux2['default'].createStore({

	listenables: _actionsModelsearch_action2['default'],

	init: function init() {
		this.model = [];
		this.loading = false;
	},

	getModel: function getModel() {
		return this.model;
	},
	getLoadingState: function getLoadingState() {
		return this.loading;
	},
	onLoadModel: function onLoadModel() {
		this.model.modelitem = [];
		this.model.loadError = null;
		this.loading = true;
		this.trigger(this.loading);
	},
	setNotEnoughCharacters: function setNotEnoughCharacters() {
		this.model.modelitem = [];
		this.model.loadError = null;
		this.loading = false;
		this.trigger(this.loading);
	},
	onLoadModelCompleted: function onLoadModelCompleted(res) {
		this.model.modelitem = res;
		this.model.loadError = '';
		this.loading = false;
		this.trigger(this.model);
		this.trigger(this.loading);
	},

	onLoadModelFailed: function onLoadModelFailed() {
		this.model.loadError = "Could not load model.";
		this.trigger(this.model);
	}

});

exports['default'] = ModelStore;
module.exports = exports['default'];

},{"../_actions/modelsearch_action":639,"lodash":333,"reflux":542}],722:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsOrderlines_actions = require('../_actions/orderlines_actions');

var _actionsOrderlines_actions2 = _interopRequireDefault(_actionsOrderlines_actions);

var OrderLinesStore = _reflux2['default'].createStore({

	listenables: _actionsOrderlines_actions2['default'],

	init: function init() {
		this.orderlines = [];
	},

	getStore: function getStore() {
		return this.orderlines;
	},

	clear: function clear() {
		this.init();
		this.trigger();
	},

	get: function get(materialId) {
		return _lodash2['default'].find(this.orderlines, { key: materialId });
	},

	add: function add(id, orderline) {
		this.orderlines.unshift({ key: id, data: orderline });
		this.trigger();
	},

	updateLine: function updateLine(id, orderline) {
		var index = _lodash2['default'].indexOf(this.orderlines, _lodash2['default'].find(this.orderlines, { key: id }));
		this.orderlines.splice(index, 1, { key: id, data: orderline });
		this.trigger();
	},

	removeOrderLine: function removeOrderLine(id) {
		_lodash2['default'].remove(this.orderlines, { key: id });
		this.trigger();
	}

});

exports['default'] = OrderLinesStore;
module.exports = exports['default'];

},{"../_actions/orderlines_actions":640,"lodash":333,"reflux":542}],723:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsPrice_service_actions = require('../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var PriceServiceStore = _reflux2['default'].createStore({
	listenables: _actionsPrice_service_actions2['default'],

	init: function init() {
		this.prices = [];
	},

	getPrices: function getPrices() {
		return this.prices;
	},
	getPricesForMaterial: function getPricesForMaterial(material) {
		var priceForMaterial = this.prices.filter(function (price) {
			return price.Code == material;
		});
		var placeholder = [];
		if (priceForMaterial.length > 0) {
			return priceForMaterial;
		} else {
			return placeholder;
		}
	},
	addPrices: function addPrices(prices) {
		this.prices = this.prices.concat(prices);
		this.trigger(this.prices);
	},
	handleError: function handleError(materials) {
		var prices = [];
		for (var i = 0; i < materials.length; i++) {
			prices.push({
				Buyable: false,
				InStockQuantity: 0,
				Loaded: false,
				Code: materials[i],
				Price: "",
				ShippingDate: "",
				IsDiscounted: false,
				DefaultPrice: "",
				DiscountPercent: "",
				ProductContext: {},
				PromotionDiscountPercent: "",
				PromotionPrice: "",
				HasPromotion: false,
				HasError: true
			});
		}
		this.addPrices(prices);
	}
});

exports['default'] = PriceServiceStore;
module.exports = exports['default'];

},{"../_actions/price_service_actions":641,"reflux":542}],724:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsProduct_line_filter_actions = require('../_actions/product_line_filter_actions');

var _actionsProduct_line_filter_actions2 = _interopRequireDefault(_actionsProduct_line_filter_actions);

var _toggle_filter_store_mixin = require('./toggle_filter_store_mixin');

var _toggle_filter_store_mixin2 = _interopRequireDefault(_toggle_filter_store_mixin);

var ProductLineFilterStore = _reflux2['default'].createStore({
  listenables: _actionsProduct_line_filter_actions2['default'],
  mixins: [_toggle_filter_store_mixin2['default']]
});

exports['default'] = ProductLineFilterStore;
module.exports = exports['default'];

},{"../_actions/product_line_filter_actions":642,"./toggle_filter_store_mixin":729,"reflux":542}],725:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsSearch_actions = require('../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var SearchResultStore = _reflux2['default'].createStore({
  listenables: [_actionsSearch_actions2['default']],

  init: function init() {
    this.state = {};
  },

  getInitialState: function getInitialState() {
    return this.state;
  },

  onGroupSelectorChange: function onGroupSelectorChange(selected) {
    this.state.selectedGroup = selected;
    this.trigger(this.state);
  },
  getBatchSize: function getBatchSize() {
    if (typeof this.state.jsPriceBatchAmount !== 'undefined') {
      return this.state.jsPriceBatchAmount;
    } else {
      return 3;
    }
  },
  getUserSignedIn: function getUserSignedIn() {
    if (typeof this.state.userIsSignedIn !== 'undefined') {
      return this.state.userIsSignedIn;
    } else {
      return false;
    }
  },
  getSelectedGroup: function getSelectedGroup() {
    if (typeof this.state.selectedGroup !== 'undefined') {
      return this.state.selectedGroup;
    }

    for (var group in this.state.groups) {
      if (this.state.groups[group].matching > 0) {
        this.state.selectedGroup = group;
        return group;
      }
    }

    this.state.selectedGroup = Object.keys(this.state.groups)[0];
    return this.state.selectedGroup;
  },

  checkFindserviceIsDown: function checkFindserviceIsDown() {
    if (this.state.groups && this.state.groups.pages) {
      return { pages: this.state.groups.pages.findServiceUnavailable, spareParts: this.state.groups.lightSparePartViewModel.findServiceUnavailable };
    } else {
      return { pages: null, spareParts: null };
    }
  },

  getTotalMatching: function getTotalMatching() {
    var totalMatching = 0;
    for (var group in this.state.groups) {
      if (!isNaN(this.state.groups[group].matching)) {
        totalMatching += this.state.groups[group].matching;
      }
    }
    return totalMatching;
  },

  getLoading: function getLoading() {
    return this.state.loading;
  },

  getSortFields: function getSortFields() {
    return this.state.groups[this.getSelectedGroup()].sortFields;
  },

  getMoreResultsAvailable: function getMoreResultsAvailable() {
    return this.state.groups[this.getSelectedGroup()].moreResultsAvailable;
  },

  getSelectedItems: function getSelectedItems() {
    //console.log('get items store');
    return this.state.groups[this.getSelectedGroup()].items;
  },

  onInvalidate: function onInvalidate() {
    this.state.loading = true;
    this.trigger(this.state);
  },

  onInvalidateCompleted: function onInvalidateCompleted(result) {
    this.state.loading = false;
    _extends(this.state.groups, result);
    this.trigger(this.state);
  },

  onInvalidateSpareParts: function onInvalidateSpareParts() {
    this.state.loading = true;
    this.trigger(this.state);
  },

  onInvalidateSparePartsCompleted: function onInvalidateSparePartsCompleted(result) {
    this.state.loading = false;
    if (this.state.groups.lightSparePartViewModel === undefined) {
      _extends(this.state.groups.spareParts, result);
    } else {
      _extends(this.state.groups.lightSparePartViewModel, result);
    }
    this.trigger(this.state);
  },

  onLoadNextPage: function onLoadNextPage() {
    this.state.loading = true;
    this.trigger(this.state);
  },

  onLoadNextPageCompleted: function onLoadNextPageCompleted(group, items, moreResultsAvailable) {
    this.state.loading = false;
    this.state.groups[group].items = [].concat(this.state.groups[group].items, items);
    this.state.groups[group].moreResultsAvailable = moreResultsAvailable;
    this.trigger(this.state);
  },

  onLoadNextPageFailed: function onLoadNextPageFailed(error) {
    this.state.loading = false;
    this.state.groups.pages.findServiceUnavailable = true;
    this.state.groups.lightSparePartViewModel.findServiceUnavailable = true;
    this.trigger(this.state);
  },

  hydrate: function hydrate(state) {
    this.state = {};
    _extends(this.state, state);
  },

  dehydrate: function dehydrate() {
    return JSON.stringify(this.state);
  }

});

exports['default'] = SearchResultStore;
module.exports = exports['default'];

},{"../_actions/search_actions":644,"reflux":542}],726:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _sort_store = require('./sort_store');

var _sort_store2 = _interopRequireDefault(_sort_store);

var _actionsSearch_actions = require('../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var SearchStore = _reflux2['default'].createStore({
  listenables: [_actionsSearch_actions2['default']],

  init: function init() {
    this.state = {
      pagesLoadedByGroup: {}
    };
  },

  getInitialState: function getInitialState() {
    return this.state;
  },

  getQuery: function getQuery() {
    return this.state.query;
  },

  onInvalidateCompleted: function onInvalidateCompleted() {
    for (var groupKey in this.state.pagesLoadedByGroup) {
      this.state.pagesLoadedByGroup[groupKey] = 1;
    }
  },

  onInvalidateSparePartsCompleted: function onInvalidateSparePartsCompleted() {
    this.state.pagesLoadedByGroup['spareParts'] = 1;
  },

  onLoadNextPageCompleted: function onLoadNextPageCompleted(group, items) {
    this.state.pagesLoadedByGroup[group] = this.state.pagesLoadedByGroup[group] || 1;
    this.state.pagesLoadedByGroup[group] += 1;
    this.trigger(this.state);
  },

  onSetQuery: function onSetQuery(newQuery) {
    this.state.query = newQuery;
    _actionsSearch_actions2['default'].invalidate();
    this.trigger(this.state);
  },

  hydrate: function hydrate(state) {
    _extends(this.state, state);
  },

  dehydrate: function dehydrate() {
    return JSON.stringify(this.state);
  }
});

exports['default'] = SearchStore;
module.exports = exports['default'];

},{"../_actions/search_actions":644,"./sort_store":728,"reflux":542}],727:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsSearch_actions = require('../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var _actionsSerial_number_filter_actions = require('../_actions/serial_number_filter_actions');

var _actionsSerial_number_filter_actions2 = _interopRequireDefault(_actionsSerial_number_filter_actions);

var SerialNumberFilterStore = _reflux2['default'].createStore({
  listenables: _actionsSerial_number_filter_actions2['default'],
  init: function init() {
    this.serialNumber = this.serialNumber || "";
    this.serialNoInvalid = this.serialNoInvalid || false;
  },
  onApplyFilter: function onApplyFilter(serial) {
    _actionsSearch_actions2['default'].invalidateSpareParts();
    this.serialNumber = serial;
  },
  onClearFilter: function onClearFilter() {
    this.serialNumber = "";
    this.serialNoInvalid = false;
    _actionsSearch_actions2['default'].invalidateSpareParts();
  },
  onUpdateFilters: function onUpdateFilters(flag) {
    //See search_actions.js and there "let doFilter=" to see where and how this is called
    if (flag === true) {
      //Update filter is called with JSON having "serialNoInvalid: true" -flag.
      this.serialNoInvalid = flag;
      this.trigger(this.serialNoInvalid);
    } else {
      //Serial is valid, no serialNoInvalid -property in JSON.
      this.serialNoInvalid = false;
      this.trigger();
    }
  },
  getInitialState: function getInitialState() {
    return this.serialNumber;
  },
  hydrate: function hydrate(state) {
    this.serialNumber = state.serialNumber;
  },
  dehydrate: function dehydrate() {
    return JSON.stringify({ serialNumber: this.serialNumber });
  }
});

exports['default'] = SerialNumberFilterStore;
module.exports = exports['default'];

},{"../_actions/search_actions":644,"../_actions/serial_number_filter_actions":645,"reflux":542}],728:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsSort_actions = require('../_actions/sort_actions');

var _actionsSort_actions2 = _interopRequireDefault(_actionsSort_actions);

var _actionsSearch_actions = require('../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var _storesSearch_store = require('../_stores/search_store');

var _storesSearch_store2 = _interopRequireDefault(_storesSearch_store);

var SortStore = _reflux2['default'].createStore({
	listenables: _actionsSort_actions2['default'],

	init: function init() {
		this.state = {};
	},

	getInitialState: function getInitialState() {
		return this.state;
	},

	onSetField: function onSetField(field) {
		this.state.field = field;
		this.trigger(this.state);
		if (isOnSearchPage()) {
			_actionsSearch_actions2['default'].invalidate();
		} else {
			_actionsSearch_actions2['default'].invalidateSpareParts();
		}
	},

	onSetOrder: function onSetOrder(order) {
		this.state.order = order;
		this.trigger(this.state);
		if (isOnSearchPage()) {
			_actionsSearch_actions2['default'].invalidate();
		} else {
			_actionsSearch_actions2['default'].invalidateSpareParts();
		}
	},

	hydrate: function hydrate(state) {
		_extends(this.state, state);
	},

	dehydrate: function dehydrate() {
		return JSON.stringify(this.state);
	}
});

function isOnSearchPage() {
	return !!_storesSearch_store2['default'].getQuery();
}

exports['default'] = SortStore;
module.exports = exports['default'];

},{"../_actions/search_actions":644,"../_actions/sort_actions":646,"../_stores/search_store":726,"reflux":542}],729:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _actionsSearch_actions = require('../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var ToggleFilterStoreMixin = {
  init: function init() {
    this.filters = this.filters || [];
  },

  onToggleFilter: function onToggleFilter(name) {
    for (var _iterator = this.filters, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
      var _ref;

      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }

      var filter = _ref;

      if (filter.name == name) {
        filter.selected = !filter.selected;
        _actionsSearch_actions2['default'].invalidateSpareParts();
        this.trigger(this.filters);
        break;
      }
    }
  },

  onClearFilters: function onClearFilters() {
    var modified = false;

    for (var _iterator2 = this.filters, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
      var _ref2;

      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }

      var filter = _ref2;

      if (filter.selected) {
        filter.selected = false;
        modified = true;
      }
    }

    if (modified) {
      _actionsSearch_actions2['default'].invalidateSpareParts();
      this.trigger(this.filters);
    }
  },

  onUpdateFilters: function onUpdateFilters(filters) {
    this.filters = filters === undefined ? [] : filters;
    this.trigger(this.filters);
  },

  getInitialState: function getInitialState() {
    return this.filters;
  },

  selectedFilters: function selectedFilters() {
    return this.filters.filter(function (x) {
      return x.selected;
    });
  },

  hydrate: function hydrate(state) {
    this.filters = state.filters;
  },

  dehydrate: function dehydrate() {
    return JSON.stringify({ filters: this.filters });
  }
};

exports['default'] = ToggleFilterStoreMixin;
module.exports = exports['default'];

},{"../_actions/search_actions":644}],730:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsTop_category_filter_actions = require('../_actions/top_category_filter_actions');

var _actionsTop_category_filter_actions2 = _interopRequireDefault(_actionsTop_category_filter_actions);

var _toggle_filter_store_mixin = require('./toggle_filter_store_mixin');

var _toggle_filter_store_mixin2 = _interopRequireDefault(_toggle_filter_store_mixin);

var TopCategoryFilterStore = _reflux2['default'].createStore({
  listenables: _actionsTop_category_filter_actions2['default'],
  mixins: [_toggle_filter_store_mixin2['default']]
});

exports['default'] = TopCategoryFilterStore;
module.exports = exports['default'];

},{"../_actions/top_category_filter_actions":647,"./toggle_filter_store_mixin":729,"reflux":542}],731:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsTreeview_actions = require('../_actions/treeview_actions');

var _actionsTreeview_actions2 = _interopRequireDefault(_actionsTreeview_actions);

var TreeViewStore = _reflux2['default'].createStore({

	listenables: _actionsTreeview_actions2['default'],

	init: function init() {
		this.tree = [];
		this.selectedNode = undefined;
		this.loadingState = true;
	},

	getTree: function getTree() {
		return this.tree;
	},

	get: function get(cacheKey) {
		return _lodash2['default'].findWhere(this.tree, { key: cacheKey });
	},

	findWhereIndex: function findWhereIndex(cacheKey) {
		return _lodash2['default'].where(this.tree, { key: key, cacheKey: cacheKey });
	},

	set: function set(key, data) {
		this.tree.push({ key: key, data: data });
	},

	setSelectedNode: function setSelectedNode(selectedNode) {
		this.selectedNode = selectedNode;
	},
	getSelectedNode: function getSelectedNode(currentNode) {
		return this.selectedNode;
	},
	setLoadingState: function setLoadingState(state) {
		this.loadingState = state;
		this.trigger(this.loadingState);
	},
	getLoadingState: function getLoadingState() {
		return this.loadingState;
	},
	onLoadNodes: function onLoadNodes() {
		//this.data.loadError = null;
	},

	onLoadNodesCompleted: function onLoadNodesCompleted(res) {
		/*res.forEach((child) => {
  		this.data.tree[child.Id] = child;
  });
  		this.data.loadError = '';
  this.trigger(this.data);*/
	},

	onLoadNodesFailed: function onLoadNodesFailed() {
		/*this.data.loadError = "Could not load illustration.";
  this.trigger(this.data);*/
	}

});

exports['default'] = TreeViewStore;
module.exports = exports['default'];

},{"../_actions/treeview_actions":648,"lodash":333,"reflux":542}],732:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _actionsUsage_type_filter_actions = require('../_actions/usage_type_filter_actions');

var _actionsUsage_type_filter_actions2 = _interopRequireDefault(_actionsUsage_type_filter_actions);

var _toggle_filter_store_mixin = require('./toggle_filter_store_mixin');

var _toggle_filter_store_mixin2 = _interopRequireDefault(_toggle_filter_store_mixin);

var UsageTypeFilterStore = _reflux2['default'].createStore({
  listenables: _actionsUsage_type_filter_actions2['default'],
  mixins: [_toggle_filter_store_mixin2['default']]
});

exports['default'] = UsageTypeFilterStore;
module.exports = exports['default'];

},{"../_actions/usage_type_filter_actions":649,"./toggle_filter_store_mixin":729,"reflux":542}],733:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var UserAddressesStore = _reflux2['default'].createStore({

		listenables: _actionsUser_addresses_actions2['default'],

		init: function init() {
				this.addresses = [];
				this.countries = [];
				this.PostalCode = false;
				this.CustomerType = false;
		},

		getAddresses: function getAddresses() {
				return this.addresses.Addresses;
		},
		getBillingAddresses: function getBillingAddresses() {
				return this.addresses.BillingAddresses;
		},
		getStatus: function getStatus() {
				return this.addresses.Success;
		},
		getCountryOptions: function getCountryOptions() {
				return this.countries;
		},
		setPostalCodeIsCorrect: function setPostalCodeIsCorrect(value) {
				this.PostalCode = value;
		},
		getPostalCodeIsCorrect: function getPostalCodeIsCorrect() {
				return this.PostalCode;
		},
		getCustomerType: function getCustomerType() {
				return this.CustomerType;
		},
		onLoadAddresses: function onLoadAddresses() {
				this.addresses = [];
				this.loadError = null;
		},

		onLoadAddressesCompleted: function onLoadAddressesCompleted(res) {
				//this.addresses = res;

				this.addresses = res;
				if (res.CountryOptions) this.countries = res.CountryOptions;
				this.loadError = '';
				this.CustomerType = res.IsBigCustomer;

				this.trigger(this.addresses);
				this.trigger(this.countries);
				this.trigger(this.CustomerType);
		},

		onLoadAddressesFailed: function onLoadAddressesFailed() {
				this.loadError = "Could not load addresses.";
				this.trigger(this.addresses);
		}

});

exports['default'] = UserAddressesStore;
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"lodash":333,"reflux":542}],734:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var UserCountryOptionsStore = _reflux2['default'].createStore({

  listenables: _actionsUser_addresses_actions2['default'],

  init: function init() {
    this.countryOptions = {};
  },
  setCountryOptions: function setCountryOptions(countries) {
    this.countryOptions = countries;
    this.trigger(this.countryOptions);
  },
  getCountryOptions: function getCountryOptions() {
    return this.countryOptions;
  }

});

exports['default'] = UserCountryOptionsStore;
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"lodash":333,"reflux":542}],735:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var UserDefaultAddressesStore = _reflux2['default'].createStore({

  listenables: _actionsUser_addresses_actions2['default'],

  init: function init() {
    this.defaultAddress = {};
  },
  setDefaultAddress: function setDefaultAddress(isDefault) {
    this.defaultAddress = isDefault;
    this.trigger(this.defaultAddress);
  },
  getDefaultAddress: function getDefaultAddress() {
    return this.defaultAddress;
  }

});

exports['default'] = UserDefaultAddressesStore;
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"lodash":333,"reflux":542}],736:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var _batchorder = require('./batchorder');

var _batchorder2 = _interopRequireDefault(_batchorder);

var batchordercart = {
	init: function init() {
		var changeQuantity = undefined;

		_jquery2['default']('.quantity').change(function () {
			changeQuantity = _jquery2['default'](this).val();
			_jquery2['default'](this).val(changeQuantity);
		}).change();

		function CartIsWorking() {
			return _jquery2['default']('#controll-cart').hasClass('adding');
		}

		_jquery2['default']('body').on('click', 'button.batch-add-to-cart', function (e) {
			e.preventDefault();

			if (_jquery2['default'](this).hasClass('loading') || _jquery2['default']('button.batch-quick-buy').hasClass('loading')) {
				return;
			}

			_jquery2['default']('button.batch-quick-buy').toggleClass('inactive');

			_jquery2['default'](this).addClass('loading');
			_jquery2['default']('#controll-cart').addClass('adding');
			_jquery2['default']('.uc-headercart').addClass('adding');
			var items = [];
			_jquery2['default']('[data-line-item].row').each(function (index, scope) {
				var item = {};
				var skuID = _jquery2['default'](this).data('line-item');
				var quantity = _jquery2['default'](".quantity[data-line-item='" + skuID + "']", scope).val();
				item['code'] = skuID;
				item['quantity'] = quantity;
				items.push(item);
			});
			_jquery2['default']('.uc-headercart').removeClass('right-off-canvas-toggle');
			_actionsCart_actions2['default'].addCartItems(items);
		});

		_jquery2['default']('body').on('click', 'button.batch-quick-buy', function (e) {

			if (CartIsWorking()) {
				return;
			}

			_jquery2['default'](this).addClass('loading');
			_jquery2['default']('#controll-cart').addClass('adding');
			_jquery2['default']('.uc-headercart').addClass('adding');
			e.preventDefault();
			var items = [];
			_jquery2['default']('[data-line-item].row').each(function (index, scope) {
				var item = {};
				var skuID = _jquery2['default'](this).data('line-item');
				var quantity = _jquery2['default'](".quantity[data-line-item='" + skuID + "']", scope).val();
				item['code'] = skuID;
				item['quantity'] = quantity;
				items.push(item);
			});
			_jquery2['default']('.uc-headercart').removeClass('right-off-canvas-toggle');
			_actionsCart_actions2['default'].quickBuyItems(items);
		});
	}
};

exports['default'] = batchordercart;
module.exports = exports['default'];

},{"../_actions/cart_actions":633,"./batchorder":737,"jquery":628}],737:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsOrderlines_actions = require('../_actions/orderlines_actions');

var _actionsOrderlines_actions2 = _interopRequireDefault(_actionsOrderlines_actions);

var _storesOrderlines_store = require('../_stores/orderlines_store');

var _storesOrderlines_store2 = _interopRequireDefault(_storesOrderlines_store);

var _apiProduct_api = require('../_api/product_api');

var _apiProduct_api2 = _interopRequireDefault(_apiProduct_api);

var orderlines = {
	init: function init() {
		var _this = this;

		//Form events
		this.materialInput = _jquery2['default']('#add-material');
		this.quantityInput = _jquery2['default']('#add-quantity');
		this.addButton = _jquery2['default']('#add-orderline');
		this.removeAllButton = _jquery2['default']('#remove-all-lines');
		this.addLinesButtons = _jquery2['default']('#add-lines-buttons');
		this.messageElm = _jquery2['default']('.orderline-message');
		this.configureFileTrigger = _jquery2['default']('.configuretext');
		this.messageId = _jquery2['default']('.message-order-line-id');
		this.messageOkElm = _jquery2['default']('#add-orderline-message-ok');
		this.messageNotFoundElm = _jquery2['default']('#add-orderline-message-notfound');
		this.messageNotBuyableElm = _jquery2['default']('#add-orderline-message-notbuyable');
		this.messageRestrictedElm = _jquery2['default']('#add-orderline-message-restricted');
		this.messageContactPrincetonDealerElm = _jquery2['default']('#add-orderline-message-contactprincetondealer');
		this.messageExistsElm = _jquery2['default']('#add-orderline-message-exists');
		this.fileMessagesElm = _jquery2['default']('#fileupload-messages');
		this.excelMessagesElm = _jquery2['default']('.fileupload-messages');

		_jquery2['default'](document).on('blur', '#line-items .quantity', function () {
			// this.defaultValue = this.value;
			var val = this.value;
			if (val !== this.defaultValue) {
				this.defaultValue = this.value;
				var materialId = _jquery2['default'](this).data('line-item'),
				    quantity = isNaN(_jquery2['default'](this).val()) || _jquery2['default'](this).val() === '' ? 1 : _jquery2['default'](this).val();

				var material = {
					material: materialId.toString(),
					quantity: Number(quantity)

				};
				_storesOrderlines_store2['default'].updateLine(material.material, material);
			}
		});

		this.materialInput.on('keydown', function (e) {
			if (e.which === 13) {
				e.preventDefault();
			}
		});

		//Open configure text dialog
		this.configureFileTrigger.on('click', function () {
			_jquery2['default']('#configure-orderline').foundation('reveal', 'open');
		});

		//Add line on tab
		this.addButton.on('keydown', function (e) {
			if (e.which === 9 && !e.shiftKey) {
				e.preventDefault();
				_this.addButton.trigger('click');
			}
		});
		this.quantityInput.on('keydown', function (e) {
			if (e.which === 13) {
				e.preventDefault();
				_this.addButton.trigger('click');
			}
		});

		//Add line on click/enter
		this.addButton.on('click', this.materialIsBuyable.bind(this));

		//Remove messages when starting to type
		this.materialInput.on('keydown', this.hideMessages.bind(this));

		//Remove all batch line items
		this.removeAllButton.on('click', this.removeAllOrderLines.bind(this));

		//Remove line item
		var self = this;
		_jquery2['default']('body').on('click', '.remove-orderline', function () {
			var lineId = _jquery2['default'](this).attr('data-line-id');
			self.removeOrderLine(lineId);
		});

		//Focus on material that already exists in orderlines
		_jquery2['default']('#orderline-exists-focus-handler').on('click', function (e) {
			e.preventDefault();
			_jquery2['default']('.quantity', '[data-line-item=' + _this.messageId.html() + ']').focus();
		});
		_jquery2['default'](".uc-orderlines form").submit(function (event) {
			event.preventDefault();
		});

		//Listen to changes in store
		_storesOrderlines_store2['default'].listen(function () {
			_this.countOrderLines();
			_this.handleVisibility();
			_this.renderOrderLines();
		});
	},

	materialIsBuyable: function materialIsBuyable() {
		var _this2 = this;

		var materialId = this.materialInput.val(),
		    quantity = isNaN(this.quantityInput.val()) || this.quantityInput.val() === '' ? 1 : this.quantityInput.val();

		var material = {
			material: materialId,
			quantity: quantity
		};

		var materialAdded = _storesOrderlines_store2['default'].get(material.material);

		if (material.material && material.quantity > 0) {
			_jquery2['default'](this.addButton).addClass('loading');
			_jquery2['default'](this.addButton).prop("disabled", true);
		}

		if (materialAdded) {
			//Show material already added in orderlines message
			_jquery2['default'](this.addButton).removeClass('loading');
			_jquery2['default'](this.addButton).prop("disabled", false);
			this.showMessage('exists', material);
			//Focus field
			this.materialInput.focus();
			return;
		}
		if (materialId.length === 0 || quantity.length === 0) {
			return;
		}

		_apiProduct_api2['default'].isbuyable(materialId).then(function (response) {
			_jquery2['default'](_this2.addButton).removeClass('loading');
			_jquery2['default'](_this2.addButton).prop("disabled", false);
			// if(response.Message) {
			// 	this.showMessage('notfound', material);
			// 	this.materialInput.focus();
			// }
			if (response.IsBuyable) {
				//Show message
				material = {
					material: response.Id,
					quantity: quantity,
					cost: response.Cost
				};
				_this2.showMessage('success', material);
				//Add orerline to store
				_this2.addOrderLine(material);
				//Clear input fields and focus
				_this2.materialInput.val('');
				_this2.quantityInput.val('');
				_this2.materialInput.focus();
			} else {
				// console.log(response);

				//Show message
				_this2.showMessage(response.Status, material, response.Message);
				//Focus field
				_this2.materialInput.focus();
			}
		})['catch'](function (message) {
			throw new Error(message);
		});
	},

	showMessage: function showMessage(message, material) {
		var text = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];

		this.hideMessages();
		switch (message) {
			case 'success':
				this.messageOkElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
			case 'ItemNotFound':
				this.messageNotFoundElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
			case 'ItemNotBuyable':
				this.messageNotBuyableElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
			case 'Restricted':
				this.messageRestrictedElm.find('.message-order-line-id').next().html(text);
				this.messageRestrictedElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
			case 'ContactPrincetonDealer':
				this.messageContactPrincetonDealerElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
			case 'exists':
				this.messageExistsElm.removeClass('u-hidden');
				this.messageId.html(material.material);
				break;
		}
	},

	addOrderLine: function addOrderLine(material) {
		//Add material to store
		_jquery2['default']('#add-to-cart-success').hide();
		_actionsOrderlines_actions2['default'].add(material.material, material);
	},

	renderOrderLines: function renderOrderLines() {
		_jquery2['default']('#line-items').empty();
		var lineItems = _storesOrderlines_store2['default'].getStore();
		var lineItemsCorrectOrder = [];

		for (var i = Object.keys(lineItems).length - 1; i > -1; i--) {
			lineItemsCorrectOrder.push(lineItems[i]);
		}

		lineItemsCorrectOrder.forEach(function (lineItem) {
			console.log(lineItem);
			var item = '<div class="row" data-line-item="' + lineItem.key + '" >';
			item += '<div class="small-6 medium-7 columns">';
			item += '<input class="materialnumber" type="text" readonly value="' + lineItem.data.material + '" />';
			item += '</div>';
			item += '<div class="small-6 medium-5 columns">';
			item += '<input data-product-cost="' + lineItem.data.cost + '" data-line-item="' + lineItem.key + '" class="quantity" type="text" value="' + lineItem.data.quantity + '" />';
			item += '<button type="button" data-line-id="' + lineItem.key + '" class="button outlined thin remove-orderline">';
			item += '<i class="icon-trash"></i><span>' + hiabconfig.batchOrder.lang.removeOrderline + '</span>';
			item += '</button>';
			item += '</div>';
			item += '</div>';
			_jquery2['default']('#line-items').append(item);
		});
	},

	countOrderLines: function countOrderLines() {
		_jquery2['default']('#orderlines-count').html(_storesOrderlines_store2['default'].getStore().length + ' ');
	},

	handleVisibility: function handleVisibility() {
		if (_storesOrderlines_store2['default'].getStore().length > 0) {
			this.removeAllButton.addClass('u-visible');
			this.addLinesButtons.addClass('u-visible-keep-layout');
		} else {
			this.removeAllButton.removeClass('u-visible');
			this.addLinesButtons.removeClass('u-visible-keep-layout');
		}
	},

	removeOrderLine: function removeOrderLine(id) {
		_actionsOrderlines_actions2['default'].removeOrderLine(id);
		this.hideMessages();
	},

	removeAllOrderLines: function removeAllOrderLines(e) {
		e.preventDefault();
		//Clear store!
		_actionsOrderlines_actions2['default'].clear();
		this.hideMessages();
		this.hideImportExcelMessage();
	},

	hideMessages: function hideMessages() {
		this.messageElm.addClass('u-hidden');
		this.fileMessagesElm.removeClass('active');
	},
	//Hide message from excel when removing orderlines
	hideImportExcelMessage: function hideImportExcelMessage() {
		this.excelMessagesElm.removeClass('active');
	}

};

exports['default'] = orderlines;
module.exports = exports['default'];

},{"../_actions/orderlines_actions":640,"../_api/product_api":659,"../_stores/orderlines_store":722,"jquery":628}],738:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _fileupload = require('fileupload');

var _fileupload2 = _interopRequireDefault(_fileupload);

var _actionsOrderlines_actions = require('../_actions/orderlines_actions');

var _actionsOrderlines_actions2 = _interopRequireDefault(_actionsOrderlines_actions);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var uploadfile = {
	init: function init() {

		var buyables = [];
		var errors = [];

		var url = hiabconfig.batchOrder.apiBaseUrl + 'UploadFile';
		_jquery2['default']('#fileupload').fileupload({
			singleFileUploads: true,
			limitMultiFileUploadSize: 1000000,
			url: url,
			dataType: 'json',
			add: function add(e, data) {
				_jquery2['default']('#add-to-cart-success').hide();
				_jquery2['default']('#fileupload button').addClass('loading');
				_jquery2['default']('.fileupload-messages p .error-import').removeClass('active');
				_jquery2['default']('.fileupload-messages p .imported').removeClass('active');
				_jquery2['default']('.fileupload-errors').removeClass('active');
				_jquery2['default']('.fileupload-messages p .importing').addClass('active');
				data.submit();
			},
			done: function done(e, data) {
				buyables = data.result.Buyables;
				errors = data.result.Errors;
				_jquery2['default']('#fileupload button').removeClass('loading');
				if (errors.length > 0) {
					_jquery2['default']('.fileupload-errors').addClass('active');
					_jquery2['default']('.error-import-count').text(errors.length);
				}
				_jquery2['default']('.fileupload-messages').addClass('active');

				_jquery2['default'].each(buyables, function (index, value) {
					var material = {
						material: value.MaterialId,
						quantity: value.Quantity,
						cost: value.Cost
					};
					_actionsOrderlines_actions2['default'].add(material.material, material);
				});
				_libCustomEvents2['default'].batchUpload(data);

				_jquery2['default']('.error-modal ul').empty();
				_jquery2['default'].each(errors, function (index, value) {
					_jquery2['default']('.error-modal ul').append('<li>' + value.ErrorMessage + '</li>');
				});

				_jquery2['default'].each(data.files, function (index, file) {
					_jquery2['default']('.file-name').text(file.name);
				});
				_jquery2['default']('.import-count').text(buyables.length);
				_jquery2['default']('.fileupload-messages p .importing').removeClass('active');
				_jquery2['default']('.fileupload-messages p .imported').addClass('active');
			},
			fail: function fail(e, data) {
				_jquery2['default']('.fileupload-messages').addClass('active');
				_jquery2['default']('.fileupload-messages p .importing').removeClass('active');
				_jquery2['default']('.fileupload-messages p .error-import .message').text(data._response.jqXHR.responseJSON);
				_jquery2['default']('.fileupload-messages p .error-import').addClass('active');
				_jquery2['default']('#fileupload button').removeClass('loading');
			},
			progressall: function progressall(e, data) {
				//var progress = parseInt(data.loaded / data.total * 100, 10);
			}
		}).prop('disabled', !_jquery2['default'].support.fileInput).parent().addClass(_jquery2['default'].support.fileInput ? undefined : 'disabled');
	}
};
exports['default'] = uploadfile;
module.exports = exports['default'];

},{"../_actions/orderlines_actions":640,"../_lib/custom-events":671,"fileupload":617,"jquery":628}],739:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

// import React from 'react';

var _checkout_cart_lineitem_update = require('./checkout_cart_lineitem_update');

var _checkout_cart_lineitem_update2 = _interopRequireDefault(_checkout_cart_lineitem_update);

var _checkout_cart_lineitem_delete = require('./checkout_cart_lineitem_delete');

var _checkout_cart_lineitem_delete2 = _interopRequireDefault(_checkout_cart_lineitem_delete);

var _checkout_cart_lineitem_comment = require('./checkout_cart_lineitem_comment');

var _checkout_cart_lineitem_comment2 = _interopRequireDefault(_checkout_cart_lineitem_comment);

var _checkout_shipping_new = require('./checkout_shipping_new');

var _checkout_shipping_new2 = _interopRequireDefault(_checkout_shipping_new);

var _actionsCheckout_actions_new = require('../_actions/checkout_actions_new');

var _actionsCheckout_actions_new2 = _interopRequireDefault(_actionsCheckout_actions_new);

var _storesCheckout_loading_store = require('../_stores/checkout_loading_store');

var _storesCheckout_loading_store2 = _interopRequireDefault(_storesCheckout_loading_store);

var _storesCheckout_order_simulation_store = require('../_stores/checkout_order_simulation_store');

var _storesCheckout_order_simulation_store2 = _interopRequireDefault(_storesCheckout_order_simulation_store);

var _storesCheckout_cart_store = require('../_stores/checkout_cart_store');

var _storesCheckout_cart_store2 = _interopRequireDefault(_storesCheckout_cart_store);

var _storesCheckout_cart_total_store = require('../_stores/checkout_cart_total_store');

var _storesCheckout_cart_total_store2 = _interopRequireDefault(_storesCheckout_cart_total_store);

var _storesCheckout_cart_alert_store = require('../_stores/checkout_cart_alert_store');

var _storesCheckout_cart_alert_store2 = _interopRequireDefault(_storesCheckout_cart_alert_store);

var _storesCheckout_cart_warning_store = require('../_stores/checkout_cart_warning_store');

var _storesCheckout_cart_warning_store2 = _interopRequireDefault(_storesCheckout_cart_warning_store);

var _storesCheckout_dangerous_goods_alert_store = require('../_stores/checkout_dangerous_goods_alert_store');

var _storesCheckout_dangerous_goods_alert_store2 = _interopRequireDefault(_storesCheckout_dangerous_goods_alert_store);

var _storesCheckout_shipping_store = require('../_stores/checkout_shipping_store');

var _storesCheckout_shipping_store2 = _interopRequireDefault(_storesCheckout_shipping_store);

var _storesCheckout_addresses_store = require('../_stores/checkout_addresses_store');

var _storesCheckout_addresses_store2 = _interopRequireDefault(_storesCheckout_addresses_store);

var _storesCheckout_billing_store = require('../_stores/checkout_billing_store');

var _storesCheckout_billing_store2 = _interopRequireDefault(_storesCheckout_billing_store);

var _storesCheckout_addresses_alert_store = require('../_stores/checkout_addresses_alert_store');

var _storesCheckout_addresses_alert_store2 = _interopRequireDefault(_storesCheckout_addresses_alert_store);

var _storesCheckout_summary_store = require('../_stores/checkout_summary_store');

var _storesCheckout_summary_store2 = _interopRequireDefault(_storesCheckout_summary_store);

var _storesCheckout_tracking_data_store = require('../_stores/checkout_tracking_data_store');

var _storesCheckout_tracking_data_store2 = _interopRequireDefault(_storesCheckout_tracking_data_store);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var alternativeLayout = hiabconfig.marketId == "JP02" ? true : false;

var validation = {
	"termsApproved": false,
	"minimalAllowedPassed": false,
	"addressValid": false,
	"hasShippingOptions": false,
	"hasValidPaymentOption": false,
	"hasNoErros": false
};
var checkoutLang = hiabconfig.checkout.lang;

var checkout = {
	init: function init() {
		if (_jquery2['default']('.uc-checkout-cart').length === 0) return;
		this.validate();
		this.reRenderCheckout();
		this.checkoutChanges();
		this.checkoutFunctionality();
		this.setShippingAddressForSummary();
	},

	validate: function validate() {
		Foundation.libs.abide.validate(_jquery2['default']('#checkoutform').find('input, select, textarea'), { type: '' });

		validation.termsApproved = _jquery2['default']('#checkout-terms-condition').is(':checked');
		validation.addressValid = _jquery2['default']('.checkout-address-info .input-wrapper.error').length === 0 && _jquery2['default']('.checkout-address-info .input-wrapper.invalid').length === 0 && _jquery2['default']('.delivery-addresses-container').length > 0;

		validation.hasShippingOptions = _jquery2['default']('#no-shipping-options').length === 0;

		var activePaymentOptions = _jquery2['default']('.payment-type').filter(":not(.disabled)");
		if (activePaymentOptions.length != 0) {
			validation.hasValidPaymentOption = true;
		}

		validation.minimalAllowedPassed = _jquery2['default']('.update-cart-ammount').length === 0;
		validation.hasNoErros = _jquery2['default']('.uc-message.error').length === 0;

		var validationErrorWrapper = _jquery2['default']('.validation-errors');
		var validationError = _jquery2['default']('.validation-errors ul');
		var completePurchaseButton = _jquery2['default']('#complete-purchase-button');

		for (var status in validation) {
			if (validation[status] === false) {
				completePurchaseButton.removeClass('loading');
				completePurchaseButton.prop('disabled', true);
				validationErrorWrapper.addClass('active');
				this.validateErrorsActions(validationErrorWrapper, validationError);
				break;
			} else {
				completePurchaseButton.prop('disabled', false);
				if (_jquery2['default'](validationError).children().length > 0) {
					_jquery2['default'](validationError).children().remove();
				}
				validationErrorWrapper.removeClass('active');
			}
		}
	},
	validateErrorsActions: function validateErrorsActions(validationErrorWrapper, validationError) {
		if (_jquery2['default'](validationError).children().length > 0) {
			_jquery2['default'](validationError).children().remove();
		}

		var checkoutMsg = checkoutLang.cartError;
		var checkoutError = '<li><a href="#" data-scroll-to=".uc-message.error">' + checkoutMsg + '</a> - ' + checkoutLang.review + '</li>';
		if (!validation.hasNoErros) {
			validationError.append(checkoutError);
		}

		var cartMsg = _jquery2['default']('.uc-checkout-cart h3').text();
		var cartError = '<li><a href="#" data-scroll-to=".uc-checkout-cart">' + cartMsg + '</a> - ' + checkoutLang.review + '</li>';
		if (!validation.minimalAllowedPassed) {
			validationError.append(cartError);
		}

		var addressMsg = _jquery2['default']('.uc-checkout-shipping .checkout-address-info h4:first-child').text();
		var addressError = '<li><a href="#" data-scroll-to=".uc-checkout-shipping .delivery-addresses-container">' + addressMsg + '</a> - ' + checkoutLang.review + '</li>';
		if (!validation.addressValid) {
			validationError.append(addressError);
		}

		var shippingMsg = _jquery2['default']('.uc-checkout-shipping .uc-checkout-shipping-options h4:first-child').text();
		var shippingError = '<li><a href="#" data-scroll-to=".uc-checkout-shipping .uc-checkout-shipping-options">' + shippingMsg + '</a> - ' + checkoutLang.review + '</li>';
		if (!validation.hasShippingOptions) {
			validationError.append(shippingError);
		}

		var paymentOptionErrorMsg = _jquery2['default']('.shipping-plant h5').text();
		var paymentOptionError = '<li><a href="#" data-scroll-to=".payment-options">' + paymentOptionErrorMsg + '</a> - ' + checkoutLang.review + '</li>';

		if (!validation.hasValidPaymentOption) {
			validationError.append(paymentOptionError);
		}

		var termsMsg = _jquery2['default']('.uc-checkout-terms h3').text();
		var termsError = '<li><a href="#" data-scroll-to=".uc-checkout-terms">' + termsMsg + '</a> - ' + checkoutLang.review + '</li>';
		if (!validation.termsApproved) {
			validationError.append(termsError);
		}
	},
	reRenderCheckout: function reRenderCheckout() {
		checkout.simulateOrder();

		_libCustomEvents2['default'].loadCartEventCheckout(window.cartContent, window.cartId);

		_storesCheckout_order_simulation_store2['default'].listen(function () {
			var simulationInfo = _storesCheckout_order_simulation_store2['default'].getStore();
			_jquery2['default']('.simulation-calculation').removeClass('loading');

			if (simulationInfo.statusCode) {
				_jquery2['default']('.simulation-item').removeClass('loaded');
				if (_jquery2['default']('.uc-message.error.order-simulation').length == 0) {
					var errorElm = '<div class="uc-message error order-simulation 500-error"><div class="row"><div class="large-6 columns">' + '<p>' + checkoutLang.cartError + '<br/>' + checkoutLang.simulationError + '</p>' + '</div></div></div>';
					_jquery2['default']('.uc-checkout-cart .cart-warnings').append(errorElm);
				}
			} else {
				if (simulationInfo.ErrorViewModel != null) {
					if (simulationInfo.ErrorViewModel.HasError) {
						_jquery2['default']('.simulation-item').removeClass('loaded');
						if (_jquery2['default']('.uc-message.error.order-simulation').length == 0) {
							_jquery2['default']('.uc-checkout-cart .cart-warnings').prepend(simulationInfo.ErrorViewModel.ErrorHtml);
						}
					}
				} else {
					_jquery2['default']('.uc-message.error.order-simulation').remove();

					_jquery2['default']('.total .key.shipping');
					_jquery2['default']('.total .value.shipping').text(simulationInfo.ShippingAmount);

					_jquery2['default']('.simulation-item').addClass('loaded');
					_jquery2['default']('.JS-TaxDescription').text(simulationInfo.TaxDescription);
					_jquery2['default']('.JS-TaxPercentage').text(simulationInfo.TaxPercentage);
					_jquery2['default']('.JS-TaxAmount').text(simulationInfo.TaxAmount);
					_jquery2['default']('.JS-TaxTotal').text(simulationInfo.Total);
				}
			}
		});

		//CART
		_storesCheckout_cart_store2['default'].listen(function () {
			var html = _storesCheckout_cart_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-cart .checkout-cart-content').html(html);
		});
		_storesCheckout_cart_total_store2['default'].listen(function () {
			var html = _storesCheckout_cart_total_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-cart .order-total').html(html);
		});
		_storesCheckout_cart_alert_store2['default'].listen(function () {
			var html = _storesCheckout_cart_alert_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-cart .cart-update-wrapper').html(html);
		});
		_storesCheckout_cart_warning_store2['default'].listen(function () {
			var html = _storesCheckout_cart_warning_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-cart .cart-warnings').html(html);
		});

		//SHIPPING
		_storesCheckout_dangerous_goods_alert_store2['default'].listen(function () {
			var html = _storesCheckout_dangerous_goods_alert_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-shipping .dangerous-goods-indicator').html(html);
		});
		_storesCheckout_addresses_store2['default'].listen(function () {
			var html = _storesCheckout_addresses_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-shipping .delivery-addresses-wrapper').html(html);
			_jquery2['default'](document).foundation('abide', 'reflow');

			//Update summary
			setTimeout(function () {
				checkout.setShippingAddressForSummary();
			}, 100);

			// if big customer no validation is needed
			if (_jquery2['default']('#countryCodeCheckout option').length === 0) {
				return;
			}

			//Validate new address
			setTimeout(function () {
				checkout.validate();
			}, 100);

			//Validate new postal code against service
			var value = _jquery2['default']('#postalCodeCheckout').val();
			var postalCodeInputWrapper = _jquery2['default']('#postalCodeCheckout').parent().parent();
			var countryCode = _jquery2['default']('#countryCodeCheckout option:selected').val();
			_checkout_shipping_new2['default'].handleShippingAddressPostalCode(postalCodeInputWrapper, value, countryCode);
		});
		_storesCheckout_billing_store2['default'].listen(function () {
			var html = _storesCheckout_billing_store2['default'].getStore();
			_jquery2['default']('.billing-addresses-container').html(html);
		});
		_storesCheckout_addresses_alert_store2['default'].listen(function () {
			var html = _storesCheckout_addresses_alert_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-shipping .delivery-addresses-alert').html(html);
		});
		_storesCheckout_shipping_store2['default'].listen(function () {
			var html = _storesCheckout_shipping_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-shipping .uc-checkout-shipping-options').html(html);
		});

		//SUMMARY
		_storesCheckout_summary_store2['default'].listen(function () {
			var html = _storesCheckout_summary_store2['default'].getStore();
			_jquery2['default']('.uc-checkout-summary .table-wrapper').html(html);
			checkout.setShippingAddressForSummary();
			if (!_jquery2['default']('.simulation-calculation').hasClass('loading')) {
				setTimeout(function () {
					checkout.simulateOrder();
				}, 100);
			}
		});

		//TRACKING DATA
		_storesCheckout_tracking_data_store2['default'].listen(function () {
			var html = _storesCheckout_tracking_data_store2['default'].getStore();
			_jquery2['default']('.tracking-data-wrapper').html(html);
		});

		//CART LOADING STATE
		_storesCheckout_loading_store2['default'].listen(function () {
			var isLoading = _storesCheckout_loading_store2['default'].getStore();
			if (isLoading) {
				_jquery2['default']('.dynamic-content').addClass('is-loading');
			} else {
				setTimeout(function () {
					_jquery2['default']('.dynamic-content').removeClass('is-loading');
				}, 100);
				setTimeout(function () {
					checkout.validate();
				}, 255);
			}
		});
	},
	simulateOrder: function simulateOrder() {

		_jquery2['default']('.simulation-calculation').addClass('loading');

		var token = _jquery2['default']('input[name="__RequestVerificationToken"]', _jquery2['default']('#checkoutform')).val();

		// if not big customer
		var countryCode = _jquery2['default']('select[name="ShippingAddress.CountryCode"] option:selected').val();
		var region = _jquery2['default']('select[name="ShippingAddress.Region"] option:selected').val();

		// if big customer
		if (countryCode == null) {
			countryCode = _jquery2['default']('#countryCodeCheckout').val();
		}
		if (region == null) {
			region = _jquery2['default']('#regionCodeCheckout').val();
		}

		var ShippingAddress = {
			CountryCode: countryCode,
			Region: region,
			PostalCode: _jquery2['default']('input[name="ShippingAddress.PostalCode"]').val(),
			City: _jquery2['default']('input[name="ShippingAddress.City"]').val()
		};

		var ShippingCosts = [];
		_jquery2['default']('[data-plant]').each(function (index) {
			var plant = _jquery2['default'](this).data('plant');
			var price = _jquery2['default'](this).children().find('.ship-type.active').data('shipping-cost');

			var ShippingCost = {
				Key: plant,
				Value: price
			};
			ShippingCosts.push(ShippingCost);
		});

		var DeliveryPriorities = [];
		var $directDelivery = _jquery2['default']('#directDelivery');
		if ($directDelivery.length > 0) {
			var plant = "";
			var price = $directDelivery.data('shipping-cost');
			var ShippingCost = {
				Key: plant,
				Value: price
			};
			ShippingCosts.push(ShippingCost);

			var deliveryPriority = {
				Key: $directDelivery.data('plant-code'),
				Value: $directDelivery.data('priority')
			};
			DeliveryPriorities.push(deliveryPriority);
		}

		var $shippingType = _jquery2['default']('.shipping-type');
		if ($shippingType.length) {
			_jquery2['default']('.shipping-type').each(function (index) {
				var $selected = _jquery2['default'](this).find('select option:selected');

				var priorityPlant = _jquery2['default'](this).parent().parent().data('plant');
				var priorityId = $selected.data('priority');

				var deliveryPriority = {
					Key: priorityPlant,
					Value: priorityId
				};
				DeliveryPriorities.push(deliveryPriority);
			});
		}

		var data = {
			__RequestVerificationToken: token,
			ShippingAddresses: {
				ShippingAddress: ShippingAddress
			},
			ShippingCosts: ShippingCosts,
			DeliveryPriorities: DeliveryPriorities
		};

		_actionsCheckout_actions_new2['default'].simulateOrder(data);
	},
	checkoutChanges: function checkoutChanges() {

		//Error list toggle
		_jquery2['default']('body').on('click', '.uc-message.error.collapsed', function (e) {
			var el = _jquery2['default'](this);
			el.hasClass("in") ? el.removeClass("in") : el.addClass("in");
		});

		//Cart changes
		//Comments
		_jquery2['default']('body').on('click', '.uc-checkout-cart .comment', function (e) {
			_checkout_cart_lineitem_comment2['default'].toggleCommentRow(e, this);
		});
		_jquery2['default']('body').on('click', '.uc-checkout-cart .clear-comment', function (e) {
			_checkout_cart_lineitem_comment2['default'].removeComment(e, this);
		});
		_jquery2['default']('body').on('click', '.uc-checkout-cart .add-comment', function (e) {
			_checkout_cart_lineitem_comment2['default'].addComment(e, this);
		});
		//Quantity, delete and upgrade
		_jquery2['default']('body').on('focus blur keypress', '.uc-checkout-cart [name="quantity"]', function (e) {
			_checkout_cart_lineitem_update2['default'].handleChange(e, this);
		});
		_jquery2['default']('body').on('click', '.uc-checkout-cart .remove-button', function (e) {
			_checkout_cart_lineitem_delete2['default'].handleDelete(e, this);
		});
		_jquery2['default']('body').on('click', '.uc-checkout-cart .checkbox-item input[type=checkbox]', function (e) {
			e.stopImmediatePropagation();
			_checkout_cart_lineitem_update2['default'].handleChange(e, this);
			//send to action
			_jquery2['default']('.uc-checkout-cart .checkbox-item input[type=checkbox]').off('change');
		});

		//Shipping changes
		_jquery2['default']('#saved-shipping-info-select').dropdown({
			fullTextSearch: 'exact',
			match: 'text',
			forceSelection: false,
			message: {
				noResults: checkoutLang.noAddressesFound
			},
			onChange: function onChange(value, text, $choice) {
				_checkout_shipping_new2['default'].handleShippingAddressChange(value);
			}
		});

		if (_jquery2['default']('#saved-billing-info-select').length > 0) {
			_jquery2['default']('#saved-billing-info-select').dropdown({
				fullTextSearch: 'exact',
				match: 'text',
				forceSelection: false,
				message: {
					noResults: checkoutLang.noAddressesFound
				},
				onChange: function onChange(value, text, $choice) {
					_checkout_shipping_new2['default'].handleBillingAddressChange(value);
				}
			});
		}

		/*Change country &| region*/
		_jquery2['default']('body').on('change', '.checkout-address-info select', function (e) {
			var shippingAddress = {};
			_jquery2['default']('.checkout-address-info .input-wrapper input').each(function () {
				shippingAddress[_jquery2['default'](this).attr('name')] = _jquery2['default'](this).val();
			});

			// if not big customer
			var countryCode = _jquery2['default']('#countryCodeCheckout').find('option:selected').val();
			var region = _jquery2['default']('#regionCodeCheckout').find('option:selected').val();

			// if big customer
			if (countryCode == null) {
				countryCode = _jquery2['default']('#countryCodeCheckout').val();
			}
			if (region == null) {
				region = _jquery2['default']('#regionCodeCheckout').val();
			}

			shippingAddress['ShippingAddress.CountryCode'] = countryCode;
			shippingAddress['ShippingAddress.Region'] = region;
			shippingAddress['UpdateAddress'] = _jquery2['default']('#UpdateAddress').is(':checked');
			_checkout_shipping_new2['default'].handleCountryCodeChange(shippingAddress);
		});

		_jquery2['default']('body').on('blur', '.checkout-address-info input', function (e) {
			var _this = this;

			if (e.target.id === 'postalCodeCheckout') {
				(function () {
					var postalCodeInputWrapper = _jquery2['default']('#postalCodeCheckout').parent().parent();

					if (_this.value !== _this.defaultValue) {
						(function () {
							_this.defaultValue = _this.value;
							var value = _this.value;
							var countryCode = _jquery2['default']('.checkout-address-info select option:selected').val();
							setTimeout(function () {
								_checkout_shipping_new2['default'].handleShippingAddressPostalCode(postalCodeInputWrapper, value, countryCode);
							}, 255);
						})();
					}
				})();
			} else {
				setTimeout(function () {
					checkout.validate();
				}, 255);
			}
		});

		/*Select shipping prioriry */
		_jquery2['default']('body').on('change', '.uc-checkout-shipping-options select', function (e) {
			var priority = _jquery2['default'](this).find('option:selected').data('priority');
			var plantVal = _jquery2['default'](e.target.parentElement).parent().parent().data('plant');
			_checkout_shipping_new2['default'].handleOptionOrPriorityChange(e, this.value, priority, '', plantVal);

			_jquery2['default']('.uc-checkout-shipping-options select').off('change');
		});

		/*Select shipping type*/
		_jquery2['default']('body').on('click', '.uc-checkout-shipping-options .ship-type:not(.active) input.shipoption[type=radio]', function (e) {
			e.stopImmediatePropagation();
			var plantVal = _jquery2['default'](e.target.parentElement).parent().parent().parent().parent().parent().data('plant');
			_checkout_shipping_new2['default'].handleOptionOrPriorityChange(e, '', '', this.value, plantVal);
			_jquery2['default']('click', '.uc-checkout-shipping-options .ship-type:not(.active) input.shipoption[type=radio]').off('change');
		});

		_jquery2['default']('body').on('click', '.uc-checkout-shipping.payment-options .payment-type:not(.disabled):not(.active) label.payment-option', function (e) {
			e.stopImmediatePropagation();
			_jquery2['default']('.payment-type').removeClass('active');
			_jquery2['default'](this).parent().addClass('active');

			var activePayment = _jquery2['default'](this).find('input').val();
			checkout.switchBtnText(activePayment);

			_jquery2['default']('click', '.uc-checkout-shipping.payment-options .payment-type:not(.disabled):not(.active) label.payment-option').off('change');
		});
	},
	switchBtnText: function switchBtnText(value) {
		var btnText = hiabconfig.checkout.lang[value];
		_jquery2['default']('#complete-purchase-button').text(btnText);
	},
	checkoutFunctionality: function checkoutFunctionality() {

		var activePayment = _jquery2['default']('.uc-checkout-shipping.payment-options .payment-type.active label.payment-option input').val();
		checkout.switchBtnText(activePayment);

		/*Dangerous goods*/
		_jquery2['default']('body').on('click', '.uc-checkout-cart .dangerous-goods i', function (e) {
			_jquery2['default'](this).next().toggle();
			_jquery2['default']('.uc-checkout-cart .dangerous-goods i').off('click');
		});
		_jquery2['default']('body').on('click', '.uc-checkout-cart .dangerous-goods span', function (e) {
			_jquery2['default'](this).hide();
			_jquery2['default']('.uc-checkout-cart .dangerous-goods span').off('click');
		});

		/*If ship type is only one its should have regular cursor*/
		_jquery2['default']('.uc-checkout-shipping-options .ship-type .ship-options').each(function () {
			if (this.parentElement.parentElement.children.length === 1) {
				this.parentElement.parentElement.children[0].firstElementChild.style.cursor = 'default';
			}
		});

		/*Complete purchase-footer*/
		/**Handle approv checkbox click*/
		_jquery2['default']('body').on('click', '#checkout-terms-condition', function (e) {
			setTimeout(function () {
				checkout.validate();
			}, 255);
			_jquery2['default']('#checkout-terms-condition').off('click');
		});
		/**Prevent post when pressing enter*/
		_jquery2['default']('body').on('keypress', '#checkoutform input', '#checkoutform', function (event) {
			if (event.keyCode == 13) {
				event.preventDefault();
			}
		});
		//add loading class to complete purchase
		_jquery2['default']('body').on('click', '#complete-purchase-button:not([disabled])', function (e) {
			_jquery2['default'](this).addClass('loading');
			setTimeout(function () {
				checkout.validate();
			}, 255);
		});
		//add changed address to summary
		_jquery2['default']('body').on('blur', '.input-wrapper input', function (e) {
			setTimeout(function () {
				checkout.validate();
			}, 255);
			checkout.setShippingAddressForSummary();
		});
		_jquery2['default']('body').on('change', '.input-wrapper [name="ShippingAddress.Region"]', function (e) {
			setTimeout(function () {
				checkout.validate();
			}, 255);
			checkout.setShippingAddressForSummary();
		});
	},
	setShippingAddressForSummary: function setShippingAddressForSummary() {

		var regionAddress = "";
		var countryAddress = "";
		var streetline2 = "";
		if (alternativeLayout) {
			if (_jquery2['default']('[name="ShippingAddress.Region"]').length > 0 && _jquery2['default']('[name="ShippingAddress.Region"]').val()) {
				regionAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Region"]').find('option:selected').text() + ', ' + _jquery2['default']('[name="ShippingAddress.City"]').val() + '</span>';

				if (typeof _jquery2['default']('[name="ShippingAddress.Region"]').val() === 'undefined') {
					regionAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Region"]').val() + ', ' + _jquery2['default']('[name="ShippingAddress.City"]').val() + '</span>';
				}
			} else {

				if (_jquery2['default']('[name="ShippingAddress.Region"]').find('option:selected').text() === "") {
					regionAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Region"]').val();+'</span>';
				}
				if (typeof _jquery2['default']('[name="ShippingAddress.Region"]').val() === 'undefined') {
					regionAddress = "";
				}
			}
		} else {
			if (_jquery2['default']('[name="ShippingAddress.Region"]').length > 0 && _jquery2['default']('[name="ShippingAddress.Region"]').val()) {
				regionAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Region"]').find('option:selected').text() + '</span>';
			}

			if (_jquery2['default']('[name="ShippingAddress.Region"]').find('option:selected').text() === "") {
				regionAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Region"]').val();+'</span>';
			}

			if (typeof _jquery2['default']('[name="ShippingAddress.Region"]').val() === 'undefined') {
				regionAddress = "";
			}
		}

		if (_jquery2['default']('[name="ShippingAddress.CountryCode"]').find('option:selected').val()) {
			countryAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.CountryCode"]').find('option:selected').text() + '</span>';
		}

		if (_jquery2['default']('[name="ShippingAddress.CountryCode"]').find('option:selected').text() === "") {
			countryAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.CountryCode"]').val();+'</span>';
		}

		if (typeof _jquery2['default']('[name="ShippingAddress.Line2"]').val() === 'undefined') {
			streetline2 = "";
		} else {
			streetline2 = _jquery2['default']('[name="ShippingAddress.Line2"]').val();
		}

		var shippingAddress = '';

		if (alternativeLayout) {
			shippingAddress = countryAddress + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.PostalCode"]').val() + '</span>' + regionAddress + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Line1"]').val() + '</span>' + streetline2 + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.CompanyName"]').val() + '</span>' + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.FirstName"]').val() + '</span>';
		} else {
			shippingAddress = '<span class="line">' + _jquery2['default']('[name="ShippingAddress.CompanyName"]').val() + '</span>' + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.FirstName"]').val() + '</span>' + countryAddress + regionAddress + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.Line1"]').val() + '</span>' + streetline2 + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.PostalCode"]').val() + '</span>' + '<span class="line">' + _jquery2['default']('[name="ShippingAddress.City"]').val() + '</span>';
		}

		_jquery2['default']('.checkout-shipping-address').html(shippingAddress);
		_jquery2['default']('#checkout-shipping-address-mobile').html(shippingAddress);
	}

};
exports['default'] = checkout;
module.exports = exports['default'];

},{"../_actions/checkout_actions_new":636,"../_lib/custom-events":671,"../_stores/checkout_addresses_alert_store":701,"../_stores/checkout_addresses_store":702,"../_stores/checkout_billing_store":703,"../_stores/checkout_cart_alert_store":704,"../_stores/checkout_cart_store":705,"../_stores/checkout_cart_total_store":706,"../_stores/checkout_cart_warning_store":707,"../_stores/checkout_dangerous_goods_alert_store":708,"../_stores/checkout_loading_store":709,"../_stores/checkout_order_simulation_store":710,"../_stores/checkout_shipping_store":711,"../_stores/checkout_summary_store":713,"../_stores/checkout_tracking_data_store":714,"./checkout_cart_lineitem_comment":740,"./checkout_cart_lineitem_delete":741,"./checkout_cart_lineitem_update":743,"./checkout_shipping_new":745,"jquery":628}],740:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _apiCheckout_apiNew = require('../_api/checkout_api-new');

var _apiCheckout_apiNew2 = _interopRequireDefault(_apiCheckout_apiNew);

var _actionsCheckout_actions_new = require('../_actions/checkout_actions_new');

var _actionsCheckout_actions_new2 = _interopRequireDefault(_actionsCheckout_actions_new);

var _checkout_cart_lineitem_loading = require('./checkout_cart_lineitem_loading');

var _checkout_cart_lineitem_loading2 = _interopRequireDefault(_checkout_cart_lineitem_loading);

var CheckoutCartLineItemComment = {

	addComment: function addComment(e, elm) {
		e.preventDefault();

		var skuId = _jquery2['default'](elm).attr('data-sku-id'),
		    comment = _jquery2['default']('[data-comment-input-id=\'' + skuId + '\']').val();

		// CheckoutCartLineItemLoading.handleLoadingEvent(skuId);
		this.saveComment(skuId, comment);
	},

	removeComment: function removeComment(e, elm) {
		e.preventDefault();

		var skuId = _jquery2['default'](elm).attr('data-sku-id'),
		    comment = _jquery2['default']('[data-comment-input-id=\'' + skuId + '\']');

		// CheckoutCartLineItemLoading.handleLoadingEvent(skuId);
		comment.val('');

		this.saveComment(skuId, comment.val());
	},

	saveComment: function saveComment(skuId, comment) {
		var parentRow = _jquery2['default']('[data-line-id=\'' + skuId + '\']'),
		    commentRow = _jquery2['default']('[data-comment-id=\'' + skuId + '\']');

		_apiCheckout_apiNew2['default'].updateCartItemCustomerComment(skuId, comment)
		// new way to handle it
		.then(function (res) {
			if (res.Success) {
				commentRow.removeClass('is-open');
				parentRow.removeClass('is-active');
				parentRow.addClass('is-saved');
				if (comment !== "") {
					parentRow.addClass('has-comment');
				} else {
					parentRow.removeClass('has-comment');
				}
			}
		})['catch'](function (res) {
			_actionsCheckout_actions_new2['default'].loadCheckout.failed(res);
		});
	},

	toggleCommentRow: function toggleCommentRow(e, elm) {
		e.preventDefault();
		var skuId = _jquery2['default'](elm).attr('data-sku-id'),
		    parentRow = _jquery2['default']('[data-line-id=\'' + skuId + '\']'),
		    commentRow = _jquery2['default']('[data-comment-id=\'' + skuId + '\']');

		if (commentRow.is('.is-open')) {
			commentRow.removeClass('is-open');
			parentRow.removeClass('is-active');
		} else {
			commentRow.addClass('is-open');
			parentRow.addClass('is-active');
		}
	}
};
exports['default'] = CheckoutCartLineItemComment;
module.exports = exports['default'];

},{"../_actions/checkout_actions_new":636,"../_api/checkout_api-new":653,"./checkout_cart_lineitem_loading":742,"classnames":299,"jquery":628}],741:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _checkout_cart_lineitem_loading = require('./checkout_cart_lineitem_loading');

var _checkout_cart_lineitem_loading2 = _interopRequireDefault(_checkout_cart_lineitem_loading);

var _actionsCheckout_actions_new = require('../_actions/checkout_actions_new');

var _actionsCheckout_actions_new2 = _interopRequireDefault(_actionsCheckout_actions_new);

var CheckoutCartLineItemDelete = {
	handleDelete: function handleDelete(e, elm) {
		e.preventDefault();
		var skuId = _jquery2['default'](elm).attr('data-sku-id');
		// CheckoutCartLineItemLoading.handleLoadingEvent(skuId);
		_actionsCheckout_actions_new2['default'].deleteCheckoutCartItem(skuId);
	}
};
exports['default'] = CheckoutCartLineItemDelete;
module.exports = exports['default'];

},{"../_actions/checkout_actions_new":636,"./checkout_cart_lineitem_loading":742,"jquery":628}],742:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var CheckoutCartLineItemLoading = {
		handleLoadingEvent: function handleLoadingEvent(skuId) {
				var lineItemRow = _jquery2['default']('[data-line-id=\'' + skuId + '\']'),
				    commentRow = _jquery2['default']('[data-comment-id=\'' + skuId + '\']');

				lineItemRow.addClass('is-loading');
				commentRow.addClass('is-loading');
				_jquery2['default']('.uc-checkout-shipping-options,  .uc-checkout-summary').addClass('loading');

				//Remove event from buttons
				_jquery2['default']('.uc-checkout-cart [name="quantity"]').off();
				_jquery2['default']('.uc-checkout-cart .remove-button').off();
				_jquery2['default']('.uc-checkout-cart .comment').off();
				_jquery2['default']('.uc-checkout-cart .clear-comment').off();
				_jquery2['default']('.uc-checkout-cart .add-comment').off();
		}
};
exports['default'] = CheckoutCartLineItemLoading;
module.exports = exports['default'];

},{"jquery":628}],743:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesCheckout_store = require('../_stores/checkout_store');

var _storesCheckout_store2 = _interopRequireDefault(_storesCheckout_store);

var _actionsCheckout_actions_new = require('../_actions/checkout_actions_new');

var _actionsCheckout_actions_new2 = _interopRequireDefault(_actionsCheckout_actions_new);

var _checkout_cart_lineitem_loading = require('./checkout_cart_lineitem_loading');

var _checkout_cart_lineitem_loading2 = _interopRequireDefault(_checkout_cart_lineitem_loading);

var CheckoutCartLineItemUpdate = {
	currentVal: null,
	isInt: function isInt(value) {
		var x;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === 1 ? false : true;
		} else {
			return false;
		}
	},

	handleChange: function handleChange(e, elm) {
		var skuId = _jquery2['default'](elm).attr('data-sku-id'),
		    quantity = null,
		    upgraded = null;
		if (e.target.type === 'checkbox') {
			quantity = null, upgraded = e.target.checked;
			_actionsCheckout_actions_new2['default'].updateCheckoutCartItem(skuId, quantity, upgraded);
		} else {
			quantity = _jquery2['default'](elm).val(), upgraded = null;

			if (!this.isInt(quantity)) return;

			if (e.type === 'focusin') {
				this.currentVal = quantity;
			}

			if (e.type === 'keypress' && e.which === 13) {
				_actionsCheckout_actions_new2['default'].updateCheckoutCartItem(skuId, quantity, upgraded);
			}
			if (e.type === 'focusout' && this.currentVal != quantity) {
				_actionsCheckout_actions_new2['default'].updateCheckoutCartItem(skuId, quantity, upgraded);
			}
		}
	}
};
exports['default'] = CheckoutCartLineItemUpdate;
module.exports = exports['default'];

},{"../_actions/checkout_actions_new":636,"../_stores/checkout_store":712,"./checkout_cart_lineitem_loading":742,"jquery":628}],744:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesCheckout_store = require('../_stores/checkout_store');

var _storesCheckout_store2 = _interopRequireDefault(_storesCheckout_store);

var _actionsCheckout_actions = require('../_actions/checkout_actions');

var _actionsCheckout_actions2 = _interopRequireDefault(_actionsCheckout_actions);

var CheckoutShipping = {
	currentVal: null,
	isInt: function isInt(value) {
		var x;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === 1 ? false : true;
		} else {
			return false;
		}
	},

	handleOptionOrPriorityChange: function handleOptionOrPriorityChange(e, priorityVal, optionVal, plantVal) {
		_jquery2['default']('#shipping-address, .uc-checkout-shipping-options,  .uc-checkout-summary').addClass('loading');

		_actionsCheckout_actions2['default'].updateShippingOptionOrPriority({ priority: priorityVal, option: optionVal, plant: plantVal });
	},
	handleOptionOrPriorityChangeUs: function handleOptionOrPriorityChangeUs(e, priorityVal, optionVal, plantVal, specProc) {
		_jquery2['default']('#shipping-address, .uc-checkout-shipping-options,  .uc-checkout-summary').addClass('loading');
		_actionsCheckout_actions2['default'].updateShippingOptionOrPriority({ priority: priorityVal, option: optionVal, plant: plantVal, specProc: specProc });
	},
	handleCountryCodeChange: function handleCountryCodeChange(e, value) {
		_jquery2['default']('#shipping-address input[name="ShippingAddress.PostalCode"], .uc-checkout-shipping-options,  .uc-checkout-summary').addClass('loading');

		_actionsCheckout_actions2['default'].updateCountryCode(value);
	}

};

exports['default'] = CheckoutShipping;
module.exports = exports['default'];

},{"../_actions/checkout_actions":635,"../_stores/checkout_store":712,"jquery":628}],745:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsCheckout_actions_new = require('../_actions/checkout_actions_new');

var _actionsCheckout_actions_new2 = _interopRequireDefault(_actionsCheckout_actions_new);

var _checkoutNew = require('./checkout-new');

var _checkoutNew2 = _interopRequireDefault(_checkoutNew);

var postalCodeInput = _jquery2['default']('#postalCodeCheckout');

var CheckoutShipping = {
	currentVal: null,
	isInt: function isInt(value) {
		var x;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === 1 ? false : true;
		} else {
			return false;
		}
	},

	handleOptionOrPriorityChange: function handleOptionOrPriorityChange(e, serviceId, priorityVal, optionVal, plantVal) {
		_actionsCheckout_actions_new2['default'].updateShippingOptionOrPriority({ serviceId: serviceId, priority: priorityVal, option: optionVal, plant: plantVal });
	},
	handleCountryCodeChange: function handleCountryCodeChange(shippingAddress) {
		_actionsCheckout_actions_new2['default'].updateCountryCode(shippingAddress);
	},
	handleShippingAddressChange: function handleShippingAddressChange(id) {
		_actionsCheckout_actions_new2['default'].changeShippingAddress(id);
	},
	handleBillingAddressChange: function handleBillingAddressChange(id) {
		_actionsCheckout_actions_new2['default'].changeBillingAddress(id);
	},
	handleShippingAddressPostalCode: function handleShippingAddressPostalCode(postalCodeInputWrapper, value, countryCode) {

		if (value.length === 0) {
			postalCodeInputWrapper.addClass('invalid');
			postalCodeInputWrapper.addClass('error');
			postalCodeInputWrapper.removeClass('missing-country');
			return false;
		} else {
			if (countryCode.length === 0) {
				postalCodeInputWrapper.addClass('invalid');
				postalCodeInputWrapper.addClass('missing-country');
				return false;
			}
		}

		postalCodeInputWrapper.removeClass('missing-country');
		postalCodeInputWrapper.removeClass('request-error');
		postalCodeInputWrapper.removeClass('error');
		postalCodeInputWrapper.removeClass('invalid');
		postalCodeInputWrapper.addClass('loading');

		_jquery2['default'].ajax({
			type: 'GET',
			url: hiabconfig.addresses.apiBaseUrl + 'ValidatePostalCode?countryCode=' + countryCode + '&postalcode=' + value
		}).done(function (data) {
			postalCodeInputWrapper.removeClass('loading');
			if (data === true) {
				postalCodeInputWrapper.removeClass('error');
				postalCodeInputWrapper.removeClass('invalid');
				postalCodeInputWrapper.removeClass('request-error');
				_checkoutNew2['default'].simulateOrder();
			} else {
				postalCodeInputWrapper.addClass('error');
				postalCodeInputWrapper.addClass('invalid');
			}
			_checkoutNew2['default'].validate();
		}).error(function (jqXHR, textStatus, errorThrown) {
			postalCodeInputWrapper.addClass('error');
			postalCodeInputWrapper.addClass('invalid');
			postalCodeInputWrapper.addClass('request-error');
			postalCodeInputWrapper.removeClass('loading');
			_checkoutNew2['default'].validate();
		});
	}

};

exports['default'] = CheckoutShipping;
module.exports = exports['default'];

},{"../_actions/checkout_actions_new":636,"./checkout-new":739,"jquery":628}],746:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _apiTreeview_api = require('../../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _brandnavigation_history = require('./brandnavigation_history');

var _brandnavigation_history2 = _interopRequireDefault(_brandnavigation_history);

var _brandnavigation_tree = require('./brandnavigation_tree');

var _brandnavigation_tree2 = _interopRequireDefault(_brandnavigation_tree);

var _visualbrowsing = require('./visualbrowsing');

var _visualbrowsing2 = _interopRequireDefault(_visualbrowsing);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _brands = require('./brands');

var _brands2 = _interopRequireDefault(_brands);

var _storesIllustrationForOverlay_store = require('../../_stores/illustrationForOverlay_store');

var _storesIllustrationForOverlay_store2 = _interopRequireDefault(_storesIllustrationForOverlay_store);

var BrandNavigation = (function (_React$Component) {
	_inherits(BrandNavigation, _React$Component);

	function BrandNavigation(props) {
		_classCallCheck(this, BrandNavigation);

		_React$Component.call(this, props);
		this.state = { currentChild: {
				Description: null,
				IsRoot: null },
			children: {
				data: [] },
			history: [],
			isLoading: false,
			Illustration: null
		};
	}

	BrandNavigation.prototype.fetchNodes = function fetchNodes() {
		var _this = this;

		var currentnav = _storesHistory_store2['default'].getCurrentNav(),
		    id = 0;

		if (!currentnav.IsRoot) id = currentnav.Id;

		this.setState({
			//currentChild: currentnav,
			isLoading: true
		});

		_apiTreeview_api2['default'].getNodes(id).then(function (response) {
			_this.setState({ currentChild: currentnav,
				children: _storesTreeview_store2['default'].get(id),
				history: _storesHistory_store2['default'].getStore(),
				isLoading: false });
		})['catch'](function (message) {
			if (message === 204 && currentnav.Documents.length > 0) {
				var _history = _storesHistory_store2['default'].getStore();
				_this.setState({ currentChild: currentnav,
					children: { data: [], key: currentnav.Id },
					history: _storesHistory_store2['default'].getStore(),
					isLoading: false });
			} else {
				throw new Error(message);
			}
		});
	};

	BrandNavigation.prototype.componentDidMount = function componentDidMount() {
		var _this2 = this;

		this.fetchNodes();
		//Listen for changes in history store!
		this.unsubscribe = _storesHistory_store2['default'].listen(function () {
			_this2.fetchNodes();
		});

		this.unsubscribe2 = _storesIllustrationForOverlay_store2['default'].listen(function (res) {
			if (res.illustration && _this2.state.currentChild.IllustrationLink === res.illustration.Id) {
				_this2.state.currentChild.Illustration = res.illustration;
				_this2.setState(_this2.state);
			}
		});
	};

	BrandNavigation.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();

		this.unsubscribe2();
	};

	BrandNavigation.prototype.render = function render() {

		var logoNavClass = _classnames2['default']({
			'row': true,
			'u-visible': this.state.currentChild.IsRoot,
			'u-hidden': !this.state.currentChild.IsRoot
		});

		var navClass = _classnames2['default']({
			'row': true,
			'u-visible': !this.state.currentChild.IsRoot,
			'u-hidden': this.state.currentChild.IsRoot
		});

		var loadingClass = _classnames2['default']({
			'large-4 medium-8 small-7 columns u-bl-black full-height brand-nav-main is-loading': this.state.isLoading,
			'large-4 medium-8 small-7 columns u-bl-black full-height brand-nav-main': !this.state.isLoading
		});

		// let brandChildren = this.state.brandChildren ? this.state.brandChildren : this.state.children;

		return _react2['default'].createElement(
			'div',
			{ className: 'full-height' },
			_react2['default'].createElement(
				'div',
				{ className: logoNavClass },
				_react2['default'].createElement(
					'div',
					{ className: 'large-12 columns text-center' },
					_react2['default'].createElement(_brands2['default'], { items: this.state.children, currentChild: this.state.currentChild })
				)
			),
			_react2['default'].createElement(
				'div',
				{ className: navClass },
				_react2['default'].createElement(_brandnavigation_history2['default'], { history: this.state.history, fetchnodes: this.fetchNodes.bind(this), currentChild: this.state.currentChild }),
				_react2['default'].createElement(
					'div',
					{ className: loadingClass },
					_react2['default'].createElement(_brandnavigation_tree2['default'], { items: this.state.children, fetchnodes: this.fetchNodes.bind(this), currentChild: this.state.currentChild })
				),
				_react2['default'].createElement(
					'div',
					{ className: 'large-6 columns show-for-large-up' },
					_react2['default'].createElement(_visualbrowsing2['default'], { items: this.state.children, currentChild: this.state.currentChild })
				)
			)
		);
	};

	return BrandNavigation;
})(_react2['default'].Component);

;
exports['default'] = BrandNavigation;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_api/treeview_api":661,"../../_stores/history_store":716,"../../_stores/illustrationForOverlay_store":717,"../../_stores/treeview_store":731,"./brandnavigation_history":747,"./brandnavigation_tree":749,"./brands":751,"./visualbrowsing":755,"classnames":299,"react":525}],747:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _brandnavigation_history_item = require('./brandnavigation_history_item');

var _brandnavigation_history_item2 = _interopRequireDefault(_brandnavigation_history_item);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var BrandNavigationHistory = (function (_React$Component) {
	_inherits(BrandNavigationHistory, _React$Component);

	function BrandNavigationHistory(props) {
		_classCallCheck(this, BrandNavigationHistory);

		_React$Component.call(this, props);
		this.props = {
			history: []
		};
	}

	BrandNavigationHistory.prototype.render = function render() {
		var _this = this;

		var history = this.props.history.map(function (historynode, index) {
			return _react2['default'].createElement(_brandnavigation_history_item2['default'], { key: index, item: historynode, fetchnodes: _this.props.fetchnodes });
		});

		return _react2['default'].createElement(
			'div',
			{ className: 'large-2 medium-4 small-5 columns u-txt-right full-height' },
			_react2['default'].createElement('div', { className: 'brand-header clearfix' }),
			_react2['default'].createElement(
				'nav',
				{ className: 'brandtree-history' },
				_react2['default'].createElement(
					'ul',
					null,
					history
				)
			)
		);
	};

	return BrandNavigationHistory;
})(_react2['default'].Component);

;
exports['default'] = BrandNavigationHistory;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_stores/history_store":716,"./brandnavigation_history_item":748,"react":525}],748:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var BrandNavigationHistoryItem = (function (_React$Component) {
	_inherits(BrandNavigationHistoryItem, _React$Component);

	function BrandNavigationHistoryItem(props) {
		var _this = this;

		_classCallCheck(this, BrandNavigationHistoryItem);

		_React$Component.call(this, props);

		this.handleClick = function (e) {
			e.preventDefault();
			_storesHistory_store2['default'].removeHistoryAfter(_this.props.item.data.Id);
			_storesHistory_store2['default'].setCurrentNav(_this.props.item.data);
			_actionsHistory_actions2['default'].storeUpdated();
		};
	}

	BrandNavigationHistoryItem.prototype.render = function render() {

		var item = this.props.item;

		return _react2['default'].createElement(
			'li',
			null,
			_react2['default'].createElement(
				'a',
				{ onClick: this.handleClick.bind(this), href: '#' },
				_react2['default'].createElement('i', { className: 'icon-angle-left' }),
				item.data.Description
			)
		);
	};

	return BrandNavigationHistoryItem;
})(_react2['default'].Component);

;
exports['default'] = BrandNavigationHistoryItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_stores/history_store":716,"react":525}],749:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _brandnavigation_tree_item = require('./brandnavigation_tree_item');

var _brandnavigation_tree_item2 = _interopRequireDefault(_brandnavigation_tree_item);

var _documents = require('./documents');

var _documents2 = _interopRequireDefault(_documents);

var BrandNavigationHistory = (function (_React$Component) {
	_inherits(BrandNavigationHistory, _React$Component);

	function BrandNavigationHistory(props) {
		_classCallCheck(this, BrandNavigationHistory);

		_React$Component.call(this, props);
		this.props = {};
	}

	BrandNavigationHistory.prototype.render = function render() {
		var _this = this;

		var children = undefined;
		if (this.props.items && this.props.items.data.length > 0) {
			children = this.props.items.data.map(function (childnode) {
				//Do not show top node level in navigation
				if (childnode.Parent === hiabconfig.explodedViews.rootModel.Id) return;

				return _react2['default'].createElement(_brandnavigation_tree_item2['default'], { key: childnode.Id, item: childnode, currentChild: _this.props.currentChild });
			});
		}

		var nodeName = null,
		    documents = [];

		if (this.props.currentChild !== null) {
			nodeName = this.props.currentChild.Description;
			documents = this.props.currentChild.Documents;
		}

		return _react2['default'].createElement(
			'div',
			{ className: 'full-height' },
			_react2['default'].createElement(
				'h4',
				null,
				nodeName
			),
			_react2['default'].createElement(
				'nav',
				{ className: 'brandtree-menu full-height' },
				_react2['default'].createElement(_documents2['default'], { documents: documents }),
				_react2['default'].createElement(
					'ul',
					null,
					children
				)
			)
		);
	};

	return BrandNavigationHistory;
})(_react2['default'].Component);

;
exports['default'] = BrandNavigationHistory;

/* jshint ignore:end */
module.exports = exports['default'];

},{"./brandnavigation_tree_item":750,"./documents":752,"react":525}],750:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var _actionsIllustration_actions = require('../../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var BrandNavigationTreeItem = (function (_React$Component) {
	_inherits(BrandNavigationTreeItem, _React$Component);

	function BrandNavigationTreeItem(props) {
		var _this = this;

		_classCallCheck(this, BrandNavigationTreeItem);

		_React$Component.call(this, props);

		this.handleClick = function (e) {
			if (_this.props.item.NodeType !== 0) {
				e.preventDefault();
				_storesHistory_store2['default'].set(_this.props.currentChild.Id, _this.props.currentChild);
				_storesHistory_store2['default'].setCurrentNav(_this.props.item);
				_actionsHistory_actions2['default'].storeUpdated();
				if (_this.props.item.IllustrationLink && _this.props.item.IllustrationLink !== "00000000-0000-0000-0000-000000000000") {
					_actionsIllustration_actions2['default'].loadIllustrationForOverlay(_this.props.item.IllustrationLink, _this.props.item.NodeType);
				}
			}
		};
	}

	BrandNavigationTreeItem.prototype.render = function render() {
		var _props$item = this.props.item;
		var Id = _props$item.Id;
		var Description = _props$item.Description;
		var NodeType = _props$item.NodeType;

		var url = hiabconfig.explodedViews.explodedViewsURL + Id;

		var isModel = NodeType === 0;

		return _react2['default'].createElement(
			'li',
			null,
			isModel ? _react2['default'].createElement(
				'a',
				{ className: 'link', href: url },
				_react2['default'].createElement('i', { className: 'icon-angle-right' }),
				Description
			) : _react2['default'].createElement(
				'a',
				{ onClick: this.handleClick.bind(this), href: '#' },
				_react2['default'].createElement('i', { className: 'icon-angle-right' }),
				Description
			)
		);
	};

	return BrandNavigationTreeItem;
})(_react2['default'].Component);

;
exports['default'] = BrandNavigationTreeItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_actions/illustration_actions":638,"../../_stores/history_store":716,"../../_stores/treeview_store":731,"react":525}],751:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var Brands = (function (_React$Component) {
	_inherits(Brands, _React$Component);

	function Brands(props) {
		var _this = this;

		_classCallCheck(this, Brands);

		_React$Component.call(this, props);

		this.handleClick = function (item, e) {
			e.preventDefault();

			//Push parent to history navigation
			_storesHistory_store2['default'].set(_this.props.currentChild.Id, _this.props.currentChild);

			e.currentTarget.className = e.currentTarget.className + ' is-loading';
			_storesHistory_store2['default'].setCurrentNav(item);
			_actionsHistory_actions2['default'].storeUpdated();
		};

		this.props = {
			currentChild: null,
			items: []
		};
	}

	Brands.prototype.render = function render() {
		var _this2 = this;

		var brands = [];
		if (this.props.items.data) {
			brands = this.props.items.data.map(function (item) {
				return _react2['default'].createElement(
					'li',
					{ key: item.Id },
					_react2['default'].createElement(
						'a',
						{ href: '#', onClick: _this2.handleClick.bind(_this2, item) },
						_react2['default'].createElement(
							'span',
							null,
							item.Description
						)
					)
				);
			});
		}
		// console.log('brands');
		// console.log(brands);
		return _react2['default'].createElement(
			'nav',
			{ className: 'brand-logos' },
			_react2['default'].createElement(
				'ul',
				null,
				brands
			)
		);
	};

	return Brands;
})(_react2['default'].Component);

;
exports['default'] = Brands;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_stores/history_store":716,"react":525}],752:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var Documents = (function (_React$Component) {
	_inherits(Documents, _React$Component);

	function Documents(props) {
		_classCallCheck(this, Documents);

		_React$Component.call(this, props);
		this.props = {
			documents: []
		};
	}

	Documents.prototype.render = function render() {

		if (!this.props.documents) return null;
		if (this.props.documents.length === 0) return null;

		var documents = this.props.documents.map(function (document) {
			return _react2['default'].createElement(
				'li',
				null,
				_react2['default'].createElement(
					'a',
					{ href: document.DocumentLink, target: '_blank' },
					_react2['default'].createElement('i', { className: 'icon-doc' }),
					document.Description
				)
			);
		});

		return _react2['default'].createElement(
			'ul',
			{ className: 'documents' },
			documents
		);
	};

	return Documents;
})(_react2['default'].Component);

;
exports['default'] = Documents;

/* jshint ignore:end */
module.exports = exports['default'];

},{"react":525}],753:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesModelsearch_store = require('../../_stores/modelsearch_store');

var _storesModelsearch_store2 = _interopRequireDefault(_storesModelsearch_store);

var ModelSearchResult = (function (_React$Component) {
	_inherits(ModelSearchResult, _React$Component);

	function ModelSearchResult(props) {
		var _this = this;

		_classCallCheck(this, ModelSearchResult);

		_React$Component.call(this, props);

		this.handleClick = function (url, e) {
			if (_this.props.item.NodeType === 0) {
				if (document.getElementById('illustration')) return window.location.reload(true);
				return window.location = url;
			}
			e.preventDefault();
		};

		this.state = {
			searchResults: []
		};
	}

	ModelSearchResult.prototype.componentDidMount = function componentDidMount() {
		var _this2 = this;

		this.unsubscribe = _storesModelsearch_store2['default'].listen(function () {
			_this2.setState({ searchResults: _storesModelsearch_store2['default'].getModel().modelitem });
			_jquery2['default']('#search-result').addClass('is-open');
		});
	};

	ModelSearchResult.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	ModelSearchResult.prototype.render = function render() {
		var _this3 = this;

		if (!this.state.searchResults) return null;

		var models = [];
		var url = hiabconfig.explodedViews.explodedViewsURL;

		models = this.state.searchResults.map(function (model) {
			if (model.Documents.length === 0) {
				return _react2['default'].createElement(
					'li',
					{ key: model.Id },
					_react2['default'].createElement(
						'a',
						{ onClick: _this3.handleClick.bind(_this3, url), href: url + model.Id },
						_react2['default'].createElement('i', { className: 'icon-angle-right' }),
						model.Description
					)
				);
			} else {
				return false;
			}
		});
		return _react2['default'].createElement(
			'ul',
			null,
			models
		);
	};

	return ModelSearchResult;
})(_react2['default'].Component);

;
exports['default'] = ModelSearchResult;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_stores/modelsearch_store":721,"classnames":299,"jquery":628,"react":525}],754:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _apiModelsearch_api = require('../../_api/modelsearch_api');

var _apiModelsearch_api2 = _interopRequireDefault(_apiModelsearch_api);

var _actionsModelsearch_action = require('../../_actions/modelsearch_action');

var _actionsModelsearch_action2 = _interopRequireDefault(_actionsModelsearch_action);

var _storesModelsearch_store = require('../../_stores/modelsearch_store');

var _storesModelsearch_store2 = _interopRequireDefault(_storesModelsearch_store);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var doneTypingInterval = 200;

var ModelSearch = (function (_React$Component) {
	_inherits(ModelSearch, _React$Component);

	function ModelSearch(props) {
		_classCallCheck(this, ModelSearch);

		_React$Component.call(this, props);
		this.state = {
			loading: _storesModelsearch_store2['default'].getLoadingState()
		};
		this.typingTimer = null;
	}

	ModelSearch.prototype.doSearch = function doSearch(e) {
		e.preventDefault();
		var search = e.target.value;

		if (e.target.tagName === 'BUTTON') {
			search = this.refs.searchInput.value;
		}
		if (search.trim().length > 1) {
			_actionsModelsearch_action2['default'].loadModel(search);
			$('#search-result h4.search-res-for-req').hide();
			$('#search-result h4.search-res-for').show();
			$('#search-result h4.search-res-for span').text(' ' + $('#model-search .search-main').val());
			this.setState({
				loading: _storesModelsearch_store2['default'].getLoadingState()
			});
		} else {
			// console.log('hej');
			_apiModelsearch_api2['default'].abortSearch();
			_storesModelsearch_store2['default'].setNotEnoughCharacters();
			$('#search-result h4.search-res-for').hide();
			$('#search-result h4.search-res-for-req').show();
		}
		return false;
	};

	ModelSearch.prototype.handleKeyup = function handleKeyup(e) {
		var _this = this;

		// e.preventDefault();
		if (this.typingTimer) clearTimeout(this.typingTimer);

		var value = e.target.value;
		this.typingTimer = setTimeout(function () {
			_this.doneTyping(value);
		}, doneTypingInterval);
	};

	ModelSearch.prototype.handleKeydown = function handleKeydown(e) {
		// e.preventDefault();
		// console.log('interupt');
		if (this.typingTimer) clearTimeout(this.typingTimer);
	};

	ModelSearch.prototype.doneTyping = function doneTyping(value) {
		if (value.trim().length > 1) {
			_actionsModelsearch_action2['default'].loadModel(value);
			$('#search-result h4.search-res-for-req').hide();
			$('#search-result h4.search-res-for').show();
			$('#search-result h4.search-res-for span').text(' ' + $('#model-search .search-main').val());
			this.setState({
				loading: _storesModelsearch_store2['default'].getLoadingState()
			});
		} else {
			// console.log('hej');
			_apiModelsearch_api2['default'].abortSearch();
			_storesModelsearch_store2['default'].setNotEnoughCharacters();
			$('#search-result h4.search-res-for').hide();
			$('#search-result h4.search-res-for-req').show();
		}
	};

	ModelSearch.prototype.componentDidMount = function componentDidMount() {
		var _this2 = this;

		this.unsubscribe = _storesModelsearch_store2['default'].listen(function () {
			_this2.setState({
				loading: _storesModelsearch_store2['default'].getLoadingState()
			});
		});
	};

	//onChange={this.doSearch.bind(this)}
	//onKeyUp={this.handleKeyup.bind(this)} onKeyDown={this.handleKeydown.bind(this)}

	ModelSearch.prototype.render = function render() {
		var lang = hiabconfig.explodedViews.lang;
		var btnClass = _classnames2['default']({
			'loading': this.state.loading,
			'button': true
		});
		return _react2['default'].createElement(
			'form',
			{ onSubmit: this.doSearch.bind(this) },
			_react2['default'].createElement(
				'div',
				{ className: 'row collapse' },
				_react2['default'].createElement(
					'div',
					{ className: 'medium-10 small-9 columns' },
					_react2['default'].createElement('input', { className: 'search-main', ref: 'searchInput', type: 'search', placeholder: lang.searchFor, name: 'model',
						value: this.state.search, onKeyUp: this.handleKeyup.bind(this), onKeyDown: this.handleKeydown.bind(this) })
				),
				_react2['default'].createElement(
					'div',
					{ className: 'medium-2 small-3 columns' },
					_react2['default'].createElement(
						'button',
						{ className: btnClass, onClick: this.doSearch.bind(this) },
						lang.searchBtn
					)
				)
			)
		);
	};

	return ModelSearch;
})(_react2['default'].Component);

;
exports['default'] = ModelSearch;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/modelsearch_action":639,"../../_api/modelsearch_api":658,"../../_stores/modelsearch_store":721,"classnames":299,"react":525}],755:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var _illustrationHotspots = require('../illustration/hotspots');

var _illustrationHotspots2 = _interopRequireDefault(_illustrationHotspots);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var VisualBrowsing = (function (_React$Component) {
	_inherits(VisualBrowsing, _React$Component);

	function VisualBrowsing(props) {
		var _this = this;

		_classCallCheck(this, VisualBrowsing);

		_React$Component.call(this, props);

		this.handleClick = function (hotspot, e) {

			if (hotspot.IllustrationLinkNodeType === 2) {
				//Push parent to history navigation
				_storesHistory_store2['default'].set(_this.props.currentChild.Id, _this.props.currentChild);
				_storesHistory_store2['default'].setCurrentNav({
					'Id': hotspot.IllustrationLink,
					'Description': hotspot.IllustrationLinkNodeDescription,
					'IsRoot': false
				});
				_actionsHistory_actions2['default'].storeUpdated();
			}

			if (hotspot.IllustrationLinkNodeType === 0) {
				var linkUrl = window.location.origin + hiabconfig.explodedViews.explodedViewsURL + hotspot.IllustrationLink;
				window.location.href = linkUrl;
				return true;
			}

			e.preventDefault();
		};

		this.imgOnLoad = function (e) {

			_this.setState({
				illustration: {
					img: {
						height: e.target.naturalHeight,
						width: e.target.naturalWidth
					}
				}
			});
		};

		this.props = {
			currentChild: null
		};

		this.state = {
			illustration: {
				img: {
					height: null,
					width: null
				}
			}
		};
	}

	VisualBrowsing.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.currentChild.Illustration || $.isEmptyObject(this.props.currentChild.Illustration)) return null;

		var hotspots = [];

		this.props.currentChild.Illustration.Hotspots.forEach(function (hotspot, key) {
			var hotspotKey = 'hotspot' + key;
			hotspots.push(_react2['default'].createElement(_illustrationHotspots2['default'], { key: hotspotKey, hotspot: hotspot, imgprops: _this2.state.illustration.img, clickHandler: _this2.handleClick.bind(_this2, hotspot) }));
		});

		//let imgsrcDev = 'http://hiabecom-dev.knowitecommerce.se/' + this.props.currentChild.Illustration.Image;
		var imgsrc = this.props.currentChild.Illustration.Image;

		//let imgsrc = 'http://hiabecom-dev.knowitecommerce.se/' + this.props.currentChild.Illustration.Image;

		return _react2['default'].createElement(
			'figure',
			{ className: '' },
			_react2['default'].createElement('img', { src: imgsrc, alt: '', onLoad: this.imgOnLoad.bind(this) }),
			hotspots
		);
	};

	return VisualBrowsing;
})(_react2['default'].Component);

;
exports['default'] = VisualBrowsing;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_stores/history_store":716,"../../_stores/illustration_store":718,"../../_stores/treeview_store":731,"../illustration/hotspots":769,"react":525}],756:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _breadcrumb_item = require('./breadcrumb_item');

var _breadcrumb_item2 = _interopRequireDefault(_breadcrumb_item);

var _apiBreadcrumb_api = require('../../_api/breadcrumb_api');

var _apiBreadcrumb_api2 = _interopRequireDefault(_apiBreadcrumb_api);

var Breadcrumb = (function (_React$Component) {
	_inherits(Breadcrumb, _React$Component);

	function Breadcrumb(props) {
		_classCallCheck(this, Breadcrumb);

		_React$Component.call(this, props);

		this.state = {
			breadcrumb: []
		};
	}

	Breadcrumb.prototype.fetchBreadcrumb = function fetchBreadcrumb(modelId) {
		var _this = this;

		var isMachine = false;
		var isModel = false;
		if (hiabconfig.hasEquipmentTypeRestriction) {
			document.getElementsByClassName("uc-breadcrumb")[0].style.display = 'none';
			return null;
		}

		if (modelId.substring(0, 8) == 'machine-') {
			isMachine = true;
			modelId = modelId.replace('machine-', '');
		}

		if (modelId.substring(0, 6) == 'model-') {
			isModel = true;
			modelId = modelId.replace('model-', '');
		}

		if (isMachine) {
			_apiBreadcrumb_api2['default'].getMachineBreadcrumb(modelId).then(function (response) {
				_this.setState({ breadcrumb: [response] });
			})['catch'](function (message) {
				throw new Error(message);
			});
		} else if (isModel) {
			_apiBreadcrumb_api2['default'].getModelBreadcrumb(modelId).then(function (response) {
				_this.setState({ breadcrumb: [response] });
			})['catch'](function (message) {
				throw new Error(message);
			});
		} else {
			_apiBreadcrumb_api2['default'].getBreadcrumb(modelId).then(function (response) {
				_this.setState({ breadcrumb: response });
			})['catch'](function (message) {
				throw new Error(message);
			});
		}
	};

	Breadcrumb.prototype.componentDidMount = function componentDidMount() {
		if (this.props.model) {
			this.fetchBreadcrumb(this.props.model);
		}
	};

	Breadcrumb.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.model) return null;

		var bredcrumbItems = null;
		var lang = hiabconfig.search.lang;
		var loading = "breadcrumbs is-loading";
		var isMachine = this.props.model.substring(0, 8) == 'machine-';
		var isModel = this.props.model.substring(0, 6) == 'model-';

		if (this.state.breadcrumb.length > 0) {
			loading = "breadcrumbs";
		}

		if (isMachine) {
			if (this.state.breadcrumb.length > 0) {
				bredcrumbItems = _react2['default'].createElement(
					'li',
					{ className: 'machine-breadcrumb-item' },
					lang.serialnumber,
					': ',
					this.state.breadcrumb[0].label,
					' | ',
					this.state.breadcrumb[0].materialnumber
				);
			}
		} else if (isModel) {
			if (this.state.breadcrumb.length > 0) {
				bredcrumbItems = _react2['default'].createElement(
					'li',
					{ className: 'machine-breadcrumb-item' },
					this.state.breadcrumb[0].modelName
				);
			}
		} else {
			bredcrumbItems = this.state.breadcrumb.map(function (item) {
				return _react2['default'].createElement(_breadcrumb_item2['default'], { key: item.Id, item: item, model: _this2.props.model });
			});
		}

		return _react2['default'].createElement(
			'ul',
			{ className: loading },
			bredcrumbItems
		);
	};

	return Breadcrumb;
})(_react2['default'].Component);

;
exports['default'] = Breadcrumb;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_api/breadcrumb_api":651,"./breadcrumb_item":757,"react":525}],757:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactRouter = require('react-router');

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesBreadcrumb_store = require('../../_stores/breadcrumb_store');

var _storesBreadcrumb_store2 = _interopRequireDefault(_storesBreadcrumb_store);

var _storesHistory_store = require('../../_stores/history_store');

var _storesHistory_store2 = _interopRequireDefault(_storesHistory_store);

var _actionsHistory_actions = require('../../_actions/history_actions');

var _actionsHistory_actions2 = _interopRequireDefault(_actionsHistory_actions);

var BreadcrumbItem = (function (_React$Component) {
	_inherits(BreadcrumbItem, _React$Component);

	function BreadcrumbItem(props) {
		var _this = this;

		_classCallCheck(this, BreadcrumbItem);

		_React$Component.call(this, props);

		this.handleClick = function (e) {
			if (_this.props.item.Id === _this.props.model) return window.location.reload(true);
			_this.pushToHistory();
			_storesHistory_store2['default'].removeHistoryAfter(_this.props.item.Id);
			_storesHistory_store2['default'].setCurrentNav({
				Id: _this.props.item.Id,
				Description: _this.props.item.Description,
				Illustration: _this.props.item.Illustration
			});

			//Notify other components that history changed
			_actionsHistory_actions2['default'].storeUpdated();
			_jquery2['default']('body').addClass('brandtree-open');
			e.preventDefault();
		};
	}

	BreadcrumbItem.prototype.pushToHistory = function pushToHistory() {
		//Push root element to history
		_storesHistory_store2['default'].set(_storesHistory_store2['default'].getCurrentNav().Id, _storesHistory_store2['default'].getCurrentNav());

		//Push it to hisotry
		var breadcrumitems = _storesBreadcrumb_store2['default'].get(this.props.model).data;
		for (var i = 0; i < breadcrumitems.length; i++) {
			var item = breadcrumitems[i];
			var historyItem = { Id: item.Id,
				Description: item.Description,
				Illustration: item.Illustration
			};

			_storesHistory_store2['default'].set(historyItem.Id, historyItem);
		}
	};

	BreadcrumbItem.prototype.render = function render() {
		var explodedViewsUrl = hiabconfig.explodedViews.explodedViewsURL;
		var item = this.props.item;
		var breadCrumItem = _react2['default'].createElement(
			_reactRouter.Link,
			{ onClick: this.handleClick.bind(this), to: explodedViewsUrl + this.props.model },
			item.Description
		);

		return _react2['default'].createElement(
			'li',
			null,
			breadCrumItem
		);
	};

	return BreadcrumbItem;
})(_react2['default'].Component);

;
exports['default'] = BreadcrumbItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/history_actions":637,"../../_stores/breadcrumb_store":698,"../../_stores/history_store":716,"jquery":628,"react":525,"react-router":381}],758:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesBrand_filter_store = require('../../_stores/brand_filter_store');

var _storesBrand_filter_store2 = _interopRequireDefault(_storesBrand_filter_store);

var _actionsBrand_filter_actions = require('../../_actions/brand_filter_actions');

var _actionsBrand_filter_actions2 = _interopRequireDefault(_actionsBrand_filter_actions);

var _filter_toggle = require('./filter_toggle');

var _filter_toggle2 = _interopRequireDefault(_filter_toggle);

var brandLogos = {
  'Hiab||HIAB': '/Styles/Images/Logos/hiab_small.png',
  'Jonsered||JONSERED': '/Styles/Images/Logos/jonsered_small.png',
  'Loglift||LOGLIFT': '/Styles/Images/Logos/loglift_small.png',
  'Multilift||MULTILIFT': '/Styles/Images/Logos/multilift_small.png',
  'Moffett||MOFFETT': '/Styles/Images/Logos/moffett_small.png',
  'Del||DEL': '/Styles/Images/Logos/del_small.png',
  'Zepro||ZEPRO': '/Styles/Images/Logos/zepro_small.png',
  'Waltco||WALTCO': '/Styles/Images/Logos/waltco_small.png'
};

var translations = {};

var BrandFilter = (function (_React$Component) {
  _inherits(BrandFilter, _React$Component);

  function BrandFilter(props) {
    _classCallCheck(this, BrandFilter);

    _React$Component.call(this, props);

    this.state = {
      filters: _storesBrand_filter_store2['default'].getInitialState()
    };

    translations.brand = LocalizationStore.getTranslation('/Search/Brand');
  }

  BrandFilter.prototype.componentDidMount = function componentDidMount() {
    this.unsubscribe = _storesBrand_filter_store2['default'].listen(this.onFiltersChange.bind(this));

    // one minor problem:
    // someone clicking a checkbox before react is hooked. possible solutions:
    // 1) Look through checboxes in this function and set state accordingly
    // 2) Or keep all checkboxes disabled
  };

  BrandFilter.prototype.componentWillUnmount = function componentWillUnmount() {
    this.unsubscribe();
  };

  BrandFilter.prototype.onFiltersChange = function onFiltersChange(filters) {
    this.setState({ filters: filters });
  };

  BrandFilter.prototype.handleFilterToggle = function handleFilterToggle(brand) {
    _actionsBrand_filter_actions2['default'].toggleFilter(brand);
  };

  BrandFilter.prototype.handleAllFilterToggle = function handleAllFilterToggle() {
    // 'all' filter == no filter
    _actionsBrand_filter_actions2['default'].clearFilters();
  };

  BrandFilter.prototype.render = function render() {
    var _this = this;

    // console.log(this.state.filters);
    // return false;
    if (this.state.filters.length === 0) return false;

    var noFilterSelected = this.state.filters.filter(function (x) {
      return x.selected;
    }).length == 0;
    var selectedAbleItems = false;

    var inputs = this.state.filters.map(function (x) {
      return _react2['default'].createElement(_filter_toggle2['default'], { key: x.name,
        count: x.count,
        name: x.name,
        label: x.displayName,
        logo: brandLogos[x.name],
        inactive: x.count == 0,
        selected: x.selected,
        toggle: _this.handleFilterToggle.bind(_this, x.name) });
    });

    if (inputs.length > 0) {
      selectedAbleItems = true;
    }

    var brandOpen = _classnames2['default']({
      'filter-wrapper': true,
      'is-open': this.props.isOpen,
      'has-items': true });
    //props.hasItems
    var brandToggle = _classnames2['default']({
      'is-open': this.props.isOpen,
      'has-items': true });

    //props.hasItems
    return _react2['default'].createElement(
      'div',
      { className: 'filter-item' },
      _react2['default'].createElement(
        'h3',
        { className: brandToggle, 'data-toggle': '#brand-filter' },
        translations.brand,
        _react2['default'].createElement('i', { className: 'icon-angle-down' })
      ),
      _react2['default'].createElement(
        'div',
        { className: brandOpen, id: 'brand-filter' },
        _react2['default'].createElement(
          'nav',
          null,
          _react2['default'].createElement(
            'ul',
            { className: 'checkbox-filter' },
            selectedAbleItems ? _react2['default'].createElement(_filter_toggle2['default'], { label: 'All', selected: noFilterSelected, inactive: false, toggle: this.handleAllFilterToggle.bind(this) }) : null,
            selectedAbleItems ? inputs : null
          )
        )
      )
    );

    // return (
    //   <div className="uc-filter-brand">
    //     <div className="row">
    //       <div className="small-12 columns">
    //         <ul className="checkbox-filter">
    //           <FilterToggle label="All" selected={noFilterSelected} inactive={false} toggle={this.handleAllFilterToggle.bind(this)} />
    //
    //           {this.state.filters.map(x =>
    //             <FilterToggle key={x.name}
    //                           name={x.name}
    //                           label={x.name.split("||")[1]}
    //                           logo={brandLogos[x.name]}
    //                           inactive={x.count == 0 && !x.selected}
    //                           selected={x.selected}
    //                           toggle={this.handleFilterToggle.bind(this, x.name)} /> )}
    //         </ul>
    //       </div>
    //     </div>
    //   </div>
    // )
  };

  return BrandFilter;
})(_react2['default'].Component);

exports['default'] = BrandFilter;
module.exports = exports['default'];

},{"../../_actions/brand_filter_actions":632,"../../_stores/brand_filter_store":697,"./filter_toggle":760,"classnames":299,"react":525}],759:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesFilter_count_store = require('../../_stores/filter_count_store');

var _storesFilter_count_store2 = _interopRequireDefault(_storesFilter_count_store);

var FilterCount = (function (_React$Component) {
  _inherits(FilterCount, _React$Component);

  function FilterCount(props) {
    _classCallCheck(this, FilterCount);

    _React$Component.call(this, props);
    this.state = {
      filterCount: _storesFilter_count_store2['default'].getInitialState()
    };
  }

  FilterCount.prototype.componentDidMount = function componentDidMount() {
    this.unsubscribe = _storesFilter_count_store2['default'].listen(this.onFilterCountUpdate.bind(this));
  };

  FilterCount.prototype.componentWillUnmount = function componentWillUnmount() {
    this.unsubscribe();
  };

  FilterCount.prototype.onFilterCountUpdate = function onFilterCountUpdate(filterCount) {
    this.setState({ filterCount: filterCount });
  };

  FilterCount.prototype.render = function render() {
    var filterCount = this.state.filterCount;

    return _react2['default'].createElement(
      'span',
      { id: 'active-filters' },
      filterCount
    );
  };

  return FilterCount;
})(_react2['default'].Component);

exports['default'] = FilterCount;
module.exports = exports['default'];

},{"../../_stores/filter_count_store":715,"react":525}],760:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var FilterToggle = function FilterToggle(props) {
  var label = props.label;
  var name = props.name;
  var count = props.count;
  var logo = props.logo;
  var selected = props.selected;
  var inactive = props.inactive;
  var toggle = props.toggle;

  var className = selected ? 'is-selected ' : '';
  className += inactive ? 'inactive' : '';

  return _react2['default'].createElement(
    'li',
    { className: className },
    _react2['default'].createElement(
      'label',
      { htmlFor: name },
      _react2['default'].createElement('input', { id: name, disabled: inactive, checked: selected, type: 'checkbox', onChange: toggle }),
      logo ? _react2['default'].createElement('img', { src: logo, alt: label }) : label,
      typeof count != 'undefined' ? _react2['default'].createElement(
        'span',
        { className: 'count' },
        count
      ) : null
    )
  );
};

FilterToggle.PropTypes = {
  label: _react2['default'].PropTypes.string,
  logo: _react2['default'].PropTypes.string,
  selected: _react2['default'].PropTypes.boolean,
  inactive: _react2['default'].PropTypes.boolean,
  toggle: _react2['default'].PropTypes['function']
};

exports['default'] = FilterToggle;
module.exports = exports['default'];

},{"react":525}],761:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _actionsUsage_type_filter_actions = require('../../_actions/usage_type_filter_actions');

var _actionsUsage_type_filter_actions2 = _interopRequireDefault(_actionsUsage_type_filter_actions);

// import GroupSelector from '../search/group_selector';

var _filter_count = require('./filter_count');

var _filter_count2 = _interopRequireDefault(_filter_count);

var _usage_type_filter = require('./usage_type_filter');

var _usage_type_filter2 = _interopRequireDefault(_usage_type_filter);

var _serial_number_filter = require('./serial_number_filter');

var _serial_number_filter2 = _interopRequireDefault(_serial_number_filter);

var _brand_filter = require('./brand_filter');

var _brand_filter2 = _interopRequireDefault(_brand_filter);

// import UsageTypeFilterStore from '../../_stores/usage_type_filter_store';

var _product_line_filter = require('./product_line_filter');

var _product_line_filter2 = _interopRequireDefault(_product_line_filter);

// import ProductLineFilterStore from '../../_stores/product_line_filter_store';

var _top_category_filter = require('./top_category_filter');

var _top_category_filter2 = _interopRequireDefault(_top_category_filter);

// import TopCategoryFilterStore from '../../_stores/top_category_filter_store';
// import SigsFilter from './sigs_filter';
// import Sorter from './sorter';

var translations = {};

var Filters = (function (_React$Component) {
  _inherits(Filters, _React$Component);

  function Filters(props) {
    _classCallCheck(this, Filters);

    _React$Component.call(this, props);
    this.state = {
      selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
      totalMatching: _storesSearch_result_store2['default'].getTotalMatching(),
      loading: _storesSearch_result_store2['default'].getLoading(),
      query: SearchStore.getQuery(),
      showExtraFilters: false
    };

    // productLineFilters: ProductLineFilterStore.getInitialState(),
    // usageTypeFilters: UsageTypeFilterStore.getInitialState(),
    // topCategoryFilters: TopCategoryFilterStore.getInitialState(),
    translations.filters = _storesLocalization_store2['default'].getTranslation('/Filter/Filters');
    translations.clearAll = _storesLocalization_store2['default'].getTranslation('/Filter/ClearAll');
    translations.yourSearchFor = _storesLocalization_store2['default'].getTranslation('/Search/SearchFor');
    translations.resultedIn = _storesLocalization_store2['default'].getTranslation('/Search/ResultedIn');
    translations.hits = _storesLocalization_store2['default'].getTranslation('/Search/Hits');
    translations.hit = _storesLocalization_store2['default'].getTranslation('/Search/Hit');
    translations.searching = _storesLocalization_store2['default'].getTranslation('/Search/Searching');
    translations.loading = _storesLocalization_store2['default'].getTranslation('/Search/Loading');
  }

  // const UsageType = (props) =>{
  //
  //   let usageTypeOpen = classNames({
  //     'filter-wrapper': true,
  //     'is-open': props.isOpen,
  //     'has-items': props.hasItems
  //   });
  //   let usageTypeToggle = classNames({
  //     'is-open': props.isOpen,
  //     'has-items': props.hasItems
  //   });
  //
  //   return(
  //     <div className="filter-item">
  //       <h3 className={usageTypeToggle} data-toggle="#usage-type-filter">{translations.usageType}<i className="icon-angle-down"></i></h3>
  //       <div className={usageTypeOpen} id="usage-type-filter">
  //         <UsageTypeFilter />
  //       </div>
  //     </div>
  //   );
  // }
  //
  // const ProductLine = (props) =>{
  //
  //   let productLineOpen = classNames({
  //     'filter-wrapper': true,
  //     'is-open': props.isOpen,
  //     'has-items': props.hasItems
  //   });
  //   let productLineToggle = classNames({
  //     'is-open': props.hasItems,
  //     'has-items': props.hasItems
  //   });
  //
  //   return (
  //     <div className="filter-item">
  //       <h3 className={productLineToggle} data-toggle="#product-line-filter">{translations.productLine}<i className="icon-angle-down"></i></h3>
  //       <div className={productLineOpen} id="product-line-filter">
  //         <ProductLineFilter />
  //       </div>
  //     </div>
  //   );
  // }
  //
  // const TopCategory = (props) =>{
  //
  //   let topCategoryOpen = classNames({
  //     'filter-wrapper': true,
  //     'is-open': props.isOpen,
  //     'has-items': props.hasItems
  //   });
  //   let topCategoryToggle = classNames({
  //     'is-open': props.isOpen,
  //     'has-items': props.hasItems
  //   });
  //
  //   return (
  //     <div className="filter-item">
  //       <h3 className={topCategoryToggle} data-toggle="#top-category-filter">{translations.topCategory}<i className="icon-angle-down"></i></h3>
  //       <div className={topCategoryOpen} id="top-category-filter">
  //         <TopCategoryFilter />
  //       </div>
  //     </div>
  //   );
  // }

  Filters.prototype.toggleExtraFilters = function toggleExtraFilters() {
    this.setState({ showExtraFilters: !this.state.showExtraFilters });
  };

  Filters.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    this.unsubscribe1 = _storesSearch_result_store2['default'].listen(function () {
      return _this.setState({
        selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
        totalMatching: _storesSearch_result_store2['default'].getTotalMatching(),
        loading: _storesSearch_result_store2['default'].getLoading()
      });
    });

    // productLineFilters: ProductLineFilterStore.getInitialState(),
    // usageTypeFilters: UsageTypeFilterStore.getInitialState(),
    // topCategoryFilters: TopCategoryFilterStore.getInitialState(),
    this.unsubscribe2 = SearchStore.listen(function () {
      _this.setState({
        query: SearchStore.getQuery()
      });
    });
  };

  Filters.prototype.componentWillUnmount = function componentWillUnmount() {
    this.unsubscribe();
    this.unsubscribe2();
  };

  Filters.prototype.render = function render() {
    var _state = this.state;
    var selectedGroup = _state.selectedGroup;
    var totalMatching = _state.totalMatching;
    var query = _state.query;
    var loading = _state.loading;
    var showExtraFilters = _state.showExtraFilters;

    var showFilters = selectedGroup == 'spareParts' || selectedGroup == 'lightSparePartViewModel' ? true : false;

    var isOnSearchPage = typeof query !== 'undefined';

    // let hasUsageType = this.state.usageTypeFilters.length > 0 ? true : false;
    // let hasProducLine = this.state.productLineFilters.length > 0 ? true : false;
    // let hasTopCategory = this.state.topCategoryFilters.length > 0 ? true : false;

    var filtersClass = _classnames2['default']({
      'uc-filters': true,
      'is-loading': this.state.loading
    });
    // {isOnSearchPage ? <UsageType isOpen={true} hasItems={hasUsageType} /> : <UsageType isOpen={false} hasItems={hasUsageType} />}
    // {isOnSearchPage ? <ProductLine isOpen={true} hasItems={hasProducLine} /> : <ProductLine isOpen={false} hasItems={hasProducLine} />}
    // {isOnSearchPage ? <TopCategory isOpen={true} hasItems={hasTopCategory} /> : null}
    return _react2['default'].createElement(
      'section',
      { className: filtersClass },
      _storesSearch_result_store2['default'].getUserSignedIn() ? isOnSearchPage ? _react2['default'].createElement(_serial_number_filter2['default'], { isOpen: true }) : null : null,
      isOnSearchPage ? _react2['default'].createElement(_brand_filter2['default'], { isOpen: true }) : _react2['default'].createElement(_brand_filter2['default'], { isOpen: false }),
      isOnSearchPage ? _react2['default'].createElement(_product_line_filter2['default'], { isOpen: true }) : _react2['default'].createElement(_product_line_filter2['default'], { isOpen: false }),
      isOnSearchPage ? _react2['default'].createElement(_top_category_filter2['default'], { isOpen: true }) : null,
      isOnSearchPage ? _react2['default'].createElement(_usage_type_filter2['default'], { isOpen: true }) : _react2['default'].createElement(_usage_type_filter2['default'], { isOpen: false })
    );
  };

  return Filters;
})(_react2['default'].Component);

exports['default'] = Filters;
module.exports = exports['default'];

},{"../../_actions/usage_type_filter_actions":649,"../../_stores/localization_store":719,"../../_stores/search_result_store":725,"./brand_filter":758,"./filter_count":759,"./product_line_filter":762,"./serial_number_filter":763,"./top_category_filter":765,"./usage_type_filter":766,"classnames":299,"react":525}],762:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesProduct_line_filter_store = require('../../_stores/product_line_filter_store');

var _storesProduct_line_filter_store2 = _interopRequireDefault(_storesProduct_line_filter_store);

// import UsageTypeFilterActions from '../../_actions/usage_type_filter_actions';

var _actionsProduct_line_filter_actions = require('../../_actions/product_line_filter_actions');

var _actionsProduct_line_filter_actions2 = _interopRequireDefault(_actionsProduct_line_filter_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _filter_toggle = require('./filter_toggle');

var _filter_toggle2 = _interopRequireDefault(_filter_toggle);

var translations = {};

var ProductLineFilter = (function (_React$Component) {
		_inherits(ProductLineFilter, _React$Component);

		function ProductLineFilter(props) {
				_classCallCheck(this, ProductLineFilter);

				_React$Component.call(this, props);

				this.state = {
						filters: _storesProduct_line_filter_store2['default'].getInitialState()
				};

				translations.productLine = _storesLocalization_store2['default'].getTranslation('/Search/ProductLineTitle');
		}

		ProductLineFilter.prototype.componentDidMount = function componentDidMount() {
				this.unsubscribe = _storesProduct_line_filter_store2['default'].listen(this.onFiltersChange.bind(this));
		};

		ProductLineFilter.prototype.componentWillUnmount = function componentWillUnmount() {
				this.unsubscribe();
		};

		ProductLineFilter.prototype.onFiltersChange = function onFiltersChange(filters) {
				this.setState({ filters: filters });
		};

		ProductLineFilter.prototype.handleFilterToggle = function handleFilterToggle(productLine) {
				// console.log('klick');
				_actionsProduct_line_filter_actions2['default'].toggleFilter(productLine);
		};

		ProductLineFilter.prototype.handleAllFilterToggle = function handleAllFilterToggle() {
				// 'all' filter == no filter
				_actionsProduct_line_filter_actions2['default'].onClearFilters();
		};

		ProductLineFilter.prototype.render = function render() {
				var _this = this;

				if (this.state.filters.length === 0) return false;

				var noFilterSelected = this.state.filters.filter(function (x) {
						return x.selected;
				}).length == 0;
				var selectedAbleItems = false;

				var inputs = this.state.filters.map(function (x) {
						return _react2['default'].createElement(_filter_toggle2['default'], { key: x.name,
								count: x.count,
								name: x.name,
								label: x.displayName,
								inactive: x.count == 0,
								selected: x.selected,
								toggle: _this.handleFilterToggle.bind(_this, x.name) });
				});

				if (inputs.length > 0) {
						selectedAbleItems = true;
				}

				var productLineOpen = _classnames2['default']({
						'filter-wrapper': true,
						'is-open': this.props.isOpen,
						'has-items': true });
				//props.hasItems
				var productLineToggle = _classnames2['default']({
						'is-open': this.props.isOpen,
						'has-items': true });

				//props.hasItems
				return _react2['default'].createElement(
						'div',
						{ className: 'filter-item' },
						_react2['default'].createElement(
								'h3',
								{ className: productLineToggle, 'data-toggle': '#product-line-filter' },
								translations.productLine,
								_react2['default'].createElement('i', { className: 'icon-angle-down' })
						),
						_react2['default'].createElement(
								'div',
								{ className: productLineOpen, id: 'product-line-filter' },
								_react2['default'].createElement(
										'nav',
										null,
										_react2['default'].createElement(
												'ul',
												{ className: 'checkbox-filter' },
												selectedAbleItems ? _react2['default'].createElement(_filter_toggle2['default'], { label: 'All', selected: noFilterSelected, inactive: false, toggle: this.handleAllFilterToggle.bind(this) }) : null,
												selectedAbleItems ? inputs : null
										)
								)
						)
				);

				// return (
				// 	<nav>
				//     <ul className="checkbox-filter">
				// 		{selectedAbleItems ? <FilterToggle label="All" selected={noFilterSelected} inactive={false} toggle={this.handleAllFilterToggle.bind(this)} /> : null}
				// 		{selectedAbleItems ? inputs : null}
				// 		{selectedAbleItems ? null : noItems}
				//     </ul>
				// 	</nav>
				// )
		};

		return ProductLineFilter;
})(_react2['default'].Component);

exports['default'] = ProductLineFilter;
module.exports = exports['default'];

},{"../../_actions/product_line_filter_actions":642,"../../_stores/localization_store":719,"../../_stores/product_line_filter_store":724,"./filter_toggle":760,"classnames":299,"react":525}],763:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reflux = require('reflux');

var _reflux2 = _interopRequireDefault(_reflux);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesSerial_number_filter_store = require('../../_stores/serial_number_filter_store');

var _storesSerial_number_filter_store2 = _interopRequireDefault(_storesSerial_number_filter_store);

// import UsageTypeFilterActions from '../../_actions/usage_type_filter_actions';

var _actionsSerial_number_filter_actions = require('../../_actions/serial_number_filter_actions');

var _actionsSerial_number_filter_actions2 = _interopRequireDefault(_actionsSerial_number_filter_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _filter_toggle = require('./filter_toggle');

var _filter_toggle2 = _interopRequireDefault(_filter_toggle);

var translations = {};

var SerialNumberFilter = (function (_React$Component) {
	_inherits(SerialNumberFilter, _React$Component);

	function SerialNumberFilter(props) {
		var _this = this;

		_classCallCheck(this, SerialNumberFilter);

		_React$Component.call(this, props);
		// Connects this.state in component to this.data in store

		this.emptyFilterField = function () {
			_this.setState({ serialNumber: "", serialNoInvalid: false });
			_actionsSerial_number_filter_actions2['default'].clearFilter();
		};

		mixins: [_reflux2['default'].connect(_storesSerial_number_filter_store2['default'], "serialNumberFilter")], this.state = {
			serialNumber: "",
			showEmptyValueButton: false,
			serialNoInvalid: false
		};

		translations.serialApplyButtonText = _storesLocalization_store2['default'].getTranslation('/Search/Filters/Serial/ApplyButtonText');
		translations.serialPlaceholderText = _storesLocalization_store2['default'].getTranslation('/Search/Filters/Serial/PlaceholderText');
		translations.serialDescription = _storesLocalization_store2['default'].getTranslation('/Search/Filters/Serial/Description');
		translations.serialTitle = _storesLocalization_store2['default'].getTranslation('/Search/Filters/Serial/Title');
		translations.serialErrorNotFound = _storesLocalization_store2['default'].getTranslation('/Search/Filters/Serial/Error/SerialNotFound');
	}

	SerialNumberFilter.prototype.componentDidMount = function componentDidMount() {
		this.unsubscribe = _storesSerial_number_filter_store2['default'].listen(this.onUpdateFilters.bind(this));
	};

	SerialNumberFilter.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	SerialNumberFilter.prototype.handleFilterToggle = function handleFilterToggle() {
		_actionsSerial_number_filter_actions2['default'].applyFilter(this.state.serialNumber);
	};

	SerialNumberFilter.prototype.onUpdateFilters = function onUpdateFilters() {
		this.setState({ serialNoInvalid: _storesSerial_number_filter_store2['default'].serialNoInvalid });
		if (this.state.serialNumber == "") {
			//Backend returns serial is invalid -flag with an empty serial passed, so handle that here. (there should not be a visual error displayed then)
			this.setState({ serialNoInvalid: false });
		}
	};

	SerialNumberFilter.prototype.render = function render() {
		var _this2 = this;

		var serialFilterOpen = _classnames2['default']({
			'filter-wrapper': true,
			'is-open': this.props.isOpen,
			'has-items': true, //props.hasItems
			'serial-filter-wrapper': true
		});
		var serialFilterToggle = _classnames2['default']({
			'is-open': this.props.isOpen,
			'has-items': true });

		//props.hasItems
		return _react2['default'].createElement(
			'div',
			{ className: 'filter-item' },
			_react2['default'].createElement(
				'h3',
				{ className: serialFilterToggle, 'data-toggle': '#serial-number-filter' },
				translations.serialTitle,
				_react2['default'].createElement('i', { className: 'icon-angle-down' })
			),
			_react2['default'].createElement(
				'div',
				{ className: serialFilterOpen, id: 'serial-number-filter' },
				_react2['default'].createElement(
					'strong',
					null,
					translations.serialDescription
				),
				_react2['default'].createElement(
					'div',
					{ className: 'serial-filter-input-wrapper' },
					_react2['default'].createElement('input', { type: 'text', name: 'serial-filter-input', placeholder: translations.serialPlaceholderText, className: this.state.serialNoInvalid ? 'serial-filter-input error' : 'serial-filter-input', value: this.state.serialNumber, onChange: function (e) {
							return _this2.setState({ serialNumber: e.target.value });
						} }),
					this.state.filterValue != "" ? _react2['default'].createElement(
						'a',
						{ href: '#', className: 'empty-filter-value', onClick: this.emptyFilterField.bind(this) },
						_react2['default'].createElement('i', { className: 'icon-cancel-circled' })
					) : ""
				),
				this.state.serialNoInvalid && _react2['default'].createElement(
					'span',
					{ className: 'error' },
					translations.serialErrorNotFound
				),
				_react2['default'].createElement(
					'button',
					{ className: 'button waves-effect waves-light serial-filter-apply-button', onClick: this.handleFilterToggle.bind(this) },
					translations.serialApplyButtonText
				)
			)
		);
	};

	return SerialNumberFilter;
})(_react2['default'].Component);

exports['default'] = SerialNumberFilter;
module.exports = exports['default'];

},{"../../_actions/serial_number_filter_actions":645,"../../_stores/localization_store":719,"../../_stores/serial_number_filter_store":727,"./filter_toggle":760,"classnames":299,"react":525,"reflux":542}],764:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesSort_store = require('../../_stores/sort_store');

var _storesSort_store2 = _interopRequireDefault(_storesSort_store);

var _actionsSort_actions = require('../../_actions/sort_actions');

var _actionsSort_actions2 = _interopRequireDefault(_actionsSort_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var translations = {};

var Sorter = (function (_React$Component) {
  _inherits(Sorter, _React$Component);

  function Sorter(props) {
    _classCallCheck(this, Sorter);

    _React$Component.call(this, props);

    var sortStoreState = _storesSort_store2['default'].getInitialState();
    this.state = {
      order: sortStoreState.order,
      field: sortStoreState.field,
      sortFields: _storesSearch_result_store2['default'].getSortFields()
    };

    translations.sortBy = _storesLocalization_store2['default'].getTranslation('/Filter/SortBy');
    translations.ascending = _storesLocalization_store2['default'].getTranslation('/Filter/Ascending');
    translations.descending = _storesLocalization_store2['default'].getTranslation('/Filter/Descending');
  }

  Sorter.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    this.sortUnsubscribe = _storesSort_store2['default'].listen(this.onSortStoreUpdate.bind(this));

    this.searchResultUnsubscribe = _storesSearch_result_store2['default'].listen(function () {
      return _this.setState({
        sortFields: _storesSearch_result_store2['default'].getSortFields()
      });
    });
  };

  Sorter.prototype.componentWillUnmount = function componentWillUnmount() {
    this.sortUnsubscribe();
    this.searchResultUnsubscribe();
  };

  Sorter.prototype.onSortStoreUpdate = function onSortStoreUpdate(storeState) {
    this.setState(storeState);
  };

  Sorter.prototype.handleFieldChange = function handleFieldChange(e) {
    var field = e.target.value;
    _actionsSort_actions2['default'].setField(field);
  };

  Sorter.prototype.handleOrderChange = function handleOrderChange(e) {
    var order = e.target.value;
    _actionsSort_actions2['default'].setOrder(order);
  };

  Sorter.prototype.render = function render() {
    var sortOptions = [];
    for (var field in this.state.sortFields) {
      var fieldName = this.state.sortFields[field];
      sortOptions.push(_react2['default'].createElement(
        'option',
        { value: field, key: "sort-" + field },
        fieldName
      ));
    }

    return _react2['default'].createElement(
      'div',
      { className: 'uc-list-sorter' },
      _react2['default'].createElement(
        'select',
        {
          key: 'sort-by',
          selected: this.state.sortByType,
          onChange: this.handleFieldChange,
          className: 'sort-by left type',
          id: 'sortyby'
        },
        sortOptions
      ),
      _react2['default'].createElement(
        'select',
        { className: 'sort-direction',
          value: this.state.order,
          onChange: this.handleOrderChange },
        _react2['default'].createElement(
          'option',
          { value: 'ascending' },
          translations.ascending
        ),
        _react2['default'].createElement(
          'option',
          { value: 'descending' },
          translations.descending
        )
      )
    );
  };

  return Sorter;
})(_react2['default'].Component);

exports['default'] = Sorter;
module.exports = exports['default'];

},{"../../_actions/sort_actions":646,"../../_stores/localization_store":719,"../../_stores/search_result_store":725,"../../_stores/sort_store":728,"react":525}],765:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesTop_category_filter_store = require('../../_stores/top_category_filter_store');

var _storesTop_category_filter_store2 = _interopRequireDefault(_storesTop_category_filter_store);

// import UsageTypeFilterActions from '../../_actions/usage_type_filter_actions';

var _actionsTop_category_filter_actions = require('../../_actions/top_category_filter_actions');

var _actionsTop_category_filter_actions2 = _interopRequireDefault(_actionsTop_category_filter_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _filter_toggle = require('./filter_toggle');

var _filter_toggle2 = _interopRequireDefault(_filter_toggle);

var translations = {};

var SigsFilter = (function (_React$Component) {
		_inherits(SigsFilter, _React$Component);

		function SigsFilter(props) {
				_classCallCheck(this, SigsFilter);

				_React$Component.call(this, props);

				this.state = {
						filters: _storesTop_category_filter_store2['default'].getInitialState()
				};

				translations.topCategory = _storesLocalization_store2['default'].getTranslation('/Search/TopCategoriesTitle');
		}

		SigsFilter.prototype.componentDidMount = function componentDidMount() {
				this.unsubscribe = _storesTop_category_filter_store2['default'].listen(this.onFiltersChange.bind(this));
		};

		SigsFilter.prototype.componentWillUnmount = function componentWillUnmount() {
				this.unsubscribe();
		};

		SigsFilter.prototype.onFiltersChange = function onFiltersChange(filters) {
				this.setState({ filters: filters });
		};

		SigsFilter.prototype.handleFilterToggle = function handleFilterToggle(topCategory) {
				_actionsTop_category_filter_actions2['default'].toggleFilter(topCategory);
		};

		SigsFilter.prototype.handleAllFilterToggle = function handleAllFilterToggle() {
				// 'all' filter == no filter
				_storesTop_category_filter_store2['default'].onClearFilters();
		};

		SigsFilter.prototype.render = function render() {
				var _this = this;

				if (this.state.filters.length === 0) return false;

				var noFilterSelected = this.state.filters.filter(function (x) {
						return x.selected;
				}).length == 0;
				var selectedAbleItems = false;

				var inputs = this.state.filters.map(function (x) {
						return _react2['default'].createElement(_filter_toggle2['default'], { key: x.name,
								count: x.count,
								name: x.name,
								label: x.displayName,
								inactive: x.count == 0,
								selected: x.selected,
								toggle: _this.handleFilterToggle.bind(_this, x.name) });
				});

				if (inputs.length > 0) {
						selectedAbleItems = true;
				}

				var topCategoryOpen = _classnames2['default']({
						'filter-wrapper': true,
						'is-open': this.props.isOpen,
						'has-items': true });
				//props.hasItems
				var topCategoryToggle = _classnames2['default']({
						'is-open': this.props.isOpen,
						'has-items': true });

				//props.hasItems
				return _react2['default'].createElement(
						'div',
						{ className: 'filter-item' },
						_react2['default'].createElement(
								'h3',
								{ className: topCategoryToggle, 'data-toggle': '#top-category-filter' },
								translations.topCategory,
								_react2['default'].createElement('i', { className: 'icon-angle-down' })
						),
						_react2['default'].createElement(
								'div',
								{ className: topCategoryOpen, id: 'top-category-filter' },
								_react2['default'].createElement(
										'nav',
										null,
										_react2['default'].createElement(
												'ul',
												{ className: 'checkbox-filter' },
												selectedAbleItems ? _react2['default'].createElement(_filter_toggle2['default'], { label: 'All', selected: noFilterSelected, inactive: false, toggle: this.handleAllFilterToggle.bind(this) }) : null,
												selectedAbleItems ? inputs : null
										)
								)
						)
				);
		};

		return SigsFilter;
})(_react2['default'].Component);

exports['default'] = SigsFilter;
module.exports = exports['default'];

},{"../../_actions/top_category_filter_actions":647,"../../_stores/localization_store":719,"../../_stores/top_category_filter_store":730,"./filter_toggle":760,"classnames":299,"react":525}],766:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesUsage_type_filter_store = require('../../_stores/usage_type_filter_store');

var _storesUsage_type_filter_store2 = _interopRequireDefault(_storesUsage_type_filter_store);

var _actionsUsage_type_filter_actions = require('../../_actions/usage_type_filter_actions');

var _actionsUsage_type_filter_actions2 = _interopRequireDefault(_actionsUsage_type_filter_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _filter_toggle = require('./filter_toggle');

var _filter_toggle2 = _interopRequireDefault(_filter_toggle);

var translations = {};

var UsageTypeFilter = (function (_React$Component) {
		_inherits(UsageTypeFilter, _React$Component);

		function UsageTypeFilter(props) {
				_classCallCheck(this, UsageTypeFilter);

				_React$Component.call(this, props);

				this.state = {
						filters: _storesUsage_type_filter_store2['default'].getInitialState()
				};

				translations.usageType = _storesLocalization_store2['default'].getTranslation('/Filter/UsageType');
		}

		UsageTypeFilter.prototype.componentDidMount = function componentDidMount() {
				this.unsubscribe = _storesUsage_type_filter_store2['default'].listen(this.onFiltersChange.bind(this));
		};

		UsageTypeFilter.prototype.componentWillUnmount = function componentWillUnmount() {
				this.unsubscribe();
		};

		UsageTypeFilter.prototype.onFiltersChange = function onFiltersChange(filters) {
				this.setState({ filters: filters });
		};

		UsageTypeFilter.prototype.handleFilterToggle = function handleFilterToggle(usageType) {
				_actionsUsage_type_filter_actions2['default'].toggleFilter(usageType);
		};

		UsageTypeFilter.prototype.handleAllFilterToggle = function handleAllFilterToggle() {
				// 'all' filter == no filter
				_actionsUsage_type_filter_actions2['default'].onClearFilters();
		};

		UsageTypeFilter.prototype.render = function render() {
				var _this = this;

				if (this.state.filters.length === 0) return false;

				var noFilterSelected = this.state.filters.filter(function (x) {
						return x.selected;
				}).length == 0;
				var selectedAbleItems = false;

				var inputs = this.state.filters.map(function (x) {
						return _react2['default'].createElement(_filter_toggle2['default'], { key: x.name,
								count: x.count,
								name: x.name,
								label: x.displayName,
								inactive: x.count == 0,
								selected: x.selected,
								toggle: _this.handleFilterToggle.bind(_this, x.name) });
				});

				if (inputs.length > 0) {
						selectedAbleItems = true;
				}

				var usageTypeOpen = _classnames2['default']({
						'filter-wrapper': true,
						'is-open': this.props.isOpen,
						'has-items': true });
				//props.hasItems
				var usageTypeToggle = _classnames2['default']({
						'is-open': this.props.isOpen,
						'has-items': true });

				//{selectedAbleItems ? null : noItems}
				//props.hasItems
				return _react2['default'].createElement(
						'div',
						{ className: 'filter-item' },
						_react2['default'].createElement(
								'h3',
								{ className: usageTypeToggle, 'data-toggle': '#usage-type-filter' },
								translations.usageType,
								_react2['default'].createElement('i', { className: 'icon-angle-down' })
						),
						_react2['default'].createElement(
								'div',
								{ className: usageTypeOpen, id: 'usage-type-filter' },
								_react2['default'].createElement(
										'nav',
										null,
										_react2['default'].createElement(
												'ul',
												{ className: 'checkbox-filter' },
												selectedAbleItems ? _react2['default'].createElement(_filter_toggle2['default'], { label: 'All', selected: noFilterSelected, inactive: false, toggle: this.handleAllFilterToggle.bind(this) }) : null,
												selectedAbleItems ? inputs : null
										)
								)
						)
				);
		};

		return UsageTypeFilter;
})(_react2['default'].Component);

exports['default'] = UsageTypeFilter;
module.exports = exports['default'];

},{"../../_actions/usage_type_filter_actions":649,"../../_stores/localization_store":719,"../../_stores/usage_type_filter_store":732,"./filter_toggle":760,"classnames":299,"react":525}],767:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _superagent = require('superagent');

var _superagent2 = _interopRequireDefault(_superagent);

var _promise = require('promise');

var _promise2 = _interopRequireDefault(_promise);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var LanguageSelector = (function () {
  function LanguageSelector() {
    _classCallCheck(this, LanguageSelector);
  }

  LanguageSelector.prototype.init = function init() {
    var languageSelector = _jquery2['default']('.uc-language-selector');
    var that = this;
    var pathName = '';

    languageSelector.find('a').click(function (e) {
      e.preventDefault();
      var link = _jquery2['default'](e.target);
      var language = link.data('language');
      var url = '';
      that.set(language).then(function (response) {
        window.location.href = response.Url;
      }, function (error) {
        //console.log('could not set language:', error);
      });
    });
  };

  LanguageSelector.prototype.set = function set(language) {
    _jquery2['default']('.uc-languages .icon-globe').addClass('loading');

    return new _promise2['default'](function (resolve, reject) {
      var url = '/Header/SetLanguage';
      _superagent2['default'].post(url).send({ language: language }).end(function (error, response) {
        if (response.badRequest) {
          reject('\'' + language + '\' is not supported');
        } else if (response.body) {
          resolve(response.body);
        } else {
          reject('http error');
        }
        _jquery2['default']('.uc-languages .icon-globe').removeClass('loading');
      });
    });
  };

  return LanguageSelector;
})();

exports['default'] = new LanguageSelector();
module.exports = exports['default'];

},{"jquery":628,"promise":335,"superagent":547}],768:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _wishlistWishlistHeader = require('./../wishlist/wishlistHeader');

var _wishlistWishlistHeader2 = _interopRequireDefault(_wishlistWishlistHeader);

var AddToCartButtons = (function (_React$Component) {
	_inherits(AddToCartButtons, _React$Component);

	function AddToCartButtons(props) {
		_classCallCheck(this, AddToCartButtons);

		_React$Component.call(this, props);
	}

	AddToCartButtons.prototype.render = function render() {
		var lang = hiabconfig.explodedViews.lang;
		var expandKit = '.' + this.props.part.Id;
		var addButtons = null;
		var tdClass = 'buy';
		var context = JSON.stringify(this.props.ProductContext);
		var materialNumberAsId = this.props.part.MaterialId.split('.').join('-');

		var toggleOfCanvas = _wishlistWishlistHeader2['default'].GetSelectedWishlistData() == null;

		var savedCartClass = _classnames2['default']({
			'button': true,
			'wishlist': true,
			'exploded-saved-cart-add': true,
			'saved-cart-add': true,
			'right-off-canvas-toggle': toggleOfCanvas
		});

		if (this.props.Buyable && !this.props.part.IsBlocked) {
			tdClass += ' no-padding-top';
			addButtons = _react2['default'].createElement(
				'div',
				{ className: 'button-wrapper', 'data-product-context': context },
				_react2['default'].createElement(
					'button',
					{ 'data-product-sku': this.props.part.MaterialId, className: savedCartClass },
					_react2['default'].createElement('i', { className: 'icon-saved-cart-add' })
				),
				_react2['default'].createElement(
					'button',
					{ 'data-product-sku': this.props.part.MaterialId, className: 'button add-to-cart' },
					lang.addtocart
				),
				_react2['default'].createElement(
					'button',
					{ 'data-product-sku': this.props.part.MaterialId, className: 'button quick-buy' },
					lang.quickbuy
				),
				this.props.isKit > 0 ? _react2['default'].createElement(
					'button',
					{ className: 'button expand-kit', 'data-toggle': expandKit },
					_react2['default'].createElement('i', { className: 'icon-down-open' })
				) : null,
				_react2['default'].createElement('div', { id: materialNumberAsId, className: 'SparePartResult-info' })
			);
		} else {
			if (this.props.isKit) {
				addButtons = _react2['default'].createElement(
					'div',
					null,
					_react2['default'].createElement(
						'button',
						{ className: 'button expand-kit', 'data-toggle': expandKit },
						_react2['default'].createElement('i', { className: 'icon-down-open' })
					)
				);
			}
		}

		return _react2['default'].createElement(
			'td',
			{ className: tdClass, colSpan: '7' },
			addButtons
		);
	};

	return AddToCartButtons;
})(_react2['default'].Component);

;
exports['default'] = AddToCartButtons;

/* jshint ignore:end */
module.exports = exports['default'];

},{"./../wishlist/wishlistHeader":790,"classnames":299,"react":525}],769:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _actionsIllustration_actions = require('../../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var HotSpots = (function (_React$Component) {
	_inherits(HotSpots, _React$Component);

	function HotSpots(props) {
		var _this = this;

		_classCallCheck(this, HotSpots);

		_React$Component.call(this, props);

		this.handleClick = function (e) {
			var hotspot = _this.props.hotspot,
			    noValue = '00000000-0000-0000-0000-000000000000';
			//If hotspot differ from noValue then link to another illustration
			if (hotspot.IllustrationLink !== noValue) {

				var model = hotspot.ModelForIllustrationLink === noValue ? _this.props.model : hotspot.ModelForIllustrationLink;
				window.location = hiabconfig.explodedViews.explodedViewsURL + model + '/' + _this.props.hotspot.IllustrationLink;
				return window.location.reload(true);
			}
			e.preventDefault();
			_this.props.setHotspot(_this.props.hotspot);
		};

		this.props = {
			hotspot: {
				IllustrationLink: null
			},
			imgprops: {
				height: 0,
				width: 0
			}
		};
	}

	HotSpots.prototype.calculatePosition = function calculatePosition(hotspot) {

		var width = this.props.imgprops.width,
		    height = this.props.imgprops.height,
		    hotspotHeight = hotspot.Height > 0 ? hotspot.Height + 10 : hotspot.Height,
		    hotspotWidth = hotspot.Width > 0 ? hotspot.Width + 10 : hotspot.Width;

		//Relative position
		if (hotspot.YPercent != null && hotspot.XPercent != null && hotspot.XPercent != 0 && hotspot.YPercent != 0) {
			var _pos = {
				xPos: hotspot.XPercent,
				yPos: hotspot.YPercent,
				height: hotspotHeight / height * 100,
				width: hotspotWidth / width * 100
			};
			return _pos;
		}
		var pos = {
			xPos: hotspot.X / width * 100,
			yPos: hotspot.Y / height * 100,
			height: hotspotHeight / height * 100,
			width: hotspotWidth / width * 100
		};

		return pos;
	};

	HotSpots.prototype.positionStyleHotspot = function positionStyleHotspot(hotspot) {
		var pos = this.calculatePosition(hotspot);
		var style = {
			height: pos.height + '%',
			left: pos.xPos + '%',
			top: pos.yPos + '%',
			width: pos.width + '%'
		};

		return style;
	};

	HotSpots.prototype.render = function render() {

		var style = this.positionStyleHotspot(this.props.hotspot);
		var clickHandler = this.props.clickHandler ? this.props.clickHandler : this.handleClick.bind(this);
		var hotspotText = this.props.hotspot.Type === 2 || this.props.hotspot.Type === 3 ? '' : this.props.hotspot.Text;

		var classes = _classnames2['default']({
			'hotspot': true,
			'transparent': this.props.hotspot.Type === 2 || this.props.hotspot.Type === 3
		});

		return _react2['default'].createElement(
			'div',
			{ style: style, className: classes, onClick: clickHandler },
			_react2['default'].createElement(
				'span',
				{ className: 'hotspot-text' },
				hotspotText
			)
		);
	};

	return HotSpots;
})(_react2['default'].Component);

;
exports['default'] = HotSpots;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/illustration_actions":638,"classnames":299,"react":525}],770:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var IllustrationInfo = (function (_React$Component) {
	_inherits(IllustrationInfo, _React$Component);

	function IllustrationInfo(props) {
		_classCallCheck(this, IllustrationInfo);

		_React$Component.call(this, props);

		this.props = {
			illustration: null
		};

		this.state = {
			illustration: null
		};
	}

	IllustrationInfo.prototype.render = function render() {
		if (this.props.loadingTreeView || this.props.loadingIllustration) return null;
		if (!this.props.illustration) return null;
		if (!_lodash2['default'].isEmpty(this.props.illustration)) return null;

		return _react2['default'].createElement(
			'section',
			{ className: 'text-image-block-skew' },
			_react2['default'].createElement(
				'div',
				{ className: 'link-wrapp' },
				_react2['default'].createElement(
					'div',
					{ className: 'image' },
					_react2['default'].createElement('i', { className: 'icon-drawing' })
				),
				_react2['default'].createElement(
					'div',
					{ className: 'content' },
					_react2['default'].createElement(
						'div',
						{ className: 'text-wrapper' },
						_react2['default'].createElement(
							'p',
							null,
							hiabconfig.explodedViews.infoText
						)
					)
				)
			)
		);
	};

	return IllustrationInfo;
})(_react2['default'].Component);

;
exports['default'] = IllustrationInfo;

/* jshint ignore:end */
module.exports = exports['default'];

},{"lodash":333,"react":525,"react-dom":351}],771:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _hotspots = require('./hotspots');

var _hotspots2 = _interopRequireDefault(_hotspots);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var _actionsIllustration_actions = require('../../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var _libPanzoom = require('../../_lib/panzoom');

var _libPanzoom2 = _interopRequireDefault(_libPanzoom);

var Illustration = (function (_React$Component) {
	_inherits(Illustration, _React$Component);

	function Illustration(props) {
		var _this = this;

		_classCallCheck(this, Illustration);

		_React$Component.call(this, props);

		this.imgOnLoad = function (e) {

			$('img').bind('contextmenu', function (e) {
				e.preventDefault();
				return false;
			});

			_this.setState({
				illustration: {
					img: {
						height: e.target.naturalHeight,
						width: e.target.naturalWidth
					}
				}
			});
			_storesIllustration_store2['default'].setLoadingState(false);
		};

		this.props = {
			illustration: {
				Hotspots: []
			}
		};

		this.state = {
			illustration: {
				img: {
					height: null,
					width: null
				}

			}
		};
	}

	Illustration.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
		_libPanzoom2['default'].init(_reactDom2['default'].findDOMNode(this));
	};

	Illustration.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.illustration) return null;
		if (!this.props.illustration.Image) return null;

		var hotspots = [];

		this.props.illustration.Hotspots.forEach(function (hotspot, key) {
			var hotspotKey = 'hotspot' + key;
			hotspots.push(_react2['default'].createElement(_hotspots2['default'], { key: hotspotKey, hotspot: hotspot, imgprops: _this2.state.illustration.img, setHotspot: _this2.props.setHotspot, model: _this2.props.model }));
		});
		//let imgsrc = 'http://hiabecom-dev.knowitecommerce.se' + this.props.illustration.Image;
		var imgsrc = this.props.illustration.Image;

		return _react2['default'].createElement(
			'div',
			{ className: 'uc-explodedview' },
			_react2['default'].createElement(
				'div',
				{ className: 'explodedview-zoom-container' },
				_react2['default'].createElement(
					'div',
					{ className: 'aspect-ratio' },
					_react2['default'].createElement(
						'figure',
						null,
						_react2['default'].createElement('img', { src: imgsrc, alt: '', onLoad: this.imgOnLoad.bind(this), onError: this.imgOnLoad.bind(this) }),
						hotspots
					)
				)
			),
			_react2['default'].createElement(
				'div',
				{ className: 'zoom-controls' },
				_react2['default'].createElement(
					'button',
					{ className: 'button link zoom-in zoom' },
					'+'
				),
				_react2['default'].createElement(
					'button',
					{ className: 'button link zoom-out zoom' },
					'-'
				),
				_react2['default'].createElement(
					'button',
					{ className: 'button link zoom-reset zoom' },
					_react2['default'].createElement('i', { className: 'icon-resize-small' })
				)
			)
		);
	};

	return Illustration;
})(_react2['default'].Component);

;
exports['default'] = Illustration;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/illustration_actions":638,"../../_lib/panzoom":679,"../../_stores/illustration_store":718,"./hotspots":769,"react":525,"react-dom":351}],772:[function(require,module,exports){
(function (global){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _illustration = require('./illustration');

var _illustration2 = _interopRequireDefault(_illustration);

var _illustrationInfo = require('./illustration-info');

var _illustrationInfo2 = _interopRequireDefault(_illustrationInfo);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var _actionsIllustration_actions = require('../../_actions/illustration_actions');

var _actionsIllustration_actions2 = _interopRequireDefault(_actionsIllustration_actions);

var _partlist = require('./partlist');

var _partlist2 = _interopRequireDefault(_partlist);

var _treeviewModeltree = require('../treeview/modeltree');

var _treeviewModeltree2 = _interopRequireDefault(_treeviewModeltree);

var _apiTreeview_api = require('../../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _storesModel_tree_search_store = require('../../_stores/model_tree_search_store');

var _storesModel_tree_search_store2 = _interopRequireDefault(_storesModel_tree_search_store);

var _treeviewModeltreesearch = require('../treeview/modeltreesearch');

var _treeviewModeltreesearch2 = _interopRequireDefault(_treeviewModeltreesearch);

var _breadcrumbBreadcrumb = require('../breadcrumb/breadcrumb');

var _breadcrumbBreadcrumb2 = _interopRequireDefault(_breadcrumbBreadcrumb);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

/* jshint ignore:start */

var IllustrationContainer = (function (_React$Component) {
	_inherits(IllustrationContainer, _React$Component);

	function IllustrationContainer(props) {
		_classCallCheck(this, IllustrationContainer);

		_React$Component.call(this, props);

		this.handleCloseSearchResContainer = function (e) {
			e.preventDefault();
			if (e.target.tagName === 'I') {
				e.target.parentElement.parentElement.className += ' hide';
			} else {
				e.target.parentElement.className += ' hide';
			}
		};

		this.state = {
			illustration: null,
			hotspotId: null,
			loadingTreeView: _storesTreeview_store2['default'].getLoadingState(),
			loadingIllustration: _storesIllustration_store2['default'].getLoadingState(),
			modelTreeSearchResult: null,
			modelTreeSearchValue: '',
			isMachine: false
		};
	}

	IllustrationContainer.prototype.setHotspot = function setHotspot(hotspot) {

		this.setState({
			hotspotId: hotspot.Id
		});

		//Scroll to part
		var $target = _jquery2['default']('#hotspot-' + hotspot.Id);
		var $targetOffset = $target.offset().top;
		var $targetHeight = $target.height();
		var $windowHeight = _jquery2['default'](window).height();
		var $offset = $targetOffset;

		if ($target.length === 0 && $targetHeight > $windowHeight) return;

		$offset = $targetOffset - ($windowHeight / 2 - $targetHeight / 2);

		_jquery2['default']('html, body').stop().animate({
			'scrollTop': $offset
		}, 600, 'swing', function () {});
	};

	IllustrationContainer.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		_actionsIllustration_actions2['default'].loadIllustration(nextProps.params.illustration, nextProps.params.model);
	};

	IllustrationContainer.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.setState({
			loadingIllustration: true
		});

		_actionsIllustration_actions2['default'].loadIllustration(this.props.params.illustration, this.props.params.model);
		this.setState({
			loadingIllustration: true
		});

		this.unsubscribe = _storesIllustration_store2['default'].listen(function () {
			_this.setState({
				illustration: _storesIllustration_store2['default'].getIllustration().illustration,
				hotspotId: null,
				loadingIllustration: _storesIllustration_store2['default'].getLoadingState()
			});
			triggerAnalyticsPageView(illustration.Code, window.location.href);
		});

		this.unsubscribe = _storesTreeview_store2['default'].listen(function () {
			_this.setState({
				loadingTreeView: _storesTreeview_store2['default'].getLoadingState()
			});
		});

		this.unsubscribe = _storesModel_tree_search_store2['default'].listen(function (res) {
			if (!res.ExceptionMessage) {
				document.querySelector('.uc-model-tree-search-result-container').className = 'uc-model-tree-search-result-container';
				_this.setState({
					modelTreeSearchResult: res,
					modelTreeSearchValue: _storesModel_tree_search_store2['default'].getSearchValue()
				});
			}
		});
	};

	IllustrationContainer.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	IllustrationContainer.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.params) return null;

		var lang = hiabconfig.explodedViews.lang;
		var illustrationClass = _classnames2['default']({
			'is-loading': false,
			'row': true,
			'white': true,
			'explodedview': true
		});
		if (this.state.loadingTreeView || this.state.loadingIllustration) {
			illustrationClass = _classnames2['default']({
				'is-loading': true,
				'row': true,
				'white': true,
				'explodedview': true
			});
		}
		var openDrawingBtn = null;
		if (this.state.illustration && typeof this.state.illustration.Image !== 'undefined') {
			var language = hiabconfig.preferredCulture;
			var isMachine = this.props.params.model.substring(0, 8) == 'machine-';
			var url = '';
			if (isMachine) {
				url = hiabconfig.printableIllustration.baseUrl + '?lang=' + language + '&id=' + this.props.params.illustration + '&modelId=' + this.props.params.model.replace('machine-', '');
			} else {
				url = hiabconfig.printableIllustration.baseUrl + '?lang=' + language + '&id=' + this.props.params.illustration + '&modelId=' + this.props.params.model.replace('model-', '');;
			}
			openDrawingBtn = _react2['default'].createElement(
				'a',
				{ href: url, target: '_blank', className: 'button outlined thin button-modeltree right' },
				lang.openDrawing
			);
		}

		var modelTreeSearchResults = [];
		var searchResultFor = hiabconfig.searchInModel.lang.searchFor;

		if (this.state.modelTreeSearchResult) {
			(function () {
				// console.log(this.state.modelTreeSearchResult);
				var isMachine = _this2.props.params.model.substring(0, 8) == 'machine-';
				if (_this2.state.modelTreeSearchResult.length > 0) {
					_this2.state.modelTreeSearchResult.forEach(function (item) {
						var key = 'search-' + item.IllustrationCode;
						var url = null;
						if (isMachine) {
							url = hiabconfig.explodedViews.explodedViewsURL + 'machine-' + item.MachineId + '/' + item.Parent + '/' + item.IllustrationLink;
						} else {
							url = hiabconfig.explodedViews.explodedViewsURL + item.BaseModelId + (item.Id ? '/' + item.Id : '') + (item.IllustrationLink ? '/' + item.IllustrationLink : '');
						}
						modelTreeSearchResults.push(_react2['default'].createElement(
							'li',
							{ key: key },
							_react2['default'].createElement(
								'a',
								{ href: url },
								item.IllustrationCode,
								' - ',
								item.Description
							)
						));
					});
				} else {
					modelTreeSearchResults.push(_react2['default'].createElement(
						'li',
						{ key: hiabconfig.search.lang.noResults },
						hiabconfig.search.lang.noResults
					));
				}
			})();
		}
		return _react2['default'].createElement(
			'div',
			null,
			_react2['default'].createElement(
				'div',
				{ className: 'uc-breadcrumb text-center' },
				_react2['default'].createElement(_breadcrumbBreadcrumb2['default'], { model: this.props.params.model })
			),
			_react2['default'].createElement(
				'div',
				{ className: illustrationClass },
				_react2['default'].createElement(
					'div',
					{ className: 'local-offcanvas clearfix is-open' },
					_react2['default'].createElement(
						'div',
						{ className: 'medium-3 columns drawer drawer-left' },
						_react2['default'].createElement(
							'button',
							{ className: 'button outlined thin hide-for-large-up', 'data-toggle': '.local-offcanvas' },
							lang.toggleExplodedview,
							_react2['default'].createElement('i', { className: 'icon-angle-double-right' })
						),
						_react2['default'].createElement(_treeviewModeltree2['default'], { model: this.props.params.model, nodeId: this.props.params.nodeId, illustration: this.props.params.illustration, children: this.state.children })
					),
					_react2['default'].createElement(
						'div',
						{ className: 'medium-12 large-9 columns u-collapse-left-for-large-up' },
						_react2['default'].createElement(
							'div',
							{ className: 'clearfix' },
							_react2['default'].createElement(
								'button',
								{ className: 'button outlined thin hide-for-large-up button-modeltree left', 'data-toggle': '.local-offcanvas' },
								_react2['default'].createElement('i', { className: 'icon-angle-double-left' }),
								lang.toggleSpareparts
							),
							openDrawingBtn
						),
						_react2['default'].createElement(_illustrationInfo2['default'], { loadingTreeView: this.state.loadingTreeView, loadingIllustration: this.state.loadingIllustration, illustration: this.state.illustration }),
						_react2['default'].createElement(
							'div',
							{ className: 'uc-model-tree-search-result-container hide' },
							_react2['default'].createElement(
								'button',
								{ className: 'button circle active right', type: 'button', onClick: this.handleCloseSearchResContainer.bind(this) },
								_react2['default'].createElement('i', { className: 'icon-close' })
							),
							_react2['default'].createElement(
								'h4',
								null,
								searchResultFor,
								' ',
								this.state.modelTreeSearchValue
							),
							_react2['default'].createElement(
								'ul',
								null,
								modelTreeSearchResults
							)
						),
						_react2['default'].createElement(_illustration2['default'], { illustration: this.state.illustration, setHotspot: this.setHotspot.bind(this), model: this.props.params.model }),
						_react2['default'].createElement(_partlist2['default'], { illustration: this.state.illustration, hotspotId: this.state.hotspotId, model: this.props.params.model }),
						_react2['default'].createElement('a', { href: '#', 'data-toggle': '.local-offcanvas', className: 'exit-local-off-canvas' })
					)
				)
			)
		);
	};

	return IllustrationContainer;
})(_react2['default'].Component);

;

function triggerAnalyticsPageView(code, url) {
	if (typeof global.dataLayer === 'undefined' && !hiabconfig.EnableGoogleTagManager) return false;

	global.dataLayer.push({
		'event': 'virtualPageView',
		'virtualPageUrl': url,
		'virtualPageTitle': 'Exploded views - ' + code
	});
}

exports['default'] = IllustrationContainer;

/* jshint ignore:end */
module.exports = exports['default'];

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../../_actions/illustration_actions":638,"../../_api/treeview_api":661,"../../_stores/illustration_store":718,"../../_stores/model_tree_search_store":720,"../../_stores/treeview_store":731,"../breadcrumb/breadcrumb":756,"../treeview/modeltree":785,"../treeview/modeltreesearch":787,"./illustration":771,"./illustration-info":770,"./partlist":776,"classnames":299,"jquery":628,"react":525}],773:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactRouter = require('react-router');

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _addtocart_buttons = require('./addtocart_buttons');

var _addtocart_buttons2 = _interopRequireDefault(_addtocart_buttons);

var _hotspots = require('./hotspots');

var _hotspots2 = _interopRequireDefault(_hotspots);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _actionsCart_actions = require('../../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var lang = hiabconfig.explodedViews.lang;
var princetonDealersUrl = hiabconfig.urls.princetonDealers;
var princetonDealersUrlTitle = lang.princetonDealersTitle;

var Kit = (function (_React$Component) {
	_inherits(Kit, _React$Component);

	function Kit(props) {
		_classCallCheck(this, Kit);

		_React$Component.call(this, props);

		this.props = {
			part: null,
			IsQueryable: false
		};

		this.state = {
			quantity: 1,
			Buyable: false,
			InStockQuantity: 0,
			Loaded: false,
			Code: "",
			Price: "",
			ShippingDate: "",
			IsDiscounted: false,
			DefaultPrice: "",
			DiscountPercent: "",
			ProductContext: null,
			PromotionDiscountPercent: "",
			PromotionPrice: "",
			HasPromotion: false,
			HasError: false
		};
	}

	Kit.prototype.componentDidUpdate = function componentDidUpdate() {
		if (this.props.part.GotScaledPrices) {
			_jquery2['default'](document).foundation('tooltip', 'reflow');
		}
	};

	Kit.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		if (nextProps.price.length === 0) return null;
		this.setStateFromProps(nextProps.price);
	};

	Kit.prototype.setStateFromProps = function setStateFromProps(price) {
		this.setState({
			Buyable: price[0].Buyable,
			InStockQuantity: price[0].InStockQuantity,
			Loaded: true,
			Code: price[0].Code,
			Price: price[0].Price,
			ShippingDate: price[0].ShippingDate,
			IsDiscounted: price[0].IsDiscounted,
			DefaultPrice: price[0].DefaultPrice,
			DiscountPercent: price[0].DiscountPercent,
			ProductContext: price[0].ProductContext,
			PromotionDiscountPercent: price[0].PromotionDiscountPercent,
			PromotionPrice: price[0].PromotionPrice,
			HasPromotion: price[0].HasPromotion,
			HasError: price[0].HasPromotion
		});
		this.forceUpdate();
	};

	Kit.prototype.isInt = function isInt(value, length) {
		var x = undefined;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === length ? false : true;
		} else {
			return false;
		}
	};

	Kit.prototype.handleChange = function handleChange(event) {
		// let quantity = this.refs.quantity.value;
		event.target.value = event.target.value.substring(0, 9);
		if (event.target.value !== '' && !this.isInt(event.target.value, 1)) {
			event.target.value = this.state.quantity;
		}
		this.setState({ quantity: event.target.value });
	};

	Kit.prototype.handleBlur = function handleBlur(event) {
		// let quantity = this.refs.quantity.value;
		if (event.target.value === '') {
			event.target.value = this.state.quantity;
		}

		this.setState({ quantity: event.target.value });
	};

	Kit.prototype.handleKeyDown = function handleKeyDown(e) {
		var input = this.refs.quantity;
		// console.log(e);
		e.target.value = e.target.value.substring(0, 9);
		if (e.target.value !== '' && !this.isInt(input.value, 0)) {
			e.target.value = this.state.quantity;
		}
		e.target.value = parseInt(e.target.value, 10);

		var quantity = input.value;
		var skuID = e.target.getAttribute('data-product-sku');

		if (e.which == 13) {
			_jquery2['default'](input).animate({
				lineHeight: "60px",
				opacity: "0.1"
			}, {
				duration: 300,
				specialEasing: {
					lineHeight: "linear"
				},
				complete: function complete() {
					_jquery2['default'](input).animate({
						lineHeight: "18px",
						opacity: "1"
					}, 200);
				}
			});
			_actionsCart_actions2['default'].addCartItem(skuID, quantity);
		}
	};

	Kit.prototype.render = function render() {
		if (this.props.part === null) return null;

		var discountClass = _classnames2['default']({
			'gross-discount-contianer': true,
			'default': this.state.HasPromotion
		});

		var stockInfo = this.state.InStockQuantity;

		if (stockInfo === undefined || !stockInfo || stockInfo === 0 && this.state.ShippingDate !== '') stockInfo = this.state.ShippingDate;

		var product = _react2['default'].createElement(
			'a',
			{ href: this.props.part.Url, className: 'a-black' },
			_react2['default'].createElement(
				'strong',
				null,
				this.props.part.Name
			),
			' ',
			_react2['default'].createElement(
				'span',
				{ className: 'serial-no' },
				this.props.part.MaterialId
			)
		);

		var price = _react2['default'].createElement(
			'span',
			{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
			this.props.part.Price
		);

		var nonDealerDiscount = this.state.HasPromotion ? this.state.Price + ' - ' + lang.grossprice + ': ' + this.state.DefaultPrice : lang.grossprice + ': ' + this.state.DefaultPrice;

		var grossDiscountContianer = this.state.IsDiscounted ? _react2['default'].createElement(
			'span',
			{ className: discountClass },
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				this.props.isDealer ? lang.netPrice + ': ' + this.state.Price : nonDealerDiscount
			),
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				lang.discount,
				': ',
				this.state.DiscountPercent,
				'%'
			)
		) : _react2['default'].createElement(
			'span',
			{ className: discountClass },
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				this.state.Price
			)
		);

		var stock = stockInfo !== undefined && stockInfo && stockInfo !== '' ? _react2['default'].createElement(
			'span',
			{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'availability', className: 'complaint' },
			_react2['default'].createElement('i', { className: 'icon-cubes' }),
			stockInfo
		) : '';

		if (this.props.part.Url === '') {
			product = _react2['default'].createElement(
				'span',
				null,
				_react2['default'].createElement(
					'strong',
					null,
					this.props.part.Name
				),
				' ',
				_react2['default'].createElement(
					'span',
					{ className: 'serial-no' },
					this.props.part.MaterialId
				)
			);
		}

		if (!this.state.Buyable) {
			grossDiscountContianer = null;
			stock = null;
			if (this.state.HasError) {
				price = _react2['default'].createElement(
					'span',
					{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
					hiabconfig.SparePartFooter.lang.priceError
				);
			} else {
				price = _react2['default'].createElement(
					'span',
					{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
					hiabconfig.explodedViews.lang.sendFeedBack
				);
			}
		}

		var displayPrice = this.props.isDealer && this.state.IsDiscounted ? this.state.DefaultPrice : this.state.Price;
		var cost = this.state.Price;

		var toggleId = this.props.part.Id;

		var partsWrapperClass = _classnames2['default']({
			'kit-item medium-up-add-tocart': true,
			toggleId: true,
			'medium-up-add-tocart': true,
			// 'is-active': this.props.hotspotId === this.props.part.HotspotId,
			'has-tip': this.state.Buyable && this.props.part.GotScaledPrices,
			'tip-top': this.state.Buyable && this.props.part.GotScaledPrices
		});

		var toolTip = this.state.Buyable && this.props.part.GotScaledPrices ? { 'data-tooltip': 'true' } : null;
		var toolTipTitle = this.state.Buyable && this.props.part.GotScaledPrices ? { 'title': hiabconfig.explodedViews.lang.scalledPricesTooltip } : null;
		var toolTipAria = this.state.Buyable && this.props.part.GotScaledPrices ? { 'aria-haspopup': 'true' } : null;

		var parentKey = 'parent-' + this.props.part.Id;
		var blockedInfo = null;

		// console.log(this.props.part);

		if (this.props.part.IsBlocked && this.props.part.RestrictionType == 'Princeton') {
			blockedInfo = princetonDealersUrl != "" ? _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				_react2['default'].createElement(
					'a',
					{ target: '_blank', href: princetonDealersUrl, title: princetonDealersUrlTitle },
					this.props.part.RestrictionText
				)
			) : _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				this.props.part.RestrictionText
			);
		} else if (this.props.part.IsBlocked) {
			blockedInfo = _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				this.props.part.RestrictionText
			);
		}

		if (this.props.part.IsBlocked) {
			return _react2['default'].createElement(
				'tr',
				{ key: parentKey },
				_react2['default'].createElement(
					'td',
					{ className: 'item' },
					lang.kit
				),
				_react2['default'].createElement(
					'td',
					{ className: 'product' },
					product
				),
				_react2['default'].createElement(
					'td',
					{ className: 'product', colSpan: '5' },
					blockedInfo
				),
				_react2['default'].createElement(_addtocart_buttons2['default'], { isKit: true, part: this.props.part, Buyable: this.state.Buyable, ProductContext: this.state.ProductContext, isBlocked: this.props.isBlocked })
			);
		}

		return _react2['default'].createElement(
			'tr',
			_extends({ key: parentKey, className: partsWrapperClass }, toolTip, toolTipTitle, toolTipAria),
			_react2['default'].createElement(
				'td',
				{ className: 'item' },
				lang.kit
			),
			_react2['default'].createElement(
				'td',
				{ className: 'product' },
				product
			),
			_react2['default'].createElement(
				'td',
				{ className: 'quantity' },
				_react2['default'].createElement('input', { className: 'amount', type: 'text',
					'data-product-sku': this.props.part.MaterialId,
					'data-product-cost': cost,
					onChange: this.handleChange.bind(this),
					ref: 'quantity',
					readOnly: !this.state.Buyable,
					onBlur: this.handleBlur.bind(this),
					defaultValue: this.state.quantity
				}),
				_react2['default'].createElement(
					'span',
					{ className: 'unit' },
					this.props.part.UoM
				)
			),
			_react2['default'].createElement(
				'td',
				{ className: 'price' },
				this.state.Buyable ? _react2['default'].createElement(Price, { isDealer: this.props.isDealer, hasPromotion: this.state.HasPromotion, promotionPrice: this.state.PromotionPrice, promotionPercent: this.state.PromotionDiscountPercent, gotScaledPrices: this.props.part.GotScaledPrices, Price: displayPrice, MaterialId: this.state.Code }) : !this.state.Buyable && this.state.Loaded ? price : _react2['default'].createElement(FetchPrice, null)
			),
			_react2['default'].createElement(
				'td',
				null,
				grossDiscountContianer
			),
			_react2['default'].createElement(
				'td',
				{ className: 'stock' },
				stock
			),
			_react2['default'].createElement('td', { className: 'subview' }),
			_react2['default'].createElement(_addtocart_buttons2['default'], { isKit: true, part: this.props.part, Buyable: this.state.Buyable, ProductContext: this.state.ProductContext })
		);
	};

	return Kit;
})(_react2['default'].Component);

;

var FetchPrice = function FetchPrice(props) {
	return _react2['default'].createElement(
		'div',
		{ className: 'fetching' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt text-center' },
			_react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center', style: { "float": "left" } }),
			' ',
			_react2['default'].createElement(
				'span',
				{ className: 'text-center', style: { "float": "left", "paddingleft": "10px" } },
				lang.fetchingInformation
			)
		)
	);
};

var Price = function Price(props) {
	var MaterialId = props.MaterialId;
	var isDealer = props.isDealer;
	var Price = props.Price;
	var gotScaledPrices = props.gotScaledPrices;
	var hasPromotion = props.hasPromotion;
	var promotionPercent = props.promotionPercent;
	var promotionPrice = props.promotionPrice;

	var gotScaledPricesIcon = gotScaledPrices ? _react2['default'].createElement('i', { className: 'icon-money' }) : null;
	var promotionIcon = hasPromotion ? _react2['default'].createElement('i', { className: 'icon-tags' }) : null;
	var promotionElement = hasPromotion ? promotionPrice + ' - ' + lang.promotionTitle + ' ' + promotionPercent + '%' : null;
	var dealerPrice = _react2['default'].createElement(
		'span',
		null,
		lang.grossprice,
		':',
		_react2['default'].createElement(
			'strong',
			null,
			Price
		)
	);
	var priceElm = isDealer ? dealerPrice : Price;
	var klass = _classnames2['default']({
		'complaint': true,
		'discount-price': hasPromotion
	});

	return _react2['default'].createElement(
		'div',
		null,
		hasPromotion && isDealer ? dealerPrice : null,
		_react2['default'].createElement(
			'span',
			{ 'data-product-id': MaterialId, 'data-active-tab': 'price', className: klass },
			gotScaledPricesIcon,
			promotionIcon,
			hasPromotion ? promotionElement : priceElm
		)
	);
};

exports['default'] = Kit;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/cart_actions":633,"../../_stores/illustration_store":718,"../../_stores/treeview_store":731,"./addtocart_buttons":768,"./hotspots":769,"classnames":299,"jquery":628,"react":525,"react-dom":351,"react-router":381}],774:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactRouter = require('react-router');

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var KitPart = (function (_React$Component) {
	_inherits(KitPart, _React$Component);

	function KitPart(props) {
		_classCallCheck(this, KitPart);

		_React$Component.call(this, props);

		this.props = {
			partsList: null,
			kitName: null,
			kitId: null,
			toggleId: null
		};
	}

	KitPart.prototype.render = function render() {
		if (this.props.partsList === null) return null;

		var kitName = this.props.kitName;
		var kitId = this.props.kitId;
		var parts = [];
		var liKey = 0;
		//this is untested
		this.props.partsList.forEach(function (part) {
			var product = _react2['default'].createElement(
				'a',
				{ href: part.Url, className: 'a-black' },
				_react2['default'].createElement(
					'strong',
					null,
					part.Name
				),
				' ',
				_react2['default'].createElement(
					'span',
					{ className: 'serial-no' },
					part.MaterialId
				)
			);
			if (part.Url === '') {
				product = _react2['default'].createElement(
					'span',
					null,
					_react2['default'].createElement(
						'strong',
						null,
						part.Name
					),
					' ',
					_react2['default'].createElement(
						'span',
						{ className: 'serial-no' },
						part.MaterialId
					)
				);
			}
			var quantity = _react2['default'].createElement(
				'span',
				null,
				' - ',
				part.Quantity,
				' ',
				part.UoM
			);
			var key = part.Id + liKey;
			liKey++;
			// console.log(part);
			parts.push(_react2['default'].createElement(
				'li',
				{ key: key, className: 'product' },
				product,
				quantity
			));
		});
		var kitClass = "kit-parts-list-row " + this.props.toggleId;
		//this is untested end
		//the return function is allso untested
		// <li key="header" className="header">
		// 	{hiabconfig.explodedViews.lang.kit} {kitName} {kitId} {hiabconfig.explodedViews.lang.contains}:
		// </li>
		return _react2['default'].createElement(
			'tr',
			{ className: kitClass },
			_react2['default'].createElement(
				'td',
				{ className: 'wrapper', colSpan: '8' },
				_react2['default'].createElement(
					'div',
					{ className: 'kit-parts-list-row' },
					_react2['default'].createElement(
						'ul',
						null,
						parts
					)
				)
			)
		);
	};

	return KitPart;
})(_react2['default'].Component);

;
exports['default'] = KitPart;

/* jshint ignore:end */
module.exports = exports['default'];

},{"classnames":299,"jquery":628,"react":525,"react-dom":351,"react-router":381}],775:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactRouter = require('react-router');

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _addtocart_buttons = require('./addtocart_buttons');

var _addtocart_buttons2 = _interopRequireDefault(_addtocart_buttons);

var _hotspots = require('./hotspots');

var _hotspots2 = _interopRequireDefault(_hotspots);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _actionsCart_actions = require('../../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var lang = hiabconfig.explodedViews.lang;
var princetonDealersUrl = hiabconfig.urls.princetonDealers;
var princetonDealersUrlTitle = lang.princetonDealersTitle;

var Part = (function (_React$Component) {
	_inherits(Part, _React$Component);

	function Part(props) {
		_classCallCheck(this, Part);

		_React$Component.call(this, props);

		this.props = {
			part: null,
			hotspotId: null,
			elementValue: ''
		};

		this.state = {
			Buyable: false,
			InStockQuantity: 0,
			Loaded: false,
			Code: "",
			Price: "",
			ShippingDate: "",
			IsDiscounted: false,
			DefaultPrice: "",
			DiscountPercent: "",
			ProductContext: null,
			PromotionDiscountPercent: "",
			PromotionPrice: "",
			HasPromotion: false,
			HasError: false
		};
	}

	Part.prototype.componentDidUpdate = function componentDidUpdate() {
		if (this.props.part.GotScaledPrices) {
			_jquery2['default'](document).foundation('tooltip', 'reflow');
		}
	};

	Part.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		if (nextProps.price.length === 0) return null;
		this.setStateFromProps(nextProps.price);
	};

	Part.prototype.setStateFromProps = function setStateFromProps(price) {
		this.setState({
			Buyable: price[0].Buyable,
			InStockQuantity: price[0].InStockQuantity,
			Loaded: true,
			Code: price[0].Code,
			Price: price[0].Price,
			ShippingDate: price[0].ShippingDate,
			IsDiscounted: price[0].IsDiscounted,
			DefaultPrice: price[0].DefaultPrice,
			DiscountPercent: price[0].DiscountPercent,
			ProductContext: price[0].ProductContext,
			PromotionDiscountPercent: price[0].PromotionDiscountPercent,
			PromotionPrice: price[0].PromotionPrice,
			HasPromotion: price[0].HasPromotion,
			HasError: price[0].HasError
		});
		if (this.props.part.GotScaledPrices) {
			_jquery2['default'](document).foundation('tooltip', 'reflow');
		}
		this.forceUpdate();
	};

	Part.prototype.illustrationLinkButton = function illustrationLinkButton() {
		var part = this.props.part,
		    noValue = '00000000-0000-0000-0000-000000000000';
		if (part.IllustrationLink !== noValue && part.SectionForIllustration !== noValue) {
			var model = part.ModelForIllustrationLink === noValue ? this.props.model : part.ModelForIllustrationLink;
			var explodedViewsUrl = hiabconfig.explodedViews.explodedViewsURL;
			var url = '' + explodedViewsUrl + model + '/' + part.SectionForIllustration + '/' + part.IllustrationLink;
			return _react2['default'].createElement(
				'a',
				{ className: 'button link', href: url },
				_react2['default'].createElement('i', { className: 'icon-level-down' })
			);
		}

		return null;
	};

	Part.prototype.isInt = function isInt(value, length) {
		var x = undefined;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === length ? false : true;
		} else {
			return false;
		}
	};

	Part.prototype.handleChange = function handleChange(event) {
		// let quantity = this.refs.quantity.value;
		event.target.value = event.target.value.substring(0, 9);
		if (event.target.value !== '' && !this.isInt(event.target.value, 1)) {
			event.target.value = this.props.part.Quantity;
		}
		this.setState({ quantity: event.target.value });
	};

	Part.prototype.handleBlur = function handleBlur(event) {
		var quantity = this.refs.quantity.value;
		if (event.target.value === '') {
			event.target.value = this.props.part.Quantity;
		}
		this.setState({ quantity: event.target.value });
	};

	Part.prototype.handleKeyDown = function handleKeyDown(e) {
		var input = this.refs.quantity;
		// console.log(e);
		e.target.value = e.target.value.substring(0, 9);
		if (e.target.value !== '' && !this.isInt(input.value, 0)) {
			e.target.value = this.props.part.Quantity;
		}
		e.target.value = parseInt(e.target.value, 10);

		var quantity = input.value;
		var skuID = e.target.getAttribute('data-product-sku');

		if (e.which == 13) {
			_jquery2['default'](input).animate({
				lineHeight: "60px",
				opacity: "0.1"
			}, {
				duration: 300,
				specialEasing: {
					lineHeight: "linear"
				},
				complete: function complete() {
					_jquery2['default'](input).animate({
						lineHeight: "18px",
						opacity: "1"
					}, 200);
				}
			});
			_actionsCart_actions2['default'].addCartItem(skuID, quantity);
		}
	};

	Part.prototype.render = function render() {

		if (this.props.part === null) return null;

		var klass = _classnames2['default']({
			'medium-up-add-tocart': true,
			'is-active': this.props.hotspotId === this.props.part.HotspotId,
			'has-tip': this.state.Buyable && this.props.part.GotScaledPrices,
			'tip-top': this.state.Buyable && this.props.part.GotScaledPrices
		});

		var stockInfo = this.state.InStockQuantity;

		if (stockInfo === undefined || !stockInfo || stockInfo === 0 && this.state.ShippingDate !== '') stockInfo = this.state.ShippingDate;

		var hotspotId = 'hotspot-' + this.props.part.HotspotId;

		var price = _react2['default'].createElement(
			'span',
			{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
			this.props.part.Price
		);

		var discountClass = _classnames2['default']({
			'gross-discount-contianer': true,
			'default': this.state.HasPromotion
		});

		var nonDealerDiscount = this.state.HasPromotion ? this.state.Price + ' - ' + lang.grossprice + ': ' + this.state.DefaultPrice : lang.grossprice + ': ' + this.state.DefaultPrice;

		var grossDiscountContianer = this.state.IsDiscounted ? _react2['default'].createElement(
			'span',
			{ className: discountClass },
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				this.props.isDealer ? lang.netPrice + ': ' + this.state.Price : nonDealerDiscount
			),
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				lang.discount,
				': ',
				this.state.DiscountPercent,
				'%'
			)
		) : _react2['default'].createElement(
			'span',
			{ className: discountClass },
			_react2['default'].createElement(
				'span',
				{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint spanval' },
				this.state.Price
			)
		);

		var stock = stockInfo !== undefined && stockInfo && stockInfo !== '' ? _react2['default'].createElement(
			'span',
			{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'availability', className: 'complaint' },
			_react2['default'].createElement('i', { className: 'icon-cubes' }),
			stockInfo
		) : '';
		var product = _react2['default'].createElement(
			'a',
			{ href: this.props.part.Url, className: 'a-black' },
			_react2['default'].createElement(
				'strong',
				null,
				this.props.part.Name
			),
			_react2['default'].createElement(
				'span',
				{ className: 'serial-no' },
				this.props.part.MaterialId
			)
		);

		if (!this.state.Buyable) {
			grossDiscountContianer = null;
			stock = null;
			if (this.state.HasError) {
				price = _react2['default'].createElement(
					'span',
					{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
					hiabconfig.SparePartFooter.lang.priceError
				);
			} else {
				price = _react2['default'].createElement(
					'span',
					{ 'data-product-id': this.props.part.MaterialId, 'data-active-tab': 'price', className: 'complaint' },
					hiabconfig.explodedViews.lang.sendFeedBack
				);
			}
		}

		var displayPrice = this.props.isDealer && this.state.IsDiscounted ? this.state.DefaultPrice : this.state.Price;
		var cost = this.state.Price;

		if (this.props.part.Url === '') {
			product = _react2['default'].createElement(
				'span',
				{ className: 'serial-no' },
				this.props.part.MaterialId
			);
		}
		var toolTip = this.state.Buyable && this.props.part.GotScaledPrices ? { 'data-tooltip': 'true' } : null;
		var toolTipTitle = this.state.Buyable && this.props.part.GotScaledPrices ? { 'title': hiabconfig.explodedViews.lang.scalledPricesTooltip } : null;
		var toolTipAria = this.state.Buyable && this.props.part.GotScaledPrices ? { 'aria-haspopup': 'true' } : null;

		var blockedInfo = null;

		// console.log(this.props.part);

		if (this.props.part.IsBlocked && this.props.part.RestrictionType == 'Princeton') {
			blockedInfo = princetonDealersUrl != "" ? _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				_react2['default'].createElement(
					'a',
					{ target: '_blank', href: princetonDealersUrl, title: princetonDealersUrlTitle },
					this.props.part.RestrictionText
				)
			) : _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				this.props.part.RestrictionText
			);
		} else if (this.props.part.IsBlocked) {
			blockedInfo = _react2['default'].createElement(
				'span',
				{ className: 'u-line' },
				this.props.part.RestrictionText
			);
		}

		if (this.props.part.IsBlocked) {
			return _react2['default'].createElement(
				'tr',
				{ className: klass },
				_react2['default'].createElement(
					'td',
					{ className: 'item' },
					this.props.part.HotspotId
				),
				_react2['default'].createElement(
					'td',
					{ className: 'product' },
					product
				),
				_react2['default'].createElement(
					'td',
					{ className: 'product', colSpan: '6' },
					blockedInfo
				)
			);
		}
		return _react2['default'].createElement(
			'tr',
			_extends({ className: klass, id: hotspotId }, toolTip, toolTipTitle, toolTipAria),
			_react2['default'].createElement(
				'td',
				{ className: 'item' },
				this.props.part.HotspotId
			),
			_react2['default'].createElement(
				'td',
				{ className: 'product' },
				product
			),
			_react2['default'].createElement(
				'td',
				{ className: 'quantity' },
				_react2['default'].createElement('input', { className: 'amount', type: 'text',
					'data-product-sku': this.props.part.MaterialId,
					'data-product-cost': cost,
					onChange: this.handleChange.bind(this),
					ref: 'quantity',
					readOnly: !this.state.Buyable,
					onBlur: this.handleBlur.bind(this),
					defaultValue: this.props.part.Quantity }),
				_react2['default'].createElement(
					'span',
					{ className: 'unit' },
					this.props.part.UoM
				)
			),
			_react2['default'].createElement(
				'td',
				{ className: 'price' },
				this.state.Buyable ? _react2['default'].createElement(Price, { isDealer: this.props.isDealer, hasPromotion: this.state.HasPromotion, promotionPrice: this.state.PromotionPrice, promotionPercent: this.state.PromotionDiscountPercent, gotScaledPrices: this.props.part.GotScaledPrices, Price: displayPrice, MaterialId: this.state.Code }) : !this.state.Buyable && this.state.Loaded ? price : _react2['default'].createElement(FetchPrice, null)
			),
			_react2['default'].createElement(
				'td',
				null,
				grossDiscountContianer
			),
			_react2['default'].createElement(
				'td',
				{ className: 'stock' },
				stock
			),
			_react2['default'].createElement(
				'td',
				{ className: 'subview' },
				this.illustrationLinkButton()
			),
			_react2['default'].createElement(_addtocart_buttons2['default'], { part: this.props.part, Buyable: this.state.Buyable, ProductContext: this.state.ProductContext })
		);
	};

	return Part;
})(_react2['default'].Component);

;

var FetchPrice = function FetchPrice(props) {
	return _react2['default'].createElement(
		'div',
		{ className: 'fetching' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt text-center' },
			_react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center', style: { "float": "left" } }),
			' ',
			_react2['default'].createElement(
				'span',
				{ className: 'text-center', style: { "float": "left", "paddingleft": "10px" } },
				lang.fetchingInformation
			)
		)
	);
};

var Price = function Price(props) {
	var MaterialId = props.MaterialId;
	var isDealer = props.isDealer;
	var Price = props.Price;
	var gotScaledPrices = props.gotScaledPrices;
	var hasPromotion = props.hasPromotion;
	var promotionPercent = props.promotionPercent;
	var promotionPrice = props.promotionPrice;

	var gotScaledPricesIcon = gotScaledPrices ? _react2['default'].createElement('i', { className: 'icon-money' }) : null;
	var promotionIcon = hasPromotion ? _react2['default'].createElement('i', { className: 'icon-tags' }) : null;
	var promotionElement = hasPromotion ? promotionPrice + ' - ' + lang.promotionTitle + ' ' + promotionPercent + '%' : null;
	var dealerPrice = _react2['default'].createElement(
		'span',
		null,
		lang.grossprice,
		':',
		_react2['default'].createElement(
			'strong',
			null,
			Price
		)
	);
	var priceElm = isDealer ? dealerPrice : Price;
	var klass = _classnames2['default']({
		'complaint': true,
		'discount-price': hasPromotion
	});

	return _react2['default'].createElement(
		'div',
		null,
		hasPromotion && isDealer ? dealerPrice : null,
		_react2['default'].createElement(
			'span',
			{ 'data-product-id': MaterialId, 'data-active-tab': 'price', className: klass },
			gotScaledPricesIcon,
			promotionIcon,
			hasPromotion ? promotionElement : priceElm
		)
	);
};

exports['default'] = Part;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/cart_actions":633,"../../_stores/illustration_store":718,"../../_stores/treeview_store":731,"./addtocart_buttons":768,"./hotspots":769,"classnames":299,"jquery":628,"react":525,"react-dom":351,"react-router":381}],776:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _part = require('./part');

var _part2 = _interopRequireDefault(_part);

var _kit = require('./kit');

var _kit2 = _interopRequireDefault(_kit);

var _kitpart = require('./kitpart');

var _kitpart2 = _interopRequireDefault(_kitpart);

var _addtocart_buttons = require('./addtocart_buttons');

var _addtocart_buttons2 = _interopRequireDefault(_addtocart_buttons);

var _actionsPrice_service_actions = require('../../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesPrice_service_store = require('../../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var PartList = (function (_React$Component) {
	_inherits(PartList, _React$Component);

	function PartList(props) {
		_classCallCheck(this, PartList);

		_React$Component.call(this, props);
		this.props = {
			illustration: {
				PartList: []
			},
			hotspotId: null

		};
		this.state = {
			prices: []
		};
	}

	PartList.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.unsubscribe = _storesPrice_service_store2['default'].listen(function () {
			_this.setState({
				prices: _storesPrice_service_store2['default'].getPrices()
			});
		});
	};

	PartList.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		if (!this.props.illustration) return null;
		if (!this.props.illustration.PartList) return null;

		// console.log('partlist-1');

		if (this.state.prices.length === 0 && this.props.illustration.Id === nextProps.illustration.Id) {
			this.priceRequest();
		}
		if (this.props.illustration.Id !== nextProps.illustration.Id) {
			this.setState({
				prices: []
			});
		}
	};

	PartList.prototype.priceRequest = function priceRequest() {

		this.props.illustration.Kits.forEach(function (item) {
			if (item.IsQueryable && !item.IsBlocked) {
				_actionsPrice_service_actions2['default'].addMaterials(item.MaterialId);
			}
		});
		this.props.illustration.PartList.forEach(function (item) {
			if (item.IsQueryable && !item.IsBlocked) {
				_actionsPrice_service_actions2['default'].addMaterials(item.MaterialId);
			}
		});

		_actionsPrice_service_actions2['default'].fetchPrices(hiabconfig.jsPriceBatchAmount);
	};

	PartList.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.illustration) return null;
		if (!this.props.illustration.PartList && !this.props.illustration.Kits) return null;

		var PriceServiceUnavailableMessage = undefined;
		if (this.props.illustration.PriceServiceUnavailableMessage) {
			PriceServiceUnavailableMessage = _react2['default'].createElement(
				'p',
				{ className: 'price-manage-info' },
				_react2['default'].createElement('i', { className: 'icon-attention-circled' }),
				this.props.illustration.PriceServiceUnavailableMessage
			);
		}

		var parts = [];
		var kitParts = [];

		if (this.props.illustration.Kits) {
			this.props.illustration.Kits.forEach(function (kit) {

				var key = 'mobile' + kit.Id;
				var parts = 'parts-' + kit.Id;

				var price = [];

				if (kit.IsQueryable) {
					price = _this2.state.prices.filter(function (price) {
						return price.Code == kit.MaterialId;
					});
				} else {
					price = [{
						Buyable: false,
						InStockQuantity: 0,
						Code: kit.MaterialId,
						Price: "",
						ShippingDate: "",
						IsDiscounted: false,
						DefaultPrice: "",
						DiscountPercent: "",
						ProductContex: null
					}];
				}

				kitParts.push(_react2['default'].createElement(_kit2['default'], { isDealer: _this2.state.isDealer, price: price, part: kit, key: kit.Id, isBlocked: kit.isBlocked }));

				if (kit.PartList.length > 0) {
					kitParts.push(_react2['default'].createElement(_kitpart2['default'], { toggleId: kit.Id, kitName: _this2.props.illustration.Name, kitId: _this2.props.illustration.MaterialId, partsList: kit.PartList, key: parts }));
				}
				var productContext = null;
				var buyable = false;
				if (typeof price[0] !== 'undefined') {
					buyable = price[0].Buyable;
					productContext = price[0].ProductContext;
				}
				if (kit.IsQueryable) {
					kitParts.push(_react2['default'].createElement(
						'tr',
						{ key: key, className: 'small-add-tocart' },
						_react2['default'].createElement(_addtocart_buttons2['default'], { Buyable: buyable, part: kit, isKit: true, ProductContext: productContext })
					));
					//kitParts.push(<tr key={key} className="small-add-tocart"><AddToCartButtons Buyable={buyable} part={kit} isKit={true} /></tr>);
				}
			});
		}
		if (this.props.illustration.PartList) {
			this.props.illustration.PartList.forEach(function (part) {
				var key = 'mobile' + part.Id;
				var price = [];
				if (part.IsQueryable) {
					price = _this2.state.prices.filter(function (price) {
						return price.Code == part.MaterialId;
					});
				} else {
					price = [{
						Buyable: false,
						InStockQuantity: 0,
						Code: part.MaterialId,
						Price: "",
						ShippingDate: "",
						IsDiscounted: false,
						DefaultPrice: "",
						DiscountPercent: "",
						ProductContex: null
					}];
				}

				parts.push(_react2['default'].createElement(_part2['default'], { isDealer: _this2.state.isDealer, price: price, part: part, key: part.Id, hotspotId: _this2.props.hotspotId, isBlocked: part.isBlocked, model: _this2.props.model }));

				var buyable = false;
				var productContext = null;
				if (typeof price[0] !== 'undefined') {
					buyable = price[0].Buyable;
					productContext = price[0].ProductContext;
				}
				if (part.IsQueryable) {
					parts.push(_react2['default'].createElement(
						'tr',
						{ key: key, className: 'small-add-tocart' },
						_react2['default'].createElement(_addtocart_buttons2['default'], { Buyable: buyable, part: part, ProductContext: productContext })
					));
					//parts.push(<tr key={key} className="small-add-tocart"><AddToCartButtons Buyable={buyable} part={part} /></tr>);
				}
			});
		}

		if (parts.length === 0 && kitParts.length === 0) return null;

		var lang = hiabconfig.explodedViews.lang;

		return _react2['default'].createElement(
			'div',
			null,
			PriceServiceUnavailableMessage,
			_react2['default'].createElement(
				'table',
				{ className: 'uc-producttable' },
				_react2['default'].createElement(
					'thead',
					null,
					_react2['default'].createElement(
						'tr',
						null,
						_react2['default'].createElement(
							'th',
							{ scope: 'col' },
							'#'
						),
						_react2['default'].createElement(
							'th',
							{ scope: 'col' },
							lang.part
						),
						_react2['default'].createElement(
							'th',
							{ scope: 'col' },
							lang.quantity
						),
						_react2['default'].createElement(
							'th',
							{ scope: 'col' },
							lang.price
						),
						_react2['default'].createElement('th', null),
						_react2['default'].createElement(
							'th',
							{ scope: 'col' },
							lang.stock
						),
						_react2['default'].createElement('th', { scope: 'col' }),
						_react2['default'].createElement('th', { scope: 'col' })
					)
				),
				_react2['default'].createElement(
					'tbody',
					null,
					kitParts,
					parts
				)
			)
		);
	};

	return PartList;
})(_react2['default'].Component);

;
exports['default'] = PartList;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/price_service_actions":641,"../../_stores/price_service_store":723,"./addtocart_buttons":768,"./kit":773,"./kitpart":774,"./part":775,"jquery":628,"react":525}],777:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var UrlHandler = {
    GetUrlParameters: function GetUrlParameters() {
        var vars = [],
            hash = undefined;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');

        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }

        // console.log(vars);
        return vars;
    },

    GetParameterByString: function GetParameterByString(param) {
        var result = UrlHandler.GetUrlParameters()[param];
        // console.log(result);

        return result;
    }
};

exports['default'] = UrlHandler;
module.exports = exports['default'];

},{}],778:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var GroupSelector = (function (_React$Component) {
  _inherits(GroupSelector, _React$Component);

  function GroupSelector(props) {
    _classCallCheck(this, GroupSelector);

    _React$Component.call(this, props);
    this.state = {
      groups: _storesSearch_result_store2['default'].getInitialState().groups,
      selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
      loading: _storesSearch_result_store2['default'].getLoading()
    };
  }

  GroupSelector.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    this.unsubscribe = _storesSearch_result_store2['default'].listen(function () {
      return _this.setState({
        groups: _storesSearch_result_store2['default'].getInitialState().groups,
        selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
        loading: _storesSearch_result_store2['default'].getLoading()
      });
    });
  };

  GroupSelector.prototype.componentWillUnmount = function componentWillUnmount() {
    this.unsubscribe();
  };

  GroupSelector.prototype.handleChange = function handleChange(e) {
    this.setState({
      selectedGroup: e.target.value
    });
    _storesSearch_result_store2['default'].onGroupSelectorChange(e.target.value);
  };

  GroupSelector.prototype.render = function render() {
    var _this2 = this;

    var groups = this.state.groups;

    var groupNames = Object.keys(groups);

    var radioFilterClass = _classnames2['default']({
      'radio-filter': true,
      'is-loading': this.state.loading
    });

    if (groupNames.length < 2) return null;

    return _react2['default'].createElement(
      'div',
      { className: 'uc-filter-type' },
      _react2['default'].createElement(
        'div',
        { className: 'row' },
        _react2['default'].createElement(
          'div',
          { className: 'small-12 columns', id: 'group-selector' },
          _react2['default'].createElement(
            'ul',
            { className: radioFilterClass },
            groupNames.map(function (name) {
              var group = groups[name];
              var label = group.label;
              var matching = group.matching;

              var isSelected = name === _this2.state.selectedGroup;
              if (label !== undefined) return _react2['default'].createElement(
                'li',
                { key: name },
                _react2['default'].createElement(
                  'label',
                  { htmlFor: "filter-" + name },
                  _react2['default'].createElement('input', {
                    name: 'filter-type',
                    type: 'radio',
                    id: "filter-" + name,
                    value: name,
                    checked: isSelected,
                    onChange: _this2.handleChange.bind(_this2),
                    disabled: matching == 0 && !isSelected
                  }),
                  label,
                  ' ',
                  _react2['default'].createElement(
                    'span',
                    { className: 'hits' },
                    matching
                  )
                )
              );
            })
          )
        )
      )
    );
  };

  return GroupSelector;
})(_react2['default'].Component);

exports['default'] = GroupSelector;
module.exports = exports['default'];

},{"../../_stores/search_result_store":725,"classnames":299,"react":525}],779:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var OtherResult = (function (_React$Component) {
	_inherits(OtherResult, _React$Component);

	function OtherResult(props) {
		_classCallCheck(this, OtherResult);

		_React$Component.call(this, props);
	}

	OtherResult.prototype.imgOnLoad = function imgOnLoad() {
		var ua = window.navigator.userAgent;
		var trident = ua.indexOf('Trident/');
		var msie = ua.indexOf('MSIE ');

		if (msie > 0 || trident > 0) {
			Foundation.libs.equalizer.equalize($('.uc-productlist ul'));
			Foundation.libs.equalizer.equalize($('.uc-productlist'));
			Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
		} else {
			$(document).foundation('equalizer', 'reflow');
		}
	};

	OtherResult.prototype.render = function render() {
		var item = this.props.item;

		var images = _react2['default'].createElement(
			'div',
			{ className: 'icon' },
			_react2['default'].createElement('i', { className: 'icon-doc-inv' })
		);
		var target = null;
		if (item.images) {
			var image = '/img/product-placeholder2x2.png';
			if (item.images[0].url && item.images[0].url !== '') image = item.images[0].url;
			images = _react2['default'].createElement(
				'div',
				{ className: 'image', 'data-equalizer-watch': 'image' },
				_react2['default'].createElement('img', { onLoad: this.imgOnLoad.bind(this), onError: this.imgOnLoad.bind(this), src: image, alt: item.name })
			);
		}
		if (item.target) {
			target = item.target;
		}
		return _react2['default'].createElement(
			'li',
			{ key: item.url },
			_react2['default'].createElement(
				'div',
				{ className: 'item-wrapper' },
				images,
				_react2['default'].createElement(
					'div',
					{ className: 'item-name', 'data-equalizer-watch': 'item-name' },
					_react2['default'].createElement(
						'h4',
						null,
						item.name
					)
				),
				_react2['default'].createElement(
					'div',
					{ 'data-equalizer-watch': 'add-to-btns u-dt', className: 'add-to-btns u-dt' },
					_react2['default'].createElement(
						'a',
						{ href: item.url, target: target, className: 'button center not-buyable add-to-cart' },
						item.linkText
					)
				)
			)
		);
	};

	return OtherResult;
})(_react2['default'].Component);

exports['default'] = OtherResult;
module.exports = exports['default'];

},{"react":525}],780:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _other_result = require('./other_result');

var _other_result2 = _interopRequireDefault(_other_result);

var _spare_part_result = require('./spare_part_result');

var _spare_part_result2 = _interopRequireDefault(_spare_part_result);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _storesSearch_store = require('../../_stores/search_store');

var _storesSearch_store2 = _interopRequireDefault(_storesSearch_store);

var _actionsSearch_actions = require('../../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _actionsPrice_service_actions = require('../../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesPrice_service_store = require('../../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _libCustomSearchEvents = require('../../_lib/custom-search-events');

var _libCustomSearchEvents2 = _interopRequireDefault(_libCustomSearchEvents);

var translations = {};

var Result = (function (_React$Component) {
  _inherits(Result, _React$Component);

  function Result(props) {
    _classCallCheck(this, Result);

    _React$Component.call(this, props);
    this.state = {
      batchSize: _storesSearch_result_store2['default'].getBatchSize(),
      selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
      resultItems: _storesSearch_result_store2['default'].getSelectedItems(),
      moreResultsAvailable: _storesSearch_result_store2['default'].getMoreResultsAvailable(),
      isSignedIn: _storesSearch_result_store2['default'].getUserSignedIn(),
      loading: false,
      isDealer: false
    };

    translations.loadMore = _storesLocalization_store2['default'].getTranslation('/Search/LoadMore');
  }

  Result.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    reflow();

    if (this.state.selectedGroup == 'lightSparePartViewModel' || this.state.selectedGroup == 'spareParts') {
      this.priceRequest();
    }

    this.unsubscribe = _storesSearch_result_store2['default'].listen(function (searchStoreState) {
      _this.setState({
        batchSize: _storesSearch_result_store2['default'].getBatchSize(),
        selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
        resultItems: _storesSearch_result_store2['default'].getSelectedItems(),
        moreResultsAvailable: _storesSearch_result_store2['default'].getMoreResultsAvailable(),
        isSignedIn: _storesSearch_result_store2['default'].getUserSignedIn(),
        loading: searchStoreState.loading
      });
      if (_this.state.selectedGroup == 'lightSparePartViewModel' || _this.state.selectedGroup == 'spareParts') {
        _this.priceRequest();
      }
    });
    this.unsubscribe2 = _storesPrice_service_store2['default'].listen(function (priceServiceStore) {
      reflow();
    });
    this.setState({
      isDealer: $('body.is-dealer').length > 0
    });
    _libCustomSearchEvents2['default'].trackFullSearchPageLoad();
  };

  Result.prototype.loadNextPage = function loadNextPage() {
    _actionsSearch_actions2['default'].loadNextPage(this.state.selectedGroup);
  };

  Result.prototype.priceRequest = function priceRequest() {
    var pricesInStore = _storesPrice_service_store2['default'].getPrices();
    var pricesInStoreCodes = pricesInStore.map(function (priceInStore) {
      return priceInStore.Code;
    });

    var resultItemsNotInPriceStore = this.state.resultItems.filter(function (resultItem) {
      return pricesInStoreCodes.indexOf(resultItem.materialNumber) < 0;
    });

    resultItemsNotInPriceStore.forEach(function (item) {
      if (item.isQueryable) {
        _actionsPrice_service_actions2['default'].addMaterials(item.materialNumber);
      }
    });
    _actionsPrice_service_actions2['default'].fetchPrices(_storesSearch_result_store2['default'].getBatchSize());
  };

  Result.prototype.render = function render() {
    var _this2 = this;

    var _state = this.state;
    var selectedGroup = _state.selectedGroup;
    var loading = _state.loading;
    var resultItems = _state.resultItems;
    var moreResultsAvailable = _state.moreResultsAvailable;

    if (!resultItems) return null;

    var result = [];
    if (selectedGroup == 'lightSparePartViewModel' || selectedGroup == 'spareParts') {
      result = resultItems.map(function (x) {
        return _react2['default'].createElement(_spare_part_result2['default'], _extends({ isDealer: _this2.state.isDealer, userIsSignedIn: _this2.state.isSignedIn, type: selectedGroup, key: x.materialNumber }, x));
      });
    } else {
      result = resultItems.map(function (resultItem) {
        return _react2['default'].createElement(_other_result2['default'], { key: resultItem.url, item: resultItem });
      });
    }

    var sectionClass = 'uc-productlist';
    sectionClass += loading ? ' loading' : '';
    var listClass = selectedGroup == 'spareParts' ? "result-spare-parts" : "result-other";

    return _react2['default'].createElement(
      'section',
      { 'data-equalizer': 'add-to-btns', 'data-options': 'equalize_on_stack: true', 'data-equalizer-mq': 'small-up', className: sectionClass },
      _react2['default'].createElement(
        'div',
        { className: 'amount-price-stock-watch', 'data-equalizer': 'amount-price-stock', 'data-options': 'equalize_on_stack: true' },
        _react2['default'].createElement(
          'div',
          { className: 'item-wrapper-watch' },
          _react2['default'].createElement(
            'ul',
            { 'data-equalizer': 'item-name', 'data-options': 'equalize_on_stack: true', 'data-equalizer-mq': 'small-up', className: listClass },
            result
          ),
          moreResultsAvailable ? _react2['default'].createElement(LoadMoreButton, { onClick: this.loadNextPage.bind(this) }) : null
        )
      )
    );
  };

  return Result;
})(_react2['default'].Component);

exports['default'] = Result;

function reflow() {
  var ua = window.navigator.userAgent;
  var trident = ua.indexOf('Trident/');
  var msie = ua.indexOf('MSIE ');
  if (msie > 0 || trident > 0) {
    $(document).ready(function () {
      Foundation.libs.equalizer.equalize($('.result-spare-parts'));
      Foundation.libs.equalizer.equalize($('.uc-productlist'));
      Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
      Foundation.libs.equalizer.equalize($('.item-name-watch'));
    });
  } else {
    $(document).foundation('equalizer', 'reflow');
  }
}

var LoadMoreButton = function LoadMoreButton(props) {
  return _react2['default'].createElement(
    'div',
    { className: 'uc-loadmore-products' },
    _react2['default'].createElement(
      'button',
      { onClick: props.onClick },
      translations.loadMore,
      ' ',
      _react2['default'].createElement('i', { className: 'animate-spin icon-spin4' })
    )
  );
};
module.exports = exports['default'];

},{"../../_actions/price_service_actions":641,"../../_actions/search_actions":644,"../../_lib/custom-search-events":672,"../../_stores/localization_store":719,"../../_stores/price_service_store":723,"../../_stores/search_result_store":725,"../../_stores/search_store":726,"./other_result":779,"./spare_part_result":784,"react":525}],781:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _actionsSearch_actions = require('../../_actions/search_actions');

var _actionsSearch_actions2 = _interopRequireDefault(_actionsSearch_actions);

var _storesSearch_store = require('../../_stores/search_store');

var _storesSearch_store2 = _interopRequireDefault(_storesSearch_store);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _searchSmart_search = require('../../search/smart_search');

var _searchSmart_search2 = _interopRequireDefault(_searchSmart_search);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _actionsPrice_service_actions = require('../../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesBrand_filter_store = require('../../_stores/brand_filter_store');

var _storesBrand_filter_store2 = _interopRequireDefault(_storesBrand_filter_store);

var _storesProduct_line_filter_store = require('../../_stores/product_line_filter_store');

var _storesProduct_line_filter_store2 = _interopRequireDefault(_storesProduct_line_filter_store);

var _storesUsage_type_filter_store = require('../../_stores/usage_type_filter_store');

var _storesUsage_type_filter_store2 = _interopRequireDefault(_storesUsage_type_filter_store);

var _storesTop_category_filter_store = require('../../_stores/top_category_filter_store');

var _storesTop_category_filter_store2 = _interopRequireDefault(_storesTop_category_filter_store);

var doneTypingInterval = 300;
var lang = hiabconfig.search.lang;

var SearchField = (function (_React$Component) {
	_inherits(SearchField, _React$Component);

	function SearchField(props) {
		_classCallCheck(this, SearchField);

		_React$Component.call(this, props);
		this.state = {
			loading: false,
			searchSerial: false,
			searchTabsModal: false
		};
		this.typingTimer = null;
	}

	SearchField.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.initSmartSearch(this.state.searchSerial);
		_storesSearch_result_store2['default'].listen(function () {
			if (!_storesSearch_result_store2['default'].getLoading()) {
				if (_jquery2['default']('#search-field-modal .spinner').length > 0) {
					_jquery2['default']('#search-field-modal .spinner').remove();
				}
				if (_jquery2['default']('.uc-searchmodal').hasClass('is-open') && _jquery2['default']('body').hasClass('searchmodal-open')) {
					_jquery2['default']('.uc-searchmodal').removeClass('is-open');
					_jquery2['default']('body').removeClass('searchmodal-open');
				}
			}
		});
		_storesSearch_store2['default'].listen(function (searchStoreState) {
			_this.setState({
				loading: searchStoreState.loading
			});
		});
	};

	SearchField.prototype.initSmartSearch = function initSmartSearch(searchSerial) {
		if (isOnSearchPage()) {
			if (searchSerial) {
				_searchSmart_search2['default'].init(searchSerial, isOnSearchPage());
			}
		} else {
			_searchSmart_search2['default'].init(searchSerial, isOnSearchPage());
		}
	};

	SearchField.prototype.handleQueryChange = function handleQueryChange(query) {
		var _this2 = this;

		if (query != '' && query.length > 1) {
			if (isOnSearchPage()) {
				if (!this.state.searchSerial) {
					if (this.typingTimer) clearTimeout(this.typingTimer);
					this.typingTimer = setTimeout(function () {
						_this2.doneTyping(query);
					}, doneTypingInterval);
				}
			}
		}
	};

	SearchField.prototype.doneTyping = function doneTyping(query) {
		// clear filters when makeing a new serach
		_storesBrand_filter_store2['default'].onClearFilters();
		_storesProduct_line_filter_store2['default'].onClearFilters();
		_storesUsage_type_filter_store2['default'].onClearFilters();
		_storesTop_category_filter_store2['default'].onClearFilters();

		_actionsPrice_service_actions2['default'].abortFetchPrices();
		_actionsSearch_actions2['default'].setQuery(query);
		var spinner = '<div class="spinner">' + lang.searching + ' <i class="animate-spin icon-spin4"></i></div>';
		if (_jquery2['default']('.uc-searchmodal').hasClass('is-open') && _jquery2['default']('body').hasClass('searchmodal-open')) {
			if (_jquery2['default']('#search-field-modal .spinner').length === 0) {
				_jquery2['default']('#search-field-modal').append(spinner);
			}
		}
	};

	SearchField.prototype.clickEnterSubmit = function clickEnterSubmit(e) {
		function setLoaderIconAndSubmit() {
			var buttons = document.querySelectorAll('#search-field button, #search-field-modal button');
			for (var i = 0; i < buttons.length; i++) {
				buttons[i].className += ' loading';
			}
			document.getElementById('search-main').form.submit();
		}
		if (this.state.searchSerial) {
			var key = e.which || e.charCode || e.keyCode;
			if (key === 13 || e.target.nodeName === 'BUTTON' || e.target.nodeName === 'SPAN' || e.target.nodeName === 'I') {
				e.preventDefault();
			}
		} else if (document.getElementById('illustration')) {
			var key = e.which || e.charCode || e.keyCode;
			if (key === 13 || e.target.nodeName === 'BUTTON' || e.target.nodeName === 'SPAN' || e.target.nodeName === 'I') {
				setLoaderIconAndSubmit();
			}
		} else if (isOnSearchPage()) {
			var query = _jquery2['default']('#search-main').val();
			if (query != '' && query.length > 1) {
				this.doneTyping(query);
			}
			_jquery2['default']('#search-main').focus();
		} else {
			setLoaderIconAndSubmit();
		}
	};

	SearchField.prototype.handleSubmit = function handleSubmit(e) {
		if (isOnSearchPage() && !this.state.searchSerial) {
			e.preventDefault();
			_actionsSearch_actions2['default'].invalidate();
		} else {
			if (this.state.searchSerial) {
				e.preventDefault();
			} else {
				var buttons = e.target.querySelectorAll('button');
				for (var button in buttons) {
					if (buttons.hasOwnProperty(button)) {
						buttons[button].className += ' loading';
					}
				}
			}
		}
	};

	SearchField.prototype.toggleSearchModal = function toggleSearchModal() {
		if (_jquery2['default']('.uc-searchmodal').is('.is-open')) {
			this.setState({ searchTabsModal: false });
			_jquery2['default']('.uc-searchmodal').removeClass('is-open');
		} else {
			this.setState({ searchTabsModal: true });
			_jquery2['default']('.uc-searchmodal').addClass('is-open');
			_jquery2['default']('body').addClass('searchmodal-open');
			_jquery2['default']('.search-main').focus();
		}
	};

	SearchField.prototype.handleChangePath = function handleChangePath(e) {
		var searchSelectorValue = e.target.value === lang.serialnumber;
		this.state.searchSerial = searchSelectorValue;
		this.setState({
			searchSerial: e.target.value === lang.serialnumber
		});

		_searchSmart_search2['default'].setContext(this.state.searchSerial, isOnSearchPage());

		if (isOnSearchPage()) {
			// TODO: Terminate current requests
			if (this.state.searchSerial) {
				this.initSmartSearch(this.state.searchSerial, true);
			} else {
				if (_jquery2['default']('#search-field .uc-searchfield .ui-autocomplete-input').length > 0 || _jquery2['default']('#search-field-modal .uc-searchfield .ui-autocomplete-input').length > 0) {
					_searchSmart_search2['default'].destroyAutoComplete();
				}
			}
		} else {
			this.initSmartSearch(this.state.searchSerial, false);
			_jquery2['default']('#search-main').focus();
		}
	};

	SearchField.prototype.render = function render() {
		var _this3 = this;

		var inputClassnames = _classnames2['default']({
			'search-main': true,
			loading: this.state.loading
		});

		var inputProps = {
			onKeyDown: function onKeyDown(e) {
				return _this3.clickEnterSubmit.bind(_this3);
			},
			onKeyUp: function onKeyUp(e) {
				return _this3.handleQueryChange(e.target.value);
			},
			defaultValue: _storesSearch_store2['default'].getQuery(),
			type: 'search',
			id: 'search-main',
			className: inputClassnames,
			name: 'query',
			placeholder: hiabconfig.userLoggedIn ? this.state.searchSerial ? lang.placeholderSerial : lang.placeholderCatalog : lang.placeholder
		};
		var dataAddClass = '';
		var dataAddedClass = '';
		if (isOnSearchPage() && !this.state.searchSerial) {
			inputProps["data-disable-autocomplete"] = true;
		} else {
			if (!this.state.searchSerial) {
				dataAddClass = '#search-field button-search-desktop';
				dataAddedClass = 'loading';
			}
		}

		var searchInput = _react2['default'].createElement(
			'div',
			{ className: 'clearfix' },
			_react2['default'].createElement('input', inputProps)
		),
		    searchTabs = "";

		if (hiabconfig.userLoggedIn) {
			searchInput = _react2['default'].createElement(
				'div',
				{ className: 'clearfix ui action input' },
				_react2['default'].createElement('input', inputProps)
			);
			searchTabs = _react2['default'].createElement(
				'div',
				{ className: 'search-tabs' },
				_react2['default'].createElement(
					'div',
					{ className: 'search-tab' },
					_react2['default'].createElement('input', { type: 'radio', id: this.state.searchTabsModal ? "part-number-mobile" : "part-number", name: 'search-for', defaultChecked: true, value: lang.catalog, onChange: this.handleChangePath.bind(this) }),
					_react2['default'].createElement(
						'label',
						{ htmlFor: this.state.searchTabsModal ? "part-number-mobile" : "part-number" },
						_react2['default'].createElement('span', { className: 'icon-search' }),
						lang.catalog
					)
				),
				_react2['default'].createElement(
					'div',
					{ className: 'search-tab' },
					_react2['default'].createElement('input', { type: 'radio', id: this.state.searchTabsModal ? "serial-mobile" : "serial", name: 'search-for', value: lang.serialnumber, onChange: this.handleChangePath.bind(this) }),
					_react2['default'].createElement(
						'label',
						{ htmlFor: this.state.searchTabsModal ? "serial-mobile" : "serial" },
						_react2['default'].createElement('span', { className: 'icon-search' }),
						lang.serialnumber
					)
				)
			);
		}
		return _react2['default'].createElement(
			'div',
			{ className: 'uc-searchfield clearfix' },
			_react2['default'].createElement(
				'form',
				{ action: hiabconfig.searchPage.url, method: 'get', onSubmit: this.handleSubmit.bind(this) },
				_react2['default'].createElement(
					'button',
					{ className: 'button button-search-tablet searchModal', type: 'button', onClick: this.toggleSearchModal.bind(this) },
					_react2['default'].createElement('i', { className: 'icon-search' }),
					_react2['default'].createElement(
						'span',
						null,
						lang.search
					)
				),
				searchTabs,
				_react2['default'].createElement(
					'button',
					{ className: 'button js-init-search', 'data-add-class': dataAddClass, 'data-added-class': dataAddedClass, type: 'button', onClick: this.clickEnterSubmit.bind(this) },
					_react2['default'].createElement('i', { className: 'icon-search' }),
					_react2['default'].createElement(
						'span',
						null,
						lang.search
					)
				),
				searchInput
			)
		);
	};

	return SearchField;
})(_react2['default'].Component);

exports['default'] = SearchField;

function isOnSearchPage() {
	return !!_storesSearch_store2['default'].getQuery();
}
module.exports = exports['default'];

},{"../../_actions/price_service_actions":641,"../../_actions/search_actions":644,"../../_stores/brand_filter_store":697,"../../_stores/product_line_filter_store":724,"../../_stores/search_result_store":725,"../../_stores/search_store":726,"../../_stores/top_category_filter_store":730,"../../_stores/usage_type_filter_store":732,"../../search/smart_search":817,"classnames":299,"jquery":628,"react":525}],782:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesSearch_result_store = require('../../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _actionsUsage_type_filter_actions = require('../../_actions/usage_type_filter_actions');

var _actionsUsage_type_filter_actions2 = _interopRequireDefault(_actionsUsage_type_filter_actions);

var _actionsBrand_filter_actions = require('../../_actions/brand_filter_actions');

var _actionsBrand_filter_actions2 = _interopRequireDefault(_actionsBrand_filter_actions);

// import GroupSelector from '../search/group_selector';

var _filterFilter_count = require('../filter/filter_count');

var _filterFilter_count2 = _interopRequireDefault(_filterFilter_count);

var _filterUsage_type_filter = require('../filter/usage_type_filter');

var _filterUsage_type_filter2 = _interopRequireDefault(_filterUsage_type_filter);

var _filterBrand_filter = require('../filter/brand_filter');

var _filterBrand_filter2 = _interopRequireDefault(_filterBrand_filter);

var _filterSorter = require('../filter/sorter');

var _filterSorter2 = _interopRequireDefault(_filterSorter);

var translations = {};

var SearchHeader = (function (_React$Component) {
  _inherits(SearchHeader, _React$Component);

  function SearchHeader(props) {
    _classCallCheck(this, SearchHeader);

    _React$Component.call(this, props);
    this.state = {
      selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
      totalMatching: _storesSearch_result_store2['default'].getTotalMatching(),
      loading: _storesSearch_result_store2['default'].getLoading(),
      query: SearchStore.getQuery(),
      showExtraFilters: false
    };

    translations.filters = _storesLocalization_store2['default'].getTranslation('/Filter/Filters');
    translations.clearAll = _storesLocalization_store2['default'].getTranslation('/Filter/ClearAll');
    translations.yourSearchFor = _storesLocalization_store2['default'].getTranslation('/Search/SearchFor');
    translations.resultedIn = _storesLocalization_store2['default'].getTranslation('/Search/ResultedIn');
    translations.hits = _storesLocalization_store2['default'].getTranslation('/Search/Hits');
    translations.hit = _storesLocalization_store2['default'].getTranslation('/Search/Hit');
    translations.searching = _storesLocalization_store2['default'].getTranslation('/Search/Searching');
    translations.loading = _storesLocalization_store2['default'].getTranslation('/Search/Loading');
  }

  SearchHeader.prototype.handleClearAllClick = function handleClearAllClick() {
    // todo: make sure this does not trigger fifty ajax requests
    _actionsUsage_type_filter_actions2['default'].clearFilters();
    _actionsBrand_filter_actions2['default'].clearFilters();
  };

  SearchHeader.prototype.toggleExtraFilters = function toggleExtraFilters() {
    this.setState({ showExtraFilters: !this.state.showExtraFilters });
  };

  SearchHeader.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    this.unsubscribe1 = _storesSearch_result_store2['default'].listen(function () {
      return _this.setState({
        selectedGroup: _storesSearch_result_store2['default'].getSelectedGroup(),
        totalMatching: _storesSearch_result_store2['default'].getTotalMatching(),
        loading: _storesSearch_result_store2['default'].getLoading()
      });
    });

    this.unsubscribe2 = SearchStore.listen(function () {
      _this.setState({
        query: SearchStore.getQuery()
      });
    });
  };

  SearchHeader.prototype.componentWillUnmount = function componentWillUnmount() {
    this.unsubscribe();
    this.unsubscribe2();
  };

  SearchHeader.prototype.render = function render() {
    var _state = this.state;
    var selectedGroup = _state.selectedGroup;
    var totalMatching = _state.totalMatching;
    var query = _state.query;
    var loading = _state.loading;
    var showExtraFilters = _state.showExtraFilters;

    var showFilters = selectedGroup == 'spareParts' || selectedGroup == 'lightSparePartViewModel' ? true : false;

    var isOnSearchPage = typeof query !== 'undefined';

    return _react2['default'].createElement(
      'section',
      { className: 'uc-filter' },
      _react2['default'].createElement(
        'div',
        { className: 'row' },
        _react2['default'].createElement(
          'div',
          { className: 'small-12 columns filter-sorter' },
          _react2['default'].createElement(
            'div',
            { className: 'filter-sorter-left' },
            _react2['default'].createElement(ResultSummary, { query: query, totalMatching: totalMatching, isOnSearchPage: isOnSearchPage, loading: loading })
          ),
          _react2['default'].createElement(
            'div',
            { className: 'filter-sorter-right' },
            _react2['default'].createElement(
              'div',
              { className: 'uc-layout-toggle right hide-for-small' },
              _react2['default'].createElement(
                'button',
                { id: 'grid', className: 'button circle active' },
                _react2['default'].createElement('i', { className: 'icon-th-large' })
              ),
              _react2['default'].createElement(
                'button',
                { id: 'list', className: 'button circle' },
                _react2['default'].createElement('i', { className: 'icon-menu-1' })
              )
            )
          )
        )
      )
    );
  };

  return SearchHeader;
})(_react2['default'].Component);

exports['default'] = SearchHeader;

var ExtraFilters = function ExtraFilters(props) {
  return _react2['default'].createElement(
    'div',
    { className: 'medium-4 medium-pull-8 large-3 large-pull-9 columns filter-toggle' },
    _react2['default'].createElement(
      'button',
      { className: 'round button left filters-expand', onClick: props.toggleExtraFilters },
      _react2['default'].createElement('i', { className: 'icon-angle-down' }),
      translations.filters,
      ': ',
      _react2['default'].createElement(_filterFilter_count2['default'], null)
    ),
    _react2['default'].createElement(
      'button',
      { className: 'button text filters-clear', onClick: props.handleClearAll },
      translations.clearAll
    )
  );
};

var ResultSummary = function ResultSummary(props) {
  var query = props.query;
  var totalMatching = props.totalMatching;
  var loading = props.loading;
  var isOnSearchPage = props.isOnSearchPage;

  return _react2['default'].createElement(
    'div',
    { className: 'uc-result-header' },
    loading ? _react2['default'].createElement(
      'h4',
      null,
      _react2['default'].createElement('i', { className: 'animate-spin icon-spin4' }),
      ' ',
      translations.searching
    ) : null,
    isOnSearchPage && !loading ? _react2['default'].createElement(
      'h4',
      null,
      translations.yourSearchFor,
      ' ',
      _react2['default'].createElement(
        'span',
        { className: 'query' },
        query
      ),
      ' ',
      translations.resultedIn,
      ' ',
      _react2['default'].createElement(
        'span',
        { className: 'hits' },
        totalMatching,
        ' ',
        totalMatching == 1 ? translations.hit : translations.hits
      )
    ) : null
  );
};
module.exports = exports['default'];

},{"../../_actions/brand_filter_actions":632,"../../_actions/usage_type_filter_actions":649,"../../_stores/localization_store":719,"../../_stores/search_result_store":725,"../filter/brand_filter":758,"../filter/filter_count":759,"../filter/sorter":764,"../filter/usage_type_filter":766,"react":525}],783:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _stringformat = require('stringformat');

var _stringformat2 = _interopRequireDefault(_stringformat);

var _storesPrice_service_store = require('../../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var translations = {};

var SparePartFooter = (function (_React$Component) {
	_inherits(SparePartFooter, _React$Component);

	function SparePartFooter(props) {
		_classCallCheck(this, SparePartFooter);

		_React$Component.call(this, props);

		translations.materialNumber = _storesLocalization_store2['default'].getTranslation('/Product/Information/MaterialNumber');
		translations.addToCart = _storesLocalization_store2['default'].getTranslation('/Product/Information/AddToCart');
		translations.quickBuy = _storesLocalization_store2['default'].getTranslation('/Product/Information/QuickBuy');
		translations.replacedBy = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/ReplacedByShort');
		translations.viewReplacingProduct = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/ViewReplacingProduct');
		translations.viewDetails = _storesLocalization_store2['default'].getTranslation('/Filter/ViewDetails');
		translations.notBuyable = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/NotBuyable');
		translations.discount = _storesLocalization_store2['default'].getTranslation('/Product/Information/Discount');
		translations.fetchingInfo = _storesLocalization_store2['default'].getTranslation('/Search/FetchingInformation');
		translations.promotionTitle = _storesLocalization_store2['default'].getTranslation('/General/Promotion/Discount/Title');
		translations.promotionWas = _storesLocalization_store2['default'].getTranslation('/General/Promotion/Was');
		translations.priceError = _storesLocalization_store2['default'].getTranslation('/Product/PriceError');
		translations.grossPrice = _storesLocalization_store2['default'].getTranslation('/Product/Information/Price/Was');

		if (this.props.translations) {
			translations.materialNumber = this.props.translations.materialNumber;
			translations.addToCart = this.props.translations.addToCart;
			translations.quickBuy = this.props.translations.quickBuy;
			translations.replacedBy = this.props.translations.replacedBy;
			translations.viewReplacingProduct = this.props.translations.viewReplacingProduct;
			translations.viewDetails = this.props.translations.viewDetails;
			translations.notBuyable = this.props.translations.notBuyable;
			translations.discount = this.props.translations.discount;
			translations.fetchingInfo = this.props.translations.fetchingInfo;
			translations.promotionTitle = this.props.translations.promotionTitle;
			translations.promotionWas = this.props.translations.promotionWas;
			translations.priceError = this.props.translations.priceError;
			translations.grossPrice = this.props.translations.grossPrice;
		}

		this.state = {
			Buyable: false,
			InStockQuantity: 0,
			Loaded: false,
			Code: "",
			Price: "",
			ShippingDate: "",
			IsDiscounted: false,
			DefaultPrice: "",
			DiscountPercent: "",
			ProductContext: {},
			PromotionDiscountPercent: "",
			PromotionPrice: "",
			HasPromotion: false,
			HasError: false
		};
	}

	SparePartFooter.prototype.componentDidUpdate = function componentDidUpdate() {
		if (this.state.Loaded) {
			this.reflow();
		}
	};

	SparePartFooter.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		//this.reflow();

		var price = _storesPrice_service_store2['default'].getPricesForMaterial(this.props.materialNumber);
		if (price.length > 0) {
			this.setPriceForFooter(price);
		}

		this.unsubscribe = _storesPrice_service_store2['default'].listen(function () {
			if (!_this.state.Loaded) {
				var _price = _storesPrice_service_store2['default'].getPricesForMaterial(_this.props.materialNumber);
				if (_price.length > 0) {
					_this.setPriceForFooter(_price);
				}
			}
		});
	};

	SparePartFooter.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	SparePartFooter.prototype.setPriceForFooter = function setPriceForFooter(price) {
		this.setState({
			Buyable: price[0].Buyable,
			InStockQuantity: price[0].InStockQuantity,
			Loaded: true,
			Code: price[0].Code,
			Price: price[0].Price,
			ShippingDate: price[0].ShippingDate,
			IsDiscounted: price[0].IsDiscounted,
			DefaultPrice: price[0].DefaultPrice,
			DiscountPercent: price[0].DiscountPercent,
			ProductContext: price[0].ProductContext,
			PromotionDiscountPercent: price[0].PromotionDiscountPercent,
			PromotionPrice: price[0].PromotionPrice,
			HasPromotion: price[0].HasPromotion,
			HasError: price[0].HasError
		});

		var materialNumber = this.state.Code.split('.').join('-');
		var productCardBanner = '';

		if (this.state.HasPromotion) {
			// let translationPromoitionDiscount = translations.promotionTitle;
			// let promotionPercent = translationPromoitionDiscount+' '+this.state.PromotionDiscountPercent+'%';
			productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-tags"></i></span></div>';
			// productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-tags"></i>'+promotionPercent+'</span></div>';
			$('#li-' + materialNumber + ' .image').append(productCardBanner);
		}

		if (!this.state.HasPromotion && this.props.gotScaledPrices && this.state.Buyable) {
			productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-money"></i></span></div>';
			// productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-money"></i></span></div>';
			$('#li-' + materialNumber + ' .image').append(productCardBanner);
		}

		this.reflow();
	};

	SparePartFooter.prototype.reflow = function reflow() {
		var ua = window.navigator.userAgent;
		var trident = ua.indexOf('Trident/');
		var msie = ua.indexOf('MSIE ');

		if (msie > 0 || trident > 0) {
			Foundation.libs.equalizer.equalize($('.uc-productlist ul'));
			Foundation.libs.equalizer.equalize($('.uc-productlist'));
			Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
			Foundation.libs.equalizer.equalize($('.item-name-watch'));
			Foundation.libs.equalizer.equalize($('.main-li-watch'));
			Foundation.libs.equalizer.equalize($('.add-to-btns'));
		} else {
			$(document).foundation('equalizer', 'reflow');
		}
	};

	SparePartFooter.prototype.render = function render() {
		return _react2['default'].createElement(
			'div',
			null,
			this.state.Buyable ? _react2['default'].createElement(BuyFooter, { materialNumber: this.state.Code,
				price: this.state.Price,
				inStockQuantity: this.state.InStockQuantity,
				shippingDate: this.state.ShippingDate,
				isDiscounted: this.state.IsDiscounted,
				defaultPrice: this.state.DefaultPrice,
				discountPercent: this.state.DiscountPercent,
				productContext: this.state.ProductContext,
				gotScaledPrices: this.props.gotScaledPrices,
				userIsDealer: this.props.isDealer,
				hasPromotion: this.state.HasPromotion,
				promotionPrice: this.state.PromotionPrice
			}) : !this.state.Buyable && this.state.Loaded ? _react2['default'].createElement(ViewDetailsFooter, { hasError: this.state.HasError, detailsUrl: this.props.url }) : _react2['default'].createElement(FetchPriceFooter, null)
		);
	};

	return SparePartFooter;
})(_react2['default'].Component);

exports['default'] = SparePartFooter;

var FetchPriceFooter = function FetchPriceFooter(props) {
	return _react2['default'].createElement(
		'div',
		{ className: 'footer loading' },
		_react2['default'].createElement('div', { className: 'campaing-wrapper', 'data-equalizer-watch': 'campaing-wrapper' }),
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center', style: { "display": "block" } }),
			_react2['default'].createElement(
				'span',
				{ className: 'text-center', style: { "display": "block" } },
				translations.fetchingInfo
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
			_react2['default'].createElement(
				'button',
				{ className: 'button left add-to-cart' },
				translations.addToCart
			),
			_react2['default'].createElement(
				'button',
				{ className: 'button right quick-buy' },
				translations.quickBuy
			)
		)
	);
};

var BuyFooter = function BuyFooter(props) {
	var materialNumber = props.materialNumber;
	var price = props.price;
	var inStockQuantity = props.inStockQuantity;
	var shippingDate = props.shippingDate;
	var isDiscounted = props.isDiscounted;
	var defaultPrice = props.defaultPrice;
	var discountPercent = props.discountPercent;
	var productContext = props.productContext;
	var gotScaledPrices = props.gotScaledPrices;
	var promotionPrice = props.promotionPrice;
	var hasPromotion = props.hasPromotion;
	var userIsDealer = props.userIsDealer;

	var materialNumberAsId = materialNumber.split('.').join('-');
	var context = JSON.stringify(productContext);
	// let gotScaledPricesIcon = gotScaledPrices && !hasPromotion ? <i className="icon-money"></i> : null;

	var gotScaledPricesIcon = '';

	var dealerIndication = '';
	if (userIsDealer) {
		if (isDiscounted) {
			dealerIndication = translations.promotionWas + ': ';
		} else {
			dealerIndication = translations.grossPrice + ': ';
		}
	}

	var translationGross = translations.discount.substring(0, translations.discount.indexOf('}') + 1);
	var translationDiscount = translations.discount.substring(translations.discount.indexOf('}') + 2).replace("1", "0");
	var translationWas = translations.promotionWas;
	var translationPromoitionDiscount = translations.promotionTitle;

	var defaultPriceText = _stringformat2['default'](translationGross, defaultPrice);
	var discountPercentText = _stringformat2['default'](translationDiscount, discountPercent);
	var promotionPriceText = translationWas + ': ' + price;
	var shippingInfo = null;
	/*
 shippingInfo = <div className="shippping-date"><p>#!Ships: {shippingDate}</p></div>
 */

	var campaingInfo = _classnames2['default']({
		'campaing-info': true,
		'clearfix': true,
		'default': isDiscounted && hasPromotion,
		'hide': !isDiscounted && !hasPromotion
	});

	var cost = price;
	var hasSelectedWishlist = $('.wishlist-toggle').hasClass('active');

	var savedCartClass = _classnames2['default']({
		'sml': true,
		'button': true,
		'wishlist': true,
		'search-saved-cart-add': true,
		'saved-cart-add': true,
		'right-off-canvas-toggle': !hasSelectedWishlist
	});

	return _react2['default'].createElement(
		'div',
		{ className: 'footer' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement(
				'div',
				{ className: 'left' },
				_react2['default'].createElement('input', { 'data-product-sku': materialNumber, 'data-product-cost': cost, className: 'amount', name: 'aumont-x', defaultValue: '1' }),
				_react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'price', className: 'price left' },
					hasPromotion ? null : gotScaledPricesIcon,
					hasPromotion ? '' + promotionPrice : '' + dealerIndication + price
				)
			),
			_react2['default'].createElement(
				'div',
				{ className: 'right' },
				inStockQuantity !== undefined && inStockQuantity ? _react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'availability', className: 'stock right txt-left' },
					_react2['default'].createElement('i', { className: 'icon-cubes' }),
					inStockQuantity
				) : shippingDate !== undefined && shippingDate !== '' ? _react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'availability', className: 'stock right txt-left' },
					_react2['default'].createElement('i', { className: 'icon-cubes' }),
					shippingDate
				) : null
			),
			_react2['default'].createElement(
				'div',
				{ className: 'bottom clearfix' },
				_react2['default'].createElement(
					'div',
					{ className: campaingInfo },
					isDiscounted && !hasPromotion ? _react2['default'].createElement(
						'span',
						null,
						_react2['default'].createElement(
							'p',
							{ className: 'gross' },
							defaultPriceText
						),
						_react2['default'].createElement(
							'p',
							null,
							discountPercentText
						)
					) : '',
					isDiscounted && hasPromotion ? _react2['default'].createElement(
						'span',
						null,
						_react2['default'].createElement(
							'p',
							{ className: 'gross' },
							defaultPriceText
						),
						_react2['default'].createElement(
							'p',
							null,
							discountPercentText
						),
						_react2['default'].createElement(
							'p',
							{ className: 'default-campaing' },
							promotionPriceText
						)
					) : '',
					!isDiscounted && hasPromotion ? _react2['default'].createElement(
						'span',
						null,
						_react2['default'].createElement(
							'p',
							{ className: 'default-campaing' },
							promotionPriceText
						)
					) : ''
				),
				shippingInfo
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns', 'data-product-context': context },
			_react2['default'].createElement(
				'button',
				{ 'data-product-sku': materialNumber, className: savedCartClass },
				_react2['default'].createElement('i', { className: 'icon-saved-cart-add' })
			),
			_react2['default'].createElement(
				'button',
				{ 'data-product-sku': materialNumber, className: 'button add-to-cart' },
				translations.addToCart
			),
			_react2['default'].createElement(
				'button',
				{ 'data-product-sku': materialNumber, className: 'button quick-buy' },
				translations.quickBuy
			)
		),
		_react2['default'].createElement('div', { id: materialNumberAsId, className: 'SparePartResult-info' })
	);
};

BuyFooter.propTypes = {
	discountPercent: _react2['default'].PropTypes.string,
	defaultPrice: _react2['default'].PropTypes.string,
	materialNumber: _react2['default'].PropTypes.string,
	price: _react2['default'].PropTypes.string,
	inStockQuantity: _react2['default'].PropTypes.number,
	shippingDate: _react2['default'].PropTypes.string
};

var ViewDetailsFooter = function ViewDetailsFooter(props) {
	var detailsUrl = props.detailsUrl;
	var hasError = props.hasError;

	var detailsText = hasError ? translations.priceError : translations.notBuyable;
	return _react2['default'].createElement(
		'div',
		{ className: 'footer' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement(
				'span',
				{ className: 'u-txt-center u-dt' },
				detailsText
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
			_react2['default'].createElement(
				'a',
				{ className: 'button center not-buyable', href: detailsUrl },
				translations.viewDetails
			)
		)
	);
};

ViewDetailsFooter.propTypes = {
	detailsUrl: _react2['default'].PropTypes.string
};
module.exports = exports['default'];

},{"../../_stores/localization_store":719,"../../_stores/price_service_store":723,"classnames":299,"react":525,"stringformat":546}],784:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactLazyLoad = require('react-lazy-load');

var _reactLazyLoad2 = _interopRequireDefault(_reactLazyLoad);

var _stringformat = require('stringformat');

var _stringformat2 = _interopRequireDefault(_stringformat);

var _spare_part_footer = require('./spare_part_footer');

var _spare_part_footer2 = _interopRequireDefault(_spare_part_footer);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesLocalization_store = require('../../_stores/localization_store');

var _storesLocalization_store2 = _interopRequireDefault(_storesLocalization_store);

var translations = {};

var SparePartResult = (function (_React$Component) {
  _inherits(SparePartResult, _React$Component);

  function SparePartResult(props) {
    _classCallCheck(this, SparePartResult);

    _React$Component.call(this, props);

    translations.materialNumber = _storesLocalization_store2['default'].getTranslation('/Product/Information/MaterialNumber');
    translations.addToCart = _storesLocalization_store2['default'].getTranslation('/Product/Information/AddToCart');
    translations.quickBuy = _storesLocalization_store2['default'].getTranslation('/Product/Information/QuickBuy');
    translations.replacedBy = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/ReplacedByShort');
    translations.viewReplacingProduct = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/ViewReplacingProduct');
    translations.viewDetails = _storesLocalization_store2['default'].getTranslation('/Filter/ViewDetails');
    translations.notBuyable = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/NotBuyable');
    translations.notBuyableSignIn = _storesLocalization_store2['default'].getTranslation('/Product/Information/NotBuyable/NotBuyableSignIn');
    translations.scaledPricesTooltip = _storesLocalization_store2['default'].getTranslation('/Product/Information/ScaledPrices/Tooltip');
  }

  SparePartResult.prototype.componentDidMount = function componentDidMount() {
    // this.imgOnLoad();
  };

  SparePartResult.prototype.componentDidUpdate = function componentDidUpdate() {
    // this.imgOnLoad();
    if (this.props.gotScaledPrices) {
      $(document).foundation('tooltip', 'reflow');
    }
  };

  SparePartResult.prototype.isReplaced = function isReplaced() {
    return !!this.props.replacementName && !this.props.isQueryable;
    this.imgOnLoad();
  };

  SparePartResult.prototype.isQueryable = function isQueryable() {
    return this.props.isQueryable;
    this.imgOnLoad();
  };

  SparePartResult.prototype.imgOnLoad = function imgOnLoad() {
    var ua = window.navigator.userAgent;
    var trident = ua.indexOf('Trident/');
    var msie = ua.indexOf('MSIE ');
    if (msie > 0 || trident > 0) {
      $(document).ready(function () {
        Foundation.libs.equalizer.equalize($('.result-spare-parts'));
        Foundation.libs.equalizer.equalize($('.uc-productlist'));
        Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
        // Foundation.libs.equalizer.equalize($('.main-li-watch'));
      });
    } else {
        $(document).foundation('equalizer', 'reflow');
      }
  };

  SparePartResult.prototype.render = function render() {
    //rendered once for each material
    var _props = this.props;
    var name = _props.name;
    var materialNumber = _props.materialNumber;
    var url = _props.url;
    var price = _props.price;
    var inStockQuantity = _props.inStockQuantity;
    var isBuyable = _props.isBuyable;
    var images = _props.images;
    var replacementMaterialNumber = _props.replacementMaterialNumber;
    var replacementUrl = _props.replacementUrl;
    var shippingDate = _props.shippingDate;
    var defaultPrice = _props.defaultPrice;
    var isQueryable = _props.isQueryable;
    var gotScaledPrices = _props.gotScaledPrices;
    var isBlocked = _props.isBlocked;
    var restrictionType = _props.restrictionType;
    var restrictionText = _props.restrictionText;

    var hasImage = images && images.length > 0;
    var materialNumberAsId = 'li-' + materialNumber.split('.').join('-');
    var toolTip = gotScaledPrices && isQueryable ? { 'data-tooltip': 'true' } : null;
    var toolTipTitle = gotScaledPrices && isQueryable ? { 'title': translations.scaledPricesTooltip } : null;
    var toolTipAria = gotScaledPrices && isQueryable ? { 'aria-haspopup': 'true' } : null;

    var itemWrapperClass = _classnames2['default']({
      'item-wrapper': true,
      'has-tip': gotScaledPrices,
      'tip-top': gotScaledPrices
    });
    return _react2['default'].createElement(
      'li',
      { id: materialNumberAsId },
      _react2['default'].createElement(
        'div',
        _extends({ className: itemWrapperClass }, toolTip, toolTipTitle, toolTipAria),
        _react2['default'].createElement(
          'div',
          { className: 'image' },
          _react2['default'].createElement('div', { className: 'filler' }),
          _react2['default'].createElement(
            _reactLazyLoad2['default'],
            { height: 133, offsetVertical: 380 },
            hasImage ? _react2['default'].createElement(
              'a',
              { href: url },
              _react2['default'].createElement('img', { src: images[0].url + '?preset=list', alt: images[0].seoText })
            ) : null
          )
        ),
        _react2['default'].createElement(
          'div',
          { className: 'item-name', 'data-equalizer-watch': 'item-name' },
          _react2['default'].createElement(
            'h4',
            null,
            _react2['default'].createElement(
              'a',
              { href: url },
              name
            )
          ),
          _react2['default'].createElement(
            'p',
            null,
            _react2['default'].createElement(
              'span',
              null,
              materialNumber
            )
          ),
          _react2['default'].createElement('div', { className: 'campaing-info' })
        ),
        _react2['default'].createElement(
          'div',
          { className: 'footer-wrapper' },
          this.isReplaced() ? _react2['default'].createElement(ReplacementFooter, { replacementUrl: replacementUrl, replacementMaterialNumber: replacementMaterialNumber }) : this.isQueryable() && !isBlocked ? _react2['default'].createElement(_spare_part_footer2['default'], { isDealer: this.props.isDealer, gotScaledPrices: gotScaledPrices, materialNumber: materialNumber, url: url }) : _react2['default'].createElement(ViewDetailsFooter, { id: materialNumberAsId, signedIn: this.props.userIsSignedIn, detailsUrl: url, isBlocked: isBlocked, restrictionType: restrictionType, restrictionText: restrictionText })
        )
      )
    );
  };

  return SparePartResult;
})(_react2['default'].Component);

exports['default'] = SparePartResult;

SparePartResult.propTypes = {
  name: _react2['default'].PropTypes.string,
  materialNumber: _react2['default'].PropTypes.string,
  url: _react2['default'].PropTypes.string,
  price: _react2['default'].PropTypes.string,
  stock: _react2['default'].PropTypes.string,
  isBuyable: _react2['default'].PropTypes.bool,
  images: _react2['default'].PropTypes.array,
  replacementName: _react2['default'].PropTypes.string,
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

var ReplacementFooter = function ReplacementFooter(props) {
  var replacementMaterialNumber = props.replacementMaterialNumber;
  var replacementUrl = props.replacementUrl;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { 'data-product-id': replacementMaterialNumber, 'data-active-tab': 'other', className: 'u-txt-center replaced text-center', style: { "display": "block" } },
        translations.replacedBy,
        ': ',
        _react2['default'].createElement(
          'a',
          { href: replacementUrl },
          replacementMaterialNumber
        )
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: replacementUrl },
        translations.viewReplacingProduct
      )
    )
  );
};

ReplacementFooter.propTypes = {
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

//shown if not queryable
var ViewDetailsFooter = function ViewDetailsFooter(props) {
  var id = props.id;
  var detailsUrl = props.detailsUrl;
  var signedIn = props.signedIn;
  var isBlocked = props.isBlocked;
  var restrictionType = props.restrictionType;
  var restrictionText = props.restrictionText;

  var materialStatus = isBlocked && restrictionType != null && restrictionType.length > 0 ? restrictionText : signedIn ? translations.notBuyable : translations.notBuyableSignIn;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { className: 'u-txt-center u-dt' },
        materialStatus
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: detailsUrl },
        translations.viewDetails
      )
    )
  );
};

ViewDetailsFooter.propTypes = {
  detailsUrl: _react2['default'].PropTypes.string
};
module.exports = exports['default'];

},{"../../_stores/localization_store":719,"./spare_part_footer":783,"classnames":299,"react":525,"react-lazy-load":353,"stringformat":546}],785:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _modeltreeitem = require('./modeltreeitem');

var _modeltreeitem2 = _interopRequireDefault(_modeltreeitem);

var _apiTreeview_api = require('../../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var _modeltreesearch = require('./modeltreesearch');

var _modeltreesearch2 = _interopRequireDefault(_modeltreesearch);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var ModelTree = (function (_React$Component) {
	_inherits(ModelTree, _React$Component);

	function ModelTree(props) {
		_classCallCheck(this, ModelTree);

		_React$Component.call(this, props);

		this.state = {
			children: {
				data: [],
				isMachine: false
			},
			sectionChildren: {}
		};
	}

	ModelTree.prototype.prefetchNodes = function prefetchNodes(model) {
		var _this = this;

		if (!this.props.model) return null;

		_storesTreeview_store2['default'].setLoadingState(true);
		var isMachine = this.props.model.substring(0, 8) == 'machine-';
		var isModel = this.props.model.substring(0, 6) == 'model-';

		if (isMachine) {
			model = this.props.model.replace('machine-', '');
		} else if (isModel) {
			model = this.props.model.replace('model-', '');
		} else {
			model = this.props.model;
		}

		_apiTreeview_api2['default'].getNodes(this.props.model).then(function (response) {
			_storesTreeview_store2['default'].setLoadingState(false);
			if (isMachine) {
				_this.setState({
					children: {
						key: model,
						isMachine: true,
						data: [response]
					}
				});
			} else {
				var _ret = (function () {
					var rootModelChild = _storesTreeview_store2['default'].get(model);
					console.log(rootModelChild);

					if (!rootModelChild.data[0]) return {
							v: undefined
						};
					_storesTreeview_store2['default'].setLoadingState(true);

					_apiTreeview_api2['default'].getNodes(rootModelChild.data[0].Id).then(function (response) {
						_this.setState({
							children: rootModelChild
						});
						_storesTreeview_store2['default'].setSelectedNode(rootModelChild.data[0].Id);
						_storesTreeview_store2['default'].setLoadingState(false);
					})['catch'](function (message) {
						_storesTreeview_store2['default'].setLoadingState(false);
						throw new Error(message);
					});
				})();

				if (typeof _ret === 'object') return _ret.v;
			}
		})['catch'](function (message) {
			_storesTreeview_store2['default'].setLoadingState(false);
			throw new Error(message);
		});
	};

	ModelTree.prototype.selectNode = function selectNode(nodeId) {
		_storesTreeview_store2['default'].setSelectedNode(nodeId);
	};

	ModelTree.prototype.fetchAscendantNodes = function fetchAscendantNodes(sectionChildren) {
		var _this2 = this;

		if (!this.props.model) return null;

		var isMachine = this.props.model.substring(0, 8) == 'machine-';
		_storesTreeview_store2['default'].setLoadingState(true);
		_jquery2['default']('#illustration').addClass('is-loading-menu-an');
		_apiTreeview_api2['default'].getAscendantNodes(this.props.model, this.props.illustration, this.props.nodeId).then(function (response) {
			//update store
			if (isMachine) {
				_this2.setState({
					children: {
						key: _this2.props.model.replace('machine-', ''),
						isMachine: true,
						data: [response]
					}
				});
			} else {
				var parents = _lodash2['default'].uniq(response, function (node) {
					return node.Parent;
				});
				parents.forEach(function (node) {
					_storesTreeview_store2['default'].set(node.Parent, _lodash2['default'].where(response, { Parent: node.Parent }));
				});

				_this2.setState({
					children: _storesTreeview_store2['default'].get(_this2.props.model)
				});
			}
			_storesTreeview_store2['default'].setLoadingState(false);
			_jquery2['default']('#illustration').removeClass('is-loading-menu-an');
		})['catch'](function (message) {
			_storesTreeview_store2['default'].setLoadingState(false);
			_jquery2['default']('#illustration').removeClass('is-loading-menu-an');
			throw new Error(message);
		});
	};

	ModelTree.prototype.fetchChildNodes = function fetchChildNodes(parent, isopen) {
		var _this3 = this;

		_storesTreeview_store2['default'].setLoadingState(true);
		_jquery2['default']('#illustration').addClass('is-loading-menu-cn');
		_apiTreeview_api2['default'].getNodes(parent).then(function (response) {
			var children = _lodash2['default'].isUndefined(response) ? {} : _storesTreeview_store2['default'].get(parent);
			_this3.state.sectionChildren = children;
			console.log(children);
			_this3.fetchAscendantNodes();
			_storesTreeview_store2['default'].setLoadingState(false);
			_jquery2['default']('#illustration').removeClass('is-loading-menu-cn');
		})['catch'](function (message) {
			if (message === 204) {
				var children = {};
				_this3.state.sectionChildren = children;
				_this3.fetchAscendantNodes();
				_storesTreeview_store2['default'].setLoadingState(false);
				_jquery2['default']('#illustration').removeClass('is-loading-menu-cn');
			} else {
				_storesTreeview_store2['default'].setLoadingState(false);
				_jquery2['default']('#illustration').removeClass('is-loading-menu-cn');
				throw new Error(message);
			}
		});
	};

	ModelTree.prototype.componentWillMount = function componentWillMount() {
		if (this.props.model && this.props.illustration) {
			this.fetchChildNodes(this.props.nodeId, true);
			this.selectNode(this.props.illustration);
		} else if (this.props.model && this.props.nodeId) {
			this.fetchChildNodes(this.props.nodeId, true);
			this.selectNode(this.props.nodeId);
		} else {
			this.prefetchNodes(this.props.model);
		}
	};

	ModelTree.prototype.render = function render() {
		var _this4 = this;

		if (!this.props.model) return null;
		var isMachine = this.props.model.substring(0, 8) == 'machine-';
		var children = null;
		var modelTreeItemProps = null;

		if (this.state.children.isMachine) {
			modelTreeItemProps = {
				isMachine: true,
				key: this.props.model,
				node: this.state.children.data,
				model: this.props.model,
				selectedNodeId: _storesTreeview_store2['default'].getSelectedNode(),
				onSelectNode: this.selectNode.bind(this),
				sectionChildren: this.state.children.data[0]
			};

			children = _react2['default'].createElement(_modeltreeitem2['default'], modelTreeItemProps);
		} else {
			children = this.state.children.data.map(function (node) {
				modelTreeItemProps = {
					isMachine: false,
					key: node.Id,
					node: node,
					documents: node.Documents,
					model: _this4.props.model,
					selectedNodeId: _storesTreeview_store2['default'].getSelectedNode(),
					onSelectNode: _this4.selectNode.bind(_this4),
					sectionChildren: _this4.state.sectionChildren ? _this4.state.sectionChildren : null
				};
				return _react2['default'].createElement(_modeltreeitem2['default'], modelTreeItemProps);
			});
		}

		var ulClass = _classnames2['default']({
			'machine': isMachine
		});
		return _react2['default'].createElement(
			'nav',
			{ className: 'uc-treemenu' },
			_react2['default'].createElement(
				'div',
				null,
				_react2['default'].createElement(_modeltreesearch2['default'], { isMachine: isMachine, modelId: this.props.model })
			),
			_react2['default'].createElement(
				'ul',
				{ className: ulClass },
				children
			)
		);
	};

	return ModelTree;
})(_react2['default'].Component);

;
exports['default'] = ModelTree;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_api/treeview_api":661,"../../_stores/treeview_store":731,"./modeltreeitem":786,"./modeltreesearch":787,"classnames":299,"jquery":628,"lodash":333,"react":525}],786:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactRouter = require('react-router');

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _apiTreeview_api = require('../../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var _storesIllustration_store = require('../../_stores/illustration_store');

var _storesIllustration_store2 = _interopRequireDefault(_storesIllustration_store);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var ModelTreeItem = (function (_React$Component) {
	_inherits(ModelTreeItem, _React$Component);

	function ModelTreeItem(props) {
		var _this = this;

		_classCallCheck(this, ModelTreeItem);

		_React$Component.call(this, props);

		this.toggleExpand = function (e) {
			e.preventDefault();
			var isopen = !_this.state.isopen;
			_this.fetchChildNodes(_this.props.node.Id, isopen);
		};

		this.handleClick = function (e) {
			if (_this.state.isopen) {
				var _parent = $(e.target).closest('li');
				if (_parent.hasClass('is-open')) {
					_parent.removeClass('is-open');
					_parent.removeClass('is-selected');
					_this.state.isopen = false;
					return;
				}
			}

			if (_this.props.isMachine || _this.props.isModelType) {
				if (!$(e.target).hasClass('active')) {
					_storesIllustration_store2['default'].setLoadingState(true);
					_this.props.onSelectNode($(e.target).data('node-id'));
				}
			} else {
				if (_this.props.node.IllustrationLink && _this.props.node.IllustrationLink !== '00000000-0000-0000-0000-000000000000') {
					if (_this.props.node.IllustrationLink != _storesIllustration_store2['default'].getIllustration().illustration.Id) {
						_storesIllustration_store2['default'].setLoadingState(true);
					}
				}
				_this.props.onSelectNode(_this.props.node.Id);

				if (_this.props.node.IsLeaf && !_this.props.documents) return;

				var children = _this.fetchChildNodes(_this.props.node.Id, true);
			}
		};

		this.state = {
			children: {
				data: []
			},
			isopen: false
		};

		this.props = {};
	}

	ModelTreeItem.prototype.componentDidMount = function componentDidMount() {
		var children = _storesTreeview_store2['default'].get(this.props.node.Id);
		if (!children && !this.props.sectionChildren) return;
		if (this.props.isMachine) {
			this.setState({
				children: {
					data: this.props.sectionChildren
				},
				isopen: true
			});
		} else {
			this.setState({
				children: children ? children : this.props.sectionChildren,
				isopen: true
			});
		}
	};

	ModelTreeItem.prototype.updateSelectedNodeOnBackClick = function updateSelectedNodeOnBackClick(self) {
		$(window).bind('popstate', function (event) {
			var href = window.location.href;
			var IllustrationLink = href.substr(href.lastIndexOf('/') + 1);
			var links = href.split('/');

			var ids = [];
			for (var i = links.length - 3; i < links.length; i++) {
				if (links[i].length === 36) {
					ids.push(links[i]);
				}
			}

			ids.reverse();

			var liToSetSelected = undefined;
			switch (ids.length) {
				case 1:
					liToSetSelected = $('.uc-treemenu ul > li:first-of-type').attr('data-node-id');
					break;
				case 2:
					liToSetSelected = ids[0];
					break;
				case 3:
					liToSetSelected = ids[1];
					break;
			}

			var changedSelected = false;
			if (self.props.node.Id === liToSetSelected) {
				$('.uc-treemenu li[data-node-id="' + self.props.node.Id + '"]').addClass('is-selected');
			} else {
				$('.uc-treemenu li[data-node-id="' + self.props.node.Id + '"]').removeClass('is-selected');
			}
		});
	};

	ModelTreeItem.prototype.fetchChildNodes = function fetchChildNodes(parent, isopen) {
		var _this2 = this;

		_storesTreeview_store2['default'].setLoadingState(true);

		_apiTreeview_api2['default'].getNodes(parent).then(function (response) {
			var children = _lodash2['default'].isUndefined(response) ? {} : _storesTreeview_store2['default'].get(parent);
			_this2.setState({
				children: children,
				isopen: isopen
			});
			_storesTreeview_store2['default'].setLoadingState(false);
		})['catch'](function (message) {
			throw new Error(message);
			_storesTreeview_store2['default'].setLoadingState(false);
		});
	};

	ModelTreeItem.prototype.render = function render() {
		var _this3 = this;

		var lang = hiabconfig.explodedViews.lang;
		var machineItems = null;
		var children = null;
		var url = null;
		var code = '';
		var illustrationId = '';
		var classes = null;
		var expand = '';
		var number = 0;

		var viewUrl = hiabconfig.explodedViews.explodedViewsURL;
		if (hiabconfig.hasEquipmentTypeRestriction) {
			viewUrl = hiabconfig.explodedViews.searchDrawingsPageUrl;
		}

		if (this.props.isMachine) {
			(function () {
				var machineUrl = viewUrl + _this3.props.model + '/';

				machineItems = _this3.props.sectionChildren.map(function (childnode) {
					var isActive = childnode.IllustrationLink !== '00000000-0000-0000-0000-000000000000';
					var description = childnode.Description ? ' - ' + childnode.Description : '';
					var keyId = 'key-' + childnode.Id;
					var linkClass = _classnames2['default']({
						'link': true,
						'machine-link': true,
						'inactive': !isActive
					});
					return _react2['default'].createElement(
						'li',
						{ key: keyId, 'data-node-id': childnode.Id },
						_react2['default'].createElement(
							'div',
							null,
							isActive ? _react2['default'].createElement(
								_reactRouter.Link,
								{ 'data-node-id': childnode.Id, className: 'link machine-link', onClick: _this3.handleClick.bind(_this3), to: machineUrl + childnode.Id + '/' + childnode.IllustrationLink },
								childnode.ModelCode,
								description
							) : _react2['default'].createElement(
								'span',
								{ className: linkClass },
								childnode.ModelCode,
								description,
								_react2['default'].createElement(
									'i',
									null,
									' - ',
									lang.inactiveNode
								)
							)
						)
					);
				});
			})();
		} else {
			children = this.state.children.data.map(function (childnode) {
				var modelTreeItemProps = {
					key: childnode.Id,
					node: childnode,
					model: _this3.props.model,
					onSelectNode: _this3.props.onSelectNode,
					selectedNodeId: _this3.props.selectedNodeId,
					illustration: _this3.props.illustration,
					documents: childnode.Documents.map(function (documentNode) {
						var id = number++ + "-" + documentNode.Description;
						return _react2['default'].createElement(
							'li',
							{ key: id, className: 'document', 'data-node-id': id },
							_react2['default'].createElement(
								'div',
								null,
								_react2['default'].createElement(
									'a',
									{ 'data-node-id': id, href: documentNode.DocumentLink, target: '_blank', className: 'link' },
									_react2['default'].createElement('i', { className: 'icon-doc' }),
									documentNode.Description
								)
							)
						);
					})
				};

				return _react2['default'].createElement(ModelTreeItem, modelTreeItemProps);
			});

			this.updateSelectedNodeOnBackClick(this);

			if (this.props.node.IllustrationLink && this.props.node.IllustrationLink !== '00000000-0000-0000-0000-000000000000') {
				code = this.props.node.NodeType.toString() === '0' ? this.props.node.IllustrationCode + ' ' : '';
				illustrationId = this.props.node.IllustrationLink;
			}

			classes = _classnames2['default']({
				'has-children': true,
				'is-open': this.state.isopen,
				'is-selected': this.props.selectedNodeId === this || this.props.selectedNodeId === this.props.node.Id || this.props.selectedNodeId === illustrationId
			});
			if (!this.props.node.IsLeaf || this.props.node.Documents) {
				expand = _react2['default'].createElement(
					'a',
					{ className: 'expand', href: '#', onClick: this.toggleExpand.bind(this) },
					_react2['default'].createElement('i', { className: 'icon-angle-down' })
				);
			}

			url = viewUrl + this.props.model + (this.props.node.Id ? '/' + this.props.node.Id : '') + (illustrationId ? '/' + illustrationId : '');
		}

		return _react2['default'].createElement(
			'div',
			null,
			this.props.isMachine ? machineItems : _react2['default'].createElement(
				'li',
				{ className: classes, 'data-node-id': this.props.node.Id },
				_react2['default'].createElement(
					'div',
					null,
					_react2['default'].createElement(
						_reactRouter.Link,
						{ 'data-node-id': this.props.node.Id, className: 'link', onClick: this.handleClick.bind(this), to: url },
						code,
						this.props.node.Description
					),
					expand
				),
				_react2['default'].createElement(
					'ul',
					null,
					this.props.documents,
					children
				)
			)
		);
	};

	return ModelTreeItem;
})(_react2['default'].Component);

;

exports['default'] = ModelTreeItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_api/treeview_api":661,"../../_stores/illustration_store":718,"../../_stores/treeview_store":731,"classnames":299,"lodash":333,"react":525,"react-router":381}],787:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _actionsTreeview_actions = require('../../_actions/treeview_actions');

var _actionsTreeview_actions2 = _interopRequireDefault(_actionsTreeview_actions);

var _storesTreeview_store = require('../../_stores/treeview_store');

var _storesTreeview_store2 = _interopRequireDefault(_storesTreeview_store);

var _apiTreeview_api = require('../../_api/treeview_api');

var _apiTreeview_api2 = _interopRequireDefault(_apiTreeview_api);

var _storesModel_tree_search_store = require('../../_stores/model_tree_search_store');

var _storesModel_tree_search_store2 = _interopRequireDefault(_storesModel_tree_search_store);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var doneTypingInterval = 300;

var ModelTreeSearch = (function (_React$Component) {
	_inherits(ModelTreeSearch, _React$Component);

	function ModelTreeSearch(props) {
		var _this = this;

		_classCallCheck(this, ModelTreeSearch);

		_React$Component.call(this, props);

		this.handleSubmit = function (e) {
			e.preventDefault();
			_actionsTreeview_actions2['default'].searchNodesInModel(e.target.querySelector('input[type="text"]').value, _this.props.modelId, _this.props.isMachine);
			if (!_this.state.isLoading) {
				_this.setState({
					isLoading: true
				});
			}
		};

		this.handleClick = function (e) {
			e.preventDefault();
			var value = e.target.tagName === 'I' ? e.target.parentElement.form.querySelector('input[type="text"]').value : e.target.form.querySelector('input[type="text"]').value;
			_actionsTreeview_actions2['default'].searchNodesInModel(value, _this.props.modelId, _this.props.isMachine);
			if (!_this.state.isLoading) {
				_this.setState({
					isLoading: true
				});
			}
		};

		this.state = {
			isLoading: false
		};
		// this.props = {};
		this.typingTimer = null;
	}

	ModelTreeSearch.prototype.componentDidMount = function componentDidMount() {
		var _this2 = this;

		this.unsubscribe = _storesModel_tree_search_store2['default'].listen(function (res) {
			_this2.setState({
				isLoading: false
			});
		});
	};

	ModelTreeSearch.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	ModelTreeSearch.prototype.handleKeyup = function handleKeyup(e) {
		var _this3 = this;

		// e.preventDefault();
		if (this.typingTimer) clearTimeout(this.typingTimer);

		var value = e.target.value;
		this.typingTimer = setTimeout(function () {
			_this3.doneTyping(value);
		}, doneTypingInterval);
	};

	ModelTreeSearch.prototype.handleKeydown = function handleKeydown(e) {
		// e.preventDefault();
		if (this.typingTimer) clearTimeout(this.typingTimer);
	};

	ModelTreeSearch.prototype.doneTyping = function doneTyping(value) {
		_actionsTreeview_actions2['default'].searchNodesInModel(value, this.props.modelId, this.props.isMachine);
		_storesModel_tree_search_store2['default'].setSearchValue(value);
		if (!this.state.isLoading) {
			this.setState({
				isLoading: true
			});
		}
	};

	ModelTreeSearch.prototype.render = function render() {

		var buttonClass = _classnames2['default']({
			'button loading': this.state.isLoading,
			'button': !this.state.isLoading
		});

		return _react2['default'].createElement(
			'div',
			{ className: 'uc-model-tree-search' },
			_react2['default'].createElement(
				'form',
				{ action: '', method: 'get', onSubmit: this.handleSubmit.bind(this) },
				_react2['default'].createElement('input', { type: 'text', name: 'model-tree-search-text', onKeyUp: this.handleKeyup.bind(this), onKeyDown: this.handleKeydown.bind(this) }),
				_react2['default'].createElement(
					'button',
					{ className: buttonClass, type: 'submit', onClick: this.handleClick.bind(this) },
					_react2['default'].createElement('i', { className: 'icon-search', onClick: this.handleClick.bind(this) })
				)
			)
		);
	};

	return ModelTreeSearch;
})(_react2['default'].Component);

;
exports['default'] = ModelTreeSearch;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../../_actions/treeview_actions":648,"../../_api/treeview_api":661,"../../_stores/model_tree_search_store":720,"../../_stores/treeview_store":731,"classnames":299,"react":525}],788:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _wishlistHeader = require('./wishlistHeader');

var _wishlistHeader2 = _interopRequireDefault(_wishlistHeader);

var _notificationsMessageInjector = require('./../../notifications/messageInjector');

var _notificationsMessageInjector2 = _interopRequireDefault(_notificationsMessageInjector);

var invokingElement = null;
var wishlistLineitems = [];
var mobileWishlistToggle = _jquery2['default']('.show-for-medium-down .wishlist-toggle');

var LineitemHandler = {
	init: function init() {
		//handle add line item on product detail page
		_jquery2['default'](document).on('click', 'button.saved-cart-add', function (e) {
			if (_wishlistHeader2['default'].GetSelectedWishlistData() == null) {
				_jquery2['default']('#wishlistControlls').addClass('is-open');
				_jquery2['default']('.drawer-main .drawer-right').addClass('wishlist-active');
				var wishlistsExists = _jquery2['default']('#wishlistSelect .menu .item').length > 0;
				if (!wishlistsExists) {
					_jquery2['default']('.wishlist-manage').hide();
					_jquery2['default']('.wishlist-create').show();
				}
			}

			invokingElement = _jquery2['default'](e.currentTarget);
			wishlistLineitems = [];
			var code = invokingElement.data('product-sku');
			var quantity = _jquery2['default'](".amount[data-product-sku='" + code + "']").val();
			var cost = _jquery2['default'](".amount[data-product-sku='" + code + "']").data('product-cost');

			var item = {
				Code: code,
				Quantity: quantity,
				Cost: cost
			};
			wishlistLineitems.push(item);

			if (_wishlistHeader2['default'].GetSelectedWishlistData() == null) return;
			LineitemHandler.AddToWishlist();
		});

		//handle add line item on batchorder page
		_jquery2['default'](document).on('click', 'button.batch-saved-cart-add', function (e) {
			if (_wishlistHeader2['default'].GetSelectedWishlistData() == null) {
				_jquery2['default']('#wishlistControlls').addClass('is-open');
				_jquery2['default']('.drawer-main .drawer-right').addClass('wishlist-active');
				var wishlistsExists = _jquery2['default']('#wishlistSelect .menu .item').length > 0;
				if (!wishlistsExists) {
					_jquery2['default']('.wishlist-manage').hide();
					_jquery2['default']('.wishlist-create').show();
				}
			}

			invokingElement = _jquery2['default'](e.currentTarget);
			wishlistLineitems = [];

			_jquery2['default']('div#line-items .row input.quantity').each(function () {
				var currentRow = _jquery2['default'](this);
				var code = currentRow.data('line-item');
				var cost = currentRow.data('product-cost');
				console.log(cost);
				var quantity = currentRow.val();
				var item = {
					Code: code,
					Quantity: quantity,
					Cost: cost
				};
				wishlistLineitems.push(item);
			});

			if (_wishlistHeader2['default'].GetSelectedWishlistData() == null) return;
			LineitemHandler.AddToWishlist(BatchSuccessCallback);
		});

		function BatchSuccessCallback() {
			if (_jquery2['default']('.fileupload-messages').length > 0) {
				var text = hiabconfig.wishlist.addedItemToWishlist;
				var html = "<p>" + text + "</p>";
				_jquery2['default']('#add-to-cart-success .uc-message.success').html(html);
				_jquery2['default']('#add-to-cart-success').show();
				_jquery2['default']('#remove-all-lines').click();
			}
		}
	},
	AddToWishlist: function AddToWishlist() {
		var successCallback = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];

		if (invokingElement == null && wishlistLineitems.length == 0) return;

		var url = "/api/wishlist/AddLineitemToWishlist?preferredCulture=" + hiabconfig.preferredCulture;
		var headerBtn = _jquery2['default']('.uc-wishlist.wishlist-header button');
		var headerControllsBtn = _jquery2['default']('#wishlistControlls button');
		var headerBtnHtml = headerBtn.html();
		var nrItemsAdded = wishlistLineitems.length;
		_jquery2['default']('#wishlistControlls').addClass('loading');
		mobileWishlistToggle.attr('disabled', true);
		mobileWishlistToggle.addClass('loading');
		headerBtn.html(_wishlistHeader2['default'].GetLoadSpinnerHtml());
		headerBtn.attr('disabled', true);
		headerBtn.addClass('adding');

		mobileWishlistToggle.attr('disabled', true);
		mobileWishlistToggle.addClass('loading');

		headerControllsBtn.attr('disabled', true);
		invokingElement.attr('disabled', true);

		_jquery2['default'].ajax({
			type: "POST",
			contentType: "application/json; charset=utf-8",
			url: url,
			data: JSON.stringify(wishlistLineitems),
			dataType: "json",
			success: function success(response) {
				if (response.SelectedWishList == null) {
					headerBtn.html(headerBtnHtml);
					_jquery2['default']('.off-canvas-wrap').foundation('offcanvas', 'show', 'move-left');
				} else {
					_wishlistHeader2['default'].RedrawAll(response);
					var html = "<span class='lineitem-added'>" + " +" + nrItemsAdded + "</span>";
					_notificationsMessageInjector2['default'].InsertAfter(html, '.uc-wishlist.wishlist-header button span');
					_jquery2['default']('#wishlistControlls').removeClass('loading');
					_notificationsMessageInjector2['default'].InsertAfter(html, '#wishlistSelect .text');

					if (successCallback != null) {
						successCallback();
					}
				}
				invokingElement.attr('disabled', false);
				invokingElement = null;
				wishlistLineitems = [];
			},
			error: function error() {

				_jquery2['default']('#wishlistControlls').removeClass('loading');
				headerBtn.attr('disabled', false);
				headerControllsBtn.attr('disabled', false);
				invokingElement.attr('disabled', false);

				mobileWishlistToggle.attr('disabled', false);
				mobileWishlistToggle.removeClass('loading');

				invokingElement = null;
				wishlistLineitems = [];

				var errorHtml = "<span>" + hiabconfig.wishlist.addItemError + "</span>";
				_jquery2['default']('.right-off-canvas-toggle').trigger('click');
				_notificationsMessageInjector2['default'].InsertAfter(errorHtml, '#wishlistSelect');
				console.log("could not add lineitem to wishlist");
			}
		});
	}
};

exports['default'] = LineitemHandler;
module.exports = exports['default'];

},{"./../../notifications/messageInjector":804,"./wishlistHeader":790,"jquery":628}],789:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _wishlistHeader = require('./wishlistHeader');

var _wishlistHeader2 = _interopRequireDefault(_wishlistHeader);

var _notificationsMessageInjector = require('./../../notifications/messageInjector');

var _notificationsMessageInjector2 = _interopRequireDefault(_notificationsMessageInjector);

var _miscellaneousUrlHandler = require('./../miscellaneous/urlHandler');

var _miscellaneousUrlHandler2 = _interopRequireDefault(_miscellaneousUrlHandler);

var _vendorsFoundation = require('./../../vendors/foundation');

var _vendorsFoundation2 = _interopRequireDefault(_vendorsFoundation);

var currentWishlistID = null;
var currentValue = null;
var inputTimer = undefined;
var defaultTimerDelay = 3000;
var isEditingCart = false;

var WishlistDetails = {

	//disables ui controls
	DisableUIControls: function DisableUIControls() {
		_jquery2['default']('.ui-control').attr('disabled', true);
	},

	isInt: function isInt(value) {
		var x;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === 1 ? false : true;
		} else {
			return false;
		}
	},

	//enables ui controls
	EnableUIControls: function EnableUIControls() {
		_jquery2['default']('.ui-control').attr('disabled', false);
		var hasLineItems = _jquery2['default']('#saved-cart tbody').html().length > 0;
		if (!hasLineItems) {
			_jquery2['default']('button.purchase').attr('disabled', true);
			_jquery2['default']('button.print').attr('disabled', true);
		}
		_vendorsFoundation2['default'].init();
		_jquery2['default'](document).foundation('abide', 'reflow');

		if (_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table tbody').children().length > 21) {
			_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table').addClass('has-more');
			if (isEditingCart) {
				_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table').addClass('is-open');
			}
		} else {
			_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table').removeClass('has-more');
		}
	},

	RedrawButtons: function RedrawButtons() {
		var url = "GetButtonsPartial?id=" + currentWishlistID + '&preferredCulture=' + hiabconfig.preferredCulture;
		_jquery2['default']('.wishlist-detail .button-group').load(url);
	},

	SelectWishlist: function SelectWishlist(ev) {
		WishlistDetails.DisableUIControls();

		var htmlContainer = _jquery2['default'](ev.currentTarget).parents('section');
		var data = { preferredCulture: hiabconfig.preferredCulture };
		var url = "SelectWishlist?id=" + currentWishlistID;
		htmlContainer.load(url, data, function () {
			WishlistDetails.EnableUIControls();
			_wishlistHeader2['default'].LoadWishlistInfo();
			_jquery2['default']('.wishlist-detail button.select').attr('disabled', true);
		});
	},

	//redraw input fields
	RedrawInputFields: function RedrawInputFields() {
		var url = "RedrawInputFields?id=" + currentWishlistID + '&preferredCulture=' + hiabconfig.preferredCulture;
		_jquery2['default']('.wishlist-detail #CartFormName').load(url, null, function () {});
	},

	//updates info partial from server
	UpdateAdditionalInfo: function UpdateAdditionalInfo() {
		var url = "GetAdditionalInfoPartial?id=" + currentWishlistID + '&preferredCulture=' + hiabconfig.preferredCulture;
		_jquery2['default']('.wishlist-detail .information-form div.additional').load(url, null, function () {});
	},

	GetWishlistLineitemByID: function GetWishlistLineitemByID(id) {
		var item = _jquery2['default']('.uc-table tbody tr').filter(function () {
			return _jquery2['default'](this).data('line-id') == id;
		});
		// console.log(item);
		return item;
	},

	HandleInputChange: function HandleInputChange(value, type, id) {
		var _this = this;

		if (!currentValue) return;

		clearTimeout(inputTimer);
		currentValue = null;

		if (type == 'quantity') {
			(function () {
				WishlistDetails.DisableUIControls();
				var url = "UpdateLineitem?id=" + currentWishlistID;
				var lineitem = _this.GetWishlistLineitemByID(id);
				var itemPrice = _jquery2['default'](lineitem).find('input').data('product-cost');
				var data = { id: id, quantity: value, price: itemPrice, preferredCulture: hiabconfig.preferredCulture };

				_jquery2['default'].ajax({
					type: "POST",
					url: url,
					data: data,
					dataType: 'json',
					success: function success(response) {
						// console.log(response);
						lineitem.find('.item-total').html(response.Total);
						WishlistDetails.UpdateAdditionalInfo();
						WishlistDetails.EnableUIControls();
					},
					error: function error() {
						WishlistDetails.UpdateAdditionalInfo();
						console.log("could not update line item");
					}
				});
			})();
		}

		if (type == 'cartName') {
			WishlistDetails.DisableUIControls();
			var url = "SaveName?id=" + currentWishlistID;
			var data = { input: value, preferredCulture: hiabconfig.preferredCulture };
			_jquery2['default']('.wishlist-detail #CartFormName').load(url, data, function () {
				_wishlistHeader2['default'].LoadWishlistInfo();
				var html = "<span>" + hiabconfig.wishlist.savedUpdateWishlist + "</span>";
				_notificationsMessageInjector2['default'].InsertAfter(html, 'input[name="NewCart.Name"]');
				WishlistDetails.UpdateAdditionalInfo();
				WishlistDetails.EnableUIControls();
			});
		}

		if (type == 'cartDesc') {
			WishlistDetails.DisableUIControls();
			var url = "SaveDescription?id=" + currentWishlistID;
			var data = { input: value, preferredCulture: hiabconfig.preferredCulture };
			_jquery2['default']('.wishlist-detail #CartFormName').load(url, data, function () {
				_wishlistHeader2['default'].LoadWishlistInfo();
				var html = "<span>" + hiabconfig.wishlist.savedUpdateWishlist + "</span>";
				_notificationsMessageInjector2['default'].InsertAfter(html, 'input[name="NewCart.Desc"]');
				WishlistDetails.UpdateAdditionalInfo();
				WishlistDetails.EnableUIControls();
			});
		}
	},

	init: function init() {
		if (_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table tbody').children().length > 21) {
			_jquery2['default']('.uc-wishlist.uc-checkout-cart .uc-table').addClass('has-more');
		}
		var purchaseBtn = _jquery2['default']('.uc-wishlist.wishlist-detail .button-group button.purchase');
		purchaseBtn.removeClass('loading');

		//adds btns to confirm or cancel cart delete
		function InjectOkCancelButtons() {
			var okBtn = "<button class='ok right sml'>" + hiabconfig.wishlist.btnTextOk + "</button>";
			var cancelBtn = "<button class='cancel right sml' name='Wishlist.Cancel'>" + hiabconfig.wishlist.btnTextCancel + "</button>";
			var deleteBtn = _jquery2['default']('button.delete').hide();
			_jquery2['default'](okBtn).insertAfter(deleteBtn);
			_jquery2['default'](cancelBtn).insertAfter(deleteBtn);
		};

		//handles purchase btn click
		_jquery2['default'](document).on('click', 'button.purchase', function () {
			var btn = _jquery2['default']('.uc-wishlist.wishlist-detail .button-group button.purchase');
			btn.addClass('loading');

			WishlistDetails.DisableUIControls();
			var url = "PurchaseWishlist?id=" + currentWishlistID;
			var data = { preferredCulture: hiabconfig.preferredCulture };

			_jquery2['default'].ajax({
				type: "POST",
				url: url,
				data: data,
				dataType: 'json',
				success: function success(response) {
					btn.removeClass('loading');
					window.location.href = response.Url;
				},
				error: function error() {
					WishlistDetails.EnableUIControls();
					btn.removeClass('loading');
				}
			});
		});

		//handles select btn click
		_jquery2['default'](document).on('click', 'button.select', function (ev) {
			WishlistDetails.SelectWishlist(ev);
		});

		//handles delete ok btn click
		_jquery2['default'](document).on('click', '.wishlist-detail button.ok', function () {
			WishlistDetails.DisableUIControls();

			var url = "DeleteWishlist?id=" + currentWishlistID;
			var data = { preferredCulture: hiabconfig.preferredCulture };

			_jquery2['default'].ajax({
				type: "POST",
				url: url,
				data: data,
				dataType: 'json',
				success: function success(response) {
					window.location.href = response.Url;
				},
				error: function error() {
					WishlistDetails.EnableUIControls();
				}
			});
		});

		//handles delete cancel btn click
		_jquery2['default'](document).on('click', 'button[name="Wishlist.Cancel"]', function () {
			WishlistDetails.RedrawButtons();
		});

		//handles delete btn click
		_jquery2['default'](document).on('click', 'button.delete', function () {
			InjectOkCancelButtons();
		});

		//auto save name when updated
		_jquery2['default'](document).on('focus blur keypress', 'input[name="NewCart.Name"]', function (e) {
			var el = _jquery2['default'](e.currentTarget);
			var inputText = el.val();

			if (inputText.length > 0) {
				if (typeof inputTimer !== "undefined") {
					clearTimeout(inputTimer);
				}

				if (e.type === 'focusin') {
					currentValue = inputText;
				}

				if (e.type === 'focusout' && currentValue != inputText) {
					WishlistDetails.HandleInputChange(inputText, 'cartName');
				}

				if (e.type === 'keypress' && e.which === 13 && currentValue && currentValue != inputText) {
					WishlistDetails.HandleInputChange(inputText, 'cartName');
				}

				if (e.type === 'keypress' && currentValue != inputText) {
					inputTimer = setTimeout(function () {
						WishlistDetails.HandleInputChange(_jquery2['default'](e.currentTarget).val(), 'cartName');
					}, defaultTimerDelay);
				}
			}
		});

		_jquery2['default'](document).on('focus blur keypress', 'input[name="NewCart.Desc"]', function (e) {
			var el = _jquery2['default'](e.currentTarget);
			var inputText = el.val();
			if (typeof inputTimer !== "undefined") {
				clearTimeout(inputTimer);
			}

			if (e.type === 'focusin') {
				currentValue = inputText;
				if (inputText.length == 0) {
					currentValue = " ";
				}
			}

			if (e.type === 'focusout' && currentValue != inputText) {
				WishlistDetails.HandleInputChange(inputText, 'cartDesc');
			}
			if (e.type === 'keypress' && e.which === 13 && currentValue && currentValue != inputText) {
				WishlistDetails.HandleInputChange(inputText, 'cartDesc');
				return;
			}
			if (e.type === 'keypress' && currentValue != inputText) {
				inputTimer = setTimeout(function () {
					WishlistDetails.HandleInputChange(_jquery2['default'](e.currentTarget).val(), 'cartDesc');
				}, defaultTimerDelay);
			}
		});

		_jquery2['default'](document).on('focus blur keypress enterKey', '.uc-checkout-cart.uc-wishlist input[name="quantity"]', function (e) {
			var el = _jquery2['default'](e.currentTarget);
			var inputText = el.val();
			var id = el.data('sku-id');
			isEditingCart = true;

			if (WishlistDetails.isInt(inputText)) {
				if (typeof inputTimer !== "undefined") {
					clearTimeout(inputTimer);
				}
				if (e.type === 'focusin') {
					currentValue = inputText;
				}
				if (e.type === 'focusout' && currentValue != inputText) {
					WishlistDetails.HandleInputChange(inputText, 'quantity', id);
				}
				if (e.type === 'keypress' && e.which === 13 && currentValue && currentValue != inputText) {
					WishlistDetails.HandleInputChange(inputText, 'quantity', id);
					return;
				}
				if (e.type === 'keypress' && currentValue != inputText) {
					inputTimer = setTimeout(function () {
						WishlistDetails.HandleInputChange(_jquery2['default'](e.currentTarget).val(), 'quantity', id);
					}, defaultTimerDelay);
				}
			}
		});

		//handle delete btn click on lineitem
		_jquery2['default'](document).on('click', 'button.remove-button', function (e) {
			WishlistDetails.DisableUIControls();

			var el = _jquery2['default'](e.currentTarget);
			var id = el.data('sku-id');
			var url = "DeleteLineitem?id=" + currentWishlistID;
			var data = { id: id, preferredCulture: hiabconfig.preferredCulture };
			isEditingCart = true;

			_jquery2['default'].ajax({
				type: "POST",
				url: url,
				data: data,
				dataType: 'json',
				success: function success(response) {
					// console.log(response);
					var lineitemRow = el.parents('tr');
					//get variant html..
					if (lineitemRow.hasClass('table-sub-data')) {
						lineitemRow.prev().remove(); //removes desktop html
					}
					if (lineitemRow.hasClass('lineitem')) {
						lineitemRow.next().remove(); //removes mobile html
					}
					lineitemRow.remove();
					var itemCount = _jquery2['default']('#saved-cart tr.lineitem').length;
					_jquery2['default']('.wishlist-detail .lineitems span:first-of-type').html(itemCount);
					UpdateLineitemRowCount();

					_wishlistHeader2['default'].LoadWishlistInfo();
					WishlistDetails.UpdateAdditionalInfo();
					WishlistDetails.EnableUIControls();
				},
				error: function error() {
					WishlistDetails.UpdateAdditionalInfo();
					console.log("could not remove line item");
				}
			});
		});

		function UpdateLineitemRowCount() {
			var rows = _jquery2['default']('#saved-cart tr.lineitem td:first-of-type span');
			var rowsMobile = _jquery2['default']('#saved-cart tr.table-sub-data td:first-of-type span');
			var rowCount = 1;
			rows.each(function () {
				_jquery2['default'](this).html(rowCount);
				rowCount += 1;
			});
			rowCount = 1;
			rowsMobile.each(function () {
				_jquery2['default'](this).html(rowCount);
				rowCount += 1;
			});
		}

		//get wishlist id from url on page load
		_jquery2['default'](function () {
			currentWishlistID = _miscellaneousUrlHandler2['default'].GetParameterByString("id");
		});
	}
};

exports['default'] = WishlistDetails;
module.exports = exports['default'];

},{"./../../notifications/messageInjector":804,"./../../vendors/foundation":829,"./../miscellaneous/urlHandler":777,"./wishlistHeader":790,"jquery":628}],790:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _vendorsFoundation = require('./../../vendors/foundation');

var _vendorsFoundation2 = _interopRequireDefault(_vendorsFoundation);

var _lineitemHandler = require('./lineitemHandler');

var _lineitemHandler2 = _interopRequireDefault(_lineitemHandler);

var _notificationsMessageInjector = require('./../../notifications/messageInjector');

var _notificationsMessageInjector2 = _interopRequireDefault(_notificationsMessageInjector);

var _wishlistDetail = require('./wishlistDetail');

var _wishlistDetail2 = _interopRequireDefault(_wishlistDetail);

var _wishlistListing = require('./wishlistListing');

var _wishlistListing2 = _interopRequireDefault(_wishlistListing);

var selectedWishlistData = null;
var mobileWishlistToggle = _jquery2['default']('.show-for-medium-down .wishlist-toggle');

var WishlistHeader = {
	GetSelectedWishlistData: function GetSelectedWishlistData() {
		return selectedWishlistData;
	},

	GetLoadSpinnerHtml: function GetLoadSpinnerHtml() {
		return "<i class='animate-spin icon-spin4'></i>";
	},

	//reloads html
	RedrawAll: function RedrawAll(response) {

		mobileWishlistToggle.attr('disabled', false);
		mobileWishlistToggle.removeClass('loading');

		WishlistHeader.HandleHeaderInfo(response);
		_jquery2['default']('.drawer-right .uc-wishlist').html(response.OffCanvas);
		WishlistHeader.SetupWishlistDropdown();
		_vendorsFoundation2['default'].init();
		_jquery2['default'](document).foundation('abide', 'reflow');
	},

	//outputs selected wishlist info in header controls
	HandleHeaderInfo: function HandleHeaderInfo(response) {
		_jquery2['default']('.uc-wishlist.wishlist-header.show-for-large-up').replaceWith(response.HeaderButtonLargeUp);
		_jquery2['default']('.uc-wishlist.wishlist-header.show-for-medium-up').replaceWith(response.HeaderButtonMediumUp);
		_jquery2['default']('.uc-wishlist.wishlist-header.show-for-small-only').replaceWith(response.HeaderButtonSmallOnly);

		var selectedCartInfo = response.SelectedWishList;
		if (selectedCartInfo != null && selectedCartInfo.Name.length > 0) {
			var selectedCartText = selectedCartInfo.Name + " - " + selectedCartInfo.LineItems.length + " " + hiabconfig.wishlist.nrLineitems;
			var newHtml = "<span>" + selectedCartText + "</span>";
			_jquery2['default']('.wishlist-header.sticky').html(newHtml);
			_jquery2['default']('.wishlist-header.sticky').removeClass('wishlist-empty').addClass('wishlist-selected');
			_jquery2['default']('.saved-cart-add').removeClass('right-off-canvas-toggle');
			_jquery2['default']('.batch-saved-cart-add').removeClass('right-off-canvas-toggle');
			_jquery2['default']('#controll-wishlist button span').hide();
			_jquery2['default']('.siteheader-main-right .wishlist-toggle span').hide();
			_jquery2['default']('#controll-wishlist').addClass('wishlist-selected');
			_jquery2['default']('.uc-scrollcontrols-sticky').addClass('wishlist-selected');

			if (_jquery2['default']('.uc-scrollcontrols-sticky').css('display') == 'block') {
				//Change position top for product-summary-sticky to avoid displaying underneith wishlist-header.
				_jquery2['default']('body').addClass("wishlist-header-is-visible");
			} else {
				_jquery2['default']('body').removeClass("wishlist-header-is-visible");
			}
		} else {
			var numberofwishlist = _jquery2['default']('.wishlist-header.show-for-large-up button span').attr('data-numberofwishlist');
			_jquery2['default']('.wishlist-header.wishlist-selected.sticky').removeClass('wishlist-selected').addClass('wishlist-empty').empty();
			_jquery2['default']('.saved-cart-add').addClass('right-off-canvas-toggle');
			_jquery2['default']('.batch-saved-cart-add').addClass('right-off-canvas-toggle');
			_jquery2['default']('#controll-wishlist').removeClass('wishlist-selected');
			_jquery2['default']('.uc-scrollcontrols-sticky').removeClass('wishlist-selected');
			_jquery2['default']('#controll-wishlist button span').show().html(numberofwishlist);
			_jquery2['default']('.siteheader-main-right .wishlist-toggle span').show().html(numberofwishlist);

			if (_jquery2['default']('.uc-scrollcontrols-sticky').css('display') == 'none') {
				//Change position top for product-summary-sticky to avoid displaying underneith wishlist-header.
				_jquery2['default']('body').removeClass("wishlist-header-is-visible");
			}
		}
	},

	//offmenu canvas wishlist changed
	SetupWishlistDropdown: function SetupWishlistDropdown() {
		var dropdownSettings = {
			fullTextSearch: 'exact',
			match: 'text',
			minCharacters: 3,
			forceSelection: false,
			selectOnKeydown: false,
			// action: 'select',
			message: {
				noResults: hiabconfig.wishlist.noSavedWishlists
			}
		};
		var dd = _jquery2['default']('#wishlistSelect');
		dd.dropdown('refresh');

		dd.dropdown({
			dropdownSettings: dropdownSettings,
			onChange: function onChange(value, text, $choice) {
				WishlistHeader.SelectWishlist(value);
			}
		});
	},

	SelectWishlist: function SelectWishlist(value) {
		var url = "/api/wishlist/SelectWishlist";
		var data = { name: value, preferredCulture: hiabconfig.preferredCulture };
		_jquery2['default']('button.purchase').attr('disabled', true);

		mobileWishlistToggle.attr('disabled', true);
		mobileWishlistToggle.addClass('loading');

		_jquery2['default'].ajax({
			type: "GET",
			url: url,
			data: data,
			dataType: 'json',
			success: function success(response) {
				selectedWishlistData = response.SelectedWishList;
				_wishlistDetail2['default'].RedrawButtons();
				WishlistHeader.RedrawAll(response);
				_jquery2['default']('.saved-cart-add').removeClass('right-off-canvas-toggle');
				_lineitemHandler2['default'].AddToWishlist();
				var headerBtn = _jquery2['default']('.uc-wishlist.wishlist-header button');
				if (headerBtn.hasClass('adding')) {
					_jquery2['default']('.close-off-canvas').trigger('click');
				}
			},
			error: function error() {
				console.log("error fetching wishlist info");
			}
		});
	},

	LoadWishlistInfo: function LoadWishlistInfo() {

		mobileWishlistToggle.attr('disabled', true);
		mobileWishlistToggle.addClass('loading');

		var url = "/api/wishlist/GetAllWishlists";
		var data = { preferredCulture: hiabconfig.preferredCulture };
		_jquery2['default'].ajax({
			type: "GET",
			url: url,
			dataType: 'json',
			data: data,
			success: function success(response) {
				selectedWishlistData = response.SelectedWishList;
				WishlistHeader.RedrawAll(response);
				_jquery2['default']('button.button.wishlist').attr('disabled', false);
				if (selectedWishlistData == null) {
					_jquery2['default']('button.button.wishlist').addClass('right-off-canvas-toggle');
				}
			},
			error: function error() {
				console.log("error fetching wishlist info for header");
			}
		});
	},

	init: function init() {
		//toggles visibility, clears inputs, resets validation
		function ResetUIControls() {
			_jquery2['default']('.wishlist-manage').show();
			_jquery2['default']('.wishlist-create').hide();
			_jquery2['default']('.wishlist-create input[name="name"]').val("");
			_jquery2['default']('.wishlist-create input[name="desc"]').val("");
			_jquery2['default']('#NewCartForm-OffCanvas .input-wrapper').removeClass('error');
			_jquery2['default']('.wishlist-create button[name="Wishlist.Save"]').attr('disabled', false);
		}

		//enables wishlist on off-canvas
		_jquery2['default'](document).on('click', '.wishlist-toggle', function () {
			_jquery2['default']('.drawer-main .drawer-right').addClass('wishlist-active');
			//show create controls if no wishlist available
			var wishlistsExists = _jquery2['default']('#wishlistSelect .menu .item').length > 0;
			if (!wishlistsExists) {
				_jquery2['default']('.wishlist-manage').hide();
				_jquery2['default']('.wishlist-create').show();
			}
		});

		_jquery2['default'](document).on('click', '.close-off-canvas', function () {
			_jquery2['default']('#wishlistHeaderContainer').removeClass('is-open');
			ResetUIControls();
			setTimeout(function () {
				_jquery2['default']('.drawer-main .drawer-right').removeClass('wishlist-active');
			}, 300);
		});

		//hack for validating required input (because abide sucks)
		_jquery2['default']('body').on('blur change keypress', '#NewCartForm-OffCanvas input[required]', function (e) {
			var input = _jquery2['default'](e.currentTarget);
			if (input.val().length == 0) {
				input.closest('.input-wrapper').addClass('error');
				_jquery2['default']('.wishlist-create button[name="Wishlist.Save"]').attr('disabled', true);
			} else {
				input.closest('.input-wrapper').removeClass('error');
				_jquery2['default']('.wishlist-create button[name="Wishlist.Save"]').attr('disabled', false);
			}
		});

		//use service to merge carts
		//then redirect to url checkout
		_jquery2['default'](document).on('click', '.wishlist-manage button.purchase', function () {

			var btn = _jquery2['default']('.wishlist-manage button.purchase');

			var id = selectedWishlistData.Id;
			var url = "/api/wishlist/PurchaseWishlist";
			var data = { wishlistName: id, preferredCulture: hiabconfig.preferredCulture };

			btn.addClass('loading');

			_jquery2['default'].ajax({
				type: "GET",
				url: url,
				data: data,
				dataType: 'json',
				success: function success(response) {
					btn.removeClass('loading');
					if (response.Error.length == 0) window.location.href = hiabconfig.checkout.apiBaseUrl;
				},
				error: function error() {
					btn.removeClass('loading');
				}
			});
		});

		//shows controls for creating
		_jquery2['default'](document).on('click', '.wishlist-manage button.create', function () {
			_jquery2['default']('.wishlist-create input[name="name"]').val("");
			_jquery2['default']('.wishlist-create input[name="desc"]').val("");
			_jquery2['default']('.wishlist-manage').hide();
			_jquery2['default']('.wishlist-create').show();
		});

		_jquery2['default'](document).on('click', '.wishlist-create button[name="Wishlist.Save"]', function (e) {
			e.preventDefault();

			Foundation.libs.abide.validate(_jquery2['default']('#NewCartForm-OffCanvas').find('input'), { type: '' });

			var name = _jquery2['default']('.wishlist-create input[name="name"]').val();
			var desc = _jquery2['default']('.wishlist-create input[name="desc"]').val();

			var noError = _jquery2['default']('#NewCartForm-OffCanvas .input-wrapper.error').length === 0;
			var hasLength = name.length > 0;

			if (noError && hasLength) {
				var id = null;
				var url = "/api/wishlist/CreateOrUpdateWishlist";
				var data = { id: id, name: name, desc: desc, preferredCulture: hiabconfig.preferredCulture };

				_jquery2['default']('.wishlist-create button').attr('disabled', true);
				_jquery2['default'].ajax({
					type: "GET",
					url: url,
					data: data,
					dataType: 'json',
					success: function success(response) {
						selectedWishlistData = response.SelectedWishList;
						WishlistHeader.RedrawAll(response);
						_wishlistDetail2['default'].RedrawInputFields();
						_wishlistListing2['default'].RedrawListing(selectedWishlistData.Id); //new value!
						var html = "<span>" + hiabconfig.wishlist.savedWishlist + "</span>";
						_notificationsMessageInjector2['default'].InsertAfter(html, '#wishlistSelect');
						if (_jquery2['default']('.uc-wishlist .uc-order-filters h4').length > 0) {
							_wishlistListing2['default'].RedrawWishlistCount();
							_wishlistListing2['default'].UpdatePagination();
						}
						_lineitemHandler2['default'].AddToWishlist();
						var headerBtn = _jquery2['default']('.uc-wishlist.wishlist-header button');
						if (headerBtn.hasClass('adding')) {
							_jquery2['default']('.close-off-canvas').trigger('click');
						}
					},
					error: function error() {
						console.log("error saving wishlist info");
					}
				});
			}
		});

		_jquery2['default'](document).on('click', '.wishlist-create button[name="Wishlist.Cancel"]', function (e) {
			e.preventDefault();
			ResetUIControls();
		});

		//load wishlist info async when page loaded
		_jquery2['default'](function () {
			WishlistHeader.LoadWishlistInfo();
			_lineitemHandler2['default'].init();
		});
	}
};

exports['default'] = WishlistHeader;
module.exports = exports['default'];

},{"./../../notifications/messageInjector":804,"./../../vendors/foundation":829,"./lineitemHandler":788,"./wishlistDetail":789,"./wishlistListing":791,"jquery":628}],791:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _wishlistHeader = require('./wishlistHeader');

var _wishlistHeader2 = _interopRequireDefault(_wishlistHeader);

var _notificationsMessageInjector = require('./../../notifications/messageInjector');

var _notificationsMessageInjector2 = _interopRequireDefault(_notificationsMessageInjector);

var _vendorsFoundation = require('./../../vendors/foundation');

var _vendorsFoundation2 = _interopRequireDefault(_vendorsFoundation);

var WishlistListing = {

    RedrawListing: function RedrawListing(id) {
        var url = "GetWishlistPartial?id=" + id + '&preferredCulture=' + hiabconfig.preferredCulture;
        _jquery2['default']('.uc-order-history-table').load(url);
    },

    RedrawWishlistCount: function RedrawWishlistCount() {
        var updateNumberUrl = "UpdateTotalWishlistNo" + '?preferredCulture=' + hiabconfig.preferredCulture;;
        _jquery2['default']('.uc-order-filters').load(updateNumberUrl);
    },

    UpdatePagination: function UpdatePagination() {
        var url = "UpdatePagination" + '?preferredCulture=' + hiabconfig.preferredCulture;;
        _jquery2['default']('.pagination-centered').load(url);
    },

    init: function init() {
        function ResetControls() {
            _jquery2['default']('#NewCartForm input[required]').val("");
            _jquery2['default']('input#description').val("");
            _jquery2['default']('#NewCartForm .input-wrapper').removeClass('error');
            _vendorsFoundation2['default'].init();
            _jquery2['default'](document).foundation('abide', 'reflow');
        };

        //cancel link navigation while list is loading
        _jquery2['default'](document).on('click', '.uc-order-history-table.loading a', function (e) {
            e.preventDefault();
            return 0;
        });

        //handle save btn click
        _jquery2['default']('#NewCartForm button[name="Wishlist.Save"]').click(function (e) {
            Foundation.libs.abide.validate(_jquery2['default']('#NewCartForm').find('input'), { type: '' });

            e.preventDefault();

            var inputName = _jquery2['default']('#NewCartForm input[name="NewCart.Name"]');
            var name = inputName.val();

            var inputDesc = _jquery2['default']('#NewCartForm input[name="NewCart.Desc"]');
            var description = inputDesc.val();

            var noError = _jquery2['default']('#NewCartForm .input-wrapper.error').length === 0;
            var hasLength = name.length > 0;

            if (noError && hasLength) {
                (function () {
                    _notificationsMessageInjector2['default'].Replace("<i class='animate-spin icon-spin4'></i>", ".msg-container");
                    var table = _jquery2['default']('.uc-order-history-table').addClass('loading');
                    table.find('button').attr('disabled', true);
                    var url = "CreateNewWishlist";
                    var data = { name: name, desc: description, preferredCulture: hiabconfig.preferredCulture };

                    _jquery2['default']('.uc-order-history-table').load(url, data, function () {
                        _wishlistHeader2['default'].LoadWishlistInfo();
                        WishlistListing.RedrawWishlistCount();
                        WishlistListing.UpdatePagination();
                        table.removeClass('loading');
                        table.find('button').attr('disabled', false);
                        var html = "<span>" + hiabconfig.wishlist.addedWishlist + "</span>";
                        _notificationsMessageInjector2['default'].Replace(html, ".msg-container");
                        ResetControls();
                    });
                })();
            }
        });

        //handle cancel btn click
        _jquery2['default']('#NewCartForm button[name="Wishlist.Cancel"]').click(function (e) {
            e.preventDefault();

            setTimeout(function () {
                ResetControls();
            }, 300);
        });

        //handle select cart click
        _jquery2['default'](document).on("click", '.uc-order-history-table button', function (e) {
            e.preventDefault();

            var el = _jquery2['default'](this);
            var idText = el.parents('tr').find('.name-id').data('id');
            var url = "SetSelectedWishlist";
            var data = { id: idText, preferredCulture: hiabconfig.preferredCulture };
            _jquery2['default']('.uc-order-history-table').load(url, data, function () {
                WishlistListing.UpdatePagination();
                _wishlistHeader2['default'].SelectWishlist(idText);
            });
        });

        //handle pagination click
        _jquery2['default'](document).on("click", '.pagination.uc-pagination li', function (e) {
            e.preventDefault();

            var el = _jquery2['default'](this);
            if (!el.hasClass('current')) {
                var clickedPageNo = ExtractPageNoFromHref(el);
                var url = "GetPage/?page=" + clickedPageNo;
                _jquery2['default']('.uc-order-history-table').load(url, null, function () {
                    WishlistListing.UpdatePagination();
                });
            }
        });

        function ExtractPageNoFromHref(el) {
            var href = el.find('a').attr('href');
            var clickedPageNo = href.substring(6);

            return clickedPageNo;
        }

        //check for deleted cart and output msg if found
        _jquery2['default'](function () {
            var url = "GetDeletedWishlist" + '?preferredCulture=' + hiabconfig.preferredCulture;
            _jquery2['default'].ajax({
                type: "GET",
                url: url,
                dataType: 'json',
                success: function success(response) {
                    if (response.id != "") {
                        var html = "<span>" + hiabconfig.wishlist.removedWishlist + "</span>";
                        _notificationsMessageInjector2['default'].Replace(html, ".msg-container");
                    }
                },
                error: function error() {
                    console.log("error");
                }
            });
        });
    }
};

exports['default'] = WishlistListing;
module.exports = exports['default'];

},{"./../../notifications/messageInjector":804,"./../../vendors/foundation":829,"./wishlistHeader":790,"jquery":628}],792:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactRouter = require('react-router');

var _reactRouter2 = _interopRequireDefault(_reactRouter);

var _componentsIllustrationIllustration_container = require('./components/illustration/illustration_container');

var _componentsIllustrationIllustration_container2 = _interopRequireDefault(_componentsIllustrationIllustration_container);

var RouteHandler = _reactRouter2['default'].RouteHandler,
    Route = _reactRouter2['default'].Route,
    DefaultRoute = _reactRouter2['default'].DefaultRoute;

var OtherContainer = (function (_React$Component) {
  _inherits(OtherContainer, _React$Component);

  function OtherContainer(props) {
    _classCallCheck(this, OtherContainer);

    _React$Component.call(this, props);
  }

  OtherContainer.prototype.componentDidMount = function componentDidMount() {};

  OtherContainer.prototype.render = function render() {
    return _react2['default'].createElement(RouteHandler, null);
  };

  return OtherContainer;
})(_react2['default'].Component);

;

var url = hiabconfig.explodedViews.explodedViewsURL;

if (hiabconfig.hasEquipmentTypeRestriction) {
  url = hiabconfig.explodedViews.searchDrawingsPageUrl;
}

var routes = _react2['default'].createElement(
  Route,
  { handler: OtherContainer, ignoreScrollBehavior: true, path: url },
  _react2['default'].createElement(DefaultRoute, { handler: _componentsIllustrationIllustration_container2['default'] }),
  _react2['default'].createElement(Route, { name: 'model', path: ':model', handler: _componentsIllustrationIllustration_container2['default'] }),
  _react2['default'].createElement(Route, { name: 'nodeId', path: ':model/:nodeId', handler: _componentsIllustrationIllustration_container2['default'] }),
  _react2['default'].createElement(Route, { name: 'illustration', path: ':model/:nodeId/:illustration', handler: _componentsIllustrationIllustration_container2['default'] })
);

_reactRouter2['default'].run(routes, _reactRouter2['default'].HistoryLocation, function (Handler) {
  if (document.getElementById('illustration') === null) return;
  _reactDom2['default'].render(_react2['default'].createElement(Handler, null), document.getElementById('illustration'));
});

exports['default'] = _componentsIllustrationIllustration_container2['default'];

/* jshint ignore:end */
module.exports = exports['default'];

},{"./components/illustration/illustration_container":772,"react":525,"react-dom":351,"react-router":381}],793:[function(require,module,exports){
/* jshint ignore:start */
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var ImpersonatedUser = (function (_React$Component) {
	_inherits(ImpersonatedUser, _React$Component);

	function ImpersonatedUser(props) {
		_classCallCheck(this, ImpersonatedUser);

		_React$Component.call(this, props);
	}

	ImpersonatedUser.prototype.render = function render() {
		if (!this.props.impersonated || !this.props.impersonated.IsImpersonated) return null;

		var lang = hiabconfig.impersonator.lang;

		return _react2["default"].createElement(
			"div",
			{ className: "impersonated-user" },
			_react2["default"].createElement(
				"span",
				{ className: "header" },
				lang.impersonateheader
			),
			_react2["default"].createElement(
				"span",
				{ className: "user-data" },
				this.props.impersonated.CustomerName,
				" - ",
				this.props.impersonated.CustomerId
			),
			_react2["default"].createElement(
				"span",
				{ className: "user-data" },
				this.props.impersonated.CompanyName
			)
		);
	};

	return ImpersonatedUser;
})(_react2["default"].Component);

;
exports["default"] = ImpersonatedUser;

/* jshint ignore:end */
module.exports = exports["default"];

},{"react":525}],794:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _impersonator_container = require('./impersonator_container');

var _impersonator_container2 = _interopRequireDefault(_impersonator_container);

var Impersonator = {
	init: function init() {
		this.impersonator = _jquery2['default']('#impersonator');

		//Render impersonator
		this.renderReactComponents();
	},

	renderReactComponents: function renderReactComponents() {
		if (this.impersonator.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_impersonator_container2['default'], null), this.impersonator[0]);
		}
	}
};

exports['default'] = Impersonator;
module.exports = exports['default'];

},{"./impersonator_container":796,"jquery":628,"react":525,"react-dom":351}],795:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var ImpersonatorAutoCompleter = (function (_React$Component) {
	_inherits(ImpersonatorAutoCompleter, _React$Component);

	function ImpersonatorAutoCompleter(props) {
		_classCallCheck(this, ImpersonatorAutoCompleter);

		_React$Component.call(this, props);

		this.handleNoHitsSearch = function (e) {
			$('.user-search-field').autocomplete("search", $('.user-search-field').val());
			$(".impersonation-error").addClass('hidden');
		};
	}

	ImpersonatorAutoCompleter.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		var lang = hiabconfig.impersonator.lang;
		$(".user-search-field").autocomplete({
			minLength: 2,
			delay: 300,
			source: function source(request, response) {
				$.ajax({
					url: hiabconfig.impersonator.apiBaseUrl + 'Search',
					data: {
						query: request.term
					},
					beforeSend: function beforeSend() {
						$('.user-search button').addClass('loading');
					},
					complete: function complete() {
						$('.user-search button').removeClass('loading');
					},
					success: function success(data) {
						$(".impersonation-error").addClass('hidden');
						if (data.length == 0) {
							data.push({
								NoHits: true,
								Title: lang.nohits + ': ' + request.term
							});
						}
						response(data);
					}
				});
			},

			appendTo: $('.user-search').after(),
			open: function open(event, ui) {
				$('.user-search .header').on('mouseover click', function () {
					return false;
				});
			},
			select: function select(event, ui) {
				_this.props.handleClick(ui.item, event);
			}
		});

		$('.user-search-field').autocomplete('instance')._renderItem = function (ul, item) {
			var html = '<div class="row">' + '<div class="small-5 columns"><span>' + item.CompanyName + '</span></div>' + '<div class="small-4 columns"><span>' + item.CustomerName + '</span></div>' + '<div class="small-3 columns"><span>' + item.CustomerId + '</span></div>' + '</div>';
			return $('<li>').append(html).appendTo(ul);
		};

		$('.user-search-field').autocomplete('instance')._renderMenu = function (ul, items) {

			var that = this;
			var html = $('<li class="header"><div class="row">' + '<div class="small-5 columns">' + lang.company + '</div>' + '<div class="small-4 columns">' + lang.customer + '</div>' + '<div class="small-3 columns">' + lang.customernr + '</div>' + '</div></li>');

			if (items[0].NoHits) {
				html = $('<li class="header"><div class="row"><div class="small-12 columns">' + items[0].Title + '</div></div></li>');
				html.appendTo(ul);
				return;
			}
			html.appendTo(ul);

			$.each(items, function (index, item) {
				that._renderItemData(ul, item);
			});
		};
	};

	ImpersonatorAutoCompleter.prototype.render = function render() {
		var _this2 = this;

		var lang = hiabconfig.impersonator.lang;
		if (this.props.isOpen) this.finduser.focus();

		return _react2['default'].createElement(
			'div',
			{ className: 'user-search' },
			_react2['default'].createElement('input', { tabIndex: '-1', className: 'user-search-field', ref: function (ref) {
					return _this2.finduser = ref;
				}, placeholder: lang.placeholder, type: 'text', name: 'finduser' }),
			_react2['default'].createElement(
				'button',
				{ className: 'button', onClick: this.handleNoHitsSearch.bind(this), type: 'button' },
				lang.find
			)
		);
	};

	return ImpersonatorAutoCompleter;
})(_react2['default'].Component);

;
exports['default'] = ImpersonatorAutoCompleter;

/* jshint ignore:end */
module.exports = exports['default'];

},{"react":525}],796:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryUi = require('jquery.ui');

var _jqueryUi2 = _interopRequireDefault(_jqueryUi);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _impersonated_user = require('./impersonated_user');

var _impersonated_user2 = _interopRequireDefault(_impersonated_user);

var _impersonator_signout = require('./impersonator_signout');

var _impersonator_signout2 = _interopRequireDefault(_impersonator_signout);

var _impersonator_autocompleter = require('./impersonator_autocompleter');

var _impersonator_autocompleter2 = _interopRequireDefault(_impersonator_autocompleter);

var _apiImpersonator_api = require('../_api/impersonator_api');

var _apiImpersonator_api2 = _interopRequireDefault(_apiImpersonator_api);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var ImpersonatorContainer = (function (_React$Component) {
	_inherits(ImpersonatorContainer, _React$Component);

	function ImpersonatorContainer(props) {
		var _this = this;

		_classCallCheck(this, ImpersonatorContainer);

		_React$Component.call(this, props);

		this.handleClick = function (item, e) {
			e.preventDefault();
			_this.setState({
				isLoading: true,
				signInError: false
			});

			_apiImpersonator_api2['default'].impersonatedSignin(item.PrimaryKey).then(function (request) {
				_libCustomEvents2['default'].triggerImpersonationStartEvent(request.body);
				_this.setState({
					signInError: false,
					isLoading: true
				});
				_this.handleToggle();
				location.reload(true);
			})['catch'](function (request) {
				_this.handleError();
			});
		};

		this.handleSignOut = function (e) {
			e.preventDefault();
			_this.setState({
				isLoading: true,
				signInError: false
			});

			_apiImpersonator_api2['default'].impersonatedSignout().then(function (request) {
				document.location.href = "/" + hiabconfig.preferredCulture;
			})['catch'](function (err) {
				document.location.href = "/#/#sign-in";
			});
		};

		this.handleToggle = function (e) {
			_this.setState({
				isOpen: _this.state.isOpen ? false : true,
				signInError: false
			});
			_jquery2['default']('.user-search-field').focus();
		};

		this.state = {
			isOpen: false,
			isImpersonated: false,
			impersonated: null,
			isLoading: false,
			signInError: false
		};
	}

	ImpersonatorContainer.prototype.handleError = function handleError() {
		this.setState({
			signInError: true,
			isLoading: false,
			isOpen: true
		});
	};

	ImpersonatorContainer.prototype.componentDidMount = function componentDidMount() {
		var _this2 = this;

		_apiImpersonator_api2['default'].impersonatedUser().then(function (data) {

			_this2.setState({
				impersonated: data,
				isImpersonated: data.IsImpersonated
			});
		});
	};

	ImpersonatorContainer.prototype.render = function render() {
		if (!this.state.impersonated) return null;
		var hasError = this.state.signInError;
		var lang = hiabconfig.impersonator.lang;
		var isOpenClass = _classnames2['default']({
			'uc-impersonator': true,
			'is-open': this.state.isOpen,
			'is-impersonated': this.state.isImpersonated,
			'is-loading': this.state.isLoading
		});
		return _react2['default'].createElement(
			'div',
			{ className: isOpenClass },
			hasError ? _react2['default'].createElement(
				'div',
				{ className: 'impersonation-error' },
				lang.error
			) : _react2['default'].createElement(
				'div',
				{ className: 'impersonation-error hidden' },
				lang.error
			),
			_react2['default'].createElement(
				'button',
				{ className: 'button impersonator-toggle', onClick: this.handleToggle.bind(this), type: 'button' },
				_react2['default'].createElement('i', { className: 'icon-user-plus' }),
				lang.finduser
			),
			_react2['default'].createElement(_impersonator_autocompleter2['default'], { handleClick: this.handleClick, isOpen: this.state.isOpen }),
			_react2['default'].createElement(_impersonated_user2['default'], { impersonated: this.state.impersonated }),
			_react2['default'].createElement(_impersonator_signout2['default'], { handleSignOut: this.handleSignOut, impersonated: this.state.impersonated }),
			_react2['default'].createElement('div', { className: 'loading-overlay' })
		);
	};

	return ImpersonatorContainer;
})(_react2['default'].Component);

;
exports['default'] = ImpersonatorContainer;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_api/impersonator_api":657,"../_lib/custom-events":671,"./impersonated_user":793,"./impersonator_autocompleter":795,"./impersonator_signout":797,"classnames":299,"jquery":628,"jquery.ui":624,"react":525}],797:[function(require,module,exports){
/* jshint ignore:start */
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var ImpersonatedSignout = (function (_React$Component) {
	_inherits(ImpersonatedSignout, _React$Component);

	function ImpersonatedSignout(props) {
		_classCallCheck(this, ImpersonatedSignout);

		_React$Component.call(this, props);
	}

	ImpersonatedSignout.prototype.render = function render() {
		if (!this.props.impersonated || !this.props.impersonated.IsImpersonated) return null;

		var lang = hiabconfig.impersonator.lang;

		return _react2["default"].createElement(
			"div",
			{ className: "impersonated-signout" },
			_react2["default"].createElement(
				"a",
				{ href: "#", onClick: this.props.handleSignOut.bind(this) },
				lang.signout
			)
		);
	};

	return ImpersonatedSignout;
})(_react2["default"].Component);

;
exports["default"] = ImpersonatedSignout;

/* jshint ignore:end */
module.exports = exports["default"];

},{"react":525}],798:[function(require,module,exports){
'use strict';

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

require('babel-polyfill');

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _vendorsFoundation = require('./vendors/foundation');

var _vendorsFoundation2 = _interopRequireDefault(_vendorsFoundation);

var _libCustomEvents = require('./_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var _libToggler = require('./_lib/toggler');

var _libToggler2 = _interopRequireDefault(_libToggler);

var _libTogglerHeader = require('./_lib/togglerHeader');

var _libTogglerHeader2 = _interopRequireDefault(_libTogglerHeader);

var _libStartpageSlider = require('./_lib/startpage-slider');

var _libStartpageSlider2 = _interopRequireDefault(_libStartpageSlider);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _illustration = require('./illustration');

var _illustration2 = _interopRequireDefault(_illustration);

var _libAddclass = require('./_lib/addclass');

var _libAddclass2 = _interopRequireDefault(_libAddclass);

var _libBrandtree = require('./_lib/brandtree');

var _libBrandtree2 = _interopRequireDefault(_libBrandtree);

var _libScrollto = require('./_lib/scrollto');

var _libScrollto2 = _interopRequireDefault(_libScrollto);

var _componentsHeaderLanguage_selector = require('./components/header/language_selector');

var _componentsHeaderLanguage_selector2 = _interopRequireDefault(_componentsHeaderLanguage_selector);

var _libListviewtoggle = require('./_lib/listviewtoggle');

var _libListviewtoggle2 = _interopRequireDefault(_libListviewtoggle);

var _libComplaintview = require('./_lib/complaintview');

var _libComplaintview2 = _interopRequireDefault(_libComplaintview);

var _batchorderBatchorder = require('./batchorder/batchorder');

var _batchorderBatchorder2 = _interopRequireDefault(_batchorderBatchorder);

var _libProductimagezoom = require('./_lib/productimagezoom');

var _libProductimagezoom2 = _interopRequireDefault(_libProductimagezoom);

var _jqueryStuck = require('jquery.stuck');

var _jqueryStuck2 = _interopRequireDefault(_jqueryStuck);

var _minicartMinicart = require('./minicart/minicart');

var _minicartMinicart2 = _interopRequireDefault(_minicartMinicart);

var _libScrollcontrols = require('./_lib/scrollcontrols');

var _libScrollcontrols2 = _interopRequireDefault(_libScrollcontrols);

var _libScrollcontrolsProductdetail = require('./_lib/scrollcontrols-productdetail');

var _libScrollcontrolsProductdetail2 = _interopRequireDefault(_libScrollcontrolsProductdetail);

var _libAddtocart = require('./_lib/addtocart');

var _libAddtocart2 = _interopRequireDefault(_libAddtocart);

var _batchorderUploadfile = require('./batchorder/uploadfile');

var _batchorderUploadfile2 = _interopRequireDefault(_batchorderUploadfile);

var _batchorderBatchorderCart = require('./batchorder/batchorder-cart');

var _batchorderBatchorderCart2 = _interopRequireDefault(_batchorderBatchorderCart);

var _checkoutCheckoutNew = require('./checkout/checkout-new');

var _checkoutCheckoutNew2 = _interopRequireDefault(_checkoutCheckoutNew);

var _notificationsNotifications = require('./notifications/notifications');

var _notificationsNotifications2 = _interopRequireDefault(_notificationsNotifications);

var _waves = require('waves');

var _waves2 = _interopRequireDefault(_waves);

var _libUseraddresses = require('./_lib/useraddresses');

var _libUseraddresses2 = _interopRequireDefault(_libUseraddresses);

var _libPrint = require('./_lib/print');

var _libPrint2 = _interopRequireDefault(_libPrint);

var _libSemanticDropdown = require('./_lib/semantic-dropdown');

var _libSemanticDropdown2 = _interopRequireDefault(_libSemanticDropdown);

var _libAutosubmit = require('./_lib/autosubmit');

var _libAutosubmit2 = _interopRequireDefault(_libAutosubmit);

var _impersonatorImpersonator = require('./impersonator/impersonator');

var _impersonatorImpersonator2 = _interopRequireDefault(_impersonatorImpersonator);

var _libDatepicker = require('./_lib/datepicker');

var _libDatepicker2 = _interopRequireDefault(_libDatepicker);

require('./server');

var _libDatepickerLang = require('./_lib/datepicker-lang');

var _libDatepickerLang2 = _interopRequireDefault(_libDatepickerLang);

var _libSearchresult = require('./_lib/searchresult');

var _libSearchresult2 = _interopRequireDefault(_libSearchresult);

var _libIeEqualizerFix = require('./_lib/ie-equalizer-fix');

var _libIeEqualizerFix2 = _interopRequireDefault(_libIeEqualizerFix);

var _libCookie = require('./_lib/cookie');

var _libCookie2 = _interopRequireDefault(_libCookie);

var _libClearCart = require('./_lib/clear-cart');

var _libClearCart2 = _interopRequireDefault(_libClearCart);

var _libDetectVendor = require('./_lib/detectVendor');

var _libDetectVendor2 = _interopRequireDefault(_libDetectVendor);

var _libProductContains = require('./_lib/product-contains');

var _libProductContains2 = _interopRequireDefault(_libProductContains);

var _libConfirmationpage = require('./_lib/confirmationpage');

var _libConfirmationpage2 = _interopRequireDefault(_libConfirmationpage);

var _libProductCardFooter = require('./_lib/product-card-footer');

var _libProductCardFooter2 = _interopRequireDefault(_libProductCardFooter);

var _libScaledPrices = require('./_lib/scaled-prices');

var _libScaledPrices2 = _interopRequireDefault(_libScaledPrices);

var _libShare = require('./_lib/share');

var _libShare2 = _interopRequireDefault(_libShare);

var _componentsWishlistWishlistHeader = require('./components/wishlist/wishlistHeader');

var _componentsWishlistWishlistHeader2 = _interopRequireDefault(_componentsWishlistWishlistHeader);

var _componentsWishlistWishlistListing = require('./components/wishlist/wishlistListing');

var _componentsWishlistWishlistListing2 = _interopRequireDefault(_componentsWishlistWishlistListing);

var _componentsWishlistWishlistDetail = require('./components/wishlist/wishlistDetail');

var _componentsWishlistWishlistDetail2 = _interopRequireDefault(_componentsWishlistWishlistDetail);

var _libFits_my_machine = require('./_lib/fits_my_machine');

var _libFits_my_machine2 = _interopRequireDefault(_libFits_my_machine);

var _libSelfregistration = require('./_lib/selfregistration');

var _libSelfregistration2 = _interopRequireDefault(_libSelfregistration);

var _orderhistoryOrderhistory = require('./orderhistory/orderhistory');

var _orderhistoryOrderhistory2 = _interopRequireDefault(_orderhistoryOrderhistory);

var _salesforcerecommendationsSalesforcerecommendations = require('./salesforcerecommendations/salesforcerecommendations');

var _salesforcerecommendationsSalesforcerecommendations2 = _interopRequireDefault(_salesforcerecommendationsSalesforcerecommendations);

var hiab = {
  init: function init() {

    _vendorsFoundation2['default'].init();
    _libProductCardFooter2['default'].init();
    _libCustomEvents2['default'].init();
    _componentsHeaderLanguage_selector2['default'].init();
    _libCookie2['default'].init();
    if (_jquery2['default']('.startpage-slider').length > 0) {
      _libStartpageSlider2['default'].init();
    }
    _impersonatorImpersonator2['default'].init();
    _libDetectVendor2['default'].init();
    if (_jquery2['default']('main.uc-checkout').length > 0) {
      _checkoutCheckoutNew2['default'].init();
    }
    _salesforcerecommendationsSalesforcerecommendations2['default'].init();
    _libToggler2['default'].init();
    _libTogglerHeader2['default'].init();
    _libAddclass2['default'].init();

    _batchorderBatchorder2['default'].init();
    _libScrollto2['default'].init();

    _libListviewtoggle2['default'].init();
    _libComplaintview2['default'].init();
    _minicartMinicart2['default'].init();
    _notificationsNotifications2['default'].init();
    _libScrollcontrols2['default'].init();

    if (_jquery2['default']('.product-detailpage').length > 0) {
      _libScrollcontrolsProductdetail2['default'].init();
    }

    _libAddtocart2['default'].init();
    _batchorderBatchorderCart2['default'].init();
    _libUseraddresses2['default'].init();
    _libPrint2['default'].init();
    _libSemanticDropdown2['default'].init();
    _libAutosubmit2['default'].init();

    _libDatepicker2['default'].init();
    _libSearchresult2['default'].init();

    _libAddtocart2['default'].init();
    _libIeEqualizerFix2['default'].init();

    _libClearCart2['default'].init();

    // spinner.init();
    _libConfirmationpage2['default'].init();
    _jquery2['default'](window).stuck();
    if (_jquery2['default']('.accordion').length > 0) {
      _jquery2['default'](document).foundation({
        accordion: {
          multi_expand: true
        }
      });
    }

    if (_jquery2['default']('.complementary-information').length > 0) {
      _libProductContains2['default'].init();
    }
    if (_jquery2['default']('#productImages').length > 0) {
      _libProductimagezoom2['default'].init();
    }
    if (_jquery2['default']('.scaled-prices').length > 0) {
      _libScaledPrices2['default'].init();
    }
    if (_jquery2['default']('.uc-fileupload').length > 0) {
      _batchorderUploadfile2['default'].init();
    }

    if (_jquery2['default']('.share-modal').length > 0) {
      _libShare2['default'].init();
    }
    if (_jquery2['default']('.does-this-fit-my-machine').length > 0) {
      _libFits_my_machine2['default'].init();
    }
    if (_jquery2['default']('.uc-cms-content .item-wrapper').length > 0) {

      var nameHeight = 0;
      _jquery2['default']('.uc-cms-content .item-wrapper .item-name').each(function () {
        if (_jquery2['default'](this).height() > nameHeight) {
          nameHeight = _jquery2['default'](this).height();
        }
        _jquery2['default']('.uc-cms-content .item-wrapper .item-name').height(nameHeight);
      });

      var priceStockHeight = 0;
      _jquery2['default']('.uc-cms-content .item-wrapper .amount-price-stock').each(function () {
        if (_jquery2['default'](this).height() > priceStockHeight) {
          priceStockHeight = _jquery2['default'](this).height();
        }
        _jquery2['default']('.uc-cms-content .item-wrapper .amount-price-stock').height(priceStockHeight);
      });
    }

    if (_jquery2['default']('.uc-siteheader .uc-wishlist.wishlist-header').length > 0) {
      _componentsWishlistWishlistHeader2['default'].init();
    }

    if (_jquery2['default']('.main-content.uc-wishlist:not(.wishlist-detail)').length > 0) {
      _componentsWishlistWishlistListing2['default'].init();
    }

    if (_jquery2['default']('.main-content.uc-wishlist.wishlist-detail').length > 0) {
      _componentsWishlistWishlistDetail2['default'].init();
    }

    _waves2['default'].attach('button', ['waves-light']);
    _waves2['default'].init();

    _jquery2['default']('img').bind('contextmenu', function (e) {
      e.preventDefault();
      return false;
    });

    _jquery2['default']('body').on('keypress', '.quantity, .amount', function (e) {
      var x;
      var isInt;

      if (e.which !== 8 && e.which !== 0 && (e.which < 48 || e.which > 57) || e.which === 32) {
        return false;
      } else {
        isInt = isNaN(String.fromCharCode(e.keyCode)) ? !1 : (x = parseFloat(String.fromCharCode(e.keyCode)), (0 | x) === x);
        //e.key wont work in some browsers check if undefined
        //if it is undefined use String.fromCharCode(e.keyCode)
        if (typeof e.key !== 'undefined') {
          isInt = isNaN(e.key) ? !1 : (x = parseFloat(e.key), (0 | x) === x);
        }
        //Check if input is int, backspace or left, right, up, down
        //some browsers detect backspace and left, right, up, down which wont validate as ints
        if (isInt || e.which === 8 || e.which < 38 || e.which > 41) {
          //e.key wont work in some browsers check if undefined
          //if it is undefined use String.fromCharCode(e.keyCode)
          if (typeof e.key !== 'undefined') {
            return e.key < 1 && e.target.value.length === 0 ? false : true;
          } else {
            return String.fromCharCode(e.keyCode) < 1 && e.target.value.length === 0 ? false : true;
          }
        } else {
          return false;
        }
      }
    });

    _jquery2['default']('body').on('keyup', '.quantity, .amount', function (e) {
      var x;
      var isInt = isNaN(this.value) ? !1 : (x = parseFloat(this.value), (0 | x) === x);
      if (isInt && parseFloat(this.value) === 0) {
        this.value = '1';
      }
    });

    _jquery2['default']('body').on('blur', '.quantity, .amount', function (e) {
      if (this.value === '') {
        this.value = this.defaultValue;
      }
    });

    _jquery2['default']('body').on('submit', '.reset-password', function (e) {
      _jquery2['default']('#btnChangePsw').attr('disabled', 'disabled');
    });

    if (_jquery2['default']('#account-infromation-form').length > 0) {
      _jquery2['default']('#account-infromation-form input').on('blur', function () {
        var inputName = _jquery2['default'](this)[0].name;
        setTimeout(function () {
          Foundation.libs.abide.validate(_jquery2['default']('#account-infromation-form').find('input[name=' + inputName + ']'), { type: '' });
        }, 500);
      });
    }

    if (_jquery2['default']('#illustration').length > 0) {
      _libBrandtree2['default'].init();
      var explodedViewUrl = hiabconfig.explodedViews.explodedViewsNameInUrl;
      var urlParts = window.location.href.split('/');
      if (urlParts.indexOf(explodedViewUrl) !== -1 && urlParts[urlParts.indexOf(explodedViewUrl) + 1] === '') {
        _jquery2['default']('body').addClass('brandtree-open');
      }
    }

    if (_jquery2['default']('.uc-order-history').length > 0) {
      _orderhistoryOrderhistory2['default'].init();
    }

    if (_jquery2['default']('#self-registration')) {
      _libSelfregistration2['default'].init();
    }
  }
};

_jquery2['default'](document).ready(function ($) {
  hiab.init();
});

},{"./_lib/addclass":663,"./_lib/addtocart":664,"./_lib/autosubmit":665,"./_lib/brandtree":666,"./_lib/clear-cart":667,"./_lib/complaintview":668,"./_lib/confirmationpage":669,"./_lib/cookie":670,"./_lib/custom-events":671,"./_lib/datepicker":674,"./_lib/datepicker-lang":673,"./_lib/detectVendor":675,"./_lib/fits_my_machine":676,"./_lib/ie-equalizer-fix":677,"./_lib/listviewtoggle":678,"./_lib/print":680,"./_lib/product-card-footer":681,"./_lib/product-contains":682,"./_lib/productimagezoom":683,"./_lib/scaled-prices":684,"./_lib/scrollcontrols":686,"./_lib/scrollcontrols-productdetail":685,"./_lib/scrollto":687,"./_lib/searchresult":688,"./_lib/selfregistration":689,"./_lib/semantic-dropdown":690,"./_lib/share":691,"./_lib/startpage-slider":692,"./_lib/toggler":693,"./_lib/togglerHeader":694,"./_lib/useraddresses":695,"./batchorder/batchorder":737,"./batchorder/batchorder-cart":736,"./batchorder/uploadfile":738,"./checkout/checkout-new":739,"./components/header/language_selector":767,"./components/wishlist/wishlistDetail":789,"./components/wishlist/wishlistHeader":790,"./components/wishlist/wishlistListing":791,"./illustration":792,"./impersonator/impersonator":794,"./minicart/minicart":799,"./notifications/notifications":805,"./orderhistory/orderhistory":806,"./salesforcerecommendations/salesforcerecommendations":813,"./server":818,"./vendors/foundation":829,"babel-polyfill":3,"jquery":628,"jquery.stuck":830,"react":525,"waves":616}],799:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _minicart_content = require('./minicart_content');

var _minicart_content2 = _interopRequireDefault(_minicart_content);

var _apiCart_api = require('../_api/cart_api');

var _apiCart_api2 = _interopRequireDefault(_apiCart_api);

var _minicart_totalprice = require('./minicart_totalprice');

var _minicart_totalprice2 = _interopRequireDefault(_minicart_totalprice);

var _minicart_totalitems = require('./minicart_totalitems');

var _minicart_totalitems2 = _interopRequireDefault(_minicart_totalitems);

var minicart = {
	init: function init() {
		this.minicartContentElm = _jquery2['default']('#minicart-content');
		this.minicartFooterElm = _jquery2['default']('#cart-footer-total-value');
		this.minicartHeaderPriceElm = _jquery2['default']('#total-cart-value');
		this.minicartHeaderItemsElm = _jquery2['default']('#num-of-cart-items');
		this.minicartStickyItemsElm = _jquery2['default']('#num-of-cart-items-sticky');

		//Render minicart
		this.renderReactComponents();

		function closeClearCart() {
			_jquery2['default']('.clear-cart').removeClass('is-open');
		}

		_jquery2['default']('#checkout-button').click(function () {
			var checkoutUrl = _jquery2['default'](this).data('checkout-url');
			_jquery2['default'](this).addClass('loading');
			_jquery2['default']('.clear-cart button').prop("disabled", true);
			if (_jquery2['default']('.clear-cart').hasClass('is-open')) {
				closeClearCart();
			}
			if (typeof dataLayer !== 'undefined' && hiabconfig.EnableGoogleTagManager) {
				dataLayer.push({
					'event': 'checkout',
					'ecommerce': {
						'checkout': {
							'actionField': { 'step': 1 },
							'products': []
						}
					}
				});
			}
			window.location.href = checkoutUrl;
		});
		_jquery2['default']('.minicart-header button').click(function () {
			if (_jquery2['default']('.clear-cart').hasClass('is-open')) {
				closeClearCart();
			}
		});
		_jquery2['default']('.exit-off-canvas').click(function () {
			if (_jquery2['default']('.clear-cart').hasClass('is-open')) {
				closeClearCart();
			}
		});
	},

	renderReactComponents: function renderReactComponents() {
		if (this.minicartContentElm.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_minicart_content2['default'], null), this.minicartContentElm[0]);
		}

		if (this.minicartFooterElm.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_minicart_totalprice2['default'], null), this.minicartFooterElm[0]);
		}

		if (this.minicartHeaderPriceElm.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_minicart_totalprice2['default'], null), this.minicartHeaderPriceElm[0]);
		}

		if (this.minicartHeaderItemsElm.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_minicart_totalitems2['default'], null), this.minicartHeaderItemsElm[0]);
		}
		if (this.minicartStickyItemsElm.length > 0) {
			_reactDom2['default'].render(_react2['default'].createElement(_minicart_totalitems2['default'], null), this.minicartStickyItemsElm[0]);
		}
	}
};

exports['default'] = minicart;
module.exports = exports['default'];

},{"../_api/cart_api":652,"./minicart_content":800,"./minicart_totalitems":802,"./minicart_totalprice":803,"jquery":628,"react":525,"react-dom":351}],800:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var _minicart_lineitem = require('./minicart_lineitem');

var _minicart_lineitem2 = _interopRequireDefault(_minicart_lineitem);

var MinicartContent = (function (_React$Component) {
	_inherits(MinicartContent, _React$Component);

	function MinicartContent(props) {
		_classCallCheck(this, MinicartContent);

		_React$Component.call(this, props);
		this.state = {
			cart: {
				CartItems: []
			}
		};
	}

	MinicartContent.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		if (hiabconfig.userLoggedIn) {
			_actionsCart_actions2['default'].loadCart(true);
		}

		this.unsubscribe = _storesCart_store2['default'].listen(function () {
			_this.setState({
				cart: _storesCart_store2['default'].getStore().Cart
			});
		});
	};

	MinicartContent.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	MinicartContent.prototype.render = function render() {
		if (!this.state.cart || !this.state.cart.CartItems) return null;
		var lineItems = this.state.cart.CartItems.map(function (lineItem) {
			return _react2['default'].createElement(_minicart_lineitem2['default'], { key: lineItem.Code, item: lineItem });
		});

		return _react2['default'].createElement(
			'ul',
			null,
			lineItems
		);
	};

	return MinicartContent;
})(_react2['default'].Component);

;
exports['default'] = MinicartContent;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/cart_actions":633,"../_stores/cart_store":699,"./minicart_lineitem":801,"jquery":628,"react":525}],801:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _actionsCart_actions = require('../_actions/cart_actions');

var _actionsCart_actions2 = _interopRequireDefault(_actionsCart_actions);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var MinicartLineItem = (function (_React$Component) {
	_inherits(MinicartLineItem, _React$Component);

	function MinicartLineItem(props) {
		var _this = this;

		_classCallCheck(this, MinicartLineItem);

		_React$Component.call(this, props);

		this.handleSubmit = function (e) {
			e.preventDefault();
			_this.handleBlur();
		};

		this.handleDelete = function (e) {
			e.preventDefault();
			var skuID = _this.props.item.Code;
			_actionsCart_actions2['default'].deleteCartItem(skuID);
			_this.setState({ loading: true });
		};

		this.state = {
			loading: false,
			itemValue: 0
		};
	}

	MinicartLineItem.prototype.isInt = function isInt(value) {
		var x;
		var isInt = isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
		if (isInt) {
			return value < 1 && value.length === 1 ? false : true;
		} else {
			return false;
		}
	};

	MinicartLineItem.prototype.handleChange = function handleChange(e) {
		var quantity = e.target.value;
		if (quantity !== '' && !this.isInt(quantity)) return;
		this.setState({ itemValue: quantity });
	};

	MinicartLineItem.prototype.handleBlur = function handleBlur() {
		var skuID = this.props.item.Code,
		    quantity = this.state.itemValue;
		// Reset to intial quantity if the field is empty on blur
		if (quantity === '') {
			this.setState({
				itemValue: this.props.item.Quantity
			});
			quantity = this.props.item.Quantity;
			return;
		}
		if (this.props.item.Quantity !== parseInt(quantity)) {
			_actionsCart_actions2['default'].updateCartItem(skuID, quantity);
			this.setState({ loading: true });
		}
	};

	MinicartLineItem.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) {
		this.setState({
			loading: false,
			itemValue: props.item.Quantity
		});
	};

	MinicartLineItem.prototype.componentDidMount = function componentDidMount() {
		this.setState({
			itemValue: this.props.item.Quantity
		});
	};

	MinicartLineItem.prototype.componentWillUnmount = function componentWillUnmount() {
		// this.updateQuantity();
	};

	MinicartLineItem.prototype.render = function render() {
		var item = this.props.item;
		var image = '/styles/images/product-placeholder2x2.png';
		if (item.ImageUrl && item.ImageUrl !== '') image = item.ImageUrl + '?preset=mini';

		var lang = hiabconfig.explodedViews.lang;

		var partOfCampaign = item.HasPromotion;

		var itemClass = _classnames2['default']({
			'loading': this.state.loading,
			'is-discounted': partOfCampaign
		});
		var defaultPriceContainer = partOfCampaign ? _react2['default'].createElement(
			'span',
			{ className: 'default' },
			item.Price,
			' - '
		) : null;
		var grossDiscountContianer = item.IsDiscounted ? _react2['default'].createElement(
			'span',
			{ className: 'gross-discount-contianer' },
			defaultPriceContainer,
			_react2['default'].createElement(
				'span',
				{ className: 'gross' },
				lang.grossprice,
				' ',
				item.DefaultPrice
			),
			_react2['default'].createElement(
				'span',
				{ className: 'discount' },
				lang.promotionTitle,
				' ',
				item.DiscountPercentage
			)
		) : _react2['default'].createElement(
			'span',
			{ className: 'gross-discount-contianer' },
			_react2['default'].createElement(
				'span',
				{ className: 'default' },
				item.Price
			)
		);
		if (!item.IsDiscounted && !item.HasPromotion) {
			grossDiscountContianer = null;
		}
		var altText = item.Code + " " + item.DisplayName;
		var placedPrice = _react2['default'].createElement(
			'span',
			{ className: 'price left' },
			'x ',
			item.PlacedPrice
		);
		if (partOfCampaign) {
			placedPrice = _react2['default'].createElement(
				'span',
				{ className: 'price left' },
				'x ',
				_react2['default'].createElement(
					'div',
					{ className: 'discount-price' },
					_react2['default'].createElement('i', { className: 'icon-tags' }),
					item.PlacedPrice,
					_react2['default'].createElement(
						'span',
						null,
						' - '
					),
					lang.promotionTitle,
					' ',
					item.PromotionDiscountPercent,
					' %'
				)
			);
		}
		return _react2['default'].createElement(
			'li',
			{ className: itemClass },
			_react2['default'].createElement(
				'form',
				{ className: 'item-wrapper clearfix minicart-item', onSubmit: this.handleSubmit.bind(this) },
				_react2['default'].createElement(
					'div',
					{ className: 'cart-row clearfix' },
					_react2['default'].createElement(
						'div',
						{ className: 'image' },
						_react2['default'].createElement(
							'a',
							{ href: item.Url },
							_react2['default'].createElement('img', { src: image, alt: altText })
						)
					),
					_react2['default'].createElement(
						'div',
						{ className: 'item-name' },
						_react2['default'].createElement(
							'h4',
							null,
							_react2['default'].createElement(
								'a',
								{ href: item.Url },
								item.DisplayName
							)
						),
						_react2['default'].createElement(
							'p',
							null,
							hiabconfig.cart.lang.materialNumber,
							': ',
							_react2['default'].createElement(
								'span',
								null,
								item.Code
							),
							grossDiscountContianer
						)
					),
					_react2['default'].createElement(
						'div',
						{ className: 'item-remove' },
						_react2['default'].createElement(
							'button',
							{ type: 'button', onClick: this.handleDelete.bind(this), className: 'button nostyle' },
							_react2['default'].createElement('i', { className: 'icon-cancel-circled' })
						)
					)
				),
				_react2['default'].createElement(
					'div',
					{ className: 'ammount-data' },
					_react2['default'].createElement(
						'div',
						{ className: 'amount-price-stock u-dt' },
						_react2['default'].createElement('input', {
							tabIndex: '-1',
							className: 'amount',
							name: 'aumont-x',
							onBlur: this.handleBlur.bind(this),
							onChange: this.handleChange.bind(this),
							value: this.state.itemValue }),
						placedPrice
					),
					_react2['default'].createElement(
						'div',
						{ className: 'item-total' },
						_react2['default'].createElement(
							'span',
							{ className: 'price' },
							item.ExtendedPrice
						)
					)
				)
			)
		);
	};

	return MinicartLineItem;
})(_react2['default'].Component);

;
exports['default'] = MinicartLineItem;

/* jshint ignore:end */
module.exports = exports['default'];
/*partOfCampaignContainer*/

},{"../_actions/cart_actions":633,"../_stores/cart_store":699,"classnames":299,"react":525}],802:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var _actionsOrderlines_actions = require('../_actions/orderlines_actions');

var _actionsOrderlines_actions2 = _interopRequireDefault(_actionsOrderlines_actions);

var MinicartTotalItems = (function (_React$Component) {
	_inherits(MinicartTotalItems, _React$Component);

	function MinicartTotalItems(props) {
		_classCallCheck(this, MinicartTotalItems);

		_React$Component.call(this, props);
		this.state = {
			cart: {}
		};
	}

	MinicartTotalItems.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.unsubscribe = _storesCart_store2['default'].listen(function () {
			_this.setState({
				cart: _storesCart_store2['default'].getStore().Cart
			});
		});
	};

	MinicartTotalItems.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	MinicartTotalItems.prototype.componentDidUpdate = function componentDidUpdate(res) {
		if (this.state.cart) {
			// console.log(this.state);
			// if( $('[data-product-sku]').length > 0 && !$('.drawer-main').hasClass('move-left')){
			// 	$('.uc-headercart').removeClass('adding');
			// 	$('#controll-cart').removeClass('adding');
			// }

			// if( $('[data-line-item]').length > 0 /*&& !$('.drawer-main').hasClass('move-left')*/){
			if ($('[data-line-item]').length > 0 && this.state.cart.ItemCount !== 0) {
				$('#add-to-cart-success').first().css('display', 'block');
				$('.fileupload-messages').removeClass('active');
				$('.orderline-message').addClass('u-hidden');
				_actionsOrderlines_actions2['default'].clear();
				$('button').removeClass('loading');
				$('.uc-headercart').removeClass('adding');
				$('#controll-cart').removeClass('adding');
			}

			if (this.state.cart.ItemCount == 0) {
				$('.uc-headercart').removeClass('right-off-canvas-toggle');
				$('#controll-cart button').removeClass('right-off-canvas-toggle');
			} else {
				$('.uc-headercart').addClass('right-off-canvas-toggle');
				$('#controll-cart button').addClass('right-off-canvas-toggle');
			}

			if ($('.drawer-main').hasClass('move-left') && this.state.cart.ItemCount == 0) {
				$('.drawer-main').removeClass('move-left');
			}
		}
	};

	MinicartTotalItems.prototype.render = function render() {
		if (!this.state.cart || !this.state.cart.ItemCount && this.state.cart.ItemCount !== 0) return null;

		return _react2['default'].createElement(
			'span',
			null,
			this.state.cart.ItemCount
		);
	};

	return MinicartTotalItems;
})(_react2['default'].Component);

;
exports['default'] = MinicartTotalItems;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/orderlines_actions":640,"../_stores/cart_store":699,"react":525}],803:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var MinicartTotalPrice = (function (_React$Component) {
	_inherits(MinicartTotalPrice, _React$Component);

	function MinicartTotalPrice(props) {
		_classCallCheck(this, MinicartTotalPrice);

		_React$Component.call(this, props);
		this.state = {
			cart: {}
		};
	}

	MinicartTotalPrice.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.unsubscribe = _storesCart_store2['default'].listen(function () {
			_this.setState({
				cart: _storesCart_store2['default'].getStore().Cart
			});
		});
	};

	MinicartTotalPrice.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	MinicartTotalPrice.prototype.render = function render() {
		if (!this.state.cart || !this.state.cart.SubTotal) return null;

		return _react2['default'].createElement(
			'span',
			null,
			this.state.cart.SubTotal
		);
	};

	return MinicartTotalPrice;
})(_react2['default'].Component);

;
exports['default'] = MinicartTotalPrice;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_stores/cart_store":699,"react":525}],804:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var Injector = {
    Replace: function Replace(html, containerSelector) {
        var container = _jquery2['default'](containerSelector);
        container.html(_jquery2['default'](html).addClass('msg'));

        setTimeout(function () {
            var container = _jquery2['default'](containerSelector);
            var content = _jquery2['default'](container.children('.msg'));
            if (content.length < 1) {
                content = _jquery2['default'](containerSelector).parent().find('.msg');
            }
            _jquery2['default'](content).hide('fast', function () {
                _jquery2['default'](content).remove();
            });
        }, 3000);
    },

    InsertAfter: function InsertAfter(html, targetSelector) {
        var element = _jquery2['default'](targetSelector);
        _jquery2['default'](html).insertAfter(element).addClass('msg');

        setTimeout(function () {
            var element = _jquery2['default'](targetSelector).next('.msg');
            if (element.length < 1) {
                element = _jquery2['default'](targetSelector).parent().find('.msg');
            }
            _jquery2['default'](element).hide('fast', function () {
                _jquery2['default'](element).remove();
            });
        }, 3000);
    }
};

exports['default'] = Injector;
module.exports = exports['default'];

},{"jquery":628}],805:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _storesCart_store = require('../_stores/cart_store');

var _storesCart_store2 = _interopRequireDefault(_storesCart_store);

var notifications = {
	init: function init() {
		var _this = this;

		_storesCart_store2['default'].listen(function () {
			if (_storesCart_store2['default'].cart.error) {
				_this.displayErrorMessage(_storesCart_store2['default'].cart.error.Failed);
			} else {
				_this.removeErrorMessage(_storesCart_store2['default'].cart.Added);
			}
		});

		//Render minicart
		this.renderReactComponents();
	},

	displayErrorMessage: function displayErrorMessage(products) {
		var _this2 = this;

		for (var item in products) {
			if (products.hasOwnProperty(item)) {
				var _ret = (function () {

					if (typeof products[item].Response.status === 'undefined') return {
							v: false
						};
					// if(products[item].Response.status === 200) return false;

					var materialNumber = products[item].Code + '';
					var materialNumberAsId = '#' + materialNumber.split('.').join('-');
					if (_jquery2['default'](materialNumberAsId).children().length < 1) {
						_jquery2['default']('<div class="small-12 columns info-add-to-cart">\n\t\t          <i class="icon-attention-circled"></i>\n\t\t          <p>' + products[item].WarningMessage + '</p>\n\t\t        </div>').appendTo(materialNumberAsId);
					} else {
						_jquery2['default'](materialNumberAsId).show();
					}
					_this2.removeLoadingIcons(products[item].Code);
					setTimeout(function () {
						_jquery2['default'](materialNumberAsId).hide();
					}, 4000);
				})();

				if (typeof _ret === 'object') return _ret.v;
			}
		}
	},

	removeErrorMessage: function removeErrorMessage(products) {
		for (var item in products) {
			if (products.hasOwnProperty(item)) {
				var materialNumber = products[item].Code + '';
				var materialNumberAsId = '#' + materialNumber.split('.').join('-');
				_jquery2['default'](materialNumberAsId).hide();
				this.removeLoadingIcons(products[item].Code);
			}
		}
	},

	removeLoadingIcons: function removeLoadingIcons(productCode) {
		_jquery2['default']('button[data-product-sku="' + productCode + '"]').removeClass('loading');
		var headerCart = _jquery2['default']('.uc-headercart')[0];
		var controllCart = _jquery2['default']('#controll-cart')[0];
		headerCart.className = headerCart.className.replace(' adding', '');
		controllCart.className = controllCart.className.replace(' adding', '');
	},

	renderReactComponents: function renderReactComponents() {}
};

exports['default'] = notifications;
module.exports = exports['default'];

},{"../_stores/cart_store":699,"jquery":628,"react":525,"react-dom":351}],806:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _libCustomEvents = require('../_lib/custom-events');

var _libCustomEvents2 = _interopRequireDefault(_libCustomEvents);

var showClearFilter = false;
var showClearSearch = false;
var isOrderHistory = false;
var isOrderDetailHistory = false;
var isMyOpenOrder = false;
var data = {};

var orderHistory = {
  init: function init() {

    if (_jquery2['default']('#order-history').length > 0) {

      isOrderHistory = true;
      this.searchOrder = document.getElementById('search-orders');
      this.searchBy = document.getElementById('SearchBy');

      this.dateFrom = document.getElementById('datefrom');
      this.dateTo = document.getElementById('dateto');
      this.orderStatus = document.getElementById('OrderStatus');

      this.market = document.getElementById('market');
      this.customer = document.getElementById('customer');
      this.contact = document.getElementById('contact');

      var market = orderHistory.hasValue(this.market);
      var customer = orderHistory.hasValue(this.customer);
      var contact = orderHistory.hasValue(this.contact);

      if (market || customer || contact) {
        _jquery2['default']('#clearAdvancedFilter').addClass('show');
      } else {
        _jquery2['default']('#clearAdvancedFilter').removeClass('show');
      }

      var searchOrder = orderHistory.hasValue(this.searchOrder);
      var searchBy = orderHistory.selectHasNewValue(this.searchBy);

      if (searchOrder || searchBy) {
        showClearSearch = true;
        orderHistory.showClearSearch();
      } else {
        showClearFilter = false;
        orderHistory.showSearch();
      }

      var dateFrom = orderHistory.hasValue(this.dateFrom);
      var dateTo = orderHistory.hasValue(this.dateTo);
      var orderStatus = orderHistory.selectHasNewValue(this.orderStatus);

      if (dateTo || dateFrom || orderStatus) {
        showClearFilter = true;
        orderHistory.showClearFilter();
      } else {
        showClearFilter = false;
        orderHistory.showFilter();
      }
    }
    if (_jquery2['default']('#open-orders').length > 0) {

      isMyOpenOrder = true;

      this.searchOrder = document.getElementById('search-orders');
      this.searchBy = document.getElementById('SearchBy');

      this.dateFrom = document.getElementById('datefrom');
      this.dateTo = document.getElementById('dateto');
      this.orderStatus = document.getElementById('OrderStatus');

      var searchOrder = orderHistory.hasValue(this.searchOrder);
      var searchBy = orderHistory.selectHasNewValue(this.searchBy);

      if (searchOrder || searchBy) {
        showClearSearch = true;
        orderHistory.showClearSearch();
      } else {
        showClearFilter = false;
        orderHistory.showSearch();
      }

      var dateFrom = orderHistory.hasValue(this.dateFrom);
      var dateTo = orderHistory.hasValue(this.dateTo);

      if (dateTo || dateFrom) {
        showClearFilter = true;
        orderHistory.showClearFilter();
      } else {
        showClearFilter = false;
        orderHistory.showFilter();
      }
    }
    if (_jquery2['default']('#order-history-detail').length > 0) {
      isOrderDetailHistory = true;
    }
    if (_jquery2['default']('#open-orders').length > 0 || _jquery2['default']('#order-history').length > 0) {
      document.getElementById("search-orders").addEventListener("keyup", function (event) {
        if (event.keyCode == 13 && this.value === '') {
          document.getElementById("clearSearch").click();
        }
      });
    }
    _jquery2['default']('#search').on('click', function (e) {
      orderHistory.createDataModel();
    });

    _jquery2['default']('#filter').on('click', function (e) {
      orderHistory.createDataModel();
    });

    _jquery2['default']('#search-orderlines').on('click', function (e) {
      orderHistory.createDataModel();
    });

    _jquery2['default']('#search-orders').on("keyup", function () {
      if (orderHistory.hasInputChanged(this)) {
        _jquery2['default']('#search').prop("disabled", false);
        orderHistory.showSearch();
      } else {
        if (showClearSearch) {
          orderHistory.showClearSearch();
        } else {
          if (document.getElementById('search-orders').value === "" && document.getElementById('SearchBy').value === "OrderNumber") {
            _jquery2['default']('#search').prop("disabled", true);
          }
        }
      }
    });

    _jquery2['default']('#SearchBy').on("change", function () {
      _jquery2['default']("#SearchBy option:selected").each(function () {
        if (orderHistory.selectHasChanged(this)) {
          _jquery2['default']('#search').prop("disabled", false);
          orderHistory.showSearch();
        } else {
          if (showClearSearch) {
            orderHistory.showClearSearch();
          } else {
            if (document.getElementById('search-orders').value === "" && document.getElementById('SearchBy').value === "OrderNumber") {
              _jquery2['default']('#search').prop("disabled", true);
            }
          }
        }
      });
    });

    _jquery2['default']('#dateto').on("keyup", function () {
      if (orderHistory.hasInputChanged(this)) {
        _jquery2['default']('#filter').prop("disabled", false);
        orderHistory.showFilter();
      } else {
        if (showClearFilter) {
          orderHistory.showClearFilter();
        } else {
          if (document.getElementById('dateto').value === "" && document.getElementById('datefrom').value === "" && document.getElementById('SearchBy').value === "All") {
            _jquery2['default']('#filter').prop("disabled", true);
          }
        }
      }
    });
    _jquery2['default']('#dateto').on("change", function () {
      var fromDate = document.getElementById('datefrom').value;
      var toDate = document.getElementById('dateto').value;
      if (Date.parse(new Date(fromDate)) > Date.parse(new Date(toDate))) {
        document.getElementById('datefrom').value = toDate;
      }
      if (orderHistory.hasInputChanged(this)) {
        _jquery2['default']('#filter').prop("disabled", false);
        orderHistory.showFilter();
      } else {
        if (showClearFilter) {
          orderHistory.showClearFilter();
        } else {
          if (document.getElementById('dateto').value === "" && document.getElementById('datefrom').value === "" && document.getElementById('SearchBy').value === "All") {
            _jquery2['default']('#filter').prop("disabled", true);
          }
        }
      }
    });

    _jquery2['default']('#datefrom').on("keyup", function () {
      if (orderHistory.hasInputChanged(this)) {
        _jquery2['default']('#filter').prop("disabled", false);
        orderHistory.showFilter();
      } else {
        if (showClearFilter) {
          orderHistory.showClearFilter();
        } else {
          if (document.getElementById('dateto').value === "" && document.getElementById('datefrom').value === "" && document.getElementById('SearchBy').value === "All") {
            _jquery2['default']('#filter').prop("disabled", true);
          }
        }
      }
    });

    _jquery2['default']('#datefrom').on("change", function () {
      var fromDate = document.getElementById('datefrom').value;
      var toDate = document.getElementById('dateto').value;
      if (Date.parse(new Date(fromDate)) > Date.parse(new Date(toDate))) {
        document.getElementById('dateto').value = fromDate;
      }
      if (orderHistory.hasInputChanged(this)) {
        _jquery2['default']('#filter').prop("disabled", false);
        orderHistory.showFilter();
      } else {
        if (showClearFilter) {
          orderHistory.showClearFilter();
        } else {
          if (document.getElementById('dateto').value === "" && document.getElementById('datefrom').value === "" && document.getElementById('SearchBy').value === "All") {
            _jquery2['default']('#filter').prop("disabled", true);
          }
        }
      }
    });

    _jquery2['default']('#OrderStatus').on("change", function () {
      _jquery2['default']("#OrderStatus option:selected").each(function () {
        if (orderHistory.selectHasChanged(this)) {
          _jquery2['default']('#filter').prop("disabled", false);
          orderHistory.showFilter();
        } else {
          if (showClearFilter) {
            orderHistory.showClearFilter();
          } else {
            if (document.getElementById('dateto').value === "" && document.getElementById('datefrom').value === "" && document.getElementById('SearchBy').value === "All") {
              _jquery2['default']('#filter').prop("disabled", true);
            }
          }
        }
      });
    });

    _jquery2['default']('#search-order-history').on("keyup", function (e) {
      if (orderHistory.selectHasChanged(this)) {
        _jquery2['default']('#clear-orderlines').hide();
        _jquery2['default']('#search-orderlines').show().prop("disabled", false);
        if (e.keyCode === 13) {
          //Handle enter key press
          e.preventDefault();
          orderHistory.filterOrderLines();
        }
        orderHistory.filterOrderLines();
      }
      if (_jquery2['default'](this).val() === "") {
        _jquery2['default']('#clear-orderlines').hide();
        _jquery2['default']('#search-orderlines').show();
        _jquery2['default']('#search-orderlines').prop("disabled", this.value.length === 0);
        orderHistory.filterOrderLines();
      }
    }).on('blur', function () {
      if (_jquery2['default'](this).val() === "") {
        _jquery2['default']('#search-orderlines').prop("disabled", this.value.length === 0);
      }
    });

    _jquery2['default']('#search-orderlines').on('click', function (e) {
      e.preventDefault();
      orderHistory.filterOrderLines();
    });

    _jquery2['default']('#clear-orderlines').on('click', function (e) {
      e.preventDefault();
      _jquery2['default']('#clear-orderlines').hide();
      _jquery2['default']('#search-order-history').val('');
      _jquery2['default']('.orderline-wrapper').show();
      _jquery2['default']('#search-orderlines').show().prop("disabled", true);
    });

    _jquery2['default']('.orderline-status-filter input').on('click', function () {
      orderHistory.filterOrderLines();
    });
  },

  filterOrderLines: function filterOrderLines() {
    var stringFilter = _jquery2['default']('#search-order-history').prop('value');
    var selectedStatusFilter = _jquery2['default']('.orderline-status-filter input:checked').attr('value');
    if (selectedStatusFilter === "status-open") {
      _jquery2['default']('.orderline-wrapper').hide();
      _jquery2['default']('.isOpen').parents('.orderline-wrapper').show();
      if (stringFilter !== "") {
        _jquery2['default']('.orderline-wrapper').hide();
        _jquery2['default']('.isOpen').parents('.orderline-wrapper[data-materialid*="' + stringFilter + '"]').show();
        _jquery2['default']('#search-orderlines').hide();
        _jquery2['default']('#clear-orderlines').show();
      }
    } else if (selectedStatusFilter === "status-shipped") {
      _jquery2['default']('.orderline-wrapper').hide();
      _jquery2['default']('.orderline-wrapper').each(function () {
        _jquery2['default']('.isShipped').parents('.orderline-wrapper').show();
        if (stringFilter !== "") {
          _jquery2['default']('.orderline-wrapper').hide();
          _jquery2['default']('.isShipped').parents('.orderline-wrapper[data-materialid*="' + stringFilter + '"]').show();
          _jquery2['default']('#search-orderlines').hide();
          _jquery2['default']('#clear-orderlines').show();
        }
      });
    } else if (selectedStatusFilter === "status-all") {
      _jquery2['default']('.orderline-wrapper').show();
      if (stringFilter !== "") {
        _jquery2['default']('.orderline-wrapper').hide();
        _jquery2['default']('.orderline-wrapper[data-materialid*="' + stringFilter + '"]').show();
        _jquery2['default']('#search-orderlines').hide();
        _jquery2['default']('#clear-orderlines').show();
      }
    }
  },

  hasValue: function hasValue(el) {
    if (el != null && el.value !== "") {
      return true;
    }
    return false;
  },

  selectHasNewValue: function selectHasNewValue(el) {
    if (el != null && (el.value === "OrderNumber" || el.value === "All")) {
      return false;
    }
    return true;
  },

  hasInputChanged: function hasInputChanged(el) {
    if (el != null && el.value !== "" && el.defaultValue !== el.value) {
      return true;
    }
    return false;
  },

  selectHasChanged: function selectHasChanged(el) {
    if (el != null && el.defaultValue !== el.value && el.defaultSeleced !== true) {
      return true;
    }
    return false;
  },

  showClearSearch: function showClearSearch() {
    _jquery2['default']('#search').removeClass('show');
    _jquery2['default']('#clearSearch').addClass('show');
  },

  showSearch: function showSearch() {
    _jquery2['default']('#clearSearch').removeClass('show');
    _jquery2['default']('#search').addClass('show');
  },

  showFilter: function showFilter() {
    _jquery2['default']('#clearFilter').removeClass('show');
    _jquery2['default']('#filter').addClass('show');
  },

  showClearFilter: function showClearFilter() {
    _jquery2['default']('#filter').removeClass('show');
    _jquery2['default']('#clearFilter').addClass('show');
  },
  createDataModel: function createDataModel() {
    if (isOrderHistory) {
      data = {
        'event': 'Order-history-search',
        'page': 'Order history',
        'search_for': document.getElementById('SearchBy').value,
        'search_term': document.getElementById('search-orders').value,
        'date_to': document.getElementById('dateto').value,
        'date_from': document.getElementById('datefrom').value,
        'order_status': document.getElementById('OrderStatus').value
      };
    } else if (isOrderDetailHistory) {
      data = {
        'event': 'Order-history-search',
        'page': 'My open orders',
        'search_term': document.getElementById('search-order-history').value
      };
    } else if (isMyOpenOrder) {
      data = {
        'event': 'Order-history-search',
        'page': 'My open orders',
        'search_for': document.getElementById('SearchBy').value,
        'search_term': document.getElementById('search-orders').value,
        'date_to': document.getElementById('dateto').value,
        'date_from': document.getElementById('datefrom').value
      };
    }
    _libCustomEvents2['default'].triggerDataLayerPush(data);
  }
};

exports['default'] = orderHistory;
module.exports = exports['default'];

},{"../_lib/custom-events":671,"jquery":628}],807:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesPrice_service_store = require('../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _stringformat = require('stringformat');

var _stringformat2 = _interopRequireDefault(_stringformat);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var translations = {};

var ItemFooter = (function (_React$Component) {
	_inherits(ItemFooter, _React$Component);

	function ItemFooter(props) {
		_classCallCheck(this, ItemFooter);

		_React$Component.call(this, props);

		if (this.props.translations) {
			translations.materialNumber = this.props.translations.materialNumber;
			translations.addToCart = this.props.translations.addToCart;
			translations.quickBuy = this.props.translations.quickBuy;
			translations.replacedBy = this.props.translations.replacedBy;
			translations.viewReplacingProduct = this.props.translations.viewReplacingProduct;
			translations.viewDetails = this.props.translations.viewDetails;
			translations.notBuyable = this.props.translations.notBuyable;
			translations.discount = this.props.translations.discount;
			translations.fetchingInfo = this.props.translations.fetchingInfo;
			translations.promotionTitle = this.props.translations.promotionTitle;
			translations.promotionWas = this.props.translations.promotionWas;
			translations.priceError = this.props.translations.priceError;
			translations.grossPrice = this.props.translations.grossPrice;
		}

		this.state = {
			Buyable: false,
			InStockQuantity: 0,
			Loaded: false,
			Code: "",
			Price: "",
			ShippingDate: "",
			IsDiscounted: false,
			DefaultPrice: "",
			DiscountPercent: "",
			ProductContext: {},
			PromotionDiscountPercent: "",
			PromotionPrice: "",
			HasPromotion: false,
			HasError: false
		};
	}

	ItemFooter.prototype.componentDidUpdate = function componentDidUpdate() {
		if (this.state.Loaded) {
			this.reflow();
		}
	};

	ItemFooter.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		//this.reflow();

		var price = _storesPrice_service_store2['default'].getPricesForMaterial(this.props.materialNumber);
		if (price.length > 0) {
			this.setPriceForFooter(price);
		}

		this.unsubscribe = _storesPrice_service_store2['default'].listen(function () {
			if (!_this.state.Loaded) {
				var _price = _storesPrice_service_store2['default'].getPricesForMaterial(_this.props.materialNumber);
				if (_price.length > 0) {
					_this.setPriceForFooter(_price);
				}
			}
		});
	};

	ItemFooter.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	ItemFooter.prototype.setPriceForFooter = function setPriceForFooter(price) {
		this.setState({
			Buyable: price[0].Buyable,
			InStockQuantity: price[0].InStockQuantity,
			Loaded: true,
			Code: price[0].Code,
			Price: price[0].Price,
			ShippingDate: price[0].ShippingDate,
			IsDiscounted: price[0].IsDiscounted,
			DefaultPrice: price[0].DefaultPrice,
			DiscountPercent: price[0].DiscountPercent,
			ProductContext: price[0].ProductContext,
			PromotionDiscountPercent: price[0].PromotionDiscountPercent,
			PromotionPrice: price[0].PromotionPrice,
			HasPromotion: price[0].HasPromotion,
			HasError: price[0].HasError
		});

		var materialNumber = this.state.Code.split('.').join('-');
		var productCardBanner = '';

		if (this.state.HasPromotion) {
			productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-tags"></i></span></div>';
			$('#li-' + materialNumber + ' .image').append(productCardBanner);
		}

		if (!this.state.HasPromotion && this.props.gotScaledPrices && this.state.Buyable) {
			productCardBanner = '<div class="discount-price"><span class="price"><i class="icon-money"></i></span></div>';
			$('#li-' + materialNumber + ' .image').append(productCardBanner);
		}

		this.reflow();
	};

	ItemFooter.prototype.reflow = function reflow() {
		var ua = window.navigator.userAgent;
		var trident = ua.indexOf('Trident/');
		var msie = ua.indexOf('MSIE ');

		if (msie > 0 || trident > 0) {
			Foundation.libs.equalizer.equalize($('.uc-productlist ul'));
			Foundation.libs.equalizer.equalize($('.uc-productlist'));
			Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
			Foundation.libs.equalizer.equalize($('.item-name-watch'));
		} else {
			$(document).foundation('equalizer', 'reflow');
		}
	};

	ItemFooter.prototype.render = function render() {
		return _react2['default'].createElement(
			'div',
			null,
			this.state.Buyable ? _react2['default'].createElement(BuyFooter, { materialNumber: this.state.Code,
				price: this.state.Price,
				inStockQuantity: this.state.InStockQuantity,
				shippingDate: this.state.ShippingDate,
				isDiscounted: this.state.IsDiscounted,
				defaultPrice: this.state.DefaultPrice,
				discountPercent: this.state.DiscountPercent,
				productContext: this.state.ProductContext,
				gotScaledPrices: this.props.gotScaledPrices,
				userIsDealer: this.props.isDealer,
				hasPromotion: this.state.HasPromotion,
				promotionPrice: this.state.PromotionPrice
			}) : !this.state.Buyable && this.state.Loaded ? _react2['default'].createElement(ViewDetailsFooter, { hasError: this.state.HasError, detailsUrl: this.props.url }) : _react2['default'].createElement(FetchPriceFooter, null)
		);
	};

	return ItemFooter;
})(_react2['default'].Component);

exports['default'] = ItemFooter;

var FetchPriceFooter = function FetchPriceFooter(props) {
	return _react2['default'].createElement(
		'div',
		{ className: 'footer loading' },
		_react2['default'].createElement('div', { className: 'campaing-wrapper', 'data-equalizer-watch': 'campaing-wrapper' }),
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center', style: { "display": "block" } }),
			_react2['default'].createElement(
				'span',
				{ className: 'text-center', style: { "display": "block" } },
				translations.fetchingInfo
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
			_react2['default'].createElement(
				'button',
				{ className: 'button left add-to-cart' },
				translations.addToCart
			),
			_react2['default'].createElement(
				'button',
				{ className: 'button right quick-buy' },
				translations.quickBuy
			)
		)
	);
};

var BuyFooter = function BuyFooter(props) {
	var materialNumber = props.materialNumber;
	var price = props.price;
	var inStockQuantity = props.inStockQuantity;
	var shippingDate = props.shippingDate;
	var isDiscounted = props.isDiscounted;
	var defaultPrice = props.defaultPrice;
	var discountPercent = props.discountPercent;
	var productContext = props.productContext;
	var gotScaledPrices = props.gotScaledPrices;
	var promotionPrice = props.promotionPrice;
	var hasPromotion = props.hasPromotion;
	var userIsDealer = props.userIsDealer;

	var materialNumberAsId = materialNumber.split('.').join('-');
	var context = JSON.stringify(productContext);

	var gotScaledPricesIcon = '';

	var dealerIndication = '';
	if (userIsDealer) {
		if (isDiscounted) {
			dealerIndication = translations.promotionWas + ': ';
		} else {
			dealerIndication = translations.grossPrice + ': ';
		}
	}

	var translationGross = translations.discount.substring(0, translations.discount.indexOf('}') + 1);
	var translationDiscount = translations.discount.substring(translations.discount.indexOf('}') + 2).replace("1", "0");
	var translationWas = translations.promotionWas;
	var translationPromoitionDiscount = translations.promotionTitle;

	var defaultPriceText = _stringformat2['default'](translationGross, defaultPrice);
	var discountPercentText = _stringformat2['default'](translationDiscount, discountPercent);
	var promotionPriceText = translationWas + ': ' + price;
	var shippingInfo = null;

	var campaingInfo = _classnames2['default']({
		'campaing-info': true,
		'clearfix': true,
		'default': isDiscounted && hasPromotion,
		'hide': !isDiscounted && !hasPromotion
	});

	var cost = price;
	var hasSelectedWishlist = $('.wishlist-toggle').hasClass('active');

	var savedCartClass = _classnames2['default']({
		'sml': true,
		'button': true,
		'wishlist': true,
		'search-saved-cart-add': true,
		'saved-cart-add': true,
		'right-off-canvas-toggle': !hasSelectedWishlist
	});

	return _react2['default'].createElement(
		'div',
		{ className: 'footer' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement(
				'div',
				{ className: 'price-stock-wrapper' },
				_react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'price', className: 'price left' },
					hasPromotion ? null : gotScaledPricesIcon,
					hasPromotion ? '' + promotionPrice : '' + dealerIndication + price
				),
				inStockQuantity !== undefined && inStockQuantity ? _react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'availability', className: 'stock' },
					_react2['default'].createElement('i', { className: 'icon-cubes' }),
					inStockQuantity
				) : shippingDate !== undefined && shippingDate !== '' ? _react2['default'].createElement(
					'span',
					{ 'data-product-id': materialNumber, 'data-active-tab': 'availability', className: 'stock' },
					_react2['default'].createElement('i', { className: 'icon-cubes' }),
					shippingDate
				) : null
			),
			_react2['default'].createElement(
				'div',
				{ className: campaingInfo },
				isDiscounted && !hasPromotion ? _react2['default'].createElement(
					'span',
					null,
					_react2['default'].createElement(
						'p',
						{ className: 'gross' },
						defaultPriceText
					),
					_react2['default'].createElement(
						'p',
						null,
						discountPercentText
					)
				) : '',
				isDiscounted && hasPromotion ? _react2['default'].createElement(
					'span',
					null,
					_react2['default'].createElement(
						'p',
						{ className: 'gross' },
						defaultPriceText
					),
					_react2['default'].createElement(
						'p',
						null,
						discountPercentText
					),
					_react2['default'].createElement(
						'p',
						{ className: 'default-campaing' },
						promotionPriceText
					)
				) : '',
				!isDiscounted && hasPromotion ? _react2['default'].createElement(
					'span',
					null,
					_react2['default'].createElement(
						'p',
						{ className: 'default-campaing' },
						promotionPriceText
					)
				) : ''
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns', 'data-product-context': context },
			_react2['default'].createElement('input', { 'data-product-sku': materialNumber, className: 'amount', name: 'aumont-x', defaultValue: '1' }),
			_react2['default'].createElement(
				'div',
				{ className: 'buttons' },
				_react2['default'].createElement(
					'button',
					{ 'data-product-sku': materialNumber, className: savedCartClass },
					_react2['default'].createElement('i', { className: 'icon-saved-cart-add' })
				),
				_react2['default'].createElement(
					'button',
					{ 'data-product-sku': materialNumber, className: 'button add-to-cart' },
					_react2['default'].createElement('i', { className: 'icon-minicart' })
				)
			)
		),
		_react2['default'].createElement('div', { id: materialNumberAsId, className: 'SparePartResult-info' })
	);
};

BuyFooter.propTypes = {
	discountPercent: _react2['default'].PropTypes.string,
	defaultPrice: _react2['default'].PropTypes.string,
	materialNumber: _react2['default'].PropTypes.string,
	price: _react2['default'].PropTypes.string,
	inStockQuantity: _react2['default'].PropTypes.number,
	shippingDate: _react2['default'].PropTypes.string
};

var ViewDetailsFooter = function ViewDetailsFooter(props) {
	var detailsUrl = props.detailsUrl;
	var hasError = props.hasError;

	var detailsText = hasError ? translations.priceError : translations.notBuyable;
	return _react2['default'].createElement(
		'div',
		{ className: 'footer' },
		_react2['default'].createElement(
			'div',
			{ className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
			_react2['default'].createElement(
				'span',
				{ className: 'u-txt-center u-dt' },
				detailsText
			)
		),
		_react2['default'].createElement(
			'div',
			{ className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
			_react2['default'].createElement(
				'a',
				{ className: 'button center not-buyable', href: detailsUrl },
				translations.viewDetails
			)
		)
	);
};

ViewDetailsFooter.propTypes = {
	detailsUrl: _react2['default'].PropTypes.string
};
module.exports = exports['default'];

},{"../_stores/price_service_store":723,"classnames":299,"react":525,"stringformat":546}],808:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactLazyLoad = require('react-lazy-load');

var _reactLazyLoad2 = _interopRequireDefault(_reactLazyLoad);

var _componentsSearchSpare_part_footer = require('../components/search/spare_part_footer');

var _componentsSearchSpare_part_footer2 = _interopRequireDefault(_componentsSearchSpare_part_footer);

var _stringformat = require('stringformat');

var _stringformat2 = _interopRequireDefault(_stringformat);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var translations = {};

var ItemResult = (function (_React$Component) {
  _inherits(ItemResult, _React$Component);

  function ItemResult(props) {
    _classCallCheck(this, ItemResult);

    _React$Component.call(this, props);
  }

  ItemResult.prototype.componentDidUpdate = function componentDidUpdate() {
    // this.imgOnLoad();
    if (this.props.GotScaledPrices) {
      $(document).foundation('tooltip', 'reflow');
    }
  };

  ItemResult.prototype.imgOnLoad = function imgOnLoad() {
    var ua = window.navigator.userAgent;
    var trident = ua.indexOf('Trident/');
    var msie = ua.indexOf('MSIE ');
    if (msie > 0 || trident > 0) {
      $(document).ready(function () {
        Foundation.libs.equalizer.equalize($('.result-spare-parts'));
        Foundation.libs.equalizer.equalize($('.uc-productlist'));
        Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
      });
    } else {
      $(document).foundation('equalizer', 'reflow');
    }
  };

  ItemResult.prototype.render = function render() {

    var hasImage = this.props.Images && this.props.Images.length > 0;
    var materialNumberAsId = this.props.MaterialNumber ? 'li-' + this.props.MaterialNumber.split('.').join('-') : "";
    var toolTip = this.props.GotScaledPrices && this.props.IsQueryable ? { 'data-tooltip': 'true' } : null;
    var toolTipTitle = this.props.GotScaledPrices && this.props.IsQueryable ? { 'title': translations.scaledPricesTooltip } : null;
    var toolTipAria = this.props.GotScaledPrices && this.props.IsQueryable ? { 'aria-haspopup': 'true' } : null;
    var translations = hiabconfig.SparePartFooter.lang;
    var itemWrapperClass = _classnames2['default']({
      'item-wrapper': true,
      'has-tip': this.props.GotScaledPrices,
      'tip-top': this.props.GotScaledPrices
    });

    return _react2['default'].createElement(
      'li',
      { id: materialNumberAsId },
      _react2['default'].createElement(
        'div',
        _extends({ className: itemWrapperClass }, toolTip, toolTipTitle, toolTipAria),
        _react2['default'].createElement(
          'div',
          { className: 'image' },
          _react2['default'].createElement('div', { className: 'filler' }),
          hasImage ? _react2['default'].createElement(
            'a',
            { href: this.props.Url },
            _react2['default'].createElement('img', { src: this.props.Images[0].Url + '?preset=list', alt: this.props.Images[0].SeoText })
          ) : null
        ),
        _react2['default'].createElement(
          'div',
          { className: 'item-name', 'data-equalizer-watch': 'item-name' },
          _react2['default'].createElement(
            'h4',
            null,
            _react2['default'].createElement(
              'a',
              { href: this.props.Url },
              this.props.Name
            )
          ),
          _react2['default'].createElement(
            'p',
            null,
            _react2['default'].createElement(
              'span',
              null,
              this.props.MaterialNumber
            )
          ),
          _react2['default'].createElement('div', { className: 'campaing-info' })
        ),
        _react2['default'].createElement(
          'div',
          { className: 'footer-wrapper' },
          this.props.IsReplaced ? _react2['default'].createElement(ReplacementFooter, { replacementUrl: this.props.ReplacementUrl, replacementMaterialNumber: this.props.ReplacementMaterialNumber, translations: translations }) : this.props.IsQueryable && !this.props.IsBlocked ? _react2['default'].createElement(_componentsSearchSpare_part_footer2['default'], _extends({ isDealer: this.props.isDealer, gotScaledPrices: this.props.GotScaledPrices, materialNumber: this.props.MaterialNumber, url: this.props.Url, translations: translations, isBuyable: this.props.IsBuyable }, this.props)) : _react2['default'].createElement(ViewDetailsFooter, { id: materialNumberAsId, signedIn: this.props.userIsSignedIn, detailsUrl: this.props.Url, isBlocked: this.props.IsBlocked, restrictionType: this.props.RestrictionType, translations: translations })
        )
      )
    );
  };

  return ItemResult;
})(_react2['default'].Component);

exports['default'] = ItemResult;

ItemResult.propTypes = {
  name: _react2['default'].PropTypes.string,
  materialNumber: _react2['default'].PropTypes.string,
  url: _react2['default'].PropTypes.string,
  price: _react2['default'].PropTypes.string,
  stock: _react2['default'].PropTypes.string,
  isBuyable: _react2['default'].PropTypes.bool,
  images: _react2['default'].PropTypes.array,
  replacementName: _react2['default'].PropTypes.string,
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

var ReplacementFooter = function ReplacementFooter(props) {
  var replacementMaterialNumber = props.replacementMaterialNumber;
  var replacementUrl = props.replacementUrl;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { 'data-product-id': replacementMaterialNumber, 'data-active-tab': 'other', className: 'u-txt-center replaced text-center', style: { "display": "block" } },
        translations.replacedBy,
        ': ',
        _react2['default'].createElement(
          'a',
          { href: replacementUrl },
          replacementMaterialNumber
        )
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: replacementUrl },
        translations.viewReplacingProduct
      )
    )
  );
};

ReplacementFooter.propTypes = {
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

//shown if not queryable
var ViewDetailsFooter = function ViewDetailsFooter(props) {
  var id = props.id;
  var detailsUrl = props.detailsUrl;
  var signedIn = props.signedIn;
  var isBlocked = props.isBlocked;
  var restrictionType = props.restrictionType;
  var translations = props.translations;

  var materialStatus = isBlocked && restrictionType != null && restrictionType == 'Princeton' ? translations.princeton : signedIn ? translations.notBuyable : translations.notBuyableSignIn;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { className: 'u-txt-center u-dt' },
        materialStatus
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: detailsUrl },
        translations.viewDetails
      )
    )
  );
};

ViewDetailsFooter.propTypes = {
  detailsUrl: _react2['default'].PropTypes.string
};
module.exports = exports['default'];

},{"../components/search/spare_part_footer":783,"classnames":299,"react":525,"react-lazy-load":353,"stringformat":546}],809:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactLazyLoad = require('react-lazy-load');

var _reactLazyLoad2 = _interopRequireDefault(_reactLazyLoad);

var _footer_condensed = require('./footer_condensed');

var _footer_condensed2 = _interopRequireDefault(_footer_condensed);

var _stringformat = require('stringformat');

var _stringformat2 = _interopRequireDefault(_stringformat);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var translations = {};

var CondensedItemResult = (function (_React$Component) {
  _inherits(CondensedItemResult, _React$Component);

  function CondensedItemResult(props) {
    _classCallCheck(this, CondensedItemResult);

    _React$Component.call(this, props);
  }

  CondensedItemResult.prototype.componentDidUpdate = function componentDidUpdate() {
    if (this.props.GotScaledPrices) {
      $(document).foundation('tooltip', 'reflow');
    }
  };

  CondensedItemResult.prototype.imgOnLoad = function imgOnLoad() {
    var ua = window.navigator.userAgent;
    var trident = ua.indexOf('Trident/');
    var msie = ua.indexOf('MSIE ');
    if (msie > 0 || trident > 0) {
      $(document).ready(function () {
        Foundation.libs.equalizer.equalize($('.result-spare-parts'));
        Foundation.libs.equalizer.equalize($('.uc-productlist'));
        Foundation.libs.equalizer.equalize($('.amount-price-stock-watch'));
      });
    } else {
      $(document).foundation('equalizer', 'reflow');
    }
  };

  CondensedItemResult.prototype.render = function render() {
    var hasImage = this.props.Images && this.props.Images.length > 0;

    var materialNumberAsId = this.props.MaterialNumber ? 'li-' + this.props.MaterialNumber.split('.').join('-') : "";
    var toolTip = this.props.GotScaledPrices && this.props.IsQueryable ? { 'data-tooltip': 'true' } : null;
    var toolTipTitle = this.props.GotScaledPrices && this.props.IsQueryable ? { 'title': translations.scaledPricesTooltip } : null;
    var toolTipAria = this.props.GotScaledPrices && this.props.IsQueryable ? { 'aria-haspopup': 'true' } : null;
    var translations = hiabconfig.SparePartFooter.lang;

    var itemWrapperClass = _classnames2['default']({
      'item-wrapper': true,
      'has-tip': this.props.GotScaledPrices,
      'tip-top': this.props.GotScaledPrices
    });

    return _react2['default'].createElement(
      'li',
      { id: materialNumberAsId },
      _react2['default'].createElement(
        'div',
        _extends({ className: itemWrapperClass }, toolTip, toolTipTitle, toolTipAria),
        _react2['default'].createElement(
          'div',
          { className: 'header' },
          _react2['default'].createElement(
            'div',
            { className: 'image' },
            hasImage ? _react2['default'].createElement(
              'a',
              { href: this.props.Url },
              _react2['default'].createElement('img', { src: this.props.Images[0].Url + '?preset=list', alt: this.props.Images[0].SeoText })
            ) : null
          ),
          _react2['default'].createElement(
            'div',
            { className: 'item-name', 'data-equalizer-watch': 'item-name' },
            _react2['default'].createElement(
              'h4',
              null,
              _react2['default'].createElement(
                'a',
                { href: this.props.Url },
                this.props.Name
              )
            ),
            _react2['default'].createElement(
              'p',
              null,
              _react2['default'].createElement(
                'span',
                null,
                this.props.MaterialNumber
              )
            ),
            _react2['default'].createElement('div', { className: 'campaing-info' })
          )
        ),
        _react2['default'].createElement(
          'div',
          { className: 'footer-wrapper' },
          this.props.IsReplaced ? _react2['default'].createElement(ReplacementFooter, { replacementUrl: this.props.ReplacementUrl, replacementMaterialNumber: this.props.ReplacementMaterialNumber, translations: translations }) : this.props.IsQueryable && !this.props.IsBlocked ? _react2['default'].createElement(_footer_condensed2['default'], { isDealer: this.props.isDealer, gotScaledPrices: this.props.GotScaledPrices, materialNumber: this.props.MaterialNumber, url: this.props.Url, translations: translations, isBuyable: this.props.isBuyable }) : _react2['default'].createElement(ViewDetailsFooter, { id: materialNumberAsId, signedIn: this.props.userIsSignedIn, detailsUrl: this.props.Url, isBlocked: this.props.IsBlocked, restrictionType: this.props.RestrictionType, translations: translations })
        )
      )
    );
  };

  return CondensedItemResult;
})(_react2['default'].Component);

exports['default'] = CondensedItemResult;

CondensedItemResult.propTypes = {
  name: _react2['default'].PropTypes.string,
  materialNumber: _react2['default'].PropTypes.string,
  url: _react2['default'].PropTypes.string,
  price: _react2['default'].PropTypes.string,
  stock: _react2['default'].PropTypes.string,
  isBuyable: _react2['default'].PropTypes.bool,
  images: _react2['default'].PropTypes.array,
  replacementName: _react2['default'].PropTypes.string,
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

var ReplacementFooter = function ReplacementFooter(props) {
  var replacementMaterialNumber = props.replacementMaterialNumber;
  var replacementUrl = props.replacementUrl;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { 'data-product-id': replacementMaterialNumber, 'data-active-tab': 'other', className: 'u-txt-center replaced text-center', style: { "display": "block" } },
        translations.replacedBy,
        ': ',
        _react2['default'].createElement(
          'a',
          { href: replacementUrl },
          replacementMaterialNumber
        )
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: replacementUrl },
        translations.viewReplacingProduct
      )
    )
  );
};

ReplacementFooter.propTypes = {
  replacementMaterialNumber: _react2['default'].PropTypes.string,
  replacementUrl: _react2['default'].PropTypes.string
};

//shown if not queryable
var ViewDetailsFooter = function ViewDetailsFooter(props) {
  var id = props.id;
  var detailsUrl = props.detailsUrl;
  var signedIn = props.signedIn;
  var isBlocked = props.isBlocked;
  var restrictionType = props.restrictionType;

  var materialStatus = isBlocked && restrictionType != null && restrictionType == 'Princeton' ? translations.princeton : signedIn ? translations.notBuyable : translations.notBuyableSignIn;

  return _react2['default'].createElement(
    'div',
    { className: 'footer' },
    _react2['default'].createElement(
      'div',
      { className: 'amount-price-stock u-dt', 'data-equalizer-watch': 'amount-price-stock' },
      _react2['default'].createElement(
        'span',
        { className: 'u-txt-center u-dt' },
        materialStatus
      )
    ),
    _react2['default'].createElement(
      'div',
      { className: 'add-to-btns u-dt', 'data-equalizer-watch': 'add-to-btns' },
      _react2['default'].createElement(
        'a',
        { className: 'button center not-buyable', href: detailsUrl },
        translations.viewDetails
      )
    )
  );
};

ViewDetailsFooter.propTypes = {
  detailsUrl: _react2['default'].PropTypes.string
};
module.exports = exports['default'];

},{"./footer_condensed":807,"classnames":299,"react":525,"react-lazy-load":353,"stringformat":546}],810:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _actionsPrice_service_actions = require('../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesPrice_service_store = require('../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _storesSearch_result_store = require('../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _item = require('./item');

var _item2 = _interopRequireDefault(_item);

var List = (function (_React$Component) {
  _inherits(List, _React$Component);

  function List(props) {
    _classCallCheck(this, List);

    _React$Component.call(this, props);
    this.state = {
      isSignedIn: $('body.userLoggedIn').length > 0,
      loading: false,
      isDealer: $('body.is-dealer').length > 0
    };
    this.priceRequest();
  }

  List.prototype.componentDidMount = function componentDidMount() {};

  List.prototype.componentWillUnMount = function componentWillUnMount() {
    RecommendationsStore.unsubscribe();
  };

  List.prototype.priceRequest = function priceRequest() {

    this.props.response.Recommendations.forEach(function (item) {
      if (item.IsQueryable) {
        _actionsPrice_service_actions2['default'].addMaterials(item.MaterialNumber);
      }
    });
    _actionsPrice_service_actions2['default'].fetchPrices(_storesSearch_result_store2['default'].getBatchSize());
  };

  List.prototype.render = function render() {
    var _this = this;

    if (!this.props.response.Recommendations) {
      $(".product-recommendations." + this.props.response.Id).hide();
      return null;
    }

    var resultItems = this.props.response.Recommendations;
    var result = [];

    result = resultItems.map(function (x) {
      return _react2['default'].createElement(_item2['default'], _extends({ isDealer: _this.state.isDealer, userIsSignedIn: _this.state.isSignedIn, key: x.MaterialNumber }, x));
    });

    return _react2['default'].createElement(
      'ul',
      { className: 'list' },
      result
    );
  };

  return List;
})(_react2['default'].Component);

exports['default'] = List;
module.exports = exports['default'];

},{"../_actions/price_service_actions":641,"../_stores/price_service_store":723,"../_stores/search_result_store":725,"./item":808,"react":525}],811:[function(require,module,exports){
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var translations = hiabconfig.SparePartFooter.lang;

var ListSkeleton = (function (_React$Component) {
    _inherits(ListSkeleton, _React$Component);

    function ListSkeleton(props) {
        _classCallCheck(this, ListSkeleton);

        _React$Component.call(this, props);
        this.state = {};
    }

    ListSkeleton.prototype.componentDidMount = function componentDidMount() {};

    ListSkeleton.prototype.componentWillUnMount = function componentWillUnMount() {
        RecommendationsStore.unsubscribe();
    };

    ListSkeleton.prototype.render = function render() {

        return _react2["default"].createElement(
            "ul",
            { className: "result-spare-parts list" },
            _react2["default"].createElement(
                "li",
                null,
                _react2["default"].createElement(
                    "div",
                    { className: "item-wrapper" },
                    _react2["default"].createElement(
                        "div",
                        { className: "image" },
                        _react2["default"].createElement("div", { className: "filler" }),
                        _react2["default"].createElement(
                            "div",
                            { className: "LazyLoad is-visible" },
                            _react2["default"].createElement("img", { src: "/Styles/images/product-placeholder2x2.png", alt: "product name" })
                        ),
                        _react2["default"].createElement("div", { className: "discount-price" })
                    ),
                    _react2["default"].createElement(
                        "div",
                        { className: "item-name skeleton" },
                        _react2["default"].createElement(
                            "span",
                            { classNamename: "text-center" },
                            _react2["default"].createElement("i", { className: "icon-spin4 animate-spin text-center" }),
                            " ",
                            translations.fetchingInfo
                        ),
                        _react2["default"].createElement("div", { className: "campaing-info" })
                    )
                )
            ),
            _react2["default"].createElement(
                "li",
                null,
                _react2["default"].createElement(
                    "div",
                    { className: "item-wrapper" },
                    _react2["default"].createElement(
                        "div",
                        { className: "image" },
                        _react2["default"].createElement("div", { className: "filler" }),
                        _react2["default"].createElement(
                            "div",
                            { className: "LazyLoad is-visible" },
                            _react2["default"].createElement("img", { src: "/Styles/images/product-placeholder2x2.png", alt: "product name" })
                        ),
                        _react2["default"].createElement("div", { className: "discount-price" })
                    ),
                    _react2["default"].createElement(
                        "div",
                        { className: "item-name skeleton" },
                        _react2["default"].createElement(
                            "span",
                            { classNamename: "text-center" },
                            _react2["default"].createElement("i", { className: "icon-spin4 animate-spin text-center" }),
                            " ",
                            translations.fetchingInfo
                        ),
                        _react2["default"].createElement("div", { className: "campaing-info" })
                    )
                )
            ),
            _react2["default"].createElement(
                "li",
                null,
                _react2["default"].createElement(
                    "div",
                    { className: "item-wrapper" },
                    _react2["default"].createElement(
                        "div",
                        { className: "image" },
                        _react2["default"].createElement("div", { className: "filler" }),
                        _react2["default"].createElement(
                            "div",
                            { className: "LazyLoad is-visible" },
                            _react2["default"].createElement("img", { src: "/Styles/images/product-placeholder2x2.png", alt: "product name" })
                        ),
                        _react2["default"].createElement("div", { className: "discount-price" })
                    ),
                    _react2["default"].createElement(
                        "div",
                        { className: "item-name skeleton" },
                        _react2["default"].createElement(
                            "span",
                            { classNamename: "text-center" },
                            _react2["default"].createElement("i", { className: "icon-spin4 animate-spin text-center" }),
                            " ",
                            translations.fetchingInfo
                        ),
                        _react2["default"].createElement("div", { className: "campaing-info" })
                    )
                )
            ),
            _react2["default"].createElement(
                "li",
                null,
                _react2["default"].createElement(
                    "div",
                    { className: "item-wrapper" },
                    _react2["default"].createElement(
                        "div",
                        { className: "image" },
                        _react2["default"].createElement("div", { className: "filler" }),
                        _react2["default"].createElement(
                            "div",
                            { className: "LazyLoad is-visible" },
                            _react2["default"].createElement("img", { src: "/Styles/images/product-placeholder2x2.png", alt: "product name" })
                        ),
                        _react2["default"].createElement("div", { className: "discount-price" })
                    ),
                    _react2["default"].createElement(
                        "div",
                        { className: "item-name skeleton" },
                        _react2["default"].createElement(
                            "span",
                            { classNamename: "text-center" },
                            _react2["default"].createElement("i", { className: "icon-spin4 animate-spin text-center" }),
                            " ",
                            translations.fetchingInfo
                        ),
                        _react2["default"].createElement("div", { className: "campaing-info" })
                    )
                )
            )
        );
    };

    return ListSkeleton;
})(_react2["default"].Component);

exports["default"] = ListSkeleton;
module.exports = exports["default"];

},{"react":525}],812:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var setHeight = 0;
var nameHeight = 0;
var amtHeight = 0;

var reflow = {
  init: function init() {
    _jquery2['default'](window).on("resize", function () {
      reflow.reflow();
    });
  },

  reflow: function reflow(id) {
    var ua = window.navigator.userAgent;
    var trident = ua.indexOf('Trident/');
    var msie = ua.indexOf('MSIE ');
    if (msie > 0 || trident > 0) {
      Foundation.libs.equalizer.equalize(_jquery2['default']('#' + id + ' .amount-price-stock-watch'));
      Foundation.libs.equalizer.equalize(_jquery2['default']('#' + id + ' .item-name-watch'));
    } else {
      _jquery2['default'](document).foundation('equalizer', 'reflow');
    }
    _jquery2['default']('#' + id + ' .recomended-slider  li').each(function (index) {
      if (_jquery2['default'](this).height() > setHeight) {
        setHeight = _jquery2['default'](this).height();
      }
      var itemName = _jquery2['default'](this).children().find('.item-name');
      var amtItem = _jquery2['default'](this).children().find('.footer').children('.amount-price-stock');
      if (itemName.height() > nameHeight) {
        nameHeight = itemName.height();
      }
      if (amtItem.height() > amtHeight) {
        amtHeight = amtItem.height();
      }
    });

    _jquery2['default']('#' + id + ' .recomended-slider .item-name').height(nameHeight);
    _jquery2['default']('#' + id + ' .recomended-slider .amount-price-stock').height(amtHeight);
    _jquery2['default']('#' + id + ' .productdetail-slider').height(setHeight);
    _jquery2['default']('#' + id + ' .uc-product-upsell .lSSlideWrapper').height(setHeight);
  }
};

exports['default'] = reflow;
module.exports = exports['default'];

},{"jquery":628,"react":525}],813:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _list_skeleton = require('./list_skeleton');

var _list_skeleton2 = _interopRequireDefault(_list_skeleton);

var _slider_skeleton = require('./slider_skeleton');

var _slider_skeleton2 = _interopRequireDefault(_slider_skeleton);

var _actionsSalesforce_recommendations_actions = require('../_actions/salesforce_recommendations_actions');

var _actionsSalesforce_recommendations_actions2 = _interopRequireDefault(_actionsSalesforce_recommendations_actions);

var recommendationRequest = {};

var SalesforceRecommendations = {
    init: function init() {

        _jquery2['default']('.load-skeleton-list').each(function () {
            _reactDom2['default'].render(_react2['default'].createElement(_list_skeleton2['default'], null), this);
        });

        _jquery2['default']('.load-skeleton-slider').each(function () {
            _reactDom2['default'].render(_react2['default'].createElement(_slider_skeleton2['default'], null), this);
        });

        _jquery2['default']('.product-recommendations').each(function () {
            recommendationRequest = {
                Id: _jquery2['default'](this).data('id'),
                Type: _jquery2['default'](this).data('recommendation-type'),
                MaterialNumber: _jquery2['default'](this).data('element'),
                NumberOfItems: _jquery2['default'](this).data('amount'),
                CurrentUrl: window.location.href,
                BlockStyle: _jquery2['default'](this).data('blockstyle'),
                LanguageCode: hiabconfig.preferredCulture
            };
            _actionsSalesforce_recommendations_actions2['default'].loadRecommendations(recommendationRequest);
        });
    }
};

exports['default'] = SalesforceRecommendations;
module.exports = exports['default'];

},{"../_actions/salesforce_recommendations_actions":643,"./list_skeleton":811,"./slider_skeleton":815,"jquery":628,"react":525,"react-dom":351}],814:[function(require,module,exports){
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _storesSearch_result_store = require('../_stores/search_result_store');

var _storesSearch_result_store2 = _interopRequireDefault(_storesSearch_result_store);

var _actionsPrice_service_actions = require('../_actions/price_service_actions');

var _actionsPrice_service_actions2 = _interopRequireDefault(_actionsPrice_service_actions);

var _storesPrice_service_store = require('../_stores/price_service_store');

var _storesPrice_service_store2 = _interopRequireDefault(_storesPrice_service_store);

var _item = require('./item');

var _item2 = _interopRequireDefault(_item);

var _item_condensed = require('./item_condensed');

var _item_condensed2 = _interopRequireDefault(_item_condensed);

var _reflow = require('./reflow');

var _reflow2 = _interopRequireDefault(_reflow);

var _lightslider = require('lightslider');

var _lightslider2 = _interopRequireDefault(_lightslider);

var Slider = (function (_React$Component) {
  _inherits(Slider, _React$Component);

  function Slider(props) {
    _classCallCheck(this, Slider);

    _React$Component.call(this, props);
    this.state = {
      isSignedIn: $('body.userLoggedIn').length > 0,
      loading: false,
      isDealer: $('body.is-dealer').length > 0,
      blockId: props.response.Id,
      sliderHeight: 0
    };
  }

  Slider.prototype.componentDidMount = function componentDidMount() {
    var _this = this;

    this.priceRequest();

    var id = this.state.blockId;
    var slider = $("#" + id + ' .recomended-slider').lightSlider({
      controls: false,
      item: 3,
      loop: false,
      slideMove: 1,
      slideMargin: 0,
      speed: 850, //ms'
      auto: false,
      slideEndAnimation: true,
      enableDrag: false,
      adaptiveHeight: true,
      responsive: [{
        breakpoint: 1220,
        settings: {
          item: 3
        }
      }, {
        breakpoint: 920,
        settings: {
          item: 2
        }
      }, {
        breakpoint: 630,
        settings: {
          item: 1
        }
      }],
      onSliderLoad: function onSliderLoad(el) {
        var newSliderWidth = slider.width() + 1;
        slider.width(newSliderWidth);
        slider.addClass('loaded');
      }
    });

    $('#' + id + ' .slider-control.next').on('click', function () {
      slider.goToNextSlide();
    });

    $('#' + id + ' .slider-control.prev').on('click', function () {
      slider.goToPrevSlide();
    });

    this.unsubscribe = _storesPrice_service_store2['default'].listen(function () {
      _this.reflow(slider);
    });
  };

  Slider.prototype.componentWillUnMount = function componentWillUnMount() {
    RecommendationsStore.unsubscribe();
    _storesPrice_service_store2['default'].unsubscribe();
  };

  Slider.prototype.priceRequest = function priceRequest() {
    this.props.response.Recommendations.forEach(function (item) {
      if (item.IsQueryable) {
        _actionsPrice_service_actions2['default'].addMaterials(item.MaterialNumber);
      }
    });
    _actionsPrice_service_actions2['default'].fetchPrices(_storesSearch_result_store2['default'].getBatchSize());
  };

  Slider.prototype.reflow = function reflow(slider) {

    var nameHeight = 0;
    var amountHeight = 0;

    $(slider.children()).each(function (index) {
      if ($(this).find('.item-name').height() > nameHeight) {
        nameHeight = $(this).find('.item-name').height();
      }
      if ($(this).find('.amount-price-stock').height() > amountHeight) {
        amountHeight = $(this).find('.amount-price-stock').height();
      }
    });

    slider.find('.item-name').height(nameHeight);
    slider.find('.amount-price-stock').height(amountHeight);
  };

  Slider.prototype.render = function render() {
    var _this2 = this;

    if (!this.props.response.Recommendations) {
      $(".product-recommendations." + this.props.response.Id).hide();
      return null;
    }

    var resultItems = this.props.response.Recommendations;
    var result = [];

    if (this.props.response.BlockStyle == 'condensed-slider') {
      result = resultItems.map(function (x) {
        return _react2['default'].createElement(_item_condensed2['default'], _extends({ isDealer: _this2.state.isDealer, userIsSignedIn: _this2.state.isSignedIn, key: x.MaterialNumber }, x));
      });
    } else {
      result = resultItems.map(function (x) {
        return _react2['default'].createElement(_item2['default'], _extends({ isDealer: _this2.state.isDealer, userIsSignedIn: _this2.state.isSignedIn, key: x.MaterialNumber }, x));
      });
    }

    return _react2['default'].createElement(
      'div',
      null,
      _react2['default'].createElement(
        'div',
        { className: 'slider-control prev' },
        _react2['default'].createElement('img', { src: '/Styles/images/sliderNav.png', alt: '' })
      ),
      _react2['default'].createElement(
        'div',
        { className: 'slider-control next' },
        _react2['default'].createElement('img', { src: '/Styles/images/sliderNav.png', alt: '' })
      ),
      _react2['default'].createElement(
        'ul',
        { className: 'result-spare-parts recomended-slider', 'data-equalizer-mq': 'medium-up', 'data-options': 'equalize_on_stack: true', 'data-equalizer': 'item-name' },
        result
      )
    );
  };

  return Slider;
})(_react2['default'].Component);

exports['default'] = Slider;
module.exports = exports['default'];

},{"../_actions/price_service_actions":641,"../_stores/price_service_store":723,"../_stores/search_result_store":725,"./item":808,"./item_condensed":809,"./reflow":812,"lightslider":629,"react":525}],815:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var translations = hiabconfig.SparePartFooter.lang;

var SliderSkeleton = (function (_React$Component) {
  _inherits(SliderSkeleton, _React$Component);

  function SliderSkeleton(props) {
    _classCallCheck(this, SliderSkeleton);

    _React$Component.call(this, props);
    this.state = {};
  }

  SliderSkeleton.prototype.componentDidMount = function componentDidMount() {};

  SliderSkeleton.prototype.componentWillUnMount = function componentWillUnMount() {
    RecommendationsStore.unsubscribe();
  };

  SliderSkeleton.prototype.render = function render() {

    var divStyle = {
      width: '100% !important'
    };

    return _react2['default'].createElement(
      'div',
      null,
      _react2['default'].createElement(
        'div',
        { className: 'slider-control prev' },
        _react2['default'].createElement('img', { src: '/Styles/images/sliderNav.png', alt: '' })
      ),
      _react2['default'].createElement(
        'div',
        { className: 'slider-control next' },
        _react2['default'].createElement('img', { src: '/Styles/images/sliderNav.png', alt: '' })
      ),
      _react2['default'].createElement(
        'ul',
        { className: 'result-spare-parts recommendation-slider' },
        _react2['default'].createElement(
          'li',
          null,
          _react2['default'].createElement(
            'div',
            { className: 'item-wrapper skeleton' },
            _react2['default'].createElement(
              'div',
              { className: 'header' },
              _react2['default'].createElement(
                'div',
                { className: 'image' },
                _react2['default'].createElement('img', { src: '/Styles/images/product-placeholder2x2.png', alt: 'product name' })
              ),
              _react2['default'].createElement('div', { className: 'item-name' })
            ),
            _react2['default'].createElement(
              'div',
              { className: 'footer' },
              _react2['default'].createElement(
                'div',
                { className: 'amount-price-stock u-dt ' },
                _react2['default'].createElement(
                  'div',
                  { className: 'text-center', style: divStyle },
                  _react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center' })
                ),
                _react2['default'].createElement(
                  'span',
                  { className: 'text-center' },
                  translations.fetchingInfo
                )
              ),
              _react2['default'].createElement('div', { className: 'add-to-btns u-dt' })
            )
          )
        ),
        _react2['default'].createElement(
          'li',
          null,
          _react2['default'].createElement(
            'div',
            { className: 'item-wrapper skeleton' },
            _react2['default'].createElement(
              'div',
              { className: 'header' },
              _react2['default'].createElement(
                'div',
                { className: 'image' },
                _react2['default'].createElement('img', { src: '/Styles/images/product-placeholder2x2.png', alt: 'product name' })
              ),
              _react2['default'].createElement('div', { className: 'item-name' })
            ),
            _react2['default'].createElement(
              'div',
              { className: 'footer' },
              _react2['default'].createElement(
                'div',
                { className: 'amount-price-stock u-dt' },
                _react2['default'].createElement(
                  'div',
                  { className: 'text-center', style: divStyle },
                  _react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center' })
                ),
                _react2['default'].createElement(
                  'span',
                  { className: 'text-center' },
                  translations.fetchingInfo
                )
              ),
              _react2['default'].createElement('div', { className: 'add-to-btns u-dt' })
            )
          )
        ),
        _react2['default'].createElement(
          'li',
          null,
          _react2['default'].createElement(
            'div',
            { className: 'item-wrapper skeleton' },
            _react2['default'].createElement(
              'div',
              { className: 'header' },
              _react2['default'].createElement(
                'div',
                { className: 'image' },
                _react2['default'].createElement('img', { src: '/Styles/images/product-placeholder2x2.png', alt: 'product name' })
              ),
              _react2['default'].createElement('div', { className: 'item-name' })
            ),
            _react2['default'].createElement(
              'div',
              { className: 'footer' },
              _react2['default'].createElement(
                'div',
                { className: 'amount-price-stock u-dt' },
                _react2['default'].createElement(
                  'div',
                  { className: 'text-center', style: divStyle },
                  _react2['default'].createElement('i', { className: 'icon-spin4 animate-spin text-center' })
                ),
                _react2['default'].createElement(
                  'span',
                  { className: 'text-center' },
                  translations.fetchingInfo
                )
              ),
              _react2['default'].createElement('div', { className: 'add-to-btns u-dt' })
            )
          )
        )
      )
    );
  };

  return SliderSkeleton;
})(_react2['default'].Component);

exports['default'] = SliderSkeleton;
module.exports = exports['default'];

},{"react":525}],816:[function(require,module,exports){
//Extended autocompleter to support search suggestions, pages and columns
'use strict';

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var lang = hiabconfig.search.lang;

_jquery2['default'].widget("custom.smartsearch", _jquery2['default'].ui.autocomplete, {
	bestBetsFacetName: 'bestbet',
	_create: function _create() {
		this._super();
		this.widget().menu("option", "items", "> :not(.bestbets,.leftcol,.rightcol,.fullWidth, .show-all-results)");
	},
	_renderMenu: function _renderMenu(ul, items) {

		if (items[0].loading) {
			this.displayLoading(ul, items);
		} else {
			if (items[0].error || items[0].invalid || items[0].nohits) {
				if (items[0].invalid) this.displayInvalidMessage(ul, items);else if (items[0].error) this.displayErrorMessage(ul, items);else if (items[0].nohits) this.displayNoHitsMessage(ul, items);
			} else {
				if (items[0].facet === 'modeltypes' || items[0].facet === 'serialnumbers' || items[0].facet === 'document') {
					var emptyModal = _jquery2['default']('#machine-modal ul');
					emptyModal.empty();
					this.renderSerialNumbers(ul, items);
				} else {
					if (items.length == 1) {
						this.displayOneColumn(ul, items);
					} else {
						this.divideIntoColumns(ul, items);
					}
				}
			}
		}
	},
	_renderItem: function _renderItem(ul, item) {
		var liItem = _jquery2['default']('<li>');
		var queryPharse = _jquery2['default']('.uc-siteheader #search-main').val().length > 0 ? _jquery2['default']('.uc-siteheader #search-main').val() : _jquery2['default']('.uc-searchmodal #search-main').val();
		var queryVar = '?query=' + queryPharse;
		var itemUrl = item.isDocument ? item.url : item.url + queryVar;
		var url = hiabconfig.explodedViews.explodedViewsURL;

		if (hiabconfig.hasEquipmentTypeRestriction) {
			url = hiabconfig.explodedViews.searchDrawingsPageUrl;
		}

		if (item.ismachine) {
			if (typeof item.materialnumber === 'undefined') {
				liItem.append('<a href="' + url + 'machine-' + itemUrl + '"><i class="icon-model"></i><strong>' + item.label + '</strong><i class="icon-angle-right"></i></a>').appendTo(ul);
			} else {
				liItem.append('<a href="' + url + 'machine-' + itemUrl + '"><i class="icon-model"></i><strong>' + item.label + '</strong><span>' + item.materialnumber + '</span><i class="icon-angle-right"></i></a>').appendTo(ul);
			}
		} else if (item.ismodel) {
			liItem.append('<a href="' + url + 'model-' + itemUrl + '"><i class="icon-model"></i><strong>' + item.label + '</strong><i class="icon-angle-right"></i></a>').appendTo(ul);
		} else if (item.isdocument) {
			liItem.append('<a href="' + itemUrl + '" target="_blank"><strong><i class="icon-doc"></i>' + item.label + '</strong><span>' + hiabconfig.search.lang.openPdf + '<i class="icon-angle-right"></i></span></a>').appendTo(ul);
		} else {
			if (typeof item.materialnumber === 'undefined') {
				liItem.append('<a href="' + itemUrl + '">' + item.label + '</a>').appendTo(ul);
			} else {
				liItem.append('<a href="' + itemUrl + '">' + item.label + '<span>' + item.materialnumber + '</span></a>').appendTo(ul);
			}
		}
		return liItem;
	},
	displayLoading: function displayLoading(ul, items) {
		ul.removeClass('serial-number-result');
		ul.addClass('ui-state-disabled');
		var spinner = _jquery2['default']('<li>').addClass('spinner').text(items[0].label).append('<i class="animate-spin icon-spin4"></i>');
		spinner.appendTo(ul);
	},
	displayNoHitsMessage: function displayNoHitsMessage(ul, items) {
		ul.removeClass('serial-number-result');
		ul.addClass('ui-state-disabled');
		var noHits = _jquery2['default']('<li>').addClass('no-hits').text(items[0].label);
		noHits.appendTo(ul);
	},
	displayInvalidMessage: function displayInvalidMessage(ul, items) {
		ul.removeClass('serial-number-result');
		var noHits = _jquery2['default']('<li>').addClass('no-hits').text(items[0].label);
		noHits.appendTo(ul);
	},
	displayErrorMessage: function displayErrorMessage(ul, items) {
		ul.removeClass('serial-number-result');
		var error = _jquery2['default']('<li>').addClass('no-hits').html('<i class="icon-attention-circled"></i> ' + items[0].label);
		error.appendTo(ul);
	},
	renderSerialNumbers: function renderSerialNumbers(ul, items) {
		var that = this;

		ul.addClass('serial-number-result');
		ul.addClass('clearfix');

		var facetGroups = [];

		facetGroups = _lodash2['default'].groupBy(items, function (item) {
			return item.facet;
		});

		_jquery2['default']('<li>').addClass('fullWidth').appendTo(ul);

		_jquery2['default'].each(facetGroups, function (index, facetItem) {

			var facetLabel = facetItem[0].facetlabel.replace(/\s/g, "");
			var models = facetItem[0].facet === 'modeltypes' ? true : false;
			var headingItem = "";
			var loadMore = models && facetItem[0].results.length > 5;

			if (models && facetItem[0].results.length > 1) {
				var margin = "";
				if (Object.keys(facetGroups).length > 1) {
					margin = "model-type";
				}
				headingItem = _jquery2['default']('<div class="clearfix ' + margin + '">').append('<h3>' + facetItem[0].facetlabel + '<span class="info">' + hiabconfig.search.lang.info + '</span>' + '</h3>');
			} else {
				headingItem = headingItem = _jquery2['default']('<div class="clearfix">').append('<h3>' + facetItem[0].facetlabel + '</h3>');
			}

			_jquery2['default']('li.fullWidth', ul).append(headingItem);

			var subItems = _jquery2['default']('<ul>');
			subItems.attr('id', facetLabel);
			subItems.addClass('serial-result-column');
			headingItem.append(subItems);

			_jquery2['default'].each(facetItem[0].results, function (i, item) {
				if (i < 5) {
					that._renderItemData(headingItem.find('ul'), item);
				}
			});

			if (loadMore) {
				(function () {
					var viewAllModal = _jquery2['default']('#machine-modal ul');
					var header = _jquery2['default']('<h4>' + facetItem[0].facetlabel + '</h3>');
					var url = hiabconfig.explodedViews.explodedViewsURL;

					if (hiabconfig.hasEquipmentTypeRestriction) {
						url = hiabconfig.explodedViews.searchDrawingsPageUrl;
					}

					viewAllModal.append(header);

					_jquery2['default'].each(facetItem[0].results, function (i, item) {
						var liItem = _jquery2['default']('<li>');
						liItem.append('<a href="' + url + 'model-' + item.url + '"><i class="icon-model"></i><strong>' + item.label + '</strong>' + item.materialnumber + '<i class="icon-angle-right"></i></a>').appendTo(viewAllModal);
					});
					var submit = _jquery2['default']('<li id="show-machine-modal" class="show-all-results"><button type="submit" class="button">' + lang.showAllResults + ' (' + facetItem[0].hits + ') </button></li>');
					submit.appendTo(ul);
				})();
			}
		});

		_jquery2['default']("#show-machine-modal").on('click', function () {
			_jquery2['default']('#machine-modal').foundation('reveal', 'open');
		});

		ul.removeClass('ui-state-disabled');
	},
	displayOneColumn: function displayOneColumn(ul, items) {
		ul.removeClass('serial-number-result');
		var that = this;
		var facetGroups = [];
		facetGroups = _lodash2['default'].groupBy(items, function (item) {
			return item.facet;
		});
		//Create columns
		_jquery2['default']('<li>').addClass('bestbets').appendTo(ul);
		_jquery2['default']('<li>').addClass('fullWidth').appendTo(ul);

		_jquery2['default'].each(facetGroups, function (index, facetItem) {

			var headingItem = _jquery2['default']('<div>').append('<h3>' + facetItem[0].facetlabel + '</h3>');
			var subItems = _jquery2['default']('<ul>');

			subItems.addClass('clearfix');
			headingItem.append(subItems);

			_jquery2['default']('li.fullWidth', ul).append(headingItem);

			//Render items
			_jquery2['default'].each(facetItem[0].results, function (i, item) {
				that._renderItemData(headingItem.find('ul'), item);
			});
		});

		var submit = _jquery2['default']('<li class="show-all-results"><button type="submit" class="button">' + lang.showAllResults + '</button></li>');
		submit.appendTo(ul);

		ul.removeClass('ui-state-disabled');
	},
	divideIntoColumns: function divideIntoColumns(ul, items) {
		ul.removeClass('serial-number-result');

		var that = this;
		var facetGroups = [];
		facetGroups = _lodash2['default'].groupBy(items, function (item) {
			return item.facet;
		});

		var numOfItemsInCol = Math.ceil((_lodash2['default'].size(facetGroups) - 1) / 2);

		//Create columns
		_jquery2['default']('<li>').addClass('bestbets').appendTo(ul);
		_jquery2['default']('<li>').addClass('leftcol').appendTo(ul);
		_jquery2['default']('<li>').addClass('rightcol').appendTo(ul);

		var counter = 0;

		_jquery2['default'].each(facetGroups, function (index, facetItem) {

			var headingItem = _jquery2['default']('<div>').append('<h3>' + facetItem[0].facetlabel + '</h3>');
			var subItems = _jquery2['default']('<ul>');

			subItems.addClass('clearfix');
			headingItem.append(subItems);

			if (facetItem[0].facet === that.bestBetsFacetName) {
				//Append to best bets search
				_jquery2['default']('li:first', ul).append(headingItem);
			} else {
				//Split into columns
				if (counter < numOfItemsInCol) _jquery2['default']('li.leftcol', ul).append(headingItem);else _jquery2['default']('li.rightcol', ul).append(headingItem);
				counter++;
			}

			//Render items
			_jquery2['default'].each(facetItem[0].results, function (i, item) {
				that._renderItemData(headingItem.find('ul'), item);
			});
		});

		var submit = _jquery2['default']('<li class="show-all-results"><button type="submit" class="button">' + lang.showAllResults + '</button></li>');
		submit.appendTo(ul);

		ul.removeClass('ui-state-disabled');
	}

});

},{"jquery":628,"lodash":333}],817:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _jqueryUi = require('jquery.ui');

var _jqueryUi2 = _interopRequireDefault(_jqueryUi);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _autocompleter = require('./autocompleter');

var _autocompleter2 = _interopRequireDefault(_autocompleter);

var _libCustomSearchEvents = require('../_lib/custom-search-events');

var _libCustomSearchEvents2 = _interopRequireDefault(_libCustomSearchEvents);

var searchVal = '';
var searchingForSerial = false;
var isOnSearchPage = false;
var inputField = [];

var smartsearch = {
	init: function init(searchSerial, searchPage) {
		searchingForSerial = searchSerial;
		isOnSearchPage = searchPage;
		var searchPath = searchingForSerial ? hiabconfig.search.serialSearchApi : hiabconfig.search.smartSearchApi;

		// Handle key focus click
		_jquery2['default']('.search-main').bind('focus click', this.handleFocus);

		// Ensures that we only have one event handler firing wheneve the event is triggered.
		// There seems to be something in the code base that runs this init-method several times, meaning that we end up with too many handlers.
		_jquery2['default']('.search-main').off('keydown').on('keydown', this.handleKeyDown);

		_jquery2['default']('body').on('click', '.js-init-search', function (e) {
			smartsearch.triggerSerialSearch(e);
		});

		//Create autocompleter
		_jquery2['default']('.uc-searchmodal #search-main, .uc-siteheader #search-main').each(function (index) {
			var scope = _jquery2['default'](this).parents('.uc-searchfield');

			inputField[index] = _jquery2['default'](this).smartsearch({
				appendTo: _jquery2['default']('form', scope),
				delay: 300,
				minLength: 1,
				open: function open(event, ui) {
					_jquery2['default']('.uc-searchfield').removeClass('is-loading');

					var autocomplete = _jquery2['default']('.ui-autocomplete', scope);
					searchVal = inputField[index].val();
					//Remove tabindex
					autocomplete.removeAttr('tabindex');
					_jquery2['default']('li', autocomplete).removeAttr('tabindex');
					_jquery2['default']('button', autocomplete).removeAttr('tabindex');
				},
				close: function close(event, ui) {
					if (_jquery2['default']('.uc-searchmodal.is-open').length > 0 || _jquery2['default']('body.searchmodal-open').length > 0) {
						if (_jquery2['default']('.uc-searchmodal ul.ui-autocomplete').children().hasClass('spinner')) {
							_jquery2['default']('.uc-searchfield').removeClass('is-loading');
							_jquery2['default']('.ui-autocomplete').empty();
							_jquery2['default']('.ui-autocomplete').hide();
							return true;
						} else {
							_jquery2['default']('.uc-searchmodal ul.ui-autocomplete').show();
							return false;
						}
					} else {
						_jquery2['default']('.uc-searchfield').removeClass('is-loading');
						_jquery2['default']('.ui-autocomplete').empty();
						_jquery2['default']('.ui-autocomplete').hide();
					}
				},
				response: function response(event, ui) {
					_jquery2['default']('.uc-searchfield').removeClass('is-loading');
					_jquery2['default']('.ui-autocomplete').show();
				},

				search: function search() {
					_jquery2['default']('.ui-autocomplete ').show();
					_jquery2['default'](this).parents('.uc-searchfield').addClass('is-loading');
				},

				source: function source(req, res) {
					// New request 300ms after key stroke
					var $this = _jquery2['default'](this);
					var $element = _jquery2['default'](this.element);
					var previous_request = $element.data("jqXHR");
					if (previous_request) {
						// a previous request has been made.
						// though we don't know if it's concluded
						// we can try and kill it in case it hasn't
						previous_request.abort();
					}
					$element.data("jqXHR", _jquery2['default'].ajax({
						type: 'GET',
						url: searchPath + encodeURIComponent(req.term),
						dataType: 'json',
						beforeSend: function beforeSend() {

							if (searchingForSerial) {
								if (req.term.length < 4) {
									res([{
										'label': hiabconfig.search.lang.invalidLength,
										'val': -1,
										'invalid': true,
										'error': false
									}]);
									return false;
								} else if (/^[a-z]+$/i.test(req.term)) {
									res([{
										'label': hiabconfig.search.lang.invalidCharacters,
										'val': -1,
										'invalid': true,
										'error': false
									}]);
									return false;
								} else {
									res([{
										'label': hiabconfig.search.lang.searchingSerial,
										'val': -1,
										'invalid': false,
										'error': false,
										'loading': true
									}]);
									return true;
								}
							} else {
								res([{
									'label': hiabconfig.search.lang.searching,
									'val': -1,
									'invalid': false,
									'error': false,
									'loading': true
								}]);
								return true;
							}
						},
						success: function success(search) {
							if (search.findServiceErrorMessage === '') {
								var c = [];
								_jquery2['default'].each(search.results, function (index, item) {
									c.push(item);
								});

								if (search.hits === 0) {
									var noHitsTerm = searchingForSerial ? hiabconfig.search.lang.noResultsSerial : hiabconfig.search.lang.noResults;
									res([{
										'label': noHitsTerm,
										'val': -1,
										'nohits': true
									}]);
								} else {
									res(c);
								}
							} else {
								res([{
									'label': search.findServiceErrorMessage,
									'val': -1,
									'nohits': false,
									'error': true
								}]);
							}

							_libCustomSearchEvents2['default'].trackQuickSearch(req.term, search.hits, search.results);
						},
						error: function error(data) {
							res([{
								'label': hiabconfig.search.lang.errorMsg,
								'val': -1,
								'nohits': false,
								'error': true
							}]);
						}
					}));
				}
			});
		});
	},

	handleKeyDown: function handleKeyDown(event) {

		if (searchingForSerial) {
			_jquery2['default'](this).smartsearch({ disabled: true });
		}

		//Get a flat list
		var list = _jquery2['default']('.ui-autocomplete li ul li');
		var $element = _jquery2['default'](this);
		if (event.keyCode == _jquery2['default'].ui.keyCode.ENTER) {
			_jquery2['default'](this).smartsearch({ disabled: false });

			var selectedItem = _jquery2['default']('.ui-autocomplete .ui-state-focus a');
			if (selectedItem.length > 0) {
				//Search or navigate?
				if (selectedItem.parents('.bestbets').length > 0) {
					return;
				} else {

					if (selectedItem.attr('target') === '_blank') {
						window.open(selectedItem.attr('href'));
						return false;
					}

					window.location.href = selectedItem.attr('href');
					return false;
				}
			} else {
				if (!searchingForSerial) {
					$element.data("jqXHR").abort();
					_jquery2['default']('#search-field .uc-searchfield button').addClass('loading');
					_jquery2['default']('.uc-searchfield').removeClass('is-loading');
					_jquery2['default'](".ui-autocomplete").each(function (index) {
						_jquery2['default'](this).empty();
						_jquery2['default'](this).hide();
					});
				} else {
					smartsearch.triggerSerialSearch(event);
				}
			}
		}

		if (event.keyCode == _jquery2['default'].ui.keyCode.UP || event.keyCode == _jquery2['default'].ui.keyCode.DOWN) {

			if (event.keyCode == _jquery2['default'].ui.keyCode.DOWN) {
				var selectnext = _jquery2['default'].map(list, function (item, index) {
					if (_jquery2['default'](item).is('.ui-state-focus')) {
						return list[index + 1];
					}
				});
				if (selectnext.length === 0) selectnext = list[0];
				_jquery2['default'](list).removeClass('ui-state-focus');
				_jquery2['default'](selectnext).addClass('ui-state-focus');

				if (_jquery2['default'](selectnext).parents('li').is('.bestbets')) {
					_jquery2['default']('#search-main').val(_jquery2['default'](selectnext).text());
				} else {
					_jquery2['default']('#search-main').val(searchVal);
				}
			}
			if (event.keyCode == _jquery2['default'].ui.keyCode.UP) {
				var selectnext = _jquery2['default'].map(list, function (item, index) {
					if (_jquery2['default'](item).is('.ui-state-focus')) {
						return list[index - 1];
					}
				});
				if (selectnext.length === 0) selectnext = list[list.length - 1];

				_jquery2['default'](list).removeClass('ui-state-focus');
				_jquery2['default'](selectnext).addClass('ui-state-focus');

				if (_jquery2['default'](selectnext).parents('li').is('.bestbets')) {
					_jquery2['default']('#search-main').val(_jquery2['default'](selectnext).text());
				} else {
					_jquery2['default']('#search-main').val(searchVal);
				}
			}

			event.stopImmediatePropagation();
		}
	},
	setContext: function setContext(searchingForSerial, searchPage) {
		searchingForSerial = searchingForSerial;
		isOnSearchPage = searchPage;
	},
	handleFocus: function handleFocus() {
		if (isOnSearchPage) {
			return false;
		} else {
			if (searchingForSerial) {
				return false;
			} else {
				if (_jquery2['default']('#search-field .uc-searchfield .ui-autocomplete-input').length > 0 && _jquery2['default']('body.searchmodal-open').length == 0) {
					_jquery2['default'](inputField).each(function (index) {
						if (inputField[index].val().length > 0) {
							inputField[index].smartsearch('search', inputField[index].val());
						}
					});
				}
			}
		}

		_jquery2['default']('.ui-autocomplete li ul li, .ui-autocomplete .show-all-results').removeClass('ui-state-focus');
	},

	triggerSerialSearch: function triggerSerialSearch(event) {
		if (typeof event !== "undefined" && searchingForSerial) {

			event.stopImmediatePropagation();

			_jquery2['default'](inputField).each(function (index) {
				if (inputField[index].val().length > 0) {
					inputField[index].smartsearch({ disabled: false });
					inputField[index].smartsearch('search', inputField[index].val());
				}
			});
		}
		_jquery2['default']('#search-main').focus();
	},

	destroyAutoComplete: function destroyAutoComplete() {
		_jquery2['default'](inputField).each(function (index) {
			inputField[index].smartsearch('destroy');
		});
	}

};
exports['default'] = smartsearch;
module.exports = exports['default'];

},{"../_lib/custom-search-events":672,"./autocompleter":816,"jquery":628,"jquery.ui":624,"lodash":333}],818:[function(require,module,exports){
(function (global){
// React has to be provided through the global(window in browser) object to allow dynamically
// hooking into components rendered on the server.
'use strict';

global.React = require('react');
global.ReactDOM = require('react-dom');
global.ReactDOMServer = require('react-dom/server');

// global.ProductStore = require('./_stores/product_store');
global.SortStore = require('./_stores/sort_store');
global.BrandFilterStore = require('./_stores/brand_filter_store');
global.UsageTypeFilterStore = require('./_stores/usage_type_filter_store');
global.ProductLineFilterStore = require('./_stores/product_line_filter_store');
global.SerialNumberFilterStore = require('./_stores/serial_number_filter_store');
global.TopCategoryFilterStore = require('./_stores/top_category_filter_store');
global.CategoryFilterStore = require('./_stores/category_filter_store');
global.LocalizationStore = require('./_stores/localization_store');
global.SearchResultStore = require('./_stores/search_result_store');
global.SearchStore = require('./_stores/search_store');

global.SearchHeader = require('./components/search/search_header');
global.GroupSelector = require('./components/search/group_selector');
global.ResultList = require('./components/search/result_list');
global.Filters = require('./components/filter/filters');

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"./_stores/brand_filter_store":697,"./_stores/category_filter_store":700,"./_stores/localization_store":719,"./_stores/product_line_filter_store":724,"./_stores/search_result_store":725,"./_stores/search_store":726,"./_stores/serial_number_filter_store":727,"./_stores/sort_store":728,"./_stores/top_category_filter_store":730,"./_stores/usage_type_filter_store":732,"./components/filter/filters":761,"./components/search/group_selector":778,"./components/search/result_list":780,"./components/search/search_header":782,"react":525,"react-dom":351,"react-dom/server":352}],819:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var _address_field = require('./address_field');

var _address_field2 = _interopRequireDefault(_address_field);

var _country_region_container = require('./country_region_container');

var _country_region_container2 = _interopRequireDefault(_country_region_container);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesUser_country_options_store = require('../_stores/user_country_options_store');

var _storesUser_country_options_store2 = _interopRequireDefault(_storesUser_country_options_store);

var _storesAddress_field_store = require('../_stores/address_field_store');

var _storesAddress_field_store2 = _interopRequireDefault(_storesAddress_field_store);

var _storesUser_addresses_store = require('../_stores/user_addresses_store');

var _storesUser_addresses_store2 = _interopRequireDefault(_storesUser_addresses_store);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var alternativeLayout = hiabconfig.marketId == "JP02" ? true : false;

var UserAddressesAddItem = (function (_React$Component) {
	_inherits(UserAddressesAddItem, _React$Component);

	function UserAddressesAddItem(props) {
		var _this = this;

		_classCallCheck(this, UserAddressesAddItem);

		_React$Component.call(this, props);

		this.handleToggle = function (formId) {
			_jquery2['default']('#' + formId).toggleClass('adding');
			_this.resetForm();
		};

		this.setAddressItem = function (key, value) {
			_this.state.item[key] = value;
			_this.setState({
				item: _this.state.item,
				canSubmit: _this.validateForm()
			});
			_this.forceUpdate();
		};

		this.handleSubmit = function (e) {
			e.preventDefault();
		};

		this.state = {
			item: {},
			countryOptions: [],
			canSubmit: false,
			regionValue: 'no',
			changed: false,
			isEditing: false,
			saved: false,
			makeDefault: false,
			execute: false,
			isLoading: false
		};

		this.state.item = {
			IsDefault: false,
			AddressId: '',
			Modified: new Date(),
			CompanyName: '',
			FirstName: '',
			LastName: '',
			CountryName: '',
			CountryCode: 'default',
			City: '',
			PostalCode: '',
			Line1: '',
			Line2: '',
			Region: '',
			Email: '',
			DaytimePhoneNumber: '',
			regionValue: 'default'
		};

		this.elements = {};
	}

	UserAddressesAddItem.prototype.resetForm = function resetForm() {
		var item = {
			IsDefault: false,
			AddressId: '',
			Modified: new Date(),
			CompanyName: '',
			FirstName: '',
			LastName: '',
			CountryName: '',
			CountryCode: 'default',
			City: '',
			PostalCode: '',
			Line1: '',
			Line2: '',
			Region: '',
			Email: '',
			DaytimePhoneNumber: '',
			regionValue: 'default'
		};
		this.setDirty(false);
		this.setState({
			item: item,
			countryOptions: _storesUser_country_options_store2['default'].getCountryOptions()
		});
	};

	UserAddressesAddItem.prototype.setDirty = function setDirty(isDirty) {
		var _this2 = this;

		Object.keys(this.elements).forEach(function (key) {
			_this2.elements[key].setState({
				isDirty: isDirty
			});
		});
	};

	UserAddressesAddItem.prototype.create = function create(e) {
		e.stopPropagation();
		if (e.target.tagName !== 'BUTTON') {
			e.target = e.target.parentElement;
		}

		if (!e.target.disabled) {
			_actionsUser_addresses_actions2['default'].checkPostalCode(this.state.item.CountryCode, this.state.item.PostalCode);
			if (this.validateForm()) {
				this.setState({
					isLoading: true
				});
				this.state.execute = true;
			}
		}
	};

	UserAddressesAddItem.prototype.validateForm = function validateForm() {
		var _this3 = this;

		return Object.keys(this.elements).every(function (key) {
			return _this3.elements[key].state.isValid && _jquery2['default']('#create-address input.invalid').length === 0 && _jquery2['default']('#create-address select.invalid').length === 0;
		});
	};

	UserAddressesAddItem.prototype.makeDefault = function makeDefault(e) {
		e.stopPropagation();
		if (e.target.tagName !== 'BUTTON') {
			e.target = e.target.parentElement;
		}
		var stop = e.target.disabled;

		if (!stop && this.validateForm()) {
			/*&& this.validPostalCode(e.target)*/
			this.state.makeDefault = true;
			this.state.execute = true;
			_actionsUser_addresses_actions2['default'].checkPostalCode(this.state.item.CountryCode, this.state.item.PostalCode);
			this.setState({
				isLoading: true
			});
		}
	};

	UserAddressesAddItem.prototype.componentDidMount = function componentDidMount() {
		var _this4 = this;

		this.unsubscribe = _storesUser_country_options_store2['default'].listen(function () {
			if (_this4.state.saved) {
				_this4.resetForm();
			} else {
				_this4.setState({
					countryOptions: _storesUser_country_options_store2['default'].getCountryOptions()
				});
			}
		});

		this.validateForm();

		this.createAdress = _storesUser_addresses_store2['default'].listen(function (res) {
			_this4.setState({
				isLoading: false
			});
		});

		this.createAdress = _storesAddress_field_store2['default'].listen(function (res) {

			if (!res) {
				_jquery2['default']('#create-address input[name="ShippingAddress.PostalCode"]').addClass('invalid');
			} else {
				_jquery2['default']('#create-address input[name="ShippingAddress.PostalCode"]').removeClass('invalid');
			}

			_this4.setState({
				canSubmit: res && _this4.validateForm()
			});

			if (_this4.state.execute) {
				if (res) {
					if (_this4.state.makeDefault) {
						_this4.setAddressItem('IsDefault', !_this4.state.item.IsDefault);
						_this4.state.makeDefault = false;
					}
					_actionsUser_addresses_actions2['default'].createAddress(_this4.state.item);
					_this4.setState({
						saved: true,
						canSubmit: false
					});
				} else {
					_this4.setState({
						canSubmit: false
					});

					_this4.elements.postalcode.setState({
						isValid: false
					});
				}
				_this4.state.execute = false;
			}
		});
	};

	UserAddressesAddItem.prototype.componentWillUnmount = function componentWillUnmount() {
		this.createAdress();
	};

	UserAddressesAddItem.prototype.render = function render() {
		var _this5 = this;

		if (!this.state) return null;
		if (!this.state.item) return null;

		var item = this.state.item;
		var lang = hiabconfig.addresses.lang;
		var formId = "create-address";

		var formClassNames = _classnames2['default']({
			'row': true,
			'user-address': true,
			'collapse': true,
			'add-new': true,
			'is-loading': this.state.isLoading
		});

		var defaultButton = _react2['default'].createElement(
			'button',
			{ disabled: !this.validateForm(), onClick: this.makeDefault.bind(this), type: 'button', className: 'button make-default ' },
			_react2['default'].createElement('i', { className: 'icon-check', onClick: this.makeDefault.bind(this) }),
			_react2['default'].createElement(
				'span',
				{ onClick: this.makeDefault.bind(this) },
				lang.makeDefault
			)
		);

		if (item.IsDefault == true) {
			defaultButton = _react2['default'].createElement(
				'button',
				{ disabled: !this.validateForm(), onClick: this.makeDefault.bind(this), type: 'button', className: 'button make-default ' },
				_react2['default'].createElement('i', { className: 'icon-check', onClick: this.makeDefault.bind(this) }),
				_react2['default'].createElement(
					'span',
					{ onClick: this.makeDefault.bind(this) },
					lang.resetDefault
				)
			);
		}

		var postalCodeInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.postalcode = c;
			}, name: 'PostalCode', countryCode: this.state.item.CountryCode, value: item.PostalCode, setAddressItem: this.setAddressItem.bind(this), label: lang.postalCode, validator: 'minLength', minLength: '1', maxLength: '10' });

		var countryRegionSelect = _react2['default'].createElement(_country_region_container2['default'], { ref: function (c) {
				return _this5.elements.countryRegionContainer = c;
			}, setAddressItem: this.setAddressItem.bind(this), countryOptions: this.state.countryOptions, item: item });

		if (alternativeLayout) {
			countryRegionSelect = _react2['default'].createElement(_country_region_container2['default'], { ref: function (c) {
					return _this5.elements.countryRegionContainer = c;
				}, setAddressItem: this.setAddressItem.bind(this), countryOptions: this.state.countryOptions, postalCode: postalCodeInput, item: item });
		}

		var companyNameInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.companyname = c;
			}, name: 'CompanyName', value: item.CompanyName, setAddressItem: this.setAddressItem.bind(this), label: lang.companyname, validator: 'minLength', minLength: '2', maxLength: '35' });
		var additionalInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.firstname = c;
			}, name: 'FirstName', value: item.FirstName, setAddressItem: this.setAddressItem.bind(this), label: lang.firstname, validator: 'minLength', minLength: '0', maxLength: '35' });
		var phoneInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.phonenumber = c;
			}, name: 'DaytimePhoneNumber', value: item.DaytimePhoneNumber, setAddressItem: this.setAddressItem.bind(this), label: lang.phoneNumber, errorMessage: lang.errorPhone, validator: 'phone', minLength: '2', maxLength: '15' });
		var emailInput = hiabconfig.addresses.emailFieldEnabled ? _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.email = c;
			}, name: 'Email', value: item.Email, setAddressItem: this.setAddressItem.bind(this), label: lang.eMail, validator: 'email', errorMessage: hiabconfig.addresses.lang.errorMail, maxLength: '241' }) : null;
		var line1Input = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.line1 = c;
			}, name: 'Line1', value: item.Line1, setAddressItem: this.setAddressItem.bind(this), label: lang.street, otherAddressField: item.Line2, validator: 'minLength', minLength: '2', maxLength: '35' });
		var line2Input = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.line2 = c;
			}, name: 'Line2', value: item.Line2, setAddressItem: this.setAddressItem.bind(this), otherAddressField: item.Line1, validator: 'minLength', minLength: '0', maxLength: '40' });

		var cityInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this5.elements.city = c;
			}, name: 'City', value: item.City, setAddressItem: this.setAddressItem.bind(this), label: lang.city, validator: 'minLength', minLength: '2', maxLength: '35' });

		return _react2['default'].createElement(
			'div',
			null,
			_react2['default'].createElement(
				'div',
				{ className: 'uc-user-addresses' },
				_react2['default'].createElement(
					'form',
					{ id: 'create-address', className: formClassNames, onSubmit: this.handleSubmit.bind(this) },
					_react2['default'].createElement(
						'label',
						{ className: 'u-mb-0', htmlFor: 'AddressId' },
						_react2['default'].createElement('input', { ref: 'addressId', className: 'AddressId', type: 'hidden', defaultValue: item.AddressId })
					),
					_react2['default'].createElement(
						'label',
						{ className: 'u-mb-0', htmlFor: 'Modified' },
						_react2['default'].createElement('input', { ref: 'modified', className: 'Modified', type: 'hidden', defaultValue: new Date() })
					),
					_react2['default'].createElement(
						'label',
						{ htmlFor: 'IsDefault', className: 'u-mb-0' },
						_react2['default'].createElement('input', { ref: 'isDeault', className: 'IsDefault', type: 'radio', defaultValue: 'false', defaultChecked: true, hidden: true })
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns medium-4 small-10 address-title' },
						' '
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns medium-8 small-2 edit-toggle' },
						_react2['default'].createElement(
							'button',
							{ className: 'button circle right edit-toggle-button', onClick: this.handleToggle.bind(this, formId) },
							_react2['default'].createElement('i', { className: 'icon-addressediting' })
						),
						_react2['default'].createElement(
							'nav',
							{ className: 'addressediting-menu small-hidden' },
							_react2['default'].createElement(
								'ul',
								null,
								_react2['default'].createElement(
									'li',
									null,
									_react2['default'].createElement(
										'button',
										{ disabled: !this.state.canSubmit, onClick: this.create.bind(this), type: 'button', className: 'button save' },
										_react2['default'].createElement('i', { className: 'icon-ok', onClick: this.create.bind(this) }),
										_react2['default'].createElement(
											'span',
											{ onClick: this.create.bind(this) },
											lang.save
										)
									)
								),
								_react2['default'].createElement(
									'li',
									null,
									defaultButton
								)
							)
						)
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns large-12 edit-address' },
						_react2['default'].createElement(
							'nav',
							{ className: 'addressediting-menu-small' },
							_react2['default'].createElement(
								'ul',
								null,
								_react2['default'].createElement(
									'li',
									null,
									_react2['default'].createElement(
										'button',
										{ disabled: !this.state.canSubmit, onClick: this.create.bind(this), type: 'button', className: 'button save' },
										_react2['default'].createElement('i', { className: 'icon-ok', onClick: this.create.bind(this) }),
										_react2['default'].createElement(
											'span',
											{ onClick: this.create.bind(this) },
											lang.save
										)
									)
								),
								_react2['default'].createElement(
									'li',
									null,
									defaultButton
								)
							)
						),
						_react2['default'].createElement(
							'div',
							{ className: 'row collapse edit-inputs' },
							_react2['default'].createElement(
								'div',
								{ className: 'columns medium-4' },
								alternativeLayout ? countryRegionSelect : companyNameInput,
								alternativeLayout ? "" : additionalInput,
								alternativeLayout ? "" : phoneInput,
								alternativeLayout ? "" : emailInput
							),
							_react2['default'].createElement(
								'div',
								{ className: 'columns medium-4' },
								alternativeLayout ? cityInput : countryRegionSelect,
								alternativeLayout ? line1Input : "",
								alternativeLayout ? line2Input : ""
							),
							_react2['default'].createElement(
								'div',
								{ className: 'columns medium-4' },
								alternativeLayout ? companyNameInput : line1Input,
								alternativeLayout ? additionalInput : line2Input,
								alternativeLayout ? phoneInput : postalCodeInput,
								alternativeLayout ? emailInput : cityInput
							)
						)
					)
				)
			),
			_react2['default'].createElement(
				'div',
				{ className: 'add-address' },
				_react2['default'].createElement(
					'button',
					{ className: 'button' },
					_react2['default'].createElement('i', { className: 'icon-plus-circled' }),
					_react2['default'].createElement(
						'span',
						null,
						lang.addNewAddressButton
					)
				)
			)
		);
	};

	return UserAddressesAddItem;
})(_react2['default'].Component);

;
exports['default'] = UserAddressesAddItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"../_stores/address_field_store":696,"../_stores/user_addresses_store":733,"../_stores/user_country_options_store":734,"./address_field":822,"./country_region_container":825,"classnames":299,"jquery":628,"react":525,"react-dom":351}],820:[function(require,module,exports){
/* jshint ignore:start */
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var AddressDefaultIndicator = (function (_React$Component) {
	_inherits(AddressDefaultIndicator, _React$Component);

	function AddressDefaultIndicator(props) {
		_classCallCheck(this, AddressDefaultIndicator);

		_React$Component.call(this, props);
	}

	AddressDefaultIndicator.prototype.render = function render() {
		if (!this.props.isDefault) return null;

		return _react2["default"].createElement(
			"div",
			{ className: "default-indication" },
			_react2["default"].createElement(
				"h4",
				null,
				hiabconfig.addresses.lang.defaultIndication
			)
		);
	};

	return AddressDefaultIndicator;
})(_react2["default"].Component);

;
exports["default"] = AddressDefaultIndicator;

/* jshint ignore:end */
module.exports = exports["default"];

},{"react":525}],821:[function(require,module,exports){
/* jshint ignore:start */
"use strict";

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var AddressErrorMessage = (function (_React$Component) {
	_inherits(AddressErrorMessage, _React$Component);

	function AddressErrorMessage(props) {
		_classCallCheck(this, AddressErrorMessage);

		_React$Component.call(this, props);
	}

	AddressErrorMessage.prototype.render = function render() {
		if (this.props.isValid) return null;

		return _react2["default"].createElement(
			"span",
			{ className: "error-msg-react" },
			this.props.errorMessage
		);
	};

	return AddressErrorMessage;
})(_react2["default"].Component);

;
exports["default"] = AddressErrorMessage;

/* jshint ignore:end */
module.exports = exports["default"];

},{"react":525}],822:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _address_error_message = require('./address_error_message');

var _address_error_message2 = _interopRequireDefault(_address_error_message);

var _validator = require('validator');

var _validator2 = _interopRequireDefault(_validator);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var AddressField = (function (_React$Component) {
	_inherits(AddressField, _React$Component);

	function AddressField(props) {
		var _this = this;

		_classCallCheck(this, AddressField);

		_React$Component.call(this, props);

		this.handleChange = function (e) {
			if (e.target.value.length > _this.props.maxLength) return false;
			if (_this.props.countryCode) {
				_actionsUser_addresses_actions2['default'].checkPostalCode(_this.props.countryCode, e.target.value);
			}
			_this.state.isValid = _this.validate(String(e.target.value));
			_this.state.isDirty = true;
			_this.props.setAddressItem(_this.props.name, e.target.value);
		};

		this.handleBlur = function (e) {
			_this.setState({
				isDirty: true
			});
			_this.handleChange(e);
		};

		this.preventSubmit = function (e) {
			var code = e.which || e.keyCode;
			if (code == '13') {
				e.preventDefault();
			}
		};

		this.state = {
			isValid: false,
			isDirty: false,
			value: null
		};
	}

	AddressField.prototype.validate = function validate(value, otherAddressLength) {
		var resCollection = [];
		var validationTypes = this.props.validator ? this.props.validator.split(',') : [];
		for (var i = 0; i < validationTypes.length; i++) {
			switch (validationTypes[i]) {
				case 'email':
					resCollection.push(_validator2['default'].isEmail(value) || _validator2['default'].isEmpty(value));
					break;
				case 'phone':
					resCollection.push(_validator2['default'].isLength(value, { min: this.props.minLength, max: this.props.maxLength }) && !_validator2['default'].matches(value, /[A-Za-z]/));
					break;
				case 'minLength':
					resCollection.push(_validator2['default'].isLength(value, { min: this.props.minLength }));
					break;
				default:
					resCollection.push(true);
					break;
			}
		}

		if (resCollection.indexOf(false) > -1) {
			return false;
		} else {
			return true;
		}
	};

	AddressField.prototype.componentDidMount = function componentDidMount() {
		this.state.isValid = this.validate(String(this.props.value));
	};

	AddressField.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {

		this.setState({
			isValid: this.validate(String(nextProps.value))
		});
	};

	AddressField.prototype.render = function render() {

		var isValid = this.state.isValid || !this.state.isDirty;

		var inputClasses = _classnames2['default']({
			'required': true,
			'invalid': !isValid
		});

		// required for mvc to map to view models
		var prefixedName = "ShippingAddress." + this.props.name;

		return _react2['default'].createElement(
			'label',
			{ htmlFor: prefixedName },
			this.props.label,
			_react2['default'].createElement('input', { className: inputClasses, name: prefixedName, onKeyDown: this.preventSubmit.bind(this), onChange: this.handleChange.bind(this), onBlur: this.handleBlur.bind(this), type: 'text', placeholder: '', value: this.props.value }),
			_react2['default'].createElement(_address_error_message2['default'], { isValid: isValid, errorMessage: this.props.errorMessage })
		);
	};

	return AddressField;
})(_react2['default'].Component);

;
exports['default'] = AddressField;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"./address_error_message":821,"classnames":299,"react":525,"validator":551}],823:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _storesUser_country_options_store = require('../_stores/user_country_options_store');

var _storesUser_country_options_store2 = _interopRequireDefault(_storesUser_country_options_store);

var _country_region_container = require('./country_region_container');

var _country_region_container2 = _interopRequireDefault(_country_region_container);

var _address_default_indicator = require('./address_default_indicator');

var _address_default_indicator2 = _interopRequireDefault(_address_default_indicator);

var _address_field = require('./address_field');

var _address_field2 = _interopRequireDefault(_address_field);

var _storesAddress_field_store = require('../_stores/address_field_store');

var _storesAddress_field_store2 = _interopRequireDefault(_storesAddress_field_store);

var alternativeLayout = hiabconfig.marketId == "JP02" ? true : false;

var AddressItem = (function (_React$Component) {
	_inherits(AddressItem, _React$Component);

	function AddressItem(props) {
		var _this = this;

		_classCallCheck(this, AddressItem);

		_React$Component.call(this, props);

		this.handleToggleEdit = function (e) {
			_this.setState({
				isEditing: !_this.state.isEditing
			});
			if (!_this.state.isEditing) {
				_actionsUser_addresses_actions2['default'].checkPostalCode(_this.props.item.CountryCode, _this.props.item.PostalCode);
			}
		};

		this.setAddressItem = function (key, value) {
			_this.props.item[key] = value;
			_this.setState({
				// item: this.props.item,
				canSubmit: _this.validateForm()
			});
			_this.forceUpdate();
		};

		this.handleSubmit = function (e) {
			e.preventDefault();
		};

		this.state = {
			item: {},
			countryOptions: [],
			canSubmit: false,
			regionValue: 'no',
			changed: false,
			isEditing: false,
			isOpen: false,
			makeDefault: false,
			execute: false,
			isLoading: false
		};

		this.elements = {};
	}

	AddressItem.prototype.validateForm = function validateForm() {
		var _this2 = this;

		return Object.keys(this.elements).every(function (key) {
			return _this2.elements[key].state.isValid && $('#' + _this2.props.item.AddressId + ' input.invalid').length === 0 && $('#' + _this2.props.item.AddressId + ' select.invalid').length === 0;
		});
	};

	AddressItem.prototype.makeDefault = function makeDefault(e) {
		e.stopPropagation();
		if (e.target.tagName !== 'BUTTON') {
			e.target = e.target.parentElement;
		}
		var stop = e.target.disabled;
		if (!stop) {
			this.state.makeDefault = true;
			this.state.execute = true;
			_actionsUser_addresses_actions2['default'].checkPostalCode(this.props.item.CountryCode, this.props.item.PostalCode);
			this.setState({
				isLoading: true
			});
		}
	};

	AddressItem.prototype.save = function save(e) {
		e.stopPropagation();
		if (e.target.tagName !== 'BUTTON') {
			e.target = e.target.parentElement;
		}

		if (!e.target.disabled) {
			_actionsUser_addresses_actions2['default'].checkPostalCode(this.props.item.CountryCode, this.props.item.PostalCode);
			if (this.validateForm()) {
				this.setState({
					isLoading: true,
					execute: true
				});
				this.state.execute = true;
			}
		}
	};

	AddressItem.prototype.remove = function remove(e) {
		_actionsUser_addresses_actions2['default'].deleteAddress(this.props.item);
		this.setState({
			isLoading: true
		});
	};

	AddressItem.prototype.componentDidMount = function componentDidMount() {
		var _this3 = this;

		this.saveAdress = _storesAddress_field_store2['default'].listen(function (res) {

			if (!res) {
				$('#' + _this3.props.item.AddressId + ' input[name="ShippingAddress.PostalCode"]').addClass('invalid');
			} else {
				$('#' + _this3.props.item.AddressId + ' input[name="ShippingAddress.PostalCode"]').removeClass('invalid');
			}

			_this3.setState({
				canSubmit: res
			});
			if (_this3.state.execute) {
				if (res) {
					if (_this3.state.makeDefault) {
						_this3.state.makeDefault = false;
						_this3.props.item.IsDefault = !_this3.props.item.IsDefault;
						_actionsUser_addresses_actions2['default'].updateAddress(_this3.props.item);
					} else {
						_actionsUser_addresses_actions2['default'].updateAddress(_this3.props.item);
						_this3.setState({
							canSubmit: false,
							isOpen: false
						});
					}
				} else {
					_this3.setState({
						canSubmit: false
					});

					_this3.elements.postalcode.setState({
						isValid: false
					});
				}

				_this3.state.execute = false;
			}
		});
	};

	AddressItem.prototype.componentWillUnmount = function componentWillUnmount() {
		this.saveAdress();
	};

	AddressItem.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		this.setState({
			// item: this.props.item,
			isEditing: this.state.isOpen,
			isLoading: false
		});
	};

	AddressItem.prototype.render = function render() {
		var _this4 = this;

		if (!this.props) return null;

		var lang = hiabconfig.addresses.lang;
		var item = this.props.item;
		var addressId = item.AddressId;
		var canEdit = !this.props.isBigCustomer;

		var formClassNames = _classnames2['default']({
			'row': true,
			'user-address': true,
			'collapse': true,
			'default': item.IsDefault,
			'editing': this.state.isEditing,
			'is-loading': this.state.isLoading
		});

		var title = item.FirstName ? item.CompanyName + ', ' + item.FirstName + '.' : item.CompanyName + '.';
		var street = item.Line2 ? item.Line1 + ' ' + item.Line2 : item.Line1;

		var regionName = undefined;
		if (this.props.countryOptions) {
			var country = _lodash2['default'].find(this.props.countryOptions, function (o) {
				return o.CountryCode == item.CountryCode;
			});

			if (country) {
				var region = _lodash2['default'].find(country.Regions, function (o) {
					return o.Code == item.Region;
				});
				regionName = region ? ', ' + region.Name : null;
			}
		}
		var addressItemNameElm = _react2['default'].createElement(
			'span',
			null,
			title,
			_react2['default'].createElement('br', null),
			street,
			', ',
			item.PostalCode,
			' ',
			item.City,
			regionName,
			' ',
			item.CountryName
		);
		if (alternativeLayout) {
			addressItemNameElm = _react2['default'].createElement(
				'span',
				null,
				title,
				_react2['default'].createElement('br', null),
				item.CountryName,
				' ',
				item.PostalCode,
				regionName,
				'. ',
				item.City,
				' ',
				street
			);
		}
		var defaultRadio = _react2['default'].createElement('input', { ref: 'isDeault', className: 'IsDefault', type: 'radio', defaultValue: item.IsDefault, hidden: true });
		if (item.IsDefault) {
			defaultRadio = _react2['default'].createElement('input', { ref: 'isDeault', className: 'IsDefault', type: 'radio', defaultValue: item.IsDefault, defaultChecked: true, hidden: true });
		}

		var defaultButton = _react2['default'].createElement(
			'button',
			{ disabled: !this.validateForm(), onClick: this.makeDefault.bind(this), type: 'button', className: 'button make-default ' },
			_react2['default'].createElement('i', { className: 'icon-check', onClick: this.makeDefault.bind(this) }),
			_react2['default'].createElement(
				'span',
				{ onClick: this.makeDefault.bind(this) },
				lang.makeDefault
			)
		);
		if (item.IsDefault) {
			defaultButton = _react2['default'].createElement(
				'button',
				{ disabled: !this.validateForm(), onClick: this.makeDefault.bind(this), type: 'button', className: 'button make-default ' },
				_react2['default'].createElement('i', { className: 'icon-check', onClick: this.makeDefault.bind(this) }),
				_react2['default'].createElement(
					'span',
					{ onClick: this.makeDefault.bind(this) },
					lang.resetDefault
				)
			);
		}

		var postalCodeInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.postalcode = c;
			}, name: 'PostalCode', countryCode: this.props.item.CountryCode, value: item.PostalCode, setAddressItem: this.setAddressItem.bind(this), label: lang.postalCode, validator: 'minLength', minLength: '1', maxLength: '10' });

		var countryRegionSelect = _react2['default'].createElement(_country_region_container2['default'], { ref: function (c) {
				return _this4.elements.countryRegionContainer = c;
			}, setAddressItem: this.setAddressItem.bind(this), countryOptions: this.props.countryOptions, item: this.props.item });
		if (alternativeLayout) {
			countryRegionSelect = _react2['default'].createElement(_country_region_container2['default'], { ref: function (c) {
					return _this4.elements.countryRegionContainer = c;
				}, setAddressItem: this.setAddressItem.bind(this), countryOptions: this.props.countryOptions, postalCode: postalCodeInput, item: this.props.item });
		}

		var cityInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.city = c;
			}, name: 'City', value: item.City, setAddressItem: this.setAddressItem.bind(this), label: lang.city, validator: 'minLength', minLength: '2', maxLength: '35' });
		var line1Input = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.line1 = c;
			}, name: 'Line1', value: item.Line1, setAddressItem: this.setAddressItem.bind(this), label: lang.street, otherAddressField: item.Line2, validator: 'minLength', minLength: '2', maxLength: '35' });
		var line2Input = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.line2 = c;
			}, name: 'Line2', value: item.Line2, setAddressItem: this.setAddressItem.bind(this), otherAddressField: item.Line1, validator: 'minLength', minLength: '0', maxLength: '40' });
		var companyNameInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.companyname = c;
			}, name: 'CompanyName', value: item.CompanyName, setAddressItem: this.setAddressItem.bind(this), label: lang.companyname, validator: 'minLength', minLength: '2', maxLength: '35' });
		var additionalInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.firstname = c;
			}, name: 'FirstName', value: item.FirstName, setAddressItem: this.setAddressItem.bind(this), label: lang.firstname, validator: 'minLength', minLength: '0', maxLength: '35' });
		var phoneInput = _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.phonenumber = c;
			}, name: 'DaytimePhoneNumber', value: item.DaytimePhoneNumber, setAddressItem: this.setAddressItem.bind(this), label: lang.phoneNumber, errorMessage: lang.errorPhone, validator: 'phone', minLength: '2', maxLength: '15' });
		var emailInput = hiabconfig.addresses.emailFieldEnabled ? _react2['default'].createElement(_address_field2['default'], { ref: function (c) {
				return _this4.elements.email = c;
			}, name: 'Email', value: item.Email, setAddressItem: this.setAddressItem.bind(this), label: lang.eMail, validator: 'email', errorMessage: hiabconfig.addresses.lang.errorMail, maxLength: '241' }) : null;
		var defaultAddress = !this.props.isBigCustomer ? _react2['default'].createElement(_address_default_indicator2['default'], { isDefault: item.IsDefault }) : "";
		return _react2['default'].createElement(
			'div',
			{ className: 'form-wrapper' },
			defaultAddress,
			_react2['default'].createElement(
				'form',
				{ id: item.AddressId, className: formClassNames, onSubmit: this.handleSubmit.bind(this) },
				_react2['default'].createElement(
					'label',
					{ className: 'u-mb-0', htmlFor: 'Modified' },
					_react2['default'].createElement('input', { ref: 'modified', className: 'Modified', type: 'hidden', defaultValue: new Date() })
				),
				_react2['default'].createElement(
					'label',
					{ htmlFor: 'IsDefault', className: 'u-mb-0' },
					defaultRadio
				),
				_react2['default'].createElement(
					'div',
					{ className: 'columns medium-11 small-10 address-title' },
					addressItemNameElm
				),
				canEdit ? _react2['default'].createElement(
					'div',
					{ className: 'columns medium-6 small-2 edit-toggle' },
					_react2['default'].createElement(
						'button',
						{ className: 'button circle right edit-toggle-button', onClick: this.handleToggleEdit.bind(this) },
						_react2['default'].createElement('i', { className: 'icon-addressediting' })
					),
					_react2['default'].createElement(
						'nav',
						{ className: 'addressediting-menu small-hidden' },
						_react2['default'].createElement(
							'ul',
							null,
							_react2['default'].createElement(
								'li',
								null,
								_react2['default'].createElement(
									'button',
									{ disabled: !this.state.canSubmit, onClick: this.save.bind(this), 'data-form-id': item.AddressId, className: 'button save' },
									_react2['default'].createElement('i', { className: 'icon-ok', onClick: this.save.bind(this) }),
									_react2['default'].createElement(
										'span',
										{ onClick: this.save.bind(this) },
										lang.save
									)
								)
							),
							_react2['default'].createElement(
								'li',
								null,
								defaultButton
							),
							_react2['default'].createElement(
								'li',
								null,
								_react2['default'].createElement(
									'button',
									{ onClick: this.remove.bind(this), 'data-form-id': item.AddressId, className: 'button remove' },
									_react2['default'].createElement('i', { className: 'icon-trash' }),
									_react2['default'].createElement(
										'span',
										null,
										lang.remove
									)
								)
							)
						)
					)
				) : "",
				canEdit ? _react2['default'].createElement(
					'div',
					{ className: 'columns large-12 edit-address' },
					_react2['default'].createElement(
						'nav',
						{ className: 'addressediting-menu-small' },
						_react2['default'].createElement(
							'ul',
							null,
							_react2['default'].createElement(
								'li',
								null,
								_react2['default'].createElement(
									'button',
									{ disabled: !this.state.canSubmit, onClick: this.save.bind(this), 'data-form-id': item.AddressId, className: 'button save' },
									_react2['default'].createElement('i', { className: 'icon-ok', onClick: this.save.bind(this) }),
									_react2['default'].createElement(
										'span',
										{ onClick: this.save.bind(this) },
										lang.save
									)
								)
							),
							_react2['default'].createElement(
								'li',
								null,
								defaultButton
							),
							_react2['default'].createElement(
								'li',
								null,
								_react2['default'].createElement(
									'button',
									{ onClick: this.remove.bind(this), 'data-form-id': item.AddressId, className: 'button remove' },
									_react2['default'].createElement('i', { className: 'icon-trash' }),
									_react2['default'].createElement(
										'span',
										null,
										lang.remove
									)
								)
							)
						)
					),
					_react2['default'].createElement(
						'div',
						{ className: 'row collapse edit-inputs' },
						_react2['default'].createElement(
							'div',
							{ className: 'columns medium-4' },
							alternativeLayout ? countryRegionSelect : companyNameInput,
							alternativeLayout ? "" : additionalInput,
							alternativeLayout ? "" : phoneInput,
							alternativeLayout ? "" : emailInput
						),
						_react2['default'].createElement(
							'div',
							{ className: 'columns medium-4' },
							alternativeLayout ? cityInput : countryRegionSelect,
							alternativeLayout ? line1Input : "",
							alternativeLayout ? line2Input : ""
						),
						_react2['default'].createElement(
							'div',
							{ className: 'columns medium-4' },
							alternativeLayout ? companyNameInput : line1Input,
							alternativeLayout ? additionalInput : line2Input,
							alternativeLayout ? phoneInput : postalCodeInput,
							alternativeLayout ? emailInput : cityInput
						)
					)
				) : ""
			)
		);
	};

	return AddressItem;
})(_react2['default'].Component);

;
exports['default'] = AddressItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"../_stores/address_field_store":696,"../_stores/user_country_options_store":734,"./address_default_indicator":820,"./address_field":822,"./country_region_container":825,"classnames":299,"lodash":333,"react":525,"react-dom":351}],824:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var CountryDropdown = (function (_React$Component) {
	_inherits(CountryDropdown, _React$Component);

	function CountryDropdown(props) {
		_classCallCheck(this, CountryDropdown);

		_React$Component.call(this, props);
	}

	CountryDropdown.prototype.render = function render() {
		if (!this.props.countryOptions) return null;

		var countryOptions = this.props.countryOptions.map(function (countryOption) {
			return _react2['default'].createElement(
				'option',
				{ key: countryOption.CountryCode, value: countryOption.CountryCode },
				countryOption.Name
			);
		});

		var isValid = this.props.isValid;

		var inputClasses = _classnames2['default']({
			'invalid': !isValid
		});

		return _react2['default'].createElement(
			'label',
			{ htmlFor: 'CountryName' },
			hiabconfig.addresses.lang.country,
			_react2['default'].createElement(
				'select',
				{ onChange: this.props.handleCountryChange.bind(this), onBlur: this.props.handleBlur.bind(this), name: 'ShippingAddress.CountryCode', value: this.props.item.CountryCode, className: inputClasses },
				_react2['default'].createElement(
					'option',
					{ key: 'country.default', value: 'default' },
					hiabconfig.addresses.lang.selectCountry
				),
				countryOptions
			)
		);
	};

	return CountryDropdown;
})(_react2['default'].Component);

;
exports['default'] = CountryDropdown;

/* jshint ignore:end */
module.exports = exports['default'];

},{"classnames":299,"react":525}],825:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _country_dropdown = require('./country_dropdown');

var _country_dropdown2 = _interopRequireDefault(_country_dropdown);

var _region_dropdown = require('./region_dropdown');

var _region_dropdown2 = _interopRequireDefault(_region_dropdown);

var _checkoutCheckout_shipping = require('../checkout/checkout_shipping');

var _checkoutCheckout_shipping2 = _interopRequireDefault(_checkoutCheckout_shipping);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var CountryRegionContainer = (function (_React$Component) {
	_inherits(CountryRegionContainer, _React$Component);

	function CountryRegionContainer(props) {
		var _this = this;

		_classCallCheck(this, CountryRegionContainer);

		_React$Component.call(this, props);

		this.handleBlur = function (e) {
			_this.setState({
				isDirty: true
			});
		};

		this.handleCountryChange = function (e) {
			var setLoading = false;
			var selectedContry = _lodash2['default'].find(_this.props.countryOptions, function (o) {
				return o.CountryCode === e.target.value;
			});
			_this.props.setAddressItem('CountryCode', selectedContry.CountryCode);
			_this.props.setAddressItem('CountryName', selectedContry.Name);
			_this.props.setAddressItem('RegionOptions', selectedContry.Regions);
			_this.props.setAddressItem('Region', '');

			_actionsUser_addresses_actions2['default'].checkPostalCode(selectedContry.CountryCode, _this.props.item.PostalCode);

			_this.setState({
				isValid: _this.validate(e.target.value)
			});
		};

		this.state = {
			isValid: false,
			isDirty: false
		};
	}

	CountryRegionContainer.prototype.validate = function validate(value) {
		return value !== 'default';
	};

	CountryRegionContainer.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
		this.setState({
			isValid: this.validate(nextProps.item.CountryCode)
		});
	};

	CountryRegionContainer.prototype.render = function render() {
		var _this2 = this;

		var selectedCountry = _lodash2['default'].find(this.props.countryOptions, function (o) {
			return o.CountryCode === _this2.props.item.CountryCode;
		});
		var regions = null;
		var countryCode = null;
		var postalCodeElm = null;

		if (selectedCountry) regions = selectedCountry.Regions;
		if (selectedCountry) countryCode = selectedCountry.CountryCode;
		if (this.props.postalCode) postalCodeElm = this.props.postalCode;

		var countryProps = {
			countryOptions: this.props.countryOptions,
			item: this.props.item,
			handleCountryChange: this.handleCountryChange,
			setAddressItem: this.props.setAddressItem,
			isValid: this.state.isValid,
			isDirty: this.state.isDirty,
			handleBlur: this.handleBlur
		};

		var regionProps = {
			item: this.props.item,
			regions: regions,
			handleRegionChange: this.handleRegionChange,
			setAddressItem: this.props.setAddressItem,
			required: countryCode !== 'JP'
		};

		return _react2['default'].createElement(
			'div',
			null,
			_react2['default'].createElement(_country_dropdown2['default'], countryProps),
			postalCodeElm,
			_react2['default'].createElement(_region_dropdown2['default'], regionProps)
		);
	};

	return CountryRegionContainer;
})(_react2['default'].Component);

;
exports['default'] = CountryRegionContainer;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"../checkout/checkout_shipping":744,"./country_dropdown":824,"./region_dropdown":826,"lodash":333,"react":525}],826:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var RegionDropdown = (function (_React$Component) {
	_inherits(RegionDropdown, _React$Component);

	function RegionDropdown(props) {
		var _this = this;

		_classCallCheck(this, RegionDropdown);

		_React$Component.call(this, props);

		this.handleRegionChange = function (e) {
			_this.handleBlur(e);
		};

		this.handleBlur = function (e) {

			if (_this.props.required) {
				_this.setState({
					isDirty: !_this.validate(e.target.value),
					isValid: _this.validate(e.target.value)
				});

				if (!e.target.value || e.target.value === 'default') {
					if (e.target.className.indexOf('invalid') === -1) {
						e.target.className += ' invalid';
					}
				} else {
					e.target.className = e.target.className.replace(' invalid', '');
				}

				_this.props.setAddressItem('Region', e.target.value);
			} else {
				_this.setState({
					isDirty: false,
					isValid: true
				});
				e.target.className = e.target.className.replace(' invalid', '');
				// console.log(e.target.value);
				_this.props.setAddressItem('Region', e.target.value);
			}
		};

		this.state = {
			isDirty: true,
			isValid: false
		};
	}

	RegionDropdown.prototype.validate = function validate(value) {
		return value !== 'default';
	};

	RegionDropdown.prototype.render = function render() {
		var _this2 = this;

		if (!this.props.regions || this.props.regions.length === 0) return null;
		// console.log(this.props.required);

		var i = 0;
		var regionVal = '';
		var possibleRegionCodes = [];
		var regionOptions = this.props.regions.map(function (region) {
			var key = _this2.props.item.AddressId + region.Code + i++;
			possibleRegionCodes.push(region.Code);

			return _react2['default'].createElement(
				'option',
				{ key: key, value: region.Code },
				region.Name
			);
		});

		regionVal = possibleRegionCodes.indexOf(this.props.item.Region) !== -1 ? this.props.item.Region : 'default';
		var isValid = regionVal !== 'default';
		if (!this.props.required) isValid = true;

		var inputClasses = _classnames2['default']({
			'invalid': !isValid,
			'Region': true
		});

		return _react2['default'].createElement(
			'label',
			{ htmlFor: 'Region' },
			hiabconfig.addresses.lang.region,
			_react2['default'].createElement(
				'select',
				{ onChange: this.handleRegionChange.bind(this), onBlur: this.handleBlur.bind(this), name: 'ShippingAddress.Region', className: inputClasses, value: regionVal },
				_react2['default'].createElement(
					'option',
					{ key: 'region.default', value: 'default' },
					hiabconfig.addresses.lang.selectRegion
				),
				regionOptions
			)
		);
	};

	return RegionDropdown;
})(_react2['default'].Component);

;
exports['default'] = RegionDropdown;

/* jshint ignore:end */
module.exports = exports['default'];

},{"classnames":299,"react":525}],827:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _storesUser_default_addresses_store = require('../_stores/user_default_addresses_store');

var _storesUser_default_addresses_store2 = _interopRequireDefault(_storesUser_default_addresses_store);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var _storesUser_addresses_store = require('../_stores/user_addresses_store');

var _storesUser_addresses_store2 = _interopRequireDefault(_storesUser_addresses_store);

var alternativeLayout = hiabconfig.marketId == "JP02" ? true : false;

var UserAddressesDefault = (function (_React$Component) {
	_inherits(UserAddressesDefault, _React$Component);

	function UserAddressesDefault(props) {
		_classCallCheck(this, UserAddressesDefault);

		_React$Component.call(this, props);
		this.state = {
			loading: false,
			currentAddressItem: null,
			countryOptions: _storesUser_addresses_store2['default'].getCountryOptions()
		};
	}

	UserAddressesDefault.prototype.componentDidMount = function componentDidMount() {
		var _this = this;

		this.unsubscribe = _storesUser_default_addresses_store2['default'].listen(function () {
			return _this.setState({
				currentAddressItem: _storesUser_default_addresses_store2['default'].getDefaultAddress(),
				countryOptions: _storesUser_addresses_store2['default'].getCountryOptions()
			});
		});
	};

	UserAddressesDefault.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	UserAddressesDefault.prototype.render = function render() {
		var lang = hiabconfig.addresses.lang;
		var item = this.state.currentAddressItem;

		if (!this.state.currentAddressItem) return null;

		var regionName = undefined;

		if (item) {
			var country = _lodash2['default'].find(this.state.countryOptions, function (o) {
				return o.Name == item.CountryName;
			});
			if (country) {
				var region = _lodash2['default'].find(country.Regions, function (o) {
					return o.Code == item.Region;
				});
				regionName = region ? region.Name : null;
			}
		}

		if (!item) return _react2['default'].createElement(
			'div',
			{ className: 'uc-message' },
			_react2['default'].createElement(
				'p',
				null,
				lang.noDefaulFirstLine
			),
			_react2['default'].createElement(
				'p',
				null,
				lang.noDefaulSecondLine
			)
		);
		var firstNameElm = null;
		if (item.FirstName.length > 0) {
			firstNameElm = _react2['default'].createElement(
				'p',
				null,
				_react2['default'].createElement(
					'span',
					{ className: 'u-line u-size14 u-bold' },
					lang.firstname
				),
				_react2['default'].createElement(
					'span',
					{ className: 'u-line u-size12' },
					item.FirstName
				)
			);
		}
		var regionElm = null;
		if (regionName) {
			regionElm = _react2['default'].createElement(
				'p',
				null,
				_react2['default'].createElement(
					'span',
					{ className: 'u-line u-size14 u-bold' },
					lang.region
				),
				_react2['default'].createElement(
					'span',
					{ className: 'u-line u-size12' },
					regionName
				)
			);
		}
		var title = item.FirstName ? item.CompanyName + ', ' + item.FirstName + '.' : item.CompanyName + '.';
		var street = item.Line2 ? item.Line1 + ' ' + item.Line2 : item.Line1;
		var regionItem = regionName ? ', ' + regionName : '';

		var itemNameElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				title,
				_react2['default'].createElement('br', null),
				street,
				' ',
				item.PostalCode,
				' ',
				item.City,
				regionItem,
				' ',
				item.CountryName
			)
		);
		if (alternativeLayout) {
			itemNameElm = _react2['default'].createElement(
				'p',
				null,
				_react2['default'].createElement(
					'span',
					{ className: 'u-line u-size14 u-bold' },
					title,
					_react2['default'].createElement('br', null),
					item.CountryName,
					' ',
					item.PostalCode,
					regionName,
					'. ',
					item.City,
					' ',
					street
				)
			);
		}

		var companyNameElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.companyname
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.CompanyName
			)
		);
		var phonenumberElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.phoneNumber
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.DaytimePhoneNumber
			)
		);
		var emailElm = hiabconfig.addresses.emailFieldEnabled ? _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.eMail
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.Email
			)
		) : null;
		var countryElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.country
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.CountryName
			)
		);
		var streetElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.street
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.Line1
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.Line2
			)
		);
		var cityElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.city
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.City
			)
		);
		var postalElm = _react2['default'].createElement(
			'p',
			null,
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size14 u-bold' },
				lang.postalCode
			),
			_react2['default'].createElement(
				'span',
				{ className: 'u-line u-size12' },
				item.PostalCode
			)
		);

		return _react2['default'].createElement(
			'div',
			{ className: 'uc-user-default-address' },
			_react2['default'].createElement(
				'header',
				null,
				_react2['default'].createElement(
					'h4',
					null,
					lang.defaultHeader
				)
			),
			_react2['default'].createElement(
				'div',
				{ className: 'uc-user-default-address-wrapper' },
				_react2['default'].createElement(
					'div',
					{ className: 'row' },
					_react2['default'].createElement(
						'div',
						{ className: 'columns large-12' },
						itemNameElm
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns medium-4' },
						alternativeLayout ? countryElm : companyNameElm,
						alternativeLayout ? postalElm : firstNameElm,
						alternativeLayout ? regionElm : phonenumberElm,
						alternativeLayout ? "" : emailElm
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns medium-4' },
						alternativeLayout ? cityElm : countryElm,
						alternativeLayout ? streetElm : regionElm
					),
					_react2['default'].createElement(
						'div',
						{ className: 'columns medium-4' },
						alternativeLayout ? companyNameElm : streetElm,
						alternativeLayout ? firstNameElm : cityElm,
						alternativeLayout ? phonenumberElm : postalElm,
						alternativeLayout ? emailElm : ""
					)
				)
			)
		);
	};

	return UserAddressesDefault;
})(_react2['default'].Component);

;
exports['default'] = UserAddressesDefault;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"../_stores/user_addresses_store":733,"../_stores/user_default_addresses_store":735,"jquery":628,"lodash":333,"react":525}],828:[function(require,module,exports){
/* jshint ignore:start */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _storesUser_addresses_store = require('../_stores/user_addresses_store');

var _storesUser_addresses_store2 = _interopRequireDefault(_storesUser_addresses_store);

var _actionsUser_addresses_actions = require('../_actions/user_addresses_actions');

var _actionsUser_addresses_actions2 = _interopRequireDefault(_actionsUser_addresses_actions);

var _address_item = require('./address_item');

var _address_item2 = _interopRequireDefault(_address_item);

var _user_addresses_default = require('./user_addresses_default');

var _user_addresses_default2 = _interopRequireDefault(_user_addresses_default);

var _storesUser_default_addresses_store = require('../_stores/user_default_addresses_store');

var _storesUser_default_addresses_store2 = _interopRequireDefault(_storesUser_default_addresses_store);

var _storesUser_country_options_store = require('../_stores/user_country_options_store');

var _storesUser_country_options_store2 = _interopRequireDefault(_storesUser_country_options_store);

var _address_add_item = require('./address_add_item');

var _address_add_item2 = _interopRequireDefault(_address_add_item);

var doneTypingInterval = 300;

var UserAddressesItem = (function (_React$Component) {
	_inherits(UserAddressesItem, _React$Component);

	function UserAddressesItem(props) {
		var _this = this;

		_classCallCheck(this, UserAddressesItem);

		_React$Component.call(this, props);

		this.handleSubmit = function (e) {
			var value = e.target.value;
			_this.typingTimer = setTimeout(function () {
				_this.doneTyping(value);
			}, doneTypingInterval);
		};

		this.state = {
			addressItems: [],
			billingAddressItems: [],
			countryOptions: [],
			isSaving: false,
			resultStatus: null,
			filterListIsEmpty: false,
			filterBillingListIsEmpty: false,
			hideElements: true,
			isBigCustomer: false
		};
		this.typingTimer = null;
	}

	UserAddressesItem.prototype.clearFilter = function clearFilter(e) {
		var _this2 = this;

		e.preventDefault();

		_jquery2['default']('#clear-spinner').show();
		_jquery2['default']('#clear-text').hide();
		var filterInput = _reactDom2['default'].findDOMNode(this.refs.filter);
		filterInput.value = '';
		setTimeout(function () {
			return _this2.doneTyping('');
		}, 100);
	};

	UserAddressesItem.prototype.resetFilterAfterLoad = function resetFilterAfterLoad() {
		var filterInput = _reactDom2['default'].findDOMNode(this.refs.filter);
		filterInput.value = '';
		this.doneTyping('');
	};

	UserAddressesItem.prototype.handleKeyup = function handleKeyup(e) {
		var _this3 = this;

		// e.preventDefault();
		if (this.typingTimer) clearTimeout(this.typingTimer);

		var value = e.target.value;
		this.typingTimer = setTimeout(function () {
			_this3.doneTyping(value);
		}, doneTypingInterval);
	};

	UserAddressesItem.prototype.handleKeydown = function handleKeydown(e) {
		// e.preventDefault();
		if (this.typingTimer) clearTimeout(this.typingTimer);
	};

	UserAddressesItem.prototype.doneTyping = function doneTyping(value) {
		_jquery2['default']('.uc-user-address h4.all').addClass('is-loading');

		var addressList = _storesUser_addresses_store2['default'].getAddresses();
		var billingAddressList = _storesUser_addresses_store2['default'].getBillingAddresses();
		var updatedAddressList = null;
		var updatedBillingAddressList = null;

		if (value.length > 0 && !this.state.isBigCustomer) {

			_jquery2['default']('.search-addresses button').show();

			updatedAddressList = addressList.filter(function (item) {
				return item.Name.toLowerCase().search(value.toLowerCase()) !== -1;
			});

			this.setState({
				addressItems: updatedAddressList,
				billingAddressItems: updatedBillingAddressList,
				filterListIsEmpty: updatedAddressList.length === 0
			});

			this.forceUpdate();
		} else if (value.length > 0 && this.state.isBigCustomer) {

			_jquery2['default']('.search-addresses button').show();
			updatedAddressList = addressList.filter(function (item) {
				return item.Name.toLowerCase().search(value.toLowerCase()) !== -1;
			});

			updatedBillingAddressList = billingAddressList.filter(function (item) {
				return item.Name.toLowerCase().search(value.toLowerCase()) !== -1;
			});

			this.setState({
				addressItems: updatedAddressList,
				billingAddressItems: updatedBillingAddressList,
				filterListIsEmpty: updatedAddressList.length === 0,
				filterBillingListIsEmpty: updatedBillingAddressList.length === 0
			});

			this.forceUpdate();
		} else {

			this.setState({
				addressItems: addressList,
				billingAddressItems: billingAddressList,
				filterListIsEmpty: false,
				filterBillingListIsEmpty: false
			});

			this.forceUpdate();

			_jquery2['default']('.search-addresses button').hide();
			_jquery2['default']('#clear-spinner').hide();
			_jquery2['default']('#clear-text').show();
		}
		_jquery2['default']('.uc-user-address h4.all').removeClass('is-loading');
	};

	UserAddressesItem.prototype.componentDidMount = function componentDidMount() {
		var _this4 = this;

		//Load content
		_actionsUser_addresses_actions2['default'].loadAddresses();
		_jquery2['default']('.uc-user-address h4.all').addClass('is-loading');

		this.unsubscribe = _storesUser_addresses_store2['default'].listen(function () {
			_this4.setState({
				addressItems: _storesUser_addresses_store2['default'].getAddresses(),
				billingAddressItems: _storesUser_addresses_store2['default'].getBillingAddresses(),
				resultStatus: _storesUser_addresses_store2['default'].getStatus(),
				countryOptions: _storesUser_addresses_store2['default'].getCountryOptions(),
				hideElements: false,
				isBigCustomer: _storesUser_addresses_store2['default'].getCustomerType()
			});

			_storesUser_country_options_store2['default'].setCountryOptions(_this4.state.countryOptions);
			if (_this4.state.resultStatus !== null && typeof _this4.state.resultStatus !== 'undefined') {
				if (_jquery2['default']('.add-new.adding').length > 0) {
					_jquery2['default']('.add-new').removeClass('is-loading');
					_jquery2['default']('.add-new').removeClass('adding');
				}
				_jquery2['default']('#address-message').removeClass('hide');
				setTimeout(function () {
					_jquery2['default']('#address-message').addClass('hide');
				}, 3500);
				_this4.resetFilterAfterLoad();
			}
			_jquery2['default']('.uc-user-address h4.all').removeClass('is-loading');

			var defaultAddress = _lodash2['default'].find(_storesUser_addresses_store2['default'].getAddresses(), function (o) {
				return o.IsDefault;
			});

			if (defaultAddress) {
				_storesUser_default_addresses_store2['default'].setDefaultAddress(defaultAddress);
			} else {
				_storesUser_default_addresses_store2['default'].setDefaultAddress(null);
			}
		});
	};

	UserAddressesItem.prototype.componentWillUnmount = function componentWillUnmount() {
		this.unsubscribe();
	};

	UserAddressesItem.prototype.render = function render() {
		var _this5 = this;

		var resultStatus = this.state.resultStatus;

		if (!this.state.addressItems) return null;
		var addressList = this.state.addressItems;

		var addresses = addressList.map(function (addressItem) {
			return _react2['default'].createElement(_address_item2['default'], { key: addressItem.AddressId, isBigCustomer: _this5.state.isBigCustomer, item: addressItem, countryOptions: _this5.state.countryOptions });
		});

		var billingAddresses = null;
		var bigCustomerInfo = null;

		if (this.state.isBigCustomer) {

			if (!this.state.billingAddressItems) return null;
			var billingAddressesList = this.state.billingAddressItems;

			var filterBillingMessageClass = _classnames2['default']({
				'uc-message': true,
				'address-result-message': true,
				'info': true,
				'hide': !this.state.filterBillingListIsEmpty
			});

			addresses = _react2['default'].createElement(
				'div',
				{ id: 'user-shipping-address', className: 'address-listing is-open' },
				addresses
			);

			var findAddressInfo = hiabconfig.addresses.lang.findAddressInfo;

			bigCustomerInfo = _react2['default'].createElement(
				'div',
				{ className: 'clearfix big-customer-info' },
				_react2['default'].createElement(
					'p',
					null,
					findAddressInfo.slice(0, findAddressInfo.indexOf('{0}')),
					' ',
					_react2['default'].createElement(
						'a',
						{ 'data-scroll-to': '.address-type-title.shipping' },
						hiabconfig.addresses.lang.shippingAddresses,
						_react2['default'].createElement('i', { className: 'icon-angle-down' })
					),
					findAddressInfo.slice(findAddressInfo.indexOf('{0}') + 3, findAddressInfo.indexOf('{1}')),
					' ',
					_react2['default'].createElement(
						'a',
						{ 'data-scroll-to': '.address-type-title.billing' },
						hiabconfig.addresses.lang.billingAddresses,
						_react2['default'].createElement('i', { className: 'icon-angle-down' })
					),
					findAddressInfo.slice(findAddressInfo.indexOf('{1}') + 3)
				)
			);

			billingAddresses = this.state.billingAddressItems.map(function (addressItem) {
				return _react2['default'].createElement(_address_item2['default'], { key: addressItem.AddressId, isBigCustomer: _this5.state.isBigCustomer, item: addressItem, countryOptions: _this5.state.countryOptions });
			});

			billingAddresses = _react2['default'].createElement(
				'div',
				null,
				_react2['default'].createElement(
					'div',
					{ className: 'address-type-title billing' },
					_react2['default'].createElement(
						'h4',
						{ className: 'all' },
						hiabconfig.addresses.lang.allBillingAddresses
					),
					_react2['default'].createElement(
						'button',
						{ id: 'toggle-billing-address', className: 'show-more address-book round button right' },
						_react2['default'].createElement(
							'span',
							{ className: 'show' },
							hiabconfig.addresses.lang.hideAll
						),
						_react2['default'].createElement(
							'span',
							{ className: 'hide' },
							hiabconfig.addresses.lang.showAll
						)
					)
				),
				_react2['default'].createElement(
					'div',
					{ className: filterBillingMessageClass },
					_react2['default'].createElement(
						'p',
						null,
						hiabconfig.checkout.lang.noAddressesFound
					)
				),
				_react2['default'].createElement(
					'div',
					{ id: 'user-billing-address', className: 'address-listing is-open' },
					billingAddresses
				)
			);
		}

		var resultMessage = null;

		if (resultStatus === true) {
			resultMessage = _react2['default'].createElement(
				'div',
				{ id: 'address-message', className: 'uc-message success address-result-message hide' },
				_react2['default'].createElement(
					'p',
					null,
					hiabconfig.addresses.lang.saved
				)
			);
		} else {
			resultMessage = _react2['default'].createElement(
				'div',
				{ id: 'address-message', className: 'uc-message error address-result-message hide' },
				_react2['default'].createElement(
					'p',
					null,
					hiabconfig.addresses.lang.notSaved
				)
			);
		}

		var filterMessageClass = _classnames2['default']({
			'uc-message': true,
			'address-result-message': true,
			'info': true,
			'hide': !this.state.filterListIsEmpty
		});

		var searchAddressesClass = _classnames2['default']({
			'search-addresses-wrapper': true,
			'hide': this.state.hideElements
		});
		var addAddressesClass = _classnames2['default']({
			'hide': this.state.hideElements || this.state.isBigCustomer
		});

		return _react2['default'].createElement(
			'div',
			null,
			_react2['default'].createElement(
				'div',
				{ className: searchAddressesClass },
				_react2['default'].createElement(
					'header',
					null,
					_react2['default'].createElement(
						'h4',
						null,
						hiabconfig.addresses.lang.findAddresses
					)
				),
				_react2['default'].createElement(
					'div',
					{ className: 'search-addresses' },
					_react2['default'].createElement(
						'p',
						null,
						hiabconfig.addresses.lang.findAddressesInfo
					),
					_react2['default'].createElement(
						'form',
						{ action: '', method: 'post', onSubmit: this.handleSubmit.bind(this) },
						_react2['default'].createElement('input', { ref: 'filter', type: 'text', name: 'model-tree-search-text', onKeyUp: this.handleKeyup.bind(this), onKeyDown: this.handleKeydown.bind(this) }),
						_react2['default'].createElement(
							'button',
							{ className: 'round button', onClick: this.clearFilter.bind(this) },
							_react2['default'].createElement('i', { id: 'clear-spinner', className: 'hide animate-spin icon-spin4' }),
							_react2['default'].createElement(
								'span',
								{ id: 'clear-text' },
								'Clear'
							)
						)
					),
					bigCustomerInfo
				)
			),
			resultMessage,
			_react2['default'].createElement(
				'div',
				{ className: addAddressesClass },
				_react2['default'].createElement(_address_add_item2['default'], null)
			),
			_react2['default'].createElement(
				'div',
				{ className: 'address-type-title shipping' },
				_react2['default'].createElement(
					'h4',
					{ className: 'all' },
					this.state.isBigCustomer ? hiabconfig.addresses.lang.allShippingAddresses : hiabconfig.addresses.lang.allAddresses
				),
				this.state.isBigCustomer ? _react2['default'].createElement(
					'button',
					{ id: 'toggle-shipping-address', className: 'show-more address-book round button right' },
					_react2['default'].createElement(
						'span',
						{ className: 'show' },
						hiabconfig.addresses.lang.hideAll
					),
					_react2['default'].createElement(
						'span',
						{ className: 'hide' },
						hiabconfig.addresses.lang.showAll
					)
				) : null
			),
			_react2['default'].createElement(
				'div',
				{ className: filterMessageClass },
				_react2['default'].createElement(
					'p',
					null,
					hiabconfig.checkout.lang.noAddressesFound
				)
			),
			addresses,
			billingAddresses
		);
	};

	return UserAddressesItem;
})(_react2['default'].Component);

;
exports['default'] = UserAddressesItem;

/* jshint ignore:end */
module.exports = exports['default'];

},{"../_actions/user_addresses_actions":650,"../_stores/user_addresses_store":733,"../_stores/user_country_options_store":734,"../_stores/user_default_addresses_store":735,"./address_add_item":819,"./address_item":823,"./user_addresses_default":827,"classnames":299,"jquery":628,"lodash":333,"react":525,"react-dom":351}],829:[function(require,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

var _foundation = require('foundation');

var _foundation2 = _interopRequireDefault(_foundation);

var _foundationOffcanvas = require('foundation.offcanvas');

var _foundationOffcanvas2 = _interopRequireDefault(_foundationOffcanvas);

var foundation = {
	init: function init() {
		var dateformat = hiabconfig.datepicker.lang.format;
		var datepickerdateRegex = new RegExp('^' + dateformat.replace(/y/ig, "[0-9]").replace(/mm/ig, "((0[1-9]|1[012])|[1-9])").replace(/m/ig, "((0[1-9]|1[012])|[1-9])").replace(/dd/ig, "((0[1-9]|[12][0-9]|3[01])|[1-9])").replace(/d/ig, "((0[1-9]|[12][0-9]|3[01])|[1-9])").replace(/\//g, '\\/').replace(/\./g, '\\.') + '$');

		_jquery2['default'](document).foundation({
			abide: {
				live_validate: false,
				validate_on_blur: true,
				focus_on_invalid: false,
				error_labels: true,
				timeout: 250,
				patterns: {
					currency: /^\d+(\.\d+)*$/,
					name: /^[a-zA-Z\s]*$/,
					textwithnonenglishchars: /^(?!.*--)[^\d\W][\u00BF-\u1FFF\u2C00-\uD7FF-' a-zA-Z \.]+[\u00BF-\u1FFF\u2C00-\uD7FFa-zA-Z][^\d\W]*$/i,
					address: /^(?!.*--)(?!.*(po box|p.o. box|p. o. box|p.o.|p.o|p. o.))[\u00BF-\u1FFF\u2C00-\uD7FF-,:'. a-zA-Z0-9]+[\u00BF-\u1FFF\u2C00-\uD7FFa-zA-Z0-9][\w.]*$/i,
					company: /^(?!.*--)[\u00BF-\u1FFF\u2C00-\uD7FF-'&,. \w]+[\u00BF-\u1FFF\u2C00-\uD7FF-'&,. \w][\w.]*$/i,
					postalcode: /^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/,
					countrycode: /^[A-Za-z]{2}$/,
					phone: /^[^a-zA-Z]{5,15}$/,
					selfregistrationphone: /^(\+|\({0,1})+([0-9-() ]){5,20}[\d)]$/,
					serialNumber: /^(?!.*--)[a-zA-Z0-9,-\s]+$/,
					passwordreg: /^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~])|(?=.*[a-z])(?=.*[0-9])(?=.*[!"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~]))[a-zA-Z0-9!"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~]{8,}$/,
					datepickerdate: datepickerdateRegex
				}
			}
		});

		this.offcanvasWrapper = _jquery2['default']('[data-offcanvas]');
		this.closeBtns = _jquery2['default']('[data-offcanvas-close]');
		this.bindOffcanvasCloseEvent();
	},

	bindOffcanvasCloseEvent: function bindOffcanvasCloseEvent() {
		this.closeBtns.on('click', this.offCanvasClose.bind(this));
	},

	offCanvasClose: function offCanvasClose(e) {
		e.preventDefault();
		this.offcanvasWrapper.removeClass('move-right').removeClass('move-left');
	}

};

exports['default'] = foundation;
module.exports = exports['default'];

},{"foundation":622,"foundation.offcanvas":623,"jquery":628}],830:[function(require,module,exports){
"use strict";

(function () {
  (function ($) {
    return $.fn.stuck = function (opts) {
      var Stuck;
      Stuck = (function () {
        Stuck.prototype.elements = [];

        Stuck.prototype.resizing = false;

        function Stuck(w, opts) {
          this.window = w;
          this.body = $("body");
          this.loadElements();
          this.calculateTopOffset();
          if (this.isIOS()) {
            this.body.on({
              touchmove: (function (_this) {
                return function () {
                  return _this.update();
                };
              })(this)
            });
          }
          this.window.scroll((function (_this) {
            return function () {
              return _this.update();
            };
          })(this));
          this.window.resize((function (_this) {
            return function () {
              return _this.resize();
            };
          })(this));
          this.update();
          this;
        }

        Stuck.prototype.isIOS = function () {
          return this._isIOS || (this._isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent));
        };

        Stuck.prototype.resize = function () {
          this.resizing = true;
          this.calculateTopOffset();
          this.update();
        };

        Stuck.prototype.loadElements = function () {
          var classes, container, divs, i, name, node, release, spacer, top, x, y;
          divs = $(".stuck");
          i = divs.length;
          y = 0;
          while (i--) {
            node = divs.eq(y);
            y++;
            release = false;
            container = '';
            classes = node.attr("class").split(/\s+/);
            spacer = $("<div/>");
            x = classes.length;
            while (x--) {
              name = classes[x];
              if (name === "release") {
                release = true;
                container = node.closest(".release-container");
              }
              if (!(name === "stuck" || name === "release")) {
                spacer.addClass(name);
              }
            }
            spacer.height(node.outerHeight()).hide().css("background-color", "transparent").addClass('spacer').insertBefore(node);
            top = node.offset().top - parseInt(node.css('margin-top'));
            this.elements.push({
              node: node,
              spacer: spacer,
              top: top,
              top_offset: 0,
              fixed: false,
              release: release,
              container: container,
              contained: false
            });
          }
        };

        Stuck.prototype.calculateTopOffset = function () {
          var collide_flag, collide_y, collision, el, elements, i, matrix, max_height, row_element, value, x, y, z;
          matrix = [];
          i = this.elements.length;
          x = 0;
          while (i--) {
            el = this.elements[x];
            x++;
            y = matrix.length;
            if (y === 0) {
              if (!el.release) {
                matrix.push([el]);
              }
            } else {
              collide_flag = false;
              while (y-- && !collide_flag) {
                max_height = 0;
                elements = matrix[y];
                z = elements.length;
                while (z--) {
                  row_element = elements[z];
                  collision = this.collide(row_element.node, el.node);
                  if (collision) {
                    value = row_element.top_offset + row_element.node.outerHeight(true);
                    if (value > max_height) {
                      max_height = value;
                    }
                    collide_flag = true;
                    if (matrix[y + 1] != null) {
                      collide_y = y + 1;
                    } else {
                      collide_y = -1;
                    }
                  } else {
                    if (y === 0) {
                      collide_y = 0;
                    }
                  }
                }
              }
              if (collide_flag) {
                el.top_offset = max_height;
                if (!el.release) {
                  if (collide_y >= 0) {
                    matrix[collide_y].push(el);
                  } else {
                    matrix.push([el]);
                  }
                }
              } else {
                el.top_offset = 0;
                if (!el.release) {
                  matrix[0].push(el);
                }
              }
            }
          }
        };

        Stuck.prototype.collide = function (node1, node2) {
          var n1l, n2l;
          n1l = node1.offset().left;
          n2l = node2.offset().left;
          if (n1l === n2l) {
            return true;
          } else if (n1l < n2l) {
            if (Math.floor(n1l) + node1.width() > Math.ceil(n2l)) {
              return true;
            } else {
              return false;
            }
          } else {
            if (Math.floor(n2l) + node2.width() > Math.ceil(n1l)) {
              return true;
            } else {
              return false;
            }
          }
        };

        Stuck.prototype.update = function () {
          var el, i, window_top;
          window_top = this.window.scrollTop();
          i = this.elements.length;
          while (i--) {
            el = this.elements[i];
            if (this.resizing) {
              if (el.fixed) {
                el.top = el.spacer.offset().top - parseInt(el.spacer.css('margin-top'));
              } else {
                el.top = el.node.offset().top - parseInt(el.node.css('margin-top'));
              }
              if (el.fixed) {
                el.node.css({
                  top: el.top_offset,
                  left: el.spacer.offset().left,
                  width: el.spacer.outerWidth()
                });
              }
              if (el.contained && window_top > el.container.offset().top + el.container.height() - el.node.height() - el.top_offset) {
                el.node.css({
                  position: "absolute",
                  top: el.container.height() - el.node.height(),
                  left: '',
                  width: '',
                  "z-index": ''
                });
              }
            }
            if (el.fixed && el.release && !el.contained && window_top > el.container.offset().top + el.container.height() - el.node.height() - el.top_offset) {
              el.contained = true;
              el.container.css("position", "relative");
              el.node.css({
                position: "absolute",
                top: el.container.height() - el.node.height(),
                left: '',
                width: '',
                "z-index": ''
              });
            }
            if (el.contained && window_top < el.container.offset().top + el.container.height() - el.node.height() - el.top_offset) {
              el.contained = false;
              el.container.css("position", '');
              el.node.css({
                position: "fixed",
                top: el.top_offset,
                left: el.spacer.offset().left,
                width: el.spacer.outerWidth(),
                "z-index": 99
              }).addClass('fixed');
            }
            if (!el.fixed && window_top > el.top - el.top_offset) {
              el.fixed = true;
              el.spacer.show();
              el.node.css({
                position: "fixed",
                top: el.top_offset,
                left: el.spacer.offset().left,
                width: el.spacer.outerWidth(),
                "z-index": 99
              }).addClass('fixed');
            }
            if (el.fixed && window_top < el.top - el.top_offset) {
              el.fixed = false;
              el.spacer.hide();
              el.node.css({
                position: "relative",
                top: '',
                left: '',
                width: '',
                "z-index": ''
              });
            }
          }
          this.resizing = false;
        };

        Stuck.prototype.destroy = function () {
          var i;
          i = this.elements.length;
          while (i--) {
            this.elements[i].spacer.remove();
          }
          this.window.unbind('scroll');
          this.window.unbind('resize');
          this.window = this.elements = null;
        };

        return Stuck;
      })();
      return new Stuck(this, opts);
    };
  })(jQuery);
}).call(undefined);

},{}]},{},[798])
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYXNhcC9icm93c2VyLWFzYXAuanMiLCJub2RlX21vZHVsZXMvYXNhcC9icm93c2VyLXJhdy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vcmVnZXhwL2VzY2FwZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtbnVtYmVyLXZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktY29weS13aXRoaW4uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktZmlsbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LXNwZWNpZXMtY29uc3RydWN0b3IuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jbGFzc29mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXRvLWpzb24uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jcmVhdGUtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RhdGUtdG8tcHJpbWl0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19lbnVtLWJ1Zy1rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0ta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMtaXMtcmVnZXhwLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZpeC1yZS13a3MuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmxhZ3MuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19odG1sLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2llOC1kb20tZGVmaW5lLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1yZWdleHAuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGVmaW5lLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fa2V5b2YuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbGlicmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21hdGgtbG9nMXAuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGEuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YWRhdGEuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZm9yY2VkLXBhbS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi1leHQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtcGllLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXRvLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX293bi1rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWZsb2F0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWludC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJ0aWFsLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhdGguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVwbGFjZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtcHJvdG8uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctcGFkLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXRyaW0uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXdzLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL191aWQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MtZXh0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUucmVnZXhwLmVzY2FwZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5jb3B5LXdpdGhpbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWxsLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbHRlci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZm9yLWVhY2guanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZnJvbS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pbmRleC1vZi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pcy1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5qb2luLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lmxhc3QtaW5kZXgtb2YuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubWFwLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm9mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS1yaWdodC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuc2xpY2UuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuc29tZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb3J0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNwZWNpZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS5ub3cuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXByaW1pdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXN0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5iaW5kLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hcC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmFjb3NoLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYXNpbmguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hdGFuaC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNicnQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jbHozMi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNvc2guanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5leHBtMS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmh5cG90LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguaW11bC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5sb2cyLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpbmguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC50YW5oLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgudHJ1bmMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLW5hbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1wcm90b3R5cGUtb2YuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QucHJldmVudC1leHRlbnNpb25zLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtZmxvYXQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnByb21pc2UuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5hcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5oYXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5wcmV2ZW50LWV4dGVuc2lvbnMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5jb25zdHJ1Y3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2guanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC50by1zdHJpbmcuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc2V0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5hbmNob3IuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJpZy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmVuZHMtd2l0aC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRjb2xvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udHNpemUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0YWxpY3MuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5saW5rLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5yYXcuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1Yi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3VwLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy50cmltLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN5bWJvbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5hcnJheS1idWZmZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXkuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQ4LWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXkuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDgtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi53ZWFrLW1hcC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi53ZWFrLXNldC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hc2FwLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LmVycm9yLmlzLWVycm9yLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC50by1qc29uLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5pbXVsaC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLmlzdWJoLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgudW11bGguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1nZXR0ZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1zZXR0ZXIuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LnZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYnNlcnZhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVmaW5lLW1ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVsZXRlLW1ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtbWV0YWRhdGEuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLWtleXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW1ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW93bi1tZXRhZGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lm1ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnNldC50by1qc29uLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5hdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcubWF0Y2gtYWxsLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtZW5kLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtc3RhcnQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tbGVmdC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1yaWdodC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3ltYm9sLm9ic2VydmFibGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3lzdGVtLmdsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuaW1tZWRpYXRlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXBvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLnRpbWVycy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9zaGltLmpzIiwibm9kZV9tb2R1bGVzL2Nhbi11c2UtZG9tL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NsYXNzbmFtZXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZXZlbnRlbWl0dGVyMy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudGxpc3RlbmVyL2V2ZW50bGlzdGVuZXIuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvRXZlbnRMaXN0ZW5lci5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudC5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9jYW1lbGl6ZS5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9jYW1lbGl6ZVN0eWxlTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9jb250YWluc05vZGUuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvY3JlYXRlQXJyYXlGcm9tTWl4ZWQuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvY3JlYXRlTm9kZXNGcm9tTWFya3VwLmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL2VtcHR5RnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvZW1wdHlPYmplY3QuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvZm9jdXNOb2RlLmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL2dldEFjdGl2ZUVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvZ2V0TWFya3VwV3JhcC5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9nZXRVbmJvdW5kZWRTY3JvbGxQb3NpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9oeXBoZW5hdGUuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvaHlwaGVuYXRlU3R5bGVOYW1lLmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL2ludmFyaWFudC5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9pc05vZGUuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvaXNUZXh0Tm9kZS5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi9rZXlNaXJyb3IuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIva2V5T2YuanMiLCJub2RlX21vZHVsZXMvZmJqcy9saWIvbWFwT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL21lbW9pemVTdHJpbmdPbmx5LmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL3BlcmZvcm1hbmNlLmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL3BlcmZvcm1hbmNlTm93LmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL3NoYWxsb3dFcXVhbC5qcyIsIm5vZGVfbW9kdWxlcy9mYmpzL2xpYi90b0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2ZianMvbGliL3dhcm5pbmcuanMiLCJub2RlX21vZHVsZXMvaW52YXJpYW50L2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLmRlYm91bmNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC50aHJvdHRsZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3Byb21pc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcHJvbWlzZS9saWIvY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9wcm9taXNlL2xpYi9kb25lLmpzIiwibm9kZV9tb2R1bGVzL3Byb21pc2UvbGliL2VzNi1leHRlbnNpb25zLmpzIiwibm9kZV9tb2R1bGVzL3Byb21pc2UvbGliL2ZpbmFsbHkuanMiLCJub2RlX21vZHVsZXMvcHJvbWlzZS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcHJvbWlzZS9saWIvbm9kZS1leHRlbnNpb25zLmpzIiwibm9kZV9tb2R1bGVzL3Byb21pc2UvbGliL3N5bmNocm9ub3VzLmpzIiwibm9kZV9tb2R1bGVzL3Byb3AtdHlwZXMvY2hlY2tQcm9wVHlwZXMuanMiLCJub2RlX21vZHVsZXMvcHJvcC10eXBlcy9mYWN0b3J5V2l0aFRocm93aW5nU2hpbXMuanMiLCJub2RlX21vZHVsZXMvcHJvcC10eXBlcy9mYWN0b3J5V2l0aFR5cGVDaGVja2Vycy5qcyIsIm5vZGVfbW9kdWxlcy9wcm9wLXR5cGVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Byb3AtdHlwZXMvbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0LmpzIiwibm9kZV9tb2R1bGVzL3Byb3AtdHlwZXMvbm9kZV9tb2R1bGVzL2ZianMvbGliL2VtcHR5RnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvcHJvcC10eXBlcy9ub2RlX21vZHVsZXMvZmJqcy9saWIvaW52YXJpYW50LmpzIiwibm9kZV9tb2R1bGVzL3Byb3AtdHlwZXMvbm9kZV9tb2R1bGVzL2ZianMvbGliL3dhcm5pbmcuanMiLCJub2RlX21vZHVsZXMvcmVhY3QtZG9tL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9zZXJ2ZXIuanMiLCJub2RlX21vZHVsZXMvcmVhY3QtbGF6eS1sb2FkL2xpYi9MYXp5TG9hZC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1sYXp5LWxvYWQvbGliL3V0aWxzL2dldEVsZW1lbnRQb3NpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1sYXp5LWxvYWQvbGliL3V0aWxzL2luVmlld3BvcnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QtbGF6eS1sb2FkL2xpYi91dGlscy9wYXJlbnRTY3JvbGwuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9DYW5jZWxsYXRpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9IaXN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvTWF0Y2guanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9OYXZpZ2F0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvUGF0aFV0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvUHJvcFR5cGVzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvUmVkaXJlY3QuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9Sb3V0ZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL1Njcm9sbEhpc3RvcnkuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9TdGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL1RyYW5zaXRpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9hY3Rpb25zL0xvY2F0aW9uQWN0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL2JlaGF2aW9ycy9JbWl0YXRlQnJvd3NlckJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvYmVoYXZpb3JzL1Njcm9sbFRvVG9wQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9jb21wb25lbnRzL0NvbnRleHRXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvY29tcG9uZW50cy9EZWZhdWx0Um91dGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9jb21wb25lbnRzL0xpbmsuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9jb21wb25lbnRzL05vdEZvdW5kUm91dGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9jb21wb25lbnRzL1JlZGlyZWN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvY29tcG9uZW50cy9Sb3V0ZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL2NvbXBvbmVudHMvUm91dGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvY3JlYXRlUm91dGVyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW4uanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9nZXRXaW5kb3dTY3JvbGxQb3NpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvaXNSZWFjdENoaWxkcmVuLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvbG9jYXRpb25zL0hhc2hMb2NhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL2xvY2F0aW9ucy9IaXN0b3J5TG9jYXRpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL2xpYi9sb2NhdGlvbnMvUmVmcmVzaExvY2F0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvbG9jYXRpb25zL1N0YXRpY0xvY2F0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9saWIvbG9jYXRpb25zL1Rlc3RMb2NhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL3J1blJvdXRlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL3N1cHBvcnRzSGlzdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1yb3V0ZXIvbGliL3dhcm5pbmcuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL25vZGVfbW9kdWxlcy9vYmplY3QtYXNzaWduL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9ub2RlX21vZHVsZXMvcXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL25vZGVfbW9kdWxlcy9xcy9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL25vZGVfbW9kdWxlcy9xcy9saWIvcGFyc2UuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtcm91dGVyL25vZGVfbW9kdWxlcy9xcy9saWIvc3RyaW5naWZ5LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LXJvdXRlci9ub2RlX21vZHVsZXMvcXMvbGliL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9BdXRvRm9jdXNVdGlscy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvQmVmb3JlSW5wdXRFdmVudFBsdWdpbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvQ1NTUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0NTU1Byb3BlcnR5T3BlcmF0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvQ2FsbGJhY2tRdWV1ZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvQ2hhbmdlRXZlbnRQbHVnaW4uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0NsaWVudFJlYWN0Um9vdEluZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9ET01DaGlsZHJlbk9wZXJhdGlvbnMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0RPTVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9ET01Qcm9wZXJ0eU9wZXJhdGlvbnMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0Rhbmdlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvRGVmYXVsdEV2ZW50UGx1Z2luT3JkZXIuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0VudGVyTGVhdmVFdmVudFBsdWdpbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvRXZlbnRDb25zdGFudHMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0V2ZW50UGx1Z2luSHViLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9FdmVudFBsdWdpblJlZ2lzdHJ5LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9FdmVudFBsdWdpblV0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9FdmVudFByb3BhZ2F0b3JzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9GYWxsYmFja0NvbXBvc2l0aW9uU3RhdGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL0hUTUxET01Qcm9wZXJ0eUNvbmZpZy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvTGlua2VkVmFsdWVVdGlscy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvT2JqZWN0LmFzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUG9vbGVkQ2xhc3MuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdEJyb3dzZXJDb21wb25lbnRNaXhpbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdENoaWxkUmVjb25jaWxlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RDaGlsZHJlbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RDbGFzcy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RDb21wb25lbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdENvbXBvbmVudEVudmlyb25tZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdENvbXBvc2l0ZUNvbXBvbmVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RDdXJyZW50T3duZXIuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdERPTUJ1dHRvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RET01Db21wb25lbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NRmFjdG9yaWVzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdERPTUZlYXR1cmVGbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RET01JRE9wZXJhdGlvbnMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NSW5wdXQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NT3B0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdERPTVNlbGVjdC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RET01TZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NU2VydmVyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdERPTVRleHRDb21wb25lbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RE9NVGV4dGFyZWEuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RGVmYXVsdEJhdGNoaW5nU3RyYXRlZ3kuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RGVmYXVsdEluamVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3REZWZhdWx0UGVyZi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdEVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RWxlbWVudFZhbGlkYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RFbXB0eUNvbXBvbmVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RFbXB0eUNvbXBvbmVudFJlZ2lzdHJ5LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdEVycm9yVXRpbHMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RXZlbnRFbWl0dGVyTWl4aW4uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0RXZlbnRMaXN0ZW5lci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RJbmplY3Rpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0SW5wdXRTZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0SW5zdGFuY2VIYW5kbGVzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdEluc3RhbmNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdElzb21vcnBoaWMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0TWFya3VwQ2hlY2tzdW0uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0TW91bnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0TXVsdGlDaGlsZC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0TmF0aXZlQ29tcG9uZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdE5vb3BVcGRhdGVRdWV1ZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RPd25lci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RQZXJmLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RQcm9wVHlwZXMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0UmVjb25jaWxlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvUmVhY3RSZWYuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0Um9vdEluZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdFNlcnZlckJhdGNoaW5nU3RyYXRlZ3kuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0U2VydmVyUmVuZGVyaW5nLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdFVwZGF0ZVF1ZXVlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9SZWFjdFVwZGF0ZXMuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1JlYWN0VmVyc2lvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvU1ZHRE9NUHJvcGVydHlDb25maWcuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1NlbGVjdEV2ZW50UGx1Z2luLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TZXJ2ZXJSZWFjdFJvb3RJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvU2ltcGxlRXZlbnRQbHVnaW4uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1N5bnRoZXRpY0NsaXBib2FyZEV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNDb21wb3NpdGlvbkV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNEcmFnRXZlbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL1N5bnRoZXRpY0V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNGb2N1c0V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNJbnB1dEV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNLZXlib2FyZEV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNNb3VzZUV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNUb3VjaEV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNVSUV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9TeW50aGV0aWNXaGVlbEV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9UcmFuc2FjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvVmlld3BvcnRNZXRyaWNzLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9hY2N1bXVsYXRlSW50by5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvYWRsZXIzMi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvY2FuRGVmaW5lUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL2Rhbmdlcm91c1N0eWxlVmFsdWUuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL2RlcHJlY2F0ZWQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL2VzY2FwZVRleHRDb250ZW50Rm9yQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZmluZERPTU5vZGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL2ZsYXR0ZW5DaGlsZHJlbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZm9yRWFjaEFjY3VtdWxhdGVkLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9nZXRFdmVudENoYXJDb2RlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9nZXRFdmVudEtleS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZ2V0RXZlbnRNb2RpZmllclN0YXRlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9nZXRFdmVudFRhcmdldC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZ2V0SXRlcmF0b3JGbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZ2V0Tm9kZUZvckNoYXJhY3Rlck9mZnNldC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvZ2V0VGV4dENvbnRlbnRBY2Nlc3Nvci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvaXNFdmVudFN1cHBvcnRlZC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvaXNUZXh0SW5wdXRFbGVtZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9vbmx5Q2hpbGQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL3F1b3RlQXR0cmlidXRlVmFsdWVGb3JCcm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9yZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvc2V0SW5uZXJIVE1MLmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2xpYi9zZXRUZXh0Q29udGVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9saWIvc2hvdWxkVXBkYXRlUmVhY3RDb21wb25lbnQuanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL3RyYXZlcnNlQWxsQ2hpbGRyZW4uanMiLCJub2RlX21vZHVsZXMvcmVhY3QvbGliL3ZhbGlkYXRlRE9NTmVzdGluZy5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9yZWFjdC5qcyIsIm5vZGVfbW9kdWxlcy9yZWR1Y2UtY29tcG9uZW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC1jb3JlL2xpYi9BY3Rpb25NZXRob2RzLmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC1jb3JlL2xpYi9LZWVwLmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC1jb3JlL2xpYi9MaXN0ZW5lck1ldGhvZHMuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4LWNvcmUvbGliL1B1Ymxpc2hlck1ldGhvZHMuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4LWNvcmUvbGliL1N0b3JlTWV0aG9kcy5qcyIsIm5vZGVfbW9kdWxlcy9yZWZsdXgtY29yZS9saWIvYmluZE1ldGhvZHMuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4LWNvcmUvbGliL2NyZWF0ZUFjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWZsdXgtY29yZS9saWIvY3JlYXRlU3RvcmUuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4LWNvcmUvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC1jb3JlL2xpYi9qb2lucy5qcyIsIm5vZGVfbW9kdWxlcy9yZWZsdXgtY29yZS9saWIvbWl4ZXIuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4LWNvcmUvbGliL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC9zcmMvTGlzdGVuZXJNaXhpbi5qcyIsIm5vZGVfbW9kdWxlcy9yZWZsdXgvc3JjL2Nvbm5lY3QuanMiLCJub2RlX21vZHVsZXMvcmVmbHV4L3NyYy9jb25uZWN0RmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL3JlZmx1eC9zcmMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcmVmbHV4L3NyYy9saXN0ZW5Uby5qcyIsIm5vZGVfbW9kdWxlcy9yZWZsdXgvc3JjL2xpc3RlblRvTWFueS5qcyIsIm5vZGVfbW9kdWxlcy9yZWdlbmVyYXRvci1ydW50aW1lL3J1bnRpbWUuanMiLCJub2RlX21vZHVsZXMvc3RyaW5nZm9ybWF0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvYWxwaGEuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9ibGFja2xpc3QuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9jb250YWlucy5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2VxdWFscy5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2VzY2FwZS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzQWZ0ZXIuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0FscGhhLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNBbHBoYW51bWVyaWMuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0FzY2lpLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNCYXNlNjQuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0JlZm9yZS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzQm9vbGVhbi5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzQnl0ZUxlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzQ3JlZGl0Q2FyZC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzQ3VycmVuY3kuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0RhdGFVUkkuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0RhdGUuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0RlY2ltYWwuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0RpdmlzaWJsZUJ5LmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNFbWFpbC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzRW1wdHkuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0ZRRE4uanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0Zsb2F0LmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNGdWxsV2lkdGguanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0hhbGZXaWR0aC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSGV4Q29sb3IuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0hleGFkZWNpbWFsLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNJUC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSVNCTi5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSVNJTi5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSVNPODYwMS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSVNTTi5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSW4uanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc0ludC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzSlNPTi5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzTGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNMb3dlcmNhc2UuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc01BQ0FkZHJlc3MuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc01ENS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzTW9iaWxlUGhvbmUuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc01vbmdvSWQuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc011bHRpYnl0ZS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzTnVtZXJpYy5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzU3Vycm9nYXRlUGFpci5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL2lzVVJMLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNVVUlELmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvaXNVcHBlcmNhc2UuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc1ZhcmlhYmxlV2lkdGguanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9pc1doaXRlbGlzdGVkLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvbHRyaW0uanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9tYXRjaGVzLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvbm9ybWFsaXplRW1haWwuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi9ydHJpbS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL3N0cmlwTG93LmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdG9Cb29sZWFuLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdG9EYXRlLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdG9GbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL3RvSW50LmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdHJpbS5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL3VuZXNjYXBlLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdXRpbC9hc3NlcnRTdHJpbmcuanMiLCJub2RlX21vZHVsZXMvdmFsaWRhdG9yL2xpYi91dGlsL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL3ZhbGlkYXRvci9saWIvdXRpbC90b1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy92YWxpZGF0b3IvbGliL3doaXRlbGlzdC5qcyIsInNyYy9kZXBlbmRlbmNpZXMvV2F2ZXMvZGlzdC93YXZlcy5taW4uanMiLCJzcmMvZGVwZW5kZW5jaWVzL2JsdWVpbXAtZmlsZS11cGxvYWQvanMvanF1ZXJ5LmZpbGV1cGxvYWQuanMiLCJzcmMvZGVwZW5kZW5jaWVzL2JsdWVpbXAtZmlsZS11cGxvYWQvanMvdmVuZG9yL2pxdWVyeS51aS53aWRnZXQuanMiLCJzcmMvZGVwZW5kZW5jaWVzL2NsaXBib2FyZC9kaXN0L2NsaXBib2FyZC5taW4uanMiLCJzcmMvZGVwZW5kZW5jaWVzL2V6LXBsdXMvc3JjL2pxdWVyeS5lei1wbHVzLmpzIiwic3JjL2RlcGVuZGVuY2llcy9mb3VuZGF0aW9uLWRhdGVwaWNrZXIvanMvZm91bmRhdGlvbi1kYXRlcGlja2VyLm1pbi5qcyIsInNyYy9kZXBlbmRlbmNpZXMvZm91bmRhdGlvbi9qcy9mb3VuZGF0aW9uLmpzIiwic3JjL2RlcGVuZGVuY2llcy9mb3VuZGF0aW9uL2pzL2ZvdW5kYXRpb24vZm91bmRhdGlvbi5vZmZjYW52YXMuanMiLCJzcmMvZGVwZW5kZW5jaWVzL2pxdWVyeS11aS9qcXVlcnktdWkubWluLmpzIiwic3JjL2RlcGVuZGVuY2llcy9qcXVlcnkuY29va2llL2pxdWVyeS5jb29raWUuanMiLCJzcmMvZGVwZW5kZW5jaWVzL2pxdWVyeS5pbnZpZXcvanF1ZXJ5Lmludmlldy5taW4uanMiLCJzcmMvZGVwZW5kZW5jaWVzL2pxdWVyeS5wYW56b29tL2Rpc3QvanF1ZXJ5LnBhbnpvb20uanMiLCJzcmMvZGVwZW5kZW5jaWVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qcyIsInNyYy9kZXBlbmRlbmNpZXMvbGlnaHRzbGlkZXIvZGlzdC9qcy9saWdodHNsaWRlci5taW4uanMiLCJzcmMvZGVwZW5kZW5jaWVzL3NlbWFudGljLXVpLWRyb3Bkb3duL2Ryb3Bkb3duLm1pbi5qcyIsInNyYy9kZXBlbmRlbmNpZXMvc2VtYW50aWMtdWktdHJhbnNpdGlvbi90cmFuc2l0aW9uLm1pbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL2JyYW5kX2ZpbHRlcl9hY3Rpb25zLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FjdGlvbnMvY2FydF9hY3Rpb25zLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FjdGlvbnMvY2F0ZWdvcnlfZmlsdGVyX2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9uc19uZXcuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy9oaXN0b3J5X2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy9pbGx1c3RyYXRpb25fYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL21vZGVsc2VhcmNoX2FjdGlvbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL29yZGVybGluZXNfYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL3ByaWNlX3NlcnZpY2VfYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL3Byb2R1Y3RfbGluZV9maWx0ZXJfYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL3NhbGVzZm9yY2VfcmVjb21tZW5kYXRpb25zX2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy9zZWFyY2hfYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL3NlcmlhbF9udW1iZXJfZmlsdGVyX2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy9zb3J0X2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy90b3BfY2F0ZWdvcnlfZmlsdGVyX2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYWN0aW9ucy90cmVldmlld19hY3Rpb25zLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FjdGlvbnMvdXNhZ2VfdHlwZV9maWx0ZXJfYWN0aW9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hY3Rpb25zL3VzZXJfYWRkcmVzc2VzX2FjdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYXBpL2JyZWFkY3J1bWJfYXBpLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FwaS9jYXJ0X2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvY2hlY2tvdXRfYXBpLW5ldy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvY2hlY2tvdXRfYXBpLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FwaS9pbGx1c3RyYXRpb25Gb3JPdmVybGF5X2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvaWxsdXN0cmF0aW9uX2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvaW1wZXJzb25hdG9yX2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvbW9kZWxzZWFyY2hfYXBpLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FwaS9wcm9kdWN0X2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19hcGkvc2FsZXNmb3JjZV9yZWNvbW1lbmRhdGlvbnNfYXBpLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2FwaS90cmVldmlld19hcGkuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fYXBpL3VzZXJfYWRkcmVzc2VzX2FwaS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvYWRkY2xhc3MuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL2FkZHRvY2FydC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvYXV0b3N1Ym1pdC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvYnJhbmR0cmVlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9jbGVhci1jYXJ0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9jb21wbGFpbnR2aWV3LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9jb25maXJtYXRpb25wYWdlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9jb29raWUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL2N1c3RvbS1ldmVudHMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL2N1c3RvbS1zZWFyY2gtZXZlbnRzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9kYXRlcGlja2VyLWxhbmcuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL2RhdGVwaWNrZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL2RldGVjdFZlbmRvci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvZml0c19teV9tYWNoaW5lLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9pZS1lcXVhbGl6ZXItZml4LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9saXN0dmlld3RvZ2dsZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvcGFuem9vbS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvcHJpbnQuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3Byb2R1Y3QtY2FyZC1mb290ZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3Byb2R1Y3QtY29udGFpbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3Byb2R1Y3RpbWFnZXpvb20uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3NjYWxlZC1wcmljZXMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3Njcm9sbGNvbnRyb2xzLXByb2R1Y3RkZXRhaWwuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3Njcm9sbGNvbnRyb2xzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9zY3JvbGx0by5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvc2VhcmNocmVzdWx0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9zZWxmcmVnaXN0cmF0aW9uLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX2xpYi9zZW1hbnRpYy1kcm9wZG93bi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19saWIvc2hhcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3N0YXJ0cGFnZS1zbGlkZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3RvZ2dsZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3RvZ2dsZXJIZWFkZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fbGliL3VzZXJhZGRyZXNzZXMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2FkZHJlc3NfZmllbGRfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2JyYW5kX2ZpbHRlcl9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvYnJlYWRjcnVtYl9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2FydF9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2F0ZWdvcnlfZmlsdGVyX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9jaGVja291dF9hZGRyZXNzZXNfYWxlcnRfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2NoZWNrb3V0X2FkZHJlc3Nlc19zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfYmlsbGluZ19zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfY2FydF9hbGVydF9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfY2FydF9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfY2FydF90b3RhbF9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfY2FydF93YXJuaW5nX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9jaGVja291dF9kYW5nZXJvdXNfZ29vZHNfYWxlcnRfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2NoZWNrb3V0X2xvYWRpbmdfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2NoZWNrb3V0X29yZGVyX3NpbXVsYXRpb25fc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2NoZWNrb3V0X3NoaXBwaW5nX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9jaGVja291dF9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfc3VtbWFyeV9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvY2hlY2tvdXRfdHJhY2tpbmdfZGF0YV9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvZmlsdGVyX2NvdW50X3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9oaXN0b3J5X3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9pbGx1c3RyYXRpb25Gb3JPdmVybGF5X3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9pbGx1c3RyYXRpb25fc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL2xvY2FsaXphdGlvbl9zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvbW9kZWxfdHJlZV9zZWFyY2hfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL21vZGVsc2VhcmNoX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9vcmRlcmxpbmVzX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9wcmljZV9zZXJ2aWNlX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9wcm9kdWN0X2xpbmVfZmlsdGVyX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9zZWFyY2hfcmVzdWx0X3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9zZWFyY2hfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL3NlcmlhbF9udW1iZXJfZmlsdGVyX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy9zb3J0X3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy90b2dnbGVfZmlsdGVyX3N0b3JlX21peGluLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy90b3BfY2F0ZWdvcnlfZmlsdGVyX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy90cmVldmlld19zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvdXNhZ2VfdHlwZV9maWx0ZXJfc3RvcmUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9fc3RvcmVzL3VzZXJfYWRkcmVzc2VzX3N0b3JlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvX3N0b3Jlcy91c2VyX2NvdW50cnlfb3B0aW9uc19zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL19zdG9yZXMvdXNlcl9kZWZhdWx0X2FkZHJlc3Nlc19zdG9yZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2JhdGNob3JkZXIvYmF0Y2hvcmRlci1jYXJ0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvYmF0Y2hvcmRlci9iYXRjaG9yZGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvYmF0Y2hvcmRlci91cGxvYWRmaWxlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY2hlY2tvdXQvY2hlY2tvdXQtbmV3LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY2hlY2tvdXQvY2hlY2tvdXRfY2FydF9saW5laXRlbV9jb21tZW50LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY2hlY2tvdXQvY2hlY2tvdXRfY2FydF9saW5laXRlbV9kZWxldGUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jaGVja291dC9jaGVja291dF9jYXJ0X2xpbmVpdGVtX2xvYWRpbmcuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jaGVja291dC9jaGVja291dF9jYXJ0X2xpbmVpdGVtX3VwZGF0ZS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NoZWNrb3V0L2NoZWNrb3V0X3NoaXBwaW5nLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY2hlY2tvdXQvY2hlY2tvdXRfc2hpcHBpbmdfbmV3LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vYnJhbmRuYXZpZ2F0aW9uLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vYnJhbmRuYXZpZ2F0aW9uX2hpc3RvcnkuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2JyYW5kbmF2aWdhdGlvbi9icmFuZG5hdmlnYXRpb25faGlzdG9yeV9pdGVtLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vYnJhbmRuYXZpZ2F0aW9uX3RyZWUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2JyYW5kbmF2aWdhdGlvbi9icmFuZG5hdmlnYXRpb25fdHJlZV9pdGVtLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vYnJhbmRzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vZG9jdW1lbnRzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vbW9kZWxzZWFyY2gtcmVzdWx0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmFuZG5hdmlnYXRpb24vbW9kZWxzZWFyY2guanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2JyYW5kbmF2aWdhdGlvbi92aXN1YWxicm93c2luZy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvYnJlYWRjcnVtYi9icmVhZGNydW1iLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9icmVhZGNydW1iL2JyZWFkY3J1bWJfaXRlbS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvZmlsdGVyL2JyYW5kX2ZpbHRlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlcl9jb3VudC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlcl90b2dnbGUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2ZpbHRlci9maWx0ZXJzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9maWx0ZXIvcHJvZHVjdF9saW5lX2ZpbHRlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvZmlsdGVyL3NlcmlhbF9udW1iZXJfZmlsdGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9maWx0ZXIvc29ydGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9maWx0ZXIvdG9wX2NhdGVnb3J5X2ZpbHRlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvZmlsdGVyL3VzYWdlX3R5cGVfZmlsdGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9oZWFkZXIvbGFuZ3VhZ2Vfc2VsZWN0b3IuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2lsbHVzdHJhdGlvbi9hZGR0b2NhcnRfYnV0dG9ucy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvaWxsdXN0cmF0aW9uL2hvdHNwb3RzLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9pbGx1c3RyYXRpb24vaWxsdXN0cmF0aW9uLWluZm8uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2lsbHVzdHJhdGlvbi9pbGx1c3RyYXRpb24uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2lsbHVzdHJhdGlvbi9pbGx1c3RyYXRpb25fY29udGFpbmVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9pbGx1c3RyYXRpb24va2l0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9pbGx1c3RyYXRpb24va2l0cGFydC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvaWxsdXN0cmF0aW9uL3BhcnQuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL2lsbHVzdHJhdGlvbi9wYXJ0bGlzdC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvbWlzY2VsbGFuZW91cy91cmxIYW5kbGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy9zZWFyY2gvZ3JvdXBfc2VsZWN0b3IuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3NlYXJjaC9vdGhlcl9yZXN1bHQuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3NlYXJjaC9yZXN1bHRfbGlzdC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvc2VhcmNoL3NlYXJjaF9maWVsZC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvc2VhcmNoL3NlYXJjaF9oZWFkZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3NlYXJjaC9zcGFyZV9wYXJ0X2Zvb3Rlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvc2VhcmNoL3NwYXJlX3BhcnRfcmVzdWx0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy90cmVldmlldy9tb2RlbHRyZWUuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3RyZWV2aWV3L21vZGVsdHJlZWl0ZW0uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3RyZWV2aWV3L21vZGVsdHJlZXNlYXJjaC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvd2lzaGxpc3QvbGluZWl0ZW1IYW5kbGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvY29tcG9uZW50cy93aXNobGlzdC93aXNobGlzdERldGFpbC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2NvbXBvbmVudHMvd2lzaGxpc3Qvd2lzaGxpc3RIZWFkZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9jb21wb25lbnRzL3dpc2hsaXN0L3dpc2hsaXN0TGlzdGluZy5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2lsbHVzdHJhdGlvbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2ltcGVyc29uYXRvci9pbXBlcnNvbmF0ZWRfdXNlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2ltcGVyc29uYXRvci9pbXBlcnNvbmF0b3IuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9pbXBlcnNvbmF0b3IvaW1wZXJzb25hdG9yX2F1dG9jb21wbGV0ZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9pbXBlcnNvbmF0b3IvaW1wZXJzb25hdG9yX2NvbnRhaW5lci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL2ltcGVyc29uYXRvci9pbXBlcnNvbmF0b3Jfc2lnbm91dC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL21haW4uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9taW5pY2FydC9taW5pY2FydC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL21pbmljYXJ0L21pbmljYXJ0X2NvbnRlbnQuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9taW5pY2FydC9taW5pY2FydF9saW5laXRlbS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL21pbmljYXJ0L21pbmljYXJ0X3RvdGFsaXRlbXMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9taW5pY2FydC9taW5pY2FydF90b3RhbHByaWNlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvbm90aWZpY2F0aW9ucy9tZXNzYWdlSW5qZWN0b3IuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9ub3RpZmljYXRpb25zL25vdGlmaWNhdGlvbnMuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9vcmRlcmhpc3Rvcnkvb3JkZXJoaXN0b3J5LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9mb290ZXJfY29uZGVuc2VkLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9pdGVtLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9pdGVtX2NvbmRlbnNlZC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3NhbGVzZm9yY2VyZWNvbW1lbmRhdGlvbnMvbGlzdC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3NhbGVzZm9yY2VyZWNvbW1lbmRhdGlvbnMvbGlzdF9za2VsZXRvbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3NhbGVzZm9yY2VyZWNvbW1lbmRhdGlvbnMvcmVmbG93LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9zYWxlc2ZvcmNlcmVjb21tZW5kYXRpb25zLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9zbGlkZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy9zYWxlc2ZvcmNlcmVjb21tZW5kYXRpb25zL3NsaWRlcl9za2VsZXRvbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3NlYXJjaC9hdXRvY29tcGxldGVyLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvc2VhcmNoL3NtYXJ0X3NlYXJjaC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3NlcnZlci5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3VzZXJfYWRkcmVzc2VzL2FkZHJlc3NfYWRkX2l0ZW0uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy91c2VyX2FkZHJlc3Nlcy9hZGRyZXNzX2RlZmF1bHRfaW5kaWNhdG9yLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvdXNlcl9hZGRyZXNzZXMvYWRkcmVzc19lcnJvcl9tZXNzYWdlLmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvdXNlcl9hZGRyZXNzZXMvYWRkcmVzc19maWVsZC5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3VzZXJfYWRkcmVzc2VzL2FkZHJlc3NfaXRlbS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3VzZXJfYWRkcmVzc2VzL2NvdW50cnlfZHJvcGRvd24uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy91c2VyX2FkZHJlc3Nlcy9jb3VudHJ5X3JlZ2lvbl9jb250YWluZXIuanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy91c2VyX2FkZHJlc3Nlcy9yZWdpb25fZHJvcGRvd24uanMiLCJDOi9Qcm9qZWN0cy9oaWFiLmVjb20vRnJvbnRlbmQvc3JjL3RoZW1lcy9oaWFiLmVjb20vc2NyaXB0cy91c2VyX2FkZHJlc3Nlcy91c2VyX2FkZHJlc3Nlc19kZWZhdWx0LmpzIiwiQzovUHJvamVjdHMvaGlhYi5lY29tL0Zyb250ZW5kL3NyYy90aGVtZXMvaGlhYi5lY29tL3NjcmlwdHMvdXNlcl9hZGRyZXNzZXMvdXNlcl9hZGRyZXNzZXNfaXRlbS5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3ZlbmRvcnMvZm91bmRhdGlvbi5qcyIsIkM6L1Byb2plY3RzL2hpYWIuZWNvbS9Gcm9udGVuZC9zcmMvdGhlbWVzL2hpYWIuZWNvbS9zY3JpcHRzL3ZlbmRvcnMvanF1ZXJ5LnN0dWNrLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTs7QUNBQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTs7QUNGQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5ZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BOztBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDelhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDdmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL2pZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM5ZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakVBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMvZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM5S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDdFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDblVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNsd0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDajhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDN0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3RQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDeFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDM0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDajFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy9lQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDN0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbldBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDOU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxa0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDNUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFXQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdnRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakJBO0FBQ0E7Ozs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3I4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1akJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcjJEQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcjdNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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LG9CQUFJLEVBQUUsRUFBRTtBQUNSLHFCQUFLLEVBQUUsRUFBRTtBQUNULHlCQUFTLEVBQUUsRUFBRTtlQUNkLENBQUMsQ0FBQzthQUNKO1dBQ0Y7QUFDRCxjQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztTQUN2QixDQUFDOztBQUVGLGFBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLFlBQVc7QUFDbkMsY0FBSSxDQUFDLENBQUM7QUFDTixXQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7QUFDekIsaUJBQU8sQ0FBQyxFQUFFLEVBQUU7QUFDVixnQkFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7V0FDbEM7QUFDRCxjQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM3QixjQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM3QixjQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1NBQ3BDLENBQUM7O0FBRUYsZUFBTyxLQUFLLENBQUM7T0FFZCxDQUFBLEVBQUcsQ0FBQztBQUNMLGFBQU8sSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQzlCLENBQUM7R0FDSCxDQUFBLENBQUUsTUFBTSxDQUFDLENBQUM7Q0FFWixDQUFBLENBQUUsSUFBSSxXQUFNLENBQUMiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vIHJhd0FzYXAgcHJvdmlkZXMgZXZlcnl0aGluZyB3ZSBuZWVkIGV4Y2VwdCBleGNlcHRpb24gbWFuYWdlbWVudC5cbnZhciByYXdBc2FwID0gcmVxdWlyZShcIi4vcmF3XCIpO1xuLy8gUmF3VGFza3MgYXJlIHJlY3ljbGVkIHRvIHJlZHVjZSBHQyBjaHVybi5cbnZhciBmcmVlVGFza3MgPSBbXTtcbi8vIFdlIHF1ZXVlIGVycm9ycyB0byBlbnN1cmUgdGhleSBhcmUgdGhyb3duIGluIHJpZ2h0IG9yZGVyIChGSUZPKS5cbi8vIEFycmF5LWFzLXF1ZXVlIGlzIGdvb2QgZW5vdWdoIGhlcmUsIHNpbmNlIHdlIGFyZSBqdXN0IGRlYWxpbmcgd2l0aCBleGNlcHRpb25zLlxudmFyIHBlbmRpbmdFcnJvcnMgPSBbXTtcbnZhciByZXF1ZXN0RXJyb3JUaHJvdyA9IHJhd0FzYXAubWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyKHRocm93Rmlyc3RFcnJvcik7XG5cbmZ1bmN0aW9uIHRocm93Rmlyc3RFcnJvcigpIHtcbiAgICBpZiAocGVuZGluZ0Vycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgcGVuZGluZ0Vycm9ycy5zaGlmdCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDYWxscyBhIHRhc2sgYXMgc29vbiBhcyBwb3NzaWJsZSBhZnRlciByZXR1cm5pbmcsIGluIGl0cyBvd24gZXZlbnQsIHdpdGggcHJpb3JpdHlcbiAqIG92ZXIgb3RoZXIgZXZlbnRzIGxpa2UgYW5pbWF0aW9uLCByZWZsb3csIGFuZCByZXBhaW50LiBBbiBlcnJvciB0aHJvd24gZnJvbSBhblxuICogZXZlbnQgd2lsbCBub3QgaW50ZXJydXB0LCBub3IgZXZlbiBzdWJzdGFudGlhbGx5IHNsb3cgZG93biB0aGUgcHJvY2Vzc2luZyBvZlxuICogb3RoZXIgZXZlbnRzLCBidXQgd2lsbCBiZSByYXRoZXIgcG9zdHBvbmVkIHRvIGEgbG93ZXIgcHJpb3JpdHkgZXZlbnQuXG4gKiBAcGFyYW0ge3tjYWxsfX0gdGFzayBBIGNhbGxhYmxlIG9iamVjdCwgdHlwaWNhbGx5IGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBub1xuICogYXJndW1lbnRzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGFzYXA7XG5mdW5jdGlvbiBhc2FwKHRhc2spIHtcbiAgICB2YXIgcmF3VGFzaztcbiAgICBpZiAoZnJlZVRhc2tzLmxlbmd0aCkge1xuICAgICAgICByYXdUYXNrID0gZnJlZVRhc2tzLnBvcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJhd1Rhc2sgPSBuZXcgUmF3VGFzaygpO1xuICAgIH1cbiAgICByYXdUYXNrLnRhc2sgPSB0YXNrO1xuICAgIHJhd0FzYXAocmF3VGFzayk7XG59XG5cbi8vIFdlIHdyYXAgdGFza3Mgd2l0aCByZWN5Y2xhYmxlIHRhc2sgb2JqZWN0cy4gIEEgdGFzayBvYmplY3QgaW1wbGVtZW50c1xuLy8gYGNhbGxgLCBqdXN0IGxpa2UgYSBmdW5jdGlvbi5cbmZ1bmN0aW9uIFJhd1Rhc2soKSB7XG4gICAgdGhpcy50YXNrID0gbnVsbDtcbn1cblxuLy8gVGhlIHNvbGUgcHVycG9zZSBvZiB3cmFwcGluZyB0aGUgdGFzayBpcyB0byBjYXRjaCB0aGUgZXhjZXB0aW9uIGFuZCByZWN5Y2xlXG4vLyB0aGUgdGFzayBvYmplY3QgYWZ0ZXIgaXRzIHNpbmdsZSB1c2UuXG5SYXdUYXNrLnByb3RvdHlwZS5jYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHRoaXMudGFzay5jYWxsKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGFzYXAub25lcnJvcikge1xuICAgICAgICAgICAgLy8gVGhpcyBob29rIGV4aXN0cyBwdXJlbHkgZm9yIHRlc3RpbmcgcHVycG9zZXMuXG4gICAgICAgICAgICAvLyBJdHMgbmFtZSB3aWxsIGJlIHBlcmlvZGljYWxseSByYW5kb21pemVkIHRvIGJyZWFrIGFueSBjb2RlIHRoYXRcbiAgICAgICAgICAgIC8vIGRlcGVuZHMgb24gaXRzIGV4aXN0ZW5jZS5cbiAgICAgICAgICAgIGFzYXAub25lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJbiBhIHdlYiBicm93c2VyLCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuIEhvd2V2ZXIsIHRvIGF2b2lkXG4gICAgICAgICAgICAvLyBzbG93aW5nIGRvd24gdGhlIHF1ZXVlIG9mIHBlbmRpbmcgdGFza3MsIHdlIHJldGhyb3cgdGhlIGVycm9yIGluIGFcbiAgICAgICAgICAgIC8vIGxvd2VyIHByaW9yaXR5IHR1cm4uXG4gICAgICAgICAgICBwZW5kaW5nRXJyb3JzLnB1c2goZXJyb3IpO1xuICAgICAgICAgICAgcmVxdWVzdEVycm9yVGhyb3coKTtcbiAgICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMudGFzayA9IG51bGw7XG4gICAgICAgIGZyZWVUYXNrc1tmcmVlVGFza3MubGVuZ3RoXSA9IHRoaXM7XG4gICAgfVxufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgbWVhbnMgcG9zc2libGUgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gaXRzIG93biB0dXJuLCB3aXRoXG4vLyBwcmlvcml0eSBvdmVyIG90aGVyIGV2ZW50cyBpbmNsdWRpbmcgSU8sIGFuaW1hdGlvbiwgcmVmbG93LCBhbmQgcmVkcmF3XG4vLyBldmVudHMgaW4gYnJvd3NlcnMuXG4vL1xuLy8gQW4gZXhjZXB0aW9uIHRocm93biBieSBhIHRhc2sgd2lsbCBwZXJtYW5lbnRseSBpbnRlcnJ1cHQgdGhlIHByb2Nlc3Npbmcgb2Zcbi8vIHN1YnNlcXVlbnQgdGFza3MuIFRoZSBoaWdoZXIgbGV2ZWwgYGFzYXBgIGZ1bmN0aW9uIGVuc3VyZXMgdGhhdCBpZiBhblxuLy8gZXhjZXB0aW9uIGlzIHRocm93biBieSBhIHRhc2ssIHRoYXQgdGhlIHRhc2sgcXVldWUgd2lsbCBjb250aW51ZSBmbHVzaGluZyBhc1xuLy8gc29vbiBhcyBwb3NzaWJsZSwgYnV0IGlmIHlvdSB1c2UgYHJhd0FzYXBgIGRpcmVjdGx5LCB5b3UgYXJlIHJlc3BvbnNpYmxlIHRvXG4vLyBlaXRoZXIgZW5zdXJlIHRoYXQgbm8gZXhjZXB0aW9ucyBhcmUgdGhyb3duIGZyb20geW91ciB0YXNrLCBvciB0byBtYW51YWxseVxuLy8gY2FsbCBgcmF3QXNhcC5yZXF1ZXN0Rmx1c2hgIGlmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG5tb2R1bGUuZXhwb3J0cyA9IHJhd0FzYXA7XG5mdW5jdGlvbiByYXdBc2FwKHRhc2spIHtcbiAgICBpZiAoIXF1ZXVlLmxlbmd0aCkge1xuICAgICAgICByZXF1ZXN0Rmx1c2goKTtcbiAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgIH1cbiAgICAvLyBFcXVpdmFsZW50IHRvIHB1c2gsIGJ1dCBhdm9pZHMgYSBmdW5jdGlvbiBjYWxsLlxuICAgIHF1ZXVlW3F1ZXVlLmxlbmd0aF0gPSB0YXNrO1xufVxuXG52YXIgcXVldWUgPSBbXTtcbi8vIE9uY2UgYSBmbHVzaCBoYXMgYmVlbiByZXF1ZXN0ZWQsIG5vIGZ1cnRoZXIgY2FsbHMgdG8gYHJlcXVlc3RGbHVzaGAgYXJlXG4vLyBuZWNlc3NhcnkgdW50aWwgdGhlIG5leHQgYGZsdXNoYCBjb21wbGV0ZXMuXG52YXIgZmx1c2hpbmcgPSBmYWxzZTtcbi8vIGByZXF1ZXN0Rmx1c2hgIGlzIGFuIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG1ldGhvZCB0aGF0IGF0dGVtcHRzIHRvIGtpY2tcbi8vIG9mZiBhIGBmbHVzaGAgZXZlbnQgYXMgcXVpY2tseSBhcyBwb3NzaWJsZS4gYGZsdXNoYCB3aWxsIGF0dGVtcHQgdG8gZXhoYXVzdFxuLy8gdGhlIGV2ZW50IHF1ZXVlIGJlZm9yZSB5aWVsZGluZyB0byB0aGUgYnJvd3NlcidzIG93biBldmVudCBsb29wLlxudmFyIHJlcXVlc3RGbHVzaDtcbi8vIFRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCB0YXNrIHRvIGV4ZWN1dGUgaW4gdGhlIHRhc2sgcXVldWUuIFRoaXMgaXNcbi8vIHByZXNlcnZlZCBiZXR3ZWVuIGNhbGxzIHRvIGBmbHVzaGAgc28gdGhhdCBpdCBjYW4gYmUgcmVzdW1lZCBpZlxuLy8gYSB0YXNrIHRocm93cyBhbiBleGNlcHRpb24uXG52YXIgaW5kZXggPSAwO1xuLy8gSWYgYSB0YXNrIHNjaGVkdWxlcyBhZGRpdGlvbmFsIHRhc2tzIHJlY3Vyc2l2ZWx5LCB0aGUgdGFzayBxdWV1ZSBjYW4gZ3Jvd1xuLy8gdW5ib3VuZGVkLiBUbyBwcmV2ZW50IG1lbW9yeSBleGhhdXN0aW9uLCB0aGUgdGFzayBxdWV1ZSB3aWxsIHBlcmlvZGljYWxseVxuLy8gdHJ1bmNhdGUgYWxyZWFkeS1jb21wbGV0ZWQgdGFza3MuXG52YXIgY2FwYWNpdHkgPSAxMDI0O1xuXG4vLyBUaGUgZmx1c2ggZnVuY3Rpb24gcHJvY2Vzc2VzIGFsbCB0YXNrcyB0aGF0IGhhdmUgYmVlbiBzY2hlZHVsZWQgd2l0aFxuLy8gYHJhd0FzYXBgIHVubGVzcyBhbmQgdW50aWwgb25lIG9mIHRob3NlIHRhc2tzIHRocm93cyBhbiBleGNlcHRpb24uXG4vLyBJZiBhIHRhc2sgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgYGZsdXNoYCBlbnN1cmVzIHRoYXQgaXRzIHN0YXRlIHdpbGwgcmVtYWluXG4vLyBjb25zaXN0ZW50IGFuZCB3aWxsIHJlc3VtZSB3aGVyZSBpdCBsZWZ0IG9mZiB3aGVuIGNhbGxlZCBhZ2Fpbi5cbi8vIEhvd2V2ZXIsIGBmbHVzaGAgZG9lcyBub3QgbWFrZSBhbnkgYXJyYW5nZW1lbnRzIHRvIGJlIGNhbGxlZCBhZ2FpbiBpZiBhblxuLy8gZXhjZXB0aW9uIGlzIHRocm93bi5cbmZ1bmN0aW9uIGZsdXNoKCkge1xuICAgIHdoaWxlIChpbmRleCA8IHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICB2YXIgY3VycmVudEluZGV4ID0gaW5kZXg7XG4gICAgICAgIC8vIEFkdmFuY2UgdGhlIGluZGV4IGJlZm9yZSBjYWxsaW5nIHRoZSB0YXNrLiBUaGlzIGVuc3VyZXMgdGhhdCB3ZSB3aWxsXG4gICAgICAgIC8vIGJlZ2luIGZsdXNoaW5nIG9uIHRoZSBuZXh0IHRhc2sgdGhlIHRhc2sgdGhyb3dzIGFuIGVycm9yLlxuICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgcXVldWVbY3VycmVudEluZGV4XS5jYWxsKCk7XG4gICAgICAgIC8vIFByZXZlbnQgbGVha2luZyBtZW1vcnkgZm9yIGxvbmcgY2hhaW5zIG9mIHJlY3Vyc2l2ZSBjYWxscyB0byBgYXNhcGAuXG4gICAgICAgIC8vIElmIHdlIGNhbGwgYGFzYXBgIHdpdGhpbiB0YXNrcyBzY2hlZHVsZWQgYnkgYGFzYXBgLCB0aGUgcXVldWUgd2lsbFxuICAgICAgICAvLyBncm93LCBidXQgdG8gYXZvaWQgYW4gTyhuKSB3YWxrIGZvciBldmVyeSB0YXNrIHdlIGV4ZWN1dGUsIHdlIGRvbid0XG4gICAgICAgIC8vIHNoaWZ0IHRhc2tzIG9mZiB0aGUgcXVldWUgYWZ0ZXIgdGhleSBoYXZlIGJlZW4gZXhlY3V0ZWQuXG4gICAgICAgIC8vIEluc3RlYWQsIHdlIHBlcmlvZGljYWxseSBzaGlmdCAxMDI0IHRhc2tzIG9mZiB0aGUgcXVldWUuXG4gICAgICAgIGlmIChpbmRleCA+IGNhcGFjaXR5KSB7XG4gICAgICAgICAgICAvLyBNYW51YWxseSBzaGlmdCBhbGwgdmFsdWVzIHN0YXJ0aW5nIGF0IHRoZSBpbmRleCBiYWNrIHRvIHRoZVxuICAgICAgICAgICAgLy8gYmVnaW5uaW5nIG9mIHRoZSBxdWV1ZS5cbiAgICAgICAgICAgIGZvciAodmFyIHNjYW4gPSAwLCBuZXdMZW5ndGggPSBxdWV1ZS5sZW5ndGggLSBpbmRleDsgc2NhbiA8IG5ld0xlbmd0aDsgc2NhbisrKSB7XG4gICAgICAgICAgICAgICAgcXVldWVbc2Nhbl0gPSBxdWV1ZVtzY2FuICsgaW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcXVldWUubGVuZ3RoIC09IGluZGV4O1xuICAgICAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLmxlbmd0aCA9IDA7XG4gICAgaW5kZXggPSAwO1xuICAgIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8vIGByZXF1ZXN0Rmx1c2hgIGlzIGltcGxlbWVudGVkIHVzaW5nIGEgc3RyYXRlZ3kgYmFzZWQgb24gZGF0YSBjb2xsZWN0ZWQgZnJvbVxuLy8gZXZlcnkgYXZhaWxhYmxlIFNhdWNlTGFicyBTZWxlbml1bSB3ZWIgZHJpdmVyIHdvcmtlciBhdCB0aW1lIG9mIHdyaXRpbmcuXG4vLyBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbUctNVVZR3VwNXF4R2RFTVdraFA2QldDejA1M05VYjJFMVFvVVRVMTZ1QS9lZGl0I2dpZD03ODM3MjQ1OTNcblxuLy8gU2FmYXJpIDYgYW5kIDYuMSBmb3IgZGVza3RvcCwgaVBhZCwgYW5kIGlQaG9uZSBhcmUgdGhlIG9ubHkgYnJvd3NlcnMgdGhhdFxuLy8gaGF2ZSBXZWJLaXRNdXRhdGlvbk9ic2VydmVyIGJ1dCBub3QgdW4tcHJlZml4ZWQgTXV0YXRpb25PYnNlcnZlci5cbi8vIE11c3QgdXNlIGBnbG9iYWxgIG9yIGBzZWxmYCBpbnN0ZWFkIG9mIGB3aW5kb3dgIHRvIHdvcmsgaW4gYm90aCBmcmFtZXMgYW5kIHdlYlxuLy8gd29ya2Vycy4gYGdsb2JhbGAgaXMgYSBwcm92aXNpb24gb2YgQnJvd3NlcmlmeSwgTXIsIE1ycywgb3IgTW9wLlxuXG4vKiBnbG9iYWxzIHNlbGYgKi9cbnZhciBzY29wZSA9IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiBzZWxmO1xudmFyIEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID0gc2NvcGUuTXV0YXRpb25PYnNlcnZlciB8fCBzY29wZS5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xuXG4vLyBNdXRhdGlvbk9ic2VydmVycyBhcmUgZGVzaXJhYmxlIGJlY2F1c2UgdGhleSBoYXZlIGhpZ2ggcHJpb3JpdHkgYW5kIHdvcmtcbi8vIHJlbGlhYmx5IGV2ZXJ5d2hlcmUgdGhleSBhcmUgaW1wbGVtZW50ZWQuXG4vLyBUaGV5IGFyZSBpbXBsZW1lbnRlZCBpbiBhbGwgbW9kZXJuIGJyb3dzZXJzLlxuLy9cbi8vIC0gQW5kcm9pZCA0LTQuM1xuLy8gLSBDaHJvbWUgMjYtMzRcbi8vIC0gRmlyZWZveCAxNC0yOVxuLy8gLSBJbnRlcm5ldCBFeHBsb3JlciAxMVxuLy8gLSBpUGFkIFNhZmFyaSA2LTcuMVxuLy8gLSBpUGhvbmUgU2FmYXJpIDctNy4xXG4vLyAtIFNhZmFyaSA2LTdcbmlmICh0eXBlb2YgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJlcXVlc3RGbHVzaCA9IG1ha2VSZXF1ZXN0Q2FsbEZyb21NdXRhdGlvbk9ic2VydmVyKGZsdXNoKTtcblxuLy8gTWVzc2FnZUNoYW5uZWxzIGFyZSBkZXNpcmFibGUgYmVjYXVzZSB0aGV5IGdpdmUgZGlyZWN0IGFjY2VzcyB0byB0aGUgSFRNTFxuLy8gdGFzayBxdWV1ZSwgYXJlIGltcGxlbWVudGVkIGluIEludGVybmV0IEV4cGxvcmVyIDEwLCBTYWZhcmkgNS4wLTEsIGFuZCBPcGVyYVxuLy8gMTEtMTIsIGFuZCBpbiB3ZWIgd29ya2VycyBpbiBtYW55IGVuZ2luZXMuXG4vLyBBbHRob3VnaCBtZXNzYWdlIGNoYW5uZWxzIHlpZWxkIHRvIGFueSBxdWV1ZWQgcmVuZGVyaW5nIGFuZCBJTyB0YXNrcywgdGhleVxuLy8gd291bGQgYmUgYmV0dGVyIHRoYW4gaW1wb3NpbmcgdGhlIDRtcyBkZWxheSBvZiB0aW1lcnMuXG4vLyBIb3dldmVyLCB0aGV5IGRvIG5vdCB3b3JrIHJlbGlhYmx5IGluIEludGVybmV0IEV4cGxvcmVyIG9yIFNhZmFyaS5cblxuLy8gSW50ZXJuZXQgRXhwbG9yZXIgMTAgaXMgdGhlIG9ubHkgYnJvd3NlciB0aGF0IGhhcyBzZXRJbW1lZGlhdGUgYnV0IGRvZXNcbi8vIG5vdCBoYXZlIE11dGF0aW9uT2JzZXJ2ZXJzLlxuLy8gQWx0aG91Z2ggc2V0SW1tZWRpYXRlIHlpZWxkcyB0byB0aGUgYnJvd3NlcidzIHJlbmRlcmVyLCBpdCB3b3VsZCBiZVxuLy8gcHJlZmVycmFibGUgdG8gZmFsbGluZyBiYWNrIHRvIHNldFRpbWVvdXQgc2luY2UgaXQgZG9lcyBub3QgaGF2ZVxuLy8gdGhlIG1pbmltdW0gNG1zIHBlbmFsdHkuXG4vLyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGFwcGVhcnMgdG8gYmUgYSBidWcgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTAgTW9iaWxlIChhbmRcbi8vIERlc2t0b3AgdG8gYSBsZXNzZXIgZXh0ZW50KSB0aGF0IHJlbmRlcnMgYm90aCBzZXRJbW1lZGlhdGUgYW5kXG4vLyBNZXNzYWdlQ2hhbm5lbCB1c2VsZXNzIGZvciB0aGUgcHVycG9zZXMgb2YgQVNBUC5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9pc3N1ZXMvMzk2XG5cbi8vIFRpbWVycyBhcmUgaW1wbGVtZW50ZWQgdW5pdmVyc2FsbHkuXG4vLyBXZSBmYWxsIGJhY2sgdG8gdGltZXJzIGluIHdvcmtlcnMgaW4gbW9zdCBlbmdpbmVzLCBhbmQgaW4gZm9yZWdyb3VuZFxuLy8gY29udGV4dHMgaW4gdGhlIGZvbGxvd2luZyBicm93c2Vycy5cbi8vIEhvd2V2ZXIsIG5vdGUgdGhhdCBldmVuIHRoaXMgc2ltcGxlIGNhc2UgcmVxdWlyZXMgbnVhbmNlcyB0byBvcGVyYXRlIGluIGFcbi8vIGJyb2FkIHNwZWN0cnVtIG9mIGJyb3dzZXJzLlxuLy9cbi8vIC0gRmlyZWZveCAzLTEzXG4vLyAtIEludGVybmV0IEV4cGxvcmVyIDYtOVxuLy8gLSBpUGFkIFNhZmFyaSA0LjNcbi8vIC0gTHlueCAyLjguN1xufSBlbHNlIHtcbiAgICByZXF1ZXN0Rmx1c2ggPSBtYWtlUmVxdWVzdENhbGxGcm9tVGltZXIoZmx1c2gpO1xufVxuXG4vLyBgcmVxdWVzdEZsdXNoYCByZXF1ZXN0cyB0aGF0IHRoZSBoaWdoIHByaW9yaXR5IGV2ZW50IHF1ZXVlIGJlIGZsdXNoZWQgYXNcbi8vIHNvb24gYXMgcG9zc2libGUuXG4vLyBUaGlzIGlzIHVzZWZ1bCB0byBwcmV2ZW50IGFuIGVycm9yIHRocm93biBpbiBhIHRhc2sgZnJvbSBzdGFsbGluZyB0aGUgZXZlbnRcbi8vIHF1ZXVlIGlmIHRoZSBleGNlcHRpb24gaGFuZGxlZCBieSBOb2RlLmpz4oCZc1xuLy8gYHByb2Nlc3Mub24oXCJ1bmNhdWdodEV4Y2VwdGlvblwiKWAgb3IgYnkgYSBkb21haW4uXG5yYXdBc2FwLnJlcXVlc3RGbHVzaCA9IHJlcXVlc3RGbHVzaDtcblxuLy8gVG8gcmVxdWVzdCBhIGhpZ2ggcHJpb3JpdHkgZXZlbnQsIHdlIGluZHVjZSBhIG11dGF0aW9uIG9ic2VydmVyIGJ5IHRvZ2dsaW5nXG4vLyB0aGUgdGV4dCBvZiBhIHRleHQgbm9kZSBiZXR3ZWVuIFwiMVwiIGFuZCBcIi0xXCIuXG5mdW5jdGlvbiBtYWtlUmVxdWVzdENhbGxGcm9tTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjaykge1xuICAgIHZhciB0b2dnbGUgPSAxO1xuICAgIHZhciBvYnNlcnZlciA9IG5ldyBCcm93c2VyTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlwiKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKG5vZGUsIHtjaGFyYWN0ZXJEYXRhOiB0cnVlfSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIHJlcXVlc3RDYWxsKCkge1xuICAgICAgICB0b2dnbGUgPSAtdG9nZ2xlO1xuICAgICAgICBub2RlLmRhdGEgPSB0b2dnbGU7XG4gICAgfTtcbn1cblxuLy8gVGhlIG1lc3NhZ2UgY2hhbm5lbCB0ZWNobmlxdWUgd2FzIGRpc2NvdmVyZWQgYnkgTWFsdGUgVWJsIGFuZCB3YXMgdGhlXG4vLyBvcmlnaW5hbCBmb3VuZGF0aW9uIGZvciB0aGlzIGxpYnJhcnkuXG4vLyBodHRwOi8vd3d3Lm5vbmJsb2NraW5nLmlvLzIwMTEvMDYvd2luZG93bmV4dHRpY2suaHRtbFxuXG4vLyBTYWZhcmkgNi4wLjUgKGF0IGxlYXN0KSBpbnRlcm1pdHRlbnRseSBmYWlscyB0byBjcmVhdGUgbWVzc2FnZSBwb3J0cyBvbiBhXG4vLyBwYWdlJ3MgZmlyc3QgbG9hZC4gVGhhbmtmdWxseSwgdGhpcyB2ZXJzaW9uIG9mIFNhZmFyaSBzdXBwb3J0c1xuLy8gTXV0YXRpb25PYnNlcnZlcnMsIHNvIHdlIGRvbid0IG5lZWQgdG8gZmFsbCBiYWNrIGluIHRoYXQgY2FzZS5cblxuLy8gZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbU1lc3NhZ2VDaGFubmVsKGNhbGxiYWNrKSB7XG4vLyAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbi8vICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGNhbGxiYWNrO1xuLy8gICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbi8vICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcbi8vICAgICB9O1xuLy8gfVxuXG4vLyBGb3IgcmVhc29ucyBleHBsYWluZWQgYWJvdmUsIHdlIGFyZSBhbHNvIHVuYWJsZSB0byB1c2UgYHNldEltbWVkaWF0ZWBcbi8vIHVuZGVyIGFueSBjaXJjdW1zdGFuY2VzLlxuLy8gRXZlbiBpZiB3ZSB3ZXJlLCB0aGVyZSBpcyBhbm90aGVyIGJ1ZyBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMC5cbi8vIEl0IGlzIG5vdCBzdWZmaWNpZW50IHRvIGFzc2lnbiBgc2V0SW1tZWRpYXRlYCB0byBgcmVxdWVzdEZsdXNoYCBiZWNhdXNlXG4vLyBgc2V0SW1tZWRpYXRlYCBtdXN0IGJlIGNhbGxlZCAqYnkgbmFtZSogYW5kIHRoZXJlZm9yZSBtdXN0IGJlIHdyYXBwZWQgaW4gYVxuLy8gY2xvc3VyZS5cbi8vIE5ldmVyIGZvcmdldC5cblxuLy8gZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbVNldEltbWVkaWF0ZShjYWxsYmFjaykge1xuLy8gICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbi8vICAgICAgICAgc2V0SW1tZWRpYXRlKGNhbGxiYWNrKTtcbi8vICAgICB9O1xuLy8gfVxuXG4vLyBTYWZhcmkgNi4wIGhhcyBhIHByb2JsZW0gd2hlcmUgdGltZXJzIHdpbGwgZ2V0IGxvc3Qgd2hpbGUgdGhlIHVzZXIgaXNcbi8vIHNjcm9sbGluZy4gVGhpcyBwcm9ibGVtIGRvZXMgbm90IGltcGFjdCBBU0FQIGJlY2F1c2UgU2FmYXJpIDYuMCBzdXBwb3J0c1xuLy8gbXV0YXRpb24gb2JzZXJ2ZXJzLCBzbyB0aGF0IGltcGxlbWVudGF0aW9uIGlzIHVzZWQgaW5zdGVhZC5cbi8vIEhvd2V2ZXIsIGlmIHdlIGV2ZXIgZWxlY3QgdG8gdXNlIHRpbWVycyBpbiBTYWZhcmksIHRoZSBwcmV2YWxlbnQgd29yay1hcm91bmRcbi8vIGlzIHRvIGFkZCBhIHNjcm9sbCBldmVudCBsaXN0ZW5lciB0aGF0IGNhbGxzIGZvciBhIGZsdXNoLlxuXG4vLyBgc2V0VGltZW91dGAgZG9lcyBub3QgY2FsbCB0aGUgcGFzc2VkIGNhbGxiYWNrIGlmIHRoZSBkZWxheSBpcyBsZXNzIHRoYW5cbi8vIGFwcHJveGltYXRlbHkgNyBpbiB3ZWIgd29ya2VycyBpbiBGaXJlZm94IDggdGhyb3VnaCAxOCwgYW5kIHNvbWV0aW1lcyBub3Rcbi8vIGV2ZW4gdGhlbi5cblxuZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIHJlcXVlc3RDYWxsKCkge1xuICAgICAgICAvLyBXZSBkaXNwYXRjaCBhIHRpbWVvdXQgd2l0aCBhIHNwZWNpZmllZCBkZWxheSBvZiAwIGZvciBlbmdpbmVzIHRoYXRcbiAgICAgICAgLy8gY2FuIHJlbGlhYmx5IGFjY29tbW9kYXRlIHRoYXQgcmVxdWVzdC4gVGhpcyB3aWxsIHVzdWFsbHkgYmUgc25hcHBlZFxuICAgICAgICAvLyB0byBhIDQgbWlsaXNlY29uZCBkZWxheSwgYnV0IG9uY2Ugd2UncmUgZmx1c2hpbmcsIHRoZXJlJ3Mgbm8gZGVsYXlcbiAgICAgICAgLy8gYmV0d2VlbiBldmVudHMuXG4gICAgICAgIHZhciB0aW1lb3V0SGFuZGxlID0gc2V0VGltZW91dChoYW5kbGVUaW1lciwgMCk7XG4gICAgICAgIC8vIEhvd2V2ZXIsIHNpbmNlIHRoaXMgdGltZXIgZ2V0cyBmcmVxdWVudGx5IGRyb3BwZWQgaW4gRmlyZWZveFxuICAgICAgICAvLyB3b3JrZXJzLCB3ZSBlbmxpc3QgYW4gaW50ZXJ2YWwgaGFuZGxlIHRoYXQgd2lsbCB0cnkgdG8gZmlyZVxuICAgICAgICAvLyBhbiBldmVudCAyMCB0aW1lcyBwZXIgc2Vjb25kIHVudGlsIGl0IHN1Y2NlZWRzLlxuICAgICAgICB2YXIgaW50ZXJ2YWxIYW5kbGUgPSBzZXRJbnRlcnZhbChoYW5kbGVUaW1lciwgNTApO1xuXG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZVRpbWVyKCkge1xuICAgICAgICAgICAgLy8gV2hpY2hldmVyIHRpbWVyIHN1Y2NlZWRzIHdpbGwgY2FuY2VsIGJvdGggdGltZXJzIGFuZFxuICAgICAgICAgICAgLy8gZXhlY3V0ZSB0aGUgY2FsbGJhY2suXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dEhhbmRsZSk7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsSGFuZGxlKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG4vLyBUaGlzIGlzIGZvciBgYXNhcC5qc2Agb25seS5cbi8vIEl0cyBuYW1lIHdpbGwgYmUgcGVyaW9kaWNhbGx5IHJhbmRvbWl6ZWQgdG8gYnJlYWsgYW55IGNvZGUgdGhhdCBkZXBlbmRzIG9uXG4vLyBpdHMgZXhpc3RlbmNlLlxucmF3QXNhcC5tYWtlUmVxdWVzdENhbGxGcm9tVGltZXIgPSBtYWtlUmVxdWVzdENhbGxGcm9tVGltZXI7XG5cbi8vIEFTQVAgd2FzIG9yaWdpbmFsbHkgYSBuZXh0VGljayBzaGltIGluY2x1ZGVkIGluIFEuIFRoaXMgd2FzIGZhY3RvcmVkIG91dFxuLy8gaW50byB0aGlzIEFTQVAgcGFja2FnZS4gSXQgd2FzIGxhdGVyIGFkYXB0ZWQgdG8gUlNWUCB3aGljaCBtYWRlIGZ1cnRoZXJcbi8vIGFtZW5kbWVudHMuIFRoZXNlIGRlY2lzaW9ucywgcGFydGljdWxhcmx5IHRvIG1hcmdpbmFsaXplIE1lc3NhZ2VDaGFubmVsIGFuZFxuLy8gdG8gY2FwdHVyZSB0aGUgTXV0YXRpb25PYnNlcnZlciBpbXBsZW1lbnRhdGlvbiBpbiBhIGNsb3N1cmUsIHdlcmUgaW50ZWdyYXRlZFxuLy8gYmFjayBpbnRvIEFTQVAgcHJvcGVyLlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RpbGRlaW8vcnN2cC5qcy9ibG9iL2NkZGY3MjMyNTQ2YTljZjg1ODUyNGI3NWNkZTZmOWVkZjcyNjIwYTcvbGliL3JzdnAvYXNhcC5qc1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL3NoaW1cIik7XG5cbnJlcXVpcmUoXCJyZWdlbmVyYXRvci1ydW50aW1lL3J1bnRpbWVcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL3JlZ2V4cC9lc2NhcGVcIik7XG5cbmlmIChnbG9iYWwuX2JhYmVsUG9seWZpbGwpIHtcbiAgdGhyb3cgbmV3IEVycm9yKFwib25seSBvbmUgaW5zdGFuY2Ugb2YgYmFiZWwtcG9seWZpbGwgaXMgYWxsb3dlZFwiKTtcbn1cbmdsb2JhbC5fYmFiZWxQb2x5ZmlsbCA9IHRydWU7XG5cbnZhciBERUZJTkVfUFJPUEVSVFkgPSBcImRlZmluZVByb3BlcnR5XCI7XG5mdW5jdGlvbiBkZWZpbmUoTywga2V5LCB2YWx1ZSkge1xuICBPW2tleV0gfHwgT2JqZWN0W0RFRklORV9QUk9QRVJUWV0oTywga2V5LCB7XG4gICAgd3JpdGFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHZhbHVlOiB2YWx1ZVxuICB9KTtcbn1cblxuZGVmaW5lKFN0cmluZy5wcm90b3R5cGUsIFwicGFkTGVmdFwiLCBcIlwiLnBhZFN0YXJ0KTtcbmRlZmluZShTdHJpbmcucHJvdG90eXBlLCBcInBhZFJpZ2h0XCIsIFwiXCIucGFkRW5kKTtcblxuXCJwb3AscmV2ZXJzZSxzaGlmdCxrZXlzLHZhbHVlcyxlbnRyaWVzLGluZGV4T2YsZXZlcnksc29tZSxmb3JFYWNoLG1hcCxmaWx0ZXIsZmluZCxmaW5kSW5kZXgsaW5jbHVkZXMsam9pbixzbGljZSxjb25jYXQscHVzaCxzcGxpY2UsdW5zaGlmdCxzb3J0LGxhc3RJbmRleE9mLHJlZHVjZSxyZWR1Y2VSaWdodCxjb3B5V2l0aGluLGZpbGxcIi5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIFtdW2tleV0gJiYgZGVmaW5lKEFycmF5LCBrZXksIEZ1bmN0aW9uLmNhbGwuYmluZChbXVtrZXldKSk7XG59KTsiLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2NvcmUucmVnZXhwLmVzY2FwZScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuUmVnRXhwLmVzY2FwZTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSBmdW5jdGlvbiEnKTtcbiAgcmV0dXJuIGl0O1xufTsiLCJ2YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBtc2cpe1xuICBpZih0eXBlb2YgaXQgIT0gJ251bWJlcicgJiYgY29mKGl0KSAhPSAnTnVtYmVyJyl0aHJvdyBUeXBlRXJyb3IobXNnKTtcbiAgcmV0dXJuICtpdDtcbn07IiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJylcbiAgLCBBcnJheVByb3RvICA9IEFycmF5LnByb3RvdHlwZTtcbmlmKEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdID09IHVuZGVmaW5lZClyZXF1aXJlKCcuL19oaWRlJykoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgQXJyYXlQcm90b1tVTlNDT1BBQkxFU11ba2V5XSA9IHRydWU7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIENvbnN0cnVjdG9yLCBuYW1lLCBmb3JiaWRkZW5GaWVsZCl7XG4gIGlmKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKXtcbiAgICB0aHJvdyBUeXBlRXJyb3IobmFtZSArICc6IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICB9IHJldHVybiBpdDtcbn07IiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoIWlzT2JqZWN0KGl0KSl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhbiBvYmplY3QhJyk7XG4gIHJldHVybiBpdDtcbn07IiwiLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIHRvSW5kZXggID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKVxuICAsIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gW10uY29weVdpdGhpbiB8fCBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldC8qPSAwKi8sIHN0YXJ0Lyo9IDAsIGVuZCA9IEBsZW5ndGgqLyl7XG4gIHZhciBPICAgICA9IHRvT2JqZWN0KHRoaXMpXG4gICAgLCBsZW4gICA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxuICAgICwgdG8gICAgPSB0b0luZGV4KHRhcmdldCwgbGVuKVxuICAgICwgZnJvbSAgPSB0b0luZGV4KHN0YXJ0LCBsZW4pXG4gICAgLCBlbmQgICA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkXG4gICAgLCBjb3VudCA9IE1hdGgubWluKChlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IHRvSW5kZXgoZW5kLCBsZW4pKSAtIGZyb20sIGxlbiAtIHRvKVxuICAgICwgaW5jICAgPSAxO1xuICBpZihmcm9tIDwgdG8gJiYgdG8gPCBmcm9tICsgY291bnQpe1xuICAgIGluYyAgPSAtMTtcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcbiAgICB0byAgICs9IGNvdW50IC0gMTtcbiAgfVxuICB3aGlsZShjb3VudC0tID4gMCl7XG4gICAgaWYoZnJvbSBpbiBPKU9bdG9dID0gT1tmcm9tXTtcbiAgICBlbHNlIGRlbGV0ZSBPW3RvXTtcbiAgICB0byAgICs9IGluYztcbiAgICBmcm9tICs9IGluYztcbiAgfSByZXR1cm4gTztcbn07IiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIHRvSW5kZXggID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKVxuICAsIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZpbGwodmFsdWUgLyosIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLyl7XG4gIHZhciBPICAgICAgPSB0b09iamVjdCh0aGlzKVxuICAgICwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpXG4gICAgLCBhTGVuICAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgLCBpbmRleCAgPSB0b0luZGV4KGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCBsZW5ndGgpXG4gICAgLCBlbmQgICAgPSBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZFxuICAgICwgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0luZGV4KGVuZCwgbGVuZ3RoKTtcbiAgd2hpbGUoZW5kUG9zID4gaW5kZXgpT1tpbmRleCsrXSA9IHZhbHVlO1xuICByZXR1cm4gTztcbn07IiwidmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXRlciwgSVRFUkFUT1Ipe1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvck9mKGl0ZXIsIGZhbHNlLCByZXN1bHQucHVzaCwgcmVzdWx0LCBJVEVSQVRPUik7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuIiwiLy8gZmFsc2UgLT4gQXJyYXkjaW5kZXhPZlxuLy8gdHJ1ZSAgLT4gQXJyYXkjaW5jbHVkZXNcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIHRvSW5kZXggICA9IHJlcXVpcmUoJy4vX3RvLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKElTX0lOQ0xVREVTKXtcbiAgcmV0dXJuIGZ1bmN0aW9uKCR0aGlzLCBlbCwgZnJvbUluZGV4KXtcbiAgICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KCR0aGlzKVxuICAgICAgLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aClcbiAgICAgICwgaW5kZXggID0gdG9JbmRleChmcm9tSW5kZXgsIGxlbmd0aClcbiAgICAgICwgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIGlmKElTX0lOQ0xVREVTICYmIGVsICE9IGVsKXdoaWxlKGxlbmd0aCA+IGluZGV4KXtcbiAgICAgIHZhbHVlID0gT1tpbmRleCsrXTtcbiAgICAgIGlmKHZhbHVlICE9IHZhbHVlKXJldHVybiB0cnVlO1xuICAgIC8vIEFycmF5I3RvSW5kZXggaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcbiAgICB9IGVsc2UgZm9yKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKylpZihJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKXtcbiAgICAgIGlmKE9baW5kZXhdID09PSBlbClyZXR1cm4gSVNfSU5DTFVERVMgfHwgaW5kZXggfHwgMDtcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XG4gIH07XG59OyIsIi8vIDAgLT4gQXJyYXkjZm9yRWFjaFxuLy8gMSAtPiBBcnJheSNtYXBcbi8vIDIgLT4gQXJyYXkjZmlsdGVyXG4vLyAzIC0+IEFycmF5I3NvbWVcbi8vIDQgLT4gQXJyYXkjZXZlcnlcbi8vIDUgLT4gQXJyYXkjZmluZFxuLy8gNiAtPiBBcnJheSNmaW5kSW5kZXhcbnZhciBjdHggICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgSU9iamVjdCAgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGFzYyAgICAgID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jcmVhdGUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oVFlQRSwgJGNyZWF0ZSl7XG4gIHZhciBJU19NQVAgICAgICAgID0gVFlQRSA9PSAxXG4gICAgLCBJU19GSUxURVIgICAgID0gVFlQRSA9PSAyXG4gICAgLCBJU19TT01FICAgICAgID0gVFlQRSA9PSAzXG4gICAgLCBJU19FVkVSWSAgICAgID0gVFlQRSA9PSA0XG4gICAgLCBJU19GSU5EX0lOREVYID0gVFlQRSA9PSA2XG4gICAgLCBOT19IT0xFUyAgICAgID0gVFlQRSA9PSA1IHx8IElTX0ZJTkRfSU5ERVhcbiAgICAsIGNyZWF0ZSAgICAgICAgPSAkY3JlYXRlIHx8IGFzYztcbiAgcmV0dXJuIGZ1bmN0aW9uKCR0aGlzLCBjYWxsYmFja2ZuLCB0aGF0KXtcbiAgICB2YXIgTyAgICAgID0gdG9PYmplY3QoJHRoaXMpXG4gICAgICAsIHNlbGYgICA9IElPYmplY3QoTylcbiAgICAgICwgZiAgICAgID0gY3R4KGNhbGxiYWNrZm4sIHRoYXQsIDMpXG4gICAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKHNlbGYubGVuZ3RoKVxuICAgICAgLCBpbmRleCAgPSAwXG4gICAgICAsIHJlc3VsdCA9IElTX01BUCA/IGNyZWF0ZSgkdGhpcywgbGVuZ3RoKSA6IElTX0ZJTFRFUiA/IGNyZWF0ZSgkdGhpcywgMCkgOiB1bmRlZmluZWRcbiAgICAgICwgdmFsLCByZXM7XG4gICAgZm9yKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKylpZihOT19IT0xFUyB8fCBpbmRleCBpbiBzZWxmKXtcbiAgICAgIHZhbCA9IHNlbGZbaW5kZXhdO1xuICAgICAgcmVzID0gZih2YWwsIGluZGV4LCBPKTtcbiAgICAgIGlmKFRZUEUpe1xuICAgICAgICBpZihJU19NQVApcmVzdWx0W2luZGV4XSA9IHJlczsgICAgICAgICAgICAvLyBtYXBcbiAgICAgICAgZWxzZSBpZihyZXMpc3dpdGNoKFRZUEUpe1xuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAvLyBzb21lXG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gdmFsOyAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmRcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBpbmRleDsgICAgICAgICAgICAgICAgICAgLy8gZmluZEluZGV4XG4gICAgICAgICAgY2FzZSAyOiByZXN1bHQucHVzaCh2YWwpOyAgICAgICAgICAgICAgIC8vIGZpbHRlclxuICAgICAgICB9IGVsc2UgaWYoSVNfRVZFUlkpcmV0dXJuIGZhbHNlOyAgICAgICAgICAvLyBldmVyeVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSVNfRklORF9JTkRFWCA/IC0xIDogSVNfU09NRSB8fCBJU19FVkVSWSA/IElTX0VWRVJZIDogcmVzdWx0O1xuICB9O1xufTsiLCJ2YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgdG9PYmplY3QgID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0JylcbiAgLCBJT2JqZWN0ICAgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0aGF0LCBjYWxsYmFja2ZuLCBhTGVuLCBtZW1vLCBpc1JpZ2h0KXtcbiAgYUZ1bmN0aW9uKGNhbGxiYWNrZm4pO1xuICB2YXIgTyAgICAgID0gdG9PYmplY3QodGhhdClcbiAgICAsIHNlbGYgICA9IElPYmplY3QoTylcbiAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxuICAgICwgaW5kZXggID0gaXNSaWdodCA/IGxlbmd0aCAtIDEgOiAwXG4gICAgLCBpICAgICAgPSBpc1JpZ2h0ID8gLTEgOiAxO1xuICBpZihhTGVuIDwgMilmb3IoOzspe1xuICAgIGlmKGluZGV4IGluIHNlbGYpe1xuICAgICAgbWVtbyA9IHNlbGZbaW5kZXhdO1xuICAgICAgaW5kZXggKz0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpbmRleCArPSBpO1xuICAgIGlmKGlzUmlnaHQgPyBpbmRleCA8IDAgOiBsZW5ndGggPD0gaW5kZXgpe1xuICAgICAgdGhyb3cgVHlwZUVycm9yKCdSZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgfVxuICB9XG4gIGZvcig7aXNSaWdodCA/IGluZGV4ID49IDAgOiBsZW5ndGggPiBpbmRleDsgaW5kZXggKz0gaSlpZihpbmRleCBpbiBzZWxmKXtcbiAgICBtZW1vID0gY2FsbGJhY2tmbihtZW1vLCBzZWxmW2luZGV4XSwgaW5kZXgsIE8pO1xuICB9XG4gIHJldHVybiBtZW1vO1xufTsiLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGlzQXJyYXkgID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKVxuICAsIFNQRUNJRVMgID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcmlnaW5hbCl7XG4gIHZhciBDO1xuICBpZihpc0FycmF5KG9yaWdpbmFsKSl7XG4gICAgQyA9IG9yaWdpbmFsLmNvbnN0cnVjdG9yO1xuICAgIC8vIGNyb3NzLXJlYWxtIGZhbGxiYWNrXG4gICAgaWYodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKUMgPSB1bmRlZmluZWQ7XG4gICAgaWYoaXNPYmplY3QoQykpe1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZihDID09PSBudWxsKUMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9IHJldHVybiBDID09PSB1bmRlZmluZWQgPyBBcnJheSA6IEM7XG59OyIsIi8vIDkuNC4yLjMgQXJyYXlTcGVjaWVzQ3JlYXRlKG9yaWdpbmFsQXJyYXksIGxlbmd0aClcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3JpZ2luYWwsIGxlbmd0aCl7XG4gIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihvcmlnaW5hbCkpKGxlbmd0aCk7XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBhRnVuY3Rpb24gID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgaXNPYmplY3QgICA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgaW52b2tlICAgICA9IHJlcXVpcmUoJy4vX2ludm9rZScpXG4gICwgYXJyYXlTbGljZSA9IFtdLnNsaWNlXG4gICwgZmFjdG9yaWVzICA9IHt9O1xuXG52YXIgY29uc3RydWN0ID0gZnVuY3Rpb24oRiwgbGVuLCBhcmdzKXtcbiAgaWYoIShsZW4gaW4gZmFjdG9yaWVzKSl7XG4gICAgZm9yKHZhciBuID0gW10sIGkgPSAwOyBpIDwgbGVuOyBpKyspbltpXSA9ICdhWycgKyBpICsgJ10nO1xuICAgIGZhY3Rvcmllc1tsZW5dID0gRnVuY3Rpb24oJ0YsYScsICdyZXR1cm4gbmV3IEYoJyArIG4uam9pbignLCcpICsgJyknKTtcbiAgfSByZXR1cm4gZmFjdG9yaWVzW2xlbl0oRiwgYXJncyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLmJpbmQgfHwgZnVuY3Rpb24gYmluZCh0aGF0IC8qLCBhcmdzLi4uICovKXtcbiAgdmFyIGZuICAgICAgID0gYUZ1bmN0aW9uKHRoaXMpXG4gICAgLCBwYXJ0QXJncyA9IGFycmF5U2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICB2YXIgYm91bmQgPSBmdW5jdGlvbigvKiBhcmdzLi4uICovKXtcbiAgICB2YXIgYXJncyA9IHBhcnRBcmdzLmNvbmNhdChhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcbiAgfTtcbiAgaWYoaXNPYmplY3QoZm4ucHJvdG90eXBlKSlib3VuZC5wcm90b3R5cGUgPSBmbi5wcm90b3R5cGU7XG4gIHJldHVybiBib3VuZDtcbn07IiwiLy8gZ2V0dGluZyB0YWcgZnJvbSAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKVxuICAsIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpXG4gIC8vIEVTMyB3cm9uZyBoZXJlXG4gICwgQVJHID0gY29mKGZ1bmN0aW9uKCl7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24oaXQsIGtleSl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGl0W2tleV07XG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTsiLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBkUCAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmZcbiAgLCBjcmVhdGUgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKVxuICAsIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJylcbiAgLCBjdHggICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgYW5JbnN0YW5jZSAgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpXG4gICwgZGVmaW5lZCAgICAgPSByZXF1aXJlKCcuL19kZWZpbmVkJylcbiAgLCBmb3JPZiAgICAgICA9IHJlcXVpcmUoJy4vX2Zvci1vZicpXG4gICwgJGl0ZXJEZWZpbmUgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpXG4gICwgc3RlcCAgICAgICAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKVxuICAsIHNldFNwZWNpZXMgID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKVxuICAsIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKVxuICAsIGZhc3RLZXkgICAgID0gcmVxdWlyZSgnLi9fbWV0YScpLmZhc3RLZXlcbiAgLCBTSVpFICAgICAgICA9IERFU0NSSVBUT1JTID8gJ19zJyA6ICdzaXplJztcblxudmFyIGdldEVudHJ5ID0gZnVuY3Rpb24odGhhdCwga2V5KXtcbiAgLy8gZmFzdCBjYXNlXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KSwgZW50cnk7XG4gIGlmKGluZGV4ICE9PSAnRicpcmV0dXJuIHRoYXQuX2lbaW5kZXhdO1xuICAvLyBmcm96ZW4gb2JqZWN0IGNhc2VcbiAgZm9yKGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubil7XG4gICAgaWYoZW50cnkuayA9PSBrZXkpcmV0dXJuIGVudHJ5O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpe1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBpdGVyYWJsZSl7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5faSA9IGNyZWF0ZShudWxsKTsgLy8gaW5kZXhcbiAgICAgIHRoYXQuX2YgPSB1bmRlZmluZWQ7ICAgIC8vIGZpcnN0IGVudHJ5XG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAgICAvLyBsYXN0IGVudHJ5XG4gICAgICB0aGF0W1NJWkVdID0gMDsgICAgICAgICAvLyBzaXplXG4gICAgICBpZihpdGVyYWJsZSAhPSB1bmRlZmluZWQpZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCl7XG4gICAgICAgIGZvcih2YXIgdGhhdCA9IHRoaXMsIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pe1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmKGVudHJ5LnApZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgdmFyIHRoYXQgID0gdGhpc1xuICAgICAgICAgICwgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZihlbnRyeSl7XG4gICAgICAgICAgdmFyIG5leHQgPSBlbnRyeS5uXG4gICAgICAgICAgICAsIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmKHByZXYpcHJldi5uID0gbmV4dDtcbiAgICAgICAgICBpZihuZXh0KW5leHQucCA9IHByZXY7XG4gICAgICAgICAgaWYodGhhdC5fZiA9PSBlbnRyeSl0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZih0aGF0Ll9sID09IGVudHJ5KXRoYXQuX2wgPSBwcmV2O1xuICAgICAgICAgIHRoYXRbU0laRV0tLTtcbiAgICAgICAgfSByZXR1cm4gISFlbnRyeTtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4yLjMuNiBTZXQucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgICAgIC8vIDIzLjEuMy41IE1hcC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qLCB0aGF0ID0gdW5kZWZpbmVkICovKXtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGlzLCBDLCAnZm9yRWFjaCcpO1xuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMylcbiAgICAgICAgICAsIGVudHJ5O1xuICAgICAgICB3aGlsZShlbnRyeSA9IGVudHJ5ID8gZW50cnkubiA6IHRoaXMuX2Ype1xuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XG4gICAgICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICAgICAgd2hpbGUoZW50cnkgJiYgZW50cnkucillbnRyeSA9IGVudHJ5LnA7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAvLyAyMy4xLjMuNyBNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy4yLjMuNyBTZXQucHJvdG90eXBlLmhhcyh2YWx1ZSlcbiAgICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSl7XG4gICAgICAgIHJldHVybiAhIWdldEVudHJ5KHRoaXMsIGtleSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYoREVTQ1JJUFRPUlMpZFAoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpe1xuICAgICAgICByZXR1cm4gZGVmaW5lZCh0aGlzW1NJWkVdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbih0aGF0LCBrZXksIHZhbHVlKXtcbiAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpXG4gICAgICAsIHByZXYsIGluZGV4O1xuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxuICAgIGlmKGVudHJ5KXtcbiAgICAgIGVudHJ5LnYgPSB2YWx1ZTtcbiAgICAvLyBjcmVhdGUgbmV3IGVudHJ5XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoYXQuX2wgPSBlbnRyeSA9IHtcbiAgICAgICAgaTogaW5kZXggPSBmYXN0S2V5KGtleSwgdHJ1ZSksIC8vIDwtIGluZGV4XG4gICAgICAgIGs6IGtleSwgICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSBrZXlcbiAgICAgICAgdjogdmFsdWUsICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHZhbHVlXG4gICAgICAgIHA6IHByZXYgPSB0aGF0Ll9sLCAgICAgICAgICAgICAvLyA8LSBwcmV2aW91cyBlbnRyeVxuICAgICAgICBuOiB1bmRlZmluZWQsICAgICAgICAgICAgICAgICAgLy8gPC0gbmV4dCBlbnRyeVxuICAgICAgICByOiBmYWxzZSAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gcmVtb3ZlZFxuICAgICAgfTtcbiAgICAgIGlmKCF0aGF0Ll9mKXRoYXQuX2YgPSBlbnRyeTtcbiAgICAgIGlmKHByZXYpcHJldi5uID0gZW50cnk7XG4gICAgICB0aGF0W1NJWkVdKys7XG4gICAgICAvLyBhZGQgdG8gaW5kZXhcbiAgICAgIGlmKGluZGV4ICE9PSAnRicpdGhhdC5faVtpbmRleF0gPSBlbnRyeTtcbiAgICB9IHJldHVybiB0aGF0O1xuICB9LFxuICBnZXRFbnRyeTogZ2V0RW50cnksXG4gIHNldFN0cm9uZzogZnVuY3Rpb24oQywgTkFNRSwgSVNfTUFQKXtcbiAgICAvLyBhZGQgLmtleXMsIC52YWx1ZXMsIC5lbnRyaWVzLCBbQEBpdGVyYXRvcl1cbiAgICAvLyAyMy4xLjMuNCwgMjMuMS4zLjgsIDIzLjEuMy4xMSwgMjMuMS4zLjEyLCAyMy4yLjMuNSwgMjMuMi4zLjgsIDIzLjIuMy4xMCwgMjMuMi4zLjExXG4gICAgJGl0ZXJEZWZpbmUoQywgTkFNRSwgZnVuY3Rpb24oaXRlcmF0ZWQsIGtpbmQpe1xuICAgICAgdGhpcy5fdCA9IGl0ZXJhdGVkOyAgLy8gdGFyZ2V0XG4gICAgICB0aGlzLl9rID0ga2luZDsgICAgICAvLyBraW5kXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAvLyBwcmV2aW91c1xuICAgIH0sIGZ1bmN0aW9uKCl7XG4gICAgICB2YXIgdGhhdCAgPSB0aGlzXG4gICAgICAgICwga2luZCAgPSB0aGF0Ll9rXG4gICAgICAgICwgZW50cnkgPSB0aGF0Ll9sO1xuICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICB3aGlsZShlbnRyeSAmJiBlbnRyeS5yKWVudHJ5ID0gZW50cnkucDtcbiAgICAgIC8vIGdldCBuZXh0IGVudHJ5XG4gICAgICBpZighdGhhdC5fdCB8fCAhKHRoYXQuX2wgPSBlbnRyeSA9IGVudHJ5ID8gZW50cnkubiA6IHRoYXQuX3QuX2YpKXtcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cbiAgICAgICAgdGhhdC5fdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHN0ZXAoMSk7XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gc3RlcCBieSBraW5kXG4gICAgICBpZihraW5kID09ICdrZXlzJyAgKXJldHVybiBzdGVwKDAsIGVudHJ5LmspO1xuICAgICAgaWYoa2luZCA9PSAndmFsdWVzJylyZXR1cm4gc3RlcCgwLCBlbnRyeS52KTtcbiAgICAgIHJldHVybiBzdGVwKDAsIFtlbnRyeS5rLCBlbnRyeS52XSk7XG4gICAgfSwgSVNfTUFQID8gJ2VudHJpZXMnIDogJ3ZhbHVlcycgLCAhSVNfTUFQLCB0cnVlKTtcblxuICAgIC8vIGFkZCBbQEBzcGVjaWVzXSwgMjMuMS4yLjIsIDIzLjIuMi4yXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcbiAgfVxufTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKVxuICAsIGZyb20gICAgPSByZXF1aXJlKCcuL19hcnJheS1mcm9tLWl0ZXJhYmxlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5BTUUpe1xuICByZXR1cm4gZnVuY3Rpb24gdG9KU09OKCl7XG4gICAgaWYoY2xhc3NvZih0aGlzKSAhPSBOQU1FKXRocm93IFR5cGVFcnJvcihOQU1FICsgXCIjdG9KU09OIGlzbid0IGdlbmVyaWNcIik7XG4gICAgcmV0dXJuIGZyb20odGhpcyk7XG4gIH07XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciByZWRlZmluZUFsbCAgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpXG4gICwgZ2V0V2VhayAgICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhJykuZ2V0V2Vha1xuICAsIGFuT2JqZWN0ICAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBpc09iamVjdCAgICAgICAgICA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgYW5JbnN0YW5jZSAgICAgICAgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpXG4gICwgZm9yT2YgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19mb3Itb2YnKVxuICAsIGNyZWF0ZUFycmF5TWV0aG9kID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpXG4gICwgJGhhcyAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIGFycmF5RmluZCAgICAgICAgID0gY3JlYXRlQXJyYXlNZXRob2QoNSlcbiAgLCBhcnJheUZpbmRJbmRleCAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpXG4gICwgaWQgICAgICAgICAgICAgICAgPSAwO1xuXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24odGhhdCl7XG4gIHJldHVybiB0aGF0Ll9sIHx8ICh0aGF0Ll9sID0gbmV3IFVuY2F1Z2h0RnJvemVuU3RvcmUpO1xufTtcbnZhciBVbmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5hID0gW107XG59O1xudmFyIGZpbmRVbmNhdWdodEZyb3plbiA9IGZ1bmN0aW9uKHN0b3JlLCBrZXkpe1xuICByZXR1cm4gYXJyYXlGaW5kKHN0b3JlLmEsIGZ1bmN0aW9uKGl0KXtcbiAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgfSk7XG59O1xuVW5jYXVnaHRGcm96ZW5TdG9yZS5wcm90b3R5cGUgPSB7XG4gIGdldDogZnVuY3Rpb24oa2V5KXtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZihlbnRyeSlyZXR1cm4gZW50cnlbMV07XG4gIH0sXG4gIGhhczogZnVuY3Rpb24oa2V5KXtcbiAgICByZXR1cm4gISFmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihrZXksIHZhbHVlKXtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZihlbnRyeSllbnRyeVsxXSA9IHZhbHVlO1xuICAgIGVsc2UgdGhpcy5hLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSxcbiAgJ2RlbGV0ZSc6IGZ1bmN0aW9uKGtleSl7XG4gICAgdmFyIGluZGV4ID0gYXJyYXlGaW5kSW5kZXgodGhpcy5hLCBmdW5jdGlvbihpdCl7XG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgICB9KTtcbiAgICBpZih+aW5kZXgpdGhpcy5hLnNwbGljZShpbmRleCwgMSk7XG4gICAgcmV0dXJuICEhfmluZGV4O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpe1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBpdGVyYWJsZSl7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5faSA9IGlkKys7ICAgICAgLy8gY29sbGVjdGlvbiBpZFxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgLy8gbGVhayBzdG9yZSBmb3IgdW5jYXVnaHQgZnJvemVuIG9iamVjdHNcbiAgICAgIGlmKGl0ZXJhYmxlICE9IHVuZGVmaW5lZClmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgfSk7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcbiAgICAgIC8vIDIzLjMuMy4yIFdlYWtNYXAucHJvdG90eXBlLmRlbGV0ZShrZXkpXG4gICAgICAvLyAyMy40LjMuMyBXZWFrU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgaWYoIWlzT2JqZWN0KGtleSkpcmV0dXJuIGZhbHNlO1xuICAgICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgICAgaWYoZGF0YSA9PT0gdHJ1ZSlyZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh0aGlzKVsnZGVsZXRlJ10oa2V5KTtcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgJGhhcyhkYXRhLCB0aGlzLl9pKSAmJiBkZWxldGUgZGF0YVt0aGlzLl9pXTtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4zLjMuNCBXZWFrTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxuICAgICAgLy8gMjMuNC4zLjQgV2Vha1NldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KXtcbiAgICAgICAgaWYoIWlzT2JqZWN0KGtleSkpcmV0dXJuIGZhbHNlO1xuICAgICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgICAgaWYoZGF0YSA9PT0gdHJ1ZSlyZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh0aGlzKS5oYXMoa2V5KTtcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgJGhhcyhkYXRhLCB0aGlzLl9pKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbih0aGF0LCBrZXksIHZhbHVlKXtcbiAgICB2YXIgZGF0YSA9IGdldFdlYWsoYW5PYmplY3Qoa2V5KSwgdHJ1ZSk7XG4gICAgaWYoZGF0YSA9PT0gdHJ1ZSl1bmNhdWdodEZyb3plblN0b3JlKHRoYXQpLnNldChrZXksIHZhbHVlKTtcbiAgICBlbHNlIGRhdGFbdGhhdC5faV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhhdDtcbiAgfSxcbiAgdWZzdG9yZTogdW5jYXVnaHRGcm96ZW5TdG9yZVxufTsiLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsICRleHBvcnQgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCByZWRlZmluZSAgICAgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCByZWRlZmluZUFsbCAgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpXG4gICwgbWV0YSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhJylcbiAgLCBmb3JPZiAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2Zvci1vZicpXG4gICwgYW5JbnN0YW5jZSAgICAgICAgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpXG4gICwgaXNPYmplY3QgICAgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGZhaWxzICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsICRpdGVyRGV0ZWN0ICAgICAgID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKVxuICAsIHNldFRvU3RyaW5nVGFnICAgID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIGluaGVyaXRJZlJlcXVpcmVkID0gcmVxdWlyZSgnLi9faW5oZXJpdC1pZi1yZXF1aXJlZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKXtcbiAgdmFyIEJhc2UgID0gZ2xvYmFsW05BTUVdXG4gICAgLCBDICAgICA9IEJhc2VcbiAgICAsIEFEREVSID0gSVNfTUFQID8gJ3NldCcgOiAnYWRkJ1xuICAgICwgcHJvdG8gPSBDICYmIEMucHJvdG90eXBlXG4gICAgLCBPICAgICA9IHt9O1xuICB2YXIgZml4TWV0aG9kID0gZnVuY3Rpb24oS0VZKXtcbiAgICB2YXIgZm4gPSBwcm90b1tLRVldO1xuICAgIHJlZGVmaW5lKHByb3RvLCBLRVksXG4gICAgICBLRVkgPT0gJ2RlbGV0ZScgPyBmdW5jdGlvbihhKXtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpe1xuICAgICAgICByZXR1cm4gSVNfV0VBSyAmJiAhaXNPYmplY3QoYSkgPyBmYWxzZSA6IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTtcbiAgICAgIH0gOiBLRVkgPT0gJ2dldCcgPyBmdW5jdGlvbiBnZXQoYSl7XG4gICAgICAgIHJldHVybiBJU19XRUFLICYmICFpc09iamVjdChhKSA/IHVuZGVmaW5lZCA6IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTtcbiAgICAgIH0gOiBLRVkgPT0gJ2FkZCcgPyBmdW5jdGlvbiBhZGQoYSl7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYil7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhLCBiKTsgcmV0dXJuIHRoaXM7IH1cbiAgICApO1xuICB9O1xuICBpZih0eXBlb2YgQyAhPSAnZnVuY3Rpb24nIHx8ICEoSVNfV0VBSyB8fCBwcm90by5mb3JFYWNoICYmICFmYWlscyhmdW5jdGlvbigpe1xuICAgIG5ldyBDKCkuZW50cmllcygpLm5leHQoKTtcbiAgfSkpKXtcbiAgICAvLyBjcmVhdGUgY29sbGVjdGlvbiBjb25zdHJ1Y3RvclxuICAgIEMgPSBjb21tb24uZ2V0Q29uc3RydWN0b3Iod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUik7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICAgIG1ldGEuTkVFRCA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGluc3RhbmNlICAgICAgICAgICAgID0gbmV3IENcbiAgICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICAgICwgSEFTTlRfQ0hBSU5JTkcgICAgICAgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlXG4gICAgICAvLyBWOCB+ICBDaHJvbWl1bSA0MC0gd2Vhay1jb2xsZWN0aW9ucyB0aHJvd3Mgb24gcHJpbWl0aXZlcywgYnV0IHNob3VsZCByZXR1cm4gZmFsc2VcbiAgICAgICwgVEhST1dTX09OX1BSSU1JVElWRVMgPSBmYWlscyhmdW5jdGlvbigpeyBpbnN0YW5jZS5oYXMoMSk7IH0pXG4gICAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgICAsIEFDQ0VQVF9JVEVSQUJMRVMgICAgID0gJGl0ZXJEZXRlY3QoZnVuY3Rpb24oaXRlcil7IG5ldyBDKGl0ZXIpOyB9KSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgICAsIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbigpe1xuICAgICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgICAgdmFyICRpbnN0YW5jZSA9IG5ldyBDKClcbiAgICAgICAgICAsIGluZGV4ICAgICA9IDU7XG4gICAgICAgIHdoaWxlKGluZGV4LS0pJGluc3RhbmNlW0FEREVSXShpbmRleCwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgICAgfSk7XG4gICAgaWYoIUFDQ0VQVF9JVEVSQUJMRVMpeyBcbiAgICAgIEMgPSB3cmFwcGVyKGZ1bmN0aW9uKHRhcmdldCwgaXRlcmFibGUpe1xuICAgICAgICBhbkluc3RhbmNlKHRhcmdldCwgQywgTkFNRSk7XG4gICAgICAgIHZhciB0aGF0ID0gaW5oZXJpdElmUmVxdWlyZWQobmV3IEJhc2UsIHRhcmdldCwgQyk7XG4gICAgICAgIGlmKGl0ZXJhYmxlICE9IHVuZGVmaW5lZClmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgICAgIHJldHVybiB0aGF0O1xuICAgICAgfSk7XG4gICAgICBDLnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgcHJvdG8uY29uc3RydWN0b3IgPSBDO1xuICAgIH1cbiAgICBpZihUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKXtcbiAgICAgIGZpeE1ldGhvZCgnZGVsZXRlJyk7XG4gICAgICBmaXhNZXRob2QoJ2hhcycpO1xuICAgICAgSVNfTUFQICYmIGZpeE1ldGhvZCgnZ2V0Jyk7XG4gICAgfVxuICAgIGlmKEJVR0dZX1pFUk8gfHwgSEFTTlRfQ0hBSU5JTkcpZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmKElTX1dFQUsgJiYgcHJvdG8uY2xlYXIpZGVsZXRlIHByb3RvLmNsZWFyO1xuICB9XG5cbiAgc2V0VG9TdHJpbmdUYWcoQywgTkFNRSk7XG5cbiAgT1tOQU1FXSA9IEM7XG4gICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKEMgIT0gQmFzZSksIE8pO1xuXG4gIGlmKCFJU19XRUFLKWNvbW1vbi5zZXRTdHJvbmcoQywgTkFNRSwgSVNfTUFQKTtcblxuICByZXR1cm4gQztcbn07IiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHt2ZXJzaW9uOiAnMi40LjAnfTtcbmlmKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpX19lID0gY29yZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsIGNyZWF0ZURlc2MgICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIGluZGV4LCB2YWx1ZSl7XG4gIGlmKGluZGV4IGluIG9iamVjdCkkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTsiLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCB0aGF0LCBsZW5ndGgpe1xuICBhRnVuY3Rpb24oZm4pO1xuICBpZih0aGF0ID09PSB1bmRlZmluZWQpcmV0dXJuIGZuO1xuICBzd2l0Y2gobGVuZ3RoKXtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xuICAgIH07XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24oYSwgYil7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKGEsIGIsIGMpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oLyogLi4uYXJncyAqLyl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3VtZW50cyk7XG4gIH07XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBhbk9iamVjdCAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKVxuICAsIE5VTUJFUiAgICAgID0gJ251bWJlcic7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaGludCl7XG4gIGlmKGhpbnQgIT09ICdzdHJpbmcnICYmIGhpbnQgIT09IE5VTUJFUiAmJiBoaW50ICE9PSAnZGVmYXVsdCcpdGhyb3cgVHlwZUVycm9yKCdJbmNvcnJlY3QgaGludCcpO1xuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcbn07IiwiLy8gNy4yLjEgUmVxdWlyZU9iamVjdENvZXJjaWJsZShhcmd1bWVudClcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICBpZihpdCA9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59OyIsIi8vIFRoYW5rJ3MgSUU4IGZvciBoaXMgZnVubnkgZGVmaW5lUHJvcGVydHlcbm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gNzsgfX0pLmEgIT0gNztcbn0pOyIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudFxuICAvLyBpbiBvbGQgSUUgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCdcbiAgLCBpcyA9IGlzT2JqZWN0KGRvY3VtZW50KSAmJiBpc09iamVjdChkb2N1bWVudC5jcmVhdGVFbGVtZW50KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTsiLCIvLyBJRSA4LSBkb24ndCBlbnVtIGJ1ZyBrZXlzXG5tb2R1bGUuZXhwb3J0cyA9IChcbiAgJ2NvbnN0cnVjdG9yLGhhc093blByb3BlcnR5LGlzUHJvdG90eXBlT2YscHJvcGVydHlJc0VudW1lcmFibGUsdG9Mb2NhbGVTdHJpbmcsdG9TdHJpbmcsdmFsdWVPZidcbikuc3BsaXQoJywnKTsiLCIvLyBhbGwgZW51bWVyYWJsZSBvYmplY3Qga2V5cywgaW5jbHVkZXMgc3ltYm9sc1xudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpXG4gICwgZ09QUyAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJylcbiAgLCBwSUUgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHZhciByZXN1bHQgICAgID0gZ2V0S2V5cyhpdClcbiAgICAsIGdldFN5bWJvbHMgPSBnT1BTLmY7XG4gIGlmKGdldFN5bWJvbHMpe1xuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdClcbiAgICAgICwgaXNFbnVtICA9IHBJRS5mXG4gICAgICAsIGkgICAgICAgPSAwXG4gICAgICAsIGtleTtcbiAgICB3aGlsZShzeW1ib2xzLmxlbmd0aCA+IGkpaWYoaXNFbnVtLmNhbGwoaXQsIGtleSA9IHN5bWJvbHNbaSsrXSkpcmVzdWx0LnB1c2goa2V5KTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTsiLCJ2YXIgZ2xvYmFsICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBjb3JlICAgICAgPSByZXF1aXJlKCcuL19jb3JlJylcbiAgLCBoaWRlICAgICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgLCByZWRlZmluZSAgPSByZXF1aXJlKCcuL19yZWRlZmluZScpXG4gICwgY3R4ICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxudmFyICRleHBvcnQgPSBmdW5jdGlvbih0eXBlLCBuYW1lLCBzb3VyY2Upe1xuICB2YXIgSVNfRk9SQ0VEID0gdHlwZSAmICRleHBvcnQuRlxuICAgICwgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuR1xuICAgICwgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuU1xuICAgICwgSVNfUFJPVE8gID0gdHlwZSAmICRleHBvcnQuUFxuICAgICwgSVNfQklORCAgID0gdHlwZSAmICRleHBvcnQuQlxuICAgICwgdGFyZ2V0ICAgID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIHx8IChnbG9iYWxbbmFtZV0gPSB7fSkgOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdXG4gICAgLCBleHBvcnRzICAgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KVxuICAgICwgZXhwUHJvdG8gID0gZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSlcbiAgICAsIGtleSwgb3duLCBvdXQsIGV4cDtcbiAgaWYoSVNfR0xPQkFMKXNvdXJjZSA9IG5hbWU7XG4gIGZvcihrZXkgaW4gc291cmNlKXtcbiAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcbiAgICBvd24gPSAhSVNfRk9SQ0VEICYmIHRhcmdldCAmJiB0YXJnZXRba2V5XSAhPT0gdW5kZWZpbmVkO1xuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXG4gICAgb3V0ID0gKG93biA/IHRhcmdldCA6IHNvdXJjZSlba2V5XTtcbiAgICAvLyBiaW5kIHRpbWVycyB0byBnbG9iYWwgZm9yIGNhbGwgZnJvbSBleHBvcnQgY29udGV4dFxuICAgIGV4cCA9IElTX0JJTkQgJiYgb3duID8gY3R4KG91dCwgZ2xvYmFsKSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xuICAgIC8vIGV4dGVuZCBnbG9iYWxcbiAgICBpZih0YXJnZXQpcmVkZWZpbmUodGFyZ2V0LCBrZXksIG91dCwgdHlwZSAmICRleHBvcnQuVSk7XG4gICAgLy8gZXhwb3J0XG4gICAgaWYoZXhwb3J0c1trZXldICE9IG91dCloaWRlKGV4cG9ydHMsIGtleSwgZXhwKTtcbiAgICBpZihJU19QUk9UTyAmJiBleHBQcm90b1trZXldICE9IG91dClleHBQcm90b1trZXldID0gb3V0O1xuICB9XG59O1xuZ2xvYmFsLmNvcmUgPSBjb3JlO1xuLy8gdHlwZSBiaXRtYXBcbiRleHBvcnQuRiA9IDE7ICAgLy8gZm9yY2VkXG4kZXhwb3J0LkcgPSAyOyAgIC8vIGdsb2JhbFxuJGV4cG9ydC5TID0gNDsgICAvLyBzdGF0aWNcbiRleHBvcnQuUCA9IDg7ICAgLy8gcHJvdG9cbiRleHBvcnQuQiA9IDE2OyAgLy8gYmluZFxuJGV4cG9ydC5XID0gMzI7ICAvLyB3cmFwXG4kZXhwb3J0LlUgPSA2NDsgIC8vIHNhZmVcbiRleHBvcnQuUiA9IDEyODsgLy8gcmVhbCBwcm90byBtZXRob2QgZm9yIGBsaWJyYXJ5YCBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDsiLCJ2YXIgTUFUQ0ggPSByZXF1aXJlKCcuL193a3MnKSgnbWF0Y2gnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZKXtcbiAgdmFyIHJlID0gLy4vO1xuICB0cnkge1xuICAgICcvLi8nW0tFWV0ocmUpO1xuICB9IGNhdGNoKGUpe1xuICAgIHRyeSB7XG4gICAgICByZVtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XG4gICAgfSBjYXRjaChmKXsgLyogZW1wdHkgKi8gfVxuICB9IHJldHVybiB0cnVlO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTsiLCIndXNlIHN0cmljdCc7XG52YXIgaGlkZSAgICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgLCByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBmYWlscyAgICA9IHJlcXVpcmUoJy4vX2ZhaWxzJylcbiAgLCBkZWZpbmVkICA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKVxuICAsIHdrcyAgICAgID0gcmVxdWlyZSgnLi9fd2tzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBsZW5ndGgsIGV4ZWMpe1xuICB2YXIgU1lNQk9MICAgPSB3a3MoS0VZKVxuICAgICwgZm5zICAgICAgPSBleGVjKGRlZmluZWQsIFNZTUJPTCwgJydbS0VZXSlcbiAgICAsIHN0cmZuICAgID0gZm5zWzBdXG4gICAgLCByeGZuICAgICA9IGZuc1sxXTtcbiAgaWYoZmFpbHMoZnVuY3Rpb24oKXtcbiAgICB2YXIgTyA9IHt9O1xuICAgIE9bU1lNQk9MXSA9IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9O1xuICAgIHJldHVybiAnJ1tLRVldKE8pICE9IDc7XG4gIH0pKXtcbiAgICByZWRlZmluZShTdHJpbmcucHJvdG90eXBlLCBLRVksIHN0cmZuKTtcbiAgICBoaWRlKFJlZ0V4cC5wcm90b3R5cGUsIFNZTUJPTCwgbGVuZ3RoID09IDJcbiAgICAgIC8vIDIxLjIuNS44IFJlZ0V4cC5wcm90b3R5cGVbQEByZXBsYWNlXShzdHJpbmcsIHJlcGxhY2VWYWx1ZSlcbiAgICAgIC8vIDIxLjIuNS4xMSBSZWdFeHAucHJvdG90eXBlW0BAc3BsaXRdKHN0cmluZywgbGltaXQpXG4gICAgICA/IGZ1bmN0aW9uKHN0cmluZywgYXJnKXsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMsIGFyZyk7IH1cbiAgICAgIC8vIDIxLjIuNS42IFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF0oc3RyaW5nKVxuICAgICAgLy8gMjEuMi41LjkgUmVnRXhwLnByb3RvdHlwZVtAQHNlYXJjaF0oc3RyaW5nKVxuICAgICAgOiBmdW5jdGlvbihzdHJpbmcpeyByZXR1cm4gcnhmbi5jYWxsKHN0cmluZywgdGhpcyk7IH1cbiAgICApO1xuICB9XG59OyIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKXtcbiAgdmFyIHRoYXQgICA9IGFuT2JqZWN0KHRoaXMpXG4gICAgLCByZXN1bHQgPSAnJztcbiAgaWYodGhhdC5nbG9iYWwpICAgICByZXN1bHQgKz0gJ2cnO1xuICBpZih0aGF0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG4gIGlmKHRoYXQubXVsdGlsaW5lKSAgcmVzdWx0ICs9ICdtJztcbiAgaWYodGhhdC51bmljb2RlKSAgICByZXN1bHQgKz0gJ3UnO1xuICBpZih0aGF0LnN0aWNreSkgICAgIHJlc3VsdCArPSAneSc7XG4gIHJldHVybiByZXN1bHQ7XG59OyIsInZhciBjdHggICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgY2FsbCAgICAgICAgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKVxuICAsIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpXG4gICwgYW5PYmplY3QgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIHRvTGVuZ3RoICAgID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJylcbiAgLCBnZXRJdGVyRm4gICA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJylcbiAgLCBCUkVBSyAgICAgICA9IHt9XG4gICwgUkVUVVJOICAgICAgPSB7fTtcbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKXtcbiAgdmFyIGl0ZXJGbiA9IElURVJBVE9SID8gZnVuY3Rpb24oKXsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKVxuICAgICwgZiAgICAgID0gY3R4KGZuLCB0aGF0LCBlbnRyaWVzID8gMiA6IDEpXG4gICAgLCBpbmRleCAgPSAwXG4gICAgLCBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yLCByZXN1bHQ7XG4gIGlmKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXRlcmFibGUgKyAnIGlzIG5vdCBpdGVyYWJsZSEnKTtcbiAgLy8gZmFzdCBjYXNlIGZvciBhcnJheXMgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yXG4gIGlmKGlzQXJyYXlJdGVyKGl0ZXJGbikpZm9yKGxlbmd0aCA9IHRvTGVuZ3RoKGl0ZXJhYmxlLmxlbmd0aCk7IGxlbmd0aCA+IGluZGV4OyBpbmRleCsrKXtcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgaWYocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTilyZXR1cm4gcmVzdWx0O1xuICB9IGVsc2UgZm9yKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7ICl7XG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gICAgaWYocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTilyZXR1cm4gcmVzdWx0O1xuICB9XG59O1xuZXhwb3J0cy5CUkVBSyAgPSBCUkVBSztcbmV4cG9ydHMuUkVUVVJOID0gUkVUVVJOOyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGYgOiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuaWYodHlwZW9mIF9fZyA9PSAnbnVtYmVyJylfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWYiLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIGtleSl7XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xufTsiLCJ2YXIgZFAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpXG4gICwgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XG4gIHJldHVybiBkUC5mKG9iamVjdCwga2V5LCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG59IDogZnVuY3Rpb24ob2JqZWN0LCBrZXksIHZhbHVlKXtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgcmV0dXJuIG9iamVjdDtcbn07IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7IiwibW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XG59KTsiLCJ2YXIgaXNPYmplY3QgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fc2V0LXByb3RvJykuc2V0O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0aGF0LCB0YXJnZXQsIEMpe1xuICB2YXIgUCwgUyA9IHRhcmdldC5jb25zdHJ1Y3RvcjtcbiAgaWYoUyAhPT0gQyAmJiB0eXBlb2YgUyA9PSAnZnVuY3Rpb24nICYmIChQID0gUy5wcm90b3R5cGUpICE9PSBDLnByb3RvdHlwZSAmJiBpc09iamVjdChQKSAmJiBzZXRQcm90b3R5cGVPZil7XG4gICAgc2V0UHJvdG90eXBlT2YodGhhdCwgUCk7XG4gIH0gcmV0dXJuIHRoYXQ7XG59OyIsIi8vIGZhc3QgYXBwbHksIGh0dHA6Ly9qc3BlcmYubG5raXQuY29tL2Zhc3QtYXBwbHkvNVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgYXJncywgdGhhdCl7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoKGFyZ3MubGVuZ3RoKXtcbiAgICBjYXNlIDA6IHJldHVybiB1biA/IGZuKClcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCk7XG4gICAgY2FzZSAxOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgY2FzZSA0OiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgfSByZXR1cm4gICAgICAgICAgICAgIGZuLmFwcGx5KHRoYXQsIGFyZ3MpO1xufTsiLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGNvZihpdCkgPT0gJ1N0cmluZycgPyBpdC5zcGxpdCgnJykgOiBPYmplY3QoaXQpO1xufTsiLCIvLyBjaGVjayBvbiBkZWZhdWx0IEFycmF5IGl0ZXJhdG9yXG52YXIgSXRlcmF0b3JzICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgSVRFUkFUT1IgICA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpXG4gICwgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpdCAhPT0gdW5kZWZpbmVkICYmIChJdGVyYXRvcnMuQXJyYXkgPT09IGl0IHx8IEFycmF5UHJvdG9bSVRFUkFUT1JdID09PSBpdCk7XG59OyIsIi8vIDcuMi4yIElzQXJyYXkoYXJndW1lbnQpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gaXNBcnJheShhcmcpe1xuICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcbn07IiwiLy8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGZsb29yICAgID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNJbnRlZ2VyKGl0KXtcbiAgcmV0dXJuICFpc09iamVjdChpdCkgJiYgaXNGaW5pdGUoaXQpICYmIGZsb29yKGl0KSA9PT0gaXQ7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTsiLCIvLyA3LjIuOCBJc1JlZ0V4cChhcmd1bWVudClcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgY29mICAgICAgPSByZXF1aXJlKCcuL19jb2YnKVxuICAsIE1BVENIICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ21hdGNoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIGlzUmVnRXhwO1xuICByZXR1cm4gaXNPYmplY3QoaXQpICYmICgoaXNSZWdFeHAgPSBpdFtNQVRDSF0pICE9PSB1bmRlZmluZWQgPyAhIWlzUmVnRXhwIDogY29mKGl0KSA9PSAnUmVnRXhwJyk7XG59OyIsIi8vIGNhbGwgc29tZXRoaW5nIG9uIGl0ZXJhdG9yIHN0ZXAgd2l0aCBzYWZlIGNsb3Npbmcgb24gZXJyb3JcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZW50cmllcyA/IGZuKGFuT2JqZWN0KHZhbHVlKVswXSwgdmFsdWVbMV0pIDogZm4odmFsdWUpO1xuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICB9IGNhdGNoKGUpe1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYocmV0ICE9PSB1bmRlZmluZWQpYW5PYmplY3QocmV0LmNhbGwoaXRlcmF0b3IpKTtcbiAgICB0aHJvdyBlO1xuICB9XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKVxuICAsIGRlc2NyaXB0b3IgICAgID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpXG4gICwgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCl7XG4gIENvbnN0cnVjdG9yLnByb3RvdHlwZSA9IGNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSwge25leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCl9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZICAgICAgICA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCByZWRlZmluZSAgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBoaWRlICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIGhhcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBJdGVyYXRvcnMgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgJGl0ZXJDcmVhdGUgICAgPSByZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpXG4gICwgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJylcbiAgLCBJVEVSQVRPUiAgICAgICA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpXG4gICwgQlVHR1kgICAgICAgICAgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSkgLy8gU2FmYXJpIGhhcyBidWdneSBpdGVyYXRvcnMgdy9vIGBuZXh0YFxuICAsIEZGX0lURVJBVE9SICAgID0gJ0BAaXRlcmF0b3InXG4gICwgS0VZUyAgICAgICAgICAgPSAna2V5cydcbiAgLCBWQUxVRVMgICAgICAgICA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCl7XG4gICRpdGVyQ3JlYXRlKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KTtcbiAgdmFyIGdldE1ldGhvZCA9IGZ1bmN0aW9uKGtpbmQpe1xuICAgIGlmKCFCVUdHWSAmJiBraW5kIGluIHByb3RvKXJldHVybiBwcm90b1traW5kXTtcbiAgICBzd2l0Y2goa2luZCl7XG4gICAgICBjYXNlIEtFWVM6IHJldHVybiBmdW5jdGlvbiBrZXlzKCl7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgICBjYXNlIFZBTFVFUzogcmV0dXJuIGZ1bmN0aW9uIHZhbHVlcygpeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgfTtcbiAgdmFyIFRBRyAgICAgICAgPSBOQU1FICsgJyBJdGVyYXRvcidcbiAgICAsIERFRl9WQUxVRVMgPSBERUZBVUxUID09IFZBTFVFU1xuICAgICwgVkFMVUVTX0JVRyA9IGZhbHNlXG4gICAgLCBwcm90byAgICAgID0gQmFzZS5wcm90b3R5cGVcbiAgICAsICRuYXRpdmUgICAgPSBwcm90b1tJVEVSQVRPUl0gfHwgcHJvdG9bRkZfSVRFUkFUT1JdIHx8IERFRkFVTFQgJiYgcHJvdG9bREVGQVVMVF1cbiAgICAsICRkZWZhdWx0ICAgPSAkbmF0aXZlIHx8IGdldE1ldGhvZChERUZBVUxUKVxuICAgICwgJGVudHJpZXMgICA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWRcbiAgICAsICRhbnlOYXRpdmUgPSBOQU1FID09ICdBcnJheScgPyBwcm90by5lbnRyaWVzIHx8ICRuYXRpdmUgOiAkbmF0aXZlXG4gICAgLCBtZXRob2RzLCBrZXksIEl0ZXJhdG9yUHJvdG90eXBlO1xuICAvLyBGaXggbmF0aXZlXG4gIGlmKCRhbnlOYXRpdmUpe1xuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG90eXBlT2YoJGFueU5hdGl2ZS5jYWxsKG5ldyBCYXNlKSk7XG4gICAgaWYoSXRlcmF0b3JQcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUpe1xuICAgICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xuICAgICAgc2V0VG9TdHJpbmdUYWcoSXRlcmF0b3JQcm90b3R5cGUsIFRBRywgdHJ1ZSk7XG4gICAgICAvLyBmaXggZm9yIHNvbWUgb2xkIGVuZ2luZXNcbiAgICAgIGlmKCFMSUJSQVJZICYmICFoYXMoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SKSloaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYoREVGX1ZBTFVFUyAmJiAkbmF0aXZlICYmICRuYXRpdmUubmFtZSAhPT0gVkFMVUVTKXtcbiAgICBWQUxVRVNfQlVHID0gdHJ1ZTtcbiAgICAkZGVmYXVsdCA9IGZ1bmN0aW9uIHZhbHVlcygpeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZigoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSl7XG4gICAgaGlkZShwcm90bywgSVRFUkFUT1IsICRkZWZhdWx0KTtcbiAgfVxuICAvLyBQbHVnIGZvciBsaWJyYXJ5XG4gIEl0ZXJhdG9yc1tOQU1FXSA9ICRkZWZhdWx0O1xuICBJdGVyYXRvcnNbVEFHXSAgPSByZXR1cm5UaGlzO1xuICBpZihERUZBVUxUKXtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiAgREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKFZBTFVFUyksXG4gICAgICBrZXlzOiAgICBJU19TRVQgICAgID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoS0VZUyksXG4gICAgICBlbnRyaWVzOiAkZW50cmllc1xuICAgIH07XG4gICAgaWYoRk9SQ0VEKWZvcihrZXkgaW4gbWV0aG9kcyl7XG4gICAgICBpZighKGtleSBpbiBwcm90bykpcmVkZWZpbmUocHJvdG8sIGtleSwgbWV0aG9kc1trZXldKTtcbiAgICB9IGVsc2UgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoQlVHR1kgfHwgVkFMVUVTX0JVRyksIE5BTUUsIG1ldGhvZHMpO1xuICB9XG4gIHJldHVybiBtZXRob2RzO1xufTsiLCJ2YXIgSVRFUkFUT1IgICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbigpeyBTQUZFX0NMT1NJTkcgPSB0cnVlOyB9O1xuICBBcnJheS5mcm9tKHJpdGVyLCBmdW5jdGlvbigpeyB0aHJvdyAyOyB9KTtcbn0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihleGVjLCBza2lwQ2xvc2luZyl7XG4gIGlmKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKXJldHVybiBmYWxzZTtcbiAgdmFyIHNhZmUgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyICA9IFs3XVxuICAgICAgLCBpdGVyID0gYXJyW0lURVJBVE9SXSgpO1xuICAgIGl0ZXIubmV4dCA9IGZ1bmN0aW9uKCl7IHJldHVybiB7ZG9uZTogc2FmZSA9IHRydWV9OyB9O1xuICAgIGFycltJVEVSQVRPUl0gPSBmdW5jdGlvbigpeyByZXR1cm4gaXRlcjsgfTtcbiAgICBleGVjKGFycik7XG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZG9uZSwgdmFsdWUpe1xuICByZXR1cm4ge3ZhbHVlOiB2YWx1ZSwgZG9uZTogISFkb25lfTtcbn07IiwibW9kdWxlLmV4cG9ydHMgPSB7fTsiLCJ2YXIgZ2V0S2V5cyAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKVxuICAsIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob2JqZWN0LCBlbCl7XG4gIHZhciBPICAgICAgPSB0b0lPYmplY3Qob2JqZWN0KVxuICAgICwga2V5cyAgID0gZ2V0S2V5cyhPKVxuICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAsIGluZGV4ICA9IDBcbiAgICAsIGtleTtcbiAgd2hpbGUobGVuZ3RoID4gaW5kZXgpaWYoT1trZXkgPSBrZXlzW2luZGV4KytdXSA9PT0gZWwpcmV0dXJuIGtleTtcbn07IiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTsiLCIvLyAyMC4yLjIuMTQgTWF0aC5leHBtMSh4KVxudmFyICRleHBtMSA9IE1hdGguZXhwbTE7XG5tb2R1bGUuZXhwb3J0cyA9ICghJGV4cG0xXG4gIC8vIE9sZCBGRiBidWdcbiAgfHwgJGV4cG0xKDEwKSA+IDIyMDI1LjQ2NTc5NDgwNjcxOSB8fCAkZXhwbTEoMTApIDwgMjIwMjUuNDY1Nzk0ODA2NzE2NTE2OFxuICAvLyBUb3IgQnJvd3NlciBidWdcbiAgfHwgJGV4cG0xKC0yZS0xNykgIT0gLTJlLTE3XG4pID8gZnVuY3Rpb24gZXhwbTEoeCl7XG4gIHJldHVybiAoeCA9ICt4KSA9PSAwID8geCA6IHggPiAtMWUtNiAmJiB4IDwgMWUtNiA/IHggKyB4ICogeCAvIDIgOiBNYXRoLmV4cCh4KSAtIDE7XG59IDogJGV4cG0xOyIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubG9nMXAgfHwgZnVuY3Rpb24gbG9nMXAoeCl7XG4gIHJldHVybiAoeCA9ICt4KSA+IC0xZS04ICYmIHggPCAxZS04ID8geCAtIHggKiB4IC8gMiA6IE1hdGgubG9nKDEgKyB4KTtcbn07IiwiLy8gMjAuMi4yLjI4IE1hdGguc2lnbih4KVxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLnNpZ24gfHwgZnVuY3Rpb24gc2lnbih4KXtcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgfHwgeCAhPSB4ID8geCA6IHggPCAwID8gLTEgOiAxO1xufTsiLCJ2YXIgTUVUQSAgICAgPSByZXF1aXJlKCcuL191aWQnKSgnbWV0YScpXG4gICwgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGhhcyAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBzZXREZXNjICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmZcbiAgLCBpZCAgICAgICA9IDA7XG52YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZSB8fCBmdW5jdGlvbigpe1xuICByZXR1cm4gdHJ1ZTtcbn07XG52YXIgRlJFRVpFID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcbn0pO1xudmFyIHNldE1ldGEgPSBmdW5jdGlvbihpdCl7XG4gIHNldERlc2MoaXQsIE1FVEEsIHt2YWx1ZToge1xuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxuICAgIHc6IHt9ICAgICAgICAgIC8vIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH19KTtcbn07XG52YXIgZmFzdEtleSA9IGZ1bmN0aW9uKGl0LCBjcmVhdGUpe1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJyA/IGl0IDogKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyA/ICdTJyA6ICdQJykgKyBpdDtcbiAgaWYoIWhhcyhpdCwgTUVUQSkpe1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYoIWlzRXh0ZW5zaWJsZShpdCkpcmV0dXJuICdGJztcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmKCFjcmVhdGUpcmV0dXJuICdFJztcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuICAgIHNldE1ldGEoaXQpO1xuICAvLyByZXR1cm4gb2JqZWN0IElEXG4gIH0gcmV0dXJuIGl0W01FVEFdLmk7XG59O1xudmFyIGdldFdlYWsgPSBmdW5jdGlvbihpdCwgY3JlYXRlKXtcbiAgaWYoIWhhcyhpdCwgTUVUQSkpe1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYoIWlzRXh0ZW5zaWJsZShpdCkpcmV0dXJuIHRydWU7XG4gICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcbiAgICBpZighY3JlYXRlKXJldHVybiBmYWxzZTtcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuICAgIHNldE1ldGEoaXQpO1xuICAvLyByZXR1cm4gaGFzaCB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuICB9IHJldHVybiBpdFtNRVRBXS53O1xufTtcbi8vIGFkZCBtZXRhZGF0YSBvbiBmcmVlemUtZmFtaWx5IG1ldGhvZHMgY2FsbGluZ1xudmFyIG9uRnJlZXplID0gZnVuY3Rpb24oaXQpe1xuICBpZihGUkVFWkUgJiYgbWV0YS5ORUVEICYmIGlzRXh0ZW5zaWJsZShpdCkgJiYgIWhhcyhpdCwgTUVUQSkpc2V0TWV0YShpdCk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgbWV0YSA9IG1vZHVsZS5leHBvcnRzID0ge1xuICBLRVk6ICAgICAgTUVUQSxcbiAgTkVFRDogICAgIGZhbHNlLFxuICBmYXN0S2V5OiAgZmFzdEtleSxcbiAgZ2V0V2VhazogIGdldFdlYWssXG4gIG9uRnJlZXplOiBvbkZyZWV6ZVxufTsiLCJ2YXIgTWFwICAgICA9IHJlcXVpcmUoJy4vZXM2Lm1hcCcpXG4gICwgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgc2hhcmVkICA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdtZXRhZGF0YScpXG4gICwgc3RvcmUgICA9IHNoYXJlZC5zdG9yZSB8fCAoc2hhcmVkLnN0b3JlID0gbmV3IChyZXF1aXJlKCcuL2VzNi53ZWFrLW1hcCcpKSk7XG5cbnZhciBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwID0gZnVuY3Rpb24odGFyZ2V0LCB0YXJnZXRLZXksIGNyZWF0ZSl7XG4gIHZhciB0YXJnZXRNZXRhZGF0YSA9IHN0b3JlLmdldCh0YXJnZXQpO1xuICBpZighdGFyZ2V0TWV0YWRhdGEpe1xuICAgIGlmKCFjcmVhdGUpcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBzdG9yZS5zZXQodGFyZ2V0LCB0YXJnZXRNZXRhZGF0YSA9IG5ldyBNYXApO1xuICB9XG4gIHZhciBrZXlNZXRhZGF0YSA9IHRhcmdldE1ldGFkYXRhLmdldCh0YXJnZXRLZXkpO1xuICBpZigha2V5TWV0YWRhdGEpe1xuICAgIGlmKCFjcmVhdGUpcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB0YXJnZXRNZXRhZGF0YS5zZXQodGFyZ2V0S2V5LCBrZXlNZXRhZGF0YSA9IG5ldyBNYXApO1xuICB9IHJldHVybiBrZXlNZXRhZGF0YTtcbn07XG52YXIgb3JkaW5hcnlIYXNPd25NZXRhZGF0YSA9IGZ1bmN0aW9uKE1ldGFkYXRhS2V5LCBPLCBQKXtcbiAgdmFyIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCBmYWxzZSk7XG4gIHJldHVybiBtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBtZXRhZGF0YU1hcC5oYXMoTWV0YWRhdGFLZXkpO1xufTtcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gZnVuY3Rpb24oTWV0YWRhdGFLZXksIE8sIFApe1xuICB2YXIgbWV0YWRhdGFNYXAgPSBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIGZhbHNlKTtcbiAgcmV0dXJuIG1ldGFkYXRhTWFwID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBtZXRhZGF0YU1hcC5nZXQoTWV0YWRhdGFLZXkpO1xufTtcbnZhciBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gZnVuY3Rpb24oTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUsIE8sIFApe1xuICBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIHRydWUpLnNldChNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSk7XG59O1xudmFyIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gZnVuY3Rpb24odGFyZ2V0LCB0YXJnZXRLZXkpe1xuICB2YXIgbWV0YWRhdGFNYXAgPSBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwKHRhcmdldCwgdGFyZ2V0S2V5LCBmYWxzZSlcbiAgICAsIGtleXMgICAgICAgID0gW107XG4gIGlmKG1ldGFkYXRhTWFwKW1ldGFkYXRhTWFwLmZvckVhY2goZnVuY3Rpb24oXywga2V5KXsga2V5cy5wdXNoKGtleSk7IH0pO1xuICByZXR1cm4ga2V5cztcbn07XG52YXIgdG9NZXRhS2V5ID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xudmFyIGV4cCA9IGZ1bmN0aW9uKE8pe1xuICAkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCBPKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzdG9yZTogc3RvcmUsXG4gIG1hcDogZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcCxcbiAgaGFzOiBvcmRpbmFyeUhhc093bk1ldGFkYXRhLFxuICBnZXQ6IG9yZGluYXJ5R2V0T3duTWV0YWRhdGEsXG4gIHNldDogb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YSxcbiAga2V5czogb3JkaW5hcnlPd25NZXRhZGF0YUtleXMsXG4gIGtleTogdG9NZXRhS2V5LFxuICBleHA6IGV4cFxufTsiLCJ2YXIgZ2xvYmFsICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0XG4gICwgT2JzZXJ2ZXIgID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXJcbiAgLCBwcm9jZXNzICAgPSBnbG9iYWwucHJvY2Vzc1xuICAsIFByb21pc2UgICA9IGdsb2JhbC5Qcm9taXNlXG4gICwgaXNOb2RlICAgID0gcmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7XG4gIHZhciBoZWFkLCBsYXN0LCBub3RpZnk7XG5cbiAgdmFyIGZsdXNoID0gZnVuY3Rpb24oKXtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZihpc05vZGUgJiYgKHBhcmVudCA9IHByb2Nlc3MuZG9tYWluKSlwYXJlbnQuZXhpdCgpO1xuICAgIHdoaWxlKGhlYWQpe1xuICAgICAgZm4gICA9IGhlYWQuZm47XG4gICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm4oKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIGlmKGhlYWQpbm90aWZ5KCk7XG4gICAgICAgIGVsc2UgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYocGFyZW50KXBhcmVudC5lbnRlcigpO1xuICB9O1xuXG4gIC8vIE5vZGUuanNcbiAgaWYoaXNOb2RlKXtcbiAgICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgfTtcbiAgLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyXG4gIH0gZWxzZSBpZihPYnNlcnZlcil7XG4gICAgdmFyIHRvZ2dsZSA9IHRydWVcbiAgICAgICwgbm9kZSAgID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgICBub2RlLmRhdGEgPSB0b2dnbGUgPSAhdG9nZ2xlO1xuICAgIH07XG4gIC8vIGVudmlyb25tZW50cyB3aXRoIG1heWJlIG5vbi1jb21wbGV0ZWx5IGNvcnJlY3QsIGJ1dCBleGlzdGVudCBQcm9taXNlXG4gIH0gZWxzZSBpZihQcm9taXNlICYmIFByb21pc2UucmVzb2x2ZSl7XG4gICAgdmFyIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgICAgcHJvbWlzZS50aGVuKGZsdXNoKTtcbiAgICB9O1xuICAvLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxuICAvLyAtIHNldEltbWVkaWF0ZVxuICAvLyAtIE1lc3NhZ2VDaGFubmVsXG4gIC8vIC0gd2luZG93LnBvc3RNZXNzYWdcbiAgLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2VcbiAgLy8gLSBzZXRUaW1lb3V0XG4gIH0gZWxzZSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICAgIC8vIHN0cmFuZ2UgSUUgKyB3ZWJwYWNrIGRldiBzZXJ2ZXIgYnVnIC0gdXNlIC5jYWxsKGdsb2JhbClcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oZm4pe1xuICAgIHZhciB0YXNrID0ge2ZuOiBmbiwgbmV4dDogdW5kZWZpbmVkfTtcbiAgICBpZihsYXN0KWxhc3QubmV4dCA9IHRhc2s7XG4gICAgaWYoIWhlYWQpe1xuICAgICAgaGVhZCA9IHRhc2s7XG4gICAgICBub3RpZnkoKTtcbiAgICB9IGxhc3QgPSB0YXNrO1xuICB9O1xufTsiLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpXG4gICwgZ09QUyAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpXG4gICwgcElFICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJylcbiAgLCB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgSU9iamVjdCAgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCAkYXNzaWduICA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHZhciBBID0ge31cbiAgICAsIEIgPSB7fVxuICAgICwgUyA9IFN5bWJvbCgpXG4gICAgLCBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24oayl7IEJba10gPSBrOyB9KTtcbiAgcmV0dXJuICRhc3NpZ24oe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoJGFzc2lnbih7fSwgQikpLmpvaW4oJycpICE9IEs7XG59KSA/IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZSl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgICAgID0gdG9PYmplY3QodGFyZ2V0KVxuICAgICwgYUxlbiAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgLCBpbmRleCA9IDFcbiAgICAsIGdldFN5bWJvbHMgPSBnT1BTLmZcbiAgICAsIGlzRW51bSAgICAgPSBwSUUuZjtcbiAgd2hpbGUoYUxlbiA+IGluZGV4KXtcbiAgICB2YXIgUyAgICAgID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pXG4gICAgICAsIGtleXMgICA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUylcbiAgICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAgICwgaiAgICAgID0gMFxuICAgICAgLCBrZXk7XG4gICAgd2hpbGUobGVuZ3RoID4gailpZihpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKVRba2V5XSA9IFNba2V5XTtcbiAgfSByZXR1cm4gVDtcbn0gOiAkYXNzaWduOyIsIi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxudmFyIGFuT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBkUHMgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKVxuICAsIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpXG4gICwgSUVfUFJPVE8gICAgPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJylcbiAgLCBFbXB0eSAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cbiAgLCBQUk9UT1RZUEUgICA9ICdwcm90b3R5cGUnO1xuXG4vLyBDcmVhdGUgb2JqZWN0IHdpdGggZmFrZSBgbnVsbGAgcHJvdG90eXBlOiB1c2UgaWZyYW1lIE9iamVjdCB3aXRoIGNsZWFyZWQgcHJvdG90eXBlXG52YXIgY3JlYXRlRGljdCA9IGZ1bmN0aW9uKCl7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpXG4gICAgLCBpICAgICAgPSBlbnVtQnVnS2V5cy5sZW5ndGhcbiAgICAsIGx0ICAgICA9ICc8J1xuICAgICwgZ3QgICAgID0gJz4nXG4gICAgLCBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZShpLS0pZGVsZXRlIGNyZWF0ZURpY3RbUFJPVE9UWVBFXVtlbnVtQnVnS2V5c1tpXV07XG4gIHJldHVybiBjcmVhdGVEaWN0KCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gY3JlYXRlKE8sIFByb3BlcnRpZXMpe1xuICB2YXIgcmVzdWx0O1xuICBpZihPICE9PSBudWxsKXtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gYW5PYmplY3QoTyk7XG4gICAgcmVzdWx0ID0gbmV3IEVtcHR5O1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBudWxsO1xuICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcbiAgICByZXN1bHRbSUVfUFJPVE9dID0gTztcbiAgfSBlbHNlIHJlc3VsdCA9IGNyZWF0ZURpY3QoKTtcbiAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRQcyhyZXN1bHQsIFByb3BlcnRpZXMpO1xufTtcbiIsInZhciBhbk9iamVjdCAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpXG4gICwgdG9QcmltaXRpdmUgICAgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKVxuICAsIGRQICAgICAgICAgICAgID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xuXG5leHBvcnRzLmYgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnR5IDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcyl7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZihJRThfRE9NX0RFRklORSl0cnkge1xuICAgIHJldHVybiBkUChPLCBQLCBBdHRyaWJ1dGVzKTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxuICBpZignZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcbiAgaWYoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKU9bUF0gPSBBdHRyaWJ1dGVzLnZhbHVlO1xuICByZXR1cm4gTztcbn07IiwidmFyIGRQICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgZ2V0S2V5cyAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcyl7XG4gIGFuT2JqZWN0KE8pO1xuICB2YXIga2V5cyAgID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKVxuICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAsIGkgPSAwXG4gICAgLCBQO1xuICB3aGlsZShsZW5ndGggPiBpKWRQLmYoTywgUCA9IGtleXNbaSsrXSwgUHJvcGVydGllc1tQXSk7XG4gIHJldHVybiBPO1xufTsiLCIvLyBGb3JjZWQgcmVwbGFjZW1lbnQgcHJvdG90eXBlIGFjY2Vzc29ycyBtZXRob2RzXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKXx8ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHZhciBLID0gTWF0aC5yYW5kb20oKTtcbiAgLy8gSW4gRkYgdGhyb3dzIG9ubHkgZGVmaW5lIG1ldGhvZHNcbiAgX19kZWZpbmVTZXR0ZXJfXy5jYWxsKG51bGwsIEssIGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovfSk7XG4gIGRlbGV0ZSByZXF1aXJlKCcuL19nbG9iYWwnKVtLXTtcbn0pOyIsInZhciBwSUUgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKVxuICAsIGNyZWF0ZURlc2MgICAgID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpXG4gICwgdG9JT2JqZWN0ICAgICAgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXG4gICwgaGFzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKVxuICAsIGdPUEQgICAgICAgICAgID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCl7XG4gIE8gPSB0b0lPYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgaWYoSUU4X0RPTV9ERUZJTkUpdHJ5IHtcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxuICBpZihoYXMoTywgUCkpcmV0dXJuIGNyZWF0ZURlc2MoIXBJRS5mLmNhbGwoTywgUCksIE9bUF0pO1xufTsiLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXG4gICwgZ09QTiAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mXG4gICwgdG9TdHJpbmcgID0ge30udG9TdHJpbmc7XG5cbnZhciB3aW5kb3dOYW1lcyA9IHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgd2luZG93ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzXG4gID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMod2luZG93KSA6IFtdO1xuXG52YXIgZ2V0V2luZG93TmFtZXMgPSBmdW5jdGlvbihpdCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGdPUE4oaXQpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCl7XG4gIHJldHVybiB3aW5kb3dOYW1lcyAmJiB0b1N0cmluZy5jYWxsKGl0KSA9PSAnW29iamVjdCBXaW5kb3ddJyA/IGdldFdpbmRvd05hbWVzKGl0KSA6IGdPUE4odG9JT2JqZWN0KGl0KSk7XG59O1xuIiwiLy8gMTkuMS4yLjcgLyAxNS4yLjMuNCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxudmFyICRrZXlzICAgICAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cy1pbnRlcm5hbCcpXG4gICwgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKS5jb25jYXQoJ2xlbmd0aCcsICdwcm90b3R5cGUnKTtcblxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgfHwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhPKXtcbiAgcmV0dXJuICRrZXlzKE8sIGhpZGRlbktleXMpO1xufTsiLCJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzOyIsIi8vIDE5LjEuMi45IC8gMTUuMi4zLjIgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgaGFzICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIHRvT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0JylcbiAgLCBJRV9QUk9UTyAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKVxuICAsIE9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24oTyl7XG4gIE8gPSB0b09iamVjdChPKTtcbiAgaWYoaGFzKE8sIElFX1BST1RPKSlyZXR1cm4gT1tJRV9QUk9UT107XG4gIGlmKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3Ipe1xuICAgIHJldHVybiBPLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcbn07IiwidmFyIGhhcyAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgdG9JT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXG4gICwgYXJyYXlJbmRleE9mID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKShmYWxzZSlcbiAgLCBJRV9QUk9UTyAgICAgPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob2JqZWN0LCBuYW1lcyl7XG4gIHZhciBPICAgICAgPSB0b0lPYmplY3Qob2JqZWN0KVxuICAgICwgaSAgICAgID0gMFxuICAgICwgcmVzdWx0ID0gW11cbiAgICAsIGtleTtcbiAgZm9yKGtleSBpbiBPKWlmKGtleSAhPSBJRV9QUk9UTyloYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpaWYoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKXtcbiAgICB+YXJyYXlJbmRleE9mKHJlc3VsdCwga2V5KSB8fCByZXN1bHQucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59OyIsIi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxudmFyICRrZXlzICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKVxuICAsIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMoTyl7XG4gIHJldHVybiAka2V5cyhPLCBlbnVtQnVnS2V5cyk7XG59OyIsImV4cG9ydHMuZiA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlOyIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGNvcmUgICAgPSByZXF1aXJlKCcuL19jb3JlJylcbiAgLCBmYWlscyAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBleGVjKXtcbiAgdmFyIGZuICA9IChjb3JlLk9iamVjdCB8fCB7fSlbS0VZXSB8fCBPYmplY3RbS0VZXVxuICAgICwgZXhwID0ge307XG4gIGV4cFtLRVldID0gZXhlYyhmbik7XG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24oKXsgZm4oMSk7IH0pLCAnT2JqZWN0JywgZXhwKTtcbn07IiwidmFyIGdldEtleXMgICA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJylcbiAgLCB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCBpc0VudW0gICAgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXNFbnRyaWVzKXtcbiAgcmV0dXJuIGZ1bmN0aW9uKGl0KXtcbiAgICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KGl0KVxuICAgICAgLCBrZXlzICAgPSBnZXRLZXlzKE8pXG4gICAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG4gICAgICAsIGkgICAgICA9IDBcbiAgICAgICwgcmVzdWx0ID0gW11cbiAgICAgICwga2V5O1xuICAgIHdoaWxlKGxlbmd0aCA+IGkpaWYoaXNFbnVtLmNhbGwoTywga2V5ID0ga2V5c1tpKytdKSl7XG4gICAgICByZXN1bHQucHVzaChpc0VudHJpZXMgPyBba2V5LCBPW2tleV1dIDogT1trZXldKTtcbiAgICB9IHJldHVybiByZXN1bHQ7XG4gIH07XG59OyIsIi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbnZhciBnT1BOICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJylcbiAgLCBnT1BTICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJylcbiAgLCBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgUmVmbGVjdCAgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0ICYmIFJlZmxlY3Qub3duS2V5cyB8fCBmdW5jdGlvbiBvd25LZXlzKGl0KXtcbiAgdmFyIGtleXMgICAgICAgPSBnT1BOLmYoYW5PYmplY3QoaXQpKVxuICAgICwgZ2V0U3ltYm9scyA9IGdPUFMuZjtcbiAgcmV0dXJuIGdldFN5bWJvbHMgPyBrZXlzLmNvbmNhdChnZXRTeW1ib2xzKGl0KSkgOiBrZXlzO1xufTsiLCJ2YXIgJHBhcnNlRmxvYXQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUZsb2F0XG4gICwgJHRyaW0gICAgICAgPSByZXF1aXJlKCcuL19zdHJpbmctdHJpbScpLnRyaW07XG5cbm1vZHVsZS5leHBvcnRzID0gMSAvICRwYXJzZUZsb2F0KHJlcXVpcmUoJy4vX3N0cmluZy13cycpICsgJy0wJykgIT09IC1JbmZpbml0eSA/IGZ1bmN0aW9uIHBhcnNlRmxvYXQoc3RyKXtcbiAgdmFyIHN0cmluZyA9ICR0cmltKFN0cmluZyhzdHIpLCAzKVxuICAgICwgcmVzdWx0ID0gJHBhcnNlRmxvYXQoc3RyaW5nKTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gMCAmJiBzdHJpbmcuY2hhckF0KDApID09ICctJyA/IC0wIDogcmVzdWx0O1xufSA6ICRwYXJzZUZsb2F0OyIsInZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUludFxuICAsICR0cmltICAgICA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbVxuICAsIHdzICAgICAgICA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpXG4gICwgaGV4ICAgICAgID0gL15bXFwtK10/MFt4WF0vO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICRwYXJzZUludCh3cyArICcwOCcpICE9PSA4IHx8ICRwYXJzZUludCh3cyArICcweDE2JykgIT09IDIyID8gZnVuY3Rpb24gcGFyc2VJbnQoc3RyLCByYWRpeCl7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHJldHVybiAkcGFyc2VJbnQoc3RyaW5nLCAocmFkaXggPj4+IDApIHx8IChoZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xufSA6ICRwYXJzZUludDsiLCIndXNlIHN0cmljdCc7XG52YXIgcGF0aCAgICAgID0gcmVxdWlyZSgnLi9fcGF0aCcpXG4gICwgaW52b2tlICAgID0gcmVxdWlyZSgnLi9faW52b2tlJylcbiAgLCBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKC8qIC4uLnBhcmdzICovKXtcbiAgdmFyIGZuICAgICA9IGFGdW5jdGlvbih0aGlzKVxuICAgICwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICwgcGFyZ3MgID0gQXJyYXkobGVuZ3RoKVxuICAgICwgaSAgICAgID0gMFxuICAgICwgXyAgICAgID0gcGF0aC5fXG4gICAgLCBob2xkZXIgPSBmYWxzZTtcbiAgd2hpbGUobGVuZ3RoID4gaSlpZigocGFyZ3NbaV0gPSBhcmd1bWVudHNbaSsrXSkgPT09IF8paG9sZGVyID0gdHJ1ZTtcbiAgcmV0dXJuIGZ1bmN0aW9uKC8qIC4uLmFyZ3MgKi8pe1xuICAgIHZhciB0aGF0ID0gdGhpc1xuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCBqID0gMCwgayA9IDAsIGFyZ3M7XG4gICAgaWYoIWhvbGRlciAmJiAhYUxlbilyZXR1cm4gaW52b2tlKGZuLCBwYXJncywgdGhhdCk7XG4gICAgYXJncyA9IHBhcmdzLnNsaWNlKCk7XG4gICAgaWYoaG9sZGVyKWZvcig7bGVuZ3RoID4gajsgaisrKWlmKGFyZ3Nbal0gPT09IF8pYXJnc1tqXSA9IGFyZ3VtZW50c1trKytdO1xuICAgIHdoaWxlKGFMZW4gPiBrKWFyZ3MucHVzaChhcmd1bWVudHNbaysrXSk7XG4gICAgcmV0dXJuIGludm9rZShmbiwgYXJncywgdGhhdCk7XG4gIH07XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihiaXRtYXAsIHZhbHVlKXtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlICA6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlICAgIDogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZSAgICAgICA6IHZhbHVlXG4gIH07XG59OyIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRhcmdldCwgc3JjLCBzYWZlKXtcbiAgZm9yKHZhciBrZXkgaW4gc3JjKXJlZGVmaW5lKHRhcmdldCwga2V5LCBzcmNba2V5XSwgc2FmZSk7XG4gIHJldHVybiB0YXJnZXQ7XG59OyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGhpZGUgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIGhhcyAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgU1JDICAgICAgID0gcmVxdWlyZSgnLi9fdWlkJykoJ3NyYycpXG4gICwgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJ1xuICAsICR0b1N0cmluZyA9IEZ1bmN0aW9uW1RPX1NUUklOR11cbiAgLCBUUEwgICAgICAgPSAoJycgKyAkdG9TdHJpbmcpLnNwbGl0KFRPX1NUUklORyk7XG5cbnJlcXVpcmUoJy4vX2NvcmUnKS5pbnNwZWN0U291cmNlID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gJHRvU3RyaW5nLmNhbGwoaXQpO1xufTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTywga2V5LCB2YWwsIHNhZmUpe1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYoaXNGdW5jdGlvbiloYXModmFsLCAnbmFtZScpIHx8IGhpZGUodmFsLCAnbmFtZScsIGtleSk7XG4gIGlmKE9ba2V5XSA9PT0gdmFsKXJldHVybjtcbiAgaWYoaXNGdW5jdGlvbiloYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYoTyA9PT0gZ2xvYmFsKXtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSB7XG4gICAgaWYoIXNhZmUpe1xuICAgICAgZGVsZXRlIE9ba2V5XTtcbiAgICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZihPW2tleV0pT1trZXldID0gdmFsO1xuICAgICAgZWxzZSBoaWRlKE8sIGtleSwgdmFsKTtcbiAgICB9XG4gIH1cbi8vIGFkZCBmYWtlIEZ1bmN0aW9uI3RvU3RyaW5nIGZvciBjb3JyZWN0IHdvcmsgd3JhcHBlZCBtZXRob2RzIC8gY29uc3RydWN0b3JzIHdpdGggbWV0aG9kcyBsaWtlIExvRGFzaCBpc05hdGl2ZVxufSkoRnVuY3Rpb24ucHJvdG90eXBlLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCl7XG4gIHJldHVybiB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nICYmIHRoaXNbU1JDXSB8fCAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbn0pOyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ocmVnRXhwLCByZXBsYWNlKXtcbiAgdmFyIHJlcGxhY2VyID0gcmVwbGFjZSA9PT0gT2JqZWN0KHJlcGxhY2UpID8gZnVuY3Rpb24ocGFydCl7XG4gICAgcmV0dXJuIHJlcGxhY2VbcGFydF07XG4gIH0gOiByZXBsYWNlO1xuICByZXR1cm4gZnVuY3Rpb24oaXQpe1xuICAgIHJldHVybiBTdHJpbmcoaXQpLnJlcGxhY2UocmVnRXhwLCByZXBsYWNlcik7XG4gIH07XG59OyIsIi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSl7XG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTsiLCIvLyBXb3JrcyB3aXRoIF9fcHJvdG9fXyBvbmx5LiBPbGQgdjggY2FuJ3Qgd29yayB3aXRoIG51bGwgcHJvdG8gb2JqZWN0cy5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgY2hlY2sgPSBmdW5jdGlvbihPLCBwcm90byl7XG4gIGFuT2JqZWN0KE8pO1xuICBpZighaXNPYmplY3QocHJvdG8pICYmIHByb3RvICE9PSBudWxsKXRocm93IFR5cGVFcnJvcihwcm90byArIFwiOiBjYW4ndCBzZXQgYXMgcHJvdG90eXBlIVwiKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgKCdfX3Byb3RvX18nIGluIHt9ID8gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIGZ1bmN0aW9uKHRlc3QsIGJ1Z2d5LCBzZXQpe1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0ID0gcmVxdWlyZSgnLi9fY3R4JykoRnVuY3Rpb24uY2FsbCwgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQsIDIpO1xuICAgICAgICBzZXQodGVzdCwgW10pO1xuICAgICAgICBidWdneSA9ICEodGVzdCBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICAgIH0gY2F0Y2goZSl7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKXtcbiAgICAgICAgY2hlY2soTywgcHJvdG8pO1xuICAgICAgICBpZihidWdneSlPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBkUCAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpXG4gICwgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpXG4gICwgU1BFQ0lFUyAgICAgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKEtFWSl7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmKERFU0NSSVBUT1JTICYmIEMgJiYgIUNbU1BFQ0lFU10pZFAuZihDLCBTUEVDSUVTLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH1cbiAgfSk7XG59OyIsInZhciBkZWYgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgaGFzID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwgdGFnLCBzdGF0KXtcbiAgaWYoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSlkZWYoaXQsIFRBRywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZ30pO1xufTsiLCJ2YXIgc2hhcmVkID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ2tleXMnKVxuICAsIHVpZCAgICA9IHJlcXVpcmUoJy4vX3VpZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuICByZXR1cm4gc2hhcmVkW2tleV0gfHwgKHNoYXJlZFtrZXldID0gdWlkKGtleSkpO1xufTsiLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBTSEFSRUQgPSAnX19jb3JlLWpzX3NoYXJlZF9fJ1xuICAsIHN0b3JlICA9IGdsb2JhbFtTSEFSRURdIHx8IChnbG9iYWxbU0hBUkVEXSA9IHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB7fSk7XG59OyIsIi8vIDcuMy4yMCBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKVxudmFyIGFuT2JqZWN0ICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgU1BFQ0lFUyAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTywgRCl7XG4gIHZhciBDID0gYW5PYmplY3QoTykuY29uc3RydWN0b3IsIFM7XG4gIHJldHVybiBDID09PSB1bmRlZmluZWQgfHwgKFMgPSBhbk9iamVjdChDKVtTUEVDSUVTXSkgPT0gdW5kZWZpbmVkID8gRCA6IGFGdW5jdGlvbihTKTtcbn07IiwidmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihtZXRob2QsIGFyZyl7XG4gIHJldHVybiAhIW1ldGhvZCAmJiBmYWlscyhmdW5jdGlvbigpe1xuICAgIGFyZyA/IG1ldGhvZC5jYWxsKG51bGwsIGZ1bmN0aW9uKCl7fSwgMSkgOiBtZXRob2QuY2FsbChudWxsKTtcbiAgfSk7XG59OyIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJylcbiAgLCBkZWZpbmVkICAgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG4vLyB0cnVlICAtPiBTdHJpbmcjYXRcbi8vIGZhbHNlIC0+IFN0cmluZyNjb2RlUG9pbnRBdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihUT19TVFJJTkcpe1xuICByZXR1cm4gZnVuY3Rpb24odGhhdCwgcG9zKXtcbiAgICB2YXIgcyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKVxuICAgICAgLCBpID0gdG9JbnRlZ2VyKHBvcylcbiAgICAgICwgbCA9IHMubGVuZ3RoXG4gICAgICAsIGEsIGI7XG4gICAgaWYoaSA8IDAgfHwgaSA+PSBsKXJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcbiAgICBhID0gcy5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBhIDwgMHhkODAwIHx8IGEgPiAweGRiZmYgfHwgaSArIDEgPT09IGwgfHwgKGIgPSBzLmNoYXJDb2RlQXQoaSArIDEpKSA8IDB4ZGMwMCB8fCBiID4gMHhkZmZmXG4gICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxuICAgICAgOiBUT19TVFJJTkcgPyBzLnNsaWNlKGksIGkgKyAyKSA6IChhIC0gMHhkODAwIDw8IDEwKSArIChiIC0gMHhkYzAwKSArIDB4MTAwMDA7XG4gIH07XG59OyIsIi8vIGhlbHBlciBmb3IgU3RyaW5nI3tzdGFydHNXaXRoLCBlbmRzV2l0aCwgaW5jbHVkZXN9XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKVxuICAsIGRlZmluZWQgID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRoYXQsIHNlYXJjaFN0cmluZywgTkFNRSl7XG4gIGlmKGlzUmVnRXhwKHNlYXJjaFN0cmluZykpdGhyb3cgVHlwZUVycm9yKCdTdHJpbmcjJyArIE5BTUUgKyBcIiBkb2Vzbid0IGFjY2VwdCByZWdleCFcIik7XG4gIHJldHVybiBTdHJpbmcoZGVmaW5lZCh0aGF0KSk7XG59OyIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBmYWlscyAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJylcbiAgLCBxdW90ICAgID0gL1wiL2c7XG4vLyBCLjIuMy4yLjEgQ3JlYXRlSFRNTChzdHJpbmcsIHRhZywgYXR0cmlidXRlLCB2YWx1ZSlcbnZhciBjcmVhdGVIVE1MID0gZnVuY3Rpb24oc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgdmFyIFMgID0gU3RyaW5nKGRlZmluZWQoc3RyaW5nKSlcbiAgICAsIHAxID0gJzwnICsgdGFnO1xuICBpZihhdHRyaWJ1dGUgIT09ICcnKXAxICs9ICcgJyArIGF0dHJpYnV0ZSArICc9XCInICsgU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHF1b3QsICcmcXVvdDsnKSArICdcIic7XG4gIHJldHVybiBwMSArICc+JyArIFMgKyAnPC8nICsgdGFnICsgJz4nO1xufTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTkFNRSwgZXhlYyl7XG4gIHZhciBPID0ge307XG4gIE9bTkFNRV0gPSBleGVjKGNyZWF0ZUhUTUwpO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZhaWxzKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHRlc3QgPSAnJ1tOQU1FXSgnXCInKTtcbiAgICByZXR1cm4gdGVzdCAhPT0gdGVzdC50b0xvd2VyQ2FzZSgpIHx8IHRlc3Quc3BsaXQoJ1wiJykubGVuZ3RoID4gMztcbiAgfSksICdTdHJpbmcnLCBPKTtcbn07IiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICwgcmVwZWF0ICAgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0JylcbiAgLCBkZWZpbmVkICA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0aGF0LCBtYXhMZW5ndGgsIGZpbGxTdHJpbmcsIGxlZnQpe1xuICB2YXIgUyAgICAgICAgICAgID0gU3RyaW5nKGRlZmluZWQodGhhdCkpXG4gICAgLCBzdHJpbmdMZW5ndGggPSBTLmxlbmd0aFxuICAgICwgZmlsbFN0ciAgICAgID0gZmlsbFN0cmluZyA9PT0gdW5kZWZpbmVkID8gJyAnIDogU3RyaW5nKGZpbGxTdHJpbmcpXG4gICAgLCBpbnRNYXhMZW5ndGggPSB0b0xlbmd0aChtYXhMZW5ndGgpO1xuICBpZihpbnRNYXhMZW5ndGggPD0gc3RyaW5nTGVuZ3RoIHx8IGZpbGxTdHIgPT0gJycpcmV0dXJuIFM7XG4gIHZhciBmaWxsTGVuID0gaW50TWF4TGVuZ3RoIC0gc3RyaW5nTGVuZ3RoXG4gICAgLCBzdHJpbmdGaWxsZXIgPSByZXBlYXQuY2FsbChmaWxsU3RyLCBNYXRoLmNlaWwoZmlsbExlbiAvIGZpbGxTdHIubGVuZ3RoKSk7XG4gIGlmKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKXN0cmluZ0ZpbGxlciA9IHN0cmluZ0ZpbGxlci5zbGljZSgwLCBmaWxsTGVuKTtcbiAgcmV0dXJuIGxlZnQgPyBzdHJpbmdGaWxsZXIgKyBTIDogUyArIHN0cmluZ0ZpbGxlcjtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgZGVmaW5lZCAgID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcGVhdChjb3VudCl7XG4gIHZhciBzdHIgPSBTdHJpbmcoZGVmaW5lZCh0aGlzKSlcbiAgICAsIHJlcyA9ICcnXG4gICAgLCBuICAgPSB0b0ludGVnZXIoY291bnQpO1xuICBpZihuIDwgMCB8fCBuID09IEluZmluaXR5KXRocm93IFJhbmdlRXJyb3IoXCJDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZVwiKTtcbiAgZm9yKDtuID4gMDsgKG4gPj4+PSAxKSAmJiAoc3RyICs9IHN0cikpaWYobiAmIDEpcmVzICs9IHN0cjtcbiAgcmV0dXJuIHJlcztcbn07IiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJylcbiAgLCBmYWlscyAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsIHNwYWNlcyAgPSByZXF1aXJlKCcuL19zdHJpbmctd3MnKVxuICAsIHNwYWNlICAgPSAnWycgKyBzcGFjZXMgKyAnXSdcbiAgLCBub24gICAgID0gJ1xcdTIwMGJcXHUwMDg1J1xuICAsIGx0cmltICAgPSBSZWdFeHAoJ14nICsgc3BhY2UgKyBzcGFjZSArICcqJylcbiAgLCBydHJpbSAgID0gUmVnRXhwKHNwYWNlICsgc3BhY2UgKyAnKiQnKTtcblxudmFyIGV4cG9ydGVyID0gZnVuY3Rpb24oS0VZLCBleGVjLCBBTElBUyl7XG4gIHZhciBleHAgICA9IHt9O1xuICB2YXIgRk9SQ0UgPSBmYWlscyhmdW5jdGlvbigpe1xuICAgIHJldHVybiAhIXNwYWNlc1tLRVldKCkgfHwgbm9uW0tFWV0oKSAhPSBub247XG4gIH0pO1xuICB2YXIgZm4gPSBleHBbS0VZXSA9IEZPUkNFID8gZXhlYyh0cmltKSA6IHNwYWNlc1tLRVldO1xuICBpZihBTElBUylleHBbQUxJQVNdID0gZm47XG4gICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0UsICdTdHJpbmcnLCBleHApO1xufTtcblxuLy8gMSAtPiBTdHJpbmcjdHJpbUxlZnRcbi8vIDIgLT4gU3RyaW5nI3RyaW1SaWdodFxuLy8gMyAtPiBTdHJpbmcjdHJpbVxudmFyIHRyaW0gPSBleHBvcnRlci50cmltID0gZnVuY3Rpb24oc3RyaW5nLCBUWVBFKXtcbiAgc3RyaW5nID0gU3RyaW5nKGRlZmluZWQoc3RyaW5nKSk7XG4gIGlmKFRZUEUgJiAxKXN0cmluZyA9IHN0cmluZy5yZXBsYWNlKGx0cmltLCAnJyk7XG4gIGlmKFRZUEUgJiAyKXN0cmluZyA9IHN0cmluZy5yZXBsYWNlKHJ0cmltLCAnJyk7XG4gIHJldHVybiBzdHJpbmc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydGVyOyIsIm1vZHVsZS5leHBvcnRzID0gJ1xceDA5XFx4MEFcXHgwQlxceDBDXFx4MERcXHgyMFxceEEwXFx1MTY4MFxcdTE4MEVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzJyArXG4gICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOFxcdTIwMjlcXHVGRUZGJzsiLCJ2YXIgY3R4ICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBpbnZva2UgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19pbnZva2UnKVxuICAsIGh0bWwgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2h0bWwnKVxuICAsIGNlbCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKVxuICAsIGdsb2JhbCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBzZXRUYXNrICAgICAgICAgICAgPSBnbG9iYWwuc2V0SW1tZWRpYXRlXG4gICwgY2xlYXJUYXNrICAgICAgICAgID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlXG4gICwgTWVzc2FnZUNoYW5uZWwgICAgID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsXG4gICwgY291bnRlciAgICAgICAgICAgID0gMFxuICAsIHF1ZXVlICAgICAgICAgICAgICA9IHt9XG4gICwgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSdcbiAgLCBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbigpe1xuICB2YXIgaWQgPSArdGhpcztcbiAgaWYocXVldWUuaGFzT3duUHJvcGVydHkoaWQpKXtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQpe1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZighc2V0VGFzayB8fCAhY2xlYXJUYXNrKXtcbiAgc2V0VGFzayA9IGZ1bmN0aW9uIHNldEltbWVkaWF0ZShmbil7XG4gICAgdmFyIGFyZ3MgPSBbXSwgaSA9IDE7XG4gICAgd2hpbGUoYXJndW1lbnRzLmxlbmd0aCA+IGkpYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICBxdWV1ZVsrK2NvdW50ZXJdID0gZnVuY3Rpb24oKXtcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCl7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmKHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJyl7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGN0eChydW4sIGlkLCAxKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYoTWVzc2FnZUNoYW5uZWwpe1xuICAgIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWw7XG4gICAgcG9ydCAgICA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZihnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lciAmJiB0eXBlb2YgcG9zdE1lc3NhZ2UgPT0gJ2Z1bmN0aW9uJyAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKGlkICsgJycsICcqJyk7XG4gICAgfTtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RlbmVyLCBmYWxzZSk7XG4gIC8vIElFOC1cbiAgfSBlbHNlIGlmKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjZWwoJ3NjcmlwdCcpKXtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgICAgIHJ1bi5jYWxsKGlkKTtcbiAgICAgIH07XG4gICAgfTtcbiAgLy8gUmVzdCBvbGQgYnJvd3NlcnNcbiAgfSBlbHNlIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiAgIHNldFRhc2ssXG4gIGNsZWFyOiBjbGVhclRhc2tcbn07IiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAsIG1heCAgICAgICA9IE1hdGgubWF4XG4gICwgbWluICAgICAgID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGluZGV4LCBsZW5ndGgpe1xuICBpbmRleCA9IHRvSW50ZWdlcihpbmRleCk7XG4gIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xufTsiLCIvLyA3LjEuNCBUb0ludGVnZXJcbnZhciBjZWlsICA9IE1hdGguY2VpbFxuICAsIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXNOYU4oaXQgPSAraXQpID8gMCA6IChpdCA+IDAgPyBmbG9vciA6IGNlaWwpKGl0KTtcbn07IiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKVxuICAsIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTsiLCIvLyA3LjEuMTUgVG9MZW5ndGhcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJylcbiAgLCBtaW4gICAgICAgPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgPiAwID8gbWluKHRvSW50ZWdlcihpdCksIDB4MWZmZmZmZmZmZmZmZmYpIDogMDsgLy8gcG93KDIsIDUzKSAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTsiLCIvLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07IiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwgUyl7XG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIGl0O1xuICB2YXIgZm4sIHZhbDtcbiAgaWYoUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICBpZih0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG4gIGlmKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG4gIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNvbnZlcnQgb2JqZWN0IHRvIHByaW1pdGl2ZSB2YWx1ZVwiKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuaWYocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSl7XG4gIHZhciBMSUJSQVJZICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbGlicmFyeScpXG4gICAgLCBnbG9iYWwgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgICAsIGZhaWxzICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19mYWlscycpXG4gICAgLCAkZXhwb3J0ICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgICAsICR0eXBlZCAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL190eXBlZCcpXG4gICAgLCAkYnVmZmVyICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fdHlwZWQtYnVmZmVyJylcbiAgICAsIGN0eCAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAgICwgYW5JbnN0YW5jZSAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJylcbiAgICAsIHByb3BlcnR5RGVzYyAgICAgICAgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJylcbiAgICAsIGhpZGUgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgICAsIHJlZGVmaW5lQWxsICAgICAgICAgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKVxuICAgICwgdG9JbnRlZ2VyICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAgICwgdG9MZW5ndGggICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICAgLCB0b0luZGV4ICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKVxuICAgICwgdG9QcmltaXRpdmUgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXG4gICAgLCBoYXMgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgICAsIHNhbWUgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19zYW1lLXZhbHVlJylcbiAgICAsIGNsYXNzb2YgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19jbGFzc29mJylcbiAgICAsIGlzT2JqZWN0ICAgICAgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAgICwgdG9PYmplY3QgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICAgLCBpc0FycmF5SXRlciAgICAgICAgID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpXG4gICAgLCBjcmVhdGUgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpXG4gICAgLCBnZXRQcm90b3R5cGVPZiAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpXG4gICAgLCBnT1BOICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mXG4gICAgLCBnZXRJdGVyRm4gICAgICAgICAgID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKVxuICAgICwgdWlkICAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3VpZCcpXG4gICAgLCB3a3MgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fd2tzJylcbiAgICAsIGNyZWF0ZUFycmF5TWV0aG9kICAgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJylcbiAgICAsIGNyZWF0ZUFycmF5SW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpXG4gICAgLCBzcGVjaWVzQ29uc3RydWN0b3IgID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpXG4gICAgLCBBcnJheUl0ZXJhdG9ycyAgICAgID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKVxuICAgICwgSXRlcmF0b3JzICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICAgLCAkaXRlckRldGVjdCAgICAgICAgID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKVxuICAgICwgc2V0U3BlY2llcyAgICAgICAgICA9IHJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJylcbiAgICAsIGFycmF5RmlsbCAgICAgICAgICAgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJylcbiAgICAsIGFycmF5Q29weVdpdGhpbiAgICAgPSByZXF1aXJlKCcuL19hcnJheS1jb3B5LXdpdGhpbicpXG4gICAgLCAkRFAgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgICAsICRHT1BEICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpXG4gICAgLCBkUCAgICAgICAgICAgICAgICAgID0gJERQLmZcbiAgICAsIGdPUEQgICAgICAgICAgICAgICAgPSAkR09QRC5mXG4gICAgLCBSYW5nZUVycm9yICAgICAgICAgID0gZ2xvYmFsLlJhbmdlRXJyb3JcbiAgICAsIFR5cGVFcnJvciAgICAgICAgICAgPSBnbG9iYWwuVHlwZUVycm9yXG4gICAgLCBVaW50OEFycmF5ICAgICAgICAgID0gZ2xvYmFsLlVpbnQ4QXJyYXlcbiAgICAsIEFSUkFZX0JVRkZFUiAgICAgICAgPSAnQXJyYXlCdWZmZXInXG4gICAgLCBTSEFSRURfQlVGRkVSICAgICAgID0gJ1NoYXJlZCcgKyBBUlJBWV9CVUZGRVJcbiAgICAsIEJZVEVTX1BFUl9FTEVNRU5UICAgPSAnQllURVNfUEVSX0VMRU1FTlQnXG4gICAgLCBQUk9UT1RZUEUgICAgICAgICAgID0gJ3Byb3RvdHlwZSdcbiAgICAsIEFycmF5UHJvdG8gICAgICAgICAgPSBBcnJheVtQUk9UT1RZUEVdXG4gICAgLCAkQXJyYXlCdWZmZXIgICAgICAgID0gJGJ1ZmZlci5BcnJheUJ1ZmZlclxuICAgICwgJERhdGFWaWV3ICAgICAgICAgICA9ICRidWZmZXIuRGF0YVZpZXdcbiAgICAsIGFycmF5Rm9yRWFjaCAgICAgICAgPSBjcmVhdGVBcnJheU1ldGhvZCgwKVxuICAgICwgYXJyYXlGaWx0ZXIgICAgICAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDIpXG4gICAgLCBhcnJheVNvbWUgICAgICAgICAgID0gY3JlYXRlQXJyYXlNZXRob2QoMylcbiAgICAsIGFycmF5RXZlcnkgICAgICAgICAgPSBjcmVhdGVBcnJheU1ldGhvZCg0KVxuICAgICwgYXJyYXlGaW5kICAgICAgICAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpXG4gICAgLCBhcnJheUZpbmRJbmRleCAgICAgID0gY3JlYXRlQXJyYXlNZXRob2QoNilcbiAgICAsIGFycmF5SW5jbHVkZXMgICAgICAgPSBjcmVhdGVBcnJheUluY2x1ZGVzKHRydWUpXG4gICAgLCBhcnJheUluZGV4T2YgICAgICAgID0gY3JlYXRlQXJyYXlJbmNsdWRlcyhmYWxzZSlcbiAgICAsIGFycmF5VmFsdWVzICAgICAgICAgPSBBcnJheUl0ZXJhdG9ycy52YWx1ZXNcbiAgICAsIGFycmF5S2V5cyAgICAgICAgICAgPSBBcnJheUl0ZXJhdG9ycy5rZXlzXG4gICAgLCBhcnJheUVudHJpZXMgICAgICAgID0gQXJyYXlJdGVyYXRvcnMuZW50cmllc1xuICAgICwgYXJyYXlMYXN0SW5kZXhPZiAgICA9IEFycmF5UHJvdG8ubGFzdEluZGV4T2ZcbiAgICAsIGFycmF5UmVkdWNlICAgICAgICAgPSBBcnJheVByb3RvLnJlZHVjZVxuICAgICwgYXJyYXlSZWR1Y2VSaWdodCAgICA9IEFycmF5UHJvdG8ucmVkdWNlUmlnaHRcbiAgICAsIGFycmF5Sm9pbiAgICAgICAgICAgPSBBcnJheVByb3RvLmpvaW5cbiAgICAsIGFycmF5U29ydCAgICAgICAgICAgPSBBcnJheVByb3RvLnNvcnRcbiAgICAsIGFycmF5U2xpY2UgICAgICAgICAgPSBBcnJheVByb3RvLnNsaWNlXG4gICAgLCBhcnJheVRvU3RyaW5nICAgICAgID0gQXJyYXlQcm90by50b1N0cmluZ1xuICAgICwgYXJyYXlUb0xvY2FsZVN0cmluZyA9IEFycmF5UHJvdG8udG9Mb2NhbGVTdHJpbmdcbiAgICAsIElURVJBVE9SICAgICAgICAgICAgPSB3a3MoJ2l0ZXJhdG9yJylcbiAgICAsIFRBRyAgICAgICAgICAgICAgICAgPSB3a3MoJ3RvU3RyaW5nVGFnJylcbiAgICAsIFRZUEVEX0NPTlNUUlVDVE9SICAgPSB1aWQoJ3R5cGVkX2NvbnN0cnVjdG9yJylcbiAgICAsIERFRl9DT05TVFJVQ1RPUiAgICAgPSB1aWQoJ2RlZl9jb25zdHJ1Y3RvcicpXG4gICAgLCBBTExfQ09OU1RSVUNUT1JTICAgID0gJHR5cGVkLkNPTlNUUlxuICAgICwgVFlQRURfQVJSQVkgICAgICAgICA9ICR0eXBlZC5UWVBFRFxuICAgICwgVklFVyAgICAgICAgICAgICAgICA9ICR0eXBlZC5WSUVXXG4gICAgLCBXUk9OR19MRU5HVEggICAgICAgID0gJ1dyb25nIGxlbmd0aCEnO1xuXG4gIHZhciAkbWFwID0gY3JlYXRlQXJyYXlNZXRob2QoMSwgZnVuY3Rpb24oTywgbGVuZ3RoKXtcbiAgICByZXR1cm4gYWxsb2NhdGUoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxlbmd0aCk7XG4gIH0pO1xuXG4gIHZhciBMSVRUTEVfRU5ESUFOID0gZmFpbHMoZnVuY3Rpb24oKXtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQxNkFycmF5KFsxXSkuYnVmZmVyKVswXSA9PT0gMTtcbiAgfSk7XG5cbiAgdmFyIEZPUkNFRF9TRVQgPSAhIVVpbnQ4QXJyYXkgJiYgISFVaW50OEFycmF5W1BST1RPVFlQRV0uc2V0ICYmIGZhaWxzKGZ1bmN0aW9uKCl7XG4gICAgbmV3IFVpbnQ4QXJyYXkoMSkuc2V0KHt9KTtcbiAgfSk7XG5cbiAgdmFyIHN0cmljdFRvTGVuZ3RoID0gZnVuY3Rpb24oaXQsIFNBTUUpe1xuICAgIGlmKGl0ID09PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgdmFyIG51bWJlciA9ICtpdFxuICAgICAgLCBsZW5ndGggPSB0b0xlbmd0aChpdCk7XG4gICAgaWYoU0FNRSAmJiAhc2FtZShudW1iZXIsIGxlbmd0aCkpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgIHJldHVybiBsZW5ndGg7XG4gIH07XG5cbiAgdmFyIHRvT2Zmc2V0ID0gZnVuY3Rpb24oaXQsIEJZVEVTKXtcbiAgICB2YXIgb2Zmc2V0ID0gdG9JbnRlZ2VyKGl0KTtcbiAgICBpZihvZmZzZXQgPCAwIHx8IG9mZnNldCAlIEJZVEVTKXRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG9mZnNldCEnKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9O1xuXG4gIHZhciB2YWxpZGF0ZSA9IGZ1bmN0aW9uKGl0KXtcbiAgICBpZihpc09iamVjdChpdCkgJiYgVFlQRURfQVJSQVkgaW4gaXQpcmV0dXJuIGl0O1xuICAgIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgdHlwZWQgYXJyYXkhJyk7XG4gIH07XG5cbiAgdmFyIGFsbG9jYXRlID0gZnVuY3Rpb24oQywgbGVuZ3RoKXtcbiAgICBpZighKGlzT2JqZWN0KEMpICYmIFRZUEVEX0NPTlNUUlVDVE9SIGluIEMpKXtcbiAgICAgIHRocm93IFR5cGVFcnJvcignSXQgaXMgbm90IGEgdHlwZWQgYXJyYXkgY29uc3RydWN0b3IhJyk7XG4gICAgfSByZXR1cm4gbmV3IEMobGVuZ3RoKTtcbiAgfTtcblxuICB2YXIgc3BlY2llc0Zyb21MaXN0ID0gZnVuY3Rpb24oTywgbGlzdCl7XG4gICAgcmV0dXJuIGZyb21MaXN0KHNwZWNpZXNDb25zdHJ1Y3RvcihPLCBPW0RFRl9DT05TVFJVQ1RPUl0pLCBsaXN0KTtcbiAgfTtcblxuICB2YXIgZnJvbUxpc3QgPSBmdW5jdGlvbihDLCBsaXN0KXtcbiAgICB2YXIgaW5kZXggID0gMFxuICAgICAgLCBsZW5ndGggPSBsaXN0Lmxlbmd0aFxuICAgICAgLCByZXN1bHQgPSBhbGxvY2F0ZShDLCBsZW5ndGgpO1xuICAgIHdoaWxlKGxlbmd0aCA+IGluZGV4KXJlc3VsdFtpbmRleF0gPSBsaXN0W2luZGV4KytdO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGFkZEdldHRlciA9IGZ1bmN0aW9uKGl0LCBrZXksIGludGVybmFsKXtcbiAgICBkUChpdCwga2V5LCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gdGhpcy5fZFtpbnRlcm5hbF07IH19KTtcbiAgfTtcblxuICB2YXIgJGZyb20gPSBmdW5jdGlvbiBmcm9tKHNvdXJjZSAvKiwgbWFwZm4sIHRoaXNBcmcgKi8pe1xuICAgIHZhciBPICAgICAgID0gdG9PYmplY3Qoc291cmNlKVxuICAgICAgLCBhTGVuICAgID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCBtYXBmbiAgID0gYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWRcbiAgICAgICwgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWRcbiAgICAgICwgaXRlckZuICA9IGdldEl0ZXJGbihPKVxuICAgICAgLCBpLCBsZW5ndGgsIHZhbHVlcywgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZihpdGVyRm4gIT0gdW5kZWZpbmVkICYmICFpc0FycmF5SXRlcihpdGVyRm4pKXtcbiAgICAgIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCB2YWx1ZXMgPSBbXSwgaSA9IDA7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaSsrKXtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgICB9IE8gPSB2YWx1ZXM7XG4gICAgfVxuICAgIGlmKG1hcHBpbmcgJiYgYUxlbiA+IDIpbWFwZm4gPSBjdHgobWFwZm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgZm9yKGkgPSAwLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCksIHJlc3VsdCA9IGFsbG9jYXRlKHRoaXMsIGxlbmd0aCk7IGxlbmd0aCA+IGk7IGkrKyl7XG4gICAgICByZXN1bHRbaV0gPSBtYXBwaW5nID8gbWFwZm4oT1tpXSwgaSkgOiBPW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIHZhciAkb2YgPSBmdW5jdGlvbiBvZigvKi4uLml0ZW1zKi8pe1xuICAgIHZhciBpbmRleCAgPSAwXG4gICAgICAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgICwgcmVzdWx0ID0gYWxsb2NhdGUodGhpcywgbGVuZ3RoKTtcbiAgICB3aGlsZShsZW5ndGggPiBpbmRleClyZXN1bHRbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4KytdO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gaU9TIFNhZmFyaSA2LnggZmFpbHMgaGVyZVxuICB2YXIgVE9fTE9DQUxFX0JVRyA9ICEhVWludDhBcnJheSAmJiBmYWlscyhmdW5jdGlvbigpeyBhcnJheVRvTG9jYWxlU3RyaW5nLmNhbGwobmV3IFVpbnQ4QXJyYXkoMSkpOyB9KTtcblxuICB2YXIgJHRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9Mb2NhbGVTdHJpbmcoKXtcbiAgICByZXR1cm4gYXJyYXlUb0xvY2FsZVN0cmluZy5hcHBseShUT19MT0NBTEVfQlVHID8gYXJyYXlTbGljZS5jYWxsKHZhbGlkYXRlKHRoaXMpKSA6IHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICB9O1xuXG4gIHZhciBwcm90byA9IHtcbiAgICBjb3B5V2l0aGluOiBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCwgc3RhcnQgLyosIGVuZCAqLyl7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5V2l0aGluLmNhbGwodmFsaWRhdGUodGhpcyksIHRhcmdldCwgc3RhcnQsIGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuIC8qLCB0aGlzQXJnICovKXtcbiAgICAgIHJldHVybiBhcnJheUV2ZXJ5KHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaWxsOiBmdW5jdGlvbiBmaWxsKHZhbHVlIC8qLCBzdGFydCwgZW5kICovKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5RmlsbC5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKGNhbGxiYWNrZm4gLyosIHRoaXNBcmcgKi8pe1xuICAgICAgcmV0dXJuIHNwZWNpZXNGcm9tTGlzdCh0aGlzLCBhcnJheUZpbHRlcih2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbixcbiAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpKTtcbiAgICB9LFxuICAgIGZpbmQ6IGZ1bmN0aW9uIGZpbmQocHJlZGljYXRlIC8qLCB0aGlzQXJnICovKXtcbiAgICAgIHJldHVybiBhcnJheUZpbmQodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZmluZEluZGV4OiBmdW5jdGlvbiBmaW5kSW5kZXgocHJlZGljYXRlIC8qLCB0aGlzQXJnICovKXtcbiAgICAgIHJldHVybiBhcnJheUZpbmRJbmRleCh2YWxpZGF0ZSh0aGlzKSwgcHJlZGljYXRlLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyosIHRoaXNBcmcgKi8pe1xuICAgICAgYXJyYXlGb3JFYWNoKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQgLyosIGZyb21JbmRleCAqLyl7XG4gICAgICByZXR1cm4gYXJyYXlJbmRleE9mKHZhbGlkYXRlKHRoaXMpLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoRWxlbWVudCAvKiwgZnJvbUluZGV4ICovKXtcbiAgICAgIHJldHVybiBhcnJheUluY2x1ZGVzKHZhbGlkYXRlKHRoaXMpLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcil7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUpvaW4uYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiwgZnJvbUluZGV4ICovKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5TGFzdEluZGV4T2YuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBtYXA6IGZ1bmN0aW9uIG1hcChtYXBmbiAvKiwgdGhpc0FyZyAqLyl7XG4gICAgICByZXR1cm4gJG1hcCh2YWxpZGF0ZSh0aGlzKSwgbWFwZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4gLyosIGluaXRpYWxWYWx1ZSAqLyl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZS5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuIC8qLCBpbml0aWFsVmFsdWUgKi8peyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlSZWR1Y2VSaWdodC5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHJldmVyc2U6IGZ1bmN0aW9uIHJldmVyc2UoKXtcbiAgICAgIHZhciB0aGF0ICAgPSB0aGlzXG4gICAgICAgICwgbGVuZ3RoID0gdmFsaWRhdGUodGhhdCkubGVuZ3RoXG4gICAgICAgICwgbWlkZGxlID0gTWF0aC5mbG9vcihsZW5ndGggLyAyKVxuICAgICAgICAsIGluZGV4ICA9IDBcbiAgICAgICAgLCB2YWx1ZTtcbiAgICAgIHdoaWxlKGluZGV4IDwgbWlkZGxlKXtcbiAgICAgICAgdmFsdWUgICAgICAgICA9IHRoYXRbaW5kZXhdO1xuICAgICAgICB0aGF0W2luZGV4KytdID0gdGhhdFstLWxlbmd0aF07XG4gICAgICAgIHRoYXRbbGVuZ3RoXSAgPSB2YWx1ZTtcbiAgICAgIH0gcmV0dXJuIHRoYXQ7XG4gICAgfSxcbiAgICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4gLyosIHRoaXNBcmcgKi8pe1xuICAgICAgcmV0dXJuIGFycmF5U29tZSh2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgc29ydDogZnVuY3Rpb24gc29ydChjb21wYXJlZm4pe1xuICAgICAgcmV0dXJuIGFycmF5U29ydC5jYWxsKHZhbGlkYXRlKHRoaXMpLCBjb21wYXJlZm4pO1xuICAgIH0sXG4gICAgc3ViYXJyYXk6IGZ1bmN0aW9uIHN1YmFycmF5KGJlZ2luLCBlbmQpe1xuICAgICAgdmFyIE8gICAgICA9IHZhbGlkYXRlKHRoaXMpXG4gICAgICAgICwgbGVuZ3RoID0gTy5sZW5ndGhcbiAgICAgICAgLCAkYmVnaW4gPSB0b0luZGV4KGJlZ2luLCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSkpKFxuICAgICAgICBPLmJ1ZmZlcixcbiAgICAgICAgTy5ieXRlT2Zmc2V0ICsgJGJlZ2luICogTy5CWVRFU19QRVJfRUxFTUVOVCxcbiAgICAgICAgdG9MZW5ndGgoKGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9JbmRleChlbmQsIGxlbmd0aCkpIC0gJGJlZ2luKVxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyICRzbGljZSA9IGZ1bmN0aW9uIHNsaWNlKHN0YXJ0LCBlbmQpe1xuICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlTbGljZS5jYWxsKHZhbGlkYXRlKHRoaXMpLCBzdGFydCwgZW5kKSk7XG4gIH07XG5cbiAgdmFyICRzZXQgPSBmdW5jdGlvbiBzZXQoYXJyYXlMaWtlIC8qLCBvZmZzZXQgKi8pe1xuICAgIHZhbGlkYXRlKHRoaXMpO1xuICAgIHZhciBvZmZzZXQgPSB0b09mZnNldChhcmd1bWVudHNbMV0sIDEpXG4gICAgICAsIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgICAsIHNyYyAgICA9IHRvT2JqZWN0KGFycmF5TGlrZSlcbiAgICAgICwgbGVuICAgID0gdG9MZW5ndGgoc3JjLmxlbmd0aClcbiAgICAgICwgaW5kZXggID0gMDtcbiAgICBpZihsZW4gKyBvZmZzZXQgPiBsZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgIHdoaWxlKGluZGV4IDwgbGVuKXRoaXNbb2Zmc2V0ICsgaW5kZXhdID0gc3JjW2luZGV4KytdO1xuICB9O1xuXG4gIHZhciAkaXRlcmF0b3JzID0ge1xuICAgIGVudHJpZXM6IGZ1bmN0aW9uIGVudHJpZXMoKXtcbiAgICAgIHJldHVybiBhcnJheUVudHJpZXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKCl7XG4gICAgICByZXR1cm4gYXJyYXlLZXlzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH0sXG4gICAgdmFsdWVzOiBmdW5jdGlvbiB2YWx1ZXMoKXtcbiAgICAgIHJldHVybiBhcnJheVZhbHVlcy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGlzVEFJbmRleCA9IGZ1bmN0aW9uKHRhcmdldCwga2V5KXtcbiAgICByZXR1cm4gaXNPYmplY3QodGFyZ2V0KVxuICAgICAgJiYgdGFyZ2V0W1RZUEVEX0FSUkFZXVxuICAgICAgJiYgdHlwZW9mIGtleSAhPSAnc3ltYm9sJ1xuICAgICAgJiYga2V5IGluIHRhcmdldFxuICAgICAgJiYgU3RyaW5nKCtrZXkpID09IFN0cmluZyhrZXkpO1xuICB9O1xuICB2YXIgJGdldERlc2MgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpe1xuICAgIHJldHVybiBpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgPyBwcm9wZXJ0eURlc2MoMiwgdGFyZ2V0W2tleV0pXG4gICAgICA6IGdPUEQodGFyZ2V0LCBrZXkpO1xuICB9O1xuICB2YXIgJHNldERlc2MgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzYyl7XG4gICAgaWYoaXNUQUluZGV4KHRhcmdldCwga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKSlcbiAgICAgICYmIGlzT2JqZWN0KGRlc2MpXG4gICAgICAmJiBoYXMoZGVzYywgJ3ZhbHVlJylcbiAgICAgICYmICFoYXMoZGVzYywgJ2dldCcpXG4gICAgICAmJiAhaGFzKGRlc2MsICdzZXQnKVxuICAgICAgLy8gVE9ETzogYWRkIHZhbGlkYXRpb24gZGVzY3JpcHRvciB3L28gY2FsbGluZyBhY2Nlc3NvcnNcbiAgICAgICYmICFkZXNjLmNvbmZpZ3VyYWJsZVxuICAgICAgJiYgKCFoYXMoZGVzYywgJ3dyaXRhYmxlJykgfHwgZGVzYy53cml0YWJsZSlcbiAgICAgICYmICghaGFzKGRlc2MsICdlbnVtZXJhYmxlJykgfHwgZGVzYy5lbnVtZXJhYmxlKVxuICAgICl7XG4gICAgICB0YXJnZXRba2V5XSA9IGRlc2MudmFsdWU7XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH0gZWxzZSByZXR1cm4gZFAodGFyZ2V0LCBrZXksIGRlc2MpO1xuICB9O1xuXG4gIGlmKCFBTExfQ09OU1RSVUNUT1JTKXtcbiAgICAkR09QRC5mID0gJGdldERlc2M7XG4gICAgJERQLmYgICA9ICRzZXREZXNjO1xuICB9XG5cbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhQUxMX0NPTlNUUlVDVE9SUywgJ09iamVjdCcsIHtcbiAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6ICRnZXREZXNjLFxuICAgIGRlZmluZVByb3BlcnR5OiAgICAgICAgICAgJHNldERlc2NcbiAgfSk7XG5cbiAgaWYoZmFpbHMoZnVuY3Rpb24oKXsgYXJyYXlUb1N0cmluZy5jYWxsKHt9KTsgfSkpe1xuICAgIGFycmF5VG9TdHJpbmcgPSBhcnJheVRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKXtcbiAgICAgIHJldHVybiBhcnJheUpvaW4uY2FsbCh0aGlzKTtcbiAgICB9XG4gIH1cblxuICB2YXIgJFR5cGVkQXJyYXlQcm90b3R5cGUkID0gcmVkZWZpbmVBbGwoe30sIHByb3RvKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAkaXRlcmF0b3JzKTtcbiAgaGlkZSgkVHlwZWRBcnJheVByb3RvdHlwZSQsIElURVJBVE9SLCAkaXRlcmF0b3JzLnZhbHVlcyk7XG4gIHJlZGVmaW5lQWxsKCRUeXBlZEFycmF5UHJvdG90eXBlJCwge1xuICAgIHNsaWNlOiAgICAgICAgICAkc2xpY2UsXG4gICAgc2V0OiAgICAgICAgICAgICRzZXQsXG4gICAgY29uc3RydWN0b3I6ICAgIGZ1bmN0aW9uKCl7IC8qIG5vb3AgKi8gfSxcbiAgICB0b1N0cmluZzogICAgICAgYXJyYXlUb1N0cmluZyxcbiAgICB0b0xvY2FsZVN0cmluZzogJHRvTG9jYWxlU3RyaW5nXG4gIH0pO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnVmZmVyJywgJ2InKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2J5dGVPZmZzZXQnLCAnbycpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZUxlbmd0aCcsICdsJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdsZW5ndGgnLCAnZScpO1xuICBkUCgkVHlwZWRBcnJheVByb3RvdHlwZSQsIFRBRywge1xuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXNbVFlQRURfQVJSQVldOyB9XG4gIH0pO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBCWVRFUywgd3JhcHBlciwgQ0xBTVBFRCl7XG4gICAgQ0xBTVBFRCA9ICEhQ0xBTVBFRDtcbiAgICB2YXIgTkFNRSAgICAgICA9IEtFWSArIChDTEFNUEVEID8gJ0NsYW1wZWQnIDogJycpICsgJ0FycmF5J1xuICAgICAgLCBJU05UX1VJTlQ4ID0gTkFNRSAhPSAnVWludDhBcnJheSdcbiAgICAgICwgR0VUVEVSICAgICA9ICdnZXQnICsgS0VZXG4gICAgICAsIFNFVFRFUiAgICAgPSAnc2V0JyArIEtFWVxuICAgICAgLCBUeXBlZEFycmF5ID0gZ2xvYmFsW05BTUVdXG4gICAgICAsIEJhc2UgICAgICAgPSBUeXBlZEFycmF5IHx8IHt9XG4gICAgICAsIFRBQyAgICAgICAgPSBUeXBlZEFycmF5ICYmIGdldFByb3RvdHlwZU9mKFR5cGVkQXJyYXkpXG4gICAgICAsIEZPUkNFRCAgICAgPSAhVHlwZWRBcnJheSB8fCAhJHR5cGVkLkFCVlxuICAgICAgLCBPICAgICAgICAgID0ge31cbiAgICAgICwgVHlwZWRBcnJheVByb3RvdHlwZSA9IFR5cGVkQXJyYXkgJiYgVHlwZWRBcnJheVtQUk9UT1RZUEVdO1xuICAgIHZhciBnZXR0ZXIgPSBmdW5jdGlvbih0aGF0LCBpbmRleCl7XG4gICAgICB2YXIgZGF0YSA9IHRoYXQuX2Q7XG4gICAgICByZXR1cm4gZGF0YS52W0dFVFRFUl0oaW5kZXggKiBCWVRFUyArIGRhdGEubywgTElUVExFX0VORElBTik7XG4gICAgfTtcbiAgICB2YXIgc2V0dGVyID0gZnVuY3Rpb24odGhhdCwgaW5kZXgsIHZhbHVlKXtcbiAgICAgIHZhciBkYXRhID0gdGhhdC5fZDtcbiAgICAgIGlmKENMQU1QRUQpdmFsdWUgPSAodmFsdWUgPSBNYXRoLnJvdW5kKHZhbHVlKSkgPCAwID8gMCA6IHZhbHVlID4gMHhmZiA/IDB4ZmYgOiB2YWx1ZSAmIDB4ZmY7XG4gICAgICBkYXRhLnZbU0VUVEVSXShpbmRleCAqIEJZVEVTICsgZGF0YS5vLCB2YWx1ZSwgTElUVExFX0VORElBTik7XG4gICAgfTtcbiAgICB2YXIgYWRkRWxlbWVudCA9IGZ1bmN0aW9uKHRoYXQsIGluZGV4KXtcbiAgICAgIGRQKHRoYXQsIGluZGV4LCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKXtcbiAgICAgICAgICByZXR1cm4gZ2V0dGVyKHRoaXMsIGluZGV4KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSl7XG4gICAgICAgICAgcmV0dXJuIHNldHRlcih0aGlzLCBpbmRleCwgdmFsdWUpO1xuICAgICAgICB9LFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICB9KTtcbiAgICB9O1xuICAgIGlmKEZPUkNFRCl7XG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBkYXRhLCAkb2Zmc2V0LCAkbGVuZ3RoKXtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FLCAnX2QnKTtcbiAgICAgICAgdmFyIGluZGV4ICA9IDBcbiAgICAgICAgICAsIG9mZnNldCA9IDBcbiAgICAgICAgICAsIGJ1ZmZlciwgYnl0ZUxlbmd0aCwgbGVuZ3RoLCBrbGFzcztcbiAgICAgICAgaWYoIWlzT2JqZWN0KGRhdGEpKXtcbiAgICAgICAgICBsZW5ndGggICAgID0gc3RyaWN0VG9MZW5ndGgoZGF0YSwgdHJ1ZSlcbiAgICAgICAgICBieXRlTGVuZ3RoID0gbGVuZ3RoICogQllURVM7XG4gICAgICAgICAgYnVmZmVyICAgICA9IG5ldyAkQXJyYXlCdWZmZXIoYnl0ZUxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZihkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKXtcbiAgICAgICAgICBidWZmZXIgPSBkYXRhO1xuICAgICAgICAgIG9mZnNldCA9IHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKTtcbiAgICAgICAgICB2YXIgJGxlbiA9IGRhdGEuYnl0ZUxlbmd0aDtcbiAgICAgICAgICBpZigkbGVuZ3RoID09PSB1bmRlZmluZWQpe1xuICAgICAgICAgICAgaWYoJGxlbiAlIEJZVEVTKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSAkbGVuIC0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYoYnl0ZUxlbmd0aCA8IDApdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gdG9MZW5ndGgoJGxlbmd0aCkgKiBCWVRFUztcbiAgICAgICAgICAgIGlmKGJ5dGVMZW5ndGggKyBvZmZzZXQgPiAkbGVuKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuZ3RoID0gYnl0ZUxlbmd0aCAvIEJZVEVTO1xuICAgICAgICB9IGVsc2UgaWYoVFlQRURfQVJSQVkgaW4gZGF0YSl7XG4gICAgICAgICAgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGhpZGUodGhhdCwgJ19kJywge1xuICAgICAgICAgIGI6IGJ1ZmZlcixcbiAgICAgICAgICBvOiBvZmZzZXQsXG4gICAgICAgICAgbDogYnl0ZUxlbmd0aCxcbiAgICAgICAgICBlOiBsZW5ndGgsXG4gICAgICAgICAgdjogbmV3ICREYXRhVmlldyhidWZmZXIpXG4gICAgICAgIH0pO1xuICAgICAgICB3aGlsZShpbmRleCA8IGxlbmd0aClhZGRFbGVtZW50KHRoYXQsIGluZGV4KyspO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gY3JlYXRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCk7XG4gICAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIFR5cGVkQXJyYXkpO1xuICAgIH0gZWxzZSBpZighJGl0ZXJEZXRlY3QoZnVuY3Rpb24oaXRlcil7XG4gICAgICAvLyBWOCB3b3JrcyB3aXRoIGl0ZXJhdG9ycywgYnV0IGZhaWxzIGluIG1hbnkgb3RoZXIgY2FzZXNcbiAgICAgIC8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00NTUyXG4gICAgICBuZXcgVHlwZWRBcnJheShudWxsKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KGl0ZXIpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH0sIHRydWUpKXtcbiAgICAgIFR5cGVkQXJyYXkgPSB3cmFwcGVyKGZ1bmN0aW9uKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpe1xuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUpO1xuICAgICAgICB2YXIga2xhc3M7XG4gICAgICAgIC8vIGB3c2AgbW9kdWxlIGJ1ZywgdGVtcG9yYXJpbHkgcmVtb3ZlIHZhbGlkYXRpb24gbGVuZ3RoIGZvciBVaW50OEFycmF5XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJzb2NrZXRzL3dzL3B1bGwvNjQ1XG4gICAgICAgIGlmKCFpc09iamVjdChkYXRhKSlyZXR1cm4gbmV3IEJhc2Uoc3RyaWN0VG9MZW5ndGgoZGF0YSwgSVNOVF9VSU5UOCkpO1xuICAgICAgICBpZihkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKXtcbiAgICAgICAgICByZXR1cm4gJGxlbmd0aCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSwgJGxlbmd0aClcbiAgICAgICAgICAgIDogJG9mZnNldCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbmV3IEJhc2UoZGF0YSwgdG9PZmZzZXQoJG9mZnNldCwgQllURVMpKVxuICAgICAgICAgICAgICA6IG5ldyBCYXNlKGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmKFRZUEVEX0FSUkFZIGluIGRhdGEpcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgYXJyYXlGb3JFYWNoKFRBQyAhPT0gRnVuY3Rpb24ucHJvdG90eXBlID8gZ09QTihCYXNlKS5jb25jYXQoZ09QTihUQUMpKSA6IGdPUE4oQmFzZSksIGZ1bmN0aW9uKGtleSl7XG4gICAgICAgIGlmKCEoa2V5IGluIFR5cGVkQXJyYXkpKWhpZGUoVHlwZWRBcnJheSwga2V5LCBCYXNlW2tleV0pO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBUeXBlZEFycmF5UHJvdG90eXBlO1xuICAgICAgaWYoIUxJQlJBUlkpVHlwZWRBcnJheVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR5cGVkQXJyYXk7XG4gICAgfVxuICAgIHZhciAkbmF0aXZlSXRlcmF0b3IgICA9IFR5cGVkQXJyYXlQcm90b3R5cGVbSVRFUkFUT1JdXG4gICAgICAsIENPUlJFQ1RfSVRFUl9OQU1FID0gISEkbmF0aXZlSXRlcmF0b3IgJiYgKCRuYXRpdmVJdGVyYXRvci5uYW1lID09ICd2YWx1ZXMnIHx8ICRuYXRpdmVJdGVyYXRvci5uYW1lID09IHVuZGVmaW5lZClcbiAgICAgICwgJGl0ZXJhdG9yICAgICAgICAgPSAkaXRlcmF0b3JzLnZhbHVlcztcbiAgICBoaWRlKFR5cGVkQXJyYXksIFRZUEVEX0NPTlNUUlVDVE9SLCB0cnVlKTtcbiAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIFRZUEVEX0FSUkFZLCBOQU1FKTtcbiAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIFZJRVcsIHRydWUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgREVGX0NPTlNUUlVDVE9SLCBUeXBlZEFycmF5KTtcblxuICAgIGlmKENMQU1QRUQgPyBuZXcgVHlwZWRBcnJheSgxKVtUQUddICE9IE5BTUUgOiAhKFRBRyBpbiBUeXBlZEFycmF5UHJvdG90eXBlKSl7XG4gICAgICBkUChUeXBlZEFycmF5UHJvdG90eXBlLCBUQUcsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gTkFNRTsgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT1tOQU1FXSA9IFR5cGVkQXJyYXk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChUeXBlZEFycmF5ICE9IEJhc2UpLCBPKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TLCBOQU1FLCB7XG4gICAgICBCWVRFU19QRVJfRUxFTUVOVDogQllURVMsXG4gICAgICBmcm9tOiAkZnJvbSxcbiAgICAgIG9mOiAkb2ZcbiAgICB9KTtcblxuICAgIGlmKCEoQllURVNfUEVSX0VMRU1FTlQgaW4gVHlwZWRBcnJheVByb3RvdHlwZSkpaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBCWVRFU19QRVJfRUxFTUVOVCwgQllURVMpO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAsIE5BTUUsIHByb3RvKTtcblxuICAgIHNldFNwZWNpZXMoTkFNRSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIEZPUkNFRF9TRVQsIE5BTUUsIHtzZXQ6ICRzZXR9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIUNPUlJFQ1RfSVRFUl9OQU1FLCBOQU1FLCAkaXRlcmF0b3JzKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKFR5cGVkQXJyYXlQcm90b3R5cGUudG9TdHJpbmcgIT0gYXJyYXlUb1N0cmluZyksIE5BTUUsIHt0b1N0cmluZzogYXJyYXlUb1N0cmluZ30pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbigpe1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMSkuc2xpY2UoKTtcbiAgICB9KSwgTkFNRSwge3NsaWNlOiAkc2xpY2V9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKGZhaWxzKGZ1bmN0aW9uKCl7XG4gICAgICByZXR1cm4gWzEsIDJdLnRvTG9jYWxlU3RyaW5nKCkgIT0gbmV3IFR5cGVkQXJyYXkoWzEsIDJdKS50b0xvY2FsZVN0cmluZygpXG4gICAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uKCl7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nLmNhbGwoWzEsIDJdKTtcbiAgICB9KSksIE5BTUUsIHt0b0xvY2FsZVN0cmluZzogJHRvTG9jYWxlU3RyaW5nfSk7XG5cbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBDT1JSRUNUX0lURVJfTkFNRSA/ICRuYXRpdmVJdGVyYXRvciA6ICRpdGVyYXRvcjtcbiAgICBpZighTElCUkFSWSAmJiAhQ09SUkVDVF9JVEVSX05BTUUpaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBJVEVSQVRPUiwgJGl0ZXJhdG9yKTtcbiAgfTtcbn0gZWxzZSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH07IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCAgICAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBERVNDUklQVE9SUyAgICA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJylcbiAgLCBMSUJSQVJZICAgICAgICA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKVxuICAsICR0eXBlZCAgICAgICAgID0gcmVxdWlyZSgnLi9fdHlwZWQnKVxuICAsIGhpZGUgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgcmVkZWZpbmVBbGwgICAgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKVxuICAsIGZhaWxzICAgICAgICAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsIGFuSW5zdGFuY2UgICAgID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKVxuICAsIHRvSW50ZWdlciAgICAgID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgdG9MZW5ndGggICAgICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGdPUE4gICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mXG4gICwgZFAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgYXJyYXlGaWxsICAgICAgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJylcbiAgLCBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJylcbiAgLCBBUlJBWV9CVUZGRVIgICA9ICdBcnJheUJ1ZmZlcidcbiAgLCBEQVRBX1ZJRVcgICAgICA9ICdEYXRhVmlldydcbiAgLCBQUk9UT1RZUEUgICAgICA9ICdwcm90b3R5cGUnXG4gICwgV1JPTkdfTEVOR1RIICAgPSAnV3JvbmcgbGVuZ3RoISdcbiAgLCBXUk9OR19JTkRFWCAgICA9ICdXcm9uZyBpbmRleCEnXG4gICwgJEFycmF5QnVmZmVyICAgPSBnbG9iYWxbQVJSQVlfQlVGRkVSXVxuICAsICREYXRhVmlldyAgICAgID0gZ2xvYmFsW0RBVEFfVklFV11cbiAgLCBNYXRoICAgICAgICAgICA9IGdsb2JhbC5NYXRoXG4gICwgUmFuZ2VFcnJvciAgICAgPSBnbG9iYWwuUmFuZ2VFcnJvclxuICAsIEluZmluaXR5ICAgICAgID0gZ2xvYmFsLkluZmluaXR5XG4gICwgQmFzZUJ1ZmZlciAgICAgPSAkQXJyYXlCdWZmZXJcbiAgLCBhYnMgICAgICAgICAgICA9IE1hdGguYWJzXG4gICwgcG93ICAgICAgICAgICAgPSBNYXRoLnBvd1xuICAsIGZsb29yICAgICAgICAgID0gTWF0aC5mbG9vclxuICAsIGxvZyAgICAgICAgICAgID0gTWF0aC5sb2dcbiAgLCBMTjIgICAgICAgICAgICA9IE1hdGguTE4yXG4gICwgQlVGRkVSICAgICAgICAgPSAnYnVmZmVyJ1xuICAsIEJZVEVfTEVOR1RIICAgID0gJ2J5dGVMZW5ndGgnXG4gICwgQllURV9PRkZTRVQgICAgPSAnYnl0ZU9mZnNldCdcbiAgLCAkQlVGRkVSICAgICAgICA9IERFU0NSSVBUT1JTID8gJ19iJyA6IEJVRkZFUlxuICAsICRMRU5HVEggICAgICAgID0gREVTQ1JJUFRPUlMgPyAnX2wnIDogQllURV9MRU5HVEhcbiAgLCAkT0ZGU0VUICAgICAgICA9IERFU0NSSVBUT1JTID8gJ19vJyA6IEJZVEVfT0ZGU0VUO1xuXG4vLyBJRUVFNzU0IGNvbnZlcnNpb25zIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxudmFyIHBhY2tJRUVFNzU0ID0gZnVuY3Rpb24odmFsdWUsIG1MZW4sIG5CeXRlcyl7XG4gIHZhciBidWZmZXIgPSBBcnJheShuQnl0ZXMpXG4gICAgLCBlTGVuICAgPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgICAsIGVNYXggICA9ICgxIDw8IGVMZW4pIC0gMVxuICAgICwgZUJpYXMgID0gZU1heCA+PiAxXG4gICAgLCBydCAgICAgPSBtTGVuID09PSAyMyA/IHBvdygyLCAtMjQpIC0gcG93KDIsIC03NykgOiAwXG4gICAgLCBpICAgICAgPSAwXG4gICAgLCBzICAgICAgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwXG4gICAgLCBlLCBtLCBjO1xuICB2YWx1ZSA9IGFicyh2YWx1ZSlcbiAgaWYodmFsdWUgIT0gdmFsdWUgfHwgdmFsdWUgPT09IEluZmluaXR5KXtcbiAgICBtID0gdmFsdWUgIT0gdmFsdWUgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gZmxvb3IobG9nKHZhbHVlKSAvIExOMik7XG4gICAgaWYodmFsdWUgKiAoYyA9IHBvdygyLCAtZSkpIDwgMSl7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmKGUgKyBlQmlhcyA+PSAxKXtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBwb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG4gICAgaWYodmFsdWUgKiBjID49IDIpe1xuICAgICAgZSsrO1xuICAgICAgYyAvPSAyO1xuICAgIH1cbiAgICBpZihlICsgZUJpYXMgPj0gZU1heCl7XG4gICAgICBtID0gMDtcbiAgICAgIGUgPSBlTWF4O1xuICAgIH0gZWxzZSBpZihlICsgZUJpYXMgPj0gMSl7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogcG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogcG93KDIsIGVCaWFzIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cbiAgZm9yKDsgbUxlbiA+PSA4OyBidWZmZXJbaSsrXSA9IG0gJiAyNTUsIG0gLz0gMjU2LCBtTGVuIC09IDgpO1xuICBlID0gZSA8PCBtTGVuIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IoOyBlTGVuID4gMDsgYnVmZmVyW2krK10gPSBlICYgMjU1LCBlIC89IDI1NiwgZUxlbiAtPSA4KTtcbiAgYnVmZmVyWy0taV0gfD0gcyAqIDEyODtcbiAgcmV0dXJuIGJ1ZmZlcjtcbn07XG52YXIgdW5wYWNrSUVFRTc1NCA9IGZ1bmN0aW9uKGJ1ZmZlciwgbUxlbiwgbkJ5dGVzKXtcbiAgdmFyIGVMZW4gID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gICAgLCBlTWF4ICA9ICgxIDw8IGVMZW4pIC0gMVxuICAgICwgZUJpYXMgPSBlTWF4ID4+IDFcbiAgICAsIG5CaXRzID0gZUxlbiAtIDdcbiAgICAsIGkgICAgID0gbkJ5dGVzIC0gMVxuICAgICwgcyAgICAgPSBidWZmZXJbaS0tXVxuICAgICwgZSAgICAgPSBzICYgMTI3XG4gICAgLCBtO1xuICBzID4+PSA3O1xuICBmb3IoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW2ldLCBpLS0sIG5CaXRzIC09IDgpO1xuICBtID0gZSAmICgxIDw8IC1uQml0cykgLSAxO1xuICBlID4+PSAtbkJpdHM7XG4gIG5CaXRzICs9IG1MZW47XG4gIGZvcig7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIGlmKGUgPT09IDApe1xuICAgIGUgPSAxIC0gZUJpYXM7XG4gIH0gZWxzZSBpZihlID09PSBlTWF4KXtcbiAgICByZXR1cm4gbSA/IE5hTiA6IHMgPyAtSW5maW5pdHkgOiBJbmZpbml0eTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIHBvdygyLCBtTGVuKTtcbiAgICBlID0gZSAtIGVCaWFzO1xuICB9IHJldHVybiAocyA/IC0xIDogMSkgKiBtICogcG93KDIsIGUgLSBtTGVuKTtcbn07XG5cbnZhciB1bnBhY2tJMzIgPSBmdW5jdGlvbihieXRlcyl7XG4gIHJldHVybiBieXRlc1szXSA8PCAyNCB8IGJ5dGVzWzJdIDw8IDE2IHwgYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xufTtcbnZhciBwYWNrSTggPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBbaXQgJiAweGZmXTtcbn07XG52YXIgcGFja0kxNiA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmXTtcbn07XG52YXIgcGFja0kzMiA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmLCBpdCA+PiAxNiAmIDB4ZmYsIGl0ID4+IDI0ICYgMHhmZl07XG59O1xudmFyIHBhY2tGNjQgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBwYWNrSUVFRTc1NChpdCwgNTIsIDgpO1xufTtcbnZhciBwYWNrRjMyID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDIzLCA0KTtcbn07XG5cbnZhciBhZGRHZXR0ZXIgPSBmdW5jdGlvbihDLCBrZXksIGludGVybmFsKXtcbiAgZFAoQ1tQUk9UT1RZUEVdLCBrZXksIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzW2ludGVybmFsXTsgfX0pO1xufTtcblxudmFyIGdldCA9IGZ1bmN0aW9uKHZpZXcsIGJ5dGVzLCBpbmRleCwgaXNMaXR0bGVFbmRpYW4pe1xuICB2YXIgbnVtSW5kZXggPSAraW5kZXhcbiAgICAsIGludEluZGV4ID0gdG9JbnRlZ2VyKG51bUluZGV4KTtcbiAgaWYobnVtSW5kZXggIT0gaW50SW5kZXggfHwgaW50SW5kZXggPCAwIHx8IGludEluZGV4ICsgYnl0ZXMgPiB2aWV3WyRMRU5HVEhdKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfSU5ERVgpO1xuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iXG4gICAgLCBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXVxuICAgICwgcGFjayAgPSBzdG9yZS5zbGljZShzdGFydCwgc3RhcnQgKyBieXRlcyk7XG4gIHJldHVybiBpc0xpdHRsZUVuZGlhbiA/IHBhY2sgOiBwYWNrLnJldmVyc2UoKTtcbn07XG52YXIgc2V0ID0gZnVuY3Rpb24odmlldywgYnl0ZXMsIGluZGV4LCBjb252ZXJzaW9uLCB2YWx1ZSwgaXNMaXR0bGVFbmRpYW4pe1xuICB2YXIgbnVtSW5kZXggPSAraW5kZXhcbiAgICAsIGludEluZGV4ID0gdG9JbnRlZ2VyKG51bUluZGV4KTtcbiAgaWYobnVtSW5kZXggIT0gaW50SW5kZXggfHwgaW50SW5kZXggPCAwIHx8IGludEluZGV4ICsgYnl0ZXMgPiB2aWV3WyRMRU5HVEhdKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfSU5ERVgpO1xuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iXG4gICAgLCBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXVxuICAgICwgcGFjayAgPSBjb252ZXJzaW9uKCt2YWx1ZSk7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCBieXRlczsgaSsrKXN0b3JlW3N0YXJ0ICsgaV0gPSBwYWNrW2lzTGl0dGxlRW5kaWFuID8gaSA6IGJ5dGVzIC0gaSAtIDFdO1xufTtcblxudmFyIHZhbGlkYXRlQXJyYXlCdWZmZXJBcmd1bWVudHMgPSBmdW5jdGlvbih0aGF0LCBsZW5ndGgpe1xuICBhbkluc3RhbmNlKHRoYXQsICRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbiAgdmFyIG51bWJlckxlbmd0aCA9ICtsZW5ndGhcbiAgICAsIGJ5dGVMZW5ndGggICA9IHRvTGVuZ3RoKG51bWJlckxlbmd0aCk7XG4gIGlmKG51bWJlckxlbmd0aCAhPSBieXRlTGVuZ3RoKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgcmV0dXJuIGJ5dGVMZW5ndGg7XG59O1xuXG5pZighJHR5cGVkLkFCVil7XG4gICRBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uIEFycmF5QnVmZmVyKGxlbmd0aCl7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSB2YWxpZGF0ZUFycmF5QnVmZmVyQXJndW1lbnRzKHRoaXMsIGxlbmd0aCk7XG4gICAgdGhpcy5fYiAgICAgICA9IGFycmF5RmlsbC5jYWxsKEFycmF5KGJ5dGVMZW5ndGgpLCAwKTtcbiAgICB0aGlzWyRMRU5HVEhdID0gYnl0ZUxlbmd0aDtcbiAgfTtcblxuICAkRGF0YVZpZXcgPSBmdW5jdGlvbiBEYXRhVmlldyhidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpe1xuICAgIGFuSW5zdGFuY2UodGhpcywgJERhdGFWaWV3LCBEQVRBX1ZJRVcpO1xuICAgIGFuSW5zdGFuY2UoYnVmZmVyLCAkQXJyYXlCdWZmZXIsIERBVEFfVklFVyk7XG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlclskTEVOR1RIXVxuICAgICAgLCBvZmZzZXQgICAgICAgPSB0b0ludGVnZXIoYnl0ZU9mZnNldCk7XG4gICAgaWYob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBidWZmZXJMZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcignV3Jvbmcgb2Zmc2V0IScpO1xuICAgIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID09PSB1bmRlZmluZWQgPyBidWZmZXJMZW5ndGggLSBvZmZzZXQgOiB0b0xlbmd0aChieXRlTGVuZ3RoKTtcbiAgICBpZihvZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyTGVuZ3RoKXRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB0aGlzWyRCVUZGRVJdID0gYnVmZmVyO1xuICAgIHRoaXNbJE9GRlNFVF0gPSBvZmZzZXQ7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgaWYoREVTQ1JJUFRPUlMpe1xuICAgIGFkZEdldHRlcigkQXJyYXlCdWZmZXIsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCVUZGRVIsICdfYicpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCWVRFX09GRlNFVCwgJ19vJyk7XG4gIH1cblxuICByZWRlZmluZUFsbCgkRGF0YVZpZXdbUFJPVE9UWVBFXSwge1xuICAgIGdldEludDg6IGZ1bmN0aW9uIGdldEludDgoYnl0ZU9mZnNldCl7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdIDw8IDI0ID4+IDI0O1xuICAgIH0sXG4gICAgZ2V0VWludDg6IGZ1bmN0aW9uIGdldFVpbnQ4KGJ5dGVPZmZzZXQpe1xuICAgICAgcmV0dXJuIGdldCh0aGlzLCAxLCBieXRlT2Zmc2V0KVswXTtcbiAgICB9LFxuICAgIGdldEludDE2OiBmdW5jdGlvbiBnZXRJbnQxNihieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gKGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXSkgPDwgMTYgPj4gMTY7XG4gICAgfSxcbiAgICBnZXRVaW50MTY6IGZ1bmN0aW9uIGdldFVpbnQxNihieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MzI6IGZ1bmN0aW9uIGdldEludDMyKGJ5dGVPZmZzZXQgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKTtcbiAgICB9LFxuICAgIGdldFVpbnQzMjogZnVuY3Rpb24gZ2V0VWludDMyKGJ5dGVPZmZzZXQgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKSA+Pj4gMDtcbiAgICB9LFxuICAgIGdldEZsb2F0MzI6IGZ1bmN0aW9uIGdldEZsb2F0MzIoYnl0ZU9mZnNldCAvKiwgbGl0dGxlRW5kaWFuICovKXtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCAyMywgNCk7XG4gICAgfSxcbiAgICBnZXRGbG9hdDY0OiBmdW5jdGlvbiBnZXRGbG9hdDY0KGJ5dGVPZmZzZXQgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICByZXR1cm4gdW5wYWNrSUVFRTc1NChnZXQodGhpcywgOCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSwgNTIsIDgpO1xuICAgIH0sXG4gICAgc2V0SW50ODogZnVuY3Rpb24gc2V0SW50OChieXRlT2Zmc2V0LCB2YWx1ZSl7XG4gICAgICBzZXQodGhpcywgMSwgYnl0ZU9mZnNldCwgcGFja0k4LCB2YWx1ZSk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xuICAgICAgc2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQsIHBhY2tJOCwgdmFsdWUpO1xuICAgIH0sXG4gICAgc2V0SW50MTY6IGZ1bmN0aW9uIHNldEludDE2KGJ5dGVPZmZzZXQsIHZhbHVlIC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDE2OiBmdW5jdGlvbiBzZXRVaW50MTYoYnl0ZU9mZnNldCwgdmFsdWUgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICBzZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgcGFja0kxNiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRJbnQzMjogZnVuY3Rpb24gc2V0SW50MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0kzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRVaW50MzI6IGZ1bmN0aW9uIHNldFVpbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiwgbGl0dGxlRW5kaWFuICovKXtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrSTMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0MzI6IGZ1bmN0aW9uIHNldEZsb2F0MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyosIGxpdHRsZUVuZGlhbiAqLyl7XG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0YzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRGbG9hdDY0OiBmdW5jdGlvbiBzZXRGbG9hdDY0KGJ5dGVPZmZzZXQsIHZhbHVlIC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xuICAgICAgc2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIHBhY2tGNjQsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICBpZighZmFpbHMoZnVuY3Rpb24oKXtcbiAgICBuZXcgJEFycmF5QnVmZmVyOyAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uKCl7XG4gICAgbmV3ICRBcnJheUJ1ZmZlciguNSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gIH0pKXtcbiAgICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpe1xuICAgICAgcmV0dXJuIG5ldyBCYXNlQnVmZmVyKHZhbGlkYXRlQXJyYXlCdWZmZXJBcmd1bWVudHModGhpcywgbGVuZ3RoKSk7XG4gICAgfTtcbiAgICB2YXIgQXJyYXlCdWZmZXJQcm90byA9ICRBcnJheUJ1ZmZlcltQUk9UT1RZUEVdID0gQmFzZUJ1ZmZlcltQUk9UT1RZUEVdO1xuICAgIGZvcih2YXIga2V5cyA9IGdPUE4oQmFzZUJ1ZmZlciksIGogPSAwLCBrZXk7IGtleXMubGVuZ3RoID4gajsgKXtcbiAgICAgIGlmKCEoKGtleSA9IGtleXNbaisrXSkgaW4gJEFycmF5QnVmZmVyKSloaWRlKCRBcnJheUJ1ZmZlciwga2V5LCBCYXNlQnVmZmVyW2tleV0pO1xuICAgIH07XG4gICAgaWYoIUxJQlJBUlkpQXJyYXlCdWZmZXJQcm90by5jb25zdHJ1Y3RvciA9ICRBcnJheUJ1ZmZlcjtcbiAgfVxuICAvLyBpT1MgU2FmYXJpIDcueCBidWdcbiAgdmFyIHZpZXcgPSBuZXcgJERhdGFWaWV3KG5ldyAkQXJyYXlCdWZmZXIoMikpXG4gICAgLCAkc2V0SW50OCA9ICREYXRhVmlld1tQUk9UT1RZUEVdLnNldEludDg7XG4gIHZpZXcuc2V0SW50OCgwLCAyMTQ3NDgzNjQ4KTtcbiAgdmlldy5zZXRJbnQ4KDEsIDIxNDc0ODM2NDkpO1xuICBpZih2aWV3LmdldEludDgoMCkgfHwgIXZpZXcuZ2V0SW50OCgxKSlyZWRlZmluZUFsbCgkRGF0YVZpZXdbUFJPVE9UWVBFXSwge1xuICAgIHNldEludDg6IGZ1bmN0aW9uIHNldEludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cbnNldFRvU3RyaW5nVGFnKCRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbnNldFRvU3RyaW5nVGFnKCREYXRhVmlldywgREFUQV9WSUVXKTtcbmhpZGUoJERhdGFWaWV3W1BST1RPVFlQRV0sICR0eXBlZC5WSUVXLCB0cnVlKTtcbmV4cG9ydHNbQVJSQVlfQlVGRkVSXSA9ICRBcnJheUJ1ZmZlcjtcbmV4cG9ydHNbREFUQV9WSUVXXSA9ICREYXRhVmlldzsiLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBoaWRlICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgLCB1aWQgICAgPSByZXF1aXJlKCcuL191aWQnKVxuICAsIFRZUEVEICA9IHVpZCgndHlwZWRfYXJyYXknKVxuICAsIFZJRVcgICA9IHVpZCgndmlldycpXG4gICwgQUJWICAgID0gISEoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGdsb2JhbC5EYXRhVmlldylcbiAgLCBDT05TVFIgPSBBQlZcbiAgLCBpID0gMCwgbCA9IDksIFR5cGVkO1xuXG52YXIgVHlwZWRBcnJheUNvbnN0cnVjdG9ycyA9IChcbiAgJ0ludDhBcnJheSxVaW50OEFycmF5LFVpbnQ4Q2xhbXBlZEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5J1xuKS5zcGxpdCgnLCcpO1xuXG53aGlsZShpIDwgbCl7XG4gIGlmKFR5cGVkID0gZ2xvYmFsW1R5cGVkQXJyYXlDb25zdHJ1Y3RvcnNbaSsrXV0pe1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBUWVBFRCwgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZC5wcm90b3R5cGUsIFZJRVcsIHRydWUpO1xuICB9IGVsc2UgQ09OU1RSID0gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBBQlY6ICAgIEFCVixcbiAgQ09OU1RSOiBDT05TVFIsXG4gIFRZUEVEOiAgVFlQRUQsXG4gIFZJRVc6ICAgVklFV1xufTsiLCJ2YXIgaWQgPSAwXG4gICwgcHggPSBNYXRoLnJhbmRvbSgpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTsiLCJ2YXIgZ2xvYmFsICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGNvcmUgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY29yZScpXG4gICwgTElCUkFSWSAgICAgICAgPSByZXF1aXJlKCcuL19saWJyYXJ5JylcbiAgLCB3a3NFeHQgICAgICAgICA9IHJlcXVpcmUoJy4vX3drcy1leHQnKVxuICAsIGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XG4gIHZhciAkU3ltYm9sID0gY29yZS5TeW1ib2wgfHwgKGNvcmUuU3ltYm9sID0gTElCUkFSWSA/IHt9IDogZ2xvYmFsLlN5bWJvbCB8fCB7fSk7XG4gIGlmKG5hbWUuY2hhckF0KDApICE9ICdfJyAmJiAhKG5hbWUgaW4gJFN5bWJvbCkpZGVmaW5lUHJvcGVydHkoJFN5bWJvbCwgbmFtZSwge3ZhbHVlOiB3a3NFeHQuZihuYW1lKX0pO1xufTsiLCJleHBvcnRzLmYgPSByZXF1aXJlKCcuL193a3MnKTsiLCJ2YXIgc3RvcmUgICAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCd3a3MnKVxuICAsIHVpZCAgICAgICAgPSByZXF1aXJlKCcuL191aWQnKVxuICAsIFN5bWJvbCAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5TeW1ib2xcbiAgLCBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG5hbWUpe1xuICByZXR1cm4gc3RvcmVbbmFtZV0gfHwgKHN0b3JlW25hbWVdID1cbiAgICBVU0VfU1lNQk9MICYmIFN5bWJvbFtuYW1lXSB8fCAoVVNFX1NZTUJPTCA/IFN5bWJvbCA6IHVpZCkoJ1N5bWJvbC4nICsgbmFtZSkpO1xufTtcblxuJGV4cG9ydHMuc3RvcmUgPSBzdG9yZTsiLCJ2YXIgY2xhc3NvZiAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgSVRFUkFUT1IgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmdldEl0ZXJhdG9yTWV0aG9kID0gZnVuY3Rpb24oaXQpe1xuICBpZihpdCAhPSB1bmRlZmluZWQpcmV0dXJuIGl0W0lURVJBVE9SXVxuICAgIHx8IGl0WydAQGl0ZXJhdG9yJ11cbiAgICB8fCBJdGVyYXRvcnNbY2xhc3NvZihpdCldO1xufTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vYmVuamFtaW5nci9SZXhFeHAuZXNjYXBlXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJHJlICAgICA9IHJlcXVpcmUoJy4vX3JlcGxhY2VyJykoL1tcXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVnRXhwJywge2VzY2FwZTogZnVuY3Rpb24gZXNjYXBlKGl0KXsgcmV0dXJuICRyZShpdCk7IH19KTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHtjb3B5V2l0aGluOiByZXF1aXJlKCcuL19hcnJheS1jb3B5LXdpdGhpbicpfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdjb3B5V2l0aGluJyk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRldmVyeSAgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNCk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5ldmVyeSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjUgLyAxNS40LjQuMTYgQXJyYXkucHJvdG90eXBlLmV2ZXJ5KGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLyl7XG4gICAgcmV0dXJuICRldmVyeSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTsiLCIvLyAyMi4xLjMuNiBBcnJheS5wcm90b3R5cGUuZmlsbCh2YWx1ZSwgc3RhcnQgPSAwLCBlbmQgPSB0aGlzLmxlbmd0aClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7ZmlsbDogcmVxdWlyZSgnLi9fYXJyYXktZmlsbCcpfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmaWxsJyk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRmaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMik7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5maWx0ZXIsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pe1xuICAgIHJldHVybiAkZmlsdGVyKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy45IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXgocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRmaW5kICAgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNilcbiAgLCBLRVkgICAgID0gJ2ZpbmRJbmRleCdcbiAgLCBmb3JjZWQgID0gdHJ1ZTtcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXG5pZihLRVkgaW4gW10pQXJyYXkoMSlbS0VZXShmdW5jdGlvbigpeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuLyosIHRoYXQgPSB1bmRlZmluZWQgKi8pe1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTsiLCIndXNlIHN0cmljdCc7XG4vLyAyMi4xLjMuOCBBcnJheS5wcm90b3R5cGUuZmluZChwcmVkaWNhdGUsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJGZpbmQgICA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg1KVxuICAsIEtFWSAgICAgPSAnZmluZCdcbiAgLCBmb3JjZWQgID0gdHJ1ZTtcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXG5pZihLRVkgaW4gW10pQXJyYXkoMSlbS0VZXShmdW5jdGlvbigpeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kOiBmdW5jdGlvbiBmaW5kKGNhbGxiYWNrZm4vKiwgdGhhdCA9IHVuZGVmaW5lZCAqLyl7XG4gICAgcmV0dXJuICRmaW5kKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7XG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKShLRVkpOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJGZvckVhY2ggPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMClcbiAgLCBTVFJJQ1QgICA9IHJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5mb3JFYWNoLCB0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMCAvIDE1LjQuNC4xOCBBcnJheS5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKXtcbiAgICByZXR1cm4gJGZvckVhY2godGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGN0eCAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCAkZXhwb3J0ICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgdG9PYmplY3QgICAgICAgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIGNhbGwgICAgICAgICAgID0gcmVxdWlyZSgnLi9faXRlci1jYWxsJylcbiAgLCBpc0FycmF5SXRlciAgICA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKVxuICAsIHRvTGVuZ3RoICAgICAgID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJylcbiAgLCBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpXG4gICwgZ2V0SXRlckZuICAgICAgPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uKGl0ZXIpeyBBcnJheS5mcm9tKGl0ZXIpOyB9KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMSBBcnJheS5mcm9tKGFycmF5TGlrZSwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlLyosIG1hcGZuID0gdW5kZWZpbmVkLCB0aGlzQXJnID0gdW5kZWZpbmVkKi8pe1xuICAgIHZhciBPICAgICAgID0gdG9PYmplY3QoYXJyYXlMaWtlKVxuICAgICAgLCBDICAgICAgID0gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheVxuICAgICAgLCBhTGVuICAgID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCBtYXBmbiAgID0gYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWRcbiAgICAgICwgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWRcbiAgICAgICwgaW5kZXggICA9IDBcbiAgICAgICwgaXRlckZuICA9IGdldEl0ZXJGbihPKVxuICAgICAgLCBsZW5ndGgsIHJlc3VsdCwgc3RlcCwgaXRlcmF0b3I7XG4gICAgaWYobWFwcGluZyltYXBmbiA9IGN0eChtYXBmbiwgYUxlbiA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQsIDIpO1xuICAgIC8vIGlmIG9iamVjdCBpc24ndCBpdGVyYWJsZSBvciBpdCdzIGFycmF5IHdpdGggZGVmYXVsdCBpdGVyYXRvciAtIHVzZSBzaW1wbGUgY2FzZVxuICAgIGlmKGl0ZXJGbiAhPSB1bmRlZmluZWQgJiYgIShDID09IEFycmF5ICYmIGlzQXJyYXlJdGVyKGl0ZXJGbikpKXtcbiAgICAgIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCByZXN1bHQgPSBuZXcgQzsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpbmRleCsrKXtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IGNhbGwoaXRlcmF0b3IsIG1hcGZuLCBbc3RlcC52YWx1ZSwgaW5kZXhdLCB0cnVlKSA6IHN0ZXAudmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgICBmb3IocmVzdWx0ID0gbmV3IEMobGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4Kyspe1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gbWFwZm4oT1tpbmRleF0sIGluZGV4KSA6IE9baW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0Lmxlbmd0aCA9IGluZGV4O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRpbmRleE9mICAgICAgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKVxuICAsICRuYXRpdmUgICAgICAgPSBbXS5pbmRleE9mXG4gICwgTkVHQVRJVkVfWkVSTyA9ICEhJG5hdGl2ZSAmJiAxIC8gWzFdLmluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTEgLyAxNS40LjQuMTQgQXJyYXkucHJvdG90eXBlLmluZGV4T2Yoc2VhcmNoRWxlbWVudCBbLCBmcm9tSW5kZXhdKVxuICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQgLyosIGZyb21JbmRleCA9IDAgKi8pe1xuICAgIHJldHVybiBORUdBVElWRV9aRVJPXG4gICAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgICA/ICRuYXRpdmUuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCAwXG4gICAgICA6ICRpbmRleE9mKHRoaXMsIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pOyIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5Jywge2lzQXJyYXk6IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyl9KTsiLCIndXNlIHN0cmljdCc7XG52YXIgYWRkVG9VbnNjb3BhYmxlcyA9IHJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpXG4gICwgc3RlcCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpXG4gICwgSXRlcmF0b3JzICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgdG9JT2JqZWN0ICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbihpdGVyYXRlZCwga2luZCl7XG4gIHRoaXMuX3QgPSB0b0lPYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbiAgdGhpcy5fayA9IGtpbmQ7ICAgICAgICAgICAgICAgIC8vIGtpbmRcbi8vIDIyLjEuNS4yLjEgJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxufSwgZnVuY3Rpb24oKXtcbiAgdmFyIE8gICAgID0gdGhpcy5fdFxuICAgICwga2luZCAgPSB0aGlzLl9rXG4gICAgLCBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYoIU8gfHwgaW5kZXggPj0gTy5sZW5ndGgpe1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYoa2luZCA9PSAna2V5cycgIClyZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmKGtpbmQgPT0gJ3ZhbHVlcycpcmV0dXJuIHN0ZXAoMCwgT1tpbmRleF0pO1xuICByZXR1cm4gc3RlcCgwLCBbaW5kZXgsIE9baW5kZXhdXSk7XG59LCAndmFsdWVzJyk7XG5cbi8vIGFyZ3VtZW50c0xpc3RbQEBpdGVyYXRvcl0gaXMgJUFycmF5UHJvdG9fdmFsdWVzJSAoOS40LjQuNiwgOS40LjQuNylcbkl0ZXJhdG9ycy5Bcmd1bWVudHMgPSBJdGVyYXRvcnMuQXJyYXk7XG5cbmFkZFRvVW5zY29wYWJsZXMoJ2tleXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ3ZhbHVlcycpO1xuYWRkVG9VbnNjb3BhYmxlcygnZW50cmllcycpOyIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUuam9pbihzZXBhcmF0b3IpXG52YXIgJGV4cG9ydCAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCBhcnJheUpvaW4gPSBbXS5qb2luO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAocmVxdWlyZSgnLi9faW9iamVjdCcpICE9IE9iamVjdCB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKGFycmF5Sm9pbikpLCAnQXJyYXknLCB7XG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKXtcbiAgICByZXR1cm4gYXJyYXlKb2luLmNhbGwodG9JT2JqZWN0KHRoaXMpLCBzZXBhcmF0b3IgPT09IHVuZGVmaW5lZCA/ICcsJyA6IHNlcGFyYXRvcik7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b0lPYmplY3QgICAgID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXG4gICwgdG9JbnRlZ2VyICAgICA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAsIHRvTGVuZ3RoICAgICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsICRuYXRpdmUgICAgICAgPSBbXS5sYXN0SW5kZXhPZlxuICAsIE5FR0FUSVZFX1pFUk8gPSAhISRuYXRpdmUgJiYgMSAvIFsxXS5sYXN0SW5kZXhPZigxLCAtMCkgPCAwO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJG5hdGl2ZSkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xNCAvIDE1LjQuNC4xNSBBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCBbLCBmcm9tSW5kZXhdKVxuICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiwgZnJvbUluZGV4ID0gQFsqLTFdICovKXtcbiAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgaWYoTkVHQVRJVkVfWkVSTylyZXR1cm4gJG5hdGl2ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IDA7XG4gICAgdmFyIE8gICAgICA9IHRvSU9iamVjdCh0aGlzKVxuICAgICAgLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aClcbiAgICAgICwgaW5kZXggID0gbGVuZ3RoIC0gMTtcbiAgICBpZihhcmd1bWVudHMubGVuZ3RoID4gMSlpbmRleCA9IE1hdGgubWluKGluZGV4LCB0b0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgaWYoaW5kZXggPCAwKWluZGV4ID0gbGVuZ3RoICsgaW5kZXg7XG4gICAgZm9yKDtpbmRleCA+PSAwOyBpbmRleC0tKWlmKGluZGV4IGluIE8paWYoT1tpbmRleF0gPT09IHNlYXJjaEVsZW1lbnQpcmV0dXJuIGluZGV4IHx8IDA7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJG1hcCAgICA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSgxKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLm1hcCwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjE1IC8gMTUuNC40LjE5IEFycmF5LnByb3RvdHlwZS5tYXAoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgbWFwOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pe1xuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcblxuLy8gV2ViS2l0IEFycmF5Lm9mIGlzbid0IGdlbmVyaWNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICBmdW5jdGlvbiBGKCl7fVxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XG59KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMyBBcnJheS5vZiggLi4uaXRlbXMpXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKXtcbiAgICB2YXIgaW5kZXggID0gMFxuICAgICAgLCBhTGVuICAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgICAsIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XG4gICAgd2hpbGUoYUxlbiA+IGluZGV4KWNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIGFyZ3VtZW50c1tpbmRleCsrXSk7XG4gICAgcmVzdWx0Lmxlbmd0aCA9IGFMZW47XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRyZWR1Y2UgPSByZXF1aXJlKCcuL19hcnJheS1yZWR1Y2UnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKFtdLnJlZHVjZVJpZ2h0LCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTkgLyAxNS40LjQuMjIgQXJyYXkucHJvdG90eXBlLnJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pe1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkcmVkdWNlID0gcmVxdWlyZSgnLi9fYXJyYXktcmVkdWNlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOCAvIDE1LjQuNC4yMSBBcnJheS5wcm90b3R5cGUucmVkdWNlKGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLyl7XG4gICAgcmV0dXJuICRyZWR1Y2UodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCwgYXJndW1lbnRzWzFdLCBmYWxzZSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBodG1sICAgICAgID0gcmVxdWlyZSgnLi9faHRtbCcpXG4gICwgY29mICAgICAgICA9IHJlcXVpcmUoJy4vX2NvZicpXG4gICwgdG9JbmRleCAgICA9IHJlcXVpcmUoJy4vX3RvLWluZGV4JylcbiAgLCB0b0xlbmd0aCAgID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJylcbiAgLCBhcnJheVNsaWNlID0gW10uc2xpY2U7XG5cbi8vIGZhbGxiYWNrIGZvciBub3QgYXJyYXktbGlrZSBFUzMgc3RyaW5ncyBhbmQgRE9NIG9iamVjdHNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICBpZihodG1sKWFycmF5U2xpY2UuY2FsbChodG1sKTtcbn0pLCAnQXJyYXknLCB7XG4gIHNsaWNlOiBmdW5jdGlvbiBzbGljZShiZWdpbiwgZW5kKXtcbiAgICB2YXIgbGVuICAgPSB0b0xlbmd0aCh0aGlzLmxlbmd0aClcbiAgICAgICwga2xhc3MgPSBjb2YodGhpcyk7XG4gICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQ7XG4gICAgaWYoa2xhc3MgPT0gJ0FycmF5JylyZXR1cm4gYXJyYXlTbGljZS5jYWxsKHRoaXMsIGJlZ2luLCBlbmQpO1xuICAgIHZhciBzdGFydCAgPSB0b0luZGV4KGJlZ2luLCBsZW4pXG4gICAgICAsIHVwVG8gICA9IHRvSW5kZXgoZW5kLCBsZW4pXG4gICAgICAsIHNpemUgICA9IHRvTGVuZ3RoKHVwVG8gLSBzdGFydClcbiAgICAgICwgY2xvbmVkID0gQXJyYXkoc2l6ZSlcbiAgICAgICwgaSAgICAgID0gMDtcbiAgICBmb3IoOyBpIDwgc2l6ZTsgaSsrKWNsb25lZFtpXSA9IGtsYXNzID09ICdTdHJpbmcnXG4gICAgICA/IHRoaXMuY2hhckF0KHN0YXJ0ICsgaSlcbiAgICAgIDogdGhpc1tzdGFydCArIGldO1xuICAgIHJldHVybiBjbG9uZWQ7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkc29tZSAgID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDMpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uc29tZSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjIzIC8gMTUuNC40LjE3IEFycmF5LnByb3RvdHlwZS5zb21lKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pe1xuICAgIHJldHVybiAkc29tZSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCB0b09iamVjdCAgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIGZhaWxzICAgICA9IHJlcXVpcmUoJy4vX2ZhaWxzJylcbiAgLCAkc29ydCAgICAgPSBbXS5zb3J0XG4gICwgdGVzdCAgICAgID0gWzEsIDIsIDNdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChmYWlscyhmdW5jdGlvbigpe1xuICAvLyBJRTgtXG4gIHRlc3Quc29ydCh1bmRlZmluZWQpO1xufSkgfHwgIWZhaWxzKGZ1bmN0aW9uKCl7XG4gIC8vIFY4IGJ1Z1xuICB0ZXN0LnNvcnQobnVsbCk7XG4gIC8vIE9sZCBXZWJLaXRcbn0pIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJHNvcnQpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMjUgQXJyYXkucHJvdG90eXBlLnNvcnQoY29tcGFyZWZuKVxuICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbil7XG4gICAgcmV0dXJuIGNvbXBhcmVmbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXG4gICAgICA6ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcyksIGFGdW5jdGlvbihjb21wYXJlZm4pKTtcbiAgfVxufSk7IiwicmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKSgnQXJyYXknKTsiLCIvLyAyMC4zLjMuMSAvIDE1LjkuNC40IERhdGUubm93KClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnRGF0ZScsIHtub3c6IGZ1bmN0aW9uKCl7IHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTsgfX0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIDIwLjMuNC4zNiAvIDE1LjkuNS40MyBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZygpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZmFpbHMgICA9IHJlcXVpcmUoJy4vX2ZhaWxzJylcbiAgLCBnZXRUaW1lID0gRGF0ZS5wcm90b3R5cGUuZ2V0VGltZTtcblxudmFyIGx6ID0gZnVuY3Rpb24obnVtKXtcbiAgcmV0dXJuIG51bSA+IDkgPyBudW0gOiAnMCcgKyBudW07XG59O1xuXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKGZhaWxzKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBuZXcgRGF0ZSgtNWUxMyAtIDEpLnRvSVNPU3RyaW5nKCkgIT0gJzAzODUtMDctMjVUMDc6MDY6MzkuOTk5Wic7XG59KSB8fCAhZmFpbHMoZnVuY3Rpb24oKXtcbiAgbmV3IERhdGUoTmFOKS50b0lTT1N0cmluZygpO1xufSkpLCAnRGF0ZScsIHtcbiAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCl7XG4gICAgaWYoIWlzRmluaXRlKGdldFRpbWUuY2FsbCh0aGlzKSkpdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCB0aW1lIHZhbHVlJyk7XG4gICAgdmFyIGQgPSB0aGlzXG4gICAgICAsIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKClcbiAgICAgICwgbSA9IGQuZ2V0VVRDTWlsbGlzZWNvbmRzKClcbiAgICAgICwgcyA9IHkgPCAwID8gJy0nIDogeSA+IDk5OTkgPyAnKycgOiAnJztcbiAgICByZXR1cm4gcyArICgnMDAwMDAnICsgTWF0aC5hYnMoeSkpLnNsaWNlKHMgPyAtNiA6IC00KSArXG4gICAgICAnLScgKyBseihkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIGx6KGQuZ2V0VVRDRGF0ZSgpKSArXG4gICAgICAnVCcgKyBseihkLmdldFVUQ0hvdXJzKCkpICsgJzonICsgbHooZC5nZXRVVENNaW51dGVzKCkpICtcbiAgICAgICc6JyArIGx6KGQuZ2V0VVRDU2Vjb25kcygpKSArICcuJyArIChtID4gOTkgPyBtIDogJzAnICsgbHoobSkpICsgJ1onO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHRvT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0JylcbiAgLCB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIG5ldyBEYXRlKE5hTikudG9KU09OKCkgIT09IG51bGwgfHwgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoe3RvSVNPU3RyaW5nOiBmdW5jdGlvbigpeyByZXR1cm4gMTsgfX0pICE9PSAxO1xufSksICdEYXRlJywge1xuICB0b0pTT046IGZ1bmN0aW9uIHRvSlNPTihrZXkpe1xuICAgIHZhciBPICA9IHRvT2JqZWN0KHRoaXMpXG4gICAgICAsIHB2ID0gdG9QcmltaXRpdmUoTyk7XG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcbiAgfVxufSk7IiwidmFyIFRPX1BSSU1JVElWRSA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1ByaW1pdGl2ZScpXG4gICwgcHJvdG8gICAgICAgID0gRGF0ZS5wcm90b3R5cGU7XG5cbmlmKCEoVE9fUFJJTUlUSVZFIGluIHByb3RvKSlyZXF1aXJlKCcuL19oaWRlJykocHJvdG8sIFRPX1BSSU1JVElWRSwgcmVxdWlyZSgnLi9fZGF0ZS10by1wcmltaXRpdmUnKSk7IiwidmFyIERhdGVQcm90byAgICA9IERhdGUucHJvdG90eXBlXG4gICwgSU5WQUxJRF9EQVRFID0gJ0ludmFsaWQgRGF0ZSdcbiAgLCBUT19TVFJJTkcgICAgPSAndG9TdHJpbmcnXG4gICwgJHRvU3RyaW5nICAgID0gRGF0ZVByb3RvW1RPX1NUUklOR11cbiAgLCBnZXRUaW1lICAgICAgPSBEYXRlUHJvdG8uZ2V0VGltZTtcbmlmKG5ldyBEYXRlKE5hTikgKyAnJyAhPSBJTlZBTElEX0RBVEUpe1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKERhdGVQcm90bywgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpe1xuICAgIHZhciB2YWx1ZSA9IGdldFRpbWUuY2FsbCh0aGlzKTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XG4gIH0pO1xufSIsIi8vIDE5LjIuMy4yIC8gMTUuMy40LjUgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQodGhpc0FyZywgYXJncy4uLilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnRnVuY3Rpb24nLCB7YmluZDogcmVxdWlyZSgnLi9fYmluZCcpfSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGlzT2JqZWN0ICAgICAgID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIEhBU19JTlNUQU5DRSAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2hhc0luc3RhbmNlJylcbiAgLCBGdW5jdGlvblByb3RvICA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxuaWYoIShIQVNfSU5TVEFOQ0UgaW4gRnVuY3Rpb25Qcm90bykpcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihGdW5jdGlvblByb3RvLCBIQVNfSU5TVEFOQ0UsIHt2YWx1ZTogZnVuY3Rpb24oTyl7XG4gIGlmKHR5cGVvZiB0aGlzICE9ICdmdW5jdGlvbicgfHwgIWlzT2JqZWN0KE8pKXJldHVybiBmYWxzZTtcbiAgaWYoIWlzT2JqZWN0KHRoaXMucHJvdG90eXBlKSlyZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XG4gIC8vIGZvciBlbnZpcm9ubWVudCB3L28gbmF0aXZlIGBAQGhhc0luc3RhbmNlYCBsb2dpYyBlbm91Z2ggYGluc3RhbmNlb2ZgLCBidXQgYWRkIHRoaXM6XG4gIHdoaWxlKE8gPSBnZXRQcm90b3R5cGVPZihPKSlpZih0aGlzLnByb3RvdHlwZSA9PT0gTylyZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufX0pOyIsInZhciBkUCAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZlxuICAsIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJylcbiAgLCBoYXMgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBGUHJvdG8gICAgID0gRnVuY3Rpb24ucHJvdG90eXBlXG4gICwgbmFtZVJFICAgICA9IC9eXFxzKmZ1bmN0aW9uIChbXiAoXSopL1xuICAsIE5BTUUgICAgICAgPSAnbmFtZSc7XG5cbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlIHx8IGZ1bmN0aW9uKCl7XG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gMTkuMi40LjIgbmFtZVxuTkFNRSBpbiBGUHJvdG8gfHwgcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiBkUChGUHJvdG8sIE5BTUUsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCl7XG4gICAgdHJ5IHtcbiAgICAgIHZhciB0aGF0ID0gdGhpc1xuICAgICAgICAsIG5hbWUgPSAoJycgKyB0aGF0KS5tYXRjaChuYW1lUkUpWzFdO1xuICAgICAgaGFzKHRoYXQsIE5BTUUpIHx8ICFpc0V4dGVuc2libGUodGhhdCkgfHwgZFAodGhhdCwgTkFNRSwgY3JlYXRlRGVzYyg1LCBuYW1lKSk7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG5cbi8vIDIzLjEgTWFwIE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKCdNYXAnLCBmdW5jdGlvbihnZXQpe1xuICByZXR1cm4gZnVuY3Rpb24gTWFwKCl7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSl7XG4gICAgdmFyIGVudHJ5ID0gc3Ryb25nLmdldEVudHJ5KHRoaXMsIGtleSk7XG4gICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5LnY7XG4gIH0sXG4gIC8vIDIzLjEuMy45IE1hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpe1xuICAgIHJldHVybiBzdHJvbmcuZGVmKHRoaXMsIGtleSA9PT0gMCA/IDAgOiBrZXksIHZhbHVlKTtcbiAgfVxufSwgc3Ryb25nLCB0cnVlKTsiLCIvLyAyMC4yLjIuMyBNYXRoLmFjb3NoKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgbG9nMXAgICA9IHJlcXVpcmUoJy4vX21hdGgtbG9nMXAnKVxuICAsIHNxcnQgICAgPSBNYXRoLnNxcnRcbiAgLCAkYWNvc2ggID0gTWF0aC5hY29zaDtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhY29zaFxuICAvLyBWOCBidWc6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zNTA5XG4gICYmIE1hdGguZmxvb3IoJGFjb3NoKE51bWJlci5NQVhfVkFMVUUpKSA9PSA3MTBcbiAgLy8gVG9yIEJyb3dzZXIgYnVnOiBNYXRoLmFjb3NoKEluZmluaXR5KSAtPiBOYU4gXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcbiksICdNYXRoJywge1xuICBhY29zaDogZnVuY3Rpb24gYWNvc2goeCl7XG4gICAgcmV0dXJuICh4ID0gK3gpIDwgMSA/IE5hTiA6IHggPiA5NDkwNjI2NS42MjQyNTE1NlxuICAgICAgPyBNYXRoLmxvZyh4KSArIE1hdGguTE4yXG4gICAgICA6IGxvZzFwKHggLSAxICsgc3FydCh4IC0gMSkgKiBzcXJ0KHggKyAxKSk7XG4gIH1cbn0pOyIsIi8vIDIwLjIuMi41IE1hdGguYXNpbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkYXNpbmggID0gTWF0aC5hc2luaDtcblxuZnVuY3Rpb24gYXNpbmgoeCl7XG4gIHJldHVybiAhaXNGaW5pdGUoeCA9ICt4KSB8fCB4ID09IDAgPyB4IDogeCA8IDAgPyAtYXNpbmgoLXgpIDogTWF0aC5sb2coeCArIE1hdGguc3FydCh4ICogeCArIDEpKTtcbn1cblxuLy8gVG9yIEJyb3dzZXIgYnVnOiBNYXRoLmFzaW5oKDApIC0+IC0wIFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhc2luaCAmJiAxIC8gJGFzaW5oKDApID4gMCksICdNYXRoJywge2FzaW5oOiBhc2luaH0pOyIsIi8vIDIwLjIuMi43IE1hdGguYXRhbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkYXRhbmggID0gTWF0aC5hdGFuaDtcblxuLy8gVG9yIEJyb3dzZXIgYnVnOiBNYXRoLmF0YW5oKC0wKSAtPiAwIFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcbiAgYXRhbmg6IGZ1bmN0aW9uIGF0YW5oKHgpe1xuICAgIHJldHVybiAoeCA9ICt4KSA9PSAwID8geCA6IE1hdGgubG9nKCgxICsgeCkgLyAoMSAtIHgpKSAvIDI7XG4gIH1cbn0pOyIsIi8vIDIwLjIuMi45IE1hdGguY2JydCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHNpZ24gICAgPSByZXF1aXJlKCcuL19tYXRoLXNpZ24nKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjYnJ0OiBmdW5jdGlvbiBjYnJ0KHgpe1xuICAgIHJldHVybiBzaWduKHggPSAreCkgKiBNYXRoLnBvdyhNYXRoLmFicyh4KSwgMSAvIDMpO1xuICB9XG59KTsiLCIvLyAyMC4yLjIuMTEgTWF0aC5jbHozMih4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjbHozMjogZnVuY3Rpb24gY2x6MzIoeCl7XG4gICAgcmV0dXJuICh4ID4+Pj0gMCkgPyAzMSAtIE1hdGguZmxvb3IoTWF0aC5sb2coeCArIDAuNSkgKiBNYXRoLkxPRzJFKSA6IDMyO1xuICB9XG59KTsiLCIvLyAyMC4yLjIuMTIgTWF0aC5jb3NoKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZXhwICAgICA9IE1hdGguZXhwO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGNvc2g6IGZ1bmN0aW9uIGNvc2goeCl7XG4gICAgcmV0dXJuIChleHAoeCA9ICt4KSArIGV4cCgteCkpIC8gMjtcbiAgfVxufSk7IiwiLy8gMjAuMi4yLjE0IE1hdGguZXhwbTEoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkZXhwbTEgID0gcmVxdWlyZSgnLi9fbWF0aC1leHBtMScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICgkZXhwbTEgIT0gTWF0aC5leHBtMSksICdNYXRoJywge2V4cG0xOiAkZXhwbTF9KTsiLCIvLyAyMC4yLjIuMTYgTWF0aC5mcm91bmQoeClcbnZhciAkZXhwb3J0ICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHNpZ24gICAgICA9IHJlcXVpcmUoJy4vX21hdGgtc2lnbicpXG4gICwgcG93ICAgICAgID0gTWF0aC5wb3dcbiAgLCBFUFNJTE9OICAgPSBwb3coMiwgLTUyKVxuICAsIEVQU0lMT04zMiA9IHBvdygyLCAtMjMpXG4gICwgTUFYMzIgICAgID0gcG93KDIsIDEyNykgKiAoMiAtIEVQU0lMT04zMilcbiAgLCBNSU4zMiAgICAgPSBwb3coMiwgLTEyNik7XG5cbnZhciByb3VuZFRpZXNUb0V2ZW4gPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG4gKyAxIC8gRVBTSUxPTiAtIDEgLyBFUFNJTE9OO1xufTtcblxuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGZyb3VuZDogZnVuY3Rpb24gZnJvdW5kKHgpe1xuICAgIHZhciAkYWJzICA9IE1hdGguYWJzKHgpXG4gICAgICAsICRzaWduID0gc2lnbih4KVxuICAgICAgLCBhLCByZXN1bHQ7XG4gICAgaWYoJGFicyA8IE1JTjMyKXJldHVybiAkc2lnbiAqIHJvdW5kVGllc1RvRXZlbigkYWJzIC8gTUlOMzIgLyBFUFNJTE9OMzIpICogTUlOMzIgKiBFUFNJTE9OMzI7XG4gICAgYSA9ICgxICsgRVBTSUxPTjMyIC8gRVBTSUxPTikgKiAkYWJzO1xuICAgIHJlc3VsdCA9IGEgLSAoYSAtICRhYnMpO1xuICAgIGlmKHJlc3VsdCA+IE1BWDMyIHx8IHJlc3VsdCAhPSByZXN1bHQpcmV0dXJuICRzaWduICogSW5maW5pdHk7XG4gICAgcmV0dXJuICRzaWduICogcmVzdWx0O1xuICB9XG59KTsiLCIvLyAyMC4yLjIuMTcgTWF0aC5oeXBvdChbdmFsdWUxWywgdmFsdWUyWywg4oCmIF1dXSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBhYnMgICAgID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaHlwb3Q6IGZ1bmN0aW9uIGh5cG90KHZhbHVlMSwgdmFsdWUyKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHZhciBzdW0gID0gMFxuICAgICAgLCBpICAgID0gMFxuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCBsYXJnID0gMFxuICAgICAgLCBhcmcsIGRpdjtcbiAgICB3aGlsZShpIDwgYUxlbil7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYobGFyZyA8IGFyZyl7XG4gICAgICAgIGRpdiAgPSBsYXJnIC8gYXJnO1xuICAgICAgICBzdW0gID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZihhcmcgPiAwKXtcbiAgICAgICAgZGl2ICA9IGFyZyAvIGxhcmc7XG4gICAgICAgIHN1bSArPSBkaXYgKiBkaXY7XG4gICAgICB9IGVsc2Ugc3VtICs9IGFyZztcbiAgICB9XG4gICAgcmV0dXJuIGxhcmcgPT09IEluZmluaXR5ID8gSW5maW5pdHkgOiBsYXJnICogTWF0aC5zcXJ0KHN1bSk7XG4gIH1cbn0pOyIsIi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkaW11bCAgID0gTWF0aC5pbXVsO1xuXG4vLyBzb21lIFdlYktpdCB2ZXJzaW9ucyBmYWlscyB3aXRoIGJpZyBudW1iZXJzLCBzb21lIGhhcyB3cm9uZyBhcml0eVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHJldHVybiAkaW11bCgweGZmZmZmZmZmLCA1KSAhPSAtNSB8fCAkaW11bC5sZW5ndGggIT0gMjtcbn0pLCAnTWF0aCcsIHtcbiAgaW11bDogZnVuY3Rpb24gaW11bCh4LCB5KXtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmXG4gICAgICAsIHhuID0gK3hcbiAgICAgICwgeW4gPSAreVxuICAgICAgLCB4bCA9IFVJTlQxNiAmIHhuXG4gICAgICAsIHlsID0gVUlOVDE2ICYgeW47XG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcbiAgfVxufSk7IiwiLy8gMjAuMi4yLjIxIE1hdGgubG9nMTAoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgbG9nMTA6IGZ1bmN0aW9uIGxvZzEwKHgpe1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4xMDtcbiAgfVxufSk7IiwiLy8gMjAuMi4yLjIwIE1hdGgubG9nMXAoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtsb2cxcDogcmVxdWlyZSgnLi9fbWF0aC1sb2cxcCcpfSk7IiwiLy8gMjAuMi4yLjIyIE1hdGgubG9nMih4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cyOiBmdW5jdGlvbiBsb2cyKHgpe1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4yO1xuICB9XG59KTsiLCIvLyAyMC4yLjIuMjggTWF0aC5zaWduKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7c2lnbjogcmVxdWlyZSgnLi9fbWF0aC1zaWduJyl9KTsiLCIvLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZXhwbTEgICA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKVxuICAsIGV4cCAgICAgPSBNYXRoLmV4cDtcblxuLy8gVjggbmVhciBDaHJvbWl1bSAzOCBoYXMgYSBwcm9ibGVtIHdpdGggdmVyeSBzbWFsbCBudW1iZXJzXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuICFNYXRoLnNpbmgoLTJlLTE3KSAhPSAtMmUtMTc7XG59KSwgJ01hdGgnLCB7XG4gIHNpbmg6IGZ1bmN0aW9uIHNpbmgoeCl7XG4gICAgcmV0dXJuIE1hdGguYWJzKHggPSAreCkgPCAxXG4gICAgICA/IChleHBtMSh4KSAtIGV4cG0xKC14KSkgLyAyXG4gICAgICA6IChleHAoeCAtIDEpIC0gZXhwKC14IC0gMSkpICogKE1hdGguRSAvIDIpO1xuICB9XG59KTsiLCIvLyAyMC4yLjIuMzMgTWF0aC50YW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZXhwbTEgICA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKVxuICAsIGV4cCAgICAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0YW5oOiBmdW5jdGlvbiB0YW5oKHgpe1xuICAgIHZhciBhID0gZXhwbTEoeCA9ICt4KVxuICAgICAgLCBiID0gZXhwbTEoLXgpO1xuICAgIHJldHVybiBhID09IEluZmluaXR5ID8gMSA6IGIgPT0gSW5maW5pdHkgPyAtMSA6IChhIC0gYikgLyAoZXhwKHgpICsgZXhwKC14KSk7XG4gIH1cbn0pOyIsIi8vIDIwLjIuMi4zNCBNYXRoLnRydW5jKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIHRydW5jOiBmdW5jdGlvbiB0cnVuYyhpdCl7XG4gICAgcmV0dXJuIChpdCA+IDAgPyBNYXRoLmZsb29yIDogTWF0aC5jZWlsKShpdCk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGFzICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIGNvZiAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY29mJylcbiAgLCBpbmhlcml0SWZSZXF1aXJlZCA9IHJlcXVpcmUoJy4vX2luaGVyaXQtaWYtcmVxdWlyZWQnKVxuICAsIHRvUHJpbWl0aXZlICAgICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcbiAgLCBmYWlscyAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2ZhaWxzJylcbiAgLCBnT1BOICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZlxuICAsIGdPUEQgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mXG4gICwgZFAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgJHRyaW0gICAgICAgICAgICAgPSByZXF1aXJlKCcuL19zdHJpbmctdHJpbScpLnRyaW1cbiAgLCBOVU1CRVIgICAgICAgICAgICA9ICdOdW1iZXInXG4gICwgJE51bWJlciAgICAgICAgICAgPSBnbG9iYWxbTlVNQkVSXVxuICAsIEJhc2UgICAgICAgICAgICAgID0gJE51bWJlclxuICAsIHByb3RvICAgICAgICAgICAgID0gJE51bWJlci5wcm90b3R5cGVcbiAgLy8gT3BlcmEgfjEyIGhhcyBicm9rZW4gT2JqZWN0I3RvU3RyaW5nXG4gICwgQlJPS0VOX0NPRiAgICAgICAgPSBjb2YocmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpKHByb3RvKSkgPT0gTlVNQkVSXG4gICwgVFJJTSAgICAgICAgICAgICAgPSAndHJpbScgaW4gU3RyaW5nLnByb3RvdHlwZTtcblxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXG52YXIgdG9OdW1iZXIgPSBmdW5jdGlvbihhcmd1bWVudCl7XG4gIHZhciBpdCA9IHRvUHJpbWl0aXZlKGFyZ3VtZW50LCBmYWxzZSk7XG4gIGlmKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKXtcbiAgICBpdCA9IFRSSU0gPyBpdC50cmltKCkgOiAkdHJpbShpdCwgMyk7XG4gICAgdmFyIGZpcnN0ID0gaXQuY2hhckNvZGVBdCgwKVxuICAgICAgLCB0aGlyZCwgcmFkaXgsIG1heENvZGU7XG4gICAgaWYoZmlyc3QgPT09IDQzIHx8IGZpcnN0ID09PSA0NSl7XG4gICAgICB0aGlyZCA9IGl0LmNoYXJDb2RlQXQoMik7XG4gICAgICBpZih0aGlyZCA9PT0gODggfHwgdGhpcmQgPT09IDEyMClyZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XG4gICAgfSBlbHNlIGlmKGZpcnN0ID09PSA0OCl7XG4gICAgICBzd2l0Y2goaXQuY2hhckNvZGVBdCgxKSl7XG4gICAgICAgIGNhc2UgNjYgOiBjYXNlIDk4ICA6IHJhZGl4ID0gMjsgbWF4Q29kZSA9IDQ5OyBicmVhazsgLy8gZmFzdCBlcXVhbCAvXjBiWzAxXSskL2lcbiAgICAgICAgY2FzZSA3OSA6IGNhc2UgMTExIDogcmFkaXggPSA4OyBtYXhDb2RlID0gNTU7IGJyZWFrOyAvLyBmYXN0IGVxdWFsIC9eMG9bMC03XSskL2lcbiAgICAgICAgZGVmYXVsdCA6IHJldHVybiAraXQ7XG4gICAgICB9XG4gICAgICBmb3IodmFyIGRpZ2l0cyA9IGl0LnNsaWNlKDIpLCBpID0gMCwgbCA9IGRpZ2l0cy5sZW5ndGgsIGNvZGU7IGkgPCBsOyBpKyspe1xuICAgICAgICBjb2RlID0gZGlnaXRzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxuICAgICAgICAvLyBidXQgVG9OdW1iZXIgc2hvdWxkIHJldHVybiBOYU4gaWYgYSBzdHJpbmcgY29udGFpbnMgdW5hdmFpbGFibGUgc3ltYm9sc1xuICAgICAgICBpZihjb2RlIDwgNDggfHwgY29kZSA+IG1heENvZGUpcmV0dXJuIE5hTjtcbiAgICAgIH0gcmV0dXJuIHBhcnNlSW50KGRpZ2l0cywgcmFkaXgpO1xuICAgIH1cbiAgfSByZXR1cm4gK2l0O1xufTtcblxuaWYoISROdW1iZXIoJyAwbzEnKSB8fCAhJE51bWJlcignMGIxJykgfHwgJE51bWJlcignKzB4MScpKXtcbiAgJE51bWJlciA9IGZ1bmN0aW9uIE51bWJlcih2YWx1ZSl7XG4gICAgdmFyIGl0ID0gYXJndW1lbnRzLmxlbmd0aCA8IDEgPyAwIDogdmFsdWVcbiAgICAgICwgdGhhdCA9IHRoaXM7XG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXG4gICAgICAvLyBjaGVjayBvbiAxLi5jb25zdHJ1Y3Rvcihmb28pIGNhc2VcbiAgICAgICYmIChCUk9LRU5fQ09GID8gZmFpbHMoZnVuY3Rpb24oKXsgcHJvdG8udmFsdWVPZi5jYWxsKHRoYXQpOyB9KSA6IGNvZih0aGF0KSAhPSBOVU1CRVIpXG4gICAgICAgID8gaW5oZXJpdElmUmVxdWlyZWQobmV3IEJhc2UodG9OdW1iZXIoaXQpKSwgdGhhdCwgJE51bWJlcikgOiB0b051bWJlcihpdCk7XG4gIH07XG4gIGZvcih2YXIga2V5cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BOKEJhc2UpIDogKFxuICAgIC8vIEVTMzpcbiAgICAnTUFYX1ZBTFVFLE1JTl9WQUxVRSxOYU4sTkVHQVRJVkVfSU5GSU5JVFksUE9TSVRJVkVfSU5GSU5JVFksJyArXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XG4gICAgJ0VQU0lMT04saXNGaW5pdGUsaXNJbnRlZ2VyLGlzTmFOLGlzU2FmZUludGVnZXIsTUFYX1NBRkVfSU5URUdFUiwnICtcbiAgICAnTUlOX1NBRkVfSU5URUdFUixwYXJzZUZsb2F0LHBhcnNlSW50LGlzSW50ZWdlcidcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKyl7XG4gICAgaWYoaGFzKEJhc2UsIGtleSA9IGtleXNbal0pICYmICFoYXMoJE51bWJlciwga2V5KSl7XG4gICAgICBkUCgkTnVtYmVyLCBrZXksIGdPUEQoQmFzZSwga2V5KSk7XG4gICAgfVxuICB9XG4gICROdW1iZXIucHJvdG90eXBlID0gcHJvdG87XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsIE5VTUJFUiwgJE51bWJlcik7XG59IiwiLy8gMjAuMS4yLjEgTnVtYmVyLkVQU0lMT05cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge0VQU0lMT046IE1hdGgucG93KDIsIC01Mil9KTsiLCIvLyAyMC4xLjIuMiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKVxudmFyICRleHBvcnQgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgX2lzRmluaXRlID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuaXNGaW5pdGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge1xuICBpc0Zpbml0ZTogZnVuY3Rpb24gaXNGaW5pdGUoaXQpe1xuICAgIHJldHVybiB0eXBlb2YgaXQgPT0gJ251bWJlcicgJiYgX2lzRmluaXRlKGl0KTtcbiAgfVxufSk7IiwiLy8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtpc0ludGVnZXI6IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKX0pOyIsIi8vIDIwLjEuMi40IE51bWJlci5pc05hTihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcil7XG4gICAgcmV0dXJuIG51bWJlciAhPSBudW1iZXI7XG4gIH1cbn0pOyIsIi8vIDIwLjEuMi41IE51bWJlci5pc1NhZmVJbnRlZ2VyKG51bWJlcilcbnZhciAkZXhwb3J0ICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGlzSW50ZWdlciA9IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKVxuICAsIGFicyAgICAgICA9IE1hdGguYWJzO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNTYWZlSW50ZWdlcjogZnVuY3Rpb24gaXNTYWZlSW50ZWdlcihudW1iZXIpe1xuICAgIHJldHVybiBpc0ludGVnZXIobnVtYmVyKSAmJiBhYnMobnVtYmVyKSA8PSAweDFmZmZmZmZmZmZmZmZmO1xuICB9XG59KTsiLCIvLyAyMC4xLjIuNiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7TUFYX1NBRkVfSU5URUdFUjogMHgxZmZmZmZmZmZmZmZmZn0pOyIsIi8vIDIwLjEuMi4xMCBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7TUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmZ9KTsiLCJ2YXIgJGV4cG9ydCAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDIwLjEuMi4xMiBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksICdOdW1iZXInLCB7cGFyc2VGbG9hdDogJHBhcnNlRmxvYXR9KTsiLCJ2YXIgJGV4cG9ydCAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDIwLjEuMi4xMyBOdW1iZXIucGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE51bWJlci5wYXJzZUludCAhPSAkcGFyc2VJbnQpLCAnTnVtYmVyJywge3BhcnNlSW50OiAkcGFyc2VJbnR9KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b0ludGVnZXIgICAgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJylcbiAgLCBhTnVtYmVyVmFsdWUgPSByZXF1aXJlKCcuL19hLW51bWJlci12YWx1ZScpXG4gICwgcmVwZWF0ICAgICAgID0gcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpXG4gICwgJHRvRml4ZWQgICAgID0gMS4udG9GaXhlZFxuICAsIGZsb29yICAgICAgICA9IE1hdGguZmxvb3JcbiAgLCBkYXRhICAgICAgICAgPSBbMCwgMCwgMCwgMCwgMCwgMF1cbiAgLCBFUlJPUiAgICAgICAgPSAnTnVtYmVyLnRvRml4ZWQ6IGluY29ycmVjdCBpbnZvY2F0aW9uISdcbiAgLCBaRVJPICAgICAgICAgPSAnMCc7XG5cbnZhciBtdWx0aXBseSA9IGZ1bmN0aW9uKG4sIGMpe1xuICB2YXIgaSAgPSAtMVxuICAgICwgYzIgPSBjO1xuICB3aGlsZSgrK2kgPCA2KXtcbiAgICBjMiArPSBuICogZGF0YVtpXTtcbiAgICBkYXRhW2ldID0gYzIgJSAxZTc7XG4gICAgYzIgPSBmbG9vcihjMiAvIDFlNyk7XG4gIH1cbn07XG52YXIgZGl2aWRlID0gZnVuY3Rpb24obil7XG4gIHZhciBpID0gNlxuICAgICwgYyA9IDA7XG4gIHdoaWxlKC0taSA+PSAwKXtcbiAgICBjICs9IGRhdGFbaV07XG4gICAgZGF0YVtpXSA9IGZsb29yKGMgLyBuKTtcbiAgICBjID0gKGMgJSBuKSAqIDFlNztcbiAgfVxufTtcbnZhciBudW1Ub1N0cmluZyA9IGZ1bmN0aW9uKCl7XG4gIHZhciBpID0gNlxuICAgICwgcyA9ICcnO1xuICB3aGlsZSgtLWkgPj0gMCl7XG4gICAgaWYocyAhPT0gJycgfHwgaSA9PT0gMCB8fCBkYXRhW2ldICE9PSAwKXtcbiAgICAgIHZhciB0ID0gU3RyaW5nKGRhdGFbaV0pO1xuICAgICAgcyA9IHMgPT09ICcnID8gdCA6IHMgKyByZXBlYXQuY2FsbChaRVJPLCA3IC0gdC5sZW5ndGgpICsgdDtcbiAgICB9XG4gIH0gcmV0dXJuIHM7XG59O1xudmFyIHBvdyA9IGZ1bmN0aW9uKHgsIG4sIGFjYyl7XG4gIHJldHVybiBuID09PSAwID8gYWNjIDogbiAlIDIgPT09IDEgPyBwb3coeCwgbiAtIDEsIGFjYyAqIHgpIDogcG93KHggKiB4LCBuIC8gMiwgYWNjKTtcbn07XG52YXIgbG9nID0gZnVuY3Rpb24oeCl7XG4gIHZhciBuICA9IDBcbiAgICAsIHgyID0geDtcbiAgd2hpbGUoeDIgPj0gNDA5Nil7XG4gICAgbiArPSAxMjtcbiAgICB4MiAvPSA0MDk2O1xuICB9XG4gIHdoaWxlKHgyID49IDIpe1xuICAgIG4gICs9IDE7XG4gICAgeDIgLz0gMjtcbiAgfSByZXR1cm4gbjtcbn07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxuICAwLjAwMDA4LnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgMC45LnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgMTAwMDAwMDAwMDAwMDAwMDEyOC4udG9GaXhlZCgwKSAhPT0gJzEwMDAwMDAwMDAwMDAwMDAxMjgnXG4pIHx8ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b0ZpeGVkLmNhbGwoe30pO1xufSkpLCAnTnVtYmVyJywge1xuICB0b0ZpeGVkOiBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKXtcbiAgICB2YXIgeCA9IGFOdW1iZXJWYWx1ZSh0aGlzLCBFUlJPUilcbiAgICAgICwgZiA9IHRvSW50ZWdlcihmcmFjdGlvbkRpZ2l0cylcbiAgICAgICwgcyA9ICcnXG4gICAgICAsIG0gPSBaRVJPXG4gICAgICAsIGUsIHosIGosIGs7XG4gICAgaWYoZiA8IDAgfHwgZiA+IDIwKXRocm93IFJhbmdlRXJyb3IoRVJST1IpO1xuICAgIGlmKHggIT0geClyZXR1cm4gJ05hTic7XG4gICAgaWYoeCA8PSAtMWUyMSB8fCB4ID49IDFlMjEpcmV0dXJuIFN0cmluZyh4KTtcbiAgICBpZih4IDwgMCl7XG4gICAgICBzID0gJy0nO1xuICAgICAgeCA9IC14O1xuICAgIH1cbiAgICBpZih4ID4gMWUtMjEpe1xuICAgICAgZSA9IGxvZyh4ICogcG93KDIsIDY5LCAxKSkgLSA2OTtcbiAgICAgIHogPSBlIDwgMCA/IHggKiBwb3coMiwgLWUsIDEpIDogeCAvIHBvdygyLCBlLCAxKTtcbiAgICAgIHogKj0gMHgxMDAwMDAwMDAwMDAwMDtcbiAgICAgIGUgPSA1MiAtIGU7XG4gICAgICBpZihlID4gMCl7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBqID0gZjtcbiAgICAgICAgd2hpbGUoaiA+PSA3KXtcbiAgICAgICAgICBtdWx0aXBseSgxZTcsIDApO1xuICAgICAgICAgIGogLT0gNztcbiAgICAgICAgfVxuICAgICAgICBtdWx0aXBseShwb3coMTAsIGosIDEpLCAwKTtcbiAgICAgICAgaiA9IGUgLSAxO1xuICAgICAgICB3aGlsZShqID49IDIzKXtcbiAgICAgICAgICBkaXZpZGUoMSA8PCAyMyk7XG4gICAgICAgICAgaiAtPSAyMztcbiAgICAgICAgfVxuICAgICAgICBkaXZpZGUoMSA8PCBqKTtcbiAgICAgICAgbXVsdGlwbHkoMSwgMSk7XG4gICAgICAgIGRpdmlkZSgyKTtcbiAgICAgICAgbSA9IG51bVRvU3RyaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtdWx0aXBseSgwLCB6KTtcbiAgICAgICAgbXVsdGlwbHkoMSA8PCAtZSwgMCk7XG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpICsgcmVwZWF0LmNhbGwoWkVSTywgZik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmKGYgPiAwKXtcbiAgICAgIGsgPSBtLmxlbmd0aDtcbiAgICAgIG0gPSBzICsgKGsgPD0gZiA/ICcwLicgKyByZXBlYXQuY2FsbChaRVJPLCBmIC0gaykgKyBtIDogbS5zbGljZSgwLCBrIC0gZikgKyAnLicgKyBtLnNsaWNlKGsgLSBmKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBzICsgbTtcbiAgICB9IHJldHVybiBtO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkZmFpbHMgICAgICAgPSByZXF1aXJlKCcuL19mYWlscycpXG4gICwgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKVxuICAsICR0b1ByZWNpc2lvbiA9IDEuLnRvUHJlY2lzaW9uO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICgkZmFpbHMoZnVuY3Rpb24oKXtcbiAgLy8gSUU3LVxuICByZXR1cm4gJHRvUHJlY2lzaW9uLmNhbGwoMSwgdW5kZWZpbmVkKSAhPT0gJzEnO1xufSkgfHwgISRmYWlscyhmdW5jdGlvbigpe1xuICAvLyBWOCB+IEFuZHJvaWQgNC4zLVxuICAkdG9QcmVjaXNpb24uY2FsbCh7fSk7XG59KSksICdOdW1iZXInLCB7XG4gIHRvUHJlY2lzaW9uOiBmdW5jdGlvbiB0b1ByZWNpc2lvbihwcmVjaXNpb24pe1xuICAgIHZhciB0aGF0ID0gYU51bWJlclZhbHVlKHRoaXMsICdOdW1iZXIjdG9QcmVjaXNpb246IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTsgXG4gIH1cbn0pOyIsIi8vIDE5LjEuMy4xIE9iamVjdC5hc3NpZ24odGFyZ2V0LCBzb3VyY2UpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiwgJ09iamVjdCcsIHthc3NpZ246IHJlcXVpcmUoJy4vX29iamVjdC1hc3NpZ24nKX0pOyIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jylcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7Y3JlYXRlOiByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyl9KTsiLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuLy8gMTkuMS4yLjMgLyAxNS4yLjMuNyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSwgJ09iamVjdCcsIHtkZWZpbmVQcm9wZXJ0aWVzOiByZXF1aXJlKCcuL19vYmplY3QtZHBzJyl9KTsiLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuLy8gMTkuMS4yLjQgLyAxNS4yLjMuNiBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7ZGVmaW5lUHJvcGVydHk6IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmZ9KTsiLCIvLyAxOS4xLjIuNSBPYmplY3QuZnJlZXplKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIG1ldGEgICAgID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2ZyZWV6ZScsIGZ1bmN0aW9uKCRmcmVlemUpe1xuICByZXR1cm4gZnVuY3Rpb24gZnJlZXplKGl0KXtcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7IiwiLy8gMTkuMS4yLjYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKVxudmFyIHRvSU9iamVjdCAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2dldE93blByb3BlcnR5RGVzY3JpcHRvcicsIGZ1bmN0aW9uKCl7XG4gIHJldHVybiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSl7XG4gICAgcmV0dXJuICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodG9JT2JqZWN0KGl0KSwga2V5KTtcbiAgfTtcbn0pOyIsIi8vIDE5LjEuMi43IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE8pXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2dldE93blByb3BlcnR5TmFtZXMnLCBmdW5jdGlvbigpe1xuICByZXR1cm4gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0JykuZjtcbn0pOyIsIi8vIDE5LjEuMi45IE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxudmFyIHRvT2JqZWN0ICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgJGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2dldFByb3RvdHlwZU9mJywgZnVuY3Rpb24oKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldFByb3RvdHlwZU9mKGl0KXtcbiAgICByZXR1cm4gJGdldFByb3RvdHlwZU9mKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTsiLCIvLyAxOS4xLjIuMTEgT2JqZWN0LmlzRXh0ZW5zaWJsZShPKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnaXNFeHRlbnNpYmxlJywgZnVuY3Rpb24oJGlzRXh0ZW5zaWJsZSl7XG4gIHJldHVybiBmdW5jdGlvbiBpc0V4dGVuc2libGUoaXQpe1xuICAgIHJldHVybiBpc09iamVjdChpdCkgPyAkaXNFeHRlbnNpYmxlID8gJGlzRXh0ZW5zaWJsZShpdCkgOiB0cnVlIDogZmFsc2U7XG4gIH07XG59KTsiLCIvLyAxOS4xLjIuMTIgT2JqZWN0LmlzRnJvemVuKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0Zyb3plbicsIGZ1bmN0aW9uKCRpc0Zyb3plbil7XG4gIHJldHVybiBmdW5jdGlvbiBpc0Zyb3plbihpdCl7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTsiLCIvLyAxOS4xLjIuMTMgT2JqZWN0LmlzU2VhbGVkKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc1NlYWxlZCcsIGZ1bmN0aW9uKCRpc1NlYWxlZCl7XG4gIHJldHVybiBmdW5jdGlvbiBpc1NlYWxlZChpdCl7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc1NlYWxlZCA/ICRpc1NlYWxlZChpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTsiLCIvLyAxOS4xLjMuMTAgT2JqZWN0LmlzKHZhbHVlMSwgdmFsdWUyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge2lzOiByZXF1aXJlKCcuL19zYW1lLXZhbHVlJyl9KTsiLCIvLyAxOS4xLjIuMTQgT2JqZWN0LmtleXMoTylcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgJGtleXMgICAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbigpe1xuICByZXR1cm4gZnVuY3Rpb24ga2V5cyhpdCl7XG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTsiLCIvLyAxOS4xLjIuMTUgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIG1ldGEgICAgID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ3ByZXZlbnRFeHRlbnNpb25zJywgZnVuY3Rpb24oJHByZXZlbnRFeHRlbnNpb25zKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIHByZXZlbnRFeHRlbnNpb25zKGl0KXtcbiAgICByZXR1cm4gJHByZXZlbnRFeHRlbnNpb25zICYmIGlzT2JqZWN0KGl0KSA/ICRwcmV2ZW50RXh0ZW5zaW9ucyhtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pOyIsIi8vIDE5LjEuMi4xNyBPYmplY3Quc2VhbChPKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBtZXRhICAgICA9IHJlcXVpcmUoJy4vX21ldGEnKS5vbkZyZWV6ZTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdzZWFsJywgZnVuY3Rpb24oJHNlYWwpe1xuICByZXR1cm4gZnVuY3Rpb24gc2VhbChpdCl7XG4gICAgcmV0dXJuICRzZWFsICYmIGlzT2JqZWN0KGl0KSA/ICRzZWFsKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7IiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtzZXRQcm90b3R5cGVPZjogcmVxdWlyZSgnLi9fc2V0LXByb3RvJykuc2V0fSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKVxuICAsIHRlc3QgICAgPSB7fTtcbnRlc3RbcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyldID0gJ3onO1xuaWYodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJyl7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoT2JqZWN0LnByb3RvdHlwZSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG4gIH0sIHRydWUpO1xufSIsInZhciAkZXhwb3J0ICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJHBhcnNlRmxvYXQgPSByZXF1aXJlKCcuL19wYXJzZS1mbG9hdCcpO1xuLy8gMTguMi40IHBhcnNlRmxvYXQoc3RyaW5nKVxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkYgKiAocGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksIHtwYXJzZUZsb2F0OiAkcGFyc2VGbG9hdH0pOyIsInZhciAkZXhwb3J0ICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRwYXJzZUludCA9IHJlcXVpcmUoJy4vX3BhcnNlLWludCcpO1xuLy8gMTguMi41IHBhcnNlSW50KHN0cmluZywgcmFkaXgpXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuRiAqIChwYXJzZUludCAhPSAkcGFyc2VJbnQpLCB7cGFyc2VJbnQ6ICRwYXJzZUludH0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZICAgICAgICAgICAgPSByZXF1aXJlKCcuL19saWJyYXJ5JylcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGN0eCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgY2xhc3NvZiAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgJGV4cG9ydCAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBpc09iamVjdCAgICAgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGFGdW5jdGlvbiAgICAgICAgICA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKVxuICAsIGFuSW5zdGFuY2UgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJylcbiAgLCBmb3JPZiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19mb3Itb2YnKVxuICAsIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKVxuICAsIHRhc2sgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXRcbiAgLCBtaWNyb3Rhc2sgICAgICAgICAgPSByZXF1aXJlKCcuL19taWNyb3Rhc2snKSgpXG4gICwgUFJPTUlTRSAgICAgICAgICAgID0gJ1Byb21pc2UnXG4gICwgVHlwZUVycm9yICAgICAgICAgID0gZ2xvYmFsLlR5cGVFcnJvclxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgJFByb21pc2UgICAgICAgICAgID0gZ2xvYmFsW1BST01JU0VdXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBpc05vZGUgICAgICAgICAgICAgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJ1xuICAsIGVtcHR5ICAgICAgICAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cbiAgLCBJbnRlcm5hbCwgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBXcmFwcGVyO1xuXG52YXIgVVNFX05BVElWRSA9ICEhZnVuY3Rpb24oKXtcbiAgdHJ5IHtcbiAgICAvLyBjb3JyZWN0IHN1YmNsYXNzaW5nIHdpdGggQEBzcGVjaWVzIHN1cHBvcnRcbiAgICB2YXIgcHJvbWlzZSAgICAgPSAkUHJvbWlzZS5yZXNvbHZlKDEpXG4gICAgICAsIEZha2VQcm9taXNlID0gKHByb21pc2UuY29uc3RydWN0b3IgPSB7fSlbcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKV0gPSBmdW5jdGlvbihleGVjKXsgZXhlYyhlbXB0eSwgZW1wdHkpOyB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpICYmIHByb21pc2UudGhlbihlbXB0eSkgaW5zdGFuY2VvZiBGYWtlUHJvbWlzZTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxufSgpO1xuXG4vLyBoZWxwZXJzXG52YXIgc2FtZUNvbnN0cnVjdG9yID0gZnVuY3Rpb24oYSwgYil7XG4gIC8vIHdpdGggbGlicmFyeSB3cmFwcGVyIHNwZWNpYWwgY2FzZVxuICByZXR1cm4gYSA9PT0gYiB8fCBhID09PSAkUHJvbWlzZSAmJiBiID09PSBXcmFwcGVyO1xufTtcbnZhciBpc1RoZW5hYmxlID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgdGhlbjtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiB0eXBlb2YgKHRoZW4gPSBpdC50aGVuKSA9PSAnZnVuY3Rpb24nID8gdGhlbiA6IGZhbHNlO1xufTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICByZXR1cm4gc2FtZUNvbnN0cnVjdG9yKCRQcm9taXNlLCBDKVxuICAgID8gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgOiBuZXcgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5KEMpO1xufTtcbnZhciBQcm9taXNlQ2FwYWJpbGl0eSA9IEdlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICB2YXIgcmVzb2x2ZSwgcmVqZWN0O1xuICB0aGlzLnByb21pc2UgPSBuZXcgQyhmdW5jdGlvbigkJHJlc29sdmUsICQkcmVqZWN0KXtcbiAgICBpZihyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKCdCYWQgUHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xuICAgIHJlc29sdmUgPSAkJHJlc29sdmU7XG4gICAgcmVqZWN0ICA9ICQkcmVqZWN0O1xuICB9KTtcbiAgdGhpcy5yZXNvbHZlID0gYUZ1bmN0aW9uKHJlc29sdmUpO1xuICB0aGlzLnJlamVjdCAgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn07XG52YXIgcGVyZm9ybSA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIGV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4ge2Vycm9yOiBlfTtcbiAgfVxufTtcbnZhciBub3RpZnkgPSBmdW5jdGlvbihwcm9taXNlLCBpc1JlamVjdCl7XG4gIGlmKHByb21pc2UuX24pcmV0dXJuO1xuICBwcm9taXNlLl9uID0gdHJ1ZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYztcbiAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHZhbHVlID0gcHJvbWlzZS5fdlxuICAgICAgLCBvayAgICA9IHByb21pc2UuX3MgPT0gMVxuICAgICAgLCBpICAgICA9IDA7XG4gICAgdmFyIHJ1biA9IGZ1bmN0aW9uKHJlYWN0aW9uKXtcbiAgICAgIHZhciBoYW5kbGVyID0gb2sgPyByZWFjdGlvbi5vayA6IHJlYWN0aW9uLmZhaWxcbiAgICAgICAgLCByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZVxuICAgICAgICAsIHJlamVjdCAgPSByZWFjdGlvbi5yZWplY3RcbiAgICAgICAgLCBkb21haW4gID0gcmVhY3Rpb24uZG9tYWluXG4gICAgICAgICwgcmVzdWx0LCB0aGVuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYoaGFuZGxlcil7XG4gICAgICAgICAgaWYoIW9rKXtcbiAgICAgICAgICAgIGlmKHByb21pc2UuX2ggPT0gMilvbkhhbmRsZVVuaGFuZGxlZChwcm9taXNlKTtcbiAgICAgICAgICAgIHByb21pc2UuX2ggPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZihoYW5kbGVyID09PSB0cnVlKXJlc3VsdCA9IHZhbHVlO1xuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYoZG9tYWluKWRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7XG4gICAgICAgICAgICBpZihkb21haW4pZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKXtcbiAgICAgICAgICAgIHJlamVjdChUeXBlRXJyb3IoJ1Byb21pc2UtY2hhaW4gY3ljbGUnKSk7XG4gICAgICAgICAgfSBlbHNlIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpe1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHdoaWxlKGNoYWluLmxlbmd0aCA+IGkpcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYoaXNSZWplY3QgJiYgIXByb21pc2UuX2gpb25VbmhhbmRsZWQocHJvbWlzZSk7XG4gIH0pO1xufTtcbnZhciBvblVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3ZcbiAgICAgICwgYWJydXB0LCBoYW5kbGVyLCBjb25zb2xlO1xuICAgIGlmKGlzVW5oYW5kbGVkKHByb21pc2UpKXtcbiAgICAgIGFicnVwdCA9IHBlcmZvcm0oZnVuY3Rpb24oKXtcbiAgICAgICAgaWYoaXNOb2RlKXtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmKGhhbmRsZXIgPSBnbG9iYWwub251bmhhbmRsZWRyZWplY3Rpb24pe1xuICAgICAgICAgIGhhbmRsZXIoe3Byb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWV9KTtcbiAgICAgICAgfSBlbHNlIGlmKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3Ipe1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZihhYnJ1cHQpdGhyb3cgYWJydXB0LmVycm9yO1xuICB9KTtcbn07XG52YXIgaXNVbmhhbmRsZWQgPSBmdW5jdGlvbihwcm9taXNlKXtcbiAgaWYocHJvbWlzZS5faCA9PSAxKXJldHVybiBmYWxzZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYSB8fCBwcm9taXNlLl9jXG4gICAgLCBpICAgICA9IDBcbiAgICAsIHJlYWN0aW9uO1xuICB3aGlsZShjaGFpbi5sZW5ndGggPiBpKXtcbiAgICByZWFjdGlvbiA9IGNoYWluW2krK107XG4gICAgaWYocmVhY3Rpb24uZmFpbCB8fCAhaXNVbmhhbmRsZWQocmVhY3Rpb24ucHJvbWlzZSkpcmV0dXJuIGZhbHNlO1xuICB9IHJldHVybiB0cnVlO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciBoYW5kbGVyO1xuICAgIGlmKGlzTm9kZSl7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYoaGFuZGxlciA9IGdsb2JhbC5vbnJlamVjdGlvbmhhbmRsZWQpe1xuICAgICAgaGFuZGxlcih7cHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92fSk7XG4gICAgfVxuICB9KTtcbn07XG52YXIgJHJlamVjdCA9IGZ1bmN0aW9uKHZhbHVlKXtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZihwcm9taXNlLl9kKXJldHVybjtcbiAgcHJvbWlzZS5fZCA9IHRydWU7XG4gIHByb21pc2UgPSBwcm9taXNlLl93IHx8IHByb21pc2U7IC8vIHVud3JhcFxuICBwcm9taXNlLl92ID0gdmFsdWU7XG4gIHByb21pc2UuX3MgPSAyO1xuICBpZighcHJvbWlzZS5fYSlwcm9taXNlLl9hID0gcHJvbWlzZS5fYy5zbGljZSgpO1xuICBub3RpZnkocHJvbWlzZSwgdHJ1ZSk7XG59O1xudmFyICRyZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpe1xuICB2YXIgcHJvbWlzZSA9IHRoaXNcbiAgICAsIHRoZW47XG4gIGlmKHByb21pc2UuX2QpcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYocHJvbWlzZSA9PT0gdmFsdWUpdGhyb3cgVHlwZUVycm9yKFwiUHJvbWlzZSBjYW4ndCBiZSByZXNvbHZlZCBpdHNlbGZcIik7XG4gICAgaWYodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKXtcbiAgICAgIG1pY3JvdGFzayhmdW5jdGlvbigpe1xuICAgICAgICB2YXIgd3JhcHBlciA9IHtfdzogcHJvbWlzZSwgX2Q6IGZhbHNlfTsgLy8gd3JhcFxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoZW4uY2FsbCh2YWx1ZSwgY3R4KCRyZXNvbHZlLCB3cmFwcGVyLCAxKSwgY3R4KCRyZWplY3QsIHdyYXBwZXIsIDEpKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAkcmVqZWN0LmNhbGwod3JhcHBlciwgZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9taXNlLl92ID0gdmFsdWU7XG4gICAgICBwcm9taXNlLl9zID0gMTtcbiAgICAgIG5vdGlmeShwcm9taXNlLCBmYWxzZSk7XG4gICAgfVxuICB9IGNhdGNoKGUpe1xuICAgICRyZWplY3QuY2FsbCh7X3c6IHByb21pc2UsIF9kOiBmYWxzZX0sIGUpOyAvLyB3cmFwXG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZighVVNFX05BVElWRSl7XG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXG4gICRQcm9taXNlID0gZnVuY3Rpb24gUHJvbWlzZShleGVjdXRvcil7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkUHJvbWlzZSwgUFJPTUlTRSwgJ19oJyk7XG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcbiAgICBJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgIHRyeSB7XG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHRoaXMsIDEpLCBjdHgoJHJlamVjdCwgdGhpcywgMSkpO1xuICAgIH0gY2F0Y2goZXJyKXtcbiAgICAgICRyZWplY3QuY2FsbCh0aGlzLCBlcnIpO1xuICAgIH1cbiAgfTtcbiAgSW50ZXJuYWwgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpe1xuICAgICAgdmFyIHJlYWN0aW9uICAgID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsICRQcm9taXNlKSk7XG4gICAgICByZWFjdGlvbi5vayAgICAgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgICA9IHR5cGVvZiBvblJlamVjdGVkID09ICdmdW5jdGlvbicgJiYgb25SZWplY3RlZDtcbiAgICAgIHJlYWN0aW9uLmRvbWFpbiA9IGlzTm9kZSA/IHByb2Nlc3MuZG9tYWluIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fYy5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX2EpdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX3Mpbm90aWZ5KHRoaXMsIGZhbHNlKTtcbiAgICAgIHJldHVybiByZWFjdGlvbi5wcm9taXNlO1xuICAgIH0sXG4gICAgLy8gMjUuNC41LjEgUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2gob25SZWplY3RlZClcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbihvblJlamVjdGVkKXtcbiAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbiAgICB9XG4gIH0pO1xuICBQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHByb21pc2UgID0gbmV3IEludGVybmFsO1xuICAgIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG4gICAgdGhpcy5yZXNvbHZlID0gY3R4KCRyZXNvbHZlLCBwcm9taXNlLCAxKTtcbiAgICB0aGlzLnJlamVjdCAgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHtQcm9taXNlOiAkUHJvbWlzZX0pO1xucmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKSgkUHJvbWlzZSwgUFJPTUlTRSk7XG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKFBST01JU0UpO1xuV3JhcHBlciA9IHJlcXVpcmUoJy4vX2NvcmUnKVtQUk9NSVNFXTtcblxuLy8gc3RhdGljc1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNSBQcm9taXNlLnJlamVjdChyKVxuICByZWplY3Q6IGZ1bmN0aW9uIHJlamVjdChyKXtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHRoaXMpXG4gICAgICAsICQkcmVqZWN0ICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICAkJHJlamVjdChyKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKExJQlJBUlkgfHwgIVVTRV9OQVRJVkUpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC42IFByb21pc2UucmVzb2x2ZSh4KVxuICByZXNvbHZlOiBmdW5jdGlvbiByZXNvbHZlKHgpe1xuICAgIC8vIGluc3RhbmNlb2YgaW5zdGVhZCBvZiBpbnRlcm5hbCBzbG90IGNoZWNrIGJlY2F1c2Ugd2Ugc2hvdWxkIGZpeCBpdCB3aXRob3V0IHJlcGxhY2VtZW50IG5hdGl2ZSBQcm9taXNlIGNvcmVcbiAgICBpZih4IGluc3RhbmNlb2YgJFByb21pc2UgJiYgc2FtZUNvbnN0cnVjdG9yKHguY29uc3RydWN0b3IsIHRoaXMpKXJldHVybiB4O1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcbiAgICAgICwgJCRyZXNvbHZlICA9IGNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgICAkJHJlc29sdmUoeCk7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoVVNFX05BVElWRSAmJiByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uKGl0ZXIpe1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSl7XG4gICAgdmFyIEMgICAgICAgICAgPSB0aGlzXG4gICAgICAsIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKVxuICAgICAgLCByZXNvbHZlICAgID0gY2FwYWJpbGl0eS5yZXNvbHZlXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgdmFyIHZhbHVlcyAgICA9IFtdXG4gICAgICAgICwgaW5kZXggICAgID0gMFxuICAgICAgICAsIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uKHByb21pc2Upe1xuICAgICAgICB2YXIgJGluZGV4ICAgICAgICA9IGluZGV4KytcbiAgICAgICAgICAsIGFscmVhZHlDYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgcmVtYWluaW5nKys7XG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAgICAgICBpZihhbHJlYWR5Q2FsbGVkKXJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkICA9IHRydWU7XG4gICAgICAgICAgdmFsdWVzWyRpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICB9KTtcbiAgICBpZihhYnJ1cHQpcmVqZWN0KGFicnVwdC5lcnJvcik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfSxcbiAgLy8gMjUuNC40LjQgUHJvbWlzZS5yYWNlKGl0ZXJhYmxlKVxuICByYWNlOiBmdW5jdGlvbiByYWNlKGl0ZXJhYmxlKXtcbiAgICB2YXIgQyAgICAgICAgICA9IHRoaXNcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbihwcm9taXNlKXtcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oY2FwYWJpbGl0eS5yZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYoYWJydXB0KXJlamVjdChhYnJ1cHQuZXJyb3IpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pOyIsIi8vIDI2LjEuMSBSZWZsZWN0LmFwcGx5KHRhcmdldCwgdGhpc0FyZ3VtZW50LCBhcmd1bWVudHNMaXN0KVxudmFyICRleHBvcnQgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgYW5PYmplY3QgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCByQXBwbHkgICAgPSAocmVxdWlyZSgnLi9fZ2xvYmFsJykuUmVmbGVjdCB8fCB7fSkuYXBwbHlcbiAgLCBmQXBwbHkgICAgPSBGdW5jdGlvbi5hcHBseTtcbi8vIE1TIEVkZ2UgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICByQXBwbHkoZnVuY3Rpb24oKXt9KTtcbn0pLCAnUmVmbGVjdCcsIHtcbiAgYXBwbHk6IGZ1bmN0aW9uIGFwcGx5KHRhcmdldCwgdGhpc0FyZ3VtZW50LCBhcmd1bWVudHNMaXN0KXtcbiAgICB2YXIgVCA9IGFGdW5jdGlvbih0YXJnZXQpXG4gICAgICAsIEwgPSBhbk9iamVjdChhcmd1bWVudHNMaXN0KTtcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xuICB9XG59KTsiLCIvLyAyNi4xLjIgUmVmbGVjdC5jb25zdHJ1Y3QodGFyZ2V0LCBhcmd1bWVudHNMaXN0IFssIG5ld1RhcmdldF0pXG52YXIgJGV4cG9ydCAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgY3JlYXRlICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKVxuICAsIGFGdW5jdGlvbiAgPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCBhbk9iamVjdCAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBpc09iamVjdCAgID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBmYWlscyAgICAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsIGJpbmQgICAgICAgPSByZXF1aXJlKCcuL19iaW5kJylcbiAgLCByQ29uc3RydWN0ID0gKHJlcXVpcmUoJy4vX2dsb2JhbCcpLlJlZmxlY3QgfHwge30pLmNvbnN0cnVjdDtcblxuLy8gTVMgRWRnZSBzdXBwb3J0cyBvbmx5IDIgYXJndW1lbnRzIGFuZCBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXG4vLyBGRiBOaWdodGx5IHNldHMgdGhpcmQgYXJndW1lbnQgYXMgYG5ldy50YXJnZXRgLCBidXQgZG9lcyBub3QgY3JlYXRlIGB0aGlzYCBmcm9tIGl0XG52YXIgTkVXX1RBUkdFVF9CVUcgPSBmYWlscyhmdW5jdGlvbigpe1xuICBmdW5jdGlvbiBGKCl7fVxuICByZXR1cm4gIShyQ29uc3RydWN0KGZ1bmN0aW9uKCl7fSwgW10sIEYpIGluc3RhbmNlb2YgRik7XG59KTtcbnZhciBBUkdTX0JVRyA9ICFmYWlscyhmdW5jdGlvbigpe1xuICByQ29uc3RydWN0KGZ1bmN0aW9uKCl7fSk7XG59KTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTkVXX1RBUkdFVF9CVUcgfHwgQVJHU19CVUcpLCAnUmVmbGVjdCcsIHtcbiAgY29uc3RydWN0OiBmdW5jdGlvbiBjb25zdHJ1Y3QoVGFyZ2V0LCBhcmdzIC8qLCBuZXdUYXJnZXQqLyl7XG4gICAgYUZ1bmN0aW9uKFRhcmdldCk7XG4gICAgYW5PYmplY3QoYXJncyk7XG4gICAgdmFyIG5ld1RhcmdldCA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gVGFyZ2V0IDogYUZ1bmN0aW9uKGFyZ3VtZW50c1syXSk7XG4gICAgaWYoQVJHU19CVUcgJiYgIU5FV19UQVJHRVRfQlVHKXJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcbiAgICBpZihUYXJnZXQgPT0gbmV3VGFyZ2V0KXtcbiAgICAgIC8vIHcvbyBhbHRlcmVkIG5ld1RhcmdldCwgb3B0aW1pemF0aW9uIGZvciAwLTQgYXJndW1lbnRzXG4gICAgICBzd2l0Y2goYXJncy5sZW5ndGgpe1xuICAgICAgICBjYXNlIDA6IHJldHVybiBuZXcgVGFyZ2V0O1xuICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0pO1xuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgfVxuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBsb3Qgb2YgYXJndW1lbnRzIGNhc2VcbiAgICAgIHZhciAkYXJncyA9IFtudWxsXTtcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xuICAgICAgcmV0dXJuIG5ldyAoYmluZC5hcHBseShUYXJnZXQsICRhcmdzKSk7XG4gICAgfVxuICAgIC8vIHdpdGggYWx0ZXJlZCBuZXdUYXJnZXQsIG5vdCBzdXBwb3J0IGJ1aWx0LWluIGNvbnN0cnVjdG9yc1xuICAgIHZhciBwcm90byAgICA9IG5ld1RhcmdldC5wcm90b3R5cGVcbiAgICAgICwgaW5zdGFuY2UgPSBjcmVhdGUoaXNPYmplY3QocHJvdG8pID8gcHJvdG8gOiBPYmplY3QucHJvdG90eXBlKVxuICAgICAgLCByZXN1bHQgICA9IEZ1bmN0aW9uLmFwcGx5LmNhbGwoVGFyZ2V0LCBpbnN0YW5jZSwgYXJncyk7XG4gICAgcmV0dXJuIGlzT2JqZWN0KHJlc3VsdCkgPyByZXN1bHQgOiBpbnN0YW5jZTtcbiAgfVxufSk7IiwiLy8gMjYuMS4zIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcylcbnZhciBkUCAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpXG4gICwgJGV4cG9ydCAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGFuT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4vLyBNUyBFZGdlIGhhcyBicm9rZW4gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSAtIHRocm93aW5nIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eShkUC5mKHt9LCAxLCB7dmFsdWU6IDF9KSwgMSwge3ZhbHVlOiAyfSk7XG59KSwgJ1JlZmxlY3QnLCB7XG4gIGRlZmluZVByb3BlcnR5OiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCBhdHRyaWJ1dGVzKXtcbiAgICBhbk9iamVjdCh0YXJnZXQpO1xuICAgIHByb3BlcnR5S2V5ID0gdG9QcmltaXRpdmUocHJvcGVydHlLZXksIHRydWUpO1xuICAgIGFuT2JqZWN0KGF0dHJpYnV0ZXMpO1xuICAgIHRyeSB7XG4gICAgICBkUC5mKHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pOyIsIi8vIDI2LjEuNCBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGdPUEQgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mXG4gICwgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSl7XG4gICAgdmFyIGRlc2MgPSBnT1BEKGFuT2JqZWN0KHRhcmdldCksIHByb3BlcnR5S2V5KTtcbiAgICByZXR1cm4gZGVzYyAmJiAhZGVzYy5jb25maWd1cmFibGUgPyBmYWxzZSA6IGRlbGV0ZSB0YXJnZXRbcHJvcGVydHlLZXldO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyAyNi4xLjUgUmVmbGVjdC5lbnVtZXJhdGUodGFyZ2V0KVxudmFyICRleHBvcnQgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIEVudW1lcmF0ZSA9IGZ1bmN0aW9uKGl0ZXJhdGVkKXtcbiAgdGhpcy5fdCA9IGFuT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbiAgdmFyIGtleXMgPSB0aGlzLl9rID0gW10gICAgICAgLy8ga2V5c1xuICAgICwga2V5O1xuICBmb3Ioa2V5IGluIGl0ZXJhdGVkKWtleXMucHVzaChrZXkpO1xufTtcbnJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJykoRW51bWVyYXRlLCAnT2JqZWN0JywgZnVuY3Rpb24oKXtcbiAgdmFyIHRoYXQgPSB0aGlzXG4gICAgLCBrZXlzID0gdGhhdC5fa1xuICAgICwga2V5O1xuICBkbyB7XG4gICAgaWYodGhhdC5faSA+PSBrZXlzLmxlbmd0aClyZXR1cm4ge3ZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWV9O1xuICB9IHdoaWxlKCEoKGtleSA9IGtleXNbdGhhdC5faSsrXSkgaW4gdGhhdC5fdCkpO1xuICByZXR1cm4ge3ZhbHVlOiBrZXksIGRvbmU6IGZhbHNlfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGVudW1lcmF0ZTogZnVuY3Rpb24gZW51bWVyYXRlKHRhcmdldCl7XG4gICAgcmV0dXJuIG5ldyBFbnVtZXJhdGUodGFyZ2V0KTtcbiAgfVxufSk7IiwiLy8gMjYuMS43IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgZ09QRCAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpXG4gICwgJGV4cG9ydCAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSl7XG4gICAgcmV0dXJuIGdPUEQuZihhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XG4gIH1cbn0pOyIsIi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcbnZhciAkZXhwb3J0ICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZ2V0UHJvdG8gPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJylcbiAgLCBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGdldFByb3RvdHlwZU9mOiBmdW5jdGlvbiBnZXRQcm90b3R5cGVPZih0YXJnZXQpe1xuICAgIHJldHVybiBnZXRQcm90byhhbk9iamVjdCh0YXJnZXQpKTtcbiAgfVxufSk7IiwiLy8gMjYuMS42IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcGVydHlLZXkgWywgcmVjZWl2ZXJdKVxudmFyIGdPUEQgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKVxuICAsIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpXG4gICwgaGFzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBpc09iamVjdCAgICAgICA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgYW5PYmplY3QgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuZnVuY3Rpb24gZ2V0KHRhcmdldCwgcHJvcGVydHlLZXkvKiwgcmVjZWl2ZXIqLyl7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdGFyZ2V0IDogYXJndW1lbnRzWzJdXG4gICAgLCBkZXNjLCBwcm90bztcbiAgaWYoYW5PYmplY3QodGFyZ2V0KSA9PT0gcmVjZWl2ZXIpcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIGlmKGRlc2MgPSBnT1BELmYodGFyZ2V0LCBwcm9wZXJ0eUtleSkpcmV0dXJuIGhhcyhkZXNjLCAndmFsdWUnKVxuICAgID8gZGVzYy52YWx1ZVxuICAgIDogZGVzYy5nZXQgIT09IHVuZGVmaW5lZFxuICAgICAgPyBkZXNjLmdldC5jYWxsKHJlY2VpdmVyKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGlmKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpcmV0dXJuIGdldChwcm90bywgcHJvcGVydHlLZXksIHJlY2VpdmVyKTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge2dldDogZ2V0fSk7IiwiLy8gMjYuMS45IFJlZmxlY3QuaGFzKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGhhczogZnVuY3Rpb24gaGFzKHRhcmdldCwgcHJvcGVydHlLZXkpe1xuICAgIHJldHVybiBwcm9wZXJ0eUtleSBpbiB0YXJnZXQ7XG4gIH1cbn0pOyIsIi8vIDI2LjEuMTAgUmVmbGVjdC5pc0V4dGVuc2libGUodGFyZ2V0KVxudmFyICRleHBvcnQgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGFuT2JqZWN0ICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsICRpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGlzRXh0ZW5zaWJsZTogZnVuY3Rpb24gaXNFeHRlbnNpYmxlKHRhcmdldCl7XG4gICAgYW5PYmplY3QodGFyZ2V0KTtcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XG4gIH1cbn0pOyIsIi8vIDI2LjEuMTEgUmVmbGVjdC5vd25LZXlzKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtvd25LZXlzOiByZXF1aXJlKCcuL19vd24ta2V5cycpfSk7IiwiLy8gMjYuMS4xMiBSZWZsZWN0LnByZXZlbnRFeHRlbnNpb25zKHRhcmdldClcbnZhciAkZXhwb3J0ICAgICAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgJHByZXZlbnRFeHRlbnNpb25zID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHByZXZlbnRFeHRlbnNpb25zOiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpe1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmKCRwcmV2ZW50RXh0ZW5zaW9ucykkcHJldmVudEV4dGVuc2lvbnModGFyZ2V0KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTsiLCIvLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcbnZhciAkZXhwb3J0ICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgc2V0UHJvdG8gPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKTtcblxuaWYoc2V0UHJvdG8pJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBzZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90byl7XG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XG4gICAgdHJ5IHtcbiAgICAgIHNldFByb3RvLnNldCh0YXJnZXQsIHByb3RvKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTsiLCIvLyAyNi4xLjEzIFJlZmxlY3Quc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYgWywgcmVjZWl2ZXJdKVxudmFyIGRQICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCBnT1BEICAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJylcbiAgLCBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIGhhcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCAkZXhwb3J0ICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgY3JlYXRlRGVzYyAgICAgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJylcbiAgLCBhbk9iamVjdCAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgaXNPYmplY3QgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxuZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYvKiwgcmVjZWl2ZXIqLyl7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCA0ID8gdGFyZ2V0IDogYXJndW1lbnRzWzNdXG4gICAgLCBvd25EZXNjICA9IGdPUEQuZihhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSlcbiAgICAsIGV4aXN0aW5nRGVzY3JpcHRvciwgcHJvdG87XG4gIGlmKCFvd25EZXNjKXtcbiAgICBpZihpc09iamVjdChwcm90byA9IGdldFByb3RvdHlwZU9mKHRhcmdldCkpKXtcbiAgICAgIHJldHVybiBzZXQocHJvdG8sIHByb3BlcnR5S2V5LCBWLCByZWNlaXZlcik7XG4gICAgfVxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xuICB9XG4gIGlmKGhhcyhvd25EZXNjLCAndmFsdWUnKSl7XG4gICAgaWYob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSlyZXR1cm4gZmFsc2U7XG4gICAgZXhpc3RpbmdEZXNjcmlwdG9yID0gZ09QRC5mKHJlY2VpdmVyLCBwcm9wZXJ0eUtleSkgfHwgY3JlYXRlRGVzYygwKTtcbiAgICBleGlzdGluZ0Rlc2NyaXB0b3IudmFsdWUgPSBWO1xuICAgIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBleGlzdGluZ0Rlc2NyaXB0b3IpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBvd25EZXNjLnNldCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiAob3duRGVzYy5zZXQuY2FsbChyZWNlaXZlciwgViksIHRydWUpO1xufVxuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7c2V0OiBzZXR9KTsiLCJ2YXIgZ2xvYmFsICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGluaGVyaXRJZlJlcXVpcmVkID0gcmVxdWlyZSgnLi9faW5oZXJpdC1pZi1yZXF1aXJlZCcpXG4gICwgZFAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgZ09QTiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmZcbiAgLCBpc1JlZ0V4cCAgICAgICAgICA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpXG4gICwgJGZsYWdzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19mbGFncycpXG4gICwgJFJlZ0V4cCAgICAgICAgICAgPSBnbG9iYWwuUmVnRXhwXG4gICwgQmFzZSAgICAgICAgICAgICAgPSAkUmVnRXhwXG4gICwgcHJvdG8gICAgICAgICAgICAgPSAkUmVnRXhwLnByb3RvdHlwZVxuICAsIHJlMSAgICAgICAgICAgICAgID0gL2EvZ1xuICAsIHJlMiAgICAgICAgICAgICAgID0gL2EvZ1xuICAvLyBcIm5ld1wiIGNyZWF0ZXMgYSBuZXcgb2JqZWN0LCBvbGQgd2Via2l0IGJ1Z2d5IGhlcmVcbiAgLCBDT1JSRUNUX05FVyAgICAgICA9IG5ldyAkUmVnRXhwKHJlMSkgIT09IHJlMTtcblxuaWYocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAoIUNPUlJFQ1RfTkVXIHx8IHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmUyW3JlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpXSA9IGZhbHNlO1xuICAvLyBSZWdFeHAgY29uc3RydWN0b3IgY2FuIGFsdGVyIGZsYWdzIGFuZCBJc1JlZ0V4cCB3b3JrcyBjb3JyZWN0IHdpdGggQEBtYXRjaFxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcbn0pKSl7XG4gICRSZWdFeHAgPSBmdW5jdGlvbiBSZWdFeHAocCwgZil7XG4gICAgdmFyIHRpUkUgPSB0aGlzIGluc3RhbmNlb2YgJFJlZ0V4cFxuICAgICAgLCBwaVJFID0gaXNSZWdFeHAocClcbiAgICAgICwgZmlVICA9IGYgPT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcbiAgICAgIDogaW5oZXJpdElmUmVxdWlyZWQoQ09SUkVDVF9ORVdcbiAgICAgICAgPyBuZXcgQmFzZShwaVJFICYmICFmaVUgPyBwLnNvdXJjZSA6IHAsIGYpXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXG4gICAgICAsIHRpUkUgPyB0aGlzIDogcHJvdG8sICRSZWdFeHApO1xuICB9O1xuICB2YXIgcHJveHkgPSBmdW5jdGlvbihrZXkpe1xuICAgIGtleSBpbiAkUmVnRXhwIHx8IGRQKCRSZWdFeHAsIGtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gQmFzZVtrZXldOyB9LFxuICAgICAgc2V0OiBmdW5jdGlvbihpdCl7IEJhc2Vba2V5XSA9IGl0OyB9XG4gICAgfSk7XG4gIH07XG4gIGZvcih2YXIga2V5cyA9IGdPUE4oQmFzZSksIGkgPSAwOyBrZXlzLmxlbmd0aCA+IGk7IClwcm94eShrZXlzW2krK10pO1xuICBwcm90by5jb25zdHJ1Y3RvciA9ICRSZWdFeHA7XG4gICRSZWdFeHAucHJvdG90eXBlID0gcHJvdG87XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoZ2xvYmFsLCAnUmVnRXhwJywgJFJlZ0V4cCk7XG59XG5cbnJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJykoJ1JlZ0V4cCcpOyIsIi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzKClcbmlmKHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgLy4vZy5mbGFncyAhPSAnZycpcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihSZWdFeHAucHJvdG90eXBlLCAnZmxhZ3MnLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiByZXF1aXJlKCcuL19mbGFncycpXG59KTsiLCIvLyBAQG1hdGNoIGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ21hdGNoJywgMSwgZnVuY3Rpb24oZGVmaW5lZCwgTUFUQ0gsICRtYXRjaCl7XG4gIC8vIDIxLjEuMy4xMSBTdHJpbmcucHJvdG90eXBlLm1hdGNoKHJlZ2V4cClcbiAgcmV0dXJuIFtmdW5jdGlvbiBtYXRjaChyZWdleHApe1xuICAgICd1c2Ugc3RyaWN0JztcbiAgICB2YXIgTyAgPSBkZWZpbmVkKHRoaXMpXG4gICAgICAsIGZuID0gcmVnZXhwID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHJlZ2V4cFtNQVRDSF07XG4gICAgcmV0dXJuIGZuICE9PSB1bmRlZmluZWQgPyBmbi5jYWxsKHJlZ2V4cCwgTykgOiBuZXcgUmVnRXhwKHJlZ2V4cClbTUFUQ0hdKFN0cmluZyhPKSk7XG4gIH0sICRtYXRjaF07XG59KTsiLCIvLyBAQHJlcGxhY2UgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uKGRlZmluZWQsIFJFUExBQ0UsICRyZXBsYWNlKXtcbiAgLy8gMjEuMS4zLjE0IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKVxuICByZXR1cm4gW2Z1bmN0aW9uIHJlcGxhY2Uoc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSl7XG4gICAgJ3VzZSBzdHJpY3QnO1xuICAgIHZhciBPICA9IGRlZmluZWQodGhpcylcbiAgICAgICwgZm4gPSBzZWFyY2hWYWx1ZSA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZWFyY2hWYWx1ZVtSRVBMQUNFXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZFxuICAgICAgPyBmbi5jYWxsKHNlYXJjaFZhbHVlLCBPLCByZXBsYWNlVmFsdWUpXG4gICAgICA6ICRyZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgfSwgJHJlcGxhY2VdO1xufSk7IiwiLy8gQEBzZWFyY2ggbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc2VhcmNoJywgMSwgZnVuY3Rpb24oZGVmaW5lZCwgU0VBUkNILCAkc2VhcmNoKXtcbiAgLy8gMjEuMS4zLjE1IFN0cmluZy5wcm90b3R5cGUuc2VhcmNoKHJlZ2V4cClcbiAgcmV0dXJuIFtmdW5jdGlvbiBzZWFyY2gocmVnZXhwKXtcbiAgICAndXNlIHN0cmljdCc7XG4gICAgdmFyIE8gID0gZGVmaW5lZCh0aGlzKVxuICAgICAgLCBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbU0VBUkNIXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IGZuLmNhbGwocmVnZXhwLCBPKSA6IG5ldyBSZWdFeHAocmVnZXhwKVtTRUFSQ0hdKFN0cmluZyhPKSk7XG4gIH0sICRzZWFyY2hdO1xufSk7IiwiLy8gQEBzcGxpdCBsb2dpY1xucmVxdWlyZSgnLi9fZml4LXJlLXdrcycpKCdzcGxpdCcsIDIsIGZ1bmN0aW9uKGRlZmluZWQsIFNQTElULCAkc3BsaXQpe1xuICAndXNlIHN0cmljdCc7XG4gIHZhciBpc1JlZ0V4cCAgID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJylcbiAgICAsIF9zcGxpdCAgICAgPSAkc3BsaXRcbiAgICAsICRwdXNoICAgICAgPSBbXS5wdXNoXG4gICAgLCAkU1BMSVQgICAgID0gJ3NwbGl0J1xuICAgICwgTEVOR1RIICAgICA9ICdsZW5ndGgnXG4gICAgLCBMQVNUX0lOREVYID0gJ2xhc3RJbmRleCc7XG4gIGlmKFxuICAgICdhYmJjJ1skU1BMSVRdKC8oYikqLylbMV0gPT0gJ2MnIHx8XG4gICAgJ3Rlc3QnWyRTUExJVF0oLyg/OikvLCAtMSlbTEVOR1RIXSAhPSA0IHx8XG4gICAgJ2FiJ1skU1BMSVRdKC8oPzphYikqLylbTEVOR1RIXSAhPSAyIHx8XG4gICAgJy4nWyRTUExJVF0oLyguPykoLj8pLylbTEVOR1RIXSAhPSA0IHx8XG4gICAgJy4nWyRTUExJVF0oLygpKCkvKVtMRU5HVEhdID4gMSB8fFxuICAgICcnWyRTUExJVF0oLy4/LylbTEVOR1RIXVxuICApe1xuICAgIHZhciBOUENHID0gLygpPz8vLmV4ZWMoJycpWzFdID09PSB1bmRlZmluZWQ7IC8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgLy8gYmFzZWQgb24gZXM1LXNoaW0gaW1wbGVtZW50YXRpb24sIG5lZWQgdG8gcmV3b3JrIGl0XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24oc2VwYXJhdG9yLCBsaW1pdCl7XG4gICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHRoaXMpO1xuICAgICAgaWYoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApcmV0dXJuIFtdO1xuICAgICAgLy8gSWYgYHNlcGFyYXRvcmAgaXMgbm90IGEgcmVnZXgsIHVzZSBuYXRpdmUgc3BsaXRcbiAgICAgIGlmKCFpc1JlZ0V4cChzZXBhcmF0b3IpKXJldHVybiBfc3BsaXQuY2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKTtcbiAgICAgIHZhciBsYXN0TGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IDQyOTQ5NjcyOTUgOiBsaW1pdCA+Pj4gMDtcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgdmFyIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGgsIGk7XG4gICAgICAvLyBEb2Vzbid0IG5lZWQgZmxhZ3MgZ3ksIGJ1dCB0aGV5IGRvbid0IGh1cnRcbiAgICAgIGlmKCFOUENHKXNlcGFyYXRvcjIgPSBuZXcgUmVnRXhwKCdeJyArIHNlcGFyYXRvckNvcHkuc291cmNlICsgJyQoPyFcXFxccyknLCBmbGFncyk7XG4gICAgICB3aGlsZShtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpKXtcbiAgICAgICAgLy8gYHNlcGFyYXRvckNvcHkubGFzdEluZGV4YCBpcyBub3QgcmVsaWFibGUgY3Jvc3MtYnJvd3NlclxuICAgICAgICBsYXN0SW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdW0xFTkdUSF07XG4gICAgICAgIGlmKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpe1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgIGZvciBOUENHXG4gICAgICAgICAgaWYoIU5QQ0cgJiYgbWF0Y2hbTEVOR1RIXSA+IDEpbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbigpe1xuICAgICAgICAgICAgZm9yKGkgPSAxOyBpIDwgYXJndW1lbnRzW0xFTkdUSF0gLSAyOyBpKyspaWYoYXJndW1lbnRzW2ldID09PSB1bmRlZmluZWQpbWF0Y2hbaV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYobWF0Y2hbTEVOR1RIXSA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHJpbmdbTEVOR1RIXSkkcHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcbiAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF1bTEVOR1RIXTtcbiAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICAgIGlmKG91dHB1dFtMRU5HVEhdID49IHNwbGl0TGltaXQpYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYoc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSA9PT0gbWF0Y2guaW5kZXgpc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICB9XG4gICAgICBpZihsYXN0TGFzdEluZGV4ID09PSBzdHJpbmdbTEVOR1RIXSl7XG4gICAgICAgIGlmKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpb3V0cHV0LnB1c2goJycpO1xuICAgICAgfSBlbHNlIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4KSk7XG4gICAgICByZXR1cm4gb3V0cHV0W0xFTkdUSF0gPiBzcGxpdExpbWl0ID8gb3V0cHV0LnNsaWNlKDAsIHNwbGl0TGltaXQpIDogb3V0cHV0O1xuICAgIH07XG4gIC8vIENoYWtyYSwgVjhcbiAgfSBlbHNlIGlmKCcwJ1skU1BMSVRdKHVuZGVmaW5lZCwgMClbTEVOR1RIXSl7XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24oc2VwYXJhdG9yLCBsaW1pdCl7XG4gICAgICByZXR1cm4gc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDAgPyBbXSA6IF9zcGxpdC5jYWxsKHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgIH07XG4gIH1cbiAgLy8gMjEuMS4zLjE3IFN0cmluZy5wcm90b3R5cGUuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdClcbiAgcmV0dXJuIFtmdW5jdGlvbiBzcGxpdChzZXBhcmF0b3IsIGxpbWl0KXtcbiAgICB2YXIgTyAgPSBkZWZpbmVkKHRoaXMpXG4gICAgICAsIGZuID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XG4gICAgcmV0dXJuIGZuICE9PSB1bmRlZmluZWQgPyBmbi5jYWxsKHNlcGFyYXRvciwgTywgbGltaXQpIDogJHNwbGl0LmNhbGwoU3RyaW5nKE8pLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgfSwgJHNwbGl0XTtcbn0pOyIsIid1c2Ugc3RyaWN0JztcbnJlcXVpcmUoJy4vZXM2LnJlZ2V4cC5mbGFncycpO1xudmFyIGFuT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCAkZmxhZ3MgICAgICA9IHJlcXVpcmUoJy4vX2ZsYWdzJylcbiAgLCBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJylcbiAgLCBUT19TVFJJTkcgICA9ICd0b1N0cmluZydcbiAgLCAkdG9TdHJpbmcgICA9IC8uL1tUT19TVFJJTkddO1xuXG52YXIgZGVmaW5lID0gZnVuY3Rpb24oZm4pe1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKFJlZ0V4cC5wcm90b3R5cGUsIFRPX1NUUklORywgZm4sIHRydWUpO1xufTtcblxuLy8gMjEuMi41LjE0IFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcoKVxuaWYocmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpeyByZXR1cm4gJHRvU3RyaW5nLmNhbGwoe3NvdXJjZTogJ2EnLCBmbGFnczogJ2InfSkgIT0gJy9hL2InOyB9KSl7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpe1xuICAgIHZhciBSID0gYW5PYmplY3QodGhpcyk7XG4gICAgcmV0dXJuICcvJy5jb25jYXQoUi5zb3VyY2UsICcvJyxcbiAgICAgICdmbGFncycgaW4gUiA/IFIuZmxhZ3MgOiAhREVTQ1JJUFRPUlMgJiYgUiBpbnN0YW5jZW9mIFJlZ0V4cCA/ICRmbGFncy5jYWxsKFIpIDogdW5kZWZpbmVkKTtcbiAgfSk7XG4vLyBGRjQ0LSBSZWdFeHAjdG9TdHJpbmcgaGFzIGEgd3JvbmcgbmFtZVxufSBlbHNlIGlmKCR0b1N0cmluZy5uYW1lICE9IFRPX1NUUklORyl7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpe1xuICAgIHJldHVybiAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbiAgfSk7XG59IiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKCdTZXQnLCBmdW5jdGlvbihnZXQpe1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCl7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4yLjMuMSBTZXQucHJvdG90eXBlLmFkZCh2YWx1ZSlcbiAgYWRkOiBmdW5jdGlvbiBhZGQodmFsdWUpe1xuICAgIHJldHVybiBzdHJvbmcuZGVmKHRoaXMsIHZhbHVlID0gdmFsdWUgPT09IDAgPyAwIDogdmFsdWUsIHZhbHVlKTtcbiAgfVxufSwgc3Ryb25nKTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4yIFN0cmluZy5wcm90b3R5cGUuYW5jaG9yKG5hbWUpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdhbmNob3InLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGFuY2hvcihuYW1lKXtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYScsICduYW1lJywgbmFtZSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjMgU3RyaW5nLnByb3RvdHlwZS5iaWcoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYmlnJywgZnVuY3Rpb24oY3JlYXRlSFRNTCl7XG4gIHJldHVybiBmdW5jdGlvbiBiaWcoKXtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmlnJywgJycsICcnKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNCBTdHJpbmcucHJvdG90eXBlLmJsaW5rKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JsaW5rJywgZnVuY3Rpb24oY3JlYXRlSFRNTCl7XG4gIHJldHVybiBmdW5jdGlvbiBibGluaygpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdibGluaycsICcnLCAnJyk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjUgU3RyaW5nLnByb3RvdHlwZS5ib2xkKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JvbGQnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJvbGQoKXtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYicsICcnLCAnJyk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkYXQgICAgID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykoZmFsc2UpO1xuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMy4zIFN0cmluZy5wcm90b3R5cGUuY29kZVBvaW50QXQocG9zKVxuICBjb2RlUG9pbnRBdDogZnVuY3Rpb24gY29kZVBvaW50QXQocG9zKXtcbiAgICByZXR1cm4gJGF0KHRoaXMsIHBvcyk7XG4gIH1cbn0pOyIsIi8vIDIxLjEuMy42IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgoc2VhcmNoU3RyaW5nIFssIGVuZFBvc2l0aW9uXSlcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHRvTGVuZ3RoICA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICwgY29udGV4dCAgID0gcmVxdWlyZSgnLi9fc3RyaW5nLWNvbnRleHQnKVxuICAsIEVORFNfV0lUSCA9ICdlbmRzV2l0aCdcbiAgLCAkZW5kc1dpdGggPSAnJ1tFTkRTX1dJVEhdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKEVORFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIGVuZHNXaXRoOiBmdW5jdGlvbiBlbmRzV2l0aChzZWFyY2hTdHJpbmcgLyosIGVuZFBvc2l0aW9uID0gQGxlbmd0aCAqLyl7XG4gICAgdmFyIHRoYXQgPSBjb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgRU5EU19XSVRIKVxuICAgICAgLCBlbmRQb3NpdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkXG4gICAgICAsIGxlbiAgICA9IHRvTGVuZ3RoKHRoYXQubGVuZ3RoKVxuICAgICAgLCBlbmQgICAgPSBlbmRQb3NpdGlvbiA9PT0gdW5kZWZpbmVkID8gbGVuIDogTWF0aC5taW4odG9MZW5ndGgoZW5kUG9zaXRpb24pLCBsZW4pXG4gICAgICAsIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiAkZW5kc1dpdGhcbiAgICAgID8gJGVuZHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBlbmQpXG4gICAgICA6IHRoYXQuc2xpY2UoZW5kIC0gc2VhcmNoLmxlbmd0aCwgZW5kKSA9PT0gc2VhcmNoO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy42IFN0cmluZy5wcm90b3R5cGUuZml4ZWQoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZml4ZWQnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZpeGVkKCl7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3R0JywgJycsICcnKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNyBTdHJpbmcucHJvdG90eXBlLmZvbnRjb2xvcihjb2xvcilcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZvbnRjb2xvcicsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xuICByZXR1cm4gZnVuY3Rpb24gZm9udGNvbG9yKGNvbG9yKXtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdjb2xvcicsIGNvbG9yKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuOCBTdHJpbmcucHJvdG90eXBlLmZvbnRzaXplKHNpemUpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmb250c2l6ZScsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xuICByZXR1cm4gZnVuY3Rpb24gZm9udHNpemUoc2l6ZSl7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2ZvbnQnLCAnc2l6ZScsIHNpemUpO1xuICB9XG59KTsiLCJ2YXIgJGV4cG9ydCAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHRvSW5kZXggICAgICAgID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKVxuICAsIGZyb21DaGFyQ29kZSAgID0gU3RyaW5nLmZyb21DaGFyQ29kZVxuICAsICRmcm9tQ29kZVBvaW50ID0gU3RyaW5nLmZyb21Db2RlUG9pbnQ7XG5cbi8vIGxlbmd0aCBzaG91bGQgYmUgMSwgb2xkIEZGIHByb2JsZW1cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCEhJGZyb21Db2RlUG9pbnQgJiYgJGZyb21Db2RlUG9pbnQubGVuZ3RoICE9IDEpLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuMiBTdHJpbmcuZnJvbUNvZGVQb2ludCguLi5jb2RlUG9pbnRzKVxuICBmcm9tQ29kZVBvaW50OiBmdW5jdGlvbiBmcm9tQ29kZVBvaW50KHgpeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgdmFyIHJlcyAgPSBbXVxuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCBpICAgID0gMFxuICAgICAgLCBjb2RlO1xuICAgIHdoaWxlKGFMZW4gPiBpKXtcbiAgICAgIGNvZGUgPSArYXJndW1lbnRzW2krK107XG4gICAgICBpZih0b0luZGV4KGNvZGUsIDB4MTBmZmZmKSAhPT0gY29kZSl0aHJvdyBSYW5nZUVycm9yKGNvZGUgKyAnIGlzIG5vdCBhIHZhbGlkIGNvZGUgcG9pbnQnKTtcbiAgICAgIHJlcy5wdXNoKGNvZGUgPCAweDEwMDAwXG4gICAgICAgID8gZnJvbUNoYXJDb2RlKGNvZGUpXG4gICAgICAgIDogZnJvbUNoYXJDb2RlKCgoY29kZSAtPSAweDEwMDAwKSA+PiAxMCkgKyAweGQ4MDAsIGNvZGUgJSAweDQwMCArIDB4ZGMwMClcbiAgICAgICk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTsiLCIvLyAyMS4xLjMuNyBTdHJpbmcucHJvdG90eXBlLmluY2x1ZGVzKHNlYXJjaFN0cmluZywgcG9zaXRpb24gPSAwKVxuJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBjb250ZXh0ICA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0JylcbiAgLCBJTkNMVURFUyA9ICdpbmNsdWRlcyc7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoSU5DTFVERVMpLCAnU3RyaW5nJywge1xuICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoU3RyaW5nIC8qLCBwb3NpdGlvbiA9IDAgKi8pe1xuICAgIHJldHVybiAhIX5jb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgSU5DTFVERVMpXG4gICAgICAuaW5kZXhPZihzZWFyY2hTdHJpbmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuOSBTdHJpbmcucHJvdG90eXBlLml0YWxpY3MoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnaXRhbGljcycsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xuICByZXR1cm4gZnVuY3Rpb24gaXRhbGljcygpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdpJywgJycsICcnKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRhdCAgPSByZXF1aXJlKCcuL19zdHJpbmctYXQnKSh0cnVlKTtcblxuLy8gMjEuMS4zLjI3IFN0cmluZy5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxucmVxdWlyZSgnLi9faXRlci1kZWZpbmUnKShTdHJpbmcsICdTdHJpbmcnLCBmdW5jdGlvbihpdGVyYXRlZCl7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uKCl7XG4gIHZhciBPICAgICA9IHRoaXMuX3RcbiAgICAsIGluZGV4ID0gdGhpcy5faVxuICAgICwgcG9pbnQ7XG4gIGlmKGluZGV4ID49IE8ubGVuZ3RoKXJldHVybiB7dmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZX07XG4gIHBvaW50ID0gJGF0KE8sIGluZGV4KTtcbiAgdGhpcy5faSArPSBwb2ludC5sZW5ndGg7XG4gIHJldHVybiB7dmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZX07XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMCBTdHJpbmcucHJvdG90eXBlLmxpbmsodXJsKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnbGluaycsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xuICByZXR1cm4gZnVuY3Rpb24gbGluayh1cmwpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdhJywgJ2hyZWYnLCB1cmwpO1xuICB9XG59KTsiLCJ2YXIgJGV4cG9ydCAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMi40IFN0cmluZy5yYXcoY2FsbFNpdGUsIC4uLnN1YnN0aXR1dGlvbnMpXG4gIHJhdzogZnVuY3Rpb24gcmF3KGNhbGxTaXRlKXtcbiAgICB2YXIgdHBsICA9IHRvSU9iamVjdChjYWxsU2l0ZS5yYXcpXG4gICAgICAsIGxlbiAgPSB0b0xlbmd0aCh0cGwubGVuZ3RoKVxuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgLCByZXMgID0gW11cbiAgICAgICwgaSAgICA9IDA7XG4gICAgd2hpbGUobGVuID4gaSl7XG4gICAgICByZXMucHVzaChTdHJpbmcodHBsW2krK10pKTtcbiAgICAgIGlmKGkgPCBhTGVuKXJlcy5wdXNoKFN0cmluZyhhcmd1bWVudHNbaV0pKTtcbiAgICB9IHJldHVybiByZXMuam9pbignJyk7XG4gIH1cbn0pOyIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5yZXBlYXQoY291bnQpXG4gIHJlcGVhdDogcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpXG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMSBTdHJpbmcucHJvdG90eXBlLnNtYWxsKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3NtYWxsJywgZnVuY3Rpb24oY3JlYXRlSFRNTCl7XG4gIHJldHVybiBmdW5jdGlvbiBzbWFsbCgpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XG4gIH1cbn0pOyIsIi8vIDIxLjEuMy4xOCBTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIFssIHBvc2l0aW9uIF0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHRvTGVuZ3RoICAgID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJylcbiAgLCBjb250ZXh0ICAgICA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0JylcbiAgLCBTVEFSVFNfV0lUSCA9ICdzdGFydHNXaXRoJ1xuICAsICRzdGFydHNXaXRoID0gJydbU1RBUlRTX1dJVEhdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKFNUQVJUU19XSVRIKSwgJ1N0cmluZycsIHtcbiAgc3RhcnRzV2l0aDogZnVuY3Rpb24gc3RhcnRzV2l0aChzZWFyY2hTdHJpbmcgLyosIHBvc2l0aW9uID0gMCAqLyl7XG4gICAgdmFyIHRoYXQgICA9IGNvbnRleHQodGhpcywgc2VhcmNoU3RyaW5nLCBTVEFSVFNfV0lUSClcbiAgICAgICwgaW5kZXggID0gdG9MZW5ndGgoTWF0aC5taW4oYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRoYXQubGVuZ3RoKSlcbiAgICAgICwgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRzdGFydHNXaXRoXG4gICAgICA/ICRzdGFydHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBpbmRleClcbiAgICAgIDogdGhhdC5zbGljZShpbmRleCwgaW5kZXggKyBzZWFyY2gubGVuZ3RoKSA9PT0gc2VhcmNoO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMiBTdHJpbmcucHJvdG90eXBlLnN0cmlrZSgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdzdHJpa2UnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN0cmlrZSgpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzdHJpa2UnLCAnJywgJycpO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMyBTdHJpbmcucHJvdG90eXBlLnN1YigpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdzdWInLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1Yigpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzdWInLCAnJywgJycpO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xNCBTdHJpbmcucHJvdG90eXBlLnN1cCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdzdXAnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1cCgpe1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzdXAnLCAnJywgJycpO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyAyMS4xLjMuMjUgU3RyaW5nLnByb3RvdHlwZS50cmltKClcbnJlcXVpcmUoJy4vX3N0cmluZy10cmltJykoJ3RyaW0nLCBmdW5jdGlvbigkdHJpbSl7XG4gIHJldHVybiBmdW5jdGlvbiB0cmltKCl7XG4gICAgcmV0dXJuICR0cmltKHRoaXMsIDMpO1xuICB9O1xufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gRUNNQVNjcmlwdCA2IHN5bWJvbHMgc2hpbVxudmFyIGdsb2JhbCAgICAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBoYXMgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgREVTQ1JJUFRPUlMgICAgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpXG4gICwgJGV4cG9ydCAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHJlZGVmaW5lICAgICAgID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKVxuICAsIE1FVEEgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWV0YScpLktFWVxuICAsICRmYWlscyAgICAgICAgID0gcmVxdWlyZSgnLi9fZmFpbHMnKVxuICAsIHNoYXJlZCAgICAgICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkJylcbiAgLCBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJylcbiAgLCB1aWQgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3VpZCcpXG4gICwgd2tzICAgICAgICAgICAgPSByZXF1aXJlKCcuL193a3MnKVxuICAsIHdrc0V4dCAgICAgICAgID0gcmVxdWlyZSgnLi9fd2tzLWV4dCcpXG4gICwgd2tzRGVmaW5lICAgICAgPSByZXF1aXJlKCcuL193a3MtZGVmaW5lJylcbiAgLCBrZXlPZiAgICAgICAgICA9IHJlcXVpcmUoJy4vX2tleW9mJylcbiAgLCBlbnVtS2V5cyAgICAgICA9IHJlcXVpcmUoJy4vX2VudW0ta2V5cycpXG4gICwgaXNBcnJheSAgICAgICAgPSByZXF1aXJlKCcuL19pcy1hcnJheScpXG4gICwgYW5PYmplY3QgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIHRvSU9iamVjdCAgICAgID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXG4gICwgdG9QcmltaXRpdmUgICAgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKVxuICAsIGNyZWF0ZURlc2MgICAgID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpXG4gICwgX2NyZWF0ZSAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJylcbiAgLCBnT1BORXh0ICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuLWV4dCcpXG4gICwgJEdPUEQgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpXG4gICwgJERQICAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsICRrZXlzICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKVxuICAsIGdPUEQgICAgICAgICAgID0gJEdPUEQuZlxuICAsIGRQICAgICAgICAgICAgID0gJERQLmZcbiAgLCBnT1BOICAgICAgICAgICA9IGdPUE5FeHQuZlxuICAsICRTeW1ib2wgICAgICAgID0gZ2xvYmFsLlN5bWJvbFxuICAsICRKU09OICAgICAgICAgID0gZ2xvYmFsLkpTT05cbiAgLCBfc3RyaW5naWZ5ICAgICA9ICRKU09OICYmICRKU09OLnN0cmluZ2lmeVxuICAsIFBST1RPVFlQRSAgICAgID0gJ3Byb3RvdHlwZSdcbiAgLCBISURERU4gICAgICAgICA9IHdrcygnX2hpZGRlbicpXG4gICwgVE9fUFJJTUlUSVZFICAgPSB3a3MoJ3RvUHJpbWl0aXZlJylcbiAgLCBpc0VudW0gICAgICAgICA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlXG4gICwgU3ltYm9sUmVnaXN0cnkgPSBzaGFyZWQoJ3N5bWJvbC1yZWdpc3RyeScpXG4gICwgQWxsU3ltYm9scyAgICAgPSBzaGFyZWQoJ3N5bWJvbHMnKVxuICAsIE9QU3ltYm9scyAgICAgID0gc2hhcmVkKCdvcC1zeW1ib2xzJylcbiAgLCBPYmplY3RQcm90byAgICA9IE9iamVjdFtQUk9UT1RZUEVdXG4gICwgVVNFX05BVElWRSAgICAgPSB0eXBlb2YgJFN5bWJvbCA9PSAnZnVuY3Rpb24nXG4gICwgUU9iamVjdCAgICAgICAgPSBnbG9iYWwuUU9iamVjdDtcbi8vIERvbid0IHVzZSBzZXR0ZXJzIGluIFF0IFNjcmlwdCwgaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzE3M1xudmFyIHNldHRlciA9ICFRT2JqZWN0IHx8ICFRT2JqZWN0W1BST1RPVFlQRV0gfHwgIVFPYmplY3RbUFJPVE9UWVBFXS5maW5kQ2hpbGQ7XG5cbi8vIGZhbGxiYWNrIGZvciBvbGQgQW5kcm9pZCwgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTY4N1xudmFyIHNldFN5bWJvbERlc2MgPSBERVNDUklQVE9SUyAmJiAkZmFpbHMoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIF9jcmVhdGUoZFAoe30sICdhJywge1xuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIGRQKHRoaXMsICdhJywge3ZhbHVlOiA3fSkuYTsgfVxuICB9KSkuYSAhPSA3O1xufSkgPyBmdW5jdGlvbihpdCwga2V5LCBEKXtcbiAgdmFyIHByb3RvRGVzYyA9IGdPUEQoT2JqZWN0UHJvdG8sIGtleSk7XG4gIGlmKHByb3RvRGVzYylkZWxldGUgT2JqZWN0UHJvdG9ba2V5XTtcbiAgZFAoaXQsIGtleSwgRCk7XG4gIGlmKHByb3RvRGVzYyAmJiBpdCAhPT0gT2JqZWN0UHJvdG8pZFAoT2JqZWN0UHJvdG8sIGtleSwgcHJvdG9EZXNjKTtcbn0gOiBkUDtcblxudmFyIHdyYXAgPSBmdW5jdGlvbih0YWcpe1xuICB2YXIgc3ltID0gQWxsU3ltYm9sc1t0YWddID0gX2NyZWF0ZSgkU3ltYm9sW1BST1RPVFlQRV0pO1xuICBzeW0uX2sgPSB0YWc7XG4gIHJldHVybiBzeW07XG59O1xuXG52YXIgaXNTeW1ib2wgPSBVU0VfTkFUSVZFICYmIHR5cGVvZiAkU3ltYm9sLml0ZXJhdG9yID09ICdzeW1ib2wnID8gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnO1xufSA6IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGl0IGluc3RhbmNlb2YgJFN5bWJvbDtcbn07XG5cbnZhciAkZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShpdCwga2V5LCBEKXtcbiAgaWYoaXQgPT09IE9iamVjdFByb3RvKSRkZWZpbmVQcm9wZXJ0eShPUFN5bWJvbHMsIGtleSwgRCk7XG4gIGFuT2JqZWN0KGl0KTtcbiAga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKTtcbiAgYW5PYmplY3QoRCk7XG4gIGlmKGhhcyhBbGxTeW1ib2xzLCBrZXkpKXtcbiAgICBpZighRC5lbnVtZXJhYmxlKXtcbiAgICAgIGlmKCFoYXMoaXQsIEhJRERFTikpZFAoaXQsIEhJRERFTiwgY3JlYXRlRGVzYygxLCB7fSkpO1xuICAgICAgaXRbSElEREVOXVtrZXldID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYoaGFzKGl0LCBISURERU4pICYmIGl0W0hJRERFTl1ba2V5XSlpdFtISURERU5dW2tleV0gPSBmYWxzZTtcbiAgICAgIEQgPSBfY3JlYXRlKEQsIHtlbnVtZXJhYmxlOiBjcmVhdGVEZXNjKDAsIGZhbHNlKX0pO1xuICAgIH0gcmV0dXJuIHNldFN5bWJvbERlc2MoaXQsIGtleSwgRCk7XG4gIH0gcmV0dXJuIGRQKGl0LCBrZXksIEQpO1xufTtcbnZhciAkZGVmaW5lUHJvcGVydGllcyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoaXQsIFApe1xuICBhbk9iamVjdChpdCk7XG4gIHZhciBrZXlzID0gZW51bUtleXMoUCA9IHRvSU9iamVjdChQKSlcbiAgICAsIGkgICAgPSAwXG4gICAgLCBsID0ga2V5cy5sZW5ndGhcbiAgICAsIGtleTtcbiAgd2hpbGUobCA+IGkpJGRlZmluZVByb3BlcnR5KGl0LCBrZXkgPSBrZXlzW2krK10sIFBba2V5XSk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgJGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpdCwgUCl7XG4gIHJldHVybiBQID09PSB1bmRlZmluZWQgPyBfY3JlYXRlKGl0KSA6ICRkZWZpbmVQcm9wZXJ0aWVzKF9jcmVhdGUoaXQpLCBQKTtcbn07XG52YXIgJHByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gcHJvcGVydHlJc0VudW1lcmFibGUoa2V5KXtcbiAgdmFyIEUgPSBpc0VudW0uY2FsbCh0aGlzLCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKTtcbiAgaWYodGhpcyA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gRSB8fCAhaGFzKHRoaXMsIGtleSkgfHwgIWhhcyhBbGxTeW1ib2xzLCBrZXkpIHx8IGhhcyh0aGlzLCBISURERU4pICYmIHRoaXNbSElEREVOXVtrZXldID8gRSA6IHRydWU7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSl7XG4gIGl0ICA9IHRvSU9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGlmKGl0ID09PSBPYmplY3RQcm90byAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhaGFzKE9QU3ltYm9scywga2V5KSlyZXR1cm47XG4gIHZhciBEID0gZ09QRChpdCwga2V5KTtcbiAgaWYoRCAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0pKUQuZW51bWVyYWJsZSA9IHRydWU7XG4gIHJldHVybiBEO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlOYW1lcyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoaXQpe1xuICB2YXIgbmFtZXMgID0gZ09QTih0b0lPYmplY3QoaXQpKVxuICAgICwgcmVzdWx0ID0gW11cbiAgICAsIGkgICAgICA9IDBcbiAgICAsIGtleTtcbiAgd2hpbGUobmFtZXMubGVuZ3RoID4gaSl7XG4gICAgaWYoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOICYmIGtleSAhPSBNRVRBKXJlc3VsdC5wdXNoKGtleSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG52YXIgJGdldE93blByb3BlcnR5U3ltYm9scyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5U3ltYm9scyhpdCl7XG4gIHZhciBJU19PUCAgPSBpdCA9PT0gT2JqZWN0UHJvdG9cbiAgICAsIG5hbWVzICA9IGdPUE4oSVNfT1AgPyBPUFN5bWJvbHMgOiB0b0lPYmplY3QoaXQpKVxuICAgICwgcmVzdWx0ID0gW11cbiAgICAsIGkgICAgICA9IDBcbiAgICAsIGtleTtcbiAgd2hpbGUobmFtZXMubGVuZ3RoID4gaSl7XG4gICAgaWYoaGFzKEFsbFN5bWJvbHMsIGtleSA9IG5hbWVzW2krK10pICYmIChJU19PUCA/IGhhcyhPYmplY3RQcm90bywga2V5KSA6IHRydWUpKXJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIDE5LjQuMS4xIFN5bWJvbChbZGVzY3JpcHRpb25dKVxuaWYoIVVTRV9OQVRJVkUpe1xuICAkU3ltYm9sID0gZnVuY3Rpb24gU3ltYm9sKCl7XG4gICAgaWYodGhpcyBpbnN0YW5jZW9mICRTeW1ib2wpdGhyb3cgVHlwZUVycm9yKCdTeW1ib2wgaXMgbm90IGEgY29uc3RydWN0b3IhJyk7XG4gICAgdmFyIHRhZyA9IHVpZChhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7XG4gICAgdmFyICRzZXQgPSBmdW5jdGlvbih2YWx1ZSl7XG4gICAgICBpZih0aGlzID09PSBPYmplY3RQcm90bykkc2V0LmNhbGwoT1BTeW1ib2xzLCB2YWx1ZSk7XG4gICAgICBpZihoYXModGhpcywgSElEREVOKSAmJiBoYXModGhpc1tISURERU5dLCB0YWcpKXRoaXNbSElEREVOXVt0YWddID0gZmFsc2U7XG4gICAgICBzZXRTeW1ib2xEZXNjKHRoaXMsIHRhZywgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xuICAgIH07XG4gICAgaWYoREVTQ1JJUFRPUlMgJiYgc2V0dGVyKXNldFN5bWJvbERlc2MoT2JqZWN0UHJvdG8sIHRhZywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgc2V0OiAkc2V0fSk7XG4gICAgcmV0dXJuIHdyYXAodGFnKTtcbiAgfTtcbiAgcmVkZWZpbmUoJFN5bWJvbFtQUk9UT1RZUEVdLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpe1xuICAgIHJldHVybiB0aGlzLl9rO1xuICB9KTtcblxuICAkR09QRC5mID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiAgJERQLmYgICA9ICRkZWZpbmVQcm9wZXJ0eTtcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mID0gZ09QTkV4dC5mID0gJGdldE93blByb3BlcnR5TmFtZXM7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1waWUnKS5mICA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKS5mID0gJGdldE93blByb3BlcnR5U3ltYm9scztcblxuICBpZihERVNDUklQVE9SUyAmJiAhcmVxdWlyZSgnLi9fbGlicmFyeScpKXtcbiAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcbiAgfVxuXG4gIHdrc0V4dC5mID0gZnVuY3Rpb24obmFtZSl7XG4gICAgcmV0dXJuIHdyYXAod2tzKG5hbWUpKTtcbiAgfVxufVxuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCB7U3ltYm9sOiAkU3ltYm9sfSk7XG5cbmZvcih2YXIgc3ltYm9scyA9IChcbiAgLy8gMTkuNC4yLjIsIDE5LjQuMi4zLCAxOS40LjIuNCwgMTkuNC4yLjYsIDE5LjQuMi44LCAxOS40LjIuOSwgMTkuNC4yLjEwLCAxOS40LjIuMTEsIDE5LjQuMi4xMiwgMTkuNC4yLjEzLCAxOS40LjIuMTRcbiAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCxzcGVjaWVzLHNwbGl0LHRvUHJpbWl0aXZlLHRvU3RyaW5nVGFnLHVuc2NvcGFibGVzJ1xuKS5zcGxpdCgnLCcpLCBpID0gMDsgc3ltYm9scy5sZW5ndGggPiBpOyApd2tzKHN5bWJvbHNbaSsrXSk7XG5cbmZvcih2YXIgc3ltYm9scyA9ICRrZXlzKHdrcy5zdG9yZSksIGkgPSAwOyBzeW1ib2xzLmxlbmd0aCA+IGk7ICl3a3NEZWZpbmUoc3ltYm9sc1tpKytdKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ1N5bWJvbCcsIHtcbiAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG4gICdmb3InOiBmdW5jdGlvbihrZXkpe1xuICAgIHJldHVybiBoYXMoU3ltYm9sUmVnaXN0cnksIGtleSArPSAnJylcbiAgICAgID8gU3ltYm9sUmVnaXN0cnlba2V5XVxuICAgICAgOiBTeW1ib2xSZWdpc3RyeVtrZXldID0gJFN5bWJvbChrZXkpO1xuICB9LFxuICAvLyAxOS40LjIuNSBTeW1ib2wua2V5Rm9yKHN5bSlcbiAga2V5Rm9yOiBmdW5jdGlvbiBrZXlGb3Ioa2V5KXtcbiAgICBpZihpc1N5bWJvbChrZXkpKXJldHVybiBrZXlPZihTeW1ib2xSZWdpc3RyeSwga2V5KTtcbiAgICB0aHJvdyBUeXBlRXJyb3Ioa2V5ICsgJyBpcyBub3QgYSBzeW1ib2whJyk7XG4gIH0sXG4gIHVzZVNldHRlcjogZnVuY3Rpb24oKXsgc2V0dGVyID0gdHJ1ZTsgfSxcbiAgdXNlU2ltcGxlOiBmdW5jdGlvbigpeyBzZXR0ZXIgPSBmYWxzZTsgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdPYmplY3QnLCB7XG4gIC8vIDE5LjEuMi4yIE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbiAgY3JlYXRlOiAkY3JlYXRlLFxuICAvLyAxOS4xLjIuNCBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcbiAgZGVmaW5lUHJvcGVydHk6ICRkZWZpbmVQcm9wZXJ0eSxcbiAgLy8gMTkuMS4yLjMgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiAgZGVmaW5lUHJvcGVydGllczogJGRlZmluZVByb3BlcnRpZXMsXG4gIC8vIDE5LjEuMi42IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUClcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICAvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxuICBnZXRPd25Qcm9wZXJ0eU5hbWVzOiAkZ2V0T3duUHJvcGVydHlOYW1lcyxcbiAgLy8gMTkuMS4yLjggT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhPKVxuICBnZXRPd25Qcm9wZXJ0eVN5bWJvbHM6ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHNcbn0pO1xuXG4vLyAyNC4zLjIgSlNPTi5zdHJpbmdpZnkodmFsdWUgWywgcmVwbGFjZXIgWywgc3BhY2VdXSlcbiRKU09OICYmICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCFVU0VfTkFUSVZFIHx8ICRmYWlscyhmdW5jdGlvbigpe1xuICB2YXIgUyA9ICRTeW1ib2woKTtcbiAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cbiAgLy8gV2ViS2l0IGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyBudWxsXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXG4gIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7YTogU30pICE9ICd7fScgfHwgX3N0cmluZ2lmeShPYmplY3QoUykpICE9ICd7fSc7XG59KSksICdKU09OJywge1xuICBzdHJpbmdpZnk6IGZ1bmN0aW9uIHN0cmluZ2lmeShpdCl7XG4gICAgaWYoaXQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bWJvbChpdCkpcmV0dXJuOyAvLyBJRTggcmV0dXJucyBzdHJpbmcgb24gdW5kZWZpbmVkXG4gICAgdmFyIGFyZ3MgPSBbaXRdXG4gICAgICAsIGkgICAgPSAxXG4gICAgICAsIHJlcGxhY2VyLCAkcmVwbGFjZXI7XG4gICAgd2hpbGUoYXJndW1lbnRzLmxlbmd0aCA+IGkpYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICByZXBsYWNlciA9IGFyZ3NbMV07XG4gICAgaWYodHlwZW9mIHJlcGxhY2VyID09ICdmdW5jdGlvbicpJHJlcGxhY2VyID0gcmVwbGFjZXI7XG4gICAgaWYoJHJlcGxhY2VyIHx8ICFpc0FycmF5KHJlcGxhY2VyKSlyZXBsYWNlciA9IGZ1bmN0aW9uKGtleSwgdmFsdWUpe1xuICAgICAgaWYoJHJlcGxhY2VyKXZhbHVlID0gJHJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSk7XG4gICAgICBpZighaXNTeW1ib2wodmFsdWUpKXJldHVybiB2YWx1ZTtcbiAgICB9O1xuICAgIGFyZ3NbMV0gPSByZXBsYWNlcjtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG4gIH1cbn0pO1xuXG4vLyAxOS40LjMuNCBTeW1ib2wucHJvdG90eXBlW0BAdG9QcmltaXRpdmVdKGhpbnQpXG4kU3ltYm9sW1BST1RPVFlQRV1bVE9fUFJJTUlUSVZFXSB8fCByZXF1aXJlKCcuL19oaWRlJykoJFN5bWJvbFtQUk9UT1RZUEVdLCBUT19QUklNSVRJVkUsICRTeW1ib2xbUFJPVE9UWVBFXS52YWx1ZU9mKTtcbi8vIDE5LjQuMy41IFN5bWJvbC5wcm90b3R5cGVbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKCRTeW1ib2wsICdTeW1ib2wnKTtcbi8vIDIwLjIuMS45IE1hdGhbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKE1hdGgsICdNYXRoJywgdHJ1ZSk7XG4vLyAyNC4zLjMgSlNPTltAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoZ2xvYmFsLkpTT04sICdKU09OJywgdHJ1ZSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJHR5cGVkICAgICAgID0gcmVxdWlyZSgnLi9fdHlwZWQnKVxuICAsIGJ1ZmZlciAgICAgICA9IHJlcXVpcmUoJy4vX3R5cGVkLWJ1ZmZlcicpXG4gICwgYW5PYmplY3QgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCB0b0luZGV4ICAgICAgPSByZXF1aXJlKCcuL190by1pbmRleCcpXG4gICwgdG9MZW5ndGggICAgID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJylcbiAgLCBpc09iamVjdCAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIEFycmF5QnVmZmVyICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLkFycmF5QnVmZmVyXG4gICwgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpXG4gICwgJEFycmF5QnVmZmVyID0gYnVmZmVyLkFycmF5QnVmZmVyXG4gICwgJERhdGFWaWV3ICAgID0gYnVmZmVyLkRhdGFWaWV3XG4gICwgJGlzVmlldyAgICAgID0gJHR5cGVkLkFCViAmJiBBcnJheUJ1ZmZlci5pc1ZpZXdcbiAgLCAkc2xpY2UgICAgICAgPSAkQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlXG4gICwgVklFVyAgICAgICAgID0gJHR5cGVkLlZJRVdcbiAgLCBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChBcnJheUJ1ZmZlciAhPT0gJEFycmF5QnVmZmVyKSwge0FycmF5QnVmZmVyOiAkQXJyYXlCdWZmZXJ9KTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhJHR5cGVkLkNPTlNUUiwgQVJSQVlfQlVGRkVSLCB7XG4gIC8vIDI0LjEuMy4xIEFycmF5QnVmZmVyLmlzVmlldyhhcmcpXG4gIGlzVmlldzogZnVuY3Rpb24gaXNWaWV3KGl0KXtcbiAgICByZXR1cm4gJGlzVmlldyAmJiAkaXNWaWV3KGl0KSB8fCBpc09iamVjdChpdCkgJiYgVklFVyBpbiBpdDtcbiAgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5VICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICByZXR1cm4gIW5ldyAkQXJyYXlCdWZmZXIoMikuc2xpY2UoMSwgdW5kZWZpbmVkKS5ieXRlTGVuZ3RoO1xufSksIEFSUkFZX0JVRkZFUiwge1xuICAvLyAyNC4xLjQuMyBBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2Uoc3RhcnQsIGVuZClcbiAgc2xpY2U6IGZ1bmN0aW9uIHNsaWNlKHN0YXJ0LCBlbmQpe1xuICAgIGlmKCRzbGljZSAhPT0gdW5kZWZpbmVkICYmIGVuZCA9PT0gdW5kZWZpbmVkKXJldHVybiAkc2xpY2UuY2FsbChhbk9iamVjdCh0aGlzKSwgc3RhcnQpOyAvLyBGRiBmaXhcbiAgICB2YXIgbGVuICAgID0gYW5PYmplY3QodGhpcykuYnl0ZUxlbmd0aFxuICAgICAgLCBmaXJzdCAgPSB0b0luZGV4KHN0YXJ0LCBsZW4pXG4gICAgICAsIGZpbmFsICA9IHRvSW5kZXgoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQsIGxlbilcbiAgICAgICwgcmVzdWx0ID0gbmV3IChzcGVjaWVzQ29uc3RydWN0b3IodGhpcywgJEFycmF5QnVmZmVyKSkodG9MZW5ndGgoZmluYWwgLSBmaXJzdCkpXG4gICAgICAsIHZpZXdTICA9IG5ldyAkRGF0YVZpZXcodGhpcylcbiAgICAgICwgdmlld1QgID0gbmV3ICREYXRhVmlldyhyZXN1bHQpXG4gICAgICAsIGluZGV4ICA9IDA7XG4gICAgd2hpbGUoZmlyc3QgPCBmaW5hbCl7XG4gICAgICB2aWV3VC5zZXRVaW50OChpbmRleCsrLCB2aWV3Uy5nZXRVaW50OChmaXJzdCsrKSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShBUlJBWV9CVUZGRVIpOyIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL190eXBlZCcpLkFCViwge1xuICBEYXRhVmlldzogcmVxdWlyZSgnLi9fdHlwZWQtYnVmZmVyJykuRGF0YVZpZXdcbn0pOyIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0Zsb2F0MzInLCA0LCBmdW5jdGlvbihpbml0KXtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTsiLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDY0JywgOCwgZnVuY3Rpb24oaW5pdCl7XG4gIHJldHVybiBmdW5jdGlvbiBGbG9hdDY0QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7IiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50MTYnLCAyLCBmdW5jdGlvbihpbml0KXtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7IiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50MzInLCA0LCBmdW5jdGlvbihpbml0KXtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDMyQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7IiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50OCcsIDEsIGZ1bmN0aW9uKGluaXQpe1xuICByZXR1cm4gZnVuY3Rpb24gSW50OEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCl7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pOyIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQxNicsIDIsIGZ1bmN0aW9uKGluaXQpe1xuICByZXR1cm4gZnVuY3Rpb24gVWludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7IiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDMyJywgNCwgZnVuY3Rpb24oaW5pdCl7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTsiLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50OCcsIDEsIGZ1bmN0aW9uKGluaXQpe1xuICByZXR1cm4gZnVuY3Rpb24gVWludDhBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTsiLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50OCcsIDEsIGZ1bmN0aW9uKGluaXQpe1xuICByZXR1cm4gZnVuY3Rpb24gVWludDhDbGFtcGVkQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSwgdHJ1ZSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGVhY2ggICAgICAgICA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSgwKVxuICAsIHJlZGVmaW5lICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBtZXRhICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhJylcbiAgLCBhc3NpZ24gICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtYXNzaWduJylcbiAgLCB3ZWFrICAgICAgICAgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKVxuICAsIGlzT2JqZWN0ICAgICA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgZ2V0V2VhayAgICAgID0gbWV0YS5nZXRXZWFrXG4gICwgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZVxuICAsIHVuY2F1Z2h0RnJvemVuU3RvcmUgPSB3ZWFrLnVmc3RvcmVcbiAgLCB0bXAgICAgICAgICAgPSB7fVxuICAsIEludGVybmFsTWFwO1xuXG52YXIgd3JhcHBlciA9IGZ1bmN0aW9uKGdldCl7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCl7XG4gICAgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7XG4gIH07XG59O1xuXG52YXIgbWV0aG9kcyA9IHtcbiAgLy8gMjMuMy4zLjMgV2Vha01hcC5wcm90b3R5cGUuZ2V0KGtleSlcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KXtcbiAgICBpZihpc09iamVjdChrZXkpKXtcbiAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgaWYoZGF0YSA9PT0gdHJ1ZSlyZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh0aGlzKS5nZXQoa2V5KTtcbiAgICAgIHJldHVybiBkYXRhID8gZGF0YVt0aGlzLl9pXSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0sXG4gIC8vIDIzLjMuMy41IFdlYWtNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKXtcbiAgICByZXR1cm4gd2Vhay5kZWYodGhpcywga2V5LCB2YWx1ZSk7XG4gIH1cbn07XG5cbi8vIDIzLjMgV2Vha01hcCBPYmplY3RzXG52YXIgJFdlYWtNYXAgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKSgnV2Vha01hcCcsIHdyYXBwZXIsIG1ldGhvZHMsIHdlYWssIHRydWUsIHRydWUpO1xuXG4vLyBJRTExIFdlYWtNYXAgZnJvemVuIGtleXMgZml4XG5pZihuZXcgJFdlYWtNYXAoKS5zZXQoKE9iamVjdC5mcmVlemUgfHwgT2JqZWN0KSh0bXApLCA3KS5nZXQodG1wKSAhPSA3KXtcbiAgSW50ZXJuYWxNYXAgPSB3ZWFrLmdldENvbnN0cnVjdG9yKHdyYXBwZXIpO1xuICBhc3NpZ24oSW50ZXJuYWxNYXAucHJvdG90eXBlLCBtZXRob2RzKTtcbiAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgZWFjaChbJ2RlbGV0ZScsICdoYXMnLCAnZ2V0JywgJ3NldCddLCBmdW5jdGlvbihrZXkpe1xuICAgIHZhciBwcm90byAgPSAkV2Vha01hcC5wcm90b3R5cGVcbiAgICAgICwgbWV0aG9kID0gcHJvdG9ba2V5XTtcbiAgICByZWRlZmluZShwcm90bywga2V5LCBmdW5jdGlvbihhLCBiKXtcbiAgICAgIC8vIHN0b3JlIGZyb3plbiBvYmplY3RzIG9uIGludGVybmFsIHdlYWttYXAgc2hpbVxuICAgICAgaWYoaXNPYmplY3QoYSkgJiYgIWlzRXh0ZW5zaWJsZShhKSl7XG4gICAgICAgIGlmKCF0aGlzLl9mKXRoaXMuX2YgPSBuZXcgSW50ZXJuYWxNYXA7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9mW2tleV0oYSwgYik7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NldCcgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXG4gICAgICB9IHJldHVybiBtZXRob2QuY2FsbCh0aGlzLCBhLCBiKTtcbiAgICB9KTtcbiAgfSk7XG59IiwiJ3VzZSBzdHJpY3QnO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcblxuLy8gMjMuNCBXZWFrU2V0IE9iamVjdHNcbnJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKSgnV2Vha1NldCcsIGZ1bmN0aW9uKGdldCl7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrU2V0KCl7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy40LjMuMSBXZWFrU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKXtcbiAgICByZXR1cm4gd2Vhay5kZWYodGhpcywgdmFsdWUsIHRydWUpO1xuICB9XG59LCB3ZWFrLCBmYWxzZSwgdHJ1ZSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG52YXIgJGV4cG9ydCAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkaW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoZWwgLyosIGZyb21JbmRleCA9IDAgKi8pe1xuICAgIHJldHVybiAkaW5jbHVkZXModGhpcywgZWwsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdpbmNsdWRlcycpOyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9yd2FsZHJvbi90YzM5LW5vdGVzL2Jsb2IvbWFzdGVyL2VzNi8yMDE0LTA5L3NlcHQtMjUubWQjNTEwLWdsb2JhbGFzYXAtZm9yLWVucXVldWluZy1hLW1pY3JvdGFza1xudmFyICRleHBvcnQgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKVxuICAsIHByb2Nlc3MgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLnByb2Nlc3NcbiAgLCBpc05vZGUgICAgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG5cbiRleHBvcnQoJGV4cG9ydC5HLCB7XG4gIGFzYXA6IGZ1bmN0aW9uIGFzYXAoZm4pe1xuICAgIHZhciBkb21haW4gPSBpc05vZGUgJiYgcHJvY2Vzcy5kb21haW47XG4gICAgbWljcm90YXNrKGRvbWFpbiA/IGRvbWFpbi5iaW5kKGZuKSA6IGZuKTtcbiAgfVxufSk7IiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9wcm9wb3NhbC1pcy1lcnJvclxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGNvZiAgICAgPSByZXF1aXJlKCcuL19jb2YnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdFcnJvcicsIHtcbiAgaXNFcnJvcjogZnVuY3Rpb24gaXNFcnJvcihpdCl7XG4gICAgcmV0dXJuIGNvZihpdCkgPT09ICdFcnJvcic7XG4gIH1cbn0pOyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EYXZpZEJydWFudC9NYXAtU2V0LnByb3RvdHlwZS50b0pTT05cbnZhciAkZXhwb3J0ICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuUiwgJ01hcCcsIHt0b0pTT046IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tdG8tanNvbicpKCdNYXAnKX0pOyIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGlhZGRoOiBmdW5jdGlvbiBpYWRkaCh4MCwgeDEsIHkwLCB5MSl7XG4gICAgdmFyICR4MCA9IHgwID4+PiAwXG4gICAgICAsICR4MSA9IHgxID4+PiAwXG4gICAgICAsICR5MCA9IHkwID4+PiAwO1xuICAgIHJldHVybiAkeDEgKyAoeTEgPj4+IDApICsgKCgkeDAgJiAkeTAgfCAoJHgwIHwgJHkwKSAmIH4oJHgwICsgJHkwID4+PiAwKSkgPj4+IDMxKSB8IDA7XG4gIH1cbn0pOyIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGltdWxoOiBmdW5jdGlvbiBpbXVsaCh1LCB2KXtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmXG4gICAgICAsICR1ID0gK3VcbiAgICAgICwgJHYgPSArdlxuICAgICAgLCB1MCA9ICR1ICYgVUlOVDE2XG4gICAgICAsIHYwID0gJHYgJiBVSU5UMTZcbiAgICAgICwgdTEgPSAkdSA+PiAxNlxuICAgICAgLCB2MSA9ICR2ID4+IDE2XG4gICAgICAsIHQgID0gKHUxICogdjAgPj4+IDApICsgKHUwICogdjAgPj4+IDE2KTtcbiAgICByZXR1cm4gdTEgKiB2MSArICh0ID4+IDE2KSArICgodTAgKiB2MSA+Pj4gMCkgKyAodCAmIFVJTlQxNikgPj4gMTYpO1xuICB9XG59KTsiLCIvLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9CcmVuZGFuRWljaC80Mjk0ZDVjMjEyYTZkMjI1NDcwM1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBpc3ViaDogZnVuY3Rpb24gaXN1YmgoeDAsIHgxLCB5MCwgeTEpe1xuICAgIHZhciAkeDAgPSB4MCA+Pj4gMFxuICAgICAgLCAkeDEgPSB4MSA+Pj4gMFxuICAgICAgLCAkeTAgPSB5MCA+Pj4gMDtcbiAgICByZXR1cm4gJHgxIC0gKHkxID4+PiAwKSAtICgofiR4MCAmICR5MCB8IH4oJHgwIF4gJHkwKSAmICR4MCAtICR5MCA+Pj4gMCkgPj4+IDMxKSB8IDA7XG4gIH1cbn0pOyIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIHVtdWxoOiBmdW5jdGlvbiB1bXVsaCh1LCB2KXtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmXG4gICAgICAsICR1ID0gK3VcbiAgICAgICwgJHYgPSArdlxuICAgICAgLCB1MCA9ICR1ICYgVUlOVDE2XG4gICAgICAsIHYwID0gJHYgJiBVSU5UMTZcbiAgICAgICwgdTEgPSAkdSA+Pj4gMTZcbiAgICAgICwgdjEgPSAkdiA+Pj4gMTZcbiAgICAgICwgdCAgPSAodTEgKiB2MCA+Pj4gMCkgKyAodTAgKiB2MCA+Pj4gMTYpO1xuICAgIHJldHVybiB1MSAqIHYxICsgKHQgPj4+IDE2KSArICgodTAgKiB2MSA+Pj4gMCkgKyAodCAmIFVJTlQxNikgPj4+IDE2KTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgdG9PYmplY3QgICAgICAgID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0JylcbiAgLCBhRnVuY3Rpb24gICAgICAgPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcblxuLy8gQi4yLjIuMiBPYmplY3QucHJvdG90eXBlLl9fZGVmaW5lR2V0dGVyX18oUCwgZ2V0dGVyKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fZGVmaW5lR2V0dGVyX186IGZ1bmN0aW9uIF9fZGVmaW5lR2V0dGVyX18oUCwgZ2V0dGVyKXtcbiAgICAkZGVmaW5lUHJvcGVydHkuZih0b09iamVjdCh0aGlzKSwgUCwge2dldDogYUZ1bmN0aW9uKGdldHRlciksIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZX0pO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b09iamVjdCAgICAgICAgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIGFGdW5jdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKVxuICAsICRkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xuXG4vLyBCLjIuMi4zIE9iamVjdC5wcm90b3R5cGUuX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpXG5yZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICRleHBvcnQoJGV4cG9ydC5QICsgcmVxdWlyZSgnLi9fb2JqZWN0LWZvcmNlZC1wYW0nKSwgJ09iamVjdCcsIHtcbiAgX19kZWZpbmVTZXR0ZXJfXzogZnVuY3Rpb24gX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpe1xuICAgICRkZWZpbmVQcm9wZXJ0eS5mKHRvT2JqZWN0KHRoaXMpLCBQLCB7c2V0OiBhRnVuY3Rpb24oc2V0dGVyKSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlfSk7XG4gIH1cbn0pOyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC12YWx1ZXMtZW50cmllc1xudmFyICRleHBvcnQgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkZW50cmllcyA9IHJlcXVpcmUoJy4vX29iamVjdC10by1hcnJheScpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgZW50cmllczogZnVuY3Rpb24gZW50cmllcyhpdCl7XG4gICAgcmV0dXJuICRlbnRyaWVzKGl0KTtcbiAgfVxufSk7IiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LWdldG93bnByb3BlcnR5ZGVzY3JpcHRvcnNcbnZhciAkZXhwb3J0ICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgb3duS2V5cyAgICAgICAgPSByZXF1aXJlKCcuL19vd24ta2V5cycpXG4gICwgdG9JT2JqZWN0ICAgICAgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCBnT1BEICAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJylcbiAgLCBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yczogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmplY3Qpe1xuICAgIHZhciBPICAgICAgID0gdG9JT2JqZWN0KG9iamVjdClcbiAgICAgICwgZ2V0RGVzYyA9IGdPUEQuZlxuICAgICAgLCBrZXlzICAgID0gb3duS2V5cyhPKVxuICAgICAgLCByZXN1bHQgID0ge31cbiAgICAgICwgaSAgICAgICA9IDBcbiAgICAgICwga2V5O1xuICAgIHdoaWxlKGtleXMubGVuZ3RoID4gaSljcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGtleSA9IGtleXNbaSsrXSwgZ2V0RGVzYyhPLCBrZXkpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCAgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCB0b09iamVjdCAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIHRvUHJpbWl0aXZlICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXG4gICwgZ2V0UHJvdG90eXBlT2YgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpXG4gICwgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG4vLyBCLjIuMi40IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBHZXR0ZXJfXyhQKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fbG9va3VwR2V0dGVyX186IGZ1bmN0aW9uIF9fbG9va3VwR2V0dGVyX18oUCl7XG4gICAgdmFyIE8gPSB0b09iamVjdCh0aGlzKVxuICAgICAgLCBLID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSlcbiAgICAgICwgRDtcbiAgICBkbyB7XG4gICAgICBpZihEID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIEspKXJldHVybiBELmdldDtcbiAgICB9IHdoaWxlKE8gPSBnZXRQcm90b3R5cGVPZihPKSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ICAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHRvT2JqZWN0ICAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgdG9QcmltaXRpdmUgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcbiAgLCBnZXRQcm90b3R5cGVPZiAgICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJylcbiAgLCBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG5cbi8vIEIuMi4yLjUgT2JqZWN0LnByb3RvdHlwZS5fX2xvb2t1cFNldHRlcl9fKFApXG5yZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICRleHBvcnQoJGV4cG9ydC5QICsgcmVxdWlyZSgnLi9fb2JqZWN0LWZvcmNlZC1wYW0nKSwgJ09iamVjdCcsIHtcbiAgX19sb29rdXBTZXR0ZXJfXzogZnVuY3Rpb24gX19sb29rdXBTZXR0ZXJfXyhQKXtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpXG4gICAgICAsIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKVxuICAgICAgLCBEO1xuICAgIGRvIHtcbiAgICAgIGlmKEQgPSBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgSykpcmV0dXJuIEQuc2V0O1xuICAgIH0gd2hpbGUoTyA9IGdldFByb3RvdHlwZU9mKE8pKTtcbiAgfVxufSk7IiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJHZhbHVlcyA9IHJlcXVpcmUoJy4vX29iamVjdC10by1hcnJheScpKGZhbHNlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XG4gIHZhbHVlczogZnVuY3Rpb24gdmFsdWVzKGl0KXtcbiAgICByZXR1cm4gJHZhbHVlcyhpdCk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96ZW5wYXJzaW5nL2VzLW9ic2VydmFibGVcbnZhciAkZXhwb3J0ICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgZ2xvYmFsICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGNvcmUgICAgICAgID0gcmVxdWlyZSgnLi9fY29yZScpXG4gICwgbWljcm90YXNrICAgPSByZXF1aXJlKCcuL19taWNyb3Rhc2snKSgpXG4gICwgT0JTRVJWQUJMRSAgPSByZXF1aXJlKCcuL193a3MnKSgnb2JzZXJ2YWJsZScpXG4gICwgYUZ1bmN0aW9uICAgPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCBhbk9iamVjdCAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgYW5JbnN0YW5jZSAgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpXG4gICwgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKVxuICAsIGhpZGUgICAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgZm9yT2YgICAgICAgPSByZXF1aXJlKCcuL19mb3Itb2YnKVxuICAsIFJFVFVSTiAgICAgID0gZm9yT2YuUkVUVVJOO1xuXG52YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oZm4pe1xuICByZXR1cm4gZm4gPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGFGdW5jdGlvbihmbik7XG59O1xuXG52YXIgY2xlYW51cFN1YnNjcmlwdGlvbiA9IGZ1bmN0aW9uKHN1YnNjcmlwdGlvbil7XG4gIHZhciBjbGVhbnVwID0gc3Vic2NyaXB0aW9uLl9jO1xuICBpZihjbGVhbnVwKXtcbiAgICBzdWJzY3JpcHRpb24uX2MgPSB1bmRlZmluZWQ7XG4gICAgY2xlYW51cCgpO1xuICB9XG59O1xuXG52YXIgc3Vic2NyaXB0aW9uQ2xvc2VkID0gZnVuY3Rpb24oc3Vic2NyaXB0aW9uKXtcbiAgcmV0dXJuIHN1YnNjcmlwdGlvbi5fbyA9PT0gdW5kZWZpbmVkO1xufTtcblxudmFyIGNsb3NlU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24oc3Vic2NyaXB0aW9uKXtcbiAgaWYoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXtcbiAgICBzdWJzY3JpcHRpb24uX28gPSB1bmRlZmluZWQ7XG4gICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICB9XG59O1xuXG52YXIgU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24ob2JzZXJ2ZXIsIHN1YnNjcmliZXIpe1xuICBhbk9iamVjdChvYnNlcnZlcik7XG4gIHRoaXMuX2MgPSB1bmRlZmluZWQ7XG4gIHRoaXMuX28gPSBvYnNlcnZlcjtcbiAgb2JzZXJ2ZXIgPSBuZXcgU3Vic2NyaXB0aW9uT2JzZXJ2ZXIodGhpcyk7XG4gIHRyeSB7XG4gICAgdmFyIGNsZWFudXAgICAgICA9IHN1YnNjcmliZXIob2JzZXJ2ZXIpXG4gICAgICAsIHN1YnNjcmlwdGlvbiA9IGNsZWFudXA7XG4gICAgaWYoY2xlYW51cCAhPSBudWxsKXtcbiAgICAgIGlmKHR5cGVvZiBjbGVhbnVwLnVuc3Vic2NyaWJlID09PSAnZnVuY3Rpb24nKWNsZWFudXAgPSBmdW5jdGlvbigpeyBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTsgfTtcbiAgICAgIGVsc2UgYUZ1bmN0aW9uKGNsZWFudXApO1xuICAgICAgdGhpcy5fYyA9IGNsZWFudXA7XG4gICAgfVxuICB9IGNhdGNoKGUpe1xuICAgIG9ic2VydmVyLmVycm9yKGUpO1xuICAgIHJldHVybjtcbiAgfSBpZihzdWJzY3JpcHRpb25DbG9zZWQodGhpcykpY2xlYW51cFN1YnNjcmlwdGlvbih0aGlzKTtcbn07XG5cblN1YnNjcmlwdGlvbi5wcm90b3R5cGUgPSByZWRlZmluZUFsbCh7fSwge1xuICB1bnN1YnNjcmliZTogZnVuY3Rpb24gdW5zdWJzY3JpYmUoKXsgY2xvc2VTdWJzY3JpcHRpb24odGhpcyk7IH1cbn0pO1xuXG52YXIgU3Vic2NyaXB0aW9uT2JzZXJ2ZXIgPSBmdW5jdGlvbihzdWJzY3JpcHRpb24pe1xuICB0aGlzLl9zID0gc3Vic2NyaXB0aW9uO1xufTtcblxuU3Vic2NyaXB0aW9uT2JzZXJ2ZXIucHJvdG90eXBlID0gcmVkZWZpbmVBbGwoe30sIHtcbiAgbmV4dDogZnVuY3Rpb24gbmV4dCh2YWx1ZSl7XG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IHRoaXMuX3M7XG4gICAgaWYoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXtcbiAgICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBtID0gZ2V0TWV0aG9kKG9ic2VydmVyLm5leHQpO1xuICAgICAgICBpZihtKXJldHVybiBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY2xvc2VTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBlcnJvcjogZnVuY3Rpb24gZXJyb3IodmFsdWUpe1xuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xuICAgIGlmKHN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXRocm93IHZhbHVlO1xuICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcbiAgICBzdWJzY3JpcHRpb24uX28gPSB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBtID0gZ2V0TWV0aG9kKG9ic2VydmVyLmVycm9yKTtcbiAgICAgIGlmKCFtKXRocm93IHZhbHVlO1xuICAgICAgdmFsdWUgPSBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGNvbXBsZXRlOiBmdW5jdGlvbiBjb21wbGV0ZSh2YWx1ZSl7XG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IHRoaXMuX3M7XG4gICAgaWYoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXtcbiAgICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcbiAgICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBtID0gZ2V0TWV0aG9kKG9ic2VydmVyLmNvbXBsZXRlKTtcbiAgICAgICAgdmFsdWUgPSBtID8gbS5jYWxsKG9ic2VydmVyLCB2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gICAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9IGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH1cbn0pO1xuXG52YXIgJE9ic2VydmFibGUgPSBmdW5jdGlvbiBPYnNlcnZhYmxlKHN1YnNjcmliZXIpe1xuICBhbkluc3RhbmNlKHRoaXMsICRPYnNlcnZhYmxlLCAnT2JzZXJ2YWJsZScsICdfZicpLl9mID0gYUZ1bmN0aW9uKHN1YnNjcmliZXIpO1xufTtcblxucmVkZWZpbmVBbGwoJE9ic2VydmFibGUucHJvdG90eXBlLCB7XG4gIHN1YnNjcmliZTogZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKXtcbiAgICByZXR1cm4gbmV3IFN1YnNjcmlwdGlvbihvYnNlcnZlciwgdGhpcy5fZik7XG4gIH0sXG4gIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goZm4pe1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICByZXR1cm4gbmV3IChjb3JlLlByb21pc2UgfHwgZ2xvYmFsLlByb21pc2UpKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgICBhRnVuY3Rpb24oZm4pO1xuICAgICAgdmFyIHN1YnNjcmlwdGlvbiA9IHRoYXQuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dCA6IGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGZuKHZhbHVlKTtcbiAgICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogcmVqZWN0LFxuICAgICAgICBjb21wbGV0ZTogcmVzb2x2ZVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn0pO1xuXG5yZWRlZmluZUFsbCgkT2JzZXJ2YWJsZSwge1xuICBmcm9tOiBmdW5jdGlvbiBmcm9tKHgpe1xuICAgIHZhciBDID0gdHlwZW9mIHRoaXMgPT09ICdmdW5jdGlvbicgPyB0aGlzIDogJE9ic2VydmFibGU7XG4gICAgdmFyIG1ldGhvZCA9IGdldE1ldGhvZChhbk9iamVjdCh4KVtPQlNFUlZBQkxFXSk7XG4gICAgaWYobWV0aG9kKXtcbiAgICAgIHZhciBvYnNlcnZhYmxlID0gYW5PYmplY3QobWV0aG9kLmNhbGwoeCkpO1xuICAgICAgcmV0dXJuIG9ic2VydmFibGUuY29uc3RydWN0b3IgPT09IEMgPyBvYnNlcnZhYmxlIDogbmV3IEMoZnVuY3Rpb24ob2JzZXJ2ZXIpe1xuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZS5zdWJzY3JpYmUob2JzZXJ2ZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQyhmdW5jdGlvbihvYnNlcnZlcil7XG4gICAgICB2YXIgZG9uZSA9IGZhbHNlO1xuICAgICAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XG4gICAgICAgIGlmKCFkb25lKXtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYoZm9yT2YoeCwgZmFsc2UsIGZ1bmN0aW9uKGl0KXtcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChpdCk7XG4gICAgICAgICAgICAgIGlmKGRvbmUpcmV0dXJuIFJFVFVSTjtcbiAgICAgICAgICAgIH0pID09PSBSRVRVUk4pcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICBpZihkb25lKXRocm93IGU7XG4gICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCl7IGRvbmUgPSB0cnVlOyB9O1xuICAgIH0pO1xuICB9LFxuICBvZjogZnVuY3Rpb24gb2YoKXtcbiAgICBmb3IodmFyIGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aCwgaXRlbXMgPSBBcnJheShsKTsgaSA8IGw7KWl0ZW1zW2ldID0gYXJndW1lbnRzW2krK107XG4gICAgcmV0dXJuIG5ldyAodHlwZW9mIHRoaXMgPT09ICdmdW5jdGlvbicgPyB0aGlzIDogJE9ic2VydmFibGUpKGZ1bmN0aW9uKG9ic2VydmVyKXtcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24oKXtcbiAgICAgICAgaWYoIWRvbmUpe1xuICAgICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7ICsraSl7XG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KGl0ZW1zW2ldKTtcbiAgICAgICAgICAgIGlmKGRvbmUpcmV0dXJuO1xuICAgICAgICAgIH0gb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKXsgZG9uZSA9IHRydWU7IH07XG4gICAgfSk7XG4gIH1cbn0pO1xuXG5oaWRlKCRPYnNlcnZhYmxlLnByb3RvdHlwZSwgT0JTRVJWQUJMRSwgZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuRywge09ic2VydmFibGU6ICRPYnNlcnZhYmxlfSk7XG5cbnJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJykoJ09ic2VydmFibGUnKTsiLCJ2YXIgbWV0YWRhdGEgICAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX21ldGFkYXRhJylcbiAgLCBhbk9iamVjdCAgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5XG4gICwgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YSA9IG1ldGFkYXRhLnNldDtcblxubWV0YWRhdGEuZXhwKHtkZWZpbmVNZXRhZGF0YTogZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgdGFyZ2V0S2V5KXtcbiAgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSwgYW5PYmplY3QodGFyZ2V0KSwgdG9NZXRhS2V5KHRhcmdldEtleSkpO1xufX0pOyIsInZhciBtZXRhZGF0YSAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIHRvTWV0YUtleSAgICAgICAgICAgICAgPSBtZXRhZGF0YS5rZXlcbiAgLCBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwID0gbWV0YWRhdGEubWFwXG4gICwgc3RvcmUgICAgICAgICAgICAgICAgICA9IG1ldGFkYXRhLnN0b3JlO1xuXG5tZXRhZGF0YS5leHAoe2RlbGV0ZU1ldGFkYXRhOiBmdW5jdGlvbiBkZWxldGVNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0IC8qLCB0YXJnZXRLZXkgKi8pe1xuICB2YXIgdGFyZ2V0S2V5ICAgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pXG4gICAgLCBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoYW5PYmplY3QodGFyZ2V0KSwgdGFyZ2V0S2V5LCBmYWxzZSk7XG4gIGlmKG1ldGFkYXRhTWFwID09PSB1bmRlZmluZWQgfHwgIW1ldGFkYXRhTWFwWydkZWxldGUnXShtZXRhZGF0YUtleSkpcmV0dXJuIGZhbHNlO1xuICBpZihtZXRhZGF0YU1hcC5zaXplKXJldHVybiB0cnVlO1xuICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBzdG9yZS5nZXQodGFyZ2V0KTtcbiAgdGFyZ2V0TWV0YWRhdGFbJ2RlbGV0ZSddKHRhcmdldEtleSk7XG4gIHJldHVybiAhIXRhcmdldE1ldGFkYXRhLnNpemUgfHwgc3RvcmVbJ2RlbGV0ZSddKHRhcmdldCk7XG59fSk7IiwidmFyIFNldCAgICAgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9lczYuc2V0JylcbiAgLCBmcm9tICAgICAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FycmF5LWZyb20taXRlcmFibGUnKVxuICAsIG1ldGFkYXRhICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBnZXRQcm90b3R5cGVPZiAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5c1xuICAsIHRvTWV0YUtleSAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xuXG52YXIgb3JkaW5hcnlNZXRhZGF0YUtleXMgPSBmdW5jdGlvbihPLCBQKXtcbiAgdmFyIG9LZXlzICA9IG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApXG4gICAgLCBwYXJlbnQgPSBnZXRQcm90b3R5cGVPZihPKTtcbiAgaWYocGFyZW50ID09PSBudWxsKXJldHVybiBvS2V5cztcbiAgdmFyIHBLZXlzICA9IG9yZGluYXJ5TWV0YWRhdGFLZXlzKHBhcmVudCwgUCk7XG4gIHJldHVybiBwS2V5cy5sZW5ndGggPyBvS2V5cy5sZW5ndGggPyBmcm9tKG5ldyBTZXQob0tleXMuY29uY2F0KHBLZXlzKSkpIDogcEtleXMgOiBvS2V5cztcbn07XG5cbm1ldGFkYXRhLmV4cCh7Z2V0TWV0YWRhdGFLZXlzOiBmdW5jdGlvbiBnZXRNZXRhZGF0YUtleXModGFyZ2V0IC8qLCB0YXJnZXRLZXkgKi8pe1xuICByZXR1cm4gb3JkaW5hcnlNZXRhZGF0YUtleXMoYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDIgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzFdKSk7XG59fSk7IiwidmFyIG1ldGFkYXRhICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgZ2V0UHJvdG90eXBlT2YgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXNcbiAgLCBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gbWV0YWRhdGEuZ2V0XG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleTtcblxudmFyIG9yZGluYXJ5R2V0TWV0YWRhdGEgPSBmdW5jdGlvbihNZXRhZGF0YUtleSwgTywgUCl7XG4gIHZhciBoYXNPd24gPSBvcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgaWYoaGFzT3duKXJldHVybiBvcmRpbmFyeUdldE93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgdmFyIHBhcmVudCA9IGdldFByb3RvdHlwZU9mKE8pO1xuICByZXR1cm4gcGFyZW50ICE9PSBudWxsID8gb3JkaW5hcnlHZXRNZXRhZGF0YShNZXRhZGF0YUtleSwgcGFyZW50LCBQKSA6IHVuZGVmaW5lZDtcbn07XG5cbm1ldGFkYXRhLmV4cCh7Z2V0TWV0YWRhdGE6IGZ1bmN0aW9uIGdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQgLyosIHRhcmdldEtleSAqLyl7XG4gIHJldHVybiBvcmRpbmFyeUdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCBhbk9iamVjdCh0YXJnZXQpLCBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pKTtcbn19KTsiLCJ2YXIgbWV0YWRhdGEgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5c1xuICAsIHRvTWV0YUtleSAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoe2dldE93bk1ldGFkYXRhS2V5czogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGFLZXlzKHRhcmdldCAvKiwgdGFyZ2V0S2V5ICovKXtcbiAgcmV0dXJuIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKGFuT2JqZWN0KHRhcmdldCksIGFyZ3VtZW50cy5sZW5ndGggPCAyID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1sxXSkpO1xufX0pOyIsInZhciBtZXRhZGF0YSAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIG9yZGluYXJ5R2V0T3duTWV0YWRhdGEgPSBtZXRhZGF0YS5nZXRcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoe2dldE93bk1ldGFkYXRhOiBmdW5jdGlvbiBnZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0IC8qLCB0YXJnZXRLZXkgKi8pe1xuICByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59fSk7IiwidmFyIG1ldGFkYXRhICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgZ2V0UHJvdG90eXBlT2YgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXNcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xuXG52YXIgb3JkaW5hcnlIYXNNZXRhZGF0YSA9IGZ1bmN0aW9uKE1ldGFkYXRhS2V5LCBPLCBQKXtcbiAgdmFyIGhhc093biA9IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICBpZihoYXNPd24pcmV0dXJuIHRydWU7XG4gIHZhciBwYXJlbnQgPSBnZXRQcm90b3R5cGVPZihPKTtcbiAgcmV0dXJuIHBhcmVudCAhPT0gbnVsbCA/IG9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCkgOiBmYWxzZTtcbn07XG5cbm1ldGFkYXRhLmV4cCh7aGFzTWV0YWRhdGE6IGZ1bmN0aW9uIGhhc01ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQgLyosIHRhcmdldEtleSAqLyl7XG4gIHJldHVybiBvcmRpbmFyeUhhc01ldGFkYXRhKG1ldGFkYXRhS2V5LCBhbk9iamVjdCh0YXJnZXQpLCBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pKTtcbn19KTsiLCJ2YXIgbWV0YWRhdGEgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX21ldGFkYXRhJylcbiAgLCBhbk9iamVjdCAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBvcmRpbmFyeUhhc093bk1ldGFkYXRhID0gbWV0YWRhdGEuaGFzXG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleTtcblxubWV0YWRhdGEuZXhwKHtoYXNPd25NZXRhZGF0YTogZnVuY3Rpb24gaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiwgdGFyZ2V0S2V5ICovKXtcbiAgcmV0dXJuIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIGFuT2JqZWN0KHRhcmdldClcbiAgICAsIGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1syXSkpO1xufX0pOyIsInZhciBtZXRhZGF0YSAgICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIGFGdW5jdGlvbiAgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5XG4gICwgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YSA9IG1ldGFkYXRhLnNldDtcblxubWV0YWRhdGEuZXhwKHttZXRhZGF0YTogZnVuY3Rpb24gbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpe1xuICByZXR1cm4gZnVuY3Rpb24gZGVjb3JhdG9yKHRhcmdldCwgdGFyZ2V0S2V5KXtcbiAgICBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKFxuICAgICAgbWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsXG4gICAgICAodGFyZ2V0S2V5ICE9PSB1bmRlZmluZWQgPyBhbk9iamVjdCA6IGFGdW5jdGlvbikodGFyZ2V0KSxcbiAgICAgIHRvTWV0YUtleSh0YXJnZXRLZXkpXG4gICAgKTtcbiAgfTtcbn19KTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgJGV4cG9ydCAgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7dG9KU09OOiByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXRvLWpzb24nKSgnU2V0Jyl9KTsiLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vbWF0aGlhc2J5bmVucy9TdHJpbmcucHJvdG90eXBlLmF0XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgJGF0ICAgICA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgYXQ6IGZ1bmN0aW9uIGF0KHBvcyl7XG4gICAgcmV0dXJuICRhdCh0aGlzLCBwb3MpO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL1N0cmluZy5wcm90b3R5cGUubWF0Y2hBbGwvXG52YXIgJGV4cG9ydCAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGRlZmluZWQgICAgID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpXG4gICwgdG9MZW5ndGggICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGlzUmVnRXhwICAgID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJylcbiAgLCBnZXRGbGFncyAgICA9IHJlcXVpcmUoJy4vX2ZsYWdzJylcbiAgLCBSZWdFeHBQcm90byA9IFJlZ0V4cC5wcm90b3R5cGU7XG5cbnZhciAkUmVnRXhwU3RyaW5nSXRlcmF0b3IgPSBmdW5jdGlvbihyZWdleHAsIHN0cmluZyl7XG4gIHRoaXMuX3IgPSByZWdleHA7XG4gIHRoaXMuX3MgPSBzdHJpbmc7XG59O1xuXG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKCRSZWdFeHBTdHJpbmdJdGVyYXRvciwgJ1JlZ0V4cCBTdHJpbmcnLCBmdW5jdGlvbiBuZXh0KCl7XG4gIHZhciBtYXRjaCA9IHRoaXMuX3IuZXhlYyh0aGlzLl9zKTtcbiAgcmV0dXJuIHt2YWx1ZTogbWF0Y2gsIGRvbmU6IG1hdGNoID09PSBudWxsfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgbWF0Y2hBbGw6IGZ1bmN0aW9uIG1hdGNoQWxsKHJlZ2V4cCl7XG4gICAgZGVmaW5lZCh0aGlzKTtcbiAgICBpZighaXNSZWdFeHAocmVnZXhwKSl0aHJvdyBUeXBlRXJyb3IocmVnZXhwICsgJyBpcyBub3QgYSByZWdleHAhJyk7XG4gICAgdmFyIFMgICAgID0gU3RyaW5nKHRoaXMpXG4gICAgICAsIGZsYWdzID0gJ2ZsYWdzJyBpbiBSZWdFeHBQcm90byA/IFN0cmluZyhyZWdleHAuZmxhZ3MpIDogZ2V0RmxhZ3MuY2FsbChyZWdleHApXG4gICAgICAsIHJ4ICAgID0gbmV3IFJlZ0V4cChyZWdleHAuc291cmNlLCB+ZmxhZ3MuaW5kZXhPZignZycpID8gZmxhZ3MgOiAnZycgKyBmbGFncyk7XG4gICAgcngubGFzdEluZGV4ID0gdG9MZW5ndGgocmVnZXhwLmxhc3RJbmRleCk7XG4gICAgcmV0dXJuIG5ldyAkUmVnRXhwU3RyaW5nSXRlcmF0b3IocngsIFMpO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICRwYWQgICAgPSByZXF1aXJlKCcuL19zdHJpbmctcGFkJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICBwYWRFbmQ6IGZ1bmN0aW9uIHBhZEVuZChtYXhMZW5ndGggLyosIGZpbGxTdHJpbmcgPSAnICcgKi8pe1xuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGZhbHNlKTtcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkcGFkICAgID0gcmVxdWlyZSgnLi9fc3RyaW5nLXBhZCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgcGFkU3RhcnQ6IGZ1bmN0aW9uIHBhZFN0YXJ0KG1heExlbmd0aCAvKiwgZmlsbFN0cmluZyA9ICcgJyAqLyl7XG4gICAgcmV0dXJuICRwYWQodGhpcywgbWF4TGVuZ3RoLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zZWJtYXJrYmFnZS9lY21hc2NyaXB0LXN0cmluZy1sZWZ0LXJpZ2h0LXRyaW1cbnJlcXVpcmUoJy4vX3N0cmluZy10cmltJykoJ3RyaW1MZWZ0JywgZnVuY3Rpb24oJHRyaW0pe1xuICByZXR1cm4gZnVuY3Rpb24gdHJpbUxlZnQoKXtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMSk7XG4gIH07XG59LCAndHJpbVN0YXJ0Jyk7IiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3NlYm1hcmtiYWdlL2VjbWFzY3JpcHQtc3RyaW5nLWxlZnQtcmlnaHQtdHJpbVxucmVxdWlyZSgnLi9fc3RyaW5nLXRyaW0nKSgndHJpbVJpZ2h0JywgZnVuY3Rpb24oJHRyaW0pe1xuICByZXR1cm4gZnVuY3Rpb24gdHJpbVJpZ2h0KCl7XG4gICAgcmV0dXJuICR0cmltKHRoaXMsIDIpO1xuICB9O1xufSwgJ3RyaW1FbmQnKTsiLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ2FzeW5jSXRlcmF0b3InKTsiLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ29ic2VydmFibGUnKTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL3Byb3Bvc2FsLWdsb2JhbFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdTeXN0ZW0nLCB7Z2xvYmFsOiByZXF1aXJlKCcuL19nbG9iYWwnKX0pOyIsInZhciAkaXRlcmF0b3JzICAgID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKVxuICAsIHJlZGVmaW5lICAgICAgPSByZXF1aXJlKCcuL19yZWRlZmluZScpXG4gICwgZ2xvYmFsICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGlkZSAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIEl0ZXJhdG9ycyAgICAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsIHdrcyAgICAgICAgICAgPSByZXF1aXJlKCcuL193a3MnKVxuICAsIElURVJBVE9SICAgICAgPSB3a3MoJ2l0ZXJhdG9yJylcbiAgLCBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpXG4gICwgQXJyYXlWYWx1ZXMgICA9IEl0ZXJhdG9ycy5BcnJheTtcblxuZm9yKHZhciBjb2xsZWN0aW9ucyA9IFsnTm9kZUxpc3QnLCAnRE9NVG9rZW5MaXN0JywgJ01lZGlhTGlzdCcsICdTdHlsZVNoZWV0TGlzdCcsICdDU1NSdWxlTGlzdCddLCBpID0gMDsgaSA8IDU7IGkrKyl7XG4gIHZhciBOQU1FICAgICAgID0gY29sbGVjdGlvbnNbaV1cbiAgICAsIENvbGxlY3Rpb24gPSBnbG9iYWxbTkFNRV1cbiAgICAsIHByb3RvICAgICAgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlXG4gICAgLCBrZXk7XG4gIGlmKHByb3RvKXtcbiAgICBpZighcHJvdG9bSVRFUkFUT1JdKWhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgaWYoIXByb3RvW1RPX1NUUklOR19UQUddKWhpZGUocHJvdG8sIFRPX1NUUklOR19UQUcsIE5BTUUpO1xuICAgIEl0ZXJhdG9yc1tOQU1FXSA9IEFycmF5VmFsdWVzO1xuICAgIGZvcihrZXkgaW4gJGl0ZXJhdG9ycylpZighcHJvdG9ba2V5XSlyZWRlZmluZShwcm90bywga2V5LCAkaXRlcmF0b3JzW2tleV0sIHRydWUpO1xuICB9XG59IiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsICR0YXNrICAgPSByZXF1aXJlKCcuL190YXNrJyk7XG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuQiwge1xuICBzZXRJbW1lZGlhdGU6ICAgJHRhc2suc2V0LFxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcbn0pOyIsIi8vIGllOS0gc2V0VGltZW91dCAmIHNldEludGVydmFsIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBmaXhcbnZhciBnbG9iYWwgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCAkZXhwb3J0ICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBpbnZva2UgICAgID0gcmVxdWlyZSgnLi9faW52b2tlJylcbiAgLCBwYXJ0aWFsICAgID0gcmVxdWlyZSgnLi9fcGFydGlhbCcpXG4gICwgbmF2aWdhdG9yICA9IGdsb2JhbC5uYXZpZ2F0b3JcbiAgLCBNU0lFICAgICAgID0gISFuYXZpZ2F0b3IgJiYgL01TSUUgLlxcLi8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsgLy8gPC0gZGlydHkgaWU5LSBjaGVja1xudmFyIHdyYXAgPSBmdW5jdGlvbihzZXQpe1xuICByZXR1cm4gTVNJRSA/IGZ1bmN0aW9uKGZuLCB0aW1lIC8qLCAuLi5hcmdzICovKXtcbiAgICByZXR1cm4gc2V0KGludm9rZShcbiAgICAgIHBhcnRpYWwsXG4gICAgICBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMiksXG4gICAgICB0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pXG4gICAgKSwgdGltZSk7XG4gIH0gOiBzZXQ7XG59O1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIgKyAkZXhwb3J0LkYgKiBNU0lFLCB7XG4gIHNldFRpbWVvdXQ6ICB3cmFwKGdsb2JhbC5zZXRUaW1lb3V0KSxcbiAgc2V0SW50ZXJ2YWw6IHdyYXAoZ2xvYmFsLnNldEludGVydmFsKVxufSk7IiwicmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zeW1ib2wnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmNyZWF0ZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydGllcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5rZXlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LW5hbWVzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5mcmVlemUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LnNlYWwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1zZWFsZWQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5mdW5jdGlvbi5iaW5kJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmZ1bmN0aW9uLm5hbWUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnBhcnNlLWludCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIuY29uc3RydWN0b3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLnRvLWZpeGVkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci50by1wcmVjaXNpb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmVwc2lsb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmlzLWZpbml0ZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtaW50ZWdlcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5pcy1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLm1heC1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLm1pbi1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWZsb2F0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5hY29zaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmFzaW5oJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguYXRhbmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5jYnJ0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguY2x6MzInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5jb3NoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguZXhwbTEnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5mcm91bmQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5oeXBvdCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmltdWwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5sb2cxMCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGgubG9nMicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLnNpZ24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5zaW5oJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGgudGFuaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLnRydW5jJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5mcm9tLWNvZGUtcG9pbnQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnJhdycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcudHJpbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmVuZHMtd2l0aCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3RhcnRzLXdpdGgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmlnJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5ibGluaycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuYm9sZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRjb2xvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udHNpemUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLml0YWxpY3MnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmxpbmsnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnNtYWxsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnN1YicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3VwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUubm93Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUudG8tanNvbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWlzby1zdHJpbmcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZGF0ZS50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZGF0ZS50by1wcmltaXRpdmUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuZnJvbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5qb2luJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LnNvcnQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuZm9yLWVhY2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkubWFwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZpbHRlcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zb21lJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UtcmlnaHQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkubGFzdC1pbmRleC1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5jb3B5LXdpdGhpbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5maWxsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZpbmQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuZmluZC1pbmRleCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5jb25zdHJ1Y3RvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5mbGFncycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAubWF0Y2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnJlcGxhY2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnNlYXJjaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAuc3BsaXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucHJvbWlzZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc2V0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LndlYWstbWFwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LndlYWstc2V0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuaW50OC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmludDE2LWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQzMi1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuYXBwbHknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5jb25zdHJ1Y3QnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5kZWZpbmUtcHJvcGVydHknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5kZWxldGUtcHJvcGVydHknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuaXMtZXh0ZW5zaWJsZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0Lm93bi1rZXlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcuYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1sZWZ0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy50cmltLXJpZ2h0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy5tYXRjaC1hbGwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWFwLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3lzdGVtLmdsb2JhbCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5lcnJvci5pcy1lcnJvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmlhZGRoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGguaXN1YmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5pbXVsaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLnVtdWxoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVmaW5lLW1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVsZXRlLW1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW93bi1tZXRhZGF0YS1rZXlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW93bi1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0Lm1ldGFkYXRhJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LmFzYXAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JzZXJ2YWJsZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL3dlYi50aW1lcnMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy93ZWIuaW1tZWRpYXRlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL21vZHVsZXMvX2NvcmUnKTsiLCJ2YXIgY2FuVXNlRE9NID0gISEoXG4gIHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmXG4gIHdpbmRvdy5kb2N1bWVudCAmJlxuICB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudFxuKTtcblxubW9kdWxlLmV4cG9ydHMgPSBjYW5Vc2VET007IiwiLyohXG4gIENvcHlyaWdodCAoYykgMjAxNiBKZWQgV2F0c29uLlxuICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UgKE1JVCksIHNlZVxuICBodHRwOi8vamVkd2F0c29uLmdpdGh1Yi5pby9jbGFzc25hbWVzXG4qL1xuLyogZ2xvYmFsIGRlZmluZSAqL1xuXG4oZnVuY3Rpb24gKCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIGhhc093biA9IHt9Lmhhc093blByb3BlcnR5O1xuXG5cdGZ1bmN0aW9uIGNsYXNzTmFtZXMgKCkge1xuXHRcdHZhciBjbGFzc2VzID0gW107XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGFyZyA9IGFyZ3VtZW50c1tpXTtcblx0XHRcdGlmICghYXJnKSBjb250aW51ZTtcblxuXHRcdFx0dmFyIGFyZ1R5cGUgPSB0eXBlb2YgYXJnO1xuXG5cdFx0XHRpZiAoYXJnVHlwZSA9PT0gJ3N0cmluZycgfHwgYXJnVHlwZSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0Y2xhc3Nlcy5wdXNoKGFyZyk7XG5cdFx0XHR9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJnKSkge1xuXHRcdFx0XHRjbGFzc2VzLnB1c2goY2xhc3NOYW1lcy5hcHBseShudWxsLCBhcmcpKTtcblx0XHRcdH0gZWxzZSBpZiAoYXJnVHlwZSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Zm9yICh2YXIga2V5IGluIGFyZykge1xuXHRcdFx0XHRcdGlmIChoYXNPd24uY2FsbChhcmcsIGtleSkgJiYgYXJnW2tleV0pIHtcblx0XHRcdFx0XHRcdGNsYXNzZXMucHVzaChrZXkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBjbGFzc2VzLmpvaW4oJyAnKTtcblx0fVxuXG5cdGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykge1xuXHRcdG1vZHVsZS5leHBvcnRzID0gY2xhc3NOYW1lcztcblx0fSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkZWZpbmUuYW1kID09PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gcmVnaXN0ZXIgYXMgJ2NsYXNzbmFtZXMnLCBjb25zaXN0ZW50IHdpdGggbnBtIHBhY2thZ2UgbmFtZVxuXHRcdGRlZmluZSgnY2xhc3NuYW1lcycsIFtdLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gY2xhc3NOYW1lcztcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHR3aW5kb3cuY2xhc3NOYW1lcyA9IGNsYXNzTmFtZXM7XG5cdH1cbn0oKSk7XG4iLCJcclxuLyoqXHJcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXHJcbiAqL1xyXG5cclxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xyXG59XHJcblxyXG4vKipcclxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXHJcbiAqXHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcclxuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBNaXhpbiB0aGUgZW1pdHRlciBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXHJcbiAqIEByZXR1cm4ge09iamVjdH1cclxuICogQGFwaSBwcml2YXRlXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XHJcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XHJcbiAgICBvYmpba2V5XSA9IEVtaXR0ZXIucHJvdG90eXBlW2tleV07XHJcbiAgfVxyXG4gIHJldHVybiBvYmo7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICAodGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW10pXHJcbiAgICAucHVzaChmbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAqIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIGZ1bmN0aW9uIG9uKCkge1xyXG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcclxuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgfVxyXG5cclxuICBvbi5mbiA9IGZuO1xyXG4gIHRoaXMub24oZXZlbnQsIG9uKTtcclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxyXG4gKiByZWdpc3RlcmVkIGNhbGxiYWNrcy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcblxyXG4gIC8vIGFsbFxyXG4gIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyBzcGVjaWZpYyBldmVudFxyXG4gIHZhciBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxyXG4gIHZhciBjYjtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xyXG4gICAgY2IgPSBjYWxsYmFja3NbaV07XHJcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xyXG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge01peGVkfSAuLi5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxyXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG5cclxuICBpZiAoY2FsbGJhY2tzKSB7XHJcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XHJcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY2FsbGJhY2tzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhcnJheSBvZiBjYWxsYmFja3MgZm9yIGBldmVudGAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtBcnJheX1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG4gIHJldHVybiB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHJldHVybiAhISB0aGlzLmxpc3RlbmVycyhldmVudCkubGVuZ3RoO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vL1xuLy8gV2Ugc3RvcmUgb3VyIEVFIG9iamVjdHMgaW4gYSBwbGFpbiBvYmplY3Qgd2hvc2UgcHJvcGVydGllcyBhcmUgZXZlbnQgbmFtZXMuXG4vLyBJZiBgT2JqZWN0LmNyZWF0ZShudWxsKWAgaXMgbm90IHN1cHBvcnRlZCB3ZSBwcmVmaXggdGhlIGV2ZW50IG5hbWVzIHdpdGggYVxuLy8gYH5gIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBidWlsdC1pbiBvYmplY3QgcHJvcGVydGllcyBhcmUgbm90IG92ZXJyaWRkZW4gb3Jcbi8vIHVzZWQgYXMgYW4gYXR0YWNrIHZlY3Rvci5cbi8vIFdlIGFsc28gYXNzdW1lIHRoYXQgYE9iamVjdC5jcmVhdGUobnVsbClgIGlzIGF2YWlsYWJsZSB3aGVuIHRoZSBldmVudCBuYW1lXG4vLyBpcyBhbiBFUzYgU3ltYm9sLlxuLy9cbnZhciBwcmVmaXggPSB0eXBlb2YgT2JqZWN0LmNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJyA/ICd+JyA6IGZhbHNlO1xuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgc2luZ2xlIEV2ZW50RW1pdHRlciBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBFdmVudCBoYW5kbGVyIHRvIGJlIGNhbGxlZC5cbiAqIEBwYXJhbSB7TWl4ZWR9IGNvbnRleHQgQ29udGV4dCBmb3IgZnVuY3Rpb24gZXhlY3V0aW9uLlxuICogQHBhcmFtIHtCb29sZWFufSBbb25jZT1mYWxzZV0gT25seSBlbWl0IG9uY2VcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBFRShmbiwgY29udGV4dCwgb25jZSkge1xuICB0aGlzLmZuID0gZm47XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMub25jZSA9IG9uY2UgfHwgZmFsc2U7XG59XG5cbi8qKlxuICogTWluaW1hbCBFdmVudEVtaXR0ZXIgaW50ZXJmYWNlIHRoYXQgaXMgbW9sZGVkIGFnYWluc3QgdGhlIE5vZGUuanNcbiAqIEV2ZW50RW1pdHRlciBpbnRlcmZhY2UuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7IC8qIE5vdGhpbmcgdG8gc2V0ICovIH1cblxuLyoqXG4gKiBIb2xkIHRoZSBhc3NpZ25lZCBFdmVudEVtaXR0ZXJzIGJ5IG5hbWUuXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcml2YXRlXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYXJyYXkgbGlzdGluZyB0aGUgZXZlbnRzIGZvciB3aGljaCB0aGUgZW1pdHRlciBoYXMgcmVnaXN0ZXJlZFxuICogbGlzdGVuZXJzLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNcbiAgICAsIG5hbWVzID0gW11cbiAgICAsIG5hbWU7XG5cbiAgaWYgKCFldmVudHMpIHJldHVybiBuYW1lcztcblxuICBmb3IgKG5hbWUgaW4gZXZlbnRzKSB7XG4gICAgaWYgKGhhcy5jYWxsKGV2ZW50cywgbmFtZSkpIG5hbWVzLnB1c2gocHJlZml4ID8gbmFtZS5zbGljZSgxKSA6IG5hbWUpO1xuICB9XG5cbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICByZXR1cm4gbmFtZXMuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZXZlbnRzKSk7XG4gIH1cblxuICByZXR1cm4gbmFtZXM7XG59O1xuXG4vKipcbiAqIFJldHVybiBhIGxpc3Qgb2YgYXNzaWduZWQgZXZlbnQgbGlzdGVuZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBUaGUgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIGxpc3RlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZXhpc3RzIFdlIG9ubHkgbmVlZCB0byBrbm93IGlmIHRoZXJlIGFyZSBsaXN0ZW5lcnMuXG4gKiBAcmV0dXJucyB7QXJyYXl8Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKGV2ZW50LCBleGlzdHMpIHtcbiAgdmFyIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnRcbiAgICAsIGF2YWlsYWJsZSA9IHRoaXMuX2V2ZW50cyAmJiB0aGlzLl9ldmVudHNbZXZ0XTtcblxuICBpZiAoZXhpc3RzKSByZXR1cm4gISFhdmFpbGFibGU7XG4gIGlmICghYXZhaWxhYmxlKSByZXR1cm4gW107XG4gIGlmIChhdmFpbGFibGUuZm4pIHJldHVybiBbYXZhaWxhYmxlLmZuXTtcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IGF2YWlsYWJsZS5sZW5ndGgsIGVlID0gbmV3IEFycmF5KGwpOyBpIDwgbDsgaSsrKSB7XG4gICAgZWVbaV0gPSBhdmFpbGFibGVbaV0uZm47XG4gIH1cblxuICByZXR1cm4gZWU7XG59O1xuXG4vKipcbiAqIEVtaXQgYW4gZXZlbnQgdG8gYWxsIHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gSW5kaWNhdGlvbiBpZiB3ZSd2ZSBlbWl0dGVkIGFuIGV2ZW50LlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdChldmVudCwgYTEsIGEyLCBhMywgYTQsIGE1KSB7XG4gIHZhciBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50O1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbZXZ0XSkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbZXZ0XVxuICAgICwgbGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICwgYXJnc1xuICAgICwgaTtcblxuICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIGxpc3RlbmVycy5mbikge1xuICAgIGlmIChsaXN0ZW5lcnMub25jZSkgdGhpcy5yZW1vdmVMaXN0ZW5lcihldmVudCwgbGlzdGVuZXJzLmZuLCB1bmRlZmluZWQsIHRydWUpO1xuXG4gICAgc3dpdGNoIChsZW4pIHtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0KSwgdHJ1ZTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSksIHRydWU7XG4gICAgICBjYXNlIDM6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyKSwgdHJ1ZTtcbiAgICAgIGNhc2UgNDogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIsIGEzKSwgdHJ1ZTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIsIGEzLCBhNCksIHRydWU7XG4gICAgICBjYXNlIDY6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyLCBhMywgYTQsIGE1KSwgdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAxLCBhcmdzID0gbmV3IEFycmF5KGxlbiAtMSk7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZuLmFwcGx5KGxpc3RlbmVycy5jb250ZXh0LCBhcmdzKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbGVuZ3RoID0gbGlzdGVuZXJzLmxlbmd0aFxuICAgICAgLCBqO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobGlzdGVuZXJzW2ldLm9uY2UpIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyc1tpXS5mbiwgdW5kZWZpbmVkLCB0cnVlKTtcblxuICAgICAgc3dpdGNoIChsZW4pIHtcbiAgICAgICAgY2FzZSAxOiBsaXN0ZW5lcnNbaV0uZm4uY2FsbChsaXN0ZW5lcnNbaV0uY29udGV4dCk7IGJyZWFrO1xuICAgICAgICBjYXNlIDI6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhMSk7IGJyZWFrO1xuICAgICAgICBjYXNlIDM6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhMSwgYTIpOyBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAoIWFyZ3MpIGZvciAoaiA9IDEsIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0xKTsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICBhcmdzW2ogLSAxXSA9IGFyZ3VtZW50c1tqXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsaXN0ZW5lcnNbaV0uZm4uYXBwbHkobGlzdGVuZXJzW2ldLmNvbnRleHQsIGFyZ3MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlciBhIG5ldyBFdmVudExpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IE5hbWUgb2YgdGhlIGV2ZW50LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gQ2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge01peGVkfSBbY29udGV4dD10aGlzXSBUaGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gb24oZXZlbnQsIGZuLCBjb250ZXh0KSB7XG4gIHZhciBsaXN0ZW5lciA9IG5ldyBFRShmbiwgY29udGV4dCB8fCB0aGlzKVxuICAgICwgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50cykgdGhpcy5fZXZlbnRzID0gcHJlZml4ID8ge30gOiBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSB0aGlzLl9ldmVudHNbZXZ0XSA9IGxpc3RlbmVyO1xuICBlbHNlIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdLmZuKSB0aGlzLl9ldmVudHNbZXZ0XS5wdXNoKGxpc3RlbmVyKTtcbiAgICBlbHNlIHRoaXMuX2V2ZW50c1tldnRdID0gW1xuICAgICAgdGhpcy5fZXZlbnRzW2V2dF0sIGxpc3RlbmVyXG4gICAgXTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBBZGQgYW4gRXZlbnRMaXN0ZW5lciB0aGF0J3Mgb25seSBjYWxsZWQgb25jZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgTmFtZSBvZiB0aGUgZXZlbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBDYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TWl4ZWR9IFtjb250ZXh0PXRoaXNdIFRoZSBjb250ZXh0IG9mIHRoZSBmdW5jdGlvbi5cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UoZXZlbnQsIGZuLCBjb250ZXh0KSB7XG4gIHZhciBsaXN0ZW5lciA9IG5ldyBFRShmbiwgY29udGV4dCB8fCB0aGlzLCB0cnVlKVxuICAgICwgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50cykgdGhpcy5fZXZlbnRzID0gcHJlZml4ID8ge30gOiBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSB0aGlzLl9ldmVudHNbZXZ0XSA9IGxpc3RlbmVyO1xuICBlbHNlIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdLmZuKSB0aGlzLl9ldmVudHNbZXZ0XS5wdXNoKGxpc3RlbmVyKTtcbiAgICBlbHNlIHRoaXMuX2V2ZW50c1tldnRdID0gW1xuICAgICAgdGhpcy5fZXZlbnRzW2V2dF0sIGxpc3RlbmVyXG4gICAgXTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBUaGUgZXZlbnQgd2Ugd2FudCB0byByZW1vdmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgbGlzdGVuZXIgdGhhdCB3ZSBuZWVkIHRvIGZpbmQuXG4gKiBAcGFyYW0ge01peGVkfSBjb250ZXh0IE9ubHkgcmVtb3ZlIGxpc3RlbmVycyBtYXRjaGluZyB0aGlzIGNvbnRleHQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9uY2UgT25seSByZW1vdmUgb25jZSBsaXN0ZW5lcnMuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoZXZlbnQsIGZuLCBjb250ZXh0LCBvbmNlKSB7XG4gIHZhciBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50O1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbZXZ0XSkgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1tldnRdXG4gICAgLCBldmVudHMgPSBbXTtcblxuICBpZiAoZm4pIHtcbiAgICBpZiAobGlzdGVuZXJzLmZuKSB7XG4gICAgICBpZiAoXG4gICAgICAgICAgIGxpc3RlbmVycy5mbiAhPT0gZm5cbiAgICAgICAgfHwgKG9uY2UgJiYgIWxpc3RlbmVycy5vbmNlKVxuICAgICAgICB8fCAoY29udGV4dCAmJiBsaXN0ZW5lcnMuY29udGV4dCAhPT0gY29udGV4dClcbiAgICAgICkge1xuICAgICAgICBldmVudHMucHVzaChsaXN0ZW5lcnMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uZm4gIT09IGZuXG4gICAgICAgICAgfHwgKG9uY2UgJiYgIWxpc3RlbmVyc1tpXS5vbmNlKVxuICAgICAgICAgIHx8IChjb250ZXh0ICYmIGxpc3RlbmVyc1tpXS5jb250ZXh0ICE9PSBjb250ZXh0KVxuICAgICAgICApIHtcbiAgICAgICAgICBldmVudHMucHVzaChsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy9cbiAgLy8gUmVzZXQgdGhlIGFycmF5LCBvciByZW1vdmUgaXQgY29tcGxldGVseSBpZiB3ZSBoYXZlIG5vIG1vcmUgbGlzdGVuZXJzLlxuICAvL1xuICBpZiAoZXZlbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2V2ZW50c1tldnRdID0gZXZlbnRzLmxlbmd0aCA9PT0gMSA/IGV2ZW50c1swXSA6IGV2ZW50cztcbiAgfSBlbHNlIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW2V2dF07XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgb3Igb25seSB0aGUgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBUaGUgZXZlbnQgd2FudCB0byByZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyhldmVudCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cykgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKGV2ZW50KSBkZWxldGUgdGhpcy5fZXZlbnRzW3ByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnRdO1xuICBlbHNlIHRoaXMuX2V2ZW50cyA9IHByZWZpeCA/IHt9IDogT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBBbGlhcyBtZXRob2RzIG5hbWVzIGJlY2F1c2UgcGVvcGxlIHJvbGwgbGlrZSB0aGF0LlxuLy9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uO1xuXG4vL1xuLy8gVGhpcyBmdW5jdGlvbiBkb2Vzbid0IGFwcGx5IGFueW1vcmUuXG4vL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy9cbi8vIEV4cG9zZSB0aGUgcHJlZml4LlxuLy9cbkV2ZW50RW1pdHRlci5wcmVmaXhlZCA9IHByZWZpeDtcblxuLy9cbi8vIEV4cG9zZSB0aGUgbW9kdWxlLlxuLy9cbmlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG1vZHVsZSkge1xuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbn1cbiIsIihmdW5jdGlvbihyb290LGZhY3Rvcnkpe1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGZhY3RvcnkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3QuZXZlbnRMaXN0ZW5lciA9IGZhY3RvcnkoKTtcbiAgfVxufSh0aGlzLCBmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIHdyYXAoc3RhbmRhcmQsIGZhbGxiYWNrKSB7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uIChlbCwgZXZ0TmFtZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpIHtcblx0XHRcdGlmIChlbFtzdGFuZGFyZF0pIHtcblx0XHRcdFx0ZWxbc3RhbmRhcmRdKGV2dE5hbWUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKTtcblx0XHRcdH0gZWxzZSBpZiAoZWxbZmFsbGJhY2tdKSB7XG5cdFx0XHRcdGVsW2ZhbGxiYWNrXSgnb24nICsgZXZ0TmFtZSwgbGlzdGVuZXIpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG4gICAgcmV0dXJuIHtcblx0XHRhZGQ6IHdyYXAoJ2FkZEV2ZW50TGlzdGVuZXInLCAnYXR0YWNoRXZlbnQnKSxcblx0XHRyZW1vdmU6IHdyYXAoJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCAnZGV0YWNoRXZlbnQnKVxuXHR9O1xufSkpOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgRXZlbnRMaXN0ZW5lclxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9lbXB0eUZ1bmN0aW9uJyk7XG5cbi8qKlxuICogVXBzdHJlYW0gdmVyc2lvbiBvZiBldmVudCBsaXN0ZW5lci4gRG9lcyBub3QgdGFrZSBpbnRvIGFjY291bnQgc3BlY2lmaWNcbiAqIG5hdHVyZSBvZiBwbGF0Zm9ybS5cbiAqL1xudmFyIEV2ZW50TGlzdGVuZXIgPSB7XG4gIC8qKlxuICAgKiBMaXN0ZW4gdG8gRE9NIGV2ZW50cyBkdXJpbmcgdGhlIGJ1YmJsZSBwaGFzZS5cbiAgICpcbiAgICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdGFyZ2V0IERPTSBlbGVtZW50IHRvIHJlZ2lzdGVyIGxpc3RlbmVyIG9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRUeXBlIEV2ZW50IHR5cGUsIGUuZy4gJ2NsaWNrJyBvciAnbW91c2VvdmVyJy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2sgZnVuY3Rpb24uXG4gICAqIEByZXR1cm4ge29iamVjdH0gT2JqZWN0IHdpdGggYSBgcmVtb3ZlYCBtZXRob2QuXG4gICAqL1xuICBsaXN0ZW46IGZ1bmN0aW9uICh0YXJnZXQsIGV2ZW50VHlwZSwgY2FsbGJhY2spIHtcbiAgICBpZiAodGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgY2FsbGJhY2ssIGZhbHNlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgY2FsbGJhY2ssIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHRhcmdldC5hdHRhY2hFdmVudCkge1xuICAgICAgdGFyZ2V0LmF0dGFjaEV2ZW50KCdvbicgKyBldmVudFR5cGUsIGNhbGxiYWNrKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRhcmdldC5kZXRhY2hFdmVudCgnb24nICsgZXZlbnRUeXBlLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBMaXN0ZW4gdG8gRE9NIGV2ZW50cyBkdXJpbmcgdGhlIGNhcHR1cmUgcGhhc2UuXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRXZlbnRUYXJnZXR9IHRhcmdldCBET00gZWxlbWVudCB0byByZWdpc3RlciBsaXN0ZW5lciBvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50VHlwZSBFdmVudCB0eXBlLCBlLmcuICdjbGljaycgb3IgJ21vdXNlb3ZlcicuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHtvYmplY3R9IE9iamVjdCB3aXRoIGEgYHJlbW92ZWAgbWV0aG9kLlxuICAgKi9cbiAgY2FwdHVyZTogZnVuY3Rpb24gKHRhcmdldCwgZXZlbnRUeXBlLCBjYWxsYmFjaykge1xuICAgIGlmICh0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBjYWxsYmFjaywgdHJ1ZSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZW1vdmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignQXR0ZW1wdGVkIHRvIGxpc3RlbiB0byBldmVudHMgZHVyaW5nIHRoZSBjYXB0dXJlIHBoYXNlIG9uIGEgJyArICdicm93c2VyIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCB0aGUgY2FwdHVyZSBwaGFzZS4gWW91ciBhcHBsaWNhdGlvbiAnICsgJ3dpbGwgbm90IHJlY2VpdmUgc29tZSBldmVudHMuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZW1vdmU6IGVtcHR5RnVuY3Rpb25cbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG4gIHJlZ2lzdGVyRGVmYXVsdDogZnVuY3Rpb24gKCkge31cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRMaXN0ZW5lcjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgRXhlY3V0aW9uRW52aXJvbm1lbnRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBjYW5Vc2VET00gPSAhISh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQgJiYgd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xuXG4vKipcbiAqIFNpbXBsZSwgbGlnaHR3ZWlnaHQgbW9kdWxlIGFzc2lzdGluZyB3aXRoIHRoZSBkZXRlY3Rpb24gYW5kIGNvbnRleHQgb2ZcbiAqIFdvcmtlci4gSGVscHMgYXZvaWQgY2lyY3VsYXIgZGVwZW5kZW5jaWVzIGFuZCBhbGxvd3MgY29kZSB0byByZWFzb24gYWJvdXRcbiAqIHdoZXRoZXIgb3Igbm90IHRoZXkgYXJlIGluIGEgV29ya2VyLCBldmVuIGlmIHRoZXkgbmV2ZXIgaW5jbHVkZSB0aGUgbWFpblxuICogYFJlYWN0V29ya2VyYCBkZXBlbmRlbmN5LlxuICovXG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSB7XG5cbiAgY2FuVXNlRE9NOiBjYW5Vc2VET00sXG5cbiAgY2FuVXNlV29ya2VyczogdHlwZW9mIFdvcmtlciAhPT0gJ3VuZGVmaW5lZCcsXG5cbiAgY2FuVXNlRXZlbnRMaXN0ZW5lcnM6IGNhblVzZURPTSAmJiAhISh3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciB8fCB3aW5kb3cuYXR0YWNoRXZlbnQpLFxuXG4gIGNhblVzZVZpZXdwb3J0OiBjYW5Vc2VET00gJiYgISF3aW5kb3cuc2NyZWVuLFxuXG4gIGlzSW5Xb3JrZXI6ICFjYW5Vc2VET00gLy8gRm9yIG5vdywgdGhpcyBpcyB0cnVlIC0gbWlnaHQgY2hhbmdlIGluIHRoZSBmdXR1cmUuXG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRXhlY3V0aW9uRW52aXJvbm1lbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGNhbWVsaXplXG4gKiBAdHlwZWNoZWNrc1xuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgX2h5cGhlblBhdHRlcm4gPSAvLSguKS9nO1xuXG4vKipcbiAqIENhbWVsY2FzZXMgYSBoeXBoZW5hdGVkIHN0cmluZywgZm9yIGV4YW1wbGU6XG4gKlxuICogICA+IGNhbWVsaXplKCdiYWNrZ3JvdW5kLWNvbG9yJylcbiAqICAgPCBcImJhY2tncm91bmRDb2xvclwiXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZ1xuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBjYW1lbGl6ZShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKF9oeXBoZW5QYXR0ZXJuLCBmdW5jdGlvbiAoXywgY2hhcmFjdGVyKSB7XG4gICAgcmV0dXJuIGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpO1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYW1lbGl6ZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgY2FtZWxpemVTdHlsZU5hbWVcbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FtZWxpemUgPSByZXF1aXJlKCcuL2NhbWVsaXplJyk7XG5cbnZhciBtc1BhdHRlcm4gPSAvXi1tcy0vO1xuXG4vKipcbiAqIENhbWVsY2FzZXMgYSBoeXBoZW5hdGVkIENTUyBwcm9wZXJ0eSBuYW1lLCBmb3IgZXhhbXBsZTpcbiAqXG4gKiAgID4gY2FtZWxpemVTdHlsZU5hbWUoJ2JhY2tncm91bmQtY29sb3InKVxuICogICA8IFwiYmFja2dyb3VuZENvbG9yXCJcbiAqICAgPiBjYW1lbGl6ZVN0eWxlTmFtZSgnLW1vei10cmFuc2l0aW9uJylcbiAqICAgPCBcIk1velRyYW5zaXRpb25cIlxuICogICA+IGNhbWVsaXplU3R5bGVOYW1lKCctbXMtdHJhbnNpdGlvbicpXG4gKiAgIDwgXCJtc1RyYW5zaXRpb25cIlxuICpcbiAqIEFzIEFuZGkgU21pdGggc3VnZ2VzdHNcbiAqIChodHRwOi8vd3d3LmFuZGlzbWl0aC5jb20vYmxvZy8yMDEyLzAyL21vZGVybml6ci1wcmVmaXhlZC8pLCBhbiBgLW1zYCBwcmVmaXhcbiAqIGlzIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGNhbWVsaXplU3R5bGVOYW1lKHN0cmluZykge1xuICByZXR1cm4gY2FtZWxpemUoc3RyaW5nLnJlcGxhY2UobXNQYXR0ZXJuLCAnbXMtJykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhbWVsaXplU3R5bGVOYW1lOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBjb250YWluc05vZGVcbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaXNUZXh0Tm9kZSA9IHJlcXVpcmUoJy4vaXNUZXh0Tm9kZScpO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UgKi9cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBnaXZlbiBET00gbm9kZSBjb250YWlucyBvciBpcyBhbm90aGVyIERPTSBub2RlLlxuICpcbiAqIEBwYXJhbSB7P0RPTU5vZGV9IG91dGVyTm9kZSBPdXRlciBET00gbm9kZS5cbiAqIEBwYXJhbSB7P0RPTU5vZGV9IGlubmVyTm9kZSBJbm5lciBET00gbm9kZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYG91dGVyTm9kZWAgY29udGFpbnMgb3IgaXMgYGlubmVyTm9kZWAuXG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5zTm9kZShfeCwgX3gyKSB7XG4gIHZhciBfYWdhaW4gPSB0cnVlO1xuXG4gIF9mdW5jdGlvbjogd2hpbGUgKF9hZ2Fpbikge1xuICAgIHZhciBvdXRlck5vZGUgPSBfeCxcbiAgICAgICAgaW5uZXJOb2RlID0gX3gyO1xuICAgIF9hZ2FpbiA9IGZhbHNlO1xuXG4gICAgaWYgKCFvdXRlck5vZGUgfHwgIWlubmVyTm9kZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSBpZiAob3V0ZXJOb2RlID09PSBpbm5lck5vZGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaXNUZXh0Tm9kZShvdXRlck5vZGUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChpc1RleHROb2RlKGlubmVyTm9kZSkpIHtcbiAgICAgIF94ID0gb3V0ZXJOb2RlO1xuICAgICAgX3gyID0gaW5uZXJOb2RlLnBhcmVudE5vZGU7XG4gICAgICBfYWdhaW4gPSB0cnVlO1xuICAgICAgY29udGludWUgX2Z1bmN0aW9uO1xuICAgIH0gZWxzZSBpZiAob3V0ZXJOb2RlLmNvbnRhaW5zKSB7XG4gICAgICByZXR1cm4gb3V0ZXJOb2RlLmNvbnRhaW5zKGlubmVyTm9kZSk7XG4gICAgfSBlbHNlIGlmIChvdXRlck5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24pIHtcbiAgICAgIHJldHVybiAhIShvdXRlck5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24oaW5uZXJOb2RlKSAmIDE2KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbnRhaW5zTm9kZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgY3JlYXRlQXJyYXlGcm9tTWl4ZWRcbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9BcnJheSA9IHJlcXVpcmUoJy4vdG9BcnJheScpO1xuXG4vKipcbiAqIFBlcmZvcm0gYSBoZXVyaXN0aWMgdGVzdCB0byBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIFwiYXJyYXktbGlrZVwiLlxuICpcbiAqICAgQSBtb25rIGFza2VkIEpvc2h1LCBhIFplbiBtYXN0ZXIsIFwiSGFzIGEgZG9nIEJ1ZGRoYSBuYXR1cmU/XCJcbiAqICAgSm9zaHUgcmVwbGllZDogXCJNdS5cIlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gZGV0ZXJtaW5lcyBpZiBpdHMgYXJndW1lbnQgaGFzIFwiYXJyYXkgbmF0dXJlXCI6IGl0IHJldHVybnNcbiAqIHRydWUgaWYgdGhlIGFyZ3VtZW50IGlzIGFuIGFjdHVhbCBhcnJheSwgYW4gYGFyZ3VtZW50cycgb2JqZWN0LCBvciBhblxuICogSFRNTENvbGxlY3Rpb24gKGUuZy4gbm9kZS5jaGlsZE5vZGVzIG9yIG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoKSkuXG4gKlxuICogSXQgd2lsbCByZXR1cm4gZmFsc2UgZm9yIG90aGVyIGFycmF5LWxpa2Ugb2JqZWN0cyBsaWtlIEZpbGVsaXN0LlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBoYXNBcnJheU5hdHVyZShvYmopIHtcbiAgcmV0dXJuKFxuICAgIC8vIG5vdCBudWxsL2ZhbHNlXG4gICAgISFvYmogJiYgKFxuICAgIC8vIGFycmF5cyBhcmUgb2JqZWN0cywgTm9kZUxpc3RzIGFyZSBmdW5jdGlvbnMgaW4gU2FmYXJpXG4gICAgdHlwZW9mIG9iaiA9PSAnb2JqZWN0JyB8fCB0eXBlb2Ygb2JqID09ICdmdW5jdGlvbicpICYmXG4gICAgLy8gcXVhY2tzIGxpa2UgYW4gYXJyYXlcbiAgICAnbGVuZ3RoJyBpbiBvYmogJiZcbiAgICAvLyBub3Qgd2luZG93XG4gICAgISgnc2V0SW50ZXJ2YWwnIGluIG9iaikgJiZcbiAgICAvLyBubyBET00gbm9kZSBzaG91bGQgYmUgY29uc2lkZXJlZCBhbiBhcnJheS1saWtlXG4gICAgLy8gYSAnc2VsZWN0JyBlbGVtZW50IGhhcyAnbGVuZ3RoJyBhbmQgJ2l0ZW0nIHByb3BlcnRpZXMgb24gSUU4XG4gICAgdHlwZW9mIG9iai5ub2RlVHlwZSAhPSAnbnVtYmVyJyAmJiAoXG4gICAgLy8gYSByZWFsIGFycmF5XG4gICAgQXJyYXkuaXNBcnJheShvYmopIHx8XG4gICAgLy8gYXJndW1lbnRzXG4gICAgJ2NhbGxlZScgaW4gb2JqIHx8XG4gICAgLy8gSFRNTENvbGxlY3Rpb24vTm9kZUxpc3RcbiAgICAnaXRlbScgaW4gb2JqKVxuICApO1xufVxuXG4vKipcbiAqIEVuc3VyZSB0aGF0IHRoZSBhcmd1bWVudCBpcyBhbiBhcnJheSBieSB3cmFwcGluZyBpdCBpbiBhbiBhcnJheSBpZiBpdCBpcyBub3QuXG4gKiBDcmVhdGVzIGEgY29weSBvZiB0aGUgYXJndW1lbnQgaWYgaXQgaXMgYWxyZWFkeSBhbiBhcnJheS5cbiAqXG4gKiBUaGlzIGlzIG1vc3RseSB1c2VmdWwgaWRpb21hdGljYWxseTpcbiAqXG4gKiAgIHZhciBjcmVhdGVBcnJheUZyb21NaXhlZCA9IHJlcXVpcmUoJ2NyZWF0ZUFycmF5RnJvbU1peGVkJyk7XG4gKlxuICogICBmdW5jdGlvbiB0YWtlc09uZU9yTW9yZVRoaW5ncyh0aGluZ3MpIHtcbiAqICAgICB0aGluZ3MgPSBjcmVhdGVBcnJheUZyb21NaXhlZCh0aGluZ3MpO1xuICogICAgIC4uLlxuICogICB9XG4gKlxuICogVGhpcyBhbGxvd3MgeW91IHRvIHRyZWF0IGB0aGluZ3MnIGFzIGFuIGFycmF5LCBidXQgYWNjZXB0IHNjYWxhcnMgaW4gdGhlIEFQSS5cbiAqXG4gKiBJZiB5b3UgbmVlZCB0byBjb252ZXJ0IGFuIGFycmF5LWxpa2Ugb2JqZWN0LCBsaWtlIGBhcmd1bWVudHNgLCBpbnRvIGFuIGFycmF5XG4gKiB1c2UgdG9BcnJheSBpbnN0ZWFkLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHthcnJheX1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQXJyYXlGcm9tTWl4ZWQob2JqKSB7XG4gIGlmICghaGFzQXJyYXlOYXR1cmUob2JqKSkge1xuICAgIHJldHVybiBbb2JqXTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gb2JqLnNsaWNlKCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRvQXJyYXkob2JqKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUFycmF5RnJvbU1peGVkOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBjcmVhdGVOb2Rlc0Zyb21NYXJrdXBcbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuLyplc2xpbnQtZGlzYWJsZSBmYi13d3cvdW5zYWZlLWh0bWwqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJy4vRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcblxudmFyIGNyZWF0ZUFycmF5RnJvbU1peGVkID0gcmVxdWlyZSgnLi9jcmVhdGVBcnJheUZyb21NaXhlZCcpO1xudmFyIGdldE1hcmt1cFdyYXAgPSByZXF1aXJlKCcuL2dldE1hcmt1cFdyYXAnKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCcuL2ludmFyaWFudCcpO1xuXG4vKipcbiAqIER1bW15IGNvbnRhaW5lciB1c2VkIHRvIHJlbmRlciBhbGwgbWFya3VwLlxuICovXG52YXIgZHVtbXlOb2RlID0gRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykgOiBudWxsO1xuXG4vKipcbiAqIFBhdHRlcm4gdXNlZCBieSBgZ2V0Tm9kZU5hbWVgLlxuICovXG52YXIgbm9kZU5hbWVQYXR0ZXJuID0gL15cXHMqPChcXHcrKS87XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIGBub2RlTmFtZWAgb2YgdGhlIGZpcnN0IGVsZW1lbnQgaW4gYSBzdHJpbmcgb2YgbWFya3VwLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtYXJrdXAgU3RyaW5nIG9mIG1hcmt1cC5cbiAqIEByZXR1cm4gez9zdHJpbmd9IE5vZGUgbmFtZSBvZiB0aGUgc3VwcGxpZWQgbWFya3VwLlxuICovXG5mdW5jdGlvbiBnZXROb2RlTmFtZShtYXJrdXApIHtcbiAgdmFyIG5vZGVOYW1lTWF0Y2ggPSBtYXJrdXAubWF0Y2gobm9kZU5hbWVQYXR0ZXJuKTtcbiAgcmV0dXJuIG5vZGVOYW1lTWF0Y2ggJiYgbm9kZU5hbWVNYXRjaFsxXS50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgbm9kZXMgcmVuZGVyZWQgZnJvbSB0aGUgc3VwcGxpZWQgbWFya3VwLiBUaGVcbiAqIG9wdGlvbmFsbHkgc3VwcGxpZWQgYGhhbmRsZVNjcmlwdGAgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIG9uY2UgZm9yIGVhY2hcbiAqIDxzY3JpcHQ+IGVsZW1lbnQgdGhhdCBpcyByZW5kZXJlZC4gSWYgbm8gYGhhbmRsZVNjcmlwdGAgZnVuY3Rpb24gaXMgc3VwcGxpZWQsXG4gKiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGlmIGFueSA8c2NyaXB0PiBlbGVtZW50cyBhcmUgcmVuZGVyZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1hcmt1cCBBIHN0cmluZyBvZiB2YWxpZCBIVE1MIG1hcmt1cC5cbiAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBoYW5kbGVTY3JpcHQgSW52b2tlZCBvbmNlIGZvciBlYWNoIHJlbmRlcmVkIDxzY3JpcHQ+LlxuICogQHJldHVybiB7YXJyYXk8RE9NRWxlbWVudHxET01UZXh0Tm9kZT59IEFuIGFycmF5IG9mIHJlbmRlcmVkIG5vZGVzLlxuICovXG5mdW5jdGlvbiBjcmVhdGVOb2Rlc0Zyb21NYXJrdXAobWFya3VwLCBoYW5kbGVTY3JpcHQpIHtcbiAgdmFyIG5vZGUgPSBkdW1teU5vZGU7XG4gICEhIWR1bW15Tm9kZSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdjcmVhdGVOb2Rlc0Zyb21NYXJrdXAgZHVtbXkgbm90IGluaXRpYWxpemVkJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICB2YXIgbm9kZU5hbWUgPSBnZXROb2RlTmFtZShtYXJrdXApO1xuXG4gIHZhciB3cmFwID0gbm9kZU5hbWUgJiYgZ2V0TWFya3VwV3JhcChub2RlTmFtZSk7XG4gIGlmICh3cmFwKSB7XG4gICAgbm9kZS5pbm5lckhUTUwgPSB3cmFwWzFdICsgbWFya3VwICsgd3JhcFsyXTtcblxuICAgIHZhciB3cmFwRGVwdGggPSB3cmFwWzBdO1xuICAgIHdoaWxlICh3cmFwRGVwdGgtLSkge1xuICAgICAgbm9kZSA9IG5vZGUubGFzdENoaWxkO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBub2RlLmlubmVySFRNTCA9IG1hcmt1cDtcbiAgfVxuXG4gIHZhciBzY3JpcHRzID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG4gIGlmIChzY3JpcHRzLmxlbmd0aCkge1xuICAgICFoYW5kbGVTY3JpcHQgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnY3JlYXRlTm9kZXNGcm9tTWFya3VwKC4uLik6IFVuZXhwZWN0ZWQgPHNjcmlwdD4gZWxlbWVudCByZW5kZXJlZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgY3JlYXRlQXJyYXlGcm9tTWl4ZWQoc2NyaXB0cykuZm9yRWFjaChoYW5kbGVTY3JpcHQpO1xuICB9XG5cbiAgdmFyIG5vZGVzID0gY3JlYXRlQXJyYXlGcm9tTWl4ZWQobm9kZS5jaGlsZE5vZGVzKTtcbiAgd2hpbGUgKG5vZGUubGFzdENoaWxkKSB7XG4gICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmxhc3RDaGlsZCk7XG4gIH1cbiAgcmV0dXJuIG5vZGVzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZU5vZGVzRnJvbU1hcmt1cDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZW1wdHlGdW5jdGlvblxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBtYWtlRW1wdHlGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYXJnO1xuICB9O1xufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gYWNjZXB0cyBhbmQgZGlzY2FyZHMgaW5wdXRzOyBpdCBoYXMgbm8gc2lkZSBlZmZlY3RzLiBUaGlzIGlzXG4gKiBwcmltYXJpbHkgdXNlZnVsIGlkaW9tYXRpY2FsbHkgZm9yIG92ZXJyaWRhYmxlIGZ1bmN0aW9uIGVuZHBvaW50cyB3aGljaFxuICogYWx3YXlzIG5lZWQgdG8gYmUgY2FsbGFibGUsIHNpbmNlIEpTIGxhY2tzIGEgbnVsbC1jYWxsIGlkaW9tIGFsYSBDb2NvYS5cbiAqL1xuZnVuY3Rpb24gZW1wdHlGdW5jdGlvbigpIHt9XG5cbmVtcHR5RnVuY3Rpb24udGhhdFJldHVybnMgPSBtYWtlRW1wdHlGdW5jdGlvbjtcbmVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNGYWxzZSA9IG1ha2VFbXB0eUZ1bmN0aW9uKGZhbHNlKTtcbmVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNUcnVlID0gbWFrZUVtcHR5RnVuY3Rpb24odHJ1ZSk7XG5lbXB0eUZ1bmN0aW9uLnRoYXRSZXR1cm5zTnVsbCA9IG1ha2VFbXB0eUZ1bmN0aW9uKG51bGwpO1xuZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc1RoaXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzO1xufTtcbmVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNBcmd1bWVudCA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGFyZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZW1wdHlGdW5jdGlvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZW1wdHlPYmplY3RcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlbXB0eU9iamVjdCA9IHt9O1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBPYmplY3QuZnJlZXplKGVtcHR5T2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbXB0eU9iamVjdDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZm9jdXNOb2RlXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZSBpbnB1dC90ZXh0YXJlYSB0byBmb2N1c1xuICovXG5mdW5jdGlvbiBmb2N1c05vZGUobm9kZSkge1xuICAvLyBJRTggY2FuIHRocm93IFwiQ2FuJ3QgbW92ZSBmb2N1cyB0byB0aGUgY29udHJvbCBiZWNhdXNlIGl0IGlzIGludmlzaWJsZSxcbiAgLy8gbm90IGVuYWJsZWQsIG9yIG9mIGEgdHlwZSB0aGF0IGRvZXMgbm90IGFjY2VwdCB0aGUgZm9jdXMuXCIgZm9yIGFsbCBraW5kcyBvZlxuICAvLyByZWFzb25zIHRoYXQgYXJlIHRvbyBleHBlbnNpdmUgYW5kIGZyYWdpbGUgdG8gdGVzdC5cbiAgdHJ5IHtcbiAgICBub2RlLmZvY3VzKCk7XG4gIH0gY2F0Y2ggKGUpIHt9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZm9jdXNOb2RlOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBnZXRBY3RpdmVFbGVtZW50XG4gKiBAdHlwZWNoZWNrc1xuICovXG5cbi8qIGVzbGludC1kaXNhYmxlIGZiLXd3dy90eXBlb2YtdW5kZWZpbmVkICovXG5cbi8qKlxuICogU2FtZSBhcyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGJ1dCB3cmFwcyBpbiBhIHRyeS1jYXRjaCBibG9jay4gSW4gSUUgaXQgaXNcbiAqIG5vdCBzYWZlIHRvIGNhbGwgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBpZiB0aGVyZSBpcyBub3RoaW5nIGZvY3VzZWQuXG4gKlxuICogVGhlIGFjdGl2ZUVsZW1lbnQgd2lsbCBiZSBudWxsIG9ubHkgaWYgdGhlIGRvY3VtZW50IG9yIGRvY3VtZW50IGJvZHkgaXMgbm90XG4gKiB5ZXQgZGVmaW5lZC5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBnZXRBY3RpdmVFbGVtZW50KCkgLyo/RE9NRWxlbWVudCove1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBkb2N1bWVudC5ib2R5O1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWN0aXZlRWxlbWVudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZ2V0TWFya3VwV3JhcFxuICovXG5cbi8qZXNsaW50LWRpc2FibGUgZmItd3d3L3Vuc2FmZS1odG1sICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnLi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnLi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBEdW1teSBjb250YWluZXIgdXNlZCB0byBkZXRlY3Qgd2hpY2ggd3JhcHMgYXJlIG5lY2Vzc2FyeS5cbiAqL1xudmFyIGR1bW15Tm9kZSA9IEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpIDogbnVsbDtcblxuLyoqXG4gKiBTb21lIGJyb3dzZXJzIGNhbm5vdCB1c2UgYGlubmVySFRNTGAgdG8gcmVuZGVyIGNlcnRhaW4gZWxlbWVudHMgc3RhbmRhbG9uZSxcbiAqIHNvIHdlIHdyYXAgdGhlbSwgcmVuZGVyIHRoZSB3cmFwcGVkIG5vZGVzLCB0aGVuIGV4dHJhY3QgdGhlIGRlc2lyZWQgbm9kZS5cbiAqXG4gKiBJbiBJRTgsIGNlcnRhaW4gZWxlbWVudHMgY2Fubm90IHJlbmRlciBhbG9uZSwgc28gd3JhcCBhbGwgZWxlbWVudHMgKCcqJykuXG4gKi9cblxudmFyIHNob3VsZFdyYXAgPSB7fTtcblxudmFyIHNlbGVjdFdyYXAgPSBbMSwgJzxzZWxlY3QgbXVsdGlwbGU9XCJ0cnVlXCI+JywgJzwvc2VsZWN0PiddO1xudmFyIHRhYmxlV3JhcCA9IFsxLCAnPHRhYmxlPicsICc8L3RhYmxlPiddO1xudmFyIHRyV3JhcCA9IFszLCAnPHRhYmxlPjx0Ym9keT48dHI+JywgJzwvdHI+PC90Ym9keT48L3RhYmxlPiddO1xuXG52YXIgc3ZnV3JhcCA9IFsxLCAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+JywgJzwvc3ZnPiddO1xuXG52YXIgbWFya3VwV3JhcCA9IHtcbiAgJyonOiBbMSwgJz88ZGl2PicsICc8L2Rpdj4nXSxcblxuICAnYXJlYSc6IFsxLCAnPG1hcD4nLCAnPC9tYXA+J10sXG4gICdjb2wnOiBbMiwgJzx0YWJsZT48dGJvZHk+PC90Ym9keT48Y29sZ3JvdXA+JywgJzwvY29sZ3JvdXA+PC90YWJsZT4nXSxcbiAgJ2xlZ2VuZCc6IFsxLCAnPGZpZWxkc2V0PicsICc8L2ZpZWxkc2V0PiddLFxuICAncGFyYW0nOiBbMSwgJzxvYmplY3Q+JywgJzwvb2JqZWN0PiddLFxuICAndHInOiBbMiwgJzx0YWJsZT48dGJvZHk+JywgJzwvdGJvZHk+PC90YWJsZT4nXSxcblxuICAnb3B0Z3JvdXAnOiBzZWxlY3RXcmFwLFxuICAnb3B0aW9uJzogc2VsZWN0V3JhcCxcblxuICAnY2FwdGlvbic6IHRhYmxlV3JhcCxcbiAgJ2NvbGdyb3VwJzogdGFibGVXcmFwLFxuICAndGJvZHknOiB0YWJsZVdyYXAsXG4gICd0Zm9vdCc6IHRhYmxlV3JhcCxcbiAgJ3RoZWFkJzogdGFibGVXcmFwLFxuXG4gICd0ZCc6IHRyV3JhcCxcbiAgJ3RoJzogdHJXcmFwXG59O1xuXG4vLyBJbml0aWFsaXplIHRoZSBTVkcgZWxlbWVudHMgc2luY2Ugd2Uga25vdyB0aGV5J2xsIGFsd2F5cyBuZWVkIHRvIGJlIHdyYXBwZWRcbi8vIGNvbnNpc3RlbnRseS4gSWYgdGhleSBhcmUgY3JlYXRlZCBpbnNpZGUgYSA8ZGl2PiB0aGV5IHdpbGwgYmUgaW5pdGlhbGl6ZWQgaW5cbi8vIHRoZSB3cm9uZyBuYW1lc3BhY2UgKGFuZCB3aWxsIG5vdCBkaXNwbGF5KS5cbnZhciBzdmdFbGVtZW50cyA9IFsnY2lyY2xlJywgJ2NsaXBQYXRoJywgJ2RlZnMnLCAnZWxsaXBzZScsICdnJywgJ2ltYWdlJywgJ2xpbmUnLCAnbGluZWFyR3JhZGllbnQnLCAnbWFzaycsICdwYXRoJywgJ3BhdHRlcm4nLCAncG9seWdvbicsICdwb2x5bGluZScsICdyYWRpYWxHcmFkaWVudCcsICdyZWN0JywgJ3N0b3AnLCAndGV4dCcsICd0c3BhbiddO1xuc3ZnRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAobm9kZU5hbWUpIHtcbiAgbWFya3VwV3JhcFtub2RlTmFtZV0gPSBzdmdXcmFwO1xuICBzaG91bGRXcmFwW25vZGVOYW1lXSA9IHRydWU7XG59KTtcblxuLyoqXG4gKiBHZXRzIHRoZSBtYXJrdXAgd3JhcCBjb25maWd1cmF0aW9uIGZvciB0aGUgc3VwcGxpZWQgYG5vZGVOYW1lYC5cbiAqXG4gKiBOT1RFOiBUaGlzIGxhemlseSBkZXRlY3RzIHdoaWNoIHdyYXBzIGFyZSBuZWNlc3NhcnkgZm9yIHRoZSBjdXJyZW50IGJyb3dzZXIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5vZGVOYW1lIExvd2VyY2FzZSBgbm9kZU5hbWVgLlxuICogQHJldHVybiB7P2FycmF5fSBNYXJrdXAgd3JhcCBjb25maWd1cmF0aW9uLCBpZiBhcHBsaWNhYmxlLlxuICovXG5mdW5jdGlvbiBnZXRNYXJrdXBXcmFwKG5vZGVOYW1lKSB7XG4gICEhIWR1bW15Tm9kZSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdNYXJrdXAgd3JhcHBpbmcgbm9kZSBub3QgaW5pdGlhbGl6ZWQnKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIGlmICghbWFya3VwV3JhcC5oYXNPd25Qcm9wZXJ0eShub2RlTmFtZSkpIHtcbiAgICBub2RlTmFtZSA9ICcqJztcbiAgfVxuICBpZiAoIXNob3VsZFdyYXAuaGFzT3duUHJvcGVydHkobm9kZU5hbWUpKSB7XG4gICAgaWYgKG5vZGVOYW1lID09PSAnKicpIHtcbiAgICAgIGR1bW15Tm9kZS5pbm5lckhUTUwgPSAnPGxpbmsgLz4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBkdW1teU5vZGUuaW5uZXJIVE1MID0gJzwnICsgbm9kZU5hbWUgKyAnPjwvJyArIG5vZGVOYW1lICsgJz4nO1xuICAgIH1cbiAgICBzaG91bGRXcmFwW25vZGVOYW1lXSA9ICFkdW1teU5vZGUuZmlyc3RDaGlsZDtcbiAgfVxuICByZXR1cm4gc2hvdWxkV3JhcFtub2RlTmFtZV0gPyBtYXJrdXBXcmFwW25vZGVOYW1lXSA6IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWFya3VwV3JhcDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZ2V0VW5ib3VuZGVkU2Nyb2xsUG9zaXRpb25cbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEdldHMgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgc3VwcGxpZWQgZWxlbWVudCBvciB3aW5kb3cuXG4gKlxuICogVGhlIHJldHVybiB2YWx1ZXMgYXJlIHVuYm91bmRlZCwgdW5saWtlIGBnZXRTY3JvbGxQb3NpdGlvbmAuIFRoaXMgbWVhbnMgdGhleVxuICogbWF5IGJlIG5lZ2F0aXZlIG9yIGV4Y2VlZCB0aGUgZWxlbWVudCBib3VuZGFyaWVzICh3aGljaCBpcyBwb3NzaWJsZSB1c2luZ1xuICogaW5lcnRpYWwgc2Nyb2xsaW5nKS5cbiAqXG4gKiBAcGFyYW0ge0RPTVdpbmRvd3xET01FbGVtZW50fSBzY3JvbGxhYmxlXG4gKiBAcmV0dXJuIHtvYmplY3R9IE1hcCB3aXRoIGB4YCBhbmQgYHlgIGtleXMuXG4gKi9cbmZ1bmN0aW9uIGdldFVuYm91bmRlZFNjcm9sbFBvc2l0aW9uKHNjcm9sbGFibGUpIHtcbiAgaWYgKHNjcm9sbGFibGUgPT09IHdpbmRvdykge1xuICAgIHJldHVybiB7XG4gICAgICB4OiB3aW5kb3cucGFnZVhPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXG4gICAgICB5OiB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB4OiBzY3JvbGxhYmxlLnNjcm9sbExlZnQsXG4gICAgeTogc2Nyb2xsYWJsZS5zY3JvbGxUb3BcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRVbmJvdW5kZWRTY3JvbGxQb3NpdGlvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgaHlwaGVuYXRlXG4gKiBAdHlwZWNoZWNrc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIF91cHBlcmNhc2VQYXR0ZXJuID0gLyhbQS1aXSkvZztcblxuLyoqXG4gKiBIeXBoZW5hdGVzIGEgY2FtZWxjYXNlZCBzdHJpbmcsIGZvciBleGFtcGxlOlxuICpcbiAqICAgPiBoeXBoZW5hdGUoJ2JhY2tncm91bmRDb2xvcicpXG4gKiAgIDwgXCJiYWNrZ3JvdW5kLWNvbG9yXCJcbiAqXG4gKiBGb3IgQ1NTIHN0eWxlIG5hbWVzLCB1c2UgYGh5cGhlbmF0ZVN0eWxlTmFtZWAgaW5zdGVhZCB3aGljaCB3b3JrcyBwcm9wZXJseVxuICogd2l0aCBhbGwgdmVuZG9yIHByZWZpeGVzLCBpbmNsdWRpbmcgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGh5cGhlbmF0ZShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKF91cHBlcmNhc2VQYXR0ZXJuLCAnLSQxJykudG9Mb3dlckNhc2UoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoeXBoZW5hdGU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGh5cGhlbmF0ZVN0eWxlTmFtZVxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBoeXBoZW5hdGUgPSByZXF1aXJlKCcuL2h5cGhlbmF0ZScpO1xuXG52YXIgbXNQYXR0ZXJuID0gL15tcy0vO1xuXG4vKipcbiAqIEh5cGhlbmF0ZXMgYSBjYW1lbGNhc2VkIENTUyBwcm9wZXJ0eSBuYW1lLCBmb3IgZXhhbXBsZTpcbiAqXG4gKiAgID4gaHlwaGVuYXRlU3R5bGVOYW1lKCdiYWNrZ3JvdW5kQ29sb3InKVxuICogICA8IFwiYmFja2dyb3VuZC1jb2xvclwiXG4gKiAgID4gaHlwaGVuYXRlU3R5bGVOYW1lKCdNb3pUcmFuc2l0aW9uJylcbiAqICAgPCBcIi1tb3otdHJhbnNpdGlvblwiXG4gKiAgID4gaHlwaGVuYXRlU3R5bGVOYW1lKCdtc1RyYW5zaXRpb24nKVxuICogICA8IFwiLW1zLXRyYW5zaXRpb25cIlxuICpcbiAqIEFzIE1vZGVybml6ciBzdWdnZXN0cyAoaHR0cDovL21vZGVybml6ci5jb20vZG9jcy8jcHJlZml4ZWQpLCBhbiBgbXNgIHByZWZpeFxuICogaXMgY29udmVydGVkIHRvIGAtbXMtYC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGh5cGhlbmF0ZVN0eWxlTmFtZShzdHJpbmcpIHtcbiAgcmV0dXJuIGh5cGhlbmF0ZShzdHJpbmcpLnJlcGxhY2UobXNQYXR0ZXJuLCAnLW1zLScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGh5cGhlbmF0ZVN0eWxlTmFtZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgaW52YXJpYW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFVzZSBpbnZhcmlhbnQoKSB0byBhc3NlcnQgc3RhdGUgd2hpY2ggeW91ciBwcm9ncmFtIGFzc3VtZXMgdG8gYmUgdHJ1ZS5cbiAqXG4gKiBQcm92aWRlIHNwcmludGYtc3R5bGUgZm9ybWF0IChvbmx5ICVzIGlzIHN1cHBvcnRlZCkgYW5kIGFyZ3VtZW50c1xuICogdG8gcHJvdmlkZSBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IGJyb2tlIGFuZCB3aGF0IHlvdSB3ZXJlXG4gKiBleHBlY3RpbmcuXG4gKlxuICogVGhlIGludmFyaWFudCBtZXNzYWdlIHdpbGwgYmUgc3RyaXBwZWQgaW4gcHJvZHVjdGlvbiwgYnV0IHRoZSBpbnZhcmlhbnRcbiAqIHdpbGwgcmVtYWluIHRvIGVuc3VyZSBsb2dpYyBkb2VzIG5vdCBkaWZmZXIgaW4gcHJvZHVjdGlvbi5cbiAqL1xuXG5mdW5jdGlvbiBpbnZhcmlhbnQoY29uZGl0aW9uLCBmb3JtYXQsIGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YXJpYW50IHJlcXVpcmVzIGFuIGVycm9yIG1lc3NhZ2UgYXJndW1lbnQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIWNvbmRpdGlvbikge1xuICAgIHZhciBlcnJvcjtcbiAgICBpZiAoZm9ybWF0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGVycm9yID0gbmV3IEVycm9yKCdNaW5pZmllZCBleGNlcHRpb24gb2NjdXJyZWQ7IHVzZSB0aGUgbm9uLW1pbmlmaWVkIGRldiBlbnZpcm9ubWVudCAnICsgJ2ZvciB0aGUgZnVsbCBlcnJvciBtZXNzYWdlIGFuZCBhZGRpdGlvbmFsIGhlbHBmdWwgd2FybmluZ3MuJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBhcmdzID0gW2EsIGIsIGMsIGQsIGUsIGZdO1xuICAgICAgdmFyIGFyZ0luZGV4ID0gMDtcbiAgICAgIGVycm9yID0gbmV3IEVycm9yKGZvcm1hdC5yZXBsYWNlKC8lcy9nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBhcmdzW2FyZ0luZGV4KytdO1xuICAgICAgfSkpO1xuICAgICAgZXJyb3IubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICB9XG5cbiAgICBlcnJvci5mcmFtZXNUb1BvcCA9IDE7IC8vIHdlIGRvbid0IGNhcmUgYWJvdXQgaW52YXJpYW50J3Mgb3duIGZyYW1lXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnZhcmlhbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGlzTm9kZVxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIG9yIG5vdCB0aGUgb2JqZWN0IGlzIGEgRE9NIG5vZGUuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaXNOb2RlKG9iamVjdCkge1xuICByZXR1cm4gISEob2JqZWN0ICYmICh0eXBlb2YgTm9kZSA9PT0gJ2Z1bmN0aW9uJyA/IG9iamVjdCBpbnN0YW5jZW9mIE5vZGUgOiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiB0eXBlb2Ygb2JqZWN0Lm5vZGVUeXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2Ygb2JqZWN0Lm5vZGVOYW1lID09PSAnc3RyaW5nJykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTm9kZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgaXNUZXh0Tm9kZVxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpc05vZGUgPSByZXF1aXJlKCcuL2lzTm9kZScpO1xuXG4vKipcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIG9yIG5vdCB0aGUgb2JqZWN0IGlzIGEgRE9NIHRleHQgbm9kZS5cbiAqL1xuZnVuY3Rpb24gaXNUZXh0Tm9kZShvYmplY3QpIHtcbiAgcmV0dXJuIGlzTm9kZShvYmplY3QpICYmIG9iamVjdC5ub2RlVHlwZSA9PSAzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGV4dE5vZGU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGtleU1pcnJvclxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCcuL2ludmFyaWFudCcpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYW4gZW51bWVyYXRpb24gd2l0aCBrZXlzIGVxdWFsIHRvIHRoZWlyIHZhbHVlLlxuICpcbiAqIEZvciBleGFtcGxlOlxuICpcbiAqICAgdmFyIENPTE9SUyA9IGtleU1pcnJvcih7Ymx1ZTogbnVsbCwgcmVkOiBudWxsfSk7XG4gKiAgIHZhciBteUNvbG9yID0gQ09MT1JTLmJsdWU7XG4gKiAgIHZhciBpc0NvbG9yVmFsaWQgPSAhIUNPTE9SU1tteUNvbG9yXTtcbiAqXG4gKiBUaGUgbGFzdCBsaW5lIGNvdWxkIG5vdCBiZSBwZXJmb3JtZWQgaWYgdGhlIHZhbHVlcyBvZiB0aGUgZ2VuZXJhdGVkIGVudW0gd2VyZVxuICogbm90IGVxdWFsIHRvIHRoZWlyIGtleXMuXG4gKlxuICogICBJbnB1dDogIHtrZXkxOiB2YWwxLCBrZXkyOiB2YWwyfVxuICogICBPdXRwdXQ6IHtrZXkxOiBrZXkxLCBrZXkyOiBrZXkyfVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqL1xudmFyIGtleU1pcnJvciA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIHJldCA9IHt9O1xuICB2YXIga2V5O1xuICAhKG9iaiBpbnN0YW5jZW9mIE9iamVjdCAmJiAhQXJyYXkuaXNBcnJheShvYmopKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdrZXlNaXJyb3IoLi4uKTogQXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmV0W2tleV0gPSBrZXk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5TWlycm9yOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBrZXlPZlxuICovXG5cbi8qKlxuICogQWxsb3dzIGV4dHJhY3Rpb24gb2YgYSBtaW5pZmllZCBrZXkuIExldCdzIHRoZSBidWlsZCBzeXN0ZW0gbWluaWZ5IGtleXNcbiAqIHdpdGhvdXQgbG9zaW5nIHRoZSBhYmlsaXR5IHRvIGR5bmFtaWNhbGx5IHVzZSBrZXkgc3RyaW5ncyBhcyB2YWx1ZXNcbiAqIHRoZW1zZWx2ZXMuIFBhc3MgaW4gYW4gb2JqZWN0IHdpdGggYSBzaW5nbGUga2V5L3ZhbCBwYWlyIGFuZCBpdCB3aWxsIHJldHVyblxuICogeW91IHRoZSBzdHJpbmcga2V5IG9mIHRoYXQgc2luZ2xlIHJlY29yZC4gU3VwcG9zZSB5b3Ugd2FudCB0byBncmFiIHRoZVxuICogdmFsdWUgZm9yIGEga2V5ICdjbGFzc05hbWUnIGluc2lkZSBvZiBhbiBvYmplY3QuIEtleS92YWwgbWluaWZpY2F0aW9uIG1heVxuICogaGF2ZSBhbGlhc2VkIHRoYXQga2V5IHRvIGJlICd4YTEyJy4ga2V5T2Yoe2NsYXNzTmFtZTogbnVsbH0pIHdpbGwgcmV0dXJuXG4gKiAneGExMicgaW4gdGhhdCBjYXNlLiBSZXNvbHZlIGtleXMgeW91IHdhbnQgdG8gdXNlIG9uY2UgYXQgc3RhcnR1cCB0aW1lLCB0aGVuXG4gKiByZXVzZSB0aG9zZSByZXNvbHV0aW9ucy5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBrZXlPZiA9IGZ1bmN0aW9uIChvbmVLZXlPYmopIHtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gb25lS2V5T2JqKSB7XG4gICAgaWYgKCFvbmVLZXlPYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJldHVybiBrZXk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleU9mOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBtYXBPYmplY3RcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogRXhlY3V0ZXMgdGhlIHByb3ZpZGVkIGBjYWxsYmFja2Agb25jZSBmb3IgZWFjaCBlbnVtZXJhYmxlIG93biBwcm9wZXJ0eSBpbiB0aGVcbiAqIG9iamVjdCBhbmQgY29uc3RydWN0cyBhIG5ldyBvYmplY3QgZnJvbSB0aGUgcmVzdWx0cy4gVGhlIGBjYWxsYmFja2AgaXNcbiAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gKlxuICogIC0gdGhlIHByb3BlcnR5IHZhbHVlXG4gKiAgLSB0aGUgcHJvcGVydHkgbmFtZVxuICogIC0gdGhlIG9iamVjdCBiZWluZyB0cmF2ZXJzZWRcbiAqXG4gKiBQcm9wZXJ0aWVzIHRoYXQgYXJlIGFkZGVkIGFmdGVyIHRoZSBjYWxsIHRvIGBtYXBPYmplY3RgIHdpbGwgbm90IGJlIHZpc2l0ZWRcbiAqIGJ5IGBjYWxsYmFja2AuIElmIHRoZSB2YWx1ZXMgb2YgZXhpc3RpbmcgcHJvcGVydGllcyBhcmUgY2hhbmdlZCwgdGhlIHZhbHVlXG4gKiBwYXNzZWQgdG8gYGNhbGxiYWNrYCB3aWxsIGJlIHRoZSB2YWx1ZSBhdCB0aGUgdGltZSBgbWFwT2JqZWN0YCB2aXNpdHMgdGhlbS5cbiAqIFByb3BlcnRpZXMgdGhhdCBhcmUgZGVsZXRlZCBiZWZvcmUgYmVpbmcgdmlzaXRlZCBhcmUgbm90IHZpc2l0ZWQuXG4gKlxuICogQGdyZXAgZnVuY3Rpb24gb2JqZWN0TWFwKClcbiAqIEBncmVwIGZ1bmN0aW9uIG9iak1hcCgpXG4gKlxuICogQHBhcmFtIHs/b2JqZWN0fSBvYmplY3RcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcGFyYW0geyp9IGNvbnRleHRcbiAqIEByZXR1cm4gez9vYmplY3R9XG4gKi9cbmZ1bmN0aW9uIG1hcE9iamVjdChvYmplY3QsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIGlmICghb2JqZWN0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgbmFtZSkpIHtcbiAgICAgIHJlc3VsdFtuYW1lXSA9IGNhbGxiYWNrLmNhbGwoY29udGV4dCwgb2JqZWN0W25hbWVdLCBuYW1lLCBvYmplY3QpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcE9iamVjdDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgbWVtb2l6ZVN0cmluZ09ubHlcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIE1lbW9pemVzIHRoZSByZXR1cm4gdmFsdWUgb2YgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgb25lIHN0cmluZyBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybiB7ZnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIG1lbW9pemVTdHJpbmdPbmx5KGNhbGxiYWNrKSB7XG4gIHZhciBjYWNoZSA9IHt9O1xuICByZXR1cm4gZnVuY3Rpb24gKHN0cmluZykge1xuICAgIGlmICghY2FjaGUuaGFzT3duUHJvcGVydHkoc3RyaW5nKSkge1xuICAgICAgY2FjaGVbc3RyaW5nXSA9IGNhbGxiYWNrLmNhbGwodGhpcywgc3RyaW5nKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlW3N0cmluZ107XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWVtb2l6ZVN0cmluZ09ubHk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHBlcmZvcm1hbmNlXG4gKiBAdHlwZWNoZWNrc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnLi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgcGVyZm9ybWFuY2U7XG5cbmlmIChFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00pIHtcbiAgcGVyZm9ybWFuY2UgPSB3aW5kb3cucGVyZm9ybWFuY2UgfHwgd2luZG93Lm1zUGVyZm9ybWFuY2UgfHwgd2luZG93LndlYmtpdFBlcmZvcm1hbmNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBlcmZvcm1hbmNlIHx8IHt9OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBwZXJmb3JtYW5jZU5vd1xuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBwZXJmb3JtYW5jZSA9IHJlcXVpcmUoJy4vcGVyZm9ybWFuY2UnKTtcblxudmFyIHBlcmZvcm1hbmNlTm93O1xuXG4vKipcbiAqIERldGVjdCBpZiB3ZSBjYW4gdXNlIGB3aW5kb3cucGVyZm9ybWFuY2Uubm93KClgIGFuZCBncmFjZWZ1bGx5IGZhbGxiYWNrIHRvXG4gKiBgRGF0ZS5ub3coKWAgaWYgaXQgZG9lc24ndCBleGlzdC4gV2UgbmVlZCB0byBzdXBwb3J0IEZpcmVmb3ggPCAxNSBmb3Igbm93XG4gKiBiZWNhdXNlIG9mIEZhY2Vib29rJ3MgdGVzdGluZyBpbmZyYXN0cnVjdHVyZS5cbiAqL1xuaWYgKHBlcmZvcm1hbmNlLm5vdykge1xuICBwZXJmb3JtYW5jZU5vdyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcGVyZm9ybWFuY2Uubm93KCk7XG4gIH07XG59IGVsc2Uge1xuICBwZXJmb3JtYW5jZU5vdyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gRGF0ZS5ub3coKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwZXJmb3JtYW5jZU5vdzsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgc2hhbGxvd0VxdWFsXG4gKiBAdHlwZWNoZWNrc1xuICogXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFBlcmZvcm1zIGVxdWFsaXR5IGJ5IGl0ZXJhdGluZyB0aHJvdWdoIGtleXMgb24gYW4gb2JqZWN0IGFuZCByZXR1cm5pbmcgZmFsc2VcbiAqIHdoZW4gYW55IGtleSBoYXMgdmFsdWVzIHdoaWNoIGFyZSBub3Qgc3RyaWN0bHkgZXF1YWwgYmV0d2VlbiB0aGUgYXJndW1lbnRzLlxuICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIHZhbHVlcyBvZiBhbGwga2V5cyBhcmUgc3RyaWN0bHkgZXF1YWwuXG4gKi9cbmZ1bmN0aW9uIHNoYWxsb3dFcXVhbChvYmpBLCBvYmpCKSB7XG4gIGlmIChvYmpBID09PSBvYmpCKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iakEgIT09ICdvYmplY3QnIHx8IG9iakEgPT09IG51bGwgfHwgdHlwZW9mIG9iakIgIT09ICdvYmplY3QnIHx8IG9iakIgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIga2V5c0EgPSBPYmplY3Qua2V5cyhvYmpBKTtcbiAgdmFyIGtleXNCID0gT2JqZWN0LmtleXMob2JqQik7XG5cbiAgaWYgKGtleXNBLmxlbmd0aCAhPT0ga2V5c0IubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVGVzdCBmb3IgQSdzIGtleXMgZGlmZmVyZW50IGZyb20gQi5cbiAgdmFyIGJIYXNPd25Qcm9wZXJ0eSA9IGhhc093blByb3BlcnR5LmJpbmQob2JqQik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5c0EubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWJIYXNPd25Qcm9wZXJ0eShrZXlzQVtpXSkgfHwgb2JqQVtrZXlzQVtpXV0gIT09IG9iakJba2V5c0FbaV1dKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hhbGxvd0VxdWFsOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSB0b0FycmF5XG4gKiBAdHlwZWNoZWNrc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJy4vaW52YXJpYW50Jyk7XG5cbi8qKlxuICogQ29udmVydCBhcnJheS1saWtlIG9iamVjdHMgdG8gYXJyYXlzLlxuICpcbiAqIFRoaXMgQVBJIGFzc3VtZXMgdGhlIGNhbGxlciBrbm93cyB0aGUgY29udGVudHMgb2YgdGhlIGRhdGEgdHlwZS4gRm9yIGxlc3NcbiAqIHdlbGwgZGVmaW5lZCBpbnB1dHMgdXNlIGNyZWF0ZUFycmF5RnJvbU1peGVkLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fGZ1bmN0aW9ufGZpbGVsaXN0fSBvYmpcbiAqIEByZXR1cm4ge2FycmF5fVxuICovXG5mdW5jdGlvbiB0b0FycmF5KG9iaikge1xuICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDtcblxuICAvLyBTb21lIGJyb3dzZSBidWlsdGluIG9iamVjdHMgY2FuIHJlcG9ydCB0eXBlb2YgJ2Z1bmN0aW9uJyAoZS5nLiBOb2RlTGlzdCBpblxuICAvLyBvbGQgdmVyc2lvbnMgb2YgU2FmYXJpKS5cbiAgISghQXJyYXkuaXNBcnJheShvYmopICYmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyB8fCB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAndG9BcnJheTogQXJyYXktbGlrZSBvYmplY3QgZXhwZWN0ZWQnKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgISh0eXBlb2YgbGVuZ3RoID09PSAnbnVtYmVyJykgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAndG9BcnJheTogT2JqZWN0IG5lZWRzIGEgbGVuZ3RoIHByb3BlcnR5JykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICEobGVuZ3RoID09PSAwIHx8IGxlbmd0aCAtIDEgaW4gb2JqKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICd0b0FycmF5OiBPYmplY3Qgc2hvdWxkIGhhdmUga2V5cyBmb3IgaW5kaWNlcycpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAvLyBPbGQgSUUgZG9lc24ndCBnaXZlIGNvbGxlY3Rpb25zIGFjY2VzcyB0byBoYXNPd25Qcm9wZXJ0eS4gQXNzdW1lIGlucHV0c1xuICAvLyB3aXRob3V0IG1ldGhvZCB3aWxsIHRocm93IGR1cmluZyB0aGUgc2xpY2UgY2FsbCBhbmQgc2tpcCBzdHJhaWdodCB0byB0aGVcbiAgLy8gZmFsbGJhY2suXG4gIGlmIChvYmouaGFzT3duUHJvcGVydHkpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG9iaik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gSUUgPCA5IGRvZXMgbm90IHN1cHBvcnQgQXJyYXkjc2xpY2Ugb24gY29sbGVjdGlvbnMgb2JqZWN0c1xuICAgIH1cbiAgfVxuXG4gIC8vIEZhbGwgYmFjayB0byBjb3B5aW5nIGtleSBieSBrZXkuIFRoaXMgYXNzdW1lcyBhbGwga2V5cyBoYXZlIGEgdmFsdWUsXG4gIC8vIHNvIHdpbGwgbm90IHByZXNlcnZlIHNwYXJzZWx5IHBvcHVsYXRlZCBpbnB1dHMuXG4gIHZhciByZXQgPSBBcnJheShsZW5ndGgpO1xuICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgbGVuZ3RoOyBpaSsrKSB7XG4gICAgcmV0W2lpXSA9IG9ialtpaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0FycmF5OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSB3YXJuaW5nXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW1wdHlGdW5jdGlvbiA9IHJlcXVpcmUoJy4vZW1wdHlGdW5jdGlvbicpO1xuXG4vKipcbiAqIFNpbWlsYXIgdG8gaW52YXJpYW50IGJ1dCBvbmx5IGxvZ3MgYSB3YXJuaW5nIGlmIHRoZSBjb25kaXRpb24gaXMgbm90IG1ldC5cbiAqIFRoaXMgY2FuIGJlIHVzZWQgdG8gbG9nIGlzc3VlcyBpbiBkZXZlbG9wbWVudCBlbnZpcm9ubWVudHMgaW4gY3JpdGljYWxcbiAqIHBhdGhzLiBSZW1vdmluZyB0aGUgbG9nZ2luZyBjb2RlIGZvciBwcm9kdWN0aW9uIGVudmlyb25tZW50cyB3aWxsIGtlZXAgdGhlXG4gKiBzYW1lIGxvZ2ljIGFuZCBmb2xsb3cgdGhlIHNhbWUgY29kZSBwYXRocy5cbiAqL1xuXG52YXIgd2FybmluZyA9IGVtcHR5RnVuY3Rpb247XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHdhcm5pbmcgPSBmdW5jdGlvbiAoY29uZGl0aW9uLCBmb3JtYXQpIHtcbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4gPiAyID8gX2xlbiAtIDIgOiAwKSwgX2tleSA9IDI7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleSAtIDJdID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgd2FybmluZyhjb25kaXRpb24sIGZvcm1hdCwgLi4uYXJncylgIHJlcXVpcmVzIGEgd2FybmluZyAnICsgJ21lc3NhZ2UgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBpZiAoZm9ybWF0LmluZGV4T2YoJ0ZhaWxlZCBDb21wb3NpdGUgcHJvcFR5cGU6ICcpID09PSAwKSB7XG4gICAgICByZXR1cm47IC8vIElnbm9yZSBDb21wb3NpdGVDb21wb25lbnQgcHJvcHR5cGUgY2hlY2suXG4gICAgfVxuXG4gICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgIHZhciBhcmdJbmRleCA9IDA7XG4gICAgICB2YXIgbWVzc2FnZSA9ICdXYXJuaW5nOiAnICsgZm9ybWF0LnJlcGxhY2UoLyVzL2csIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGFyZ3NbYXJnSW5kZXgrK107XG4gICAgICB9KTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIC0tLSBXZWxjb21lIHRvIGRlYnVnZ2luZyBSZWFjdCAtLS1cbiAgICAgICAgLy8gVGhpcyBlcnJvciB3YXMgdGhyb3duIGFzIGEgY29udmVuaWVuY2Ugc28gdGhhdCB5b3UgY2FuIHVzZSB0aGlzIHN0YWNrXG4gICAgICAgIC8vIHRvIGZpbmQgdGhlIGNhbGxzaXRlIHRoYXQgY2F1c2VkIHRoaXMgd2FybmluZyB0byBmaXJlLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICB9IGNhdGNoICh4KSB7fVxuICAgIH1cbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3YXJuaW5nOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBVc2UgaW52YXJpYW50KCkgdG8gYXNzZXJ0IHN0YXRlIHdoaWNoIHlvdXIgcHJvZ3JhbSBhc3N1bWVzIHRvIGJlIHRydWUuXG4gKlxuICogUHJvdmlkZSBzcHJpbnRmLXN0eWxlIGZvcm1hdCAob25seSAlcyBpcyBzdXBwb3J0ZWQpIGFuZCBhcmd1bWVudHNcbiAqIHRvIHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgd2hhdCBicm9rZSBhbmQgd2hhdCB5b3Ugd2VyZVxuICogZXhwZWN0aW5nLlxuICpcbiAqIFRoZSBpbnZhcmlhbnQgbWVzc2FnZSB3aWxsIGJlIHN0cmlwcGVkIGluIHByb2R1Y3Rpb24sIGJ1dCB0aGUgaW52YXJpYW50XG4gKiB3aWxsIHJlbWFpbiB0byBlbnN1cmUgbG9naWMgZG9lcyBub3QgZGlmZmVyIGluIHByb2R1Y3Rpb24uXG4gKi9cblxudmFyIGludmFyaWFudCA9IGZ1bmN0aW9uKGNvbmRpdGlvbiwgZm9ybWF0LCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFyaWFudCByZXF1aXJlcyBhbiBlcnJvciBtZXNzYWdlIGFyZ3VtZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFjb25kaXRpb24pIHtcbiAgICB2YXIgZXJyb3I7XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcihcbiAgICAgICAgJ01pbmlmaWVkIGV4Y2VwdGlvbiBvY2N1cnJlZDsgdXNlIHRoZSBub24tbWluaWZpZWQgZGV2IGVudmlyb25tZW50ICcgK1xuICAgICAgICAnZm9yIHRoZSBmdWxsIGVycm9yIG1lc3NhZ2UgYW5kIGFkZGl0aW9uYWwgaGVscGZ1bCB3YXJuaW5ncy4nXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYXJncyA9IFthLCBiLCBjLCBkLCBlLCBmXTtcbiAgICAgIHZhciBhcmdJbmRleCA9IDA7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcihcbiAgICAgICAgZm9ybWF0LnJlcGxhY2UoLyVzL2csIGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJnc1thcmdJbmRleCsrXTsgfSlcbiAgICAgICk7XG4gICAgICBlcnJvci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgIH1cblxuICAgIGVycm9yLmZyYW1lc1RvUG9wID0gMTsgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCBpbnZhcmlhbnQncyBvd24gZnJhbWVcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpbnZhcmlhbnQ7XG4iLCIvKipcbiAqIGxvZGFzaCAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnMgPGh0dHBzOi8vanF1ZXJ5Lm9yZy8+XG4gKiBSZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4zIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKi9cblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuICovXG52YXIgcmVUcmltID0gL15cXHMrfFxccyskL2c7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc0JhZEhleCA9IC9eWy0rXTB4WzAtOWEtZl0rJC9pO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc0JpbmFyeSA9IC9eMGJbMDFdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc09jdGFsID0gL14wb1swLTddKyQvaTtcblxuLyoqIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHdpdGhvdXQgYSBkZXBlbmRlbmN5IG9uIGByb290YC4gKi9cbnZhciBmcmVlUGFyc2VJbnQgPSBwYXJzZUludDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcy4gKi9cbnZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4vKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4LFxuICAgIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IERhdGVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLlxuICovXG52YXIgbm93ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiByb290LkRhdGUubm93KCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gdGhhdCBkZWxheXMgaW52b2tpbmcgYGZ1bmNgIHVudGlsIGFmdGVyIGB3YWl0YFxuICogbWlsbGlzZWNvbmRzIGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gd2FzXG4gKiBpbnZva2VkLiBUaGUgZGVib3VuY2VkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYCBtZXRob2QgdG8gY2FuY2VsXG4gKiBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0byBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS5cbiAqIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgIHNob3VsZCBiZSBpbnZva2VkIG9uIHRoZVxuICogbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudFxuICogY2FsbHMgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2BcbiAqIGludm9jYXRpb24uXG4gKlxuICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAqIGlzIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC5cbiAqXG4gKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAqIHVudGlsIHRvIHRoZSBuZXh0IHRpY2ssIHNpbWlsYXIgdG8gYHNldFRpbWVvdXRgIHdpdGggYSB0aW1lb3V0IG9mIGAwYC5cbiAqXG4gKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAqIGZvciBkZXRhaWxzIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYF8uZGVib3VuY2VgIGFuZCBgXy50aHJvdHRsZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWJvdW5jZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPWZhbHNlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XVxuICogIFRoZSBtYXhpbXVtIHRpbWUgYGZ1bmNgIGlzIGFsbG93ZWQgdG8gYmUgZGVsYXllZCBiZWZvcmUgaXQncyBpbnZva2VkLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBkZWJvdW5jZWQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIEF2b2lkIGNvc3RseSBjYWxjdWxhdGlvbnMgd2hpbGUgdGhlIHdpbmRvdyBzaXplIGlzIGluIGZsdXguXG4gKiBqUXVlcnkod2luZG93KS5vbigncmVzaXplJywgXy5kZWJvdW5jZShjYWxjdWxhdGVMYXlvdXQsIDE1MCkpO1xuICpcbiAqIC8vIEludm9rZSBgc2VuZE1haWxgIHdoZW4gY2xpY2tlZCwgZGVib3VuY2luZyBzdWJzZXF1ZW50IGNhbGxzLlxuICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uZGVib3VuY2Uoc2VuZE1haWwsIDMwMCwge1xuICogICAnbGVhZGluZyc6IHRydWUsXG4gKiAgICd0cmFpbGluZyc6IGZhbHNlXG4gKiB9KSk7XG4gKlxuICogLy8gRW5zdXJlIGBiYXRjaExvZ2AgaXMgaW52b2tlZCBvbmNlIGFmdGVyIDEgc2Vjb25kIG9mIGRlYm91bmNlZCBjYWxscy5cbiAqIHZhciBkZWJvdW5jZWQgPSBfLmRlYm91bmNlKGJhdGNoTG9nLCAyNTAsIHsgJ21heFdhaXQnOiAxMDAwIH0pO1xuICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICogalF1ZXJ5KHNvdXJjZSkub24oJ21lc3NhZ2UnLCBkZWJvdW5jZWQpO1xuICpcbiAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgZGVib3VuY2VkIGludm9jYXRpb24uXG4gKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCBkZWJvdW5jZWQuY2FuY2VsKTtcbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICB2YXIgbGFzdEFyZ3MsXG4gICAgICBsYXN0VGhpcyxcbiAgICAgIG1heFdhaXQsXG4gICAgICByZXN1bHQsXG4gICAgICB0aW1lcklkLFxuICAgICAgbGFzdENhbGxUaW1lLFxuICAgICAgbGFzdEludm9rZVRpbWUgPSAwLFxuICAgICAgbGVhZGluZyA9IGZhbHNlLFxuICAgICAgbWF4aW5nID0gZmFsc2UsXG4gICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgd2FpdCA9IHRvTnVtYmVyKHdhaXQpIHx8IDA7XG4gIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgIGxlYWRpbmcgPSAhIW9wdGlvbnMubGVhZGluZztcbiAgICBtYXhpbmcgPSAnbWF4V2FpdCcgaW4gb3B0aW9ucztcbiAgICBtYXhXYWl0ID0gbWF4aW5nID8gbmF0aXZlTWF4KHRvTnVtYmVyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0O1xuICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gIH1cblxuICBmdW5jdGlvbiBpbnZva2VGdW5jKHRpbWUpIHtcbiAgICB2YXIgYXJncyA9IGxhc3RBcmdzLFxuICAgICAgICB0aGlzQXJnID0gbGFzdFRoaXM7XG5cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBsZWFkaW5nRWRnZSh0aW1lKSB7XG4gICAgLy8gUmVzZXQgYW55IGBtYXhXYWl0YCB0aW1lci5cbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgLy8gU3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgdHJhaWxpbmcgZWRnZS5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIC8vIEludm9rZSB0aGUgbGVhZGluZyBlZGdlLlxuICAgIHJldHVybiBsZWFkaW5nID8gaW52b2tlRnVuYyh0aW1lKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbWFpbmluZ1dhaXQodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsXG4gICAgICAgIHJlc3VsdCA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgIHJldHVybiBtYXhpbmcgPyBuYXRpdmVNaW4ocmVzdWx0LCBtYXhXYWl0IC0gdGltZVNpbmNlTGFzdEludm9rZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBzaG91bGRJbnZva2UodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWU7XG5cbiAgICAvLyBFaXRoZXIgdGhpcyBpcyB0aGUgZmlyc3QgY2FsbCwgYWN0aXZpdHkgaGFzIHN0b3BwZWQgYW5kIHdlJ3JlIGF0IHRoZVxuICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LlxuICAgIHJldHVybiAobGFzdENhbGxUaW1lID09PSB1bmRlZmluZWQgfHwgKHRpbWVTaW5jZUxhc3RDYWxsID49IHdhaXQpIHx8XG4gICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXJFeHBpcmVkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkge1xuICAgICAgcmV0dXJuIHRyYWlsaW5nRWRnZSh0aW1lKTtcbiAgICB9XG4gICAgLy8gUmVzdGFydCB0aGUgdGltZXIuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCByZW1haW5pbmdXYWl0KHRpbWUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWlsaW5nRWRnZSh0aW1lKSB7XG4gICAgdGltZXJJZCA9IHVuZGVmaW5lZDtcblxuICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS5cbiAgICBpZiAodHJhaWxpbmcgJiYgbGFzdEFyZ3MpIHtcbiAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgIH1cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWwoKSB7XG4gICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgIH1cbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDtcbiAgcmV0dXJuIGRlYm91bmNlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAqIFtsYW5ndWFnZSB0eXBlXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcylcbiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3ltYm9sLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3ltYm9sKCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzeW1ib2xUYWcpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBudW1iZXIuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9OdW1iZXIoMy4yKTtcbiAqIC8vID0+IDMuMlxuICpcbiAqIF8udG9OdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiA1ZS0zMjRcbiAqXG4gKiBfLnRvTnVtYmVyKEluZmluaXR5KTtcbiAqIC8vID0+IEluZmluaXR5XG4gKlxuICogXy50b051bWJlcignMy4yJyk7XG4gKiAvLyA9PiAzLjJcbiAqL1xuZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgcmV0dXJuIE5BTjtcbiAgfVxuICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnZhbHVlT2YoKSA6IHZhbHVlO1xuICAgIHZhbHVlID0gaXNPYmplY3Qob3RoZXIpID8gKG90aGVyICsgJycpIDogb3RoZXI7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogK3ZhbHVlO1xuICB9XG4gIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0sICcnKTtcbiAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeS50ZXN0KHZhbHVlKTtcbiAgcmV0dXJuIChpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkpXG4gICAgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpXG4gICAgOiAocmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGVib3VuY2U7XG4iLCIvKipcbiAqIGxvZGFzaCAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnMgPGh0dHBzOi8vanF1ZXJ5Lm9yZy8+XG4gKiBSZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4zIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKi9cblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuICovXG52YXIgcmVUcmltID0gL15cXHMrfFxccyskL2c7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc0JhZEhleCA9IC9eWy0rXTB4WzAtOWEtZl0rJC9pO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc0JpbmFyeSA9IC9eMGJbMDFdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVJc09jdGFsID0gL14wb1swLTddKyQvaTtcblxuLyoqIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHdpdGhvdXQgYSBkZXBlbmRlbmN5IG9uIGByb290YC4gKi9cbnZhciBmcmVlUGFyc2VJbnQgPSBwYXJzZUludDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcy4gKi9cbnZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4vKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4LFxuICAgIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IERhdGVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLlxuICovXG52YXIgbm93ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiByb290LkRhdGUubm93KCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gdGhhdCBkZWxheXMgaW52b2tpbmcgYGZ1bmNgIHVudGlsIGFmdGVyIGB3YWl0YFxuICogbWlsbGlzZWNvbmRzIGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gd2FzXG4gKiBpbnZva2VkLiBUaGUgZGVib3VuY2VkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYCBtZXRob2QgdG8gY2FuY2VsXG4gKiBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0byBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS5cbiAqIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgIHNob3VsZCBiZSBpbnZva2VkIG9uIHRoZVxuICogbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudFxuICogY2FsbHMgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2BcbiAqIGludm9jYXRpb24uXG4gKlxuICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAqIGlzIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC5cbiAqXG4gKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAqIHVudGlsIHRvIHRoZSBuZXh0IHRpY2ssIHNpbWlsYXIgdG8gYHNldFRpbWVvdXRgIHdpdGggYSB0aW1lb3V0IG9mIGAwYC5cbiAqXG4gKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAqIGZvciBkZXRhaWxzIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYF8uZGVib3VuY2VgIGFuZCBgXy50aHJvdHRsZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWJvdW5jZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPWZhbHNlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XVxuICogIFRoZSBtYXhpbXVtIHRpbWUgYGZ1bmNgIGlzIGFsbG93ZWQgdG8gYmUgZGVsYXllZCBiZWZvcmUgaXQncyBpbnZva2VkLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBkZWJvdW5jZWQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIEF2b2lkIGNvc3RseSBjYWxjdWxhdGlvbnMgd2hpbGUgdGhlIHdpbmRvdyBzaXplIGlzIGluIGZsdXguXG4gKiBqUXVlcnkod2luZG93KS5vbigncmVzaXplJywgXy5kZWJvdW5jZShjYWxjdWxhdGVMYXlvdXQsIDE1MCkpO1xuICpcbiAqIC8vIEludm9rZSBgc2VuZE1haWxgIHdoZW4gY2xpY2tlZCwgZGVib3VuY2luZyBzdWJzZXF1ZW50IGNhbGxzLlxuICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uZGVib3VuY2Uoc2VuZE1haWwsIDMwMCwge1xuICogICAnbGVhZGluZyc6IHRydWUsXG4gKiAgICd0cmFpbGluZyc6IGZhbHNlXG4gKiB9KSk7XG4gKlxuICogLy8gRW5zdXJlIGBiYXRjaExvZ2AgaXMgaW52b2tlZCBvbmNlIGFmdGVyIDEgc2Vjb25kIG9mIGRlYm91bmNlZCBjYWxscy5cbiAqIHZhciBkZWJvdW5jZWQgPSBfLmRlYm91bmNlKGJhdGNoTG9nLCAyNTAsIHsgJ21heFdhaXQnOiAxMDAwIH0pO1xuICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICogalF1ZXJ5KHNvdXJjZSkub24oJ21lc3NhZ2UnLCBkZWJvdW5jZWQpO1xuICpcbiAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgZGVib3VuY2VkIGludm9jYXRpb24uXG4gKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCBkZWJvdW5jZWQuY2FuY2VsKTtcbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICB2YXIgbGFzdEFyZ3MsXG4gICAgICBsYXN0VGhpcyxcbiAgICAgIG1heFdhaXQsXG4gICAgICByZXN1bHQsXG4gICAgICB0aW1lcklkLFxuICAgICAgbGFzdENhbGxUaW1lLFxuICAgICAgbGFzdEludm9rZVRpbWUgPSAwLFxuICAgICAgbGVhZGluZyA9IGZhbHNlLFxuICAgICAgbWF4aW5nID0gZmFsc2UsXG4gICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgd2FpdCA9IHRvTnVtYmVyKHdhaXQpIHx8IDA7XG4gIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgIGxlYWRpbmcgPSAhIW9wdGlvbnMubGVhZGluZztcbiAgICBtYXhpbmcgPSAnbWF4V2FpdCcgaW4gb3B0aW9ucztcbiAgICBtYXhXYWl0ID0gbWF4aW5nID8gbmF0aXZlTWF4KHRvTnVtYmVyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0O1xuICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gIH1cblxuICBmdW5jdGlvbiBpbnZva2VGdW5jKHRpbWUpIHtcbiAgICB2YXIgYXJncyA9IGxhc3RBcmdzLFxuICAgICAgICB0aGlzQXJnID0gbGFzdFRoaXM7XG5cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBsZWFkaW5nRWRnZSh0aW1lKSB7XG4gICAgLy8gUmVzZXQgYW55IGBtYXhXYWl0YCB0aW1lci5cbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgLy8gU3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgdHJhaWxpbmcgZWRnZS5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIC8vIEludm9rZSB0aGUgbGVhZGluZyBlZGdlLlxuICAgIHJldHVybiBsZWFkaW5nID8gaW52b2tlRnVuYyh0aW1lKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbWFpbmluZ1dhaXQodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsXG4gICAgICAgIHJlc3VsdCA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgIHJldHVybiBtYXhpbmcgPyBuYXRpdmVNaW4ocmVzdWx0LCBtYXhXYWl0IC0gdGltZVNpbmNlTGFzdEludm9rZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBzaG91bGRJbnZva2UodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWU7XG5cbiAgICAvLyBFaXRoZXIgdGhpcyBpcyB0aGUgZmlyc3QgY2FsbCwgYWN0aXZpdHkgaGFzIHN0b3BwZWQgYW5kIHdlJ3JlIGF0IHRoZVxuICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LlxuICAgIHJldHVybiAobGFzdENhbGxUaW1lID09PSB1bmRlZmluZWQgfHwgKHRpbWVTaW5jZUxhc3RDYWxsID49IHdhaXQpIHx8XG4gICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXJFeHBpcmVkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkge1xuICAgICAgcmV0dXJuIHRyYWlsaW5nRWRnZSh0aW1lKTtcbiAgICB9XG4gICAgLy8gUmVzdGFydCB0aGUgdGltZXIuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCByZW1haW5pbmdXYWl0KHRpbWUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWlsaW5nRWRnZSh0aW1lKSB7XG4gICAgdGltZXJJZCA9IHVuZGVmaW5lZDtcblxuICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS5cbiAgICBpZiAodHJhaWxpbmcgJiYgbGFzdEFyZ3MpIHtcbiAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgIH1cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWwoKSB7XG4gICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgIH1cbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDtcbiAgcmV0dXJuIGRlYm91bmNlZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gKiBldmVyeSBgd2FpdGAgbWlsbGlzZWNvbmRzLiBUaGUgdGhyb3R0bGVkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYFxuICogbWV0aG9kIHRvIGNhbmNlbCBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0b1xuICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gKiBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgXG4gKiB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWQgd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlXG4gKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gKiByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgIGludm9jYXRpb24uXG4gKlxuICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb25cbiAqIGlzIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC5cbiAqXG4gKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAqIHVudGlsIHRvIHRoZSBuZXh0IHRpY2ssIHNpbWlsYXIgdG8gYHNldFRpbWVvdXRgIHdpdGggYSB0aW1lb3V0IG9mIGAwYC5cbiAqXG4gKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAqIGZvciBkZXRhaWxzIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYF8udGhyb3R0bGVgIGFuZCBgXy5kZWJvdW5jZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB0aHJvdHRsZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuXG4gKiBqUXVlcnkod2luZG93KS5vbignc2Nyb2xsJywgXy50aHJvdHRsZSh1cGRhdGVQb3NpdGlvbiwgMTAwKSk7XG4gKlxuICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gKiB2YXIgdGhyb3R0bGVkID0gXy50aHJvdHRsZShyZW5ld1Rva2VuLCAzMDAwMDAsIHsgJ3RyYWlsaW5nJzogZmFsc2UgfSk7XG4gKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgdGhyb3R0bGVkKTtcbiAqXG4gKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIHRocm90dGxlZCBpbnZvY2F0aW9uLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgdGhyb3R0bGVkLmNhbmNlbCk7XG4gKi9cbmZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgdmFyIGxlYWRpbmcgPSB0cnVlLFxuICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgIGxlYWRpbmcgPSAnbGVhZGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy5sZWFkaW5nIDogbGVhZGluZztcbiAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICB9XG4gIHJldHVybiBkZWJvdW5jZShmdW5jLCB3YWl0LCB7XG4gICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICdtYXhXYWl0Jzogd2FpdCxcbiAgICAndHJhaWxpbmcnOiB0cmFpbGluZ1xuICB9KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAqIFtsYW5ndWFnZSB0eXBlXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcylcbiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3ltYm9sLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3ltYm9sKCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzeW1ib2xUYWcpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBudW1iZXIuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9OdW1iZXIoMy4yKTtcbiAqIC8vID0+IDMuMlxuICpcbiAqIF8udG9OdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiA1ZS0zMjRcbiAqXG4gKiBfLnRvTnVtYmVyKEluZmluaXR5KTtcbiAqIC8vID0+IEluZmluaXR5XG4gKlxuICogXy50b051bWJlcignMy4yJyk7XG4gKiAvLyA9PiAzLjJcbiAqL1xuZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgcmV0dXJuIE5BTjtcbiAgfVxuICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnZhbHVlT2YoKSA6IHZhbHVlO1xuICAgIHZhbHVlID0gaXNPYmplY3Qob3RoZXIpID8gKG90aGVyICsgJycpIDogb3RoZXI7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogK3ZhbHVlO1xuICB9XG4gIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0sICcnKTtcbiAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeS50ZXN0KHZhbHVlKTtcbiAgcmV0dXJuIChpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkpXG4gICAgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpXG4gICAgOiAocmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdGhyb3R0bGU7XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBsb2Rhc2ggMy4xMC4xIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIC1kIC1vIC4vaW5kZXguanNgXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE1IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTUgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cbjsoZnVuY3Rpb24oKSB7XG5cbiAgLyoqIFVzZWQgYXMgYSBzYWZlIHJlZmVyZW5jZSBmb3IgYHVuZGVmaW5lZGAgaW4gcHJlLUVTNSBlbnZpcm9ubWVudHMuICovXG4gIHZhciB1bmRlZmluZWQ7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLiAqL1xuICB2YXIgVkVSU0lPTiA9ICczLjEwLjEnO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG4gIHZhciBCSU5EX0ZMQUcgPSAxLFxuICAgICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICAgIENVUlJZX0ZMQUcgPSA4LFxuICAgICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgICBQQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NCxcbiAgICAgIEFSWV9GTEFHID0gMTI4LFxuICAgICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuICAvKiogVXNlZCBhcyBkZWZhdWx0IG9wdGlvbnMgZm9yIGBfLnRydW5jYC4gKi9cbiAgdmFyIERFRkFVTFRfVFJVTkNfTEVOR1RIID0gMzAsXG4gICAgICBERUZBVUxUX1RSVU5DX09NSVNTSU9OID0gJy4uLic7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IHdoZW4gYSBmdW5jdGlvbiBiZWNvbWVzIGhvdC4gKi9cbiAgdmFyIEhPVF9DT1VOVCA9IDE1MCxcbiAgICAgIEhPVF9TUEFOID0gMTY7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIHNpemUgdG8gZW5hYmxlIGxhcmdlIGFycmF5IG9wdGltaXphdGlvbnMuICovXG4gIHZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4gIC8qKiBVc2VkIHRvIGluZGljYXRlIHRoZSB0eXBlIG9mIGxhenkgaXRlcmF0ZWVzLiAqL1xuICB2YXIgTEFaWV9GSUxURVJfRkxBRyA9IDEsXG4gICAgICBMQVpZX01BUF9GTEFHID0gMjtcblxuICAvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xuICB2YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbiAgdmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4gIC8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG4gIHZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggZW1wdHkgc3RyaW5nIGxpdGVyYWxzIGluIGNvbXBpbGVkIHRlbXBsYXRlIHNvdXJjZS4gKi9cbiAgdmFyIHJlRW1wdHlTdHJpbmdMZWFkaW5nID0gL1xcYl9fcCBcXCs9ICcnOy9nLFxuICAgICAgcmVFbXB0eVN0cmluZ01pZGRsZSA9IC9cXGIoX19wIFxcKz0pICcnIFxcKy9nLFxuICAgICAgcmVFbXB0eVN0cmluZ1RyYWlsaW5nID0gLyhfX2VcXCguKj9cXCl8XFxiX190XFwpKSBcXCtcXG4nJzsvZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBIVE1MIGVudGl0aWVzIGFuZCBIVE1MIGNoYXJhY3RlcnMuICovXG4gIHZhciByZUVzY2FwZWRIdG1sID0gLyYoPzphbXB8bHR8Z3R8cXVvdHwjMzl8Izk2KTsvZyxcbiAgICAgIHJlVW5lc2NhcGVkSHRtbCA9IC9bJjw+XCInYF0vZyxcbiAgICAgIHJlSGFzRXNjYXBlZEh0bWwgPSBSZWdFeHAocmVFc2NhcGVkSHRtbC5zb3VyY2UpLFxuICAgICAgcmVIYXNVbmVzY2FwZWRIdG1sID0gUmVnRXhwKHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZUVzY2FwZSA9IC88JS0oW1xcc1xcU10rPyklPi9nLFxuICAgICAgcmVFdmFsdWF0ZSA9IC88JShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUludGVycG9sYXRlID0gLzwlPShbXFxzXFxTXSs/KSU+L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xuICB2YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxuXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICAgIHJlSXNQbGFpblByb3AgPSAvXlxcdyokLyxcbiAgICAgIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIFtzeW50YXggY2hhcmFjdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcGF0dGVybnMpXG4gICAqIGFuZCB0aG9zZSBvdXRsaW5lZCBieSBbYEVzY2FwZVJlZ0V4cFBhdHRlcm5gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1lc2NhcGVyZWdleHBwYXR0ZXJuKS5cbiAgICovXG4gIHZhciByZVJlZ0V4cENoYXJzID0gL15bOiEsXXxbXFxcXF4kLiorPygpW1xcXXt9fFxcL118KF5bMC05YS1mQS1GbnJ0dXZ4XSl8KFtcXG5cXHJcXHUyMDI4XFx1MjAyOV0pL2csXG4gICAgICByZUhhc1JlZ0V4cENoYXJzID0gUmVnRXhwKHJlUmVnRXhwQ2hhcnMuc291cmNlKTtcblxuICAvKiogVXNlZCB0byBtYXRjaCBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpLiAqL1xuICB2YXIgcmVDb21ib01hcmsgPSAvW1xcdTAzMDAtXFx1MDM2ZlxcdWZlMjAtXFx1ZmUyM10vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbiAgdmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIFtFUyB0ZW1wbGF0ZSBkZWxpbWl0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10ZW1wbGF0ZS1saXRlcmFsLWxleGljYWwtY29tcG9uZW50cykuICovXG4gIHZhciByZUVzVGVtcGxhdGUgPSAvXFwkXFx7KFteXFxcXH1dKig/OlxcXFwuW15cXFxcfV0qKSopXFx9L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgZmxhZ3MgZnJvbSB0aGVpciBjb2VyY2VkIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUZsYWdzID0gL1xcdyokLztcblxuICAvKiogVXNlZCB0byBkZXRlY3QgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlSGFzSGV4UHJlZml4ID0gL14wW3hYXS87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkgPiA1KS4gKi9cbiAgdmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xuICB2YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBsYXRpbi0xIHN1cHBsZW1lbnRhcnkgbGV0dGVycyAoZXhjbHVkaW5nIG1hdGhlbWF0aWNhbCBvcGVyYXRvcnMpLiAqL1xuICB2YXIgcmVMYXRpbjEgPSAvW1xceGMwLVxceGQ2XFx4ZDgtXFx4ZGVcXHhkZi1cXHhmNlxceGY4LVxceGZmXS9nO1xuXG4gIC8qKiBVc2VkIHRvIGVuc3VyZSBjYXB0dXJpbmcgb3JkZXIgb2YgdGVtcGxhdGUgZGVsaW1pdGVycy4gKi9cbiAgdmFyIHJlTm9NYXRjaCA9IC8oJF4pLztcblxuICAvKiogVXNlZCB0byBtYXRjaCB1bmVzY2FwZWQgY2hhcmFjdGVycyBpbiBjb21waWxlZCBzdHJpbmcgbGl0ZXJhbHMuICovXG4gIHZhciByZVVuZXNjYXBlZFN0cmluZyA9IC9bJ1xcblxcclxcdTIwMjhcXHUyMDI5XFxcXF0vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCB3b3JkcyB0byBjcmVhdGUgY29tcG91bmQgd29yZHMuICovXG4gIHZhciByZVdvcmRzID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciB1cHBlciA9ICdbQS1aXFxcXHhjMC1cXFxceGQ2XFxcXHhkOC1cXFxceGRlXScsXG4gICAgICAgIGxvd2VyID0gJ1thLXpcXFxceGRmLVxcXFx4ZjZcXFxceGY4LVxcXFx4ZmZdKyc7XG5cbiAgICByZXR1cm4gUmVnRXhwKHVwcGVyICsgJysoPz0nICsgdXBwZXIgKyBsb3dlciArICcpfCcgKyB1cHBlciArICc/JyArIGxvd2VyICsgJ3wnICsgdXBwZXIgKyAnK3xbMC05XSsnLCAnZycpO1xuICB9KCkpO1xuXG4gIC8qKiBVc2VkIHRvIGFzc2lnbiBkZWZhdWx0IGBjb250ZXh0YCBvYmplY3QgcHJvcGVydGllcy4gKi9cbiAgdmFyIGNvbnRleHRQcm9wcyA9IFtcbiAgICAnQXJyYXknLCAnQXJyYXlCdWZmZXInLCAnRGF0ZScsICdFcnJvcicsICdGbG9hdDMyQXJyYXknLCAnRmxvYXQ2NEFycmF5JyxcbiAgICAnRnVuY3Rpb24nLCAnSW50OEFycmF5JywgJ0ludDE2QXJyYXknLCAnSW50MzJBcnJheScsICdNYXRoJywgJ051bWJlcicsXG4gICAgJ09iamVjdCcsICdSZWdFeHAnLCAnU2V0JywgJ1N0cmluZycsICdfJywgJ2NsZWFyVGltZW91dCcsICdpc0Zpbml0ZScsXG4gICAgJ3BhcnNlRmxvYXQnLCAncGFyc2VJbnQnLCAnc2V0VGltZW91dCcsICdUeXBlRXJyb3InLCAnVWludDhBcnJheScsXG4gICAgJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ1VpbnQxNkFycmF5JywgJ1VpbnQzMkFycmF5JywgJ1dlYWtNYXAnXG4gIF07XG5cbiAgLyoqIFVzZWQgdG8gbWFrZSB0ZW1wbGF0ZSBzb3VyY2VVUkxzIGVhc2llciB0byBpZGVudGlmeS4gKi9cbiAgdmFyIHRlbXBsYXRlQ291bnRlciA9IC0xO1xuXG4gIC8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIG9mIHR5cGVkIGFycmF5cy4gKi9cbiAgdmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG4gIHR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tpbnQ4VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDE2VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG4gIHR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tkYXRlVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Vycm9yVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tvYmplY3RUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3NldFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuICAvKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBzdXBwb3J0ZWQgYnkgYF8uY2xvbmVgLiAqL1xuICB2YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuICBjbG9uZWFibGVUYWdzW2FyZ3NUYWddID0gY2xvbmVhYmxlVGFnc1thcnJheVRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2FycmF5QnVmZmVyVGFnXSA9IGNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDhUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbdWludDhUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50OENsYW1wZWRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbiAgY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbiAgY2xvbmVhYmxlVGFnc1ttYXBUYWddID0gY2xvbmVhYmxlVGFnc1tzZXRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBsYXRpbi0xIHN1cHBsZW1lbnRhcnkgbGV0dGVycyB0byBiYXNpYyBsYXRpbiBsZXR0ZXJzLiAqL1xuICB2YXIgZGVidXJyZWRMZXR0ZXJzID0ge1xuICAgICdcXHhjMCc6ICdBJywgICdcXHhjMSc6ICdBJywgJ1xceGMyJzogJ0EnLCAnXFx4YzMnOiAnQScsICdcXHhjNCc6ICdBJywgJ1xceGM1JzogJ0EnLFxuICAgICdcXHhlMCc6ICdhJywgICdcXHhlMSc6ICdhJywgJ1xceGUyJzogJ2EnLCAnXFx4ZTMnOiAnYScsICdcXHhlNCc6ICdhJywgJ1xceGU1JzogJ2EnLFxuICAgICdcXHhjNyc6ICdDJywgICdcXHhlNyc6ICdjJyxcbiAgICAnXFx4ZDAnOiAnRCcsICAnXFx4ZjAnOiAnZCcsXG4gICAgJ1xceGM4JzogJ0UnLCAgJ1xceGM5JzogJ0UnLCAnXFx4Y2EnOiAnRScsICdcXHhjYic6ICdFJyxcbiAgICAnXFx4ZTgnOiAnZScsICAnXFx4ZTknOiAnZScsICdcXHhlYSc6ICdlJywgJ1xceGViJzogJ2UnLFxuICAgICdcXHhjQyc6ICdJJywgICdcXHhjZCc6ICdJJywgJ1xceGNlJzogJ0knLCAnXFx4Y2YnOiAnSScsXG4gICAgJ1xceGVDJzogJ2knLCAgJ1xceGVkJzogJ2knLCAnXFx4ZWUnOiAnaScsICdcXHhlZic6ICdpJyxcbiAgICAnXFx4ZDEnOiAnTicsICAnXFx4ZjEnOiAnbicsXG4gICAgJ1xceGQyJzogJ08nLCAgJ1xceGQzJzogJ08nLCAnXFx4ZDQnOiAnTycsICdcXHhkNSc6ICdPJywgJ1xceGQ2JzogJ08nLCAnXFx4ZDgnOiAnTycsXG4gICAgJ1xceGYyJzogJ28nLCAgJ1xceGYzJzogJ28nLCAnXFx4ZjQnOiAnbycsICdcXHhmNSc6ICdvJywgJ1xceGY2JzogJ28nLCAnXFx4ZjgnOiAnbycsXG4gICAgJ1xceGQ5JzogJ1UnLCAgJ1xceGRhJzogJ1UnLCAnXFx4ZGInOiAnVScsICdcXHhkYyc6ICdVJyxcbiAgICAnXFx4ZjknOiAndScsICAnXFx4ZmEnOiAndScsICdcXHhmYic6ICd1JywgJ1xceGZjJzogJ3UnLFxuICAgICdcXHhkZCc6ICdZJywgICdcXHhmZCc6ICd5JywgJ1xceGZmJzogJ3knLFxuICAgICdcXHhjNic6ICdBZScsICdcXHhlNic6ICdhZScsXG4gICAgJ1xceGRlJzogJ1RoJywgJ1xceGZlJzogJ3RoJyxcbiAgICAnXFx4ZGYnOiAnc3MnXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gbWFwIGNoYXJhY3RlcnMgdG8gSFRNTCBlbnRpdGllcy4gKi9cbiAgdmFyIGh0bWxFc2NhcGVzID0ge1xuICAgICcmJzogJyZhbXA7JyxcbiAgICAnPCc6ICcmbHQ7JyxcbiAgICAnPic6ICcmZ3Q7JyxcbiAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICBcIidcIjogJyYjMzk7JyxcbiAgICAnYCc6ICcmIzk2OydcbiAgfTtcblxuICAvKiogVXNlZCB0byBtYXAgSFRNTCBlbnRpdGllcyB0byBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgaHRtbFVuZXNjYXBlcyA9IHtcbiAgICAnJmFtcDsnOiAnJicsXG4gICAgJyZsdDsnOiAnPCcsXG4gICAgJyZndDsnOiAnPicsXG4gICAgJyZxdW90Oyc6ICdcIicsXG4gICAgJyYjMzk7JzogXCInXCIsXG4gICAgJyYjOTY7JzogJ2AnXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG4gIHZhciBvYmplY3RUeXBlcyA9IHtcbiAgICAnZnVuY3Rpb24nOiB0cnVlLFxuICAgICdvYmplY3QnOiB0cnVlXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGluY2x1c2lvbiBpbiBjb21waWxlZCByZWdleGVzLiAqL1xuICB2YXIgcmVnZXhwRXNjYXBlcyA9IHtcbiAgICAnMCc6ICd4MzAnLCAnMSc6ICd4MzEnLCAnMic6ICd4MzInLCAnMyc6ICd4MzMnLCAnNCc6ICd4MzQnLFxuICAgICc1JzogJ3gzNScsICc2JzogJ3gzNicsICc3JzogJ3gzNycsICc4JzogJ3gzOCcsICc5JzogJ3gzOScsXG4gICAgJ0EnOiAneDQxJywgJ0InOiAneDQyJywgJ0MnOiAneDQzJywgJ0QnOiAneDQ0JywgJ0UnOiAneDQ1JywgJ0YnOiAneDQ2JyxcbiAgICAnYSc6ICd4NjEnLCAnYic6ICd4NjInLCAnYyc6ICd4NjMnLCAnZCc6ICd4NjQnLCAnZSc6ICd4NjUnLCAnZic6ICd4NjYnLFxuICAgICduJzogJ3g2ZScsICdyJzogJ3g3MicsICd0JzogJ3g3NCcsICd1JzogJ3g3NScsICd2JzogJ3g3NicsICd4JzogJ3g3OCdcbiAgfTtcblxuICAvKiogVXNlZCB0byBlc2NhcGUgY2hhcmFjdGVycyBmb3IgaW5jbHVzaW9uIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy4gKi9cbiAgdmFyIHN0cmluZ0VzY2FwZXMgPSB7XG4gICAgJ1xcXFwnOiAnXFxcXCcsXG4gICAgXCInXCI6IFwiJ1wiLFxuICAgICdcXG4nOiAnbicsXG4gICAgJ1xccic6ICdyJyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbiAgdmFyIGZyZWVFeHBvcnRzID0gb2JqZWN0VHlwZXNbdHlwZW9mIGV4cG9ydHNdICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG4gIHZhciBmcmVlTW9kdWxlID0gb2JqZWN0VHlwZXNbdHlwZW9mIG1vZHVsZV0gJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG4gIHZhciBmcmVlR2xvYmFsID0gZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSAmJiB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCAmJiBnbG9iYWwuT2JqZWN0ICYmIGdsb2JhbDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xuICB2YXIgZnJlZVNlbGYgPSBvYmplY3RUeXBlc1t0eXBlb2Ygc2VsZl0gJiYgc2VsZiAmJiBzZWxmLk9iamVjdCAmJiBzZWxmO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgd2luZG93YC4gKi9cbiAgdmFyIGZyZWVXaW5kb3cgPSBvYmplY3RUeXBlc1t0eXBlb2Ygd2luZG93XSAmJiB3aW5kb3cgJiYgd2luZG93Lk9iamVjdCAmJiB3aW5kb3c7XG5cbiAgLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbiAgdmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHMgJiYgZnJlZUV4cG9ydHM7XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAqXG4gICAqIFRoZSBgdGhpc2AgdmFsdWUgaXMgdXNlZCBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0IHRvIGF2b2lkIEdyZWFzZW1vbmtleSdzXG4gICAqIHJlc3RyaWN0ZWQgYHdpbmRvd2Agb2JqZWN0LCBvdGhlcndpc2UgdGhlIGB3aW5kb3dgIG9iamVjdCBpcyB1c2VkLlxuICAgKi9cbiAgdmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8ICgoZnJlZVdpbmRvdyAhPT0gKHRoaXMgJiYgdGhpcy53aW5kb3cpKSAmJiBmcmVlV2luZG93KSB8fCBmcmVlU2VsZiB8fCB0aGlzO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgY29tcGFyZUFzY2VuZGluZ2Agd2hpY2ggY29tcGFyZXMgdmFsdWVzIGFuZFxuICAgKiBzb3J0cyB0aGVtIGluIGFzY2VuZGluZyBvcmRlciB3aXRob3V0IGd1YXJhbnRlZWluZyBhIHN0YWJsZSBzb3J0LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzb3J0IG9yZGVyIGluZGljYXRvciBmb3IgYHZhbHVlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VDb21wYXJlQXNjZW5kaW5nKHZhbHVlLCBvdGhlcikge1xuICAgIGlmICh2YWx1ZSAhPT0gb3RoZXIpIHtcbiAgICAgIHZhciB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICB2YWxJc1VuZGVmID0gdmFsdWUgPT09IHVuZGVmaW5lZCxcbiAgICAgICAgICB2YWxJc1JlZmxleGl2ZSA9IHZhbHVlID09PSB2YWx1ZTtcblxuICAgICAgdmFyIG90aElzTnVsbCA9IG90aGVyID09PSBudWxsLFxuICAgICAgICAgIG90aElzVW5kZWYgPSBvdGhlciA9PT0gdW5kZWZpbmVkLFxuICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gb3RoZXIgPT09IG90aGVyO1xuXG4gICAgICBpZiAoKHZhbHVlID4gb3RoZXIgJiYgIW90aElzTnVsbCkgfHwgIXZhbElzUmVmbGV4aXZlIHx8XG4gICAgICAgICAgKHZhbElzTnVsbCAmJiAhb3RoSXNVbmRlZiAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAodmFsSXNVbmRlZiAmJiBvdGhJc1JlZmxleGl2ZSkpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgICBpZiAoKHZhbHVlIDwgb3RoZXIgJiYgIXZhbElzTnVsbCkgfHwgIW90aElzUmVmbGV4aXZlIHx8XG4gICAgICAgICAgKG90aElzTnVsbCAmJiAhdmFsSXNVbmRlZiAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAob3RoSXNVbmRlZiAmJiB2YWxJc1JlZmxleGl2ZSkpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kSW5kZXhgIGFuZCBgXy5maW5kTGFzdEluZGV4YCB3aXRob3V0XG4gICAqIHN1cHBvcnQgZm9yIGNhbGxiYWNrIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21SaWdodCkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXhPZk5hTihhcnJheSwgZnJvbUluZGV4KTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRnVuY3Rpb25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgZW52aXJvbm1lbnRzXG4gICAqIHdpdGggaW5jb3JyZWN0IGB0eXBlb2ZgIHJlc3VsdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUlzRnVuY3Rpb24odmFsdWUpIHtcbiAgICAvLyBBdm9pZCBhIENoYWtyYSBKSVQgYnVnIGluIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgMTEuXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qYXNoa2VuYXMvdW5kZXJzY29yZS9pc3N1ZXMvMTYyMSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJyB8fCBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGlmIGl0J3Mgbm90IG9uZS4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkXG4gICAqIGZvciBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlVG9TdHJpbmcodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1MZWZ0YCB0byBnZXQgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXJcbiAgICogb2YgYHN0cmluZ2AgdGhhdCBpcyBub3QgZm91bmQgaW4gYGNoYXJzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFycyBUaGUgY2hhcmFjdGVycyB0byBmaW5kLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG5vdCBmb3VuZCBpbiBgY2hhcnNgLlxuICAgKi9cbiAgZnVuY3Rpb24gY2hhcnNMZWZ0SW5kZXgoc3RyaW5nLCBjaGFycykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgY2hhcnMuaW5kZXhPZihzdHJpbmcuY2hhckF0KGluZGV4KSkgPiAtMSkge31cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy50cmltYCBhbmQgYF8udHJpbVJpZ2h0YCB0byBnZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlclxuICAgKiBvZiBgc3RyaW5nYCB0aGF0IGlzIG5vdCBmb3VuZCBpbiBgY2hhcnNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNoYXJzIFRoZSBjaGFyYWN0ZXJzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGNoYXJhY3RlciBub3QgZm91bmQgaW4gYGNoYXJzYC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzUmlnaHRJbmRleChzdHJpbmcsIGNoYXJzKSB7XG4gICAgdmFyIGluZGV4ID0gc3RyaW5nLmxlbmd0aDtcblxuICAgIHdoaWxlIChpbmRleC0tICYmIGNoYXJzLmluZGV4T2Yoc3RyaW5nLmNoYXJBdChpbmRleCkpID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8uc29ydEJ5YCB0byBjb21wYXJlIHRyYW5zZm9ybWVkIGVsZW1lbnRzIG9mIGEgY29sbGVjdGlvbiBhbmQgc3RhYmxlXG4gICAqIHNvcnQgdGhlbSBpbiBhc2NlbmRpbmcgb3JkZXIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzb3J0IG9yZGVyIGluZGljYXRvciBmb3IgYG9iamVjdGAuXG4gICAqL1xuICBmdW5jdGlvbiBjb21wYXJlQXNjZW5kaW5nKG9iamVjdCwgb3RoZXIpIHtcbiAgICByZXR1cm4gYmFzZUNvbXBhcmVBc2NlbmRpbmcob2JqZWN0LmNyaXRlcmlhLCBvdGhlci5jcml0ZXJpYSkgfHwgKG9iamVjdC5pbmRleCAtIG90aGVyLmluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnNvcnRCeU9yZGVyYCB0byBjb21wYXJlIG11bHRpcGxlIHByb3BlcnRpZXMgb2YgYSB2YWx1ZSB0byBhbm90aGVyXG4gICAqIGFuZCBzdGFibGUgc29ydCB0aGVtLlxuICAgKlxuICAgKiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlc3MgYXJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIuIE90aGVyd2lzZSxcbiAgICogYSB2YWx1ZSBpcyBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIGlmIGl0cyBjb3JyZXNwb25kaW5nIG9yZGVyIGlzIFwiYXNjXCIsIGFuZFxuICAgKiBkZXNjZW5kaW5nIGlmIFwiZGVzY1wiLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICogQHBhcmFtIHtib29sZWFuW119IG9yZGVycyBUaGUgb3JkZXIgdG8gc29ydCBieSBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGBvYmplY3RgLlxuICAgKi9cbiAgZnVuY3Rpb24gY29tcGFyZU11bHRpcGxlKG9iamVjdCwgb3RoZXIsIG9yZGVycykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBvYmpDcml0ZXJpYSA9IG9iamVjdC5jcml0ZXJpYSxcbiAgICAgICAgb3RoQ3JpdGVyaWEgPSBvdGhlci5jcml0ZXJpYSxcbiAgICAgICAgbGVuZ3RoID0gb2JqQ3JpdGVyaWEubGVuZ3RoLFxuICAgICAgICBvcmRlcnNMZW5ndGggPSBvcmRlcnMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBiYXNlQ29tcGFyZUFzY2VuZGluZyhvYmpDcml0ZXJpYVtpbmRleF0sIG90aENyaXRlcmlhW2luZGV4XSk7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGlmIChpbmRleCA+PSBvcmRlcnNMZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvcmRlciA9IG9yZGVyc1tpbmRleF07XG4gICAgICAgIHJldHVybiByZXN1bHQgKiAoKG9yZGVyID09PSAnYXNjJyB8fCBvcmRlciA9PT0gdHJ1ZSkgPyAxIDogLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBGaXhlcyBhbiBgQXJyYXkjc29ydGAgYnVnIGluIHRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgYXBwbGljYXRpb25zXG4gICAgLy8gdGhhdCBjYXVzZXMgaXQsIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgdG8gcHJvdmlkZSB0aGUgc2FtZSB2YWx1ZSBmb3JcbiAgICAvLyBgb2JqZWN0YCBhbmQgYG90aGVyYC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qYXNoa2VuYXMvdW5kZXJzY29yZS9wdWxsLzEyNDdcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIC8vXG4gICAgLy8gVGhpcyBhbHNvIGVuc3VyZXMgYSBzdGFibGUgc29ydCBpbiBWOCBhbmQgb3RoZXIgZW5naW5lcy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTkwIGZvciBtb3JlIGRldGFpbHMuXG4gICAgcmV0dXJuIG9iamVjdC5pbmRleCAtIG90aGVyLmluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8uZGVidXJyYCB0byBjb252ZXJ0IGxhdGluLTEgc3VwcGxlbWVudGFyeSBsZXR0ZXJzIHRvIGJhc2ljIGxhdGluIGxldHRlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsZXR0ZXIgVGhlIG1hdGNoZWQgbGV0dGVyIHRvIGRlYnVyci5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZGVidXJyZWQgbGV0dGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gZGVidXJyTGV0dGVyKGxldHRlcikge1xuICAgIHJldHVybiBkZWJ1cnJlZExldHRlcnNbbGV0dGVyXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmVzY2FwZWAgdG8gY29udmVydCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIGVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICBmdW5jdGlvbiBlc2NhcGVIdG1sQ2hhcihjaHIpIHtcbiAgICByZXR1cm4gaHRtbEVzY2FwZXNbY2hyXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmVzY2FwZVJlZ0V4cGAgdG8gZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGluY2x1c2lvbiBpbiBjb21waWxlZCByZWdleGVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsZWFkaW5nQ2hhciBUaGUgY2FwdHVyZSBncm91cCBmb3IgYSBsZWFkaW5nIGNoYXJhY3Rlci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHdoaXRlc3BhY2VDaGFyIFRoZSBjYXB0dXJlIGdyb3VwIGZvciBhIHdoaXRlc3BhY2UgY2hhcmFjdGVyLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICovXG4gIGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cENoYXIoY2hyLCBsZWFkaW5nQ2hhciwgd2hpdGVzcGFjZUNoYXIpIHtcbiAgICBpZiAobGVhZGluZ0NoYXIpIHtcbiAgICAgIGNociA9IHJlZ2V4cEVzY2FwZXNbY2hyXTtcbiAgICB9IGVsc2UgaWYgKHdoaXRlc3BhY2VDaGFyKSB7XG4gICAgICBjaHIgPSBzdHJpbmdFc2NhcGVzW2Nocl07XG4gICAgfVxuICAgIHJldHVybiAnXFxcXCcgKyBjaHI7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy50ZW1wbGF0ZWAgdG8gZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGluY2x1c2lvbiBpbiBjb21waWxlZCBzdHJpbmcgbGl0ZXJhbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIGVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICBmdW5jdGlvbiBlc2NhcGVTdHJpbmdDaGFyKGNocikge1xuICAgIHJldHVybiAnXFxcXCcgKyBzdHJpbmdFc2NhcGVzW2Nocl07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gaW5kZXhPZk5hTihhcnJheSwgZnJvbUluZGV4LCBmcm9tUmlnaHQpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAwIDogLTEpO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmIChvdGhlciAhPT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gICAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYHRyaW1tZWRMZWZ0SW5kZXhgIGFuZCBgdHJpbW1lZFJpZ2h0SW5kZXhgIHRvIGRldGVybWluZSBpZiBhXG4gICAqIGNoYXJhY3RlciBjb2RlIGlzIHdoaXRlc3BhY2UuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjaGFyQ29kZSBUaGUgY2hhcmFjdGVyIGNvZGUgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBjaGFyQ29kZWAgaXMgd2hpdGVzcGFjZSwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaXNTcGFjZShjaGFyQ29kZSkge1xuICAgIHJldHVybiAoKGNoYXJDb2RlIDw9IDE2MCAmJiAoY2hhckNvZGUgPj0gOSAmJiBjaGFyQ29kZSA8PSAxMykgfHwgY2hhckNvZGUgPT0gMzIgfHwgY2hhckNvZGUgPT0gMTYwKSB8fCBjaGFyQ29kZSA9PSA1NzYwIHx8IGNoYXJDb2RlID09IDYxNTggfHxcbiAgICAgIChjaGFyQ29kZSA+PSA4MTkyICYmIChjaGFyQ29kZSA8PSA4MjAyIHx8IGNoYXJDb2RlID09IDgyMzIgfHwgY2hhckNvZGUgPT0gODIzMyB8fCBjaGFyQ29kZSA9PSA4MjM5IHx8IGNoYXJDb2RlID09IDgyODcgfHwgY2hhckNvZGUgPT0gMTIyODggfHwgY2hhckNvZGUgPT0gNjUyNzkpKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoYXJyYXlbaW5kZXhdID09PSBwbGFjZWhvbGRlcikge1xuICAgICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgICAgcmVzdWx0WysrcmVzSW5kZXhdID0gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQW4gaW1wbGVtZW50YXRpb24gb2YgYF8udW5pcWAgb3B0aW1pemVkIGZvciBzb3J0ZWQgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydFxuICAgKiBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZS12YWx1ZS1mcmVlIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gc29ydGVkVW5pcShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgc2VlbixcbiAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlLCBpbmRleCwgYXJyYXkpIDogdmFsdWU7XG5cbiAgICAgIGlmICghaW5kZXggfHwgc2VlbiAhPT0gY29tcHV0ZWQpIHtcbiAgICAgICAgc2VlbiA9IGNvbXB1dGVkO1xuICAgICAgICByZXN1bHRbKytyZXNJbmRleF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltTGVmdGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgbm9uLXdoaXRlc3BhY2VcbiAgICogY2hhcmFjdGVyIG9mIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG5vbi13aGl0ZXNwYWNlIGNoYXJhY3Rlci5cbiAgICovXG4gIGZ1bmN0aW9uIHRyaW1tZWRMZWZ0SW5kZXgoc3RyaW5nKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCAmJiBpc1NwYWNlKHN0cmluZy5jaGFyQ29kZUF0KGluZGV4KSkpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1SaWdodGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZVxuICAgKiBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIuXG4gICAqL1xuICBmdW5jdGlvbiB0cmltbWVkUmlnaHRJbmRleChzdHJpbmcpIHtcbiAgICB2YXIgaW5kZXggPSBzdHJpbmcubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGluZGV4LS0gJiYgaXNTcGFjZShzdHJpbmcuY2hhckNvZGVBdChpbmRleCkpKSB7fVxuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnVuZXNjYXBlYCB0byBjb252ZXJ0IEhUTUwgZW50aXRpZXMgdG8gY2hhcmFjdGVycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNociBUaGUgbWF0Y2hlZCBjaGFyYWN0ZXIgdG8gdW5lc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVuZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICBmdW5jdGlvbiB1bmVzY2FwZUh0bWxDaGFyKGNocikge1xuICAgIHJldHVybiBodG1sVW5lc2NhcGVzW2Nocl07XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IHByaXN0aW5lIGBsb2Rhc2hgIGZ1bmN0aW9uIHVzaW5nIHRoZSBnaXZlbiBgY29udGV4dGAgb2JqZWN0LlxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBfXG4gICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dD1yb290XSBUaGUgY29udGV4dCBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBhIG5ldyBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogXy5taXhpbih7ICdmb28nOiBfLmNvbnN0YW50KCdmb28nKSB9KTtcbiAgICpcbiAgICogdmFyIGxvZGFzaCA9IF8ucnVuSW5Db250ZXh0KCk7XG4gICAqIGxvZGFzaC5taXhpbih7ICdiYXInOiBsb2Rhc2guY29uc3RhbnQoJ2JhcicpIH0pO1xuICAgKlxuICAgKiBfLmlzRnVuY3Rpb24oXy5mb28pO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqIF8uaXNGdW5jdGlvbihfLmJhcik7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5mb28pO1xuICAgKiAvLyA9PiBmYWxzZVxuICAgKiBsb2Rhc2guaXNGdW5jdGlvbihsb2Rhc2guYmFyKTtcbiAgICogLy8gPT4gdHJ1ZVxuICAgKlxuICAgKiAvLyB1c2luZyBgY29udGV4dGAgdG8gbW9jayBgRGF0ZSNnZXRUaW1lYCB1c2UgaW4gYF8ubm93YFxuICAgKiB2YXIgbW9jayA9IF8ucnVuSW5Db250ZXh0KHtcbiAgICogICAnRGF0ZSc6IGZ1bmN0aW9uKCkge1xuICAgKiAgICAgcmV0dXJuIHsgJ2dldFRpbWUnOiBnZXRUaW1lTW9jayB9O1xuICAgKiAgIH1cbiAgICogfSk7XG4gICAqXG4gICAqIC8vIG9yIGNyZWF0aW5nIGEgc3VwZWQtdXAgYGRlZmVyYCBpbiBOb2RlLmpzXG4gICAqIHZhciBkZWZlciA9IF8ucnVuSW5Db250ZXh0KHsgJ3NldFRpbWVvdXQnOiBzZXRJbW1lZGlhdGUgfSkuZGVmZXI7XG4gICAqL1xuICBmdW5jdGlvbiBydW5JbkNvbnRleHQoY29udGV4dCkge1xuICAgIC8vIEF2b2lkIGlzc3VlcyB3aXRoIHNvbWUgRVMzIGVudmlyb25tZW50cyB0aGF0IGF0dGVtcHQgdG8gdXNlIHZhbHVlcywgbmFtZWRcbiAgICAvLyBhZnRlciBidWlsdC1pbiBjb25zdHJ1Y3RvcnMgbGlrZSBgT2JqZWN0YCwgZm9yIHRoZSBjcmVhdGlvbiBvZiBsaXRlcmFscy5cbiAgICAvLyBFUzUgY2xlYXJzIHRoaXMgdXAgYnkgc3RhdGluZyB0aGF0IGxpdGVyYWxzIG11c3QgdXNlIGJ1aWx0LWluIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTEuMS41IGZvciBtb3JlIGRldGFpbHMuXG4gICAgY29udGV4dCA9IGNvbnRleHQgPyBfLmRlZmF1bHRzKHJvb3QuT2JqZWN0KCksIGNvbnRleHQsIF8ucGljayhyb290LCBjb250ZXh0UHJvcHMpKSA6IHJvb3Q7XG5cbiAgICAvKiogTmF0aXZlIGNvbnN0cnVjdG9yIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEFycmF5ID0gY29udGV4dC5BcnJheSxcbiAgICAgICAgRGF0ZSA9IGNvbnRleHQuRGF0ZSxcbiAgICAgICAgRXJyb3IgPSBjb250ZXh0LkVycm9yLFxuICAgICAgICBGdW5jdGlvbiA9IGNvbnRleHQuRnVuY3Rpb24sXG4gICAgICAgIE1hdGggPSBjb250ZXh0Lk1hdGgsXG4gICAgICAgIE51bWJlciA9IGNvbnRleHQuTnVtYmVyLFxuICAgICAgICBPYmplY3QgPSBjb250ZXh0Lk9iamVjdCxcbiAgICAgICAgUmVnRXhwID0gY29udGV4dC5SZWdFeHAsXG4gICAgICAgIFN0cmluZyA9IGNvbnRleHQuU3RyaW5nLFxuICAgICAgICBUeXBlRXJyb3IgPSBjb250ZXh0LlR5cGVFcnJvcjtcblxuICAgIC8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGUsXG4gICAgICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICAgICAgc3RyaW5nUHJvdG8gPSBTdHJpbmcucHJvdG90eXBlO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xuICAgIHZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4gICAgLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG4gICAgdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgICAvKiogVXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgSURzLiAqL1xuICAgIHZhciBpZENvdW50ZXIgPSAwO1xuXG4gICAgLyoqXG4gICAgICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAgICAgKiBvZiB2YWx1ZXMuXG4gICAgICovXG4gICAgdmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byByZXN0b3JlIHRoZSBvcmlnaW5hbCBgX2AgcmVmZXJlbmNlIGluIGBfLm5vQ29uZmxpY3RgLiAqL1xuICAgIHZhciBvbGREYXNoID0gcm9vdC5fO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbiAgICB2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICAgICAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gICAgICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbiAgICApO1xuXG4gICAgLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgQXJyYXlCdWZmZXIgPSBjb250ZXh0LkFycmF5QnVmZmVyLFxuICAgICAgICBjbGVhclRpbWVvdXQgPSBjb250ZXh0LmNsZWFyVGltZW91dCxcbiAgICAgICAgcGFyc2VGbG9hdCA9IGNvbnRleHQucGFyc2VGbG9hdCxcbiAgICAgICAgcG93ID0gTWF0aC5wb3csXG4gICAgICAgIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGUsXG4gICAgICAgIFNldCA9IGdldE5hdGl2ZShjb250ZXh0LCAnU2V0JyksXG4gICAgICAgIHNldFRpbWVvdXQgPSBjb250ZXh0LnNldFRpbWVvdXQsXG4gICAgICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlLFxuICAgICAgICBVaW50OEFycmF5ID0gY29udGV4dC5VaW50OEFycmF5LFxuICAgICAgICBXZWFrTWFwID0gZ2V0TmF0aXZlKGNvbnRleHQsICdXZWFrTWFwJyk7XG5cbiAgICAvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xuICAgIHZhciBuYXRpdmVDZWlsID0gTWF0aC5jZWlsLFxuICAgICAgICBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyksXG4gICAgICAgIG5hdGl2ZUZsb29yID0gTWF0aC5mbG9vcixcbiAgICAgICAgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKSxcbiAgICAgICAgbmF0aXZlSXNGaW5pdGUgPSBjb250ZXh0LmlzRmluaXRlLFxuICAgICAgICBuYXRpdmVLZXlzID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2tleXMnKSxcbiAgICAgICAgbmF0aXZlTWF4ID0gTWF0aC5tYXgsXG4gICAgICAgIG5hdGl2ZU1pbiA9IE1hdGgubWluLFxuICAgICAgICBuYXRpdmVOb3cgPSBnZXROYXRpdmUoRGF0ZSwgJ25vdycpLFxuICAgICAgICBuYXRpdmVQYXJzZUludCA9IGNvbnRleHQucGFyc2VJbnQsXG4gICAgICAgIG5hdGl2ZVJhbmRvbSA9IE1hdGgucmFuZG9tO1xuXG4gICAgLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG4gICAgdmFyIE5FR0FUSVZFX0lORklOSVRZID0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLFxuICAgICAgICBQT1NJVElWRV9JTkZJTklUWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblxuICAgIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG4gICAgdmFyIE1BWF9BUlJBWV9MRU5HVEggPSA0Mjk0OTY3Mjk1LFxuICAgICAgICBNQVhfQVJSQVlfSU5ERVggPSBNQVhfQVJSQVlfTEVOR1RIIC0gMSxcbiAgICAgICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuICAgIC8qKlxuICAgICAqIFVzZWQgYXMgdGhlIFttYXhpbXVtIGxlbmd0aF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtbnVtYmVyLm1heF9zYWZlX2ludGVnZXIpXG4gICAgICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAgICAgKi9cbiAgICB2YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbiAgICAvKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbiAgICB2YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbiAgICAvKiogVXNlZCB0byBsb29rdXAgdW5taW5pZmllZCBmdW5jdGlvbiBuYW1lcy4gKi9cbiAgICB2YXIgcmVhbE5hbWVzID0ge307XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGxvZGFzaGAgb2JqZWN0IHdoaWNoIHdyYXBzIGB2YWx1ZWAgdG8gZW5hYmxlIGltcGxpY2l0IGNoYWluaW5nLlxuICAgICAqIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucywgYW5kIGZ1bmN0aW9ucyBjYW5cbiAgICAgKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gICAgICogcHJpbWl0aXZlIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBlbmQgdGhlIGNoYWluIHJldHVybmluZyB0aGUgdW53cmFwcGVkXG4gICAgICogdmFsdWUuIEV4cGxpY2l0IGNoYWluaW5nIG1heSBiZSBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC4gVGhlIGV4ZWN1dGlvbiBvZlxuICAgICAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gICAgICogaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAgICAgKlxuICAgICAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICAgICAqIGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gc3RyYXRlZ3kgd2hpY2ggbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgY2FuIGhlbHBcbiAgICAgKiB0byBhdm9pZCB0aGUgY3JlYXRpb24gb2YgaW50ZXJtZWRpYXRlIGRhdGEgc3RydWN0dXJlcyBhbmQgZ3JlYXRseSByZWR1Y2UgdGhlXG4gICAgICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gICAgICpcbiAgICAgKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAgICpcbiAgICAgKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAgICAgKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgcmV2ZXJzZWAsIGBzaGlmdGAsIGBzbGljZWAsIGBzb3J0YCxcbiAgICAgKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYFN0cmluZ2AgbWV0aG9kcyBhcmU6XG4gICAgICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24gYXJlOlxuICAgICAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICAgICAqIGBmaXJzdGAsIGBpbml0aWFsYCwgYGxhc3RgLCBgbWFwYCwgYHBsdWNrYCwgYHJlamVjdGAsIGByZXN0YCwgYHJldmVyc2VgLFxuICAgICAqIGBzbGljZWAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdG9BcnJheWAsXG4gICAgICogYW5kIGB3aGVyZWBcbiAgICAgKlxuICAgICAqIFRoZSBjaGFpbmFibGUgd3JhcHBlciBtZXRob2RzIGFyZTpcbiAgICAgKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICAgICAqIGBjYWxsYmFja2AsIGBjaGFpbmAsIGBjaHVua2AsIGBjb21taXRgLCBgY29tcGFjdGAsIGBjb25jYXRgLCBgY29uc3RhbnRgLFxuICAgICAqIGBjb3VudEJ5YCwgYGNyZWF0ZWAsIGBjdXJyeWAsIGBkZWJvdW5jZWAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLFxuICAgICAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAgICAgKiBgZHJvcFdoaWxlYCwgYGZpbGxgLCBgZmlsdGVyYCwgYGZsYXR0ZW5gLCBgZmxhdHRlbkRlZXBgLCBgZmxvd2AsIGBmbG93UmlnaHRgLFxuICAgICAqIGBmb3JFYWNoYCwgYGZvckVhY2hSaWdodGAsIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsXG4gICAgICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAgICAgKiBgaW52b2tlYCwgYGtleXNgLCBga2V5c0luYCwgYG1hcGAsIGBtYXBLZXlzYCwgYG1hcFZhbHVlc2AsIGBtYXRjaGVzYCxcbiAgICAgKiBgbWF0Y2hlc1Byb3BlcnR5YCwgYG1lbW9pemVgLCBgbWVyZ2VgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCxcbiAgICAgKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAgICAgKiBgcGFydGl0aW9uYCwgYHBpY2tgLCBgcGxhbnRgLCBgcGx1Y2tgLCBgcHJvcGVydHlgLCBgcHJvcGVydHlPZmAsIGBwdWxsYCxcbiAgICAgKiBgcHVsbEF0YCwgYHB1c2hgLCBgcmFuZ2VgLCBgcmVhcmdgLCBgcmVqZWN0YCwgYHJlbW92ZWAsIGByZXN0YCwgYHJlc3RQYXJhbWAsXG4gICAgICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAgICAgKiBgc29ydEJ5T3JkZXJgLCBgc3BsaWNlYCwgYHNwcmVhZGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsXG4gICAgICogYHRha2VXaGlsZWAsIGB0YXBgLCBgdGhyb3R0bGVgLCBgdGhydWAsIGB0aW1lc2AsIGB0b0FycmF5YCwgYHRvUGxhaW5PYmplY3RgLFxuICAgICAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICAgICAqIGB2YWx1ZXNJbmAsIGB3aGVyZWAsIGB3aXRob3V0YCwgYHdyYXBgLCBgeG9yYCwgYHppcGAsIGB6aXBPYmplY3RgLCBgemlwV2l0aGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gICAgICogYGFkZGAsIGBhdHRlbXB0YCwgYGNhbWVsQ2FzZWAsIGBjYXBpdGFsaXplYCwgYGNlaWxgLCBgY2xvbmVgLCBgY2xvbmVEZWVwYCxcbiAgICAgKiBgZGVidXJyYCwgYGVuZHNXaXRoYCwgYGVzY2FwZWAsIGBlc2NhcGVSZWdFeHBgLCBgZXZlcnlgLCBgZmluZGAsIGBmaW5kSW5kZXhgLFxuICAgICAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAgICAgKiBgZmxvb3JgLCBgZ2V0YCwgYGd0YCwgYGd0ZWAsIGBoYXNgLCBgaWRlbnRpdHlgLCBgaW5jbHVkZXNgLCBgaW5kZXhPZmAsXG4gICAgICogYGluUmFuZ2VgLCBgaXNBcmd1bWVudHNgLCBgaXNBcnJheWAsIGBpc0Jvb2xlYW5gLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsXG4gICAgICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAgICAgKiBgaXNOYXRpdmVgLCBgaXNOYU5gLCBgaXNOdWxsYCwgYGlzTnVtYmVyYCwgYGlzT2JqZWN0YCwgYGlzUGxhaW5PYmplY3RgLFxuICAgICAqIGBpc1JlZ0V4cGAsIGBpc1N0cmluZ2AsIGBpc1VuZGVmaW5lZGAsIGBpc1R5cGVkQXJyYXlgLCBgam9pbmAsIGBrZWJhYkNhc2VgLFxuICAgICAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gICAgICogYG5vd2AsIGBwYWRgLCBgcGFkTGVmdGAsIGBwYWRSaWdodGAsIGBwYXJzZUludGAsIGBwb3BgLCBgcmFuZG9tYCwgYHJlZHVjZWAsXG4gICAgICogYHJlZHVjZVJpZ2h0YCwgYHJlcGVhdGAsIGByZXN1bHRgLCBgcm91bmRgLCBgcnVuSW5Db250ZXh0YCwgYHNoaWZ0YCwgYHNpemVgLFxuICAgICAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAgICAgKiBgc3RhcnRzV2l0aGAsIGBzdW1gLCBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltTGVmdGAsIGB0cmltUmlnaHRgLCBgdHJ1bmNgLFxuICAgICAqIGB1bmVzY2FwZWAsIGB1bmlxdWVJZGAsIGB2YWx1ZWAsIGFuZCBgd29yZHNgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBtZXRob2QgYHNhbXBsZWAgd2lsbCByZXR1cm4gYSB3cmFwcGVkIHZhbHVlIHdoZW4gYG5gIGlzIHByb3ZpZGVkLFxuICAgICAqIG90aGVyd2lzZSBhbiB1bndyYXBwZWQgdmFsdWUgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAbmFtZSBfXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQGNhdGVnb3J5IENoYWluXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcCBpbiBhIGBsb2Rhc2hgIGluc3RhbmNlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDIsIDNdKTtcbiAgICAgKlxuICAgICAqIC8vIHJldHVybnMgYW4gdW53cmFwcGVkIHZhbHVlXG4gICAgICogd3JhcHBlZC5yZWR1Y2UoZnVuY3Rpb24odG90YWwsIG4pIHtcbiAgICAgKiAgIHJldHVybiB0b3RhbCArIG47XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gNlxuICAgICAqXG4gICAgICogLy8gcmV0dXJucyBhIHdyYXBwZWQgdmFsdWVcbiAgICAgKiB2YXIgc3F1YXJlcyA9IHdyYXBwZWQubWFwKGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICAgICAgaWYgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzQXJyYXkodmFsdWUpICYmICEodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikpIHtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fY2hhaW5fXycpICYmIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX3dyYXBwZWRfXycpKSB7XG4gICAgICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTG9kYXNoKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FjdGlvbnM9W11dIEFjdGlvbnMgdG8gcGVmb3JtIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICAgICAgdGhpcy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgdGhpcy5fX2FjdGlvbnNfXyA9IGFjdGlvbnMgfHwgW107XG4gICAgICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW4gb2JqZWN0IGVudmlyb25tZW50IGZlYXR1cmUgZmxhZ3MuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICB2YXIgc3VwcG9ydCA9IGxvZGFzaC5zdXBwb3J0ID0ge307XG5cbiAgICAvKipcbiAgICAgKiBCeSBkZWZhdWx0LCB0aGUgdGVtcGxhdGUgZGVsaW1pdGVycyB1c2VkIGJ5IGxvZGFzaCBhcmUgbGlrZSB0aG9zZSBpblxuICAgICAqIGVtYmVkZGVkIFJ1YnkgKEVSQikuIENoYW5nZSB0aGUgZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZVxuICAgICAqIGFsdGVybmF0aXZlIGRlbGltaXRlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBsb2Rhc2gudGVtcGxhdGVTZXR0aW5ncyA9IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBgZGF0YWAgcHJvcGVydHkgdmFsdWVzIHRvIGJlIEhUTUwtZXNjYXBlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSBSZWdFeHBcbiAgICAgICAqL1xuICAgICAgJ2VzY2FwZSc6IHJlRXNjYXBlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGNvZGUgdG8gYmUgZXZhbHVhdGVkLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIFJlZ0V4cFxuICAgICAgICovXG4gICAgICAnZXZhbHVhdGUnOiByZUV2YWx1YXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gaW5qZWN0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIFJlZ0V4cFxuICAgICAgICovXG4gICAgICAnaW50ZXJwb2xhdGUnOiByZUludGVycG9sYXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gcmVmZXJlbmNlIHRoZSBkYXRhIG9iamVjdCBpbiB0aGUgdGVtcGxhdGUgdGV4dC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSBzdHJpbmdcbiAgICAgICAqL1xuICAgICAgJ3ZhcmlhYmxlJzogJycsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byBpbXBvcnQgdmFyaWFibGVzIGludG8gdGhlIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICovXG4gICAgICAnaW1wb3J0cyc6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWZlcmVuY2UgdG8gdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzLmltcG9ydHNcbiAgICAgICAgICogQHR5cGUgRnVuY3Rpb25cbiAgICAgICAgICovXG4gICAgICAgICdfJzogbG9kYXNoXG4gICAgICB9XG4gICAgfTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBsYXp5IHdyYXBwZXIgb2JqZWN0IHdoaWNoIHdyYXBzIGB2YWx1ZWAgdG8gZW5hYmxlIGxhenkgZXZhbHVhdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICAgICAgdGhpcy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICAgICAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgICAgIHRoaXMuX19maWx0ZXJlZF9fID0gZmFsc2U7XG4gICAgICB0aGlzLl9faXRlcmF0ZWVzX18gPSBbXTtcbiAgICAgIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGxhenkgd3JhcHBlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsb25lXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlDbG9uZSgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcy5fX3dyYXBwZWRfXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBhcnJheUNvcHkodGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19kaXJfXyA9IHRoaXMuX19kaXJfXztcbiAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0aGlzLl9fZmlsdGVyZWRfXztcbiAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fID0gYXJyYXlDb3B5KHRoaXMuX19pdGVyYXRlZXNfXyk7XG4gICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IHRoaXMuX190YWtlQ291bnRfXztcbiAgICAgIHJlc3VsdC5fX3ZpZXdzX18gPSBhcnJheUNvcHkodGhpcy5fX3ZpZXdzX18pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlcyB0aGUgZGlyZWN0aW9uIG9mIGxhenkgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHJldmVyc2VkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlSZXZlcnNlKCkge1xuICAgICAgaWYgKHRoaXMuX19maWx0ZXJlZF9fKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIHJlc3VsdC5fX2Rpcl9fID0gLTE7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyAqPSAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHVud3JhcHBlZCB2YWx1ZSBmcm9tIGl0cyBsYXp5IHdyYXBwZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5VmFsdWUoKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9fd3JhcHBlZF9fLnZhbHVlKCksXG4gICAgICAgICAgZGlyID0gdGhpcy5fX2Rpcl9fLFxuICAgICAgICAgIGlzQXJyID0gaXNBcnJheShhcnJheSksXG4gICAgICAgICAgaXNSaWdodCA9IGRpciA8IDAsXG4gICAgICAgICAgYXJyTGVuZ3RoID0gaXNBcnIgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHZpZXcgPSBnZXRWaWV3KDAsIGFyckxlbmd0aCwgdGhpcy5fX3ZpZXdzX18pLFxuICAgICAgICAgIHN0YXJ0ID0gdmlldy5zdGFydCxcbiAgICAgICAgICBlbmQgPSB2aWV3LmVuZCxcbiAgICAgICAgICBsZW5ndGggPSBlbmQgLSBzdGFydCxcbiAgICAgICAgICBpbmRleCA9IGlzUmlnaHQgPyBlbmQgOiAoc3RhcnQgLSAxKSxcbiAgICAgICAgICBpdGVyYXRlZXMgPSB0aGlzLl9faXRlcmF0ZWVzX18sXG4gICAgICAgICAgaXRlckxlbmd0aCA9IGl0ZXJhdGVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHRha2VDb3VudCA9IG5hdGl2ZU1pbihsZW5ndGgsIHRoaXMuX190YWtlQ291bnRfXyk7XG5cbiAgICAgIGlmICghaXNBcnIgfHwgYXJyTGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSB8fCAoYXJyTGVuZ3RoID09IGxlbmd0aCAmJiB0YWtlQ291bnQgPT0gbGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gYmFzZVdyYXBwZXJWYWx1ZSgoaXNSaWdodCAmJiBpc0FycikgPyBhcnJheS5yZXZlcnNlKCkgOiBhcnJheSwgdGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKGxlbmd0aC0tICYmIHJlc0luZGV4IDwgdGFrZUNvdW50KSB7XG4gICAgICAgIGluZGV4ICs9IGRpcjtcblxuICAgICAgICB2YXIgaXRlckluZGV4ID0gLTEsXG4gICAgICAgICAgICB2YWx1ZSA9IGFycmF5W2luZGV4XTtcblxuICAgICAgICB3aGlsZSAoKytpdGVySW5kZXggPCBpdGVyTGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIGRhdGEgPSBpdGVyYXRlZXNbaXRlckluZGV4XSxcbiAgICAgICAgICAgICAgaXRlcmF0ZWUgPSBkYXRhLml0ZXJhdGVlLFxuICAgICAgICAgICAgICB0eXBlID0gZGF0YS50eXBlLFxuICAgICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgICAgIGlmICh0eXBlID09IExBWllfTUFQX0ZMQUcpIHtcbiAgICAgICAgICAgIHZhbHVlID0gY29tcHV0ZWQ7XG4gICAgICAgICAgfSBlbHNlIGlmICghY29tcHV0ZWQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IExBWllfRklMVEVSX0ZMQUcpIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5L3ZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG5hbWUgQ2FjaGVcbiAgICAgKiBAbWVtYmVyT2YgXy5tZW1vaXplXG4gICAgICovXG4gICAgZnVuY3Rpb24gTWFwQ2FjaGUoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgXy5tZW1vaXplLkNhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCBzdWNjZXNzZnVsbHksIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBEZWxldGUoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNhY2hlZCB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBfLm1lbW9pemUuQ2FjaGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2FjaGVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcEdldChrZXkpIHtcbiAgICAgIHJldHVybiBrZXkgPT0gJ19fcHJvdG9fXycgPyB1bmRlZmluZWQgOiB0aGlzLl9fZGF0YV9fW2tleV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgY2FjaGVkIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBfLm1lbW9pemUuQ2FjaGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwSGFzKGtleSkge1xuICAgICAgcmV0dXJuIGtleSAhPSAnX19wcm90b19fJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX19kYXRhX18sIGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBgdmFsdWVgIHRvIGBrZXlgIG9mIHRoZSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIF8ubWVtb2l6ZS5DYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gY2FjaGUuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2FjaGUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2FjaGUgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcFNldChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoa2V5ICE9ICdfX3Byb3RvX18nKSB7XG4gICAgICAgIHRoaXMuX19kYXRhX19ba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBDcmVhdGVzIGEgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gdmFsdWVzID8gdmFsdWVzLmxlbmd0aCA6IDA7XG5cbiAgICAgIHRoaXMuZGF0YSA9IHsgJ2hhc2gnOiBuYXRpdmVDcmVhdGUobnVsbCksICdzZXQnOiBuZXcgU2V0IH07XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdGhpcy5wdXNoKHZhbHVlc1tsZW5ndGhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiBgY2FjaGVgIG1pbWlja2luZyB0aGUgcmV0dXJuIHNpZ25hdHVyZSBvZlxuICAgICAqIGBfLmluZGV4T2ZgIGJ5IHJldHVybmluZyBgMGAgaWYgdGhlIHZhbHVlIGlzIGZvdW5kLCBlbHNlIGAtMWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBgMGAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgLTFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhY2hlSW5kZXhPZihjYWNoZSwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gY2FjaGUuZGF0YSxcbiAgICAgICAgICByZXN1bHQgPSAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzT2JqZWN0KHZhbHVlKSkgPyBkYXRhLnNldC5oYXModmFsdWUpIDogZGF0YS5oYXNoW3ZhbHVlXTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA/IDAgOiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBwdXNoXG4gICAgICogQG1lbWJlck9mIFNldENhY2hlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FjaGVQdXNoKHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIGRhdGEuc2V0LmFkZCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhLmhhc2hbdmFsdWVdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGFycmF5IGpvaW5pbmcgYGFycmF5YCB3aXRoIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBqb2luLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBqb2luLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGNvbmNhdGVuYXRlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheUNvbmNhdChhcnJheSwgb3RoZXIpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBvdGhJbmRleCA9IC0xLFxuICAgICAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGggKyBvdGhMZW5ndGgpO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsrb3RoSW5kZXggPCBvdGhMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4KytdID0gb3RoZXJbb3RoSW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb3BpZXMgdGhlIHZhbHVlcyBvZiBgc291cmNlYCB0byBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIGZyb20uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG5cbiAgICAgIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgYXJyYXlbaW5kZXhdID0gc291cmNlW2luZGV4XTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheUVhY2goYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaFJpZ2h0YCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICAgKiBjYWxsYmFjayBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5RWFjaFJpZ2h0KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGlmIChpdGVyYXRlZShhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5ldmVyeWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheUV2ZXJ5KGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCFwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VFeHRyZW11bWAgZm9yIGFycmF5cyB3aGljaCBpbnZva2VzIGBpdGVyYXRlZWBcbiAgICAgKiB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGZ1bmN0aW9uIHVzZWQgdG8gY29tcGFyZSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHsqfSBleFZhbHVlIFRoZSBpbml0aWFsIGV4dHJlbXVtIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBleHRyZW11bSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheUV4dHJlbXVtKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvciwgZXhWYWx1ZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGNvbXB1dGVkID0gZXhWYWx1ZSxcbiAgICAgICAgICByZXN1bHQgPSBjb21wdXRlZDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY3VycmVudCA9ICtpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKGNvbXBhcmF0b3IoY3VycmVudCwgY29tcHV0ZWQpKSB7XG4gICAgICAgICAgY29tcHV0ZWQgPSBjdXJyZW50O1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5maWx0ZXJgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICAgICAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXNJbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgICByZXN1bHRbKytyZXNJbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAgICAgKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBlbmRzIHRoZSBlbGVtZW50cyBvZiBgdmFsdWVzYCB0byBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGFycmF5W29mZnNldCArIGluZGV4XSA9IHZhbHVlc1tpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnJlZHVjZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEZyb21BcnJheV0gU3BlY2lmeSB1c2luZyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgXG4gICAgICogIGFzIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVJlZHVjZShhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0RnJvbUFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIGlmIChpbml0RnJvbUFycmF5ICYmIGxlbmd0aCkge1xuICAgICAgICBhY2N1bXVsYXRvciA9IGFycmF5WysraW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgYWNjdW11bGF0b3IgPSBpdGVyYXRlZShhY2N1bXVsYXRvciwgYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VSaWdodGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAgICogY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEZyb21BcnJheV0gU3BlY2lmeSB1c2luZyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWBcbiAgICAgKiAgYXMgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5UmVkdWNlUmlnaHQoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEZyb21BcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmIChpbml0RnJvbUFycmF5ICYmIGxlbmd0aCkge1xuICAgICAgICBhY2N1bXVsYXRvciA9IGFycmF5Wy0tbGVuZ3RoXTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBhY2N1bXVsYXRvciA9IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCBhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zdW1gIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICAgICAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVN1bShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gMDtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdCArPSAraXRlcmF0ZWUoYXJyYXlbbGVuZ3RoXSkgfHwgMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5kZWZhdWx0c2AgdG8gY3VzdG9taXplIGl0cyBgXy5hc3NpZ25gIHVzZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBvYmplY3RWYWx1ZSBUaGUgZGVzdGluYXRpb24gb2JqZWN0IHByb3BlcnR5IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc291cmNlVmFsdWUgVGhlIHNvdXJjZSBvYmplY3QgcHJvcGVydHkgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnbkRlZmF1bHRzKG9iamVjdFZhbHVlLCBzb3VyY2VWYWx1ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdFZhbHVlID09PSB1bmRlZmluZWQgPyBzb3VyY2VWYWx1ZSA6IG9iamVjdFZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZWQgYnkgYF8udGVtcGxhdGVgIHRvIGN1c3RvbWl6ZSBpdHMgYF8uYXNzaWduYCB1c2UuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhc3NpZ25EZWZhdWx0c2AgZXhjZXB0IHRoYXQgaXQgaWdub3Jlc1xuICAgICAqIGluaGVyaXRlZCBwcm9wZXJ0eSB2YWx1ZXMgd2hlbiBjaGVja2luZyBpZiBhIHByb3BlcnR5IGlzIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IG9iamVjdFZhbHVlIFRoZSBkZXN0aW5hdGlvbiBvYmplY3QgcHJvcGVydHkgdmFsdWUuXG4gICAgICogQHBhcmFtIHsqfSBzb3VyY2VWYWx1ZSBUaGUgc291cmNlIG9iamVjdCBwcm9wZXJ0eSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoZSBvYmplY3QgYW5kIHNvdXJjZSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhc3NpZ25Pd25EZWZhdWx0cyhvYmplY3RWYWx1ZSwgc291cmNlVmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gKG9iamVjdFZhbHVlID09PSB1bmRlZmluZWQgfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKVxuICAgICAgICA/IHNvdXJjZVZhbHVlXG4gICAgICAgIDogb2JqZWN0VmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmFzc2lnbmAgZm9yIGN1c3RvbWl6aW5nIGFzc2lnbmVkIHZhbHVlcyB3aXRob3V0XG4gICAgICogc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsIG11bHRpcGxlIHNvdXJjZXMsIGFuZCBgdGhpc2AgYmluZGluZyBgY3VzdG9taXplcmBcbiAgICAgKiBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhc3NpZ25XaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBwcm9wcyA9IGtleXMoc291cmNlKSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF0sXG4gICAgICAgICAgICB2YWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplcih2YWx1ZSwgc291cmNlW2tleV0sIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuXG4gICAgICAgIGlmICgocmVzdWx0ID09PSByZXN1bHQgPyAocmVzdWx0ICE9PSB2YWx1ZSkgOiAodmFsdWUgPT09IHZhbHVlKSkgfHxcbiAgICAgICAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICAgICAqIG11bHRpcGxlIHNvdXJjZXMsIGFuZCBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IGJhc2VDb3B5KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0cmluZyBjb2xsZWN0aW9uc1xuICAgICAqIGFuZCBpbmRpdmlkdWFsIGtleSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfHN0cmluZ1tdfSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgb3IgaW5kZXhlcyBvZiBlbGVtZW50cyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBpY2tlZCBlbGVtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXQoY29sbGVjdGlvbiwgcHJvcHMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzTmlsID0gY29sbGVjdGlvbiA9PSBudWxsLFxuICAgICAgICAgIGlzQXJyID0gIWlzTmlsICYmIGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pLFxuICAgICAgICAgIGxlbmd0aCA9IGlzQXJyID8gY29sbGVjdGlvbi5sZW5ndGggOiAwLFxuICAgICAgICAgIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KHByb3BzTGVuZ3RoKTtcblxuICAgICAgd2hpbGUoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICAgIGlmIChpc0Fycikge1xuICAgICAgICAgIHJlc3VsdFtpbmRleF0gPSBpc0luZGV4KGtleSwgbGVuZ3RoKSA/IGNvbGxlY3Rpb25ba2V5XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHRbaW5kZXhdID0gaXNOaWwgPyB1bmRlZmluZWQgOiBjb2xsZWN0aW9uW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gY29weS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ29weShzb3VyY2UsIHByb3BzLCBvYmplY3QpIHtcbiAgICAgIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICAgIG9iamVjdFtrZXldID0gc291cmNlW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICAgICAqIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gW2Z1bmM9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYSBjYWxsYmFjay5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiBmdW5jO1xuICAgICAgaWYgKHR5cGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBmdW5jXG4gICAgICAgICAgOiBiaW5kQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpO1xuICAgICAgfVxuICAgICAgaWYgKGZ1bmMgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gaWRlbnRpdHk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gYmFzZU1hdGNoZXMoZnVuYyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gcHJvcGVydHkoZnVuYylcbiAgICAgICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nXG4gICAgICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCBgdmFsdWVgIGJlbG9uZ3MgdG8uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICAgICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICAgICAgaWYgKCFpc0RlZXApIHtcbiAgICAgICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgICAgICBpc0Z1bmMgPSB0YWcgPT0gZnVuY1RhZztcblxuICAgICAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gaW5pdENsb25lT2JqZWN0KGlzRnVuYyA/IHt9IDogdmFsdWUpO1xuICAgICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICAgICAgPyBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApXG4gICAgICAgICAgICA6IChvYmplY3QgPyB2YWx1ZSA6IHt9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgICAgIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICAgICAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgICAgIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSB2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQWRkIHRoZSBzb3VyY2UgdmFsdWUgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCBpdHMgY2xvbmUuXG4gICAgICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gICAgICBzdGFja0IucHVzaChyZXN1bHQpO1xuXG4gICAgICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBiYXNlQ2xvbmUoc3ViVmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAgICAgKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIHZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgICAgIHJldHVybiBmdW5jdGlvbihwcm90b3R5cGUpIHtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHByb3RvdHlwZSkpIHtcbiAgICAgICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBuZXcgb2JqZWN0O1xuICAgICAgICAgIG9iamVjdC5wcm90b3R5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCB7fTtcbiAgICAgIH07XG4gICAgfSgpKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmRlbGF5YCBhbmQgYF8uZGVmZXJgIHdoaWNoIGFjY2VwdHMgYW4gaW5kZXhcbiAgICAgKiBvZiB3aGVyZSB0byBzbGljZSB0aGUgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzIFRoZSBhcmd1bWVudHMgcHJvdmlkZSB0byBgZnVuY2AuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXIgaWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURlbGF5KGZ1bmMsIHdhaXQsIGFyZ3MpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7IH0sIHdhaXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmRpZmZlcmVuY2VgIHdoaWNoIGFjY2VwdHMgYSBzaW5nbGUgYXJyYXlcbiAgICAgKiBvZiB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluZGV4T2YgPSBnZXRJbmRleE9mKCksXG4gICAgICAgICAgaXNDb21tb24gPSBpbmRleE9mID09IGJhc2VJbmRleE9mLFxuICAgICAgICAgIGNhY2hlID0gKGlzQ29tbW9uICYmIHZhbHVlcy5sZW5ndGggPj0gTEFSR0VfQVJSQVlfU0laRSkgPyBjcmVhdGVDYWNoZSh2YWx1ZXMpIDogbnVsbCxcbiAgICAgICAgICB2YWx1ZXNMZW5ndGggPSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgaW5kZXhPZiA9IGNhY2hlSW5kZXhPZjtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzID0gY2FjaGU7XG4gICAgICB9XG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcblxuICAgICAgICBpZiAoaXNDb21tb24gJiYgdmFsdWUgPT09IHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHZhbHVlc0luZGV4ID0gdmFsdWVzTGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICh2YWx1ZXNJbmRleC0tKSB7XG4gICAgICAgICAgICBpZiAodmFsdWVzW3ZhbHVlc0luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleE9mKHZhbHVlcywgdmFsdWUsIDApIDwgMCkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICovXG4gICAgdmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoUmlnaHRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAgICAgKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R8c3RyaW5nfSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUVhY2hSaWdodCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd25SaWdodCwgdHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ldmVyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICAgICAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbGwgZWxlbWVudHMgcGFzcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdHJ1ZTtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSAhIXByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGV4dHJlbXVtIHZhbHVlIG9mIGBjb2xsZWN0aW9uYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvciBlYWNoIHZhbHVlXG4gICAgICogaW4gYGNvbGxlY3Rpb25gIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2ggdGhlIHZhbHVlIGlzIHJhbmtlZC5cbiAgICAgKiBUaGUgYGl0ZXJhdGVlYCBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGNvbXBhcmUgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7Kn0gZXhWYWx1ZSBUaGUgaW5pdGlhbCBleHRyZW11bSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZXh0cmVtdW0gdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUV4dHJlbXVtKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBjb21wYXJhdG9yLCBleFZhbHVlKSB7XG4gICAgICB2YXIgY29tcHV0ZWQgPSBleFZhbHVlLFxuICAgICAgICAgIHJlc3VsdCA9IGNvbXB1dGVkO1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSAraXRlcmF0ZWUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgaWYgKGNvbXBhcmF0b3IoY3VycmVudCwgY29tcHV0ZWQpIHx8IChjdXJyZW50ID09PSBleFZhbHVlICYmIGN1cnJlbnQgPT09IHJlc3VsdCkpIHtcbiAgICAgICAgICBjb21wdXRlZCA9IGN1cnJlbnQ7XG4gICAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maWxsYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmaWxsLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGZpbGwgYGFycmF5YCB3aXRoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHN0YXJ0ID0gc3RhcnQgPT0gbnVsbCA/IDAgOiAoK3N0YXJ0IHx8IDApO1xuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICAgICAgfVxuICAgICAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoZW5kID4+PiAwKTtcbiAgICAgIHN0YXJ0ID4+Pj0gMDtcblxuICAgICAgd2hpbGUgKHN0YXJ0IDwgbGVuZ3RoKSB7XG4gICAgICAgIGFycmF5W3N0YXJ0KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsdGVyYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAgICAgKiB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLCB3aGljaCBpdGVyYXRlc1xuICAgICAqIG92ZXIgYGNvbGxlY3Rpb25gIHVzaW5nIHRoZSBwcm92aWRlZCBgZWFjaEZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEtleV0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGtleSBvZiB0aGUgZm91bmQgZWxlbWVudFxuICAgICAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZm91bmQgZWxlbWVudCBvciBpdHMga2V5LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHJlc3VsdCA9IHJldEtleSA/IGtleSA6IHZhbHVlO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZsYXR0ZW5gIHdpdGggYWRkZWQgc3VwcG9ydCBmb3IgcmVzdHJpY3RpbmdcbiAgICAgKiBmbGF0dGVuaW5nIGFuZCBzcGVjaWZ5aW5nIHRoZSBzdGFydCBpbmRleC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzU3RyaWN0XSBSZXN0cmljdCBmbGF0dGVuaW5nIHRvIGFycmF5cy1saWtlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgaXNEZWVwLCBpc1N0cmljdCwgcmVzdWx0KSB7XG4gICAgICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgICAgICAgICAgKGlzU3RyaWN0IHx8IGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSkpIHtcbiAgICAgICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBmbGF0dGVuIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGlzRGVlcCwgaXNTdHJpY3QsIHJlc3VsdCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzU3RyaWN0KSB7XG4gICAgICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICAgICAqIG92ZXIgYG9iamVjdGAgcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGludm9raW5nIGBpdGVyYXRlZWAgZm9yXG4gICAgICogZWFjaCBwcm9wZXJ0eS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5XG4gICAgICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgdmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJhc2VGb3JgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllc1xuICAgICAqIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUZvclJpZ2h0ID0gY3JlYXRlQmFzZUZvcih0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckluYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JJbihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICAgICAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93blJpZ2h0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gICAgICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JPd25SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZvclJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZ1bmN0aW9uc2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZlxuICAgICAqIGBvYmplY3RgIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZpbHRlcmVkIGZyb20gdGhvc2UgcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBmaWx0ZXIuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZ1bmN0aW9ucyhvYmplY3QsIHByb3BzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24ob2JqZWN0W2tleV0pKSB7XG4gICAgICAgICAgcmVzdWx0WysrcmVzSW5kZXhdID0ga2V5O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRgIHdpdGhvdXQgc3VwcG9ydCBmb3Igc3RyaW5nIHBhdGhzXG4gICAgICogYW5kIGRlZmF1bHQgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0aEtleV0gVGhlIGtleSByZXByZXNlbnRhdGlvbiBvZiBwYXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCwgcGF0aEtleSkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChwYXRoS2V5ICE9PSB1bmRlZmluZWQgJiYgcGF0aEtleSBpbiB0b09iamVjdChvYmplY3QpKSB7XG4gICAgICAgIHBhdGggPSBbcGF0aEtleV07XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAwLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W3BhdGhbaW5kZXgrK11dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChpbmRleCAmJiBpbmRleCA9PSBsZW5ndGgpID8gb2JqZWN0IDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRXF1YWxgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYHRoaXNgIGJpbmRpbmdcbiAgICAgKiBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCBvdGhlciA9PSBudWxsIHx8ICghaXNPYmplY3QodmFsdWUpICYmICFpc09iamVjdExpa2Uob3RoZXIpKSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiYXNlSXNFcXVhbCwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAgICAgKiBkZWVwIGNvbXBhcmlzb25zIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgICAgIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBvdGhJc0FyciA9IGlzQXJyYXkob3RoZXIpLFxuICAgICAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgICAgIG90aFRhZyA9IGFycmF5VGFnO1xuXG4gICAgICBpZiAoIW9iaklzQXJyKSB7XG4gICAgICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICAgICAgaWYgKG9ialRhZyA9PSBhcmdzVGFnKSB7XG4gICAgICAgICAgb2JqVGFnID0gb2JqZWN0VGFnO1xuICAgICAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgICAgICBvYmpJc0FyciA9IGlzVHlwZWRBcnJheShvYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIW90aElzQXJyKSB7XG4gICAgICAgIG90aFRhZyA9IG9ialRvU3RyaW5nLmNhbGwob3RoZXIpO1xuICAgICAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgICAgICBvdGhUYWcgPSBvYmplY3RUYWc7XG4gICAgICAgIH0gZWxzZSBpZiAob3RoVGFnICE9IG9iamVjdFRhZykge1xuICAgICAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcsXG4gICAgICAgICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZztcblxuICAgICAgaWYgKGlzU2FtZVRhZyAmJiAhKG9iaklzQXJyIHx8IG9iaklzT2JqKSkge1xuICAgICAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0xvb3NlKSB7XG4gICAgICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgICAgICBvdGhJc1dyYXBwZWQgPSBvdGhJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCAnX193cmFwcGVkX18nKTtcblxuICAgICAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzU2FtZVRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBkZXRlY3RpbmcgY2lyY3VsYXIgcmVmZXJlbmNlcyBzZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyNKTy5cbiAgICAgIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICAgICAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgICAgIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF0gPT0gb3RoZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEFkZCBgb2JqZWN0YCBhbmQgYG90aGVyYCB0byB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICBzdGFja0EucHVzaChvYmplY3QpO1xuICAgICAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gKG9iaklzQXJyID8gZXF1YWxBcnJheXMgOiBlcXVhbE9iamVjdHMpKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuXG4gICAgICBzdGFja0EucG9wKCk7XG4gICAgICBzdGFja0IucG9wKCk7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICAgICAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBtYXRjaERhdGEgVGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICAgICAgdmFyIGluZGV4ID0gbWF0Y2hEYXRhLmxlbmd0aCxcbiAgICAgICAgICBsZW5ndGggPSBpbmRleCxcbiAgICAgICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAhbGVuZ3RoO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICAgICAgPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV1cbiAgICAgICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgY3VzdG9taXplciwgdHJ1ZSkgOiByZXN1bHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICAgICAqIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNgIHdoaWNoIGRvZXMgbm90IGNsb25lIGBzb3VyY2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkge1xuICAgICAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICAgICAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICAgICAgdmFyIGtleSA9IG1hdGNoRGF0YVswXVswXSxcbiAgICAgICAgICAgIHZhbHVlID0gbWF0Y2hEYXRhWzBdWzFdO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIHRvT2JqZWN0KG9iamVjdCkpKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJc01hdGNoKG9iamVjdCwgbWF0Y2hEYXRhKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc1Byb3BlcnR5YCB3aGljaCBkb2VzIG5vdCBjbG9uZSBgc3JjVmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheShwYXRoKSxcbiAgICAgICAgICBpc0NvbW1vbiA9IGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSksXG4gICAgICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gICAgICBwYXRoID0gdG9QYXRoKHBhdGgpO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gICAgICAgIGlmICgoaXNBcnIgfHwgIWlzQ29tbW9uKSAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAga2V5ID0gbGFzdChwYXRoKTtcbiAgICAgICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWVcbiAgICAgICAgICA/IChzcmNWYWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gb2JqZWN0KSlcbiAgICAgICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVyZ2VgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsXG4gICAgICogbXVsdGlwbGUgc291cmNlcywgYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIG1lcmdlZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIHZhbHVlcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIsIHN0YWNrQSwgc3RhY2tCKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHZhciBpc1NyY0FyciA9IGlzQXJyYXlMaWtlKHNvdXJjZSkgJiYgKGlzQXJyYXkoc291cmNlKSB8fCBpc1R5cGVkQXJyYXkoc291cmNlKSksXG4gICAgICAgICAgcHJvcHMgPSBpc1NyY0FyciA/IHVuZGVmaW5lZCA6IGtleXMoc291cmNlKTtcblxuICAgICAgYXJyYXlFYWNoKHByb3BzIHx8IHNvdXJjZSwgZnVuY3Rpb24oc3JjVmFsdWUsIGtleSkge1xuICAgICAgICBpZiAocHJvcHMpIHtcbiAgICAgICAgICBrZXkgPSBzcmNWYWx1ZTtcbiAgICAgICAgICBzcmNWYWx1ZSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc09iamVjdExpa2Uoc3JjVmFsdWUpKSB7XG4gICAgICAgICAgc3RhY2tBIHx8IChzdGFja0EgPSBbXSk7XG4gICAgICAgICAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG4gICAgICAgICAgYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBiYXNlTWVyZ2UsIGN1c3RvbWl6ZXIsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIodmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaXNDb21tb24gPSByZXN1bHQgPT09IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICAgICAgcmVzdWx0ID0gc3JjVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICgocmVzdWx0ICE9PSB1bmRlZmluZWQgfHwgKGlzU3JjQXJyICYmICEoa2V5IGluIG9iamVjdCkpKSAmJlxuICAgICAgICAgICAgICAoaXNDb21tb24gfHwgKHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlc3VsdCAhPT0gdmFsdWUpIDogKHZhbHVlID09PSB2YWx1ZSkpKSkge1xuICAgICAgICAgICAgb2JqZWN0W2tleV0gPSByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlTWVyZ2VgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAgICAgKiBkZWVwIG1lcmdlcyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICAgICAqIHJlZmVyZW5jZXMgdG8gYmUgbWVyZ2VkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIG1lcmdlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG1lcmdlRnVuYyBUaGUgZnVuY3Rpb24gdG8gbWVyZ2UgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIG1lcmdlZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIHZhbHVlcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBtZXJnZUZ1bmMsIGN1c3RvbWl6ZXIsIHN0YWNrQSwgc3RhY2tCKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aCxcbiAgICAgICAgICBzcmNWYWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHNyY1ZhbHVlKSB7XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBzdGFja0JbbGVuZ3RoXTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciB2YWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKHZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgaXNDb21tb24gPSByZXN1bHQgPT09IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIHJlc3VsdCA9IHNyY1ZhbHVlO1xuICAgICAgICBpZiAoaXNBcnJheUxpa2Uoc3JjVmFsdWUpICYmIChpc0FycmF5KHNyY1ZhbHVlKSB8fCBpc1R5cGVkQXJyYXkoc3JjVmFsdWUpKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgICA6IChpc0FycmF5TGlrZSh2YWx1ZSkgPyBhcnJheUNvcHkodmFsdWUpIDogW10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzUGxhaW5PYmplY3Qoc3JjVmFsdWUpIHx8IGlzQXJndW1lbnRzKHNyY1ZhbHVlKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGlzQXJndW1lbnRzKHZhbHVlKVxuICAgICAgICAgICAgPyB0b1BsYWluT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgOiAoaXNQbGFpbk9iamVjdCh2YWx1ZSkgPyB2YWx1ZSA6IHt9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBBZGQgdGhlIHNvdXJjZSB2YWx1ZSB0byB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMgYW5kIGFzc29jaWF0ZVxuICAgICAgLy8gaXQgd2l0aCBpdHMgbWVyZ2VkIHZhbHVlLlxuICAgICAgc3RhY2tBLnB1c2goc3JjVmFsdWUpO1xuICAgICAgc3RhY2tCLnB1c2gocmVzdWx0KTtcblxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBvYmplY3Rba2V5XSA9IG1lcmdlRnVuYyhyZXN1bHQsIHNyY1ZhbHVlLCBjdXN0b21pemVyLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlc3VsdCAhPT0gdmFsdWUpIDogKHZhbHVlID09PSB2YWx1ZSkpIHtcbiAgICAgICAgb2JqZWN0W2tleV0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gICAgICB2YXIgcGF0aEtleSA9IChwYXRoICsgJycpO1xuICAgICAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHVsbEF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBpbmRleCBhcmd1bWVudHMgYW5kIGNhcHR1cmluZyB0aGUgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfSBpbmRleGVzIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBpbmRleGVzLmxlbmd0aCA6IDA7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBpZiAoaW5kZXggIT0gcHJldmlvdXMgJiYgaXNJbmRleChpbmRleCkpIHtcbiAgICAgICAgICB2YXIgcHJldmlvdXMgPSBpbmRleDtcbiAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZG9tYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nXG4gICAgICogYW5kIHJldHVybmluZyBmbG9hdGluZy1wb2ludCBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluIFRoZSBtaW5pbXVtIHBvc3NpYmxlIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtYXggVGhlIG1heGltdW0gcG9zc2libGUgdmFsdWUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcmFuZG9tIG51bWJlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmFuZG9tKG1pbiwgbWF4KSB7XG4gICAgICByZXR1cm4gbWluICsgbmF0aXZlRmxvb3IobmF0aXZlUmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlZHVjZWAgYW5kIGBfLnJlZHVjZVJpZ2h0YCB3aXRob3V0IHN1cHBvcnRcbiAgICAgKiBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYGNvbGxlY3Rpb25gXG4gICAgICogdXNpbmcgdGhlIHByb3ZpZGVkIGBlYWNoRnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5pdEZyb21Db2xsZWN0aW9uIFNwZWNpZnkgdXNpbmcgdGhlIGZpcnN0IG9yIGxhc3QgZWxlbWVudFxuICAgICAqICBvZiBgY29sbGVjdGlvbmAgYXMgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VSZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0RnJvbUNvbGxlY3Rpb24sIGVhY2hGdW5jKSB7XG4gICAgICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgYWNjdW11bGF0b3IgPSBpbml0RnJvbUNvbGxlY3Rpb25cbiAgICAgICAgICA/IChpbml0RnJvbUNvbGxlY3Rpb24gPSBmYWxzZSwgdmFsdWUpXG4gICAgICAgICAgOiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBiYXNlU2V0RGF0YSA9ICFtZXRhTWFwID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBkYXRhKSB7XG4gICAgICBtZXRhTWFwLnNldChmdW5jLCBkYXRhKTtcbiAgICAgIHJldHVybiBmdW5jO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zbGljZWAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6ICgrc3RhcnQgfHwgMCk7XG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gICAgICB9XG4gICAgICBlbmQgPSAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gbGVuZ3RoKSA/IGxlbmd0aCA6ICgrZW5kIHx8IDApO1xuICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgZW5kICs9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgICAgIHN0YXJ0ID4+Pj0gMDtcblxuICAgICAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXggKyBzdGFydF07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvbWVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICAgICAqIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSBwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuICFyZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0QnlgIHdoaWNoIHVzZXMgYGNvbXBhcmVyYCB0byBkZWZpbmVcbiAgICAgKiB0aGUgc29ydCBvcmRlciBvZiBgYXJyYXlgIGFuZCByZXBsYWNlcyBjcml0ZXJpYSBvYmplY3RzIHdpdGggdGhlaXJcbiAgICAgKiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNvcnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyZXIgVGhlIGZ1bmN0aW9uIHRvIGRlZmluZSBzb3J0IG9yZGVyLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb3J0QnkoYXJyYXksIGNvbXBhcmVyKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBhcnJheS5zb3J0KGNvbXBhcmVyKTtcbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBhcnJheVtsZW5ndGhdID0gYXJyYXlbbGVuZ3RoXS52YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0QnlPcmRlcmAgd2l0aG91dCBwYXJhbSBndWFyZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBpdGVyYXRlZXMgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbltdfSBvcmRlcnMgVGhlIHNvcnQgb3JkZXJzIG9mIGBpdGVyYXRlZXNgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydEJ5T3JkZXIoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpIHtcbiAgICAgIHZhciBjYWxsYmFjayA9IGdldENhbGxiYWNrKCksXG4gICAgICAgICAgaW5kZXggPSAtMTtcblxuICAgICAgaXRlcmF0ZWVzID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBmdW5jdGlvbihpdGVyYXRlZSkgeyByZXR1cm4gY2FsbGJhY2soaXRlcmF0ZWUpOyB9KTtcblxuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VNYXAoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgdmFyIGNyaXRlcmlhID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBmdW5jdGlvbihpdGVyYXRlZSkgeyByZXR1cm4gaXRlcmF0ZWUodmFsdWUpOyB9KTtcbiAgICAgICAgcmV0dXJuIHsgJ2NyaXRlcmlhJzogY3JpdGVyaWEsICdpbmRleCc6ICsraW5kZXgsICd2YWx1ZSc6IHZhbHVlIH07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGJhc2VTb3J0QnkocmVzdWx0LCBmdW5jdGlvbihvYmplY3QsIG90aGVyKSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlTXVsdGlwbGUob2JqZWN0LCBvdGhlciwgb3JkZXJzKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnN1bWAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzXG4gICAgICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTdW0oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSAwO1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdCArPSAraXRlcmF0ZWUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB8fCAwO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuaXFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICAgICAqIGFuZCBgdGhpc2AgYmluZGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZS12YWx1ZS1mcmVlIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VVbmlxKGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5kZXhPZiA9IGdldEluZGV4T2YoKSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgaXNDb21tb24gPSBpbmRleE9mID09IGJhc2VJbmRleE9mLFxuICAgICAgICAgIGlzTGFyZ2UgPSBpc0NvbW1vbiAmJiBsZW5ndGggPj0gTEFSR0VfQVJSQVlfU0laRSxcbiAgICAgICAgICBzZWVuID0gaXNMYXJnZSA/IGNyZWF0ZUNhY2hlKCkgOiBudWxsLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICBpZiAoc2Vlbikge1xuICAgICAgICBpbmRleE9mID0gY2FjaGVJbmRleE9mO1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNMYXJnZSA9IGZhbHNlO1xuICAgICAgICBzZWVuID0gaXRlcmF0ZWUgPyBbXSA6IHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlLCBpbmRleCwgYXJyYXkpIDogdmFsdWU7XG5cbiAgICAgICAgaWYgKGlzQ29tbW9uICYmIHZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICAgIHZhciBzZWVuSW5kZXggPSBzZWVuLmxlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoc2VlbkluZGV4LS0pIHtcbiAgICAgICAgICAgIGlmIChzZWVuW3NlZW5JbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleE9mKHNlZW4sIGNvbXB1dGVkLCAwKSA8IDApIHtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUgfHwgaXNMYXJnZSkge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnZhbHVlc2AgYW5kIGBfLnZhbHVlc0luYCB3aGljaCBjcmVhdGVzIGFuXG4gICAgICogYXJyYXkgb2YgYG9iamVjdGAgcHJvcGVydHkgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzXG4gICAgICogb2YgYHByb3BzYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVZhbHVlcyhvYmplY3QsIHByb3BzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5kcm9wUmlnaHRXaGlsZWAsIGBfLmRyb3BXaGlsZWAsIGBfLnRha2VSaWdodFdoaWxlYCxcbiAgICAgKiBhbmQgYF8udGFrZVdoaWxlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEcm9wXSBTcGVjaWZ5IGRyb3BwaW5nIGVsZW1lbnRzIGluc3RlYWQgb2YgdGFraW5nIHRoZW0uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VXaGlsZShhcnJheSwgcHJlZGljYXRlLCBpc0Ryb3AsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSAmJiBwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7fVxuICAgICAgcmV0dXJuIGlzRHJvcFxuICAgICAgICA/IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IDAgOiBpbmRleCksIChmcm9tUmlnaHQgPyBpbmRleCArIDEgOiBsZW5ndGgpKVxuICAgICAgICA6IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IGluZGV4ICsgMSA6IDApLCAoZnJvbVJpZ2h0ID8gbGVuZ3RoIDogaW5kZXgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgd3JhcHBlclZhbHVlYCB3aGljaCByZXR1cm5zIHRoZSByZXN1bHQgb2ZcbiAgICAgKiBwZXJmb3JtaW5nIGEgc2VxdWVuY2Ugb2YgYWN0aW9ucyBvbiB0aGUgdW53cmFwcGVkIGB2YWx1ZWAsIHdoZXJlIGVhY2hcbiAgICAgKiBzdWNjZXNzaXZlIGFjdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFjdGlvbnMgQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlV3JhcHBlclZhbHVlKHZhbHVlLCBhY3Rpb25zKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdmFsdWU7XG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnZhbHVlKCk7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhY3Rpb25zLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGFjdGlvbiA9IGFjdGlvbnNbaW5kZXhdO1xuICAgICAgICByZXN1bHQgPSBhY3Rpb24uZnVuYy5hcHBseShhY3Rpb24udGhpc0FyZywgYXJyYXlQdXNoKFtyZXN1bHRdLCBhY3Rpb24uYXJncykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiaW5hcnlJbmRleChhcnJheSwgdmFsdWUsIHJldEhpZ2hlc3QpIHtcbiAgICAgIHZhciBsb3cgPSAwLFxuICAgICAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PT0gdmFsdWUgJiYgaGlnaCA8PSBIQUxGX01BWF9BUlJBWV9MRU5HVEgpIHtcbiAgICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgICAgICBjb21wdXRlZCA9IGFycmF5W21pZF07XG5cbiAgICAgICAgICBpZiAoKHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpKSAmJiBjb21wdXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmluYXJ5SW5kZXhCeShhcnJheSwgdmFsdWUsIGlkZW50aXR5LCByZXRIaWdoZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJpbmFyeUluZGV4YCBleGNlcHQgdGhhdCBpdCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yXG4gICAgICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICAgICAqIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEhpZ2hlc3RdIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBoaWdoZXN0IHF1YWxpZmllZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmluYXJ5SW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlLCByZXRIaWdoZXN0KSB7XG4gICAgICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgdmFyIGxvdyA9IDAsXG4gICAgICAgICAgaGlnaCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgICAgICB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICB2YWxJc1VuZGVmID0gdmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgdmFyIG1pZCA9IG5hdGl2ZUZsb29yKChsb3cgKyBoaWdoKSAvIDIpLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZShhcnJheVttaWRdKSxcbiAgICAgICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzUmVmbGV4aXZlID0gY29tcHV0ZWQgPT09IGNvbXB1dGVkO1xuXG4gICAgICAgIGlmICh2YWxJc05hTikge1xuICAgICAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzTnVsbCkge1xuICAgICAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIGlzRGVmICYmIChyZXRIaWdoZXN0IHx8IGNvbXB1dGVkICE9IG51bGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiAocmV0SGlnaGVzdCB8fCBpc0RlZik7XG4gICAgICAgIH0gZWxzZSBpZiAoY29tcHV0ZWQgPT0gbnVsbCkge1xuICAgICAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldExvdyA9IHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXRMb3cpIHtcbiAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBuYXRpdmVNaW4oaGlnaCwgTUFYX0FSUkFZX0lOREVYKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VDYWxsYmFja2Agd2hpY2ggb25seSBzdXBwb3J0cyBgdGhpc2AgYmluZGluZ1xuICAgICAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICAgICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gaWRlbnRpdHk7XG4gICAgICB9XG4gICAgICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmdW5jO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgICAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUpO1xuICAgICAgICB9O1xuICAgICAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICAgIH07XG4gICAgICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgICB9O1xuICAgICAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gYXJyYXkgYnVmZmVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXlCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBhcnJheSBidWZmZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYnVmZmVyQ2xvbmUoYnVmZmVyKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5QnVmZmVyKGJ1ZmZlci5ieXRlTGVuZ3RoKSxcbiAgICAgICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICAgICAgdmlldy5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICAgICAqIHBsYWNlaG9sZGVycywgYW5kIHByb3ZpZGVkIGFyZ3VtZW50cyBpbnRvIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICAgICAgdmFyIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsrYXJnc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gICAgICogaXMgdGFpbG9yZWQgZm9yIGBfLnBhcnRpYWxSaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gICAgICB2YXIgaG9sZGVyc0luZGV4ID0gLTEsXG4gICAgICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICAgIGFyZ3NMZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkoYXJnc0xlbmd0aCArIHJpZ2h0TGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsrYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgICAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICAgIH1cbiAgICAgIHZhciBvZmZzZXQgPSBhcmdzSW5kZXg7XG4gICAgICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W29mZnNldCArIHJpZ2h0SW5kZXhdID0gcGFydGlhbHNbcmlnaHRJbmRleF07XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtvZmZzZXQgKyBob2xkZXJzW2hvbGRlcnNJbmRleF1dID0gYXJnc1thcmdzSW5kZXgrK107XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5jb3VudEJ5YCwgYF8uZ3JvdXBCeWAsIGBfLmluZGV4QnlgLCBvciBgXy5wYXJ0aXRpb25gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBrZXlzIGFuZCB2YWx1ZXMgb2YgdGhlIGFjY3VtdWxhdG9yIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaW5pdGlhbGl6ZXJdIFRoZSBmdW5jdGlvbiB0byBpbml0aWFsaXplIHRoZSBhY2N1bXVsYXRvciBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWdncmVnYXRvciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVBZ2dyZWdhdG9yKHNldHRlciwgaW5pdGlhbGl6ZXIpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gaW5pdGlhbGl6ZXIgPyBpbml0aWFsaXplcigpIDoge307XG4gICAgICAgIGl0ZXJhdGVlID0gZ2V0Q2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuXG4gICAgICAgIGlmIChpc0FycmF5KGNvbGxlY3Rpb24pKSB7XG4gICAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICAgIGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuXG4gICAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGNvbGxlY3Rpb25baW5kZXhdO1xuICAgICAgICAgICAgc2V0dGVyKHJlc3VsdCwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbiksIGNvbGxlY3Rpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICBzZXR0ZXIocmVzdWx0LCB2YWx1ZSwgaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbiksIGNvbGxlY3Rpb24pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5hc3NpZ25gLCBgXy5kZWZhdWx0c2AsIG9yIGBfLm1lcmdlYCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXNzaWduZXIgVGhlIGZ1bmN0aW9uIHRvIGFzc2lnbiB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYXNzaWduZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQXNzaWduZXIoYXNzaWduZXIpIHtcbiAgICAgIHJldHVybiByZXN0UGFyYW0oZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID09IG51bGwgPyAwIDogc291cmNlcy5sZW5ndGgsXG4gICAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoID4gMiA/IHNvdXJjZXNbbGVuZ3RoIC0gMl0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBndWFyZCA9IGxlbmd0aCA+IDIgPyBzb3VyY2VzWzJdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdGhpc0FyZyA9IGxlbmd0aCA+IDEgPyBzb3VyY2VzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmICh0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgY3VzdG9taXplciA9IGJpbmRDYWxsYmFjayhjdXN0b21pemVyLCB0aGlzQXJnLCA1KTtcbiAgICAgICAgICBsZW5ndGggLT0gMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXN0b21pemVyID0gdHlwZW9mIHRoaXNBcmcgPT0gJ2Z1bmN0aW9uJyA/IHRoaXNBcmcgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgbGVuZ3RoIC09IChjdXN0b21pemVyID8gMSA6IDApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IGN1c3RvbWl6ZXI7XG4gICAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgICAgICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgICAgICBhc3NpZ25lcihvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICAgICAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSxcbiAgICAgICAgICAgIGl0ZXJhYmxlID0gdG9PYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVbaW5kZXhdLCBpbmRleCwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICAgICAgdmFyIGl0ZXJhYmxlID0gdG9PYmplY3Qob2JqZWN0KSxcbiAgICAgICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgICAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgICAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCaW5kV3JhcHBlcihmdW5jLCB0aGlzQXJnKSB7XG4gICAgICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgU2V0YCBjYWNoZSBvYmplY3QgdG8gb3B0aW1pemUgbGluZWFyIHNlYXJjaGVzIG9mIGxhcmdlIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxPYmplY3R9IFJldHVybnMgdGhlIG5ldyBjYWNoZSBvYmplY3QgaWYgYFNldGAgaXMgc3VwcG9ydGVkLCBlbHNlIGBudWxsYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDYWNoZSh2YWx1ZXMpIHtcbiAgICAgIHJldHVybiAobmF0aXZlQ3JlYXRlICYmIFNldCkgPyBuZXcgU2V0Q2FjaGUodmFsdWVzKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgY29tcG91bmQgd29yZHMgb3V0IG9mIHRoZSB3b3JkcyBpbiBhXG4gICAgICogZ2l2ZW4gc3RyaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gY29tYmluZSBlYWNoIHdvcmQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG91bmRlciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDb21wb3VuZGVyKGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgYXJyYXkgPSB3b3JkcyhkZWJ1cnIoc3RyaW5nKSksXG4gICAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgICByZXN1bHQgPSAnJztcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrKHJlc3VsdCwgYXJyYXlbaW5kZXhdLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgKiB3aGV0aGVyIGl0IHdhcyBpbnZva2VkIGFzIHBhcnQgb2YgYSBgbmV3YCBleHByZXNzaW9uIG9yIGJ5IGBjYWxsYCBvciBgYXBwbHlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBDdG9yIFRoZSBjb25zdHJ1Y3RvciB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3RvcldyYXBwZXIoQ3Rvcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAgICAgLy8gU2VlIGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWVjbWFzY3JpcHQtZnVuY3Rpb24tb2JqZWN0cy1jYWxsLXRoaXNhcmd1bWVudC1hcmd1bWVudHNsaXN0XG4gICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEN0b3I7XG4gICAgICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICAgICAgY2FzZSAyOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSk7XG4gICAgICAgICAgY2FzZSA2OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7XG4gICAgICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRoaXNCaW5kaW5nID0gYmFzZUNyZWF0ZShDdG9yLnByb3RvdHlwZSksXG4gICAgICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgICAgICAvLyBNaW1pYyB0aGUgY29uc3RydWN0b3IncyBgcmV0dXJuYCBiZWhhdmlvci5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDEzLjIuMiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uY3VycnlgIG9yIGBfLmN1cnJ5UmlnaHRgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZsYWcgVGhlIGN1cnJ5IGJpdCBmbGFnLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJ5IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUN1cnJ5KGZsYWcpIHtcbiAgICAgIGZ1bmN0aW9uIGN1cnJ5RnVuYyhmdW5jLCBhcml0eSwgZ3VhcmQpIHtcbiAgICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGZ1bmMsIGFyaXR5LCBndWFyZCkpIHtcbiAgICAgICAgICBhcml0eSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcHBlcihmdW5jLCBmbGFnLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJpdHkpO1xuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeUZ1bmMucGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VycnlGdW5jO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5kZWZhdWx0c2Agb3IgYF8uZGVmYXVsdHNEZWVwYCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXNzaWduZXIgVGhlIGZ1bmN0aW9uIHRvIGFzc2lnbiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBkZWZhdWx0cyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0cyhhc3NpZ25lciwgY3VzdG9taXplcikge1xuICAgICAgcmV0dXJuIHJlc3RQYXJhbShmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHZhciBvYmplY3QgPSBhcmdzWzBdO1xuICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGFyZ3MucHVzaChjdXN0b21pemVyKTtcbiAgICAgICAgcmV0dXJuIGFzc2lnbmVyLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8ubWF4YCBvciBgXy5taW5gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGNvbXBhcmUgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7Kn0gZXhWYWx1ZSBUaGUgaW5pdGlhbCBleHRyZW11bSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBleHRyZW11bSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVFeHRyZW11bShjb21wYXJhdG9yLCBleFZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICAgICAgaWYgKHRoaXNBcmcgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpKSB7XG4gICAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgaXRlcmF0ZWUgPSBnZXRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gICAgICAgIGlmIChpdGVyYXRlZS5sZW5ndGggPT0gMSkge1xuICAgICAgICAgIGNvbGxlY3Rpb24gPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gY29sbGVjdGlvbiA6IHRvSXRlcmFibGUoY29sbGVjdGlvbik7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGFycmF5RXh0cmVtdW0oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IsIGV4VmFsdWUpO1xuICAgICAgICAgIGlmICghKGNvbGxlY3Rpb24ubGVuZ3RoICYmIHJlc3VsdCA9PT0gZXhWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlRXh0cmVtdW0oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IsIGV4VmFsdWUpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUZpbmQoZWFjaEZ1bmMsIGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgICBwcmVkaWNhdGUgPSBnZXRDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgICAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHZhciBpbmRleCA9IGJhc2VGaW5kSW5kZXgoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBmcm9tUmlnaHQpO1xuICAgICAgICAgIHJldHVybiBpbmRleCA+IC0xID8gY29sbGVjdGlvbltpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmluZEluZGV4YCBvciBgXy5maW5kTGFzdEluZGV4YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGaW5kSW5kZXgoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIHByZWRpY2F0ZSA9IGdldENhbGxiYWNrKHByZWRpY2F0ZSwgdGhpc0FyZywgMyk7XG4gICAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5maW5kS2V5YCBvciBgXy5maW5kTGFzdEtleWAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9iamVjdEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhbiBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGaW5kS2V5KG9iamVjdEZ1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QsIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgICBwcmVkaWNhdGUgPSBnZXRDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgICAgICByZXR1cm4gYmFzZUZpbmQob2JqZWN0LCBwcmVkaWNhdGUsIG9iamVjdEZ1bmMsIHRydWUpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmxvd2Agb3IgYF8uZmxvd1JpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxvdyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGbG93KGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgd3JhcHBlcixcbiAgICAgICAgICAgIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICAgICAgbGVmdEluZGV4ID0gMCxcbiAgICAgICAgICAgIGZ1bmNzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgICAgIHZhciBmdW5jID0gZnVuY3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXdyYXBwZXIgJiYgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUudGhydSAmJiBnZXRGdW5jTmFtZShmdW5jKSA9PSAnd3JhcHBlcicpIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSBuZXcgTG9kYXNoV3JhcHBlcihbXSwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gd3JhcHBlciA/IC0xIDogbGVuZ3RoO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGZ1bmMgPSBmdW5jc1tpbmRleF07XG5cbiAgICAgICAgICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgICAgICAgICAgZGF0YSA9IGZ1bmNOYW1lID09ICd3cmFwcGVyJyA/IGdldERhdGEoZnVuYykgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0xhemlhYmxlKGRhdGFbMF0pICYmIGRhdGFbMV0gPT0gKEFSWV9GTEFHIHwgQ1VSUllfRkxBRyB8IFBBUlRJQUxfRkxBRyB8IFJFQVJHX0ZMQUcpICYmICFkYXRhWzRdLmxlbmd0aCAmJiBkYXRhWzldID09IDEpIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSB3cmFwcGVyW2dldEZ1bmNOYW1lKGRhdGFbMF0pXS5hcHBseSh3cmFwcGVyLCBkYXRhWzNdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcHBlciA9IChmdW5jLmxlbmd0aCA9PSAxICYmIGlzTGF6aWFibGUoZnVuYykpID8gd3JhcHBlcltmdW5jTmFtZV0oKSA6IHdyYXBwZXIudGhydShmdW5jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgICB2YWx1ZSA9IGFyZ3NbMF07XG5cbiAgICAgICAgICBpZiAod3JhcHBlciAmJiBhcmdzLmxlbmd0aCA9PSAxICYmIGlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlci5wbGFudCh2YWx1ZSkudmFsdWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gbGVuZ3RoID8gZnVuY3NbaW5kZXhdLmFwcGx5KHRoaXMsIGFyZ3MpIDogdmFsdWU7XG5cbiAgICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuY3NbaW5kZXhdLmNhbGwodGhpcywgcmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5mb3JFYWNoYCBvciBgXy5mb3JFYWNoUmlnaHRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhcnJheUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhbiBhcnJheS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUZvckVhY2goYXJyYXlGdW5jLCBlYWNoRnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgICAgIHJldHVybiAodHlwZW9mIGl0ZXJhdGVlID09ICdmdW5jdGlvbicgJiYgdGhpc0FyZyA9PT0gdW5kZWZpbmVkICYmIGlzQXJyYXkoY29sbGVjdGlvbikpXG4gICAgICAgICAgPyBhcnJheUZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpXG4gICAgICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5mb3JJbmAgb3IgYF8uZm9ySW5SaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9iamVjdEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhbiBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZWFjaCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGb3JJbihvYmplY3RGdW5jKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZXJhdGVlICE9ICdmdW5jdGlvbicgfHwgdGhpc0FyZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaXRlcmF0ZWUgPSBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3RGdW5jKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNJbik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBmb3IgYF8uZm9yT3duYCBvciBgXy5mb3JPd25SaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9iamVjdEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhbiBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZWFjaCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGb3JPd24ob2JqZWN0RnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVyYXRlZSAhPSAnZnVuY3Rpb24nIHx8IHRoaXNBcmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGl0ZXJhdGVlID0gYmluZENhbGxiYWNrKGl0ZXJhdGVlLCB0aGlzQXJnLCAzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0RnVuYyhvYmplY3QsIGl0ZXJhdGVlKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5tYXBLZXlzYCBvciBgXy5tYXBWYWx1ZXNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc01hcEtleXNdIFNwZWNpZnkgbWFwcGluZyBrZXlzIGluc3RlYWQgb2YgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1hcCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVPYmplY3RNYXBwZXIoaXNNYXBLZXlzKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgIGl0ZXJhdGVlID0gZ2V0Q2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuXG4gICAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgICB2YXIgbWFwcGVkID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgb2JqZWN0KTtcbiAgICAgICAgICBrZXkgPSBpc01hcEtleXMgPyBtYXBwZWQgOiBrZXk7XG4gICAgICAgICAgdmFsdWUgPSBpc01hcEtleXMgPyB2YWx1ZSA6IG1hcHBlZDtcbiAgICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5wYWRMZWZ0YCBvciBgXy5wYWRSaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBwYWRkaW5nIGZyb20gdGhlIHJpZ2h0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYWREaXIoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICAgIHN0cmluZyA9IGJhc2VUb1N0cmluZyhzdHJpbmcpO1xuICAgICAgICByZXR1cm4gKGZyb21SaWdodCA/IHN0cmluZyA6ICcnKSArIGNyZWF0ZVBhZGRpbmcoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSArIChmcm9tUmlnaHQgPyAnJyA6IHN0cmluZyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5wYXJ0aWFsYCBvciBgXy5wYXJ0aWFsUmlnaHRgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZsYWcgVGhlIHBhcnRpYWwgYml0IGZsYWcuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcGFydGlhbCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYXJ0aWFsKGZsYWcpIHtcbiAgICAgIHZhciBwYXJ0aWFsRnVuYyA9IHJlc3RQYXJhbShmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBwYXJ0aWFsRnVuYy5wbGFjZWhvbGRlcik7XG4gICAgICAgIHJldHVybiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGZsYWcsIHVuZGVmaW5lZCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcGFydGlhbEZ1bmM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5yZWR1Y2VgIG9yIGBfLnJlZHVjZVJpZ2h0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYW4gYXJyYXkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZWFjaCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVSZWR1Y2UoYXJyYXlGdW5jLCBlYWNoRnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgdGhpc0FyZykge1xuICAgICAgICB2YXIgaW5pdEZyb21BcnJheSA9IGFyZ3VtZW50cy5sZW5ndGggPCAzO1xuICAgICAgICByZXR1cm4gKHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIHRoaXNBcmcgPT09IHVuZGVmaW5lZCAmJiBpc0FycmF5KGNvbGxlY3Rpb24pKVxuICAgICAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEZyb21BcnJheSlcbiAgICAgICAgICA6IGJhc2VSZWR1Y2UoY29sbGVjdGlvbiwgZ2V0Q2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDQpLCBhY2N1bXVsYXRvciwgaW5pdEZyb21BcnJheSwgZWFjaEZ1bmMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzUmlnaHRdIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICAgICAgaXNCaW5kID0gYml0bWFzayAmIEJJTkRfRkxBRyxcbiAgICAgICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICAgICAgaXNDdXJyeUJvdW5kID0gYml0bWFzayAmIENVUlJZX0JPVU5EX0ZMQUcsXG4gICAgICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgICAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRpYWxzKSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQ3VycnkgfHwgaXNDdXJyeVJpZ2h0KSB7XG4gICAgICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgICAgICBsZW5ndGggLT0gYXJnc0hvbGRlcnMubGVuZ3RoO1xuICAgICAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG5ld0FyaXR5ID0gbmF0aXZlTWF4KGFyaXR5IC0gbGVuZ3RoLCAwKSxcbiAgICAgICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICAgICAgbmV3UGFydGlhbHMgPSBpc0N1cnJ5ID8gYXJncyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICAgICAgYml0bWFzayAmPSB+KGlzQ3VycnkgPyBQQVJUSUFMX1JJR0hUX0ZMQUcgOiBQQVJUSUFMX0ZMQUcpO1xuXG4gICAgICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgICAgIGlmIChpc0xhemlhYmxlKGZ1bmMpKSB7XG4gICAgICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdC5wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgICAgICBpZiAoYXJnUG9zKSB7XG4gICAgICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgYXJncy5sZW5ndGgpIHtcbiAgICAgICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoZSBwYWRkaW5nIHJlcXVpcmVkIGZvciBgc3RyaW5nYCBiYXNlZCBvbiB0aGUgZ2l2ZW4gYGxlbmd0aGAuXG4gICAgICogVGhlIGBjaGFyc2Agc3RyaW5nIGlzIHRydW5jYXRlZCBpZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZXhjZWVkcyBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNyZWF0ZSBwYWRkaW5nIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZCBmb3IgYHN0cmluZ2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUGFkZGluZyhzdHJpbmcsIGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIHZhciBzdHJMZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgbGVuZ3RoID0gK2xlbmd0aDtcblxuICAgICAgaWYgKHN0ckxlbmd0aCA+PSBsZW5ndGggfHwgIW5hdGl2ZUlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgICAgdmFyIHBhZExlbmd0aCA9IGxlbmd0aCAtIHN0ckxlbmd0aDtcbiAgICAgIGNoYXJzID0gY2hhcnMgPT0gbnVsbCA/ICcgJyA6IChjaGFycyArICcnKTtcbiAgICAgIHJldHVybiByZXBlYXQoY2hhcnMsIG5hdGl2ZUNlaWwocGFkTGVuZ3RoIC8gY2hhcnMubGVuZ3RoKSkuc2xpY2UoMCwgcGFkTGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AgYW5kIHRoZSBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aG9zZSBwcm92aWRlZCB0b1xuICAgICAqIHRoZSB3cmFwcGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIG9mIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBwZXJgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgICAgIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAgICAgLy8gY29udmVydGluZyBpdCB0byBhbiBhcnJheSBiZWZvcmUgcHJvdmlkaW5nIGl0IGBmdW5jYC5cbiAgICAgICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVmdExlbmd0aCArIGFyZ3NMZW5ndGgpO1xuXG4gICAgICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICAgICAgcmV0dXJuIGZuLmFwcGx5KGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5jZWlsYCwgYF8uZmxvb3JgLCBvciBgXy5yb3VuZGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2ROYW1lIFRoZSBuYW1lIG9mIHRoZSBgTWF0aGAgbWV0aG9kIHRvIHVzZSB3aGVuIHJvdW5kaW5nLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJvdW5kIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJvdW5kKG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBmdW5jID0gTWF0aFttZXRob2ROYW1lXTtcbiAgICAgIHJldHVybiBmdW5jdGlvbihudW1iZXIsIHByZWNpc2lvbikge1xuICAgICAgICBwcmVjaXNpb24gPSBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/IDAgOiAoK3ByZWNpc2lvbiB8fCAwKTtcbiAgICAgICAgaWYgKHByZWNpc2lvbikge1xuICAgICAgICAgIHByZWNpc2lvbiA9IHBvdygxMCwgcHJlY2lzaW9uKTtcbiAgICAgICAgICByZXR1cm4gZnVuYyhudW1iZXIgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jKG51bWJlcik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5zb3J0ZWRJbmRleGAgb3IgYF8uc29ydGVkTGFzdEluZGV4YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGluZGV4IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVNvcnRlZEluZGV4KHJldEhpZ2hlc3QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihhcnJheSwgdmFsdWUsIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGdldENhbGxiYWNrKGl0ZXJhdGVlKTtcbiAgICAgICAgcmV0dXJuIChpdGVyYXRlZSA9PSBudWxsICYmIGNhbGxiYWNrID09PSBiYXNlQ2FsbGJhY2spXG4gICAgICAgICAgPyBiaW5hcnlJbmRleChhcnJheSwgdmFsdWUsIHJldEhpZ2hlc3QpXG4gICAgICAgICAgOiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgY2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDEpLCByZXRIaWdoZXN0KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZWl0aGVyIGN1cnJpZXMgb3IgaW52b2tlcyBgZnVuY2Agd2l0aCBvcHRpb25hbFxuICAgICAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gICAgICogIFRoZSBiaXRtYXNrIG1heSBiZSBjb21wb3NlZCBvZiB0aGUgZm9sbG93aW5nIGZsYWdzOlxuICAgICAqICAgICAxIC0gYF8uYmluZGBcbiAgICAgKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gICAgICogICAgIDQgLSBgXy5jdXJyeWAgb3IgYF8uY3VycnlSaWdodGAgb2YgYSBib3VuZCBmdW5jdGlvblxuICAgICAqICAgICA4IC0gYF8uY3VycnlgXG4gICAgICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICAgICAqICAgIDMyIC0gYF8ucGFydGlhbGBcbiAgICAgKiAgICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAgICAgKiAgIDEyOCAtIGBfLnJlYXJnYFxuICAgICAqICAgMjU2IC0gYF8uYXJ5YFxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzXSBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICAgICAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBCSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgYml0bWFzayAmPSB+KFBBUlRJQUxfRkxBRyB8IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCAtPSAoaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMCk7XG4gICAgICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgICAgICB2YXIgcGFydGlhbHNSaWdodCA9IHBhcnRpYWxzLFxuICAgICAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgICAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyksXG4gICAgICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgICAgICBhcml0eSA9IG5ld0RhdGFbOV07XG4gICAgICB9XG4gICAgICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgICAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgICAgIDogKG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCkgfHwgMCk7XG5cbiAgICAgIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlQmluZFdyYXBwZXIobmV3RGF0YVswXSwgbmV3RGF0YVsyXSk7XG4gICAgICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFBBUlRJQUxfRkxBRyB8fCBiaXRtYXNrID09IChCSU5EX0ZMQUcgfCBQQVJUSUFMX0ZMQUcpKSAmJiAhbmV3RGF0YVs0XS5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHZhciBzZXR0ZXIgPSBkYXRhID8gYmFzZVNldERhdGEgOiBzZXREYXRhO1xuICAgICAgcmV0dXJuIHNldHRlcihyZXN1bHQsIG5ld0RhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAgICAgKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgYXJyYXlzLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gICAgICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKGlzTG9vc2UgPyBvdGhWYWx1ZSA6IGFyclZhbHVlLCBpc0xvb3NlID8gYXJyVmFsdWUgOiBvdGhWYWx1ZSwgaW5kZXgpIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgICAgICBpZiAoIWFycmF5U29tZShvdGhlciwgZnVuY3Rpb24ob3RoVmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICAgICAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnKSB7XG4gICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICBjYXNlIGJvb2xUYWc6XG4gICAgICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgICAgICAvLyB0byBgMWAgb3IgYDBgIHRyZWF0aW5nIGludmFsaWQgZGF0ZXMgY29lcmNlZCB0byBgTmFOYCBhcyBub3QgZXF1YWwuXG4gICAgICAgICAgcmV0dXJuICtvYmplY3QgPT0gK290aGVyO1xuXG4gICAgICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgICAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICAgICAgcmV0dXJuIChvYmplY3QgIT0gK29iamVjdClcbiAgICAgICAgICAgID8gb3RoZXIgIT0gK290aGVyXG4gICAgICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAgICAgLy8gb2JqZWN0cyBhcyBlcXVhbC4gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEwLjYuNCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICAgIHJldHVybiBvYmplY3QgPT0gKG90aGVyICsgJycpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gICAgICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgICAgIG90aFByb3BzID0ga2V5cyhvdGhlciksXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gICAgICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNMb29zZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7XG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgICAgICBpZiAoIShpc0xvb3NlID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBza2lwQ3RvciA9IGlzTG9vc2U7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgICAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogb2JqVmFsdWUsIGlzTG9vc2U/IG9ialZhbHVlIDogb3RoVmFsdWUsIGtleSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXNraXBDdG9yKSB7XG4gICAgICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLlxuICAgICAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBvYmplY3QgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvdGhlcikgJiZcbiAgICAgICAgICAgICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJlxuICAgICAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXBwcm9wcmlhdGUgXCJjYWxsYmFja1wiIGZ1bmN0aW9uLiBJZiB0aGUgYF8uY2FsbGJhY2tgIG1ldGhvZCBpc1xuICAgICAqIGN1c3RvbWl6ZWQgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBjdXN0b20gbWV0aG9kLCBvdGhlcndpc2UgaXQgcmV0dXJuc1xuICAgICAqIHRoZSBgYmFzZUNhbGxiYWNrYCBmdW5jdGlvbi4gSWYgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0aGUgY2hvc2VuIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCB3aXRoIHRoZW0gYW5kIGl0cyByZXN1bHQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2hvc2VuIGZ1bmN0aW9uIG9yIGl0cyByZXN1bHQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0Q2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpIHtcbiAgICAgIHZhciByZXN1bHQgPSBsb2Rhc2guY2FsbGJhY2sgfHwgY2FsbGJhY2s7XG4gICAgICByZXN1bHQgPSByZXN1bHQgPT09IGNhbGxiYWNrID8gYmFzZUNhbGxiYWNrIDogcmVzdWx0O1xuICAgICAgcmV0dXJuIGFyZ0NvdW50ID8gcmVzdWx0KGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICAgICAgcmV0dXJuIG1ldGFNYXAuZ2V0KGZ1bmMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gZnVuYy5uYW1lLFxuICAgICAgICAgIGFycmF5ID0gcmVhbE5hbWVzW3Jlc3VsdF0sXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGRhdGEgPSBhcnJheVtsZW5ndGhdLFxuICAgICAgICAgICAgb3RoZXJGdW5jID0gZGF0YS5mdW5jO1xuICAgICAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgICAgICByZXR1cm4gZGF0YS5uYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGFwcHJvcHJpYXRlIFwiaW5kZXhPZlwiIGZ1bmN0aW9uLiBJZiB0aGUgYF8uaW5kZXhPZmAgbWV0aG9kIGlzXG4gICAgICogY3VzdG9taXplZCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGN1c3RvbSBtZXRob2QsIG90aGVyd2lzZSBpdCByZXR1cm5zXG4gICAgICogdGhlIGBiYXNlSW5kZXhPZmAgZnVuY3Rpb24uIElmIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQgdGhlIGNob3NlbiBmdW5jdGlvblxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0aGVtIGFuZCBpdHMgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb258bnVtYmVyfSBSZXR1cm5zIHRoZSBjaG9zZW4gZnVuY3Rpb24gb3IgaXRzIHJlc3VsdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRJbmRleE9mKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoLmluZGV4T2YgfHwgaW5kZXhPZjtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gaW5kZXhPZiA/IGJhc2VJbmRleE9mIDogcmVzdWx0O1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb24gPyByZXN1bHQoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpIDogcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgdmFsdWUgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGF2b2lkIGEgW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpXG4gICAgICogdGhhdCBhZmZlY3RzIFNhZmFyaSBvbiBhdCBsZWFzdCBpT1MgOC4xLTguMyBBUk02NC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICAgICAqL1xuICAgIHZhciBnZXRMZW5ndGggPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcHJvcGVyeSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRNYXRjaERhdGEob2JqZWN0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkge1xuICAgICAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgICAgIHJldHVybiBpc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB2aWV3LCBhcHBseWluZyBhbnkgYHRyYW5zZm9ybXNgIHRvIHRoZSBgc3RhcnRgIGFuZCBgZW5kYCBwb3NpdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgb2YgdGhlIHZpZXcuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSB2aWV3LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHRyYW5zZm9ybXMgVGhlIHRyYW5zZm9ybWF0aW9ucyB0byBhcHBseSB0byB0aGUgdmlldy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBgc3RhcnRgIGFuZCBgZW5kYFxuICAgICAqICBwb3NpdGlvbnMgb2YgdGhlIHZpZXcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0VmlldyhzdGFydCwgZW5kLCB0cmFuc2Zvcm1zKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSB0cmFuc2Zvcm1zLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGRhdGEgPSB0cmFuc2Zvcm1zW2luZGV4XSxcbiAgICAgICAgICAgIHNpemUgPSBkYXRhLnNpemU7XG5cbiAgICAgICAgc3dpdGNoIChkYXRhLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdkcm9wJzogICAgICBzdGFydCArPSBzaXplOyBicmVhaztcbiAgICAgICAgICBjYXNlICdkcm9wUmlnaHQnOiBlbmQgLT0gc2l6ZTsgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndGFrZSc6ICAgICAgZW5kID0gbmF0aXZlTWluKGVuZCwgc3RhcnQgKyBzaXplKTsgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndGFrZVJpZ2h0Jzogc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQsIGVuZCAtIHNpemUpOyBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHsgJ3N0YXJ0Jzogc3RhcnQsICdlbmQnOiBlbmQgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gbmV3IGFycmF5LmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgICAgIC8vIEFkZCBhcnJheSBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gICAgICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgICAgICByZXN1bHQuaW5kZXggPSBhcnJheS5pbmRleDtcbiAgICAgICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRDbG9uZU9iamVjdChvYmplY3QpIHtcbiAgICAgIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICAgICAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICAgICAgQ3RvciA9IE9iamVjdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQ3RvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUgYmFzZWQgb24gaXRzIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICAgICAqIGBCb29sZWFuYCwgYERhdGVgLCBgRXJyb3JgLCBgTnVtYmVyYCwgYFJlZ0V4cGAsIG9yIGBTdHJpbmdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICAgICAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgICAgIHJldHVybiBidWZmZXJDbG9uZShvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgYm9vbFRhZzpcbiAgICAgICAgY2FzZSBkYXRlVGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3Rvcigrb2JqZWN0KTtcblxuICAgICAgICBjYXNlIGZsb2F0MzJUYWc6IGNhc2UgZmxvYXQ2NFRhZzpcbiAgICAgICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgICAgICBjYXNlIHVpbnQ4VGFnOiBjYXNlIHVpbnQ4Q2xhbXBlZFRhZzogY2FzZSB1aW50MTZUYWc6IGNhc2UgdWludDMyVGFnOlxuICAgICAgICAgIHZhciBidWZmZXIgPSBvYmplY3QuYnVmZmVyO1xuICAgICAgICAgIHJldHVybiBuZXcgQ3Rvcihpc0RlZXAgPyBidWZmZXJDbG9uZShidWZmZXIpIDogYnVmZmVyLCBvYmplY3QuYnl0ZU9mZnNldCwgb2JqZWN0Lmxlbmd0aCk7XG5cbiAgICAgICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3RvcihvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgICAgIHZhciByZXN1bHQgPSBuZXcgQ3RvcihvYmplY3Quc291cmNlLCByZUZsYWdzLmV4ZWMob2JqZWN0KSk7XG4gICAgICAgICAgcmVzdWx0Lmxhc3RJbmRleCA9IG9iamVjdC5sYXN0SW5kZXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb24gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnZva2VQYXRoKG9iamVjdCwgcGF0aCwgYXJncykge1xuICAgICAgaWYgKG9iamVjdCAhPSBudWxsICYmICFpc0tleShwYXRoLCBvYmplY3QpKSB7XG4gICAgICAgIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gICAgICAgIG9iamVjdCA9IHBhdGgubGVuZ3RoID09IDEgPyBvYmplY3QgOiBiYXNlR2V0KG9iamVjdCwgYmFzZVNsaWNlKHBhdGgsIDAsIC0xKSk7XG4gICAgICAgIHBhdGggPSBsYXN0KHBhdGgpO1xuICAgICAgfVxuICAgICAgdmFyIGZ1bmMgPSBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IG9iamVjdFtwYXRoXTtcbiAgICAgIHJldHVybiBmdW5jID09IG51bGwgPyB1bmRlZmluZWQgOiBmdW5jLmFwcGx5KG9iamVjdCwgYXJncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aChnZXRMZW5ndGgodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7XG4gICAgICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gICAgICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gICAgICByZXR1cm4gdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHByb3ZpZGVkIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgdmFsdWUgYXJndW1lbnQuXG4gICAgICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDtcbiAgICAgIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgICAgICA6ICh0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkpIHtcbiAgICAgICAgdmFyIG90aGVyID0gb2JqZWN0W2luZGV4XTtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgaWYgKCh0eXBlID09ICdzdHJpbmcnICYmIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkpIHx8IHR5cGUgPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSk7XG4gICAgICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTGF6aWFibGUoZnVuYykge1xuICAgICAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyk7XG4gICAgICBpZiAoIShmdW5jTmFtZSBpbiBMYXp5V3JhcHBlci5wcm90b3R5cGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG4gICAgICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICAgICAgcmV0dXJuICEhZGF0YSAmJiBmdW5jID09PSBkYXRhWzBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyBiYXNlZCBvbiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9sZW5ndGgpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gICAgICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAgICAgKlxuICAgICAqIE1lcmdpbmcgbWV0YWRhdGEgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIHdyYXBwZXJzIHJlcXVpcmVkIHRvIGludm9rZSBhIGZ1bmN0aW9uLlxuICAgICAqIFRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtZXRob2RzIGxpa2UgYF8uYmluZGAsIGBfLmN1cnJ5YCwgYW5kIGBfLnBhcnRpYWxgXG4gICAgICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAgICAgKiBhdWdtZW50IGZ1bmN0aW9uIGFyZ3VtZW50cywgbWFraW5nIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFyZSBleGVjdXRlZCBpbXBvcnRhbnQsXG4gICAgICogcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZSBhbiBleGNlcHRpb24gZm9yIGEgc2FmZVxuICAgICAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgc291cmNlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGF0YWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVyZ2VEYXRhKGRhdGEsIHNvdXJjZSkge1xuICAgICAgdmFyIGJpdG1hc2sgPSBkYXRhWzFdLFxuICAgICAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICAgICAgbmV3Qml0bWFzayA9IGJpdG1hc2sgfCBzcmNCaXRtYXNrLFxuICAgICAgICAgIGlzQ29tbW9uID0gbmV3Qml0bWFzayA8IEFSWV9GTEFHO1xuXG4gICAgICB2YXIgaXNDb21ibyA9XG4gICAgICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gQ1VSUllfRkxBRykgfHxcbiAgICAgICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBSRUFSR19GTEFHICYmIGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgfHxcbiAgICAgICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAgICAgLy8gRXhpdCBlYXJseSBpZiBtZXRhZGF0YSBjYW4ndCBiZSBtZXJnZWQuXG4gICAgICBpZiAoIShpc0NvbW1vbiB8fCBpc0NvbWJvKSkge1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYHRoaXNBcmdgIGlmIGF2YWlsYWJsZS5cbiAgICAgIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgICAgIGRhdGFbMl0gPSBzb3VyY2VbMl07XG4gICAgICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gICAgICB9XG4gICAgICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICAgICAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgICAgIGRhdGFbNF0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbM10sIFBMQUNFSE9MREVSKSA6IGFycmF5Q29weShzb3VyY2VbNF0pO1xuICAgICAgfVxuICAgICAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgICAgIHZhbHVlID0gc291cmNlWzVdO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICAgICAgZGF0YVs1XSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3NSaWdodChwYXJ0aWFscywgdmFsdWUsIHNvdXJjZVs2XSkgOiBhcnJheUNvcHkodmFsdWUpO1xuICAgICAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzZdKTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyZ1Bvc2AgaWYgYXZhaWxhYmxlLlxuICAgICAgdmFsdWUgPSBzb3VyY2VbN107XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZGF0YVs3XSA9IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgICAgIGlmIChzcmNCaXRtYXNrICYgQVJZX0ZMQUcpIHtcbiAgICAgICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJpdHlgIGlmIG9uZSBpcyBub3QgcHJvdmlkZWQuXG4gICAgICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gICAgICBkYXRhWzBdID0gc291cmNlWzBdO1xuICAgICAgZGF0YVsxXSA9IG5ld0JpdG1hc2s7XG5cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZWQgYnkgYF8uZGVmYXVsdHNEZWVwYCB0byBjdXN0b21pemUgaXRzIGBfLm1lcmdlYCB1c2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqZWN0VmFsdWUgVGhlIGRlc3RpbmF0aW9uIG9iamVjdCBwcm9wZXJ0eSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IHNvdXJjZVZhbHVlIFRoZSBzb3VyY2Ugb2JqZWN0IHByb3BlcnR5IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZXJnZURlZmF1bHRzKG9iamVjdFZhbHVlLCBzb3VyY2VWYWx1ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdFZhbHVlID09PSB1bmRlZmluZWQgPyBzb3VyY2VWYWx1ZSA6IG1lcmdlKG9iamVjdFZhbHVlLCBzb3VyY2VWYWx1ZSwgbWVyZ2VEZWZhdWx0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnBpY2tgIHdoaWNoIHBpY2tzIGBvYmplY3RgIHByb3BlcnRpZXMgc3BlY2lmaWVkXG4gICAgICogYnkgYHByb3BzYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBpY2tCeUFycmF5KG9iamVjdCwgcHJvcHMpIHtcbiAgICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICByZXN1bHRba2V5XSA9IG9iamVjdFtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5waWNrYCB3aGljaCBwaWNrcyBgb2JqZWN0YCBwcm9wZXJ0aWVzIGBwcmVkaWNhdGVgXG4gICAgICogcmV0dXJucyB0cnV0aHkgZm9yLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGlja0J5Q2FsbGJhY2sob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGJhc2VGb3JJbihvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBrZXksIG9iamVjdCkpIHtcbiAgICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVvcmRlciBgYXJyYXlgIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4ZXMgd2hlcmUgdGhlIGVsZW1lbnQgYXRcbiAgICAgKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gICAgICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBUaGUgYXJyYW5nZWQgYXJyYXkgaW5kZXhlcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZW9yZGVyKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgICAgICBvbGRBcnJheSA9IGFycmF5Q29weShhcnJheSk7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgICAgIGFycmF5W2xlbmd0aF0gPSBpc0luZGV4KGluZGV4LCBhcnJMZW5ndGgpID8gb2xkQXJyYXlbaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICAgICAqIHBlcmlvZCBvZiB0aW1lLCBpdCB3aWxsIHRyaXAgaXRzIGJyZWFrZXIgYW5kIHRyYW5zaXRpb24gdG8gYW4gaWRlbnRpdHkgZnVuY3Rpb25cbiAgICAgKiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWUgW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDcwKVxuICAgICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICAgICAqIEBwYXJhbSB7Kn0gZGF0YSBUaGUgbWV0YWRhdGEuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgc2V0RGF0YSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjb3VudCA9IDAsXG4gICAgICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgICAgIHZhciBzdGFtcCA9IG5vdygpLFxuICAgICAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgICAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb3VudCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICAgICAgfTtcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBvZiBgT2JqZWN0LmtleXNgIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlXG4gICAgICogb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNoaW1LZXlzKG9iamVjdCkge1xuICAgICAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICAgICAgcHJvcHNMZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgbGVuZ3RoID0gcHJvcHNMZW5ndGggJiYgb2JqZWN0Lmxlbmd0aDtcblxuICAgICAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAgICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKChhbGxvd0luZGV4ZXMgJiYgaXNJbmRleChrZXksIGxlbmd0aCkpIHx8IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGFycmF5LWxpa2Ugb2JqZWN0IGlmIGl0J3Mgbm90IG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0l0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoIWlzQXJyYXlMaWtlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWVzKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc09iamVjdCh2YWx1ZSkgPyB2YWx1ZSA6IE9iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBvYmplY3QgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b09iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBiYXNlVG9TdHJpbmcodmFsdWUpLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN0cmluZykge1xuICAgICAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXJcbiAgICAgICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICAgICAgOiBuZXcgTG9kYXNoV3JhcHBlcih3cmFwcGVyLl9fd3JhcHBlZF9fLCB3cmFwcGVyLl9fY2hhaW5fXywgYXJyYXlDb3B5KHdyYXBwZXIuX19hY3Rpb25zX18pKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGVsZW1lbnRzIHNwbGl0IGludG8gZ3JvdXBzIHRoZSBsZW5ndGggb2YgYHNpemVgLlxuICAgICAqIElmIGBjb2xsZWN0aW9uYCBjYW4ndCBiZSBzcGxpdCBldmVubHksIHRoZSBmaW5hbCBjaHVuayB3aWxsIGJlIHRoZSByZW1haW5pbmdcbiAgICAgKiBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmsuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgY29udGFpbmluZyBjaHVua3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2h1bmsoWydhJywgJ2InLCAnYycsICdkJ10sIDIpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYiddLCBbJ2MnLCAnZCddXVxuICAgICAqXG4gICAgICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMyk7XG4gICAgICogLy8gPT4gW1snYScsICdiJywgJ2MnXSwgWydkJ11dXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2h1bmsoYXJyYXksIHNpemUsIGd1YXJkKSB7XG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PSBudWxsKSB7XG4gICAgICAgIHNpemUgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2l6ZSA9IG5hdGl2ZU1heChuYXRpdmVGbG9vcihzaXplKSB8fCAxLCAxKTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobmF0aXZlQ2VpbChsZW5ndGggLyBzaXplKSk7XG5cbiAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbKytyZXNJbmRleF0gPSBiYXNlU2xpY2UoYXJyYXksIGluZGV4LCAoaW5kZXggKz0gc2l6ZSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHdpdGggYWxsIGZhbHNleSB2YWx1ZXMgcmVtb3ZlZC4gVGhlIHZhbHVlcyBgZmFsc2VgLCBgbnVsbGAsXG4gICAgICogYDBgLCBgXCJcImAsIGB1bmRlZmluZWRgLCBhbmQgYE5hTmAgYXJlIGZhbHNleS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb21wYWN0KFswLCAxLCBmYWxzZSwgMiwgJycsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYWN0KGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICByZXN1bHRbKytyZXNJbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHVuaXF1ZSBgYXJyYXlgIHZhbHVlcyBub3QgaW5jbHVkZWQgaW4gdGhlIG90aGVyXG4gICAgICogcHJvdmlkZWQgYXJyYXlzIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW3ZhbHVlc10gVGhlIGFycmF5cyBvZiB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZShbMSwgMiwgM10sIFs0LCAyXSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2UgPSByZXN0UGFyYW0oZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgcmV0dXJuIChpc09iamVjdExpa2UoYXJyYXkpICYmIGlzQXJyYXlMaWtlKGFycmF5KSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCBmYWxzZSwgdHJ1ZSkpXG4gICAgICAgIDogW107XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBkcm9wLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wKGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBuLCBndWFyZCkgOiBuID09IG51bGwpIHtcbiAgICAgICAgbiA9IDE7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGVuZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBkcm9wLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgbiwgZ3VhcmQpIDogbiA9PSBudWxsKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfVxuICAgICAgbiA9IGxlbmd0aCAtICgrbiB8fCAwKTtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIDAsIG4gPCAwID8gMCA6IG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGVuZC5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IG1hdGNoIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUoWzEsIDIsIDNdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiA+IDE7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5wbHVjayhfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BSaWdodFdoaWxlKGFycmF5LCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VXaGlsZShhcnJheSwgZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKSwgdHJ1ZSwgdHJ1ZSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBleGNsdWRpbmcgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gICAgICogRWxlbWVudHMgYXJlIGRyb3BwZWQgdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gICAgICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcFdoaWxlKFsxLCAyLCAzXSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gPCAzO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFszXVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5kcm9wV2hpbGUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5kcm9wV2hpbGUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5wbHVjayhfLmRyb3BXaGlsZSh1c2VycywgJ2FjdGl2ZScpLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcFdoaWxlKGFycmF5LCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VXaGlsZShhcnJheSwgZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKSwgdHJ1ZSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaWxscyBlbGVtZW50cyBvZiBgYXJyYXlgIHdpdGggYHZhbHVlYCBmcm9tIGBzdGFydGAgdXAgdG8sIGJ1dCBub3RcbiAgICAgKiBpbmNsdWRpbmcsIGBlbmRgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmaWxsLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGZpbGwgYGFycmF5YCB3aXRoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDNdO1xuICAgICAqXG4gICAgICogXy5maWxsKGFycmF5LCAnYScpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYScsICdhJ11cbiAgICAgKlxuICAgICAqIF8uZmlsbChBcnJheSgzKSwgMik7XG4gICAgICogLy8gPT4gWzIsIDIsIDJdXG4gICAgICpcbiAgICAgKiBfLmZpbGwoWzQsIDYsIDhdLCAnKicsIDEsIDIpO1xuICAgICAqIC8vID0+IFs0LCAnKicsIDhdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoc3RhcnQgJiYgdHlwZW9mIHN0YXJ0ICE9ICdudW1iZXInICYmIGlzSXRlcmF0ZWVDYWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQpKSB7XG4gICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgZW5kID0gbGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VGaWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3RcbiAgICAgKiBlbGVtZW50IGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gICAgICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZvdW5kIGVsZW1lbnQsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsIGZ1bmN0aW9uKGNocikge1xuICAgICAqICAgcmV0dXJuIGNoci51c2VyID09ICdiYXJuZXknO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzYCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgeyAndXNlcic6ICdmcmVkJywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCAnYWN0aXZlJywgZmFsc2UpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgdmFyIGZpbmRJbmRleCA9IGNyZWF0ZUZpbmRJbmRleCgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHNcbiAgICAgKiBvZiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsIGZ1bmN0aW9uKGNocikge1xuICAgICAqICAgcmV0dXJuIGNoci51c2VyID09ICdwZWJibGVzJztcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uZmluZExhc3RJbmRleCh1c2VycywgJ2FjdGl2ZScsIGZhbHNlKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uZmluZExhc3RJbmRleCh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICB2YXIgZmluZExhc3RJbmRleCA9IGNyZWF0ZUZpbmRJbmRleCh0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBoZWFkXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmlyc3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiBfLmZpcnN0KFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaXJzdChhcnJheSkge1xuICAgICAgcmV0dXJuIGFycmF5ID8gYXJyYXlbMF0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYSBuZXN0ZWQgYXJyYXkuIElmIGBpc0RlZXBgIGlzIGB0cnVlYCB0aGUgYXJyYXkgaXMgcmVjdXJzaXZlbHlcbiAgICAgKiBmbGF0dGVuZWQsIG90aGVyd2lzZSBpdCBpcyBvbmx5IGZsYXR0ZW5lZCBhIHNpbmdsZSBsZXZlbC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgZmxhdHRlbi5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbihbMSwgWzIsIDMsIFs0XV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgWzRdXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgYGlzRGVlcGBcbiAgICAgKiBfLmZsYXR0ZW4oWzEsIFsyLCAzLCBbNF1dXSwgdHJ1ZSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbihhcnJheSwgaXNEZWVwLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgaXNEZWVwLCBndWFyZCkpIHtcbiAgICAgICAgaXNEZWVwID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIGlzRGVlcCkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBmbGF0dGVucyBhIG5lc3RlZCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byByZWN1cnNpdmVseSBmbGF0dGVuLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVlcChbMSwgWzIsIDMsIFs0XV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuRGVlcChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBiYXNlRmxhdHRlbihhcnJheSwgdHJ1ZSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0IGlzIHVzZWQgYXMgdGhlIG9mZnNldFxuICAgICAqIGZyb20gdGhlIGVuZCBvZiBgYXJyYXlgLiBJZiBgYXJyYXlgIGlzIHNvcnRlZCBwcm92aWRpbmcgYHRydWVgIGZvciBgZnJvbUluZGV4YFxuICAgICAqIHBlcmZvcm1zIGEgZmFzdGVyIGJpbmFyeSBzZWFyY2guXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gICAgICogIHRvIHBlcmZvcm0gYSBiaW5hcnkgc2VhcmNoIG9uIGEgc29ydGVkIGFycmF5LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIGBmcm9tSW5kZXhgXG4gICAgICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAgICAgKiBfLmluZGV4T2YoWzEsIDEsIDIsIDJdLCAyLCB0cnVlKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgICAgIGZyb21JbmRleCA9IGZyb21JbmRleCA8IDAgPyBuYXRpdmVNYXgobGVuZ3RoICsgZnJvbUluZGV4LCAwKSA6IGZyb21JbmRleDtcbiAgICAgIH0gZWxzZSBpZiAoZnJvbUluZGV4KSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJlxuICAgICAgICAgICAgKHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gYXJyYXlbaW5kZXhdKSA6IChhcnJheVtpbmRleF0gIT09IGFycmF5W2luZGV4XSkpKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCB8fCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBidXQgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbml0aWFsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdGlhbChhcnJheSkge1xuICAgICAgcmV0dXJuIGRyb3BSaWdodChhcnJheSwgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgYXJlIGluY2x1ZGVkIGluIGFsbCBvZiB0aGUgcHJvdmlkZWRcbiAgICAgKiBhcnJheXMgdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2Ygc2hhcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIF8uaW50ZXJzZWN0aW9uKFsxLCAyXSwgWzQsIDJdLCBbMiwgMV0pO1xuICAgICAqIC8vID0+IFsyXVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb24gPSByZXN0UGFyYW0oZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgb3RoTGVuZ3RoID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgICAgICBvdGhJbmRleCA9IG90aExlbmd0aCxcbiAgICAgICAgICBjYWNoZXMgPSBBcnJheShsZW5ndGgpLFxuICAgICAgICAgIGluZGV4T2YgPSBnZXRJbmRleE9mKCksXG4gICAgICAgICAgaXNDb21tb24gPSBpbmRleE9mID09IGJhc2VJbmRleE9mLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAob3RoSW5kZXgtLSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheXNbb3RoSW5kZXhdID0gaXNBcnJheUxpa2UodmFsdWUgPSBhcnJheXNbb3RoSW5kZXhdKSA/IHZhbHVlIDogW107XG4gICAgICAgIGNhY2hlc1tvdGhJbmRleF0gPSAoaXNDb21tb24gJiYgdmFsdWUubGVuZ3RoID49IDEyMCkgPyBjcmVhdGVDYWNoZShvdGhJbmRleCAmJiB2YWx1ZSkgOiBudWxsO1xuICAgICAgfVxuICAgICAgdmFyIGFycmF5ID0gYXJyYXlzWzBdLFxuICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHNlZW4gPSBjYWNoZXNbMF07XG5cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmICgoc2VlbiA/IGNhY2hlSW5kZXhPZihzZWVuLCB2YWx1ZSkgOiBpbmRleE9mKHJlc3VsdCwgdmFsdWUsIDApKSA8IDApIHtcbiAgICAgICAgICB2YXIgb3RoSW5kZXggPSBvdGhMZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKC0tb3RoSW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBjYWNoZSA9IGNhY2hlc1tvdGhJbmRleF07XG4gICAgICAgICAgICBpZiAoKGNhY2hlID8gY2FjaGVJbmRleE9mKGNhY2hlLCB2YWx1ZSkgOiBpbmRleE9mKGFycmF5c1tvdGhJbmRleF0sIHZhbHVlLCAwKSkgPCAwKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBhcnJheVtsZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgYXJyYXlgIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58bnVtYmVyfSBbZnJvbUluZGV4PWFycmF5Lmxlbmd0aC0xXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb21cbiAgICAgKiAgb3IgYHRydWVgIHRvIHBlcmZvcm0gYSBiaW5hcnkgc2VhcmNoIG9uIGEgc29ydGVkIGFycmF5LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBwZXJmb3JtaW5nIGEgYmluYXJ5IHNlYXJjaFxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDEsIDIsIDJdLCAyLCB0cnVlKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBsZW5ndGg7XG4gICAgICBpZiAodHlwZW9mIGZyb21JbmRleCA9PSAnbnVtYmVyJykge1xuICAgICAgICBpbmRleCA9IChmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiBuYXRpdmVNaW4oZnJvbUluZGV4IHx8IDAsIGxlbmd0aCAtIDEpKSArIDE7XG4gICAgICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgICAgICBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgdHJ1ZSkgLSAxO1xuICAgICAgICB2YXIgb3RoZXIgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IG90aGVyKSA6IChvdGhlciAhPT0gb3RoZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGluZGV4LCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgcHJvdmlkZWQgdmFsdWVzIGZyb20gYGFycmF5YCB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy53aXRob3V0YCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgMywgMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfLnB1bGwoYXJyYXksIDIsIDMpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgYXJyYXkgPSBhcmdzWzBdO1xuXG4gICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgaW5kZXhPZiA9IGdldEluZGV4T2YoKSxcbiAgICAgICAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGZyb21JbmRleCA9IDAsXG4gICAgICAgICAgICB2YWx1ZSA9IGFyZ3NbaW5kZXhdO1xuXG4gICAgICAgIHdoaWxlICgoZnJvbUluZGV4ID0gaW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkpID4gLTEpIHtcbiAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgZnJvbUluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZWxlbWVudHMgZnJvbSBgYXJyYXlgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGluZGV4ZXMgYW5kIHJldHVybnNcbiAgICAgKiBhbiBhcnJheSBvZiB0aGUgcmVtb3ZlZCBlbGVtZW50cy4gSW5kZXhlcyBtYXkgYmUgc3BlY2lmaWVkIGFzIGFuIGFycmF5IG9mXG4gICAgICogaW5kZXhlcyBvciBhcyBpbmRpdmlkdWFsIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uYXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IFtpbmRleGVzXSBUaGUgaW5kZXhlcyBvZiBlbGVtZW50cyB0byByZW1vdmUsXG4gICAgICogIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIGluZGV4ZXMgb3IgYXJyYXlzIG9mIGluZGV4ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzUsIDEwLCAxNSwgMjBdO1xuICAgICAqIHZhciBldmVucyA9IF8ucHVsbEF0KGFycmF5LCAxLCAzKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbNSwgMTVdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhldmVucyk7XG4gICAgICogLy8gPT4gWzEwLCAyMF1cbiAgICAgKi9cbiAgICB2YXIgcHVsbEF0ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICBpbmRleGVzID0gYmFzZUZsYXR0ZW4oaW5kZXhlcyk7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlQXQoYXJyYXksIGluZGV4ZXMpO1xuICAgICAgYmFzZVB1bGxBdChhcnJheSwgaW5kZXhlcy5zb3J0KGJhc2VDb21wYXJlQXNjZW5kaW5nKSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSBgYXJyYXlgIHRoYXQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yXG4gICAgICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHJlbW92ZWQgZWxlbWVudHMuIFRoZSBwcmVkaWNhdGUgaXMgYm91bmQgdG9cbiAgICAgKiBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gICAgICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5maWx0ZXJgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgMywgNF07XG4gICAgICogdmFyIGV2ZW5zID0gXy5yZW1vdmUoYXJyYXksIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsxLCAzXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZXZlbnMpO1xuICAgICAqIC8vID0+IFsyLCA0XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlbW92ZShhcnJheSwgcHJlZGljYXRlLCB0aGlzQXJnKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpbmRleGVzID0gW10sXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBwcmVkaWNhdGUgPSBnZXRDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICAgIGluZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJhc2VQdWxsQXQoYXJyYXksIGluZGV4ZXMpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBidXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyB0YWlsXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzdChhcnJheSkge1xuICAgICAgcmV0dXJuIGRyb3AoYXJyYXksIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGZyb20gYHN0YXJ0YCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW5zdGVhZCBvZiBgQXJyYXkjc2xpY2VgIHRvIHN1cHBvcnQgbm9kZVxuICAgICAqIGxpc3RzIGluIElFIDwgOSBhbmQgdG8gZW5zdXJlIGRlbnNlIGFycmF5cyBhcmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgJiYgdHlwZW9mIGVuZCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc3RhcnQsIGVuZCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgYmluYXJ5IHNlYXJjaCB0byBkZXRlcm1pbmUgdGhlIGxvd2VzdCBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZFxuICAgICAqIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci4gSWYgYW4gaXRlcmF0ZWVcbiAgICAgKiBmdW5jdGlvbiBpcyBwcm92aWRlZCBpdCBpcyBpbnZva2VkIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YFxuICAgICAqIHRvIGNvbXB1dGUgdGhlaXIgc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZFxuICAgICAqIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gICAgICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXgoWzMwLCA1MF0sIDQwKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4KFs0LCA0LCA1LCA1XSwgNSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogdmFyIGRpY3QgPSB7ICdkYXRhJzogeyAndGhpcnR5JzogMzAsICdmb3J0eSc6IDQwLCAnZmlmdHknOiA1MCB9IH07XG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBhbiBpdGVyYXRlZSBmdW5jdGlvblxuICAgICAqIF8uc29ydGVkSW5kZXgoWyd0aGlydHknLCAnZmlmdHknXSwgJ2ZvcnR5JywgZnVuY3Rpb24od29yZCkge1xuICAgICAqICAgcmV0dXJuIHRoaXMuZGF0YVt3b3JkXTtcbiAgICAgKiB9LCBkaWN0KTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uc29ydGVkSW5kZXgoW3sgJ3gnOiAzMCB9LCB7ICd4JzogNTAgfV0sIHsgJ3gnOiA0MCB9LCAneCcpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICB2YXIgc29ydGVkSW5kZXggPSBjcmVhdGVTb3J0ZWRJbmRleCgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRJbmRleGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUgaGlnaGVzdFxuICAgICAqIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0b1xuICAgICAqIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleChbNCwgNCwgNSwgNV0sIDUpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKi9cbiAgICB2YXIgc29ydGVkTGFzdEluZGV4ID0gY3JlYXRlU29ydGVkSW5kZXgodHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gdGFrZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZShhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgbiwgZ3VhcmQpIDogbiA9PSBudWxsKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VTbGljZShhcnJheSwgMCwgbiA8IDAgPyAwIDogbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgdGFrZW4gZnJvbSB0aGUgZW5kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHRha2UuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFszXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0KGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBuLCBndWFyZCkgOiBuID09IG51bGwpIHtcbiAgICAgICAgbiA9IDE7XG4gICAgICB9XG4gICAgICBuID0gbGVuZ3RoIC0gKCtuIHx8IDApO1xuICAgICAgcmV0dXJuIGJhc2VTbGljZShhcnJheSwgbiA8IDAgPyAwIDogbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuIEVsZW1lbnRzIGFyZVxuICAgICAqIHRha2VuIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvIGB0aGlzQXJnYFxuICAgICAqIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKFsxLCAyLCAzXSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gPiAxO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy50YWtlUmlnaHRXaGlsZSh1c2VycywgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH0pLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VSaWdodFdoaWxlKGFycmF5LCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VXaGlsZShhcnJheSwgZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKSwgZmFsc2UsIHRydWUpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBiZWdpbm5pbmcuIEVsZW1lbnRzXG4gICAgICogYXJlIHRha2VuIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvXG4gICAgICogYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2VXaGlsZShbMSwgMiwgM10sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuIDwgMztcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy50YWtlV2hpbGUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy50YWtlV2hpbGUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy50YWtlV2hpbGUodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VXaGlsZShhcnJheSwgcHJlZGljYXRlLCB0aGlzQXJnKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldENhbGxiYWNrKHByZWRpY2F0ZSwgdGhpc0FyZywgMykpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzLCBpbiBvcmRlciwgZnJvbSBhbGwgb2YgdGhlIHByb3ZpZGVkIGFycmF5c1xuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbihbMSwgMl0sIFs0LCAyXSwgWzIsIDFdKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgNF1cbiAgICAgKi9cbiAgICB2YXIgdW5pb24gPSByZXN0UGFyYW0oZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCBmYWxzZSwgdHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgYW4gYXJyYXksIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGluIHdoaWNoIG9ubHkgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiBlYWNoIGVsZW1lbnRcbiAgICAgKiBpcyBrZXB0LiBQcm92aWRpbmcgYHRydWVgIGZvciBgaXNTb3J0ZWRgIHBlcmZvcm1zIGEgZmFzdGVyIHNlYXJjaCBhbGdvcml0aG1cbiAgICAgKiBmb3Igc29ydGVkIGFycmF5cy4gSWYgYW4gaXRlcmF0ZWUgZnVuY3Rpb24gaXMgcHJvdmlkZWQgaXQgaXMgaW52b2tlZCBmb3JcbiAgICAgKiBlYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2ggdW5pcXVlbmVzc1xuICAgICAqIGlzIGNvbXB1dGVkLiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGFsaWFzIHVuaXF1ZVxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzU29ydGVkXSBTcGVjaWZ5IHRoZSBhcnJheSBpcyBzb3J0ZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbaXRlcmF0ZWVdIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlLXZhbHVlLWZyZWUgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5pcShbMiwgMSwgMl0pO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgYGlzU29ydGVkYFxuICAgICAqIF8udW5pcShbMSwgMSwgMl0sIHRydWUpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgYW4gaXRlcmF0ZWUgZnVuY3Rpb25cbiAgICAgKiBfLnVuaXEoWzEsIDIuNSwgMS41LCAyXSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIHRoaXMuZmxvb3Iobik7XG4gICAgICogfSwgTWF0aCk7XG4gICAgICogLy8gPT4gWzEsIDIuNV1cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy51bmlxKFt7ICd4JzogMSB9LCB7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfSwgeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxKGFycmF5LCBpc1NvcnRlZCwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoaXNTb3J0ZWQgIT0gbnVsbCAmJiB0eXBlb2YgaXNTb3J0ZWQgIT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXNBcmcgPSBpdGVyYXRlZTtcbiAgICAgICAgaXRlcmF0ZWUgPSBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgaXNTb3J0ZWQsIHRoaXNBcmcpID8gdW5kZWZpbmVkIDogaXNTb3J0ZWQ7XG4gICAgICAgIGlzU29ydGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgY2FsbGJhY2sgPSBnZXRDYWxsYmFjaygpO1xuICAgICAgaWYgKCEoaXRlcmF0ZWUgPT0gbnVsbCAmJiBjYWxsYmFjayA9PT0gYmFzZUNhbGxiYWNrKSkge1xuICAgICAgICBpdGVyYXRlZSA9IGNhbGxiYWNrKGl0ZXJhdGVlLCB0aGlzQXJnLCAzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoaXNTb3J0ZWQgJiYgZ2V0SW5kZXhPZigpID09IGJhc2VJbmRleE9mKVxuICAgICAgICA/IHNvcnRlZFVuaXEoYXJyYXksIGl0ZXJhdGVlKVxuICAgICAgICA6IGJhc2VVbmlxKGFycmF5LCBpdGVyYXRlZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgZ3JvdXBlZFxuICAgICAqIGVsZW1lbnRzIGFuZCBjcmVhdGVzIGFuIGFycmF5IHJlZ3JvdXBpbmcgdGhlIGVsZW1lbnRzIHRvIHRoZWlyIHByZS16aXBcbiAgICAgKiBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZWdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB6aXBwZWQgPSBfLnppcChbJ2ZyZWQnLCAnYmFybmV5J10sIFszMCwgNDBdLCBbdHJ1ZSwgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBbWydmcmVkJywgMzAsIHRydWVdLCBbJ2Jhcm5leScsIDQwLCBmYWxzZV1dXG4gICAgICpcbiAgICAgKiBfLnVuemlwKHppcHBlZCk7XG4gICAgICogLy8gPT4gW1snZnJlZCcsICdiYXJuZXknXSwgWzMwLCA0MF0sIFt0cnVlLCBmYWxzZV1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXAoYXJyYXkpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gMDtcblxuICAgICAgYXJyYXkgPSBhcnJheUZpbHRlcihhcnJheSwgZnVuY3Rpb24oZ3JvdXApIHtcbiAgICAgICAgaWYgKGlzQXJyYXlMaWtlKGdyb3VwKSkge1xuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChncm91cC5sZW5ndGgsIGxlbmd0aCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlNYXAoYXJyYXksIGJhc2VQcm9wZXJ0eShpbmRleCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuemlwYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGFuIGl0ZXJhdGVlIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgcmVncm91cGVkIHZhbHVlcyBzaG91bGQgYmUgY29tYmluZWQuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYFxuICAgICAqIGFuZCBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6IChhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGZ1bmN0aW9uIHRvIGNvbWJpbmUgcmVncm91cGVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZWdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB6aXBwZWQgPSBfLnppcChbMSwgMl0sIFsxMCwgMjBdLCBbMTAwLCAyMDBdKTtcbiAgICAgKiAvLyA9PiBbWzEsIDEwLCAxMDBdLCBbMiwgMjAsIDIwMF1dXG4gICAgICpcbiAgICAgKiBfLnVuemlwV2l0aCh6aXBwZWQsIF8uYWRkKTtcbiAgICAgKiAvLyA9PiBbMywgMzAsIDMwMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bnppcFdpdGgoYXJyYXksIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHVuemlwKGFycmF5KTtcbiAgICAgIGlmIChpdGVyYXRlZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBpdGVyYXRlZSA9IGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgNCk7XG4gICAgICByZXR1cm4gYXJyYXlNYXAocmVzdWx0LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICByZXR1cm4gYXJyYXlSZWR1Y2UoZ3JvdXAsIGl0ZXJhdGVlLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBleGNsdWRpbmcgYWxsIHByb3ZpZGVkIHZhbHVlcyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbHRlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ud2l0aG91dChbMSwgMiwgMSwgM10sIDEsIDIpO1xuICAgICAqIC8vID0+IFszXVxuICAgICAqL1xuICAgIHZhciB3aXRob3V0ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZShhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgaXMgdGhlIFtzeW1tZXRyaWMgZGlmZmVyZW5jZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ltbWV0cmljX2RpZmZlcmVuY2UpXG4gICAgICogb2YgdGhlIHByb3ZpZGVkIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ueG9yKFsxLCAyXSwgWzQsIDJdKTtcbiAgICAgKiAvLyA9PiBbMSwgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB4b3IoKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyYXkgPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICBpZiAoaXNBcnJheUxpa2UoYXJyYXkpKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3VsdFxuICAgICAgICAgICAgPyBhcnJheVB1c2goYmFzZURpZmZlcmVuY2UocmVzdWx0LCBhcnJheSksIGJhc2VEaWZmZXJlbmNlKGFycmF5LCByZXN1bHQpKVxuICAgICAgICAgICAgOiBhcnJheTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdCA/IGJhc2VVbmlxKHJlc3VsdCkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMsIHRoZSBmaXJzdCBvZiB3aGljaCBjb250YWlucyB0aGUgZmlyc3RcbiAgICAgKiBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCB0aGUgc2Vjb25kIG9mIHdoaWNoIGNvbnRhaW5zIHRoZSBzZWNvbmQgZWxlbWVudHNcbiAgICAgKiBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXAoWydmcmVkJywgJ2Jhcm5leSddLCBbMzAsIDQwXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snZnJlZCcsIDMwLCB0cnVlXSwgWydiYXJuZXknLCA0MCwgZmFsc2VdXVxuICAgICAqL1xuICAgIHZhciB6aXAgPSByZXN0UGFyYW0odW56aXApO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8ucGFpcnNgOyB0aGlzIG1ldGhvZCByZXR1cm5zIGFuIG9iamVjdCBjb21wb3NlZCBmcm9tIGFycmF5c1xuICAgICAqIG9mIHByb3BlcnR5IG5hbWVzIGFuZCB2YWx1ZXMuIFByb3ZpZGUgZWl0aGVyIGEgc2luZ2xlIHR3byBkaW1lbnNpb25hbCBhcnJheSxcbiAgICAgKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAgb3IgdHdvIGFycmF5cywgb25lIG9mIHByb3BlcnR5IG5hbWVzXG4gICAgICogYW5kIG9uZSBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBvYmplY3RcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlcz1bXV0gVGhlIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnppcE9iamVjdChbWydmcmVkJywgMzBdLCBbJ2Jhcm5leScsIDQwXV0pO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiAzMCwgJ2Jhcm5leSc6IDQwIH1cbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0KFsnZnJlZCcsICdiYXJuZXknXSwgWzMwLCA0MF0pO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiAzMCwgJ2Jhcm5leSc6IDQwIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB6aXBPYmplY3QocHJvcHMsIHZhbHVlcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcHJvcHMgPyBwcm9wcy5sZW5ndGggOiAwLFxuICAgICAgICAgIHJlc3VsdCA9IHt9O1xuXG4gICAgICBpZiAobGVuZ3RoICYmICF2YWx1ZXMgJiYgIWlzQXJyYXkocHJvcHNbMF0pKSB7XG4gICAgICAgIHZhbHVlcyA9IFtdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWVzW2luZGV4XTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkpIHtcbiAgICAgICAgICByZXN1bHRba2V5WzBdXSA9IGtleVsxXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhbiBpdGVyYXRlZSB0byBzcGVjaWZ5XG4gICAgICogaG93IGdyb3VwZWQgdmFsdWVzIHNob3VsZCBiZSBjb21iaW5lZC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgXG4gICAgICogYW5kIGludm9rZWQgd2l0aCBmb3VyIGFyZ3VtZW50czogKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGdyb3VwKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lIGdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwV2l0aChbMSwgMl0sIFsxMCwgMjBdLCBbMTAwLCAyMDBdLCBfLmFkZCk7XG4gICAgICogLy8gPT4gWzExMSwgMjIyXVxuICAgICAqL1xuICAgIHZhciB6aXBXaXRoID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgaXRlcmF0ZWUgPSBsZW5ndGggPiAyID8gYXJyYXlzW2xlbmd0aCAtIDJdIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHRoaXNBcmcgPSBsZW5ndGggPiAxID8gYXJyYXlzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpZiAobGVuZ3RoID4gMiAmJiB0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBsZW5ndGggLT0gMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZXJhdGVlID0gKGxlbmd0aCA+IDEgJiYgdHlwZW9mIHRoaXNBcmcgPT0gJ2Z1bmN0aW9uJykgPyAoLS1sZW5ndGgsIHRoaXNBcmcpIDogdW5kZWZpbmVkO1xuICAgICAgICB0aGlzQXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJyYXlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgIHJldHVybiB1bnppcFdpdGgoYXJyYXlzLCBpdGVyYXRlZSwgdGhpc0FyZyk7XG4gICAgfSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGxvZGFzaGAgb2JqZWN0IHRoYXQgd3JhcHMgYHZhbHVlYCB3aXRoIGV4cGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluaW5nIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ2hhaW5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiB2YXIgeW91bmdlc3QgPSBfLmNoYWluKHVzZXJzKVxuICAgICAqICAgLnNvcnRCeSgnYWdlJylcbiAgICAgKiAgIC5tYXAoZnVuY3Rpb24oY2hyKSB7XG4gICAgICogICAgIHJldHVybiBjaHIudXNlciArICcgaXMgJyArIGNoci5hZ2U7XG4gICAgICogICB9KVxuICAgICAqICAgLmZpcnN0KClcbiAgICAgKiAgIC52YWx1ZSgpO1xuICAgICAqIC8vID0+ICdwZWJibGVzIGlzIDEnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2hhaW4odmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBsb2Rhc2godmFsdWUpO1xuICAgICAgcmVzdWx0Ll9fY2hhaW5fXyA9IHRydWU7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGludm9rZXMgYGludGVyY2VwdG9yYCBhbmQgcmV0dXJucyBgdmFsdWVgLiBUaGUgaW50ZXJjZXB0b3IgaXNcbiAgICAgKiBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuIFRoZSBwdXJwb3NlIG9mXG4gICAgICogdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluIGluIG9yZGVyIHRvIHBlcmZvcm0gb3BlcmF0aW9uc1xuICAgICAqIG9uIGludGVybWVkaWF0ZSByZXN1bHRzIHdpdGhpbiB0aGUgY2hhaW4uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ2hhaW5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm92aWRlIHRvIGBpbnRlcmNlcHRvcmAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaW50ZXJjZXB0b3IgVGhlIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyLCAzXSlcbiAgICAgKiAgLnRhcChmdW5jdGlvbihhcnJheSkge1xuICAgICAqICAgIGFycmF5LnBvcCgpO1xuICAgICAqICB9KVxuICAgICAqICAucmV2ZXJzZSgpXG4gICAgICogIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRhcCh2YWx1ZSwgaW50ZXJjZXB0b3IsIHRoaXNBcmcpIHtcbiAgICAgIGludGVyY2VwdG9yLmNhbGwodGhpc0FyZywgdmFsdWUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udGFwYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSByZXN1bHQgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDaGFpblxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXygnICBhYmMgICcpXG4gICAgICogIC5jaGFpbigpXG4gICAgICogIC50cmltKClcbiAgICAgKiAgLnRocnUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgICByZXR1cm4gW3ZhbHVlXTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydhYmMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRocnUodmFsdWUsIGludGVyY2VwdG9yLCB0aGlzQXJnKSB7XG4gICAgICByZXR1cm4gaW50ZXJjZXB0b3IuY2FsbCh0aGlzQXJnLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5hYmxlcyBleHBsaWNpdCBtZXRob2QgY2hhaW5pbmcgb24gdGhlIHdyYXBwZXIgb2JqZWN0LlxuICAgICAqXG4gICAgICogQG5hbWUgY2hhaW5cbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDaGFpblxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyB3aXRob3V0IGV4cGxpY2l0IGNoYWluaW5nXG4gICAgICogXyh1c2VycykuZmlyc3QoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICpcbiAgICAgKiAvLyB3aXRoIGV4cGxpY2l0IGNoYWluaW5nXG4gICAgICogXyh1c2VycykuY2hhaW4oKVxuICAgICAqICAgLmZpcnN0KClcbiAgICAgKiAgIC5waWNrKCd1c2VyJylcbiAgICAgKiAgIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNoYWluKCkge1xuICAgICAgcmV0dXJuIGNoYWluKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIHRoZSBjaGFpbmVkIHNlcXVlbmNlIGFuZCByZXR1cm5zIHRoZSB3cmFwcGVkIHJlc3VsdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIGNvbW1pdFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENoYWluXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyXTtcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oYXJyYXkpLnB1c2goMyk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkID0gd3JhcHBlZC5jb21taXQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLmxhc3QoKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNvbW1pdCgpIHtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih0aGlzLnZhbHVlKCksIHRoaXMuX19jaGFpbl9fKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGFycmF5IGpvaW5pbmcgYSB3cmFwcGVkIGFycmF5IHdpdGggYW55IGFkZGl0aW9uYWwgYXJyYXlzXG4gICAgICogYW5kL29yIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBuYW1lIGNvbmNhdFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENoYWluXG4gICAgICogQHBhcmFtIHsuLi4qfSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGNvbmNhdGVuYXRlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGNvbmNhdGVuYXRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzFdO1xuICAgICAqIHZhciB3cmFwcGVkID0gXyhhcnJheSkuY29uY2F0KDIsIFszXSwgW1s0XV0pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cod3JhcHBlZC52YWx1ZSgpKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgWzRdXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqL1xuICAgIHZhciB3cmFwcGVyQ29uY2F0ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKHZhbHVlcykge1xuICAgICAgdmFsdWVzID0gYmFzZUZsYXR0ZW4odmFsdWVzKTtcbiAgICAgIHJldHVybiB0aGlzLnRocnUoZnVuY3Rpb24oYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5Q29uY2F0KGlzQXJyYXkoYXJyYXkpID8gYXJyYXkgOiBbdG9PYmplY3QoYXJyYXkpXSwgdmFsdWVzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBjaGFpbmVkIHNlcXVlbmNlIHBsYW50aW5nIGB2YWx1ZWAgYXMgdGhlIHdyYXBwZWQgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAbmFtZSBwbGFudFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENoYWluXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyXTtcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oYXJyYXkpLm1hcChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIE1hdGgucG93KHZhbHVlLCAyKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHZhciBvdGhlciA9IFszLCA0XTtcbiAgICAgKiB2YXIgb3RoZXJXcmFwcGVkID0gd3JhcHBlZC5wbGFudChvdGhlcik7XG4gICAgICpcbiAgICAgKiBvdGhlcldyYXBwZWQudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbOSwgMTZdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclBsYW50KHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIHBhcmVudCA9IHRoaXM7XG5cbiAgICAgIHdoaWxlIChwYXJlbnQgaW5zdGFuY2VvZiBiYXNlTG9kYXNoKSB7XG4gICAgICAgIHZhciBjbG9uZSA9IHdyYXBwZXJDbG9uZShwYXJlbnQpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSBjbG9uZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQgPSBjbG9uZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcHJldmlvdXMgPSBjbG9uZTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50Ll9fd3JhcHBlZF9fO1xuICAgICAgfVxuICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgdGhlIHdyYXBwZWQgYXJyYXkgc28gdGhlIGZpcnN0IGVsZW1lbnQgYmVjb21lcyB0aGUgbGFzdCwgdGhlXG4gICAgICogc2Vjb25kIGVsZW1lbnQgYmVjb21lcyB0aGUgc2Vjb25kIHRvIGxhc3QsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIHRoZSB3cmFwcGVkIGFycmF5LlxuICAgICAqXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENoYWluXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHJldmVyc2VkIGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8oYXJyYXkpLnJldmVyc2UoKS52YWx1ZSgpXG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclJldmVyc2UoKSB7XG4gICAgICB2YXIgdmFsdWUgPSB0aGlzLl9fd3JhcHBlZF9fO1xuXG4gICAgICB2YXIgaW50ZXJjZXB0b3IgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gKHdyYXBwZWQgJiYgd3JhcHBlZC5fX2Rpcl9fIDwgMCkgPyB2YWx1ZSA6IHZhbHVlLnJldmVyc2UoKTtcbiAgICAgIH07XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgICAgICB2YXIgd3JhcHBlZCA9IHZhbHVlO1xuICAgICAgICBpZiAodGhpcy5fX2FjdGlvbnNfXy5sZW5ndGgpIHtcbiAgICAgICAgICB3cmFwcGVkID0gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHdyYXBwZWQgPSB3cmFwcGVkLnJldmVyc2UoKTtcbiAgICAgICAgd3JhcHBlZC5fX2FjdGlvbnNfXy5wdXNoKHsgJ2Z1bmMnOiB0aHJ1LCAnYXJncyc6IFtpbnRlcmNlcHRvcl0sICd0aGlzQXJnJzogdW5kZWZpbmVkIH0pO1xuICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIod3JhcHBlZCwgdGhpcy5fX2NoYWluX18pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMudGhydShpbnRlcmNlcHRvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvZHVjZXMgdGhlIHJlc3VsdCBvZiBjb2VyY2luZyB0aGUgdW53cmFwcGVkIHZhbHVlIHRvIGEgc3RyaW5nLlxuICAgICAqXG4gICAgICogQG5hbWUgdG9TdHJpbmdcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDaGFpblxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvZXJjZWQgc3RyaW5nIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyLCAzXSkudG9TdHJpbmcoKTtcbiAgICAgKiAvLyA9PiAnMSwyLDMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICh0aGlzLnZhbHVlKCkgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgdGhlIGNoYWluZWQgc2VxdWVuY2UgdG8gZXh0cmFjdCB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQG5hbWUgdmFsdWVcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBydW4sIHRvSlNPTiwgdmFsdWVPZlxuICAgICAqIEBjYXRlZ29yeSBDaGFpblxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJWYWx1ZSgpIHtcbiAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKHRoaXMuX193cmFwcGVkX18sIHRoaXMuX19hY3Rpb25zX18pO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4ga2V5cywgb3IgaW5kZXhlcyxcbiAgICAgKiBvZiBgY29sbGVjdGlvbmAuIEtleXMgbWF5IGJlIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIGFyZ3VtZW50cyBvciBhcyBhcnJheXNcbiAgICAgKiBvZiBrZXlzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXXxzdHJpbmd8c3RyaW5nW10pfSBbcHJvcHNdIFRoZSBwcm9wZXJ0eSBuYW1lc1xuICAgICAqICBvciBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHBpY2ssIHNwZWNpZmllZCBpbmRpdmlkdWFsbHkgb3IgaW4gYXJyYXlzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBpY2tlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5hdChbJ2EnLCAnYicsICdjJ10sIFswLCAyXSk7XG4gICAgICogLy8gPT4gWydhJywgJ2MnXVxuICAgICAqXG4gICAgICogXy5hdChbJ2Jhcm5leScsICdmcmVkJywgJ3BlYmJsZXMnXSwgMCwgMik7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAncGViYmxlcyddXG4gICAgICovXG4gICAgdmFyIGF0ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByb3BzKSB7XG4gICAgICByZXR1cm4gYmFzZUF0KGNvbGxlY3Rpb24sIGJhc2VGbGF0dGVuKHByb3BzKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocm91Z2ggYGl0ZXJhdGVlYC4gVGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVcbiAgICAgKiBvZiBlYWNoIGtleSBpcyB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBrZXkgd2FzIHJldHVybmVkIGJ5IGBpdGVyYXRlZWAuXG4gICAgICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY291bnRCeShbNC4zLCA2LjEsIDYuNF0sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBNYXRoLmZsb29yKG4pO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJzQnOiAxLCAnNic6IDIgfVxuICAgICAqXG4gICAgICogXy5jb3VudEJ5KFs0LjMsIDYuMSwgNi40XSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIHRoaXMuZmxvb3Iobik7XG4gICAgICogfSwgTWF0aCk7XG4gICAgICogLy8gPT4geyAnNCc6IDEsICc2JzogMiB9XG4gICAgICpcbiAgICAgKiBfLmNvdW50QnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogMiwgJzUnOiAxIH1cbiAgICAgKi9cbiAgICB2YXIgY291bnRCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSA/ICsrcmVzdWx0W2tleV0gOiAocmVzdWx0W2tleV0gPSAxKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgKiphbGwqKiBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAuXG4gICAgICogVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgYWxsXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmV2ZXJ5KFt0cnVlLCAxLCBudWxsLCAneWVzJ10sIEJvb2xlYW4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5ldmVyeSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uZXZlcnkodXNlcnMsICdhY3RpdmUnLCBmYWxzZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBldmVyeShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RXZlcnkgOiBiYXNlRXZlcnk7XG4gICAgICBpZiAodGhpc0FyZyAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcHJlZGljYXRlICE9ICdmdW5jdGlvbicgfHwgdGhpc0FyZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IGdldENhbGxiYWNrKHByZWRpY2F0ZSwgdGhpc0FyZywgMyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBwcmVkaWNhdGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzXG4gICAgICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmRcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBzZWxlY3RcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihbNCwgNSwgNl0sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFs0LCA2XVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJywgZmFsc2UpLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcHJlZGljYXRlID0gZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gICAgICogaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgZGV0ZWN0XG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF0Y2hlZCBlbGVtZW50LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgZnVuY3Rpb24oY2hyKSB7XG4gICAgICogICByZXR1cm4gY2hyLmFnZSA8IDQwO1xuICAgICAqIH0pLCAndXNlcicpO1xuICAgICAqIC8vID0+ICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgJ2FjdGl2ZScsIGZhbHNlKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKi9cbiAgICB2YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5maW5kTGFzdChbMSwgMiwgMywgNF0sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAxO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICB2YXIgZmluZExhc3QgPSBjcmVhdGVGaW5kKGJhc2VFYWNoUmlnaHQsIHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIGFuZCB0aGVcbiAgICAgKiBzb3VyY2Ugb2JqZWN0LCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBoYXMgZXF1aXZhbGVudCBwcm9wZXJ0eVxuICAgICAqIHZhbHVlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBjb21wYXJpbmcgYXJyYXlzLCBib29sZWFucywgYERhdGVgIG9iamVjdHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgYW5kIHN0cmluZ3MuIE9iamVjdHMgYXJlIGNvbXBhcmVkIGJ5XG4gICAgICogdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZvciBjb21wYXJpbmcgYSBzaW5nbGVcbiAgICAgKiBvd24gb3IgaW5oZXJpdGVkIHByb3BlcnR5IHZhbHVlIHNlZSBgXy5tYXRjaGVzUHJvcGVydHlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5yZXN1bHQoXy5maW5kV2hlcmUodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiAnYmFybmV5J1xuICAgICAqXG4gICAgICogXy5yZXN1bHQoXy5maW5kV2hlcmUodXNlcnMsIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZFdoZXJlKGNvbGxlY3Rpb24sIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZpbmQoY29sbGVjdGlvbiwgYmFzZU1hdGNoZXMoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICAgICAqIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czpcbiAgICAgKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHlcbiAgICAgKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgXCJDb2xsZWN0aW9uc1wiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhIFwibGVuZ3RoXCIgcHJvcGVydHlcbiAgICAgKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAgICAgKiBtYXkgYmUgdXNlZCBmb3Igb2JqZWN0IGl0ZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBlYWNoXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R8c3RyaW5nfSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXyhbMSwgMl0pLmZvckVhY2goZnVuY3Rpb24obikge1xuICAgICAqICAgY29uc29sZS5sb2cobik7XG4gICAgICogfSkudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBsb2dzIGVhY2ggdmFsdWUgZnJvbSBsZWZ0IHRvIHJpZ2h0IGFuZCByZXR1cm5zIHRoZSBhcnJheVxuICAgICAqXG4gICAgICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhuLCBrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgdmFyIGZvckVhY2ggPSBjcmVhdGVGb3JFYWNoKGFycmF5RWFjaCwgYmFzZUVhY2gpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JFYWNoYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBlYWNoUmlnaHRcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyXSkuZm9yRWFjaFJpZ2h0KGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKG4pO1xuICAgICAqIH0pLnZhbHVlKCk7XG4gICAgICogLy8gPT4gbG9ncyBlYWNoIHZhbHVlIGZyb20gcmlnaHQgdG8gbGVmdCBhbmQgcmV0dXJucyB0aGUgYXJyYXlcbiAgICAgKi9cbiAgICB2YXIgZm9yRWFjaFJpZ2h0ID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2hSaWdodCwgYmFzZUVhY2hSaWdodCk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocm91Z2ggYGl0ZXJhdGVlYC4gVGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVcbiAgICAgKiBvZiBlYWNoIGtleSBpcyBhbiBhcnJheSBvZiB0aGUgZWxlbWVudHMgcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlIGtleS5cbiAgICAgKiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ncm91cEJ5KFs0LjIsIDYuMSwgNi40XSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIE1hdGguZmxvb3Iobik7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnNCc6IFs0LjJdLCAnNic6IFs2LjEsIDYuNF0gfVxuICAgICAqXG4gICAgICogXy5ncm91cEJ5KFs0LjIsIDYuMSwgNi40XSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIHRoaXMuZmxvb3Iobik7XG4gICAgICogfSwgTWF0aCk7XG4gICAgICogLy8gPT4geyAnNCc6IFs0LjJdLCAnNic6IFs2LjEsIDYuNF0gfVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLmdyb3VwQnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogWydvbmUnLCAndHdvJ10sICc1JzogWyd0aHJlZSddIH1cbiAgICAgKi9cbiAgICB2YXIgZ3JvdXBCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRba2V5XSA9IFt2YWx1ZV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiBgY29sbGVjdGlvbmAgdXNpbmdcbiAgICAgKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0IGlzIHVzZWQgYXMgdGhlIG9mZnNldFxuICAgICAqIGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gICAgICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24gPyBnZXRMZW5ndGgoY29sbGVjdGlvbikgOiAwO1xuICAgICAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgICAgIGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgICAgIGZyb21JbmRleCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuICh0eXBlb2YgY29sbGVjdGlvbiA9PSAnc3RyaW5nJyB8fCAhaXNBcnJheShjb2xsZWN0aW9uKSAmJiBpc1N0cmluZyhjb2xsZWN0aW9uKSlcbiAgICAgICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgICAgIDogKCEhbGVuZ3RoICYmIGdldEluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhyb3VnaCBgaXRlcmF0ZWVgLiBUaGUgY29ycmVzcG9uZGluZyB2YWx1ZVxuICAgICAqIG9mIGVhY2gga2V5IGlzIHRoZSBsYXN0IGVsZW1lbnQgcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlIGtleS4gVGhlXG4gICAgICogaXRlcmF0ZWUgZnVuY3Rpb24gaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBrZXlEYXRhID0gW1xuICAgICAqICAgeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sXG4gICAgICogICB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uaW5kZXhCeShrZXlEYXRhLCAnZGlyJyk7XG4gICAgICogLy8gPT4geyAnbGVmdCc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAncmlnaHQnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAgICAgKlxuICAgICAqIF8uaW5kZXhCeShrZXlEYXRhLCBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgKiAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKG9iamVjdC5jb2RlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdkJzogeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfSB9XG4gICAgICpcbiAgICAgKiBfLmluZGV4Qnkoa2V5RGF0YSwgZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICogICByZXR1cm4gdGhpcy5mcm9tQ2hhckNvZGUob2JqZWN0LmNvZGUpO1xuICAgICAqIH0sIFN0cmluZyk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAnZCc6IHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH0gfVxuICAgICAqL1xuICAgIHZhciBpbmRleEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBtZXRob2QgYXQgYHBhdGhgIG9mIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAsIHJldHVybmluZ1xuICAgICAqIGFuIGFycmF5IG9mIHRoZSByZXN1bHRzIG9mIGVhY2ggaW52b2tlZCBtZXRob2QuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgICAqIGFyZSBwcm92aWRlZCB0byBlYWNoIGludm9rZWQgbWV0aG9kLiBJZiBgbWV0aG9kTmFtZWAgaXMgYSBmdW5jdGlvbiBpdCBpc1xuICAgICAqIGludm9rZWQgZm9yLCBhbmQgYHRoaXNgIGJvdW5kIHRvLCBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb258c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlIG9yXG4gICAgICogIHRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnZva2UoW1s1LCAxLCA3XSwgWzMsIDIsIDFdXSwgJ3NvcnQnKTtcbiAgICAgKiAvLyA9PiBbWzEsIDUsIDddLCBbMSwgMiwgM11dXG4gICAgICpcbiAgICAgKiBfLmludm9rZShbMTIzLCA0NTZdLCBTdHJpbmcucHJvdG90eXBlLnNwbGl0LCAnJyk7XG4gICAgICogLy8gPT4gW1snMScsICcyJywgJzMnXSwgWyc0JywgJzUnLCAnNiddXVxuICAgICAqL1xuICAgIHZhciBpbnZva2UgPSByZXN0UGFyYW0oZnVuY3Rpb24oY29sbGVjdGlvbiwgcGF0aCwgYXJncykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaXNGdW5jID0gdHlwZW9mIHBhdGggPT0gJ2Z1bmN0aW9uJyxcbiAgICAgICAgICBpc1Byb3AgPSBpc0tleShwYXRoKSxcbiAgICAgICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgZnVuYyA9IGlzRnVuYyA/IHBhdGggOiAoKGlzUHJvcCAmJiB2YWx1ZSAhPSBudWxsKSA/IHZhbHVlW3BhdGhdIDogdW5kZWZpbmVkKTtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gZnVuYyA/IGZ1bmMuYXBwbHkodmFsdWUsIGFyZ3MpIDogaW52b2tlUGF0aCh2YWx1ZSwgcGF0aCwgYXJncyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICAgICAqIGBpdGVyYXRlZWAuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gICAgICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAgICAgKiBgXy5ldmVyeWAsIGBfLmZpbHRlcmAsIGBfLm1hcGAsIGBfLm1hcFZhbHVlc2AsIGBfLnJlamVjdGAsIGFuZCBgXy5zb21lYC5cbiAgICAgKlxuICAgICAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICAgICAqIGBhcnlgLCBgY2FsbGJhY2tgLCBgY2h1bmtgLCBgY2xvbmVgLCBgY3JlYXRlYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLFxuICAgICAqIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsIGBmaWxsYCwgYGZsYXR0ZW5gLCBgaW52ZXJ0YCwgYG1heGAsIGBtaW5gLFxuICAgICAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gICAgICogYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsIGByYW5kb21gLCBgcmFuZ2VgLCBgc2FtcGxlYCwgYHNvbWVgLFxuICAgICAqIGBzdW1gLCBgdW5pcWAsIGFuZCBgd29yZHNgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgY29sbGVjdFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIDM7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5tYXAoWzEsIDJdLCB0aW1lc1RocmVlKTtcbiAgICAgKiAvLyA9PiBbMywgNl1cbiAgICAgKlxuICAgICAqIF8ubWFwKHsgJ2EnOiAxLCAnYic6IDIgfSwgdGltZXNUaHJlZSk7XG4gICAgICogLy8gPT4gWzMsIDZdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICAgICAgaXRlcmF0ZWUgPSBnZXRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbGVtZW50cyBzcGxpdCBpbnRvIHR3byBncm91cHMsIHRoZSBmaXJzdCBvZiB3aGljaFxuICAgICAqIGNvbnRhaW5zIGVsZW1lbnRzIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciwgd2hpbGUgdGhlIHNlY29uZCBvZiB3aGljaFxuICAgICAqIGNvbnRhaW5zIGVsZW1lbnRzIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZFxuICAgICAqIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYXJ0aXRpb24oWzEsIDIsIDNdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDI7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gW1sxLCAzXSwgWzJdXVxuICAgICAqXG4gICAgICogXy5wYXJ0aXRpb24oWzEuMiwgMi4zLCAzLjRdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gdGhpcy5mbG9vcihuKSAlIDI7XG4gICAgICogfSwgTWF0aCk7XG4gICAgICogLy8gPT4gW1sxLjIsIDMuNF0sIFsyLjNdXVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogdmFyIG1hcHBlciA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICogICByZXR1cm4gXy5wbHVjayhhcnJheSwgJ3VzZXInKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ubWFwKF8ucGFydGl0aW9uKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogZmFsc2UgfSksIG1hcHBlcik7XG4gICAgICogLy8gPT4gW1sncGViYmxlcyddLCBbJ2Jhcm5leScsICdmcmVkJ11dXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLm1hcChfLnBhcnRpdGlvbih1c2VycywgJ2FjdGl2ZScsIGZhbHNlKSwgbWFwcGVyKTtcbiAgICAgKiAvLyA9PiBbWydiYXJuZXknLCAncGViYmxlcyddLCBbJ2ZyZWQnXV1cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5tYXAoXy5wYXJ0aXRpb24odXNlcnMsICdhY3RpdmUnKSwgbWFwcGVyKTtcbiAgICAgKiAvLyA9PiBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKi9cbiAgICB2YXIgcGFydGl0aW9uID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFtrZXkgPyAwIDogMV0ucHVzaCh2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24oKSB7IHJldHVybiBbW10sIFtdXTsgfSk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiBgcGF0aGAgZnJvbSBhbGwgZWxlbWVudHMgaW4gYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBwbHVjay5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5wbHVjayh1c2VycywgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIHZhciB1c2VySW5kZXggPSBfLmluZGV4QnkodXNlcnMsICd1c2VyJyk7XG4gICAgICogXy5wbHVjayh1c2VySW5kZXgsICdhZ2UnKTtcbiAgICAgKiAvLyA9PiBbMzYsIDQwXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBsdWNrKGNvbGxlY3Rpb24sIHBhdGgpIHtcbiAgICAgIHJldHVybiBtYXAoY29sbGVjdGlvbiwgcHJvcGVydHkocGF0aCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZHVjZXMgYGNvbGxlY3Rpb25gIHRvIGEgdmFsdWUgd2hpY2ggaXMgdGhlIGFjY3VtdWxhdGVkIHJlc3VsdCBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJvdWdoIGBpdGVyYXRlZWAsIHdoZXJlIGVhY2ggc3VjY2Vzc2l2ZVxuICAgICAqIGludm9jYXRpb24gaXMgc3VwcGxpZWQgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJldmlvdXMuIElmIGBhY2N1bXVsYXRvcmBcbiAgICAgKiBpcyBub3QgcHJvdmlkZWQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIGlzIHVzZWQgYXMgdGhlIGluaXRpYWxcbiAgICAgKiB2YWx1ZS4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6XG4gICAgICogKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICAgICAqIGBfLnJlZHVjZWAsIGBfLnJlZHVjZVJpZ2h0YCwgYW5kIGBfLnRyYW5zZm9ybWAuXG4gICAgICpcbiAgICAgKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZTpcbiAgICAgKiBgYXNzaWduYCwgYGRlZmF1bHRzYCwgYGRlZmF1bHRzRGVlcGAsIGBpbmNsdWRlc2AsIGBtZXJnZWAsIGBzb3J0QnlBbGxgLFxuICAgICAqIGFuZCBgc29ydEJ5T3JkZXJgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgZm9sZGwsIGluamVjdFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlZHVjZShbMSwgMl0sIGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gICAgICogICByZXR1cm4gdG90YWwgKyBuO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8ucmVkdWNlKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24ocmVzdWx0LCBuLCBrZXkpIHtcbiAgICAgKiAgIHJlc3VsdFtrZXldID0gbiAqIDM7XG4gICAgICogICByZXR1cm4gcmVzdWx0O1xuICAgICAqIH0sIHt9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMywgJ2InOiA2IH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICB2YXIgcmVkdWNlID0gY3JlYXRlUmVkdWNlKGFycmF5UmVkdWNlLCBiYXNlRWFjaCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnJlZHVjZWAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgZm9sZHJcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gW1swLCAxXSwgWzIsIDNdLCBbNCwgNV1dO1xuICAgICAqXG4gICAgICogXy5yZWR1Y2VSaWdodChhcnJheSwgZnVuY3Rpb24oZmxhdHRlbmVkLCBvdGhlcikge1xuICAgICAqICAgcmV0dXJuIGZsYXR0ZW5lZC5jb25jYXQob3RoZXIpO1xuICAgICAqIH0sIFtdKTtcbiAgICAgKiAvLyA9PiBbNCwgNSwgMiwgMywgMCwgMV1cbiAgICAgKi9cbiAgICB2YXIgcmVkdWNlUmlnaHQgPSBjcmVhdGVSZWR1Y2UoYXJyYXlSZWR1Y2VSaWdodCwgYmFzZUVhY2hSaWdodCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8uZmlsdGVyYDsgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gXG4gICAgICogdGhhdCBgcHJlZGljYXRlYCBkb2VzICoqbm90KiogcmV0dXJuIHRydXRoeSBmb3IuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlamVjdChbMSwgMiwgMywgNF0sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFsxLCAzXVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5yZWplY3QodXNlcnMsIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9KSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnBsdWNrKF8ucmVqZWN0KHVzZXJzLCAnYWN0aXZlJywgZmFsc2UpLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8ucGx1Y2soXy5yZWplY3QodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVqZWN0KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcHJlZGljYXRlID0gZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXR1cm4gIXByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIHJhbmRvbSBlbGVtZW50IG9yIGBuYCByYW5kb20gZWxlbWVudHMgZnJvbSBhIGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIHNhbXBsZShzKS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zYW1wbGUoWzEsIDIsIDMsIDRdKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZShbMSwgMiwgMywgNF0sIDIpO1xuICAgICAqIC8vID0+IFszLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhbXBsZShjb2xsZWN0aW9uLCBuLCBndWFyZCkge1xuICAgICAgaWYgKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgbiwgZ3VhcmQpIDogbiA9PSBudWxsKSB7XG4gICAgICAgIGNvbGxlY3Rpb24gPSB0b0l0ZXJhYmxlKGNvbGxlY3Rpb24pO1xuICAgICAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gICAgICAgIHJldHVybiBsZW5ndGggPiAwID8gY29sbGVjdGlvbltiYXNlUmFuZG9tKDAsIGxlbmd0aCAtIDEpXSA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IHRvQXJyYXkoY29sbGVjdGlvbiksXG4gICAgICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuXG4gICAgICBuID0gbmF0aXZlTWluKG4gPCAwID8gMCA6ICgrbiB8fCAwKSwgbGVuZ3RoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgICAgICB2YXIgcmFuZCA9IGJhc2VSYW5kb20oaW5kZXgsIGxhc3RJbmRleCksXG4gICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdFtyYW5kXTtcblxuICAgICAgICByZXN1bHRbcmFuZF0gPSByZXN1bHRbaW5kZXhdO1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXN1bHQubGVuZ3RoID0gbjtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBzaHVmZmxlZCB2YWx1ZXMsIHVzaW5nIGEgdmVyc2lvbiBvZiB0aGVcbiAgICAgKiBbRmlzaGVyLVlhdGVzIHNodWZmbGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlci1ZYXRlc19zaHVmZmxlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2h1ZmZsZShbMSwgMiwgMywgNF0pO1xuICAgICAqIC8vID0+IFs0LCAxLCAzLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIHNhbXBsZShjb2xsZWN0aW9uLCBQT1NJVElWRV9JTkZJTklUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2l6ZSBvZiBgY29sbGVjdGlvbmAgYnkgcmV0dXJuaW5nIGl0cyBsZW5ndGggZm9yIGFycmF5LWxpa2VcbiAgICAgKiB2YWx1ZXMgb3IgdGhlIG51bWJlciBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGZvciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zaXplKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5zaXplKHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogXy5zaXplKCdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gN1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNpemUoY29sbGVjdGlvbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24gPyBnZXRMZW5ndGgoY29sbGVjdGlvbikgOiAwO1xuICAgICAgcmV0dXJuIGlzTGVuZ3RoKGxlbmd0aCkgPyBsZW5ndGggOiBrZXlzKGNvbGxlY3Rpb24pLmxlbmd0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yICoqYW55KiogZWxlbWVudCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICogVGhlIGZ1bmN0aW9uIHJldHVybnMgYXMgc29vbiBhcyBpdCBmaW5kcyBhIHBhc3NpbmcgdmFsdWUgYW5kIGRvZXMgbm90IGl0ZXJhdGVcbiAgICAgKiBvdmVyIHRoZSBlbnRpcmUgY29sbGVjdGlvbi4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgYW55XG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb21lKFtudWxsLCAwLCAneWVzJywgZmFsc2VdLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzYCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnNvbWUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnNvbWUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLnNvbWUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U29tZSA6IGJhc2VTb21lO1xuICAgICAgaWYgKHRoaXNBcmcgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgcHJlZGljYXRlLCB0aGlzQXJnKSkge1xuICAgICAgICBwcmVkaWNhdGUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHByZWRpY2F0ZSAhPSAnZnVuY3Rpb24nIHx8IHRoaXNBcmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcmVkaWNhdGUgPSBnZXRDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgcHJlZGljYXRlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGVsZW1lbnRzLCBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZSByZXN1bHRzIG9mXG4gICAgICogcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYSBjb2xsZWN0aW9uIHRocm91Z2ggYGl0ZXJhdGVlYC4gVGhpcyBtZXRob2QgcGVyZm9ybXNcbiAgICAgKiBhIHN0YWJsZSBzb3J0LCB0aGF0IGlzLCBpdCBwcmVzZXJ2ZXMgdGhlIG9yaWdpbmFsIHNvcnQgb3JkZXIgb2YgZXF1YWwgZWxlbWVudHMuXG4gICAgICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICAgICAqICBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0QnkoWzEsIDIsIDNdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gTWF0aC5zaW4obik7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gWzMsIDEsIDJdXG4gICAgICpcbiAgICAgKiBfLnNvcnRCeShbMSwgMiwgM10sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiB0aGlzLnNpbihuKTtcbiAgICAgKiB9LCBNYXRoKTtcbiAgICAgKiAvLyA9PiBbMywgMSwgMl1cbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5wbHVjayhfLnNvcnRCeSh1c2VycywgJ3VzZXInKSwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRCeShjb2xsZWN0aW9uLCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAodGhpc0FyZyAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBpdGVyYXRlZSwgdGhpc0FyZykpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgIGl0ZXJhdGVlID0gZ2V0Q2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZU1hcChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiB7ICdjcml0ZXJpYSc6IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pLCAnaW5kZXgnOiArK2luZGV4LCAndmFsdWUnOiB2YWx1ZSB9O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYmFzZVNvcnRCeShyZXN1bHQsIGNvbXBhcmVBc2NlbmRpbmcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc29ydEJ5YCBleGNlcHQgdGhhdCBpdCBjYW4gc29ydCBieSBtdWx0aXBsZSBpdGVyYXRlZXNcbiAgICAgKiBvciBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYW4gaXRlcmF0ZWUgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gICAgICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGFuIGl0ZXJhdGVlIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdfE9iamVjdHxPYmplY3RbXXxzdHJpbmd8c3RyaW5nW10pfSBpdGVyYXRlZXNcbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LCBzcGVjaWZpZWQgYXMgaW5kaXZpZHVhbCB2YWx1ZXMgb3IgYXJyYXlzIG9mIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzb3J0ZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQ4IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDIgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5tYXAoXy5zb3J0QnlBbGwodXNlcnMsIFsndXNlcicsICdhZ2UnXSksIF8udmFsdWVzKTtcbiAgICAgKiAvLyA9PiBbWydiYXJuZXknLCAzNF0sIFsnYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCA0Ml0sIFsnZnJlZCcsIDQ4XV1cbiAgICAgKlxuICAgICAqIF8ubWFwKF8uc29ydEJ5QWxsKHVzZXJzLCAndXNlcicsIGZ1bmN0aW9uKGNocikge1xuICAgICAqICAgcmV0dXJuIE1hdGguZmxvb3IoY2hyLmFnZSAvIDEwKTtcbiAgICAgKiB9KSwgXy52YWx1ZXMpO1xuICAgICAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydiYXJuZXknLCAzNF0sIFsnZnJlZCcsIDQ4XSwgWydmcmVkJywgNDJdXVxuICAgICAqL1xuICAgIHZhciBzb3J0QnlBbGwgPSByZXN0UGFyYW0oZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWVzKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBndWFyZCA9IGl0ZXJhdGVlc1syXTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChpdGVyYXRlZXNbMF0sIGl0ZXJhdGVlc1sxXSwgZ3VhcmQpKSB7XG4gICAgICAgIGl0ZXJhdGVlcy5sZW5ndGggPSAxO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VTb3J0QnlPcmRlcihjb2xsZWN0aW9uLCBiYXNlRmxhdHRlbihpdGVyYXRlZXMpLCBbXSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRCeUFsbGAgZXhjZXB0IHRoYXQgaXQgYWxsb3dzIHNwZWNpZnlpbmcgdGhlXG4gICAgICogc29ydCBvcmRlcnMgb2YgdGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsXG4gICAgICogdmFsdWVzIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsIGEgdmFsdWUgaXMgc29ydGVkIGluXG4gICAgICogYXNjZW5kaW5nIG9yZGVyIGlmIGl0cyBjb3JyZXNwb25kaW5nIG9yZGVyIGlzIFwiYXNjXCIsIGFuZCBkZXNjZW5kaW5nIGlmIFwiZGVzY1wiLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBhbiBpdGVyYXRlZSB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYW4gaXRlcmF0ZWUgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXXxPYmplY3RbXXxzdHJpbmdbXX0gaXRlcmF0ZWVzIFRoZSBpdGVyYXRlZXMgdG8gc29ydCBieS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW5bXX0gW29yZGVyc10gVGhlIHNvcnQgb3JkZXJzIG9mIGBpdGVyYXRlZXNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDggfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MiB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBzb3J0IGJ5IGB1c2VyYCBpbiBhc2NlbmRpbmcgb3JkZXIgYW5kIGJ5IGBhZ2VgIGluIGRlc2NlbmRpbmcgb3JkZXJcbiAgICAgKiBfLm1hcChfLnNvcnRCeU9yZGVyKHVzZXJzLCBbJ3VzZXInLCAnYWdlJ10sIFsnYXNjJywgJ2Rlc2MnXSksIF8udmFsdWVzKTtcbiAgICAgKiAvLyA9PiBbWydiYXJuZXknLCAzNl0sIFsnYmFybmV5JywgMzRdLCBbJ2ZyZWQnLCA0OF0sIFsnZnJlZCcsIDQyXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0QnlPcmRlcihjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycywgZ3VhcmQpIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGl0ZXJhdGVlcywgb3JkZXJzLCBndWFyZCkpIHtcbiAgICAgICAgb3JkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FycmF5KGl0ZXJhdGVlcykpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gaXRlcmF0ZWVzID09IG51bGwgPyBbXSA6IFtpdGVyYXRlZXNdO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FycmF5KG9yZGVycykpIHtcbiAgICAgICAgb3JkZXJzID0gb3JkZXJzID09IG51bGwgPyBbXSA6IFtvcmRlcnNdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VTb3J0QnlPcmRlcihjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIGFuZCB0aGVcbiAgICAgKiBzb3VyY2Ugb2JqZWN0LCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzIHRoYXQgaGF2ZSBlcXVpdmFsZW50XG4gICAgICogcHJvcGVydHkgdmFsdWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBhcnJheXMsIGJvb2xlYW5zLCBgRGF0ZWAgb2JqZWN0cyxcbiAgICAgKiBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLCBhbmQgc3RyaW5ncy4gT2JqZWN0cyBhcmUgY29tcGFyZWQgYnlcbiAgICAgKiB0aGVpciBvd24sIG5vdCBpbmhlcml0ZWQsIGVudW1lcmFibGUgcHJvcGVydGllcy4gRm9yIGNvbXBhcmluZyBhIHNpbmdsZVxuICAgICAqIG93biBvciBpbmhlcml0ZWQgcHJvcGVydHkgdmFsdWUgc2VlIGBfLm1hdGNoZXNQcm9wZXJ0eWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSwgJ3BldHMnOiBbJ2hvcHB5J10gfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSwgJ3BldHMnOiBbJ2JhYnkgcHVzcycsICdkaW5vJ10gfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnBsdWNrKF8ud2hlcmUodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydiYXJuZXknXVxuICAgICAqXG4gICAgICogXy5wbHVjayhfLndoZXJlKHVzZXJzLCB7ICdwZXRzJzogWydkaW5vJ10gfSksICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydmcmVkJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3aGVyZShjb2xsZWN0aW9uLCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBmaWx0ZXIoY29sbGVjdGlvbiwgYmFzZU1hdGNoZXMoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICAgICAqICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IERhdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICAgICAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAgICAgKiB9LCBfLm5vdygpKTtcbiAgICAgKiAvLyA9PiBsb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBmdW5jdGlvbiB0byBiZSBpbnZva2VkXG4gICAgICovXG4gICAgdmFyIG5vdyA9IG5hdGl2ZU5vdyB8fCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICB9O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmJlZm9yZWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiBgZnVuY2Agb25jZSBpdCBpcyBjYWxsZWQgYG5gIG9yIG1vcmUgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGNhbGxzIGJlZm9yZSBgZnVuY2AgaXMgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZXN0cmljdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByZXN0cmljdGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgc2F2ZXMgPSBbJ3Byb2ZpbGUnLCAnc2V0dGluZ3MnXTtcbiAgICAgKlxuICAgICAqIHZhciBkb25lID0gXy5hZnRlcihzYXZlcy5sZW5ndGgsIGZ1bmN0aW9uKCkge1xuICAgICAqICAgY29uc29sZS5sb2coJ2RvbmUgc2F2aW5nIScpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogXy5mb3JFYWNoKHNhdmVzLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICogICBhc3luY1NhdmUoeyAndHlwZSc6IHR5cGUsICdjb21wbGV0ZSc6IGRvbmUgfSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gbG9ncyAnZG9uZSBzYXZpbmchJyBhZnRlciB0aGUgdHdvIGFzeW5jIHNhdmVzIGhhdmUgY29tcGxldGVkXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWZ0ZXIobiwgZnVuYykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB2YXIgdGVtcCA9IG47XG4gICAgICAgICAgbiA9IGZ1bmM7XG4gICAgICAgICAgZnVuYyA9IHRlbXA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBuID0gbmF0aXZlSXNGaW5pdGUobiA9ICtuKSA/IG4gOiAwO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoLS1uIDwgMSkge1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB1cCB0byBgbmAgYXJndW1lbnRzIGlnbm9yaW5nIGFueVxuICAgICAqIGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgY2FwLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnOCcsICcxMCddLCBfLmFyeShwYXJzZUludCwgMSkpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnkoZnVuYywgbiwgZ3VhcmQpIHtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChmdW5jLCBuLCBndWFyZCkpIHtcbiAgICAgICAgbiA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIG4gPSAoZnVuYyAmJiBuID09IG51bGwpID8gZnVuYy5sZW5ndGggOiBuYXRpdmVNYXgoK24gfHwgMCwgMCk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBBUllfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCwgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50c1xuICAgICAqIG9mIHRoZSBjcmVhdGVkIGZ1bmN0aW9uLCB3aGlsZSBpdCBpcyBjYWxsZWQgbGVzcyB0aGFuIGBuYCB0aW1lcy4gU3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBjYWxscyBhdCB3aGljaCBgZnVuY2AgaXMgbm8gbG9uZ2VyIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogalF1ZXJ5KCcjYWRkJykub24oJ2NsaWNrJywgXy5iZWZvcmUoNSwgYWRkQ29udGFjdFRvTGlzdCkpO1xuICAgICAqIC8vID0+IGFsbG93cyBhZGRpbmcgdXAgdG8gNCBjb250YWN0cyB0byB0aGUgbGlzdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJlZm9yZShuLCBmdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB2YXIgdGVtcCA9IG47XG4gICAgICAgICAgbiA9IGZ1bmM7XG4gICAgICAgICAgZnVuYyA9IHRlbXA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICgtLW4gPiAwKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuIDw9IDEpIHtcbiAgICAgICAgICBmdW5jID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGB0aGlzQXJnYFxuICAgICAqIGFuZCBwcmVwZW5kcyBhbnkgYWRkaXRpb25hbCBgXy5iaW5kYCBhcmd1bWVudHMgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlXG4gICAgICogYm91bmQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAgICAgKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAgdGhpcyBtZXRob2QgZG9lcyBub3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gICAgICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAgICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGdyZWV0ID0gZnVuY3Rpb24oZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gICAgICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAgICAgKlxuICAgICAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCAnaGknKTtcbiAgICAgKiBib3VuZCgnIScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkISdcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICAgICAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkISdcbiAgICAgKi9cbiAgICB2YXIgYmluZCA9IHJlc3RQYXJhbShmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGJpbmQucGxhY2Vob2xkZXIpO1xuICAgICAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEJpbmRzIG1ldGhvZHMgb2YgYW4gb2JqZWN0IHRvIHRoZSBvYmplY3QgaXRzZWxmLCBvdmVyd3JpdGluZyB0aGUgZXhpc3RpbmdcbiAgICAgKiBtZXRob2QuIE1ldGhvZCBuYW1lcyBtYXkgYmUgc3BlY2lmaWVkIGFzIGluZGl2aWR1YWwgYXJndW1lbnRzIG9yIGFzIGFycmF5c1xuICAgICAqIG9mIG1ldGhvZCBuYW1lcy4gSWYgbm8gbWV0aG9kIG5hbWVzIGFyZSBwcm92aWRlZCBhbGwgZW51bWVyYWJsZSBmdW5jdGlvblxuICAgICAqIHByb3BlcnRpZXMsIG93biBhbmQgaW5oZXJpdGVkLCBvZiBgb2JqZWN0YCBhcmUgYm91bmQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lcyBub3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGJvdW5kIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBiaW5kIGFuZCBhc3NpZ24gdGhlIGJvdW5kIG1ldGhvZHMgdG8uXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW21ldGhvZE5hbWVzXSBUaGUgb2JqZWN0IG1ldGhvZCBuYW1lcyB0byBiaW5kLFxuICAgICAqICBzcGVjaWZpZWQgYXMgaW5kaXZpZHVhbCBtZXRob2QgbmFtZXMgb3IgYXJyYXlzIG9mIG1ldGhvZCBuYW1lcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdmlldyA9IHtcbiAgICAgKiAgICdsYWJlbCc6ICdkb2NzJyxcbiAgICAgKiAgICdvbkNsaWNrJzogZnVuY3Rpb24oKSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdjbGlja2VkICcgKyB0aGlzLmxhYmVsKTtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5iaW5kQWxsKHZpZXcpO1xuICAgICAqIGpRdWVyeSgnI2RvY3MnKS5vbignY2xpY2snLCB2aWV3Lm9uQ2xpY2spO1xuICAgICAqIC8vID0+IGxvZ3MgJ2NsaWNrZWQgZG9jcycgd2hlbiB0aGUgZWxlbWVudCBpcyBjbGlja2VkXG4gICAgICovXG4gICAgdmFyIGJpbmRBbGwgPSByZXN0UGFyYW0oZnVuY3Rpb24ob2JqZWN0LCBtZXRob2ROYW1lcykge1xuICAgICAgbWV0aG9kTmFtZXMgPSBtZXRob2ROYW1lcy5sZW5ndGggPyBiYXNlRmxhdHRlbihtZXRob2ROYW1lcykgOiBmdW5jdGlvbnMob2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gbWV0aG9kTmFtZXMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gbWV0aG9kTmFtZXNbaW5kZXhdO1xuICAgICAgICBvYmplY3Rba2V5XSA9IGNyZWF0ZVdyYXBwZXIob2JqZWN0W2tleV0sIEJJTkRfRkxBRywgb2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBtZXRob2QgYXQgYG9iamVjdFtrZXldYCBhbmQgcHJlcGVuZHNcbiAgICAgKiBhbnkgYWRkaXRpb25hbCBgXy5iaW5kS2V5YCBhcmd1bWVudHMgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIGJvdW5kIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIGBfLmJpbmRgIGJ5IGFsbG93aW5nIGJvdW5kIGZ1bmN0aW9ucyB0byByZWZlcmVuY2VcbiAgICAgKiBtZXRob2RzIHRoYXQgbWF5IGJlIHJlZGVmaW5lZCBvciBkb24ndCB5ZXQgZXhpc3QuXG4gICAgICogU2VlIFtQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZV0oaHR0cDovL3BldGVyLm1pY2hhdXguY2EvYXJ0aWNsZXMvbGF6eS1mdW5jdGlvbi1kZWZpbml0aW9uLXBhdHRlcm4pXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kS2V5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0aGUgbWV0aG9kIGJlbG9uZ3MgdG8uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAndXNlcic6ICdmcmVkJyxcbiAgICAgKiAgICdncmVldCc6IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kS2V5KG9iamVjdCwgJ2dyZWV0JywgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiBvYmplY3QuZ3JlZXQgPSBmdW5jdGlvbihncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICd5YSAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpeWEgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBwbGFjZWhvbGRlcnNcbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmRLZXkob2JqZWN0LCAnZ3JlZXQnLCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaXlhIGZyZWQhJ1xuICAgICAqL1xuICAgIHZhciBiaW5kS2V5ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKG9iamVjdCwga2V5LCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kS2V5LnBsYWNlaG9sZGVyKTtcbiAgICAgICAgYml0bWFzayB8PSBQQVJUSUFMX0ZMQUc7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcHBlcihrZXksIGJpdG1hc2ssIG9iamVjdCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyBvbmUgb3IgbW9yZSBhcmd1bWVudHMgb2YgYGZ1bmNgIHRoYXQgd2hlblxuICAgICAqIGNhbGxlZCBlaXRoZXIgaW52b2tlcyBgZnVuY2AgcmV0dXJuaW5nIGl0cyByZXN1bHQsIGlmIGFsbCBgZnVuY2AgYXJndW1lbnRzXG4gICAgICogaGF2ZSBiZWVuIHByb3ZpZGVkLCBvciByZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIG9uZSBvciBtb3JlIG9mIHRoZVxuICAgICAqIHJlbWFpbmluZyBgZnVuY2AgYXJndW1lbnRzLCBhbmQgc28gb24uIFRoZSBhcml0eSBvZiBgZnVuY2AgbWF5IGJlIHNwZWNpZmllZFxuICAgICAqIGlmIGBmdW5jLmxlbmd0aGAgaXMgbm90IHN1ZmZpY2llbnQuXG4gICAgICpcbiAgICAgKiBUaGUgYF8uY3VycnkucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gICAgICogbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBjdXJyaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHk9ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFiYyA9IGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAgICAgKiAgIHJldHVybiBbYSwgYiwgY107XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBjdXJyaWVkID0gXy5jdXJyeShhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgxKSgyKSgzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMikoMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgcGxhY2Vob2xkZXJzXG4gICAgICogY3VycmllZCgxKShfLCAzKSgyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICB2YXIgY3VycnkgPSBjcmVhdGVDdXJyeShDVVJSWV9GTEFHKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY3VycnlgIGV4Y2VwdCB0aGF0IGFyZ3VtZW50cyBhcmUgYXBwbGllZCB0byBgZnVuY2BcbiAgICAgKiBpbiB0aGUgbWFubmVyIG9mIGBfLnBhcnRpYWxSaWdodGAgaW5zdGVhZCBvZiBgXy5wYXJ0aWFsYC5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5jdXJyeVJpZ2h0LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgY3VycmllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5PWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhYmMgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgY3VycmllZCA9IF8uY3VycnlSaWdodChhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgzKSgyKSgxKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMiwgMykoMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgcGxhY2Vob2xkZXJzXG4gICAgICogY3VycmllZCgzKSgxLCBfKSgyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICB2YXIgY3VycnlSaWdodCA9IGNyZWF0ZUN1cnJ5KENVUlJZX1JJR0hUX0ZMQUcpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGRlYm91bmNlZCBmdW5jdGlvbiB0aGF0IGRlbGF5cyBpbnZva2luZyBgZnVuY2AgdW50aWwgYWZ0ZXIgYHdhaXRgXG4gICAgICogbWlsbGlzZWNvbmRzIGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gd2FzXG4gICAgICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICAgICAqIGRlbGF5ZWQgaW52b2NhdGlvbnMuIFByb3ZpZGUgYW4gb3B0aW9ucyBvYmplY3QgdG8gaW5kaWNhdGUgdGhhdCBgZnVuY2BcbiAgICAgKiBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gICAgICogU3Vic2VxdWVudCBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0XG4gICAgICogYGZ1bmNgIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzIGludm9rZWRcbiAgICAgKiBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIGlzXG4gICAgICogaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHA6Ly9kcnVwYWxtb3Rpb24uY29tL2FydGljbGUvZGVib3VuY2UtYW5kLXRocm90dGxlLXZpc3VhbC1leHBsYW5hdGlvbilcbiAgICAgKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV0gU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZ1xuICAgICAqICBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XSBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlXG4gICAgICogIGRlbGF5ZWQgYmVmb3JlIGl0IGlzIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXSBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZ1xuICAgICAqICBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gYXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eFxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gICAgICpcbiAgICAgKiAvLyBpbnZva2UgYHNlbmRNYWlsYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgZGVib3VuY2luZyBzdWJzZXF1ZW50IGNhbGxzXG4gICAgICogalF1ZXJ5KCcjcG9zdGJveCcpLm9uKCdjbGljaycsIF8uZGVib3VuY2Uoc2VuZE1haWwsIDMwMCwge1xuICAgICAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICAgICAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAgICAgKiB9KSk7XG4gICAgICpcbiAgICAgKiAvLyBlbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzXG4gICAgICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICAgICAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7XG4gICAgICogICAnbWF4V2FpdCc6IDEwMDBcbiAgICAgKiB9KSk7XG4gICAgICpcbiAgICAgKiAvLyBjYW5jZWwgYSBkZWJvdW5jZWQgY2FsbFxuICAgICAqIHZhciB0b2RvQ2hhbmdlcyA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDEwMDApO1xuICAgICAqIE9iamVjdC5vYnNlcnZlKG1vZGVscy50b2RvLCB0b2RvQ2hhbmdlcyk7XG4gICAgICpcbiAgICAgKiBPYmplY3Qub2JzZXJ2ZShtb2RlbHMsIGZ1bmN0aW9uKGNoYW5nZXMpIHtcbiAgICAgKiAgIGlmIChfLmZpbmQoY2hhbmdlcywgeyAndXNlcic6ICd0b2RvJywgJ3R5cGUnOiAnZGVsZXRlJ30pKSB7XG4gICAgICogICAgIHRvZG9DaGFuZ2VzLmNhbmNlbCgpO1xuICAgICAqICAgfVxuICAgICAqIH0sIFsnZGVsZXRlJ10pO1xuICAgICAqXG4gICAgICogLy8gLi4uYXQgc29tZSBwb2ludCBgbW9kZWxzLnRvZG9gIGlzIGNoYW5nZWRcbiAgICAgKiBtb2RlbHMudG9kby5jb21wbGV0ZWQgPSB0cnVlO1xuICAgICAqXG4gICAgICogLy8gLi4uYmVmb3JlIDEgc2Vjb25kIGhhcyBwYXNzZWQgYG1vZGVscy50b2RvYCBpcyBkZWxldGVkXG4gICAgICogLy8gd2hpY2ggY2FuY2VscyB0aGUgZGVib3VuY2VkIGB0b2RvQ2hhbmdlc2AgY2FsbFxuICAgICAqIGRlbGV0ZSBtb2RlbHMudG9kbztcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgYXJncyxcbiAgICAgICAgICBtYXhUaW1lb3V0SWQsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgIHN0YW1wLFxuICAgICAgICAgIHRoaXNBcmcsXG4gICAgICAgICAgdGltZW91dElkLFxuICAgICAgICAgIHRyYWlsaW5nQ2FsbCxcbiAgICAgICAgICBsYXN0Q2FsbGVkID0gMCxcbiAgICAgICAgICBtYXhXYWl0ID0gZmFsc2UsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB3YWl0ID0gd2FpdCA8IDAgPyAwIDogKCt3YWl0IHx8IDApO1xuICAgICAgaWYgKG9wdGlvbnMgPT09IHRydWUpIHtcbiAgICAgICAgdmFyIGxlYWRpbmcgPSB0cnVlO1xuICAgICAgICB0cmFpbGluZyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgICAgIG1heFdhaXQgPSAnbWF4V2FpdCcgaW4gb3B0aW9ucyAmJiBuYXRpdmVNYXgoK29wdGlvbnMubWF4V2FpdCB8fCAwLCB3YWl0KTtcbiAgICAgICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgICAgICBpZiAodGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heFRpbWVvdXRJZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dChtYXhUaW1lb3V0SWQpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RDYWxsZWQgPSAwO1xuICAgICAgICBtYXhUaW1lb3V0SWQgPSB0aW1lb3V0SWQgPSB0cmFpbGluZ0NhbGwgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNvbXBsZXRlKGlzQ2FsbGVkLCBpZCkge1xuICAgICAgICBpZiAoaWQpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaWQpO1xuICAgICAgICB9XG4gICAgICAgIG1heFRpbWVvdXRJZCA9IHRpbWVvdXRJZCA9IHRyYWlsaW5nQ2FsbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGlzQ2FsbGVkKSB7XG4gICAgICAgICAgbGFzdENhbGxlZCA9IG5vdygpO1xuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgaWYgKCF0aW1lb3V0SWQgJiYgIW1heFRpbWVvdXRJZCkge1xuICAgICAgICAgICAgYXJncyA9IHRoaXNBcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlbGF5ZWQoKSB7XG4gICAgICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdygpIC0gc3RhbXApO1xuICAgICAgICBpZiAocmVtYWluaW5nIDw9IDAgfHwgcmVtYWluaW5nID4gd2FpdCkge1xuICAgICAgICAgIGNvbXBsZXRlKHRyYWlsaW5nQ2FsbCwgbWF4VGltZW91dElkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGRlbGF5ZWQsIHJlbWFpbmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gbWF4RGVsYXllZCgpIHtcbiAgICAgICAgY29tcGxldGUodHJhaWxpbmcsIHRpbWVvdXRJZCk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgc3RhbXAgPSBub3coKTtcbiAgICAgICAgdGhpc0FyZyA9IHRoaXM7XG4gICAgICAgIHRyYWlsaW5nQ2FsbCA9IHRyYWlsaW5nICYmICh0aW1lb3V0SWQgfHwgIWxlYWRpbmcpO1xuXG4gICAgICAgIGlmIChtYXhXYWl0ID09PSBmYWxzZSkge1xuICAgICAgICAgIHZhciBsZWFkaW5nQ2FsbCA9IGxlYWRpbmcgJiYgIXRpbWVvdXRJZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIW1heFRpbWVvdXRJZCAmJiAhbGVhZGluZykge1xuICAgICAgICAgICAgbGFzdENhbGxlZCA9IHN0YW1wO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgcmVtYWluaW5nID0gbWF4V2FpdCAtIChzdGFtcCAtIGxhc3RDYWxsZWQpLFxuICAgICAgICAgICAgICBpc0NhbGxlZCA9IHJlbWFpbmluZyA8PSAwIHx8IHJlbWFpbmluZyA+IG1heFdhaXQ7XG5cbiAgICAgICAgICBpZiAoaXNDYWxsZWQpIHtcbiAgICAgICAgICAgIGlmIChtYXhUaW1lb3V0SWQpIHtcbiAgICAgICAgICAgICAgbWF4VGltZW91dElkID0gY2xlYXJUaW1lb3V0KG1heFRpbWVvdXRJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmICghbWF4VGltZW91dElkKSB7XG4gICAgICAgICAgICBtYXhUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KG1heERlbGF5ZWQsIHJlbWFpbmluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0NhbGxlZCAmJiB0aW1lb3V0SWQpIHtcbiAgICAgICAgICB0aW1lb3V0SWQgPSBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghdGltZW91dElkICYmIHdhaXQgIT09IG1heFdhaXQpIHtcbiAgICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGRlbGF5ZWQsIHdhaXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsZWFkaW5nQ2FsbCkge1xuICAgICAgICAgIGlzQ2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0NhbGxlZCAmJiAhdGltZW91dElkICYmICFtYXhUaW1lb3V0SWQpIHtcbiAgICAgICAgICBhcmdzID0gdGhpc0FyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgZGVib3VuY2VkLmNhbmNlbCA9IGNhbmNlbDtcbiAgICAgIHJldHVybiBkZWJvdW5jZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmZXJzIGludm9raW5nIHRoZSBgZnVuY2AgdW50aWwgdGhlIGN1cnJlbnQgY2FsbCBzdGFjayBoYXMgY2xlYXJlZC4gQW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIGBmdW5jYCB3aGVuIGl0IGlzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWZlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgZnVuY3Rpb24gd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAnZGVmZXJyZWQnKTtcbiAgICAgKiAvLyBsb2dzICdkZWZlcnJlZCcgYWZ0ZXIgb25lIG9yIG1vcmUgbWlsbGlzZWNvbmRzXG4gICAgICovXG4gICAgdmFyIGRlZmVyID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgMSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIGBmdW5jYCBhZnRlciBgd2FpdGAgbWlsbGlzZWNvbmRzLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gYGZ1bmNgIHdoZW4gaXQgaXMgaW52b2tlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3YWl0IFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5IGludm9jYXRpb24uXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIGZ1bmN0aW9uIHdpdGguXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXIgaWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVsYXkoZnVuY3Rpb24odGV4dCkge1xuICAgICAqICAgY29uc29sZS5sb2codGV4dCk7XG4gICAgICogfSwgMTAwMCwgJ2xhdGVyJyk7XG4gICAgICogLy8gPT4gbG9ncyAnbGF0ZXInIGFmdGVyIG9uZSBzZWNvbmRcbiAgICAgKi9cbiAgICB2YXIgZGVsYXkgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgd2FpdCwgYXJncykge1xuICAgICAgcmV0dXJuIGJhc2VEZWxheShmdW5jLCB3YWl0LCBhcmdzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHJlc3VsdCBvZiBpbnZva2luZyB0aGUgcHJvdmlkZWRcbiAgICAgKiBmdW5jdGlvbnMgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24sIHdoZXJlIGVhY2hcbiAgICAgKiBzdWNjZXNzaXZlIGludm9jYXRpb24gaXMgc3VwcGxpZWQgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJldmlvdXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gey4uLkZ1bmN0aW9ufSBbZnVuY3NdIEZ1bmN0aW9ucyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGFkZFNxdWFyZSA9IF8uZmxvdyhfLmFkZCwgc3F1YXJlKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93ID0gY3JlYXRlRmxvdygpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbG93YCBleGNlcHQgdGhhdCBpdCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdFxuICAgICAqIGludm9rZXMgdGhlIHByb3ZpZGVkIGZ1bmN0aW9ucyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgYmFja2Zsb3csIGNvbXBvc2VcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gey4uLkZ1bmN0aW9ufSBbZnVuY3NdIEZ1bmN0aW9ucyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGFkZFNxdWFyZSA9IF8uZmxvd1JpZ2h0KHNxdWFyZSwgXy5hZGQpO1xuICAgICAqIGFkZFNxdWFyZSgxLCAyKTtcbiAgICAgKiAvLyA9PiA5XG4gICAgICovXG4gICAgdmFyIGZsb3dSaWdodCA9IGNyZWF0ZUZsb3codHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBtZW1vaXplcyB0aGUgcmVzdWx0IG9mIGBmdW5jYC4gSWYgYHJlc29sdmVyYCBpc1xuICAgICAqIHByb3ZpZGVkIGl0IGRldGVybWluZXMgdGhlIGNhY2hlIGtleSBmb3Igc3RvcmluZyB0aGUgcmVzdWx0IGJhc2VkIG9uIHRoZVxuICAgICAqIGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uIEJ5IGRlZmF1bHQsIHRoZSBmaXJzdCBhcmd1bWVudFxuICAgICAqIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbiBpcyBjb2VyY2VkIHRvIGEgc3RyaW5nIGFuZCB1c2VkIGFzIHRoZVxuICAgICAqIGNhY2hlIGtleS4gVGhlIGBmdW5jYCBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjYWNoZSBpcyBleHBvc2VkIGFzIHRoZSBgY2FjaGVgIHByb3BlcnR5IG9uIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlIFtgTWFwYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtcHJvcGVydGllcy1vZi10aGUtbWFwLXByb3RvdHlwZS1vYmplY3QpXG4gICAgICogbWV0aG9kIGludGVyZmFjZSBvZiBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6aW5nIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXBwZXJDYXNlID0gXy5tZW1vaXplKGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAqICAgcmV0dXJuIHN0cmluZy50b1VwcGVyQ2FzZSgpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogdXBwZXJDYXNlKCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0ZSRUQnXG4gICAgICpcbiAgICAgKiAvLyBtb2RpZnlpbmcgdGhlIHJlc3VsdCBjYWNoZVxuICAgICAqIHVwcGVyQ2FzZS5jYWNoZS5zZXQoJ2ZyZWQnLCAnQkFSTkVZJyk7XG4gICAgICogdXBwZXJDYXNlKCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0JBUk5FWSdcbiAgICAgKlxuICAgICAqIC8vIHJlcGxhY2luZyBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gICAgICogdmFyIG90aGVyID0geyAndXNlcic6ICdiYXJuZXknIH07XG4gICAgICogdmFyIGlkZW50aXR5ID0gXy5tZW1vaXplKF8uaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogaWRlbnRpdHkob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAgICAgKiBpZGVudGl0eShvdGhlcik7XG4gICAgICogLy8gPT4geyAndXNlcic6ICdmcmVkJyB9XG4gICAgICpcbiAgICAgKiBfLm1lbW9pemUuQ2FjaGUgPSBXZWFrTWFwO1xuICAgICAqIHZhciBpZGVudGl0eSA9IF8ubWVtb2l6ZShfLmlkZW50aXR5KTtcbiAgICAgKlxuICAgICAqIGlkZW50aXR5KG9iamVjdCk7XG4gICAgICogLy8gPT4geyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogaWRlbnRpdHkob3RoZXIpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVtb2l6ZShmdW5jLCByZXNvbHZlcikge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicgfHwgKHJlc29sdmVyICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBrZXkgPSByZXNvbHZlciA/IHJlc29sdmVyLmFwcGx5KHRoaXMsIGFyZ3MpIDogYXJnc1swXSxcbiAgICAgICAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7XG5cbiAgICAgICAgaWYgKGNhY2hlLmhhcyhrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGNhY2hlLmdldChrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBtZW1vaXplZC5jYWNoZSA9IGNhY2hlLnNldChrZXksIHJlc3VsdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBuZXcgbWVtb2l6ZS5DYWNoZTtcbiAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBydW5zIGVhY2ggYXJndW1lbnQgdGhyb3VnaCBhIGNvcnJlc3BvbmRpbmdcbiAgICAgKiB0cmFuc2Zvcm0gZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbdHJhbnNmb3Jtc10gVGhlIGZ1bmN0aW9ucyB0byB0cmFuc2Zvcm1cbiAgICAgKiBhcmd1bWVudHMsIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIGZ1bmN0aW9ucyBvciBhcnJheXMgb2YgZnVuY3Rpb25zLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBkb3VibGVkKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBtb2RkZWQgPSBfLm1vZEFyZ3MoZnVuY3Rpb24oeCwgeSkge1xuICAgICAqICAgcmV0dXJuIFt4LCB5XTtcbiAgICAgKiB9LCBzcXVhcmUsIGRvdWJsZWQpO1xuICAgICAqXG4gICAgICogbW9kZGVkKDEsIDIpO1xuICAgICAqIC8vID0+IFsxLCA0XVxuICAgICAqXG4gICAgICogbW9kZGVkKDUsIDEwKTtcbiAgICAgKiAvLyA9PiBbMjUsIDIwXVxuICAgICAqL1xuICAgIHZhciBtb2RBcmdzID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGZ1bmMsIHRyYW5zZm9ybXMpIHtcbiAgICAgIHRyYW5zZm9ybXMgPSBiYXNlRmxhdHRlbih0cmFuc2Zvcm1zKTtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nIHx8ICFhcnJheUV2ZXJ5KHRyYW5zZm9ybXMsIGJhc2VJc0Z1bmN0aW9uKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG4gICAgICByZXR1cm4gcmVzdFBhcmFtKGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gbmF0aXZlTWluKGFyZ3MubGVuZ3RoLCBsZW5ndGgpO1xuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gdHJhbnNmb3Jtc1tpbmRleF0oYXJnc1tpbmRleF0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBuZWdhdGVzIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBgZnVuY2AuIFRoZVxuICAgICAqIGBmdW5jYCBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBuZWdhdGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGlzRXZlbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMDtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihbMSwgMiwgMywgNCwgNSwgNl0sIF8ubmVnYXRlKGlzRXZlbikpO1xuICAgICAqIC8vID0+IFsxLCAzLCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG5lZ2F0ZShwcmVkaWNhdGUpIHtcbiAgICAgIGlmICh0eXBlb2YgcHJlZGljYXRlICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gIXByZWRpY2F0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpcyByZXN0cmljdGVkIHRvIGludm9raW5nIGBmdW5jYCBvbmNlLiBSZXBlYXQgY2FsbHNcbiAgICAgKiB0byB0aGUgZnVuY3Rpb24gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgY2FsbC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBpbml0aWFsaXplID0gXy5vbmNlKGNyZWF0ZUFwcGxpY2F0aW9uKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogaW5pdGlhbGl6ZSgpO1xuICAgICAqIC8vIGBpbml0aWFsaXplYCBpbnZva2VzIGBjcmVhdGVBcHBsaWNhdGlvbmAgb25jZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9uY2UoZnVuYykge1xuICAgICAgcmV0dXJuIGJlZm9yZSgyLCBmdW5jKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGBwYXJ0aWFsYCBhcmd1bWVudHMgcHJlcGVuZGVkXG4gICAgICogdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi4gVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5iaW5kYCBleGNlcHRcbiAgICAgKiBpdCBkb2VzICoqbm90KiogYWx0ZXIgdGhlIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBwYXJ0aWFsbHlcbiAgICAgKiBhcHBsaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseSBhcmd1bWVudHMgdG8uXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcGFydGlhbGx5IGFwcGxpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBuYW1lKSB7XG4gICAgICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyBuYW1lO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgc2F5SGVsbG9UbyA9IF8ucGFydGlhbChncmVldCwgJ2hlbGxvJyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgcGxhY2Vob2xkZXJzXG4gICAgICogdmFyIGdyZWV0RnJlZCA9IF8ucGFydGlhbChncmVldCwgXywgJ2ZyZWQnKTtcbiAgICAgKiBncmVldEZyZWQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQnXG4gICAgICovXG4gICAgdmFyIHBhcnRpYWwgPSBjcmVhdGVQYXJ0aWFsKFBBUlRJQUxfRkxBRyk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnBhcnRpYWxgIGV4Y2VwdCB0aGF0IHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50c1xuICAgICAqIGFyZSBhcHBlbmRlZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWxSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lcyBub3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIHBhcnRpYWxseVxuICAgICAqIGFwcGxpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXJ0aWFsbHkgYXBwbGllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGdyZWV0ID0gZnVuY3Rpb24oZ3JlZXRpbmcsIG5hbWUpIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIG5hbWU7XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2ZyZWQnKTtcbiAgICAgKiBncmVldEZyZWQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQnXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBwbGFjZWhvbGRlcnNcbiAgICAgKiB2YXIgc2F5SGVsbG9UbyA9IF8ucGFydGlhbFJpZ2h0KGdyZWV0LCAnaGVsbG8nLCBfKTtcbiAgICAgKiBzYXlIZWxsb1RvKCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQnXG4gICAgICovXG4gICAgdmFyIHBhcnRpYWxSaWdodCA9IGNyZWF0ZVBhcnRpYWwoUEFSVElBTF9SSUdIVF9GTEFHKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggYXJndW1lbnRzIGFycmFuZ2VkIGFjY29yZGluZ1xuICAgICAqIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgYXJndW1lbnQgdmFsdWUgYXQgdGhlIGZpcnN0IGluZGV4IGlzXG4gICAgICogcHJvdmlkZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCB0aGUgYXJndW1lbnQgdmFsdWUgYXQgdGhlIHNlY29uZCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlYXJyYW5nZSBhcmd1bWVudHMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFyZ3VtZW50IGluZGV4ZXMsXG4gICAgICogIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIGluZGV4ZXMgb3IgYXJyYXlzIG9mIGluZGV4ZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciByZWFyZ2VkID0gXy5yZWFyZyhmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH0sIDIsIDAsIDEpO1xuICAgICAqXG4gICAgICogcmVhcmdlZCgnYicsICdjJywgJ2EnKVxuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqXG4gICAgICogdmFyIG1hcCA9IF8ucmVhcmcoXy5tYXAsIFsxLCAwXSk7XG4gICAgICogbWFwKGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogMztcbiAgICAgKiB9LCBbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFszLCA2LCA5XVxuICAgICAqL1xuICAgIHZhciByZWFyZyA9IHJlc3RQYXJhbShmdW5jdGlvbihmdW5jLCBpbmRleGVzKSB7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBSRUFSR19GTEFHLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBiYXNlRmxhdHRlbihpbmRleGVzKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXMgYW4gYXJyYXkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gICAgICogICByZXR1cm4gd2hhdCArICcgJyArIF8uaW5pdGlhbChuYW1lcykuam9pbignLCAnKSArXG4gICAgICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gc3RhcnQsIDApLFxuICAgICAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICByZXN0W2luZGV4XSA9IGFyZ3Nbc3RhcnQgKyBpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCByZXN0KTtcbiAgICAgICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgICAgICBpbmRleCA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IHN0YXJ0KSB7XG4gICAgICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIG90aGVyQXJnc1tzdGFydF0gPSByZXN0O1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uIGFuZCBhbiBhcnJheSBvZiBhcmd1bWVudHMgbXVjaCBsaWtlIFtgRnVuY3Rpb24jYXBwbHlgXShodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS4zLjQuMykuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtzcHJlYWQgb3BlcmF0b3JdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL09wZXJhdG9ycy9TcHJlYWRfb3BlcmF0b3IpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gc3ByZWFkIGFyZ3VtZW50cyBvdmVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgc2F5ID0gXy5zcHJlYWQoZnVuY3Rpb24od2hvLCB3aGF0KSB7XG4gICAgICogICByZXR1cm4gd2hvICsgJyBzYXlzICcgKyB3aGF0O1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KFsnZnJlZCcsICdoZWxsbyddKTtcbiAgICAgKiAvLyA9PiAnZnJlZCBzYXlzIGhlbGxvJ1xuICAgICAqXG4gICAgICogLy8gd2l0aCBhIFByb21pc2VcbiAgICAgKiB2YXIgbnVtYmVycyA9IFByb21pc2UuYWxsKFtcbiAgICAgKiAgIFByb21pc2UucmVzb2x2ZSg0MCksXG4gICAgICogICBQcm9taXNlLnJlc29sdmUoMzYpXG4gICAgICogXSk7XG4gICAgICpcbiAgICAgKiBudW1iZXJzLnRoZW4oXy5zcHJlYWQoZnVuY3Rpb24oeCwgeSkge1xuICAgICAqICAgcmV0dXJuIHggKyB5O1xuICAgICAqIH0pKTtcbiAgICAgKiAvLyA9PiBhIFByb21pc2Ugb2YgNzZcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzcHJlYWQoZnVuYykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFycmF5KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHRocm90dGxlZCBmdW5jdGlvbiB0aGF0IG9ubHkgaW52b2tlcyBgZnVuY2AgYXQgbW9zdCBvbmNlIHBlclxuICAgICAqIGV2ZXJ5IGB3YWl0YCBtaWxsaXNlY29uZHMuIFRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgXG4gICAgICogbWV0aG9kIHRvIGNhbmNlbCBkZWxheWVkIGludm9jYXRpb25zLiBQcm92aWRlIGFuIG9wdGlvbnMgb2JqZWN0IHRvIGluZGljYXRlXG4gICAgICogdGhhdCBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlXG4gICAgICogYHdhaXRgIHRpbWVvdXQuIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gICAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBjYWxsLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpcyBpbnZva2VkXG4gICAgICogb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhlIHRocm90dGxlZCBmdW5jdGlvbiBpc1xuICAgICAqIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC5cbiAgICAgKlxuICAgICAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwOi8vZHJ1cGFsbW90aW9uLmNvbS9hcnRpY2xlL2RlYm91bmNlLWFuZC10aHJvdHRsZS12aXN1YWwtZXhwbGFuYXRpb24pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV0gU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZ1xuICAgICAqICBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV0gU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmdcbiAgICAgKiAgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIGF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmdcbiAgICAgKiBqUXVlcnkod2luZG93KS5vbignc2Nyb2xsJywgXy50aHJvdHRsZSh1cGRhdGVQb3NpdGlvbiwgMTAwKSk7XG4gICAgICpcbiAgICAgKiAvLyBpbnZva2UgYHJlbmV3VG9rZW5gIHdoZW4gdGhlIGNsaWNrIGV2ZW50IGlzIGZpcmVkLCBidXQgbm90IG1vcmUgdGhhbiBvbmNlIGV2ZXJ5IDUgbWludXRlc1xuICAgICAqIGpRdWVyeSgnLmludGVyYWN0aXZlJykub24oJ2NsaWNrJywgXy50aHJvdHRsZShyZW5ld1Rva2VuLCAzMDAwMDAsIHtcbiAgICAgKiAgICd0cmFpbGluZyc6IGZhbHNlXG4gICAgICogfSkpO1xuICAgICAqXG4gICAgICogLy8gY2FuY2VsIGEgdHJhaWxpbmcgdGhyb3R0bGVkIGNhbGxcbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICAgICAgbGVhZGluZyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gJ2xlYWRpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMubGVhZGluZyA6IGxlYWRpbmc7XG4gICAgICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVib3VuY2UoZnVuYywgd2FpdCwgeyAnbGVhZGluZyc6IGxlYWRpbmcsICdtYXhXYWl0JzogK3dhaXQsICd0cmFpbGluZyc6IHRyYWlsaW5nIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHByb3ZpZGVzIGB2YWx1ZWAgdG8gdGhlIHdyYXBwZXIgZnVuY3Rpb24gYXMgaXRzXG4gICAgICogZmlyc3QgYXJndW1lbnQuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgZnVuY3Rpb24gYXJlXG4gICAgICogYXBwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIHdyYXBwZXIgZnVuY3Rpb24uIFRoZSB3cmFwcGVyIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gd3JhcHBlciBUaGUgd3JhcHBlciBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHAgPSBfLndyYXAoXy5lc2NhcGUsIGZ1bmN0aW9uKGZ1bmMsIHRleHQpIHtcbiAgICAgKiAgIHJldHVybiAnPHA+JyArIGZ1bmModGV4dCkgKyAnPC9wPic7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBwKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICc8cD5mcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXM8L3A+J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXAodmFsdWUsIHdyYXBwZXIpIHtcbiAgICAgIHdyYXBwZXIgPSB3cmFwcGVyID09IG51bGwgPyBpZGVudGl0eSA6IHdyYXBwZXI7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcHBlcih3cmFwcGVyLCBQQVJUSUFMX0ZMQUcsIHVuZGVmaW5lZCwgW3ZhbHVlXSwgW10pO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgaXNEZWVwYCBpcyBgdHJ1ZWAgbmVzdGVkIG9iamVjdHMgYXJlIGNsb25lZCxcbiAgICAgKiBvdGhlcndpc2UgdGhleSBhcmUgYXNzaWduZWQgYnkgcmVmZXJlbmNlLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQgaXNcbiAgICAgKiBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIGNsb25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgXG4gICAgICogY2xvbmluZyBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0b1xuICAgICAqIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudDsgKHZhbHVlIFssIGluZGV4fGtleSwgb2JqZWN0XSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvbiB0aGVcbiAgICAgKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L2luZnJhc3RydWN0dXJlLmh0bWwjaW50ZXJuYWwtc3RydWN0dXJlZC1jbG9uaW5nLWFsZ29yaXRobSkuXG4gICAgICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAgICAgKiBjb25zdHJ1Y3RvcnMgb3RoZXIgdGhhbiBgT2JqZWN0YCBhcmUgY2xvbmVkIHRvIHBsYWluIGBPYmplY3RgIG9iamVjdHMuIEFuXG4gICAgICogZW1wdHkgb2JqZWN0IGlzIHJldHVybmVkIGZvciB1bmNsb25lYWJsZSB2YWx1ZXMgc3VjaCBhcyBmdW5jdGlvbnMsIERPTSBub2RlcyxcbiAgICAgKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBjdXN0b21pemVyYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiB2YXIgc2hhbGxvdyA9IF8uY2xvbmUodXNlcnMpO1xuICAgICAqIHNoYWxsb3dbMF0gPT09IHVzZXJzWzBdO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIHZhciBkZWVwID0gXy5jbG9uZSh1c2VycywgdHJ1ZSk7XG4gICAgICogZGVlcFswXSA9PT0gdXNlcnNbMF07XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIGEgY3VzdG9taXplciBjYWxsYmFja1xuICAgICAqIHZhciBlbCA9IF8uY2xvbmUoZG9jdW1lbnQuYm9keSwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIGlmIChfLmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZShmYWxzZSk7XG4gICAgICogICB9XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBlbCA9PT0gZG9jdW1lbnQuYm9keVxuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogZWwubm9kZU5hbWVcbiAgICAgKiAvLyA9PiBCT0RZXG4gICAgICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gICAgICogLy8gPT4gMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lKHZhbHVlLCBpc0RlZXAsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgICAgIGlmIChpc0RlZXAgJiYgdHlwZW9mIGlzRGVlcCAhPSAnYm9vbGVhbicgJiYgaXNJdGVyYXRlZUNhbGwodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplcikpIHtcbiAgICAgICAgaXNEZWVwID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICh0eXBlb2YgaXNEZWVwID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpc0FyZyA9IGN1c3RvbWl6ZXI7XG4gICAgICAgIGN1c3RvbWl6ZXIgPSBpc0RlZXA7XG4gICAgICAgIGlzRGVlcCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICAgICAgPyBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDEpKVxuICAgICAgICA6IGJhc2VDbG9uZSh2YWx1ZSwgaXNEZWVwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQgaXMgaW52b2tlZFxuICAgICAqIHRvIHByb2R1Y2UgdGhlIGNsb25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgIGNsb25pbmdcbiAgICAgKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAgICAgKiBhbmQgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudDsgKHZhbHVlIFssIGluZGV4fGtleSwgb2JqZWN0XSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvbiB0aGVcbiAgICAgKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L2luZnJhc3RydWN0dXJlLmh0bWwjaW50ZXJuYWwtc3RydWN0dXJlZC1jbG9uaW5nLWFsZ29yaXRobSkuXG4gICAgICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAgICAgKiBjb25zdHJ1Y3RvcnMgb3RoZXIgdGhhbiBgT2JqZWN0YCBhcmUgY2xvbmVkIHRvIHBsYWluIGBPYmplY3RgIG9iamVjdHMuIEFuXG4gICAgICogZW1wdHkgb2JqZWN0IGlzIHJldHVybmVkIGZvciB1bmNsb25lYWJsZSB2YWx1ZXMgc3VjaCBhcyBmdW5jdGlvbnMsIERPTSBub2RlcyxcbiAgICAgKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGRlZXAgY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBjdXN0b21pemVyYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIHZhciBkZWVwID0gXy5jbG9uZURlZXAodXNlcnMpO1xuICAgICAqIGRlZXBbMF0gPT09IHVzZXJzWzBdO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAgICAgKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNFbGVtZW50KHZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqIGVsLm5vZGVOYW1lXG4gICAgICogLy8gPT4gQk9EWVxuICAgICAqIGVsLmNoaWxkTm9kZXMubGVuZ3RoO1xuICAgICAqIC8vID0+IDIwXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVEZWVwKHZhbHVlLCBjdXN0b21pemVyLCB0aGlzQXJnKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDEpKVxuICAgICAgICA6IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmd0KDMsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3QoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uZ3QoMSwgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBndCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA+IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ndGUoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndGUoMywgMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndGUoMSwgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBndGUodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPj0gb3RoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgICAgICBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgJiYgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gYXJyYXlUYWc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBib29sZWFuIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNCb29sZWFuKGZhbHNlKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQm9vbGVhbihudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSBmYWxzZSB8fCAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBib29sVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYERhdGVgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUobmV3IERhdGUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNEYXRlKCdNb24gQXByaWwgMjMgMjAxMicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNEYXRlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBkYXRlVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoJzxib2R5PicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gISF2YWx1ZSAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMSAmJiBpc09iamVjdExpa2UodmFsdWUpICYmICFpc1BsYWluT2JqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCBpcyBhblxuICAgICAqIGBhcmd1bWVudHNgIG9iamVjdCwgYXJyYXksIHN0cmluZywgb3IgalF1ZXJ5LWxpa2UgY29sbGVjdGlvbiB3aXRoIGEgbGVuZ3RoXG4gICAgICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkodHJ1ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiYgKGlzQXJyYXkodmFsdWUpIHx8IGlzU3RyaW5nKHZhbHVlKSB8fCBpc0FyZ3VtZW50cyh2YWx1ZSkgfHxcbiAgICAgICAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0Z1bmN0aW9uKHZhbHVlLnNwbGljZSkpKSkge1xuICAgICAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAha2V5cyh2YWx1ZSkubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmVcbiAgICAgKiBlcXVpdmFsZW50LiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQgaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy5cbiAgICAgKiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjb21wYXJpc29ucyBhcmUgaGFuZGxlZCBieSB0aGUgbWV0aG9kXG4gICAgICogaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBvdGhlciBbLCBpbmRleHxrZXldKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBjb21wYXJpbmcgYXJyYXlzLCBib29sZWFucywgYERhdGVgIG9iamVjdHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgYW5kIHN0cmluZ3MuIE9iamVjdHMgYXJlIGNvbXBhcmVkIGJ5XG4gICAgICogdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NIG5vZGVzXG4gICAgICogYXJlICoqbm90Kiogc3VwcG9ydGVkLiBQcm92aWRlIGEgY3VzdG9taXplciBmdW5jdGlvbiB0byBleHRlbmQgc3VwcG9ydFxuICAgICAqIGZvciBjb21wYXJpbmcgb3RoZXIgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGFsaWFzIGVxXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBjdXN0b21pemVyYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAgICAgKlxuICAgICAqIG9iamVjdCA9PSBvdGhlcjtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0VxdWFsKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIGEgY3VzdG9taXplciBjYWxsYmFja1xuICAgICAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICAgICAqIHZhciBvdGhlciA9IFsnaGknLCAnZ29vZGJ5ZSddO1xuICAgICAqXG4gICAgICogXy5pc0VxdWFsKGFycmF5LCBvdGhlciwgZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICogICBpZiAoXy5ldmVyeShbdmFsdWUsIG90aGVyXSwgUmVnRXhwLnByb3RvdHlwZS50ZXN0LCAvXmgoPzppfGVsbG8pJC8pKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VxdWFsKHZhbHVlLCBvdGhlciwgY3VzdG9taXplciwgdGhpc0FyZykge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBiaW5kQ2FsbGJhY2soY3VzdG9taXplciwgdGhpc0FyZywgMykgOiB1bmRlZmluZWQ7XG4gICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIodmFsdWUsIG90aGVyKSA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiAgcmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIpIDogISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gYEVycm9yYCwgYEV2YWxFcnJvcmAsIGBSYW5nZUVycm9yYCwgYFJlZmVyZW5jZUVycm9yYCxcbiAgICAgKiBgU3ludGF4RXJyb3JgLCBgVHlwZUVycm9yYCwgb3IgYFVSSUVycm9yYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGVycm9yIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IobmV3IEVycm9yKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IoRXJyb3IpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgdHlwZW9mIHZhbHVlLm1lc3NhZ2UgPT0gJ3N0cmluZycgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZXJyb3JUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBmaW5pdGUgcHJpbWl0aXZlIG51bWJlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiBbYE51bWJlci5pc0Zpbml0ZWBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5pc2Zpbml0ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZmluaXRlIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKDEwKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKCcxMCcpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKHRydWUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKE9iamVjdCgxMCkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRmluaXRlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIG5hdGl2ZUlzRmluaXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbihfKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAgICAgLy8gYW5kIFNhZmFyaSA4IGVxdWl2YWxlbnRzIHdoaWNoIHJldHVybiAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICAgICAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBmdW5jVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZSBbbGFuZ3VhZ2UgdHlwZV0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4OCkgb2YgYE9iamVjdGAuXG4gICAgICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KHt9KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdCgxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMjkxIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBgb2JqZWN0YCBhbmQgYHNvdXJjZWAgdG8gZGV0ZXJtaW5lIGlmXG4gICAgICogYG9iamVjdGAgY29udGFpbnMgZXF1aXZhbGVudCBwcm9wZXJ0eSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCBpcyBwcm92aWRlZFxuICAgICAqIGl0IGlzIGludm9rZWQgdG8gY29tcGFyZSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgXG4gICAgICogY29tcGFyaXNvbnMgYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGJvdW5kXG4gICAgICogdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIG90aGVyLCBpbmRleHxrZXkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBwcm9wZXJ0aWVzIG9mIGFycmF5cywgYm9vbGVhbnMsXG4gICAgICogYERhdGVgIG9iamVjdHMsIG51bWJlcnMsIGBPYmplY3RgIG9iamVjdHMsIHJlZ2V4ZXMsIGFuZCBzdHJpbmdzLiBGdW5jdGlvbnNcbiAgICAgKiBhbmQgRE9NIG5vZGVzIGFyZSAqKm5vdCoqIHN1cHBvcnRlZC4gUHJvdmlkZSBhIGN1c3RvbWl6ZXIgZnVuY3Rpb24gdG8gZXh0ZW5kXG4gICAgICogc3VwcG9ydCBmb3IgY29tcGFyaW5nIG90aGVyIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2FnZSc6IDQwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2FnZSc6IDM2IH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnZ3JlZXRpbmcnOiAnaGVsbG8nIH07XG4gICAgICogdmFyIHNvdXJjZSA9IHsgJ2dyZWV0aW5nJzogJ2hpJyB9O1xuICAgICAqXG4gICAgICogXy5pc01hdGNoKG9iamVjdCwgc291cmNlLCBmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgKiAgIHJldHVybiBfLmV2ZXJ5KFt2YWx1ZSwgb3RoZXJdLCBSZWdFeHAucHJvdG90eXBlLnRlc3QsIC9eaCg/Oml8ZWxsbykkLykgfHwgdW5kZWZpbmVkO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc01hdGNoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyLCB0aGlzQXJnKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGJpbmRDYWxsYmFjayhjdXN0b21pemVyLCB0aGlzQXJnLCAzKSA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIGdldE1hdGNoRGF0YShzb3VyY2UpLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgTmFOYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBub3QgdGhlIHNhbWUgYXMgW2Bpc05hTmBdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi40KVxuICAgICAqIHdoaWNoIHJldHVybnMgYHRydWVgIGZvciBgdW5kZWZpbmVkYCBhbmQgb3RoZXIgbm9uLW51bWVyaWMgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgTmFOYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKE5hTik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hTihuZXcgTnVtYmVyKE5hTikpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGlzTmFOKHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hTih1bmRlZmluZWQpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOYU4odmFsdWUpIHtcbiAgICAgIC8vIEFuIGBOYU5gIHByaW1pdGl2ZSBpcyB0aGUgb25seSB2YWx1ZSB0aGF0IGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuXG4gICAgICAvLyBQZXJmb3JtIHRoZSBgdG9TdHJpbmdUYWdgIGNoZWNrIGZpcnN0IHRvIGF2b2lkIGVycm9ycyB3aXRoIHNvbWUgaG9zdCBvYmplY3RzIGluIElFLlxuICAgICAgcmV0dXJuIGlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSAhPSArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOYXRpdmUoQXJyYXkucHJvdG90eXBlLnB1c2gpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOYXRpdmUoXyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc05hdGl2ZSh2YWx1ZSkge1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiByZUlzSG9zdEN0b3IudGVzdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYG51bGxgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgbnVsbGAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc051bGwobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bGwodm9pZCAwKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTnVsbCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTnVtYmVyYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRvIGV4Y2x1ZGUgYEluZmluaXR5YCwgYC1JbmZpbml0eWAsIGFuZCBgTmFOYCwgd2hpY2ggYXJlIGNsYXNzaWZpZWRcbiAgICAgKiBhcyBudW1iZXJzLCB1c2UgdGhlIGBfLmlzRmluaXRlYCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoOC40KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKE5hTik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcignOC40Jyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc051bWJlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBudW1iZXJUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGF0IGlzLCBhbiBvYmplY3QgY3JlYXRlZCBieSB0aGVcbiAgICAgKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgYXNzdW1lcyBvYmplY3RzIGNyZWF0ZWQgYnkgdGhlIGBPYmplY3RgIGNvbnN0cnVjdG9yXG4gICAgICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgdmFyIEN0b3I7XG5cbiAgICAgIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICAgICAgaWYgKCEoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBvYmplY3RUYWcgJiYgIWlzQXJndW1lbnRzKHZhbHVlKSkgfHxcbiAgICAgICAgICAoIWhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjb25zdHJ1Y3RvcicpICYmIChDdG9yID0gdmFsdWUuY29uc3RydWN0b3IsIHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgIShDdG9yIGluc3RhbmNlb2YgQ3RvcikpKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBJRSA8IDkgaXRlcmF0ZXMgaW5oZXJpdGVkIHByb3BlcnRpZXMgYmVmb3JlIG93biBwcm9wZXJ0aWVzLiBJZiB0aGUgZmlyc3RcbiAgICAgIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgICAgIC8vIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICAvLyBJbiBtb3N0IGVudmlyb25tZW50cyBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYmVmb3JlXG4gICAgICAvLyBpdHMgaW5oZXJpdGVkIHByb3BlcnRpZXMuIElmIHRoZSBsYXN0IGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzXG4gICAgICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgICAgIGJhc2VGb3JJbih2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICByZXN1bHQgPSBrZXk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCByZXN1bHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgUmVnRXhwYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNSZWdFeHAoL2FiYy8pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNSZWdFeHAoJy9hYmMvJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1JlZ0V4cCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSByZWdleHBUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzdHJpbmdUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSB0eXBlZCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNUeXBlZEFycmF5KFtdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29ialRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0KDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsdCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA8IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sdGUoMSwgMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5sdGUoMywgMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5sdGUoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsdGUodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPD0gb3RoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogKGZ1bmN0aW9uKCkge1xuICAgICAqICAgcmV0dXJuIF8udG9BcnJheShhcmd1bWVudHMpLnNsaWNlKDEpO1xuICAgICAqIH0oMSwgMiwgMykpO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvQXJyYXkodmFsdWUpIHtcbiAgICAgIHZhciBsZW5ndGggPSB2YWx1ZSA/IGdldExlbmd0aCh2YWx1ZSkgOiAwO1xuICAgICAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXModmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5Q29weSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHBsYWluIG9iamVjdCBmbGF0dGVuaW5nIGluaGVyaXRlZCBlbnVtZXJhYmxlXG4gICAgICogcHJvcGVydGllcyBvZiBgdmFsdWVgIHRvIG93biBwcm9wZXJ0aWVzIG9mIHRoZSBwbGFpbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29udmVydGVkIHBsYWluIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgbmV3IEZvbyk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMSB9LCBfLnRvUGxhaW5PYmplY3QobmV3IEZvbykpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9QbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDb3B5KHZhbHVlLCBrZXlzSW4odmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBtZXJnZXMgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiB0aGUgc291cmNlIG9iamVjdChzKSwgdGhhdFxuICAgICAqIGRvbid0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAgaW50byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LiBTdWJzZXF1ZW50IHNvdXJjZXNcbiAgICAgKiBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy4gSWYgYGN1c3RvbWl6ZXJgIGlzXG4gICAgICogcHJvdmlkZWQgaXQgaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBtZXJnZWQgdmFsdWVzIG9mIHRoZSBkZXN0aW5hdGlvbiBhbmRcbiAgICAgKiBzb3VyY2UgcHJvcGVydGllcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAgbWVyZ2luZyBpcyBoYW5kbGVkXG4gICAgICogYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZFxuICAgICAqIHdpdGggZml2ZSBhcmd1bWVudHM6IChvYmplY3RWYWx1ZSwgc291cmNlVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBjdXN0b21pemVyYC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnZGF0YSc6IFt7ICd1c2VyJzogJ2Jhcm5leScgfSwgeyAndXNlcic6ICdmcmVkJyB9XVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgYWdlcyA9IHtcbiAgICAgKiAgICdkYXRhJzogW3sgJ2FnZSc6IDM2IH0sIHsgJ2FnZSc6IDQwIH1dXG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8ubWVyZ2UodXNlcnMsIGFnZXMpO1xuICAgICAqIC8vID0+IHsgJ2RhdGEnOiBbeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSwgeyAndXNlcic6ICdmcmVkJywgJ2FnZSc6IDQwIH1dIH1cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIGEgY3VzdG9taXplciBjYWxsYmFja1xuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAnZnJ1aXRzJzogWydhcHBsZSddLFxuICAgICAqICAgJ3ZlZ2V0YWJsZXMnOiBbJ2JlZXQnXVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgb3RoZXIgPSB7XG4gICAgICogICAnZnJ1aXRzJzogWydiYW5hbmEnXSxcbiAgICAgKiAgICd2ZWdldGFibGVzJzogWydjYXJyb3QnXVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLm1lcmdlKG9iamVjdCwgb3RoZXIsIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgKiAgIGlmIChfLmlzQXJyYXkoYSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIGEuY29uY2F0KGIpO1xuICAgICAqICAgfVxuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2ZydWl0cyc6IFsnYXBwbGUnLCAnYmFuYW5hJ10sICd2ZWdldGFibGVzJzogWydiZWV0JywgJ2NhcnJvdCddIH1cbiAgICAgKi9cbiAgICB2YXIgbWVyZ2UgPSBjcmVhdGVBc3NpZ25lcihiYXNlTWVyZ2UpO1xuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIHNvdXJjZSBvYmplY3QocykgdG8gdGhlIGRlc3RpbmF0aW9uXG4gICAgICogb2JqZWN0LiBTdWJzZXF1ZW50IHNvdXJjZXMgb3ZlcndyaXRlIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHNvdXJjZXMuXG4gICAgICogSWYgYGN1c3RvbWl6ZXJgIGlzIHByb3ZpZGVkIGl0IGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIFRoZSBgY3VzdG9taXplcmAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggZml2ZSBhcmd1bWVudHM6XG4gICAgICogKG9iamVjdFZhbHVlLCBzb3VyY2VWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YCBhbmQgaXMgYmFzZWQgb25cbiAgICAgKiBbYE9iamVjdC5hc3NpZ25gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QuYXNzaWduKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBhbGlhcyBleHRlbmRcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ3VzZXInOiAnYmFybmV5JyB9LCB7ICdhZ2UnOiA0MCB9LCB7ICd1c2VyJzogJ2ZyZWQnIH0pO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XG4gICAgICpcbiAgICAgKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAgICAgKiB2YXIgZGVmYXVsdHMgPSBfLnBhcnRpYWxSaWdodChfLmFzc2lnbiwgZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICogICByZXR1cm4gXy5pc1VuZGVmaW5lZCh2YWx1ZSkgPyBvdGhlciA6IHZhbHVlO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogZGVmYXVsdHMoeyAndXNlcic6ICdiYXJuZXknIH0sIHsgJ2FnZSc6IDM2IH0sIHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gICAgICogLy8gPT4geyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ24gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcikge1xuICAgICAgcmV0dXJuIGN1c3RvbWl6ZXJcbiAgICAgICAgPyBhc3NpZ25XaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKVxuICAgICAgICA6IGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgdGhhdCBpbmhlcml0cyBmcm9tIHRoZSBnaXZlbiBgcHJvdG90eXBlYCBvYmplY3QuIElmIGFcbiAgICAgKiBgcHJvcGVydGllc2Agb2JqZWN0IGlzIHByb3ZpZGVkIGl0cyBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGFyZSBhc3NpZ25lZFxuICAgICAqIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvdG90eXBlIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbcHJvcGVydGllc10gVGhlIHByb3BlcnRpZXMgdG8gYXNzaWduIHRvIHRoZSBvYmplY3QuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gU2hhcGUoKSB7XG4gICAgICogICB0aGlzLnggPSAwO1xuICAgICAqICAgdGhpcy55ID0gMDtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBDaXJjbGUoKSB7XG4gICAgICogICBTaGFwZS5jYWxsKHRoaXMpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIENpcmNsZS5wcm90b3R5cGUgPSBfLmNyZWF0ZShTaGFwZS5wcm90b3R5cGUsIHtcbiAgICAgKiAgICdjb25zdHJ1Y3Rvcic6IENpcmNsZVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogdmFyIGNpcmNsZSA9IG5ldyBDaXJjbGU7XG4gICAgICogY2lyY2xlIGluc3RhbmNlb2YgQ2lyY2xlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNpcmNsZSBpbnN0YW5jZW9mIFNoYXBlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGUocHJvdG90eXBlLCBwcm9wZXJ0aWVzLCBndWFyZCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VDcmVhdGUocHJvdG90eXBlKTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChwcm90b3R5cGUsIHByb3BlcnRpZXMsIGd1YXJkKSkge1xuICAgICAgICBwcm9wZXJ0aWVzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BlcnRpZXMgPyBiYXNlQXNzaWduKHJlc3VsdCwgcHJvcGVydGllcykgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIHNvdXJjZSBvYmplY3QocykgdG8gdGhlIGRlc3RpbmF0aW9uXG4gICAgICogb2JqZWN0IGZvciBhbGwgZGVzdGluYXRpb24gcHJvcGVydGllcyB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuIE9uY2UgYVxuICAgICAqIHByb3BlcnR5IGlzIHNldCwgYWRkaXRpb25hbCB2YWx1ZXMgb2YgdGhlIHNhbWUgcHJvcGVydHkgYXJlIGlnbm9yZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0cyh7ICd1c2VyJzogJ2Jhcm5leScgfSwgeyAnYWdlJzogMzYgfSwgeyAndXNlcic6ICdmcmVkJyB9KTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzID0gY3JlYXRlRGVmYXVsdHMoYXNzaWduLCBhc3NpZ25EZWZhdWx0cyk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmRlZmF1bHRzYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBhc3NpZ25zXG4gICAgICogZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdHNEZWVwKHsgJ3VzZXInOiB7ICduYW1lJzogJ2Jhcm5leScgfSB9LCB7ICd1c2VyJzogeyAnbmFtZSc6ICdmcmVkJywgJ2FnZSc6IDM2IH0gfSk7XG4gICAgICogLy8gPT4geyAndXNlcic6IHsgJ25hbWUnOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0gfVxuICAgICAqXG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzRGVlcCA9IGNyZWF0ZURlZmF1bHRzKG1lcmdlLCBtZXJnZURlZmF1bHRzKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUga2V5IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFJldHVybnMgdGhlIGtleSBvZiB0aGUgbWF0Y2hlZCBlbGVtZW50LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnYmFybmV5JzogIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgJ2ZyZWQnOiAgICB7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8uZmluZEtleSh1c2VycywgZnVuY3Rpb24oY2hyKSB7XG4gICAgICogICByZXR1cm4gY2hyLmFnZSA8IDQwO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdiYXJuZXknIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICAgICAqIF8uZmluZEtleSh1c2VycywgJ2FjdGl2ZScsIGZhbHNlKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKi9cbiAgICB2YXIgZmluZEtleSA9IGNyZWF0ZUZpbmRLZXkoYmFzZUZvck93bik7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRLZXlgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBhIGNvbGxlY3Rpb24gaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICAgICAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gICAgICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFJldHVybnMgdGhlIGtleSBvZiB0aGUgbWF0Y2hlZCBlbGVtZW50LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnYmFybmV5JzogIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgJ2ZyZWQnOiAgICB7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIGZ1bmN0aW9uKGNocikge1xuICAgICAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiByZXR1cm5zIGBwZWJibGVzYCBhc3N1bWluZyBgXy5maW5kS2V5YCByZXR1cm5zIGBiYXJuZXlgXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+ICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCAnYWN0aXZlJywgZmFsc2UpO1xuICAgICAqIC8vID0+ICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMnXG4gICAgICovXG4gICAgdmFyIGZpbmRMYXN0S2V5ID0gY3JlYXRlRmluZEtleShiYXNlRm9yT3duUmlnaHQpO1xuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IGludm9raW5nXG4gICAgICogYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXRcbiAgICAgKiBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvckluKG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gbG9ncyAnYScsICdiJywgYW5kICdjJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciBmb3JJbiA9IGNyZWF0ZUZvckluKGJhc2VGb3IpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JJbmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzIG9mXG4gICAgICogYG9iamVjdGAgaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9ySW5SaWdodChuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IGxvZ3MgJ2MnLCAnYicsIGFuZCAnYScgYXNzdW1pbmcgYF8uZm9ySW4gYCBsb2dzICdhJywgJ2InLCBhbmQgJ2MnXG4gICAgICovXG4gICAgdmFyIGZvckluUmlnaHQgPSBjcmVhdGVGb3JJbihiYXNlRm9yUmlnaHQpO1xuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBpbnZva2luZyBgaXRlcmF0ZWVgXG4gICAgICogZm9yIGVhY2ggcHJvcGVydHkuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvblxuICAgICAqIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JPd24obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBsb2dzICdhJyBhbmQgJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgdmFyIGZvck93biA9IGNyZWF0ZUZvck93bihiYXNlRm9yT3duKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9yT3duYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIHByb3BlcnRpZXMgb2ZcbiAgICAgKiBgb2JqZWN0YCBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JPd25SaWdodChuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IGxvZ3MgJ2InIGFuZCAnYScgYXNzdW1pbmcgYF8uZm9yT3duYCBsb2dzICdhJyBhbmQgJ2InXG4gICAgICovXG4gICAgdmFyIGZvck93blJpZ2h0ID0gY3JlYXRlRm9yT3duKGJhc2VGb3JPd25SaWdodCk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZyb20gYWxsIGVudW1lcmFibGUgcHJvcGVydGllcyxcbiAgICAgKiBvd24gYW5kIGluaGVyaXRlZCwgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgbWV0aG9kc1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mdW5jdGlvbnMoXyk7XG4gICAgICogLy8gPT4gWydhZnRlcicsICdhcnknLCAnYXNzaWduJywgLi4uXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZ1bmN0aW9ucyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBiYXNlRnVuY3Rpb25zKG9iamVjdCwga2V5c0luKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzXG4gICAgICogYHVuZGVmaW5lZGAgdGhlIGBkZWZhdWx0VmFsdWVgIGlzIHVzZWQgaW4gaXRzIHBsYWNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGlmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcyBgdW5kZWZpbmVkYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgJ2EuYi5jJywgJ2RlZmF1bHQnKTtcbiAgICAgKiAvLyA9PiAnZGVmYXVsdCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCB0b1BhdGgocGF0aCksIHBhdGggKyAnJyk7XG4gICAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0VmFsdWUgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBwcm9wZXJ0eSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IHsgJ2InOiB7ICdjJzogMyB9IH0gfTtcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhcyhvYmplY3QsICdhLmIuYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgWydhJywgJ2InLCAnYyddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzKG9iamVjdCwgcGF0aCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcGF0aCk7XG4gICAgICBpZiAoIXJlc3VsdCAmJiAhaXNLZXkocGF0aCkpIHtcbiAgICAgICAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHBhdGggPSBsYXN0KHBhdGgpO1xuICAgICAgICByZXN1bHQgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcGF0aCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0IHx8IChpc0xlbmd0aChvYmplY3QubGVuZ3RoKSAmJiBpc0luZGV4KHBhdGgsIG9iamVjdC5sZW5ndGgpICYmXG4gICAgICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBpbnZlcnRlZCBrZXlzIGFuZCB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICogSWYgYG9iamVjdGAgY29udGFpbnMgZHVwbGljYXRlIHZhbHVlcywgc3Vic2VxdWVudCB2YWx1ZXMgb3ZlcndyaXRlIHByb3BlcnR5XG4gICAgICogYXNzaWdubWVudHMgb2YgcHJldmlvdXMgdmFsdWVzIHVubGVzcyBgbXVsdGlWYWx1ZWAgaXMgYHRydWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZlcnQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbbXVsdGlWYWx1ZV0gQWxsb3cgbXVsdGlwbGUgdmFsdWVzIHBlciBrZXkuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9O1xuICAgICAqXG4gICAgICogXy5pbnZlcnQob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogJ2MnLCAnMic6ICdiJyB9XG4gICAgICpcbiAgICAgKiAvLyB3aXRoIGBtdWx0aVZhbHVlYFxuICAgICAqIF8uaW52ZXJ0KG9iamVjdCwgdHJ1ZSk7XG4gICAgICogLy8gPT4geyAnMSc6IFsnYScsICdjJ10sICcyJzogWydiJ10gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGludmVydChvYmplY3QsIG11bHRpVmFsdWUsIGd1YXJkKSB7XG4gICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwob2JqZWN0LCBtdWx0aVZhbHVlLCBndWFyZCkpIHtcbiAgICAgICAgbXVsdGlWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XSxcbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgaWYgKG11bHRpVmFsdWUpIHtcbiAgICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIHZhbHVlKSkge1xuICAgICAgICAgICAgcmVzdWx0W3ZhbHVlXS5wdXNoKGtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdFt2YWx1ZV0gPSBba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W3ZhbHVlXSA9IGtleTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLiBTZWUgdGhlXG4gICAgICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5rZXlzKVxuICAgICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmtleXMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogXy5rZXlzKCdoaScpO1xuICAgICAqIC8vID0+IFsnMCcsICcxJ11cbiAgICAgKi9cbiAgICB2YXIga2V5cyA9ICFuYXRpdmVLZXlzID8gc2hpbUtleXMgOiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHZhciBDdG9yID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICAgICAodHlwZW9mIG9iamVjdCAhPSAnZnVuY3Rpb24nICYmIGlzQXJyYXlMaWtlKG9iamVjdCkpKSB7XG4gICAgICAgIHJldHVybiBzaGltS2V5cyhvYmplY3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzT2JqZWN0KG9iamVjdCkgPyBuYXRpdmVLZXlzKG9iamVjdCkgOiBbXTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5rZXlzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuICAgICAgbGVuZ3RoID0gKGxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSkgJiYgbGVuZ3RoKSB8fCAwO1xuXG4gICAgICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzUHJvdG8gPSB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlID09PSBvYmplY3QsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDA7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmICghKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAgICAgIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1hcFZhbHVlc2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlXG4gICAgICogc2FtZSB2YWx1ZXMgYXMgYG9iamVjdGAgYW5kIGtleXMgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgZWFjaCBvd24gZW51bWVyYWJsZVxuICAgICAqIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocm91Z2ggYGl0ZXJhdGVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gICAgICogIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwS2V5cyh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIHJldHVybiBrZXkgKyB2YWx1ZTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdhMSc6IDEsICdiMic6IDIgfVxuICAgICAqL1xuICAgIHZhciBtYXBLZXlzID0gY3JlYXRlT2JqZWN0TWFwcGVyKHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBrZXlzIGFzIGBvYmplY3RgIGFuZCB2YWx1ZXMgZ2VuZXJhdGVkIGJ5XG4gICAgICogcnVubmluZyBlYWNoIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocm91Z2ggYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogaXRlcmF0ZWUgZnVuY3Rpb24gaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqXG4gICAgICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICAgICAqXG4gICAgICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICAgICAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICAgICAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAgICAgKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICAgICAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAgICAgKiAgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tYXBWYWx1ZXMoeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAqIDM7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDMsICdiJzogNiB9XG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnZnJlZCc6ICAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5tYXBWYWx1ZXModXNlcnMsICdhZ2UnKTtcbiAgICAgKiAvLyA9PiB7ICdmcmVkJzogNDAsICdwZWJibGVzJzogMSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgdmFyIG1hcFZhbHVlcyA9IGNyZWF0ZU9iamVjdE1hcHBlcigpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnBpY2tgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGVcbiAgICAgKiBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYG9iamVjdGAgdGhhdCBhcmUgbm90IG9taXR0ZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufC4uLihzdHJpbmd8c3RyaW5nW10pfSBbcHJlZGljYXRlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXJcbiAgICAgKiAgaXRlcmF0aW9uIG9yIHByb3BlcnR5IG5hbWVzIHRvIG9taXQsIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIHByb3BlcnR5XG4gICAgICogIG5hbWVzIG9yIGFycmF5cyBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9O1xuICAgICAqXG4gICAgICogXy5vbWl0KG9iamVjdCwgJ2FnZScpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnZnJlZCcgfVxuICAgICAqXG4gICAgICogXy5vbWl0KG9iamVjdCwgXy5pc051bWJlcik7XG4gICAgICogLy8gPT4geyAndXNlcic6ICdmcmVkJyB9XG4gICAgICovXG4gICAgdmFyIG9taXQgPSByZXN0UGFyYW0oZnVuY3Rpb24ob2JqZWN0LCBwcm9wcykge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcHJvcHNbMF0gIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgcHJvcHMgPSBhcnJheU1hcChiYXNlRmxhdHRlbihwcm9wcyksIFN0cmluZyk7XG4gICAgICAgIHJldHVybiBwaWNrQnlBcnJheShvYmplY3QsIGJhc2VEaWZmZXJlbmNlKGtleXNJbihvYmplY3QpLCBwcm9wcykpO1xuICAgICAgfVxuICAgICAgdmFyIHByZWRpY2F0ZSA9IGJpbmRDYWxsYmFjayhwcm9wc1swXSwgcHJvcHNbMV0sIDMpO1xuICAgICAgcmV0dXJuIHBpY2tCeUNhbGxiYWNrKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiAhcHJlZGljYXRlKHZhbHVlLCBrZXksIG9iamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gICAgICogZS5nLiBgW1trZXkxLCB2YWx1ZTFdLCBba2V5MiwgdmFsdWUyXV1gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFpcnMoeyAnYmFybmV5JzogMzYsICdmcmVkJzogNDAgfSk7XG4gICAgICogLy8gPT4gW1snYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCA0MF1dIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFpcnMob2JqZWN0KSB7XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBwcm9wcyA9IGtleXMob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIHBpY2tlZCBgb2JqZWN0YCBwcm9wZXJ0aWVzLiBQcm9wZXJ0eVxuICAgICAqIG5hbWVzIG1heSBiZSBzcGVjaWZpZWQgYXMgaW5kaXZpZHVhbCBhcmd1bWVudHMgb3IgYXMgYXJyYXlzIG9mIHByb3BlcnR5XG4gICAgICogbmFtZXMuIElmIGBwcmVkaWNhdGVgIGlzIHByb3ZpZGVkIGl0IGlzIGludm9rZWQgZm9yIGVhY2ggcHJvcGVydHkgb2YgYG9iamVjdGBcbiAgICAgKiBwaWNraW5nIHRoZSBwcm9wZXJ0aWVzIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufC4uLihzdHJpbmd8c3RyaW5nW10pfSBbcHJlZGljYXRlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXJcbiAgICAgKiAgaXRlcmF0aW9uIG9yIHByb3BlcnR5IG5hbWVzIHRvIHBpY2ssIHNwZWNpZmllZCBhcyBpbmRpdmlkdWFsIHByb3BlcnR5XG4gICAgICogIG5hbWVzIG9yIGFycmF5cyBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYHByZWRpY2F0ZWAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9O1xuICAgICAqXG4gICAgICogXy5waWNrKG9iamVjdCwgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAgICAgKlxuICAgICAqIF8ucGljayhvYmplY3QsIF8uaXNTdHJpbmcpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnZnJlZCcgfVxuICAgICAqL1xuICAgIHZhciBwaWNrID0gcmVzdFBhcmFtKGZ1bmN0aW9uKG9iamVjdCwgcHJvcHMpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZW9mIHByb3BzWzBdID09ICdmdW5jdGlvbidcbiAgICAgICAgPyBwaWNrQnlDYWxsYmFjayhvYmplY3QsIGJpbmRDYWxsYmFjayhwcm9wc1swXSwgcHJvcHNbMV0sIDMpKVxuICAgICAgICA6IHBpY2tCeUFycmF5KG9iamVjdCwgYmFzZUZsYXR0ZW4ocHJvcHMpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZ2V0YCBleGNlcHQgdGhhdCBpZiB0aGUgcmVzb2x2ZWQgdmFsdWUgaXMgYSBmdW5jdGlvblxuICAgICAqIGl0IGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgaXRzIHBhcmVudCBvYmplY3QgYW5kIGl0cyByZXN1bHRcbiAgICAgKiBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHJlc29sdmUuXG4gICAgICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgaWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzIGB1bmRlZmluZWRgLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MxJzogMywgJ2MyJzogXy5jb25zdGFudCg0KSB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzEnKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzInKTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhLmIuYycsIF8uY29uc3RhbnQoJ2RlZmF1bHQnKSk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzdWx0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3RbcGF0aF07XG4gICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG9iamVjdCAhPSBudWxsICYmICFpc0tleShwYXRoLCBvYmplY3QpKSB7XG4gICAgICAgICAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgICAgICAgICBvYmplY3QgPSBwYXRoLmxlbmd0aCA9PSAxID8gb2JqZWN0IDogYmFzZUdldChvYmplY3QsIGJhc2VTbGljZShwYXRoLCAwLCAtMSkpO1xuICAgICAgICAgIHJlc3VsdCA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2xhc3QocGF0aCldO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzRnVuY3Rpb24ocmVzdWx0KSA/IHJlc3VsdC5jYWxsKG9iamVjdCkgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgYHBhdGhgIG9uIGBvYmplY3RgLiBJZiBhIHBvcnRpb24gb2YgYHBhdGhgXG4gICAgICogZG9lcyBub3QgZXhpc3QgaXQgaXMgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gYXVnbWVudC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5zZXQob2JqZWN0LCAnYVswXS5iLmMnLCA0KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QuYVswXS5iLmMpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uc2V0KG9iamVjdCwgJ3hbMF0ueS56JywgNSk7XG4gICAgICogY29uc29sZS5sb2cob2JqZWN0LnhbMF0ueS56KTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0KG9iamVjdCwgcGF0aCwgdmFsdWUpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfVxuICAgICAgdmFyIHBhdGhLZXkgPSAocGF0aCArICcnKTtcbiAgICAgIHBhdGggPSAob2JqZWN0W3BhdGhLZXldICE9IG51bGwgfHwgaXNLZXkocGF0aCwgb2JqZWN0KSkgPyBbcGF0aEtleV0gOiB0b1BhdGgocGF0aCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLFxuICAgICAgICAgIGxhc3RJbmRleCA9IGxlbmd0aCAtIDEsXG4gICAgICAgICAgbmVzdGVkID0gb2JqZWN0O1xuXG4gICAgICB3aGlsZSAobmVzdGVkICE9IG51bGwgJiYgKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gcGF0aFtpbmRleF07XG4gICAgICAgIGlmIChpc09iamVjdChuZXN0ZWQpKSB7XG4gICAgICAgICAgaWYgKGluZGV4ID09IGxhc3RJbmRleCkge1xuICAgICAgICAgICAgbmVzdGVkW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5lc3RlZFtrZXldID09IG51bGwpIHtcbiAgICAgICAgICAgIG5lc3RlZFtrZXldID0gaXNJbmRleChwYXRoW2luZGV4ICsgMV0pID8gW10gOiB7fTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbmVzdGVkID0gbmVzdGVkW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIGFsdGVybmF0aXZlIHRvIGBfLnJlZHVjZWA7IHRoaXMgbWV0aG9kIHRyYW5zZm9ybXMgYG9iamVjdGAgdG8gYSBuZXdcbiAgICAgKiBgYWNjdW11bGF0b3JgIG9iamVjdCB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIHJ1bm5pbmcgZWFjaCBvZiBpdHMgb3duIGVudW1lcmFibGVcbiAgICAgKiBwcm9wZXJ0aWVzIHRocm91Z2ggYGl0ZXJhdGVlYCwgd2l0aCBlYWNoIGludm9jYXRpb24gcG90ZW50aWFsbHkgbXV0YXRpbmdcbiAgICAgKiB0aGUgYGFjY3VtdWxhdG9yYCBvYmplY3QuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZFxuICAgICAqIHdpdGggZm91ciBhcmd1bWVudHM6IChhY2N1bXVsYXRvciwgdmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zXG4gICAgICogbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGN1c3RvbSBhY2N1bXVsYXRvciB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJhbnNmb3JtKFsyLCAzLCA0XSwgZnVuY3Rpb24ocmVzdWx0LCBuKSB7XG4gICAgICogICByZXN1bHQucHVzaChuICo9IG4pO1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gWzQsIDldXG4gICAgICpcbiAgICAgKiBfLnRyYW5zZm9ybSh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHJlc3VsdCwgbiwga2V5KSB7XG4gICAgICogICByZXN1bHRba2V5XSA9IG4gKiAzO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAzLCAnYic6IDYgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyYW5zZm9ybShvYmplY3QsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgdGhpc0FyZykge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheShvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuICAgICAgaXRlcmF0ZWUgPSBnZXRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgNCk7XG5cbiAgICAgIGlmIChhY2N1bXVsYXRvciA9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc0FyciB8fCBpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgICAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICAgICAgaWYgKGlzQXJyKSB7XG4gICAgICAgICAgICBhY2N1bXVsYXRvciA9IGlzQXJyYXkob2JqZWN0KSA/IG5ldyBDdG9yIDogW107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFjY3VtdWxhdG9yID0gYmFzZUNyZWF0ZShpc0Z1bmN0aW9uKEN0b3IpID8gQ3Rvci5wcm90b3R5cGUgOiB1bmRlZmluZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IHt9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAoaXNBcnIgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKShvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBvYmplY3QpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy52YWx1ZXMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiBfLnZhbHVlcygnaGknKTtcbiAgICAgKiAvLyA9PiBbJ2gnLCAnaSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgdmFsdWVzXG4gICAgICogb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnZhbHVlc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHZhbHVlc0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzSW4ob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBuYCBpcyBiZXR3ZWVuIGBzdGFydGAgYW5kIHVwIHRvIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gSWZcbiAgICAgKiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkIGl0IGlzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG5gIGlzIGluIHRoZSByYW5nZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoMywgMiwgNCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDQsIDgpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg0LCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDIsIDIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoMS4yLCAyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNS4yLCA0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluUmFuZ2UodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gK3N0YXJ0IHx8IDA7XG4gICAgICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZCA9ICtlbmQgfHwgMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSA+PSBuYXRpdmVNaW4oc3RhcnQsIGVuZCkgJiYgdmFsdWUgPCBuYXRpdmVNYXgoc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvZHVjZXMgYSByYW5kb20gbnVtYmVyIGJldHdlZW4gYG1pbmAgYW5kIGBtYXhgIChpbmNsdXNpdmUpLiBJZiBvbmx5IG9uZVxuICAgICAqIGFyZ3VtZW50IGlzIHByb3ZpZGVkIGEgbnVtYmVyIGJldHdlZW4gYDBgIGFuZCB0aGUgZ2l2ZW4gbnVtYmVyIGlzIHJldHVybmVkLlxuICAgICAqIElmIGBmbG9hdGluZ2AgaXMgYHRydWVgLCBvciBlaXRoZXIgYG1pbmAgb3IgYG1heGAgYXJlIGZsb2F0cywgYSBmbG9hdGluZy1wb2ludFxuICAgICAqIG51bWJlciBpcyByZXR1cm5lZCBpbnN0ZWFkIG9mIGFuIGludGVnZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFttaW49MF0gVGhlIG1pbmltdW0gcG9zc2libGUgdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFttYXg9MV0gVGhlIG1heGltdW0gcG9zc2libGUgdmFsdWUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZmxvYXRpbmddIFNwZWNpZnkgcmV0dXJuaW5nIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJhbmRvbSBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDAsIDUpO1xuICAgICAqIC8vID0+IGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA1XG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSg1KTtcbiAgICAgKiAvLyA9PiBhbHNvIGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA1XG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSg1LCB0cnVlKTtcbiAgICAgKiAvLyA9PiBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDEuMiwgNS4yKTtcbiAgICAgKiAvLyA9PiBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBiZXR3ZWVuIDEuMiBhbmQgNS4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmFuZG9tKG1pbiwgbWF4LCBmbG9hdGluZykge1xuICAgICAgaWYgKGZsb2F0aW5nICYmIGlzSXRlcmF0ZWVDYWxsKG1pbiwgbWF4LCBmbG9hdGluZykpIHtcbiAgICAgICAgbWF4ID0gZmxvYXRpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB2YXIgbm9NaW4gPSBtaW4gPT0gbnVsbCxcbiAgICAgICAgICBub01heCA9IG1heCA9PSBudWxsO1xuXG4gICAgICBpZiAoZmxvYXRpbmcgPT0gbnVsbCkge1xuICAgICAgICBpZiAobm9NYXggJiYgdHlwZW9mIG1pbiA9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICBmbG9hdGluZyA9IG1pbjtcbiAgICAgICAgICBtaW4gPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBtYXggPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSBtYXg7XG4gICAgICAgICAgbm9NYXggPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobm9NaW4gJiYgbm9NYXgpIHtcbiAgICAgICAgbWF4ID0gMTtcbiAgICAgICAgbm9NYXggPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG1pbiA9ICttaW4gfHwgMDtcbiAgICAgIGlmIChub01heCkge1xuICAgICAgICBtYXggPSBtaW47XG4gICAgICAgIG1pbiA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXggPSArbWF4IHx8IDA7XG4gICAgICB9XG4gICAgICBpZiAoZmxvYXRpbmcgfHwgbWluICUgMSB8fCBtYXggJSAxKSB7XG4gICAgICAgIHZhciByYW5kID0gbmF0aXZlUmFuZG9tKCk7XG4gICAgICAgIHJldHVybiBuYXRpdmVNaW4obWluICsgKHJhbmQgKiAobWF4IC0gbWluICsgcGFyc2VGbG9hdCgnMWUtJyArICgocmFuZCArICcnKS5sZW5ndGggLSAxKSkpKSwgbWF4KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlUmFuZG9tKG1pbiwgbWF4KTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBbY2FtZWwgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2FtZWxDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhbWVsIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJy0tZm9vLWJhcicpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICpcbiAgICAgKiBfLmNhbWVsQ2FzZSgnX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqL1xuICAgIHZhciBjYW1lbENhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHdvcmQgPSB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gKHdvcmQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB3b3JkLnNsaWNlKDEpKSA6IHdvcmQpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ2FwaXRhbGl6ZXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjYXBpdGFsaXplLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhcGl0YWxpemVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXBpdGFsaXplKCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0ZyZWQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FwaXRhbGl6ZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IGJhc2VUb1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIHN0cmluZyAmJiAoc3RyaW5nLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyaW5nLnNsaWNlKDEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWJ1cnJzIGBzdHJpbmdgIGJ5IGNvbnZlcnRpbmcgW2xhdGluLTEgc3VwcGxlbWVudGFyeSBsZXR0ZXJzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbi0xX1N1cHBsZW1lbnRfKFVuaWNvZGVfYmxvY2spI0NoYXJhY3Rlcl90YWJsZSlcbiAgICAgKiB0byBiYXNpYyBsYXRpbiBsZXR0ZXJzIGFuZCByZW1vdmluZyBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGRlYnVyci5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBkZWJ1cnJlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVidXJyKCdkw6lqw6AgdnUnKTtcbiAgICAgKiAvLyA9PiAnZGVqYSB2dSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWJ1cnIoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiBzdHJpbmcgJiYgc3RyaW5nLnJlcGxhY2UocmVMYXRpbjEsIGRlYnVyckxldHRlcikucmVwbGFjZShyZUNvbWJvTWFyaywgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBlbmRzIHdpdGggdGhlIGdpdmVuIHRhcmdldCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gc2VhcmNoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFyZ2V0XSBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3NpdGlvbj1zdHJpbmcubGVuZ3RoXSBUaGUgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBzdHJpbmdgIGVuZHMgd2l0aCBgdGFyZ2V0YCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmVuZHNXaXRoKCdhYmMnLCAnYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdiJywgMik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVuZHNXaXRoKHN0cmluZywgdGFyZ2V0LCBwb3NpdGlvbikge1xuICAgICAgc3RyaW5nID0gYmFzZVRvU3RyaW5nKHN0cmluZyk7XG4gICAgICB0YXJnZXQgPSAodGFyZ2V0ICsgJycpO1xuXG4gICAgICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIHBvc2l0aW9uID0gcG9zaXRpb24gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IGxlbmd0aFxuICAgICAgICA6IG5hdGl2ZU1pbihwb3NpdGlvbiA8IDAgPyAwIDogKCtwb3NpdGlvbiB8fCAwKSwgbGVuZ3RoKTtcblxuICAgICAgcG9zaXRpb24gLT0gdGFyZ2V0Lmxlbmd0aDtcbiAgICAgIHJldHVybiBwb3NpdGlvbiA+PSAwICYmIHN0cmluZy5pbmRleE9mKHRhcmdldCwgcG9zaXRpb24pID09IHBvc2l0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBjaGFyYWN0ZXJzIFwiJlwiLCBcIjxcIiwgXCI+XCIsICdcIicsIFwiJ1wiLCBhbmQgXCJcXGBcIiwgaW4gYHN0cmluZ2AgdG9cbiAgICAgKiB0aGVpciBjb3JyZXNwb25kaW5nIEhUTUwgZW50aXRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm8gb3RoZXIgY2hhcmFjdGVycyBhcmUgZXNjYXBlZC4gVG8gZXNjYXBlIGFkZGl0aW9uYWwgY2hhcmFjdGVyc1xuICAgICAqIHVzZSBhIHRoaXJkLXBhcnR5IGxpYnJhcnkgbGlrZSBbX2hlX10oaHR0cHM6Ly9tdGhzLmJlL2hlKS5cbiAgICAgKlxuICAgICAqIFRob3VnaCB0aGUgXCI+XCIgY2hhcmFjdGVyIGlzIGVzY2FwZWQgZm9yIHN5bW1ldHJ5LCBjaGFyYWN0ZXJzIGxpa2VcbiAgICAgKiBcIj5cIiBhbmQgXCIvXCIgZG9uJ3QgbmVlZCBlc2NhcGluZyBpbiBIVE1MIGFuZCBoYXZlIG5vIHNwZWNpYWwgbWVhbmluZ1xuICAgICAqIHVubGVzcyB0aGV5J3JlIHBhcnQgb2YgYSB0YWcgb3IgdW5xdW90ZWQgYXR0cmlidXRlIHZhbHVlLlxuICAgICAqIFNlZSBbTWF0aGlhcyBCeW5lbnMncyBhcnRpY2xlXShodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvYW1iaWd1b3VzLWFtcGVyc2FuZHMpXG4gICAgICogKHVuZGVyIFwic2VtaS1yZWxhdGVkIGZ1biBmYWN0XCIpIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBCYWNrdGlja3MgYXJlIGVzY2FwZWQgYmVjYXVzZSBpbiBJbnRlcm5ldCBFeHBsb3JlciA8IDksIHRoZXkgY2FuIGJyZWFrIG91dFxuICAgICAqIG9mIGF0dHJpYnV0ZSB2YWx1ZXMgb3IgSFRNTCBjb21tZW50cy4gU2VlIFsjNTldKGh0dHBzOi8vaHRtbDVzZWMub3JnLyM1OSksXG4gICAgICogWyMxMDJdKGh0dHBzOi8vaHRtbDVzZWMub3JnLyMxMDIpLCBbIzEwOF0oaHR0cHM6Ly9odG1sNXNlYy5vcmcvIzEwOCksIGFuZFxuICAgICAqIFsjMTMzXShodHRwczovL2h0bWw1c2VjLm9yZy8jMTMzKSBvZiB0aGUgW0hUTUw1IFNlY3VyaXR5IENoZWF0c2hlZXRdKGh0dHBzOi8vaHRtbDVzZWMub3JnLylcbiAgICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogV2hlbiB3b3JraW5nIHdpdGggSFRNTCB5b3Ugc2hvdWxkIGFsd2F5cyBbcXVvdGUgYXR0cmlidXRlIHZhbHVlc10oaHR0cDovL3dvbmtvLmNvbS9wb3N0L2h0bWwtZXNjYXBpbmcpXG4gICAgICogdG8gcmVkdWNlIFhTUyB2ZWN0b3JzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGUoc3RyaW5nKSB7XG4gICAgICAvLyBSZXNldCBgbGFzdEluZGV4YCBiZWNhdXNlIGluIElFIDwgOSBgU3RyaW5nI3JlcGxhY2VgIGRvZXMgbm90LlxuICAgICAgc3RyaW5nID0gYmFzZVRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc1VuZXNjYXBlZEh0bWwudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlVW5lc2NhcGVkSHRtbCwgZXNjYXBlSHRtbENoYXIpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVzY2FwZXMgdGhlIGBSZWdFeHBgIHNwZWNpYWwgY2hhcmFjdGVycyBcIlxcXCIsIFwiL1wiLCBcIl5cIiwgXCIkXCIsIFwiLlwiLCBcInxcIiwgXCI/XCIsXG4gICAgICogXCIqXCIsIFwiK1wiLCBcIihcIiwgXCIpXCIsIFwiW1wiLCBcIl1cIiwgXCJ7XCIgYW5kIFwifVwiIGluIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGVSZWdFeHAoJ1tsb2Rhc2hdKGh0dHBzOi8vbG9kYXNoLmNvbS8pJyk7XG4gICAgICogLy8gPT4gJ1xcW2xvZGFzaFxcXVxcKGh0dHBzOlxcL1xcL2xvZGFzaFxcLmNvbVxcL1xcKSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzUmVnRXhwQ2hhcnMudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlUmVnRXhwQ2hhcnMsIGVzY2FwZVJlZ0V4cENoYXIpXG4gICAgICAgIDogKHN0cmluZyB8fCAnKD86KScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIFtrZWJhYiBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MZXR0ZXJfY2FzZSNTcGVjaWFsX2Nhc2Vfc3R5bGVzKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGtlYmFiIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5rZWJhYkNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdfX2Zvb19iYXJfXycpO1xuICAgICAqIC8vID0+ICdmb28tYmFyJ1xuICAgICAqL1xuICAgIHZhciBrZWJhYkNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnLScgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlcyBpZiBpdCdzIHNob3J0ZXIgdGhhbiBgbGVuZ3RoYC5cbiAgICAgKiBQYWRkaW5nIGNoYXJhY3RlcnMgYXJlIHRydW5jYXRlZCBpZiB0aGV5IGNhbid0IGJlIGV2ZW5seSBkaXZpZGVkIGJ5IGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCA4KTtcbiAgICAgKiAvLyA9PiAnICBhYmMgICAnXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgOCwgJ18tJyk7XG4gICAgICogLy8gPT4gJ18tYWJjXy1fJ1xuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDMpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFkKHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gYmFzZVRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBsZW5ndGggPSArbGVuZ3RoO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIGlmIChzdHJMZW5ndGggPj0gbGVuZ3RoIHx8ICFuYXRpdmVJc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgbWlkID0gKGxlbmd0aCAtIHN0ckxlbmd0aCkgLyAyLFxuICAgICAgICAgIGxlZnRMZW5ndGggPSBuYXRpdmVGbG9vcihtaWQpLFxuICAgICAgICAgIHJpZ2h0TGVuZ3RoID0gbmF0aXZlQ2VpbChtaWQpO1xuXG4gICAgICBjaGFycyA9IGNyZWF0ZVBhZGRpbmcoJycsIHJpZ2h0TGVuZ3RoLCBjaGFycyk7XG4gICAgICByZXR1cm4gY2hhcnMuc2xpY2UoMCwgbGVmdExlbmd0aCkgKyBzdHJpbmcgKyBjaGFycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IHNpZGUgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuIFBhZGRpbmdcbiAgICAgKiBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBleGNlZWQgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWRMZWZ0KCdhYmMnLCA2KTtcbiAgICAgKiAvLyA9PiAnICAgYWJjJ1xuICAgICAqXG4gICAgICogXy5wYWRMZWZ0KCdhYmMnLCA2LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnXy1fYWJjJ1xuICAgICAqXG4gICAgICogXy5wYWRMZWZ0KCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIHZhciBwYWRMZWZ0ID0gY3JlYXRlUGFkRGlyKCk7XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSByaWdodCBzaWRlIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLiBQYWRkaW5nXG4gICAgICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkUmlnaHQoJ2FiYycsIDYpO1xuICAgICAqIC8vID0+ICdhYmMgICAnXG4gICAgICpcbiAgICAgKiBfLnBhZFJpZ2h0KCdhYmMnLCA2LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnYWJjXy1fJ1xuICAgICAqXG4gICAgICogXy5wYWRSaWdodCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICB2YXIgcGFkUmlnaHQgPSBjcmVhdGVQYWREaXIodHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBpbnRlZ2VyIG9mIHRoZSBzcGVjaWZpZWQgcmFkaXguIElmIGByYWRpeGAgaXNcbiAgICAgKiBgdW5kZWZpbmVkYCBvciBgMGAsIGEgYHJhZGl4YCBvZiBgMTBgIGlzIHVzZWQgdW5sZXNzIGB2YWx1ZWAgaXMgYSBoZXhhZGVjaW1hbCxcbiAgICAgKiBpbiB3aGljaCBjYXNlIGEgYHJhZGl4YCBvZiBgMTZgIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgYWxpZ25zIHdpdGggdGhlIFtFUzUgaW1wbGVtZW50YXRpb25dKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jRSlcbiAgICAgKiBvZiBgcGFyc2VJbnRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcmFkaXhdIFRoZSByYWRpeCB0byBpbnRlcnByZXQgYHZhbHVlYCBieS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYXJzZUludCgnMDgnKTtcbiAgICAgKiAvLyA9PiA4XG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnMDgnLCAnMTAnXSwgXy5wYXJzZUludCk7XG4gICAgICogLy8gPT4gWzYsIDgsIDEwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhcnNlSW50KHN0cmluZywgcmFkaXgsIGd1YXJkKSB7XG4gICAgICAvLyBGaXJlZm94IDwgMjEgYW5kIE9wZXJhIDwgMTUgZm9sbG93IEVTMyBmb3IgYHBhcnNlSW50YC5cbiAgICAgIC8vIENocm9tZSBmYWlscyB0byB0cmltIGxlYWRpbmcgPEJPTT4gd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTA5IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIHJhZGl4LCBndWFyZCkgOiByYWRpeCA9PSBudWxsKSB7XG4gICAgICAgIHJhZGl4ID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocmFkaXgpIHtcbiAgICAgICAgcmFkaXggPSArcmFkaXg7XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgICByZXR1cm4gbmF0aXZlUGFyc2VJbnQoc3RyaW5nLCByYWRpeCB8fCAocmVIYXNIZXhQcmVmaXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGVhdHMgdGhlIGdpdmVuIHN0cmluZyBgbmAgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXBlYXQoJyonLCAzKTtcbiAgICAgKiAvLyA9PiAnKioqJ1xuICAgICAqXG4gICAgICogXy5yZXBlYXQoJ2FiYycsIDIpO1xuICAgICAqIC8vID0+ICdhYmNhYmMnXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnYWJjJywgMCk7XG4gICAgICogLy8gPT4gJydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIG4gPSArbjtcbiAgICAgIGlmIChuIDwgMSB8fCAhc3RyaW5nIHx8ICFuYXRpdmVJc0Zpbml0ZShuKSkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgLy8gTGV2ZXJhZ2UgdGhlIGV4cG9uZW50aWF0aW9uIGJ5IHNxdWFyaW5nIGFsZ29yaXRobSBmb3IgYSBmYXN0ZXIgcmVwZWF0LlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0V4cG9uZW50aWF0aW9uX2J5X3NxdWFyaW5nIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBkbyB7XG4gICAgICAgIGlmIChuICUgMikge1xuICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgICAgbiA9IG5hdGl2ZUZsb29yKG4gLyAyKTtcbiAgICAgICAgc3RyaW5nICs9IHN0cmluZztcbiAgICAgIH0gd2hpbGUgKG4pO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIFtzbmFrZSBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TbmFrZV9jYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNuYWtlIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCctLWZvby1iYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKi9cbiAgICB2YXIgc25ha2VDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJ18nIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gW3N0YXJ0IGNhc2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xldHRlcl9jYXNlI1N0eWxpc3RpY19vcl9zcGVjaWFsaXNlZF91c2FnZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdGFydCBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCctLWZvby1iYXInKTtcbiAgICAgKiAvLyA9PiAnRm9vIEJhcidcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnRm9vIEJhcidcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCdfX2Zvb19iYXJfXycpO1xuICAgICAqIC8vID0+ICdGb28gQmFyJ1xuICAgICAqL1xuICAgIHZhciBzdGFydENhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnICcgOiAnJykgKyAod29yZC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHdvcmQuc2xpY2UoMSkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIHN0YXJ0cyB3aXRoIHRoZSBnaXZlbiB0YXJnZXQgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldF0gVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zaXRpb249MF0gVGhlIHBvc2l0aW9uIHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgc3RyaW5nYCBzdGFydHMgd2l0aCBgdGFyZ2V0YCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5zdGFydHNXaXRoKCdhYmMnLCAnYicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdiJywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc3RyaW5nLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHBvc2l0aW9uID0gcG9zaXRpb24gPT0gbnVsbFxuICAgICAgICA/IDBcbiAgICAgICAgOiBuYXRpdmVNaW4ocG9zaXRpb24gPCAwID8gMCA6ICgrcG9zaXRpb24gfHwgMCksIHN0cmluZy5sZW5ndGgpO1xuXG4gICAgICByZXR1cm4gc3RyaW5nLmxhc3RJbmRleE9mKHRhcmdldCwgcG9zaXRpb24pID09IHBvc2l0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbiB0aGF0IGNhbiBpbnRlcnBvbGF0ZSBkYXRhIHByb3BlcnRpZXNcbiAgICAgKiBpbiBcImludGVycG9sYXRlXCIgZGVsaW1pdGVycywgSFRNTC1lc2NhcGUgaW50ZXJwb2xhdGVkIGRhdGEgcHJvcGVydGllcyBpblxuICAgICAqIFwiZXNjYXBlXCIgZGVsaW1pdGVycywgYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdCBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVycy4gRGF0YVxuICAgICAqIHByb3BlcnRpZXMgbWF5IGJlIGFjY2Vzc2VkIGFzIGZyZWUgdmFyaWFibGVzIGluIHRoZSB0ZW1wbGF0ZS4gSWYgYSBzZXR0aW5nXG4gICAgICogb2JqZWN0IGlzIHByb3ZpZGVkIGl0IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgXy50ZW1wbGF0ZVNldHRpbmdzYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSW4gdGhlIGRldmVsb3BtZW50IGJ1aWxkIGBfLnRlbXBsYXRlYCB1dGlsaXplc1xuICAgICAqIFtzb3VyY2VVUkxzXShodHRwOi8vd3d3Lmh0bWw1cm9ja3MuY29tL2VuL3R1dG9yaWFscy9kZXZlbG9wZXJ0b29scy9zb3VyY2VtYXBzLyN0b2Mtc291cmNldXJsKVxuICAgICAqIGZvciBlYXNpZXIgZGVidWdnaW5nLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gcHJlY29tcGlsaW5nIHRlbXBsYXRlcyBzZWVcbiAgICAgKiBbbG9kYXNoJ3MgY3VzdG9tIGJ1aWxkcyBkb2N1bWVudGF0aW9uXShodHRwczovL2xvZGFzaC5jb20vY3VzdG9tLWJ1aWxkcykuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBDaHJvbWUgZXh0ZW5zaW9uIHNhbmRib3hlcyBzZWVcbiAgICAgKiBbQ2hyb21lJ3MgZXh0ZW5zaW9ucyBkb2N1bWVudGF0aW9uXShodHRwczovL2RldmVsb3Blci5jaHJvbWUuY29tL2V4dGVuc2lvbnMvc2FuZGJveGluZ0V2YWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgdGVtcGxhdGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5lc2NhcGVdIFRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5ldmFsdWF0ZV0gVGhlIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmltcG9ydHNdIEFuIG9iamVjdCB0byBpbXBvcnQgaW50byB0aGUgdGVtcGxhdGUgYXMgZnJlZSB2YXJpYWJsZXMuXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IFtvcHRpb25zLmludGVycG9sYXRlXSBUaGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMuc291cmNlVVJMXSBUaGUgc291cmNlVVJMIG9mIHRoZSB0ZW1wbGF0ZSdzIGNvbXBpbGVkIHNvdXJjZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMudmFyaWFibGVdIFRoZSBkYXRhIG9iamVjdCB2YXJpYWJsZSBuYW1lLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW290aGVyT3B0aW9uc10gRW5hYmxlcyB0aGUgbGVnYWN5IGBvcHRpb25zYCBwYXJhbSBzaWduYXR1cmUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIgdG8gY3JlYXRlIGEgY29tcGlsZWQgdGVtcGxhdGVcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyA8JT0gdXNlciAlPiEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ2ZyZWQnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkISdcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyIHRvIGVzY2FwZSBkYXRhIHByb3BlcnR5IHZhbHVlc1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzxiPjwlLSB2YWx1ZSAlPjwvYj4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICc8c2NyaXB0PicgfSk7XG4gICAgICogLy8gPT4gJzxiPiZsdDtzY3JpcHQmZ3Q7PC9iPidcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBcImV2YWx1YXRlXCIgZGVsaW1pdGVyIHRvIGV4ZWN1dGUgSmF2YVNjcmlwdCBhbmQgZ2VuZXJhdGUgSFRNTFxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIF8uZm9yRWFjaCh1c2VycywgZnVuY3Rpb24odXNlcikgeyAlPjxsaT48JS0gdXNlciAlPjwvbGk+PCUgfSk7ICU+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgaW50ZXJuYWwgYHByaW50YCBmdW5jdGlvbiBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVyc1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIHByaW50KFwiaGVsbG8gXCIgKyB1c2VyKTsgJT4hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdiYXJuZXknIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBiYXJuZXkhJ1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIEVTIGRlbGltaXRlciBhcyBhbiBhbHRlcm5hdGl2ZSB0byB0aGUgZGVmYXVsdCBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gJHsgdXNlciB9IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAncGViYmxlcycgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIHBlYmJsZXMhJ1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgY3VzdG9tIHRlbXBsYXRlIGRlbGltaXRlcnNcbiAgICAgKiBfLnRlbXBsYXRlU2V0dGluZ3MuaW50ZXJwb2xhdGUgPSAve3soW1xcc1xcU10rPyl9fS9nO1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIHt7IHVzZXIgfX0hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdtdXN0YWNoZScgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIG11c3RhY2hlISdcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIGJhY2tzbGFzaGVzIHRvIHRyZWF0IGRlbGltaXRlcnMgYXMgcGxhaW4gdGV4dFxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlPSBcIlxcXFw8JS0gdmFsdWUgJVxcXFw+XCIgJT4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICdpZ25vcmVkJyB9KTtcbiAgICAgKiAvLyA9PiAnPCUtIHZhbHVlICU+J1xuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBpbXBvcnRzYCBvcHRpb24gdG8gaW1wb3J0IGBqUXVlcnlgIGFzIGBqcWBcbiAgICAgKiB2YXIgdGV4dCA9ICc8JSBqcS5lYWNoKHVzZXJzLCBmdW5jdGlvbih1c2VyKSB7ICU+PGxpPjwlLSB1c2VyICU+PC9saT48JSB9KTsgJT4nO1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUodGV4dCwgeyAnaW1wb3J0cyc6IHsgJ2pxJzogalF1ZXJ5IH0gfSk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyB1c2luZyB0aGUgYHNvdXJjZVVSTGAgb3B0aW9uIHRvIHNwZWNpZnkgYSBjdXN0b20gc291cmNlVVJMIGZvciB0aGUgdGVtcGxhdGVcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyA8JT0gdXNlciAlPiEnLCB7ICdzb3VyY2VVUkwnOiAnL2Jhc2ljL2dyZWV0aW5nLmpzdCcgfSk7XG4gICAgICogY29tcGlsZWQoZGF0YSk7XG4gICAgICogLy8gPT4gZmluZCB0aGUgc291cmNlIG9mIFwiZ3JlZXRpbmcuanN0XCIgdW5kZXIgdGhlIFNvdXJjZXMgdGFiIG9yIFJlc291cmNlcyBwYW5lbCBvZiB0aGUgd2ViIGluc3BlY3RvclxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGB2YXJpYWJsZWAgb3B0aW9uIHRvIGVuc3VyZSBhIHdpdGgtc3RhdGVtZW50IGlzbid0IHVzZWQgaW4gdGhlIGNvbXBpbGVkIHRlbXBsYXRlXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGkgPCU9IGRhdGEudXNlciAlPiEnLCB7ICd2YXJpYWJsZSc6ICdkYXRhJyB9KTtcbiAgICAgKiBjb21waWxlZC5zb3VyY2U7XG4gICAgICogLy8gPT4gZnVuY3Rpb24oZGF0YSkge1xuICAgICAqIC8vICAgdmFyIF9fdCwgX19wID0gJyc7XG4gICAgICogLy8gICBfX3AgKz0gJ2hpICcgKyAoKF9fdCA9ICggZGF0YS51c2VyICkpID09IG51bGwgPyAnJyA6IF9fdCkgKyAnISc7XG4gICAgICogLy8gICByZXR1cm4gX19wO1xuICAgICAqIC8vIH1cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgc291cmNlYCBwcm9wZXJ0eSB0byBpbmxpbmUgY29tcGlsZWQgdGVtcGxhdGVzIGZvciBtZWFuaW5nZnVsXG4gICAgICogLy8gbGluZSBudW1iZXJzIGluIGVycm9yIG1lc3NhZ2VzIGFuZCBhIHN0YWNrIHRyYWNlXG4gICAgICogZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4oY3dkLCAnanN0LmpzJyksICdcXFxuICAgICAqICAgdmFyIEpTVCA9IHtcXFxuICAgICAqICAgICBcIm1haW5cIjogJyArIF8udGVtcGxhdGUobWFpblRleHQpLnNvdXJjZSArICdcXFxuICAgICAqICAgfTtcXFxuICAgICAqICcpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRlbXBsYXRlKHN0cmluZywgb3B0aW9ucywgb3RoZXJPcHRpb25zKSB7XG4gICAgICAvLyBCYXNlZCBvbiBKb2huIFJlc2lnJ3MgYHRtcGxgIGltcGxlbWVudGF0aW9uIChodHRwOi8vZWpvaG4ub3JnL2Jsb2cvamF2YXNjcmlwdC1taWNyby10ZW1wbGF0aW5nLylcbiAgICAgIC8vIGFuZCBMYXVyYSBEb2t0b3JvdmEncyBkb1QuanMgKGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1QpLlxuICAgICAgdmFyIHNldHRpbmdzID0gbG9kYXNoLnRlbXBsYXRlU2V0dGluZ3M7XG5cbiAgICAgIGlmIChvdGhlck9wdGlvbnMgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBvcHRpb25zLCBvdGhlck9wdGlvbnMpKSB7XG4gICAgICAgIG9wdGlvbnMgPSBvdGhlck9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIG9wdGlvbnMgPSBhc3NpZ25XaXRoKGJhc2VBc3NpZ24oe30sIG90aGVyT3B0aW9ucyB8fCBvcHRpb25zKSwgc2V0dGluZ3MsIGFzc2lnbk93bkRlZmF1bHRzKTtcblxuICAgICAgdmFyIGltcG9ydHMgPSBhc3NpZ25XaXRoKGJhc2VBc3NpZ24oe30sIG9wdGlvbnMuaW1wb3J0cyksIHNldHRpbmdzLmltcG9ydHMsIGFzc2lnbk93bkRlZmF1bHRzKSxcbiAgICAgICAgICBpbXBvcnRzS2V5cyA9IGtleXMoaW1wb3J0cyksXG4gICAgICAgICAgaW1wb3J0c1ZhbHVlcyA9IGJhc2VWYWx1ZXMoaW1wb3J0cywgaW1wb3J0c0tleXMpO1xuXG4gICAgICB2YXIgaXNFc2NhcGluZyxcbiAgICAgICAgICBpc0V2YWx1YXRpbmcsXG4gICAgICAgICAgaW5kZXggPSAwLFxuICAgICAgICAgIGludGVycG9sYXRlID0gb3B0aW9ucy5pbnRlcnBvbGF0ZSB8fCByZU5vTWF0Y2gsXG4gICAgICAgICAgc291cmNlID0gXCJfX3AgKz0gJ1wiO1xuXG4gICAgICAvLyBDb21waWxlIHRoZSByZWdleHAgdG8gbWF0Y2ggZWFjaCBkZWxpbWl0ZXIuXG4gICAgICB2YXIgcmVEZWxpbWl0ZXJzID0gUmVnRXhwKFxuICAgICAgICAob3B0aW9ucy5lc2NhcGUgfHwgcmVOb01hdGNoKS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICBpbnRlcnBvbGF0ZS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICAoaW50ZXJwb2xhdGUgPT09IHJlSW50ZXJwb2xhdGUgPyByZUVzVGVtcGxhdGUgOiByZU5vTWF0Y2gpLnNvdXJjZSArICd8JyArXG4gICAgICAgIChvcHRpb25zLmV2YWx1YXRlIHx8IHJlTm9NYXRjaCkuc291cmNlICsgJ3wkJ1xuICAgICAgLCAnZycpO1xuXG4gICAgICAvLyBVc2UgYSBzb3VyY2VVUkwgZm9yIGVhc2llciBkZWJ1Z2dpbmcuXG4gICAgICB2YXIgc291cmNlVVJMID0gJy8vIyBzb3VyY2VVUkw9JyArXG4gICAgICAgICgnc291cmNlVVJMJyBpbiBvcHRpb25zXG4gICAgICAgICAgPyBvcHRpb25zLnNvdXJjZVVSTFxuICAgICAgICAgIDogKCdsb2Rhc2gudGVtcGxhdGVTb3VyY2VzWycgKyAoKyt0ZW1wbGF0ZUNvdW50ZXIpICsgJ10nKVxuICAgICAgICApICsgJ1xcbic7XG5cbiAgICAgIHN0cmluZy5yZXBsYWNlKHJlRGVsaW1pdGVycywgZnVuY3Rpb24obWF0Y2gsIGVzY2FwZVZhbHVlLCBpbnRlcnBvbGF0ZVZhbHVlLCBlc1RlbXBsYXRlVmFsdWUsIGV2YWx1YXRlVmFsdWUsIG9mZnNldCkge1xuICAgICAgICBpbnRlcnBvbGF0ZVZhbHVlIHx8IChpbnRlcnBvbGF0ZVZhbHVlID0gZXNUZW1wbGF0ZVZhbHVlKTtcblxuICAgICAgICAvLyBFc2NhcGUgY2hhcmFjdGVycyB0aGF0IGNhbid0IGJlIGluY2x1ZGVkIGluIHN0cmluZyBsaXRlcmFscy5cbiAgICAgICAgc291cmNlICs9IHN0cmluZy5zbGljZShpbmRleCwgb2Zmc2V0KS5yZXBsYWNlKHJlVW5lc2NhcGVkU3RyaW5nLCBlc2NhcGVTdHJpbmdDaGFyKTtcblxuICAgICAgICAvLyBSZXBsYWNlIGRlbGltaXRlcnMgd2l0aCBzbmlwcGV0cy5cbiAgICAgICAgaWYgKGVzY2FwZVZhbHVlKSB7XG4gICAgICAgICAgaXNFc2NhcGluZyA9IHRydWU7XG4gICAgICAgICAgc291cmNlICs9IFwiJyArXFxuX19lKFwiICsgZXNjYXBlVmFsdWUgKyBcIikgK1xcbidcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZhbHVhdGVWYWx1ZSkge1xuICAgICAgICAgIGlzRXZhbHVhdGluZyA9IHRydWU7XG4gICAgICAgICAgc291cmNlICs9IFwiJztcXG5cIiArIGV2YWx1YXRlVmFsdWUgKyBcIjtcXG5fX3AgKz0gJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnRlcnBvbGF0ZVZhbHVlKSB7XG4gICAgICAgICAgc291cmNlICs9IFwiJyArXFxuKChfX3QgPSAoXCIgKyBpbnRlcnBvbGF0ZVZhbHVlICsgXCIpKSA9PSBudWxsID8gJycgOiBfX3QpICtcXG4nXCI7XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSBvZmZzZXQgKyBtYXRjaC5sZW5ndGg7XG5cbiAgICAgICAgLy8gVGhlIEpTIGVuZ2luZSBlbWJlZGRlZCBpbiBBZG9iZSBwcm9kdWN0cyByZXF1aXJlcyByZXR1cm5pbmcgdGhlIGBtYXRjaGBcbiAgICAgICAgLy8gc3RyaW5nIGluIG9yZGVyIHRvIHByb2R1Y2UgdGhlIGNvcnJlY3QgYG9mZnNldGAgdmFsdWUuXG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH0pO1xuXG4gICAgICBzb3VyY2UgKz0gXCInO1xcblwiO1xuXG4gICAgICAvLyBJZiBgdmFyaWFibGVgIGlzIG5vdCBzcGVjaWZpZWQgd3JhcCBhIHdpdGgtc3RhdGVtZW50IGFyb3VuZCB0aGUgZ2VuZXJhdGVkXG4gICAgICAvLyBjb2RlIHRvIGFkZCB0aGUgZGF0YSBvYmplY3QgdG8gdGhlIHRvcCBvZiB0aGUgc2NvcGUgY2hhaW4uXG4gICAgICB2YXIgdmFyaWFibGUgPSBvcHRpb25zLnZhcmlhYmxlO1xuICAgICAgaWYgKCF2YXJpYWJsZSkge1xuICAgICAgICBzb3VyY2UgPSAnd2l0aCAob2JqKSB7XFxuJyArIHNvdXJjZSArICdcXG59XFxuJztcbiAgICAgIH1cbiAgICAgIC8vIENsZWFudXAgY29kZSBieSBzdHJpcHBpbmcgZW1wdHkgc3RyaW5ncy5cbiAgICAgIHNvdXJjZSA9IChpc0V2YWx1YXRpbmcgPyBzb3VyY2UucmVwbGFjZShyZUVtcHR5U3RyaW5nTGVhZGluZywgJycpIDogc291cmNlKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nTWlkZGxlLCAnJDEnKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nVHJhaWxpbmcsICckMTsnKTtcblxuICAgICAgLy8gRnJhbWUgY29kZSBhcyB0aGUgZnVuY3Rpb24gYm9keS5cbiAgICAgIHNvdXJjZSA9ICdmdW5jdGlvbignICsgKHZhcmlhYmxlIHx8ICdvYmonKSArICcpIHtcXG4nICtcbiAgICAgICAgKHZhcmlhYmxlXG4gICAgICAgICAgPyAnJ1xuICAgICAgICAgIDogJ29iaiB8fCAob2JqID0ge30pO1xcbidcbiAgICAgICAgKSArXG4gICAgICAgIFwidmFyIF9fdCwgX19wID0gJydcIiArXG4gICAgICAgIChpc0VzY2FwaW5nXG4gICAgICAgICAgID8gJywgX19lID0gXy5lc2NhcGUnXG4gICAgICAgICAgIDogJydcbiAgICAgICAgKSArXG4gICAgICAgIChpc0V2YWx1YXRpbmdcbiAgICAgICAgICA/ICcsIF9faiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xcbicgK1xuICAgICAgICAgICAgXCJmdW5jdGlvbiBwcmludCgpIHsgX19wICs9IF9fai5jYWxsKGFyZ3VtZW50cywgJycpIH1cXG5cIlxuICAgICAgICAgIDogJztcXG4nXG4gICAgICAgICkgK1xuICAgICAgICBzb3VyY2UgK1xuICAgICAgICAncmV0dXJuIF9fcFxcbn0nO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYXR0ZW1wdChmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uKGltcG9ydHNLZXlzLCBzb3VyY2VVUkwgKyAncmV0dXJuICcgKyBzb3VyY2UpLmFwcGx5KHVuZGVmaW5lZCwgaW1wb3J0c1ZhbHVlcyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24ncyBzb3VyY2UgYnkgaXRzIGB0b1N0cmluZ2AgbWV0aG9kIG9yXG4gICAgICAvLyB0aGUgYHNvdXJjZWAgcHJvcGVydHkgYXMgYSBjb252ZW5pZW5jZSBmb3IgaW5saW5pbmcgY29tcGlsZWQgdGVtcGxhdGVzLlxuICAgICAgcmVzdWx0LnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIGlmIChpc0Vycm9yKHJlc3VsdCkpIHtcbiAgICAgICAgdGhyb3cgcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2Ugb3Igc3BlY2lmaWVkIGNoYXJhY3RlcnMgZnJvbSBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byB0cmltLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9d2hpdGVzcGFjZV0gVGhlIGNoYXJhY3RlcnMgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltKCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKlxuICAgICAqIF8udHJpbSgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnICBmb28gICcsICcgIGJhciAgJ10sIF8udHJpbSk7XG4gICAgICogLy8gPT4gWydmb28nLCAnYmFyJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltKHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICB2YXIgdmFsdWUgPSBzdHJpbmc7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmICghc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgY2hhcnMsIGd1YXJkKSA6IGNoYXJzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5zbGljZSh0cmltbWVkTGVmdEluZGV4KHN0cmluZyksIHRyaW1tZWRSaWdodEluZGV4KHN0cmluZykgKyAxKTtcbiAgICAgIH1cbiAgICAgIGNoYXJzID0gKGNoYXJzICsgJycpO1xuICAgICAgcmV0dXJuIHN0cmluZy5zbGljZShjaGFyc0xlZnRJbmRleChzdHJpbmcsIGNoYXJzKSwgY2hhcnNSaWdodEluZGV4KHN0cmluZywgY2hhcnMpICsgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBsZWFkaW5nIHdoaXRlc3BhY2Ugb3Igc3BlY2lmaWVkIGNoYXJhY3RlcnMgZnJvbSBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byB0cmltLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9d2hpdGVzcGFjZV0gVGhlIGNoYXJhY3RlcnMgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltTGVmdCgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICdhYmMgICdcbiAgICAgKlxuICAgICAqIF8udHJpbUxlZnQoJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMtXy0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbUxlZnQoc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHN0cmluZztcbiAgICAgIHN0cmluZyA9IGJhc2VUb1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKCFzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIGlmIChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBjaGFycywgZ3VhcmQpIDogY2hhcnMgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKHRyaW1tZWRMZWZ0SW5kZXgoc3RyaW5nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKGNoYXJzTGVmdEluZGV4KHN0cmluZywgKGNoYXJzICsgJycpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0cmFpbGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbVJpZ2h0KCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJyAgYWJjJ1xuICAgICAqXG4gICAgICogXy50cmltUmlnaHQoJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICctXy1hYmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbVJpZ2h0KHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICB2YXIgdmFsdWUgPSBzdHJpbmc7XG4gICAgICBzdHJpbmcgPSBiYXNlVG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmICghc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICBpZiAoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgY2hhcnMsIGd1YXJkKSA6IGNoYXJzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5zbGljZSgwLCB0cmltbWVkUmlnaHRJbmRleChzdHJpbmcpICsgMSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKDAsIGNoYXJzUmlnaHRJbmRleChzdHJpbmcsIChjaGFycyArICcnKSkgKyAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcnVuY2F0ZXMgYHN0cmluZ2AgaWYgaXQncyBsb25nZXIgdGhhbiB0aGUgZ2l2ZW4gbWF4aW11bSBzdHJpbmcgbGVuZ3RoLlxuICAgICAqIFRoZSBsYXN0IGNoYXJhY3RlcnMgb2YgdGhlIHRydW5jYXRlZCBzdHJpbmcgYXJlIHJlcGxhY2VkIHdpdGggdGhlIG9taXNzaW9uXG4gICAgICogc3RyaW5nIHdoaWNoIGRlZmF1bHRzIHRvIFwiLi4uXCIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJ1bmNhdGUuXG4gICAgICogQHBhcmFtIHtPYmplY3R8bnVtYmVyfSBbb3B0aW9uc10gVGhlIG9wdGlvbnMgb2JqZWN0IG9yIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubGVuZ3RoPTMwXSBUaGUgbWF4aW11bSBzdHJpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5vbWlzc2lvbj0nLi4uJ10gVGhlIHN0cmluZyB0byBpbmRpY2F0ZSB0ZXh0IGlzIG9taXR0ZWQuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBbb3B0aW9ucy5zZXBhcmF0b3JdIFRoZSBzZXBhcmF0b3IgcGF0dGVybiB0byB0cnVuY2F0ZSB0by5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cnVuY2F0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRydW5jKCdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm9yaW5vJyk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hiby4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmMoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCAyNCk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZSwgbi4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmMoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnbGVuZ3RoJzogMjQsXG4gICAgICogICAnc2VwYXJhdG9yJzogJyAnXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZSwuLi4nXG4gICAgICpcbiAgICAgKiBfLnRydW5jKCdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm9yaW5vJywge1xuICAgICAqICAgJ2xlbmd0aCc6IDI0LFxuICAgICAqICAgJ3NlcGFyYXRvcic6IC8sPyArL1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUuLi4nXG4gICAgICpcbiAgICAgKiBfLnRydW5jKCdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm9yaW5vJywge1xuICAgICAqICAgJ29taXNzaW9uJzogJyBbLi4uXSdcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnIFsuLi5dJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRydW5jKHN0cmluZywgb3B0aW9ucywgZ3VhcmQpIHtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIG9wdGlvbnMsIGd1YXJkKSkge1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IERFRkFVTFRfVFJVTkNfTEVOR1RILFxuICAgICAgICAgIG9taXNzaW9uID0gREVGQVVMVF9UUlVOQ19PTUlTU0lPTjtcblxuICAgICAgaWYgKG9wdGlvbnMgIT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICB2YXIgc2VwYXJhdG9yID0gJ3NlcGFyYXRvcicgaW4gb3B0aW9ucyA/IG9wdGlvbnMuc2VwYXJhdG9yIDogc2VwYXJhdG9yO1xuICAgICAgICAgIGxlbmd0aCA9ICdsZW5ndGgnIGluIG9wdGlvbnMgPyAoK29wdGlvbnMubGVuZ3RoIHx8IDApIDogbGVuZ3RoO1xuICAgICAgICAgIG9taXNzaW9uID0gJ29taXNzaW9uJyBpbiBvcHRpb25zID8gYmFzZVRvU3RyaW5nKG9wdGlvbnMub21pc3Npb24pIDogb21pc3Npb247XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGVuZ3RoID0gK29wdGlvbnMgfHwgMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc3RyaW5nID0gYmFzZVRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAobGVuZ3RoID49IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBlbmQgPSBsZW5ndGggLSBvbWlzc2lvbi5sZW5ndGg7XG4gICAgICBpZiAoZW5kIDwgMSkge1xuICAgICAgICByZXR1cm4gb21pc3Npb247XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gc3RyaW5nLnNsaWNlKDAsIGVuZCk7XG4gICAgICBpZiAoc2VwYXJhdG9yID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCArIG9taXNzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKGlzUmVnRXhwKHNlcGFyYXRvcikpIHtcbiAgICAgICAgaWYgKHN0cmluZy5zbGljZShlbmQpLnNlYXJjaChzZXBhcmF0b3IpKSB7XG4gICAgICAgICAgdmFyIG1hdGNoLFxuICAgICAgICAgICAgICBuZXdFbmQsXG4gICAgICAgICAgICAgIHN1YnN0cmluZyA9IHN0cmluZy5zbGljZSgwLCBlbmQpO1xuXG4gICAgICAgICAgaWYgKCFzZXBhcmF0b3IuZ2xvYmFsKSB7XG4gICAgICAgICAgICBzZXBhcmF0b3IgPSBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgKHJlRmxhZ3MuZXhlYyhzZXBhcmF0b3IpIHx8ICcnKSArICdnJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgIHdoaWxlICgobWF0Y2ggPSBzZXBhcmF0b3IuZXhlYyhzdWJzdHJpbmcpKSkge1xuICAgICAgICAgICAgbmV3RW5kID0gbWF0Y2guaW5kZXg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCBuZXdFbmQgPT0gbnVsbCA/IGVuZCA6IG5ld0VuZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc3RyaW5nLmluZGV4T2Yoc2VwYXJhdG9yLCBlbmQpICE9IGVuZCkge1xuICAgICAgICB2YXIgaW5kZXggPSByZXN1bHQubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0ICsgb21pc3Npb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8uZXNjYXBlYDsgdGhpcyBtZXRob2QgY29udmVydHMgdGhlIEhUTUwgZW50aXRpZXNcbiAgICAgKiBgJmFtcDtgLCBgJmx0O2AsIGAmZ3Q7YCwgYCZxdW90O2AsIGAmIzM5O2AsIGFuZCBgJiM5NjtgIGluIGBzdHJpbmdgIHRvIHRoZWlyXG4gICAgICogY29ycmVzcG9uZGluZyBjaGFyYWN0ZXJzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vIG90aGVyIEhUTUwgZW50aXRpZXMgYXJlIHVuZXNjYXBlZC4gVG8gdW5lc2NhcGUgYWRkaXRpb25hbCBIVE1MXG4gICAgICogZW50aXRpZXMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHVuZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVuZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICdmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmVzY2FwZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IGJhc2VUb1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIChzdHJpbmcgJiYgcmVIYXNFc2NhcGVkSHRtbC50ZXN0KHN0cmluZykpXG4gICAgICAgID8gc3RyaW5nLnJlcGxhY2UocmVFc2NhcGVkSHRtbCwgdW5lc2NhcGVIdG1sQ2hhcilcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BsaXRzIGBzdHJpbmdgIGludG8gYW4gYXJyYXkgb2YgaXRzIHdvcmRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBbcGF0dGVybl0gVGhlIHBhdHRlcm4gdG8gbWF0Y2ggd29yZHMuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGEgY2FsbGJhY2sgZm9yIGZ1bmN0aW9ucyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiBbJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnLCAvW14sIF0rL2cpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAnJicsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3b3JkcyhzdHJpbmcsIHBhdHRlcm4sIGd1YXJkKSB7XG4gICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBwYXR0ZXJuLCBndWFyZCkpIHtcbiAgICAgICAgcGF0dGVybiA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHN0cmluZyA9IGJhc2VUb1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIHN0cmluZy5tYXRjaChwYXR0ZXJuIHx8IHJlV29yZHMpIHx8IFtdO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEF0dGVtcHRzIHRvIGludm9rZSBgZnVuY2AsIHJldHVybmluZyBlaXRoZXIgdGhlIHJlc3VsdCBvciB0aGUgY2F1Z2h0IGVycm9yXG4gICAgICogb2JqZWN0LiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIGBmdW5jYCB3aGVuIGl0IGlzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGF0dGVtcHQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGBmdW5jYCByZXN1bHQgb3IgZXJyb3Igb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBhdm9pZCB0aHJvd2luZyBlcnJvcnMgZm9yIGludmFsaWQgc2VsZWN0b3JzXG4gICAgICogdmFyIGVsZW1lbnRzID0gXy5hdHRlbXB0KGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICogICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICogfSwgJz5fPicpO1xuICAgICAqXG4gICAgICogaWYgKF8uaXNFcnJvcihlbGVtZW50cykpIHtcbiAgICAgKiAgIGVsZW1lbnRzID0gW107XG4gICAgICogfVxuICAgICAqL1xuICAgIHZhciBhdHRlbXB0ID0gcmVzdFBhcmFtKGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgcmV0dXJuIGlzRXJyb3IoZSkgPyBlIDogbmV3IEVycm9yKGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gICAgICogYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi4gSWYgYGZ1bmNgIGlzIGEgcHJvcGVydHkgbmFtZSB0aGVcbiAgICAgKiBjcmVhdGVkIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGZvciBhIGdpdmVuIGVsZW1lbnQuIElmIGBmdW5jYFxuICAgICAqIGlzIGFuIG9iamVjdCB0aGUgY3JlYXRlZCBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBjb250YWluXG4gICAgICogdGhlIGVxdWl2YWxlbnQgb2JqZWN0IHByb3BlcnRpZXMsIG90aGVyd2lzZSBpdCByZXR1cm5zIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAYWxpYXMgaXRlcmF0ZWVcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7Kn0gW2Z1bmM9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYSBjYWxsYmFjay5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIHdyYXAgdG8gY3JlYXRlIGN1c3RvbSBjYWxsYmFjayBzaG9ydGhhbmRzXG4gICAgICogXy5jYWxsYmFjayA9IF8ud3JhcChfLmNhbGxiYWNrLCBmdW5jdGlvbihjYWxsYmFjaywgZnVuYywgdGhpc0FyZykge1xuICAgICAqICAgdmFyIG1hdGNoID0gL14oLis/KV9fKFtnbF10KSguKykkLy5leGVjKGZ1bmMpO1xuICAgICAqICAgaWYgKCFtYXRjaCkge1xuICAgICAqICAgICByZXR1cm4gY2FsbGJhY2soZnVuYywgdGhpc0FyZyk7XG4gICAgICogICB9XG4gICAgICogICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICogICAgIHJldHVybiBtYXRjaFsyXSA9PSAnZ3QnXG4gICAgICogICAgICAgPyBvYmplY3RbbWF0Y2hbMV1dID4gbWF0Y2hbM11cbiAgICAgKiAgICAgICA6IG9iamVjdFttYXRjaFsxXV0gPCBtYXRjaFszXTtcbiAgICAgKiAgIH07XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcih1c2VycywgJ2FnZV9fZ3QzNicpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBndWFyZCkge1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGZ1bmMsIHRoaXNBcmcsIGd1YXJkKSkge1xuICAgICAgICB0aGlzQXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZShmdW5jKVxuICAgICAgICA/IG1hdGNoZXMoZnVuYylcbiAgICAgICAgOiBiYXNlQ2FsbGJhY2soZnVuYywgdGhpc0FyZyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxpdHlcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZXR1cm4gZnJvbSB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICAgICAqIHZhciBnZXR0ZXIgPSBfLmNvbnN0YW50KG9iamVjdCk7XG4gICAgICpcbiAgICAgKiBnZXR0ZXIoKSA9PT0gb2JqZWN0O1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb25zdGFudCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IHByb3ZpZGVkIHRvIGl0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxpdHlcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICAgICAqXG4gICAgICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBhIGdpdmVuIG9iamVjdFxuICAgICAqIGFuZCBgc291cmNlYCwgcmV0dXJuaW5nIGB0cnVlYCBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGhhcyBlcXVpdmFsZW50IHByb3BlcnR5XG4gICAgICogdmFsdWVzLCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYm9vbGVhbnMsIGBEYXRlYCBvYmplY3RzLFxuICAgICAqIG51bWJlcnMsIGBPYmplY3RgIG9iamVjdHMsIHJlZ2V4ZXMsIGFuZCBzdHJpbmdzLiBPYmplY3RzIGFyZSBjb21wYXJlZCBieVxuICAgICAqIHRoZWlyIG93biwgbm90IGluaGVyaXRlZCwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLiBGb3IgY29tcGFyaW5nIGEgc2luZ2xlXG4gICAgICogb3duIG9yIGluaGVyaXRlZCBwcm9wZXJ0eSB2YWx1ZSBzZWUgYF8ubWF0Y2hlc1Byb3BlcnR5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIodXNlcnMsIF8ubWF0Y2hlcyh7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0pKTtcbiAgICAgKiAvLyA9PiBbeyAndXNlcic6ICdmcmVkJywgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VNYXRjaGVzKGJhc2VDbG9uZShzb3VyY2UsIHRydWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBjb21wYXJlcyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgYHBhdGhgIG9uIGEgZ2l2ZW5cbiAgICAgKiBvYmplY3QgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBjb21wYXJpbmcgYXJyYXlzLCBib29sZWFucywgYERhdGVgIG9iamVjdHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgYW5kIHN0cmluZ3MuIE9iamVjdHMgYXJlIGNvbXBhcmVkIGJ5XG4gICAgICogdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmluZCh1c2VycywgXy5tYXRjaGVzUHJvcGVydHkoJ3VzZXInLCAnZnJlZCcpKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIGJhc2VDbG9uZShzcmNWYWx1ZSwgdHJ1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb24gYSBnaXZlbiBvYmplY3QuXG4gICAgICogQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiBfLmNvbnN0YW50KDIpIH0gfSB9LFxuICAgICAqICAgeyAnYSc6IHsgJ2InOiB7ICdjJzogXy5jb25zdGFudCgxKSB9IH0gfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLm1hcChvYmplY3RzLCBfLm1ldGhvZCgnYS5iLmMnKSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICpcbiAgICAgKiBfLmludm9rZShfLnNvcnRCeShvYmplY3RzLCBfLm1ldGhvZChbJ2EnLCAnYicsICdjJ10pKSwgJ2EuYi5jJyk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgdmFyIG1ldGhvZCA9IHJlc3RQYXJhbShmdW5jdGlvbihwYXRoLCBhcmdzKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBpbnZva2VQYXRoKG9iamVjdCwgcGF0aCwgYXJncyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1ldGhvZGA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiB0aGUgbWV0aG9kIGF0IGEgZ2l2ZW4gcGF0aCBvbiBgb2JqZWN0YC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZVxuICAgICAqIHByb3ZpZGVkIHRvIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gXy50aW1lcygzLCBfLmNvbnN0YW50KSxcbiAgICAgKiAgICAgb2JqZWN0ID0geyAnYSc6IGFycmF5LCAnYic6IGFycmF5LCAnYyc6IGFycmF5IH07XG4gICAgICpcbiAgICAgKiBfLm1hcChbJ2FbMl0nLCAnY1swXSddLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIHZhciBtZXRob2RPZiA9IHJlc3RQYXJhbShmdW5jdGlvbihvYmplY3QsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBpbnZva2VQYXRoKG9iamVjdCwgcGF0aCwgYXJncyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhbGwgb3duIGVudW1lcmFibGUgZnVuY3Rpb24gcHJvcGVydGllcyBvZiBhIHNvdXJjZSBvYmplY3QgdG8gdGhlXG4gICAgICogZGVzdGluYXRpb24gb2JqZWN0LiBJZiBgb2JqZWN0YCBpcyBhIGZ1bmN0aW9uIHRoZW4gbWV0aG9kcyBhcmUgYWRkZWQgdG9cbiAgICAgKiBpdHMgcHJvdG90eXBlIGFzIHdlbGwuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVXNlIGBfLnJ1bkluQ29udGV4dGAgdG8gY3JlYXRlIGEgcHJpc3RpbmUgYGxvZGFzaGAgZnVuY3Rpb24gdG9cbiAgICAgKiBhdm9pZCBjb25mbGljdHMgY2F1c2VkIGJ5IG1vZGlmeWluZyB0aGUgb3JpZ2luYWwuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBbb2JqZWN0PWxvZGFzaF0gVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmNoYWluPXRydWVdIFNwZWNpZnkgd2hldGhlciB0aGUgZnVuY3Rpb25zIGFkZGVkXG4gICAgICogIGFyZSBjaGFpbmFibGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufE9iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gdm93ZWxzKHN0cmluZykge1xuICAgICAqICAgcmV0dXJuIF8uZmlsdGVyKHN0cmluZywgZnVuY3Rpb24odikge1xuICAgICAqICAgICByZXR1cm4gL1thZWlvdV0vaS50ZXN0KHYpO1xuICAgICAqICAgfSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5taXhpbih7ICd2b3dlbHMnOiB2b3dlbHMgfSk7XG4gICAgICogXy52b3dlbHMoJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqXG4gICAgICogXygnZnJlZCcpLnZvd2VscygpLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKlxuICAgICAqIF8ubWl4aW4oeyAndm93ZWxzJzogdm93ZWxzIH0sIHsgJ2NoYWluJzogZmFsc2UgfSk7XG4gICAgICogXygnZnJlZCcpLnZvd2VscygpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWl4aW4ob2JqZWN0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgICAgdmFyIGlzT2JqID0gaXNPYmplY3Qoc291cmNlKSxcbiAgICAgICAgICAgIHByb3BzID0gaXNPYmogPyBrZXlzKHNvdXJjZSkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBtZXRob2ROYW1lcyA9IChwcm9wcyAmJiBwcm9wcy5sZW5ndGgpID8gYmFzZUZ1bmN0aW9ucyhzb3VyY2UsIHByb3BzKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoIShtZXRob2ROYW1lcyA/IG1ldGhvZE5hbWVzLmxlbmd0aCA6IGlzT2JqKSkge1xuICAgICAgICAgIG1ldGhvZE5hbWVzID0gZmFsc2U7XG4gICAgICAgICAgb3B0aW9ucyA9IHNvdXJjZTtcbiAgICAgICAgICBzb3VyY2UgPSBvYmplY3Q7XG4gICAgICAgICAgb2JqZWN0ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFtZXRob2ROYW1lcykge1xuICAgICAgICBtZXRob2ROYW1lcyA9IGJhc2VGdW5jdGlvbnMoc291cmNlLCBrZXlzKHNvdXJjZSkpO1xuICAgICAgfVxuICAgICAgdmFyIGNoYWluID0gdHJ1ZSxcbiAgICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzRnVuYyA9IGlzRnVuY3Rpb24ob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSBtZXRob2ROYW1lcy5sZW5ndGg7XG5cbiAgICAgIGlmIChvcHRpb25zID09PSBmYWxzZSkge1xuICAgICAgICBjaGFpbiA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChvcHRpb25zKSAmJiAnY2hhaW4nIGluIG9wdGlvbnMpIHtcbiAgICAgICAgY2hhaW4gPSBvcHRpb25zLmNoYWluO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIG1ldGhvZE5hbWUgPSBtZXRob2ROYW1lc1tpbmRleF0sXG4gICAgICAgICAgICBmdW5jID0gc291cmNlW21ldGhvZE5hbWVdO1xuXG4gICAgICAgIG9iamVjdFttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIGlmIChpc0Z1bmMpIHtcbiAgICAgICAgICBvYmplY3QucHJvdG90eXBlW21ldGhvZE5hbWVdID0gKGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIGNoYWluQWxsID0gdGhpcy5fX2NoYWluX187XG4gICAgICAgICAgICAgIGlmIChjaGFpbiB8fCBjaGFpbkFsbCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvYmplY3QodGhpcy5fX3dyYXBwZWRfXyksXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbnMgPSByZXN1bHQuX19hY3Rpb25zX18gPSBhcnJheUNvcHkodGhpcy5fX2FjdGlvbnNfXyk7XG5cbiAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goeyAnZnVuYyc6IGZ1bmMsICdhcmdzJzogYXJndW1lbnRzLCAndGhpc0FyZyc6IG9iamVjdCB9KTtcbiAgICAgICAgICAgICAgICByZXN1bHQuX19jaGFpbl9fID0gY2hhaW5BbGw7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShvYmplY3QsIGFycmF5UHVzaChbdGhpcy52YWx1ZSgpXSwgYXJndW1lbnRzKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0oZnVuYykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGBfYCB2YXJpYWJsZSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG9cbiAgICAgKiB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBsb2Rhc2ggPSBfLm5vQ29uZmxpY3QoKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgcm9vdC5fID0gb2xkRGFzaDtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgbm8tb3BlcmF0aW9uIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdW5kZWZpbmVkYCByZWdhcmRsZXNzIG9mIHRoZVxuICAgICAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gICAgICpcbiAgICAgKiBfLm5vb3Aob2JqZWN0KSA9PT0gdW5kZWZpbmVkO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub29wKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBhdCBgcGF0aGAgb24gYVxuICAgICAqIGdpdmVuIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICAgICAqICAgeyAnYSc6IHsgJ2InOiB7ICdjJzogMSB9IH0gfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLm1hcChvYmplY3RzLCBfLnByb3BlcnR5KCdhLmIuYycpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ucGx1Y2soXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYicsICdjJ10pKSwgJ2EuYi5jJyk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHkocGF0aCkge1xuICAgICAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHBhdGgpIDogYmFzZVByb3BlcnR5RGVlcChwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucHJvcGVydHlgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zXG4gICAgICogdGhlIHByb3BlcnR5IHZhbHVlIGF0IGEgZ2l2ZW4gcGF0aCBvbiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMCwgMSwgMl0sXG4gICAgICogICAgIG9iamVjdCA9IHsgJ2EnOiBhcnJheSwgJ2InOiBhcnJheSwgJ2MnOiBhcnJheSB9O1xuICAgICAqXG4gICAgICogXy5tYXAoWydhWzJdJywgJ2NbMF0nXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLnByb3BlcnR5T2Yob2JqZWN0KSk7XG4gICAgICogLy8gPT4gWzIsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHlPZihvYmplY3QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgdG9QYXRoKHBhdGgpLCBwYXRoICsgJycpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG51bWJlcnMgKHBvc2l0aXZlIGFuZC9vciBuZWdhdGl2ZSkgcHJvZ3Jlc3NpbmcgZnJvbVxuICAgICAqIGBzdGFydGAgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gSWYgYGVuZGAgaXMgbm90IHNwZWNpZmllZCBpdCBpc1xuICAgICAqIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuIElmIGBlbmRgIGlzIGxlc3MgdGhhbiBgc3RhcnRgXG4gICAgICogYSB6ZXJvLWxlbmd0aCByYW5nZSBpcyBjcmVhdGVkIHVubGVzcyBhIG5lZ2F0aXZlIGBzdGVwYCBpcyBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0xXSBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBudW1iZXJzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDQpO1xuICAgICAqIC8vID0+IFswLCAxLCAyLCAzXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCwgMjAsIDUpO1xuICAgICAqIC8vID0+IFswLCA1LCAxMCwgMTVdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIC00LCAtMSk7XG4gICAgICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXApIHtcbiAgICAgIGlmIChzdGVwICYmIGlzSXRlcmF0ZWVDYWxsKHN0YXJ0LCBlbmQsIHN0ZXApKSB7XG4gICAgICAgIGVuZCA9IHN0ZXAgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBzdGFydCA9ICtzdGFydCB8fCAwO1xuICAgICAgc3RlcCA9IHN0ZXAgPT0gbnVsbCA/IDEgOiAoK3N0ZXAgfHwgMCk7XG5cbiAgICAgIGlmIChlbmQgPT0gbnVsbCkge1xuICAgICAgICBlbmQgPSBzdGFydDtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5kID0gK2VuZCB8fCAwO1xuICAgICAgfVxuICAgICAgLy8gVXNlIGBBcnJheShsZW5ndGgpYCBzbyBlbmdpbmVzIGxpa2UgQ2hha3JhIGFuZCBWOCBhdm9pZCBzbG93ZXIgbW9kZXMuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly95b3V0dS5iZS9YQXFJcEdVOFpaayN0PTE3bTI1cyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KG5hdGl2ZUNlaWwoKGVuZCAtIHN0YXJ0KSAvIChzdGVwIHx8IDEpKSwgMCksXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IHN0YXJ0O1xuICAgICAgICBzdGFydCArPSBzdGVwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBpdGVyYXRlZSBmdW5jdGlvbiBgbmAgdGltZXMsIHJldHVybmluZyBhbiBhcnJheSBvZiB0aGUgcmVzdWx0c1xuICAgICAqIG9mIGVhY2ggaW52b2NhdGlvbi4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGhcbiAgICAgKiBvbmUgYXJndW1lbnQ7IChpbmRleCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbGl0eVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gaW52b2tlIGBpdGVyYXRlZWAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZGljZVJvbGxzID0gXy50aW1lcygzLCBfLnBhcnRpYWwoXy5yYW5kb20sIDEsIDYsIGZhbHNlKSk7XG4gICAgICogLy8gPT4gWzMsIDYsIDRdXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDMsIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIG1hZ2UuY2FzdFNwZWxsKG4pO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IGludm9rZXMgYG1hZ2UuY2FzdFNwZWxsKG4pYCB0aHJlZSB0aW1lcyB3aXRoIGBuYCBvZiBgMGAsIGAxYCwgYW5kIGAyYFxuICAgICAqXG4gICAgICogXy50aW1lcygzLCBmdW5jdGlvbihuKSB7XG4gICAgICogICB0aGlzLmNhc3Qobik7XG4gICAgICogfSwgbWFnZSk7XG4gICAgICogLy8gPT4gYWxzbyBpbnZva2VzIGBtYWdlLmNhc3RTcGVsbChuKWAgdGhyZWUgdGltZXNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aW1lcyhuLCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgbiA9IG5hdGl2ZUZsb29yKG4pO1xuXG4gICAgICAvLyBFeGl0IGVhcmx5IHRvIGF2b2lkIGEgSlNDIEpJVCBidWcgaW4gU2FmYXJpIDhcbiAgICAgIC8vIHdoZXJlIGBBcnJheSgwKWAgaXMgdHJlYXRlZCBhcyBgQXJyYXkoMSlgLlxuICAgICAgaWYgKG4gPCAxIHx8ICFuYXRpdmVJc0Zpbml0ZShuKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCkpO1xuXG4gICAgICBpdGVyYXRlZSA9IGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMSk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG4pIHtcbiAgICAgICAgaWYgKGluZGV4IDwgTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgICAgICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlcmF0ZWUoaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBJRC4gSWYgYHByZWZpeGAgaXMgcHJvdmlkZWQgdGhlIElEIGlzIGFwcGVuZGVkIHRvIGl0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxpdHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ByZWZpeF0gVGhlIHZhbHVlIHRvIHByZWZpeCB0aGUgSUQgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmlxdWUgSUQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoJ2NvbnRhY3RfJyk7XG4gICAgICogLy8gPT4gJ2NvbnRhY3RfMTA0J1xuICAgICAqXG4gICAgICogXy51bmlxdWVJZCgpO1xuICAgICAqIC8vID0+ICcxMDUnXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcXVlSWQocHJlZml4KSB7XG4gICAgICB2YXIgaWQgPSArK2lkQ291bnRlcjtcbiAgICAgIHJldHVybiBiYXNlVG9TdHJpbmcocHJlZml4KSArIGlkO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhdWdlbmQgVGhlIGZpcnN0IG51bWJlciB0byBhZGQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGFkZGVuZCBUaGUgc2Vjb25kIG51bWJlciB0byBhZGQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmFkZCg2LCA0KTtcbiAgICAgKiAvLyA9PiAxMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZChhdWdlbmQsIGFkZGVuZCkge1xuICAgICAgcmV0dXJuICgrYXVnZW5kIHx8IDApICsgKCthZGRlbmQgfHwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyBgbmAgcm91bmRlZCB1cCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciB0byByb3VuZCB1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHVwIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgdXAgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNC4wMDYpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg2LjAwNCwgMik7XG4gICAgICogLy8gPT4gNi4wMVxuICAgICAqXG4gICAgICogXy5jZWlsKDYwNDAsIC0yKTtcbiAgICAgKiAvLyA9PiA2MTAwXG4gICAgICovXG4gICAgdmFyIGNlaWwgPSBjcmVhdGVSb3VuZCgnY2VpbCcpO1xuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyBgbmAgcm91bmRlZCBkb3duIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIHRvIHJvdW5kIGRvd24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb249MF0gVGhlIHByZWNpc2lvbiB0byByb3VuZCBkb3duIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgZG93biBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoMC4wNDYsIDIpO1xuICAgICAqIC8vID0+IDAuMDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQwMDBcbiAgICAgKi9cbiAgICB2YXIgZmxvb3IgPSBjcmVhdGVSb3VuZCgnZmxvb3InKTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG1heGltdW0gdmFsdWUgb2YgYGNvbGxlY3Rpb25gLiBJZiBgY29sbGVjdGlvbmAgaXMgZW1wdHkgb3IgZmFsc2V5XG4gICAgICogYC1JbmZpbml0eWAgaXMgcmV0dXJuZWQuIElmIGFuIGl0ZXJhdGVlIGZ1bmN0aW9uIGlzIHByb3ZpZGVkIGl0IGlzIGludm9rZWRcbiAgICAgKiBmb3IgZWFjaCB2YWx1ZSBpbiBgY29sbGVjdGlvbmAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaCB0aGUgdmFsdWVcbiAgICAgKiBpcyByYW5rZWQuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tYXgoWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiA4XG4gICAgICpcbiAgICAgKiBfLm1heChbXSk7XG4gICAgICogLy8gPT4gLUluZmluaXR5XG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLm1heCh1c2VycywgZnVuY3Rpb24oY2hyKSB7XG4gICAgICogICByZXR1cm4gY2hyLmFnZTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfVxuICAgICAqXG4gICAgICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAgICAgKiBfLm1heCh1c2VycywgJ2FnZScpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XG4gICAgICovXG4gICAgdmFyIG1heCA9IGNyZWF0ZUV4dHJlbXVtKGd0LCBORUdBVElWRV9JTkZJTklUWSk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIGBjb2xsZWN0aW9uYC4gSWYgYGNvbGxlY3Rpb25gIGlzIGVtcHR5IG9yIGZhbHNleVxuICAgICAqIGBJbmZpbml0eWAgaXMgcmV0dXJuZWQuIElmIGFuIGl0ZXJhdGVlIGZ1bmN0aW9uIGlzIHByb3ZpZGVkIGl0IGlzIGludm9rZWRcbiAgICAgKiBmb3IgZWFjaCB2YWx1ZSBpbiBgY29sbGVjdGlvbmAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaCB0aGUgdmFsdWVcbiAgICAgKiBpcyByYW5rZWQuIFRoZSBgaXRlcmF0ZWVgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAgICAgKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAgICAgKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gICAgICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5taW4oWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiBfLm1pbihbXSk7XG4gICAgICogLy8gPT4gSW5maW5pdHlcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWluKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAgICAgKiAgIHJldHVybiBjaHIuYWdlO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH1cbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5taW4odXNlcnMsICdhZ2UnKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICovXG4gICAgdmFyIG1pbiA9IGNyZWF0ZUV4dHJlbXVtKGx0LCBQT1NJVElWRV9JTkZJTklUWSk7XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIGBuYCByb3VuZGVkIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIHRvIHJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcHJlY2lzaW9uPTBdIFRoZSBwcmVjaXNpb24gdG8gcm91bmQgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYsIDIpO1xuICAgICAqIC8vID0+IDQuMDFcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQxMDBcbiAgICAgKi9cbiAgICB2YXIgcm91bmQgPSBjcmVhdGVSb3VuZCgncm91bmQnKTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHN1bSBvZiB0aGUgdmFsdWVzIGluIGBjb2xsZWN0aW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3VtKFs0LCA2XSk7XG4gICAgICogLy8gPT4gMTBcbiAgICAgKlxuICAgICAqIF8uc3VtKHsgJ2EnOiA0LCAnYic6IDYgfSk7XG4gICAgICogLy8gPT4gMTBcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnbic6IDQgfSxcbiAgICAgKiAgIHsgJ24nOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5zdW0ob2JqZWN0cywgZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICogICByZXR1cm4gb2JqZWN0Lm47XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gMTBcbiAgICAgKlxuICAgICAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gICAgICogXy5zdW0ob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiAxMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bShjb2xsZWN0aW9uLCBpdGVyYXRlZSwgdGhpc0FyZykge1xuICAgICAgaWYgKHRoaXNBcmcgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpKSB7XG4gICAgICAgIGl0ZXJhdGVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaXRlcmF0ZWUgPSBnZXRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gICAgICByZXR1cm4gaXRlcmF0ZWUubGVuZ3RoID09IDFcbiAgICAgICAgPyBhcnJheVN1bShpc0FycmF5KGNvbGxlY3Rpb24pID8gY29sbGVjdGlvbiA6IHRvSXRlcmFibGUoY29sbGVjdGlvbiksIGl0ZXJhdGVlKVxuICAgICAgICA6IGJhc2VTdW0oY29sbGVjdGlvbiwgaXRlcmF0ZWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbiAgICBsb2Rhc2gucHJvdG90eXBlID0gYmFzZUxvZGFzaC5wcm90b3R5cGU7XG5cbiAgICBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuICAgIExvZGFzaFdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTG9kYXNoV3JhcHBlcjtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG4gICAgLy8gQWRkIGZ1bmN0aW9ucyB0byB0aGUgYE1hcGAgY2FjaGUuXG4gICAgTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcERlbGV0ZTtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwR2V0O1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBIYXM7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcFNldDtcblxuICAgIC8vIEFkZCBmdW5jdGlvbnMgdG8gdGhlIGBTZXRgIGNhY2hlLlxuICAgIFNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gY2FjaGVQdXNoO1xuXG4gICAgLy8gQXNzaWduIGNhY2hlIHRvIGBfLm1lbW9pemVgLlxuICAgIG1lbW9pemUuQ2FjaGUgPSBNYXBDYWNoZTtcblxuICAgIC8vIEFkZCBmdW5jdGlvbnMgdGhhdCByZXR1cm4gd3JhcHBlZCB2YWx1ZXMgd2hlbiBjaGFpbmluZy5cbiAgICBsb2Rhc2guYWZ0ZXIgPSBhZnRlcjtcbiAgICBsb2Rhc2guYXJ5ID0gYXJ5O1xuICAgIGxvZGFzaC5hc3NpZ24gPSBhc3NpZ247XG4gICAgbG9kYXNoLmF0ID0gYXQ7XG4gICAgbG9kYXNoLmJlZm9yZSA9IGJlZm9yZTtcbiAgICBsb2Rhc2guYmluZCA9IGJpbmQ7XG4gICAgbG9kYXNoLmJpbmRBbGwgPSBiaW5kQWxsO1xuICAgIGxvZGFzaC5iaW5kS2V5ID0gYmluZEtleTtcbiAgICBsb2Rhc2guY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICBsb2Rhc2guY2hhaW4gPSBjaGFpbjtcbiAgICBsb2Rhc2guY2h1bmsgPSBjaHVuaztcbiAgICBsb2Rhc2guY29tcGFjdCA9IGNvbXBhY3Q7XG4gICAgbG9kYXNoLmNvbnN0YW50ID0gY29uc3RhbnQ7XG4gICAgbG9kYXNoLmNvdW50QnkgPSBjb3VudEJ5O1xuICAgIGxvZGFzaC5jcmVhdGUgPSBjcmVhdGU7XG4gICAgbG9kYXNoLmN1cnJ5ID0gY3Vycnk7XG4gICAgbG9kYXNoLmN1cnJ5UmlnaHQgPSBjdXJyeVJpZ2h0O1xuICAgIGxvZGFzaC5kZWJvdW5jZSA9IGRlYm91bmNlO1xuICAgIGxvZGFzaC5kZWZhdWx0cyA9IGRlZmF1bHRzO1xuICAgIGxvZGFzaC5kZWZhdWx0c0RlZXAgPSBkZWZhdWx0c0RlZXA7XG4gICAgbG9kYXNoLmRlZmVyID0gZGVmZXI7XG4gICAgbG9kYXNoLmRlbGF5ID0gZGVsYXk7XG4gICAgbG9kYXNoLmRpZmZlcmVuY2UgPSBkaWZmZXJlbmNlO1xuICAgIGxvZGFzaC5kcm9wID0gZHJvcDtcbiAgICBsb2Rhc2guZHJvcFJpZ2h0ID0gZHJvcFJpZ2h0O1xuICAgIGxvZGFzaC5kcm9wUmlnaHRXaGlsZSA9IGRyb3BSaWdodFdoaWxlO1xuICAgIGxvZGFzaC5kcm9wV2hpbGUgPSBkcm9wV2hpbGU7XG4gICAgbG9kYXNoLmZpbGwgPSBmaWxsO1xuICAgIGxvZGFzaC5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgbG9kYXNoLmZsYXR0ZW4gPSBmbGF0dGVuO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVlcCA9IGZsYXR0ZW5EZWVwO1xuICAgIGxvZGFzaC5mbG93ID0gZmxvdztcbiAgICBsb2Rhc2guZmxvd1JpZ2h0ID0gZmxvd1JpZ2h0O1xuICAgIGxvZGFzaC5mb3JFYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZm9yRWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5mb3JJbiA9IGZvckluO1xuICAgIGxvZGFzaC5mb3JJblJpZ2h0ID0gZm9ySW5SaWdodDtcbiAgICBsb2Rhc2guZm9yT3duID0gZm9yT3duO1xuICAgIGxvZGFzaC5mb3JPd25SaWdodCA9IGZvck93blJpZ2h0O1xuICAgIGxvZGFzaC5mdW5jdGlvbnMgPSBmdW5jdGlvbnM7XG4gICAgbG9kYXNoLmdyb3VwQnkgPSBncm91cEJ5O1xuICAgIGxvZGFzaC5pbmRleEJ5ID0gaW5kZXhCeTtcbiAgICBsb2Rhc2guaW5pdGlhbCA9IGluaXRpYWw7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbjtcbiAgICBsb2Rhc2guaW52ZXJ0ID0gaW52ZXJ0O1xuICAgIGxvZGFzaC5pbnZva2UgPSBpbnZva2U7XG4gICAgbG9kYXNoLmtleXMgPSBrZXlzO1xuICAgIGxvZGFzaC5rZXlzSW4gPSBrZXlzSW47XG4gICAgbG9kYXNoLm1hcCA9IG1hcDtcbiAgICBsb2Rhc2gubWFwS2V5cyA9IG1hcEtleXM7XG4gICAgbG9kYXNoLm1hcFZhbHVlcyA9IG1hcFZhbHVlcztcbiAgICBsb2Rhc2gubWF0Y2hlcyA9IG1hdGNoZXM7XG4gICAgbG9kYXNoLm1hdGNoZXNQcm9wZXJ0eSA9IG1hdGNoZXNQcm9wZXJ0eTtcbiAgICBsb2Rhc2gubWVtb2l6ZSA9IG1lbW9pemU7XG4gICAgbG9kYXNoLm1lcmdlID0gbWVyZ2U7XG4gICAgbG9kYXNoLm1ldGhvZCA9IG1ldGhvZDtcbiAgICBsb2Rhc2gubWV0aG9kT2YgPSBtZXRob2RPZjtcbiAgICBsb2Rhc2gubWl4aW4gPSBtaXhpbjtcbiAgICBsb2Rhc2gubW9kQXJncyA9IG1vZEFyZ3M7XG4gICAgbG9kYXNoLm5lZ2F0ZSA9IG5lZ2F0ZTtcbiAgICBsb2Rhc2gub21pdCA9IG9taXQ7XG4gICAgbG9kYXNoLm9uY2UgPSBvbmNlO1xuICAgIGxvZGFzaC5wYWlycyA9IHBhaXJzO1xuICAgIGxvZGFzaC5wYXJ0aWFsID0gcGFydGlhbDtcbiAgICBsb2Rhc2gucGFydGlhbFJpZ2h0ID0gcGFydGlhbFJpZ2h0O1xuICAgIGxvZGFzaC5wYXJ0aXRpb24gPSBwYXJ0aXRpb247XG4gICAgbG9kYXNoLnBpY2sgPSBwaWNrO1xuICAgIGxvZGFzaC5wbHVjayA9IHBsdWNrO1xuICAgIGxvZGFzaC5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgIGxvZGFzaC5wcm9wZXJ0eU9mID0gcHJvcGVydHlPZjtcbiAgICBsb2Rhc2gucHVsbCA9IHB1bGw7XG4gICAgbG9kYXNoLnB1bGxBdCA9IHB1bGxBdDtcbiAgICBsb2Rhc2gucmFuZ2UgPSByYW5nZTtcbiAgICBsb2Rhc2gucmVhcmcgPSByZWFyZztcbiAgICBsb2Rhc2gucmVqZWN0ID0gcmVqZWN0O1xuICAgIGxvZGFzaC5yZW1vdmUgPSByZW1vdmU7XG4gICAgbG9kYXNoLnJlc3QgPSByZXN0O1xuICAgIGxvZGFzaC5yZXN0UGFyYW0gPSByZXN0UGFyYW07XG4gICAgbG9kYXNoLnNldCA9IHNldDtcbiAgICBsb2Rhc2guc2h1ZmZsZSA9IHNodWZmbGU7XG4gICAgbG9kYXNoLnNsaWNlID0gc2xpY2U7XG4gICAgbG9kYXNoLnNvcnRCeSA9IHNvcnRCeTtcbiAgICBsb2Rhc2guc29ydEJ5QWxsID0gc29ydEJ5QWxsO1xuICAgIGxvZGFzaC5zb3J0QnlPcmRlciA9IHNvcnRCeU9yZGVyO1xuICAgIGxvZGFzaC5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgbG9kYXNoLnRha2UgPSB0YWtlO1xuICAgIGxvZGFzaC50YWtlUmlnaHQgPSB0YWtlUmlnaHQ7XG4gICAgbG9kYXNoLnRha2VSaWdodFdoaWxlID0gdGFrZVJpZ2h0V2hpbGU7XG4gICAgbG9kYXNoLnRha2VXaGlsZSA9IHRha2VXaGlsZTtcbiAgICBsb2Rhc2gudGFwID0gdGFwO1xuICAgIGxvZGFzaC50aHJvdHRsZSA9IHRocm90dGxlO1xuICAgIGxvZGFzaC50aHJ1ID0gdGhydTtcbiAgICBsb2Rhc2gudGltZXMgPSB0aW1lcztcbiAgICBsb2Rhc2gudG9BcnJheSA9IHRvQXJyYXk7XG4gICAgbG9kYXNoLnRvUGxhaW5PYmplY3QgPSB0b1BsYWluT2JqZWN0O1xuICAgIGxvZGFzaC50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgbG9kYXNoLnVuaW9uID0gdW5pb247XG4gICAgbG9kYXNoLnVuaXEgPSB1bmlxO1xuICAgIGxvZGFzaC51bnppcCA9IHVuemlwO1xuICAgIGxvZGFzaC51bnppcFdpdGggPSB1bnppcFdpdGg7XG4gICAgbG9kYXNoLnZhbHVlcyA9IHZhbHVlcztcbiAgICBsb2Rhc2gudmFsdWVzSW4gPSB2YWx1ZXNJbjtcbiAgICBsb2Rhc2gud2hlcmUgPSB3aGVyZTtcbiAgICBsb2Rhc2gud2l0aG91dCA9IHdpdGhvdXQ7XG4gICAgbG9kYXNoLndyYXAgPSB3cmFwO1xuICAgIGxvZGFzaC54b3IgPSB4b3I7XG4gICAgbG9kYXNoLnppcCA9IHppcDtcbiAgICBsb2Rhc2guemlwT2JqZWN0ID0gemlwT2JqZWN0O1xuICAgIGxvZGFzaC56aXBXaXRoID0gemlwV2l0aDtcblxuICAgIC8vIEFkZCBhbGlhc2VzLlxuICAgIGxvZGFzaC5iYWNrZmxvdyA9IGZsb3dSaWdodDtcbiAgICBsb2Rhc2guY29sbGVjdCA9IG1hcDtcbiAgICBsb2Rhc2guY29tcG9zZSA9IGZsb3dSaWdodDtcbiAgICBsb2Rhc2guZWFjaCA9IGZvckVhY2g7XG4gICAgbG9kYXNoLmVhY2hSaWdodCA9IGZvckVhY2hSaWdodDtcbiAgICBsb2Rhc2guZXh0ZW5kID0gYXNzaWduO1xuICAgIGxvZGFzaC5pdGVyYXRlZSA9IGNhbGxiYWNrO1xuICAgIGxvZGFzaC5tZXRob2RzID0gZnVuY3Rpb25zO1xuICAgIGxvZGFzaC5vYmplY3QgPSB6aXBPYmplY3Q7XG4gICAgbG9kYXNoLnNlbGVjdCA9IGZpbHRlcjtcbiAgICBsb2Rhc2gudGFpbCA9IHJlc3Q7XG4gICAgbG9kYXNoLnVuaXF1ZSA9IHVuaXE7XG5cbiAgICAvLyBBZGQgZnVuY3Rpb25zIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBtaXhpbihsb2Rhc2gsIGxvZGFzaCk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvLyBBZGQgZnVuY3Rpb25zIHRoYXQgcmV0dXJuIHVud3JhcHBlZCB2YWx1ZXMgd2hlbiBjaGFpbmluZy5cbiAgICBsb2Rhc2guYWRkID0gYWRkO1xuICAgIGxvZGFzaC5hdHRlbXB0ID0gYXR0ZW1wdDtcbiAgICBsb2Rhc2guY2FtZWxDYXNlID0gY2FtZWxDYXNlO1xuICAgIGxvZGFzaC5jYXBpdGFsaXplID0gY2FwaXRhbGl6ZTtcbiAgICBsb2Rhc2guY2VpbCA9IGNlaWw7XG4gICAgbG9kYXNoLmNsb25lID0gY2xvbmU7XG4gICAgbG9kYXNoLmNsb25lRGVlcCA9IGNsb25lRGVlcDtcbiAgICBsb2Rhc2guZGVidXJyID0gZGVidXJyO1xuICAgIGxvZGFzaC5lbmRzV2l0aCA9IGVuZHNXaXRoO1xuICAgIGxvZGFzaC5lc2NhcGUgPSBlc2NhcGU7XG4gICAgbG9kYXNoLmVzY2FwZVJlZ0V4cCA9IGVzY2FwZVJlZ0V4cDtcbiAgICBsb2Rhc2guZXZlcnkgPSBldmVyeTtcbiAgICBsb2Rhc2guZmluZCA9IGZpbmQ7XG4gICAgbG9kYXNoLmZpbmRJbmRleCA9IGZpbmRJbmRleDtcbiAgICBsb2Rhc2guZmluZEtleSA9IGZpbmRLZXk7XG4gICAgbG9kYXNoLmZpbmRMYXN0ID0gZmluZExhc3Q7XG4gICAgbG9kYXNoLmZpbmRMYXN0SW5kZXggPSBmaW5kTGFzdEluZGV4O1xuICAgIGxvZGFzaC5maW5kTGFzdEtleSA9IGZpbmRMYXN0S2V5O1xuICAgIGxvZGFzaC5maW5kV2hlcmUgPSBmaW5kV2hlcmU7XG4gICAgbG9kYXNoLmZpcnN0ID0gZmlyc3Q7XG4gICAgbG9kYXNoLmZsb29yID0gZmxvb3I7XG4gICAgbG9kYXNoLmdldCA9IGdldDtcbiAgICBsb2Rhc2guZ3QgPSBndDtcbiAgICBsb2Rhc2guZ3RlID0gZ3RlO1xuICAgIGxvZGFzaC5oYXMgPSBoYXM7XG4gICAgbG9kYXNoLmlkZW50aXR5ID0gaWRlbnRpdHk7XG4gICAgbG9kYXNoLmluY2x1ZGVzID0gaW5jbHVkZXM7XG4gICAgbG9kYXNoLmluZGV4T2YgPSBpbmRleE9mO1xuICAgIGxvZGFzaC5pblJhbmdlID0gaW5SYW5nZTtcbiAgICBsb2Rhc2guaXNBcmd1bWVudHMgPSBpc0FyZ3VtZW50cztcbiAgICBsb2Rhc2guaXNBcnJheSA9IGlzQXJyYXk7XG4gICAgbG9kYXNoLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcbiAgICBsb2Rhc2guaXNEYXRlID0gaXNEYXRlO1xuICAgIGxvZGFzaC5pc0VsZW1lbnQgPSBpc0VsZW1lbnQ7XG4gICAgbG9kYXNoLmlzRW1wdHkgPSBpc0VtcHR5O1xuICAgIGxvZGFzaC5pc0VxdWFsID0gaXNFcXVhbDtcbiAgICBsb2Rhc2guaXNFcnJvciA9IGlzRXJyb3I7XG4gICAgbG9kYXNoLmlzRmluaXRlID0gaXNGaW5pdGU7XG4gICAgbG9kYXNoLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuICAgIGxvZGFzaC5pc01hdGNoID0gaXNNYXRjaDtcbiAgICBsb2Rhc2guaXNOYU4gPSBpc05hTjtcbiAgICBsb2Rhc2guaXNOYXRpdmUgPSBpc05hdGl2ZTtcbiAgICBsb2Rhc2guaXNOdWxsID0gaXNOdWxsO1xuICAgIGxvZGFzaC5pc051bWJlciA9IGlzTnVtYmVyO1xuICAgIGxvZGFzaC5pc09iamVjdCA9IGlzT2JqZWN0O1xuICAgIGxvZGFzaC5pc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdDtcbiAgICBsb2Rhc2guaXNSZWdFeHAgPSBpc1JlZ0V4cDtcbiAgICBsb2Rhc2guaXNTdHJpbmcgPSBpc1N0cmluZztcbiAgICBsb2Rhc2guaXNUeXBlZEFycmF5ID0gaXNUeXBlZEFycmF5O1xuICAgIGxvZGFzaC5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuICAgIGxvZGFzaC5rZWJhYkNhc2UgPSBrZWJhYkNhc2U7XG4gICAgbG9kYXNoLmxhc3QgPSBsYXN0O1xuICAgIGxvZGFzaC5sYXN0SW5kZXhPZiA9IGxhc3RJbmRleE9mO1xuICAgIGxvZGFzaC5sdCA9IGx0O1xuICAgIGxvZGFzaC5sdGUgPSBsdGU7XG4gICAgbG9kYXNoLm1heCA9IG1heDtcbiAgICBsb2Rhc2gubWluID0gbWluO1xuICAgIGxvZGFzaC5ub0NvbmZsaWN0ID0gbm9Db25mbGljdDtcbiAgICBsb2Rhc2gubm9vcCA9IG5vb3A7XG4gICAgbG9kYXNoLm5vdyA9IG5vdztcbiAgICBsb2Rhc2gucGFkID0gcGFkO1xuICAgIGxvZGFzaC5wYWRMZWZ0ID0gcGFkTGVmdDtcbiAgICBsb2Rhc2gucGFkUmlnaHQgPSBwYWRSaWdodDtcbiAgICBsb2Rhc2gucGFyc2VJbnQgPSBwYXJzZUludDtcbiAgICBsb2Rhc2gucmFuZG9tID0gcmFuZG9tO1xuICAgIGxvZGFzaC5yZWR1Y2UgPSByZWR1Y2U7XG4gICAgbG9kYXNoLnJlZHVjZVJpZ2h0ID0gcmVkdWNlUmlnaHQ7XG4gICAgbG9kYXNoLnJlcGVhdCA9IHJlcGVhdDtcbiAgICBsb2Rhc2gucmVzdWx0ID0gcmVzdWx0O1xuICAgIGxvZGFzaC5yb3VuZCA9IHJvdW5kO1xuICAgIGxvZGFzaC5ydW5JbkNvbnRleHQgPSBydW5JbkNvbnRleHQ7XG4gICAgbG9kYXNoLnNpemUgPSBzaXplO1xuICAgIGxvZGFzaC5zbmFrZUNhc2UgPSBzbmFrZUNhc2U7XG4gICAgbG9kYXNoLnNvbWUgPSBzb21lO1xuICAgIGxvZGFzaC5zb3J0ZWRJbmRleCA9IHNvcnRlZEluZGV4O1xuICAgIGxvZGFzaC5zb3J0ZWRMYXN0SW5kZXggPSBzb3J0ZWRMYXN0SW5kZXg7XG4gICAgbG9kYXNoLnN0YXJ0Q2FzZSA9IHN0YXJ0Q2FzZTtcbiAgICBsb2Rhc2guc3RhcnRzV2l0aCA9IHN0YXJ0c1dpdGg7XG4gICAgbG9kYXNoLnN1bSA9IHN1bTtcbiAgICBsb2Rhc2gudGVtcGxhdGUgPSB0ZW1wbGF0ZTtcbiAgICBsb2Rhc2gudHJpbSA9IHRyaW07XG4gICAgbG9kYXNoLnRyaW1MZWZ0ID0gdHJpbUxlZnQ7XG4gICAgbG9kYXNoLnRyaW1SaWdodCA9IHRyaW1SaWdodDtcbiAgICBsb2Rhc2gudHJ1bmMgPSB0cnVuYztcbiAgICBsb2Rhc2gudW5lc2NhcGUgPSB1bmVzY2FwZTtcbiAgICBsb2Rhc2gudW5pcXVlSWQgPSB1bmlxdWVJZDtcbiAgICBsb2Rhc2gud29yZHMgPSB3b3JkcztcblxuICAgIC8vIEFkZCBhbGlhc2VzLlxuICAgIGxvZGFzaC5hbGwgPSBldmVyeTtcbiAgICBsb2Rhc2guYW55ID0gc29tZTtcbiAgICBsb2Rhc2guY29udGFpbnMgPSBpbmNsdWRlcztcbiAgICBsb2Rhc2guZXEgPSBpc0VxdWFsO1xuICAgIGxvZGFzaC5kZXRlY3QgPSBmaW5kO1xuICAgIGxvZGFzaC5mb2xkbCA9IHJlZHVjZTtcbiAgICBsb2Rhc2guZm9sZHIgPSByZWR1Y2VSaWdodDtcbiAgICBsb2Rhc2guaGVhZCA9IGZpcnN0O1xuICAgIGxvZGFzaC5pbmNsdWRlID0gaW5jbHVkZXM7XG4gICAgbG9kYXNoLmluamVjdCA9IHJlZHVjZTtcblxuICAgIG1peGluKGxvZGFzaCwgKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHNvdXJjZSA9IHt9O1xuICAgICAgYmFzZUZvck93bihsb2Rhc2gsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgICAgaWYgKCFsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdKSB7XG4gICAgICAgICAgc291cmNlW21ldGhvZE5hbWVdID0gZnVuYztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH0oKSksIGZhbHNlKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIEFkZCBmdW5jdGlvbnMgY2FwYWJsZSBvZiByZXR1cm5pbmcgd3JhcHBlZCBhbmQgdW53cmFwcGVkIHZhbHVlcyB3aGVuIGNoYWluaW5nLlxuICAgIGxvZGFzaC5zYW1wbGUgPSBzYW1wbGU7XG5cbiAgICBsb2Rhc2gucHJvdG90eXBlLnNhbXBsZSA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgIGlmICghdGhpcy5fX2NoYWluX18gJiYgbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBzYW1wbGUodGhpcy52YWx1ZSgpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnRocnUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHNhbXBsZSh2YWx1ZSwgbik7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUgc3RyaW5nXG4gICAgICovXG4gICAgbG9kYXNoLlZFUlNJT04gPSBWRVJTSU9OO1xuXG4gICAgLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuICAgIGFycmF5RWFjaChbJ2JpbmQnLCAnYmluZEtleScsICdjdXJyeScsICdjdXJyeVJpZ2h0JywgJ3BhcnRpYWwnLCAncGFydGlhbFJpZ2h0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgIGxvZGFzaFttZXRob2ROYW1lXS5wbGFjZWhvbGRlciA9IGxvZGFzaDtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgZm9yIGBfLmRyb3BgIGFuZCBgXy50YWtlYCB2YXJpYW50cy5cbiAgICBhcnJheUVhY2goWydkcm9wJywgJ3Rha2UnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgdmFyIGZpbHRlcmVkID0gdGhpcy5fX2ZpbHRlcmVkX187XG4gICAgICAgIGlmIChmaWx0ZXJlZCAmJiAhaW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIG4gPSBuID09IG51bGwgPyAxIDogbmF0aXZlTWF4KG5hdGl2ZUZsb29yKG4pIHx8IDAsIDApO1xuXG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLmNsb25lKCk7XG4gICAgICAgIGlmIChmaWx0ZXJlZCkge1xuICAgICAgICAgIHJlc3VsdC5fX3Rha2VDb3VudF9fID0gbmF0aXZlTWluKHJlc3VsdC5fX3Rha2VDb3VudF9fLCBuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQuX192aWV3c19fLnB1c2goeyAnc2l6ZSc6IG4sICd0eXBlJzogbWV0aG9kTmFtZSArIChyZXN1bHQuX19kaXJfXyA8IDAgPyAnUmlnaHQnIDogJycpIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZSArICdSaWdodCddID0gZnVuY3Rpb24obikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKClbbWV0aG9kTmFtZV0obikucmV2ZXJzZSgpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgdGhhdCBhY2NlcHQgYW4gYGl0ZXJhdGVlYCB2YWx1ZS5cbiAgICBhcnJheUVhY2goWydmaWx0ZXInLCAnbWFwJywgJ3Rha2VXaGlsZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIHR5cGUgPSBpbmRleCArIDEsXG4gICAgICAgICAgaXNGaWx0ZXIgPSB0eXBlICE9IExBWllfTUFQX0ZMQUc7XG5cbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLmNsb25lKCk7XG4gICAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fLnB1c2goeyAnaXRlcmF0ZWUnOiBnZXRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMSksICd0eXBlJzogdHlwZSB9KTtcbiAgICAgICAgcmVzdWx0Ll9fZmlsdGVyZWRfXyA9IHJlc3VsdC5fX2ZpbHRlcmVkX18gfHwgaXNGaWx0ZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uZmlyc3RgIGFuZCBgXy5sYXN0YC5cbiAgICBhcnJheUVhY2goWydmaXJzdCcsICdsYXN0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgdGFrZU5hbWUgPSAndGFrZScgKyAoaW5kZXggPyAnUmlnaHQnIDogJycpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGFrZU5hbWVdKDEpLnZhbHVlKClbMF07XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uaW5pdGlhbGAgYW5kIGBfLnJlc3RgLlxuICAgIGFycmF5RWFjaChbJ2luaXRpYWwnLCAncmVzdCddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIGRyb3BOYW1lID0gJ2Ryb3AnICsgKGluZGV4ID8gJycgOiAnUmlnaHQnKTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZmlsdGVyZWRfXyA/IG5ldyBMYXp5V3JhcHBlcih0aGlzKSA6IHRoaXNbZHJvcE5hbWVdKDEpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgZm9yIGBfLnBsdWNrYCBhbmQgYF8ud2hlcmVgLlxuICAgIGFycmF5RWFjaChbJ3BsdWNrJywgJ3doZXJlJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgb3BlcmF0aW9uTmFtZSA9IGluZGV4ID8gJ2ZpbHRlcicgOiAnbWFwJyxcbiAgICAgICAgICBjcmVhdGVDYWxsYmFjayA9IGluZGV4ID8gYmFzZU1hdGNoZXMgOiBwcm9wZXJ0eTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbb3BlcmF0aW9uTmFtZV0oY3JlYXRlQ2FsbGJhY2sodmFsdWUpKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKGlkZW50aXR5KTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnJlamVjdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgcHJlZGljYXRlID0gZ2V0Q2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAxKTtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gIXByZWRpY2F0ZSh2YWx1ZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6ICgrc3RhcnQgfHwgMCk7XG5cbiAgICAgIHZhciByZXN1bHQgPSB0aGlzO1xuICAgICAgaWYgKHJlc3VsdC5fX2ZpbHRlcmVkX18gJiYgKHN0YXJ0ID4gMCB8fCBlbmQgPCAwKSkge1xuICAgICAgICByZXR1cm4gbmV3IExhenlXcmFwcGVyKHJlc3VsdCk7XG4gICAgICB9XG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC50YWtlUmlnaHQoLXN0YXJ0KTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhcnQpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmRyb3Aoc3RhcnQpO1xuICAgICAgfVxuICAgICAgaWYgKGVuZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVuZCA9ICgrZW5kIHx8IDApO1xuICAgICAgICByZXN1bHQgPSBlbmQgPCAwID8gcmVzdWx0LmRyb3BSaWdodCgtZW5kKSA6IHJlc3VsdC50YWtlKGVuZCAtIHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS50YWtlUmlnaHRXaGlsZSA9IGZ1bmN0aW9uKHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLnRha2VXaGlsZShwcmVkaWNhdGUsIHRoaXNBcmcpLnJldmVyc2UoKTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnRha2UoUE9TSVRJVkVfSU5GSU5JVFkpO1xuICAgIH07XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGNoZWNrSXRlcmF0ZWUgPSAvXig/OmZpbHRlcnxtYXB8cmVqZWN0KXxXaGlsZSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgcmV0VW53cmFwcGVkID0gL14oPzpmaXJzdHxsYXN0KSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgbG9kYXNoRnVuYyA9IGxvZGFzaFtyZXRVbndyYXBwZWQgPyAoJ3Rha2UnICsgKG1ldGhvZE5hbWUgPT0gJ2xhc3QnID8gJ1JpZ2h0JyA6ICcnKSkgOiBtZXRob2ROYW1lXTtcblxuICAgICAgaWYgKCFsb2Rhc2hGdW5jKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSByZXRVbndyYXBwZWQgPyBbMV0gOiBhcmd1bWVudHMsXG4gICAgICAgICAgICBjaGFpbkFsbCA9IHRoaXMuX19jaGFpbl9fLFxuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9fd3JhcHBlZF9fLFxuICAgICAgICAgICAgaXNIeWJyaWQgPSAhIXRoaXMuX19hY3Rpb25zX18ubGVuZ3RoLFxuICAgICAgICAgICAgaXNMYXp5ID0gdmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcixcbiAgICAgICAgICAgIGl0ZXJhdGVlID0gYXJnc1swXSxcbiAgICAgICAgICAgIHVzZUxhenkgPSBpc0xhenkgfHwgaXNBcnJheSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKHVzZUxhenkgJiYgY2hlY2tJdGVyYXRlZSAmJiB0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiBpdGVyYXRlZS5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIEF2b2lkIGxhenkgdXNlIGlmIHRoZSBpdGVyYXRlZSBoYXMgYSBcImxlbmd0aFwiIHZhbHVlIG90aGVyIHRoYW4gYDFgLlxuICAgICAgICAgIGlzTGF6eSA9IHVzZUxhenkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW50ZXJjZXB0b3IgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiAocmV0VW53cmFwcGVkICYmIGNoYWluQWxsKVxuICAgICAgICAgICAgPyBsb2Rhc2hGdW5jKHZhbHVlLCAxKVswXVxuICAgICAgICAgICAgOiBsb2Rhc2hGdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJyYXlQdXNoKFt2YWx1ZV0sIGFyZ3MpKTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgYWN0aW9uID0geyAnZnVuYyc6IHRocnUsICdhcmdzJzogW2ludGVyY2VwdG9yXSwgJ3RoaXNBcmcnOiB1bmRlZmluZWQgfSxcbiAgICAgICAgICAgIG9ubHlMYXp5ID0gaXNMYXp5ICYmICFpc0h5YnJpZDtcblxuICAgICAgICBpZiAocmV0VW53cmFwcGVkICYmICFjaGFpbkFsbCkge1xuICAgICAgICAgIGlmIChvbmx5TGF6eSkge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5jbG9uZSgpO1xuICAgICAgICAgICAgdmFsdWUuX19hY3Rpb25zX18ucHVzaChhY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBsb2Rhc2hGdW5jLmNhbGwodW5kZWZpbmVkLCB0aGlzLnZhbHVlKCkpWzBdO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmV0VW53cmFwcGVkICYmIHVzZUxhenkpIHtcbiAgICAgICAgICB2YWx1ZSA9IG9ubHlMYXp5ID8gdmFsdWUgOiBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgICAgICAgIHJlc3VsdC5fX2FjdGlvbnNfXy5wdXNoKGFjdGlvbik7XG4gICAgICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHJlc3VsdCwgY2hhaW5BbGwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnRocnUoaW50ZXJjZXB0b3IpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBhcnJheUVhY2goWydqb2luJywgJ3BvcCcsICdwdXNoJywgJ3JlcGxhY2UnLCAnc2hpZnQnLCAnc29ydCcsICdzcGxpY2UnLCAnc3BsaXQnLCAndW5zaGlmdCddLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9ICgvXig/OnJlcGxhY2V8c3BsaXQpJC8udGVzdChtZXRob2ROYW1lKSA/IHN0cmluZ1Byb3RvIDogYXJyYXlQcm90bylbbWV0aG9kTmFtZV0sXG4gICAgICAgICAgY2hhaW5OYW1lID0gL14oPzpwdXNofHNvcnR8dW5zaGlmdCkkLy50ZXN0KG1ldGhvZE5hbWUpID8gJ3RhcCcgOiAndGhydScsXG4gICAgICAgICAgcmV0VW53cmFwcGVkID0gL14oPzpqb2lufHBvcHxyZXBsYWNlfHNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGlmIChyZXRVbndyYXBwZWQgJiYgIXRoaXMuX19jaGFpbl9fKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcy52YWx1ZSgpLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1tjaGFpbk5hbWVdKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBNYXAgbWluaWZpZWQgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgcmVhbCBuYW1lcy5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGxvZGFzaEZ1bmMgPSBsb2Rhc2hbbWV0aG9kTmFtZV07XG4gICAgICBpZiAobG9kYXNoRnVuYykge1xuICAgICAgICB2YXIga2V5ID0gbG9kYXNoRnVuYy5uYW1lLFxuICAgICAgICAgICAgbmFtZXMgPSByZWFsTmFtZXNba2V5XSB8fCAocmVhbE5hbWVzW2tleV0gPSBbXSk7XG5cbiAgICAgICAgbmFtZXMucHVzaCh7ICduYW1lJzogbWV0aG9kTmFtZSwgJ2Z1bmMnOiBsb2Rhc2hGdW5jIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVhbE5hbWVzW2NyZWF0ZUh5YnJpZFdyYXBwZXIodW5kZWZpbmVkLCBCSU5EX0tFWV9GTEFHKS5uYW1lXSA9IFt7ICduYW1lJzogJ3dyYXBwZXInLCAnZnVuYyc6IHVuZGVmaW5lZCB9XTtcblxuICAgIC8vIEFkZCBmdW5jdGlvbnMgdG8gdGhlIGxhenkgd3JhcHBlci5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuY2xvbmUgPSBsYXp5Q2xvbmU7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnJldmVyc2UgPSBsYXp5UmV2ZXJzZTtcbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudmFsdWUgPSBsYXp5VmFsdWU7XG5cbiAgICAvLyBBZGQgY2hhaW5pbmcgZnVuY3Rpb25zIHRvIHRoZSBgbG9kYXNoYCB3cmFwcGVyLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuY2hhaW4gPSB3cmFwcGVyQ2hhaW47XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jb21taXQgPSB3cmFwcGVyQ29tbWl0O1xuICAgIGxvZGFzaC5wcm90b3R5cGUuY29uY2F0ID0gd3JhcHBlckNvbmNhdDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnBsYW50ID0gd3JhcHBlclBsYW50O1xuICAgIGxvZGFzaC5wcm90b3R5cGUucmV2ZXJzZSA9IHdyYXBwZXJSZXZlcnNlO1xuICAgIGxvZGFzaC5wcm90b3R5cGUudG9TdHJpbmcgPSB3cmFwcGVyVG9TdHJpbmc7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5ydW4gPSBsb2Rhc2gucHJvdG90eXBlLnRvSlNPTiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWVPZiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWUgPSB3cmFwcGVyVmFsdWU7XG5cbiAgICAvLyBBZGQgZnVuY3Rpb24gYWxpYXNlcyB0byB0aGUgYGxvZGFzaGAgd3JhcHBlci5cbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbGxlY3QgPSBsb2Rhc2gucHJvdG90eXBlLm1hcDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmhlYWQgPSBsb2Rhc2gucHJvdG90eXBlLmZpcnN0O1xuICAgIGxvZGFzaC5wcm90b3R5cGUuc2VsZWN0ID0gbG9kYXNoLnByb3RvdHlwZS5maWx0ZXI7XG4gICAgbG9kYXNoLnByb3RvdHlwZS50YWlsID0gbG9kYXNoLnByb3RvdHlwZS5yZXN0O1xuXG4gICAgcmV0dXJuIGxvZGFzaDtcbiAgfVxuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBsb2Rhc2guXG4gIHZhciBfID0gcnVuSW5Db250ZXh0KCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycyBsaWtlIHIuanMgY2hlY2sgZm9yIGNvbmRpdGlvbiBwYXR0ZXJucyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBsb2Rhc2ggdG8gdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBhbiBBTUQgbG9hZGVyIGlzIHByZXNlbnQgdG8gYXZvaWRcbiAgICAvLyBlcnJvcnMgaW4gY2FzZXMgd2hlcmUgbG9kYXNoIGlzIGxvYWRlZCBieSBhIHNjcmlwdCB0YWcgYW5kIG5vdCBpbnRlbmRlZFxuICAgIC8vIGFzIGFuIEFNRCBtb2R1bGUuIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvclxuICAgIC8vIG1vcmUgZGV0YWlscy5cbiAgICByb290Ll8gPSBfO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28sIHRocm91Z2ggcGF0aCBtYXBwaW5nLCBpdCBjYW4gYmVcbiAgICAvLyByZWZlcmVuY2VkIGFzIHRoZSBcInVuZGVyc2NvcmVcIiBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgYW4gYGV4cG9ydHNgIG9iamVjdC5cbiAgZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSkge1xuICAgIC8vIEV4cG9ydCBmb3IgTm9kZS5qcyBvciBSaW5nb0pTLlxuICAgIGlmIChtb2R1bGVFeHBvcnRzKSB7XG4gICAgICAoZnJlZU1vZHVsZS5leHBvcnRzID0gXykuXyA9IF87XG4gICAgfVxuICAgIC8vIEV4cG9ydCBmb3IgUmhpbm8gd2l0aCBDb21tb25KUyBzdXBwb3J0LlxuICAgIGVsc2Uge1xuICAgICAgZnJlZUV4cG9ydHMuXyA9IF87XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCBmb3IgYSBicm93c2VyIG9yIFJoaW5vLlxuICAgIHJvb3QuXyA9IF87XG4gIH1cbn0uY2FsbCh0aGlzKSk7XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliJylcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzYXAgPSByZXF1aXJlKCdhc2FwL3JhdycpO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxuLy8gU3RhdGVzOlxuLy9cbi8vIDAgLSBwZW5kaW5nXG4vLyAxIC0gZnVsZmlsbGVkIHdpdGggX3ZhbHVlXG4vLyAyIC0gcmVqZWN0ZWQgd2l0aCBfdmFsdWVcbi8vIDMgLSBhZG9wdGVkIHRoZSBzdGF0ZSBvZiBhbm90aGVyIHByb21pc2UsIF92YWx1ZVxuLy9cbi8vIG9uY2UgdGhlIHN0YXRlIGlzIG5vIGxvbmdlciBwZW5kaW5nICgwKSBpdCBpcyBpbW11dGFibGVcblxuLy8gQWxsIGBfYCBwcmVmaXhlZCBwcm9wZXJ0aWVzIHdpbGwgYmUgcmVkdWNlZCB0byBgX3tyYW5kb20gbnVtYmVyfWBcbi8vIGF0IGJ1aWxkIHRpbWUgdG8gb2JmdXNjYXRlIHRoZW0gYW5kIGRpc2NvdXJhZ2UgdGhlaXIgdXNlLlxuLy8gV2UgZG9uJ3QgdXNlIHN5bWJvbHMgb3IgT2JqZWN0LmRlZmluZVByb3BlcnR5IHRvIGZ1bGx5IGhpZGUgdGhlbVxuLy8gYmVjYXVzZSB0aGUgcGVyZm9ybWFuY2UgaXNuJ3QgZ29vZCBlbm91Z2guXG5cblxuLy8gdG8gYXZvaWQgdXNpbmcgdHJ5L2NhdGNoIGluc2lkZSBjcml0aWNhbCBmdW5jdGlvbnMsIHdlXG4vLyBleHRyYWN0IHRoZW0gdG8gaGVyZS5cbnZhciBMQVNUX0VSUk9SID0gbnVsbDtcbnZhciBJU19FUlJPUiA9IHt9O1xuZnVuY3Rpb24gZ2V0VGhlbihvYmopIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gb2JqLnRoZW47XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgTEFTVF9FUlJPUiA9IGV4O1xuICAgIHJldHVybiBJU19FUlJPUjtcbiAgfVxufVxuXG5mdW5jdGlvbiB0cnlDYWxsT25lKGZuLCBhKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZuKGEpO1xuICB9IGNhdGNoIChleCkge1xuICAgIExBU1RfRVJST1IgPSBleDtcbiAgICByZXR1cm4gSVNfRVJST1I7XG4gIH1cbn1cbmZ1bmN0aW9uIHRyeUNhbGxUd28oZm4sIGEsIGIpIHtcbiAgdHJ5IHtcbiAgICBmbihhLCBiKTtcbiAgfSBjYXRjaCAoZXgpIHtcbiAgICBMQVNUX0VSUk9SID0gZXg7XG4gICAgcmV0dXJuIElTX0VSUk9SO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcblxuZnVuY3Rpb24gUHJvbWlzZShmbikge1xuICBpZiAodHlwZW9mIHRoaXMgIT09ICdvYmplY3QnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvbWlzZXMgbXVzdCBiZSBjb25zdHJ1Y3RlZCB2aWEgbmV3Jyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ25vdCBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdGhpcy5fNDUgPSAwO1xuICB0aGlzLl84MSA9IDA7XG4gIHRoaXMuXzY1ID0gbnVsbDtcbiAgdGhpcy5fNTQgPSBudWxsO1xuICBpZiAoZm4gPT09IG5vb3ApIHJldHVybjtcbiAgZG9SZXNvbHZlKGZuLCB0aGlzKTtcbn1cblByb21pc2UuXzEwID0gbnVsbDtcblByb21pc2UuXzk3ID0gbnVsbDtcblByb21pc2UuXzYxID0gbm9vcDtcblxuUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gIGlmICh0aGlzLmNvbnN0cnVjdG9yICE9PSBQcm9taXNlKSB7XG4gICAgcmV0dXJuIHNhZmVUaGVuKHRoaXMsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKTtcbiAgfVxuICB2YXIgcmVzID0gbmV3IFByb21pc2Uobm9vcCk7XG4gIGhhbmRsZSh0aGlzLCBuZXcgSGFuZGxlcihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcmVzKSk7XG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBzYWZlVGhlbihzZWxmLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICByZXR1cm4gbmV3IHNlbGYuY29uc3RydWN0b3IoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciByZXMgPSBuZXcgUHJvbWlzZShub29wKTtcbiAgICByZXMudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgIGhhbmRsZShzZWxmLCBuZXcgSGFuZGxlcihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcmVzKSk7XG4gIH0pO1xufTtcbmZ1bmN0aW9uIGhhbmRsZShzZWxmLCBkZWZlcnJlZCkge1xuICB3aGlsZSAoc2VsZi5fODEgPT09IDMpIHtcbiAgICBzZWxmID0gc2VsZi5fNjU7XG4gIH1cbiAgaWYgKFByb21pc2UuXzEwKSB7XG4gICAgUHJvbWlzZS5fMTAoc2VsZik7XG4gIH1cbiAgaWYgKHNlbGYuXzgxID09PSAwKSB7XG4gICAgaWYgKHNlbGYuXzQ1ID09PSAwKSB7XG4gICAgICBzZWxmLl80NSA9IDE7XG4gICAgICBzZWxmLl81NCA9IGRlZmVycmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc2VsZi5fNDUgPT09IDEpIHtcbiAgICAgIHNlbGYuXzQ1ID0gMjtcbiAgICAgIHNlbGYuXzU0ID0gW3NlbGYuXzU0LCBkZWZlcnJlZF07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHNlbGYuXzU0LnB1c2goZGVmZXJyZWQpO1xuICAgIHJldHVybjtcbiAgfVxuICBoYW5kbGVSZXNvbHZlZChzZWxmLCBkZWZlcnJlZCk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZVJlc29sdmVkKHNlbGYsIGRlZmVycmVkKSB7XG4gIGFzYXAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNiID0gc2VsZi5fODEgPT09IDEgPyBkZWZlcnJlZC5vbkZ1bGZpbGxlZCA6IGRlZmVycmVkLm9uUmVqZWN0ZWQ7XG4gICAgaWYgKGNiID09PSBudWxsKSB7XG4gICAgICBpZiAoc2VsZi5fODEgPT09IDEpIHtcbiAgICAgICAgcmVzb2x2ZShkZWZlcnJlZC5wcm9taXNlLCBzZWxmLl82NSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWplY3QoZGVmZXJyZWQucHJvbWlzZSwgc2VsZi5fNjUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcmV0ID0gdHJ5Q2FsbE9uZShjYiwgc2VsZi5fNjUpO1xuICAgIGlmIChyZXQgPT09IElTX0VSUk9SKSB7XG4gICAgICByZWplY3QoZGVmZXJyZWQucHJvbWlzZSwgTEFTVF9FUlJPUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc29sdmUoZGVmZXJyZWQucHJvbWlzZSwgcmV0KTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gcmVzb2x2ZShzZWxmLCBuZXdWYWx1ZSkge1xuICAvLyBQcm9taXNlIFJlc29sdXRpb24gUHJvY2VkdXJlOiBodHRwczovL2dpdGh1Yi5jb20vcHJvbWlzZXMtYXBsdXMvcHJvbWlzZXMtc3BlYyN0aGUtcHJvbWlzZS1yZXNvbHV0aW9uLXByb2NlZHVyZVxuICBpZiAobmV3VmFsdWUgPT09IHNlbGYpIHtcbiAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgc2VsZixcbiAgICAgIG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZSBjYW5ub3QgYmUgcmVzb2x2ZWQgd2l0aCBpdHNlbGYuJylcbiAgICApO1xuICB9XG4gIGlmIChcbiAgICBuZXdWYWx1ZSAmJlxuICAgICh0eXBlb2YgbmV3VmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBuZXdWYWx1ZSA9PT0gJ2Z1bmN0aW9uJylcbiAgKSB7XG4gICAgdmFyIHRoZW4gPSBnZXRUaGVuKG5ld1ZhbHVlKTtcbiAgICBpZiAodGhlbiA9PT0gSVNfRVJST1IpIHtcbiAgICAgIHJldHVybiByZWplY3Qoc2VsZiwgTEFTVF9FUlJPUik7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoZW4gPT09IHNlbGYudGhlbiAmJlxuICAgICAgbmV3VmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlXG4gICAgKSB7XG4gICAgICBzZWxmLl84MSA9IDM7XG4gICAgICBzZWxmLl82NSA9IG5ld1ZhbHVlO1xuICAgICAgZmluYWxlKHNlbGYpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRvUmVzb2x2ZSh0aGVuLmJpbmQobmV3VmFsdWUpLCBzZWxmKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cbiAgc2VsZi5fODEgPSAxO1xuICBzZWxmLl82NSA9IG5ld1ZhbHVlO1xuICBmaW5hbGUoc2VsZik7XG59XG5cbmZ1bmN0aW9uIHJlamVjdChzZWxmLCBuZXdWYWx1ZSkge1xuICBzZWxmLl84MSA9IDI7XG4gIHNlbGYuXzY1ID0gbmV3VmFsdWU7XG4gIGlmIChQcm9taXNlLl85Nykge1xuICAgIFByb21pc2UuXzk3KHNlbGYsIG5ld1ZhbHVlKTtcbiAgfVxuICBmaW5hbGUoc2VsZik7XG59XG5mdW5jdGlvbiBmaW5hbGUoc2VsZikge1xuICBpZiAoc2VsZi5fNDUgPT09IDEpIHtcbiAgICBoYW5kbGUoc2VsZiwgc2VsZi5fNTQpO1xuICAgIHNlbGYuXzU0ID0gbnVsbDtcbiAgfVxuICBpZiAoc2VsZi5fNDUgPT09IDIpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGYuXzU0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBoYW5kbGUoc2VsZiwgc2VsZi5fNTRbaV0pO1xuICAgIH1cbiAgICBzZWxmLl81NCA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gSGFuZGxlcihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcHJvbWlzZSl7XG4gIHRoaXMub25GdWxmaWxsZWQgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT09ICdmdW5jdGlvbicgPyBvbkZ1bGZpbGxlZCA6IG51bGw7XG4gIHRoaXMub25SZWplY3RlZCA9IHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nID8gb25SZWplY3RlZCA6IG51bGw7XG4gIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG59XG5cbi8qKlxuICogVGFrZSBhIHBvdGVudGlhbGx5IG1pc2JlaGF2aW5nIHJlc29sdmVyIGZ1bmN0aW9uIGFuZCBtYWtlIHN1cmVcbiAqIG9uRnVsZmlsbGVkIGFuZCBvblJlamVjdGVkIGFyZSBvbmx5IGNhbGxlZCBvbmNlLlxuICpcbiAqIE1ha2VzIG5vIGd1YXJhbnRlZXMgYWJvdXQgYXN5bmNocm9ueS5cbiAqL1xuZnVuY3Rpb24gZG9SZXNvbHZlKGZuLCBwcm9taXNlKSB7XG4gIHZhciBkb25lID0gZmFsc2U7XG4gIHZhciByZXMgPSB0cnlDYWxsVHdvKGZuLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBpZiAoZG9uZSkgcmV0dXJuO1xuICAgIGRvbmUgPSB0cnVlO1xuICAgIHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgaWYgKGRvbmUpIHJldHVybjtcbiAgICBkb25lID0gdHJ1ZTtcbiAgICByZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgfSlcbiAgaWYgKCFkb25lICYmIHJlcyA9PT0gSVNfRVJST1IpIHtcbiAgICBkb25lID0gdHJ1ZTtcbiAgICByZWplY3QocHJvbWlzZSwgTEFTVF9FUlJPUik7XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFByb21pc2UgPSByZXF1aXJlKCcuL2NvcmUuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQcm9taXNlO1xuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICB2YXIgc2VsZiA9IGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnRoZW4uYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHRoaXM7XG4gIHNlbGYudGhlbihudWxsLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSwgMCk7XG4gIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy9UaGlzIGZpbGUgY29udGFpbnMgdGhlIEVTNiBleHRlbnNpb25zIHRvIHRoZSBjb3JlIFByb21pc2VzL0ErIEFQSVxuXG52YXIgUHJvbWlzZSA9IHJlcXVpcmUoJy4vY29yZS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG5cbi8qIFN0YXRpYyBGdW5jdGlvbnMgKi9cblxudmFyIFRSVUUgPSB2YWx1ZVByb21pc2UodHJ1ZSk7XG52YXIgRkFMU0UgPSB2YWx1ZVByb21pc2UoZmFsc2UpO1xudmFyIE5VTEwgPSB2YWx1ZVByb21pc2UobnVsbCk7XG52YXIgVU5ERUZJTkVEID0gdmFsdWVQcm9taXNlKHVuZGVmaW5lZCk7XG52YXIgWkVSTyA9IHZhbHVlUHJvbWlzZSgwKTtcbnZhciBFTVBUWVNUUklORyA9IHZhbHVlUHJvbWlzZSgnJyk7XG5cbmZ1bmN0aW9uIHZhbHVlUHJvbWlzZSh2YWx1ZSkge1xuICB2YXIgcCA9IG5ldyBQcm9taXNlKFByb21pc2UuXzYxKTtcbiAgcC5fODEgPSAxO1xuICBwLl82NSA9IHZhbHVlO1xuICByZXR1cm4gcDtcbn1cblByb21pc2UucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSByZXR1cm4gdmFsdWU7XG5cbiAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gTlVMTDtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBVTkRFRklORUQ7XG4gIGlmICh2YWx1ZSA9PT0gdHJ1ZSkgcmV0dXJuIFRSVUU7XG4gIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHJldHVybiBGQUxTRTtcbiAgaWYgKHZhbHVlID09PSAwKSByZXR1cm4gWkVSTztcbiAgaWYgKHZhbHVlID09PSAnJykgcmV0dXJuIEVNUFRZU1RSSU5HO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgdGhlbiA9IHZhbHVlLnRoZW47XG4gICAgICBpZiAodHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHRoZW4uYmluZCh2YWx1ZSkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICByZWplY3QoZXgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZVByb21pc2UodmFsdWUpO1xufTtcblxuUHJvbWlzZS5hbGwgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJyKTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJlc29sdmUoW10pO1xuICAgIHZhciByZW1haW5pbmcgPSBhcmdzLmxlbmd0aDtcbiAgICBmdW5jdGlvbiByZXMoaSwgdmFsKSB7XG4gICAgICBpZiAodmFsICYmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgUHJvbWlzZSAmJiB2YWwudGhlbiA9PT0gUHJvbWlzZS5wcm90b3R5cGUudGhlbikge1xuICAgICAgICAgIHdoaWxlICh2YWwuXzgxID09PSAzKSB7XG4gICAgICAgICAgICB2YWwgPSB2YWwuXzY1O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsLl84MSA9PT0gMSkgcmV0dXJuIHJlcyhpLCB2YWwuXzY1KTtcbiAgICAgICAgICBpZiAodmFsLl84MSA9PT0gMikgcmVqZWN0KHZhbC5fNjUpO1xuICAgICAgICAgIHZhbC50aGVuKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJlcyhpLCB2YWwpO1xuICAgICAgICAgIH0sIHJlamVjdCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aGVuID0gdmFsLnRoZW47XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgcCA9IG5ldyBQcm9taXNlKHRoZW4uYmluZCh2YWwpKTtcbiAgICAgICAgICAgIHAudGhlbihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAgIHJlcyhpLCB2YWwpO1xuICAgICAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGFyZ3NbaV0gPSB2YWw7XG4gICAgICBpZiAoLS1yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgcmVzb2x2ZShhcmdzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXMoaSwgYXJnc1tpXSk7XG4gICAgfVxuICB9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgcmVqZWN0KHZhbHVlKTtcbiAgfSk7XG59O1xuXG5Qcm9taXNlLnJhY2UgPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odmFsdWUpe1xuICAgICAgUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyogUHJvdG90eXBlIE1ldGhvZHMgKi9cblxuUHJvbWlzZS5wcm90b3R5cGVbJ2NhdGNoJ10gPSBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICByZXR1cm4gdGhpcy50aGVuKG51bGwsIG9uUmVqZWN0ZWQpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFByb21pc2UgPSByZXF1aXJlKCcuL2NvcmUuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQcm9taXNlO1xuUHJvbWlzZS5wcm90b3R5cGVbJ2ZpbmFsbHknXSA9IGZ1bmN0aW9uIChmKSB7XG4gIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmKCkpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0pO1xuICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmKCkpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9jb3JlLmpzJyk7XG5yZXF1aXJlKCcuL2RvbmUuanMnKTtcbnJlcXVpcmUoJy4vZmluYWxseS5qcycpO1xucmVxdWlyZSgnLi9lczYtZXh0ZW5zaW9ucy5qcycpO1xucmVxdWlyZSgnLi9ub2RlLWV4dGVuc2lvbnMuanMnKTtcbnJlcXVpcmUoJy4vc3luY2hyb25vdXMuanMnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZW4vcHJvbWlzZSBzcGVjaWZpYyBleHRlbnNpb25zIHRoYXQgYXJlIG9ubHkgdXNlZnVsXG4vLyBmb3Igbm9kZS5qcyBpbnRlcm9wXG5cbnZhciBQcm9taXNlID0gcmVxdWlyZSgnLi9jb3JlLmpzJyk7XG52YXIgYXNhcCA9IHJlcXVpcmUoJ2FzYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQcm9taXNlO1xuXG4vKiBTdGF0aWMgRnVuY3Rpb25zICovXG5cblByb21pc2UuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKGZuLCBhcmd1bWVudENvdW50KSB7XG4gIGlmIChcbiAgICB0eXBlb2YgYXJndW1lbnRDb3VudCA9PT0gJ251bWJlcicgJiYgYXJndW1lbnRDb3VudCAhPT0gSW5maW5pdHlcbiAgKSB7XG4gICAgcmV0dXJuIGRlbm9kZWlmeVdpdGhDb3VudChmbiwgYXJndW1lbnRDb3VudCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRlbm9kZWlmeVdpdGhvdXRDb3VudChmbik7XG4gIH1cbn1cblxudmFyIGNhbGxiYWNrRm4gPSAoXG4gICdmdW5jdGlvbiAoZXJyLCByZXMpIHsnICtcbiAgJ2lmIChlcnIpIHsgcmooZXJyKTsgfSBlbHNlIHsgcnMocmVzKTsgfScgK1xuICAnfSdcbik7XG5mdW5jdGlvbiBkZW5vZGVpZnlXaXRoQ291bnQoZm4sIGFyZ3VtZW50Q291bnQpIHtcbiAgdmFyIGFyZ3MgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudENvdW50OyBpKyspIHtcbiAgICBhcmdzLnB1c2goJ2EnICsgaSk7XG4gIH1cbiAgdmFyIGJvZHkgPSBbXG4gICAgJ3JldHVybiBmdW5jdGlvbiAoJyArIGFyZ3Muam9pbignLCcpICsgJykgeycsXG4gICAgJ3ZhciBzZWxmID0gdGhpczsnLFxuICAgICdyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJzLCByaikgeycsXG4gICAgJ3ZhciByZXMgPSBmbi5jYWxsKCcsXG4gICAgWydzZWxmJ10uY29uY2F0KGFyZ3MpLmNvbmNhdChbY2FsbGJhY2tGbl0pLmpvaW4oJywnKSxcbiAgICAnKTsnLFxuICAgICdpZiAocmVzICYmJyxcbiAgICAnKHR5cGVvZiByZXMgPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIHJlcyA9PT0gXCJmdW5jdGlvblwiKSAmJicsXG4gICAgJ3R5cGVvZiByZXMudGhlbiA9PT0gXCJmdW5jdGlvblwiJyxcbiAgICAnKSB7cnMocmVzKTt9JyxcbiAgICAnfSk7JyxcbiAgICAnfTsnXG4gIF0uam9pbignJyk7XG4gIHJldHVybiBGdW5jdGlvbihbJ1Byb21pc2UnLCAnZm4nXSwgYm9keSkoUHJvbWlzZSwgZm4pO1xufVxuZnVuY3Rpb24gZGVub2RlaWZ5V2l0aG91dENvdW50KGZuKSB7XG4gIHZhciBmbkxlbmd0aCA9IE1hdGgubWF4KGZuLmxlbmd0aCAtIDEsIDMpO1xuICB2YXIgYXJncyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGZuTGVuZ3RoOyBpKyspIHtcbiAgICBhcmdzLnB1c2goJ2EnICsgaSk7XG4gIH1cbiAgdmFyIGJvZHkgPSBbXG4gICAgJ3JldHVybiBmdW5jdGlvbiAoJyArIGFyZ3Muam9pbignLCcpICsgJykgeycsXG4gICAgJ3ZhciBzZWxmID0gdGhpczsnLFxuICAgICd2YXIgYXJnczsnLFxuICAgICd2YXIgYXJnTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsnLFxuICAgICdpZiAoYXJndW1lbnRzLmxlbmd0aCA+ICcgKyBmbkxlbmd0aCArICcpIHsnLFxuICAgICdhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggKyAxKTsnLFxuICAgICdmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeycsXG4gICAgJ2FyZ3NbaV0gPSBhcmd1bWVudHNbaV07JyxcbiAgICAnfScsXG4gICAgJ30nLFxuICAgICdyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJzLCByaikgeycsXG4gICAgJ3ZhciBjYiA9ICcgKyBjYWxsYmFja0ZuICsgJzsnLFxuICAgICd2YXIgcmVzOycsXG4gICAgJ3N3aXRjaCAoYXJnTGVuZ3RoKSB7JyxcbiAgICBhcmdzLmNvbmNhdChbJ2V4dHJhJ10pLm1hcChmdW5jdGlvbiAoXywgaW5kZXgpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgICdjYXNlICcgKyAoaW5kZXgpICsgJzonICtcbiAgICAgICAgJ3JlcyA9IGZuLmNhbGwoJyArIFsnc2VsZiddLmNvbmNhdChhcmdzLnNsaWNlKDAsIGluZGV4KSkuY29uY2F0KCdjYicpLmpvaW4oJywnKSArICcpOycgK1xuICAgICAgICAnYnJlYWs7J1xuICAgICAgKTtcbiAgICB9KS5qb2luKCcnKSxcbiAgICAnZGVmYXVsdDonLFxuICAgICdhcmdzW2FyZ0xlbmd0aF0gPSBjYjsnLFxuICAgICdyZXMgPSBmbi5hcHBseShzZWxmLCBhcmdzKTsnLFxuICAgICd9JyxcbiAgICBcbiAgICAnaWYgKHJlcyAmJicsXG4gICAgJyh0eXBlb2YgcmVzID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiByZXMgPT09IFwiZnVuY3Rpb25cIikgJiYnLFxuICAgICd0eXBlb2YgcmVzLnRoZW4gPT09IFwiZnVuY3Rpb25cIicsXG4gICAgJykge3JzKHJlcyk7fScsXG4gICAgJ30pOycsXG4gICAgJ307J1xuICBdLmpvaW4oJycpO1xuXG4gIHJldHVybiBGdW5jdGlvbihcbiAgICBbJ1Byb21pc2UnLCAnZm4nXSxcbiAgICBib2R5XG4gICkoUHJvbWlzZSwgZm4pO1xufVxuXG5Qcm9taXNlLm5vZGVpZnkgPSBmdW5jdGlvbiAoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgdmFyIGNhbGxiYWNrID1cbiAgICAgIHR5cGVvZiBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0gPT09ICdmdW5jdGlvbicgPyBhcmdzLnBvcCgpIDogbnVsbDtcbiAgICB2YXIgY3R4ID0gdGhpcztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykubm9kZWlmeShjYWxsYmFjaywgY3R4KTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgaWYgKGNhbGxiYWNrID09PSBudWxsIHx8IHR5cGVvZiBjYWxsYmFjayA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgIHJlamVjdChleCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXNhcChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY2FsbGJhY2suY2FsbChjdHgsIGV4KTtcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuUHJvbWlzZS5wcm90b3R5cGUubm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgY3R4KSB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgIT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHRoaXM7XG5cbiAgdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGFzYXAoZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2suY2FsbChjdHgsIG51bGwsIHZhbHVlKTtcbiAgICB9KTtcbiAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgIGFzYXAoZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2suY2FsbChjdHgsIGVycik7XG4gICAgfSk7XG4gIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgUHJvbWlzZSA9IHJlcXVpcmUoJy4vY29yZS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG5Qcm9taXNlLmVuYWJsZVN5bmNocm9ub3VzID0gZnVuY3Rpb24gKCkge1xuICBQcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZSgpID09IDA7XG4gIH07XG5cbiAgUHJvbWlzZS5wcm90b3R5cGUuaXNGdWxmaWxsZWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZSgpID09IDE7XG4gIH07XG5cbiAgUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmdldFN0YXRlKCkgPT0gMjtcbiAgfTtcblxuICBQcm9taXNlLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fODEgPT09IDMpIHtcbiAgICAgIHJldHVybiB0aGlzLl82NS5nZXRWYWx1ZSgpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pc0Z1bGZpbGxlZCgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBnZXQgYSB2YWx1ZSBvZiBhbiB1bmZ1bGZpbGxlZCBwcm9taXNlLicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl82NTtcbiAgfTtcblxuICBQcm9taXNlLnByb3RvdHlwZS5nZXRSZWFzb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuXzgxID09PSAzKSB7XG4gICAgICByZXR1cm4gdGhpcy5fNjUuZ2V0UmVhc29uKCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmlzUmVqZWN0ZWQoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZ2V0IGEgcmVqZWN0aW9uIHJlYXNvbiBvZiBhIG5vbi1yZWplY3RlZCBwcm9taXNlLicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl82NTtcbiAgfTtcblxuICBQcm9taXNlLnByb3RvdHlwZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fODEgPT09IDMpIHtcbiAgICAgIHJldHVybiB0aGlzLl82NS5nZXRTdGF0ZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fODEgPT09IC0xIHx8IHRoaXMuXzgxID09PSAtMikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuXzgxO1xuICB9O1xufTtcblxuUHJvbWlzZS5kaXNhYmxlU3luY2hyb25vdXMgPSBmdW5jdGlvbigpIHtcbiAgUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gdW5kZWZpbmVkO1xuICBQcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IHVuZGVmaW5lZDtcbiAgUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IHVuZGVmaW5lZDtcbiAgUHJvbWlzZS5wcm90b3R5cGUuZ2V0VmFsdWUgPSB1bmRlZmluZWQ7XG4gIFByb21pc2UucHJvdG90eXBlLmdldFJlYXNvbiA9IHVuZGVmaW5lZDtcbiAgUHJvbWlzZS5wcm90b3R5cGUuZ2V0U3RhdGUgPSB1bmRlZmluZWQ7XG59O1xuIiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG4gIHZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuICB2YXIgUmVhY3RQcm9wVHlwZXNTZWNyZXQgPSByZXF1aXJlKCcuL2xpYi9SZWFjdFByb3BUeXBlc1NlY3JldCcpO1xuICB2YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG59XG5cbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIHZhbHVlcyBtYXRjaCB3aXRoIHRoZSB0eXBlIHNwZWNzLlxuICogRXJyb3IgbWVzc2FnZXMgYXJlIG1lbW9yaXplZCBhbmQgd2lsbCBvbmx5IGJlIHNob3duIG9uY2UuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHR5cGVTcGVjcyBNYXAgb2YgbmFtZSB0byBhIFJlYWN0UHJvcFR5cGVcbiAqIEBwYXJhbSB7b2JqZWN0fSB2YWx1ZXMgUnVudGltZSB2YWx1ZXMgdGhhdCBuZWVkIHRvIGJlIHR5cGUtY2hlY2tlZFxuICogQHBhcmFtIHtzdHJpbmd9IGxvY2F0aW9uIGUuZy4gXCJwcm9wXCIsIFwiY29udGV4dFwiLCBcImNoaWxkIGNvbnRleHRcIlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbXBvbmVudE5hbWUgTmFtZSBvZiB0aGUgY29tcG9uZW50IGZvciBlcnJvciBtZXNzYWdlcy5cbiAqIEBwYXJhbSB7P0Z1bmN0aW9ufSBnZXRTdGFjayBSZXR1cm5zIHRoZSBjb21wb25lbnQgc3RhY2suXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjaGVja1Byb3BUeXBlcyh0eXBlU3BlY3MsIHZhbHVlcywgbG9jYXRpb24sIGNvbXBvbmVudE5hbWUsIGdldFN0YWNrKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgZm9yICh2YXIgdHlwZVNwZWNOYW1lIGluIHR5cGVTcGVjcykge1xuICAgICAgaWYgKHR5cGVTcGVjcy5oYXNPd25Qcm9wZXJ0eSh0eXBlU3BlY05hbWUpKSB7XG4gICAgICAgIHZhciBlcnJvcjtcbiAgICAgICAgLy8gUHJvcCB0eXBlIHZhbGlkYXRpb24gbWF5IHRocm93LiBJbiBjYXNlIHRoZXkgZG8sIHdlIGRvbid0IHdhbnQgdG9cbiAgICAgICAgLy8gZmFpbCB0aGUgcmVuZGVyIHBoYXNlIHdoZXJlIGl0IGRpZG4ndCBmYWlsIGJlZm9yZS4gU28gd2UgbG9nIGl0LlxuICAgICAgICAvLyBBZnRlciB0aGVzZSBoYXZlIGJlZW4gY2xlYW5lZCB1cCwgd2UnbGwgbGV0IHRoZW0gdGhyb3cuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGFuIGludmFyaWFudCB0aGF0IGdldHMgY2F1Z2h0LiBJdCdzIHRoZSBzYW1lXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYXMgd2l0aG91dCB0aGlzIHN0YXRlbWVudCBleGNlcHQgd2l0aCBhIGJldHRlciBtZXNzYWdlLlxuICAgICAgICAgIGludmFyaWFudCh0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gPT09ICdmdW5jdGlvbicsICclczogJXMgdHlwZSBgJXNgIGlzIGludmFsaWQ7IGl0IG11c3QgYmUgYSBmdW5jdGlvbiwgdXN1YWxseSBmcm9tICcgKyAnUmVhY3QuUHJvcFR5cGVzLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgbG9jYXRpb24sIHR5cGVTcGVjTmFtZSk7XG4gICAgICAgICAgZXJyb3IgPSB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSh2YWx1ZXMsIHR5cGVTcGVjTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIG51bGwsIFJlYWN0UHJvcFR5cGVzU2VjcmV0KTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciA9IGV4O1xuICAgICAgICB9XG4gICAgICAgIHdhcm5pbmcoIWVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgRXJyb3IsICclczogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICVzIGAlc2AgaXMgaW52YWxpZDsgdGhlIHR5cGUgY2hlY2tlciAnICsgJ2Z1bmN0aW9uIG11c3QgcmV0dXJuIGBudWxsYCBvciBhbiBgRXJyb3JgIGJ1dCByZXR1cm5lZCBhICVzLiAnICsgJ1lvdSBtYXkgaGF2ZSBmb3Jnb3R0ZW4gdG8gcGFzcyBhbiBhcmd1bWVudCB0byB0aGUgdHlwZSBjaGVja2VyICcgKyAnY3JlYXRvciAoYXJyYXlPZiwgaW5zdGFuY2VPZiwgb2JqZWN0T2YsIG9uZU9mLCBvbmVPZlR5cGUsIGFuZCAnICsgJ3NoYXBlIGFsbCByZXF1aXJlIGFuIGFyZ3VtZW50KS4nLCBjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycsIGxvY2F0aW9uLCB0eXBlU3BlY05hbWUsIHR5cGVvZiBlcnJvcik7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IubWVzc2FnZSBpbiBsb2dnZWRUeXBlRmFpbHVyZXMpKSB7XG4gICAgICAgICAgLy8gT25seSBtb25pdG9yIHRoaXMgZmFpbHVyZSBvbmNlIGJlY2F1c2UgdGhlcmUgdGVuZHMgdG8gYmUgYSBsb3Qgb2YgdGhlXG4gICAgICAgICAgLy8gc2FtZSBlcnJvci5cbiAgICAgICAgICBsb2dnZWRUeXBlRmFpbHVyZXNbZXJyb3IubWVzc2FnZV0gPSB0cnVlO1xuXG4gICAgICAgICAgdmFyIHN0YWNrID0gZ2V0U3RhY2sgPyBnZXRTdGFjaygpIDogJyc7XG5cbiAgICAgICAgICB3YXJuaW5nKGZhbHNlLCAnRmFpbGVkICVzIHR5cGU6ICVzJXMnLCBsb2NhdGlvbiwgZXJyb3IubWVzc2FnZSwgc3RhY2sgIT0gbnVsbCA/IHN0YWNrIDogJycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2hlY2tQcm9wVHlwZXM7XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlGdW5jdGlvbicpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAvLyBJbXBvcnRhbnQhXG4gIC8vIEtlZXAgdGhpcyBsaXN0IGluIHN5bmMgd2l0aCBwcm9kdWN0aW9uIHZlcnNpb24gaW4gYC4vZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMuanNgLlxuICBmdW5jdGlvbiBzaGltKCkge1xuICAgIGludmFyaWFudChcbiAgICAgIGZhbHNlLFxuICAgICAgJ0NhbGxpbmcgUHJvcFR5cGVzIHZhbGlkYXRvcnMgZGlyZWN0bHkgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgYHByb3AtdHlwZXNgIHBhY2thZ2UuICcgK1xuICAgICAgJ1VzZSBQcm9wVHlwZXMuY2hlY2tQcm9wVHlwZXMoKSB0byBjYWxsIHRoZW0uICcgK1xuICAgICAgJ1JlYWQgbW9yZSBhdCBodHRwOi8vZmIubWUvdXNlLWNoZWNrLXByb3AtdHlwZXMnXG4gICAgKTtcbiAgfTtcbiAgc2hpbS5pc1JlcXVpcmVkID0gc2hpbTtcbiAgZnVuY3Rpb24gZ2V0U2hpbSgpIHtcbiAgICByZXR1cm4gc2hpbTtcbiAgfTtcbiAgdmFyIFJlYWN0UHJvcFR5cGVzID0ge1xuICAgIGFycmF5OiBzaGltLFxuICAgIGJvb2w6IHNoaW0sXG4gICAgZnVuYzogc2hpbSxcbiAgICBudW1iZXI6IHNoaW0sXG4gICAgb2JqZWN0OiBzaGltLFxuICAgIHN0cmluZzogc2hpbSxcbiAgICBzeW1ib2w6IHNoaW0sXG5cbiAgICBhbnk6IHNoaW0sXG4gICAgYXJyYXlPZjogZ2V0U2hpbSxcbiAgICBlbGVtZW50OiBzaGltLFxuICAgIGluc3RhbmNlT2Y6IGdldFNoaW0sXG4gICAgbm9kZTogc2hpbSxcbiAgICBvYmplY3RPZjogZ2V0U2hpbSxcbiAgICBvbmVPZjogZ2V0U2hpbSxcbiAgICBvbmVPZlR5cGU6IGdldFNoaW0sXG4gICAgc2hhcGU6IGdldFNoaW1cbiAgfTtcblxuICBSZWFjdFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcyA9IGVtcHR5RnVuY3Rpb247XG4gIFJlYWN0UHJvcFR5cGVzLlByb3BUeXBlcyA9IFJlYWN0UHJvcFR5cGVzO1xuXG4gIHJldHVybiBSZWFjdFByb3BUeXBlcztcbn07XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlGdW5jdGlvbicpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG52YXIgY2hlY2tQcm9wVHlwZXMgPSByZXF1aXJlKCcuL2NoZWNrUHJvcFR5cGVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXNWYWxpZEVsZW1lbnQsIHRocm93T25EaXJlY3RBY2Nlc3MpIHtcbiAgLyogZ2xvYmFsIFN5bWJvbCAqL1xuICB2YXIgSVRFUkFUT1JfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaXRlcmF0b3I7XG4gIHZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJzsgLy8gQmVmb3JlIFN5bWJvbCBzcGVjLlxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBpdGVyYXRvciBtZXRob2QgZnVuY3Rpb24gY29udGFpbmVkIG9uIHRoZSBpdGVyYWJsZSBvYmplY3QuXG4gICAqXG4gICAqIEJlIHN1cmUgdG8gaW52b2tlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBpdGVyYWJsZSBhcyBjb250ZXh0OlxuICAgKlxuICAgKiAgICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKG15SXRlcmFibGUpO1xuICAgKiAgICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAgICogICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKG15SXRlcmFibGUpO1xuICAgKiAgICAgICAuLi5cbiAgICogICAgIH1cbiAgICpcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBtYXliZUl0ZXJhYmxlXG4gICAqIEByZXR1cm4gez9mdW5jdGlvbn1cbiAgICovXG4gIGZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICAgIHZhciBpdGVyYXRvckZuID0gbWF5YmVJdGVyYWJsZSAmJiAoSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXSk7XG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaXRlcmF0b3JGbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29sbGVjdGlvbiBvZiBtZXRob2RzIHRoYXQgYWxsb3cgZGVjbGFyYXRpb24gYW5kIHZhbGlkYXRpb24gb2YgcHJvcHMgdGhhdCBhcmVcbiAgICogc3VwcGxpZWQgdG8gUmVhY3QgY29tcG9uZW50cy4gRXhhbXBsZSB1c2FnZTpcbiAgICpcbiAgICogICB2YXIgUHJvcHMgPSByZXF1aXJlKCdSZWFjdFByb3BUeXBlcycpO1xuICAgKiAgIHZhciBNeUFydGljbGUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAqICAgICBwcm9wVHlwZXM6IHtcbiAgICogICAgICAgLy8gQW4gb3B0aW9uYWwgc3RyaW5nIHByb3AgbmFtZWQgXCJkZXNjcmlwdGlvblwiLlxuICAgKiAgICAgICBkZXNjcmlwdGlvbjogUHJvcHMuc3RyaW5nLFxuICAgKlxuICAgKiAgICAgICAvLyBBIHJlcXVpcmVkIGVudW0gcHJvcCBuYW1lZCBcImNhdGVnb3J5XCIuXG4gICAqICAgICAgIGNhdGVnb3J5OiBQcm9wcy5vbmVPZihbJ05ld3MnLCdQaG90b3MnXSkuaXNSZXF1aXJlZCxcbiAgICpcbiAgICogICAgICAgLy8gQSBwcm9wIG5hbWVkIFwiZGlhbG9nXCIgdGhhdCByZXF1aXJlcyBhbiBpbnN0YW5jZSBvZiBEaWFsb2cuXG4gICAqICAgICAgIGRpYWxvZzogUHJvcHMuaW5zdGFuY2VPZihEaWFsb2cpLmlzUmVxdWlyZWRcbiAgICogICAgIH0sXG4gICAqICAgICByZW5kZXI6IGZ1bmN0aW9uKCkgeyAuLi4gfVxuICAgKiAgIH0pO1xuICAgKlxuICAgKiBBIG1vcmUgZm9ybWFsIHNwZWNpZmljYXRpb24gb2YgaG93IHRoZXNlIG1ldGhvZHMgYXJlIHVzZWQ6XG4gICAqXG4gICAqICAgdHlwZSA6PSBhcnJheXxib29sfGZ1bmN8b2JqZWN0fG51bWJlcnxzdHJpbmd8b25lT2YoWy4uLl0pfGluc3RhbmNlT2YoLi4uKVxuICAgKiAgIGRlY2wgOj0gUmVhY3RQcm9wVHlwZXMue3R5cGV9KC5pc1JlcXVpcmVkKT9cbiAgICpcbiAgICogRWFjaCBhbmQgZXZlcnkgZGVjbGFyYXRpb24gcHJvZHVjZXMgYSBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZS4gVGhpc1xuICAgKiBhbGxvd3MgdGhlIGNyZWF0aW9uIG9mIGN1c3RvbSB2YWxpZGF0aW9uIGZ1bmN0aW9ucy4gRm9yIGV4YW1wbGU6XG4gICAqXG4gICAqICB2YXIgTXlMaW5rID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgKiAgICBwcm9wVHlwZXM6IHtcbiAgICogICAgICAvLyBBbiBvcHRpb25hbCBzdHJpbmcgb3IgVVJJIHByb3AgbmFtZWQgXCJocmVmXCIuXG4gICAqICAgICAgaHJlZjogZnVuY3Rpb24ocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gICAqICAgICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgKiAgICAgICAgaWYgKHByb3BWYWx1ZSAhPSBudWxsICYmIHR5cGVvZiBwcm9wVmFsdWUgIT09ICdzdHJpbmcnICYmXG4gICAqICAgICAgICAgICAgIShwcm9wVmFsdWUgaW5zdGFuY2VvZiBVUkkpKSB7XG4gICAqICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXG4gICAqICAgICAgICAgICAgJ0V4cGVjdGVkIGEgc3RyaW5nIG9yIGFuIFVSSSBmb3IgJyArIHByb3BOYW1lICsgJyBpbiAnICtcbiAgICogICAgICAgICAgICBjb21wb25lbnROYW1lXG4gICAqICAgICAgICAgICk7XG4gICAqICAgICAgICB9XG4gICAqICAgICAgfVxuICAgKiAgICB9LFxuICAgKiAgICByZW5kZXI6IGZ1bmN0aW9uKCkgey4uLn1cbiAgICogIH0pO1xuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG5cbiAgdmFyIEFOT05ZTU9VUyA9ICc8PGFub255bW91cz4+JztcblxuICAvLyBJbXBvcnRhbnQhXG4gIC8vIEtlZXAgdGhpcyBsaXN0IGluIHN5bmMgd2l0aCBwcm9kdWN0aW9uIHZlcnNpb24gaW4gYC4vZmFjdG9yeVdpdGhUaHJvd2luZ1NoaW1zLmpzYC5cbiAgdmFyIFJlYWN0UHJvcFR5cGVzID0ge1xuICAgIGFycmF5OiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignYXJyYXknKSxcbiAgICBib29sOiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignYm9vbGVhbicpLFxuICAgIGZ1bmM6IGNyZWF0ZVByaW1pdGl2ZVR5cGVDaGVja2VyKCdmdW5jdGlvbicpLFxuICAgIG51bWJlcjogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ251bWJlcicpLFxuICAgIG9iamVjdDogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ29iamVjdCcpLFxuICAgIHN0cmluZzogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ3N0cmluZycpLFxuICAgIHN5bWJvbDogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ3N5bWJvbCcpLFxuXG4gICAgYW55OiBjcmVhdGVBbnlUeXBlQ2hlY2tlcigpLFxuICAgIGFycmF5T2Y6IGNyZWF0ZUFycmF5T2ZUeXBlQ2hlY2tlcixcbiAgICBlbGVtZW50OiBjcmVhdGVFbGVtZW50VHlwZUNoZWNrZXIoKSxcbiAgICBpbnN0YW5jZU9mOiBjcmVhdGVJbnN0YW5jZVR5cGVDaGVja2VyLFxuICAgIG5vZGU6IGNyZWF0ZU5vZGVDaGVja2VyKCksXG4gICAgb2JqZWN0T2Y6IGNyZWF0ZU9iamVjdE9mVHlwZUNoZWNrZXIsXG4gICAgb25lT2Y6IGNyZWF0ZUVudW1UeXBlQ2hlY2tlcixcbiAgICBvbmVPZlR5cGU6IGNyZWF0ZVVuaW9uVHlwZUNoZWNrZXIsXG4gICAgc2hhcGU6IGNyZWF0ZVNoYXBlVHlwZUNoZWNrZXJcbiAgfTtcblxuICAvKipcbiAgICogaW5saW5lZCBPYmplY3QuaXMgcG9seWZpbGwgdG8gYXZvaWQgcmVxdWlyaW5nIGNvbnN1bWVycyBzaGlwIHRoZWlyIG93blxuICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvaXNcbiAgICovXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tc2VsZi1jb21wYXJlKi9cbiAgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAgIC8vIFNhbWVWYWx1ZSBhbGdvcml0aG1cbiAgICBpZiAoeCA9PT0geSkge1xuICAgICAgLy8gU3RlcHMgMS01LCA3LTEwXG4gICAgICAvLyBTdGVwcyA2LmItNi5lOiArMCAhPSAtMFxuICAgICAgcmV0dXJuIHggIT09IDAgfHwgMSAvIHggPT09IDEgLyB5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTdGVwIDYuYTogTmFOID09IE5hTlxuICAgICAgcmV0dXJuIHggIT09IHggJiYgeSAhPT0geTtcbiAgICB9XG4gIH1cbiAgLyplc2xpbnQtZW5hYmxlIG5vLXNlbGYtY29tcGFyZSovXG5cbiAgLyoqXG4gICAqIFdlIHVzZSBhbiBFcnJvci1saWtlIG9iamVjdCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBhcyBwZW9wbGUgbWF5IGNhbGxcbiAgICogUHJvcFR5cGVzIGRpcmVjdGx5IGFuZCBpbnNwZWN0IHRoZWlyIG91dHB1dC4gSG93ZXZlciwgd2UgZG9uJ3QgdXNlIHJlYWxcbiAgICogRXJyb3JzIGFueW1vcmUuIFdlIGRvbid0IGluc3BlY3QgdGhlaXIgc3RhY2sgYW55d2F5LCBhbmQgY3JlYXRpbmcgdGhlbVxuICAgKiBpcyBwcm9oaWJpdGl2ZWx5IGV4cGVuc2l2ZSBpZiB0aGV5IGFyZSBjcmVhdGVkIHRvbyBvZnRlbiwgc3VjaCBhcyB3aGF0XG4gICAqIGhhcHBlbnMgaW4gb25lT2ZUeXBlKCkgZm9yIGFueSB0eXBlIGJlZm9yZSB0aGUgb25lIHRoYXQgbWF0Y2hlZC5cbiAgICovXG4gIGZ1bmN0aW9uIFByb3BUeXBlRXJyb3IobWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICB9XG4gIC8vIE1ha2UgYGluc3RhbmNlb2YgRXJyb3JgIHN0aWxsIHdvcmsgZm9yIHJldHVybmVkIGVycm9ycy5cbiAgUHJvcFR5cGVFcnJvci5wcm90b3R5cGUgPSBFcnJvci5wcm90b3R5cGU7XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIodmFsaWRhdGUpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgdmFyIG1hbnVhbFByb3BUeXBlQ2FsbENhY2hlID0ge307XG4gICAgICB2YXIgbWFudWFsUHJvcFR5cGVXYXJuaW5nQ291bnQgPSAwO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjaGVja1R5cGUoaXNSZXF1aXJlZCwgcHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lLCBzZWNyZXQpIHtcbiAgICAgIGNvbXBvbmVudE5hbWUgPSBjb21wb25lbnROYW1lIHx8IEFOT05ZTU9VUztcbiAgICAgIHByb3BGdWxsTmFtZSA9IHByb3BGdWxsTmFtZSB8fCBwcm9wTmFtZTtcblxuICAgICAgaWYgKHNlY3JldCAhPT0gUmVhY3RQcm9wVHlwZXNTZWNyZXQpIHtcbiAgICAgICAgaWYgKHRocm93T25EaXJlY3RBY2Nlc3MpIHtcbiAgICAgICAgICAvLyBOZXcgYmVoYXZpb3Igb25seSBmb3IgdXNlcnMgb2YgYHByb3AtdHlwZXNgIHBhY2thZ2VcbiAgICAgICAgICBpbnZhcmlhbnQoXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICdDYWxsaW5nIFByb3BUeXBlcyB2YWxpZGF0b3JzIGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLiAnICtcbiAgICAgICAgICAgICdVc2UgYFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcygpYCB0byBjYWxsIHRoZW0uICcgK1xuICAgICAgICAgICAgJ1JlYWQgbW9yZSBhdCBodHRwOi8vZmIubWUvdXNlLWNoZWNrLXByb3AtdHlwZXMnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIC8vIE9sZCBiZWhhdmlvciBmb3IgcGVvcGxlIHVzaW5nIFJlYWN0LlByb3BUeXBlc1xuICAgICAgICAgIHZhciBjYWNoZUtleSA9IGNvbXBvbmVudE5hbWUgKyAnOicgKyBwcm9wTmFtZTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhbWFudWFsUHJvcFR5cGVDYWxsQ2FjaGVbY2FjaGVLZXldICYmXG4gICAgICAgICAgICAvLyBBdm9pZCBzcGFtbWluZyB0aGUgY29uc29sZSBiZWNhdXNlIHRoZXkgYXJlIG9mdGVuIG5vdCBhY3Rpb25hYmxlIGV4Y2VwdCBmb3IgbGliIGF1dGhvcnNcbiAgICAgICAgICAgIG1hbnVhbFByb3BUeXBlV2FybmluZ0NvdW50IDwgM1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgd2FybmluZyhcbiAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICdZb3UgYXJlIG1hbnVhbGx5IGNhbGxpbmcgYSBSZWFjdC5Qcm9wVHlwZXMgdmFsaWRhdGlvbiAnICtcbiAgICAgICAgICAgICAgJ2Z1bmN0aW9uIGZvciB0aGUgYCVzYCBwcm9wIG9uIGAlc2AuIFRoaXMgaXMgZGVwcmVjYXRlZCAnICtcbiAgICAgICAgICAgICAgJ2FuZCB3aWxsIHRocm93IGluIHRoZSBzdGFuZGFsb25lIGBwcm9wLXR5cGVzYCBwYWNrYWdlLiAnICtcbiAgICAgICAgICAgICAgJ1lvdSBtYXkgYmUgc2VlaW5nIHRoaXMgd2FybmluZyBkdWUgdG8gYSB0aGlyZC1wYXJ0eSBQcm9wVHlwZXMgJyArXG4gICAgICAgICAgICAgICdsaWJyYXJ5LiBTZWUgaHR0cHM6Ly9mYi5tZS9yZWFjdC13YXJuaW5nLWRvbnQtY2FsbC1wcm9wdHlwZXMgJyArICdmb3IgZGV0YWlscy4nLFxuICAgICAgICAgICAgICBwcm9wRnVsbE5hbWUsXG4gICAgICAgICAgICAgIGNvbXBvbmVudE5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBtYW51YWxQcm9wVHlwZUNhbGxDYWNoZVtjYWNoZUtleV0gPSB0cnVlO1xuICAgICAgICAgICAgbWFudWFsUHJvcFR5cGVXYXJuaW5nQ291bnQrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNSZXF1aXJlZCkge1xuICAgICAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignVGhlICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBpcyBtYXJrZWQgYXMgcmVxdWlyZWQgJyArICgnaW4gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGJ1dCBpdHMgdmFsdWUgaXMgYG51bGxgLicpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdUaGUgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIGlzIG1hcmtlZCBhcyByZXF1aXJlZCBpbiAnICsgKCdgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgYnV0IGl0cyB2YWx1ZSBpcyBgdW5kZWZpbmVkYC4nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY2hhaW5lZENoZWNrVHlwZSA9IGNoZWNrVHlwZS5iaW5kKG51bGwsIGZhbHNlKTtcbiAgICBjaGFpbmVkQ2hlY2tUeXBlLmlzUmVxdWlyZWQgPSBjaGVja1R5cGUuYmluZChudWxsLCB0cnVlKTtcblxuICAgIHJldHVybiBjaGFpbmVkQ2hlY2tUeXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoZXhwZWN0ZWRUeXBlKSB7XG4gICAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lLCBzZWNyZXQpIHtcbiAgICAgIHZhciBwcm9wVmFsdWUgPSBwcm9wc1twcm9wTmFtZV07XG4gICAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgICAgaWYgKHByb3BUeXBlICE9PSBleHBlY3RlZFR5cGUpIHtcbiAgICAgICAgLy8gYHByb3BWYWx1ZWAgYmVpbmcgaW5zdGFuY2Ugb2YsIHNheSwgZGF0ZS9yZWdleHAsIHBhc3MgdGhlICdvYmplY3QnXG4gICAgICAgIC8vIGNoZWNrLCBidXQgd2UgY2FuIG9mZmVyIGEgbW9yZSBwcmVjaXNlIGVycm9yIG1lc3NhZ2UgaGVyZSByYXRoZXIgdGhhblxuICAgICAgICAvLyAnb2YgdHlwZSBgb2JqZWN0YCcuXG4gICAgICAgIHZhciBwcmVjaXNlVHlwZSA9IGdldFByZWNpc2VUeXBlKHByb3BWYWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgcHJlY2lzZVR5cGUgKyAnYCBzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgJykgKyAoJ2AnICsgZXhwZWN0ZWRUeXBlICsgJ2AuJykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVBbnlUeXBlQ2hlY2tlcigpIHtcbiAgICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIoZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc051bGwpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlQXJyYXlPZlR5cGVDaGVja2VyKHR5cGVDaGVja2VyKSB7XG4gICAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgICBpZiAodHlwZW9mIHR5cGVDaGVja2VyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignUHJvcGVydHkgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiBjb21wb25lbnQgYCcgKyBjb21wb25lbnROYW1lICsgJ2AgaGFzIGludmFsaWQgUHJvcFR5cGUgbm90YXRpb24gaW5zaWRlIGFycmF5T2YuJyk7XG4gICAgICB9XG4gICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHByb3BWYWx1ZSkpIHtcbiAgICAgICAgdmFyIHByb3BUeXBlID0gZ2V0UHJvcFR5cGUocHJvcFZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgcHJvcFR5cGUgKyAnYCBzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYW4gYXJyYXkuJykpO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wVmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGVycm9yID0gdHlwZUNoZWNrZXIocHJvcFZhbHVlLCBpLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lICsgJ1snICsgaSArICddJywgUmVhY3RQcm9wVHlwZXNTZWNyZXQpO1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVFbGVtZW50VHlwZUNoZWNrZXIoKSB7XG4gICAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgICAgaWYgKCFpc1ZhbGlkRWxlbWVudChwcm9wVmFsdWUpKSB7XG4gICAgICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgdHlwZSAnICsgKCdgJyArIHByb3BUeXBlICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkIGEgc2luZ2xlIFJlYWN0RWxlbWVudC4nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUluc3RhbmNlVHlwZUNoZWNrZXIoZXhwZWN0ZWRDbGFzcykge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgaWYgKCEocHJvcHNbcHJvcE5hbWVdIGluc3RhbmNlb2YgZXhwZWN0ZWRDbGFzcykpIHtcbiAgICAgICAgdmFyIGV4cGVjdGVkQ2xhc3NOYW1lID0gZXhwZWN0ZWRDbGFzcy5uYW1lIHx8IEFOT05ZTU9VUztcbiAgICAgICAgdmFyIGFjdHVhbENsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwcm9wc1twcm9wTmFtZV0pO1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgJyArICgnYCcgKyBhY3R1YWxDbGFzc05hbWUgKyAnYCBzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgJykgKyAoJ2luc3RhbmNlIG9mIGAnICsgZXhwZWN0ZWRDbGFzc05hbWUgKyAnYC4nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUVudW1UeXBlQ2hlY2tlcihleHBlY3RlZFZhbHVlcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShleHBlY3RlZFZhbHVlcykpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnSW52YWxpZCBhcmd1bWVudCBzdXBwbGllZCB0byBvbmVPZiwgZXhwZWN0ZWQgYW4gaW5zdGFuY2Ugb2YgYXJyYXkuJykgOiB2b2lkIDA7XG4gICAgICByZXR1cm4gZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc051bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHBlY3RlZFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaXMocHJvcFZhbHVlLCBleHBlY3RlZFZhbHVlc1tpXSkpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgdmFsdWVzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWRWYWx1ZXMpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB2YWx1ZSBgJyArIHByb3BWYWx1ZSArICdgICcgKyAoJ3N1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBvbmUgb2YgJyArIHZhbHVlc1N0cmluZyArICcuJykpO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIodmFsaWRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlT2JqZWN0T2ZUeXBlQ2hlY2tlcih0eXBlQ2hlY2tlcikge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgaWYgKHR5cGVvZiB0eXBlQ2hlY2tlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ1Byb3BlcnR5IGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgY29tcG9uZW50IGAnICsgY29tcG9uZW50TmFtZSArICdgIGhhcyBpbnZhbGlkIFByb3BUeXBlIG5vdGF0aW9uIGluc2lkZSBvYmplY3RPZi4nKTtcbiAgICAgIH1cbiAgICAgIHZhciBwcm9wVmFsdWUgPSBwcm9wc1twcm9wTmFtZV07XG4gICAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgICAgaWYgKHByb3BUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgJyArICgnYCcgKyBwcm9wVHlwZSArICdgIHN1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBhbiBvYmplY3QuJykpO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIga2V5IGluIHByb3BWYWx1ZSkge1xuICAgICAgICBpZiAocHJvcFZhbHVlLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSB0eXBlQ2hlY2tlcihwcm9wVmFsdWUsIGtleSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSArICcuJyArIGtleSwgUmVhY3RQcm9wVHlwZXNTZWNyZXQpO1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVVuaW9uVHlwZUNoZWNrZXIoYXJyYXlPZlR5cGVDaGVja2Vycykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheU9mVHlwZUNoZWNrZXJzKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdJbnZhbGlkIGFyZ3VtZW50IHN1cHBsaWVkIHRvIG9uZU9mVHlwZSwgZXhwZWN0ZWQgYW4gaW5zdGFuY2Ugb2YgYXJyYXkuJykgOiB2b2lkIDA7XG4gICAgICByZXR1cm4gZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc051bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5T2ZUeXBlQ2hlY2tlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoZWNrZXIgPSBhcnJheU9mVHlwZUNoZWNrZXJzW2ldO1xuICAgICAgICBpZiAoY2hlY2tlcihwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUsIFJlYWN0UHJvcFR5cGVzU2VjcmV0KSA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBzdXBwbGllZCB0byAnICsgKCdgJyArIGNvbXBvbmVudE5hbWUgKyAnYC4nKSk7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVOb2RlQ2hlY2tlcigpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIGlmICghaXNOb2RlKHByb3BzW3Byb3BOYW1lXSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBzdXBwbGllZCB0byAnICsgKCdgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYSBSZWFjdE5vZGUuJykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTaGFwZVR5cGVDaGVja2VyKHNoYXBlVHlwZXMpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIHZhciBwcm9wVmFsdWUgPSBwcm9wc1twcm9wTmFtZV07XG4gICAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgICAgaWYgKHByb3BUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgYCcgKyBwcm9wVHlwZSArICdgICcgKyAoJ3N1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBgb2JqZWN0YC4nKSk7XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBrZXkgaW4gc2hhcGVUeXBlcykge1xuICAgICAgICB2YXIgY2hlY2tlciA9IHNoYXBlVHlwZXNba2V5XTtcbiAgICAgICAgaWYgKCFjaGVja2VyKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVycm9yID0gY2hlY2tlcihwcm9wVmFsdWUsIGtleSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSArICcuJyArIGtleSwgUmVhY3RQcm9wVHlwZXNTZWNyZXQpO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIodmFsaWRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNOb2RlKHByb3BWYWx1ZSkge1xuICAgIHN3aXRjaCAodHlwZW9mIHByb3BWYWx1ZSkge1xuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgICByZXR1cm4gIXByb3BWYWx1ZTtcbiAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHByb3BWYWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gcHJvcFZhbHVlLmV2ZXJ5KGlzTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BWYWx1ZSA9PT0gbnVsbCB8fCBpc1ZhbGlkRWxlbWVudChwcm9wVmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4ocHJvcFZhbHVlKTtcbiAgICAgICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwocHJvcFZhbHVlKTtcbiAgICAgICAgICB2YXIgc3RlcDtcbiAgICAgICAgICBpZiAoaXRlcmF0b3JGbiAhPT0gcHJvcFZhbHVlLmVudHJpZXMpIHtcbiAgICAgICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICAgICAgaWYgKCFpc05vZGUoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSXRlcmF0b3Igd2lsbCBwcm92aWRlIGVudHJ5IFtrLHZdIHR1cGxlcyByYXRoZXIgdGhhbiB2YWx1ZXMuXG4gICAgICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgICAgICAgIGlmICghaXNOb2RlKGVudHJ5WzFdKSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1N5bWJvbChwcm9wVHlwZSwgcHJvcFZhbHVlKSB7XG4gICAgLy8gTmF0aXZlIFN5bWJvbC5cbiAgICBpZiAocHJvcFR5cGUgPT09ICdzeW1ib2wnKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyAxOS40LjMuNSBTeW1ib2wucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddID09PSAnU3ltYm9sJ1xuICAgIGlmIChwcm9wVmFsdWVbJ0BAdG9TdHJpbmdUYWcnXSA9PT0gJ1N5bWJvbCcpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrIGZvciBub24tc3BlYyBjb21wbGlhbnQgU3ltYm9scyB3aGljaCBhcmUgcG9seWZpbGxlZC5cbiAgICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBwcm9wVmFsdWUgaW5zdGFuY2VvZiBTeW1ib2wpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEVxdWl2YWxlbnQgb2YgYHR5cGVvZmAgYnV0IHdpdGggc3BlY2lhbCBoYW5kbGluZyBmb3IgYXJyYXkgYW5kIHJlZ2V4cC5cbiAgZnVuY3Rpb24gZ2V0UHJvcFR5cGUocHJvcFZhbHVlKSB7XG4gICAgdmFyIHByb3BUeXBlID0gdHlwZW9mIHByb3BWYWx1ZTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwcm9wVmFsdWUpKSB7XG4gICAgICByZXR1cm4gJ2FycmF5JztcbiAgICB9XG4gICAgaWYgKHByb3BWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgLy8gT2xkIHdlYmtpdHMgKGF0IGxlYXN0IHVudGlsIEFuZHJvaWQgNC4wKSByZXR1cm4gJ2Z1bmN0aW9uJyByYXRoZXIgdGhhblxuICAgICAgLy8gJ29iamVjdCcgZm9yIHR5cGVvZiBhIFJlZ0V4cC4gV2UnbGwgbm9ybWFsaXplIHRoaXMgaGVyZSBzbyB0aGF0IC9ibGEvXG4gICAgICAvLyBwYXNzZXMgUHJvcFR5cGVzLm9iamVjdC5cbiAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICB9XG4gICAgaWYgKGlzU3ltYm9sKHByb3BUeXBlLCBwcm9wVmFsdWUpKSB7XG4gICAgICByZXR1cm4gJ3N5bWJvbCc7XG4gICAgfVxuICAgIHJldHVybiBwcm9wVHlwZTtcbiAgfVxuXG4gIC8vIFRoaXMgaGFuZGxlcyBtb3JlIHR5cGVzIHRoYW4gYGdldFByb3BUeXBlYC4gT25seSB1c2VkIGZvciBlcnJvciBtZXNzYWdlcy5cbiAgLy8gU2VlIGBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcmAuXG4gIGZ1bmN0aW9uIGdldFByZWNpc2VUeXBlKHByb3BWYWx1ZSkge1xuICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgaWYgKHByb3BUeXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHByb3BWYWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIH0gZWxzZSBpZiAocHJvcFZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHJldHVybiAncmVnZXhwJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHByb3BUeXBlO1xuICB9XG5cbiAgLy8gUmV0dXJucyBjbGFzcyBuYW1lIG9mIHRoZSBvYmplY3QsIGlmIGFueS5cbiAgZnVuY3Rpb24gZ2V0Q2xhc3NOYW1lKHByb3BWYWx1ZSkge1xuICAgIGlmICghcHJvcFZhbHVlLmNvbnN0cnVjdG9yIHx8ICFwcm9wVmFsdWUuY29uc3RydWN0b3IubmFtZSkge1xuICAgICAgcmV0dXJuIEFOT05ZTU9VUztcbiAgICB9XG4gICAgcmV0dXJuIHByb3BWYWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xuICB9XG5cbiAgUmVhY3RQcm9wVHlwZXMuY2hlY2tQcm9wVHlwZXMgPSBjaGVja1Byb3BUeXBlcztcbiAgUmVhY3RQcm9wVHlwZXMuUHJvcFR5cGVzID0gUmVhY3RQcm9wVHlwZXM7XG5cbiAgcmV0dXJuIFJlYWN0UHJvcFR5cGVzO1xufTtcbiIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICovXG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhciBSRUFDVF9FTEVNRU5UX1RZUEUgPSAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgIFN5bWJvbC5mb3IgJiZcbiAgICBTeW1ib2wuZm9yKCdyZWFjdC5lbGVtZW50JykpIHx8XG4gICAgMHhlYWM3O1xuXG4gIHZhciBpc1ZhbGlkRWxlbWVudCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgb2JqZWN0ICE9PSBudWxsICYmXG4gICAgICBvYmplY3QuJCR0eXBlb2YgPT09IFJFQUNUX0VMRU1FTlRfVFlQRTtcbiAgfTtcblxuICAvLyBCeSBleHBsaWNpdGx5IHVzaW5nIGBwcm9wLXR5cGVzYCB5b3UgYXJlIG9wdGluZyBpbnRvIG5ldyBkZXZlbG9wbWVudCBiZWhhdmlvci5cbiAgLy8gaHR0cDovL2ZiLm1lL3Byb3AtdHlwZXMtaW4tcHJvZFxuICB2YXIgdGhyb3dPbkRpcmVjdEFjY2VzcyA9IHRydWU7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mYWN0b3J5V2l0aFR5cGVDaGVja2VycycpKGlzVmFsaWRFbGVtZW50LCB0aHJvd09uRGlyZWN0QWNjZXNzKTtcbn0gZWxzZSB7XG4gIC8vIEJ5IGV4cGxpY2l0bHkgdXNpbmcgYHByb3AtdHlwZXNgIHlvdSBhcmUgb3B0aW5nIGludG8gbmV3IHByb2R1Y3Rpb24gYmVoYXZpb3IuXG4gIC8vIGh0dHA6Ly9mYi5tZS9wcm9wLXR5cGVzLWluLXByb2RcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2ZhY3RvcnlXaXRoVGhyb3dpbmdTaGltcycpKCk7XG59XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9ICdTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RQcm9wVHlwZXNTZWNyZXQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIFxuICovXG5cbmZ1bmN0aW9uIG1ha2VFbXB0eUZ1bmN0aW9uKGFyZykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhcmc7XG4gIH07XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBhY2NlcHRzIGFuZCBkaXNjYXJkcyBpbnB1dHM7IGl0IGhhcyBubyBzaWRlIGVmZmVjdHMuIFRoaXMgaXNcbiAqIHByaW1hcmlseSB1c2VmdWwgaWRpb21hdGljYWxseSBmb3Igb3ZlcnJpZGFibGUgZnVuY3Rpb24gZW5kcG9pbnRzIHdoaWNoXG4gKiBhbHdheXMgbmVlZCB0byBiZSBjYWxsYWJsZSwgc2luY2UgSlMgbGFja3MgYSBudWxsLWNhbGwgaWRpb20gYWxhIENvY29hLlxuICovXG52YXIgZW1wdHlGdW5jdGlvbiA9IGZ1bmN0aW9uIGVtcHR5RnVuY3Rpb24oKSB7fTtcblxuZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJucyA9IG1ha2VFbXB0eUZ1bmN0aW9uO1xuZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc0ZhbHNlID0gbWFrZUVtcHR5RnVuY3Rpb24oZmFsc2UpO1xuZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc1RydWUgPSBtYWtlRW1wdHlGdW5jdGlvbih0cnVlKTtcbmVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNOdWxsID0gbWFrZUVtcHR5RnVuY3Rpb24obnVsbCk7XG5lbXB0eUZ1bmN0aW9uLnRoYXRSZXR1cm5zVGhpcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXM7XG59O1xuZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc0FyZ3VtZW50ID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gYXJnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBlbXB0eUZ1bmN0aW9uOyIsIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFVzZSBpbnZhcmlhbnQoKSB0byBhc3NlcnQgc3RhdGUgd2hpY2ggeW91ciBwcm9ncmFtIGFzc3VtZXMgdG8gYmUgdHJ1ZS5cbiAqXG4gKiBQcm92aWRlIHNwcmludGYtc3R5bGUgZm9ybWF0IChvbmx5ICVzIGlzIHN1cHBvcnRlZCkgYW5kIGFyZ3VtZW50c1xuICogdG8gcHJvdmlkZSBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IGJyb2tlIGFuZCB3aGF0IHlvdSB3ZXJlXG4gKiBleHBlY3RpbmcuXG4gKlxuICogVGhlIGludmFyaWFudCBtZXNzYWdlIHdpbGwgYmUgc3RyaXBwZWQgaW4gcHJvZHVjdGlvbiwgYnV0IHRoZSBpbnZhcmlhbnRcbiAqIHdpbGwgcmVtYWluIHRvIGVuc3VyZSBsb2dpYyBkb2VzIG5vdCBkaWZmZXIgaW4gcHJvZHVjdGlvbi5cbiAqL1xuXG52YXIgdmFsaWRhdGVGb3JtYXQgPSBmdW5jdGlvbiB2YWxpZGF0ZUZvcm1hdChmb3JtYXQpIHt9O1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YWxpZGF0ZUZvcm1hdCA9IGZ1bmN0aW9uIHZhbGlkYXRlRm9ybWF0KGZvcm1hdCkge1xuICAgIGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhcmlhbnQgcmVxdWlyZXMgYW4gZXJyb3IgbWVzc2FnZSBhcmd1bWVudCcpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gaW52YXJpYW50KGNvbmRpdGlvbiwgZm9ybWF0LCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHZhbGlkYXRlRm9ybWF0KGZvcm1hdCk7XG5cbiAgaWYgKCFjb25kaXRpb24pIHtcbiAgICB2YXIgZXJyb3I7XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcignTWluaWZpZWQgZXhjZXB0aW9uIG9jY3VycmVkOyB1c2UgdGhlIG5vbi1taW5pZmllZCBkZXYgZW52aXJvbm1lbnQgJyArICdmb3IgdGhlIGZ1bGwgZXJyb3IgbWVzc2FnZSBhbmQgYWRkaXRpb25hbCBoZWxwZnVsIHdhcm5pbmdzLicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYXJncyA9IFthLCBiLCBjLCBkLCBlLCBmXTtcbiAgICAgIHZhciBhcmdJbmRleCA9IDA7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcihmb3JtYXQucmVwbGFjZSgvJXMvZywgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gYXJnc1thcmdJbmRleCsrXTtcbiAgICAgIH0pKTtcbiAgICAgIGVycm9yLm5hbWUgPSAnSW52YXJpYW50IFZpb2xhdGlvbic7XG4gICAgfVxuXG4gICAgZXJyb3IuZnJhbWVzVG9Qb3AgPSAxOyAvLyB3ZSBkb24ndCBjYXJlIGFib3V0IGludmFyaWFudCdzIG93biBmcmFtZVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW52YXJpYW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9lbXB0eUZ1bmN0aW9uJyk7XG5cbi8qKlxuICogU2ltaWxhciB0byBpbnZhcmlhbnQgYnV0IG9ubHkgbG9ncyBhIHdhcm5pbmcgaWYgdGhlIGNvbmRpdGlvbiBpcyBub3QgbWV0LlxuICogVGhpcyBjYW4gYmUgdXNlZCB0byBsb2cgaXNzdWVzIGluIGRldmVsb3BtZW50IGVudmlyb25tZW50cyBpbiBjcml0aWNhbFxuICogcGF0aHMuIFJlbW92aW5nIHRoZSBsb2dnaW5nIGNvZGUgZm9yIHByb2R1Y3Rpb24gZW52aXJvbm1lbnRzIHdpbGwga2VlcCB0aGVcbiAqIHNhbWUgbG9naWMgYW5kIGZvbGxvdyB0aGUgc2FtZSBjb2RlIHBhdGhzLlxuICovXG5cbnZhciB3YXJuaW5nID0gZW1wdHlGdW5jdGlvbjtcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcHJpbnRXYXJuaW5nID0gZnVuY3Rpb24gcHJpbnRXYXJuaW5nKGZvcm1hdCkge1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgIGFyZ3NbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgfVxuXG4gICAgICB2YXIgYXJnSW5kZXggPSAwO1xuICAgICAgdmFyIG1lc3NhZ2UgPSAnV2FybmluZzogJyArIGZvcm1hdC5yZXBsYWNlKC8lcy9nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBhcmdzW2FyZ0luZGV4KytdO1xuICAgICAgfSk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICAvLyAtLS0gV2VsY29tZSB0byBkZWJ1Z2dpbmcgUmVhY3QgLS0tXG4gICAgICAgIC8vIFRoaXMgZXJyb3Igd2FzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHRoYXQgeW91IGNhbiB1c2UgdGhpcyBzdGFja1xuICAgICAgICAvLyB0byBmaW5kIHRoZSBjYWxsc2l0ZSB0aGF0IGNhdXNlZCB0aGlzIHdhcm5pbmcgdG8gZmlyZS5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfSBjYXRjaCAoeCkge31cbiAgICB9O1xuXG4gICAgd2FybmluZyA9IGZ1bmN0aW9uIHdhcm5pbmcoY29uZGl0aW9uLCBmb3JtYXQpIHtcbiAgICAgIGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2B3YXJuaW5nKGNvbmRpdGlvbiwgZm9ybWF0LCAuLi5hcmdzKWAgcmVxdWlyZXMgYSB3YXJuaW5nICcgKyAnbWVzc2FnZSBhcmd1bWVudCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZm9ybWF0LmluZGV4T2YoJ0ZhaWxlZCBDb21wb3NpdGUgcHJvcFR5cGU6ICcpID09PSAwKSB7XG4gICAgICAgIHJldHVybjsgLy8gSWdub3JlIENvbXBvc2l0ZUNvbXBvbmVudCBwcm9wdHlwZSBjaGVjay5cbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbjIgPiAyID8gX2xlbjIgLSAyIDogMCksIF9rZXkyID0gMjsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICAgIGFyZ3NbX2tleTIgLSAyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICAgIH1cblxuICAgICAgICBwcmludFdhcm5pbmcuYXBwbHkodW5kZWZpbmVkLCBbZm9ybWF0XS5jb25jYXQoYXJncykpO1xuICAgICAgfVxuICAgIH07XG4gIH0pKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd2FybmluZzsiLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgncmVhY3QvbGliL1JlYWN0RE9NJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgncmVhY3QvbGliL1JlYWN0RE9NU2VydmVyJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTtcblxudmFyIF9wcm9wVHlwZXMgPSByZXF1aXJlKCdwcm9wLXR5cGVzJyk7XG5cbnZhciBfcHJvcFR5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3Byb3BUeXBlcyk7XG5cbnZhciBfcmVhY3REb20gPSByZXF1aXJlKCdyZWFjdC1kb20nKTtcblxudmFyIF9ldmVudGxpc3RlbmVyID0gcmVxdWlyZSgnZXZlbnRsaXN0ZW5lcicpO1xuXG52YXIgX2xvZGFzaCA9IHJlcXVpcmUoJ2xvZGFzaC5kZWJvdW5jZScpO1xuXG52YXIgX2xvZGFzaDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9sb2Rhc2gpO1xuXG52YXIgX2xvZGFzaDMgPSByZXF1aXJlKCdsb2Rhc2gudGhyb3R0bGUnKTtcblxudmFyIF9sb2Rhc2g0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbG9kYXNoMyk7XG5cbnZhciBfcGFyZW50U2Nyb2xsID0gcmVxdWlyZSgnLi91dGlscy9wYXJlbnRTY3JvbGwnKTtcblxudmFyIF9wYXJlbnRTY3JvbGwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcGFyZW50U2Nyb2xsKTtcblxudmFyIF9pblZpZXdwb3J0ID0gcmVxdWlyZSgnLi91dGlscy9pblZpZXdwb3J0Jyk7XG5cbnZhciBfaW5WaWV3cG9ydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pblZpZXdwb3J0KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSA/IGNhbGwgOiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgTGF6eUxvYWQgPSBmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoTGF6eUxvYWQsIF9Db21wb25lbnQpO1xuXG4gIGZ1bmN0aW9uIExhenlMb2FkKHByb3BzKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExhenlMb2FkKTtcblxuICAgIHZhciBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIChMYXp5TG9hZC5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKExhenlMb2FkKSkuY2FsbCh0aGlzLCBwcm9wcykpO1xuXG4gICAgX3RoaXMubGF6eUxvYWRIYW5kbGVyID0gX3RoaXMubGF6eUxvYWRIYW5kbGVyLmJpbmQoX3RoaXMpO1xuXG4gICAgaWYgKHByb3BzLnRocm90dGxlID4gMCkge1xuICAgICAgaWYgKHByb3BzLmRlYm91bmNlKSB7XG4gICAgICAgIF90aGlzLmxhenlMb2FkSGFuZGxlciA9ICgwLCBfbG9kYXNoMi5kZWZhdWx0KShfdGhpcy5sYXp5TG9hZEhhbmRsZXIsIHByb3BzLnRocm90dGxlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF90aGlzLmxhenlMb2FkSGFuZGxlciA9ICgwLCBfbG9kYXNoNC5kZWZhdWx0KShfdGhpcy5sYXp5TG9hZEhhbmRsZXIsIHByb3BzLnRocm90dGxlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfdGhpcy5zdGF0ZSA9IHsgdmlzaWJsZTogZmFsc2UgfTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoTGF6eUxvYWQsIFt7XG4gICAga2V5OiAnY29tcG9uZW50RGlkTW91bnQnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgIHRoaXMuX21vdW50ZWQgPSB0cnVlO1xuICAgICAgdmFyIGV2ZW50Tm9kZSA9IHRoaXMuZ2V0RXZlbnROb2RlKCk7XG5cbiAgICAgIHRoaXMubGF6eUxvYWRIYW5kbGVyKCk7XG5cbiAgICAgIGlmICh0aGlzLmxhenlMb2FkSGFuZGxlci5mbHVzaCkge1xuICAgICAgICB0aGlzLmxhenlMb2FkSGFuZGxlci5mbHVzaCgpO1xuICAgICAgfVxuXG4gICAgICAoMCwgX2V2ZW50bGlzdGVuZXIuYWRkKSh3aW5kb3csICdyZXNpemUnLCB0aGlzLmxhenlMb2FkSGFuZGxlcik7XG4gICAgICAoMCwgX2V2ZW50bGlzdGVuZXIuYWRkKShldmVudE5vZGUsICdzY3JvbGwnLCB0aGlzLmxhenlMb2FkSGFuZGxlcik7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKSB7XG4gICAgICBpZiAoIXRoaXMuc3RhdGUudmlzaWJsZSkge1xuICAgICAgICB0aGlzLmxhenlMb2FkSGFuZGxlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ3Nob3VsZENvbXBvbmVudFVwZGF0ZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNob3VsZENvbXBvbmVudFVwZGF0ZShfbmV4dFByb3BzLCBuZXh0U3RhdGUpIHtcbiAgICAgIHJldHVybiBuZXh0U3RhdGUudmlzaWJsZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdjb21wb25lbnRXaWxsVW5tb3VudCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgdGhpcy5fbW91bnRlZCA9IGZhbHNlO1xuICAgICAgaWYgKHRoaXMubGF6eUxvYWRIYW5kbGVyLmNhbmNlbCkge1xuICAgICAgICB0aGlzLmxhenlMb2FkSGFuZGxlci5jYW5jZWwoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5kZXRhY2hMaXN0ZW5lcnMoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdnZXRFdmVudE5vZGUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRFdmVudE5vZGUoKSB7XG4gICAgICByZXR1cm4gKDAsIF9wYXJlbnRTY3JvbGwyLmRlZmF1bHQpKCgwLCBfcmVhY3REb20uZmluZERPTU5vZGUpKHRoaXMpKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdnZXRPZmZzZXQnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRPZmZzZXQoKSB7XG4gICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcyxcbiAgICAgICAgICBvZmZzZXQgPSBfcHJvcHMub2Zmc2V0LFxuICAgICAgICAgIG9mZnNldFZlcnRpY2FsID0gX3Byb3BzLm9mZnNldFZlcnRpY2FsLFxuICAgICAgICAgIG9mZnNldEhvcml6b250YWwgPSBfcHJvcHMub2Zmc2V0SG9yaXpvbnRhbCxcbiAgICAgICAgICBvZmZzZXRUb3AgPSBfcHJvcHMub2Zmc2V0VG9wLFxuICAgICAgICAgIG9mZnNldEJvdHRvbSA9IF9wcm9wcy5vZmZzZXRCb3R0b20sXG4gICAgICAgICAgb2Zmc2V0TGVmdCA9IF9wcm9wcy5vZmZzZXRMZWZ0LFxuICAgICAgICAgIG9mZnNldFJpZ2h0ID0gX3Byb3BzLm9mZnNldFJpZ2h0LFxuICAgICAgICAgIHRocmVzaG9sZCA9IF9wcm9wcy50aHJlc2hvbGQ7XG5cblxuICAgICAgdmFyIF9vZmZzZXRBbGwgPSB0aHJlc2hvbGQgfHwgb2Zmc2V0O1xuICAgICAgdmFyIF9vZmZzZXRWZXJ0aWNhbCA9IG9mZnNldFZlcnRpY2FsIHx8IF9vZmZzZXRBbGw7XG4gICAgICB2YXIgX29mZnNldEhvcml6b250YWwgPSBvZmZzZXRIb3Jpem9udGFsIHx8IF9vZmZzZXRBbGw7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogb2Zmc2V0VG9wIHx8IF9vZmZzZXRWZXJ0aWNhbCxcbiAgICAgICAgYm90dG9tOiBvZmZzZXRCb3R0b20gfHwgX29mZnNldFZlcnRpY2FsLFxuICAgICAgICBsZWZ0OiBvZmZzZXRMZWZ0IHx8IF9vZmZzZXRIb3Jpem9udGFsLFxuICAgICAgICByaWdodDogb2Zmc2V0UmlnaHQgfHwgX29mZnNldEhvcml6b250YWxcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnbGF6eUxvYWRIYW5kbGVyJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gbGF6eUxvYWRIYW5kbGVyKCkge1xuICAgICAgaWYgKCF0aGlzLl9tb3VudGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBvZmZzZXQgPSB0aGlzLmdldE9mZnNldCgpO1xuICAgICAgdmFyIG5vZGUgPSAoMCwgX3JlYWN0RG9tLmZpbmRET01Ob2RlKSh0aGlzKTtcbiAgICAgIHZhciBldmVudE5vZGUgPSB0aGlzLmdldEV2ZW50Tm9kZSgpO1xuXG4gICAgICBpZiAoKDAsIF9pblZpZXdwb3J0Mi5kZWZhdWx0KShub2RlLCBldmVudE5vZGUsIG9mZnNldCkpIHtcbiAgICAgICAgdmFyIG9uQ29udGVudFZpc2libGUgPSB0aGlzLnByb3BzLm9uQ29udGVudFZpc2libGU7XG5cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmlzaWJsZTogdHJ1ZSB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKG9uQ29udGVudFZpc2libGUpIHtcbiAgICAgICAgICAgIG9uQ29udGVudFZpc2libGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldGFjaExpc3RlbmVycygpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2RldGFjaExpc3RlbmVycycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRldGFjaExpc3RlbmVycygpIHtcbiAgICAgIHZhciBldmVudE5vZGUgPSB0aGlzLmdldEV2ZW50Tm9kZSgpO1xuXG4gICAgICAoMCwgX2V2ZW50bGlzdGVuZXIucmVtb3ZlKSh3aW5kb3csICdyZXNpemUnLCB0aGlzLmxhenlMb2FkSGFuZGxlcik7XG4gICAgICAoMCwgX2V2ZW50bGlzdGVuZXIucmVtb3ZlKShldmVudE5vZGUsICdzY3JvbGwnLCB0aGlzLmxhenlMb2FkSGFuZGxlcik7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAncmVuZGVyJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIF9wcm9wczIgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGNoaWxkcmVuID0gX3Byb3BzMi5jaGlsZHJlbixcbiAgICAgICAgICBjbGFzc05hbWUgPSBfcHJvcHMyLmNsYXNzTmFtZSxcbiAgICAgICAgICBoZWlnaHQgPSBfcHJvcHMyLmhlaWdodCxcbiAgICAgICAgICB3aWR0aCA9IF9wcm9wczIud2lkdGg7XG4gICAgICB2YXIgdmlzaWJsZSA9IHRoaXMuc3RhdGUudmlzaWJsZTtcblxuXG4gICAgICB2YXIgZWxTdHlsZXMgPSB7IGhlaWdodDogaGVpZ2h0LCB3aWR0aDogd2lkdGggfTtcbiAgICAgIHZhciBlbENsYXNzZXMgPSAnTGF6eUxvYWQnICsgKHZpc2libGUgPyAnIGlzLXZpc2libGUnIDogJycpICsgKGNsYXNzTmFtZSA/ICcgJyArIGNsYXNzTmFtZSA6ICcnKTtcblxuICAgICAgcmV0dXJuIF9yZWFjdDIuZGVmYXVsdC5jcmVhdGVFbGVtZW50KHRoaXMucHJvcHMuZWxlbWVudFR5cGUsIHtcbiAgICAgICAgY2xhc3NOYW1lOiBlbENsYXNzZXMsXG4gICAgICAgIHN0eWxlOiBlbFN0eWxlc1xuICAgICAgfSwgdmlzaWJsZSAmJiBfcmVhY3QuQ2hpbGRyZW4ub25seShjaGlsZHJlbikpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBMYXp5TG9hZDtcbn0oX3JlYWN0LkNvbXBvbmVudCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IExhenlMb2FkO1xuXG5cbkxhenlMb2FkLnByb3BUeXBlcyA9IHtcbiAgY2hpbGRyZW46IF9wcm9wVHlwZXMyLmRlZmF1bHQubm9kZS5pc1JlcXVpcmVkLFxuICBjbGFzc05hbWU6IF9wcm9wVHlwZXMyLmRlZmF1bHQuc3RyaW5nLFxuICBkZWJvdW5jZTogX3Byb3BUeXBlczIuZGVmYXVsdC5ib29sLFxuICBlbGVtZW50VHlwZTogX3Byb3BUeXBlczIuZGVmYXVsdC5zdHJpbmcsXG4gIGhlaWdodDogX3Byb3BUeXBlczIuZGVmYXVsdC5vbmVPZlR5cGUoW19wcm9wVHlwZXMyLmRlZmF1bHQuc3RyaW5nLCBfcHJvcFR5cGVzMi5kZWZhdWx0Lm51bWJlcl0pLFxuICBvZmZzZXQ6IF9wcm9wVHlwZXMyLmRlZmF1bHQubnVtYmVyLFxuICBvZmZzZXRCb3R0b206IF9wcm9wVHlwZXMyLmRlZmF1bHQubnVtYmVyLFxuICBvZmZzZXRIb3Jpem9udGFsOiBfcHJvcFR5cGVzMi5kZWZhdWx0Lm51bWJlcixcbiAgb2Zmc2V0TGVmdDogX3Byb3BUeXBlczIuZGVmYXVsdC5udW1iZXIsXG4gIG9mZnNldFJpZ2h0OiBfcHJvcFR5cGVzMi5kZWZhdWx0Lm51bWJlcixcbiAgb2Zmc2V0VG9wOiBfcHJvcFR5cGVzMi5kZWZhdWx0Lm51bWJlcixcbiAgb2Zmc2V0VmVydGljYWw6IF9wcm9wVHlwZXMyLmRlZmF1bHQubnVtYmVyLFxuICB0aHJlc2hvbGQ6IF9wcm9wVHlwZXMyLmRlZmF1bHQubnVtYmVyLFxuICB0aHJvdHRsZTogX3Byb3BUeXBlczIuZGVmYXVsdC5udW1iZXIsXG4gIHdpZHRoOiBfcHJvcFR5cGVzMi5kZWZhdWx0Lm9uZU9mVHlwZShbX3Byb3BUeXBlczIuZGVmYXVsdC5zdHJpbmcsIF9wcm9wVHlwZXMyLmRlZmF1bHQubnVtYmVyXSksXG4gIG9uQ29udGVudFZpc2libGU6IF9wcm9wVHlwZXMyLmRlZmF1bHQuZnVuY1xufTtcblxuTGF6eUxvYWQuZGVmYXVsdFByb3BzID0ge1xuICBlbGVtZW50VHlwZTogJ2RpdicsXG4gIGRlYm91bmNlOiB0cnVlLFxuICBvZmZzZXQ6IDAsXG4gIG9mZnNldEJvdHRvbTogMCxcbiAgb2Zmc2V0SG9yaXpvbnRhbDogMCxcbiAgb2Zmc2V0TGVmdDogMCxcbiAgb2Zmc2V0UmlnaHQ6IDAsXG4gIG9mZnNldFRvcDogMCxcbiAgb2Zmc2V0VmVydGljYWw6IDAsXG4gIHRocm90dGxlOiAyNTBcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBnZXRFbGVtZW50UG9zaXRpb247XG4vKlxyXG4qIEZpbmRzIGVsZW1lbnQncyBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgd2hvbGUgZG9jdW1lbnQsXHJcbiogcmF0aGVyIHRoYW4gdG8gdGhlIHZpZXdwb3J0IGFzIGl0IGlzIHRoZSBjYXNlIHdpdGggLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLlxyXG4qL1xuZnVuY3Rpb24gZ2V0RWxlbWVudFBvc2l0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gIHJldHVybiB7XG4gICAgdG9wOiByZWN0LnRvcCArIHdpbmRvdy5wYWdlWU9mZnNldCxcbiAgICBsZWZ0OiByZWN0LmxlZnQgKyB3aW5kb3cucGFnZVhPZmZzZXRcbiAgfTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpblZpZXdwb3J0O1xuXG52YXIgX2dldEVsZW1lbnRQb3NpdGlvbiA9IHJlcXVpcmUoJy4vZ2V0RWxlbWVudFBvc2l0aW9uJyk7XG5cbnZhciBfZ2V0RWxlbWVudFBvc2l0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2dldEVsZW1lbnRQb3NpdGlvbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBpc0hpZGRlbiA9IGZ1bmN0aW9uIGlzSGlkZGVuKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQub2Zmc2V0UGFyZW50ID09PSBudWxsO1xufTtcblxuZnVuY3Rpb24gaW5WaWV3cG9ydChlbGVtZW50LCBjb250YWluZXIsIGN1c3RvbU9mZnNldCkge1xuICBpZiAoaXNIaWRkZW4oZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgdG9wID0gdm9pZCAwO1xuICB2YXIgYm90dG9tID0gdm9pZCAwO1xuICB2YXIgbGVmdCA9IHZvaWQgMDtcbiAgdmFyIHJpZ2h0ID0gdm9pZCAwO1xuXG4gIGlmICh0eXBlb2YgY29udGFpbmVyID09PSAndW5kZWZpbmVkJyB8fCBjb250YWluZXIgPT09IHdpbmRvdykge1xuICAgIHRvcCA9IHdpbmRvdy5wYWdlWU9mZnNldDtcbiAgICBsZWZ0ID0gd2luZG93LnBhZ2VYT2Zmc2V0O1xuICAgIGJvdHRvbSA9IHRvcCArIHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICByaWdodCA9IGxlZnQgKyB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgfSBlbHNlIHtcbiAgICB2YXIgY29udGFpbmVyUG9zaXRpb24gPSAoMCwgX2dldEVsZW1lbnRQb3NpdGlvbjIuZGVmYXVsdCkoY29udGFpbmVyKTtcblxuICAgIHRvcCA9IGNvbnRhaW5lclBvc2l0aW9uLnRvcDtcbiAgICBsZWZ0ID0gY29udGFpbmVyUG9zaXRpb24ubGVmdDtcbiAgICBib3R0b20gPSB0b3AgKyBjb250YWluZXIub2Zmc2V0SGVpZ2h0O1xuICAgIHJpZ2h0ID0gbGVmdCArIGNvbnRhaW5lci5vZmZzZXRXaWR0aDtcbiAgfVxuXG4gIHZhciBlbGVtZW50UG9zaXRpb24gPSAoMCwgX2dldEVsZW1lbnRQb3NpdGlvbjIuZGVmYXVsdCkoZWxlbWVudCk7XG5cbiAgcmV0dXJuIHRvcCA8PSBlbGVtZW50UG9zaXRpb24udG9wICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgKyBjdXN0b21PZmZzZXQudG9wICYmIGJvdHRvbSA+PSBlbGVtZW50UG9zaXRpb24udG9wIC0gY3VzdG9tT2Zmc2V0LmJvdHRvbSAmJiBsZWZ0IDw9IGVsZW1lbnRQb3NpdGlvbi5sZWZ0ICsgZWxlbWVudC5vZmZzZXRXaWR0aCArIGN1c3RvbU9mZnNldC5sZWZ0ICYmIHJpZ2h0ID49IGVsZW1lbnRQb3NpdGlvbi5sZWZ0IC0gY3VzdG9tT2Zmc2V0LnJpZ2h0O1xufSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbnZhciBzdHlsZSA9IGZ1bmN0aW9uIHN0eWxlKGVsZW1lbnQsIHByb3ApIHtcbiAgcmV0dXJuIHR5cGVvZiBnZXRDb21wdXRlZFN0eWxlICE9PSAndW5kZWZpbmVkJyA/IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wKSA6IGVsZW1lbnQuc3R5bGVbcHJvcF07XG59O1xuXG52YXIgb3ZlcmZsb3cgPSBmdW5jdGlvbiBvdmVyZmxvdyhlbGVtZW50KSB7XG4gIHJldHVybiBzdHlsZShlbGVtZW50LCAnb3ZlcmZsb3cnKSArIHN0eWxlKGVsZW1lbnQsICdvdmVyZmxvdy15JykgKyBzdHlsZShlbGVtZW50LCAnb3ZlcmZsb3cteCcpO1xufTtcblxudmFyIHNjcm9sbFBhcmVudCA9IGZ1bmN0aW9uIHNjcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG5cbiAgdmFyIHBhcmVudCA9IGVsZW1lbnQ7XG5cbiAgd2hpbGUgKHBhcmVudCkge1xuICAgIGlmIChwYXJlbnQgPT09IGRvY3VtZW50LmJvZHkgfHwgcGFyZW50ID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICghcGFyZW50LnBhcmVudE5vZGUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICgvKHNjcm9sbHxhdXRvKS8udGVzdChvdmVyZmxvdyhwYXJlbnQpKSkge1xuICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICB9XG5cbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuXG4gIHJldHVybiB3aW5kb3c7XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBzY3JvbGxQYXJlbnQ7IiwiLyoqXG4gKiBSZXByZXNlbnRzIGEgY2FuY2VsbGF0aW9uIGNhdXNlZCBieSBuYXZpZ2F0aW5nIGF3YXlcbiAqIGJlZm9yZSB0aGUgcHJldmlvdXMgdHJhbnNpdGlvbiBoYXMgZnVsbHkgcmVzb2x2ZWQuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBDYW5jZWxsYXRpb24oKSB7fVxuXG5tb2R1bGUuZXhwb3J0cyA9IENhbmNlbGxhdGlvbjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcbnZhciBjYW5Vc2VET00gPSByZXF1aXJlKCdjYW4tdXNlLWRvbScpO1xuXG52YXIgSGlzdG9yeSA9IHtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIGhpc3RvcnkuXG4gICAqXG4gICAqIE5vdGU6IFRoaXMgcHJvcGVydHkgaXMgcmVhZC1vbmx5LlxuICAgKi9cbiAgbGVuZ3RoOiAxLFxuXG4gIC8qKlxuICAgKiBTZW5kcyB0aGUgYnJvd3NlciBiYWNrIG9uZSBlbnRyeSBpbiB0aGUgaGlzdG9yeS5cbiAgICovXG4gIGJhY2s6IGZ1bmN0aW9uIGJhY2soKSB7XG4gICAgaW52YXJpYW50KGNhblVzZURPTSwgJ0Nhbm5vdCB1c2UgSGlzdG9yeS5iYWNrIHdpdGhvdXQgYSBET00nKTtcblxuICAgIC8vIERvIHRoaXMgZmlyc3Qgc28gdGhhdCBIaXN0b3J5Lmxlbmd0aCB3aWxsXG4gICAgLy8gYmUgYWNjdXJhdGUgaW4gbG9jYXRpb24gY2hhbmdlIGxpc3RlbmVycy5cbiAgICBIaXN0b3J5Lmxlbmd0aCAtPSAxO1xuXG4gICAgd2luZG93Lmhpc3RvcnkuYmFjaygpO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSGlzdG9yeTsiLCIvKiBqc2hpbnQgLVcwODQgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoJ3ZhbHVlJyBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbnZhciBQYXRoVXRpbHMgPSByZXF1aXJlKCcuL1BhdGhVdGlscycpO1xuXG5mdW5jdGlvbiBkZWVwU2VhcmNoKHJvdXRlLCBwYXRobmFtZSwgcXVlcnkpIHtcbiAgLy8gQ2hlY2sgdGhlIHN1YnRyZWUgZmlyc3QgdG8gZmluZCB0aGUgbW9zdCBkZWVwbHktbmVzdGVkIG1hdGNoLlxuICB2YXIgY2hpbGRSb3V0ZXMgPSByb3V0ZS5jaGlsZFJvdXRlcztcbiAgaWYgKGNoaWxkUm91dGVzKSB7XG4gICAgdmFyIG1hdGNoLCBjaGlsZFJvdXRlO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjaGlsZFJvdXRlcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2hpbGRSb3V0ZSA9IGNoaWxkUm91dGVzW2ldO1xuXG4gICAgICBpZiAoY2hpbGRSb3V0ZS5pc0RlZmF1bHQgfHwgY2hpbGRSb3V0ZS5pc05vdEZvdW5kKSBjb250aW51ZTsgLy8gQ2hlY2sgdGhlc2UgaW4gb3JkZXIgbGF0ZXIuXG5cbiAgICAgIGlmIChtYXRjaCA9IGRlZXBTZWFyY2goY2hpbGRSb3V0ZSwgcGF0aG5hbWUsIHF1ZXJ5KSkge1xuICAgICAgICAvLyBBIHJvdXRlIGluIHRoZSBzdWJ0cmVlIG1hdGNoZWQhIEFkZCB0aGlzIHJvdXRlIGFuZCB3ZSdyZSBkb25lLlxuICAgICAgICBtYXRjaC5yb3V0ZXMudW5zaGlmdChyb3V0ZSk7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBObyBjaGlsZCByb3V0ZXMgbWF0Y2hlZDsgdHJ5IHRoZSBkZWZhdWx0IHJvdXRlLlxuICB2YXIgZGVmYXVsdFJvdXRlID0gcm91dGUuZGVmYXVsdFJvdXRlO1xuICBpZiAoZGVmYXVsdFJvdXRlICYmIChwYXJhbXMgPSBQYXRoVXRpbHMuZXh0cmFjdFBhcmFtcyhkZWZhdWx0Um91dGUucGF0aCwgcGF0aG5hbWUpKSkgcmV0dXJuIG5ldyBNYXRjaChwYXRobmFtZSwgcGFyYW1zLCBxdWVyeSwgW3JvdXRlLCBkZWZhdWx0Um91dGVdKTtcblxuICAvLyBEb2VzIHRoZSBcIm5vdCBmb3VuZFwiIHJvdXRlIG1hdGNoP1xuICB2YXIgbm90Rm91bmRSb3V0ZSA9IHJvdXRlLm5vdEZvdW5kUm91dGU7XG4gIGlmIChub3RGb3VuZFJvdXRlICYmIChwYXJhbXMgPSBQYXRoVXRpbHMuZXh0cmFjdFBhcmFtcyhub3RGb3VuZFJvdXRlLnBhdGgsIHBhdGhuYW1lKSkpIHJldHVybiBuZXcgTWF0Y2gocGF0aG5hbWUsIHBhcmFtcywgcXVlcnksIFtyb3V0ZSwgbm90Rm91bmRSb3V0ZV0pO1xuXG4gIC8vIExhc3QgYXR0ZW1wdDogY2hlY2sgdGhpcyByb3V0ZS5cbiAgdmFyIHBhcmFtcyA9IFBhdGhVdGlscy5leHRyYWN0UGFyYW1zKHJvdXRlLnBhdGgsIHBhdGhuYW1lKTtcbiAgaWYgKHBhcmFtcykgcmV0dXJuIG5ldyBNYXRjaChwYXRobmFtZSwgcGFyYW1zLCBxdWVyeSwgW3JvdXRlXSk7XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbnZhciBNYXRjaCA9IChmdW5jdGlvbiAoKSB7XG4gIF9jcmVhdGVDbGFzcyhNYXRjaCwgbnVsbCwgW3tcbiAgICBrZXk6ICdmaW5kTWF0Y2gnLFxuXG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gbWF0Y2ggZGVwdGgtZmlyc3QgYSByb3V0ZSBpbiB0aGUgZ2l2ZW4gcm91dGUnc1xuICAgICAqIHN1YnRyZWUgYWdhaW5zdCB0aGUgZ2l2ZW4gcGF0aCBhbmQgcmV0dXJucyB0aGUgbWF0Y2ggaWYgaXRcbiAgICAgKiBzdWNjZWVkcywgbnVsbCBpZiBubyBtYXRjaCBjYW4gYmUgbWFkZS5cbiAgICAgKi9cbiAgICB2YWx1ZTogZnVuY3Rpb24gZmluZE1hdGNoKHJvdXRlcywgcGF0aCkge1xuICAgICAgdmFyIHBhdGhuYW1lID0gUGF0aFV0aWxzLndpdGhvdXRRdWVyeShwYXRoKTtcbiAgICAgIHZhciBxdWVyeSA9IFBhdGhVdGlscy5leHRyYWN0UXVlcnkocGF0aCk7XG4gICAgICB2YXIgbWF0Y2ggPSBudWxsO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcm91dGVzLmxlbmd0aDsgbWF0Y2ggPT0gbnVsbCAmJiBpIDwgbGVuOyArK2kpIG1hdGNoID0gZGVlcFNlYXJjaChyb3V0ZXNbaV0sIHBhdGhuYW1lLCBxdWVyeSk7XG5cbiAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9XG4gIH1dKTtcblxuICBmdW5jdGlvbiBNYXRjaChwYXRobmFtZSwgcGFyYW1zLCBxdWVyeSwgcm91dGVzKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE1hdGNoKTtcblxuICAgIHRoaXMucGF0aG5hbWUgPSBwYXRobmFtZTtcbiAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICB0aGlzLnF1ZXJ5ID0gcXVlcnk7XG4gICAgdGhpcy5yb3V0ZXMgPSByb3V0ZXM7XG4gIH1cblxuICByZXR1cm4gTWF0Y2g7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGNoOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFByb3BUeXBlcyA9IHJlcXVpcmUoJy4vUHJvcFR5cGVzJyk7XG5cbi8qKlxuICogQSBtaXhpbiBmb3IgY29tcG9uZW50cyB0aGF0IG1vZGlmeSB0aGUgVVJMLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICB2YXIgTXlMaW5rID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICogICAgIG1peGluczogWyBSb3V0ZXIuTmF2aWdhdGlvbiBdLFxuICogICAgIGhhbmRsZUNsaWNrKGV2ZW50KSB7XG4gKiAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICogICAgICAgdGhpcy50cmFuc2l0aW9uVG8oJ2FSb3V0ZScsIHsgdGhlOiAncGFyYW1zJyB9LCB7IHRoZTogJ3F1ZXJ5JyB9KTtcbiAqICAgICB9LFxuICogICAgIHJlbmRlcigpIHtcbiAqICAgICAgIHJldHVybiAoXG4gKiAgICAgICAgIDxhIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2t9PkNsaWNrIG1lITwvYT5cbiAqICAgICAgICk7XG4gKiAgICAgfVxuICogICB9KTtcbiAqL1xudmFyIE5hdmlnYXRpb24gPSB7XG5cbiAgY29udGV4dFR5cGVzOiB7XG4gICAgcm91dGVyOiBQcm9wVHlwZXMucm91dGVyLmlzUmVxdWlyZWRcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBhYnNvbHV0ZSBVUkwgcGF0aCBjcmVhdGVkIGZyb20gdGhlIGdpdmVuIHJvdXRlXG4gICAqIG5hbWUsIFVSTCBwYXJhbWV0ZXJzLCBhbmQgcXVlcnkgdmFsdWVzLlxuICAgKi9cbiAgbWFrZVBhdGg6IGZ1bmN0aW9uIG1ha2VQYXRoKHRvLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5yb3V0ZXIubWFrZVBhdGgodG8sIHBhcmFtcywgcXVlcnkpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHRoYXQgbWF5IHNhZmVseSBiZSB1c2VkIGFzIHRoZSBocmVmIG9mIGFcbiAgICogbGluayB0byB0aGUgcm91dGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICovXG4gIG1ha2VIcmVmOiBmdW5jdGlvbiBtYWtlSHJlZih0bywgcGFyYW1zLCBxdWVyeSkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLm1ha2VIcmVmKHRvLCBwYXJhbXMsIHF1ZXJ5KTtcbiAgfSxcblxuICAvKipcbiAgICogVHJhbnNpdGlvbnMgdG8gdGhlIFVSTCBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50cyBieSBwdXNoaW5nXG4gICAqIGEgbmV3IFVSTCBvbnRvIHRoZSBoaXN0b3J5IHN0YWNrLlxuICAgKi9cbiAgdHJhbnNpdGlvblRvOiBmdW5jdGlvbiB0cmFuc2l0aW9uVG8odG8sIHBhcmFtcywgcXVlcnkpIHtcbiAgICB0aGlzLmNvbnRleHQucm91dGVyLnRyYW5zaXRpb25Ubyh0bywgcGFyYW1zLCBxdWVyeSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFRyYW5zaXRpb25zIHRvIHRoZSBVUkwgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHMgYnkgcmVwbGFjaW5nXG4gICAqIHRoZSBjdXJyZW50IFVSTCBpbiB0aGUgaGlzdG9yeSBzdGFjay5cbiAgICovXG4gIHJlcGxhY2VXaXRoOiBmdW5jdGlvbiByZXBsYWNlV2l0aCh0bywgcGFyYW1zLCBxdWVyeSkge1xuICAgIHRoaXMuY29udGV4dC5yb3V0ZXIucmVwbGFjZVdpdGgodG8sIHBhcmFtcywgcXVlcnkpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBUcmFuc2l0aW9ucyB0byB0aGUgcHJldmlvdXMgVVJMLlxuICAgKi9cbiAgZ29CYWNrOiBmdW5jdGlvbiBnb0JhY2soKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5yb3V0ZXIuZ29CYWNrKCk7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBOYXZpZ2F0aW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ludmFyaWFudCcpO1xudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ29iamVjdC1hc3NpZ24nKTtcbnZhciBxcyA9IHJlcXVpcmUoJ3FzJyk7XG5cbnZhciBwYXJhbUNvbXBpbGVNYXRjaGVyID0gLzooW2EtekEtWl8kXVthLXpBLVowLTlfJF0qKXxbKi4oKVxcW1xcXVxcXFwrfHt9XiRdL2c7XG52YXIgcGFyYW1JbmplY3RNYXRjaGVyID0gLzooW2EtekEtWl8kXVthLXpBLVowLTlfJD9dKls/XT8pfFsqXS9nO1xudmFyIHBhcmFtSW5qZWN0VHJhaWxpbmdTbGFzaE1hdGNoZXIgPSAvXFwvXFwvXFw/fFxcL1xcP1xcL3xcXC9cXD8oPyFbXlxcLz1dKz0uKiQpL2c7XG52YXIgcXVlcnlNYXRjaGVyID0gL1xcPyguKikkLztcblxudmFyIF9jb21waWxlZFBhdHRlcm5zID0ge307XG5cbmZ1bmN0aW9uIGNvbXBpbGVQYXR0ZXJuKHBhdHRlcm4pIHtcbiAgaWYgKCEocGF0dGVybiBpbiBfY29tcGlsZWRQYXR0ZXJucykpIHtcbiAgICB2YXIgcGFyYW1OYW1lcyA9IFtdO1xuICAgIHZhciBzb3VyY2UgPSBwYXR0ZXJuLnJlcGxhY2UocGFyYW1Db21waWxlTWF0Y2hlciwgZnVuY3Rpb24gKG1hdGNoLCBwYXJhbU5hbWUpIHtcbiAgICAgIGlmIChwYXJhbU5hbWUpIHtcbiAgICAgICAgcGFyYW1OYW1lcy5wdXNoKHBhcmFtTmFtZSk7XG4gICAgICAgIHJldHVybiAnKFteLz8jXSspJztcbiAgICAgIH0gZWxzZSBpZiAobWF0Y2ggPT09ICcqJykge1xuICAgICAgICBwYXJhbU5hbWVzLnB1c2goJ3NwbGF0Jyk7XG4gICAgICAgIHJldHVybiAnKC4qPyknO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICdcXFxcJyArIG1hdGNoO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgX2NvbXBpbGVkUGF0dGVybnNbcGF0dGVybl0gPSB7XG4gICAgICBtYXRjaGVyOiBuZXcgUmVnRXhwKCdeJyArIHNvdXJjZSArICckJywgJ2knKSxcbiAgICAgIHBhcmFtTmFtZXM6IHBhcmFtTmFtZXNcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF9jb21waWxlZFBhdHRlcm5zW3BhdHRlcm5dO1xufVxuXG52YXIgUGF0aFV0aWxzID0ge1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHBhdGggaXMgYWJzb2x1dGUuXG4gICAqL1xuICBpc0Fic29sdXRlOiBmdW5jdGlvbiBpc0Fic29sdXRlKHBhdGgpIHtcbiAgICByZXR1cm4gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfSxcblxuICAvKipcbiAgICogSm9pbnMgdHdvIFVSTCBwYXRocyB0b2dldGhlci5cbiAgICovXG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oYSwgYikge1xuICAgIHJldHVybiBhLnJlcGxhY2UoL1xcLyokLywgJy8nKSArIGI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgdGhlIG5hbWVzIG9mIGFsbCBwYXJhbWV0ZXJzIGluIHRoZSBnaXZlbiBwYXR0ZXJuLlxuICAgKi9cbiAgZXh0cmFjdFBhcmFtTmFtZXM6IGZ1bmN0aW9uIGV4dHJhY3RQYXJhbU5hbWVzKHBhdHRlcm4pIHtcbiAgICByZXR1cm4gY29tcGlsZVBhdHRlcm4ocGF0dGVybikucGFyYW1OYW1lcztcbiAgfSxcblxuICAvKipcbiAgICogRXh0cmFjdHMgdGhlIHBvcnRpb25zIG9mIHRoZSBnaXZlbiBVUkwgcGF0aCB0aGF0IG1hdGNoIHRoZSBnaXZlbiBwYXR0ZXJuXG4gICAqIGFuZCByZXR1cm5zIGFuIG9iamVjdCBvZiBwYXJhbSBuYW1lID0+IHZhbHVlIHBhaXJzLiBSZXR1cm5zIG51bGwgaWYgdGhlXG4gICAqIHBhdHRlcm4gZG9lcyBub3QgbWF0Y2ggdGhlIGdpdmVuIHBhdGguXG4gICAqL1xuICBleHRyYWN0UGFyYW1zOiBmdW5jdGlvbiBleHRyYWN0UGFyYW1zKHBhdHRlcm4sIHBhdGgpIHtcbiAgICB2YXIgX2NvbXBpbGVQYXR0ZXJuID0gY29tcGlsZVBhdHRlcm4ocGF0dGVybik7XG5cbiAgICB2YXIgbWF0Y2hlciA9IF9jb21waWxlUGF0dGVybi5tYXRjaGVyO1xuICAgIHZhciBwYXJhbU5hbWVzID0gX2NvbXBpbGVQYXR0ZXJuLnBhcmFtTmFtZXM7XG5cbiAgICB2YXIgbWF0Y2ggPSBwYXRoLm1hdGNoKG1hdGNoZXIpO1xuXG4gICAgaWYgKCFtYXRjaCkgcmV0dXJuIG51bGw7XG5cbiAgICB2YXIgcGFyYW1zID0ge307XG5cbiAgICBwYXJhbU5hbWVzLmZvckVhY2goZnVuY3Rpb24gKHBhcmFtTmFtZSwgaW5kZXgpIHtcbiAgICAgIHBhcmFtc1twYXJhbU5hbWVdID0gbWF0Y2hbaW5kZXggKyAxXTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJhbXM7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB2ZXJzaW9uIG9mIHRoZSBnaXZlbiByb3V0ZSBwYXRoIHdpdGggcGFyYW1zIGludGVycG9sYXRlZC4gVGhyb3dzXG4gICAqIGlmIHRoZXJlIGlzIGEgZHluYW1pYyBzZWdtZW50IG9mIHRoZSByb3V0ZSBwYXRoIGZvciB3aGljaCB0aGVyZSBpcyBubyBwYXJhbS5cbiAgICovXG4gIGluamVjdFBhcmFtczogZnVuY3Rpb24gaW5qZWN0UGFyYW1zKHBhdHRlcm4sIHBhcmFtcykge1xuICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBzcGxhdEluZGV4ID0gMDtcblxuICAgIHJldHVybiBwYXR0ZXJuLnJlcGxhY2UocGFyYW1JbmplY3RNYXRjaGVyLCBmdW5jdGlvbiAobWF0Y2gsIHBhcmFtTmFtZSkge1xuICAgICAgcGFyYW1OYW1lID0gcGFyYW1OYW1lIHx8ICdzcGxhdCc7XG5cbiAgICAgIC8vIElmIHBhcmFtIGlzIG9wdGlvbmFsIGRvbid0IGNoZWNrIGZvciBleGlzdGVuY2VcbiAgICAgIGlmIChwYXJhbU5hbWUuc2xpY2UoLTEpID09PSAnPycpIHtcbiAgICAgICAgcGFyYW1OYW1lID0gcGFyYW1OYW1lLnNsaWNlKDAsIC0xKTtcblxuICAgICAgICBpZiAocGFyYW1zW3BhcmFtTmFtZV0gPT0gbnVsbCkgcmV0dXJuICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW52YXJpYW50KHBhcmFtc1twYXJhbU5hbWVdICE9IG51bGwsICdNaXNzaW5nIFwiJXNcIiBwYXJhbWV0ZXIgZm9yIHBhdGggXCIlc1wiJywgcGFyYW1OYW1lLCBwYXR0ZXJuKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNlZ21lbnQ7XG4gICAgICBpZiAocGFyYW1OYW1lID09PSAnc3BsYXQnICYmIEFycmF5LmlzQXJyYXkocGFyYW1zW3BhcmFtTmFtZV0pKSB7XG4gICAgICAgIHNlZ21lbnQgPSBwYXJhbXNbcGFyYW1OYW1lXVtzcGxhdEluZGV4KytdO1xuXG4gICAgICAgIGludmFyaWFudChzZWdtZW50ICE9IG51bGwsICdNaXNzaW5nIHNwbGF0ICMgJXMgZm9yIHBhdGggXCIlc1wiJywgc3BsYXRJbmRleCwgcGF0dGVybik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWdtZW50ID0gcGFyYW1zW3BhcmFtTmFtZV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzZWdtZW50O1xuICAgIH0pLnJlcGxhY2UocGFyYW1JbmplY3RUcmFpbGluZ1NsYXNoTWF0Y2hlciwgJy8nKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHBhcnNpbmcgYW55IHF1ZXJ5IHN0cmluZyBjb250YWluZWRcbiAgICogaW4gdGhlIGdpdmVuIHBhdGgsIG51bGwgaWYgdGhlIHBhdGggY29udGFpbnMgbm8gcXVlcnkgc3RyaW5nLlxuICAgKi9cbiAgZXh0cmFjdFF1ZXJ5OiBmdW5jdGlvbiBleHRyYWN0UXVlcnkocGF0aCkge1xuICAgIHZhciBtYXRjaCA9IHBhdGgubWF0Y2gocXVlcnlNYXRjaGVyKTtcbiAgICByZXR1cm4gbWF0Y2ggJiYgcXMucGFyc2UobWF0Y2hbMV0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdmVyc2lvbiBvZiB0aGUgZ2l2ZW4gcGF0aCB3aXRob3V0IHRoZSBxdWVyeSBzdHJpbmcuXG4gICAqL1xuICB3aXRob3V0UXVlcnk6IGZ1bmN0aW9uIHdpdGhvdXRRdWVyeShwYXRoKSB7XG4gICAgcmV0dXJuIHBhdGgucmVwbGFjZShxdWVyeU1hdGNoZXIsICcnKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhIHZlcnNpb24gb2YgdGhlIGdpdmVuIHBhdGggd2l0aCB0aGUgcGFyYW1ldGVycyBpbiB0aGUgZ2l2ZW5cbiAgICogcXVlcnkgbWVyZ2VkIGludG8gdGhlIHF1ZXJ5IHN0cmluZy5cbiAgICovXG4gIHdpdGhRdWVyeTogZnVuY3Rpb24gd2l0aFF1ZXJ5KHBhdGgsIHF1ZXJ5KSB7XG4gICAgdmFyIGV4aXN0aW5nUXVlcnkgPSBQYXRoVXRpbHMuZXh0cmFjdFF1ZXJ5KHBhdGgpO1xuXG4gICAgaWYgKGV4aXN0aW5nUXVlcnkpIHF1ZXJ5ID0gcXVlcnkgPyBhc3NpZ24oZXhpc3RpbmdRdWVyeSwgcXVlcnkpIDogZXhpc3RpbmdRdWVyeTtcblxuICAgIHZhciBxdWVyeVN0cmluZyA9IHFzLnN0cmluZ2lmeShxdWVyeSwgeyBhcnJheUZvcm1hdDogJ2JyYWNrZXRzJyB9KTtcblxuICAgIGlmIChxdWVyeVN0cmluZykgcmV0dXJuIFBhdGhVdGlscy53aXRob3V0UXVlcnkocGF0aCkgKyAnPycgKyBxdWVyeVN0cmluZztcblxuICAgIHJldHVybiBQYXRoVXRpbHMud2l0aG91dFF1ZXJ5KHBhdGgpO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUGF0aFV0aWxzOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ29iamVjdC1hc3NpZ24nKTtcbnZhciBSZWFjdFByb3BUeXBlcyA9IHJlcXVpcmUoJ3JlYWN0JykuUHJvcFR5cGVzO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9Sb3V0ZScpO1xuXG52YXIgUHJvcFR5cGVzID0gYXNzaWduKHt9LCBSZWFjdFByb3BUeXBlcywge1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCBhIHByb3Agc2hvdWxkIGJlIGZhbHN5LlxuICAgKi9cbiAgZmFsc3k6IGZ1bmN0aW9uIGZhbHN5KHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSkge1xuICAgIGlmIChwcm9wc1twcm9wTmFtZV0pIHJldHVybiBuZXcgRXJyb3IoJzwnICsgY29tcG9uZW50TmFtZSArICc+IHNob3VsZCBub3QgaGF2ZSBhIFwiJyArIHByb3BOYW1lICsgJ1wiIHByb3AnKTtcbiAgfSxcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgYSBwcm9wIHNob3VsZCBiZSBhIFJvdXRlIG9iamVjdC5cbiAgICovXG4gIHJvdXRlOiBSZWFjdFByb3BUeXBlcy5pbnN0YW5jZU9mKFJvdXRlKSxcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgYSBwcm9wIHNob3VsZCBiZSBhIFJvdXRlciBvYmplY3QuXG4gICAqL1xuICAvL3JvdXRlcjogUmVhY3RQcm9wVHlwZXMuaW5zdGFuY2VPZihSb3V0ZXIpIC8vIFRPRE9cbiAgcm91dGVyOiBSZWFjdFByb3BUeXBlcy5mdW5jXG5cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb3BUeXBlczsiLCIvKipcbiAqIEVuY2Fwc3VsYXRlcyBhIHJlZGlyZWN0IHRvIHRoZSBnaXZlbiByb3V0ZS5cbiAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIFJlZGlyZWN0KHRvLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gIHRoaXMudG8gPSB0bztcbiAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7XG4gIHRoaXMucXVlcnkgPSBxdWVyeTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWRpcmVjdDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnb2JqZWN0LWFzc2lnbicpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCcuL3dhcm5pbmcnKTtcbnZhciBQYXRoVXRpbHMgPSByZXF1aXJlKCcuL1BhdGhVdGlscycpO1xuXG52YXIgX2N1cnJlbnRSb3V0ZTtcblxudmFyIFJvdXRlID0gKGZ1bmN0aW9uICgpIHtcbiAgX2NyZWF0ZUNsYXNzKFJvdXRlLCBudWxsLCBbe1xuICAgIGtleTogJ2NyZWF0ZVJvdXRlJyxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBuZXcgcm91dGUuIE9wdGlvbnMgbWF5IGJlIGEgVVJMIHBhdGhuYW1lIHN0cmluZ1xuICAgICAqIHdpdGggcGxhY2Vob2xkZXJzIGZvciBuYW1lZCBwYXJhbXMgb3IgYW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBmb2xsb3dpbmdcbiAgICAgKiBwcm9wZXJ0aWVzOlxuICAgICAqXG4gICAgICogLSBuYW1lICAgICAgICAgICAgICAgICAgICAgVGhlIG5hbWUgb2YgdGhlIHJvdXRlLiBUaGlzIGlzIHVzZWQgdG8gbG9va3VwIGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZSByZWxhdGl2ZSB0byBpdHMgcGFyZW50IHJvdXRlIGFuZCBzaG91bGQgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlxdWUgYW1vbmcgYWxsIGNoaWxkIHJvdXRlcyBvZiB0aGUgc2FtZSBwYXJlbnRcbiAgICAgKiAtIHBhdGggICAgICAgICAgICAgICAgICAgICBBIFVSTCBwYXRobmFtZSBzdHJpbmcgd2l0aCBvcHRpb25hbCBwbGFjZWhvbGRlcnNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IHNwZWNpZnkgdGhlIG5hbWVzIG9mIHBhcmFtcyB0byBleHRyYWN0IGZyb21cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgVVJMIHdoZW4gdGhlIHBhdGggbWF0Y2hlcy4gRGVmYXVsdHMgdG8gYC8ke25hbWV9YFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZW4gdGhlcmUgaXMgYSBuYW1lIGdpdmVuLCBvciB0aGUgcGF0aCBvZiB0aGUgcGFyZW50XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGUsIG9yIC9cbiAgICAgKiAtIGlnbm9yZVNjcm9sbEJlaGF2aW9yICAgICBUcnVlIHRvIG1ha2UgdGhpcyByb3V0ZSAoYW5kIGFsbCBkZXNjZW5kYW50cykgaWdub3JlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHNjcm9sbCBiZWhhdmlvciBvZiB0aGUgcm91dGVyXG4gICAgICogLSBpc0RlZmF1bHQgICAgICAgICAgICAgICAgVHJ1ZSB0byBtYWtlIHRoaXMgcm91dGUgdGhlIGRlZmF1bHQgcm91dGUgYW1vbmcgYWxsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRzIHNpYmxpbmdzXG4gICAgICogLSBpc05vdEZvdW5kICAgICAgICAgICAgICAgVHJ1ZSB0byBtYWtlIHRoaXMgcm91dGUgdGhlIFwibm90IGZvdW5kXCIgcm91dGUgYW1vbmdcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGwgaXRzIHNpYmxpbmdzXG4gICAgICogLSBvbkVudGVyICAgICAgICAgICAgICAgICAgQSB0cmFuc2l0aW9uIGhvb2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlciBpcyBnb2luZyB0byBlbnRlciB0aGlzIHJvdXRlXG4gICAgICogLSBvbkxlYXZlICAgICAgICAgICAgICAgICAgQSB0cmFuc2l0aW9uIGhvb2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlciBpcyBnb2luZyB0byBsZWF2ZSB0aGlzIHJvdXRlXG4gICAgICogLSBoYW5kbGVyICAgICAgICAgICAgICAgICAgQSBSZWFjdCBjb21wb25lbnQgdGhhdCB3aWxsIGJlIHJlbmRlcmVkIHdoZW5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHJvdXRlIGlzIGFjdGl2ZVxuICAgICAqIC0gcGFyZW50Um91dGUgICAgICAgICAgICAgIFRoZSBwYXJlbnQgcm91dGUgdG8gdXNlIGZvciB0aGlzIHJvdXRlLiBUaGlzIG9wdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIGF1dG9tYXRpY2FsbHkgc3VwcGxpZWQgd2hlbiBjcmVhdGluZyByb3V0ZXMgaW5zaWRlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGNhbGxiYWNrIHRvIGFub3RoZXIgaW52b2NhdGlvbiBvZiBjcmVhdGVSb3V0ZS4gWW91XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seSBldmVyIG5lZWQgdG8gdXNlIHRoaXMgd2hlbiBkZWNsYXJpbmcgcm91dGVzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXBlbmRlbnRseSBvZiBvbmUgYW5vdGhlciB0byBtYW51YWxseSBwaWVjZSB0b2dldGhlclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSByb3V0ZSBoaWVyYXJjaHlcbiAgICAgKlxuICAgICAqIFRoZSBjYWxsYmFjayBtYXkgYmUgdXNlZCB0byBzdHJ1Y3R1cmUgeW91ciByb3V0ZSBoaWVyYXJjaHkuIEFueSBjYWxsIHRvXG4gICAgICogY3JlYXRlUm91dGUsIGNyZWF0ZURlZmF1bHRSb3V0ZSwgY3JlYXRlTm90Rm91bmRSb3V0ZSwgb3IgY3JlYXRlUmVkaXJlY3RcbiAgICAgKiBpbnNpZGUgdGhlIGNhbGxiYWNrIGF1dG9tYXRpY2FsbHkgdXNlcyB0aGlzIHJvdXRlIGFzIGl0cyBwYXJlbnQuXG4gICAgICovXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZVJvdXRlKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgb3B0aW9ucyA9IHsgcGF0aDogb3B0aW9ucyB9O1xuXG4gICAgICB2YXIgcGFyZW50Um91dGUgPSBfY3VycmVudFJvdXRlO1xuXG4gICAgICBpZiAocGFyZW50Um91dGUpIHtcbiAgICAgICAgd2FybmluZyhvcHRpb25zLnBhcmVudFJvdXRlID09IG51bGwgfHwgb3B0aW9ucy5wYXJlbnRSb3V0ZSA9PT0gcGFyZW50Um91dGUsICdZb3Ugc2hvdWxkIG5vdCB1c2UgcGFyZW50Um91dGUgd2l0aCBjcmVhdGVSb3V0ZSBpbnNpZGUgYW5vdGhlciByb3V0ZVxcJ3MgY2hpbGQgY2FsbGJhY2s7IGl0IGlzIGlnbm9yZWQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudFJvdXRlID0gb3B0aW9ucy5wYXJlbnRSb3V0ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIG5hbWUgPSBvcHRpb25zLm5hbWU7XG4gICAgICB2YXIgcGF0aCA9IG9wdGlvbnMucGF0aCB8fCBuYW1lO1xuXG4gICAgICBpZiAocGF0aCAmJiAhKG9wdGlvbnMuaXNEZWZhdWx0IHx8IG9wdGlvbnMuaXNOb3RGb3VuZCkpIHtcbiAgICAgICAgaWYgKFBhdGhVdGlscy5pc0Fic29sdXRlKHBhdGgpKSB7XG4gICAgICAgICAgaWYgKHBhcmVudFJvdXRlKSB7XG4gICAgICAgICAgICBpbnZhcmlhbnQocGF0aCA9PT0gcGFyZW50Um91dGUucGF0aCB8fCBwYXJlbnRSb3V0ZS5wYXJhbU5hbWVzLmxlbmd0aCA9PT0gMCwgJ1lvdSBjYW5ub3QgbmVzdCBwYXRoIFwiJXNcIiBpbnNpZGUgXCIlc1wiOyB0aGUgcGFyZW50IHJlcXVpcmVzIFVSTCBwYXJhbWV0ZXJzJywgcGF0aCwgcGFyZW50Um91dGUucGF0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhcmVudFJvdXRlKSB7XG4gICAgICAgICAgLy8gUmVsYXRpdmUgcGF0aHMgZXh0ZW5kIHRoZWlyIHBhcmVudC5cbiAgICAgICAgICBwYXRoID0gUGF0aFV0aWxzLmpvaW4ocGFyZW50Um91dGUucGF0aCwgcGF0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGF0aCA9ICcvJyArIHBhdGg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhdGggPSBwYXJlbnRSb3V0ZSA/IHBhcmVudFJvdXRlLnBhdGggOiAnLyc7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmlzTm90Rm91bmQgJiYgIS9cXCokLy50ZXN0KHBhdGgpKSBwYXRoICs9ICcqJzsgLy8gQXV0by1hcHBlbmQgKiB0byB0aGUgcGF0aCBvZiBub3QgZm91bmQgcm91dGVzLlxuXG4gICAgICB2YXIgcm91dGUgPSBuZXcgUm91dGUobmFtZSwgcGF0aCwgb3B0aW9ucy5pZ25vcmVTY3JvbGxCZWhhdmlvciwgb3B0aW9ucy5pc0RlZmF1bHQsIG9wdGlvbnMuaXNOb3RGb3VuZCwgb3B0aW9ucy5vbkVudGVyLCBvcHRpb25zLm9uTGVhdmUsIG9wdGlvbnMuaGFuZGxlcik7XG5cbiAgICAgIGlmIChwYXJlbnRSb3V0ZSkge1xuICAgICAgICBpZiAocm91dGUuaXNEZWZhdWx0KSB7XG4gICAgICAgICAgaW52YXJpYW50KHBhcmVudFJvdXRlLmRlZmF1bHRSb3V0ZSA9PSBudWxsLCAnJXMgbWF5IG5vdCBoYXZlIG1vcmUgdGhhbiBvbmUgZGVmYXVsdCByb3V0ZScsIHBhcmVudFJvdXRlKTtcblxuICAgICAgICAgIHBhcmVudFJvdXRlLmRlZmF1bHRSb3V0ZSA9IHJvdXRlO1xuICAgICAgICB9IGVsc2UgaWYgKHJvdXRlLmlzTm90Rm91bmQpIHtcbiAgICAgICAgICBpbnZhcmlhbnQocGFyZW50Um91dGUubm90Rm91bmRSb3V0ZSA9PSBudWxsLCAnJXMgbWF5IG5vdCBoYXZlIG1vcmUgdGhhbiBvbmUgbm90IGZvdW5kIHJvdXRlJywgcGFyZW50Um91dGUpO1xuXG4gICAgICAgICAgcGFyZW50Um91dGUubm90Rm91bmRSb3V0ZSA9IHJvdXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFyZW50Um91dGUuYXBwZW5kQ2hpbGQocm91dGUpO1xuICAgICAgfVxuXG4gICAgICAvLyBBbnkgcm91dGVzIGNyZWF0ZWQgaW4gdGhlIGNhbGxiYWNrXG4gICAgICAvLyB1c2UgdGhpcyByb3V0ZSBhcyB0aGVpciBwYXJlbnQuXG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhciBjdXJyZW50Um91dGUgPSBfY3VycmVudFJvdXRlO1xuICAgICAgICBfY3VycmVudFJvdXRlID0gcm91dGU7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwocm91dGUsIHJvdXRlKTtcbiAgICAgICAgX2N1cnJlbnRSb3V0ZSA9IGN1cnJlbnRSb3V0ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJvdXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSByb3V0ZSB0aGF0IGlzIHJlbmRlcmVkIHdoZW4gaXRzIHBhcmVudCBtYXRjaGVzXG4gICAgICogdGhlIGN1cnJlbnQgVVJMLlxuICAgICAqL1xuICB9LCB7XG4gICAga2V5OiAnY3JlYXRlRGVmYXVsdFJvdXRlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlRGVmYXVsdFJvdXRlKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBSb3V0ZS5jcmVhdGVSb3V0ZShhc3NpZ24oe30sIG9wdGlvbnMsIHsgaXNEZWZhdWx0OiB0cnVlIH0pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgcm91dGUgdGhhdCBpcyByZW5kZXJlZCB3aGVuIGl0cyBwYXJlbnQgbWF0Y2hlc1xuICAgICAqIHRoZSBjdXJyZW50IFVSTCBidXQgbm9uZSBvZiBpdHMgc2libGluZ3MgZG8uXG4gICAgICovXG4gIH0sIHtcbiAgICBrZXk6ICdjcmVhdGVOb3RGb3VuZFJvdXRlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlTm90Rm91bmRSb3V0ZShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gUm91dGUuY3JlYXRlUm91dGUoYXNzaWduKHt9LCBvcHRpb25zLCB7IGlzTm90Rm91bmQ6IHRydWUgfSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSByb3V0ZSB0aGF0IGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RzIHRoZSB0cmFuc2l0aW9uXG4gICAgICogdG8gYW5vdGhlciByb3V0ZS4gSW4gYWRkaXRpb24gdG8gdGhlIG5vcm1hbCBvcHRpb25zIHRvIGNyZWF0ZVJvdXRlLCB0aGlzXG4gICAgICogZnVuY3Rpb24gYWNjZXB0cyB0aGUgZm9sbG93aW5nIG9wdGlvbnM6XG4gICAgICpcbiAgICAgKiAtIGZyb20gICAgICAgICBBbiBhbGlhcyBmb3IgdGhlIGBwYXRoYCBvcHRpb24uIERlZmF1bHRzIHRvICpcbiAgICAgKiAtIHRvICAgICAgICAgICBUaGUgcGF0aC9yb3V0ZS9yb3V0ZSBuYW1lIHRvIHJlZGlyZWN0IHRvXG4gICAgICogLSBwYXJhbXMgICAgICAgVGhlIHBhcmFtcyB0byB1c2UgaW4gdGhlIHJlZGlyZWN0IFVSTC4gRGVmYXVsdHNcbiAgICAgKiAgICAgICAgICAgICAgICB0byB1c2luZyB0aGUgY3VycmVudCBwYXJhbXNcbiAgICAgKiAtIHF1ZXJ5ICAgICAgICBUaGUgcXVlcnkgdG8gdXNlIGluIHRoZSByZWRpcmVjdCBVUkwuIERlZmF1bHRzXG4gICAgICogICAgICAgICAgICAgICAgdG8gdXNpbmcgdGhlIGN1cnJlbnQgcXVlcnlcbiAgICAgKi9cbiAgfSwge1xuICAgIGtleTogJ2NyZWF0ZVJlZGlyZWN0JyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlUmVkaXJlY3Qob3B0aW9ucykge1xuICAgICAgcmV0dXJuIFJvdXRlLmNyZWF0ZVJvdXRlKGFzc2lnbih7fSwgb3B0aW9ucywge1xuICAgICAgICBwYXRoOiBvcHRpb25zLnBhdGggfHwgb3B0aW9ucy5mcm9tIHx8ICcqJyxcbiAgICAgICAgb25FbnRlcjogZnVuY3Rpb24gb25FbnRlcih0cmFuc2l0aW9uLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gICAgICAgICAgdHJhbnNpdGlvbi5yZWRpcmVjdChvcHRpb25zLnRvLCBvcHRpb25zLnBhcmFtcyB8fCBwYXJhbXMsIG9wdGlvbnMucXVlcnkgfHwgcXVlcnkpO1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfVxuICB9XSk7XG5cbiAgZnVuY3Rpb24gUm91dGUobmFtZSwgcGF0aCwgaWdub3JlU2Nyb2xsQmVoYXZpb3IsIGlzRGVmYXVsdCwgaXNOb3RGb3VuZCwgb25FbnRlciwgb25MZWF2ZSwgaGFuZGxlcikge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSb3V0ZSk7XG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMucGF0aCA9IHBhdGg7XG4gICAgdGhpcy5wYXJhbU5hbWVzID0gUGF0aFV0aWxzLmV4dHJhY3RQYXJhbU5hbWVzKHRoaXMucGF0aCk7XG4gICAgdGhpcy5pZ25vcmVTY3JvbGxCZWhhdmlvciA9ICEhaWdub3JlU2Nyb2xsQmVoYXZpb3I7XG4gICAgdGhpcy5pc0RlZmF1bHQgPSAhIWlzRGVmYXVsdDtcbiAgICB0aGlzLmlzTm90Rm91bmQgPSAhIWlzTm90Rm91bmQ7XG4gICAgdGhpcy5vbkVudGVyID0gb25FbnRlcjtcbiAgICB0aGlzLm9uTGVhdmUgPSBvbkxlYXZlO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kcyB0aGUgZ2l2ZW4gcm91dGUgdG8gdGhpcyByb3V0ZSdzIGNoaWxkIHJvdXRlcy5cbiAgICovXG5cbiAgX2NyZWF0ZUNsYXNzKFJvdXRlLCBbe1xuICAgIGtleTogJ2FwcGVuZENoaWxkJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwZW5kQ2hpbGQocm91dGUpIHtcbiAgICAgIGludmFyaWFudChyb3V0ZSBpbnN0YW5jZW9mIFJvdXRlLCAncm91dGUuYXBwZW5kQ2hpbGQgbXVzdCB1c2UgYSB2YWxpZCBSb3V0ZScpO1xuXG4gICAgICBpZiAoIXRoaXMuY2hpbGRSb3V0ZXMpIHRoaXMuY2hpbGRSb3V0ZXMgPSBbXTtcblxuICAgICAgdGhpcy5jaGlsZFJvdXRlcy5wdXNoKHJvdXRlKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICd0b1N0cmluZycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgdmFyIHN0cmluZyA9ICc8Um91dGUnO1xuXG4gICAgICBpZiAodGhpcy5uYW1lKSBzdHJpbmcgKz0gJyBuYW1lPVwiJyArIHRoaXMubmFtZSArICdcIic7XG5cbiAgICAgIHN0cmluZyArPSAnIHBhdGg9XCInICsgdGhpcy5wYXRoICsgJ1wiPic7XG5cbiAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFJvdXRlO1xufSkoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBSb3V0ZTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcbnZhciBjYW5Vc2VET00gPSByZXF1aXJlKCdjYW4tdXNlLWRvbScpO1xudmFyIGdldFdpbmRvd1Njcm9sbFBvc2l0aW9uID0gcmVxdWlyZSgnLi9nZXRXaW5kb3dTY3JvbGxQb3NpdGlvbicpO1xuXG5mdW5jdGlvbiBzaG91bGRVcGRhdGVTY3JvbGwoc3RhdGUsIHByZXZTdGF0ZSkge1xuICBpZiAoIXByZXZTdGF0ZSkgcmV0dXJuIHRydWU7XG5cbiAgLy8gRG9uJ3QgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiB3aGVuIG9ubHkgdGhlIHF1ZXJ5IGhhcyBjaGFuZ2VkLlxuICBpZiAoc3RhdGUucGF0aG5hbWUgPT09IHByZXZTdGF0ZS5wYXRobmFtZSkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciByb3V0ZXMgPSBzdGF0ZS5yb3V0ZXM7XG4gIHZhciBwcmV2Um91dGVzID0gcHJldlN0YXRlLnJvdXRlcztcblxuICB2YXIgc2hhcmVkQW5jZXN0b3JSb3V0ZXMgPSByb3V0ZXMuZmlsdGVyKGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgIHJldHVybiBwcmV2Um91dGVzLmluZGV4T2Yocm91dGUpICE9PSAtMTtcbiAgfSk7XG5cbiAgcmV0dXJuICFzaGFyZWRBbmNlc3RvclJvdXRlcy5zb21lKGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgIHJldHVybiByb3V0ZS5pZ25vcmVTY3JvbGxCZWhhdmlvcjtcbiAgfSk7XG59XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHJvdXRlciB3aXRoIHRoZSBhYmlsaXR5IHRvIG1hbmFnZSB3aW5kb3cgc2Nyb2xsIHBvc2l0aW9uXG4gKiBhY2NvcmRpbmcgdG8gaXRzIHNjcm9sbCBiZWhhdmlvci5cbiAqL1xudmFyIFNjcm9sbEhpc3RvcnkgPSB7XG5cbiAgc3RhdGljczoge1xuXG4gICAgLyoqXG4gICAgICogUmVjb3JkcyBjdXJlbnQgc2Nyb2xsIHBvc2l0aW9uIGFzIHRoZSBsYXN0IGtub3duIHBvc2l0aW9uIGZvciB0aGUgZ2l2ZW4gVVJMIHBhdGguXG4gICAgICovXG4gICAgcmVjb3JkU2Nyb2xsUG9zaXRpb246IGZ1bmN0aW9uIHJlY29yZFNjcm9sbFBvc2l0aW9uKHBhdGgpIHtcbiAgICAgIGlmICghdGhpcy5zY3JvbGxIaXN0b3J5KSB0aGlzLnNjcm9sbEhpc3RvcnkgPSB7fTtcblxuICAgICAgdGhpcy5zY3JvbGxIaXN0b3J5W3BhdGhdID0gZ2V0V2luZG93U2Nyb2xsUG9zaXRpb24oKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbGFzdCBrbm93biBzY3JvbGwgcG9zaXRpb24gZm9yIHRoZSBnaXZlbiBVUkwgcGF0aC5cbiAgICAgKi9cbiAgICBnZXRTY3JvbGxQb3NpdGlvbjogZnVuY3Rpb24gZ2V0U2Nyb2xsUG9zaXRpb24ocGF0aCkge1xuICAgICAgaWYgKCF0aGlzLnNjcm9sbEhpc3RvcnkpIHRoaXMuc2Nyb2xsSGlzdG9yeSA9IHt9O1xuXG4gICAgICByZXR1cm4gdGhpcy5zY3JvbGxIaXN0b3J5W3BhdGhdIHx8IG51bGw7XG4gICAgfVxuXG4gIH0sXG5cbiAgY29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgaW52YXJpYW50KHRoaXMuY29uc3RydWN0b3IuZ2V0U2Nyb2xsQmVoYXZpb3IoKSA9PSBudWxsIHx8IGNhblVzZURPTSwgJ0Nhbm5vdCB1c2Ugc2Nyb2xsIGJlaGF2aW9yIHdpdGhvdXQgYSBET00nKTtcbiAgfSxcblxuICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5fdXBkYXRlU2Nyb2xsKCk7XG4gIH0sXG5cbiAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcbiAgICB0aGlzLl91cGRhdGVTY3JvbGwocHJldlN0YXRlKTtcbiAgfSxcblxuICBfdXBkYXRlU2Nyb2xsOiBmdW5jdGlvbiBfdXBkYXRlU2Nyb2xsKHByZXZTdGF0ZSkge1xuICAgIGlmICghc2hvdWxkVXBkYXRlU2Nyb2xsKHRoaXMuc3RhdGUsIHByZXZTdGF0ZSkpIHJldHVybjtcblxuICAgIHZhciBzY3JvbGxCZWhhdmlvciA9IHRoaXMuY29uc3RydWN0b3IuZ2V0U2Nyb2xsQmVoYXZpb3IoKTtcblxuICAgIGlmIChzY3JvbGxCZWhhdmlvcikgc2Nyb2xsQmVoYXZpb3IudXBkYXRlU2Nyb2xsUG9zaXRpb24odGhpcy5jb25zdHJ1Y3Rvci5nZXRTY3JvbGxQb3NpdGlvbih0aGlzLnN0YXRlLnBhdGgpLCB0aGlzLnN0YXRlLmFjdGlvbik7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTY3JvbGxIaXN0b3J5OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFByb3BUeXBlcyA9IHJlcXVpcmUoJy4vUHJvcFR5cGVzJyk7XG5cbi8qKlxuICogQSBtaXhpbiBmb3IgY29tcG9uZW50cyB0aGF0IG5lZWQgdG8ga25vdyB0aGUgcGF0aCwgcm91dGVzLCBVUkxcbiAqIHBhcmFtcyBhbmQgcXVlcnkgdGhhdCBhcmUgY3VycmVudGx5IGFjdGl2ZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgdmFyIEFib3V0TGluayA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAqICAgICBtaXhpbnM6IFsgUm91dGVyLlN0YXRlIF0sXG4gKiAgICAgcmVuZGVyKCkge1xuICogICAgICAgdmFyIGNsYXNzTmFtZSA9IHRoaXMucHJvcHMuY2xhc3NOYW1lO1xuICpcbiAqICAgICAgIGlmICh0aGlzLmlzQWN0aXZlKCdhYm91dCcpKVxuICogICAgICAgICBjbGFzc05hbWUgKz0gJyBpcy1hY3RpdmUnO1xuICpcbiAqICAgICAgIHJldHVybiBSZWFjdC5ET00uYSh7IGNsYXNzTmFtZTogY2xhc3NOYW1lIH0sIHRoaXMucHJvcHMuY2hpbGRyZW4pO1xuICogICAgIH1cbiAqICAgfSk7XG4gKi9cbnZhciBTdGF0ZSA9IHtcblxuICBjb250ZXh0VHlwZXM6IHtcbiAgICByb3V0ZXI6IFByb3BUeXBlcy5yb3V0ZXIuaXNSZXF1aXJlZFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IFVSTCBwYXRoLlxuICAgKi9cbiAgZ2V0UGF0aDogZnVuY3Rpb24gZ2V0UGF0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0LnJvdXRlci5nZXRDdXJyZW50UGF0aCgpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IFVSTCBwYXRoIHdpdGhvdXQgdGhlIHF1ZXJ5IHN0cmluZy5cbiAgICovXG4gIGdldFBhdGhuYW1lOiBmdW5jdGlvbiBnZXRQYXRobmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0LnJvdXRlci5nZXRDdXJyZW50UGF0aG5hbWUoKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3Qgb2YgdGhlIFVSTCBwYXJhbXMgdGhhdCBhcmUgY3VycmVudGx5IGFjdGl2ZS5cbiAgICovXG4gIGdldFBhcmFtczogZnVuY3Rpb24gZ2V0UGFyYW1zKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLmdldEN1cnJlbnRQYXJhbXMoKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3Qgb2YgdGhlIHF1ZXJ5IHBhcmFtcyB0aGF0IGFyZSBjdXJyZW50bHkgYWN0aXZlLlxuICAgKi9cbiAgZ2V0UXVlcnk6IGZ1bmN0aW9uIGdldFF1ZXJ5KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLmdldEN1cnJlbnRRdWVyeSgpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRoZSByb3V0ZXMgdGhhdCBhcmUgY3VycmVudGx5IGFjdGl2ZS5cbiAgICovXG4gIGdldFJvdXRlczogZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLmdldEN1cnJlbnRSb3V0ZXMoKTtcbiAgfSxcblxuICAvKipcbiAgICogQSBoZWxwZXIgbWV0aG9kIHRvIGRldGVybWluZSBpZiBhIGdpdmVuIHJvdXRlLCBwYXJhbXMsIGFuZCBxdWVyeVxuICAgKiBhcmUgYWN0aXZlLlxuICAgKi9cbiAgaXNBY3RpdmU6IGZ1bmN0aW9uIGlzQWN0aXZlKHRvLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5yb3V0ZXIuaXNBY3RpdmUodG8sIHBhcmFtcywgcXVlcnkpO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU3RhdGU7IiwiLyoganNoaW50IC1XMDU4ICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIENhbmNlbGxhdGlvbiA9IHJlcXVpcmUoJy4vQ2FuY2VsbGF0aW9uJyk7XG52YXIgUmVkaXJlY3QgPSByZXF1aXJlKCcuL1JlZGlyZWN0Jyk7XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEgdHJhbnNpdGlvbiB0byBhIGdpdmVuIHBhdGguXG4gKlxuICogVGhlIHdpbGxUcmFuc2l0aW9uVG8gYW5kIHdpbGxUcmFuc2l0aW9uRnJvbSBoYW5kbGVycyByZWNlaXZlXG4gKiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGFzIHRoZWlyIGZpcnN0IGFyZ3VtZW50LlxuICovXG5mdW5jdGlvbiBUcmFuc2l0aW9uKHBhdGgsIHJldHJ5KSB7XG4gIHRoaXMucGF0aCA9IHBhdGg7XG4gIHRoaXMuYWJvcnRSZWFzb24gPSBudWxsO1xuICAvLyBUT0RPOiBDaGFuZ2UgdGhpcyB0byByb3V0ZXIucmV0cnlUcmFuc2l0aW9uKHRyYW5zaXRpb24pXG4gIHRoaXMucmV0cnkgPSByZXRyeS5iaW5kKHRoaXMpO1xufVxuXG5UcmFuc2l0aW9uLnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgaWYgKHRoaXMuYWJvcnRSZWFzb24gPT0gbnVsbCkgdGhpcy5hYm9ydFJlYXNvbiA9IHJlYXNvbiB8fCAnQUJPUlQnO1xufTtcblxuVHJhbnNpdGlvbi5wcm90b3R5cGUucmVkaXJlY3QgPSBmdW5jdGlvbiAodG8sIHBhcmFtcywgcXVlcnkpIHtcbiAgdGhpcy5hYm9ydChuZXcgUmVkaXJlY3QodG8sIHBhcmFtcywgcXVlcnkpKTtcbn07XG5cblRyYW5zaXRpb24ucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hYm9ydChuZXcgQ2FuY2VsbGF0aW9uKCkpO1xufTtcblxuVHJhbnNpdGlvbi5mcm9tID0gZnVuY3Rpb24gKHRyYW5zaXRpb24sIHJvdXRlcywgY29tcG9uZW50cywgY2FsbGJhY2spIHtcbiAgcm91dGVzLnJlZHVjZShmdW5jdGlvbiAoY2FsbGJhY2ssIHJvdXRlLCBpbmRleCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciB8fCB0cmFuc2l0aW9uLmFib3J0UmVhc29uKSB7XG4gICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgIH0gZWxzZSBpZiAocm91dGUub25MZWF2ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJvdXRlLm9uTGVhdmUodHJhbnNpdGlvbiwgY29tcG9uZW50c1tpbmRleF0sIGNhbGxiYWNrKTtcblxuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNhbGxiYWNrIGluIHRoZSBhcmd1bWVudCBsaXN0LCBjYWxsIGl0IGF1dG9tYXRpY2FsbHkuXG4gICAgICAgICAgaWYgKHJvdXRlLm9uTGVhdmUubGVuZ3RoIDwgMykgY2FsbGJhY2soKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNhbGxiYWNrKGUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG4gIH0sIGNhbGxiYWNrKSgpO1xufTtcblxuVHJhbnNpdGlvbi50byA9IGZ1bmN0aW9uICh0cmFuc2l0aW9uLCByb3V0ZXMsIHBhcmFtcywgcXVlcnksIGNhbGxiYWNrKSB7XG4gIHJvdXRlcy5yZWR1Y2VSaWdodChmdW5jdGlvbiAoY2FsbGJhY2ssIHJvdXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIHx8IHRyYW5zaXRpb24uYWJvcnRSZWFzb24pIHtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IpO1xuICAgICAgfSBlbHNlIGlmIChyb3V0ZS5vbkVudGVyKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcm91dGUub25FbnRlcih0cmFuc2l0aW9uLCBwYXJhbXMsIHF1ZXJ5LCBjYWxsYmFjayk7XG5cbiAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBjYWxsYmFjayBpbiB0aGUgYXJndW1lbnQgbGlzdCwgY2FsbCBpdCBhdXRvbWF0aWNhbGx5LlxuICAgICAgICAgIGlmIChyb3V0ZS5vbkVudGVyLmxlbmd0aCA8IDQpIGNhbGxiYWNrKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjYWxsYmFjayhlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBjYWxsYmFjaykoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNpdGlvbjsiLCIvKipcbiAqIEFjdGlvbnMgdGhhdCBtb2RpZnkgdGhlIFVSTC5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgTG9jYXRpb25BY3Rpb25zID0ge1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgYSBuZXcgbG9jYXRpb24gaXMgYmVpbmcgcHVzaGVkIHRvIHRoZSBoaXN0b3J5IHN0YWNrLlxuICAgKi9cbiAgUFVTSDogJ3B1c2gnLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhlIGN1cnJlbnQgbG9jYXRpb24gc2hvdWxkIGJlIHJlcGxhY2VkLlxuICAgKi9cbiAgUkVQTEFDRTogJ3JlcGxhY2UnLFxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhlIG1vc3QgcmVjZW50IGVudHJ5IHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIGhpc3Rvcnkgc3RhY2suXG4gICAqL1xuICBQT1A6ICdwb3AnXG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTG9jYXRpb25BY3Rpb25zOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIExvY2F0aW9uQWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvTG9jYXRpb25BY3Rpb25zJyk7XG5cbi8qKlxuICogQSBzY3JvbGwgYmVoYXZpb3IgdGhhdCBhdHRlbXB0cyB0byBpbWl0YXRlIHRoZSBkZWZhdWx0IGJlaGF2aW9yXG4gKiBvZiBtb2Rlcm4gYnJvd3NlcnMuXG4gKi9cbnZhciBJbWl0YXRlQnJvd3NlckJlaGF2aW9yID0ge1xuXG4gIHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiBmdW5jdGlvbiB1cGRhdGVTY3JvbGxQb3NpdGlvbihwb3NpdGlvbiwgYWN0aW9uVHlwZSkge1xuICAgIHN3aXRjaCAoYWN0aW9uVHlwZSkge1xuICAgICAgY2FzZSBMb2NhdGlvbkFjdGlvbnMuUFVTSDpcbiAgICAgIGNhc2UgTG9jYXRpb25BY3Rpb25zLlJFUExBQ0U6XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExvY2F0aW9uQWN0aW9ucy5QT1A6XG4gICAgICAgIGlmIChwb3NpdGlvbikge1xuICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyhwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSW1pdGF0ZUJyb3dzZXJCZWhhdmlvcjsiLCIvKipcbiAqIEEgc2Nyb2xsIGJlaGF2aW9yIHRoYXQgYWx3YXlzIHNjcm9sbHMgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZVxuICogYWZ0ZXIgYSB0cmFuc2l0aW9uLlxuICovXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIFNjcm9sbFRvVG9wQmVoYXZpb3IgPSB7XG5cbiAgdXBkYXRlU2Nyb2xsUG9zaXRpb246IGZ1bmN0aW9uIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKCkge1xuICAgIHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNjcm9sbFRvVG9wQmVoYXZpb3I7IiwiLyoqXG4gKiBUaGlzIGNvbXBvbmVudCBpcyBuZWNlc3NhcnkgdG8gZ2V0IGFyb3VuZCBhIGNvbnRleHQgd2FybmluZ1xuICogcHJlc2VudCBpbiBSZWFjdCAwLjEzLjAuIEl0IHNvdmxlcyB0aGlzIGJ5IHByb3ZpZGluZyBhIHNlcGFyYXRpb25cbiAqIGJldHdlZW4gdGhlIFwib3duZXJcIiBhbmQgXCJwYXJlbnRcIiBjb250ZXh0cy5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb250ZXh0V3JhcHBlciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoQ29udGV4dFdyYXBwZXIsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIGZ1bmN0aW9uIENvbnRleHRXcmFwcGVyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb250ZXh0V3JhcHBlcik7XG5cbiAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihDb250ZXh0V3JhcHBlci5wcm90b3R5cGUpLCAnY29uc3RydWN0b3InLCB0aGlzKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKENvbnRleHRXcmFwcGVyLCBbe1xuICAgIGtleTogJ3JlbmRlcicsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLmNoaWxkcmVuO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBDb250ZXh0V3JhcHBlcjtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29udGV4dFdyYXBwZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgX2dldCA9IGZ1bmN0aW9uIGdldChfeCwgX3gyLCBfeDMpIHsgdmFyIF9hZ2FpbiA9IHRydWU7IF9mdW5jdGlvbjogd2hpbGUgKF9hZ2FpbikgeyB2YXIgb2JqZWN0ID0gX3gsIHByb3BlcnR5ID0gX3gyLCByZWNlaXZlciA9IF94MzsgX2FnYWluID0gZmFsc2U7IGlmIChvYmplY3QgPT09IG51bGwpIG9iamVjdCA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyBfeCA9IHBhcmVudDsgX3gyID0gcHJvcGVydHk7IF94MyA9IHJlY2VpdmVyOyBfYWdhaW4gPSB0cnVlOyBkZXNjID0gcGFyZW50ID0gdW5kZWZpbmVkOyBjb250aW51ZSBfZnVuY3Rpb247IH0gfSBlbHNlIGlmICgndmFsdWUnIGluIGRlc2MpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgUHJvcFR5cGVzID0gcmVxdWlyZSgnLi4vUHJvcFR5cGVzJyk7XG52YXIgUm91dGVIYW5kbGVyID0gcmVxdWlyZSgnLi9Sb3V0ZUhhbmRsZXInKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vUm91dGUnKTtcblxuLyoqXG4gKiBBIDxEZWZhdWx0Um91dGU+IGNvbXBvbmVudCBpcyBhIHNwZWNpYWwga2luZCBvZiA8Um91dGU+IHRoYXRcbiAqIHJlbmRlcnMgd2hlbiBpdHMgcGFyZW50IG1hdGNoZXMgYnV0IG5vbmUgb2YgaXRzIHNpYmxpbmdzIGRvLlxuICogT25seSBvbmUgc3VjaCByb3V0ZSBtYXkgYmUgdXNlZCBhdCBhbnkgZ2l2ZW4gbGV2ZWwgaW4gdGhlXG4gKiByb3V0ZSBoaWVyYXJjaHkuXG4gKi9cblxudmFyIERlZmF1bHRSb3V0ZSA9IChmdW5jdGlvbiAoX1JvdXRlKSB7XG4gIF9pbmhlcml0cyhEZWZhdWx0Um91dGUsIF9Sb3V0ZSk7XG5cbiAgZnVuY3Rpb24gRGVmYXVsdFJvdXRlKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEZWZhdWx0Um91dGUpO1xuXG4gICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoRGVmYXVsdFJvdXRlLnByb3RvdHlwZSksICdjb25zdHJ1Y3RvcicsIHRoaXMpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICAvLyBUT0RPOiBJbmNsdWRlIHRoZXNlIGluIHRoZSBhYm92ZSBjbGFzcyBkZWZpbml0aW9uXG4gIC8vIG9uY2Ugd2UgY2FuIHVzZSBFUzcgcHJvcGVydHkgaW5pdGlhbGl6ZXJzLlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmFiZWwvYmFiZWwvaXNzdWVzLzYxOVxuXG4gIHJldHVybiBEZWZhdWx0Um91dGU7XG59KShSb3V0ZSk7XG5cbkRlZmF1bHRSb3V0ZS5wcm9wVHlwZXMgPSB7XG4gIG5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhdGg6IFByb3BUeXBlcy5mYWxzeSxcbiAgY2hpbGRyZW46IFByb3BUeXBlcy5mYWxzeSxcbiAgaGFuZGxlcjogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZFxufTtcblxuRGVmYXVsdFJvdXRlLmRlZmF1bHRQcm9wcyA9IHtcbiAgaGFuZGxlcjogUm91dGVIYW5kbGVyXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IERlZmF1bHRSb3V0ZTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnb2JqZWN0LWFzc2lnbicpO1xudmFyIFByb3BUeXBlcyA9IHJlcXVpcmUoJy4uL1Byb3BUeXBlcycpO1xuXG5mdW5jdGlvbiBpc0xlZnRDbGlja0V2ZW50KGV2ZW50KSB7XG4gIHJldHVybiBldmVudC5idXR0b24gPT09IDA7XG59XG5cbmZ1bmN0aW9uIGlzTW9kaWZpZWRFdmVudChldmVudCkge1xuICByZXR1cm4gISEoZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkgfHwgZXZlbnQuY3RybEtleSB8fCBldmVudC5zaGlmdEtleSk7XG59XG5cbi8qKlxuICogPExpbms+IGNvbXBvbmVudHMgYXJlIHVzZWQgdG8gY3JlYXRlIGFuIDxhPiBlbGVtZW50IHRoYXQgbGlua3MgdG8gYSByb3V0ZS5cbiAqIFdoZW4gdGhhdCByb3V0ZSBpcyBhY3RpdmUsIHRoZSBsaW5rIGdldHMgYW4gXCJhY3RpdmVcIiBjbGFzcyBuYW1lIChvciB0aGVcbiAqIHZhbHVlIG9mIGl0cyBgYWN0aXZlQ2xhc3NOYW1lYCBwcm9wKS5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgYXNzdW1pbmcgeW91IGhhdmUgdGhlIGZvbGxvd2luZyByb3V0ZTpcbiAqXG4gKiAgIDxSb3V0ZSBuYW1lPVwic2hvd1Bvc3RcIiBwYXRoPVwiL3Bvc3RzLzpwb3N0SURcIiBoYW5kbGVyPXtQb3N0fS8+XG4gKlxuICogWW91IGNvdWxkIHVzZSB0aGUgZm9sbG93aW5nIGNvbXBvbmVudCB0byBsaW5rIHRvIHRoYXQgcm91dGU6XG4gKlxuICogICA8TGluayB0bz1cInNob3dQb3N0XCIgcGFyYW1zPXt7IHBvc3RJRDogXCIxMjNcIiB9fSAvPlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIHBhcmFtcywgbGlua3MgbWF5IHBhc3MgYWxvbmcgcXVlcnkgc3RyaW5nIHBhcmFtZXRlcnNcbiAqIHVzaW5nIHRoZSBgcXVlcnlgIHByb3AuXG4gKlxuICogICA8TGluayB0bz1cInNob3dQb3N0XCIgcGFyYW1zPXt7IHBvc3RJRDogXCIxMjNcIiB9fSBxdWVyeT17eyBzaG93OnRydWUgfX0vPlxuICovXG5cbnZhciBMaW5rID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhMaW5rLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICBmdW5jdGlvbiBMaW5rKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBMaW5rKTtcblxuICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKExpbmsucHJvdG90eXBlKSwgJ2NvbnN0cnVjdG9yJywgdGhpcykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIC8vIFRPRE86IEluY2x1ZGUgdGhlc2UgaW4gdGhlIGFib3ZlIGNsYXNzIGRlZmluaXRpb25cbiAgLy8gb25jZSB3ZSBjYW4gdXNlIEVTNyBwcm9wZXJ0eSBpbml0aWFsaXplcnMuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iYWJlbC9iYWJlbC9pc3N1ZXMvNjE5XG5cbiAgX2NyZWF0ZUNsYXNzKExpbmssIFt7XG4gICAga2V5OiAnaGFuZGxlQ2xpY2snLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBoYW5kbGVDbGljayhldmVudCkge1xuICAgICAgdmFyIGFsbG93VHJhbnNpdGlvbiA9IHRydWU7XG4gICAgICB2YXIgY2xpY2tSZXN1bHQ7XG5cbiAgICAgIGlmICh0aGlzLnByb3BzLm9uQ2xpY2spIGNsaWNrUmVzdWx0ID0gdGhpcy5wcm9wcy5vbkNsaWNrKGV2ZW50KTtcblxuICAgICAgaWYgKGlzTW9kaWZpZWRFdmVudChldmVudCkgfHwgIWlzTGVmdENsaWNrRXZlbnQoZXZlbnQpKSByZXR1cm47XG5cbiAgICAgIGlmIChjbGlja1Jlc3VsdCA9PT0gZmFsc2UgfHwgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCA9PT0gdHJ1ZSkgYWxsb3dUcmFuc2l0aW9uID0gZmFsc2U7XG5cbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGlmIChhbGxvd1RyYW5zaXRpb24pIHRoaXMuY29udGV4dC5yb3V0ZXIudHJhbnNpdGlvblRvKHRoaXMucHJvcHMudG8sIHRoaXMucHJvcHMucGFyYW1zLCB0aGlzLnByb3BzLnF1ZXJ5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgXCJocmVmXCIgYXR0cmlidXRlIHRvIHVzZSBvbiB0aGUgRE9NIGVsZW1lbnQuXG4gICAgICovXG4gIH0sIHtcbiAgICBrZXk6ICdnZXRIcmVmJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0SHJlZigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLm1ha2VIcmVmKHRoaXMucHJvcHMudG8sIHRoaXMucHJvcHMucGFyYW1zLCB0aGlzLnByb3BzLnF1ZXJ5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgXCJjbGFzc1wiIGF0dHJpYnV0ZSB0byB1c2Ugb24gdGhlIERPTSBlbGVtZW50LCB3aGljaCBjb250YWluc1xuICAgICAqIHRoZSB2YWx1ZSBvZiB0aGUgYWN0aXZlQ2xhc3NOYW1lIHByb3BlcnR5IHdoZW4gdGhpcyA8TGluaz4gaXMgYWN0aXZlLlxuICAgICAqL1xuICB9LCB7XG4gICAga2V5OiAnZ2V0Q2xhc3NOYW1lJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q2xhc3NOYW1lKCkge1xuICAgICAgdmFyIGNsYXNzTmFtZSA9IHRoaXMucHJvcHMuY2xhc3NOYW1lO1xuXG4gICAgICBpZiAodGhpcy5nZXRBY3RpdmVTdGF0ZSgpKSBjbGFzc05hbWUgKz0gJyAnICsgdGhpcy5wcm9wcy5hY3RpdmVDbGFzc05hbWU7XG5cbiAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnZ2V0QWN0aXZlU3RhdGUnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRBY3RpdmVTdGF0ZSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRleHQucm91dGVyLmlzQWN0aXZlKHRoaXMucHJvcHMudG8sIHRoaXMucHJvcHMucGFyYW1zLCB0aGlzLnByb3BzLnF1ZXJ5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdyZW5kZXInLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgaHJlZjogdGhpcy5nZXRIcmVmKCksXG4gICAgICAgIGNsYXNzTmFtZTogdGhpcy5nZXRDbGFzc05hbWUoKSxcbiAgICAgICAgb25DbGljazogdGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpXG4gICAgICB9KTtcblxuICAgICAgaWYgKHByb3BzLmFjdGl2ZVN0eWxlICYmIHRoaXMuZ2V0QWN0aXZlU3RhdGUoKSkgcHJvcHMuc3R5bGUgPSBwcm9wcy5hY3RpdmVTdHlsZTtcblxuICAgICAgZGVsZXRlIHByb3BzLnRvO1xuICAgICAgZGVsZXRlIHByb3BzLnBhcmFtcztcbiAgICAgIGRlbGV0ZSBwcm9wcy5xdWVyeTtcbiAgICAgIGRlbGV0ZSBwcm9wcy5hY3RpdmVDbGFzc05hbWU7XG4gICAgICBkZWxldGUgcHJvcHMuYWN0aXZlU3R5bGU7XG5cbiAgICAgIHJldHVybiBSZWFjdC5ET00uYShwcm9wcywgdGhpcy5wcm9wcy5jaGlsZHJlbik7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIExpbms7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5MaW5rLmNvbnRleHRUeXBlcyA9IHtcbiAgcm91dGVyOiBQcm9wVHlwZXMucm91dGVyLmlzUmVxdWlyZWRcbn07XG5cbkxpbmsucHJvcFR5cGVzID0ge1xuICBhY3RpdmVDbGFzc05hbWU6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgdG86IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5yb3V0ZV0pLmlzUmVxdWlyZWQsXG4gIHBhcmFtczogUHJvcFR5cGVzLm9iamVjdCxcbiAgcXVlcnk6IFByb3BUeXBlcy5vYmplY3QsXG4gIGFjdGl2ZVN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICBvbkNsaWNrOiBQcm9wVHlwZXMuZnVuY1xufTtcblxuTGluay5kZWZhdWx0UHJvcHMgPSB7XG4gIGFjdGl2ZUNsYXNzTmFtZTogJ2FjdGl2ZScsXG4gIGNsYXNzTmFtZTogJydcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTGluazsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBQcm9wVHlwZXMgPSByZXF1aXJlKCcuLi9Qcm9wVHlwZXMnKTtcbnZhciBSb3V0ZUhhbmRsZXIgPSByZXF1aXJlKCcuL1JvdXRlSGFuZGxlcicpO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9Sb3V0ZScpO1xuXG4vKipcbiAqIEEgPE5vdEZvdW5kUm91dGU+IGlzIGEgc3BlY2lhbCBraW5kIG9mIDxSb3V0ZT4gdGhhdFxuICogcmVuZGVycyB3aGVuIHRoZSBiZWdpbm5pbmcgb2YgaXRzIHBhcmVudCdzIHBhdGggbWF0Y2hlc1xuICogYnV0IG5vbmUgb2YgaXRzIHNpYmxpbmdzIGRvLCBpbmNsdWRpbmcgYW55IDxEZWZhdWx0Um91dGU+LlxuICogT25seSBvbmUgc3VjaCByb3V0ZSBtYXkgYmUgdXNlZCBhdCBhbnkgZ2l2ZW4gbGV2ZWwgaW4gdGhlXG4gKiByb3V0ZSBoaWVyYXJjaHkuXG4gKi9cblxudmFyIE5vdEZvdW5kUm91dGUgPSAoZnVuY3Rpb24gKF9Sb3V0ZSkge1xuICBfaW5oZXJpdHMoTm90Rm91bmRSb3V0ZSwgX1JvdXRlKTtcblxuICBmdW5jdGlvbiBOb3RGb3VuZFJvdXRlKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBOb3RGb3VuZFJvdXRlKTtcblxuICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKE5vdEZvdW5kUm91dGUucHJvdG90eXBlKSwgJ2NvbnN0cnVjdG9yJywgdGhpcykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIC8vIFRPRE86IEluY2x1ZGUgdGhlc2UgaW4gdGhlIGFib3ZlIGNsYXNzIGRlZmluaXRpb25cbiAgLy8gb25jZSB3ZSBjYW4gdXNlIEVTNyBwcm9wZXJ0eSBpbml0aWFsaXplcnMuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iYWJlbC9iYWJlbC9pc3N1ZXMvNjE5XG5cbiAgcmV0dXJuIE5vdEZvdW5kUm91dGU7XG59KShSb3V0ZSk7XG5cbk5vdEZvdW5kUm91dGUucHJvcFR5cGVzID0ge1xuICBuYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBwYXRoOiBQcm9wVHlwZXMuZmFsc3ksXG4gIGNoaWxkcmVuOiBQcm9wVHlwZXMuZmFsc3ksXG4gIGhhbmRsZXI6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWRcbn07XG5cbk5vdEZvdW5kUm91dGUuZGVmYXVsdFByb3BzID0ge1xuICBoYW5kbGVyOiBSb3V0ZUhhbmRsZXJcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTm90Rm91bmRSb3V0ZTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBQcm9wVHlwZXMgPSByZXF1aXJlKCcuLi9Qcm9wVHlwZXMnKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vUm91dGUnKTtcblxuLyoqXG4gKiBBIDxSZWRpcmVjdD4gY29tcG9uZW50IGlzIGEgc3BlY2lhbCBraW5kIG9mIDxSb3V0ZT4gdGhhdCBhbHdheXNcbiAqIHJlZGlyZWN0cyB0byBhbm90aGVyIHJvdXRlIHdoZW4gaXQgbWF0Y2hlcy5cbiAqL1xuXG52YXIgUmVkaXJlY3QgPSAoZnVuY3Rpb24gKF9Sb3V0ZSkge1xuICBfaW5oZXJpdHMoUmVkaXJlY3QsIF9Sb3V0ZSk7XG5cbiAgZnVuY3Rpb24gUmVkaXJlY3QoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJlZGlyZWN0KTtcblxuICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFJlZGlyZWN0LnByb3RvdHlwZSksICdjb25zdHJ1Y3RvcicsIHRoaXMpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICAvLyBUT0RPOiBJbmNsdWRlIHRoZXNlIGluIHRoZSBhYm92ZSBjbGFzcyBkZWZpbml0aW9uXG4gIC8vIG9uY2Ugd2UgY2FuIHVzZSBFUzcgcHJvcGVydHkgaW5pdGlhbGl6ZXJzLlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmFiZWwvYmFiZWwvaXNzdWVzLzYxOVxuXG4gIHJldHVybiBSZWRpcmVjdDtcbn0pKFJvdXRlKTtcblxuUmVkaXJlY3QucHJvcFR5cGVzID0ge1xuICBwYXRoOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBmcm9tOiBQcm9wVHlwZXMuc3RyaW5nLCAvLyBBbGlhcyBmb3IgcGF0aC5cbiAgdG86IFByb3BUeXBlcy5zdHJpbmcsXG4gIGhhbmRsZXI6IFByb3BUeXBlcy5mYWxzeVxufTtcblxuLy8gUmVkaXJlY3RzIHNob3VsZCBub3QgaGF2ZSBhIGRlZmF1bHQgaGFuZGxlclxuUmVkaXJlY3QuZGVmYXVsdFByb3BzID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gUmVkaXJlY3Q7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgndmFsdWUnIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXG52YXIgX2dldCA9IGZ1bmN0aW9uIGdldChfeCwgX3gyLCBfeDMpIHsgdmFyIF9hZ2FpbiA9IHRydWU7IF9mdW5jdGlvbjogd2hpbGUgKF9hZ2FpbikgeyB2YXIgb2JqZWN0ID0gX3gsIHByb3BlcnR5ID0gX3gyLCByZWNlaXZlciA9IF94MzsgX2FnYWluID0gZmFsc2U7IGlmIChvYmplY3QgPT09IG51bGwpIG9iamVjdCA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyBfeCA9IHBhcmVudDsgX3gyID0gcHJvcGVydHk7IF94MyA9IHJlY2VpdmVyOyBfYWdhaW4gPSB0cnVlOyBkZXNjID0gcGFyZW50ID0gdW5kZWZpbmVkOyBjb250aW51ZSBfZnVuY3Rpb247IH0gfSBlbHNlIGlmICgndmFsdWUnIGluIGRlc2MpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ludmFyaWFudCcpO1xudmFyIFByb3BUeXBlcyA9IHJlcXVpcmUoJy4uL1Byb3BUeXBlcycpO1xudmFyIFJvdXRlSGFuZGxlciA9IHJlcXVpcmUoJy4vUm91dGVIYW5kbGVyJyk7XG5cbi8qKlxuICogPFJvdXRlPiBjb21wb25lbnRzIHNwZWNpZnkgY29tcG9uZW50cyB0aGF0IGFyZSByZW5kZXJlZCB0byB0aGUgcGFnZSB3aGVuIHRoZVxuICogVVJMIG1hdGNoZXMgYSBnaXZlbiBwYXR0ZXJuLlxuICpcbiAqIFJvdXRlcyBhcmUgYXJyYW5nZWQgaW4gYSBuZXN0ZWQgdHJlZSBzdHJ1Y3R1cmUuIFdoZW4gYSBuZXcgVVJMIGlzIHJlcXVlc3RlZCxcbiAqIHRoZSB0cmVlIGlzIHNlYXJjaGVkIGRlcHRoLWZpcnN0IHRvIGZpbmQgYSByb3V0ZSB3aG9zZSBwYXRoIG1hdGNoZXMgdGhlIFVSTC5cbiAqIFdoZW4gb25lIGlzIGZvdW5kLCBhbGwgcm91dGVzIGluIHRoZSB0cmVlIHRoYXQgbGVhZCB0byBpdCBhcmUgY29uc2lkZXJlZFxuICogXCJhY3RpdmVcIiBhbmQgdGhlaXIgY29tcG9uZW50cyBhcmUgcmVuZGVyZWQgaW50byB0aGUgRE9NLCBuZXN0ZWQgaW4gdGhlIHNhbWVcbiAqIG9yZGVyIGFzIHRoZXkgYXJlIGluIHRoZSB0cmVlLlxuICpcbiAqIFRoZSBwcmVmZXJyZWQgd2F5IHRvIGNvbmZpZ3VyZSBhIHJvdXRlciBpcyB1c2luZyBKU1guIFRoZSBYTUwtbGlrZSBzeW50YXggaXNcbiAqIGEgZ3JlYXQgd2F5IHRvIHZpc3VhbGl6ZSBob3cgcm91dGVzIGFyZSBsYWlkIG91dCBpbiBhbiBhcHBsaWNhdGlvbi5cbiAqXG4gKiAgIHZhciByb3V0ZXMgPSBbXG4gKiAgICAgPFJvdXRlIGhhbmRsZXI9e0FwcH0+XG4gKiAgICAgICA8Um91dGUgbmFtZT1cImxvZ2luXCIgaGFuZGxlcj17TG9naW59Lz5cbiAqICAgICAgIDxSb3V0ZSBuYW1lPVwibG9nb3V0XCIgaGFuZGxlcj17TG9nb3V0fS8+XG4gKiAgICAgICA8Um91dGUgbmFtZT1cImFib3V0XCIgaGFuZGxlcj17QWJvdXR9Lz5cbiAqICAgICA8L1JvdXRlPlxuICogICBdO1xuICogICBcbiAqICAgUm91dGVyLnJ1bihyb3V0ZXMsIGZ1bmN0aW9uIChIYW5kbGVyKSB7XG4gKiAgICAgUmVhY3QucmVuZGVyKDxIYW5kbGVyLz4sIGRvY3VtZW50LmJvZHkpO1xuICogICB9KTtcbiAqXG4gKiBIYW5kbGVycyBmb3IgUm91dGUgY29tcG9uZW50cyB0aGF0IGNvbnRhaW4gY2hpbGRyZW4gY2FuIHJlbmRlciB0aGVpciBhY3RpdmVcbiAqIGNoaWxkIHJvdXRlIHVzaW5nIGEgPFJvdXRlSGFuZGxlcj4gZWxlbWVudC5cbiAqXG4gKiAgIHZhciBBcHAgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gKiAgICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gKiAgICAgICByZXR1cm4gKFxuICogICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFwcGxpY2F0aW9uXCI+XG4gKiAgICAgICAgICAgPFJvdXRlSGFuZGxlci8+XG4gKiAgICAgICAgIDwvZGl2PlxuICogICAgICAgKTtcbiAqICAgICB9XG4gKiAgIH0pO1xuICpcbiAqIElmIG5vIGhhbmRsZXIgaXMgcHJvdmlkZWQgZm9yIHRoZSByb3V0ZSwgaXQgd2lsbCByZW5kZXIgYSBtYXRjaGVkIGNoaWxkIHJvdXRlLlxuICovXG5cbnZhciBSb3V0ZSA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoUm91dGUsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIGZ1bmN0aW9uIFJvdXRlKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSb3V0ZSk7XG5cbiAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihSb3V0ZS5wcm90b3R5cGUpLCAnY29uc3RydWN0b3InLCB0aGlzKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLy8gVE9ETzogSW5jbHVkZSB0aGVzZSBpbiB0aGUgYWJvdmUgY2xhc3MgZGVmaW5pdGlvblxuICAvLyBvbmNlIHdlIGNhbiB1c2UgRVM3IHByb3BlcnR5IGluaXRpYWxpemVycy5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JhYmVsL2JhYmVsL2lzc3Vlcy82MTlcblxuICBfY3JlYXRlQ2xhc3MoUm91dGUsIFt7XG4gICAga2V5OiAncmVuZGVyJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgaW52YXJpYW50KGZhbHNlLCAnJXMgZWxlbWVudHMgYXJlIGZvciByb3V0ZXIgY29uZmlndXJhdGlvbiBvbmx5IGFuZCBzaG91bGQgbm90IGJlIHJlbmRlcmVkJywgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUm91dGU7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Sb3V0ZS5wcm9wVHlwZXMgPSB7XG4gIG5hbWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhdGg6IFByb3BUeXBlcy5zdHJpbmcsXG4gIGhhbmRsZXI6IFByb3BUeXBlcy5mdW5jLFxuICBpZ25vcmVTY3JvbGxCZWhhdmlvcjogUHJvcFR5cGVzLmJvb2xcbn07XG5cblJvdXRlLmRlZmF1bHRQcm9wcyA9IHtcbiAgaGFuZGxlcjogUm91dGVIYW5kbGVyXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJvdXRlOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoJ3ZhbHVlJyBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblxudmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQoX3gsIF94MiwgX3gzKSB7IHZhciBfYWdhaW4gPSB0cnVlOyBfZnVuY3Rpb246IHdoaWxlIChfYWdhaW4pIHsgdmFyIG9iamVjdCA9IF94LCBwcm9wZXJ0eSA9IF94MiwgcmVjZWl2ZXIgPSBfeDM7IF9hZ2FpbiA9IGZhbHNlOyBpZiAob2JqZWN0ID09PSBudWxsKSBvYmplY3QgPSBGdW5jdGlvbi5wcm90b3R5cGU7IHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTsgaWYgKGRlc2MgPT09IHVuZGVmaW5lZCkgeyB2YXIgcGFyZW50ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7IGlmIChwYXJlbnQgPT09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBlbHNlIHsgX3ggPSBwYXJlbnQ7IF94MiA9IHByb3BlcnR5OyBfeDMgPSByZWNlaXZlcjsgX2FnYWluID0gdHJ1ZTsgZGVzYyA9IHBhcmVudCA9IHVuZGVmaW5lZDsgY29udGludWUgX2Z1bmN0aW9uOyB9IH0gZWxzZSBpZiAoJ3ZhbHVlJyBpbiBkZXNjKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfSB9O1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBDb250ZXh0V3JhcHBlciA9IHJlcXVpcmUoJy4vQ29udGV4dFdyYXBwZXInKTtcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdvYmplY3QtYXNzaWduJyk7XG52YXIgUHJvcFR5cGVzID0gcmVxdWlyZSgnLi4vUHJvcFR5cGVzJyk7XG5cbnZhciBSRUZfTkFNRSA9ICdfX3JvdXRlSGFuZGxlcl9fJztcblxuLyoqXG4gKiBBIDxSb3V0ZUhhbmRsZXI+IGNvbXBvbmVudCByZW5kZXJzIHRoZSBhY3RpdmUgY2hpbGQgcm91dGUgaGFuZGxlclxuICogd2hlbiByb3V0ZXMgYXJlIG5lc3RlZC5cbiAqL1xuXG52YXIgUm91dGVIYW5kbGVyID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhSb3V0ZUhhbmRsZXIsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIGZ1bmN0aW9uIFJvdXRlSGFuZGxlcigpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUm91dGVIYW5kbGVyKTtcblxuICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFJvdXRlSGFuZGxlci5wcm90b3R5cGUpLCAnY29uc3RydWN0b3InLCB0aGlzKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLy8gVE9ETzogSW5jbHVkZSB0aGVzZSBpbiB0aGUgYWJvdmUgY2xhc3MgZGVmaW5pdGlvblxuICAvLyBvbmNlIHdlIGNhbiB1c2UgRVM3IHByb3BlcnR5IGluaXRpYWxpemVycy5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JhYmVsL2JhYmVsL2lzc3Vlcy82MTlcblxuICBfY3JlYXRlQ2xhc3MoUm91dGVIYW5kbGVyLCBbe1xuICAgIGtleTogJ2dldENoaWxkQ29udGV4dCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldENoaWxkQ29udGV4dCgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJvdXRlRGVwdGg6IHRoaXMuY29udGV4dC5yb3V0ZURlcHRoICsgMVxuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdjb21wb25lbnREaWRNb3VudCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgdGhpcy5fdXBkYXRlUm91dGVDb21wb25lbnQodGhpcy5yZWZzW1JFRl9OQU1FXSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnY29tcG9uZW50RGlkVXBkYXRlJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKCkge1xuICAgICAgdGhpcy5fdXBkYXRlUm91dGVDb21wb25lbnQodGhpcy5yZWZzW1JFRl9OQU1FXSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVJvdXRlQ29tcG9uZW50KG51bGwpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ191cGRhdGVSb3V0ZUNvbXBvbmVudCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF91cGRhdGVSb3V0ZUNvbXBvbmVudChjb21wb25lbnQpIHtcbiAgICAgIHRoaXMuY29udGV4dC5yb3V0ZXIuc2V0Um91dGVDb21wb25lbnRBdERlcHRoKHRoaXMuZ2V0Um91dGVEZXB0aCgpLCBjb21wb25lbnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2dldFJvdXRlRGVwdGgnLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRSb3V0ZURlcHRoKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5yb3V0ZURlcHRoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2NyZWF0ZUNoaWxkUm91dGVIYW5kbGVyJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlQ2hpbGRSb3V0ZUhhbmRsZXIocHJvcHMpIHtcbiAgICAgIHZhciByb3V0ZSA9IHRoaXMuY29udGV4dC5yb3V0ZXIuZ2V0Um91dGVBdERlcHRoKHRoaXMuZ2V0Um91dGVEZXB0aCgpKTtcblxuICAgICAgaWYgKHJvdXRlID09IG51bGwpIHJldHVybiBudWxsO1xuXG4gICAgICB2YXIgY2hpbGRQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMgfHwgdGhpcy5wcm9wcywge1xuICAgICAgICByZWY6IFJFRl9OQU1FLFxuICAgICAgICBwYXJhbXM6IHRoaXMuY29udGV4dC5yb3V0ZXIuZ2V0Q3VycmVudFBhcmFtcygpLFxuICAgICAgICBxdWVyeTogdGhpcy5jb250ZXh0LnJvdXRlci5nZXRDdXJyZW50UXVlcnkoKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KHJvdXRlLmhhbmRsZXIsIGNoaWxkUHJvcHMpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ3JlbmRlcicsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHZhciBoYW5kbGVyID0gdGhpcy5jcmVhdGVDaGlsZFJvdXRlSGFuZGxlcigpO1xuICAgICAgLy8gPHNjcmlwdC8+IGZvciB0aGluZ3MgbGlrZSA8Q1NTVHJhbnNpdGlvbkdyb3VwLz4gdGhhdCBkb24ndCBsaWtlIG51bGxcbiAgICAgIHJldHVybiBoYW5kbGVyID8gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgQ29udGV4dFdyYXBwZXIsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGhhbmRsZXJcbiAgICAgICkgOiBSZWFjdC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnLCBudWxsKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUm91dGVIYW5kbGVyO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuUm91dGVIYW5kbGVyLmNvbnRleHRUeXBlcyA9IHtcbiAgcm91dGVEZXB0aDogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICByb3V0ZXI6IFByb3BUeXBlcy5yb3V0ZXIuaXNSZXF1aXJlZFxufTtcblxuUm91dGVIYW5kbGVyLmNoaWxkQ29udGV4dFR5cGVzID0ge1xuICByb3V0ZURlcHRoOiBQcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWRcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUm91dGVIYW5kbGVyOyIsIi8qIGpzaGludCAtVzA1OCAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCcuL3dhcm5pbmcnKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcbnZhciBjYW5Vc2VET00gPSByZXF1aXJlKCdjYW4tdXNlLWRvbScpO1xudmFyIExvY2F0aW9uQWN0aW9ucyA9IHJlcXVpcmUoJy4vYWN0aW9ucy9Mb2NhdGlvbkFjdGlvbnMnKTtcbnZhciBJbWl0YXRlQnJvd3NlckJlaGF2aW9yID0gcmVxdWlyZSgnLi9iZWhhdmlvcnMvSW1pdGF0ZUJyb3dzZXJCZWhhdmlvcicpO1xudmFyIEhhc2hMb2NhdGlvbiA9IHJlcXVpcmUoJy4vbG9jYXRpb25zL0hhc2hMb2NhdGlvbicpO1xudmFyIEhpc3RvcnlMb2NhdGlvbiA9IHJlcXVpcmUoJy4vbG9jYXRpb25zL0hpc3RvcnlMb2NhdGlvbicpO1xudmFyIFJlZnJlc2hMb2NhdGlvbiA9IHJlcXVpcmUoJy4vbG9jYXRpb25zL1JlZnJlc2hMb2NhdGlvbicpO1xudmFyIFN0YXRpY0xvY2F0aW9uID0gcmVxdWlyZSgnLi9sb2NhdGlvbnMvU3RhdGljTG9jYXRpb24nKTtcbnZhciBTY3JvbGxIaXN0b3J5ID0gcmVxdWlyZSgnLi9TY3JvbGxIaXN0b3J5Jyk7XG52YXIgY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW4gPSByZXF1aXJlKCcuL2NyZWF0ZVJvdXRlc0Zyb21SZWFjdENoaWxkcmVuJyk7XG52YXIgaXNSZWFjdENoaWxkcmVuID0gcmVxdWlyZSgnLi9pc1JlYWN0Q2hpbGRyZW4nKTtcbnZhciBUcmFuc2l0aW9uID0gcmVxdWlyZSgnLi9UcmFuc2l0aW9uJyk7XG52YXIgUHJvcFR5cGVzID0gcmVxdWlyZSgnLi9Qcm9wVHlwZXMnKTtcbnZhciBSZWRpcmVjdCA9IHJlcXVpcmUoJy4vUmVkaXJlY3QnKTtcbnZhciBIaXN0b3J5ID0gcmVxdWlyZSgnLi9IaXN0b3J5Jyk7XG52YXIgQ2FuY2VsbGF0aW9uID0gcmVxdWlyZSgnLi9DYW5jZWxsYXRpb24nKTtcbnZhciBNYXRjaCA9IHJlcXVpcmUoJy4vTWF0Y2gnKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vUm91dGUnKTtcbnZhciBzdXBwb3J0c0hpc3RvcnkgPSByZXF1aXJlKCcuL3N1cHBvcnRzSGlzdG9yeScpO1xudmFyIFBhdGhVdGlscyA9IHJlcXVpcmUoJy4vUGF0aFV0aWxzJyk7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgbG9jYXRpb24gZm9yIG5ldyByb3V0ZXJzLlxuICovXG52YXIgREVGQVVMVF9MT0NBVElPTiA9IGNhblVzZURPTSA/IEhhc2hMb2NhdGlvbiA6ICcvJztcblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBzY3JvbGwgYmVoYXZpb3IgZm9yIG5ldyByb3V0ZXJzLlxuICovXG52YXIgREVGQVVMVF9TQ1JPTExfQkVIQVZJT1IgPSBjYW5Vc2VET00gPyBJbWl0YXRlQnJvd3NlckJlaGF2aW9yIDogbnVsbDtcblxuZnVuY3Rpb24gaGFzUHJvcGVydGllcyhvYmplY3QsIHByb3BlcnRpZXMpIHtcbiAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KHByb3BlcnR5TmFtZSkgJiYgb2JqZWN0W3Byb3BlcnR5TmFtZV0gIT09IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBoYXNNYXRjaChyb3V0ZXMsIHJvdXRlLCBwcmV2UGFyYW1zLCBuZXh0UGFyYW1zLCBwcmV2UXVlcnksIG5leHRRdWVyeSkge1xuICByZXR1cm4gcm91dGVzLnNvbWUoZnVuY3Rpb24gKHIpIHtcbiAgICBpZiAociAhPT0gcm91dGUpIHJldHVybiBmYWxzZTtcblxuICAgIHZhciBwYXJhbU5hbWVzID0gcm91dGUucGFyYW1OYW1lcztcbiAgICB2YXIgcGFyYW1OYW1lO1xuXG4gICAgLy8gRW5zdXJlIHRoYXQgYWxsIHBhcmFtcyB0aGUgcm91dGUgY2FyZXMgYWJvdXQgZGlkIG5vdCBjaGFuZ2UuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBhcmFtTmFtZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHBhcmFtTmFtZSA9IHBhcmFtTmFtZXNbaV07XG5cbiAgICAgIGlmIChuZXh0UGFyYW1zW3BhcmFtTmFtZV0gIT09IHByZXZQYXJhbXNbcGFyYW1OYW1lXSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEVuc3VyZSB0aGUgcXVlcnkgaGFzbid0IGNoYW5nZWQuXG4gICAgcmV0dXJuIGhhc1Byb3BlcnRpZXMocHJldlF1ZXJ5LCBuZXh0UXVlcnkpICYmIGhhc1Byb3BlcnRpZXMobmV4dFF1ZXJ5LCBwcmV2UXVlcnkpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gYWRkUm91dGVzVG9OYW1lZFJvdXRlcyhyb3V0ZXMsIG5hbWVkUm91dGVzKSB7XG4gIHZhciByb3V0ZTtcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHJvdXRlcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHJvdXRlID0gcm91dGVzW2ldO1xuXG4gICAgaWYgKHJvdXRlLm5hbWUpIHtcbiAgICAgIGludmFyaWFudChuYW1lZFJvdXRlc1tyb3V0ZS5uYW1lXSA9PSBudWxsLCAnWW91IG1heSBub3QgaGF2ZSBtb3JlIHRoYW4gb25lIHJvdXRlIG5hbWVkIFwiJXNcIicsIHJvdXRlLm5hbWUpO1xuXG4gICAgICBuYW1lZFJvdXRlc1tyb3V0ZS5uYW1lXSA9IHJvdXRlO1xuICAgIH1cblxuICAgIGlmIChyb3V0ZS5jaGlsZFJvdXRlcykgYWRkUm91dGVzVG9OYW1lZFJvdXRlcyhyb3V0ZS5jaGlsZFJvdXRlcywgbmFtZWRSb3V0ZXMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJvdXRlSXNBY3RpdmUoYWN0aXZlUm91dGVzLCByb3V0ZU5hbWUpIHtcbiAgcmV0dXJuIGFjdGl2ZVJvdXRlcy5zb21lKGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgIHJldHVybiByb3V0ZS5uYW1lID09PSByb3V0ZU5hbWU7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBwYXJhbXNBcmVBY3RpdmUoYWN0aXZlUGFyYW1zLCBwYXJhbXMpIHtcbiAgZm9yICh2YXIgcHJvcGVydHkgaW4gcGFyYW1zKSBpZiAoU3RyaW5nKGFjdGl2ZVBhcmFtc1twcm9wZXJ0eV0pICE9PSBTdHJpbmcocGFyYW1zW3Byb3BlcnR5XSkpIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcXVlcnlJc0FjdGl2ZShhY3RpdmVRdWVyeSwgcXVlcnkpIHtcbiAgZm9yICh2YXIgcHJvcGVydHkgaW4gcXVlcnkpIGlmIChTdHJpbmcoYWN0aXZlUXVlcnlbcHJvcGVydHldKSAhPT0gU3RyaW5nKHF1ZXJ5W3Byb3BlcnR5XSkpIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgbmV3IHJvdXRlciB1c2luZyB0aGUgZ2l2ZW4gb3B0aW9ucy4gQSByb3V0ZXJcbiAqIGlzIGEgUmVhY3RDb21wb25lbnQgY2xhc3MgdGhhdCBrbm93cyBob3cgdG8gcmVhY3QgdG8gY2hhbmdlcyBpbiB0aGVcbiAqIFVSTCBhbmQga2VlcCB0aGUgY29udGVudHMgb2YgdGhlIHBhZ2UgaW4gc3luYy5cbiAqXG4gKiBPcHRpb25zIG1heSBiZSBhbnkgb2YgdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAtIHJvdXRlcyAgICAgICAgICAgKHJlcXVpcmVkKSBUaGUgcm91dGUgY29uZmlnXG4gKiAtIGxvY2F0aW9uICAgICAgICAgVGhlIGxvY2F0aW9uIHRvIHVzZS4gRGVmYXVsdHMgdG8gSGFzaExvY2F0aW9uIHdoZW5cbiAqICAgICAgICAgICAgICAgICAgICB0aGUgRE9NIGlzIGF2YWlsYWJsZSwgXCIvXCIgb3RoZXJ3aXNlXG4gKiAtIHNjcm9sbEJlaGF2aW9yICAgVGhlIHNjcm9sbCBiZWhhdmlvciB0byB1c2UuIERlZmF1bHRzIHRvIEltaXRhdGVCcm93c2VyQmVoYXZpb3JcbiAqICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSBET00gaXMgYXZhaWxhYmxlLCBudWxsIG90aGVyd2lzZVxuICogLSBvbkVycm9yICAgICAgICAgIEEgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGhhbmRsZSBlcnJvcnNcbiAqIC0gb25BYm9ydCAgICAgICAgICBBIGZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBoYW5kbGUgYWJvcnRlZCB0cmFuc2l0aW9uc1xuICpcbiAqIFdoZW4gcmVuZGVyaW5nIGluIGEgc2VydmVyLXNpZGUgZW52aXJvbm1lbnQsIHRoZSBsb2NhdGlvbiBzaG91bGQgc2ltcGx5XG4gKiBiZSB0aGUgVVJMIHBhdGggdGhhdCB3YXMgdXNlZCBpbiB0aGUgcmVxdWVzdCwgaW5jbHVkaW5nIHRoZSBxdWVyeSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlcihvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpc1JlYWN0Q2hpbGRyZW4ob3B0aW9ucykpIG9wdGlvbnMgPSB7IHJvdXRlczogb3B0aW9ucyB9O1xuXG4gIHZhciBtb3VudGVkQ29tcG9uZW50cyA9IFtdO1xuICB2YXIgbG9jYXRpb24gPSBvcHRpb25zLmxvY2F0aW9uIHx8IERFRkFVTFRfTE9DQVRJT047XG4gIHZhciBzY3JvbGxCZWhhdmlvciA9IG9wdGlvbnMuc2Nyb2xsQmVoYXZpb3IgfHwgREVGQVVMVF9TQ1JPTExfQkVIQVZJT1I7XG4gIHZhciBzdGF0ZSA9IHt9O1xuICB2YXIgbmV4dFN0YXRlID0ge307XG4gIHZhciBwZW5kaW5nVHJhbnNpdGlvbiA9IG51bGw7XG4gIHZhciBkaXNwYXRjaEhhbmRsZXIgPSBudWxsO1xuXG4gIGlmICh0eXBlb2YgbG9jYXRpb24gPT09ICdzdHJpbmcnKSBsb2NhdGlvbiA9IG5ldyBTdGF0aWNMb2NhdGlvbihsb2NhdGlvbik7XG5cbiAgaWYgKGxvY2F0aW9uIGluc3RhbmNlb2YgU3RhdGljTG9jYXRpb24pIHtcbiAgICB3YXJuaW5nKCFjYW5Vc2VET00gfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICd0ZXN0JywgJ1lvdSBzaG91bGQgbm90IHVzZSBhIHN0YXRpYyBsb2NhdGlvbiBpbiBhIERPTSBlbnZpcm9ubWVudCBiZWNhdXNlICcgKyAndGhlIHJvdXRlciB3aWxsIG5vdCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgY3VycmVudCBVUkwnKTtcbiAgfSBlbHNlIHtcbiAgICBpbnZhcmlhbnQoY2FuVXNlRE9NIHx8IGxvY2F0aW9uLm5lZWRzRE9NID09PSBmYWxzZSwgJ1lvdSBjYW5ub3QgdXNlICVzIHdpdGhvdXQgYSBET00nLCBsb2NhdGlvbik7XG4gIH1cblxuICAvLyBBdXRvbWF0aWNhbGx5IGZhbGwgYmFjayB0byBmdWxsIHBhZ2UgcmVmcmVzaGVzIGluXG4gIC8vIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCB0aGUgSFRNTCBoaXN0b3J5IEFQSS5cbiAgaWYgKGxvY2F0aW9uID09PSBIaXN0b3J5TG9jYXRpb24gJiYgIXN1cHBvcnRzSGlzdG9yeSgpKSBsb2NhdGlvbiA9IFJlZnJlc2hMb2NhdGlvbjtcblxuICB2YXIgUm91dGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXG4gICAgZGlzcGxheU5hbWU6ICdSb3V0ZXInLFxuXG4gICAgc3RhdGljczoge1xuXG4gICAgICBpc1J1bm5pbmc6IGZhbHNlLFxuXG4gICAgICBjYW5jZWxQZW5kaW5nVHJhbnNpdGlvbjogZnVuY3Rpb24gY2FuY2VsUGVuZGluZ1RyYW5zaXRpb24oKSB7XG4gICAgICAgIGlmIChwZW5kaW5nVHJhbnNpdGlvbikge1xuICAgICAgICAgIHBlbmRpbmdUcmFuc2l0aW9uLmNhbmNlbCgpO1xuICAgICAgICAgIHBlbmRpbmdUcmFuc2l0aW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgY2xlYXJBbGxSb3V0ZXM6IGZ1bmN0aW9uIGNsZWFyQWxsUm91dGVzKCkge1xuICAgICAgICBSb3V0ZXIuY2FuY2VsUGVuZGluZ1RyYW5zaXRpb24oKTtcbiAgICAgICAgUm91dGVyLm5hbWVkUm91dGVzID0ge307XG4gICAgICAgIFJvdXRlci5yb3V0ZXMgPSBbXTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogQWRkcyByb3V0ZXMgdG8gdGhpcyByb3V0ZXIgZnJvbSB0aGUgZ2l2ZW4gY2hpbGRyZW4gb2JqZWN0IChzZWUgUmVhY3RDaGlsZHJlbikuXG4gICAgICAgKi9cbiAgICAgIGFkZFJvdXRlczogZnVuY3Rpb24gYWRkUm91dGVzKHJvdXRlcykge1xuICAgICAgICBpZiAoaXNSZWFjdENoaWxkcmVuKHJvdXRlcykpIHJvdXRlcyA9IGNyZWF0ZVJvdXRlc0Zyb21SZWFjdENoaWxkcmVuKHJvdXRlcyk7XG5cbiAgICAgICAgYWRkUm91dGVzVG9OYW1lZFJvdXRlcyhyb3V0ZXMsIFJvdXRlci5uYW1lZFJvdXRlcyk7XG5cbiAgICAgICAgUm91dGVyLnJvdXRlcy5wdXNoLmFwcGx5KFJvdXRlci5yb3V0ZXMsIHJvdXRlcyk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJlcGxhY2VzIHJvdXRlcyBvZiB0aGlzIHJvdXRlciBmcm9tIHRoZSBnaXZlbiBjaGlsZHJlbiBvYmplY3QgKHNlZSBSZWFjdENoaWxkcmVuKS5cbiAgICAgICAqL1xuICAgICAgcmVwbGFjZVJvdXRlczogZnVuY3Rpb24gcmVwbGFjZVJvdXRlcyhyb3V0ZXMpIHtcbiAgICAgICAgUm91dGVyLmNsZWFyQWxsUm91dGVzKCk7XG4gICAgICAgIFJvdXRlci5hZGRSb3V0ZXMocm91dGVzKTtcbiAgICAgICAgUm91dGVyLnJlZnJlc2goKTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUGVyZm9ybXMgYSBtYXRjaCBvZiB0aGUgZ2l2ZW4gcGF0aCBhZ2FpbnN0IHRoaXMgcm91dGVyIGFuZCByZXR1cm5zIGFuIG9iamVjdFxuICAgICAgICogd2l0aCB0aGUgeyByb3V0ZXMsIHBhcmFtcywgcGF0aG5hbWUsIHF1ZXJ5IH0gdGhhdCBtYXRjaC4gUmV0dXJucyBudWxsIGlmIG5vXG4gICAgICAgKiBtYXRjaCBjYW4gYmUgbWFkZS5cbiAgICAgICAqL1xuICAgICAgbWF0Y2g6IGZ1bmN0aW9uIG1hdGNoKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGNoLmZpbmRNYXRjaChSb3V0ZXIucm91dGVzLCBwYXRoKTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyBhbiBhYnNvbHV0ZSBVUkwgcGF0aCBjcmVhdGVkIGZyb20gdGhlIGdpdmVuIHJvdXRlXG4gICAgICAgKiBuYW1lLCBVUkwgcGFyYW1ldGVycywgYW5kIHF1ZXJ5LlxuICAgICAgICovXG4gICAgICBtYWtlUGF0aDogZnVuY3Rpb24gbWFrZVBhdGgodG8sIHBhcmFtcywgcXVlcnkpIHtcbiAgICAgICAgdmFyIHBhdGg7XG4gICAgICAgIGlmIChQYXRoVXRpbHMuaXNBYnNvbHV0ZSh0bykpIHtcbiAgICAgICAgICBwYXRoID0gdG87XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHJvdXRlID0gdG8gaW5zdGFuY2VvZiBSb3V0ZSA/IHRvIDogUm91dGVyLm5hbWVkUm91dGVzW3RvXTtcblxuICAgICAgICAgIGludmFyaWFudChyb3V0ZSBpbnN0YW5jZW9mIFJvdXRlLCAnQ2Fubm90IGZpbmQgYSByb3V0ZSBuYW1lZCBcIiVzXCInLCB0byk7XG5cbiAgICAgICAgICBwYXRoID0gcm91dGUucGF0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQYXRoVXRpbHMud2l0aFF1ZXJ5KFBhdGhVdGlscy5pbmplY3RQYXJhbXMocGF0aCwgcGFyYW1zKSwgcXVlcnkpO1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHRoYXQgbWF5IHNhZmVseSBiZSB1c2VkIGFzIHRoZSBocmVmIG9mIGEgbGlua1xuICAgICAgICogdG8gdGhlIHJvdXRlIHdpdGggdGhlIGdpdmVuIG5hbWUsIFVSTCBwYXJhbWV0ZXJzLCBhbmQgcXVlcnkuXG4gICAgICAgKi9cbiAgICAgIG1ha2VIcmVmOiBmdW5jdGlvbiBtYWtlSHJlZih0bywgcGFyYW1zLCBxdWVyeSkge1xuICAgICAgICB2YXIgcGF0aCA9IFJvdXRlci5tYWtlUGF0aCh0bywgcGFyYW1zLCBxdWVyeSk7XG4gICAgICAgIHJldHVybiBsb2NhdGlvbiA9PT0gSGFzaExvY2F0aW9uID8gJyMnICsgcGF0aCA6IHBhdGg7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFRyYW5zaXRpb25zIHRvIHRoZSBVUkwgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHMgYnkgcHVzaGluZ1xuICAgICAgICogYSBuZXcgVVJMIG9udG8gdGhlIGhpc3Rvcnkgc3RhY2suXG4gICAgICAgKi9cbiAgICAgIHRyYW5zaXRpb25UbzogZnVuY3Rpb24gdHJhbnNpdGlvblRvKHRvLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gICAgICAgIHZhciBwYXRoID0gUm91dGVyLm1ha2VQYXRoKHRvLCBwYXJhbXMsIHF1ZXJ5KTtcblxuICAgICAgICBpZiAocGVuZGluZ1RyYW5zaXRpb24pIHtcbiAgICAgICAgICAvLyBSZXBsYWNlIHNvIHBlbmRpbmcgbG9jYXRpb24gZG9lcyBub3Qgc3RheSBpbiBoaXN0b3J5LlxuICAgICAgICAgIGxvY2F0aW9uLnJlcGxhY2UocGF0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9jYXRpb24ucHVzaChwYXRoKTtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBUcmFuc2l0aW9ucyB0byB0aGUgVVJMIHNwZWNpZmllZCBpbiB0aGUgYXJndW1lbnRzIGJ5IHJlcGxhY2luZ1xuICAgICAgICogdGhlIGN1cnJlbnQgVVJMIGluIHRoZSBoaXN0b3J5IHN0YWNrLlxuICAgICAgICovXG4gICAgICByZXBsYWNlV2l0aDogZnVuY3Rpb24gcmVwbGFjZVdpdGgodG8sIHBhcmFtcywgcXVlcnkpIHtcbiAgICAgICAgbG9jYXRpb24ucmVwbGFjZShSb3V0ZXIubWFrZVBhdGgodG8sIHBhcmFtcywgcXVlcnkpKTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogVHJhbnNpdGlvbnMgdG8gdGhlIHByZXZpb3VzIFVSTCBpZiBvbmUgaXMgYXZhaWxhYmxlLiBSZXR1cm5zIHRydWUgaWYgdGhlXG4gICAgICAgKiByb3V0ZXIgd2FzIGFibGUgdG8gZ28gYmFjaywgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAgICpcbiAgICAgICAqIE5vdGU6IFRoZSByb3V0ZXIgb25seSB0cmFja3MgaGlzdG9yeSBlbnRyaWVzIGluIHlvdXIgYXBwbGljYXRpb24sIG5vdCB0aGVcbiAgICAgICAqIGN1cnJlbnQgYnJvd3NlciBzZXNzaW9uLCBzbyB5b3UgY2FuIHNhZmVseSBjYWxsIHRoaXMgZnVuY3Rpb24gd2l0aG91dCBndWFyZGluZ1xuICAgICAgICogYWdhaW5zdCBzZW5kaW5nIHRoZSB1c2VyIGJhY2sgdG8gc29tZSBvdGhlciBzaXRlLiBIb3dldmVyLCB3aGVuIHVzaW5nXG4gICAgICAgKiBSZWZyZXNoTG9jYXRpb24gKHdoaWNoIGlzIHRoZSBmYWxsYmFjayBmb3IgSGlzdG9yeUxvY2F0aW9uIGluIGJyb3dzZXJzIHRoYXRcbiAgICAgICAqIGRvbid0IHN1cHBvcnQgSFRNTDUgaGlzdG9yeSkgdGhpcyBtZXRob2Qgd2lsbCAqYWx3YXlzKiBzZW5kIHRoZSBjbGllbnQgYmFja1xuICAgICAgICogYmVjYXVzZSB3ZSBjYW5ub3QgcmVsaWFibHkgdHJhY2sgaGlzdG9yeSBsZW5ndGguXG4gICAgICAgKi9cbiAgICAgIGdvQmFjazogZnVuY3Rpb24gZ29CYWNrKCkge1xuICAgICAgICBpZiAoSGlzdG9yeS5sZW5ndGggPiAxIHx8IGxvY2F0aW9uID09PSBSZWZyZXNoTG9jYXRpb24pIHtcbiAgICAgICAgICBsb2NhdGlvbi5wb3AoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdhcm5pbmcoZmFsc2UsICdnb0JhY2soKSB3YXMgaWdub3JlZCBiZWNhdXNlIHRoZXJlIGlzIG5vIHJvdXRlciBoaXN0b3J5Jyk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcblxuICAgICAgaGFuZGxlQWJvcnQ6IG9wdGlvbnMub25BYm9ydCB8fCBmdW5jdGlvbiAoYWJvcnRSZWFzb24pIHtcbiAgICAgICAgaWYgKGxvY2F0aW9uIGluc3RhbmNlb2YgU3RhdGljTG9jYXRpb24pIHRocm93IG5ldyBFcnJvcignVW5oYW5kbGVkIGFib3J0ZWQgdHJhbnNpdGlvbiEgUmVhc29uOiAnICsgYWJvcnRSZWFzb24pO1xuXG4gICAgICAgIGlmIChhYm9ydFJlYXNvbiBpbnN0YW5jZW9mIENhbmNlbGxhdGlvbikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChhYm9ydFJlYXNvbiBpbnN0YW5jZW9mIFJlZGlyZWN0KSB7XG4gICAgICAgICAgbG9jYXRpb24ucmVwbGFjZShSb3V0ZXIubWFrZVBhdGgoYWJvcnRSZWFzb24udG8sIGFib3J0UmVhc29uLnBhcmFtcywgYWJvcnRSZWFzb24ucXVlcnkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2NhdGlvbi5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgaGFuZGxlRXJyb3I6IG9wdGlvbnMub25FcnJvciB8fCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgLy8gVGhyb3cgc28gd2UgZG9uJ3Qgc2lsZW50bHkgc3dhbGxvdyBhc3luYyBlcnJvcnMuXG4gICAgICAgIHRocm93IGVycm9yOyAvLyBUaGlzIGVycm9yIHByb2JhYmx5IG9yaWdpbmF0ZWQgaW4gYSB0cmFuc2l0aW9uIGhvb2suXG4gICAgICB9LFxuXG4gICAgICBoYW5kbGVMb2NhdGlvbkNoYW5nZTogZnVuY3Rpb24gaGFuZGxlTG9jYXRpb25DaGFuZ2UoY2hhbmdlKSB7XG4gICAgICAgIFJvdXRlci5kaXNwYXRjaChjaGFuZ2UucGF0aCwgY2hhbmdlLnR5cGUpO1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBQZXJmb3JtcyBhIHRyYW5zaXRpb24gdG8gdGhlIGdpdmVuIHBhdGggYW5kIGNhbGxzIGNhbGxiYWNrKGVycm9yLCBhYm9ydFJlYXNvbilcbiAgICAgICAqIHdoZW4gdGhlIHRyYW5zaXRpb24gaXMgZmluaXNoZWQuIElmIGJvdGggYXJndW1lbnRzIGFyZSBudWxsIHRoZSByb3V0ZXIncyBzdGF0ZVxuICAgICAgICogd2FzIHVwZGF0ZWQuIE90aGVyd2lzZSB0aGUgdHJhbnNpdGlvbiBkaWQgbm90IGNvbXBsZXRlLlxuICAgICAgICpcbiAgICAgICAqIEluIGEgdHJhbnNpdGlvbiwgYSByb3V0ZXIgZmlyc3QgZGV0ZXJtaW5lcyB3aGljaCByb3V0ZXMgYXJlIGludm9sdmVkIGJ5IGJlZ2lubmluZ1xuICAgICAgICogd2l0aCB0aGUgY3VycmVudCByb3V0ZSwgdXAgdGhlIHJvdXRlIHRyZWUgdG8gdGhlIGZpcnN0IHBhcmVudCByb3V0ZSB0aGF0IGlzIHNoYXJlZFxuICAgICAgICogd2l0aCB0aGUgZGVzdGluYXRpb24gcm91dGUsIGFuZCBiYWNrIGRvd24gdGhlIHRyZWUgdG8gdGhlIGRlc3RpbmF0aW9uIHJvdXRlLiBUaGVcbiAgICAgICAqIHdpbGxUcmFuc2l0aW9uRnJvbSBob29rIGlzIGludm9rZWQgb24gYWxsIHJvdXRlIGhhbmRsZXJzIHdlJ3JlIHRyYW5zaXRpb25pbmcgYXdheVxuICAgICAgICogZnJvbSwgaW4gcmV2ZXJzZSBuZXN0aW5nIG9yZGVyLiBMaWtld2lzZSwgdGhlIHdpbGxUcmFuc2l0aW9uVG8gaG9vayBpcyBpbnZva2VkIG9uXG4gICAgICAgKiBhbGwgcm91dGUgaGFuZGxlcnMgd2UncmUgdHJhbnNpdGlvbmluZyB0by5cbiAgICAgICAqXG4gICAgICAgKiBCb3RoIHdpbGxUcmFuc2l0aW9uRnJvbSBhbmQgd2lsbFRyYW5zaXRpb25UbyBob29rcyBtYXkgZWl0aGVyIGFib3J0IG9yIHJlZGlyZWN0IHRoZVxuICAgICAgICogdHJhbnNpdGlvbi4gVG8gcmVzb2x2ZSBhc3luY2hyb25vdXNseSwgdGhleSBtYXkgdXNlIHRoZSBjYWxsYmFjayBhcmd1bWVudC4gSWYgbm9cbiAgICAgICAqIGhvb2tzIHdhaXQsIHRoZSB0cmFuc2l0aW9uIGlzIGZ1bGx5IHN5bmNocm9ub3VzLlxuICAgICAgICovXG4gICAgICBkaXNwYXRjaDogZnVuY3Rpb24gZGlzcGF0Y2gocGF0aCwgYWN0aW9uKSB7XG4gICAgICAgIFJvdXRlci5jYW5jZWxQZW5kaW5nVHJhbnNpdGlvbigpO1xuXG4gICAgICAgIHZhciBwcmV2UGF0aCA9IHN0YXRlLnBhdGg7XG4gICAgICAgIHZhciBpc1JlZnJlc2hpbmcgPSBhY3Rpb24gPT0gbnVsbDtcblxuICAgICAgICBpZiAocHJldlBhdGggPT09IHBhdGggJiYgIWlzUmVmcmVzaGluZykgcmV0dXJuOyAvLyBOb3RoaW5nIHRvIGRvIVxuXG4gICAgICAgIC8vIFJlY29yZCB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFzIGVhcmx5IGFzIHBvc3NpYmxlIHRvXG4gICAgICAgIC8vIGdldCBpdCBiZWZvcmUgYnJvd3NlcnMgdHJ5IHVwZGF0ZSBpdCBhdXRvbWF0aWNhbGx5LlxuICAgICAgICBpZiAocHJldlBhdGggJiYgYWN0aW9uID09PSBMb2NhdGlvbkFjdGlvbnMuUFVTSCkgUm91dGVyLnJlY29yZFNjcm9sbFBvc2l0aW9uKHByZXZQYXRoKTtcblxuICAgICAgICB2YXIgbWF0Y2ggPSBSb3V0ZXIubWF0Y2gocGF0aCk7XG5cbiAgICAgICAgd2FybmluZyhtYXRjaCAhPSBudWxsLCAnTm8gcm91dGUgbWF0Y2hlcyBwYXRoIFwiJXNcIi4gTWFrZSBzdXJlIHlvdSBoYXZlIDxSb3V0ZSBwYXRoPVwiJXNcIj4gc29tZXdoZXJlIGluIHlvdXIgcm91dGVzJywgcGF0aCwgcGF0aCk7XG5cbiAgICAgICAgaWYgKG1hdGNoID09IG51bGwpIG1hdGNoID0ge307XG5cbiAgICAgICAgdmFyIHByZXZSb3V0ZXMgPSBzdGF0ZS5yb3V0ZXMgfHwgW107XG4gICAgICAgIHZhciBwcmV2UGFyYW1zID0gc3RhdGUucGFyYW1zIHx8IHt9O1xuICAgICAgICB2YXIgcHJldlF1ZXJ5ID0gc3RhdGUucXVlcnkgfHwge307XG5cbiAgICAgICAgdmFyIG5leHRSb3V0ZXMgPSBtYXRjaC5yb3V0ZXMgfHwgW107XG4gICAgICAgIHZhciBuZXh0UGFyYW1zID0gbWF0Y2gucGFyYW1zIHx8IHt9O1xuICAgICAgICB2YXIgbmV4dFF1ZXJ5ID0gbWF0Y2gucXVlcnkgfHwge307XG5cbiAgICAgICAgdmFyIGZyb21Sb3V0ZXMsIHRvUm91dGVzO1xuICAgICAgICBpZiAocHJldlJvdXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICBmcm9tUm91dGVzID0gcHJldlJvdXRlcy5maWx0ZXIoZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gIWhhc01hdGNoKG5leHRSb3V0ZXMsIHJvdXRlLCBwcmV2UGFyYW1zLCBuZXh0UGFyYW1zLCBwcmV2UXVlcnksIG5leHRRdWVyeSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0b1JvdXRlcyA9IG5leHRSb3V0ZXMuZmlsdGVyKGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgICAgICAgICAgcmV0dXJuICFoYXNNYXRjaChwcmV2Um91dGVzLCByb3V0ZSwgcHJldlBhcmFtcywgbmV4dFBhcmFtcywgcHJldlF1ZXJ5LCBuZXh0UXVlcnkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZyb21Sb3V0ZXMgPSBbXTtcbiAgICAgICAgICB0b1JvdXRlcyA9IG5leHRSb3V0ZXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdHJhbnNpdGlvbiA9IG5ldyBUcmFuc2l0aW9uKHBhdGgsIFJvdXRlci5yZXBsYWNlV2l0aC5iaW5kKFJvdXRlciwgcGF0aCkpO1xuICAgICAgICBwZW5kaW5nVHJhbnNpdGlvbiA9IHRyYW5zaXRpb247XG5cbiAgICAgICAgdmFyIGZyb21Db21wb25lbnRzID0gbW91bnRlZENvbXBvbmVudHMuc2xpY2UocHJldlJvdXRlcy5sZW5ndGggLSBmcm9tUm91dGVzLmxlbmd0aCk7XG5cbiAgICAgICAgVHJhbnNpdGlvbi5mcm9tKHRyYW5zaXRpb24sIGZyb21Sb3V0ZXMsIGZyb21Db21wb25lbnRzLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IgfHwgdHJhbnNpdGlvbi5hYm9ydFJlYXNvbikgcmV0dXJuIGRpc3BhdGNoSGFuZGxlci5jYWxsKFJvdXRlciwgZXJyb3IsIHRyYW5zaXRpb24pOyAvLyBObyBuZWVkIHRvIGNvbnRpbnVlLlxuXG4gICAgICAgICAgVHJhbnNpdGlvbi50byh0cmFuc2l0aW9uLCB0b1JvdXRlcywgbmV4dFBhcmFtcywgbmV4dFF1ZXJ5LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGRpc3BhdGNoSGFuZGxlci5jYWxsKFJvdXRlciwgZXJyb3IsIHRyYW5zaXRpb24sIHtcbiAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaC5wYXRobmFtZSxcbiAgICAgICAgICAgICAgcm91dGVzOiBuZXh0Um91dGVzLFxuICAgICAgICAgICAgICBwYXJhbXM6IG5leHRQYXJhbXMsXG4gICAgICAgICAgICAgIHF1ZXJ5OiBuZXh0UXVlcnlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogU3RhcnRzIHRoaXMgcm91dGVyIGFuZCBjYWxscyBjYWxsYmFjayhyb3V0ZXIsIHN0YXRlKSB3aGVuIHRoZSByb3V0ZSBjaGFuZ2VzLlxuICAgICAgICpcbiAgICAgICAqIElmIHRoZSByb3V0ZXIncyBsb2NhdGlvbiBpcyBzdGF0aWMgKGkuZS4gYSBVUkwgcGF0aCBpbiBhIHNlcnZlciBlbnZpcm9ubWVudClcbiAgICAgICAqIHRoZSBjYWxsYmFjayBpcyBjYWxsZWQgb25seSBvbmNlLiBPdGhlcndpc2UsIHRoZSBsb2NhdGlvbiBzaG91bGQgYmUgb25lIG9mIHRoZVxuICAgICAgICogUm91dGVyLipMb2NhdGlvbiBvYmplY3RzIChlLmcuIFJvdXRlci5IYXNoTG9jYXRpb24gb3IgUm91dGVyLkhpc3RvcnlMb2NhdGlvbikuXG4gICAgICAgKi9cbiAgICAgIHJ1bjogZnVuY3Rpb24gcnVuKGNhbGxiYWNrKSB7XG4gICAgICAgIGludmFyaWFudCghUm91dGVyLmlzUnVubmluZywgJ1JvdXRlciBpcyBhbHJlYWR5IHJ1bm5pbmcnKTtcblxuICAgICAgICBkaXNwYXRjaEhhbmRsZXIgPSBmdW5jdGlvbiAoZXJyb3IsIHRyYW5zaXRpb24sIG5ld1N0YXRlKSB7XG4gICAgICAgICAgaWYgKGVycm9yKSBSb3V0ZXIuaGFuZGxlRXJyb3IoZXJyb3IpO1xuXG4gICAgICAgICAgaWYgKHBlbmRpbmdUcmFuc2l0aW9uICE9PSB0cmFuc2l0aW9uKSByZXR1cm47XG5cbiAgICAgICAgICBwZW5kaW5nVHJhbnNpdGlvbiA9IG51bGw7XG5cbiAgICAgICAgICBpZiAodHJhbnNpdGlvbi5hYm9ydFJlYXNvbikge1xuICAgICAgICAgICAgUm91dGVyLmhhbmRsZUFib3J0KHRyYW5zaXRpb24uYWJvcnRSZWFzb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjay5jYWxsKFJvdXRlciwgUm91dGVyLCBuZXh0U3RhdGUgPSBuZXdTdGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghKGxvY2F0aW9uIGluc3RhbmNlb2YgU3RhdGljTG9jYXRpb24pKSB7XG4gICAgICAgICAgaWYgKGxvY2F0aW9uLmFkZENoYW5nZUxpc3RlbmVyKSBsb2NhdGlvbi5hZGRDaGFuZ2VMaXN0ZW5lcihSb3V0ZXIuaGFuZGxlTG9jYXRpb25DaGFuZ2UpO1xuXG4gICAgICAgICAgUm91dGVyLmlzUnVubmluZyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCb290c3RyYXAgdXNpbmcgdGhlIGN1cnJlbnQgcGF0aC5cbiAgICAgICAgUm91dGVyLnJlZnJlc2goKTtcbiAgICAgIH0sXG5cbiAgICAgIHJlZnJlc2g6IGZ1bmN0aW9uIHJlZnJlc2goKSB7XG4gICAgICAgIFJvdXRlci5kaXNwYXRjaChsb2NhdGlvbi5nZXRDdXJyZW50UGF0aCgpLCBudWxsKTtcbiAgICAgIH0sXG5cbiAgICAgIHN0b3A6IGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgICAgIFJvdXRlci5jYW5jZWxQZW5kaW5nVHJhbnNpdGlvbigpO1xuXG4gICAgICAgIGlmIChsb2NhdGlvbi5yZW1vdmVDaGFuZ2VMaXN0ZW5lcikgbG9jYXRpb24ucmVtb3ZlQ2hhbmdlTGlzdGVuZXIoUm91dGVyLmhhbmRsZUxvY2F0aW9uQ2hhbmdlKTtcblxuICAgICAgICBSb3V0ZXIuaXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICB9LFxuXG4gICAgICBnZXRMb2NhdGlvbjogZnVuY3Rpb24gZ2V0TG9jYXRpb24oKSB7XG4gICAgICAgIHJldHVybiBsb2NhdGlvbjtcbiAgICAgIH0sXG5cbiAgICAgIGdldFNjcm9sbEJlaGF2aW9yOiBmdW5jdGlvbiBnZXRTY3JvbGxCZWhhdmlvcigpIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbEJlaGF2aW9yO1xuICAgICAgfSxcblxuICAgICAgZ2V0Um91dGVBdERlcHRoOiBmdW5jdGlvbiBnZXRSb3V0ZUF0RGVwdGgocm91dGVEZXB0aCkge1xuICAgICAgICB2YXIgcm91dGVzID0gc3RhdGUucm91dGVzO1xuICAgICAgICByZXR1cm4gcm91dGVzICYmIHJvdXRlc1tyb3V0ZURlcHRoXTtcbiAgICAgIH0sXG5cbiAgICAgIHNldFJvdXRlQ29tcG9uZW50QXREZXB0aDogZnVuY3Rpb24gc2V0Um91dGVDb21wb25lbnRBdERlcHRoKHJvdXRlRGVwdGgsIGNvbXBvbmVudCkge1xuICAgICAgICBtb3VudGVkQ29tcG9uZW50c1tyb3V0ZURlcHRoXSA9IGNvbXBvbmVudDtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBVUkwgcGF0aCArIHF1ZXJ5IHN0cmluZy5cbiAgICAgICAqL1xuICAgICAgZ2V0Q3VycmVudFBhdGg6IGZ1bmN0aW9uIGdldEN1cnJlbnRQYXRoKCkge1xuICAgICAgICByZXR1cm4gc3RhdGUucGF0aDtcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0aGUgY3VycmVudCBVUkwgcGF0aCB3aXRob3V0IHRoZSBxdWVyeSBzdHJpbmcuXG4gICAgICAgKi9cbiAgICAgIGdldEN1cnJlbnRQYXRobmFtZTogZnVuY3Rpb24gZ2V0Q3VycmVudFBhdGhuYW1lKCkge1xuICAgICAgICByZXR1cm4gc3RhdGUucGF0aG5hbWU7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJldHVybnMgYW4gb2JqZWN0IG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIFVSTCBwYXJhbWV0ZXJzLlxuICAgICAgICovXG4gICAgICBnZXRDdXJyZW50UGFyYW1zOiBmdW5jdGlvbiBnZXRDdXJyZW50UGFyYW1zKCkge1xuICAgICAgICByZXR1cm4gc3RhdGUucGFyYW1zO1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCBvZiB0aGUgY3VycmVudGx5IGFjdGl2ZSBxdWVyeSBwYXJhbWV0ZXJzLlxuICAgICAgICovXG4gICAgICBnZXRDdXJyZW50UXVlcnk6IGZ1bmN0aW9uIGdldEN1cnJlbnRRdWVyeSgpIHtcbiAgICAgICAgcmV0dXJuIHN0YXRlLnF1ZXJ5O1xuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIHJvdXRlcy5cbiAgICAgICAqL1xuICAgICAgZ2V0Q3VycmVudFJvdXRlczogZnVuY3Rpb24gZ2V0Q3VycmVudFJvdXRlcygpIHtcbiAgICAgICAgcmV0dXJuIHN0YXRlLnJvdXRlcztcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiByb3V0ZSwgcGFyYW1zLCBhbmQgcXVlcnkgYXJlIGFjdGl2ZS5cbiAgICAgICAqL1xuICAgICAgaXNBY3RpdmU6IGZ1bmN0aW9uIGlzQWN0aXZlKHRvLCBwYXJhbXMsIHF1ZXJ5KSB7XG4gICAgICAgIGlmIChQYXRoVXRpbHMuaXNBYnNvbHV0ZSh0bykpIHJldHVybiB0byA9PT0gc3RhdGUucGF0aDtcblxuICAgICAgICByZXR1cm4gcm91dGVJc0FjdGl2ZShzdGF0ZS5yb3V0ZXMsIHRvKSAmJiBwYXJhbXNBcmVBY3RpdmUoc3RhdGUucGFyYW1zLCBwYXJhbXMpICYmIChxdWVyeSA9PSBudWxsIHx8IHF1ZXJ5SXNBY3RpdmUoc3RhdGUucXVlcnksIHF1ZXJ5KSk7XG4gICAgICB9XG5cbiAgICB9LFxuXG4gICAgbWl4aW5zOiBbU2Nyb2xsSGlzdG9yeV0sXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgIGNoaWxkcmVuOiBQcm9wVHlwZXMuZmFsc3lcbiAgICB9LFxuXG4gICAgY2hpbGRDb250ZXh0VHlwZXM6IHtcbiAgICAgIHJvdXRlRGVwdGg6IFByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZCxcbiAgICAgIHJvdXRlcjogUHJvcFR5cGVzLnJvdXRlci5pc1JlcXVpcmVkXG4gICAgfSxcblxuICAgIGdldENoaWxkQ29udGV4dDogZnVuY3Rpb24gZ2V0Q2hpbGRDb250ZXh0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcm91dGVEZXB0aDogMSxcbiAgICAgICAgcm91dGVyOiBSb3V0ZXJcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgcmV0dXJuIHN0YXRlID0gbmV4dFN0YXRlO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSA9IG5leHRTdGF0ZSk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgIFJvdXRlci5zdG9wKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgdmFyIHJvdXRlID0gUm91dGVyLmdldFJvdXRlQXREZXB0aCgwKTtcbiAgICAgIHJldHVybiByb3V0ZSA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQocm91dGUuaGFuZGxlciwgdGhpcy5wcm9wcykgOiBudWxsO1xuICAgIH1cblxuICB9KTtcblxuICBSb3V0ZXIuY2xlYXJBbGxSb3V0ZXMoKTtcblxuICBpZiAob3B0aW9ucy5yb3V0ZXMpIFJvdXRlci5hZGRSb3V0ZXMob3B0aW9ucy5yb3V0ZXMpO1xuXG4gIHJldHVybiBSb3V0ZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUm91dGVyOyIsIi8qIGpzaGludCAtVzA4NCAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ29iamVjdC1hc3NpZ24nKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnLi93YXJuaW5nJyk7XG52YXIgRGVmYXVsdFJvdXRlID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL0RlZmF1bHRSb3V0ZScpO1xudmFyIE5vdEZvdW5kUm91dGUgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvTm90Rm91bmRSb3V0ZScpO1xudmFyIFJlZGlyZWN0ID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL1JlZGlyZWN0Jyk7XG52YXIgUm91dGUgPSByZXF1aXJlKCcuL1JvdXRlJyk7XG5cbmZ1bmN0aW9uIGNoZWNrUHJvcFR5cGVzKGNvbXBvbmVudE5hbWUsIHByb3BUeXBlcywgcHJvcHMpIHtcbiAgY29tcG9uZW50TmFtZSA9IGNvbXBvbmVudE5hbWUgfHwgJ1Vua25vd25Db21wb25lbnQnO1xuXG4gIGZvciAodmFyIHByb3BOYW1lIGluIHByb3BUeXBlcykge1xuICAgIGlmIChwcm9wVHlwZXMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICB2YXIgZXJyb3IgPSBwcm9wVHlwZXNbcHJvcE5hbWVdKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSk7XG5cbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB3YXJuaW5nKGZhbHNlLCBlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUm91dGVPcHRpb25zKHByb3BzKSB7XG4gIHZhciBvcHRpb25zID0gYXNzaWduKHt9LCBwcm9wcyk7XG4gIHZhciBoYW5kbGVyID0gb3B0aW9ucy5oYW5kbGVyO1xuXG4gIGlmIChoYW5kbGVyKSB7XG4gICAgb3B0aW9ucy5vbkVudGVyID0gaGFuZGxlci53aWxsVHJhbnNpdGlvblRvO1xuICAgIG9wdGlvbnMub25MZWF2ZSA9IGhhbmRsZXIud2lsbFRyYW5zaXRpb25Gcm9tO1xuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlRnJvbVJlYWN0RWxlbWVudChlbGVtZW50KSB7XG4gIGlmICghUmVhY3QuaXNWYWxpZEVsZW1lbnQoZWxlbWVudCkpIHJldHVybjtcblxuICB2YXIgdHlwZSA9IGVsZW1lbnQudHlwZTtcbiAgdmFyIHByb3BzID0gYXNzaWduKHt9LCB0eXBlLmRlZmF1bHRQcm9wcywgZWxlbWVudC5wcm9wcyk7XG5cbiAgaWYgKHR5cGUucHJvcFR5cGVzKSBjaGVja1Byb3BUeXBlcyh0eXBlLmRpc3BsYXlOYW1lLCB0eXBlLnByb3BUeXBlcywgcHJvcHMpO1xuXG4gIGlmICh0eXBlID09PSBEZWZhdWx0Um91dGUpIHJldHVybiBSb3V0ZS5jcmVhdGVEZWZhdWx0Um91dGUoY3JlYXRlUm91dGVPcHRpb25zKHByb3BzKSk7XG5cbiAgaWYgKHR5cGUgPT09IE5vdEZvdW5kUm91dGUpIHJldHVybiBSb3V0ZS5jcmVhdGVOb3RGb3VuZFJvdXRlKGNyZWF0ZVJvdXRlT3B0aW9ucyhwcm9wcykpO1xuXG4gIGlmICh0eXBlID09PSBSZWRpcmVjdCkgcmV0dXJuIFJvdXRlLmNyZWF0ZVJlZGlyZWN0KGNyZWF0ZVJvdXRlT3B0aW9ucyhwcm9wcykpO1xuXG4gIHJldHVybiBSb3V0ZS5jcmVhdGVSb3V0ZShjcmVhdGVSb3V0ZU9wdGlvbnMocHJvcHMpLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHByb3BzLmNoaWxkcmVuKSBjcmVhdGVSb3V0ZXNGcm9tUmVhY3RDaGlsZHJlbihwcm9wcy5jaGlsZHJlbik7XG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIHJldHVybnMgYW4gYXJyYXkgb2Ygcm91dGVzIGNyZWF0ZWQgZnJvbSB0aGUgZ2l2ZW5cbiAqIFJlYWN0Q2hpbGRyZW4sIGFsbCBvZiB3aGljaCBzaG91bGQgYmUgb25lIG9mIDxSb3V0ZT4sIDxEZWZhdWx0Um91dGU+LFxuICogPE5vdEZvdW5kUm91dGU+LCBvciA8UmVkaXJlY3Q+LCBlLmcuOlxuICpcbiAqICAgdmFyIHsgY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW4sIFJvdXRlLCBSZWRpcmVjdCB9ID0gcmVxdWlyZSgncmVhY3Qtcm91dGVyJyk7XG4gKlxuICogICB2YXIgcm91dGVzID0gY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW4oXG4gKiAgICAgPFJvdXRlIHBhdGg9XCIvXCIgaGFuZGxlcj17QXBwfT5cbiAqICAgICAgIDxSb3V0ZSBuYW1lPVwidXNlclwiIHBhdGg9XCIvdXNlci86dXNlcklkXCIgaGFuZGxlcj17VXNlcn0+XG4gKiAgICAgICAgIDxSb3V0ZSBuYW1lPVwidGFza1wiIHBhdGg9XCJ0YXNrcy86dGFza0lkXCIgaGFuZGxlcj17VGFza30vPlxuICogICAgICAgICA8UmVkaXJlY3QgZnJvbT1cInRvZG9zLzp0YXNrSWRcIiB0bz1cInRhc2tcIi8+XG4gKiAgICAgICA8L1JvdXRlPlxuICogICAgIDwvUm91dGU+XG4gKiAgICk7XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlc0Zyb21SZWFjdENoaWxkcmVuKGNoaWxkcmVuKSB7XG4gIHZhciByb3V0ZXMgPSBbXTtcblxuICBSZWFjdC5DaGlsZHJlbi5mb3JFYWNoKGNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICBpZiAoY2hpbGQgPSBjcmVhdGVSb3V0ZUZyb21SZWFjdEVsZW1lbnQoY2hpbGQpKSByb3V0ZXMucHVzaChjaGlsZCk7XG4gIH0pO1xuXG4gIHJldHVybiByb3V0ZXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW47IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnaW52YXJpYW50Jyk7XG52YXIgY2FuVXNlRE9NID0gcmVxdWlyZSgnY2FuLXVzZS1kb20nKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgd2luZG93IGFzIHsgeCwgeSB9LlxuICovXG5mdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGxQb3NpdGlvbigpIHtcbiAgaW52YXJpYW50KGNhblVzZURPTSwgJ0Nhbm5vdCBnZXQgY3VycmVudCBzY3JvbGwgcG9zaXRpb24gd2l0aG91dCBhIERPTScpO1xuXG4gIHJldHVybiB7XG4gICAgeDogd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgIHk6IHdpbmRvdy5wYWdlWU9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0V2luZG93U2Nyb2xsUG9zaXRpb247IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLkRlZmF1bHRSb3V0ZSA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9EZWZhdWx0Um91dGUnKTtcbmV4cG9ydHMuTGluayA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9MaW5rJyk7XG5leHBvcnRzLk5vdEZvdW5kUm91dGUgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvTm90Rm91bmRSb3V0ZScpO1xuZXhwb3J0cy5SZWRpcmVjdCA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9SZWRpcmVjdCcpO1xuZXhwb3J0cy5Sb3V0ZSA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9Sb3V0ZScpO1xuZXhwb3J0cy5BY3RpdmVIYW5kbGVyID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL1JvdXRlSGFuZGxlcicpO1xuZXhwb3J0cy5Sb3V0ZUhhbmRsZXIgPSBleHBvcnRzLkFjdGl2ZUhhbmRsZXI7XG5cbmV4cG9ydHMuSGFzaExvY2F0aW9uID0gcmVxdWlyZSgnLi9sb2NhdGlvbnMvSGFzaExvY2F0aW9uJyk7XG5leHBvcnRzLkhpc3RvcnlMb2NhdGlvbiA9IHJlcXVpcmUoJy4vbG9jYXRpb25zL0hpc3RvcnlMb2NhdGlvbicpO1xuZXhwb3J0cy5SZWZyZXNoTG9jYXRpb24gPSByZXF1aXJlKCcuL2xvY2F0aW9ucy9SZWZyZXNoTG9jYXRpb24nKTtcbmV4cG9ydHMuU3RhdGljTG9jYXRpb24gPSByZXF1aXJlKCcuL2xvY2F0aW9ucy9TdGF0aWNMb2NhdGlvbicpO1xuZXhwb3J0cy5UZXN0TG9jYXRpb24gPSByZXF1aXJlKCcuL2xvY2F0aW9ucy9UZXN0TG9jYXRpb24nKTtcblxuZXhwb3J0cy5JbWl0YXRlQnJvd3NlckJlaGF2aW9yID0gcmVxdWlyZSgnLi9iZWhhdmlvcnMvSW1pdGF0ZUJyb3dzZXJCZWhhdmlvcicpO1xuZXhwb3J0cy5TY3JvbGxUb1RvcEJlaGF2aW9yID0gcmVxdWlyZSgnLi9iZWhhdmlvcnMvU2Nyb2xsVG9Ub3BCZWhhdmlvcicpO1xuXG5leHBvcnRzLkhpc3RvcnkgPSByZXF1aXJlKCcuL0hpc3RvcnknKTtcbmV4cG9ydHMuTmF2aWdhdGlvbiA9IHJlcXVpcmUoJy4vTmF2aWdhdGlvbicpO1xuZXhwb3J0cy5TdGF0ZSA9IHJlcXVpcmUoJy4vU3RhdGUnKTtcblxuZXhwb3J0cy5jcmVhdGVSb3V0ZSA9IHJlcXVpcmUoJy4vUm91dGUnKS5jcmVhdGVSb3V0ZTtcbmV4cG9ydHMuY3JlYXRlRGVmYXVsdFJvdXRlID0gcmVxdWlyZSgnLi9Sb3V0ZScpLmNyZWF0ZURlZmF1bHRSb3V0ZTtcbmV4cG9ydHMuY3JlYXRlTm90Rm91bmRSb3V0ZSA9IHJlcXVpcmUoJy4vUm91dGUnKS5jcmVhdGVOb3RGb3VuZFJvdXRlO1xuZXhwb3J0cy5jcmVhdGVSZWRpcmVjdCA9IHJlcXVpcmUoJy4vUm91dGUnKS5jcmVhdGVSZWRpcmVjdDtcbmV4cG9ydHMuY3JlYXRlUm91dGVzRnJvbVJlYWN0Q2hpbGRyZW4gPSByZXF1aXJlKCcuL2NyZWF0ZVJvdXRlc0Zyb21SZWFjdENoaWxkcmVuJyk7XG5cbmV4cG9ydHMuY3JlYXRlID0gcmVxdWlyZSgnLi9jcmVhdGVSb3V0ZXInKTtcbmV4cG9ydHMucnVuID0gcmVxdWlyZSgnLi9ydW5Sb3V0ZXInKTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbmZ1bmN0aW9uIGlzVmFsaWRDaGlsZChvYmplY3QpIHtcbiAgcmV0dXJuIG9iamVjdCA9PSBudWxsIHx8IFJlYWN0LmlzVmFsaWRFbGVtZW50KG9iamVjdCk7XG59XG5cbmZ1bmN0aW9uIGlzUmVhY3RDaGlsZHJlbihvYmplY3QpIHtcbiAgcmV0dXJuIGlzVmFsaWRDaGlsZChvYmplY3QpIHx8IEFycmF5LmlzQXJyYXkob2JqZWN0KSAmJiBvYmplY3QuZXZlcnkoaXNWYWxpZENoaWxkKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1JlYWN0Q2hpbGRyZW47IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTG9jYXRpb25BY3Rpb25zID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9Mb2NhdGlvbkFjdGlvbnMnKTtcbnZhciBIaXN0b3J5ID0gcmVxdWlyZSgnLi4vSGlzdG9yeScpO1xuXG52YXIgX2xpc3RlbmVycyA9IFtdO1xudmFyIF9pc0xpc3RlbmluZyA9IGZhbHNlO1xudmFyIF9hY3Rpb25UeXBlO1xuXG5mdW5jdGlvbiBub3RpZnlDaGFuZ2UodHlwZSkge1xuICBpZiAodHlwZSA9PT0gTG9jYXRpb25BY3Rpb25zLlBVU0gpIEhpc3RvcnkubGVuZ3RoICs9IDE7XG5cbiAgdmFyIGNoYW5nZSA9IHtcbiAgICBwYXRoOiBIYXNoTG9jYXRpb24uZ2V0Q3VycmVudFBhdGgoKSxcbiAgICB0eXBlOiB0eXBlXG4gIH07XG5cbiAgX2xpc3RlbmVycy5mb3JFYWNoKGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgIGxpc3RlbmVyLmNhbGwoSGFzaExvY2F0aW9uLCBjaGFuZ2UpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlU2xhc2goKSB7XG4gIHZhciBwYXRoID0gSGFzaExvY2F0aW9uLmdldEN1cnJlbnRQYXRoKCk7XG5cbiAgaWYgKHBhdGguY2hhckF0KDApID09PSAnLycpIHJldHVybiB0cnVlO1xuXG4gIEhhc2hMb2NhdGlvbi5yZXBsYWNlKCcvJyArIHBhdGgpO1xuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb25IYXNoQ2hhbmdlKCkge1xuICBpZiAoZW5zdXJlU2xhc2goKSkge1xuICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYW4gX2FjdGlvblR5cGUgdGhlbiBhbGwgd2Uga25vdyBpcyB0aGUgaGFzaFxuICAgIC8vIGNoYW5nZWQuIEl0IHdhcyBwcm9iYWJseSBjYXVzZWQgYnkgdGhlIHVzZXIgY2xpY2tpbmcgdGhlIEJhY2tcbiAgICAvLyBidXR0b24sIGJ1dCBtYXkgaGF2ZSBhbHNvIGJlZW4gdGhlIEZvcndhcmQgYnV0dG9uIG9yIG1hbnVhbFxuICAgIC8vIG1hbmlwdWxhdGlvbi4gU28ganVzdCBndWVzcyAncG9wJy5cbiAgICB2YXIgY3VyQWN0aW9uVHlwZSA9IF9hY3Rpb25UeXBlO1xuICAgIF9hY3Rpb25UeXBlID0gbnVsbDtcbiAgICBub3RpZnlDaGFuZ2UoY3VyQWN0aW9uVHlwZSB8fCBMb2NhdGlvbkFjdGlvbnMuUE9QKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgTG9jYXRpb24gdGhhdCB1c2VzIGB3aW5kb3cubG9jYXRpb24uaGFzaGAuXG4gKi9cbnZhciBIYXNoTG9jYXRpb24gPSB7XG5cbiAgYWRkQ2hhbmdlTGlzdGVuZXI6IGZ1bmN0aW9uIGFkZENoYW5nZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgX2xpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblxuICAgIC8vIERvIHRoaXMgQkVGT1JFIGxpc3RlbmluZyBmb3IgaGFzaGNoYW5nZS5cbiAgICBlbnN1cmVTbGFzaCgpO1xuXG4gICAgaWYgKCFfaXNMaXN0ZW5pbmcpIHtcbiAgICAgIGlmICh3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIG9uSGFzaENoYW5nZSwgZmFsc2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LmF0dGFjaEV2ZW50KCdvbmhhc2hjaGFuZ2UnLCBvbkhhc2hDaGFuZ2UpO1xuICAgICAgfVxuXG4gICAgICBfaXNMaXN0ZW5pbmcgPSB0cnVlO1xuICAgIH1cbiAgfSxcblxuICByZW1vdmVDaGFuZ2VMaXN0ZW5lcjogZnVuY3Rpb24gcmVtb3ZlQ2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpIHtcbiAgICBfbGlzdGVuZXJzID0gX2xpc3RlbmVycy5maWx0ZXIoZnVuY3Rpb24gKGwpIHtcbiAgICAgIHJldHVybiBsICE9PSBsaXN0ZW5lcjtcbiAgICB9KTtcblxuICAgIGlmIChfbGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdoYXNoY2hhbmdlJywgb25IYXNoQ2hhbmdlLCBmYWxzZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnQoJ29uaGFzaGNoYW5nZScsIG9uSGFzaENoYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIF9pc0xpc3RlbmluZyA9IGZhbHNlO1xuICAgIH1cbiAgfSxcblxuICBwdXNoOiBmdW5jdGlvbiBwdXNoKHBhdGgpIHtcbiAgICBfYWN0aW9uVHlwZSA9IExvY2F0aW9uQWN0aW9ucy5QVVNIO1xuICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gcGF0aDtcbiAgfSxcblxuICByZXBsYWNlOiBmdW5jdGlvbiByZXBsYWNlKHBhdGgpIHtcbiAgICBfYWN0aW9uVHlwZSA9IExvY2F0aW9uQWN0aW9ucy5SRVBMQUNFO1xuICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2ggKyAnIycgKyBwYXRoKTtcbiAgfSxcblxuICBwb3A6IGZ1bmN0aW9uIHBvcCgpIHtcbiAgICBfYWN0aW9uVHlwZSA9IExvY2F0aW9uQWN0aW9ucy5QT1A7XG4gICAgSGlzdG9yeS5iYWNrKCk7XG4gIH0sXG5cbiAgZ2V0Q3VycmVudFBhdGg6IGZ1bmN0aW9uIGdldEN1cnJlbnRQYXRoKCkge1xuICAgIHJldHVybiBkZWNvZGVVUkkoXG4gICAgLy8gV2UgY2FuJ3QgdXNlIHdpbmRvdy5sb2NhdGlvbi5oYXNoIGhlcmUgYmVjYXVzZSBpdCdzIG5vdFxuICAgIC8vIGNvbnNpc3RlbnQgYWNyb3NzIGJyb3dzZXJzIC0gRmlyZWZveCB3aWxsIHByZS1kZWNvZGUgaXQhXG4gICAgd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoJyMnKVsxXSB8fCAnJyk7XG4gIH0sXG5cbiAgdG9TdHJpbmc6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnPEhhc2hMb2NhdGlvbj4nO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaExvY2F0aW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIExvY2F0aW9uQWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvTG9jYXRpb25BY3Rpb25zJyk7XG52YXIgSGlzdG9yeSA9IHJlcXVpcmUoJy4uL0hpc3RvcnknKTtcblxudmFyIF9saXN0ZW5lcnMgPSBbXTtcbnZhciBfaXNMaXN0ZW5pbmcgPSBmYWxzZTtcblxuZnVuY3Rpb24gbm90aWZ5Q2hhbmdlKHR5cGUpIHtcbiAgdmFyIGNoYW5nZSA9IHtcbiAgICBwYXRoOiBIaXN0b3J5TG9jYXRpb24uZ2V0Q3VycmVudFBhdGgoKSxcbiAgICB0eXBlOiB0eXBlXG4gIH07XG5cbiAgX2xpc3RlbmVycy5mb3JFYWNoKGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgIGxpc3RlbmVyLmNhbGwoSGlzdG9yeUxvY2F0aW9uLCBjaGFuZ2UpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gb25Qb3BTdGF0ZShldmVudCkge1xuICBpZiAoZXZlbnQuc3RhdGUgPT09IHVuZGVmaW5lZCkgcmV0dXJuOyAvLyBJZ25vcmUgZXh0cmFuZW91cyBwb3BzdGF0ZSBldmVudHMgaW4gV2ViS2l0LlxuXG4gIG5vdGlmeUNoYW5nZShMb2NhdGlvbkFjdGlvbnMuUE9QKTtcbn1cblxuLyoqXG4gKiBBIExvY2F0aW9uIHRoYXQgdXNlcyBIVE1MNSBoaXN0b3J5LlxuICovXG52YXIgSGlzdG9yeUxvY2F0aW9uID0ge1xuXG4gIGFkZENoYW5nZUxpc3RlbmVyOiBmdW5jdGlvbiBhZGRDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcikge1xuICAgIF9saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG5cbiAgICBpZiAoIV9pc0xpc3RlbmluZykge1xuICAgICAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIG9uUG9wU3RhdGUsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5hdHRhY2hFdmVudCgnb25wb3BzdGF0ZScsIG9uUG9wU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBfaXNMaXN0ZW5pbmcgPSB0cnVlO1xuICAgIH1cbiAgfSxcblxuICByZW1vdmVDaGFuZ2VMaXN0ZW5lcjogZnVuY3Rpb24gcmVtb3ZlQ2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpIHtcbiAgICBfbGlzdGVuZXJzID0gX2xpc3RlbmVycy5maWx0ZXIoZnVuY3Rpb24gKGwpIHtcbiAgICAgIHJldHVybiBsICE9PSBsaXN0ZW5lcjtcbiAgICB9KTtcblxuICAgIGlmIChfbGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIG9uUG9wU3RhdGUsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudCgnb25wb3BzdGF0ZScsIG9uUG9wU3RhdGUpO1xuICAgICAgfVxuXG4gICAgICBfaXNMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgICB9XG4gIH0sXG5cbiAgcHVzaDogZnVuY3Rpb24gcHVzaChwYXRoKSB7XG4gICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHsgcGF0aDogcGF0aCB9LCAnJywgcGF0aCk7XG4gICAgSGlzdG9yeS5sZW5ndGggKz0gMTtcbiAgICBub3RpZnlDaGFuZ2UoTG9jYXRpb25BY3Rpb25zLlBVU0gpO1xuICB9LFxuXG4gIHJlcGxhY2U6IGZ1bmN0aW9uIHJlcGxhY2UocGF0aCkge1xuICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZSh7IHBhdGg6IHBhdGggfSwgJycsIHBhdGgpO1xuICAgIG5vdGlmeUNoYW5nZShMb2NhdGlvbkFjdGlvbnMuUkVQTEFDRSk7XG4gIH0sXG5cbiAgcG9wOiBIaXN0b3J5LmJhY2ssXG5cbiAgZ2V0Q3VycmVudFBhdGg6IGZ1bmN0aW9uIGdldEN1cnJlbnRQYXRoKCkge1xuICAgIHJldHVybiBkZWNvZGVVUkkod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lICsgd2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XG4gIH0sXG5cbiAgdG9TdHJpbmc6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnPEhpc3RvcnlMb2NhdGlvbj4nO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSGlzdG9yeUxvY2F0aW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEhpc3RvcnlMb2NhdGlvbiA9IHJlcXVpcmUoJy4vSGlzdG9yeUxvY2F0aW9uJyk7XG52YXIgSGlzdG9yeSA9IHJlcXVpcmUoJy4uL0hpc3RvcnknKTtcblxuLyoqXG4gKiBBIExvY2F0aW9uIHRoYXQgdXNlcyBmdWxsIHBhZ2UgcmVmcmVzaGVzLiBUaGlzIGlzIHVzZWQgYXNcbiAqIHRoZSBmYWxsYmFjayBmb3IgSGlzdG9yeUxvY2F0aW9uIGluIGJyb3dzZXJzIHRoYXQgZG8gbm90XG4gKiBzdXBwb3J0IHRoZSBIVE1MNSBoaXN0b3J5IEFQSS5cbiAqL1xudmFyIFJlZnJlc2hMb2NhdGlvbiA9IHtcblxuICBwdXNoOiBmdW5jdGlvbiBwdXNoKHBhdGgpIHtcbiAgICB3aW5kb3cubG9jYXRpb24gPSBwYXRoO1xuICB9LFxuXG4gIHJlcGxhY2U6IGZ1bmN0aW9uIHJlcGxhY2UocGF0aCkge1xuICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHBhdGgpO1xuICB9LFxuXG4gIHBvcDogSGlzdG9yeS5iYWNrLFxuXG4gIGdldEN1cnJlbnRQYXRoOiBIaXN0b3J5TG9jYXRpb24uZ2V0Q3VycmVudFBhdGgsXG5cbiAgdG9TdHJpbmc6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnPFJlZnJlc2hMb2NhdGlvbj4nO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVmcmVzaExvY2F0aW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoJ3ZhbHVlJyBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcblxuZnVuY3Rpb24gdGhyb3dDYW5ub3RNb2RpZnkoKSB7XG4gIGludmFyaWFudChmYWxzZSwgJ1lvdSBjYW5ub3QgbW9kaWZ5IGEgc3RhdGljIGxvY2F0aW9uJyk7XG59XG5cbi8qKlxuICogQSBsb2NhdGlvbiB0aGF0IG9ubHkgZXZlciBjb250YWlucyBhIHNpbmdsZSBwYXRoLiBVc2VmdWwgaW5cbiAqIHN0YXRlbGVzcyBlbnZpcm9ubWVudHMgbGlrZSBzZXJ2ZXJzIHdoZXJlIHRoZXJlIGlzIG5vIHBhdGggaGlzdG9yeSxcbiAqIG9ubHkgdGhlIHBhdGggdGhhdCB3YXMgdXNlZCBpbiB0aGUgcmVxdWVzdC5cbiAqL1xuXG52YXIgU3RhdGljTG9jYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTdGF0aWNMb2NhdGlvbihwYXRoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFN0YXRpY0xvY2F0aW9uKTtcblxuICAgIHRoaXMucGF0aCA9IHBhdGg7XG4gIH1cblxuICAvLyBUT0RPOiBJbmNsdWRlIHRoZXNlIGluIHRoZSBhYm92ZSBjbGFzcyBkZWZpbml0aW9uXG4gIC8vIG9uY2Ugd2UgY2FuIHVzZSBFUzcgcHJvcGVydHkgaW5pdGlhbGl6ZXJzLlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmFiZWwvYmFiZWwvaXNzdWVzLzYxOVxuXG4gIF9jcmVhdGVDbGFzcyhTdGF0aWNMb2NhdGlvbiwgW3tcbiAgICBrZXk6ICdnZXRDdXJyZW50UGF0aCcsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEN1cnJlbnRQYXRoKCkge1xuICAgICAgcmV0dXJuIHRoaXMucGF0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICd0b1N0cmluZycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICc8U3RhdGljTG9jYXRpb24gcGF0aD1cIicgKyB0aGlzLnBhdGggKyAnXCI+JztcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gU3RhdGljTG9jYXRpb247XG59KSgpO1xuXG5TdGF0aWNMb2NhdGlvbi5wcm90b3R5cGUucHVzaCA9IHRocm93Q2Fubm90TW9kaWZ5O1xuU3RhdGljTG9jYXRpb24ucHJvdG90eXBlLnJlcGxhY2UgPSB0aHJvd0Nhbm5vdE1vZGlmeTtcblN0YXRpY0xvY2F0aW9uLnByb3RvdHlwZS5wb3AgPSB0aHJvd0Nhbm5vdE1vZGlmeTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdGF0aWNMb2NhdGlvbjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnaW52YXJpYW50Jyk7XG52YXIgTG9jYXRpb25BY3Rpb25zID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9Mb2NhdGlvbkFjdGlvbnMnKTtcbnZhciBIaXN0b3J5ID0gcmVxdWlyZSgnLi4vSGlzdG9yeScpO1xuXG4vKipcbiAqIEEgbG9jYXRpb24gdGhhdCBpcyBjb252ZW5pZW50IGZvciB0ZXN0aW5nIGFuZCBkb2VzIG5vdCByZXF1aXJlIGEgRE9NLlxuICovXG5cbnZhciBUZXN0TG9jYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBUZXN0TG9jYXRpb24oaGlzdG9yeSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZXN0TG9jYXRpb24pO1xuXG4gICAgdGhpcy5oaXN0b3J5ID0gaGlzdG9yeSB8fCBbXTtcbiAgICB0aGlzLmxpc3RlbmVycyA9IFtdO1xuICAgIHRoaXMubmVlZHNET00gPSBmYWxzZTtcbiAgICB0aGlzLl91cGRhdGVIaXN0b3J5TGVuZ3RoKCk7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoVGVzdExvY2F0aW9uLCBbe1xuICAgIGtleTogJ191cGRhdGVIaXN0b3J5TGVuZ3RoJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3VwZGF0ZUhpc3RvcnlMZW5ndGgoKSB7XG4gICAgICBIaXN0b3J5Lmxlbmd0aCA9IHRoaXMuaGlzdG9yeS5sZW5ndGg7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAnX25vdGlmeUNoYW5nZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9ub3RpZnlDaGFuZ2UodHlwZSkge1xuICAgICAgdmFyIGNoYW5nZSA9IHtcbiAgICAgICAgcGF0aDogdGhpcy5nZXRDdXJyZW50UGF0aCgpLFxuICAgICAgICB0eXBlOiB0eXBlXG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy5saXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHRoaXMubGlzdGVuZXJzW2ldLmNhbGwodGhpcywgY2hhbmdlKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdhZGRDaGFuZ2VMaXN0ZW5lcicsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZENoYW5nZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgICB0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdyZW1vdmVDaGFuZ2VMaXN0ZW5lcicsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZUNoYW5nZUxpc3RlbmVyKGxpc3RlbmVyKSB7XG4gICAgICB0aGlzLmxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzLmZpbHRlcihmdW5jdGlvbiAobCkge1xuICAgICAgICByZXR1cm4gbCAhPT0gbGlzdGVuZXI7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICdwdXNoJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gcHVzaChwYXRoKSB7XG4gICAgICB0aGlzLmhpc3RvcnkucHVzaChwYXRoKTtcbiAgICAgIHRoaXMuX3VwZGF0ZUhpc3RvcnlMZW5ndGgoKTtcbiAgICAgIHRoaXMuX25vdGlmeUNoYW5nZShMb2NhdGlvbkFjdGlvbnMuUFVTSCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAncmVwbGFjZScsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlcGxhY2UocGF0aCkge1xuICAgICAgaW52YXJpYW50KHRoaXMuaGlzdG9yeS5sZW5ndGgsICdZb3UgY2Fubm90IHJlcGxhY2UgdGhlIGN1cnJlbnQgcGF0aCB3aXRoIG5vIGhpc3RvcnknKTtcblxuICAgICAgdGhpcy5oaXN0b3J5W3RoaXMuaGlzdG9yeS5sZW5ndGggLSAxXSA9IHBhdGg7XG5cbiAgICAgIHRoaXMuX25vdGlmeUNoYW5nZShMb2NhdGlvbkFjdGlvbnMuUkVQTEFDRSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiAncG9wJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gcG9wKCkge1xuICAgICAgdGhpcy5oaXN0b3J5LnBvcCgpO1xuICAgICAgdGhpcy5fdXBkYXRlSGlzdG9yeUxlbmd0aCgpO1xuICAgICAgdGhpcy5fbm90aWZ5Q2hhbmdlKExvY2F0aW9uQWN0aW9ucy5QT1ApO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogJ2dldEN1cnJlbnRQYXRoJyxcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q3VycmVudFBhdGgoKSB7XG4gICAgICByZXR1cm4gdGhpcy5oaXN0b3J5W3RoaXMuaGlzdG9yeS5sZW5ndGggLSAxXTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6ICd0b1N0cmluZycsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICc8VGVzdExvY2F0aW9uPic7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFRlc3RMb2NhdGlvbjtcbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gVGVzdExvY2F0aW9uOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNyZWF0ZVJvdXRlciA9IHJlcXVpcmUoJy4vY3JlYXRlUm91dGVyJyk7XG5cbi8qKlxuICogQSBoaWdoLWxldmVsIGNvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGNyZWF0ZXMsIGNvbmZpZ3VyZXMsIGFuZFxuICogcnVucyBhIHJvdXRlciBpbiBvbmUgc2hvdC4gVGhlIG1ldGhvZCBzaWduYXR1cmUgaXM6XG4gKlxuICogICBSb3V0ZXIucnVuKHJvdXRlc1ssIGxvY2F0aW9uIF0sIGNhbGxiYWNrKTtcbiAqXG4gKiBVc2luZyBgd2luZG93LmxvY2F0aW9uLmhhc2hgIHRvIG1hbmFnZSB0aGUgVVJMLCB5b3UgY291bGQgZG86XG4gKlxuICogICBSb3V0ZXIucnVuKHJvdXRlcywgZnVuY3Rpb24gKEhhbmRsZXIpIHtcbiAqICAgICBSZWFjdC5yZW5kZXIoPEhhbmRsZXIvPiwgZG9jdW1lbnQuYm9keSk7XG4gKiAgIH0pO1xuICogXG4gKiBVc2luZyBIVE1MNSBoaXN0b3J5IGFuZCBhIGN1c3RvbSBcImN1cnNvclwiIHByb3A6XG4gKiBcbiAqICAgUm91dGVyLnJ1bihyb3V0ZXMsIFJvdXRlci5IaXN0b3J5TG9jYXRpb24sIGZ1bmN0aW9uIChIYW5kbGVyKSB7XG4gKiAgICAgUmVhY3QucmVuZGVyKDxIYW5kbGVyIGN1cnNvcj17Y3Vyc29yfS8+LCBkb2N1bWVudC5ib2R5KTtcbiAqICAgfSk7XG4gKlxuICogUmV0dXJucyB0aGUgbmV3bHkgY3JlYXRlZCByb3V0ZXIuXG4gKlxuICogTm90ZTogSWYgeW91IG5lZWQgdG8gc3BlY2lmeSBmdXJ0aGVyIG9wdGlvbnMgZm9yIHlvdXIgcm91dGVyIHN1Y2hcbiAqIGFzIGVycm9yL2Fib3J0IGhhbmRsaW5nIG9yIGN1c3RvbSBzY3JvbGwgYmVoYXZpb3IsIHVzZSBSb3V0ZXIuY3JlYXRlXG4gKiBpbnN0ZWFkLlxuICpcbiAqICAgdmFyIHJvdXRlciA9IFJvdXRlci5jcmVhdGUob3B0aW9ucyk7XG4gKiAgIHJvdXRlci5ydW4oZnVuY3Rpb24gKEhhbmRsZXIpIHtcbiAqICAgICAvLyAuLi5cbiAqICAgfSk7XG4gKi9cbmZ1bmN0aW9uIHJ1blJvdXRlcihyb3V0ZXMsIGxvY2F0aW9uLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBsb2NhdGlvbjtcbiAgICBsb2NhdGlvbiA9IG51bGw7XG4gIH1cblxuICB2YXIgcm91dGVyID0gY3JlYXRlUm91dGVyKHtcbiAgICByb3V0ZXM6IHJvdXRlcyxcbiAgICBsb2NhdGlvbjogbG9jYXRpb25cbiAgfSk7XG5cbiAgcm91dGVyLnJ1bihjYWxsYmFjayk7XG5cbiAgcmV0dXJuIHJvdXRlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBydW5Sb3V0ZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBzdXBwb3J0c0hpc3RvcnkoKSB7XG4gIC8qISB0YWtlbiBmcm9tIG1vZGVybml6clxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vTW9kZXJuaXpyL01vZGVybml6ci9ibG9iL21hc3Rlci9MSUNFTlNFXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2Jsb2IvbWFzdGVyL2ZlYXR1cmUtZGV0ZWN0cy9oaXN0b3J5LmpzXG4gICAqIGNoYW5nZWQgdG8gYXZvaWQgZmFsc2UgbmVnYXRpdmVzIGZvciBXaW5kb3dzIFBob25lczogaHR0cHM6Ly9naXRodWIuY29tL3JhY2t0L3JlYWN0LXJvdXRlci9pc3N1ZXMvNTg2XG4gICAqL1xuICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICBpZiAoKHVhLmluZGV4T2YoJ0FuZHJvaWQgMi4nKSAhPT0gLTEgfHwgdWEuaW5kZXhPZignQW5kcm9pZCA0LjAnKSAhPT0gLTEpICYmIHVhLmluZGV4T2YoJ01vYmlsZSBTYWZhcmknKSAhPT0gLTEgJiYgdWEuaW5kZXhPZignQ2hyb21lJykgPT09IC0xICYmIHVhLmluZGV4T2YoJ1dpbmRvd3MgUGhvbmUnKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHdpbmRvdy5oaXN0b3J5ICYmICdwdXNoU3RhdGUnIGluIHdpbmRvdy5oaXN0b3J5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1cHBvcnRzSGlzdG9yeTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvdHJlZS8wLjEzLXN0YWJsZS5cbiAqIEFuIGFkZGl0aW9uYWwgZ3JhbnQgb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHdhcm5pbmdcbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuLyoqXG4gKiBTaW1pbGFyIHRvIGludmFyaWFudCBidXQgb25seSBsb2dzIGEgd2FybmluZyBpZiB0aGUgY29uZGl0aW9uIGlzIG5vdCBtZXQuXG4gKiBUaGlzIGNhbiBiZSB1c2VkIHRvIGxvZyBpc3N1ZXMgaW4gZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzIGluIGNyaXRpY2FsXG4gKiBwYXRocy4gUmVtb3ZpbmcgdGhlIGxvZ2dpbmcgY29kZSBmb3IgcHJvZHVjdGlvbiBlbnZpcm9ubWVudHMgd2lsbCBrZWVwIHRoZVxuICogc2FtZSBsb2dpYyBhbmQgZm9sbG93IHRoZSBzYW1lIGNvZGUgcGF0aHMuXG4gKi9cblxudmFyIF9fREVWX18gPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuXG52YXIgd2FybmluZyA9IGZ1bmN0aW9uIHdhcm5pbmcoKSB7fTtcblxuaWYgKF9fREVWX18pIHtcbiAgd2FybmluZyA9IGZ1bmN0aW9uIChjb25kaXRpb24sIGZvcm1hdCkge1xuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbiA+IDIgPyBfbGVuIC0gMiA6IDApLCBfa2V5ID0gMjsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5IC0gMl0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2B3YXJuaW5nKGNvbmRpdGlvbiwgZm9ybWF0LCAuLi5hcmdzKWAgcmVxdWlyZXMgYSB3YXJuaW5nICcgKyAnbWVzc2FnZSBhcmd1bWVudCcpO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQubGVuZ3RoIDwgMTAgfHwgL15bc1xcV10qJC8udGVzdChmb3JtYXQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSB3YXJuaW5nIGZvcm1hdCBzaG91bGQgYmUgYWJsZSB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzICcgKyAnd2FybmluZy4gUGxlYXNlLCB1c2UgYSBtb3JlIGRlc2NyaXB0aXZlIGZvcm1hdCB0aGFuOiAnICsgZm9ybWF0KTtcbiAgICB9XG5cbiAgICBpZiAoZm9ybWF0LmluZGV4T2YoJ0ZhaWxlZCBDb21wb3NpdGUgcHJvcFR5cGU6ICcpID09PSAwKSB7XG4gICAgICByZXR1cm47IC8vIElnbm9yZSBDb21wb3NpdGVDb21wb25lbnQgcHJvcHR5cGUgY2hlY2suXG4gICAgfVxuXG4gICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgIHZhciBhcmdJbmRleCA9IDA7XG4gICAgICB2YXIgbWVzc2FnZSA9ICdXYXJuaW5nOiAnICsgZm9ybWF0LnJlcGxhY2UoLyVzL2csIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGFyZ3NbYXJnSW5kZXgrK107XG4gICAgICB9KTtcbiAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIC0tLSBXZWxjb21lIHRvIGRlYnVnZ2luZyBSZWFjdCAtLS1cbiAgICAgICAgLy8gVGhpcyBlcnJvciB3YXMgdGhyb3duIGFzIGEgY29udmVuaWVuY2Ugc28gdGhhdCB5b3UgY2FuIHVzZSB0aGlzIHN0YWNrXG4gICAgICAgIC8vIHRvIGZpbmQgdGhlIGNhbGxzaXRlIHRoYXQgY2F1c2VkIHRoaXMgd2FybmluZyB0byBmaXJlLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICB9IGNhdGNoICh4KSB7fVxuICAgIH1cbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3YXJuaW5nOyIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gVG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT0gbnVsbCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciBrZXlzO1xuXHR2YXIgdG8gPSBUb09iamVjdCh0YXJnZXQpO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IGFyZ3VtZW50c1tzXTtcblx0XHRrZXlzID0gT2JqZWN0LmtleXMoT2JqZWN0KGZyb20pKTtcblxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dG9ba2V5c1tpXV0gPSBmcm9tW2tleXNbaV1dO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliLycpO1xuIiwiLy8gTG9hZCBtb2R1bGVzXG5cbnZhciBTdHJpbmdpZnkgPSByZXF1aXJlKCcuL3N0cmluZ2lmeScpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgnLi9wYXJzZScpO1xuXG5cbi8vIERlY2xhcmUgaW50ZXJuYWxzXG5cbnZhciBpbnRlcm5hbHMgPSB7fTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBzdHJpbmdpZnk6IFN0cmluZ2lmeSxcbiAgICBwYXJzZTogUGFyc2Vcbn07XG4iLCIvLyBMb2FkIG1vZHVsZXNcblxudmFyIFV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG5cbi8vIERlY2xhcmUgaW50ZXJuYWxzXG5cbnZhciBpbnRlcm5hbHMgPSB7XG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZGVwdGg6IDUsXG4gICAgYXJyYXlMaW1pdDogMjAsXG4gICAgcGFyYW1ldGVyTGltaXQ6IDEwMDBcbn07XG5cblxuaW50ZXJuYWxzLnBhcnNlVmFsdWVzID0gZnVuY3Rpb24gKHN0ciwgb3B0aW9ucykge1xuXG4gICAgdmFyIG9iaiA9IHt9O1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdChvcHRpb25zLmRlbGltaXRlciwgb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA9PT0gSW5maW5pdHkgPyB1bmRlZmluZWQgOiBvcHRpb25zLnBhcmFtZXRlckxpbWl0KTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpbCA9IHBhcnRzLmxlbmd0aDsgaSA8IGlsOyArK2kpIHtcbiAgICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgdmFyIHBvcyA9IHBhcnQuaW5kZXhPZignXT0nKSA9PT0gLTEgPyBwYXJ0LmluZGV4T2YoJz0nKSA6IHBhcnQuaW5kZXhPZignXT0nKSArIDE7XG5cbiAgICAgICAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICAgICAgICAgIG9ialtVdGlscy5kZWNvZGUocGFydCldID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gVXRpbHMuZGVjb2RlKHBhcnQuc2xpY2UoMCwgcG9zKSk7XG4gICAgICAgICAgICB2YXIgdmFsID0gVXRpbHMuZGVjb2RlKHBhcnQuc2xpY2UocG9zICsgMSkpO1xuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gW10uY29uY2F0KG9ialtrZXldKS5jb25jYXQodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG5cbmludGVybmFscy5wYXJzZU9iamVjdCA9IGZ1bmN0aW9uIChjaGFpbiwgdmFsLCBvcHRpb25zKSB7XG5cbiAgICBpZiAoIWNoYWluLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cblxuICAgIHZhciByb290ID0gY2hhaW4uc2hpZnQoKTtcblxuICAgIHZhciBvYmogPSB7fTtcbiAgICBpZiAocm9vdCA9PT0gJ1tdJykge1xuICAgICAgICBvYmogPSBbXTtcbiAgICAgICAgb2JqID0gb2JqLmNvbmNhdChpbnRlcm5hbHMucGFyc2VPYmplY3QoY2hhaW4sIHZhbCwgb3B0aW9ucykpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3RbMF0gPT09ICdbJyAmJiByb290W3Jvb3QubGVuZ3RoIC0gMV0gPT09ICddJyA/IHJvb3Quc2xpY2UoMSwgcm9vdC5sZW5ndGggLSAxKSA6IHJvb3Q7XG4gICAgICAgIHZhciBpbmRleCA9IHBhcnNlSW50KGNsZWFuUm9vdCwgMTApO1xuICAgICAgICB2YXIgaW5kZXhTdHJpbmcgPSAnJyArIGluZGV4O1xuICAgICAgICBpZiAoIWlzTmFOKGluZGV4KSAmJlxuICAgICAgICAgICAgcm9vdCAhPT0gY2xlYW5Sb290ICYmXG4gICAgICAgICAgICBpbmRleFN0cmluZyA9PT0gY2xlYW5Sb290ICYmXG4gICAgICAgICAgICBpbmRleCA+PSAwICYmXG4gICAgICAgICAgICBpbmRleCA8PSBvcHRpb25zLmFycmF5TGltaXQpIHtcblxuICAgICAgICAgICAgb2JqID0gW107XG4gICAgICAgICAgICBvYmpbaW5kZXhdID0gaW50ZXJuYWxzLnBhcnNlT2JqZWN0KGNoYWluLCB2YWwsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb2JqW2NsZWFuUm9vdF0gPSBpbnRlcm5hbHMucGFyc2VPYmplY3QoY2hhaW4sIHZhbCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxuXG5pbnRlcm5hbHMucGFyc2VLZXlzID0gZnVuY3Rpb24gKGtleSwgdmFsLCBvcHRpb25zKSB7XG5cbiAgICBpZiAoIWtleSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGhlIHJlZ2V4IGNodW5rc1xuXG4gICAgdmFyIHBhcmVudCA9IC9eKFteXFxbXFxdXSopLztcbiAgICB2YXIgY2hpbGQgPSAvKFxcW1teXFxbXFxdXSpcXF0pL2c7XG5cbiAgICAvLyBHZXQgdGhlIHBhcmVudFxuXG4gICAgdmFyIHNlZ21lbnQgPSBwYXJlbnQuZXhlYyhrZXkpO1xuXG4gICAgLy8gRG9uJ3QgYWxsb3cgdGhlbSB0byBvdmVyd3JpdGUgb2JqZWN0IHByb3RvdHlwZSBwcm9wZXJ0aWVzXG5cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShzZWdtZW50WzFdKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU3Rhc2ggdGhlIHBhcmVudCBpZiBpdCBleGlzdHNcblxuICAgIHZhciBrZXlzID0gW107XG4gICAgaWYgKHNlZ21lbnRbMV0pIHtcbiAgICAgICAga2V5cy5wdXNoKHNlZ21lbnRbMV0pO1xuICAgIH1cblxuICAgIC8vIExvb3AgdGhyb3VnaCBjaGlsZHJlbiBhcHBlbmRpbmcgdG8gdGhlIGFycmF5IHVudGlsIHdlIGhpdCBkZXB0aFxuXG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlICgoc2VnbWVudCA9IGNoaWxkLmV4ZWMoa2V5KSkgIT09IG51bGwgJiYgaSA8IG9wdGlvbnMuZGVwdGgpIHtcblxuICAgICAgICArK2k7XG4gICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShzZWdtZW50WzFdLnJlcGxhY2UoL1xcW3xcXF0vZywgJycpKSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKHNlZ21lbnRbMV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUncyBhIHJlbWFpbmRlciwganVzdCBhZGQgd2hhdGV2ZXIgaXMgbGVmdFxuXG4gICAgaWYgKHNlZ21lbnQpIHtcbiAgICAgICAga2V5cy5wdXNoKCdbJyArIGtleS5zbGljZShzZWdtZW50LmluZGV4KSArICddJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVybmFscy5wYXJzZU9iamVjdChrZXlzLCB2YWwsIG9wdGlvbnMpO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIsIG9wdGlvbnMpIHtcblxuICAgIGlmIChzdHIgPT09ICcnIHx8XG4gICAgICAgIHN0ciA9PT0gbnVsbCB8fFxuICAgICAgICB0eXBlb2Ygc3RyID09PSAndW5kZWZpbmVkJykge1xuXG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBvcHRpb25zLmRlbGltaXRlciA9IHR5cGVvZiBvcHRpb25zLmRlbGltaXRlciA9PT0gJ3N0cmluZycgfHwgVXRpbHMuaXNSZWdFeHAob3B0aW9ucy5kZWxpbWl0ZXIpID8gb3B0aW9ucy5kZWxpbWl0ZXIgOiBpbnRlcm5hbHMuZGVsaW1pdGVyO1xuICAgIG9wdGlvbnMuZGVwdGggPSB0eXBlb2Ygb3B0aW9ucy5kZXB0aCA9PT0gJ251bWJlcicgPyBvcHRpb25zLmRlcHRoIDogaW50ZXJuYWxzLmRlcHRoO1xuICAgIG9wdGlvbnMuYXJyYXlMaW1pdCA9IHR5cGVvZiBvcHRpb25zLmFycmF5TGltaXQgPT09ICdudW1iZXInID8gb3B0aW9ucy5hcnJheUxpbWl0IDogaW50ZXJuYWxzLmFycmF5TGltaXQ7XG4gICAgb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA9IHR5cGVvZiBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSAnbnVtYmVyJyA/IG9wdGlvbnMucGFyYW1ldGVyTGltaXQgOiBpbnRlcm5hbHMucGFyYW1ldGVyTGltaXQ7XG5cbiAgICB2YXIgdGVtcE9iaiA9IHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnID8gaW50ZXJuYWxzLnBhcnNlVmFsdWVzKHN0ciwgb3B0aW9ucykgOiBzdHI7XG4gICAgdmFyIG9iaiA9IHt9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGFuZCBzZXR1cCB0aGUgbmV3IG9iamVjdFxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0ZW1wT2JqKTtcbiAgICBmb3IgKHZhciBpID0gMCwgaWwgPSBrZXlzLmxlbmd0aDsgaSA8IGlsOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciBuZXdPYmogPSBpbnRlcm5hbHMucGFyc2VLZXlzKGtleSwgdGVtcE9ialtrZXldLCBvcHRpb25zKTtcbiAgICAgICAgb2JqID0gVXRpbHMubWVyZ2Uob2JqLCBuZXdPYmopO1xuICAgIH1cblxuICAgIHJldHVybiBVdGlscy5jb21wYWN0KG9iaik7XG59O1xuIiwiLy8gTG9hZCBtb2R1bGVzXG5cbnZhciBVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuXG4vLyBEZWNsYXJlIGludGVybmFsc1xuXG52YXIgaW50ZXJuYWxzID0ge1xuICAgIGRlbGltaXRlcjogJyYnLFxuICAgIGFycmF5UHJlZml4R2VuZXJhdG9yczoge1xuICAgICAgICBicmFja2V0czogZnVuY3Rpb24gKHByZWZpeCwga2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1tdJztcbiAgICAgICAgfSxcbiAgICAgICAgaW5kaWNlczogZnVuY3Rpb24gKHByZWZpeCwga2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1snICsga2V5ICsgJ10nO1xuICAgICAgICB9LFxuICAgICAgICByZXBlYXQ6IGZ1bmN0aW9uIChwcmVmaXgsIGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cblxuaW50ZXJuYWxzLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChvYmosIHByZWZpeCwgZ2VuZXJhdGVBcnJheVByZWZpeCkge1xuXG4gICAgaWYgKFV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgb2JqID0gb2JqLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgb2JqID0gb2JqLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgICAgICBvYmogPSAnJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgdHlwZW9mIG9iaiA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgdHlwZW9mIG9iaiA9PT0gJ2Jvb2xlYW4nKSB7XG5cbiAgICAgICAgcmV0dXJuIFtlbmNvZGVVUklDb21wb25lbnQocHJlZml4KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmopXTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICB2YXIgb2JqS2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gb2JqS2V5cy5sZW5ndGg7IGkgPCBpbDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGludGVybmFscy5zdHJpbmdpZnkob2JqW2tleV0sIGdlbmVyYXRlQXJyYXlQcmVmaXgocHJlZml4LCBrZXkpLCBnZW5lcmF0ZUFycmF5UHJlZml4KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGludGVybmFscy5zdHJpbmdpZnkob2JqW2tleV0sIHByZWZpeCArICdbJyArIGtleSArICddJywgZ2VuZXJhdGVBcnJheVByZWZpeCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBvcHRpb25zKSB7XG5cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgZGVsaW1pdGVyID0gdHlwZW9mIG9wdGlvbnMuZGVsaW1pdGVyID09PSAndW5kZWZpbmVkJyA/IGludGVybmFscy5kZWxpbWl0ZXIgOiBvcHRpb25zLmRlbGltaXRlcjtcblxuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHxcbiAgICAgICAgb2JqID09PSBudWxsKSB7XG5cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHZhciBhcnJheUZvcm1hdDtcbiAgICBpZiAob3B0aW9ucy5hcnJheUZvcm1hdCBpbiBpbnRlcm5hbHMuYXJyYXlQcmVmaXhHZW5lcmF0b3JzKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0aW9ucy5hcnJheUZvcm1hdDtcbiAgICB9XG4gICAgZWxzZSBpZiAoJ2luZGljZXMnIGluIG9wdGlvbnMpIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSBvcHRpb25zLmluZGljZXMgPyAnaW5kaWNlcycgOiAncmVwZWF0JztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gJ2luZGljZXMnO1xuICAgIH1cblxuICAgIHZhciBnZW5lcmF0ZUFycmF5UHJlZml4ID0gaW50ZXJuYWxzLmFycmF5UHJlZml4R2VuZXJhdG9yc1thcnJheUZvcm1hdF07XG5cbiAgICB2YXIgb2JqS2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gb2JqS2V5cy5sZW5ndGg7IGkgPCBpbDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuICAgICAgICBrZXlzID0ga2V5cy5jb25jYXQoaW50ZXJuYWxzLnN0cmluZ2lmeShvYmpba2V5XSwga2V5LCBnZW5lcmF0ZUFycmF5UHJlZml4KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGtleXMuam9pbihkZWxpbWl0ZXIpO1xufTtcbiIsIi8vIExvYWQgbW9kdWxlc1xuXG5cbi8vIERlY2xhcmUgaW50ZXJuYWxzXG5cbnZhciBpbnRlcm5hbHMgPSB7fTtcblxuXG5leHBvcnRzLmFycmF5VG9PYmplY3QgPSBmdW5jdGlvbiAoc291cmNlKSB7XG5cbiAgICB2YXIgb2JqID0ge307XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gc291cmNlLmxlbmd0aDsgaSA8IGlsOyArK2kpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VbaV0gIT09ICd1bmRlZmluZWQnKSB7XG5cbiAgICAgICAgICAgIG9ialtpXSA9IHNvdXJjZVtpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG5cbmV4cG9ydHMubWVyZ2UgPSBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblxuICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5wdXNoKHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0YXJnZXRbc291cmNlXSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0YXJnZXQgPSBbdGFyZ2V0XS5jb25jYXQoc291cmNlKTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KHNvdXJjZSkpIHtcblxuICAgICAgICB0YXJnZXQgPSBleHBvcnRzLmFycmF5VG9PYmplY3QodGFyZ2V0KTtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG4gICAgZm9yICh2YXIgayA9IDAsIGtsID0ga2V5cy5sZW5ndGg7IGsgPCBrbDsgKytrKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2tdO1xuICAgICAgICB2YXIgdmFsdWUgPSBzb3VyY2Vba2V5XTtcblxuICAgICAgICBpZiAoIXRhcmdldFtrZXldKSB7XG4gICAgICAgICAgICB0YXJnZXRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBleHBvcnRzLm1lcmdlKHRhcmdldFtrZXldLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xufTtcblxuXG5leHBvcnRzLmRlY29kZSA9IGZ1bmN0aW9uIChzdHIpIHtcblxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxufTtcblxuXG5leHBvcnRzLmNvbXBhY3QgPSBmdW5jdGlvbiAob2JqLCByZWZzKSB7XG5cbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHxcbiAgICAgICAgb2JqID09PSBudWxsKSB7XG5cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICByZWZzID0gcmVmcyB8fCBbXTtcbiAgICB2YXIgbG9va3VwID0gcmVmcy5pbmRleE9mKG9iaik7XG4gICAgaWYgKGxvb2t1cCAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHJlZnNbbG9va3VwXTtcbiAgICB9XG5cbiAgICByZWZzLnB1c2gob2JqKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgdmFyIGNvbXBhY3RlZCA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpbCA9IG9iai5sZW5ndGg7IGkgPCBpbDsgKytpKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9ialtpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBjb21wYWN0ZWQucHVzaChvYmpbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBhY3RlZDtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgZm9yIChpID0gMCwgaWwgPSBrZXlzLmxlbmd0aDsgaSA8IGlsOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIG9ialtrZXldID0gZXhwb3J0cy5jb21wYWN0KG9ialtrZXldLCByZWZzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxuXG5leHBvcnRzLmlzUmVnRXhwID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59O1xuXG5cbmV4cG9ydHMuaXNCdWZmZXIgPSBmdW5jdGlvbiAob2JqKSB7XG5cbiAgICBpZiAob2JqID09PSBudWxsIHx8XG4gICAgICAgIHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiAhIShvYmouY29uc3RydWN0b3IgJiZcbiAgICAgICAgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyICYmXG4gICAgICAgIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKTtcbn07XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgQXV0b0ZvY3VzVXRpbHNcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RNb3VudCA9IHJlcXVpcmUoJy4vUmVhY3RNb3VudCcpO1xuXG52YXIgZmluZERPTU5vZGUgPSByZXF1aXJlKCcuL2ZpbmRET01Ob2RlJyk7XG52YXIgZm9jdXNOb2RlID0gcmVxdWlyZSgnZmJqcy9saWIvZm9jdXNOb2RlJyk7XG5cbnZhciBNaXhpbiA9IHtcbiAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5wcm9wcy5hdXRvRm9jdXMpIHtcbiAgICAgIGZvY3VzTm9kZShmaW5kRE9NTm9kZSh0aGlzKSk7XG4gICAgfVxuICB9XG59O1xuXG52YXIgQXV0b0ZvY3VzVXRpbHMgPSB7XG4gIE1peGluOiBNaXhpbixcblxuICBmb2N1c0RPTUNvbXBvbmVudDogZnVuY3Rpb24gKCkge1xuICAgIGZvY3VzTm9kZShSZWFjdE1vdW50LmdldE5vZGUodGhpcy5fcm9vdE5vZGVJRCkpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEF1dG9Gb2N1c1V0aWxzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIEJlZm9yZUlucHV0RXZlbnRQbHVnaW5cbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgRXZlbnRQcm9wYWdhdG9ycyA9IHJlcXVpcmUoJy4vRXZlbnRQcm9wYWdhdG9ycycpO1xudmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnZmJqcy9saWIvRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcbnZhciBGYWxsYmFja0NvbXBvc2l0aW9uU3RhdGUgPSByZXF1aXJlKCcuL0ZhbGxiYWNrQ29tcG9zaXRpb25TdGF0ZScpO1xudmFyIFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQnKTtcbnZhciBTeW50aGV0aWNJbnB1dEV2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNJbnB1dEV2ZW50Jyk7XG5cbnZhciBrZXlPZiA9IHJlcXVpcmUoJ2ZianMvbGliL2tleU9mJyk7XG5cbnZhciBFTkRfS0VZQ09ERVMgPSBbOSwgMTMsIDI3LCAzMl07IC8vIFRhYiwgUmV0dXJuLCBFc2MsIFNwYWNlXG52YXIgU1RBUlRfS0VZQ09ERSA9IDIyOTtcblxudmFyIGNhblVzZUNvbXBvc2l0aW9uRXZlbnQgPSBFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00gJiYgJ0NvbXBvc2l0aW9uRXZlbnQnIGluIHdpbmRvdztcblxudmFyIGRvY3VtZW50TW9kZSA9IG51bGw7XG5pZiAoRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NICYmICdkb2N1bWVudE1vZGUnIGluIGRvY3VtZW50KSB7XG4gIGRvY3VtZW50TW9kZSA9IGRvY3VtZW50LmRvY3VtZW50TW9kZTtcbn1cblxuLy8gV2Via2l0IG9mZmVycyBhIHZlcnkgdXNlZnVsIGB0ZXh0SW5wdXRgIGV2ZW50IHRoYXQgY2FuIGJlIHVzZWQgdG9cbi8vIGRpcmVjdGx5IHJlcHJlc2VudCBgYmVmb3JlSW5wdXRgLiBUaGUgSUUgYHRleHRpbnB1dGAgZXZlbnQgaXMgbm90IGFzXG4vLyB1c2VmdWwsIHNvIHdlIGRvbid0IHVzZSBpdC5cbnZhciBjYW5Vc2VUZXh0SW5wdXRFdmVudCA9IEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSAmJiAnVGV4dEV2ZW50JyBpbiB3aW5kb3cgJiYgIWRvY3VtZW50TW9kZSAmJiAhaXNQcmVzdG8oKTtcblxuLy8gSW4gSUU5Kywgd2UgaGF2ZSBhY2Nlc3MgdG8gY29tcG9zaXRpb24gZXZlbnRzLCBidXQgdGhlIGRhdGEgc3VwcGxpZWRcbi8vIGJ5IHRoZSBuYXRpdmUgY29tcG9zaXRpb25lbmQgZXZlbnQgbWF5IGJlIGluY29ycmVjdC4gSmFwYW5lc2UgaWRlb2dyYXBoaWNcbi8vIHNwYWNlcywgZm9yIGluc3RhbmNlIChcXHUzMDAwKSBhcmUgbm90IHJlY29yZGVkIGNvcnJlY3RseS5cbnZhciB1c2VGYWxsYmFja0NvbXBvc2l0aW9uRGF0YSA9IEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSAmJiAoIWNhblVzZUNvbXBvc2l0aW9uRXZlbnQgfHwgZG9jdW1lbnRNb2RlICYmIGRvY3VtZW50TW9kZSA+IDggJiYgZG9jdW1lbnRNb2RlIDw9IDExKTtcblxuLyoqXG4gKiBPcGVyYSA8PSAxMiBpbmNsdWRlcyBUZXh0RXZlbnQgaW4gd2luZG93LCBidXQgZG9lcyBub3QgZmlyZVxuICogdGV4dCBpbnB1dCBldmVudHMuIFJlbHkgb24ga2V5cHJlc3MgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gaXNQcmVzdG8oKSB7XG4gIHZhciBvcGVyYSA9IHdpbmRvdy5vcGVyYTtcbiAgcmV0dXJuIHR5cGVvZiBvcGVyYSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG9wZXJhLnZlcnNpb24gPT09ICdmdW5jdGlvbicgJiYgcGFyc2VJbnQob3BlcmEudmVyc2lvbigpLCAxMCkgPD0gMTI7XG59XG5cbnZhciBTUEFDRUJBUl9DT0RFID0gMzI7XG52YXIgU1BBQ0VCQVJfQ0hBUiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoU1BBQ0VCQVJfQ09ERSk7XG5cbnZhciB0b3BMZXZlbFR5cGVzID0gRXZlbnRDb25zdGFudHMudG9wTGV2ZWxUeXBlcztcblxuLy8gRXZlbnRzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIHByb3BlcnR5IG5hbWVzLlxudmFyIGV2ZW50VHlwZXMgPSB7XG4gIGJlZm9yZUlucHV0OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25CZWZvcmVJbnB1dDogbnVsbCB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uQmVmb3JlSW5wdXRDYXB0dXJlOiBudWxsIH0pXG4gICAgfSxcbiAgICBkZXBlbmRlbmNpZXM6IFt0b3BMZXZlbFR5cGVzLnRvcENvbXBvc2l0aW9uRW5kLCB0b3BMZXZlbFR5cGVzLnRvcEtleVByZXNzLCB0b3BMZXZlbFR5cGVzLnRvcFRleHRJbnB1dCwgdG9wTGV2ZWxUeXBlcy50b3BQYXN0ZV1cbiAgfSxcbiAgY29tcG9zaXRpb25FbmQ6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkNvbXBvc2l0aW9uRW5kOiBudWxsIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Db21wb3NpdGlvbkVuZENhcHR1cmU6IG51bGwgfSlcbiAgICB9LFxuICAgIGRlcGVuZGVuY2llczogW3RvcExldmVsVHlwZXMudG9wQmx1ciwgdG9wTGV2ZWxUeXBlcy50b3BDb21wb3NpdGlvbkVuZCwgdG9wTGV2ZWxUeXBlcy50b3BLZXlEb3duLCB0b3BMZXZlbFR5cGVzLnRvcEtleVByZXNzLCB0b3BMZXZlbFR5cGVzLnRvcEtleVVwLCB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlRG93bl1cbiAgfSxcbiAgY29tcG9zaXRpb25TdGFydDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uQ29tcG9zaXRpb25TdGFydDogbnVsbCB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uQ29tcG9zaXRpb25TdGFydENhcHR1cmU6IG51bGwgfSlcbiAgICB9LFxuICAgIGRlcGVuZGVuY2llczogW3RvcExldmVsVHlwZXMudG9wQmx1ciwgdG9wTGV2ZWxUeXBlcy50b3BDb21wb3NpdGlvblN0YXJ0LCB0b3BMZXZlbFR5cGVzLnRvcEtleURvd24sIHRvcExldmVsVHlwZXMudG9wS2V5UHJlc3MsIHRvcExldmVsVHlwZXMudG9wS2V5VXAsIHRvcExldmVsVHlwZXMudG9wTW91c2VEb3duXVxuICB9LFxuICBjb21wb3NpdGlvblVwZGF0ZToge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uQ29tcG9zaXRpb25VcGRhdGU6IG51bGwgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkNvbXBvc2l0aW9uVXBkYXRlQ2FwdHVyZTogbnVsbCB9KVxuICAgIH0sXG4gICAgZGVwZW5kZW5jaWVzOiBbdG9wTGV2ZWxUeXBlcy50b3BCbHVyLCB0b3BMZXZlbFR5cGVzLnRvcENvbXBvc2l0aW9uVXBkYXRlLCB0b3BMZXZlbFR5cGVzLnRvcEtleURvd24sIHRvcExldmVsVHlwZXMudG9wS2V5UHJlc3MsIHRvcExldmVsVHlwZXMudG9wS2V5VXAsIHRvcExldmVsVHlwZXMudG9wTW91c2VEb3duXVxuICB9XG59O1xuXG4vLyBUcmFjayB3aGV0aGVyIHdlJ3ZlIGV2ZXIgaGFuZGxlZCBhIGtleXByZXNzIG9uIHRoZSBzcGFjZSBrZXkuXG52YXIgaGFzU3BhY2VLZXlwcmVzcyA9IGZhbHNlO1xuXG4vKipcbiAqIFJldHVybiB3aGV0aGVyIGEgbmF0aXZlIGtleXByZXNzIGV2ZW50IGlzIGFzc3VtZWQgdG8gYmUgYSBjb21tYW5kLlxuICogVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIEZpcmVmb3ggZmlyZXMgYGtleXByZXNzYCBldmVudHMgZm9yIGtleSBjb21tYW5kc1xuICogKGN1dCwgY29weSwgc2VsZWN0LWFsbCwgZXRjLikgZXZlbiB0aG91Z2ggbm8gY2hhcmFjdGVyIGlzIGluc2VydGVkLlxuICovXG5mdW5jdGlvbiBpc0tleXByZXNzQ29tbWFuZChuYXRpdmVFdmVudCkge1xuICByZXR1cm4gKG5hdGl2ZUV2ZW50LmN0cmxLZXkgfHwgbmF0aXZlRXZlbnQuYWx0S2V5IHx8IG5hdGl2ZUV2ZW50Lm1ldGFLZXkpICYmXG4gIC8vIGN0cmxLZXkgJiYgYWx0S2V5IGlzIGVxdWl2YWxlbnQgdG8gQWx0R3IsIGFuZCBpcyBub3QgYSBjb21tYW5kLlxuICAhKG5hdGl2ZUV2ZW50LmN0cmxLZXkgJiYgbmF0aXZlRXZlbnQuYWx0S2V5KTtcbn1cblxuLyoqXG4gKiBUcmFuc2xhdGUgbmF0aXZlIHRvcCBsZXZlbCBldmVudHMgaW50byBldmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUeXBlXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGdldENvbXBvc2l0aW9uRXZlbnRUeXBlKHRvcExldmVsVHlwZSkge1xuICBzd2l0Y2ggKHRvcExldmVsVHlwZSkge1xuICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BDb21wb3NpdGlvblN0YXJ0OlxuICAgICAgcmV0dXJuIGV2ZW50VHlwZXMuY29tcG9zaXRpb25TdGFydDtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ29tcG9zaXRpb25FbmQ6XG4gICAgICByZXR1cm4gZXZlbnRUeXBlcy5jb21wb3NpdGlvbkVuZDtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ29tcG9zaXRpb25VcGRhdGU6XG4gICAgICByZXR1cm4gZXZlbnRUeXBlcy5jb21wb3NpdGlvblVwZGF0ZTtcbiAgfVxufVxuXG4vKipcbiAqIERvZXMgb3VyIGZhbGxiYWNrIGJlc3QtZ3Vlc3MgbW9kZWwgdGhpbmsgdGhpcyBldmVudCBzaWduaWZpZXMgdGhhdFxuICogY29tcG9zaXRpb24gaGFzIGJlZ3VuP1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNGYWxsYmFja0NvbXBvc2l0aW9uU3RhcnQodG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCkge1xuICByZXR1cm4gdG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcEtleURvd24gJiYgbmF0aXZlRXZlbnQua2V5Q29kZSA9PT0gU1RBUlRfS0VZQ09ERTtcbn1cblxuLyoqXG4gKiBEb2VzIG91ciBmYWxsYmFjayBtb2RlIHRoaW5rIHRoYXQgdGhpcyBldmVudCBpcyB0aGUgZW5kIG9mIGNvbXBvc2l0aW9uP1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpIHtcbiAgc3dpdGNoICh0b3BMZXZlbFR5cGUpIHtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wS2V5VXA6XG4gICAgICAvLyBDb21tYW5kIGtleXMgaW5zZXJ0IG9yIGNsZWFyIElNRSBpbnB1dC5cbiAgICAgIHJldHVybiBFTkRfS0VZQ09ERVMuaW5kZXhPZihuYXRpdmVFdmVudC5rZXlDb2RlKSAhPT0gLTE7XG4gICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcEtleURvd246XG4gICAgICAvLyBFeHBlY3QgSU1FIGtleUNvZGUgb24gZWFjaCBrZXlkb3duLiBJZiB3ZSBnZXQgYW55IG90aGVyXG4gICAgICAvLyBjb2RlIHdlIG11c3QgaGF2ZSBleGl0ZWQgZWFybGllci5cbiAgICAgIHJldHVybiBuYXRpdmVFdmVudC5rZXlDb2RlICE9PSBTVEFSVF9LRVlDT0RFO1xuICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BLZXlQcmVzczpcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wTW91c2VEb3duOlxuICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BCbHVyOlxuICAgICAgLy8gRXZlbnRzIGFyZSBub3QgcG9zc2libGUgd2l0aG91dCBjYW5jZWxsaW5nIElNRS5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBHb29nbGUgSW5wdXQgVG9vbHMgcHJvdmlkZXMgY29tcG9zaXRpb24gZGF0YSB2aWEgYSBDdXN0b21FdmVudCxcbiAqIHdpdGggdGhlIGBkYXRhYCBwcm9wZXJ0eSBwb3B1bGF0ZWQgaW4gdGhlIGBkZXRhaWxgIG9iamVjdC4gSWYgdGhpc1xuICogaXMgYXZhaWxhYmxlIG9uIHRoZSBldmVudCBvYmplY3QsIHVzZSBpdC4gSWYgbm90LCB0aGlzIGlzIGEgcGxhaW5cbiAqIGNvbXBvc2l0aW9uIGV2ZW50IGFuZCB3ZSBoYXZlIG5vdGhpbmcgc3BlY2lhbCB0byBleHRyYWN0LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFxuICogQHJldHVybiB7P3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZ2V0RGF0YUZyb21DdXN0b21FdmVudChuYXRpdmVFdmVudCkge1xuICB2YXIgZGV0YWlsID0gbmF0aXZlRXZlbnQuZGV0YWlsO1xuICBpZiAodHlwZW9mIGRldGFpbCA9PT0gJ29iamVjdCcgJiYgJ2RhdGEnIGluIGRldGFpbCkge1xuICAgIHJldHVybiBkZXRhaWwuZGF0YTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gVHJhY2sgdGhlIGN1cnJlbnQgSU1FIGNvbXBvc2l0aW9uIGZhbGxiYWNrIG9iamVjdCwgaWYgYW55LlxudmFyIGN1cnJlbnRDb21wb3NpdGlvbiA9IG51bGw7XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVHlwZSBSZWNvcmQgZnJvbSBgRXZlbnRDb25zdGFudHNgLlxuICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVGFyZ2V0SUQgSUQgb2YgYHRvcExldmVsVGFyZ2V0YC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4gez9vYmplY3R9IEEgU3ludGhldGljQ29tcG9zaXRpb25FdmVudC5cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdENvbXBvc2l0aW9uRXZlbnQodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIHZhciBldmVudFR5cGU7XG4gIHZhciBmYWxsYmFja0RhdGE7XG5cbiAgaWYgKGNhblVzZUNvbXBvc2l0aW9uRXZlbnQpIHtcbiAgICBldmVudFR5cGUgPSBnZXRDb21wb3NpdGlvbkV2ZW50VHlwZSh0b3BMZXZlbFR5cGUpO1xuICB9IGVsc2UgaWYgKCFjdXJyZW50Q29tcG9zaXRpb24pIHtcbiAgICBpZiAoaXNGYWxsYmFja0NvbXBvc2l0aW9uU3RhcnQodG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCkpIHtcbiAgICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZXMuY29tcG9zaXRpb25TdGFydDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpKSB7XG4gICAgZXZlbnRUeXBlID0gZXZlbnRUeXBlcy5jb21wb3NpdGlvbkVuZDtcbiAgfVxuXG4gIGlmICghZXZlbnRUeXBlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAodXNlRmFsbGJhY2tDb21wb3NpdGlvbkRhdGEpIHtcbiAgICAvLyBUaGUgY3VycmVudCBjb21wb3NpdGlvbiBpcyBzdG9yZWQgc3RhdGljYWxseSBhbmQgbXVzdCBub3QgYmVcbiAgICAvLyBvdmVyd3JpdHRlbiB3aGlsZSBjb21wb3NpdGlvbiBjb250aW51ZXMuXG4gICAgaWYgKCFjdXJyZW50Q29tcG9zaXRpb24gJiYgZXZlbnRUeXBlID09PSBldmVudFR5cGVzLmNvbXBvc2l0aW9uU3RhcnQpIHtcbiAgICAgIGN1cnJlbnRDb21wb3NpdGlvbiA9IEZhbGxiYWNrQ29tcG9zaXRpb25TdGF0ZS5nZXRQb29sZWQodG9wTGV2ZWxUYXJnZXQpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSBldmVudFR5cGVzLmNvbXBvc2l0aW9uRW5kKSB7XG4gICAgICBpZiAoY3VycmVudENvbXBvc2l0aW9uKSB7XG4gICAgICAgIGZhbGxiYWNrRGF0YSA9IGN1cnJlbnRDb21wb3NpdGlvbi5nZXREYXRhKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGV2ZW50ID0gU3ludGhldGljQ29tcG9zaXRpb25FdmVudC5nZXRQb29sZWQoZXZlbnRUeXBlLCB0b3BMZXZlbFRhcmdldElELCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuXG4gIGlmIChmYWxsYmFja0RhdGEpIHtcbiAgICAvLyBJbmplY3QgZGF0YSBnZW5lcmF0ZWQgZnJvbSBmYWxsYmFjayBwYXRoIGludG8gdGhlIHN5bnRoZXRpYyBldmVudC5cbiAgICAvLyBUaGlzIG1hdGNoZXMgdGhlIHByb3BlcnR5IG9mIG5hdGl2ZSBDb21wb3NpdGlvbkV2ZW50SW50ZXJmYWNlLlxuICAgIGV2ZW50LmRhdGEgPSBmYWxsYmFja0RhdGE7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGN1c3RvbURhdGEgPSBnZXREYXRhRnJvbUN1c3RvbUV2ZW50KG5hdGl2ZUV2ZW50KTtcbiAgICBpZiAoY3VzdG9tRGF0YSAhPT0gbnVsbCkge1xuICAgICAgZXZlbnQuZGF0YSA9IGN1c3RvbURhdGE7XG4gICAgfVxuICB9XG5cbiAgRXZlbnRQcm9wYWdhdG9ycy5hY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzKGV2ZW50KTtcbiAgcmV0dXJuIGV2ZW50O1xufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGUgUmVjb3JkIGZyb20gYEV2ZW50Q29uc3RhbnRzYC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4gez9zdHJpbmd9IFRoZSBzdHJpbmcgY29ycmVzcG9uZGluZyB0byB0aGlzIGBiZWZvcmVJbnB1dGAgZXZlbnQuXG4gKi9cbmZ1bmN0aW9uIGdldE5hdGl2ZUJlZm9yZUlucHV0Q2hhcnModG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCkge1xuICBzd2l0Y2ggKHRvcExldmVsVHlwZSkge1xuICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BDb21wb3NpdGlvbkVuZDpcbiAgICAgIHJldHVybiBnZXREYXRhRnJvbUN1c3RvbUV2ZW50KG5hdGl2ZUV2ZW50KTtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wS2V5UHJlc3M6XG4gICAgICAvKipcbiAgICAgICAqIElmIG5hdGl2ZSBgdGV4dElucHV0YCBldmVudHMgYXJlIGF2YWlsYWJsZSwgb3VyIGdvYWwgaXMgdG8gbWFrZVxuICAgICAgICogdXNlIG9mIHRoZW0uIEhvd2V2ZXIsIHRoZXJlIGlzIGEgc3BlY2lhbCBjYXNlOiB0aGUgc3BhY2ViYXIga2V5LlxuICAgICAgICogSW4gV2Via2l0LCBwcmV2ZW50aW5nIGRlZmF1bHQgb24gYSBzcGFjZWJhciBgdGV4dElucHV0YCBldmVudFxuICAgICAgICogY2FuY2VscyBjaGFyYWN0ZXIgaW5zZXJ0aW9uLCBidXQgaXQgKmFsc28qIGNhdXNlcyB0aGUgYnJvd3NlclxuICAgICAgICogdG8gZmFsbCBiYWNrIHRvIGl0cyBkZWZhdWx0IHNwYWNlYmFyIGJlaGF2aW9yIG9mIHNjcm9sbGluZyB0aGVcbiAgICAgICAqIHBhZ2UuXG4gICAgICAgKlxuICAgICAgICogVHJhY2tpbmcgYXQ6XG4gICAgICAgKiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MzU1MTAzXG4gICAgICAgKlxuICAgICAgICogVG8gYXZvaWQgdGhpcyBpc3N1ZSwgdXNlIHRoZSBrZXlwcmVzcyBldmVudCBhcyBpZiBubyBgdGV4dElucHV0YFxuICAgICAgICogZXZlbnQgaXMgYXZhaWxhYmxlLlxuICAgICAgICovXG4gICAgICB2YXIgd2hpY2ggPSBuYXRpdmVFdmVudC53aGljaDtcbiAgICAgIGlmICh3aGljaCAhPT0gU1BBQ0VCQVJfQ09ERSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaGFzU3BhY2VLZXlwcmVzcyA9IHRydWU7XG4gICAgICByZXR1cm4gU1BBQ0VCQVJfQ0hBUjtcblxuICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BUZXh0SW5wdXQ6XG4gICAgICAvLyBSZWNvcmQgdGhlIGNoYXJhY3RlcnMgdG8gYmUgYWRkZWQgdG8gdGhlIERPTS5cbiAgICAgIHZhciBjaGFycyA9IG5hdGl2ZUV2ZW50LmRhdGE7XG5cbiAgICAgIC8vIElmIGl0J3MgYSBzcGFjZWJhciBjaGFyYWN0ZXIsIGFzc3VtZSB0aGF0IHdlIGhhdmUgYWxyZWFkeSBoYW5kbGVkXG4gICAgICAvLyBpdCBhdCB0aGUga2V5cHJlc3MgbGV2ZWwgYW5kIGJhaWwgaW1tZWRpYXRlbHkuIEFuZHJvaWQgQ2hyb21lXG4gICAgICAvLyBkb2Vzbid0IGdpdmUgdXMga2V5Y29kZXMsIHNvIHdlIG5lZWQgdG8gYmxhY2tsaXN0IGl0LlxuICAgICAgaWYgKGNoYXJzID09PSBTUEFDRUJBUl9DSEFSICYmIGhhc1NwYWNlS2V5cHJlc3MpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjaGFycztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBGb3Igb3RoZXIgbmF0aXZlIGV2ZW50IHR5cGVzLCBkbyBub3RoaW5nLlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBGb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QgcHJvdmlkZSB0aGUgYHRleHRJbnB1dGAgZXZlbnQsIGV4dHJhY3QgdGhlXG4gKiBhcHByb3ByaWF0ZSBzdHJpbmcgdG8gdXNlIGZvciBTeW50aGV0aWNJbnB1dEV2ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGUgUmVjb3JkIGZyb20gYEV2ZW50Q29uc3RhbnRzYC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4gez9zdHJpbmd9IFRoZSBmYWxsYmFjayBzdHJpbmcgZm9yIHRoaXMgYGJlZm9yZUlucHV0YCBldmVudC5cbiAqL1xuZnVuY3Rpb24gZ2V0RmFsbGJhY2tCZWZvcmVJbnB1dENoYXJzKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpIHtcbiAgLy8gSWYgd2UgYXJlIGN1cnJlbnRseSBjb21wb3NpbmcgKElNRSkgYW5kIHVzaW5nIGEgZmFsbGJhY2sgdG8gZG8gc28sXG4gIC8vIHRyeSB0byBleHRyYWN0IHRoZSBjb21wb3NlZCBjaGFyYWN0ZXJzIGZyb20gdGhlIGZhbGxiYWNrIG9iamVjdC5cbiAgaWYgKGN1cnJlbnRDb21wb3NpdGlvbikge1xuICAgIGlmICh0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wQ29tcG9zaXRpb25FbmQgfHwgaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpKSB7XG4gICAgICB2YXIgY2hhcnMgPSBjdXJyZW50Q29tcG9zaXRpb24uZ2V0RGF0YSgpO1xuICAgICAgRmFsbGJhY2tDb21wb3NpdGlvblN0YXRlLnJlbGVhc2UoY3VycmVudENvbXBvc2l0aW9uKTtcbiAgICAgIGN1cnJlbnRDb21wb3NpdGlvbiA9IG51bGw7XG4gICAgICByZXR1cm4gY2hhcnM7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3dpdGNoICh0b3BMZXZlbFR5cGUpIHtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wUGFzdGU6XG4gICAgICAvLyBJZiBhIHBhc3RlIGV2ZW50IG9jY3VycyBhZnRlciBhIGtleXByZXNzLCB0aHJvdyBvdXQgdGhlIGlucHV0XG4gICAgICAvLyBjaGFycy4gUGFzdGUgZXZlbnRzIHNob3VsZCBub3QgbGVhZCB0byBCZWZvcmVJbnB1dCBldmVudHMuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wS2V5UHJlc3M6XG4gICAgICAvKipcbiAgICAgICAqIEFzIG9mIHYyNywgRmlyZWZveCBtYXkgZmlyZSBrZXlwcmVzcyBldmVudHMgZXZlbiB3aGVuIG5vIGNoYXJhY3RlclxuICAgICAgICogd2lsbCBiZSBpbnNlcnRlZC4gQSBmZXcgcG9zc2liaWxpdGllczpcbiAgICAgICAqXG4gICAgICAgKiAtIGB3aGljaGAgaXMgYDBgLiBBcnJvdyBrZXlzLCBFc2Mga2V5LCBldGMuXG4gICAgICAgKlxuICAgICAgICogLSBgd2hpY2hgIGlzIHRoZSBwcmVzc2VkIGtleSBjb2RlLCBidXQgbm8gY2hhciBpcyBhdmFpbGFibGUuXG4gICAgICAgKiAgIEV4OiAnQWx0R3IgKyBkYCBpbiBQb2xpc2guIFRoZXJlIGlzIG5vIG1vZGlmaWVkIGNoYXJhY3RlciBmb3JcbiAgICAgICAqICAgdGhpcyBrZXkgY29tYmluYXRpb24gYW5kIG5vIGNoYXJhY3RlciBpcyBpbnNlcnRlZCBpbnRvIHRoZVxuICAgICAgICogICBkb2N1bWVudCwgYnV0IEZGIGZpcmVzIHRoZSBrZXlwcmVzcyBmb3IgY2hhciBjb2RlIGAxMDBgIGFueXdheS5cbiAgICAgICAqICAgTm8gYGlucHV0YCBldmVudCB3aWxsIG9jY3VyLlxuICAgICAgICpcbiAgICAgICAqIC0gYHdoaWNoYCBpcyB0aGUgcHJlc3NlZCBrZXkgY29kZSwgYnV0IGEgY29tbWFuZCBjb21iaW5hdGlvbiBpc1xuICAgICAgICogICBiZWluZyB1c2VkLiBFeDogYENtZCtDYC4gTm8gY2hhcmFjdGVyIGlzIGluc2VydGVkLCBhbmQgbm9cbiAgICAgICAqICAgYGlucHV0YCBldmVudCB3aWxsIG9jY3VyLlxuICAgICAgICovXG4gICAgICBpZiAobmF0aXZlRXZlbnQud2hpY2ggJiYgIWlzS2V5cHJlc3NDb21tYW5kKG5hdGl2ZUV2ZW50KSkge1xuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShuYXRpdmVFdmVudC53aGljaCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ29tcG9zaXRpb25FbmQ6XG4gICAgICByZXR1cm4gdXNlRmFsbGJhY2tDb21wb3NpdGlvbkRhdGEgPyBudWxsIDogbmF0aXZlRXZlbnQuZGF0YTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBFeHRyYWN0IGEgU3ludGhldGljSW5wdXRFdmVudCBmb3IgYGJlZm9yZUlucHV0YCwgYmFzZWQgb24gZWl0aGVyIG5hdGl2ZVxuICogYHRleHRJbnB1dGAgb3IgZmFsbGJhY2sgYmVoYXZpb3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVHlwZSBSZWNvcmQgZnJvbSBgRXZlbnRDb25zdGFudHNgLlxuICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVGFyZ2V0SUQgSUQgb2YgYHRvcExldmVsVGFyZ2V0YC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4gez9vYmplY3R9IEEgU3ludGhldGljSW5wdXRFdmVudC5cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIHZhciBjaGFycztcblxuICBpZiAoY2FuVXNlVGV4dElucHV0RXZlbnQpIHtcbiAgICBjaGFycyA9IGdldE5hdGl2ZUJlZm9yZUlucHV0Q2hhcnModG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCk7XG4gIH0gZWxzZSB7XG4gICAgY2hhcnMgPSBnZXRGYWxsYmFja0JlZm9yZUlucHV0Q2hhcnModG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCk7XG4gIH1cblxuICAvLyBJZiBubyBjaGFyYWN0ZXJzIGFyZSBiZWluZyBpbnNlcnRlZCwgbm8gQmVmb3JlSW5wdXQgZXZlbnQgc2hvdWxkXG4gIC8vIGJlIGZpcmVkLlxuICBpZiAoIWNoYXJzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgZXZlbnQgPSBTeW50aGV0aWNJbnB1dEV2ZW50LmdldFBvb2xlZChldmVudFR5cGVzLmJlZm9yZUlucHV0LCB0b3BMZXZlbFRhcmdldElELCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuXG4gIGV2ZW50LmRhdGEgPSBjaGFycztcbiAgRXZlbnRQcm9wYWdhdG9ycy5hY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzKGV2ZW50KTtcbiAgcmV0dXJuIGV2ZW50O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBgb25CZWZvcmVJbnB1dGAgZXZlbnQgdG8gbWF0Y2hcbiAqIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMTMxMTA1LyNldmVudHMtaW5wdXRldmVudHMuXG4gKlxuICogVGhpcyBldmVudCBwbHVnaW4gaXMgYmFzZWQgb24gdGhlIG5hdGl2ZSBgdGV4dElucHV0YCBldmVudFxuICogYXZhaWxhYmxlIGluIENocm9tZSwgU2FmYXJpLCBPcGVyYSwgYW5kIElFLiBUaGlzIGV2ZW50IGZpcmVzIGFmdGVyXG4gKiBgb25LZXlQcmVzc2AgYW5kIGBvbkNvbXBvc2l0aW9uRW5kYCwgYnV0IGJlZm9yZSBgb25JbnB1dGAuXG4gKlxuICogYGJlZm9yZUlucHV0YCBpcyBzcGVjJ2QgYnV0IG5vdCBpbXBsZW1lbnRlZCBpbiBhbnkgYnJvd3NlcnMsIGFuZFxuICogdGhlIGBpbnB1dGAgZXZlbnQgZG9lcyBub3QgcHJvdmlkZSBhbnkgdXNlZnVsIGluZm9ybWF0aW9uIGFib3V0IHdoYXQgaGFzXG4gKiBhY3R1YWxseSBiZWVuIGFkZGVkLCBjb250cmFyeSB0byB0aGUgc3BlYy4gVGh1cywgYHRleHRJbnB1dGAgaXMgdGhlIGJlc3RcbiAqIGF2YWlsYWJsZSBldmVudCB0byBpZGVudGlmeSB0aGUgY2hhcmFjdGVycyB0aGF0IGhhdmUgYWN0dWFsbHkgYmVlbiBpbnNlcnRlZFxuICogaW50byB0aGUgdGFyZ2V0IG5vZGUuXG4gKlxuICogVGhpcyBwbHVnaW4gaXMgYWxzbyByZXNwb25zaWJsZSBmb3IgZW1pdHRpbmcgYGNvbXBvc2l0aW9uYCBldmVudHMsIHRodXNcbiAqIGFsbG93aW5nIHVzIHRvIHNoYXJlIGNvbXBvc2l0aW9uIGZhbGxiYWNrIGNvZGUgZm9yIGJvdGggYGJlZm9yZUlucHV0YCBhbmRcbiAqIGBjb21wb3NpdGlvbmAgZXZlbnQgdHlwZXMuXG4gKi9cbnZhciBCZWZvcmVJbnB1dEV2ZW50UGx1Z2luID0ge1xuXG4gIGV2ZW50VHlwZXM6IGV2ZW50VHlwZXMsXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGUgUmVjb3JkIGZyb20gYEV2ZW50Q29uc3RhbnRzYC5cbiAgICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUYXJnZXRJRCBJRCBvZiBgdG9wTGV2ZWxUYXJnZXRgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4geyp9IEFuIGFjY3VtdWxhdGlvbiBvZiBzeW50aGV0aWMgZXZlbnRzLlxuICAgKiBAc2VlIHtFdmVudFBsdWdpbkh1Yi5leHRyYWN0RXZlbnRzfVxuICAgKi9cbiAgZXh0cmFjdEV2ZW50czogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIHJldHVybiBbZXh0cmFjdENvbXBvc2l0aW9uRXZlbnQodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSwgZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KV07XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQmVmb3JlSW5wdXRFdmVudFBsdWdpbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgQ1NTUHJvcGVydHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQ1NTIHByb3BlcnRpZXMgd2hpY2ggYWNjZXB0IG51bWJlcnMgYnV0IGFyZSBub3QgaW4gdW5pdHMgb2YgXCJweFwiLlxuICovXG52YXIgaXNVbml0bGVzc051bWJlciA9IHtcbiAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXG4gIGJveEZsZXg6IHRydWUsXG4gIGJveEZsZXhHcm91cDogdHJ1ZSxcbiAgYm94T3JkaW5hbEdyb3VwOiB0cnVlLFxuICBjb2x1bW5Db3VudDogdHJ1ZSxcbiAgZmxleDogdHJ1ZSxcbiAgZmxleEdyb3c6IHRydWUsXG4gIGZsZXhQb3NpdGl2ZTogdHJ1ZSxcbiAgZmxleFNocmluazogdHJ1ZSxcbiAgZmxleE5lZ2F0aXZlOiB0cnVlLFxuICBmbGV4T3JkZXI6IHRydWUsXG4gIGZvbnRXZWlnaHQ6IHRydWUsXG4gIGxpbmVDbGFtcDogdHJ1ZSxcbiAgbGluZUhlaWdodDogdHJ1ZSxcbiAgb3BhY2l0eTogdHJ1ZSxcbiAgb3JkZXI6IHRydWUsXG4gIG9ycGhhbnM6IHRydWUsXG4gIHRhYlNpemU6IHRydWUsXG4gIHdpZG93czogdHJ1ZSxcbiAgekluZGV4OiB0cnVlLFxuICB6b29tOiB0cnVlLFxuXG4gIC8vIFNWRy1yZWxhdGVkIHByb3BlcnRpZXNcbiAgZmlsbE9wYWNpdHk6IHRydWUsXG4gIHN0b3BPcGFjaXR5OiB0cnVlLFxuICBzdHJva2VEYXNob2Zmc2V0OiB0cnVlLFxuICBzdHJva2VPcGFjaXR5OiB0cnVlLFxuICBzdHJva2VXaWR0aDogdHJ1ZVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJlZml4IHZlbmRvci1zcGVjaWZpYyBwcmVmaXgsIGVnOiBXZWJraXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgc3R5bGUgbmFtZSwgZWc6IHRyYW5zaXRpb25EdXJhdGlvblxuICogQHJldHVybiB7c3RyaW5nfSBzdHlsZSBuYW1lIHByZWZpeGVkIHdpdGggYHByZWZpeGAsIHByb3Blcmx5IGNhbWVsQ2FzZWQsIGVnOlxuICogV2Via2l0VHJhbnNpdGlvbkR1cmF0aW9uXG4gKi9cbmZ1bmN0aW9uIHByZWZpeEtleShwcmVmaXgsIGtleSkge1xuICByZXR1cm4gcHJlZml4ICsga2V5LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsga2V5LnN1YnN0cmluZygxKTtcbn1cblxuLyoqXG4gKiBTdXBwb3J0IHN0eWxlIG5hbWVzIHRoYXQgbWF5IGNvbWUgcGFzc2VkIGluIHByZWZpeGVkIGJ5IGFkZGluZyBwZXJtdXRhdGlvbnNcbiAqIG9mIHZlbmRvciBwcmVmaXhlcy5cbiAqL1xudmFyIHByZWZpeGVzID0gWydXZWJraXQnLCAnbXMnLCAnTW96JywgJ08nXTtcblxuLy8gVXNpbmcgT2JqZWN0LmtleXMgaGVyZSwgb3IgZWxzZSB0aGUgdmFuaWxsYSBmb3ItaW4gbG9vcCBtYWtlcyBJRTggZ28gaW50byBhblxuLy8gaW5maW5pdGUgbG9vcCwgYmVjYXVzZSBpdCBpdGVyYXRlcyBvdmVyIHRoZSBuZXdseSBhZGRlZCBwcm9wcyB0b28uXG5PYmplY3Qua2V5cyhpc1VuaXRsZXNzTnVtYmVyKS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7XG4gIHByZWZpeGVzLmZvckVhY2goZnVuY3Rpb24gKHByZWZpeCkge1xuICAgIGlzVW5pdGxlc3NOdW1iZXJbcHJlZml4S2V5KHByZWZpeCwgcHJvcCldID0gaXNVbml0bGVzc051bWJlcltwcm9wXTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBNb3N0IHN0eWxlIHByb3BlcnRpZXMgY2FuIGJlIHVuc2V0IGJ5IGRvaW5nIC5zdHlsZVtwcm9wXSA9ICcnIGJ1dCBJRThcbiAqIGRvZXNuJ3QgbGlrZSBkb2luZyB0aGF0IHdpdGggc2hvcnRoYW5kIHByb3BlcnRpZXMgc28gZm9yIHRoZSBwcm9wZXJ0aWVzIHRoYXRcbiAqIElFOCBicmVha3Mgb24sIHdoaWNoIGFyZSBsaXN0ZWQgaGVyZSwgd2UgaW5zdGVhZCB1bnNldCBlYWNoIG9mIHRoZVxuICogaW5kaXZpZHVhbCBwcm9wZXJ0aWVzLiBTZWUgaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIzODUuXG4gKiBUaGUgNC12YWx1ZSAnY2xvY2snIHByb3BlcnRpZXMgbGlrZSBtYXJnaW4sIHBhZGRpbmcsIGJvcmRlci13aWR0aCBzZWVtIHRvXG4gKiBiZWhhdmUgd2l0aG91dCBhbnkgcHJvYmxlbXMuIEN1cmlvdXNseSwgbGlzdC1zdHlsZSB3b3JrcyB0b28gd2l0aG91dCBhbnlcbiAqIHNwZWNpYWwgcHJvZGRpbmcuXG4gKi9cbnZhciBzaG9ydGhhbmRQcm9wZXJ0eUV4cGFuc2lvbnMgPSB7XG4gIGJhY2tncm91bmQ6IHtcbiAgICBiYWNrZ3JvdW5kQXR0YWNobWVudDogdHJ1ZSxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRydWUsXG4gICAgYmFja2dyb3VuZEltYWdlOiB0cnVlLFxuICAgIGJhY2tncm91bmRQb3NpdGlvblg6IHRydWUsXG4gICAgYmFja2dyb3VuZFBvc2l0aW9uWTogdHJ1ZSxcbiAgICBiYWNrZ3JvdW5kUmVwZWF0OiB0cnVlXG4gIH0sXG4gIGJhY2tncm91bmRQb3NpdGlvbjoge1xuICAgIGJhY2tncm91bmRQb3NpdGlvblg6IHRydWUsXG4gICAgYmFja2dyb3VuZFBvc2l0aW9uWTogdHJ1ZVxuICB9LFxuICBib3JkZXI6IHtcbiAgICBib3JkZXJXaWR0aDogdHJ1ZSxcbiAgICBib3JkZXJTdHlsZTogdHJ1ZSxcbiAgICBib3JkZXJDb2xvcjogdHJ1ZVxuICB9LFxuICBib3JkZXJCb3R0b206IHtcbiAgICBib3JkZXJCb3R0b21XaWR0aDogdHJ1ZSxcbiAgICBib3JkZXJCb3R0b21TdHlsZTogdHJ1ZSxcbiAgICBib3JkZXJCb3R0b21Db2xvcjogdHJ1ZVxuICB9LFxuICBib3JkZXJMZWZ0OiB7XG4gICAgYm9yZGVyTGVmdFdpZHRoOiB0cnVlLFxuICAgIGJvcmRlckxlZnRTdHlsZTogdHJ1ZSxcbiAgICBib3JkZXJMZWZ0Q29sb3I6IHRydWVcbiAgfSxcbiAgYm9yZGVyUmlnaHQ6IHtcbiAgICBib3JkZXJSaWdodFdpZHRoOiB0cnVlLFxuICAgIGJvcmRlclJpZ2h0U3R5bGU6IHRydWUsXG4gICAgYm9yZGVyUmlnaHRDb2xvcjogdHJ1ZVxuICB9LFxuICBib3JkZXJUb3A6IHtcbiAgICBib3JkZXJUb3BXaWR0aDogdHJ1ZSxcbiAgICBib3JkZXJUb3BTdHlsZTogdHJ1ZSxcbiAgICBib3JkZXJUb3BDb2xvcjogdHJ1ZVxuICB9LFxuICBmb250OiB7XG4gICAgZm9udFN0eWxlOiB0cnVlLFxuICAgIGZvbnRWYXJpYW50OiB0cnVlLFxuICAgIGZvbnRXZWlnaHQ6IHRydWUsXG4gICAgZm9udFNpemU6IHRydWUsXG4gICAgbGluZUhlaWdodDogdHJ1ZSxcbiAgICBmb250RmFtaWx5OiB0cnVlXG4gIH0sXG4gIG91dGxpbmU6IHtcbiAgICBvdXRsaW5lV2lkdGg6IHRydWUsXG4gICAgb3V0bGluZVN0eWxlOiB0cnVlLFxuICAgIG91dGxpbmVDb2xvcjogdHJ1ZVxuICB9XG59O1xuXG52YXIgQ1NTUHJvcGVydHkgPSB7XG4gIGlzVW5pdGxlc3NOdW1iZXI6IGlzVW5pdGxlc3NOdW1iZXIsXG4gIHNob3J0aGFuZFByb3BlcnR5RXhwYW5zaW9uczogc2hvcnRoYW5kUHJvcGVydHlFeHBhbnNpb25zXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENTU1Byb3BlcnR5OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBDU1NQcm9wZXJ0eU9wZXJhdGlvbnNcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ1NTUHJvcGVydHkgPSByZXF1aXJlKCcuL0NTU1Byb3BlcnR5Jyk7XG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xudmFyIFJlYWN0UGVyZiA9IHJlcXVpcmUoJy4vUmVhY3RQZXJmJyk7XG5cbnZhciBjYW1lbGl6ZVN0eWxlTmFtZSA9IHJlcXVpcmUoJ2ZianMvbGliL2NhbWVsaXplU3R5bGVOYW1lJyk7XG52YXIgZGFuZ2Vyb3VzU3R5bGVWYWx1ZSA9IHJlcXVpcmUoJy4vZGFuZ2Vyb3VzU3R5bGVWYWx1ZScpO1xudmFyIGh5cGhlbmF0ZVN0eWxlTmFtZSA9IHJlcXVpcmUoJ2ZianMvbGliL2h5cGhlbmF0ZVN0eWxlTmFtZScpO1xudmFyIG1lbW9pemVTdHJpbmdPbmx5ID0gcmVxdWlyZSgnZmJqcy9saWIvbWVtb2l6ZVN0cmluZ09ubHknKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG52YXIgcHJvY2Vzc1N0eWxlTmFtZSA9IG1lbW9pemVTdHJpbmdPbmx5KGZ1bmN0aW9uIChzdHlsZU5hbWUpIHtcbiAgcmV0dXJuIGh5cGhlbmF0ZVN0eWxlTmFtZShzdHlsZU5hbWUpO1xufSk7XG5cbnZhciBoYXNTaG9ydGhhbmRQcm9wZXJ0eUJ1ZyA9IGZhbHNlO1xudmFyIHN0eWxlRmxvYXRBY2Nlc3NvciA9ICdjc3NGbG9hdCc7XG5pZiAoRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NKSB7XG4gIHZhciB0ZW1wU3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZTtcbiAgdHJ5IHtcbiAgICAvLyBJRTggdGhyb3dzIFwiSW52YWxpZCBhcmd1bWVudC5cIiBpZiByZXNldHRpbmcgc2hvcnRoYW5kIHN0eWxlIHByb3BlcnRpZXMuXG4gICAgdGVtcFN0eWxlLmZvbnQgPSAnJztcbiAgfSBjYXRjaCAoZSkge1xuICAgIGhhc1Nob3J0aGFuZFByb3BlcnR5QnVnID0gdHJ1ZTtcbiAgfVxuICAvLyBJRTggb25seSBzdXBwb3J0cyBhY2Nlc3NpbmcgY3NzRmxvYXQgKHN0YW5kYXJkKSBhcyBzdHlsZUZsb2F0XG4gIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3NzRmxvYXQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0eWxlRmxvYXRBY2Nlc3NvciA9ICdzdHlsZUZsb2F0JztcbiAgfVxufVxuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAvLyAnbXNUcmFuc2Zvcm0nIGlzIGNvcnJlY3QsIGJ1dCB0aGUgb3RoZXIgcHJlZml4ZXMgc2hvdWxkIGJlIGNhcGl0YWxpemVkXG4gIHZhciBiYWRWZW5kb3JlZFN0eWxlTmFtZVBhdHRlcm4gPSAvXig/OndlYmtpdHxtb3p8bylbQS1aXS87XG5cbiAgLy8gc3R5bGUgdmFsdWVzIHNob3VsZG4ndCBjb250YWluIGEgc2VtaWNvbG9uXG4gIHZhciBiYWRTdHlsZVZhbHVlV2l0aFNlbWljb2xvblBhdHRlcm4gPSAvO1xccyokLztcblxuICB2YXIgd2FybmVkU3R5bGVOYW1lcyA9IHt9O1xuICB2YXIgd2FybmVkU3R5bGVWYWx1ZXMgPSB7fTtcblxuICB2YXIgd2Fybkh5cGhlbmF0ZWRTdHlsZU5hbWUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmICh3YXJuZWRTdHlsZU5hbWVzLmhhc093blByb3BlcnR5KG5hbWUpICYmIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRTdHlsZU5hbWVzW25hbWVdID0gdHJ1ZTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ1Vuc3VwcG9ydGVkIHN0eWxlIHByb3BlcnR5ICVzLiBEaWQgeW91IG1lYW4gJXM/JywgbmFtZSwgY2FtZWxpemVTdHlsZU5hbWUobmFtZSkpIDogdW5kZWZpbmVkO1xuICB9O1xuXG4gIHZhciB3YXJuQmFkVmVuZG9yZWRTdHlsZU5hbWUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmICh3YXJuZWRTdHlsZU5hbWVzLmhhc093blByb3BlcnR5KG5hbWUpICYmIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRTdHlsZU5hbWVzW25hbWVdID0gdHJ1ZTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ1Vuc3VwcG9ydGVkIHZlbmRvci1wcmVmaXhlZCBzdHlsZSBwcm9wZXJ0eSAlcy4gRGlkIHlvdSBtZWFuICVzPycsIG5hbWUsIG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpKSA6IHVuZGVmaW5lZDtcbiAgfTtcblxuICB2YXIgd2FyblN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKHdhcm5lZFN0eWxlVmFsdWVzLmhhc093blByb3BlcnR5KHZhbHVlKSAmJiB3YXJuZWRTdHlsZVZhbHVlc1t2YWx1ZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3YXJuZWRTdHlsZVZhbHVlc1t2YWx1ZV0gPSB0cnVlO1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnU3R5bGUgcHJvcGVydHkgdmFsdWVzIHNob3VsZG5cXCd0IGNvbnRhaW4gYSBzZW1pY29sb24uICcgKyAnVHJ5IFwiJXM6ICVzXCIgaW5zdGVhZC4nLCBuYW1lLCB2YWx1ZS5yZXBsYWNlKGJhZFN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uUGF0dGVybiwgJycpKSA6IHVuZGVmaW5lZDtcbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgKi9cbiAgdmFyIHdhcm5WYWxpZFN0eWxlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKG5hbWUuaW5kZXhPZignLScpID4gLTEpIHtcbiAgICAgIHdhcm5IeXBoZW5hdGVkU3R5bGVOYW1lKG5hbWUpO1xuICAgIH0gZWxzZSBpZiAoYmFkVmVuZG9yZWRTdHlsZU5hbWVQYXR0ZXJuLnRlc3QobmFtZSkpIHtcbiAgICAgIHdhcm5CYWRWZW5kb3JlZFN0eWxlTmFtZShuYW1lKTtcbiAgICB9IGVsc2UgaWYgKGJhZFN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uUGF0dGVybi50ZXN0KHZhbHVlKSkge1xuICAgICAgd2FyblN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uKG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogT3BlcmF0aW9ucyBmb3IgZGVhbGluZyB3aXRoIENTUyBwcm9wZXJ0aWVzLlxuICovXG52YXIgQ1NTUHJvcGVydHlPcGVyYXRpb25zID0ge1xuXG4gIC8qKlxuICAgKiBTZXJpYWxpemVzIGEgbWFwcGluZyBvZiBzdHlsZSBwcm9wZXJ0aWVzIGZvciB1c2UgYXMgaW5saW5lIHN0eWxlczpcbiAgICpcbiAgICogICA+IGNyZWF0ZU1hcmt1cEZvclN0eWxlcyh7d2lkdGg6ICcyMDBweCcsIGhlaWdodDogMH0pXG4gICAqICAgXCJ3aWR0aDoyMDBweDtoZWlnaHQ6MDtcIlxuICAgKlxuICAgKiBVbmRlZmluZWQgdmFsdWVzIGFyZSBpZ25vcmVkIHNvIHRoYXQgZGVjbGFyYXRpdmUgcHJvZ3JhbW1pbmcgaXMgZWFzaWVyLlxuICAgKiBUaGUgcmVzdWx0IHNob3VsZCBiZSBIVE1MLWVzY2FwZWQgYmVmb3JlIGluc2VydGlvbiBpbnRvIHRoZSBET00uXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBzdHlsZXNcbiAgICogQHJldHVybiB7P3N0cmluZ31cbiAgICovXG4gIGNyZWF0ZU1hcmt1cEZvclN0eWxlczogZnVuY3Rpb24gKHN0eWxlcykge1xuICAgIHZhciBzZXJpYWxpemVkID0gJyc7XG4gICAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgICAgaWYgKCFzdHlsZXMuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBzdHlsZVZhbHVlID0gc3R5bGVzW3N0eWxlTmFtZV07XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICB3YXJuVmFsaWRTdHlsZShzdHlsZU5hbWUsIHN0eWxlVmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHN0eWxlVmFsdWUgIT0gbnVsbCkge1xuICAgICAgICBzZXJpYWxpemVkICs9IHByb2Nlc3NTdHlsZU5hbWUoc3R5bGVOYW1lKSArICc6JztcbiAgICAgICAgc2VyaWFsaXplZCArPSBkYW5nZXJvdXNTdHlsZVZhbHVlKHN0eWxlTmFtZSwgc3R5bGVWYWx1ZSkgKyAnOyc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzZXJpYWxpemVkIHx8IG51bGw7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHZhbHVlIGZvciBtdWx0aXBsZSBzdHlsZXMgb24gYSBub2RlLiAgSWYgYSB2YWx1ZSBpcyBzcGVjaWZpZWQgYXNcbiAgICogJycgKGVtcHR5IHN0cmluZyksIHRoZSBjb3JyZXNwb25kaW5nIHN0eWxlIHByb3BlcnR5IHdpbGwgYmUgdW5zZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICAgKiBAcGFyYW0ge29iamVjdH0gc3R5bGVzXG4gICAqL1xuICBzZXRWYWx1ZUZvclN0eWxlczogZnVuY3Rpb24gKG5vZGUsIHN0eWxlcykge1xuICAgIHZhciBzdHlsZSA9IG5vZGUuc3R5bGU7XG4gICAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgICAgaWYgKCFzdHlsZXMuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHdhcm5WYWxpZFN0eWxlKHN0eWxlTmFtZSwgc3R5bGVzW3N0eWxlTmFtZV0pO1xuICAgICAgfVxuICAgICAgdmFyIHN0eWxlVmFsdWUgPSBkYW5nZXJvdXNTdHlsZVZhbHVlKHN0eWxlTmFtZSwgc3R5bGVzW3N0eWxlTmFtZV0pO1xuICAgICAgaWYgKHN0eWxlTmFtZSA9PT0gJ2Zsb2F0Jykge1xuICAgICAgICBzdHlsZU5hbWUgPSBzdHlsZUZsb2F0QWNjZXNzb3I7XG4gICAgICB9XG4gICAgICBpZiAoc3R5bGVWYWx1ZSkge1xuICAgICAgICBzdHlsZVtzdHlsZU5hbWVdID0gc3R5bGVWYWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBleHBhbnNpb24gPSBoYXNTaG9ydGhhbmRQcm9wZXJ0eUJ1ZyAmJiBDU1NQcm9wZXJ0eS5zaG9ydGhhbmRQcm9wZXJ0eUV4cGFuc2lvbnNbc3R5bGVOYW1lXTtcbiAgICAgICAgaWYgKGV4cGFuc2lvbikge1xuICAgICAgICAgIC8vIFNob3J0aGFuZCBwcm9wZXJ0eSB0aGF0IElFOCB3b24ndCBsaWtlIHVuc2V0dGluZywgc28gdW5zZXQgZWFjaFxuICAgICAgICAgIC8vIGNvbXBvbmVudCB0byBwbGFjYXRlIGl0XG4gICAgICAgICAgZm9yICh2YXIgaW5kaXZpZHVhbFN0eWxlTmFtZSBpbiBleHBhbnNpb24pIHtcbiAgICAgICAgICAgIHN0eWxlW2luZGl2aWR1YWxTdHlsZU5hbWVdID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0eWxlW3N0eWxlTmFtZV0gPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG59O1xuXG5SZWFjdFBlcmYubWVhc3VyZU1ldGhvZHMoQ1NTUHJvcGVydHlPcGVyYXRpb25zLCAnQ1NTUHJvcGVydHlPcGVyYXRpb25zJywge1xuICBzZXRWYWx1ZUZvclN0eWxlczogJ3NldFZhbHVlRm9yU3R5bGVzJ1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ1NTUHJvcGVydHlPcGVyYXRpb25zOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBDYWxsYmFja1F1ZXVlXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9vbGVkQ2xhc3MgPSByZXF1aXJlKCcuL1Bvb2xlZENsYXNzJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHBzZXVkby1ldmVudCBtb2R1bGUgdG8gaGVscCBrZWVwIHRyYWNrIG9mIGNvbXBvbmVudHMgd2FpdGluZyB0b1xuICogYmUgbm90aWZpZWQgd2hlbiB0aGVpciBET00gcmVwcmVzZW50YXRpb25zIGFyZSBhdmFpbGFibGUgZm9yIHVzZS5cbiAqXG4gKiBUaGlzIGltcGxlbWVudHMgYFBvb2xlZENsYXNzYCwgc28geW91IHNob3VsZCBuZXZlciBuZWVkIHRvIGluc3RhbnRpYXRlIHRoaXMuXG4gKiBJbnN0ZWFkLCB1c2UgYENhbGxiYWNrUXVldWUuZ2V0UG9vbGVkKClgLlxuICpcbiAqIEBjbGFzcyBSZWFjdE1vdW50UmVhZHlcbiAqIEBpbXBsZW1lbnRzIFBvb2xlZENsYXNzXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gQ2FsbGJhY2tRdWV1ZSgpIHtcbiAgdGhpcy5fY2FsbGJhY2tzID0gbnVsbDtcbiAgdGhpcy5fY29udGV4dHMgPSBudWxsO1xufVxuXG5hc3NpZ24oQ2FsbGJhY2tRdWV1ZS5wcm90b3R5cGUsIHtcblxuICAvKipcbiAgICogRW5xdWV1ZXMgYSBjYWxsYmFjayB0byBiZSBpbnZva2VkIHdoZW4gYG5vdGlmeUFsbGAgaXMgaW52b2tlZC5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgSW52b2tlZCB3aGVuIGBub3RpZnlBbGxgIGlzIGludm9rZWQuXG4gICAqIEBwYXJhbSB7P29iamVjdH0gY29udGV4dCBDb250ZXh0IHRvIGNhbGwgYGNhbGxiYWNrYCB3aXRoLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWU6IGZ1bmN0aW9uIChjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCBbXTtcbiAgICB0aGlzLl9jb250ZXh0cyA9IHRoaXMuX2NvbnRleHRzIHx8IFtdO1xuICAgIHRoaXMuX2NhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbiAgICB0aGlzLl9jb250ZXh0cy5wdXNoKGNvbnRleHQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBJbnZva2VzIGFsbCBlbnF1ZXVlZCBjYWxsYmFja3MgYW5kIGNsZWFycyB0aGUgcXVldWUuIFRoaXMgaXMgaW52b2tlZCBhZnRlclxuICAgKiB0aGUgRE9NIHJlcHJlc2VudGF0aW9uIG9mIGEgY29tcG9uZW50IGhhcyBiZWVuIGNyZWF0ZWQgb3IgdXBkYXRlZC5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBub3RpZnlBbGw6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzO1xuICAgIHZhciBjb250ZXh0cyA9IHRoaXMuX2NvbnRleHRzO1xuICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICEoY2FsbGJhY2tzLmxlbmd0aCA9PT0gY29udGV4dHMubGVuZ3RoKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdNaXNtYXRjaGVkIGxpc3Qgb2YgY29udGV4dHMgaW4gY2FsbGJhY2sgcXVldWUnKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9jYWxsYmFja3MgPSBudWxsO1xuICAgICAgdGhpcy5fY29udGV4dHMgPSBudWxsO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY2FsbGJhY2tzW2ldLmNhbGwoY29udGV4dHNbaV0pO1xuICAgICAgfVxuICAgICAgY2FsbGJhY2tzLmxlbmd0aCA9IDA7XG4gICAgICBjb250ZXh0cy5sZW5ndGggPSAwO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBpbnRlcm5hbCBxdWV1ZS5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IG51bGw7XG4gICAgdGhpcy5fY29udGV4dHMgPSBudWxsO1xuICB9LFxuXG4gIC8qKlxuICAgKiBgUG9vbGVkQ2xhc3NgIGxvb2tzIGZvciB0aGlzLlxuICAgKi9cbiAgZGVzdHJ1Y3RvcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG59KTtcblxuUG9vbGVkQ2xhc3MuYWRkUG9vbGluZ1RvKENhbGxiYWNrUXVldWUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENhbGxiYWNrUXVldWU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIENoYW5nZUV2ZW50UGx1Z2luXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgRXZlbnRQbHVnaW5IdWIgPSByZXF1aXJlKCcuL0V2ZW50UGx1Z2luSHViJyk7XG52YXIgRXZlbnRQcm9wYWdhdG9ycyA9IHJlcXVpcmUoJy4vRXZlbnRQcm9wYWdhdG9ycycpO1xudmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnZmJqcy9saWIvRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcbnZhciBSZWFjdFVwZGF0ZXMgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlcycpO1xudmFyIFN5bnRoZXRpY0V2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNFdmVudCcpO1xuXG52YXIgZ2V0RXZlbnRUYXJnZXQgPSByZXF1aXJlKCcuL2dldEV2ZW50VGFyZ2V0Jyk7XG52YXIgaXNFdmVudFN1cHBvcnRlZCA9IHJlcXVpcmUoJy4vaXNFdmVudFN1cHBvcnRlZCcpO1xudmFyIGlzVGV4dElucHV0RWxlbWVudCA9IHJlcXVpcmUoJy4vaXNUZXh0SW5wdXRFbGVtZW50Jyk7XG52YXIga2V5T2YgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlPZicpO1xuXG52YXIgdG9wTGV2ZWxUeXBlcyA9IEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXM7XG5cbnZhciBldmVudFR5cGVzID0ge1xuICBjaGFuZ2U6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkNoYW5nZTogbnVsbCB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uQ2hhbmdlQ2FwdHVyZTogbnVsbCB9KVxuICAgIH0sXG4gICAgZGVwZW5kZW5jaWVzOiBbdG9wTGV2ZWxUeXBlcy50b3BCbHVyLCB0b3BMZXZlbFR5cGVzLnRvcENoYW5nZSwgdG9wTGV2ZWxUeXBlcy50b3BDbGljaywgdG9wTGV2ZWxUeXBlcy50b3BGb2N1cywgdG9wTGV2ZWxUeXBlcy50b3BJbnB1dCwgdG9wTGV2ZWxUeXBlcy50b3BLZXlEb3duLCB0b3BMZXZlbFR5cGVzLnRvcEtleVVwLCB0b3BMZXZlbFR5cGVzLnRvcFNlbGVjdGlvbkNoYW5nZV1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgSUUgc2hpbXNcbiAqL1xudmFyIGFjdGl2ZUVsZW1lbnQgPSBudWxsO1xudmFyIGFjdGl2ZUVsZW1lbnRJRCA9IG51bGw7XG52YXIgYWN0aXZlRWxlbWVudFZhbHVlID0gbnVsbDtcbnZhciBhY3RpdmVFbGVtZW50VmFsdWVQcm9wID0gbnVsbDtcblxuLyoqXG4gKiBTRUNUSU9OOiBoYW5kbGUgYGNoYW5nZWAgZXZlbnRcbiAqL1xuZnVuY3Rpb24gc2hvdWxkVXNlQ2hhbmdlRXZlbnQoZWxlbSkge1xuICB2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIG5vZGVOYW1lID09PSAnc2VsZWN0JyB8fCBub2RlTmFtZSA9PT0gJ2lucHV0JyAmJiBlbGVtLnR5cGUgPT09ICdmaWxlJztcbn1cblxudmFyIGRvZXNDaGFuZ2VFdmVudEJ1YmJsZSA9IGZhbHNlO1xuaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICAvLyBTZWUgYGhhbmRsZUNoYW5nZWAgY29tbWVudCBiZWxvd1xuICBkb2VzQ2hhbmdlRXZlbnRCdWJibGUgPSBpc0V2ZW50U3VwcG9ydGVkKCdjaGFuZ2UnKSAmJiAoISgnZG9jdW1lbnRNb2RlJyBpbiBkb2N1bWVudCkgfHwgZG9jdW1lbnQuZG9jdW1lbnRNb2RlID4gOCk7XG59XG5cbmZ1bmN0aW9uIG1hbnVhbERpc3BhdGNoQ2hhbmdlRXZlbnQobmF0aXZlRXZlbnQpIHtcbiAgdmFyIGV2ZW50ID0gU3ludGhldGljRXZlbnQuZ2V0UG9vbGVkKGV2ZW50VHlwZXMuY2hhbmdlLCBhY3RpdmVFbGVtZW50SUQsIG5hdGl2ZUV2ZW50LCBnZXRFdmVudFRhcmdldChuYXRpdmVFdmVudCkpO1xuICBFdmVudFByb3BhZ2F0b3JzLmFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXMoZXZlbnQpO1xuXG4gIC8vIElmIGNoYW5nZSBhbmQgcHJvcGVydHljaGFuZ2UgYnViYmxlZCwgd2UnZCBqdXN0IGJpbmQgdG8gaXQgbGlrZSBhbGwgdGhlXG4gIC8vIG90aGVyIGV2ZW50cyBhbmQgaGF2ZSBpdCBnbyB0aHJvdWdoIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci4gU2luY2UgaXRcbiAgLy8gZG9lc24ndCwgd2UgbWFudWFsbHkgbGlzdGVuIGZvciB0aGUgZXZlbnRzIGFuZCBzbyB3ZSBoYXZlIHRvIGVucXVldWUgYW5kXG4gIC8vIHByb2Nlc3MgdGhlIGFic3RyYWN0IGV2ZW50IG1hbnVhbGx5LlxuICAvL1xuICAvLyBCYXRjaGluZyBpcyBuZWNlc3NhcnkgaGVyZSBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCBhbGwgZXZlbnQgaGFuZGxlcnMgcnVuXG4gIC8vIGJlZm9yZSB0aGUgbmV4dCByZXJlbmRlciAoaW5jbHVkaW5nIGV2ZW50IGhhbmRsZXJzIGF0dGFjaGVkIHRvIGFuY2VzdG9yXG4gIC8vIGVsZW1lbnRzIGluc3RlYWQgb2YgZGlyZWN0bHkgb24gdGhlIGlucHV0KS4gV2l0aG91dCB0aGlzLCBjb250cm9sbGVkXG4gIC8vIGNvbXBvbmVudHMgZG9uJ3Qgd29yayBwcm9wZXJseSBpbiBjb25qdW5jdGlvbiB3aXRoIGV2ZW50IGJ1YmJsaW5nIGJlY2F1c2VcbiAgLy8gdGhlIGNvbXBvbmVudCBpcyByZXJlbmRlcmVkIGFuZCB0aGUgdmFsdWUgcmV2ZXJ0ZWQgYmVmb3JlIGFsbCB0aGUgZXZlbnRcbiAgLy8gaGFuZGxlcnMgY2FuIHJ1bi4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvNzA4LlxuICBSZWFjdFVwZGF0ZXMuYmF0Y2hlZFVwZGF0ZXMocnVuRXZlbnRJbkJhdGNoLCBldmVudCk7XG59XG5cbmZ1bmN0aW9uIHJ1bkV2ZW50SW5CYXRjaChldmVudCkge1xuICBFdmVudFBsdWdpbkh1Yi5lbnF1ZXVlRXZlbnRzKGV2ZW50KTtcbiAgRXZlbnRQbHVnaW5IdWIucHJvY2Vzc0V2ZW50UXVldWUoZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBzdGFydFdhdGNoaW5nRm9yQ2hhbmdlRXZlbnRJRTgodGFyZ2V0LCB0YXJnZXRJRCkge1xuICBhY3RpdmVFbGVtZW50ID0gdGFyZ2V0O1xuICBhY3RpdmVFbGVtZW50SUQgPSB0YXJnZXRJRDtcbiAgYWN0aXZlRWxlbWVudC5hdHRhY2hFdmVudCgnb25jaGFuZ2UnLCBtYW51YWxEaXNwYXRjaENoYW5nZUV2ZW50KTtcbn1cblxuZnVuY3Rpb24gc3RvcFdhdGNoaW5nRm9yQ2hhbmdlRXZlbnRJRTgoKSB7XG4gIGlmICghYWN0aXZlRWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuICBhY3RpdmVFbGVtZW50LmRldGFjaEV2ZW50KCdvbmNoYW5nZScsIG1hbnVhbERpc3BhdGNoQ2hhbmdlRXZlbnQpO1xuICBhY3RpdmVFbGVtZW50ID0gbnVsbDtcbiAgYWN0aXZlRWxlbWVudElEID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SURGb3JDaGFuZ2VFdmVudCh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElEKSB7XG4gIGlmICh0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wQ2hhbmdlKSB7XG4gICAgcmV0dXJuIHRvcExldmVsVGFyZ2V0SUQ7XG4gIH1cbn1cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50c0ZvckNoYW5nZUV2ZW50SUU4KHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQpIHtcbiAgaWYgKHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BGb2N1cykge1xuICAgIC8vIHN0b3BXYXRjaGluZygpIHNob3VsZCBiZSBhIG5vb3AgaGVyZSBidXQgd2UgY2FsbCBpdCBqdXN0IGluIGNhc2Ugd2VcbiAgICAvLyBtaXNzZWQgYSBibHVyIGV2ZW50IHNvbWVob3cuXG4gICAgc3RvcFdhdGNoaW5nRm9yQ2hhbmdlRXZlbnRJRTgoKTtcbiAgICBzdGFydFdhdGNoaW5nRm9yQ2hhbmdlRXZlbnRJRTgodG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQpO1xuICB9IGVsc2UgaWYgKHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BCbHVyKSB7XG4gICAgc3RvcFdhdGNoaW5nRm9yQ2hhbmdlRXZlbnRJRTgoKTtcbiAgfVxufVxuXG4vKipcbiAqIFNFQ1RJT046IGhhbmRsZSBgaW5wdXRgIGV2ZW50XG4gKi9cbnZhciBpc0lucHV0RXZlbnRTdXBwb3J0ZWQgPSBmYWxzZTtcbmlmIChFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00pIHtcbiAgLy8gSUU5IGNsYWltcyB0byBzdXBwb3J0IHRoZSBpbnB1dCBldmVudCBidXQgZmFpbHMgdG8gdHJpZ2dlciBpdCB3aGVuXG4gIC8vIGRlbGV0aW5nIHRleHQsIHNvIHdlIGlnbm9yZSBpdHMgaW5wdXQgZXZlbnRzXG4gIGlzSW5wdXRFdmVudFN1cHBvcnRlZCA9IGlzRXZlbnRTdXBwb3J0ZWQoJ2lucHV0JykgJiYgKCEoJ2RvY3VtZW50TW9kZScgaW4gZG9jdW1lbnQpIHx8IGRvY3VtZW50LmRvY3VtZW50TW9kZSA+IDkpO1xufVxuXG4vKipcbiAqIChGb3Igb2xkIElFLikgUmVwbGFjZW1lbnQgZ2V0dGVyL3NldHRlciBmb3IgdGhlIGB2YWx1ZWAgcHJvcGVydHkgdGhhdCBnZXRzXG4gKiBzZXQgb24gdGhlIGFjdGl2ZSBlbGVtZW50LlxuICovXG52YXIgbmV3VmFsdWVQcm9wID0ge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWN0aXZlRWxlbWVudFZhbHVlUHJvcC5nZXQuY2FsbCh0aGlzKTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgLy8gQ2FzdCB0byBhIHN0cmluZyBzbyB3ZSBjYW4gZG8gZXF1YWxpdHkgY2hlY2tzLlxuICAgIGFjdGl2ZUVsZW1lbnRWYWx1ZSA9ICcnICsgdmFsO1xuICAgIGFjdGl2ZUVsZW1lbnRWYWx1ZVByb3Auc2V0LmNhbGwodGhpcywgdmFsKTtcbiAgfVxufTtcblxuLyoqXG4gKiAoRm9yIG9sZCBJRS4pIFN0YXJ0cyB0cmFja2luZyBwcm9wZXJ0eWNoYW5nZSBldmVudHMgb24gdGhlIHBhc3NlZC1pbiBlbGVtZW50XG4gKiBhbmQgb3ZlcnJpZGUgdGhlIHZhbHVlIHByb3BlcnR5IHNvIHRoYXQgd2UgY2FuIGRpc3Rpbmd1aXNoIHVzZXIgZXZlbnRzIGZyb21cbiAqIHZhbHVlIGNoYW5nZXMgaW4gSlMuXG4gKi9cbmZ1bmN0aW9uIHN0YXJ0V2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSh0YXJnZXQsIHRhcmdldElEKSB7XG4gIGFjdGl2ZUVsZW1lbnQgPSB0YXJnZXQ7XG4gIGFjdGl2ZUVsZW1lbnRJRCA9IHRhcmdldElEO1xuICBhY3RpdmVFbGVtZW50VmFsdWUgPSB0YXJnZXQudmFsdWU7XG4gIGFjdGl2ZUVsZW1lbnRWYWx1ZVByb3AgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldC5jb25zdHJ1Y3Rvci5wcm90b3R5cGUsICd2YWx1ZScpO1xuXG4gIC8vIE5vdCBndWFyZGVkIGluIGEgY2FuRGVmaW5lUHJvcGVydHkgY2hlY2s6IElFOCBzdXBwb3J0cyBkZWZpbmVQcm9wZXJ0eSBvbmx5XG4gIC8vIG9uIERPTSBlbGVtZW50c1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYWN0aXZlRWxlbWVudCwgJ3ZhbHVlJywgbmV3VmFsdWVQcm9wKTtcbiAgYWN0aXZlRWxlbWVudC5hdHRhY2hFdmVudCgnb25wcm9wZXJ0eWNoYW5nZScsIGhhbmRsZVByb3BlcnR5Q2hhbmdlKTtcbn1cblxuLyoqXG4gKiAoRm9yIG9sZCBJRS4pIFJlbW92ZXMgdGhlIGV2ZW50IGxpc3RlbmVycyBmcm9tIHRoZSBjdXJyZW50bHktdHJhY2tlZCBlbGVtZW50LFxuICogaWYgYW55IGV4aXN0cy5cbiAqL1xuZnVuY3Rpb24gc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKSB7XG4gIGlmICghYWN0aXZlRWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGRlbGV0ZSByZXN0b3JlcyB0aGUgb3JpZ2luYWwgcHJvcGVydHkgZGVmaW5pdGlvblxuICBkZWxldGUgYWN0aXZlRWxlbWVudC52YWx1ZTtcbiAgYWN0aXZlRWxlbWVudC5kZXRhY2hFdmVudCgnb25wcm9wZXJ0eWNoYW5nZScsIGhhbmRsZVByb3BlcnR5Q2hhbmdlKTtcblxuICBhY3RpdmVFbGVtZW50ID0gbnVsbDtcbiAgYWN0aXZlRWxlbWVudElEID0gbnVsbDtcbiAgYWN0aXZlRWxlbWVudFZhbHVlID0gbnVsbDtcbiAgYWN0aXZlRWxlbWVudFZhbHVlUHJvcCA9IG51bGw7XG59XG5cbi8qKlxuICogKEZvciBvbGQgSUUuKSBIYW5kbGVzIGEgcHJvcGVydHljaGFuZ2UgZXZlbnQsIHNlbmRpbmcgYSBgY2hhbmdlYCBldmVudCBpZlxuICogdGhlIHZhbHVlIG9mIHRoZSBhY3RpdmUgZWxlbWVudCBoYXMgY2hhbmdlZC5cbiAqL1xuZnVuY3Rpb24gaGFuZGxlUHJvcGVydHlDaGFuZ2UobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LnByb3BlcnR5TmFtZSAhPT0gJ3ZhbHVlJykge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgdmFsdWUgPSBuYXRpdmVFdmVudC5zcmNFbGVtZW50LnZhbHVlO1xuICBpZiAodmFsdWUgPT09IGFjdGl2ZUVsZW1lbnRWYWx1ZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBhY3RpdmVFbGVtZW50VmFsdWUgPSB2YWx1ZTtcblxuICBtYW51YWxEaXNwYXRjaENoYW5nZUV2ZW50KG5hdGl2ZUV2ZW50KTtcbn1cblxuLyoqXG4gKiBJZiBhIGBjaGFuZ2VgIGV2ZW50IHNob3VsZCBiZSBmaXJlZCwgcmV0dXJucyB0aGUgdGFyZ2V0J3MgSUQuXG4gKi9cbmZ1bmN0aW9uIGdldFRhcmdldElERm9ySW5wdXRFdmVudCh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElEKSB7XG4gIGlmICh0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wSW5wdXQpIHtcbiAgICAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMgKGkuZS4sIG5vdCBJRTggb3IgSUU5KSwgdGhlIGlucHV0IGV2ZW50IGlzIGV4YWN0bHlcbiAgICAvLyB3aGF0IHdlIHdhbnQgc28gZmFsbCB0aHJvdWdoIGhlcmUgYW5kIHRyaWdnZXIgYW4gYWJzdHJhY3QgZXZlbnRcbiAgICByZXR1cm4gdG9wTGV2ZWxUYXJnZXRJRDtcbiAgfVxufVxuXG4vLyBGb3IgSUU4IGFuZCBJRTkuXG5mdW5jdGlvbiBoYW5kbGVFdmVudHNGb3JJbnB1dEV2ZW50SUUodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCkge1xuICBpZiAodG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcEZvY3VzKSB7XG4gICAgLy8gSW4gSUU4LCB3ZSBjYW4gY2FwdHVyZSBhbG1vc3QgYWxsIC52YWx1ZSBjaGFuZ2VzIGJ5IGFkZGluZyBhXG4gICAgLy8gcHJvcGVydHljaGFuZ2UgaGFuZGxlciBhbmQgbG9va2luZyBmb3IgZXZlbnRzIHdpdGggcHJvcGVydHlOYW1lXG4gICAgLy8gZXF1YWwgdG8gJ3ZhbHVlJ1xuICAgIC8vIEluIElFOSwgcHJvcGVydHljaGFuZ2UgZmlyZXMgZm9yIG1vc3QgaW5wdXQgZXZlbnRzIGJ1dCBpcyBidWdneSBhbmRcbiAgICAvLyBkb2Vzbid0IGZpcmUgd2hlbiB0ZXh0IGlzIGRlbGV0ZWQsIGJ1dCBjb252ZW5pZW50bHksIHNlbGVjdGlvbmNoYW5nZVxuICAgIC8vIGFwcGVhcnMgdG8gZmlyZSBpbiBhbGwgb2YgdGhlIHJlbWFpbmluZyBjYXNlcyBzbyB3ZSBjYXRjaCB0aG9zZSBhbmRcbiAgICAvLyBmb3J3YXJkIHRoZSBldmVudCBpZiB0aGUgdmFsdWUgaGFzIGNoYW5nZWRcbiAgICAvLyBJbiBlaXRoZXIgY2FzZSwgd2UgZG9uJ3Qgd2FudCB0byBjYWxsIHRoZSBldmVudCBoYW5kbGVyIGlmIHRoZSB2YWx1ZVxuICAgIC8vIGlzIGNoYW5nZWQgZnJvbSBKUyBzbyB3ZSByZWRlZmluZSBhIHNldHRlciBmb3IgYC52YWx1ZWAgdGhhdCB1cGRhdGVzXG4gICAgLy8gb3VyIGFjdGl2ZUVsZW1lbnRWYWx1ZSB2YXJpYWJsZSwgYWxsb3dpbmcgdXMgdG8gaWdub3JlIHRob3NlIGNoYW5nZXNcbiAgICAvL1xuICAgIC8vIHN0b3BXYXRjaGluZygpIHNob3VsZCBiZSBhIG5vb3AgaGVyZSBidXQgd2UgY2FsbCBpdCBqdXN0IGluIGNhc2Ugd2VcbiAgICAvLyBtaXNzZWQgYSBibHVyIGV2ZW50IHNvbWVob3cuXG4gICAgc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKTtcbiAgICBzdGFydFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UodG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQpO1xuICB9IGVsc2UgaWYgKHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BCbHVyKSB7XG4gICAgc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKTtcbiAgfVxufVxuXG4vLyBGb3IgSUU4IGFuZCBJRTkuXG5mdW5jdGlvbiBnZXRUYXJnZXRJREZvcklucHV0RXZlbnRJRSh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElEKSB7XG4gIGlmICh0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wU2VsZWN0aW9uQ2hhbmdlIHx8IHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BLZXlVcCB8fCB0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wS2V5RG93bikge1xuICAgIC8vIE9uIHRoZSBzZWxlY3Rpb25jaGFuZ2UgZXZlbnQsIHRoZSB0YXJnZXQgaXMganVzdCBkb2N1bWVudCB3aGljaCBpc24ndFxuICAgIC8vIGhlbHBmdWwgZm9yIHVzIHNvIGp1c3QgY2hlY2sgYWN0aXZlRWxlbWVudCBpbnN0ZWFkLlxuICAgIC8vXG4gICAgLy8gOTklIG9mIHRoZSB0aW1lLCBrZXlkb3duIGFuZCBrZXl1cCBhcmVuJ3QgbmVjZXNzYXJ5LiBJRTggZmFpbHMgdG8gZmlyZVxuICAgIC8vIHByb3BlcnR5Y2hhbmdlIG9uIHRoZSBmaXJzdCBpbnB1dCBldmVudCBhZnRlciBzZXR0aW5nIGB2YWx1ZWAgZnJvbSBhXG4gICAgLy8gc2NyaXB0IGFuZCBmaXJlcyBvbmx5IGtleWRvd24sIGtleXByZXNzLCBrZXl1cC4gQ2F0Y2hpbmcga2V5dXAgdXN1YWxseVxuICAgIC8vIGdldHMgaXQgYW5kIGNhdGNoaW5nIGtleWRvd24gbGV0cyB1cyBmaXJlIGFuIGV2ZW50IGZvciB0aGUgZmlyc3RcbiAgICAvLyBrZXlzdHJva2UgaWYgdXNlciBkb2VzIGEga2V5IHJlcGVhdCAoaXQnbGwgYmUgYSBsaXR0bGUgZGVsYXllZDogcmlnaHRcbiAgICAvLyBiZWZvcmUgdGhlIHNlY29uZCBrZXlzdHJva2UpLiBPdGhlciBpbnB1dCBtZXRob2RzIChlLmcuLCBwYXN0ZSkgc2VlbSB0b1xuICAgIC8vIGZpcmUgc2VsZWN0aW9uY2hhbmdlIG5vcm1hbGx5LlxuICAgIGlmIChhY3RpdmVFbGVtZW50ICYmIGFjdGl2ZUVsZW1lbnQudmFsdWUgIT09IGFjdGl2ZUVsZW1lbnRWYWx1ZSkge1xuICAgICAgYWN0aXZlRWxlbWVudFZhbHVlID0gYWN0aXZlRWxlbWVudC52YWx1ZTtcbiAgICAgIHJldHVybiBhY3RpdmVFbGVtZW50SUQ7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogU0VDVElPTjogaGFuZGxlIGBjbGlja2AgZXZlbnRcbiAqL1xuZnVuY3Rpb24gc2hvdWxkVXNlQ2xpY2tFdmVudChlbGVtKSB7XG4gIC8vIFVzZSB0aGUgYGNsaWNrYCBldmVudCB0byBkZXRlY3QgY2hhbmdlcyB0byBjaGVja2JveCBhbmQgcmFkaW8gaW5wdXRzLlxuICAvLyBUaGlzIGFwcHJvYWNoIHdvcmtzIGFjcm9zcyBhbGwgYnJvd3NlcnMsIHdoZXJlYXMgYGNoYW5nZWAgZG9lcyBub3QgZmlyZVxuICAvLyB1bnRpbCBgYmx1cmAgaW4gSUU4LlxuICByZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCcgJiYgKGVsZW0udHlwZSA9PT0gJ2NoZWNrYm94JyB8fCBlbGVtLnR5cGUgPT09ICdyYWRpbycpO1xufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJREZvckNsaWNrRXZlbnQodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCkge1xuICBpZiAodG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcENsaWNrKSB7XG4gICAgcmV0dXJuIHRvcExldmVsVGFyZ2V0SUQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIHBsdWdpbiBjcmVhdGVzIGFuIGBvbkNoYW5nZWAgZXZlbnQgdGhhdCBub3JtYWxpemVzIGNoYW5nZSBldmVudHNcbiAqIGFjcm9zcyBmb3JtIGVsZW1lbnRzLiBUaGlzIGV2ZW50IGZpcmVzIGF0IGEgdGltZSB3aGVuIGl0J3MgcG9zc2libGUgdG9cbiAqIGNoYW5nZSB0aGUgZWxlbWVudCdzIHZhbHVlIHdpdGhvdXQgc2VlaW5nIGEgZmxpY2tlci5cbiAqXG4gKiBTdXBwb3J0ZWQgZWxlbWVudHMgYXJlOlxuICogLSBpbnB1dCAoc2VlIGBpc1RleHRJbnB1dEVsZW1lbnRgKVxuICogLSB0ZXh0YXJlYVxuICogLSBzZWxlY3RcbiAqL1xudmFyIENoYW5nZUV2ZW50UGx1Z2luID0ge1xuXG4gIGV2ZW50VHlwZXM6IGV2ZW50VHlwZXMsXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGUgUmVjb3JkIGZyb20gYEV2ZW50Q29uc3RhbnRzYC5cbiAgICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUYXJnZXRJRCBJRCBvZiBgdG9wTGV2ZWxUYXJnZXRgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4geyp9IEFuIGFjY3VtdWxhdGlvbiBvZiBzeW50aGV0aWMgZXZlbnRzLlxuICAgKiBAc2VlIHtFdmVudFBsdWdpbkh1Yi5leHRyYWN0RXZlbnRzfVxuICAgKi9cbiAgZXh0cmFjdEV2ZW50czogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuXG4gICAgdmFyIGdldFRhcmdldElERnVuYywgaGFuZGxlRXZlbnRGdW5jO1xuICAgIGlmIChzaG91bGRVc2VDaGFuZ2VFdmVudCh0b3BMZXZlbFRhcmdldCkpIHtcbiAgICAgIGlmIChkb2VzQ2hhbmdlRXZlbnRCdWJibGUpIHtcbiAgICAgICAgZ2V0VGFyZ2V0SURGdW5jID0gZ2V0VGFyZ2V0SURGb3JDaGFuZ2VFdmVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhhbmRsZUV2ZW50RnVuYyA9IGhhbmRsZUV2ZW50c0ZvckNoYW5nZUV2ZW50SUU4O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNUZXh0SW5wdXRFbGVtZW50KHRvcExldmVsVGFyZ2V0KSkge1xuICAgICAgaWYgKGlzSW5wdXRFdmVudFN1cHBvcnRlZCkge1xuICAgICAgICBnZXRUYXJnZXRJREZ1bmMgPSBnZXRUYXJnZXRJREZvcklucHV0RXZlbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZXRUYXJnZXRJREZ1bmMgPSBnZXRUYXJnZXRJREZvcklucHV0RXZlbnRJRTtcbiAgICAgICAgaGFuZGxlRXZlbnRGdW5jID0gaGFuZGxlRXZlbnRzRm9ySW5wdXRFdmVudElFO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2hvdWxkVXNlQ2xpY2tFdmVudCh0b3BMZXZlbFRhcmdldCkpIHtcbiAgICAgIGdldFRhcmdldElERnVuYyA9IGdldFRhcmdldElERm9yQ2xpY2tFdmVudDtcbiAgICB9XG5cbiAgICBpZiAoZ2V0VGFyZ2V0SURGdW5jKSB7XG4gICAgICB2YXIgdGFyZ2V0SUQgPSBnZXRUYXJnZXRJREZ1bmModG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCk7XG4gICAgICBpZiAodGFyZ2V0SUQpIHtcbiAgICAgICAgdmFyIGV2ZW50ID0gU3ludGhldGljRXZlbnQuZ2V0UG9vbGVkKGV2ZW50VHlwZXMuY2hhbmdlLCB0YXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgICAgZXZlbnQudHlwZSA9ICdjaGFuZ2UnO1xuICAgICAgICBFdmVudFByb3BhZ2F0b3JzLmFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXMoZXZlbnQpO1xuICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGhhbmRsZUV2ZW50RnVuYykge1xuICAgICAgaGFuZGxlRXZlbnRGdW5jKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQpO1xuICAgIH1cbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENoYW5nZUV2ZW50UGx1Z2luOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBDbGllbnRSZWFjdFJvb3RJbmRleFxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBuZXh0UmVhY3RSb290SW5kZXggPSAwO1xuXG52YXIgQ2xpZW50UmVhY3RSb290SW5kZXggPSB7XG4gIGNyZWF0ZVJlYWN0Um9vdEluZGV4OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5leHRSZWFjdFJvb3RJbmRleCsrO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENsaWVudFJlYWN0Um9vdEluZGV4OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBET01DaGlsZHJlbk9wZXJhdGlvbnNcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRGFuZ2VyID0gcmVxdWlyZSgnLi9EYW5nZXInKTtcbnZhciBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcyA9IHJlcXVpcmUoJy4vUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMnKTtcbnZhciBSZWFjdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0UGVyZicpO1xuXG52YXIgc2V0SW5uZXJIVE1MID0gcmVxdWlyZSgnLi9zZXRJbm5lckhUTUwnKTtcbnZhciBzZXRUZXh0Q29udGVudCA9IHJlcXVpcmUoJy4vc2V0VGV4dENvbnRlbnQnKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBJbnNlcnRzIGBjaGlsZE5vZGVgIGFzIGEgY2hpbGQgb2YgYHBhcmVudE5vZGVgIGF0IHRoZSBgaW5kZXhgLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gcGFyZW50Tm9kZSBQYXJlbnQgbm9kZSBpbiB3aGljaCB0byBpbnNlcnQuXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGNoaWxkTm9kZSBDaGlsZCBub2RlIHRvIGluc2VydC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleCBhdCB3aGljaCB0byBpbnNlcnQgdGhlIGNoaWxkLlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGluc2VydENoaWxkQXQocGFyZW50Tm9kZSwgY2hpbGROb2RlLCBpbmRleCkge1xuICAvLyBCeSBleHBsb2l0aW5nIGFycmF5cyByZXR1cm5pbmcgYHVuZGVmaW5lZGAgZm9yIGFuIHVuZGVmaW5lZCBpbmRleCwgd2UgY2FuXG4gIC8vIHJlbHkgZXhjbHVzaXZlbHkgb24gYGluc2VydEJlZm9yZShub2RlLCBudWxsKWAgaW5zdGVhZCBvZiBhbHNvIHVzaW5nXG4gIC8vIGBhcHBlbmRDaGlsZChub2RlKWAuIEhvd2V2ZXIsIHVzaW5nIGB1bmRlZmluZWRgIGlzIG5vdCBhbGxvd2VkIGJ5IGFsbFxuICAvLyBicm93c2VycyBzbyB3ZSBtdXN0IHJlcGxhY2UgaXQgd2l0aCBgbnVsbGAuXG5cbiAgLy8gZml4IHJlbmRlciBvcmRlciBlcnJvciBpbiBzYWZhcmlcbiAgLy8gSUU4IHdpbGwgdGhyb3cgZXJyb3Igd2hlbiBpbmRleCBvdXQgb2YgbGlzdCBzaXplLlxuICB2YXIgYmVmb3JlQ2hpbGQgPSBpbmRleCA+PSBwYXJlbnROb2RlLmNoaWxkTm9kZXMubGVuZ3RoID8gbnVsbCA6IHBhcmVudE5vZGUuY2hpbGROb2Rlcy5pdGVtKGluZGV4KTtcblxuICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShjaGlsZE5vZGUsIGJlZm9yZUNoaWxkKTtcbn1cblxuLyoqXG4gKiBPcGVyYXRpb25zIGZvciB1cGRhdGluZyB3aXRoIERPTSBjaGlsZHJlbi5cbiAqL1xudmFyIERPTUNoaWxkcmVuT3BlcmF0aW9ucyA9IHtcblxuICBkYW5nZXJvdXNseVJlcGxhY2VOb2RlV2l0aE1hcmt1cDogRGFuZ2VyLmRhbmdlcm91c2x5UmVwbGFjZU5vZGVXaXRoTWFya3VwLFxuXG4gIHVwZGF0ZVRleHRDb250ZW50OiBzZXRUZXh0Q29udGVudCxcblxuICAvKipcbiAgICogVXBkYXRlcyBhIGNvbXBvbmVudCdzIGNoaWxkcmVuIGJ5IHByb2Nlc3NpbmcgYSBzZXJpZXMgb2YgdXBkYXRlcy4gVGhlXG4gICAqIHVwZGF0ZSBjb25maWd1cmF0aW9ucyBhcmUgZWFjaCBleHBlY3RlZCB0byBoYXZlIGEgYHBhcmVudE5vZGVgIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0ge2FycmF5PG9iamVjdD59IHVwZGF0ZXMgTGlzdCBvZiB1cGRhdGUgY29uZmlndXJhdGlvbnMuXG4gICAqIEBwYXJhbSB7YXJyYXk8c3RyaW5nPn0gbWFya3VwTGlzdCBMaXN0IG9mIG1hcmt1cCBzdHJpbmdzLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByb2Nlc3NVcGRhdGVzOiBmdW5jdGlvbiAodXBkYXRlcywgbWFya3VwTGlzdCkge1xuICAgIHZhciB1cGRhdGU7XG4gICAgLy8gTWFwcGluZyBmcm9tIHBhcmVudCBJRHMgdG8gaW5pdGlhbCBjaGlsZCBvcmRlcmluZ3MuXG4gICAgdmFyIGluaXRpYWxDaGlsZHJlbiA9IG51bGw7XG4gICAgLy8gTGlzdCBvZiBjaGlsZHJlbiB0aGF0IHdpbGwgYmUgbW92ZWQgb3IgcmVtb3ZlZC5cbiAgICB2YXIgdXBkYXRlZENoaWxkcmVuID0gbnVsbDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXBkYXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdXBkYXRlID0gdXBkYXRlc1tpXTtcbiAgICAgIGlmICh1cGRhdGUudHlwZSA9PT0gUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMuTU9WRV9FWElTVElORyB8fCB1cGRhdGUudHlwZSA9PT0gUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMuUkVNT1ZFX05PREUpIHtcbiAgICAgICAgdmFyIHVwZGF0ZWRJbmRleCA9IHVwZGF0ZS5mcm9tSW5kZXg7XG4gICAgICAgIHZhciB1cGRhdGVkQ2hpbGQgPSB1cGRhdGUucGFyZW50Tm9kZS5jaGlsZE5vZGVzW3VwZGF0ZWRJbmRleF07XG4gICAgICAgIHZhciBwYXJlbnRJRCA9IHVwZGF0ZS5wYXJlbnRJRDtcblxuICAgICAgICAhdXBkYXRlZENoaWxkID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ3Byb2Nlc3NVcGRhdGVzKCk6IFVuYWJsZSB0byBmaW5kIGNoaWxkICVzIG9mIGVsZW1lbnQuIFRoaXMgJyArICdwcm9iYWJseSBtZWFucyB0aGUgRE9NIHdhcyB1bmV4cGVjdGVkbHkgbXV0YXRlZCAoZS5nLiwgYnkgdGhlICcgKyAnYnJvd3NlciksIHVzdWFsbHkgZHVlIHRvIGZvcmdldHRpbmcgYSA8dGJvZHk+IHdoZW4gdXNpbmcgdGFibGVzLCAnICsgJ25lc3RpbmcgdGFncyBsaWtlIDxmb3JtPiwgPHA+LCBvciA8YT4sIG9yIHVzaW5nIG5vbi1TVkcgZWxlbWVudHMgJyArICdpbiBhbiA8c3ZnPiBwYXJlbnQuIFRyeSBpbnNwZWN0aW5nIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUgZWxlbWVudCAnICsgJ3dpdGggUmVhY3QgSUQgYCVzYC4nLCB1cGRhdGVkSW5kZXgsIHBhcmVudElEKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaW5pdGlhbENoaWxkcmVuID0gaW5pdGlhbENoaWxkcmVuIHx8IHt9O1xuICAgICAgICBpbml0aWFsQ2hpbGRyZW5bcGFyZW50SURdID0gaW5pdGlhbENoaWxkcmVuW3BhcmVudElEXSB8fCBbXTtcbiAgICAgICAgaW5pdGlhbENoaWxkcmVuW3BhcmVudElEXVt1cGRhdGVkSW5kZXhdID0gdXBkYXRlZENoaWxkO1xuXG4gICAgICAgIHVwZGF0ZWRDaGlsZHJlbiA9IHVwZGF0ZWRDaGlsZHJlbiB8fCBbXTtcbiAgICAgICAgdXBkYXRlZENoaWxkcmVuLnB1c2godXBkYXRlZENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVuZGVyZWRNYXJrdXA7XG4gICAgLy8gbWFya3VwTGlzdCBpcyBlaXRoZXIgYSBsaXN0IG9mIG1hcmt1cCBvciBqdXN0IGEgbGlzdCBvZiBlbGVtZW50c1xuICAgIGlmIChtYXJrdXBMaXN0Lmxlbmd0aCAmJiB0eXBlb2YgbWFya3VwTGlzdFswXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJlbmRlcmVkTWFya3VwID0gRGFuZ2VyLmRhbmdlcm91c2x5UmVuZGVyTWFya3VwKG1hcmt1cExpc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZW5kZXJlZE1hcmt1cCA9IG1hcmt1cExpc3Q7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHVwZGF0ZWQgY2hpbGRyZW4gZmlyc3Qgc28gdGhhdCBgdG9JbmRleGAgaXMgY29uc2lzdGVudC5cbiAgICBpZiAodXBkYXRlZENoaWxkcmVuKSB7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHVwZGF0ZWRDaGlsZHJlbi5sZW5ndGg7IGorKykge1xuICAgICAgICB1cGRhdGVkQ2hpbGRyZW5bal0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh1cGRhdGVkQ2hpbGRyZW5bal0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgdXBkYXRlcy5sZW5ndGg7IGsrKykge1xuICAgICAgdXBkYXRlID0gdXBkYXRlc1trXTtcbiAgICAgIHN3aXRjaCAodXBkYXRlLnR5cGUpIHtcbiAgICAgICAgY2FzZSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5JTlNFUlRfTUFSS1VQOlxuICAgICAgICAgIGluc2VydENoaWxkQXQodXBkYXRlLnBhcmVudE5vZGUsIHJlbmRlcmVkTWFya3VwW3VwZGF0ZS5tYXJrdXBJbmRleF0sIHVwZGF0ZS50b0luZGV4KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5NT1ZFX0VYSVNUSU5HOlxuICAgICAgICAgIGluc2VydENoaWxkQXQodXBkYXRlLnBhcmVudE5vZGUsIGluaXRpYWxDaGlsZHJlblt1cGRhdGUucGFyZW50SURdW3VwZGF0ZS5mcm9tSW5kZXhdLCB1cGRhdGUudG9JbmRleCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMuU0VUX01BUktVUDpcbiAgICAgICAgICBzZXRJbm5lckhUTUwodXBkYXRlLnBhcmVudE5vZGUsIHVwZGF0ZS5jb250ZW50KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5URVhUX0NPTlRFTlQ6XG4gICAgICAgICAgc2V0VGV4dENvbnRlbnQodXBkYXRlLnBhcmVudE5vZGUsIHVwZGF0ZS5jb250ZW50KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5SRU1PVkVfTk9ERTpcbiAgICAgICAgICAvLyBBbHJlYWR5IHJlbW92ZWQgYnkgdGhlIGZvci1sb29wIGFib3ZlLlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59O1xuXG5SZWFjdFBlcmYubWVhc3VyZU1ldGhvZHMoRE9NQ2hpbGRyZW5PcGVyYXRpb25zLCAnRE9NQ2hpbGRyZW5PcGVyYXRpb25zJywge1xuICB1cGRhdGVUZXh0Q29udGVudDogJ3VwZGF0ZVRleHRDb250ZW50J1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRE9NQ2hpbGRyZW5PcGVyYXRpb25zOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBET01Qcm9wZXJ0eVxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuZnVuY3Rpb24gY2hlY2tNYXNrKHZhbHVlLCBiaXRtYXNrKSB7XG4gIHJldHVybiAodmFsdWUgJiBiaXRtYXNrKSA9PT0gYml0bWFzaztcbn1cblxudmFyIERPTVByb3BlcnR5SW5qZWN0aW9uID0ge1xuICAvKipcbiAgICogTWFwcGluZyBmcm9tIG5vcm1hbGl6ZWQsIGNhbWVsY2FzZWQgcHJvcGVydHkgbmFtZXMgdG8gYSBjb25maWd1cmF0aW9uIHRoYXRcbiAgICogc3BlY2lmaWVzIGhvdyB0aGUgYXNzb2NpYXRlZCBET00gcHJvcGVydHkgc2hvdWxkIGJlIGFjY2Vzc2VkIG9yIHJlbmRlcmVkLlxuICAgKi9cbiAgTVVTVF9VU0VfQVRUUklCVVRFOiAweDEsXG4gIE1VU1RfVVNFX1BST1BFUlRZOiAweDIsXG4gIEhBU19TSURFX0VGRkVDVFM6IDB4NCxcbiAgSEFTX0JPT0xFQU5fVkFMVUU6IDB4OCxcbiAgSEFTX05VTUVSSUNfVkFMVUU6IDB4MTAsXG4gIEhBU19QT1NJVElWRV9OVU1FUklDX1ZBTFVFOiAweDIwIHwgMHgxMCxcbiAgSEFTX09WRVJMT0FERURfQk9PTEVBTl9WQUxVRTogMHg0MCxcblxuICAvKipcbiAgICogSW5qZWN0IHNvbWUgc3BlY2lhbGl6ZWQga25vd2xlZGdlIGFib3V0IHRoZSBET00uIFRoaXMgdGFrZXMgYSBjb25maWcgb2JqZWN0XG4gICAqIHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKlxuICAgKiBpc0N1c3RvbUF0dHJpYnV0ZTogZnVuY3Rpb24gdGhhdCBnaXZlbiBhbiBhdHRyaWJ1dGUgbmFtZSB3aWxsIHJldHVybiB0cnVlXG4gICAqIGlmIGl0IGNhbiBiZSBpbnNlcnRlZCBpbnRvIHRoZSBET00gdmVyYmF0aW0uIFVzZWZ1bCBmb3IgZGF0YS0qIG9yIGFyaWEtKlxuICAgKiBhdHRyaWJ1dGVzIHdoZXJlIGl0J3MgaW1wb3NzaWJsZSB0byBlbnVtZXJhdGUgYWxsIG9mIHRoZSBwb3NzaWJsZVxuICAgKiBhdHRyaWJ1dGUgbmFtZXMsXG4gICAqXG4gICAqIFByb3BlcnRpZXM6IG9iamVjdCBtYXBwaW5nIERPTSBwcm9wZXJ0eSBuYW1lIHRvIG9uZSBvZiB0aGVcbiAgICogRE9NUHJvcGVydHlJbmplY3Rpb24gY29uc3RhbnRzIG9yIG51bGwuIElmIHlvdXIgYXR0cmlidXRlIGlzbid0IGluIGhlcmUsXG4gICAqIGl0IHdvbid0IGdldCB3cml0dGVuIHRvIHRoZSBET00uXG4gICAqXG4gICAqIERPTUF0dHJpYnV0ZU5hbWVzOiBvYmplY3QgbWFwcGluZyBSZWFjdCBhdHRyaWJ1dGUgbmFtZSB0byB0aGUgRE9NXG4gICAqIGF0dHJpYnV0ZSBuYW1lLiBBdHRyaWJ1dGUgbmFtZXMgbm90IHNwZWNpZmllZCB1c2UgdGhlICoqbG93ZXJjYXNlKipcbiAgICogbm9ybWFsaXplZCBuYW1lLlxuICAgKlxuICAgKiBET01BdHRyaWJ1dGVOYW1lc3BhY2VzOiBvYmplY3QgbWFwcGluZyBSZWFjdCBhdHRyaWJ1dGUgbmFtZSB0byB0aGUgRE9NXG4gICAqIGF0dHJpYnV0ZSBuYW1lc3BhY2UgVVJMLiAoQXR0cmlidXRlIG5hbWVzIG5vdCBzcGVjaWZpZWQgdXNlIG5vIG5hbWVzcGFjZS4pXG4gICAqXG4gICAqIERPTVByb3BlcnR5TmFtZXM6IHNpbWlsYXIgdG8gRE9NQXR0cmlidXRlTmFtZXMgYnV0IGZvciBET00gcHJvcGVydGllcy5cbiAgICogUHJvcGVydHkgbmFtZXMgbm90IHNwZWNpZmllZCB1c2UgdGhlIG5vcm1hbGl6ZWQgbmFtZS5cbiAgICpcbiAgICogRE9NTXV0YXRpb25NZXRob2RzOiBQcm9wZXJ0aWVzIHRoYXQgcmVxdWlyZSBzcGVjaWFsIG11dGF0aW9uIG1ldGhvZHMuIElmXG4gICAqIGB2YWx1ZWAgaXMgdW5kZWZpbmVkLCB0aGUgbXV0YXRpb24gbWV0aG9kIHNob3VsZCB1bnNldCB0aGUgcHJvcGVydHkuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkb21Qcm9wZXJ0eUNvbmZpZyB0aGUgY29uZmlnIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgICovXG4gIGluamVjdERPTVByb3BlcnR5Q29uZmlnOiBmdW5jdGlvbiAoZG9tUHJvcGVydHlDb25maWcpIHtcbiAgICB2YXIgSW5qZWN0aW9uID0gRE9NUHJvcGVydHlJbmplY3Rpb247XG4gICAgdmFyIFByb3BlcnRpZXMgPSBkb21Qcm9wZXJ0eUNvbmZpZy5Qcm9wZXJ0aWVzIHx8IHt9O1xuICAgIHZhciBET01BdHRyaWJ1dGVOYW1lc3BhY2VzID0gZG9tUHJvcGVydHlDb25maWcuRE9NQXR0cmlidXRlTmFtZXNwYWNlcyB8fCB7fTtcbiAgICB2YXIgRE9NQXR0cmlidXRlTmFtZXMgPSBkb21Qcm9wZXJ0eUNvbmZpZy5ET01BdHRyaWJ1dGVOYW1lcyB8fCB7fTtcbiAgICB2YXIgRE9NUHJvcGVydHlOYW1lcyA9IGRvbVByb3BlcnR5Q29uZmlnLkRPTVByb3BlcnR5TmFtZXMgfHwge307XG4gICAgdmFyIERPTU11dGF0aW9uTWV0aG9kcyA9IGRvbVByb3BlcnR5Q29uZmlnLkRPTU11dGF0aW9uTWV0aG9kcyB8fCB7fTtcblxuICAgIGlmIChkb21Qcm9wZXJ0eUNvbmZpZy5pc0N1c3RvbUF0dHJpYnV0ZSkge1xuICAgICAgRE9NUHJvcGVydHkuX2lzQ3VzdG9tQXR0cmlidXRlRnVuY3Rpb25zLnB1c2goZG9tUHJvcGVydHlDb25maWcuaXNDdXN0b21BdHRyaWJ1dGUpO1xuICAgIH1cblxuICAgIGZvciAodmFyIHByb3BOYW1lIGluIFByb3BlcnRpZXMpIHtcbiAgICAgICEhRE9NUHJvcGVydHkucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnaW5qZWN0RE9NUHJvcGVydHlDb25maWcoLi4uKTogWW91XFwncmUgdHJ5aW5nIHRvIGluamVjdCBET00gcHJvcGVydHkgJyArICdcXCclc1xcJyB3aGljaCBoYXMgYWxyZWFkeSBiZWVuIGluamVjdGVkLiBZb3UgbWF5IGJlIGFjY2lkZW50YWxseSAnICsgJ2luamVjdGluZyB0aGUgc2FtZSBET00gcHJvcGVydHkgY29uZmlnIHR3aWNlLCBvciB5b3UgbWF5IGJlICcgKyAnaW5qZWN0aW5nIHR3byBjb25maWdzIHRoYXQgaGF2ZSBjb25mbGljdGluZyBwcm9wZXJ0eSBuYW1lcy4nLCBwcm9wTmFtZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgICB2YXIgbG93ZXJDYXNlZCA9IHByb3BOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICB2YXIgcHJvcENvbmZpZyA9IFByb3BlcnRpZXNbcHJvcE5hbWVdO1xuXG4gICAgICB2YXIgcHJvcGVydHlJbmZvID0ge1xuICAgICAgICBhdHRyaWJ1dGVOYW1lOiBsb3dlckNhc2VkLFxuICAgICAgICBhdHRyaWJ1dGVOYW1lc3BhY2U6IG51bGwsXG4gICAgICAgIHByb3BlcnR5TmFtZTogcHJvcE5hbWUsXG4gICAgICAgIG11dGF0aW9uTWV0aG9kOiBudWxsLFxuXG4gICAgICAgIG11c3RVc2VBdHRyaWJ1dGU6IGNoZWNrTWFzayhwcm9wQ29uZmlnLCBJbmplY3Rpb24uTVVTVF9VU0VfQVRUUklCVVRFKSxcbiAgICAgICAgbXVzdFVzZVByb3BlcnR5OiBjaGVja01hc2socHJvcENvbmZpZywgSW5qZWN0aW9uLk1VU1RfVVNFX1BST1BFUlRZKSxcbiAgICAgICAgaGFzU2lkZUVmZmVjdHM6IGNoZWNrTWFzayhwcm9wQ29uZmlnLCBJbmplY3Rpb24uSEFTX1NJREVfRUZGRUNUUyksXG4gICAgICAgIGhhc0Jvb2xlYW5WYWx1ZTogY2hlY2tNYXNrKHByb3BDb25maWcsIEluamVjdGlvbi5IQVNfQk9PTEVBTl9WQUxVRSksXG4gICAgICAgIGhhc051bWVyaWNWYWx1ZTogY2hlY2tNYXNrKHByb3BDb25maWcsIEluamVjdGlvbi5IQVNfTlVNRVJJQ19WQUxVRSksXG4gICAgICAgIGhhc1Bvc2l0aXZlTnVtZXJpY1ZhbHVlOiBjaGVja01hc2socHJvcENvbmZpZywgSW5qZWN0aW9uLkhBU19QT1NJVElWRV9OVU1FUklDX1ZBTFVFKSxcbiAgICAgICAgaGFzT3ZlcmxvYWRlZEJvb2xlYW5WYWx1ZTogY2hlY2tNYXNrKHByb3BDb25maWcsIEluamVjdGlvbi5IQVNfT1ZFUkxPQURFRF9CT09MRUFOX1ZBTFVFKVxuICAgICAgfTtcblxuICAgICAgISghcHJvcGVydHlJbmZvLm11c3RVc2VBdHRyaWJ1dGUgfHwgIXByb3BlcnR5SW5mby5tdXN0VXNlUHJvcGVydHkpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ0RPTVByb3BlcnR5OiBDYW5ub3QgcmVxdWlyZSB1c2luZyBib3RoIGF0dHJpYnV0ZSBhbmQgcHJvcGVydHk6ICVzJywgcHJvcE5hbWUpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgICEocHJvcGVydHlJbmZvLm11c3RVc2VQcm9wZXJ0eSB8fCAhcHJvcGVydHlJbmZvLmhhc1NpZGVFZmZlY3RzKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdET01Qcm9wZXJ0eTogUHJvcGVydGllcyB0aGF0IGhhdmUgc2lkZSBlZmZlY3RzIG11c3QgdXNlIHByb3BlcnR5OiAlcycsIHByb3BOYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgICAhKHByb3BlcnR5SW5mby5oYXNCb29sZWFuVmFsdWUgKyBwcm9wZXJ0eUluZm8uaGFzTnVtZXJpY1ZhbHVlICsgcHJvcGVydHlJbmZvLmhhc092ZXJsb2FkZWRCb29sZWFuVmFsdWUgPD0gMSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRE9NUHJvcGVydHk6IFZhbHVlIGNhbiBiZSBvbmUgb2YgYm9vbGVhbiwgb3ZlcmxvYWRlZCBib29sZWFuLCBvciAnICsgJ251bWVyaWMgdmFsdWUsIGJ1dCBub3QgYSBjb21iaW5hdGlvbjogJXMnLCBwcm9wTmFtZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBET01Qcm9wZXJ0eS5nZXRQb3NzaWJsZVN0YW5kYXJkTmFtZVtsb3dlckNhc2VkXSA9IHByb3BOYW1lO1xuICAgICAgfVxuXG4gICAgICBpZiAoRE9NQXR0cmlidXRlTmFtZXMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgIHZhciBhdHRyaWJ1dGVOYW1lID0gRE9NQXR0cmlidXRlTmFtZXNbcHJvcE5hbWVdO1xuICAgICAgICBwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWU7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgRE9NUHJvcGVydHkuZ2V0UG9zc2libGVTdGFuZGFyZE5hbWVbYXR0cmlidXRlTmFtZV0gPSBwcm9wTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoRE9NQXR0cmlidXRlTmFtZXNwYWNlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgcHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IERPTUF0dHJpYnV0ZU5hbWVzcGFjZXNbcHJvcE5hbWVdO1xuICAgICAgfVxuXG4gICAgICBpZiAoRE9NUHJvcGVydHlOYW1lcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZSA9IERPTVByb3BlcnR5TmFtZXNbcHJvcE5hbWVdO1xuICAgICAgfVxuXG4gICAgICBpZiAoRE9NTXV0YXRpb25NZXRob2RzLmhhc093blByb3BlcnR5KHByb3BOYW1lKSkge1xuICAgICAgICBwcm9wZXJ0eUluZm8ubXV0YXRpb25NZXRob2QgPSBET01NdXRhdGlvbk1ldGhvZHNbcHJvcE5hbWVdO1xuICAgICAgfVxuXG4gICAgICBET01Qcm9wZXJ0eS5wcm9wZXJ0aWVzW3Byb3BOYW1lXSA9IHByb3BlcnR5SW5mbztcbiAgICB9XG4gIH1cbn07XG52YXIgZGVmYXVsdFZhbHVlQ2FjaGUgPSB7fTtcblxuLyoqXG4gKiBET01Qcm9wZXJ0eSBleHBvcnRzIGxvb2t1cCBvYmplY3RzIHRoYXQgY2FuIGJlIHVzZWQgbGlrZSBmdW5jdGlvbnM6XG4gKlxuICogICA+IERPTVByb3BlcnR5LmlzVmFsaWRbJ2lkJ11cbiAqICAgdHJ1ZVxuICogICA+IERPTVByb3BlcnR5LmlzVmFsaWRbJ2Zvb2JhciddXG4gKiAgIHVuZGVmaW5lZFxuICpcbiAqIEFsdGhvdWdoIHRoaXMgbWF5IGJlIGNvbmZ1c2luZywgaXQgcGVyZm9ybXMgYmV0dGVyIGluIGdlbmVyYWwuXG4gKlxuICogQHNlZSBodHRwOi8vanNwZXJmLmNvbS9rZXktZXhpc3RzXG4gKiBAc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2tleS1taXNzaW5nXG4gKi9cbnZhciBET01Qcm9wZXJ0eSA9IHtcblxuICBJRF9BVFRSSUJVVEVfTkFNRTogJ2RhdGEtcmVhY3RpZCcsXG5cbiAgLyoqXG4gICAqIE1hcCBmcm9tIHByb3BlcnR5IFwic3RhbmRhcmQgbmFtZVwiIHRvIGFuIG9iamVjdCB3aXRoIGluZm8gYWJvdXQgaG93IHRvIHNldFxuICAgKiB0aGUgcHJvcGVydHkgaW4gdGhlIERPTS4gRWFjaCBvYmplY3QgY29udGFpbnM6XG4gICAqXG4gICAqIGF0dHJpYnV0ZU5hbWU6XG4gICAqICAgVXNlZCB3aGVuIHJlbmRlcmluZyBtYXJrdXAgb3Igd2l0aCBgKkF0dHJpYnV0ZSgpYC5cbiAgICogYXR0cmlidXRlTmFtZXNwYWNlXG4gICAqIHByb3BlcnR5TmFtZTpcbiAgICogICBVc2VkIG9uIERPTSBub2RlIGluc3RhbmNlcy4gKFRoaXMgaW5jbHVkZXMgcHJvcGVydGllcyB0aGF0IG11dGF0ZSBkdWUgdG9cbiAgICogICBleHRlcm5hbCBmYWN0b3JzLilcbiAgICogbXV0YXRpb25NZXRob2Q6XG4gICAqICAgSWYgbm9uLW51bGwsIHVzZWQgaW5zdGVhZCBvZiB0aGUgcHJvcGVydHkgb3IgYHNldEF0dHJpYnV0ZSgpYCBhZnRlclxuICAgKiAgIGluaXRpYWwgcmVuZGVyLlxuICAgKiBtdXN0VXNlQXR0cmlidXRlOlxuICAgKiAgIFdoZXRoZXIgdGhlIHByb3BlcnR5IG11c3QgYmUgYWNjZXNzZWQgYW5kIG11dGF0ZWQgdXNpbmcgYCpBdHRyaWJ1dGUoKWAuXG4gICAqICAgKFRoaXMgaW5jbHVkZXMgYW55dGhpbmcgdGhhdCBmYWlscyBgPHByb3BOYW1lPiBpbiA8ZWxlbWVudD5gLilcbiAgICogbXVzdFVzZVByb3BlcnR5OlxuICAgKiAgIFdoZXRoZXIgdGhlIHByb3BlcnR5IG11c3QgYmUgYWNjZXNzZWQgYW5kIG11dGF0ZWQgYXMgYW4gb2JqZWN0IHByb3BlcnR5LlxuICAgKiBoYXNTaWRlRWZmZWN0czpcbiAgICogICBXaGV0aGVyIG9yIG5vdCBzZXR0aW5nIGEgdmFsdWUgY2F1c2VzIHNpZGUgZWZmZWN0cyBzdWNoIGFzIHRyaWdnZXJpbmdcbiAgICogICByZXNvdXJjZXMgdG8gYmUgbG9hZGVkIG9yIHRleHQgc2VsZWN0aW9uIGNoYW5nZXMuIElmIHRydWUsIHdlIHJlYWQgZnJvbVxuICAgKiAgIHRoZSBET00gYmVmb3JlIHVwZGF0aW5nIHRvIGVuc3VyZSB0aGF0IHRoZSB2YWx1ZSBpcyBvbmx5IHNldCBpZiBpdCBoYXNcbiAgICogICBjaGFuZ2VkLlxuICAgKiBoYXNCb29sZWFuVmFsdWU6XG4gICAqICAgV2hldGhlciB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIHJlbW92ZWQgd2hlbiBzZXQgdG8gYSBmYWxzZXkgdmFsdWUuXG4gICAqIGhhc051bWVyaWNWYWx1ZTpcbiAgICogICBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBtdXN0IGJlIG51bWVyaWMgb3IgcGFyc2UgYXMgYSBudW1lcmljIGFuZCBzaG91bGQgYmVcbiAgICogICByZW1vdmVkIHdoZW4gc2V0IHRvIGEgZmFsc2V5IHZhbHVlLlxuICAgKiBoYXNQb3NpdGl2ZU51bWVyaWNWYWx1ZTpcbiAgICogICBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBtdXN0IGJlIHBvc2l0aXZlIG51bWVyaWMgb3IgcGFyc2UgYXMgYSBwb3NpdGl2ZVxuICAgKiAgIG51bWVyaWMgYW5kIHNob3VsZCBiZSByZW1vdmVkIHdoZW4gc2V0IHRvIGEgZmFsc2V5IHZhbHVlLlxuICAgKiBoYXNPdmVybG9hZGVkQm9vbGVhblZhbHVlOlxuICAgKiAgIFdoZXRoZXIgdGhlIHByb3BlcnR5IGNhbiBiZSB1c2VkIGFzIGEgZmxhZyBhcyB3ZWxsIGFzIHdpdGggYSB2YWx1ZS5cbiAgICogICBSZW1vdmVkIHdoZW4gc3RyaWN0bHkgZXF1YWwgdG8gZmFsc2U7IHByZXNlbnQgd2l0aG91dCBhIHZhbHVlIHdoZW5cbiAgICogICBzdHJpY3RseSBlcXVhbCB0byB0cnVlOyBwcmVzZW50IHdpdGggYSB2YWx1ZSBvdGhlcndpc2UuXG4gICAqL1xuICBwcm9wZXJ0aWVzOiB7fSxcblxuICAvKipcbiAgICogTWFwcGluZyBmcm9tIGxvd2VyY2FzZSBwcm9wZXJ0eSBuYW1lcyB0byB0aGUgcHJvcGVybHkgY2FzZWQgdmVyc2lvbiwgdXNlZFxuICAgKiB0byB3YXJuIGluIHRoZSBjYXNlIG9mIG1pc3NpbmcgcHJvcGVydGllcy4gQXZhaWxhYmxlIG9ubHkgaW4gX19ERVZfXy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIGdldFBvc3NpYmxlU3RhbmRhcmROYW1lOiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8ge30gOiBudWxsLFxuXG4gIC8qKlxuICAgKiBBbGwgb2YgdGhlIGlzQ3VzdG9tQXR0cmlidXRlKCkgZnVuY3Rpb25zIHRoYXQgaGF2ZSBiZWVuIGluamVjdGVkLlxuICAgKi9cbiAgX2lzQ3VzdG9tQXR0cmlidXRlRnVuY3Rpb25zOiBbXSxcblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgYSBwcm9wZXJ0eSBuYW1lIGlzIGEgY3VzdG9tIGF0dHJpYnV0ZS5cbiAgICogQG1ldGhvZFxuICAgKi9cbiAgaXNDdXN0b21BdHRyaWJ1dGU6IGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBET01Qcm9wZXJ0eS5faXNDdXN0b21BdHRyaWJ1dGVGdW5jdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpc0N1c3RvbUF0dHJpYnV0ZUZuID0gRE9NUHJvcGVydHkuX2lzQ3VzdG9tQXR0cmlidXRlRnVuY3Rpb25zW2ldO1xuICAgICAgaWYgKGlzQ3VzdG9tQXR0cmlidXRlRm4oYXR0cmlidXRlTmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZGVmYXVsdCBwcm9wZXJ0eSB2YWx1ZSBmb3IgYSBET00gcHJvcGVydHkgKGkuZS4sIG5vdCBhblxuICAgKiBhdHRyaWJ1dGUpLiBNb3N0IGRlZmF1bHQgdmFsdWVzIGFyZSAnJyBvciBmYWxzZSwgYnV0IG5vdCBhbGwuIFdvcnNlIHlldCxcbiAgICogc29tZSAoaW4gcGFydGljdWxhciwgYHR5cGVgKSB2YXJ5IGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBlbGVtZW50LlxuICAgKlxuICAgKiBUT0RPOiBJcyBpdCBiZXR0ZXIgdG8gZ3JhYiBhbGwgdGhlIHBvc3NpYmxlIHByb3BlcnRpZXMgd2hlbiBjcmVhdGluZyBhblxuICAgKiBlbGVtZW50IHRvIGF2b2lkIGhhdmluZyB0byBjcmVhdGUgdGhlIHNhbWUgZWxlbWVudCB0d2ljZT9cbiAgICovXG4gIGdldERlZmF1bHRWYWx1ZUZvclByb3BlcnR5OiBmdW5jdGlvbiAobm9kZU5hbWUsIHByb3ApIHtcbiAgICB2YXIgbm9kZURlZmF1bHRzID0gZGVmYXVsdFZhbHVlQ2FjaGVbbm9kZU5hbWVdO1xuICAgIHZhciB0ZXN0RWxlbWVudDtcbiAgICBpZiAoIW5vZGVEZWZhdWx0cykge1xuICAgICAgZGVmYXVsdFZhbHVlQ2FjaGVbbm9kZU5hbWVdID0gbm9kZURlZmF1bHRzID0ge307XG4gICAgfVxuICAgIGlmICghKHByb3AgaW4gbm9kZURlZmF1bHRzKSkge1xuICAgICAgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5vZGVOYW1lKTtcbiAgICAgIG5vZGVEZWZhdWx0c1twcm9wXSA9IHRlc3RFbGVtZW50W3Byb3BdO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZURlZmF1bHRzW3Byb3BdO1xuICB9LFxuXG4gIGluamVjdGlvbjogRE9NUHJvcGVydHlJbmplY3Rpb25cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRE9NUHJvcGVydHk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIERPTVByb3BlcnR5T3BlcmF0aW9uc1xuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBET01Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRE9NUHJvcGVydHknKTtcbnZhciBSZWFjdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0UGVyZicpO1xuXG52YXIgcXVvdGVBdHRyaWJ1dGVWYWx1ZUZvckJyb3dzZXIgPSByZXF1aXJlKCcuL3F1b3RlQXR0cmlidXRlVmFsdWVGb3JCcm93c2VyJyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxuLy8gU2ltcGxpZmllZCBzdWJzZXRcbnZhciBWQUxJRF9BVFRSSUJVVEVfTkFNRV9SRUdFWCA9IC9eW2EtekEtWl9dW1xcd1xcLlxcLV0qJC87XG52YXIgaWxsZWdhbEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xudmFyIHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xuXG5mdW5jdGlvbiBpc0F0dHJpYnV0ZU5hbWVTYWZlKGF0dHJpYnV0ZU5hbWUpIHtcbiAgaWYgKHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZS5oYXNPd25Qcm9wZXJ0eShhdHRyaWJ1dGVOYW1lKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChpbGxlZ2FsQXR0cmlidXRlTmFtZUNhY2hlLmhhc093blByb3BlcnR5KGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChWQUxJRF9BVFRSSUJVVEVfTkFNRV9SRUdFWC50ZXN0KGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgdmFsaWRhdGVkQXR0cmlidXRlTmFtZUNhY2hlW2F0dHJpYnV0ZU5hbWVdID0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpbGxlZ2FsQXR0cmlidXRlTmFtZUNhY2hlW2F0dHJpYnV0ZU5hbWVdID0gdHJ1ZTtcbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdJbnZhbGlkIGF0dHJpYnV0ZSBuYW1lOiBgJXNgJywgYXR0cmlidXRlTmFtZSkgOiB1bmRlZmluZWQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkSWdub3JlVmFsdWUocHJvcGVydHlJbmZvLCB2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCB8fCBwcm9wZXJ0eUluZm8uaGFzQm9vbGVhblZhbHVlICYmICF2YWx1ZSB8fCBwcm9wZXJ0eUluZm8uaGFzTnVtZXJpY1ZhbHVlICYmIGlzTmFOKHZhbHVlKSB8fCBwcm9wZXJ0eUluZm8uaGFzUG9zaXRpdmVOdW1lcmljVmFsdWUgJiYgdmFsdWUgPCAxIHx8IHByb3BlcnR5SW5mby5oYXNPdmVybG9hZGVkQm9vbGVhblZhbHVlICYmIHZhbHVlID09PSBmYWxzZTtcbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgdmFyIHJlYWN0UHJvcHMgPSB7XG4gICAgY2hpbGRyZW46IHRydWUsXG4gICAgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw6IHRydWUsXG4gICAga2V5OiB0cnVlLFxuICAgIHJlZjogdHJ1ZVxuICB9O1xuICB2YXIgd2FybmVkUHJvcGVydGllcyA9IHt9O1xuXG4gIHZhciB3YXJuVW5rbm93blByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBpZiAocmVhY3RQcm9wcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiByZWFjdFByb3BzW25hbWVdIHx8IHdhcm5lZFByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgd2FybmVkUHJvcGVydGllc1tuYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFByb3BlcnRpZXNbbmFtZV0gPSB0cnVlO1xuICAgIHZhciBsb3dlckNhc2VkTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIGRhdGEtKiBhdHRyaWJ1dGVzIHNob3VsZCBiZSBsb3dlcmNhc2U7IHN1Z2dlc3QgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uXG4gICAgdmFyIHN0YW5kYXJkTmFtZSA9IERPTVByb3BlcnR5LmlzQ3VzdG9tQXR0cmlidXRlKGxvd2VyQ2FzZWROYW1lKSA/IGxvd2VyQ2FzZWROYW1lIDogRE9NUHJvcGVydHkuZ2V0UG9zc2libGVTdGFuZGFyZE5hbWUuaGFzT3duUHJvcGVydHkobG93ZXJDYXNlZE5hbWUpID8gRE9NUHJvcGVydHkuZ2V0UG9zc2libGVTdGFuZGFyZE5hbWVbbG93ZXJDYXNlZE5hbWVdIDogbnVsbDtcblxuICAgIC8vIEZvciBub3csIG9ubHkgd2FybiB3aGVuIHdlIGhhdmUgYSBzdWdnZXN0ZWQgY29ycmVjdGlvbi4gVGhpcyBwcmV2ZW50c1xuICAgIC8vIGxvZ2dpbmcgdG9vIG11Y2ggd2hlbiB1c2luZyB0cmFuc2ZlclByb3BzVG8uXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoc3RhbmRhcmROYW1lID09IG51bGwsICdVbmtub3duIERPTSBwcm9wZXJ0eSAlcy4gRGlkIHlvdSBtZWFuICVzPycsIG5hbWUsIHN0YW5kYXJkTmFtZSkgOiB1bmRlZmluZWQ7XG4gIH07XG59XG5cbi8qKlxuICogT3BlcmF0aW9ucyBmb3IgZGVhbGluZyB3aXRoIERPTSBwcm9wZXJ0aWVzLlxuICovXG52YXIgRE9NUHJvcGVydHlPcGVyYXRpb25zID0ge1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIG1hcmt1cCBmb3IgdGhlIElEIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVW5lc2NhcGVkIElELlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IE1hcmt1cCBzdHJpbmcuXG4gICAqL1xuICBjcmVhdGVNYXJrdXBGb3JJRDogZnVuY3Rpb24gKGlkKSB7XG4gICAgcmV0dXJuIERPTVByb3BlcnR5LklEX0FUVFJJQlVURV9OQU1FICsgJz0nICsgcXVvdGVBdHRyaWJ1dGVWYWx1ZUZvckJyb3dzZXIoaWQpO1xuICB9LFxuXG4gIHNldEF0dHJpYnV0ZUZvcklEOiBmdW5jdGlvbiAobm9kZSwgaWQpIHtcbiAgICBub2RlLnNldEF0dHJpYnV0ZShET01Qcm9wZXJ0eS5JRF9BVFRSSUJVVEVfTkFNRSwgaWQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIG1hcmt1cCBmb3IgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgKiBAcmV0dXJuIHs/c3RyaW5nfSBNYXJrdXAgc3RyaW5nLCBvciBudWxsIGlmIHRoZSBwcm9wZXJ0eSB3YXMgaW52YWxpZC5cbiAgICovXG4gIGNyZWF0ZU1hcmt1cEZvclByb3BlcnR5OiBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgcHJvcGVydHlJbmZvID0gRE9NUHJvcGVydHkucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IERPTVByb3BlcnR5LnByb3BlcnRpZXNbbmFtZV0gOiBudWxsO1xuICAgIGlmIChwcm9wZXJ0eUluZm8pIHtcbiAgICAgIGlmIChzaG91bGRJZ25vcmVWYWx1ZShwcm9wZXJ0eUluZm8sIHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lO1xuICAgICAgaWYgKHByb3BlcnR5SW5mby5oYXNCb29sZWFuVmFsdWUgfHwgcHJvcGVydHlJbmZvLmhhc092ZXJsb2FkZWRCb29sZWFuVmFsdWUgJiYgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgKyAnPVwiXCInO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgKyAnPScgKyBxdW90ZUF0dHJpYnV0ZVZhbHVlRm9yQnJvd3Nlcih2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChET01Qcm9wZXJ0eS5pc0N1c3RvbUF0dHJpYnV0ZShuYW1lKSkge1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hbWUgKyAnPScgKyBxdW90ZUF0dHJpYnV0ZVZhbHVlRm9yQnJvd3Nlcih2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB3YXJuVW5rbm93blByb3BlcnR5KG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBtYXJrdXAgZm9yIGEgY3VzdG9tIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEByZXR1cm4ge3N0cmluZ30gTWFya3VwIHN0cmluZywgb3IgZW1wdHkgc3RyaW5nIGlmIHRoZSBwcm9wZXJ0eSB3YXMgaW52YWxpZC5cbiAgICovXG4gIGNyZWF0ZU1hcmt1cEZvckN1c3RvbUF0dHJpYnV0ZTogZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKCFpc0F0dHJpYnV0ZU5hbWVTYWZlKG5hbWUpIHx8IHZhbHVlID09IG51bGwpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIG5hbWUgKyAnPScgKyBxdW90ZUF0dHJpYnV0ZVZhbHVlRm9yQnJvd3Nlcih2YWx1ZSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHZhbHVlIGZvciBhIHByb3BlcnR5IG9uIGEgbm9kZS5cbiAgICpcbiAgICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICovXG4gIHNldFZhbHVlRm9yUHJvcGVydHk6IGZ1bmN0aW9uIChub2RlLCBuYW1lLCB2YWx1ZSkge1xuICAgIHZhciBwcm9wZXJ0eUluZm8gPSBET01Qcm9wZXJ0eS5wcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KG5hbWUpID8gRE9NUHJvcGVydHkucHJvcGVydGllc1tuYW1lXSA6IG51bGw7XG4gICAgaWYgKHByb3BlcnR5SW5mbykge1xuICAgICAgdmFyIG11dGF0aW9uTWV0aG9kID0gcHJvcGVydHlJbmZvLm11dGF0aW9uTWV0aG9kO1xuICAgICAgaWYgKG11dGF0aW9uTWV0aG9kKSB7XG4gICAgICAgIG11dGF0aW9uTWV0aG9kKG5vZGUsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoc2hvdWxkSWdub3JlVmFsdWUocHJvcGVydHlJbmZvLCB2YWx1ZSkpIHtcbiAgICAgICAgdGhpcy5kZWxldGVWYWx1ZUZvclByb3BlcnR5KG5vZGUsIG5hbWUpO1xuICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eUluZm8ubXVzdFVzZUF0dHJpYnV0ZSkge1xuICAgICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lO1xuICAgICAgICB2YXIgbmFtZXNwYWNlID0gcHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWVzcGFjZTtcbiAgICAgICAgLy8gYHNldEF0dHJpYnV0ZWAgd2l0aCBvYmplY3RzIGJlY29tZXMgb25seSBgW29iamVjdF1gIGluIElFOC85LFxuICAgICAgICAvLyAoJycgKyB2YWx1ZSkgbWFrZXMgaXQgb3V0cHV0IHRoZSBjb3JyZWN0IHRvU3RyaW5nKCktdmFsdWUuXG4gICAgICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZSwgYXR0cmlidXRlTmFtZSwgJycgKyB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvcGVydHlJbmZvLmhhc0Jvb2xlYW5WYWx1ZSB8fCBwcm9wZXJ0eUluZm8uaGFzT3ZlcmxvYWRlZEJvb2xlYW5WYWx1ZSAmJiB2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCAnJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHByb3BOYW1lID0gcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZTtcbiAgICAgICAgLy8gTXVzdCBleHBsaWNpdGx5IGNhc3QgdmFsdWVzIGZvciBIQVNfU0lERV9FRkZFQ1RTLXByb3BlcnRpZXMgdG8gdGhlXG4gICAgICAgIC8vIHByb3BlcnR5IHR5cGUgYmVmb3JlIGNvbXBhcmluZzsgb25seSBgdmFsdWVgIGRvZXMgYW5kIGlzIHN0cmluZy5cbiAgICAgICAgaWYgKCFwcm9wZXJ0eUluZm8uaGFzU2lkZUVmZmVjdHMgfHwgJycgKyBub2RlW3Byb3BOYW1lXSAhPT0gJycgKyB2YWx1ZSkge1xuICAgICAgICAgIC8vIENvbnRyYXJ5IHRvIGBzZXRBdHRyaWJ1dGVgLCBvYmplY3QgcHJvcGVydGllcyBhcmUgcHJvcGVybHlcbiAgICAgICAgICAvLyBgdG9TdHJpbmdgZWQgYnkgSUU4LzkuXG4gICAgICAgICAgbm9kZVtwcm9wTmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoRE9NUHJvcGVydHkuaXNDdXN0b21BdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgIERPTVByb3BlcnR5T3BlcmF0aW9ucy5zZXRWYWx1ZUZvckF0dHJpYnV0ZShub2RlLCBuYW1lLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB3YXJuVW5rbm93blByb3BlcnR5KG5hbWUpO1xuICAgIH1cbiAgfSxcblxuICBzZXRWYWx1ZUZvckF0dHJpYnV0ZTogZnVuY3Rpb24gKG5vZGUsIG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKCFpc0F0dHJpYnV0ZU5hbWVTYWZlKG5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUobmFtZSwgJycgKyB2YWx1ZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHRoZSB2YWx1ZSBmb3IgYSBwcm9wZXJ0eSBvbiBhIG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKi9cbiAgZGVsZXRlVmFsdWVGb3JQcm9wZXJ0eTogZnVuY3Rpb24gKG5vZGUsIG5hbWUpIHtcbiAgICB2YXIgcHJvcGVydHlJbmZvID0gRE9NUHJvcGVydHkucHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IERPTVByb3BlcnR5LnByb3BlcnRpZXNbbmFtZV0gOiBudWxsO1xuICAgIGlmIChwcm9wZXJ0eUluZm8pIHtcbiAgICAgIHZhciBtdXRhdGlvbk1ldGhvZCA9IHByb3BlcnR5SW5mby5tdXRhdGlvbk1ldGhvZDtcbiAgICAgIGlmIChtdXRhdGlvbk1ldGhvZCkge1xuICAgICAgICBtdXRhdGlvbk1ldGhvZChub2RlLCB1bmRlZmluZWQpO1xuICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eUluZm8ubXVzdFVzZUF0dHJpYnV0ZSkge1xuICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcHJvcE5hbWUgPSBwcm9wZXJ0eUluZm8ucHJvcGVydHlOYW1lO1xuICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gRE9NUHJvcGVydHkuZ2V0RGVmYXVsdFZhbHVlRm9yUHJvcGVydHkobm9kZS5ub2RlTmFtZSwgcHJvcE5hbWUpO1xuICAgICAgICBpZiAoIXByb3BlcnR5SW5mby5oYXNTaWRlRWZmZWN0cyB8fCAnJyArIG5vZGVbcHJvcE5hbWVdICE9PSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICBub2RlW3Byb3BOYW1lXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoRE9NUHJvcGVydHkuaXNDdXN0b21BdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgd2FyblVua25vd25Qcm9wZXJ0eShuYW1lKTtcbiAgICB9XG4gIH1cblxufTtcblxuUmVhY3RQZXJmLm1lYXN1cmVNZXRob2RzKERPTVByb3BlcnR5T3BlcmF0aW9ucywgJ0RPTVByb3BlcnR5T3BlcmF0aW9ucycsIHtcbiAgc2V0VmFsdWVGb3JQcm9wZXJ0eTogJ3NldFZhbHVlRm9yUHJvcGVydHknLFxuICBzZXRWYWx1ZUZvckF0dHJpYnV0ZTogJ3NldFZhbHVlRm9yQXR0cmlidXRlJyxcbiAgZGVsZXRlVmFsdWVGb3JQcm9wZXJ0eTogJ2RlbGV0ZVZhbHVlRm9yUHJvcGVydHknXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBET01Qcm9wZXJ0eU9wZXJhdGlvbnM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIERhbmdlclxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJ2ZianMvbGliL0V4ZWN1dGlvbkVudmlyb25tZW50Jyk7XG5cbnZhciBjcmVhdGVOb2Rlc0Zyb21NYXJrdXAgPSByZXF1aXJlKCdmYmpzL2xpYi9jcmVhdGVOb2Rlc0Zyb21NYXJrdXAnKTtcbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlGdW5jdGlvbicpO1xudmFyIGdldE1hcmt1cFdyYXAgPSByZXF1aXJlKCdmYmpzL2xpYi9nZXRNYXJrdXBXcmFwJyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG5cbnZhciBPUEVOX1RBR19OQU1FX0VYUCA9IC9eKDxbXiBcXC8+XSspLztcbnZhciBSRVNVTFRfSU5ERVhfQVRUUiA9ICdkYXRhLWRhbmdlci1pbmRleCc7XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIGBub2RlTmFtZWAgZnJvbSBhIHN0cmluZyBvZiBtYXJrdXAuXG4gKlxuICogTk9URTogRXh0cmFjdGluZyB0aGUgYG5vZGVOYW1lYCBkb2VzIG5vdCByZXF1aXJlIGEgcmVndWxhciBleHByZXNzaW9uIG1hdGNoXG4gKiBiZWNhdXNlIHdlIG1ha2UgYXNzdW1wdGlvbnMgYWJvdXQgUmVhY3QtZ2VuZXJhdGVkIG1hcmt1cCAoaS5lLiB0aGVyZSBhcmUgbm9cbiAqIHNwYWNlcyBzdXJyb3VuZGluZyB0aGUgb3BlbmluZyB0YWcgYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBhdHRyaWJ1dGUpLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtYXJrdXAgU3RyaW5nIG9mIG1hcmt1cC5cbiAqIEByZXR1cm4ge3N0cmluZ30gTm9kZSBuYW1lIG9mIHRoZSBzdXBwbGllZCBtYXJrdXAuXG4gKiBAc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2V4dHJhY3Qtbm9kZW5hbWVcbiAqL1xuZnVuY3Rpb24gZ2V0Tm9kZU5hbWUobWFya3VwKSB7XG4gIHJldHVybiBtYXJrdXAuc3Vic3RyaW5nKDEsIG1hcmt1cC5pbmRleE9mKCcgJykpO1xufVxuXG52YXIgRGFuZ2VyID0ge1xuXG4gIC8qKlxuICAgKiBSZW5kZXJzIG1hcmt1cCBpbnRvIGFuIGFycmF5IG9mIG5vZGVzLiBUaGUgbWFya3VwIGlzIGV4cGVjdGVkIHRvIHJlbmRlclxuICAgKiBpbnRvIGEgbGlzdCBvZiByb290IG5vZGVzLiBBbHNvLCB0aGUgbGVuZ3RoIG9mIGByZXN1bHRMaXN0YCBhbmRcbiAgICogYG1hcmt1cExpc3RgIHNob3VsZCBiZSB0aGUgc2FtZS5cbiAgICpcbiAgICogQHBhcmFtIHthcnJheTxzdHJpbmc+fSBtYXJrdXBMaXN0IExpc3Qgb2YgbWFya3VwIHN0cmluZ3MgdG8gcmVuZGVyLlxuICAgKiBAcmV0dXJuIHthcnJheTxET01FbGVtZW50Pn0gTGlzdCBvZiByZW5kZXJlZCBub2Rlcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBkYW5nZXJvdXNseVJlbmRlck1hcmt1cDogZnVuY3Rpb24gKG1hcmt1cExpc3QpIHtcbiAgICAhRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2Rhbmdlcm91c2x5UmVuZGVyTWFya3VwKC4uLik6IENhbm5vdCByZW5kZXIgbWFya3VwIGluIGEgd29ya2VyICcgKyAndGhyZWFkLiBNYWtlIHN1cmUgYHdpbmRvd2AgYW5kIGBkb2N1bWVudGAgYXJlIGF2YWlsYWJsZSBnbG9iYWxseSAnICsgJ2JlZm9yZSByZXF1aXJpbmcgUmVhY3Qgd2hlbiB1bml0IHRlc3Rpbmcgb3IgdXNlICcgKyAnUmVhY3RET01TZXJ2ZXIucmVuZGVyVG9TdHJpbmcgZm9yIHNlcnZlciByZW5kZXJpbmcuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIHZhciBub2RlTmFtZTtcbiAgICB2YXIgbWFya3VwQnlOb2RlTmFtZSA9IHt9O1xuICAgIC8vIEdyb3VwIG1hcmt1cCBieSBgbm9kZU5hbWVgIGlmIGEgd3JhcCBpcyBuZWNlc3NhcnksIGVsc2UgYnkgJyonLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3VwTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgIW1hcmt1cExpc3RbaV0gPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnZGFuZ2Vyb3VzbHlSZW5kZXJNYXJrdXAoLi4uKTogTWlzc2luZyBtYXJrdXAuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICAgbm9kZU5hbWUgPSBnZXROb2RlTmFtZShtYXJrdXBMaXN0W2ldKTtcbiAgICAgIG5vZGVOYW1lID0gZ2V0TWFya3VwV3JhcChub2RlTmFtZSkgPyBub2RlTmFtZSA6ICcqJztcbiAgICAgIG1hcmt1cEJ5Tm9kZU5hbWVbbm9kZU5hbWVdID0gbWFya3VwQnlOb2RlTmFtZVtub2RlTmFtZV0gfHwgW107XG4gICAgICBtYXJrdXBCeU5vZGVOYW1lW25vZGVOYW1lXVtpXSA9IG1hcmt1cExpc3RbaV07XG4gICAgfVxuICAgIHZhciByZXN1bHRMaXN0ID0gW107XG4gICAgdmFyIHJlc3VsdExpc3RBc3NpZ25tZW50Q291bnQgPSAwO1xuICAgIGZvciAobm9kZU5hbWUgaW4gbWFya3VwQnlOb2RlTmFtZSkge1xuICAgICAgaWYgKCFtYXJrdXBCeU5vZGVOYW1lLmhhc093blByb3BlcnR5KG5vZGVOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBtYXJrdXBMaXN0QnlOb2RlTmFtZSA9IG1hcmt1cEJ5Tm9kZU5hbWVbbm9kZU5hbWVdO1xuXG4gICAgICAvLyBUaGlzIGZvci1pbiBsb29wIHNraXBzIHRoZSBob2xlcyBvZiB0aGUgc3BhcnNlIGFycmF5LiBUaGUgb3JkZXIgb2ZcbiAgICAgIC8vIGl0ZXJhdGlvbiBzaG91bGQgZm9sbG93IHRoZSBvcmRlciBvZiBhc3NpZ25tZW50LCB3aGljaCBoYXBwZW5zIHRvIG1hdGNoXG4gICAgICAvLyBudW1lcmljYWwgaW5kZXggb3JkZXIsIGJ1dCB3ZSBkb24ndCByZWx5IG9uIHRoYXQuXG4gICAgICB2YXIgcmVzdWx0SW5kZXg7XG4gICAgICBmb3IgKHJlc3VsdEluZGV4IGluIG1hcmt1cExpc3RCeU5vZGVOYW1lKSB7XG4gICAgICAgIGlmIChtYXJrdXBMaXN0QnlOb2RlTmFtZS5oYXNPd25Qcm9wZXJ0eShyZXN1bHRJbmRleCkpIHtcbiAgICAgICAgICB2YXIgbWFya3VwID0gbWFya3VwTGlzdEJ5Tm9kZU5hbWVbcmVzdWx0SW5kZXhdO1xuXG4gICAgICAgICAgLy8gUHVzaCB0aGUgcmVxdWVzdGVkIG1hcmt1cCB3aXRoIGFuIGFkZGl0aW9uYWwgUkVTVUxUX0lOREVYX0FUVFJcbiAgICAgICAgICAvLyBhdHRyaWJ1dGUuICBJZiB0aGUgbWFya3VwIGRvZXMgbm90IHN0YXJ0IHdpdGggYSA8IGNoYXJhY3RlciwgaXRcbiAgICAgICAgICAvLyB3aWxsIGJlIGRpc2NhcmRlZCBiZWxvdyAod2l0aCBhbiBhcHByb3ByaWF0ZSBjb25zb2xlLmVycm9yKS5cbiAgICAgICAgICBtYXJrdXBMaXN0QnlOb2RlTmFtZVtyZXN1bHRJbmRleF0gPSBtYXJrdXAucmVwbGFjZShPUEVOX1RBR19OQU1FX0VYUCxcbiAgICAgICAgICAvLyBUaGlzIGluZGV4IHdpbGwgYmUgcGFyc2VkIGJhY2sgb3V0IGJlbG93LlxuICAgICAgICAgICckMSAnICsgUkVTVUxUX0lOREVYX0FUVFIgKyAnPVwiJyArIHJlc3VsdEluZGV4ICsgJ1wiICcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbmRlciBlYWNoIGdyb3VwIG9mIG1hcmt1cCB3aXRoIHNpbWlsYXIgd3JhcHBpbmcgYG5vZGVOYW1lYC5cbiAgICAgIHZhciByZW5kZXJOb2RlcyA9IGNyZWF0ZU5vZGVzRnJvbU1hcmt1cChtYXJrdXBMaXN0QnlOb2RlTmFtZS5qb2luKCcnKSwgZW1wdHlGdW5jdGlvbiAvLyBEbyBub3RoaW5nIHNwZWNpYWwgd2l0aCA8c2NyaXB0PiB0YWdzLlxuICAgICAgKTtcblxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCByZW5kZXJOb2Rlcy5sZW5ndGg7ICsraikge1xuICAgICAgICB2YXIgcmVuZGVyTm9kZSA9IHJlbmRlck5vZGVzW2pdO1xuICAgICAgICBpZiAocmVuZGVyTm9kZS5oYXNBdHRyaWJ1dGUgJiYgcmVuZGVyTm9kZS5oYXNBdHRyaWJ1dGUoUkVTVUxUX0lOREVYX0FUVFIpKSB7XG5cbiAgICAgICAgICByZXN1bHRJbmRleCA9ICtyZW5kZXJOb2RlLmdldEF0dHJpYnV0ZShSRVNVTFRfSU5ERVhfQVRUUik7XG4gICAgICAgICAgcmVuZGVyTm9kZS5yZW1vdmVBdHRyaWJ1dGUoUkVTVUxUX0lOREVYX0FUVFIpO1xuXG4gICAgICAgICAgISFyZXN1bHRMaXN0Lmhhc093blByb3BlcnR5KHJlc3VsdEluZGV4KSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdEYW5nZXI6IEFzc2lnbmluZyB0byBhbiBhbHJlYWR5LW9jY3VwaWVkIHJlc3VsdCBpbmRleC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICByZXN1bHRMaXN0W3Jlc3VsdEluZGV4XSA9IHJlbmRlck5vZGU7XG5cbiAgICAgICAgICAvLyBUaGlzIHNob3VsZCBtYXRjaCByZXN1bHRMaXN0Lmxlbmd0aCBhbmQgbWFya3VwTGlzdC5sZW5ndGggd2hlblxuICAgICAgICAgIC8vIHdlJ3JlIGRvbmUuXG4gICAgICAgICAgcmVzdWx0TGlzdEFzc2lnbm1lbnRDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdEYW5nZXI6IERpc2NhcmRpbmcgdW5leHBlY3RlZCBub2RlOicsIHJlbmRlck5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWx0aG91Z2ggcmVzdWx0TGlzdCB3YXMgcG9wdWxhdGVkIG91dCBvZiBvcmRlciwgaXQgc2hvdWxkIG5vdyBiZSBhIGRlbnNlXG4gICAgLy8gYXJyYXkuXG4gICAgIShyZXN1bHRMaXN0QXNzaWdubWVudENvdW50ID09PSByZXN1bHRMaXN0Lmxlbmd0aCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRGFuZ2VyOiBEaWQgbm90IGFzc2lnbiB0byBldmVyeSBpbmRleCBvZiByZXN1bHRMaXN0LicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgICEocmVzdWx0TGlzdC5sZW5ndGggPT09IG1hcmt1cExpc3QubGVuZ3RoKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdEYW5nZXI6IEV4cGVjdGVkIG1hcmt1cCB0byByZW5kZXIgJXMgbm9kZXMsIGJ1dCByZW5kZXJlZCAlcy4nLCBtYXJrdXBMaXN0Lmxlbmd0aCwgcmVzdWx0TGlzdC5sZW5ndGgpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiByZXN1bHRMaXN0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhIG5vZGUgd2l0aCBhIHN0cmluZyBvZiBtYXJrdXAgYXQgaXRzIGN1cnJlbnQgcG9zaXRpb24gd2l0aGluIGl0c1xuICAgKiBwYXJlbnQuIFRoZSBtYXJrdXAgbXVzdCByZW5kZXIgaW50byBhIHNpbmdsZSByb290IG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gb2xkQ2hpbGQgQ2hpbGQgbm9kZSB0byByZXBsYWNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIE1hcmt1cCB0byByZW5kZXIgaW4gcGxhY2Ugb2YgdGhlIGNoaWxkIG5vZGUuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZGFuZ2Vyb3VzbHlSZXBsYWNlTm9kZVdpdGhNYXJrdXA6IGZ1bmN0aW9uIChvbGRDaGlsZCwgbWFya3VwKSB7XG4gICAgIUV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdkYW5nZXJvdXNseVJlcGxhY2VOb2RlV2l0aE1hcmt1cCguLi4pOiBDYW5ub3QgcmVuZGVyIG1hcmt1cCBpbiBhICcgKyAnd29ya2VyIHRocmVhZC4gTWFrZSBzdXJlIGB3aW5kb3dgIGFuZCBgZG9jdW1lbnRgIGFyZSBhdmFpbGFibGUgJyArICdnbG9iYWxseSBiZWZvcmUgcmVxdWlyaW5nIFJlYWN0IHdoZW4gdW5pdCB0ZXN0aW5nIG9yIHVzZSAnICsgJ1JlYWN0RE9NU2VydmVyLnJlbmRlclRvU3RyaW5nKCkgZm9yIHNlcnZlciByZW5kZXJpbmcuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICFtYXJrdXAgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnZGFuZ2Vyb3VzbHlSZXBsYWNlTm9kZVdpdGhNYXJrdXAoLi4uKTogTWlzc2luZyBtYXJrdXAuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICEob2xkQ2hpbGQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnaHRtbCcpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2Rhbmdlcm91c2x5UmVwbGFjZU5vZGVXaXRoTWFya3VwKC4uLik6IENhbm5vdCByZXBsYWNlIG1hcmt1cCBvZiB0aGUgJyArICc8aHRtbD4gbm9kZS4gVGhpcyBpcyBiZWNhdXNlIGJyb3dzZXIgcXVpcmtzIG1ha2UgdGhpcyB1bnJlbGlhYmxlICcgKyAnYW5kL29yIHNsb3cuIElmIHlvdSB3YW50IHRvIHJlbmRlciB0byB0aGUgcm9vdCB5b3UgbXVzdCB1c2UgJyArICdzZXJ2ZXIgcmVuZGVyaW5nLiBTZWUgUmVhY3RET01TZXJ2ZXIucmVuZGVyVG9TdHJpbmcoKS4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgbmV3Q2hpbGQ7XG4gICAgaWYgKHR5cGVvZiBtYXJrdXAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBuZXdDaGlsZCA9IGNyZWF0ZU5vZGVzRnJvbU1hcmt1cChtYXJrdXAsIGVtcHR5RnVuY3Rpb24pWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdDaGlsZCA9IG1hcmt1cDtcbiAgICB9XG4gICAgb2xkQ2hpbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQsIG9sZENoaWxkKTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IERhbmdlcjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgRGVmYXVsdEV2ZW50UGx1Z2luT3JkZXJcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBrZXlPZiA9IHJlcXVpcmUoJ2ZianMvbGliL2tleU9mJyk7XG5cbi8qKlxuICogTW9kdWxlIHRoYXQgaXMgaW5qZWN0YWJsZSBpbnRvIGBFdmVudFBsdWdpbkh1YmAsIHRoYXQgc3BlY2lmaWVzIGFcbiAqIGRldGVybWluaXN0aWMgb3JkZXJpbmcgb2YgYEV2ZW50UGx1Z2luYHMuIEEgY29udmVuaWVudCB3YXkgdG8gcmVhc29uIGFib3V0XG4gKiBwbHVnaW5zLCB3aXRob3V0IGhhdmluZyB0byBwYWNrYWdlIGV2ZXJ5IG9uZSBvZiB0aGVtLiBUaGlzIGlzIGJldHRlciB0aGFuXG4gKiBoYXZpbmcgcGx1Z2lucyBiZSBvcmRlcmVkIGluIHRoZSBzYW1lIG9yZGVyIHRoYXQgdGhleSBhcmUgaW5qZWN0ZWQgYmVjYXVzZVxuICogdGhhdCBvcmRlcmluZyB3b3VsZCBiZSBpbmZsdWVuY2VkIGJ5IHRoZSBwYWNrYWdpbmcgb3JkZXIuXG4gKiBgUmVzcG9uZGVyRXZlbnRQbHVnaW5gIG11c3Qgb2NjdXIgYmVmb3JlIGBTaW1wbGVFdmVudFBsdWdpbmAgc28gdGhhdFxuICogcHJldmVudGluZyBkZWZhdWx0IG9uIGV2ZW50cyBpcyBjb252ZW5pZW50IGluIGBTaW1wbGVFdmVudFBsdWdpbmAgaGFuZGxlcnMuXG4gKi9cbnZhciBEZWZhdWx0RXZlbnRQbHVnaW5PcmRlciA9IFtrZXlPZih7IFJlc3BvbmRlckV2ZW50UGx1Z2luOiBudWxsIH0pLCBrZXlPZih7IFNpbXBsZUV2ZW50UGx1Z2luOiBudWxsIH0pLCBrZXlPZih7IFRhcEV2ZW50UGx1Z2luOiBudWxsIH0pLCBrZXlPZih7IEVudGVyTGVhdmVFdmVudFBsdWdpbjogbnVsbCB9KSwga2V5T2YoeyBDaGFuZ2VFdmVudFBsdWdpbjogbnVsbCB9KSwga2V5T2YoeyBTZWxlY3RFdmVudFBsdWdpbjogbnVsbCB9KSwga2V5T2YoeyBCZWZvcmVJbnB1dEV2ZW50UGx1Z2luOiBudWxsIH0pXTtcblxubW9kdWxlLmV4cG9ydHMgPSBEZWZhdWx0RXZlbnRQbHVnaW5PcmRlcjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgRW50ZXJMZWF2ZUV2ZW50UGx1Z2luXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV2ZW50Q29uc3RhbnRzID0gcmVxdWlyZSgnLi9FdmVudENvbnN0YW50cycpO1xudmFyIEV2ZW50UHJvcGFnYXRvcnMgPSByZXF1aXJlKCcuL0V2ZW50UHJvcGFnYXRvcnMnKTtcbnZhciBTeW50aGV0aWNNb3VzZUV2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNNb3VzZUV2ZW50Jyk7XG5cbnZhciBSZWFjdE1vdW50ID0gcmVxdWlyZSgnLi9SZWFjdE1vdW50Jyk7XG52YXIga2V5T2YgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlPZicpO1xuXG52YXIgdG9wTGV2ZWxUeXBlcyA9IEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXM7XG52YXIgZ2V0Rmlyc3RSZWFjdERPTSA9IFJlYWN0TW91bnQuZ2V0Rmlyc3RSZWFjdERPTTtcblxudmFyIGV2ZW50VHlwZXMgPSB7XG4gIG1vdXNlRW50ZXI6IHtcbiAgICByZWdpc3RyYXRpb25OYW1lOiBrZXlPZih7IG9uTW91c2VFbnRlcjogbnVsbCB9KSxcbiAgICBkZXBlbmRlbmNpZXM6IFt0b3BMZXZlbFR5cGVzLnRvcE1vdXNlT3V0LCB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlT3Zlcl1cbiAgfSxcbiAgbW91c2VMZWF2ZToge1xuICAgIHJlZ2lzdHJhdGlvbk5hbWU6IGtleU9mKHsgb25Nb3VzZUxlYXZlOiBudWxsIH0pLFxuICAgIGRlcGVuZGVuY2llczogW3RvcExldmVsVHlwZXMudG9wTW91c2VPdXQsIHRvcExldmVsVHlwZXMudG9wTW91c2VPdmVyXVxuICB9XG59O1xuXG52YXIgZXh0cmFjdGVkRXZlbnRzID0gW251bGwsIG51bGxdO1xuXG52YXIgRW50ZXJMZWF2ZUV2ZW50UGx1Z2luID0ge1xuXG4gIGV2ZW50VHlwZXM6IGV2ZW50VHlwZXMsXG5cbiAgLyoqXG4gICAqIEZvciBhbG1vc3QgZXZlcnkgaW50ZXJhY3Rpb24gd2UgY2FyZSBhYm91dCwgdGhlcmUgd2lsbCBiZSBib3RoIGEgdG9wLWxldmVsXG4gICAqIGBtb3VzZW92ZXJgIGFuZCBgbW91c2VvdXRgIGV2ZW50IHRoYXQgb2NjdXJzLiBPbmx5IHVzZSBgbW91c2VvdXRgIHNvIHRoYXRcbiAgICogd2UgZG8gbm90IGV4dHJhY3QgZHVwbGljYXRlIGV2ZW50cy4gSG93ZXZlciwgbW92aW5nIHRoZSBtb3VzZSBpbnRvIHRoZVxuICAgKiBicm93c2VyIGZyb20gb3V0c2lkZSB3aWxsIG5vdCBmaXJlIGEgYG1vdXNlb3V0YCBldmVudC4gSW4gdGhpcyBjYXNlLCB3ZSB1c2VcbiAgICogdGhlIGBtb3VzZW92ZXJgIHRvcC1sZXZlbCBldmVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVHlwZSBSZWNvcmQgZnJvbSBgRXZlbnRDb25zdGFudHNgLlxuICAgKiBAcGFyYW0ge0RPTUV2ZW50VGFyZ2V0fSB0b3BMZXZlbFRhcmdldCBUaGUgbGlzdGVuaW5nIGNvbXBvbmVudCByb290IG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFRhcmdldElEIElEIG9mIGB0b3BMZXZlbFRhcmdldGAuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Kn0gQW4gYWNjdW11bGF0aW9uIG9mIHN5bnRoZXRpYyBldmVudHMuXG4gICAqIEBzZWUge0V2ZW50UGx1Z2luSHViLmV4dHJhY3RFdmVudHN9XG4gICAqL1xuICBleHRyYWN0RXZlbnRzOiBmdW5jdGlvbiAodG9wTGV2ZWxUeXBlLCB0b3BMZXZlbFRhcmdldCwgdG9wTGV2ZWxUYXJnZXRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gICAgaWYgKHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BNb3VzZU92ZXIgJiYgKG5hdGl2ZUV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgbmF0aXZlRXZlbnQuZnJvbUVsZW1lbnQpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRvcExldmVsVHlwZSAhPT0gdG9wTGV2ZWxUeXBlcy50b3BNb3VzZU91dCAmJiB0b3BMZXZlbFR5cGUgIT09IHRvcExldmVsVHlwZXMudG9wTW91c2VPdmVyKSB7XG4gICAgICAvLyBNdXN0IG5vdCBiZSBhIG1vdXNlIGluIG9yIG1vdXNlIG91dCAtIGlnbm9yaW5nLlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHdpbjtcbiAgICBpZiAodG9wTGV2ZWxUYXJnZXQud2luZG93ID09PSB0b3BMZXZlbFRhcmdldCkge1xuICAgICAgLy8gYHRvcExldmVsVGFyZ2V0YCBpcyBwcm9iYWJseSBhIHdpbmRvdyBvYmplY3QuXG4gICAgICB3aW4gPSB0b3BMZXZlbFRhcmdldDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogRmlndXJlIG91dCB3aHkgYG93bmVyRG9jdW1lbnRgIGlzIHNvbWV0aW1lcyB1bmRlZmluZWQgaW4gSUU4LlxuICAgICAgdmFyIGRvYyA9IHRvcExldmVsVGFyZ2V0Lm93bmVyRG9jdW1lbnQ7XG4gICAgICBpZiAoZG9jKSB7XG4gICAgICAgIHdpbiA9IGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luID0gd2luZG93O1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBmcm9tO1xuICAgIHZhciB0bztcbiAgICB2YXIgZnJvbUlEID0gJyc7XG4gICAgdmFyIHRvSUQgPSAnJztcbiAgICBpZiAodG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlT3V0KSB7XG4gICAgICBmcm9tID0gdG9wTGV2ZWxUYXJnZXQ7XG4gICAgICBmcm9tSUQgPSB0b3BMZXZlbFRhcmdldElEO1xuICAgICAgdG8gPSBnZXRGaXJzdFJlYWN0RE9NKG5hdGl2ZUV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgbmF0aXZlRXZlbnQudG9FbGVtZW50KTtcbiAgICAgIGlmICh0bykge1xuICAgICAgICB0b0lEID0gUmVhY3RNb3VudC5nZXRJRCh0byk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0byA9IHdpbjtcbiAgICAgIH1cbiAgICAgIHRvID0gdG8gfHwgd2luO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcm9tID0gd2luO1xuICAgICAgdG8gPSB0b3BMZXZlbFRhcmdldDtcbiAgICAgIHRvSUQgPSB0b3BMZXZlbFRhcmdldElEO1xuICAgIH1cblxuICAgIGlmIChmcm9tID09PSB0bykge1xuICAgICAgLy8gTm90aGluZyBwZXJ0YWlucyB0byBvdXIgbWFuYWdlZCBjb21wb25lbnRzLlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGxlYXZlID0gU3ludGhldGljTW91c2VFdmVudC5nZXRQb29sZWQoZXZlbnRUeXBlcy5tb3VzZUxlYXZlLCBmcm9tSUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgbGVhdmUudHlwZSA9ICdtb3VzZWxlYXZlJztcbiAgICBsZWF2ZS50YXJnZXQgPSBmcm9tO1xuICAgIGxlYXZlLnJlbGF0ZWRUYXJnZXQgPSB0bztcblxuICAgIHZhciBlbnRlciA9IFN5bnRoZXRpY01vdXNlRXZlbnQuZ2V0UG9vbGVkKGV2ZW50VHlwZXMubW91c2VFbnRlciwgdG9JRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBlbnRlci50eXBlID0gJ21vdXNlZW50ZXInO1xuICAgIGVudGVyLnRhcmdldCA9IHRvO1xuICAgIGVudGVyLnJlbGF0ZWRUYXJnZXQgPSBmcm9tO1xuXG4gICAgRXZlbnRQcm9wYWdhdG9ycy5hY2N1bXVsYXRlRW50ZXJMZWF2ZURpc3BhdGNoZXMobGVhdmUsIGVudGVyLCBmcm9tSUQsIHRvSUQpO1xuXG4gICAgZXh0cmFjdGVkRXZlbnRzWzBdID0gbGVhdmU7XG4gICAgZXh0cmFjdGVkRXZlbnRzWzFdID0gZW50ZXI7XG5cbiAgICByZXR1cm4gZXh0cmFjdGVkRXZlbnRzO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRW50ZXJMZWF2ZUV2ZW50UGx1Z2luOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBFdmVudENvbnN0YW50c1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGtleU1pcnJvciA9IHJlcXVpcmUoJ2ZianMvbGliL2tleU1pcnJvcicpO1xuXG52YXIgUHJvcGFnYXRpb25QaGFzZXMgPSBrZXlNaXJyb3IoeyBidWJibGVkOiBudWxsLCBjYXB0dXJlZDogbnVsbCB9KTtcblxuLyoqXG4gKiBUeXBlcyBvZiByYXcgc2lnbmFscyBmcm9tIHRoZSBicm93c2VyIGNhdWdodCBhdCB0aGUgdG9wIGxldmVsLlxuICovXG52YXIgdG9wTGV2ZWxUeXBlcyA9IGtleU1pcnJvcih7XG4gIHRvcEFib3J0OiBudWxsLFxuICB0b3BCbHVyOiBudWxsLFxuICB0b3BDYW5QbGF5OiBudWxsLFxuICB0b3BDYW5QbGF5VGhyb3VnaDogbnVsbCxcbiAgdG9wQ2hhbmdlOiBudWxsLFxuICB0b3BDbGljazogbnVsbCxcbiAgdG9wQ29tcG9zaXRpb25FbmQ6IG51bGwsXG4gIHRvcENvbXBvc2l0aW9uU3RhcnQ6IG51bGwsXG4gIHRvcENvbXBvc2l0aW9uVXBkYXRlOiBudWxsLFxuICB0b3BDb250ZXh0TWVudTogbnVsbCxcbiAgdG9wQ29weTogbnVsbCxcbiAgdG9wQ3V0OiBudWxsLFxuICB0b3BEb3VibGVDbGljazogbnVsbCxcbiAgdG9wRHJhZzogbnVsbCxcbiAgdG9wRHJhZ0VuZDogbnVsbCxcbiAgdG9wRHJhZ0VudGVyOiBudWxsLFxuICB0b3BEcmFnRXhpdDogbnVsbCxcbiAgdG9wRHJhZ0xlYXZlOiBudWxsLFxuICB0b3BEcmFnT3ZlcjogbnVsbCxcbiAgdG9wRHJhZ1N0YXJ0OiBudWxsLFxuICB0b3BEcm9wOiBudWxsLFxuICB0b3BEdXJhdGlvbkNoYW5nZTogbnVsbCxcbiAgdG9wRW1wdGllZDogbnVsbCxcbiAgdG9wRW5jcnlwdGVkOiBudWxsLFxuICB0b3BFbmRlZDogbnVsbCxcbiAgdG9wRXJyb3I6IG51bGwsXG4gIHRvcEZvY3VzOiBudWxsLFxuICB0b3BJbnB1dDogbnVsbCxcbiAgdG9wS2V5RG93bjogbnVsbCxcbiAgdG9wS2V5UHJlc3M6IG51bGwsXG4gIHRvcEtleVVwOiBudWxsLFxuICB0b3BMb2FkOiBudWxsLFxuICB0b3BMb2FkZWREYXRhOiBudWxsLFxuICB0b3BMb2FkZWRNZXRhZGF0YTogbnVsbCxcbiAgdG9wTG9hZFN0YXJ0OiBudWxsLFxuICB0b3BNb3VzZURvd246IG51bGwsXG4gIHRvcE1vdXNlTW92ZTogbnVsbCxcbiAgdG9wTW91c2VPdXQ6IG51bGwsXG4gIHRvcE1vdXNlT3ZlcjogbnVsbCxcbiAgdG9wTW91c2VVcDogbnVsbCxcbiAgdG9wUGFzdGU6IG51bGwsXG4gIHRvcFBhdXNlOiBudWxsLFxuICB0b3BQbGF5OiBudWxsLFxuICB0b3BQbGF5aW5nOiBudWxsLFxuICB0b3BQcm9ncmVzczogbnVsbCxcbiAgdG9wUmF0ZUNoYW5nZTogbnVsbCxcbiAgdG9wUmVzZXQ6IG51bGwsXG4gIHRvcFNjcm9sbDogbnVsbCxcbiAgdG9wU2Vla2VkOiBudWxsLFxuICB0b3BTZWVraW5nOiBudWxsLFxuICB0b3BTZWxlY3Rpb25DaGFuZ2U6IG51bGwsXG4gIHRvcFN0YWxsZWQ6IG51bGwsXG4gIHRvcFN1Ym1pdDogbnVsbCxcbiAgdG9wU3VzcGVuZDogbnVsbCxcbiAgdG9wVGV4dElucHV0OiBudWxsLFxuICB0b3BUaW1lVXBkYXRlOiBudWxsLFxuICB0b3BUb3VjaENhbmNlbDogbnVsbCxcbiAgdG9wVG91Y2hFbmQ6IG51bGwsXG4gIHRvcFRvdWNoTW92ZTogbnVsbCxcbiAgdG9wVG91Y2hTdGFydDogbnVsbCxcbiAgdG9wVm9sdW1lQ2hhbmdlOiBudWxsLFxuICB0b3BXYWl0aW5nOiBudWxsLFxuICB0b3BXaGVlbDogbnVsbFxufSk7XG5cbnZhciBFdmVudENvbnN0YW50cyA9IHtcbiAgdG9wTGV2ZWxUeXBlczogdG9wTGV2ZWxUeXBlcyxcbiAgUHJvcGFnYXRpb25QaGFzZXM6IFByb3BhZ2F0aW9uUGhhc2VzXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50Q29uc3RhbnRzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBFdmVudFBsdWdpbkh1YlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV2ZW50UGx1Z2luUmVnaXN0cnkgPSByZXF1aXJlKCcuL0V2ZW50UGx1Z2luUmVnaXN0cnknKTtcbnZhciBFdmVudFBsdWdpblV0aWxzID0gcmVxdWlyZSgnLi9FdmVudFBsdWdpblV0aWxzJyk7XG52YXIgUmVhY3RFcnJvclV0aWxzID0gcmVxdWlyZSgnLi9SZWFjdEVycm9yVXRpbHMnKTtcblxudmFyIGFjY3VtdWxhdGVJbnRvID0gcmVxdWlyZSgnLi9hY2N1bXVsYXRlSW50bycpO1xudmFyIGZvckVhY2hBY2N1bXVsYXRlZCA9IHJlcXVpcmUoJy4vZm9yRWFjaEFjY3VtdWxhdGVkJyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxuLyoqXG4gKiBJbnRlcm5hbCBzdG9yZSBmb3IgZXZlbnQgbGlzdGVuZXJzXG4gKi9cbnZhciBsaXN0ZW5lckJhbmsgPSB7fTtcblxuLyoqXG4gKiBJbnRlcm5hbCBxdWV1ZSBvZiBldmVudHMgdGhhdCBoYXZlIGFjY3VtdWxhdGVkIHRoZWlyIGRpc3BhdGNoZXMgYW5kIGFyZVxuICogd2FpdGluZyB0byBoYXZlIHRoZWlyIGRpc3BhdGNoZXMgZXhlY3V0ZWQuXG4gKi9cbnZhciBldmVudFF1ZXVlID0gbnVsbDtcblxuLyoqXG4gKiBEaXNwYXRjaGVzIGFuIGV2ZW50IGFuZCByZWxlYXNlcyBpdCBiYWNrIGludG8gdGhlIHBvb2wsIHVubGVzcyBwZXJzaXN0ZW50LlxuICpcbiAqIEBwYXJhbSB7P29iamVjdH0gZXZlbnQgU3ludGhldGljIGV2ZW50IHRvIGJlIGRpc3BhdGNoZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNpbXVsYXRlZCBJZiB0aGUgZXZlbnQgaXMgc2ltdWxhdGVkIChjaGFuZ2VzIGV4biBiZWhhdmlvcilcbiAqIEBwcml2YXRlXG4gKi9cbnZhciBleGVjdXRlRGlzcGF0Y2hlc0FuZFJlbGVhc2UgPSBmdW5jdGlvbiAoZXZlbnQsIHNpbXVsYXRlZCkge1xuICBpZiAoZXZlbnQpIHtcbiAgICBFdmVudFBsdWdpblV0aWxzLmV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlcihldmVudCwgc2ltdWxhdGVkKTtcblxuICAgIGlmICghZXZlbnQuaXNQZXJzaXN0ZW50KCkpIHtcbiAgICAgIGV2ZW50LmNvbnN0cnVjdG9yLnJlbGVhc2UoZXZlbnQpO1xuICAgIH1cbiAgfVxufTtcbnZhciBleGVjdXRlRGlzcGF0Y2hlc0FuZFJlbGVhc2VTaW11bGF0ZWQgPSBmdW5jdGlvbiAoZSkge1xuICByZXR1cm4gZXhlY3V0ZURpc3BhdGNoZXNBbmRSZWxlYXNlKGUsIHRydWUpO1xufTtcbnZhciBleGVjdXRlRGlzcGF0Y2hlc0FuZFJlbGVhc2VUb3BMZXZlbCA9IGZ1bmN0aW9uIChlKSB7XG4gIHJldHVybiBleGVjdXRlRGlzcGF0Y2hlc0FuZFJlbGVhc2UoZSwgZmFsc2UpO1xufTtcblxuLyoqXG4gKiAtIGBJbnN0YW5jZUhhbmRsZWA6IFtyZXF1aXJlZF0gTW9kdWxlIHRoYXQgcGVyZm9ybXMgbG9naWNhbCB0cmF2ZXJzYWxzIG9mIERPTVxuICogICBoaWVyYXJjaHkgZ2l2ZW4gaWRzIG9mIHRoZSBsb2dpY2FsIERPTSBlbGVtZW50cyBpbnZvbHZlZC5cbiAqL1xudmFyIEluc3RhbmNlSGFuZGxlID0gbnVsbDtcblxuZnVuY3Rpb24gdmFsaWRhdGVJbnN0YW5jZUhhbmRsZSgpIHtcbiAgdmFyIHZhbGlkID0gSW5zdGFuY2VIYW5kbGUgJiYgSW5zdGFuY2VIYW5kbGUudHJhdmVyc2VUd29QaGFzZSAmJiBJbnN0YW5jZUhhbmRsZS50cmF2ZXJzZUVudGVyTGVhdmU7XG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHZhbGlkLCAnSW5zdGFuY2VIYW5kbGUgbm90IGluamVjdGVkIGJlZm9yZSB1c2UhJykgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVGhpcyBpcyBhIHVuaWZpZWQgaW50ZXJmYWNlIGZvciBldmVudCBwbHVnaW5zIHRvIGJlIGluc3RhbGxlZCBhbmQgY29uZmlndXJlZC5cbiAqXG4gKiBFdmVudCBwbHVnaW5zIGNhbiBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICAgYGV4dHJhY3RFdmVudHNgIHtmdW5jdGlvbihzdHJpbmcsIERPTUV2ZW50VGFyZ2V0LCBzdHJpbmcsIG9iamVjdCk6ICp9XG4gKiAgICAgUmVxdWlyZWQuIFdoZW4gYSB0b3AtbGV2ZWwgZXZlbnQgaXMgZmlyZWQsIHRoaXMgbWV0aG9kIGlzIGV4cGVjdGVkIHRvXG4gKiAgICAgZXh0cmFjdCBzeW50aGV0aWMgZXZlbnRzIHRoYXQgd2lsbCBpbiB0dXJuIGJlIHF1ZXVlZCBhbmQgZGlzcGF0Y2hlZC5cbiAqXG4gKiAgIGBldmVudFR5cGVzYCB7b2JqZWN0fVxuICogICAgIE9wdGlvbmFsLCBwbHVnaW5zIHRoYXQgZmlyZSBldmVudHMgbXVzdCBwdWJsaXNoIGEgbWFwcGluZyBvZiByZWdpc3RyYXRpb25cbiAqICAgICBuYW1lcyB0aGF0IGFyZSB1c2VkIHRvIHJlZ2lzdGVyIGxpc3RlbmVycy4gVmFsdWVzIG9mIHRoaXMgbWFwcGluZyBtdXN0XG4gKiAgICAgYmUgb2JqZWN0cyB0aGF0IGNvbnRhaW4gYHJlZ2lzdHJhdGlvbk5hbWVgIG9yIGBwaGFzZWRSZWdpc3RyYXRpb25OYW1lc2AuXG4gKlxuICogICBgZXhlY3V0ZURpc3BhdGNoYCB7ZnVuY3Rpb24ob2JqZWN0LCBmdW5jdGlvbiwgc3RyaW5nKX1cbiAqICAgICBPcHRpb25hbCwgYWxsb3dzIHBsdWdpbnMgdG8gb3ZlcnJpZGUgaG93IGFuIGV2ZW50IGdldHMgZGlzcGF0Y2hlZC4gQnlcbiAqICAgICBkZWZhdWx0LCB0aGUgbGlzdGVuZXIgaXMgc2ltcGx5IGludm9rZWQuXG4gKlxuICogRWFjaCBwbHVnaW4gdGhhdCBpcyBpbmplY3RlZCBpbnRvIGBFdmVudHNQbHVnaW5IdWJgIGlzIGltbWVkaWF0ZWx5IG9wZXJhYmxlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xudmFyIEV2ZW50UGx1Z2luSHViID0ge1xuXG4gIC8qKlxuICAgKiBNZXRob2RzIGZvciBpbmplY3RpbmcgZGVwZW5kZW5jaWVzLlxuICAgKi9cbiAgaW5qZWN0aW9uOiB7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gSW5qZWN0ZWRNb3VudFxuICAgICAqIEBwdWJsaWNcbiAgICAgKi9cbiAgICBpbmplY3RNb3VudDogRXZlbnRQbHVnaW5VdGlscy5pbmplY3Rpb24uaW5qZWN0TW91bnQsXG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gSW5qZWN0ZWRJbnN0YW5jZUhhbmRsZVxuICAgICAqIEBwdWJsaWNcbiAgICAgKi9cbiAgICBpbmplY3RJbnN0YW5jZUhhbmRsZTogZnVuY3Rpb24gKEluamVjdGVkSW5zdGFuY2VIYW5kbGUpIHtcbiAgICAgIEluc3RhbmNlSGFuZGxlID0gSW5qZWN0ZWRJbnN0YW5jZUhhbmRsZTtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2VIYW5kbGUoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0SW5zdGFuY2VIYW5kbGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHZhbGlkYXRlSW5zdGFuY2VIYW5kbGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBJbnN0YW5jZUhhbmRsZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHthcnJheX0gSW5qZWN0ZWRFdmVudFBsdWdpbk9yZGVyXG4gICAgICogQHB1YmxpY1xuICAgICAqL1xuICAgIGluamVjdEV2ZW50UGx1Z2luT3JkZXI6IEV2ZW50UGx1Z2luUmVnaXN0cnkuaW5qZWN0RXZlbnRQbHVnaW5PcmRlcixcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBpbmplY3RlZE5hbWVzVG9QbHVnaW5zIE1hcCBmcm9tIG5hbWVzIHRvIHBsdWdpbiBtb2R1bGVzLlxuICAgICAqL1xuICAgIGluamVjdEV2ZW50UGx1Z2luc0J5TmFtZTogRXZlbnRQbHVnaW5SZWdpc3RyeS5pbmplY3RFdmVudFBsdWdpbnNCeU5hbWVcblxuICB9LFxuXG4gIGV2ZW50TmFtZURpc3BhdGNoQ29uZmlnczogRXZlbnRQbHVnaW5SZWdpc3RyeS5ldmVudE5hbWVEaXNwYXRjaENvbmZpZ3MsXG5cbiAgcmVnaXN0cmF0aW9uTmFtZU1vZHVsZXM6IEV2ZW50UGx1Z2luUmVnaXN0cnkucmVnaXN0cmF0aW9uTmFtZU1vZHVsZXMsXG5cbiAgLyoqXG4gICAqIFN0b3JlcyBgbGlzdGVuZXJgIGF0IGBsaXN0ZW5lckJhbmtbcmVnaXN0cmF0aW9uTmFtZV1baWRdYC4gSXMgaWRlbXBvdGVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIG9mIHRoZSBET00gZWxlbWVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlZ2lzdHJhdGlvbk5hbWUgTmFtZSBvZiBsaXN0ZW5lciAoZS5nLiBgb25DbGlja2ApLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGNhbGxiYWNrIHRvIHN0b3JlLlxuICAgKi9cbiAgcHV0TGlzdGVuZXI6IGZ1bmN0aW9uIChpZCwgcmVnaXN0cmF0aW9uTmFtZSwgbGlzdGVuZXIpIHtcbiAgICAhKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRXhwZWN0ZWQgJXMgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgdHlwZSAlcycsIHJlZ2lzdHJhdGlvbk5hbWUsIHR5cGVvZiBsaXN0ZW5lcikgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgdmFyIGJhbmtGb3JSZWdpc3RyYXRpb25OYW1lID0gbGlzdGVuZXJCYW5rW3JlZ2lzdHJhdGlvbk5hbWVdIHx8IChsaXN0ZW5lckJhbmtbcmVnaXN0cmF0aW9uTmFtZV0gPSB7fSk7XG4gICAgYmFua0ZvclJlZ2lzdHJhdGlvbk5hbWVbaWRdID0gbGlzdGVuZXI7XG5cbiAgICB2YXIgUGx1Z2luTW9kdWxlID0gRXZlbnRQbHVnaW5SZWdpc3RyeS5yZWdpc3RyYXRpb25OYW1lTW9kdWxlc1tyZWdpc3RyYXRpb25OYW1lXTtcbiAgICBpZiAoUGx1Z2luTW9kdWxlICYmIFBsdWdpbk1vZHVsZS5kaWRQdXRMaXN0ZW5lcikge1xuICAgICAgUGx1Z2luTW9kdWxlLmRpZFB1dExpc3RlbmVyKGlkLCByZWdpc3RyYXRpb25OYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgb2YgdGhlIERPTSBlbGVtZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVnaXN0cmF0aW9uTmFtZSBOYW1lIG9mIGxpc3RlbmVyIChlLmcuIGBvbkNsaWNrYCkuXG4gICAqIEByZXR1cm4gez9mdW5jdGlvbn0gVGhlIHN0b3JlZCBjYWxsYmFjay5cbiAgICovXG4gIGdldExpc3RlbmVyOiBmdW5jdGlvbiAoaWQsIHJlZ2lzdHJhdGlvbk5hbWUpIHtcbiAgICB2YXIgYmFua0ZvclJlZ2lzdHJhdGlvbk5hbWUgPSBsaXN0ZW5lckJhbmtbcmVnaXN0cmF0aW9uTmFtZV07XG4gICAgcmV0dXJuIGJhbmtGb3JSZWdpc3RyYXRpb25OYW1lICYmIGJhbmtGb3JSZWdpc3RyYXRpb25OYW1lW2lkXTtcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlcyBhIGxpc3RlbmVyIGZyb20gdGhlIHJlZ2lzdHJhdGlvbiBiYW5rLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgb2YgdGhlIERPTSBlbGVtZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVnaXN0cmF0aW9uTmFtZSBOYW1lIG9mIGxpc3RlbmVyIChlLmcuIGBvbkNsaWNrYCkuXG4gICAqL1xuICBkZWxldGVMaXN0ZW5lcjogZnVuY3Rpb24gKGlkLCByZWdpc3RyYXRpb25OYW1lKSB7XG4gICAgdmFyIFBsdWdpbk1vZHVsZSA9IEV2ZW50UGx1Z2luUmVnaXN0cnkucmVnaXN0cmF0aW9uTmFtZU1vZHVsZXNbcmVnaXN0cmF0aW9uTmFtZV07XG4gICAgaWYgKFBsdWdpbk1vZHVsZSAmJiBQbHVnaW5Nb2R1bGUud2lsbERlbGV0ZUxpc3RlbmVyKSB7XG4gICAgICBQbHVnaW5Nb2R1bGUud2lsbERlbGV0ZUxpc3RlbmVyKGlkLCByZWdpc3RyYXRpb25OYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgYmFua0ZvclJlZ2lzdHJhdGlvbk5hbWUgPSBsaXN0ZW5lckJhbmtbcmVnaXN0cmF0aW9uTmFtZV07XG4gICAgLy8gVE9ETzogVGhpcyBzaG91bGQgbmV2ZXIgYmUgbnVsbCAtLSB3aGVuIGlzIGl0P1xuICAgIGlmIChiYW5rRm9yUmVnaXN0cmF0aW9uTmFtZSkge1xuICAgICAgZGVsZXRlIGJhbmtGb3JSZWdpc3RyYXRpb25OYW1lW2lkXTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYWxsIGxpc3RlbmVycyBmb3IgdGhlIERPTSBlbGVtZW50IHdpdGggdGhlIHN1cHBsaWVkIElELlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgb2YgdGhlIERPTSBlbGVtZW50LlxuICAgKi9cbiAgZGVsZXRlQWxsTGlzdGVuZXJzOiBmdW5jdGlvbiAoaWQpIHtcbiAgICBmb3IgKHZhciByZWdpc3RyYXRpb25OYW1lIGluIGxpc3RlbmVyQmFuaykge1xuICAgICAgaWYgKCFsaXN0ZW5lckJhbmtbcmVnaXN0cmF0aW9uTmFtZV1baWRdKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgUGx1Z2luTW9kdWxlID0gRXZlbnRQbHVnaW5SZWdpc3RyeS5yZWdpc3RyYXRpb25OYW1lTW9kdWxlc1tyZWdpc3RyYXRpb25OYW1lXTtcbiAgICAgIGlmIChQbHVnaW5Nb2R1bGUgJiYgUGx1Z2luTW9kdWxlLndpbGxEZWxldGVMaXN0ZW5lcikge1xuICAgICAgICBQbHVnaW5Nb2R1bGUud2lsbERlbGV0ZUxpc3RlbmVyKGlkLCByZWdpc3RyYXRpb25OYW1lKTtcbiAgICAgIH1cblxuICAgICAgZGVsZXRlIGxpc3RlbmVyQmFua1tyZWdpc3RyYXRpb25OYW1lXVtpZF07XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBBbGxvd3MgcmVnaXN0ZXJlZCBwbHVnaW5zIGFuIG9wcG9ydHVuaXR5IHRvIGV4dHJhY3QgZXZlbnRzIGZyb20gdG9wLWxldmVsXG4gICAqIG5hdGl2ZSBicm93c2VyIGV2ZW50cy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVHlwZSBSZWNvcmQgZnJvbSBgRXZlbnRDb25zdGFudHNgLlxuICAgKiBAcGFyYW0ge0RPTUV2ZW50VGFyZ2V0fSB0b3BMZXZlbFRhcmdldCBUaGUgbGlzdGVuaW5nIGNvbXBvbmVudCByb290IG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFRhcmdldElEIElEIG9mIGB0b3BMZXZlbFRhcmdldGAuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Kn0gQW4gYWNjdW11bGF0aW9uIG9mIHN5bnRoZXRpYyBldmVudHMuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZXh0cmFjdEV2ZW50czogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIHZhciBldmVudHM7XG4gICAgdmFyIHBsdWdpbnMgPSBFdmVudFBsdWdpblJlZ2lzdHJ5LnBsdWdpbnM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBOb3QgZXZlcnkgcGx1Z2luIGluIHRoZSBvcmRlcmluZyBtYXkgYmUgbG9hZGVkIGF0IHJ1bnRpbWUuXG4gICAgICB2YXIgcG9zc2libGVQbHVnaW4gPSBwbHVnaW5zW2ldO1xuICAgICAgaWYgKHBvc3NpYmxlUGx1Z2luKSB7XG4gICAgICAgIHZhciBleHRyYWN0ZWRFdmVudHMgPSBwb3NzaWJsZVBsdWdpbi5leHRyYWN0RXZlbnRzKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgICAgIGlmIChleHRyYWN0ZWRFdmVudHMpIHtcbiAgICAgICAgICBldmVudHMgPSBhY2N1bXVsYXRlSW50byhldmVudHMsIGV4dHJhY3RlZEV2ZW50cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGV2ZW50cztcbiAgfSxcblxuICAvKipcbiAgICogRW5xdWV1ZXMgYSBzeW50aGV0aWMgZXZlbnQgdGhhdCBzaG91bGQgYmUgZGlzcGF0Y2hlZCB3aGVuXG4gICAqIGBwcm9jZXNzRXZlbnRRdWV1ZWAgaXMgaW52b2tlZC5cbiAgICpcbiAgICogQHBhcmFtIHsqfSBldmVudHMgQW4gYWNjdW11bGF0aW9uIG9mIHN5bnRoZXRpYyBldmVudHMuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZUV2ZW50czogZnVuY3Rpb24gKGV2ZW50cykge1xuICAgIGlmIChldmVudHMpIHtcbiAgICAgIGV2ZW50UXVldWUgPSBhY2N1bXVsYXRlSW50byhldmVudFF1ZXVlLCBldmVudHMpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhbGwgc3ludGhldGljIGV2ZW50cyBvbiB0aGUgZXZlbnQgcXVldWUuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJvY2Vzc0V2ZW50UXVldWU6IGZ1bmN0aW9uIChzaW11bGF0ZWQpIHtcbiAgICAvLyBTZXQgYGV2ZW50UXVldWVgIHRvIG51bGwgYmVmb3JlIHByb2Nlc3NpbmcgaXQgc28gdGhhdCB3ZSBjYW4gdGVsbCBpZiBtb3JlXG4gICAgLy8gZXZlbnRzIGdldCBlbnF1ZXVlZCB3aGlsZSBwcm9jZXNzaW5nLlxuICAgIHZhciBwcm9jZXNzaW5nRXZlbnRRdWV1ZSA9IGV2ZW50UXVldWU7XG4gICAgZXZlbnRRdWV1ZSA9IG51bGw7XG4gICAgaWYgKHNpbXVsYXRlZCkge1xuICAgICAgZm9yRWFjaEFjY3VtdWxhdGVkKHByb2Nlc3NpbmdFdmVudFF1ZXVlLCBleGVjdXRlRGlzcGF0Y2hlc0FuZFJlbGVhc2VTaW11bGF0ZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JFYWNoQWNjdW11bGF0ZWQocHJvY2Vzc2luZ0V2ZW50UXVldWUsIGV4ZWN1dGVEaXNwYXRjaGVzQW5kUmVsZWFzZVRvcExldmVsKTtcbiAgICB9XG4gICAgISFldmVudFF1ZXVlID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ3Byb2Nlc3NFdmVudFF1ZXVlKCk6IEFkZGl0aW9uYWwgZXZlbnRzIHdlcmUgZW5xdWV1ZWQgd2hpbGUgcHJvY2Vzc2luZyAnICsgJ2FuIGV2ZW50IHF1ZXVlLiBTdXBwb3J0IGZvciB0aGlzIGhhcyBub3QgeWV0IGJlZW4gaW1wbGVtZW50ZWQuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIC8vIFRoaXMgd291bGQgYmUgYSBnb29kIHRpbWUgdG8gcmV0aHJvdyBpZiBhbnkgb2YgdGhlIGV2ZW50IGhhbmRsZXJzIHRocmV3LlxuICAgIFJlYWN0RXJyb3JVdGlscy5yZXRocm93Q2F1Z2h0RXJyb3IoKTtcbiAgfSxcblxuICAvKipcbiAgICogVGhlc2UgYXJlIG5lZWRlZCBmb3IgdGVzdHMgb25seS4gRG8gbm90IHVzZSFcbiAgICovXG4gIF9fcHVyZ2U6IGZ1bmN0aW9uICgpIHtcbiAgICBsaXN0ZW5lckJhbmsgPSB7fTtcbiAgfSxcblxuICBfX2dldExpc3RlbmVyQmFuazogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsaXN0ZW5lckJhbms7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBFdmVudFBsdWdpbkh1YjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgRXZlbnRQbHVnaW5SZWdpc3RyeVxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBJbmplY3RhYmxlIG9yZGVyaW5nIG9mIGV2ZW50IHBsdWdpbnMuXG4gKi9cbnZhciBFdmVudFBsdWdpbk9yZGVyID0gbnVsbDtcblxuLyoqXG4gKiBJbmplY3RhYmxlIG1hcHBpbmcgZnJvbSBuYW1lcyB0byBldmVudCBwbHVnaW4gbW9kdWxlcy5cbiAqL1xudmFyIG5hbWVzVG9QbHVnaW5zID0ge307XG5cbi8qKlxuICogUmVjb21wdXRlcyB0aGUgcGx1Z2luIGxpc3QgdXNpbmcgdGhlIGluamVjdGVkIHBsdWdpbnMgYW5kIHBsdWdpbiBvcmRlcmluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZWNvbXB1dGVQbHVnaW5PcmRlcmluZygpIHtcbiAgaWYgKCFFdmVudFBsdWdpbk9yZGVyKSB7XG4gICAgLy8gV2FpdCB1bnRpbCBhbiBgRXZlbnRQbHVnaW5PcmRlcmAgaXMgaW5qZWN0ZWQuXG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAodmFyIHBsdWdpbk5hbWUgaW4gbmFtZXNUb1BsdWdpbnMpIHtcbiAgICB2YXIgUGx1Z2luTW9kdWxlID0gbmFtZXNUb1BsdWdpbnNbcGx1Z2luTmFtZV07XG4gICAgdmFyIHBsdWdpbkluZGV4ID0gRXZlbnRQbHVnaW5PcmRlci5pbmRleE9mKHBsdWdpbk5hbWUpO1xuICAgICEocGx1Z2luSW5kZXggPiAtMSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRXZlbnRQbHVnaW5SZWdpc3RyeTogQ2Fubm90IGluamVjdCBldmVudCBwbHVnaW5zIHRoYXQgZG8gbm90IGV4aXN0IGluICcgKyAndGhlIHBsdWdpbiBvcmRlcmluZywgYCVzYC4nLCBwbHVnaW5OYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKEV2ZW50UGx1Z2luUmVnaXN0cnkucGx1Z2luc1twbHVnaW5JbmRleF0pIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAhUGx1Z2luTW9kdWxlLmV4dHJhY3RFdmVudHMgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRXZlbnRQbHVnaW5SZWdpc3RyeTogRXZlbnQgcGx1Z2lucyBtdXN0IGltcGxlbWVudCBhbiBgZXh0cmFjdEV2ZW50c2AgJyArICdtZXRob2QsIGJ1dCBgJXNgIGRvZXMgbm90LicsIHBsdWdpbk5hbWUpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICBFdmVudFBsdWdpblJlZ2lzdHJ5LnBsdWdpbnNbcGx1Z2luSW5kZXhdID0gUGx1Z2luTW9kdWxlO1xuICAgIHZhciBwdWJsaXNoZWRFdmVudHMgPSBQbHVnaW5Nb2R1bGUuZXZlbnRUeXBlcztcbiAgICBmb3IgKHZhciBldmVudE5hbWUgaW4gcHVibGlzaGVkRXZlbnRzKSB7XG4gICAgICAhcHVibGlzaEV2ZW50Rm9yUGx1Z2luKHB1Ymxpc2hlZEV2ZW50c1tldmVudE5hbWVdLCBQbHVnaW5Nb2R1bGUsIGV2ZW50TmFtZSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRXZlbnRQbHVnaW5SZWdpc3RyeTogRmFpbGVkIHRvIHB1Ymxpc2ggZXZlbnQgYCVzYCBmb3IgcGx1Z2luIGAlc2AuJywgZXZlbnROYW1lLCBwbHVnaW5OYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUHVibGlzaGVzIGFuIGV2ZW50IHNvIHRoYXQgaXQgY2FuIGJlIGRpc3BhdGNoZWQgYnkgdGhlIHN1cHBsaWVkIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgRGlzcGF0Y2ggY29uZmlndXJhdGlvbiBmb3IgdGhlIGV2ZW50LlxuICogQHBhcmFtIHtvYmplY3R9IFBsdWdpbk1vZHVsZSBQbHVnaW4gcHVibGlzaGluZyB0aGUgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBldmVudCB3YXMgc3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHB1Ymxpc2hFdmVudEZvclBsdWdpbihkaXNwYXRjaENvbmZpZywgUGx1Z2luTW9kdWxlLCBldmVudE5hbWUpIHtcbiAgISFFdmVudFBsdWdpblJlZ2lzdHJ5LmV2ZW50TmFtZURpc3BhdGNoQ29uZmlncy5oYXNPd25Qcm9wZXJ0eShldmVudE5hbWUpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ0V2ZW50UGx1Z2luSHViOiBNb3JlIHRoYW4gb25lIHBsdWdpbiBhdHRlbXB0ZWQgdG8gcHVibGlzaCB0aGUgc2FtZSAnICsgJ2V2ZW50IG5hbWUsIGAlc2AuJywgZXZlbnROYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIEV2ZW50UGx1Z2luUmVnaXN0cnkuZXZlbnROYW1lRGlzcGF0Y2hDb25maWdzW2V2ZW50TmFtZV0gPSBkaXNwYXRjaENvbmZpZztcblxuICB2YXIgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXMgPSBkaXNwYXRjaENvbmZpZy5waGFzZWRSZWdpc3RyYXRpb25OYW1lcztcbiAgaWYgKHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzKSB7XG4gICAgZm9yICh2YXIgcGhhc2VOYW1lIGluIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzKSB7XG4gICAgICBpZiAocGhhc2VkUmVnaXN0cmF0aW9uTmFtZXMuaGFzT3duUHJvcGVydHkocGhhc2VOYW1lKSkge1xuICAgICAgICB2YXIgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZSA9IHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzW3BoYXNlTmFtZV07XG4gICAgICAgIHB1Ymxpc2hSZWdpc3RyYXRpb25OYW1lKHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWUsIFBsdWdpbk1vZHVsZSwgZXZlbnROYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoZGlzcGF0Y2hDb25maWcucmVnaXN0cmF0aW9uTmFtZSkge1xuICAgIHB1Ymxpc2hSZWdpc3RyYXRpb25OYW1lKGRpc3BhdGNoQ29uZmlnLnJlZ2lzdHJhdGlvbk5hbWUsIFBsdWdpbk1vZHVsZSwgZXZlbnROYW1lKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUHVibGlzaGVzIGEgcmVnaXN0cmF0aW9uIG5hbWUgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IGRpc3BhdGNoZWQgZXZlbnRzIGFuZFxuICogY2FuIGJlIHVzZWQgd2l0aCBgRXZlbnRQbHVnaW5IdWIucHV0TGlzdGVuZXJgIHRvIHJlZ2lzdGVyIGxpc3RlbmVycy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnaXN0cmF0aW9uTmFtZSBSZWdpc3RyYXRpb24gbmFtZSB0byBhZGQuXG4gKiBAcGFyYW0ge29iamVjdH0gUGx1Z2luTW9kdWxlIFBsdWdpbiBwdWJsaXNoaW5nIHRoZSBldmVudC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHB1Ymxpc2hSZWdpc3RyYXRpb25OYW1lKHJlZ2lzdHJhdGlvbk5hbWUsIFBsdWdpbk1vZHVsZSwgZXZlbnROYW1lKSB7XG4gICEhRXZlbnRQbHVnaW5SZWdpc3RyeS5yZWdpc3RyYXRpb25OYW1lTW9kdWxlc1tyZWdpc3RyYXRpb25OYW1lXSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdFdmVudFBsdWdpbkh1YjogTW9yZSB0aGFuIG9uZSBwbHVnaW4gYXR0ZW1wdGVkIHRvIHB1Ymxpc2ggdGhlIHNhbWUgJyArICdyZWdpc3RyYXRpb24gbmFtZSwgYCVzYC4nLCByZWdpc3RyYXRpb25OYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIEV2ZW50UGx1Z2luUmVnaXN0cnkucmVnaXN0cmF0aW9uTmFtZU1vZHVsZXNbcmVnaXN0cmF0aW9uTmFtZV0gPSBQbHVnaW5Nb2R1bGU7XG4gIEV2ZW50UGx1Z2luUmVnaXN0cnkucmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llc1tyZWdpc3RyYXRpb25OYW1lXSA9IFBsdWdpbk1vZHVsZS5ldmVudFR5cGVzW2V2ZW50TmFtZV0uZGVwZW5kZW5jaWVzO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBwbHVnaW5zIHNvIHRoYXQgdGhleSBjYW4gZXh0cmFjdCBhbmQgZGlzcGF0Y2ggZXZlbnRzLlxuICpcbiAqIEBzZWUge0V2ZW50UGx1Z2luSHVifVxuICovXG52YXIgRXZlbnRQbHVnaW5SZWdpc3RyeSA9IHtcblxuICAvKipcbiAgICogT3JkZXJlZCBsaXN0IG9mIGluamVjdGVkIHBsdWdpbnMuXG4gICAqL1xuICBwbHVnaW5zOiBbXSxcblxuICAvKipcbiAgICogTWFwcGluZyBmcm9tIGV2ZW50IG5hbWUgdG8gZGlzcGF0Y2ggY29uZmlnXG4gICAqL1xuICBldmVudE5hbWVEaXNwYXRjaENvbmZpZ3M6IHt9LFxuXG4gIC8qKlxuICAgKiBNYXBwaW5nIGZyb20gcmVnaXN0cmF0aW9uIG5hbWUgdG8gcGx1Z2luIG1vZHVsZVxuICAgKi9cbiAgcmVnaXN0cmF0aW9uTmFtZU1vZHVsZXM6IHt9LFxuXG4gIC8qKlxuICAgKiBNYXBwaW5nIGZyb20gcmVnaXN0cmF0aW9uIG5hbWUgdG8gZXZlbnQgbmFtZVxuICAgKi9cbiAgcmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llczoge30sXG5cbiAgLyoqXG4gICAqIEluamVjdHMgYW4gb3JkZXJpbmcgb2YgcGx1Z2lucyAoYnkgcGx1Z2luIG5hbWUpLiBUaGlzIGFsbG93cyB0aGUgb3JkZXJpbmdcbiAgICogdG8gYmUgZGVjb3VwbGVkIGZyb20gaW5qZWN0aW9uIG9mIHRoZSBhY3R1YWwgcGx1Z2lucyBzbyB0aGF0IG9yZGVyaW5nIGlzXG4gICAqIGFsd2F5cyBkZXRlcm1pbmlzdGljIHJlZ2FyZGxlc3Mgb2YgcGFja2FnaW5nLCBvbi10aGUtZmx5IGluamVjdGlvbiwgZXRjLlxuICAgKlxuICAgKiBAcGFyYW0ge2FycmF5fSBJbmplY3RlZEV2ZW50UGx1Z2luT3JkZXJcbiAgICogQGludGVybmFsXG4gICAqIEBzZWUge0V2ZW50UGx1Z2luSHViLmluamVjdGlvbi5pbmplY3RFdmVudFBsdWdpbk9yZGVyfVxuICAgKi9cbiAgaW5qZWN0RXZlbnRQbHVnaW5PcmRlcjogZnVuY3Rpb24gKEluamVjdGVkRXZlbnRQbHVnaW5PcmRlcikge1xuICAgICEhRXZlbnRQbHVnaW5PcmRlciA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdFdmVudFBsdWdpblJlZ2lzdHJ5OiBDYW5ub3QgaW5qZWN0IGV2ZW50IHBsdWdpbiBvcmRlcmluZyBtb3JlIHRoYW4gJyArICdvbmNlLiBZb3UgYXJlIGxpa2VseSB0cnlpbmcgdG8gbG9hZCBtb3JlIHRoYW4gb25lIGNvcHkgb2YgUmVhY3QuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIC8vIENsb25lIHRoZSBvcmRlcmluZyBzbyBpdCBjYW5ub3QgYmUgZHluYW1pY2FsbHkgbXV0YXRlZC5cbiAgICBFdmVudFBsdWdpbk9yZGVyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoSW5qZWN0ZWRFdmVudFBsdWdpbk9yZGVyKTtcbiAgICByZWNvbXB1dGVQbHVnaW5PcmRlcmluZygpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBJbmplY3RzIHBsdWdpbnMgdG8gYmUgdXNlZCBieSBgRXZlbnRQbHVnaW5IdWJgLiBUaGUgcGx1Z2luIG5hbWVzIG11c3QgYmVcbiAgICogaW4gdGhlIG9yZGVyaW5nIGluamVjdGVkIGJ5IGBpbmplY3RFdmVudFBsdWdpbk9yZGVyYC5cbiAgICpcbiAgICogUGx1Z2lucyBjYW4gYmUgaW5qZWN0ZWQgYXMgcGFydCBvZiBwYWdlIGluaXRpYWxpemF0aW9uIG9yIG9uLXRoZS1mbHkuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBpbmplY3RlZE5hbWVzVG9QbHVnaW5zIE1hcCBmcm9tIG5hbWVzIHRvIHBsdWdpbiBtb2R1bGVzLlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHNlZSB7RXZlbnRQbHVnaW5IdWIuaW5qZWN0aW9uLmluamVjdEV2ZW50UGx1Z2luc0J5TmFtZX1cbiAgICovXG4gIGluamVjdEV2ZW50UGx1Z2luc0J5TmFtZTogZnVuY3Rpb24gKGluamVjdGVkTmFtZXNUb1BsdWdpbnMpIHtcbiAgICB2YXIgaXNPcmRlcmluZ0RpcnR5ID0gZmFsc2U7XG4gICAgZm9yICh2YXIgcGx1Z2luTmFtZSBpbiBpbmplY3RlZE5hbWVzVG9QbHVnaW5zKSB7XG4gICAgICBpZiAoIWluamVjdGVkTmFtZXNUb1BsdWdpbnMuaGFzT3duUHJvcGVydHkocGx1Z2luTmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB2YXIgUGx1Z2luTW9kdWxlID0gaW5qZWN0ZWROYW1lc1RvUGx1Z2luc1twbHVnaW5OYW1lXTtcbiAgICAgIGlmICghbmFtZXNUb1BsdWdpbnMuaGFzT3duUHJvcGVydHkocGx1Z2luTmFtZSkgfHwgbmFtZXNUb1BsdWdpbnNbcGx1Z2luTmFtZV0gIT09IFBsdWdpbk1vZHVsZSkge1xuICAgICAgICAhIW5hbWVzVG9QbHVnaW5zW3BsdWdpbk5hbWVdID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ0V2ZW50UGx1Z2luUmVnaXN0cnk6IENhbm5vdCBpbmplY3QgdHdvIGRpZmZlcmVudCBldmVudCBwbHVnaW5zICcgKyAndXNpbmcgdGhlIHNhbWUgbmFtZSwgYCVzYC4nLCBwbHVnaW5OYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgICAgIG5hbWVzVG9QbHVnaW5zW3BsdWdpbk5hbWVdID0gUGx1Z2luTW9kdWxlO1xuICAgICAgICBpc09yZGVyaW5nRGlydHkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNPcmRlcmluZ0RpcnR5KSB7XG4gICAgICByZWNvbXB1dGVQbHVnaW5PcmRlcmluZygpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogTG9va3MgdXAgdGhlIHBsdWdpbiBmb3IgdGhlIHN1cHBsaWVkIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgQSBzeW50aGV0aWMgZXZlbnQuXG4gICAqIEByZXR1cm4gez9vYmplY3R9IFRoZSBwbHVnaW4gdGhhdCBjcmVhdGVkIHRoZSBzdXBwbGllZCBldmVudC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBnZXRQbHVnaW5Nb2R1bGVGb3JFdmVudDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGRpc3BhdGNoQ29uZmlnID0gZXZlbnQuZGlzcGF0Y2hDb25maWc7XG4gICAgaWYgKGRpc3BhdGNoQ29uZmlnLnJlZ2lzdHJhdGlvbk5hbWUpIHtcbiAgICAgIHJldHVybiBFdmVudFBsdWdpblJlZ2lzdHJ5LnJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzW2Rpc3BhdGNoQ29uZmlnLnJlZ2lzdHJhdGlvbk5hbWVdIHx8IG51bGw7XG4gICAgfVxuICAgIGZvciAodmFyIHBoYXNlIGluIGRpc3BhdGNoQ29uZmlnLnBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzKSB7XG4gICAgICBpZiAoIWRpc3BhdGNoQ29uZmlnLnBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzLmhhc093blByb3BlcnR5KHBoYXNlKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBQbHVnaW5Nb2R1bGUgPSBFdmVudFBsdWdpblJlZ2lzdHJ5LnJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzW2Rpc3BhdGNoQ29uZmlnLnBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzW3BoYXNlXV07XG4gICAgICBpZiAoUGx1Z2luTW9kdWxlKSB7XG4gICAgICAgIHJldHVybiBQbHVnaW5Nb2R1bGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9LFxuXG4gIC8qKlxuICAgKiBFeHBvc2VkIGZvciB1bml0IHRlc3RpbmcuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfcmVzZXRFdmVudFBsdWdpbnM6IGZ1bmN0aW9uICgpIHtcbiAgICBFdmVudFBsdWdpbk9yZGVyID0gbnVsbDtcbiAgICBmb3IgKHZhciBwbHVnaW5OYW1lIGluIG5hbWVzVG9QbHVnaW5zKSB7XG4gICAgICBpZiAobmFtZXNUb1BsdWdpbnMuaGFzT3duUHJvcGVydHkocGx1Z2luTmFtZSkpIHtcbiAgICAgICAgZGVsZXRlIG5hbWVzVG9QbHVnaW5zW3BsdWdpbk5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgICBFdmVudFBsdWdpblJlZ2lzdHJ5LnBsdWdpbnMubGVuZ3RoID0gMDtcblxuICAgIHZhciBldmVudE5hbWVEaXNwYXRjaENvbmZpZ3MgPSBFdmVudFBsdWdpblJlZ2lzdHJ5LmV2ZW50TmFtZURpc3BhdGNoQ29uZmlncztcbiAgICBmb3IgKHZhciBldmVudE5hbWUgaW4gZXZlbnROYW1lRGlzcGF0Y2hDb25maWdzKSB7XG4gICAgICBpZiAoZXZlbnROYW1lRGlzcGF0Y2hDb25maWdzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgZGVsZXRlIGV2ZW50TmFtZURpc3BhdGNoQ29uZmlnc1tldmVudE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciByZWdpc3RyYXRpb25OYW1lTW9kdWxlcyA9IEV2ZW50UGx1Z2luUmVnaXN0cnkucmVnaXN0cmF0aW9uTmFtZU1vZHVsZXM7XG4gICAgZm9yICh2YXIgcmVnaXN0cmF0aW9uTmFtZSBpbiByZWdpc3RyYXRpb25OYW1lTW9kdWxlcykge1xuICAgICAgaWYgKHJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzLmhhc093blByb3BlcnR5KHJlZ2lzdHJhdGlvbk5hbWUpKSB7XG4gICAgICAgIGRlbGV0ZSByZWdpc3RyYXRpb25OYW1lTW9kdWxlc1tyZWdpc3RyYXRpb25OYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBFdmVudFBsdWdpblJlZ2lzdHJ5OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBFdmVudFBsdWdpblV0aWxzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgUmVhY3RFcnJvclV0aWxzID0gcmVxdWlyZSgnLi9SZWFjdEVycm9yVXRpbHMnKTtcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbi8qKlxuICogSW5qZWN0ZWQgZGVwZW5kZW5jaWVzOlxuICovXG5cbi8qKlxuICogLSBgTW91bnRgOiBbcmVxdWlyZWRdIE1vZHVsZSB0aGF0IGNhbiBjb252ZXJ0IGJldHdlZW4gUmVhY3QgZG9tIElEcyBhbmRcbiAqICAgYWN0dWFsIG5vZGUgcmVmZXJlbmNlcy5cbiAqL1xudmFyIGluamVjdGlvbiA9IHtcbiAgTW91bnQ6IG51bGwsXG4gIGluamVjdE1vdW50OiBmdW5jdGlvbiAoSW5qZWN0ZWRNb3VudCkge1xuICAgIGluamVjdGlvbi5Nb3VudCA9IEluamVjdGVkTW91bnQ7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKEluamVjdGVkTW91bnQgJiYgSW5qZWN0ZWRNb3VudC5nZXROb2RlICYmIEluamVjdGVkTW91bnQuZ2V0SUQsICdFdmVudFBsdWdpblV0aWxzLmluamVjdGlvbi5pbmplY3RNb3VudCguLi4pOiBJbmplY3RlZCBNb3VudCAnICsgJ21vZHVsZSBpcyBtaXNzaW5nIGdldE5vZGUgb3IgZ2V0SUQuJykgOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59O1xuXG52YXIgdG9wTGV2ZWxUeXBlcyA9IEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXM7XG5cbmZ1bmN0aW9uIGlzRW5kaXNoKHRvcExldmVsVHlwZSkge1xuICByZXR1cm4gdG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlVXAgfHwgdG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcFRvdWNoRW5kIHx8IHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BUb3VjaENhbmNlbDtcbn1cblxuZnVuY3Rpb24gaXNNb3ZlaXNoKHRvcExldmVsVHlwZSkge1xuICByZXR1cm4gdG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlTW92ZSB8fCB0b3BMZXZlbFR5cGUgPT09IHRvcExldmVsVHlwZXMudG9wVG91Y2hNb3ZlO1xufVxuZnVuY3Rpb24gaXNTdGFydGlzaCh0b3BMZXZlbFR5cGUpIHtcbiAgcmV0dXJuIHRvcExldmVsVHlwZSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BNb3VzZURvd24gfHwgdG9wTGV2ZWxUeXBlID09PSB0b3BMZXZlbFR5cGVzLnRvcFRvdWNoU3RhcnQ7XG59XG5cbnZhciB2YWxpZGF0ZUV2ZW50RGlzcGF0Y2hlcztcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhbGlkYXRlRXZlbnREaXNwYXRjaGVzID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGRpc3BhdGNoTGlzdGVuZXJzID0gZXZlbnQuX2Rpc3BhdGNoTGlzdGVuZXJzO1xuICAgIHZhciBkaXNwYXRjaElEcyA9IGV2ZW50Ll9kaXNwYXRjaElEcztcblxuICAgIHZhciBsaXN0ZW5lcnNJc0FyciA9IEFycmF5LmlzQXJyYXkoZGlzcGF0Y2hMaXN0ZW5lcnMpO1xuICAgIHZhciBpZHNJc0FyciA9IEFycmF5LmlzQXJyYXkoZGlzcGF0Y2hJRHMpO1xuICAgIHZhciBJRHNMZW4gPSBpZHNJc0FyciA/IGRpc3BhdGNoSURzLmxlbmd0aCA6IGRpc3BhdGNoSURzID8gMSA6IDA7XG4gICAgdmFyIGxpc3RlbmVyc0xlbiA9IGxpc3RlbmVyc0lzQXJyID8gZGlzcGF0Y2hMaXN0ZW5lcnMubGVuZ3RoIDogZGlzcGF0Y2hMaXN0ZW5lcnMgPyAxIDogMDtcblxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGlkc0lzQXJyID09PSBsaXN0ZW5lcnNJc0FyciAmJiBJRHNMZW4gPT09IGxpc3RlbmVyc0xlbiwgJ0V2ZW50UGx1Z2luVXRpbHM6IEludmFsaWQgYGV2ZW50YC4nKSA6IHVuZGVmaW5lZDtcbiAgfTtcbn1cblxuLyoqXG4gKiBEaXNwYXRjaCB0aGUgZXZlbnQgdG8gdGhlIGxpc3RlbmVyLlxuICogQHBhcmFtIHtTeW50aGV0aWNFdmVudH0gZXZlbnQgU3ludGhldGljRXZlbnQgdG8gaGFuZGxlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNpbXVsYXRlZCBJZiB0aGUgZXZlbnQgaXMgc2ltdWxhdGVkIChjaGFuZ2VzIGV4biBiZWhhdmlvcilcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIEFwcGxpY2F0aW9uLWxldmVsIGNhbGxiYWNrXG4gKiBAcGFyYW0ge3N0cmluZ30gZG9tSUQgRE9NIGlkIHRvIHBhc3MgdG8gdGhlIGNhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBleGVjdXRlRGlzcGF0Y2goZXZlbnQsIHNpbXVsYXRlZCwgbGlzdGVuZXIsIGRvbUlEKSB7XG4gIHZhciB0eXBlID0gZXZlbnQudHlwZSB8fCAndW5rbm93bi1ldmVudCc7XG4gIGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBpbmplY3Rpb24uTW91bnQuZ2V0Tm9kZShkb21JRCk7XG4gIGlmIChzaW11bGF0ZWQpIHtcbiAgICBSZWFjdEVycm9yVXRpbHMuaW52b2tlR3VhcmRlZENhbGxiYWNrV2l0aENhdGNoKHR5cGUsIGxpc3RlbmVyLCBldmVudCwgZG9tSUQpO1xuICB9IGVsc2Uge1xuICAgIFJlYWN0RXJyb3JVdGlscy5pbnZva2VHdWFyZGVkQ2FsbGJhY2sodHlwZSwgbGlzdGVuZXIsIGV2ZW50LCBkb21JRCk7XG4gIH1cbiAgZXZlbnQuY3VycmVudFRhcmdldCA9IG51bGw7XG59XG5cbi8qKlxuICogU3RhbmRhcmQvc2ltcGxlIGl0ZXJhdGlvbiB0aHJvdWdoIGFuIGV2ZW50J3MgY29sbGVjdGVkIGRpc3BhdGNoZXMuXG4gKi9cbmZ1bmN0aW9uIGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlcihldmVudCwgc2ltdWxhdGVkKSB7XG4gIHZhciBkaXNwYXRjaExpc3RlbmVycyA9IGV2ZW50Ll9kaXNwYXRjaExpc3RlbmVycztcbiAgdmFyIGRpc3BhdGNoSURzID0gZXZlbnQuX2Rpc3BhdGNoSURzO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHZhbGlkYXRlRXZlbnREaXNwYXRjaGVzKGV2ZW50KTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShkaXNwYXRjaExpc3RlbmVycykpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpc3BhdGNoTGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vIExpc3RlbmVycyBhbmQgSURzIGFyZSB0d28gcGFyYWxsZWwgYXJyYXlzIHRoYXQgYXJlIGFsd2F5cyBpbiBzeW5jLlxuICAgICAgZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBzaW11bGF0ZWQsIGRpc3BhdGNoTGlzdGVuZXJzW2ldLCBkaXNwYXRjaElEc1tpXSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGRpc3BhdGNoTGlzdGVuZXJzKSB7XG4gICAgZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBzaW11bGF0ZWQsIGRpc3BhdGNoTGlzdGVuZXJzLCBkaXNwYXRjaElEcyk7XG4gIH1cbiAgZXZlbnQuX2Rpc3BhdGNoTGlzdGVuZXJzID0gbnVsbDtcbiAgZXZlbnQuX2Rpc3BhdGNoSURzID0gbnVsbDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZC9zaW1wbGUgaXRlcmF0aW9uIHRocm91Z2ggYW4gZXZlbnQncyBjb2xsZWN0ZWQgZGlzcGF0Y2hlcywgYnV0IHN0b3BzXG4gKiBhdCB0aGUgZmlyc3QgZGlzcGF0Y2ggZXhlY3V0aW9uIHJldHVybmluZyB0cnVlLCBhbmQgcmV0dXJucyB0aGF0IGlkLlxuICpcbiAqIEByZXR1cm4gez9zdHJpbmd9IGlkIG9mIHRoZSBmaXJzdCBkaXNwYXRjaCBleGVjdXRpb24gd2hvJ3MgbGlzdGVuZXIgcmV0dXJuc1xuICogdHJ1ZSwgb3IgbnVsbCBpZiBubyBsaXN0ZW5lciByZXR1cm5lZCB0cnVlLlxuICovXG5mdW5jdGlvbiBleGVjdXRlRGlzcGF0Y2hlc0luT3JkZXJTdG9wQXRUcnVlSW1wbChldmVudCkge1xuICB2YXIgZGlzcGF0Y2hMaXN0ZW5lcnMgPSBldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnM7XG4gIHZhciBkaXNwYXRjaElEcyA9IGV2ZW50Ll9kaXNwYXRjaElEcztcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YWxpZGF0ZUV2ZW50RGlzcGF0Y2hlcyhldmVudCk7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkoZGlzcGF0Y2hMaXN0ZW5lcnMpKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXNwYXRjaExpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLyBMaXN0ZW5lcnMgYW5kIElEcyBhcmUgdHdvIHBhcmFsbGVsIGFycmF5cyB0aGF0IGFyZSBhbHdheXMgaW4gc3luYy5cbiAgICAgIGlmIChkaXNwYXRjaExpc3RlbmVyc1tpXShldmVudCwgZGlzcGF0Y2hJRHNbaV0pKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaElEc1tpXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoZGlzcGF0Y2hMaXN0ZW5lcnMpIHtcbiAgICBpZiAoZGlzcGF0Y2hMaXN0ZW5lcnMoZXZlbnQsIGRpc3BhdGNoSURzKSkge1xuICAgICAgcmV0dXJuIGRpc3BhdGNoSURzO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBAc2VlIGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlclN0b3BBdFRydWVJbXBsXG4gKi9cbmZ1bmN0aW9uIGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlclN0b3BBdFRydWUoZXZlbnQpIHtcbiAgdmFyIHJldCA9IGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlclN0b3BBdFRydWVJbXBsKGV2ZW50KTtcbiAgZXZlbnQuX2Rpc3BhdGNoSURzID0gbnVsbDtcbiAgZXZlbnQuX2Rpc3BhdGNoTGlzdGVuZXJzID0gbnVsbDtcbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBFeGVjdXRpb24gb2YgYSBcImRpcmVjdFwiIGRpc3BhdGNoIC0gdGhlcmUgbXVzdCBiZSBhdCBtb3N0IG9uZSBkaXNwYXRjaFxuICogYWNjdW11bGF0ZWQgb24gdGhlIGV2ZW50IG9yIGl0IGlzIGNvbnNpZGVyZWQgYW4gZXJyb3IuIEl0IGRvZXNuJ3QgcmVhbGx5IG1ha2VcbiAqIHNlbnNlIGZvciBhbiBldmVudCB3aXRoIG11bHRpcGxlIGRpc3BhdGNoZXMgKGJ1YmJsZWQpIHRvIGtlZXAgdHJhY2sgb2YgdGhlXG4gKiByZXR1cm4gdmFsdWVzIGF0IGVhY2ggZGlzcGF0Y2ggZXhlY3V0aW9uLCBidXQgaXQgZG9lcyB0ZW5kIHRvIG1ha2Ugc2Vuc2Ugd2hlblxuICogZGVhbGluZyB3aXRoIFwiZGlyZWN0XCIgZGlzcGF0Y2hlcy5cbiAqXG4gKiBAcmV0dXJuIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIGV4ZWN1dGluZyB0aGUgc2luZ2xlIGRpc3BhdGNoLlxuICovXG5mdW5jdGlvbiBleGVjdXRlRGlyZWN0RGlzcGF0Y2goZXZlbnQpIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YWxpZGF0ZUV2ZW50RGlzcGF0Y2hlcyhldmVudCk7XG4gIH1cbiAgdmFyIGRpc3BhdGNoTGlzdGVuZXIgPSBldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnM7XG4gIHZhciBkaXNwYXRjaElEID0gZXZlbnQuX2Rpc3BhdGNoSURzO1xuICAhIUFycmF5LmlzQXJyYXkoZGlzcGF0Y2hMaXN0ZW5lcikgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnZXhlY3V0ZURpcmVjdERpc3BhdGNoKC4uLik6IEludmFsaWQgYGV2ZW50YC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIHZhciByZXMgPSBkaXNwYXRjaExpc3RlbmVyID8gZGlzcGF0Y2hMaXN0ZW5lcihldmVudCwgZGlzcGF0Y2hJRCkgOiBudWxsO1xuICBldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnMgPSBudWxsO1xuICBldmVudC5fZGlzcGF0Y2hJRHMgPSBudWxsO1xuICByZXR1cm4gcmVzO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7U3ludGhldGljRXZlbnR9IGV2ZW50XG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmZiBudW1iZXIgb2YgZGlzcGF0Y2hlcyBhY2N1bXVsYXRlZCBpcyBncmVhdGVyIHRoYW4gMC5cbiAqL1xuZnVuY3Rpb24gaGFzRGlzcGF0Y2hlcyhldmVudCkge1xuICByZXR1cm4gISFldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnM7XG59XG5cbi8qKlxuICogR2VuZXJhbCB1dGlsaXRpZXMgdGhhdCBhcmUgdXNlZnVsIGluIGNyZWF0aW5nIGN1c3RvbSBFdmVudCBQbHVnaW5zLlxuICovXG52YXIgRXZlbnRQbHVnaW5VdGlscyA9IHtcbiAgaXNFbmRpc2g6IGlzRW5kaXNoLFxuICBpc01vdmVpc2g6IGlzTW92ZWlzaCxcbiAgaXNTdGFydGlzaDogaXNTdGFydGlzaCxcblxuICBleGVjdXRlRGlyZWN0RGlzcGF0Y2g6IGV4ZWN1dGVEaXJlY3REaXNwYXRjaCxcbiAgZXhlY3V0ZURpc3BhdGNoZXNJbk9yZGVyOiBleGVjdXRlRGlzcGF0Y2hlc0luT3JkZXIsXG4gIGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlclN0b3BBdFRydWU6IGV4ZWN1dGVEaXNwYXRjaGVzSW5PcmRlclN0b3BBdFRydWUsXG4gIGhhc0Rpc3BhdGNoZXM6IGhhc0Rpc3BhdGNoZXMsXG5cbiAgZ2V0Tm9kZTogZnVuY3Rpb24gKGlkKSB7XG4gICAgcmV0dXJuIGluamVjdGlvbi5Nb3VudC5nZXROb2RlKGlkKTtcbiAgfSxcbiAgZ2V0SUQ6IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIGluamVjdGlvbi5Nb3VudC5nZXRJRChub2RlKTtcbiAgfSxcblxuICBpbmplY3Rpb246IGluamVjdGlvblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBFdmVudFBsdWdpblV0aWxzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBFdmVudFByb3BhZ2F0b3JzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgRXZlbnRQbHVnaW5IdWIgPSByZXF1aXJlKCcuL0V2ZW50UGx1Z2luSHViJyk7XG5cbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG52YXIgYWNjdW11bGF0ZUludG8gPSByZXF1aXJlKCcuL2FjY3VtdWxhdGVJbnRvJyk7XG52YXIgZm9yRWFjaEFjY3VtdWxhdGVkID0gcmVxdWlyZSgnLi9mb3JFYWNoQWNjdW11bGF0ZWQnKTtcblxudmFyIFByb3BhZ2F0aW9uUGhhc2VzID0gRXZlbnRDb25zdGFudHMuUHJvcGFnYXRpb25QaGFzZXM7XG52YXIgZ2V0TGlzdGVuZXIgPSBFdmVudFBsdWdpbkh1Yi5nZXRMaXN0ZW5lcjtcblxuLyoqXG4gKiBTb21lIGV2ZW50IHR5cGVzIGhhdmUgYSBub3Rpb24gb2YgZGlmZmVyZW50IHJlZ2lzdHJhdGlvbiBuYW1lcyBmb3IgZGlmZmVyZW50XG4gKiBcInBoYXNlc1wiIG9mIHByb3BhZ2F0aW9uLiBUaGlzIGZpbmRzIGxpc3RlbmVycyBieSBhIGdpdmVuIHBoYXNlLlxuICovXG5mdW5jdGlvbiBsaXN0ZW5lckF0UGhhc2UoaWQsIGV2ZW50LCBwcm9wYWdhdGlvblBoYXNlKSB7XG4gIHZhciByZWdpc3RyYXRpb25OYW1lID0gZXZlbnQuZGlzcGF0Y2hDb25maWcucGhhc2VkUmVnaXN0cmF0aW9uTmFtZXNbcHJvcGFnYXRpb25QaGFzZV07XG4gIHJldHVybiBnZXRMaXN0ZW5lcihpZCwgcmVnaXN0cmF0aW9uTmFtZSk7XG59XG5cbi8qKlxuICogVGFncyBhIGBTeW50aGV0aWNFdmVudGAgd2l0aCBkaXNwYXRjaGVkIGxpc3RlbmVycy4gQ3JlYXRpbmcgdGhpcyBmdW5jdGlvblxuICogaGVyZSwgYWxsb3dzIHVzIHRvIG5vdCBoYXZlIHRvIGJpbmQgb3IgY3JlYXRlIGZ1bmN0aW9ucyBmb3IgZWFjaCBldmVudC5cbiAqIE11dGF0aW5nIHRoZSBldmVudCdzIG1lbWJlcnMgYWxsb3dzIHVzIHRvIG5vdCBoYXZlIHRvIGNyZWF0ZSBhIHdyYXBwaW5nXG4gKiBcImRpc3BhdGNoXCIgb2JqZWN0IHRoYXQgcGFpcnMgdGhlIGV2ZW50IHdpdGggdGhlIGxpc3RlbmVyLlxuICovXG5mdW5jdGlvbiBhY2N1bXVsYXRlRGlyZWN0aW9uYWxEaXNwYXRjaGVzKGRvbUlELCB1cHdhcmRzLCBldmVudCkge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGRvbUlELCAnRGlzcGF0Y2hpbmcgaWQgbXVzdCBub3QgYmUgbnVsbCcpIDogdW5kZWZpbmVkO1xuICB9XG4gIHZhciBwaGFzZSA9IHVwd2FyZHMgPyBQcm9wYWdhdGlvblBoYXNlcy5idWJibGVkIDogUHJvcGFnYXRpb25QaGFzZXMuY2FwdHVyZWQ7XG4gIHZhciBsaXN0ZW5lciA9IGxpc3RlbmVyQXRQaGFzZShkb21JRCwgZXZlbnQsIHBoYXNlKTtcbiAgaWYgKGxpc3RlbmVyKSB7XG4gICAgZXZlbnQuX2Rpc3BhdGNoTGlzdGVuZXJzID0gYWNjdW11bGF0ZUludG8oZXZlbnQuX2Rpc3BhdGNoTGlzdGVuZXJzLCBsaXN0ZW5lcik7XG4gICAgZXZlbnQuX2Rpc3BhdGNoSURzID0gYWNjdW11bGF0ZUludG8oZXZlbnQuX2Rpc3BhdGNoSURzLCBkb21JRCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDb2xsZWN0IGRpc3BhdGNoZXMgKG11c3QgYmUgZW50aXJlbHkgY29sbGVjdGVkIGJlZm9yZSBkaXNwYXRjaGluZyAtIHNlZSB1bml0XG4gKiB0ZXN0cykuIExhemlseSBhbGxvY2F0ZSB0aGUgYXJyYXkgdG8gY29uc2VydmUgbWVtb3J5LiAgV2UgbXVzdCBsb29wIHRocm91Z2hcbiAqIGVhY2ggZXZlbnQgYW5kIHBlcmZvcm0gdGhlIHRyYXZlcnNhbCBmb3IgZWFjaCBvbmUuIFdlIGNhbm5vdCBwZXJmb3JtIGFcbiAqIHNpbmdsZSB0cmF2ZXJzYWwgZm9yIHRoZSBlbnRpcmUgY29sbGVjdGlvbiBvZiBldmVudHMgYmVjYXVzZSBlYWNoIGV2ZW50IG1heVxuICogaGF2ZSBhIGRpZmZlcmVudCB0YXJnZXQuXG4gKi9cbmZ1bmN0aW9uIGFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXNTaW5nbGUoZXZlbnQpIHtcbiAgaWYgKGV2ZW50ICYmIGV2ZW50LmRpc3BhdGNoQ29uZmlnLnBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzKSB7XG4gICAgRXZlbnRQbHVnaW5IdWIuaW5qZWN0aW9uLmdldEluc3RhbmNlSGFuZGxlKCkudHJhdmVyc2VUd29QaGFzZShldmVudC5kaXNwYXRjaE1hcmtlciwgYWNjdW11bGF0ZURpcmVjdGlvbmFsRGlzcGF0Y2hlcywgZXZlbnQpO1xuICB9XG59XG5cbi8qKlxuICogU2FtZSBhcyBgYWNjdW11bGF0ZVR3b1BoYXNlRGlzcGF0Y2hlc1NpbmdsZWAsIGJ1dCBza2lwcyBvdmVyIHRoZSB0YXJnZXRJRC5cbiAqL1xuZnVuY3Rpb24gYWNjdW11bGF0ZVR3b1BoYXNlRGlzcGF0Y2hlc1NpbmdsZVNraXBUYXJnZXQoZXZlbnQpIHtcbiAgaWYgKGV2ZW50ICYmIGV2ZW50LmRpc3BhdGNoQ29uZmlnLnBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzKSB7XG4gICAgRXZlbnRQbHVnaW5IdWIuaW5qZWN0aW9uLmdldEluc3RhbmNlSGFuZGxlKCkudHJhdmVyc2VUd29QaGFzZVNraXBUYXJnZXQoZXZlbnQuZGlzcGF0Y2hNYXJrZXIsIGFjY3VtdWxhdGVEaXJlY3Rpb25hbERpc3BhdGNoZXMsIGV2ZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIEFjY3VtdWxhdGVzIHdpdGhvdXQgcmVnYXJkIHRvIGRpcmVjdGlvbiwgZG9lcyBub3QgbG9vayBmb3IgcGhhc2VkXG4gKiByZWdpc3RyYXRpb24gbmFtZXMuIFNhbWUgYXMgYGFjY3VtdWxhdGVEaXJlY3REaXNwYXRjaGVzU2luZ2xlYCBidXQgd2l0aG91dFxuICogcmVxdWlyaW5nIHRoYXQgdGhlIGBkaXNwYXRjaE1hcmtlcmAgYmUgdGhlIHNhbWUgYXMgdGhlIGRpc3BhdGNoZWQgSUQuXG4gKi9cbmZ1bmN0aW9uIGFjY3VtdWxhdGVEaXNwYXRjaGVzKGlkLCBpZ25vcmVkRGlyZWN0aW9uLCBldmVudCkge1xuICBpZiAoZXZlbnQgJiYgZXZlbnQuZGlzcGF0Y2hDb25maWcucmVnaXN0cmF0aW9uTmFtZSkge1xuICAgIHZhciByZWdpc3RyYXRpb25OYW1lID0gZXZlbnQuZGlzcGF0Y2hDb25maWcucmVnaXN0cmF0aW9uTmFtZTtcbiAgICB2YXIgbGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpZCwgcmVnaXN0cmF0aW9uTmFtZSk7XG4gICAgaWYgKGxpc3RlbmVyKSB7XG4gICAgICBldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnMgPSBhY2N1bXVsYXRlSW50byhldmVudC5fZGlzcGF0Y2hMaXN0ZW5lcnMsIGxpc3RlbmVyKTtcbiAgICAgIGV2ZW50Ll9kaXNwYXRjaElEcyA9IGFjY3VtdWxhdGVJbnRvKGV2ZW50Ll9kaXNwYXRjaElEcywgaWQpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFjY3VtdWxhdGVzIGRpc3BhdGNoZXMgb24gYW4gYFN5bnRoZXRpY0V2ZW50YCwgYnV0IG9ubHkgZm9yIHRoZVxuICogYGRpc3BhdGNoTWFya2VyYC5cbiAqIEBwYXJhbSB7U3ludGhldGljRXZlbnR9IGV2ZW50XG4gKi9cbmZ1bmN0aW9uIGFjY3VtdWxhdGVEaXJlY3REaXNwYXRjaGVzU2luZ2xlKGV2ZW50KSB7XG4gIGlmIChldmVudCAmJiBldmVudC5kaXNwYXRjaENvbmZpZy5yZWdpc3RyYXRpb25OYW1lKSB7XG4gICAgYWNjdW11bGF0ZURpc3BhdGNoZXMoZXZlbnQuZGlzcGF0Y2hNYXJrZXIsIG51bGwsIGV2ZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzKGV2ZW50cykge1xuICBmb3JFYWNoQWNjdW11bGF0ZWQoZXZlbnRzLCBhY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzU2luZ2xlKTtcbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZVR3b1BoYXNlRGlzcGF0Y2hlc1NraXBUYXJnZXQoZXZlbnRzKSB7XG4gIGZvckVhY2hBY2N1bXVsYXRlZChldmVudHMsIGFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXNTaW5nbGVTa2lwVGFyZ2V0KTtcbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZUVudGVyTGVhdmVEaXNwYXRjaGVzKGxlYXZlLCBlbnRlciwgZnJvbUlELCB0b0lEKSB7XG4gIEV2ZW50UGx1Z2luSHViLmluamVjdGlvbi5nZXRJbnN0YW5jZUhhbmRsZSgpLnRyYXZlcnNlRW50ZXJMZWF2ZShmcm9tSUQsIHRvSUQsIGFjY3VtdWxhdGVEaXNwYXRjaGVzLCBsZWF2ZSwgZW50ZXIpO1xufVxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlRGlyZWN0RGlzcGF0Y2hlcyhldmVudHMpIHtcbiAgZm9yRWFjaEFjY3VtdWxhdGVkKGV2ZW50cywgYWNjdW11bGF0ZURpcmVjdERpc3BhdGNoZXNTaW5nbGUpO1xufVxuXG4vKipcbiAqIEEgc21hbGwgc2V0IG9mIHByb3BhZ2F0aW9uIHBhdHRlcm5zLCBlYWNoIG9mIHdoaWNoIHdpbGwgYWNjZXB0IGEgc21hbGwgYW1vdW50XG4gKiBvZiBpbmZvcm1hdGlvbiwgYW5kIGdlbmVyYXRlIGEgc2V0IG9mIFwiZGlzcGF0Y2ggcmVhZHkgZXZlbnQgb2JqZWN0c1wiIC0gd2hpY2hcbiAqIGFyZSBzZXRzIG9mIGV2ZW50cyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGFubm90YXRlZCB3aXRoIGEgc2V0IG9mIGRpc3BhdGNoZWRcbiAqIGxpc3RlbmVyIGZ1bmN0aW9ucy9pZHMuIFRoZSBBUEkgaXMgZGVzaWduZWQgdGhpcyB3YXkgdG8gZGlzY291cmFnZSB0aGVzZVxuICogcHJvcGFnYXRpb24gc3RyYXRlZ2llcyBmcm9tIGFjdHVhbGx5IGV4ZWN1dGluZyB0aGUgZGlzcGF0Y2hlcywgc2luY2Ugd2VcbiAqIGFsd2F5cyB3YW50IHRvIGNvbGxlY3QgdGhlIGVudGlyZSBzZXQgb2YgZGlzcGF0Y2hlcyBiZWZvcmUgZXhlY3V0aW5nIGV2ZW50IGFcbiAqIHNpbmdsZSBvbmUuXG4gKlxuICogQGNvbnN0cnVjdG9yIEV2ZW50UHJvcGFnYXRvcnNcbiAqL1xudmFyIEV2ZW50UHJvcGFnYXRvcnMgPSB7XG4gIGFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXM6IGFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXMsXG4gIGFjY3VtdWxhdGVUd29QaGFzZURpc3BhdGNoZXNTa2lwVGFyZ2V0OiBhY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzU2tpcFRhcmdldCxcbiAgYWNjdW11bGF0ZURpcmVjdERpc3BhdGNoZXM6IGFjY3VtdWxhdGVEaXJlY3REaXNwYXRjaGVzLFxuICBhY2N1bXVsYXRlRW50ZXJMZWF2ZURpc3BhdGNoZXM6IGFjY3VtdWxhdGVFbnRlckxlYXZlRGlzcGF0Y2hlc1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBFdmVudFByb3BhZ2F0b3JzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBGYWxsYmFja0NvbXBvc2l0aW9uU3RhdGVcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9vbGVkQ2xhc3MgPSByZXF1aXJlKCcuL1Bvb2xlZENsYXNzJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBnZXRUZXh0Q29udGVudEFjY2Vzc29yID0gcmVxdWlyZSgnLi9nZXRUZXh0Q29udGVudEFjY2Vzc29yJyk7XG5cbi8qKlxuICogVGhpcyBoZWxwZXIgY2xhc3Mgc3RvcmVzIGluZm9ybWF0aW9uIGFib3V0IHRleHQgY29udGVudCBvZiBhIHRhcmdldCBub2RlLFxuICogYWxsb3dpbmcgY29tcGFyaXNvbiBvZiBjb250ZW50IGJlZm9yZSBhbmQgYWZ0ZXIgYSBnaXZlbiBldmVudC5cbiAqXG4gKiBJZGVudGlmeSB0aGUgbm9kZSB3aGVyZSBzZWxlY3Rpb24gY3VycmVudGx5IGJlZ2lucywgdGhlbiBvYnNlcnZlXG4gKiBib3RoIGl0cyB0ZXh0IGNvbnRlbnQgYW5kIGl0cyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBET00uIFNpbmNlIHRoZVxuICogYnJvd3NlciBtYXkgbmF0aXZlbHkgcmVwbGFjZSB0aGUgdGFyZ2V0IG5vZGUgZHVyaW5nIGNvbXBvc2l0aW9uLCB3ZSBjYW5cbiAqIHVzZSBpdHMgcG9zaXRpb24gdG8gZmluZCBpdHMgcmVwbGFjZW1lbnQuXG4gKlxuICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gcm9vdFxuICovXG5mdW5jdGlvbiBGYWxsYmFja0NvbXBvc2l0aW9uU3RhdGUocm9vdCkge1xuICB0aGlzLl9yb290ID0gcm9vdDtcbiAgdGhpcy5fc3RhcnRUZXh0ID0gdGhpcy5nZXRUZXh0KCk7XG4gIHRoaXMuX2ZhbGxiYWNrVGV4dCA9IG51bGw7XG59XG5cbmFzc2lnbihGYWxsYmFja0NvbXBvc2l0aW9uU3RhdGUucHJvdG90eXBlLCB7XG4gIGRlc3RydWN0b3I6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICB0aGlzLl9zdGFydFRleHQgPSBudWxsO1xuICAgIHRoaXMuX2ZhbGxiYWNrVGV4dCA9IG51bGw7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHRleHQgb2YgaW5wdXQuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIGdldFRleHQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoJ3ZhbHVlJyBpbiB0aGlzLl9yb290KSB7XG4gICAgICByZXR1cm4gdGhpcy5fcm9vdC52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Jvb3RbZ2V0VGV4dENvbnRlbnRBY2Nlc3NvcigpXTtcbiAgfSxcblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHRoZSBkaWZmZXJpbmcgc3Vic3RyaW5nIGJldHdlZW4gdGhlIGluaXRpYWxseSBzdG9yZWRcbiAgICogdGV4dCBjb250ZW50IGFuZCB0aGUgY3VycmVudCBjb250ZW50LlxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICBnZXREYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX2ZhbGxiYWNrVGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2ZhbGxiYWNrVGV4dDtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnQ7XG4gICAgdmFyIHN0YXJ0VmFsdWUgPSB0aGlzLl9zdGFydFRleHQ7XG4gICAgdmFyIHN0YXJ0TGVuZ3RoID0gc3RhcnRWYWx1ZS5sZW5ndGg7XG4gICAgdmFyIGVuZDtcbiAgICB2YXIgZW5kVmFsdWUgPSB0aGlzLmdldFRleHQoKTtcbiAgICB2YXIgZW5kTGVuZ3RoID0gZW5kVmFsdWUubGVuZ3RoO1xuXG4gICAgZm9yIChzdGFydCA9IDA7IHN0YXJ0IDwgc3RhcnRMZW5ndGg7IHN0YXJ0KyspIHtcbiAgICAgIGlmIChzdGFydFZhbHVlW3N0YXJ0XSAhPT0gZW5kVmFsdWVbc3RhcnRdKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBtaW5FbmQgPSBzdGFydExlbmd0aCAtIHN0YXJ0O1xuICAgIGZvciAoZW5kID0gMTsgZW5kIDw9IG1pbkVuZDsgZW5kKyspIHtcbiAgICAgIGlmIChzdGFydFZhbHVlW3N0YXJ0TGVuZ3RoIC0gZW5kXSAhPT0gZW5kVmFsdWVbZW5kTGVuZ3RoIC0gZW5kXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc2xpY2VUYWlsID0gZW5kID4gMSA/IDEgLSBlbmQgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZmFsbGJhY2tUZXh0ID0gZW5kVmFsdWUuc2xpY2Uoc3RhcnQsIHNsaWNlVGFpbCk7XG4gICAgcmV0dXJuIHRoaXMuX2ZhbGxiYWNrVGV4dDtcbiAgfVxufSk7XG5cblBvb2xlZENsYXNzLmFkZFBvb2xpbmdUbyhGYWxsYmFja0NvbXBvc2l0aW9uU3RhdGUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhbGxiYWNrQ29tcG9zaXRpb25TdGF0ZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgSFRNTERPTVByb3BlcnR5Q29uZmlnXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRE9NUHJvcGVydHkgPSByZXF1aXJlKCcuL0RPTVByb3BlcnR5Jyk7XG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgTVVTVF9VU0VfQVRUUklCVVRFID0gRE9NUHJvcGVydHkuaW5qZWN0aW9uLk1VU1RfVVNFX0FUVFJJQlVURTtcbnZhciBNVVNUX1VTRV9QUk9QRVJUWSA9IERPTVByb3BlcnR5LmluamVjdGlvbi5NVVNUX1VTRV9QUk9QRVJUWTtcbnZhciBIQVNfQk9PTEVBTl9WQUxVRSA9IERPTVByb3BlcnR5LmluamVjdGlvbi5IQVNfQk9PTEVBTl9WQUxVRTtcbnZhciBIQVNfU0lERV9FRkZFQ1RTID0gRE9NUHJvcGVydHkuaW5qZWN0aW9uLkhBU19TSURFX0VGRkVDVFM7XG52YXIgSEFTX05VTUVSSUNfVkFMVUUgPSBET01Qcm9wZXJ0eS5pbmplY3Rpb24uSEFTX05VTUVSSUNfVkFMVUU7XG52YXIgSEFTX1BPU0lUSVZFX05VTUVSSUNfVkFMVUUgPSBET01Qcm9wZXJ0eS5pbmplY3Rpb24uSEFTX1BPU0lUSVZFX05VTUVSSUNfVkFMVUU7XG52YXIgSEFTX09WRVJMT0FERURfQk9PTEVBTl9WQUxVRSA9IERPTVByb3BlcnR5LmluamVjdGlvbi5IQVNfT1ZFUkxPQURFRF9CT09MRUFOX1ZBTFVFO1xuXG52YXIgaGFzU1ZHO1xuaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICB2YXIgaW1wbGVtZW50YXRpb24gPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbjtcbiAgaGFzU1ZHID0gaW1wbGVtZW50YXRpb24gJiYgaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZSAmJiBpbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKCdodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0Jhc2ljU3RydWN0dXJlJywgJzEuMScpO1xufVxuXG52YXIgSFRNTERPTVByb3BlcnR5Q29uZmlnID0ge1xuICBpc0N1c3RvbUF0dHJpYnV0ZTogUmVnRXhwLnByb3RvdHlwZS50ZXN0LmJpbmQoL14oZGF0YXxhcmlhKS1bYS16X11bYS16XFxkXy5cXC1dKiQvKSxcbiAgUHJvcGVydGllczoge1xuICAgIC8qKlxuICAgICAqIFN0YW5kYXJkIFByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBhY2NlcHQ6IG51bGwsXG4gICAgYWNjZXB0Q2hhcnNldDogbnVsbCxcbiAgICBhY2Nlc3NLZXk6IG51bGwsXG4gICAgYWN0aW9uOiBudWxsLFxuICAgIGFsbG93RnVsbFNjcmVlbjogTVVTVF9VU0VfQVRUUklCVVRFIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgYWxsb3dUcmFuc3BhcmVuY3k6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBhbHQ6IG51bGwsXG4gICAgYXN5bmM6IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIGF1dG9Db21wbGV0ZTogbnVsbCxcbiAgICAvLyBhdXRvRm9jdXMgaXMgcG9seWZpbGxlZC9ub3JtYWxpemVkIGJ5IEF1dG9Gb2N1c1V0aWxzXG4gICAgLy8gYXV0b0ZvY3VzOiBIQVNfQk9PTEVBTl9WQUxVRSxcbiAgICBhdXRvUGxheTogSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgY2FwdHVyZTogTVVTVF9VU0VfQVRUUklCVVRFIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgY2VsbFBhZGRpbmc6IG51bGwsXG4gICAgY2VsbFNwYWNpbmc6IG51bGwsXG4gICAgY2hhclNldDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGNoYWxsZW5nZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGNoZWNrZWQ6IE1VU1RfVVNFX1BST1BFUlRZIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgY2xhc3NJRDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIC8vIFRvIHNldCBjbGFzc05hbWUgb24gU1ZHIGVsZW1lbnRzLCBpdCdzIG5lY2Vzc2FyeSB0byB1c2UgLnNldEF0dHJpYnV0ZTtcbiAgICAvLyB0aGlzIHdvcmtzIG9uIEhUTUwgZWxlbWVudHMgdG9vIGluIGFsbCBicm93c2VycyBleGNlcHQgSUU4LiBDb252ZW5pZW50bHksXG4gICAgLy8gSUU4IGRvZXNuJ3Qgc3VwcG9ydCBTVkcgYW5kIHNvIHdlIGNhbiBzaW1wbHkgdXNlIHRoZSBhdHRyaWJ1dGUgaW5cbiAgICAvLyBicm93c2VycyB0aGF0IHN1cHBvcnQgU1ZHIGFuZCB0aGUgcHJvcGVydHkgaW4gYnJvd3NlcnMgdGhhdCBkb24ndCxcbiAgICAvLyByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgSFRNTCBvciBTVkcuXG4gICAgY2xhc3NOYW1lOiBoYXNTVkcgPyBNVVNUX1VTRV9BVFRSSUJVVEUgOiBNVVNUX1VTRV9QUk9QRVJUWSxcbiAgICBjb2xzOiBNVVNUX1VTRV9BVFRSSUJVVEUgfCBIQVNfUE9TSVRJVkVfTlVNRVJJQ19WQUxVRSxcbiAgICBjb2xTcGFuOiBudWxsLFxuICAgIGNvbnRlbnQ6IG51bGwsXG4gICAgY29udGVudEVkaXRhYmxlOiBudWxsLFxuICAgIGNvbnRleHRNZW51OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgY29udHJvbHM6IE1VU1RfVVNFX1BST1BFUlRZIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgY29vcmRzOiBudWxsLFxuICAgIGNyb3NzT3JpZ2luOiBudWxsLFxuICAgIGRhdGE6IG51bGwsIC8vIEZvciBgPG9iamVjdCAvPmAgYWN0cyBhcyBgc3JjYC5cbiAgICBkYXRlVGltZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgICdkZWZhdWx0JzogSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgZGVmZXI6IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIGRpcjogbnVsbCxcbiAgICBkaXNhYmxlZDogTVVTVF9VU0VfQVRUUklCVVRFIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgZG93bmxvYWQ6IEhBU19PVkVSTE9BREVEX0JPT0xFQU5fVkFMVUUsXG4gICAgZHJhZ2dhYmxlOiBudWxsLFxuICAgIGVuY1R5cGU6IG51bGwsXG4gICAgZm9ybTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGZvcm1BY3Rpb246IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBmb3JtRW5jVHlwZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGZvcm1NZXRob2Q6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBmb3JtTm9WYWxpZGF0ZTogSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgZm9ybVRhcmdldDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGZyYW1lQm9yZGVyOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgaGVhZGVyczogbnVsbCxcbiAgICBoZWlnaHQ6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBoaWRkZW46IE1VU1RfVVNFX0FUVFJJQlVURSB8IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIGhpZ2g6IG51bGwsXG4gICAgaHJlZjogbnVsbCxcbiAgICBocmVmTGFuZzogbnVsbCxcbiAgICBodG1sRm9yOiBudWxsLFxuICAgIGh0dHBFcXVpdjogbnVsbCxcbiAgICBpY29uOiBudWxsLFxuICAgIGlkOiBNVVNUX1VTRV9QUk9QRVJUWSxcbiAgICBpbnB1dE1vZGU6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBpbnRlZ3JpdHk6IG51bGwsXG4gICAgaXM6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBrZXlQYXJhbXM6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBrZXlUeXBlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAga2luZDogbnVsbCxcbiAgICBsYWJlbDogbnVsbCxcbiAgICBsYW5nOiBudWxsLFxuICAgIGxpc3Q6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBsb29wOiBNVVNUX1VTRV9QUk9QRVJUWSB8IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIGxvdzogbnVsbCxcbiAgICBtYW5pZmVzdDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIG1hcmdpbkhlaWdodDogbnVsbCxcbiAgICBtYXJnaW5XaWR0aDogbnVsbCxcbiAgICBtYXg6IG51bGwsXG4gICAgbWF4TGVuZ3RoOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgbWVkaWE6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBtZWRpYUdyb3VwOiBudWxsLFxuICAgIG1ldGhvZDogbnVsbCxcbiAgICBtaW46IG51bGwsXG4gICAgbWluTGVuZ3RoOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgbXVsdGlwbGU6IE1VU1RfVVNFX1BST1BFUlRZIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgbXV0ZWQ6IE1VU1RfVVNFX1BST1BFUlRZIHwgSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgbmFtZTogbnVsbCxcbiAgICBub25jZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIG5vVmFsaWRhdGU6IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIG9wZW46IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIG9wdGltdW06IG51bGwsXG4gICAgcGF0dGVybjogbnVsbCxcbiAgICBwbGFjZWhvbGRlcjogbnVsbCxcbiAgICBwb3N0ZXI6IG51bGwsXG4gICAgcHJlbG9hZDogbnVsbCxcbiAgICByYWRpb0dyb3VwOiBudWxsLFxuICAgIHJlYWRPbmx5OiBNVVNUX1VTRV9QUk9QRVJUWSB8IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIHJlbDogbnVsbCxcbiAgICByZXF1aXJlZDogSEFTX0JPT0xFQU5fVkFMVUUsXG4gICAgcmV2ZXJzZWQ6IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIHJvbGU6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICByb3dzOiBNVVNUX1VTRV9BVFRSSUJVVEUgfCBIQVNfUE9TSVRJVkVfTlVNRVJJQ19WQUxVRSxcbiAgICByb3dTcGFuOiBudWxsLFxuICAgIHNhbmRib3g6IG51bGwsXG4gICAgc2NvcGU6IG51bGwsXG4gICAgc2NvcGVkOiBIQVNfQk9PTEVBTl9WQUxVRSxcbiAgICBzY3JvbGxpbmc6IG51bGwsXG4gICAgc2VhbWxlc3M6IE1VU1RfVVNFX0FUVFJJQlVURSB8IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIHNlbGVjdGVkOiBNVVNUX1VTRV9QUk9QRVJUWSB8IEhBU19CT09MRUFOX1ZBTFVFLFxuICAgIHNoYXBlOiBudWxsLFxuICAgIHNpemU6IE1VU1RfVVNFX0FUVFJJQlVURSB8IEhBU19QT1NJVElWRV9OVU1FUklDX1ZBTFVFLFxuICAgIHNpemVzOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgc3BhbjogSEFTX1BPU0lUSVZFX05VTUVSSUNfVkFMVUUsXG4gICAgc3BlbGxDaGVjazogbnVsbCxcbiAgICBzcmM6IG51bGwsXG4gICAgc3JjRG9jOiBNVVNUX1VTRV9QUk9QRVJUWSxcbiAgICBzcmNMYW5nOiBudWxsLFxuICAgIHNyY1NldDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHN0YXJ0OiBIQVNfTlVNRVJJQ19WQUxVRSxcbiAgICBzdGVwOiBudWxsLFxuICAgIHN0eWxlOiBudWxsLFxuICAgIHN1bW1hcnk6IG51bGwsXG4gICAgdGFiSW5kZXg6IG51bGwsXG4gICAgdGFyZ2V0OiBudWxsLFxuICAgIHRpdGxlOiBudWxsLFxuICAgIHR5cGU6IG51bGwsXG4gICAgdXNlTWFwOiBudWxsLFxuICAgIHZhbHVlOiBNVVNUX1VTRV9QUk9QRVJUWSB8IEhBU19TSURFX0VGRkVDVFMsXG4gICAgd2lkdGg6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB3bW9kZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHdyYXA6IG51bGwsXG5cbiAgICAvKipcbiAgICAgKiBSREZhIFByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBhYm91dDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGRhdGF0eXBlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgaW5saXN0OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgcHJlZml4OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgLy8gcHJvcGVydHkgaXMgYWxzbyBzdXBwb3J0ZWQgZm9yIE9wZW5HcmFwaCBpbiBtZXRhIHRhZ3MuXG4gICAgcHJvcGVydHk6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICByZXNvdXJjZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgICd0eXBlb2YnOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgdm9jYWI6IE1VU1RfVVNFX0FUVFJJQlVURSxcblxuICAgIC8qKlxuICAgICAqIE5vbi1zdGFuZGFyZCBQcm9wZXJ0aWVzXG4gICAgICovXG4gICAgLy8gYXV0b0NhcGl0YWxpemUgYW5kIGF1dG9Db3JyZWN0IGFyZSBzdXBwb3J0ZWQgaW4gTW9iaWxlIFNhZmFyaSBmb3JcbiAgICAvLyBrZXlib2FyZCBoaW50cy5cbiAgICBhdXRvQ2FwaXRhbGl6ZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGF1dG9Db3JyZWN0OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgLy8gYXV0b1NhdmUgYWxsb3dzIFdlYktpdC9CbGluayB0byBwZXJzaXN0IHZhbHVlcyBvZiBpbnB1dCBmaWVsZHMgb24gcGFnZSByZWxvYWRzXG4gICAgYXV0b1NhdmU6IG51bGwsXG4gICAgLy8gY29sb3IgaXMgZm9yIFNhZmFyaSBtYXNrLWljb24gbGlua1xuICAgIGNvbG9yOiBudWxsLFxuICAgIC8vIGl0ZW1Qcm9wLCBpdGVtU2NvcGUsIGl0ZW1UeXBlIGFyZSBmb3JcbiAgICAvLyBNaWNyb2RhdGEgc3VwcG9ydC4gU2VlIGh0dHA6Ly9zY2hlbWEub3JnL2RvY3MvZ3MuaHRtbFxuICAgIGl0ZW1Qcm9wOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgaXRlbVNjb3BlOiBNVVNUX1VTRV9BVFRSSUJVVEUgfCBIQVNfQk9PTEVBTl9WQUxVRSxcbiAgICBpdGVtVHlwZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIC8vIGl0ZW1JRCBhbmQgaXRlbVJlZiBhcmUgZm9yIE1pY3JvZGF0YSBzdXBwb3J0IGFzIHdlbGwgYnV0XG4gICAgLy8gb25seSBzcGVjaWZpZWQgaW4gdGhlIHRoZSBXSEFUV0cgc3BlYyBkb2N1bWVudC4gU2VlXG4gICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvbWljcm9kYXRhLmh0bWwjbWljcm9kYXRhLWRvbS1hcGlcbiAgICBpdGVtSUQ6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBpdGVtUmVmOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgLy8gcmVzdWx0cyBzaG93IGxvb2tpbmcgZ2xhc3MgaWNvbiBhbmQgcmVjZW50IHNlYXJjaGVzIG9uIGlucHV0XG4gICAgLy8gc2VhcmNoIGZpZWxkcyBpbiBXZWJLaXQvQmxpbmtcbiAgICByZXN1bHRzOiBudWxsLFxuICAgIC8vIElFLW9ubHkgYXR0cmlidXRlIHRoYXQgc3BlY2lmaWVzIHNlY3VyaXR5IHJlc3RyaWN0aW9ucyBvbiBhbiBpZnJhbWVcbiAgICAvLyBhcyBhbiBhbHRlcm5hdGl2ZSB0byB0aGUgc2FuZGJveCBhdHRyaWJ1dGUgb24gSUU8MTBcbiAgICBzZWN1cml0eTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIC8vIElFLW9ubHkgYXR0cmlidXRlIHRoYXQgY29udHJvbHMgZm9jdXMgYmVoYXZpb3JcbiAgICB1bnNlbGVjdGFibGU6IE1VU1RfVVNFX0FUVFJJQlVURVxuICB9LFxuICBET01BdHRyaWJ1dGVOYW1lczoge1xuICAgIGFjY2VwdENoYXJzZXQ6ICdhY2NlcHQtY2hhcnNldCcsXG4gICAgY2xhc3NOYW1lOiAnY2xhc3MnLFxuICAgIGh0bWxGb3I6ICdmb3InLFxuICAgIGh0dHBFcXVpdjogJ2h0dHAtZXF1aXYnXG4gIH0sXG4gIERPTVByb3BlcnR5TmFtZXM6IHtcbiAgICBhdXRvQ29tcGxldGU6ICdhdXRvY29tcGxldGUnLFxuICAgIGF1dG9Gb2N1czogJ2F1dG9mb2N1cycsXG4gICAgYXV0b1BsYXk6ICdhdXRvcGxheScsXG4gICAgYXV0b1NhdmU6ICdhdXRvc2F2ZScsXG4gICAgLy8gYGVuY29kaW5nYCBpcyBlcXVpdmFsZW50IHRvIGBlbmN0eXBlYCwgSUU4IGxhY2tzIGFuIGBlbmN0eXBlYCBzZXR0ZXIuXG4gICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNkb20tZnMtZW5jb2RpbmdcbiAgICBlbmNUeXBlOiAnZW5jb2RpbmcnLFxuICAgIGhyZWZMYW5nOiAnaHJlZmxhbmcnLFxuICAgIHJhZGlvR3JvdXA6ICdyYWRpb2dyb3VwJyxcbiAgICBzcGVsbENoZWNrOiAnc3BlbGxjaGVjaycsXG4gICAgc3JjRG9jOiAnc3JjZG9jJyxcbiAgICBzcmNTZXQ6ICdzcmNzZXQnXG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gSFRNTERPTVByb3BlcnR5Q29uZmlnOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBMaW5rZWRWYWx1ZVV0aWxzXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0UHJvcFR5cGVzID0gcmVxdWlyZSgnLi9SZWFjdFByb3BUeXBlcycpO1xudmFyIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnMgPSByZXF1aXJlKCcuL1JlYWN0UHJvcFR5cGVMb2NhdGlvbnMnKTtcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciBoYXNSZWFkT25seVZhbHVlID0ge1xuICAnYnV0dG9uJzogdHJ1ZSxcbiAgJ2NoZWNrYm94JzogdHJ1ZSxcbiAgJ2ltYWdlJzogdHJ1ZSxcbiAgJ2hpZGRlbic6IHRydWUsXG4gICdyYWRpbyc6IHRydWUsXG4gICdyZXNldCc6IHRydWUsXG4gICdzdWJtaXQnOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBfYXNzZXJ0U2luZ2xlTGluayhpbnB1dFByb3BzKSB7XG4gICEoaW5wdXRQcm9wcy5jaGVja2VkTGluayA9PSBudWxsIHx8IGlucHV0UHJvcHMudmFsdWVMaW5rID09IG51bGwpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ0Nhbm5vdCBwcm92aWRlIGEgY2hlY2tlZExpbmsgYW5kIGEgdmFsdWVMaW5rLiBJZiB5b3Ugd2FudCB0byB1c2UgJyArICdjaGVja2VkTGluaywgeW91IHByb2JhYmx5IGRvblxcJ3Qgd2FudCB0byB1c2UgdmFsdWVMaW5rIGFuZCB2aWNlIHZlcnNhLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIF9hc3NlcnRWYWx1ZUxpbmsoaW5wdXRQcm9wcykge1xuICBfYXNzZXJ0U2luZ2xlTGluayhpbnB1dFByb3BzKTtcbiAgIShpbnB1dFByb3BzLnZhbHVlID09IG51bGwgJiYgaW5wdXRQcm9wcy5vbkNoYW5nZSA9PSBudWxsKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdDYW5ub3QgcHJvdmlkZSBhIHZhbHVlTGluayBhbmQgYSB2YWx1ZSBvciBvbkNoYW5nZSBldmVudC4gSWYgeW91IHdhbnQgJyArICd0byB1c2UgdmFsdWUgb3Igb25DaGFuZ2UsIHlvdSBwcm9iYWJseSBkb25cXCd0IHdhbnQgdG8gdXNlIHZhbHVlTGluay4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIF9hc3NlcnRDaGVja2VkTGluayhpbnB1dFByb3BzKSB7XG4gIF9hc3NlcnRTaW5nbGVMaW5rKGlucHV0UHJvcHMpO1xuICAhKGlucHV0UHJvcHMuY2hlY2tlZCA9PSBudWxsICYmIGlucHV0UHJvcHMub25DaGFuZ2UgPT0gbnVsbCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnQ2Fubm90IHByb3ZpZGUgYSBjaGVja2VkTGluayBhbmQgYSBjaGVja2VkIHByb3BlcnR5IG9yIG9uQ2hhbmdlIGV2ZW50LiAnICsgJ0lmIHlvdSB3YW50IHRvIHVzZSBjaGVja2VkIG9yIG9uQ2hhbmdlLCB5b3UgcHJvYmFibHkgZG9uXFwndCB3YW50IHRvICcgKyAndXNlIGNoZWNrZWRMaW5rJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xufVxuXG52YXIgcHJvcFR5cGVzID0ge1xuICB2YWx1ZTogZnVuY3Rpb24gKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSkge1xuICAgIGlmICghcHJvcHNbcHJvcE5hbWVdIHx8IGhhc1JlYWRPbmx5VmFsdWVbcHJvcHMudHlwZV0gfHwgcHJvcHMub25DaGFuZ2UgfHwgcHJvcHMucmVhZE9ubHkgfHwgcHJvcHMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEVycm9yKCdZb3UgcHJvdmlkZWQgYSBgdmFsdWVgIHByb3AgdG8gYSBmb3JtIGZpZWxkIHdpdGhvdXQgYW4gJyArICdgb25DaGFuZ2VgIGhhbmRsZXIuIFRoaXMgd2lsbCByZW5kZXIgYSByZWFkLW9ubHkgZmllbGQuIElmICcgKyAndGhlIGZpZWxkIHNob3VsZCBiZSBtdXRhYmxlIHVzZSBgZGVmYXVsdFZhbHVlYC4gT3RoZXJ3aXNlLCAnICsgJ3NldCBlaXRoZXIgYG9uQ2hhbmdlYCBvciBgcmVhZE9ubHlgLicpO1xuICB9LFxuICBjaGVja2VkOiBmdW5jdGlvbiAocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gICAgaWYgKCFwcm9wc1twcm9wTmFtZV0gfHwgcHJvcHMub25DaGFuZ2UgfHwgcHJvcHMucmVhZE9ubHkgfHwgcHJvcHMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEVycm9yKCdZb3UgcHJvdmlkZWQgYSBgY2hlY2tlZGAgcHJvcCB0byBhIGZvcm0gZmllbGQgd2l0aG91dCBhbiAnICsgJ2BvbkNoYW5nZWAgaGFuZGxlci4gVGhpcyB3aWxsIHJlbmRlciBhIHJlYWQtb25seSBmaWVsZC4gSWYgJyArICd0aGUgZmllbGQgc2hvdWxkIGJlIG11dGFibGUgdXNlIGBkZWZhdWx0Q2hlY2tlZGAuIE90aGVyd2lzZSwgJyArICdzZXQgZWl0aGVyIGBvbkNoYW5nZWAgb3IgYHJlYWRPbmx5YC4nKTtcbiAgfSxcbiAgb25DaGFuZ2U6IFJlYWN0UHJvcFR5cGVzLmZ1bmNcbn07XG5cbnZhciBsb2dnZWRUeXBlRmFpbHVyZXMgPSB7fTtcbmZ1bmN0aW9uIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShvd25lcikge1xuICBpZiAob3duZXIpIHtcbiAgICB2YXIgbmFtZSA9IG93bmVyLmdldE5hbWUoKTtcbiAgICBpZiAobmFtZSkge1xuICAgICAgcmV0dXJuICcgQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBuYW1lICsgJ2AuJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG4vKipcbiAqIFByb3ZpZGUgYSBsaW5rZWQgYHZhbHVlYCBhdHRyaWJ1dGUgZm9yIGNvbnRyb2xsZWQgZm9ybXMuIFlvdSBzaG91bGQgbm90IHVzZVxuICogdGhpcyBvdXRzaWRlIG9mIHRoZSBSZWFjdERPTSBjb250cm9sbGVkIGZvcm0gY29tcG9uZW50cy5cbiAqL1xudmFyIExpbmtlZFZhbHVlVXRpbHMgPSB7XG4gIGNoZWNrUHJvcFR5cGVzOiBmdW5jdGlvbiAodGFnTmFtZSwgcHJvcHMsIG93bmVyKSB7XG4gICAgZm9yICh2YXIgcHJvcE5hbWUgaW4gcHJvcFR5cGVzKSB7XG4gICAgICBpZiAocHJvcFR5cGVzLmhhc093blByb3BlcnR5KHByb3BOYW1lKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSBwcm9wVHlwZXNbcHJvcE5hbWVdKHByb3BzLCBwcm9wTmFtZSwgdGFnTmFtZSwgUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5wcm9wLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IubWVzc2FnZSBpbiBsb2dnZWRUeXBlRmFpbHVyZXMpKSB7XG4gICAgICAgIC8vIE9ubHkgbW9uaXRvciB0aGlzIGZhaWx1cmUgb25jZSBiZWNhdXNlIHRoZXJlIHRlbmRzIHRvIGJlIGEgbG90IG9mIHRoZVxuICAgICAgICAvLyBzYW1lIGVycm9yLlxuICAgICAgICBsb2dnZWRUeXBlRmFpbHVyZXNbZXJyb3IubWVzc2FnZV0gPSB0cnVlO1xuXG4gICAgICAgIHZhciBhZGRlbmR1bSA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShvd25lcik7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnRmFpbGVkIGZvcm0gcHJvcFR5cGU6ICVzJXMnLCBlcnJvci5tZXNzYWdlLCBhZGRlbmR1bSkgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gaW5wdXRQcm9wcyBQcm9wcyBmb3IgZm9ybSBjb21wb25lbnRcbiAgICogQHJldHVybiB7Kn0gY3VycmVudCB2YWx1ZSBvZiB0aGUgaW5wdXQgZWl0aGVyIGZyb20gdmFsdWUgcHJvcCBvciBsaW5rLlxuICAgKi9cbiAgZ2V0VmFsdWU6IGZ1bmN0aW9uIChpbnB1dFByb3BzKSB7XG4gICAgaWYgKGlucHV0UHJvcHMudmFsdWVMaW5rKSB7XG4gICAgICBfYXNzZXJ0VmFsdWVMaW5rKGlucHV0UHJvcHMpO1xuICAgICAgcmV0dXJuIGlucHV0UHJvcHMudmFsdWVMaW5rLnZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gaW5wdXRQcm9wcy52YWx1ZTtcbiAgfSxcblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGlucHV0UHJvcHMgUHJvcHMgZm9yIGZvcm0gY29tcG9uZW50XG4gICAqIEByZXR1cm4geyp9IGN1cnJlbnQgY2hlY2tlZCBzdGF0dXMgb2YgdGhlIGlucHV0IGVpdGhlciBmcm9tIGNoZWNrZWQgcHJvcFxuICAgKiAgICAgICAgICAgICBvciBsaW5rLlxuICAgKi9cbiAgZ2V0Q2hlY2tlZDogZnVuY3Rpb24gKGlucHV0UHJvcHMpIHtcbiAgICBpZiAoaW5wdXRQcm9wcy5jaGVja2VkTGluaykge1xuICAgICAgX2Fzc2VydENoZWNrZWRMaW5rKGlucHV0UHJvcHMpO1xuICAgICAgcmV0dXJuIGlucHV0UHJvcHMuY2hlY2tlZExpbmsudmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBpbnB1dFByb3BzLmNoZWNrZWQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBpbnB1dFByb3BzIFByb3BzIGZvciBmb3JtIGNvbXBvbmVudFxuICAgKiBAcGFyYW0ge1N5bnRoZXRpY0V2ZW50fSBldmVudCBjaGFuZ2UgZXZlbnQgdG8gaGFuZGxlXG4gICAqL1xuICBleGVjdXRlT25DaGFuZ2U6IGZ1bmN0aW9uIChpbnB1dFByb3BzLCBldmVudCkge1xuICAgIGlmIChpbnB1dFByb3BzLnZhbHVlTGluaykge1xuICAgICAgX2Fzc2VydFZhbHVlTGluayhpbnB1dFByb3BzKTtcbiAgICAgIHJldHVybiBpbnB1dFByb3BzLnZhbHVlTGluay5yZXF1ZXN0Q2hhbmdlKGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChpbnB1dFByb3BzLmNoZWNrZWRMaW5rKSB7XG4gICAgICBfYXNzZXJ0Q2hlY2tlZExpbmsoaW5wdXRQcm9wcyk7XG4gICAgICByZXR1cm4gaW5wdXRQcm9wcy5jaGVja2VkTGluay5yZXF1ZXN0Q2hhbmdlKGV2ZW50LnRhcmdldC5jaGVja2VkKTtcbiAgICB9IGVsc2UgaWYgKGlucHV0UHJvcHMub25DaGFuZ2UpIHtcbiAgICAgIHJldHVybiBpbnB1dFByb3BzLm9uQ2hhbmdlLmNhbGwodW5kZWZpbmVkLCBldmVudCk7XG4gICAgfVxuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpbmtlZFZhbHVlVXRpbHM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxNC0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIE9iamVjdC5hc3NpZ25cbiAqL1xuXG4vLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtb2JqZWN0LmFzc2lnblxuXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZXMpIHtcbiAgaWYgKHRhcmdldCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmFzc2lnbiB0YXJnZXQgY2Fubm90IGJlIG51bGwgb3IgdW5kZWZpbmVkJyk7XG4gIH1cblxuICB2YXIgdG8gPSBPYmplY3QodGFyZ2V0KTtcbiAgdmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBuZXh0SW5kZXggPSAxOyBuZXh0SW5kZXggPCBhcmd1bWVudHMubGVuZ3RoOyBuZXh0SW5kZXgrKykge1xuICAgIHZhciBuZXh0U291cmNlID0gYXJndW1lbnRzW25leHRJbmRleF07XG4gICAgaWYgKG5leHRTb3VyY2UgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGZyb20gPSBPYmplY3QobmV4dFNvdXJjZSk7XG5cbiAgICAvLyBXZSBkb24ndCBjdXJyZW50bHkgc3VwcG9ydCBhY2Nlc3NvcnMgbm9yIHByb3hpZXMuIFRoZXJlZm9yZSB0aGlzXG4gICAgLy8gY29weSBjYW5ub3QgdGhyb3cuIElmIHdlIGV2ZXIgc3VwcG9ydGVkIHRoaXMgdGhlbiB3ZSBtdXN0IGhhbmRsZVxuICAgIC8vIGV4Y2VwdGlvbnMgYW5kIHNpZGUtZWZmZWN0cy4gV2UgZG9uJ3Qgc3VwcG9ydCBzeW1ib2xzIHNvIHRoZXkgd29uJ3RcbiAgICAvLyBiZSB0cmFuc2ZlcnJlZC5cblxuICAgIGZvciAodmFyIGtleSBpbiBmcm9tKSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChmcm9tLCBrZXkpKSB7XG4gICAgICAgIHRvW2tleV0gPSBmcm9tW2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRvO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFzc2lnbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUG9vbGVkQ2xhc3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBTdGF0aWMgcG9vbGVycy4gU2V2ZXJhbCBjdXN0b20gdmVyc2lvbnMgZm9yIGVhY2ggcG90ZW50aWFsIG51bWJlciBvZlxuICogYXJndW1lbnRzLiBBIGNvbXBsZXRlbHkgZ2VuZXJpYyBwb29sZXIgaXMgZWFzeSB0byBpbXBsZW1lbnQsIGJ1dCB3b3VsZFxuICogcmVxdWlyZSBhY2Nlc3NpbmcgdGhlIGBhcmd1bWVudHNgIG9iamVjdC4gSW4gZWFjaCBvZiB0aGVzZSwgYHRoaXNgIHJlZmVycyB0b1xuICogdGhlIENsYXNzIGl0c2VsZiwgbm90IGFuIGluc3RhbmNlLiBJZiBhbnkgb3RoZXJzIGFyZSBuZWVkZWQsIHNpbXBseSBhZGQgdGhlbVxuICogaGVyZSwgb3IgaW4gdGhlaXIgb3duIGZpbGVzLlxuICovXG52YXIgb25lQXJndW1lbnRQb29sZXIgPSBmdW5jdGlvbiAoY29weUZpZWxkc0Zyb20pIHtcbiAgdmFyIEtsYXNzID0gdGhpcztcbiAgaWYgKEtsYXNzLmluc3RhbmNlUG9vbC5sZW5ndGgpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBLbGFzcy5pbnN0YW5jZVBvb2wucG9wKCk7XG4gICAgS2xhc3MuY2FsbChpbnN0YW5jZSwgY29weUZpZWxkc0Zyb20pO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEtsYXNzKGNvcHlGaWVsZHNGcm9tKTtcbiAgfVxufTtcblxudmFyIHR3b0FyZ3VtZW50UG9vbGVyID0gZnVuY3Rpb24gKGExLCBhMikge1xuICB2YXIgS2xhc3MgPSB0aGlzO1xuICBpZiAoS2xhc3MuaW5zdGFuY2VQb29sLmxlbmd0aCkge1xuICAgIHZhciBpbnN0YW5jZSA9IEtsYXNzLmluc3RhbmNlUG9vbC5wb3AoKTtcbiAgICBLbGFzcy5jYWxsKGluc3RhbmNlLCBhMSwgYTIpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEtsYXNzKGExLCBhMik7XG4gIH1cbn07XG5cbnZhciB0aHJlZUFyZ3VtZW50UG9vbGVyID0gZnVuY3Rpb24gKGExLCBhMiwgYTMpIHtcbiAgdmFyIEtsYXNzID0gdGhpcztcbiAgaWYgKEtsYXNzLmluc3RhbmNlUG9vbC5sZW5ndGgpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBLbGFzcy5pbnN0YW5jZVBvb2wucG9wKCk7XG4gICAgS2xhc3MuY2FsbChpbnN0YW5jZSwgYTEsIGEyLCBhMyk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgS2xhc3MoYTEsIGEyLCBhMyk7XG4gIH1cbn07XG5cbnZhciBmb3VyQXJndW1lbnRQb29sZXIgPSBmdW5jdGlvbiAoYTEsIGEyLCBhMywgYTQpIHtcbiAgdmFyIEtsYXNzID0gdGhpcztcbiAgaWYgKEtsYXNzLmluc3RhbmNlUG9vbC5sZW5ndGgpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBLbGFzcy5pbnN0YW5jZVBvb2wucG9wKCk7XG4gICAgS2xhc3MuY2FsbChpbnN0YW5jZSwgYTEsIGEyLCBhMywgYTQpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEtsYXNzKGExLCBhMiwgYTMsIGE0KTtcbiAgfVxufTtcblxudmFyIGZpdmVBcmd1bWVudFBvb2xlciA9IGZ1bmN0aW9uIChhMSwgYTIsIGEzLCBhNCwgYTUpIHtcbiAgdmFyIEtsYXNzID0gdGhpcztcbiAgaWYgKEtsYXNzLmluc3RhbmNlUG9vbC5sZW5ndGgpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBLbGFzcy5pbnN0YW5jZVBvb2wucG9wKCk7XG4gICAgS2xhc3MuY2FsbChpbnN0YW5jZSwgYTEsIGEyLCBhMywgYTQsIGE1KTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBLbGFzcyhhMSwgYTIsIGEzLCBhNCwgYTUpO1xuICB9XG59O1xuXG52YXIgc3RhbmRhcmRSZWxlYXNlciA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xuICB2YXIgS2xhc3MgPSB0aGlzO1xuICAhKGluc3RhbmNlIGluc3RhbmNlb2YgS2xhc3MpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1RyeWluZyB0byByZWxlYXNlIGFuIGluc3RhbmNlIGludG8gYSBwb29sIG9mIGEgZGlmZmVyZW50IHR5cGUuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICBpbnN0YW5jZS5kZXN0cnVjdG9yKCk7XG4gIGlmIChLbGFzcy5pbnN0YW5jZVBvb2wubGVuZ3RoIDwgS2xhc3MucG9vbFNpemUpIHtcbiAgICBLbGFzcy5pbnN0YW5jZVBvb2wucHVzaChpbnN0YW5jZSk7XG4gIH1cbn07XG5cbnZhciBERUZBVUxUX1BPT0xfU0laRSA9IDEwO1xudmFyIERFRkFVTFRfUE9PTEVSID0gb25lQXJndW1lbnRQb29sZXI7XG5cbi8qKlxuICogQXVnbWVudHMgYENvcHlDb25zdHJ1Y3RvcmAgdG8gYmUgYSBwb29sYWJsZSBjbGFzcywgYXVnbWVudGluZyBvbmx5IHRoZSBjbGFzc1xuICogaXRzZWxmIChzdGF0aWNhbGx5KSBub3QgYWRkaW5nIGFueSBwcm90b3R5cGljYWwgZmllbGRzLiBBbnkgQ29weUNvbnN0cnVjdG9yXG4gKiB5b3UgZ2l2ZSB0aGlzIG1heSBoYXZlIGEgYHBvb2xTaXplYCBwcm9wZXJ0eSwgYW5kIHdpbGwgbG9vayBmb3IgYVxuICogcHJvdG90eXBpY2FsIGBkZXN0cnVjdG9yYCBvbiBpbnN0YW5jZXMgKG9wdGlvbmFsKS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBDb3B5Q29uc3RydWN0b3IgQ29uc3RydWN0b3IgdGhhdCBjYW4gYmUgdXNlZCB0byByZXNldC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHBvb2xlciBDdXN0b21pemFibGUgcG9vbGVyLlxuICovXG52YXIgYWRkUG9vbGluZ1RvID0gZnVuY3Rpb24gKENvcHlDb25zdHJ1Y3RvciwgcG9vbGVyKSB7XG4gIHZhciBOZXdLbGFzcyA9IENvcHlDb25zdHJ1Y3RvcjtcbiAgTmV3S2xhc3MuaW5zdGFuY2VQb29sID0gW107XG4gIE5ld0tsYXNzLmdldFBvb2xlZCA9IHBvb2xlciB8fCBERUZBVUxUX1BPT0xFUjtcbiAgaWYgKCFOZXdLbGFzcy5wb29sU2l6ZSkge1xuICAgIE5ld0tsYXNzLnBvb2xTaXplID0gREVGQVVMVF9QT09MX1NJWkU7XG4gIH1cbiAgTmV3S2xhc3MucmVsZWFzZSA9IHN0YW5kYXJkUmVsZWFzZXI7XG4gIHJldHVybiBOZXdLbGFzcztcbn07XG5cbnZhciBQb29sZWRDbGFzcyA9IHtcbiAgYWRkUG9vbGluZ1RvOiBhZGRQb29saW5nVG8sXG4gIG9uZUFyZ3VtZW50UG9vbGVyOiBvbmVBcmd1bWVudFBvb2xlcixcbiAgdHdvQXJndW1lbnRQb29sZXI6IHR3b0FyZ3VtZW50UG9vbGVyLFxuICB0aHJlZUFyZ3VtZW50UG9vbGVyOiB0aHJlZUFyZ3VtZW50UG9vbGVyLFxuICBmb3VyQXJndW1lbnRQb29sZXI6IGZvdXJBcmd1bWVudFBvb2xlcixcbiAgZml2ZUFyZ3VtZW50UG9vbGVyOiBmaXZlQXJndW1lbnRQb29sZXJcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUG9vbGVkQ2xhc3M7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RET00gPSByZXF1aXJlKCcuL1JlYWN0RE9NJyk7XG52YXIgUmVhY3RET01TZXJ2ZXIgPSByZXF1aXJlKCcuL1JlYWN0RE9NU2VydmVyJyk7XG52YXIgUmVhY3RJc29tb3JwaGljID0gcmVxdWlyZSgnLi9SZWFjdElzb21vcnBoaWMnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGRlcHJlY2F0ZWQgPSByZXF1aXJlKCcuL2RlcHJlY2F0ZWQnKTtcblxuLy8gYHZlcnNpb25gIHdpbGwgYmUgYWRkZWQgaGVyZSBieSBSZWFjdElzb21vcnBoaWMuXG52YXIgUmVhY3QgPSB7fTtcblxuYXNzaWduKFJlYWN0LCBSZWFjdElzb21vcnBoaWMpO1xuXG5hc3NpZ24oUmVhY3QsIHtcbiAgLy8gUmVhY3RET01cbiAgZmluZERPTU5vZGU6IGRlcHJlY2F0ZWQoJ2ZpbmRET01Ob2RlJywgJ1JlYWN0RE9NJywgJ3JlYWN0LWRvbScsIFJlYWN0RE9NLCBSZWFjdERPTS5maW5kRE9NTm9kZSksXG4gIHJlbmRlcjogZGVwcmVjYXRlZCgncmVuZGVyJywgJ1JlYWN0RE9NJywgJ3JlYWN0LWRvbScsIFJlYWN0RE9NLCBSZWFjdERPTS5yZW5kZXIpLFxuICB1bm1vdW50Q29tcG9uZW50QXROb2RlOiBkZXByZWNhdGVkKCd1bm1vdW50Q29tcG9uZW50QXROb2RlJywgJ1JlYWN0RE9NJywgJ3JlYWN0LWRvbScsIFJlYWN0RE9NLCBSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlKSxcblxuICAvLyBSZWFjdERPTVNlcnZlclxuICByZW5kZXJUb1N0cmluZzogZGVwcmVjYXRlZCgncmVuZGVyVG9TdHJpbmcnLCAnUmVhY3RET01TZXJ2ZXInLCAncmVhY3QtZG9tL3NlcnZlcicsIFJlYWN0RE9NU2VydmVyLCBSZWFjdERPTVNlcnZlci5yZW5kZXJUb1N0cmluZyksXG4gIHJlbmRlclRvU3RhdGljTWFya3VwOiBkZXByZWNhdGVkKCdyZW5kZXJUb1N0YXRpY01hcmt1cCcsICdSZWFjdERPTVNlcnZlcicsICdyZWFjdC1kb20vc2VydmVyJywgUmVhY3RET01TZXJ2ZXIsIFJlYWN0RE9NU2VydmVyLnJlbmRlclRvU3RhdGljTWFya3VwKVxufSk7XG5cblJlYWN0Ll9fU0VDUkVUX0RPTV9ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEID0gUmVhY3RET007XG5SZWFjdC5fX1NFQ1JFVF9ET01fU0VSVkVSX0RPX05PVF9VU0VfT1JfWU9VX1dJTExfQkVfRklSRUQgPSBSZWFjdERPTVNlcnZlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RCcm93c2VyQ29tcG9uZW50TWl4aW5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdEluc3RhbmNlTWFwID0gcmVxdWlyZSgnLi9SZWFjdEluc3RhbmNlTWFwJyk7XG5cbnZhciBmaW5kRE9NTm9kZSA9IHJlcXVpcmUoJy4vZmluZERPTU5vZGUnKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG52YXIgZGlkV2FybktleSA9ICdfZ2V0RE9NTm9kZURpZFdhcm4nO1xuXG52YXIgUmVhY3RCcm93c2VyQ29tcG9uZW50TWl4aW4gPSB7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBET00gbm9kZSByZW5kZXJlZCBieSB0aGlzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybiB7RE9NRWxlbWVudH0gVGhlIHJvb3Qgbm9kZSBvZiB0aGlzIGNvbXBvbmVudC5cbiAgICogQGZpbmFsXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGdldERPTU5vZGU6IGZ1bmN0aW9uICgpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyh0aGlzLmNvbnN0cnVjdG9yW2RpZFdhcm5LZXldLCAnJXMuZ2V0RE9NTm9kZSguLi4pIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgJyArICdSZWFjdERPTS5maW5kRE9NTm9kZShpbnN0YW5jZSkgaW5zdGVhZC4nLCBSZWFjdEluc3RhbmNlTWFwLmdldCh0aGlzKS5nZXROYW1lKCkgfHwgdGhpcy50YWdOYW1lIHx8ICdVbmtub3duJykgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5jb25zdHJ1Y3RvcltkaWRXYXJuS2V5XSA9IHRydWU7XG4gICAgcmV0dXJuIGZpbmRET01Ob2RlKHRoaXMpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0QnJvd3NlckNvbXBvbmVudE1peGluOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXJcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgRXZlbnRQbHVnaW5IdWIgPSByZXF1aXJlKCcuL0V2ZW50UGx1Z2luSHViJyk7XG52YXIgRXZlbnRQbHVnaW5SZWdpc3RyeSA9IHJlcXVpcmUoJy4vRXZlbnRQbHVnaW5SZWdpc3RyeScpO1xudmFyIFJlYWN0RXZlbnRFbWl0dGVyTWl4aW4gPSByZXF1aXJlKCcuL1JlYWN0RXZlbnRFbWl0dGVyTWl4aW4nKTtcbnZhciBSZWFjdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0UGVyZicpO1xudmFyIFZpZXdwb3J0TWV0cmljcyA9IHJlcXVpcmUoJy4vVmlld3BvcnRNZXRyaWNzJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpc0V2ZW50U3VwcG9ydGVkID0gcmVxdWlyZSgnLi9pc0V2ZW50U3VwcG9ydGVkJyk7XG5cbi8qKlxuICogU3VtbWFyeSBvZiBgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyYCBldmVudCBoYW5kbGluZzpcbiAqXG4gKiAgLSBUb3AtbGV2ZWwgZGVsZWdhdGlvbiBpcyB1c2VkIHRvIHRyYXAgbW9zdCBuYXRpdmUgYnJvd3NlciBldmVudHMuIFRoaXNcbiAqICAgIG1heSBvbmx5IG9jY3VyIGluIHRoZSBtYWluIHRocmVhZCBhbmQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mXG4gKiAgICBSZWFjdEV2ZW50TGlzdGVuZXIsIHdoaWNoIGlzIGluamVjdGVkIGFuZCBjYW4gdGhlcmVmb3JlIHN1cHBvcnQgcGx1Z2dhYmxlXG4gKiAgICBldmVudCBzb3VyY2VzLiBUaGlzIGlzIHRoZSBvbmx5IHdvcmsgdGhhdCBvY2N1cnMgaW4gdGhlIG1haW4gdGhyZWFkLlxuICpcbiAqICAtIFdlIG5vcm1hbGl6ZSBhbmQgZGUtZHVwbGljYXRlIGV2ZW50cyB0byBhY2NvdW50IGZvciBicm93c2VyIHF1aXJrcy4gVGhpc1xuICogICAgbWF5IGJlIGRvbmUgaW4gdGhlIHdvcmtlciB0aHJlYWQuXG4gKlxuICogIC0gRm9yd2FyZCB0aGVzZSBuYXRpdmUgZXZlbnRzICh3aXRoIHRoZSBhc3NvY2lhdGVkIHRvcC1sZXZlbCB0eXBlIHVzZWQgdG9cbiAqICAgIHRyYXAgaXQpIHRvIGBFdmVudFBsdWdpbkh1YmAsIHdoaWNoIGluIHR1cm4gd2lsbCBhc2sgcGx1Z2lucyBpZiB0aGV5IHdhbnRcbiAqICAgIHRvIGV4dHJhY3QgYW55IHN5bnRoZXRpYyBldmVudHMuXG4gKlxuICogIC0gVGhlIGBFdmVudFBsdWdpbkh1YmAgd2lsbCB0aGVuIHByb2Nlc3MgZWFjaCBldmVudCBieSBhbm5vdGF0aW5nIHRoZW0gd2l0aFxuICogICAgXCJkaXNwYXRjaGVzXCIsIGEgc2VxdWVuY2Ugb2YgbGlzdGVuZXJzIGFuZCBJRHMgdGhhdCBjYXJlIGFib3V0IHRoYXQgZXZlbnQuXG4gKlxuICogIC0gVGhlIGBFdmVudFBsdWdpbkh1YmAgdGhlbiBkaXNwYXRjaGVzIHRoZSBldmVudHMuXG4gKlxuICogT3ZlcnZpZXcgb2YgUmVhY3QgYW5kIHRoZSBldmVudCBzeXN0ZW06XG4gKlxuICogKy0tLS0tLS0tLS0tLSsgICAgLlxuICogfCAgICBET00gICAgIHwgICAgLlxuICogKy0tLS0tLS0tLS0tLSsgICAgLlxuICogICAgICAgfCAgICAgICAgICAgLlxuICogICAgICAgdiAgICAgICAgICAgLlxuICogKy0tLS0tLS0tLS0tLSsgICAgLlxuICogfCBSZWFjdEV2ZW50IHwgICAgLlxuICogfCAgTGlzdGVuZXIgIHwgICAgLlxuICogKy0tLS0tLS0tLS0tLSsgICAgLiAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tLS0rXG4gKiAgICAgICB8ICAgICAgICAgICAuICAgICAgICAgICAgICAgKy0tLS0tLS0tK3xTaW1wbGVFdmVudHxcbiAqICAgICAgIHwgICAgICAgICAgIC4gICAgICAgICAgICAgICB8ICAgICAgICAgfFBsdWdpbiAgICAgfFxuICogKy0tLS0tfC0tLS0tLSsgICAgLiAgICAgICAgICAgICAgIHYgICAgICAgICArLS0tLS0tLS0tLS0rXG4gKiB8ICAgICB8ICAgICAgfCAgICAuICAgICstLS0tLS0tLS0tLS0tLSsgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0rXG4gKiB8ICAgICArLS0tLS0tLS0tLS0uLS0tPnxFdmVudFBsdWdpbkh1YnwgICAgICAgICAgICAgICAgICAgIHwgICAgRXZlbnQgICB8XG4gKiB8ICAgICAgICAgICAgfCAgICAuICAgIHwgICAgICAgICAgICAgIHwgICAgICstLS0tLS0tLS0tLSsgIHwgUHJvcGFnYXRvcnN8XG4gKiB8IFJlYWN0RXZlbnQgfCAgICAuICAgIHwgICAgICAgICAgICAgIHwgICAgIHxUYXBFdmVudCAgIHwgIHwtLS0tLS0tLS0tLS18XG4gKiB8ICBFbWl0dGVyICAgfCAgICAuICAgIHwgICAgICAgICAgICAgIHw8LS0tK3xQbHVnaW4gICAgIHwgIHxvdGhlciBwbHVnaW58XG4gKiB8ICAgICAgICAgICAgfCAgICAuICAgIHwgICAgICAgICAgICAgIHwgICAgICstLS0tLS0tLS0tLSsgIHwgIHV0aWxpdGllcyB8XG4gKiB8ICAgICArLS0tLS0tLS0tLS0uLS0tPnwgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0rXG4gKiB8ICAgICB8ICAgICAgfCAgICAuICAgICstLS0tLS0tLS0tLS0tLStcbiAqICstLS0tLXwtLS0tLS0rICAgIC4gICAgICAgICAgICAgICAgXiAgICAgICAgKy0tLS0tLS0tLS0tK1xuICogICAgICAgfCAgICAgICAgICAgLiAgICAgICAgICAgICAgICB8ICAgICAgICB8RW50ZXIvTGVhdmV8XG4gKiAgICAgICArICAgICAgICAgICAuICAgICAgICAgICAgICAgICstLS0tLS0tK3xQbHVnaW4gICAgIHxcbiAqICstLS0tLS0tLS0tLS0tKyAgIC4gICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0tLS0tK1xuICogfCBhcHBsaWNhdGlvbiB8ICAgLlxuICogfC0tLS0tLS0tLS0tLS18ICAgLlxuICogfCAgICAgICAgICAgICB8ICAgLlxuICogfCAgICAgICAgICAgICB8ICAgLlxuICogKy0tLS0tLS0tLS0tLS0rICAgLlxuICogICAgICAgICAgICAgICAgICAgLlxuICogICAgUmVhY3QgQ29yZSAgICAgLiAgR2VuZXJhbCBQdXJwb3NlIEV2ZW50IFBsdWdpbiBTeXN0ZW1cbiAqL1xuXG52YXIgYWxyZWFkeUxpc3RlbmluZ1RvID0ge307XG52YXIgaXNNb25pdG9yaW5nU2Nyb2xsVmFsdWUgPSBmYWxzZTtcbnZhciByZWFjdFRvcExpc3RlbmVyc0NvdW50ZXIgPSAwO1xuXG4vLyBGb3IgZXZlbnRzIGxpa2UgJ3N1Ym1pdCcgd2hpY2ggZG9uJ3QgY29uc2lzdGVudGx5IGJ1YmJsZSAod2hpY2ggd2UgdHJhcCBhdCBhXG4vLyBsb3dlciBub2RlIHRoYW4gYGRvY3VtZW50YCksIGJpbmRpbmcgYXQgYGRvY3VtZW50YCB3b3VsZCBjYXVzZSBkdXBsaWNhdGVcbi8vIGV2ZW50cyBzbyB3ZSBkb24ndCBpbmNsdWRlIHRoZW0gaGVyZVxudmFyIHRvcEV2ZW50TWFwcGluZyA9IHtcbiAgdG9wQWJvcnQ6ICdhYm9ydCcsXG4gIHRvcEJsdXI6ICdibHVyJyxcbiAgdG9wQ2FuUGxheTogJ2NhbnBsYXknLFxuICB0b3BDYW5QbGF5VGhyb3VnaDogJ2NhbnBsYXl0aHJvdWdoJyxcbiAgdG9wQ2hhbmdlOiAnY2hhbmdlJyxcbiAgdG9wQ2xpY2s6ICdjbGljaycsXG4gIHRvcENvbXBvc2l0aW9uRW5kOiAnY29tcG9zaXRpb25lbmQnLFxuICB0b3BDb21wb3NpdGlvblN0YXJ0OiAnY29tcG9zaXRpb25zdGFydCcsXG4gIHRvcENvbXBvc2l0aW9uVXBkYXRlOiAnY29tcG9zaXRpb251cGRhdGUnLFxuICB0b3BDb250ZXh0TWVudTogJ2NvbnRleHRtZW51JyxcbiAgdG9wQ29weTogJ2NvcHknLFxuICB0b3BDdXQ6ICdjdXQnLFxuICB0b3BEb3VibGVDbGljazogJ2RibGNsaWNrJyxcbiAgdG9wRHJhZzogJ2RyYWcnLFxuICB0b3BEcmFnRW5kOiAnZHJhZ2VuZCcsXG4gIHRvcERyYWdFbnRlcjogJ2RyYWdlbnRlcicsXG4gIHRvcERyYWdFeGl0OiAnZHJhZ2V4aXQnLFxuICB0b3BEcmFnTGVhdmU6ICdkcmFnbGVhdmUnLFxuICB0b3BEcmFnT3ZlcjogJ2RyYWdvdmVyJyxcbiAgdG9wRHJhZ1N0YXJ0OiAnZHJhZ3N0YXJ0JyxcbiAgdG9wRHJvcDogJ2Ryb3AnLFxuICB0b3BEdXJhdGlvbkNoYW5nZTogJ2R1cmF0aW9uY2hhbmdlJyxcbiAgdG9wRW1wdGllZDogJ2VtcHRpZWQnLFxuICB0b3BFbmNyeXB0ZWQ6ICdlbmNyeXB0ZWQnLFxuICB0b3BFbmRlZDogJ2VuZGVkJyxcbiAgdG9wRXJyb3I6ICdlcnJvcicsXG4gIHRvcEZvY3VzOiAnZm9jdXMnLFxuICB0b3BJbnB1dDogJ2lucHV0JyxcbiAgdG9wS2V5RG93bjogJ2tleWRvd24nLFxuICB0b3BLZXlQcmVzczogJ2tleXByZXNzJyxcbiAgdG9wS2V5VXA6ICdrZXl1cCcsXG4gIHRvcExvYWRlZERhdGE6ICdsb2FkZWRkYXRhJyxcbiAgdG9wTG9hZGVkTWV0YWRhdGE6ICdsb2FkZWRtZXRhZGF0YScsXG4gIHRvcExvYWRTdGFydDogJ2xvYWRzdGFydCcsXG4gIHRvcE1vdXNlRG93bjogJ21vdXNlZG93bicsXG4gIHRvcE1vdXNlTW92ZTogJ21vdXNlbW92ZScsXG4gIHRvcE1vdXNlT3V0OiAnbW91c2VvdXQnLFxuICB0b3BNb3VzZU92ZXI6ICdtb3VzZW92ZXInLFxuICB0b3BNb3VzZVVwOiAnbW91c2V1cCcsXG4gIHRvcFBhc3RlOiAncGFzdGUnLFxuICB0b3BQYXVzZTogJ3BhdXNlJyxcbiAgdG9wUGxheTogJ3BsYXknLFxuICB0b3BQbGF5aW5nOiAncGxheWluZycsXG4gIHRvcFByb2dyZXNzOiAncHJvZ3Jlc3MnLFxuICB0b3BSYXRlQ2hhbmdlOiAncmF0ZWNoYW5nZScsXG4gIHRvcFNjcm9sbDogJ3Njcm9sbCcsXG4gIHRvcFNlZWtlZDogJ3NlZWtlZCcsXG4gIHRvcFNlZWtpbmc6ICdzZWVraW5nJyxcbiAgdG9wU2VsZWN0aW9uQ2hhbmdlOiAnc2VsZWN0aW9uY2hhbmdlJyxcbiAgdG9wU3RhbGxlZDogJ3N0YWxsZWQnLFxuICB0b3BTdXNwZW5kOiAnc3VzcGVuZCcsXG4gIHRvcFRleHRJbnB1dDogJ3RleHRJbnB1dCcsXG4gIHRvcFRpbWVVcGRhdGU6ICd0aW1ldXBkYXRlJyxcbiAgdG9wVG91Y2hDYW5jZWw6ICd0b3VjaGNhbmNlbCcsXG4gIHRvcFRvdWNoRW5kOiAndG91Y2hlbmQnLFxuICB0b3BUb3VjaE1vdmU6ICd0b3VjaG1vdmUnLFxuICB0b3BUb3VjaFN0YXJ0OiAndG91Y2hzdGFydCcsXG4gIHRvcFZvbHVtZUNoYW5nZTogJ3ZvbHVtZWNoYW5nZScsXG4gIHRvcFdhaXRpbmc6ICd3YWl0aW5nJyxcbiAgdG9wV2hlZWw6ICd3aGVlbCdcbn07XG5cbi8qKlxuICogVG8gZW5zdXJlIG5vIGNvbmZsaWN0cyB3aXRoIG90aGVyIHBvdGVudGlhbCBSZWFjdCBpbnN0YW5jZXMgb24gdGhlIHBhZ2VcbiAqL1xudmFyIHRvcExpc3RlbmVyc0lES2V5ID0gJ19yZWFjdExpc3RlbmVyc0lEJyArIFN0cmluZyhNYXRoLnJhbmRvbSgpKS5zbGljZSgyKTtcblxuZnVuY3Rpb24gZ2V0TGlzdGVuaW5nRm9yRG9jdW1lbnQobW91bnRBdCkge1xuICAvLyBJbiBJRTgsIGBtb3VudEF0YCBpcyBhIGhvc3Qgb2JqZWN0IGFuZCBkb2Vzbid0IGhhdmUgYGhhc093blByb3BlcnR5YFxuICAvLyBkaXJlY3RseS5cbiAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW91bnRBdCwgdG9wTGlzdGVuZXJzSURLZXkpKSB7XG4gICAgbW91bnRBdFt0b3BMaXN0ZW5lcnNJREtleV0gPSByZWFjdFRvcExpc3RlbmVyc0NvdW50ZXIrKztcbiAgICBhbHJlYWR5TGlzdGVuaW5nVG9bbW91bnRBdFt0b3BMaXN0ZW5lcnNJREtleV1dID0ge307XG4gIH1cbiAgcmV0dXJuIGFscmVhZHlMaXN0ZW5pbmdUb1ttb3VudEF0W3RvcExpc3RlbmVyc0lES2V5XV07XG59XG5cbi8qKlxuICogYFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlcmAgaXMgdXNlZCB0byBhdHRhY2ggdG9wLWxldmVsIGV2ZW50IGxpc3RlbmVycy4gRm9yXG4gKiBleGFtcGxlOlxuICpcbiAqICAgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLnB1dExpc3RlbmVyKCdteUlEJywgJ29uQ2xpY2snLCBteUZ1bmN0aW9uKTtcbiAqXG4gKiBUaGlzIHdvdWxkIGFsbG9jYXRlIGEgXCJyZWdpc3RyYXRpb25cIiBvZiBgKCdvbkNsaWNrJywgbXlGdW5jdGlvbilgIG9uICdteUlEJy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xudmFyIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlciA9IGFzc2lnbih7fSwgUmVhY3RFdmVudEVtaXR0ZXJNaXhpbiwge1xuXG4gIC8qKlxuICAgKiBJbmplY3RhYmxlIGV2ZW50IGJhY2tlbmRcbiAgICovXG4gIFJlYWN0RXZlbnRMaXN0ZW5lcjogbnVsbCxcblxuICBpbmplY3Rpb246IHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gUmVhY3RFdmVudExpc3RlbmVyXG4gICAgICovXG4gICAgaW5qZWN0UmVhY3RFdmVudExpc3RlbmVyOiBmdW5jdGlvbiAoUmVhY3RFdmVudExpc3RlbmVyKSB7XG4gICAgICBSZWFjdEV2ZW50TGlzdGVuZXIuc2V0SGFuZGxlVG9wTGV2ZWwoUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLmhhbmRsZVRvcExldmVsKTtcbiAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIgPSBSZWFjdEV2ZW50TGlzdGVuZXI7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTZXRzIHdoZXRoZXIgb3Igbm90IGFueSBjcmVhdGVkIGNhbGxiYWNrcyBzaG91bGQgYmUgZW5hYmxlZC5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBlbmFibGVkIFRydWUgaWYgY2FsbGJhY2tzIHNob3VsZCBiZSBlbmFibGVkLlxuICAgKi9cbiAgc2V0RW5hYmxlZDogZnVuY3Rpb24gKGVuYWJsZWQpIHtcbiAgICBpZiAoUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLlJlYWN0RXZlbnRMaXN0ZW5lcikge1xuICAgICAgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLlJlYWN0RXZlbnRMaXN0ZW5lci5zZXRFbmFibGVkKGVuYWJsZWQpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBjYWxsYmFja3MgYXJlIGVuYWJsZWQuXG4gICAqL1xuICBpc0VuYWJsZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gISEoUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLlJlYWN0RXZlbnRMaXN0ZW5lciAmJiBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLmlzRW5hYmxlZCgpKTtcbiAgfSxcblxuICAvKipcbiAgICogV2UgbGlzdGVuIGZvciBidWJibGVkIHRvdWNoIGV2ZW50cyBvbiB0aGUgZG9jdW1lbnQgb2JqZWN0LlxuICAgKlxuICAgKiBGaXJlZm94IHY4LjAxIChhbmQgcG9zc2libHkgb3RoZXJzKSBleGhpYml0ZWQgc3RyYW5nZSBiZWhhdmlvciB3aGVuXG4gICAqIG1vdW50aW5nIGBvbm1vdXNlbW92ZWAgZXZlbnRzIGF0IHNvbWUgbm9kZSB0aGF0IHdhcyBub3QgdGhlIGRvY3VtZW50XG4gICAqIGVsZW1lbnQuIFRoZSBzeW1wdG9tcyB3ZXJlIHRoYXQgaWYgeW91ciBtb3VzZSBpcyBub3QgbW92aW5nIG92ZXIgc29tZXRoaW5nXG4gICAqIGNvbnRhaW5lZCB3aXRoaW4gdGhhdCBtb3VudCBwb2ludCAoZm9yIGV4YW1wbGUgb24gdGhlIGJhY2tncm91bmQpIHRoZVxuICAgKiB0b3AtbGV2ZWwgbGlzdGVuZXJzIGZvciBgb25tb3VzZW1vdmVgIHdvbid0IGJlIGNhbGxlZC4gSG93ZXZlciwgaWYgeW91XG4gICAqIHJlZ2lzdGVyIHRoZSBgbW91c2Vtb3ZlYCBvbiB0aGUgZG9jdW1lbnQgb2JqZWN0LCB0aGVuIGl0IHdpbGwgb2YgY291cnNlXG4gICAqIGNhdGNoIGFsbCBgbW91c2Vtb3ZlYHMuIFRoaXMgYWxvbmcgd2l0aCBpT1MgcXVpcmtzLCBqdXN0aWZpZXMgcmVzdHJpY3RpbmdcbiAgICogdG9wLWxldmVsIGxpc3RlbmVycyB0byB0aGUgZG9jdW1lbnQgb2JqZWN0IG9ubHksIGF0IGxlYXN0IGZvciB0aGVzZVxuICAgKiBtb3ZlbWVudCB0eXBlcyBvZiBldmVudHMgYW5kIHBvc3NpYmx5IGFsbCBldmVudHMuXG4gICAqXG4gICAqIEBzZWUgaHR0cDovL3d3dy5xdWlya3Ntb2RlLm9yZy9ibG9nL2FyY2hpdmVzLzIwMTAvMDkvY2xpY2tfZXZlbnRfZGVsLmh0bWxcbiAgICpcbiAgICogQWxzbywgYGtleXVwYC9ga2V5cHJlc3NgL2BrZXlkb3duYCBkbyBub3QgYnViYmxlIHRvIHRoZSB3aW5kb3cgb24gSUUsIGJ1dFxuICAgKiB0aGV5IGJ1YmJsZSB0byBkb2N1bWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlZ2lzdHJhdGlvbk5hbWUgTmFtZSBvZiBsaXN0ZW5lciAoZS5nLiBgb25DbGlja2ApLlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29udGVudERvY3VtZW50SGFuZGxlIERvY3VtZW50IHdoaWNoIG93bnMgdGhlIGNvbnRhaW5lclxuICAgKi9cbiAgbGlzdGVuVG86IGZ1bmN0aW9uIChyZWdpc3RyYXRpb25OYW1lLCBjb250ZW50RG9jdW1lbnRIYW5kbGUpIHtcbiAgICB2YXIgbW91bnRBdCA9IGNvbnRlbnREb2N1bWVudEhhbmRsZTtcbiAgICB2YXIgaXNMaXN0ZW5pbmcgPSBnZXRMaXN0ZW5pbmdGb3JEb2N1bWVudChtb3VudEF0KTtcbiAgICB2YXIgZGVwZW5kZW5jaWVzID0gRXZlbnRQbHVnaW5SZWdpc3RyeS5yZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzW3JlZ2lzdHJhdGlvbk5hbWVdO1xuXG4gICAgdmFyIHRvcExldmVsVHlwZXMgPSBFdmVudENvbnN0YW50cy50b3BMZXZlbFR5cGVzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZGVwZW5kZW5jeSA9IGRlcGVuZGVuY2llc1tpXTtcbiAgICAgIGlmICghKGlzTGlzdGVuaW5nLmhhc093blByb3BlcnR5KGRlcGVuZGVuY3kpICYmIGlzTGlzdGVuaW5nW2RlcGVuZGVuY3ldKSkge1xuICAgICAgICBpZiAoZGVwZW5kZW5jeSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BXaGVlbCkge1xuICAgICAgICAgIGlmIChpc0V2ZW50U3VwcG9ydGVkKCd3aGVlbCcpKSB7XG4gICAgICAgICAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBCdWJibGVkRXZlbnQodG9wTGV2ZWxUeXBlcy50b3BXaGVlbCwgJ3doZWVsJywgbW91bnRBdCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChpc0V2ZW50U3VwcG9ydGVkKCdtb3VzZXdoZWVsJykpIHtcbiAgICAgICAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIudHJhcEJ1YmJsZWRFdmVudCh0b3BMZXZlbFR5cGVzLnRvcFdoZWVsLCAnbW91c2V3aGVlbCcsIG1vdW50QXQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIHRvIGNhcHR1cmUgYSBkaWZmZXJlbnQgbW91c2Ugc2Nyb2xsIGV2ZW50LlxuICAgICAgICAgICAgLy8gQHNlZSBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2RvbS9ldmVudHMvdGVzdHMvc2Nyb2xsLmh0bWxcbiAgICAgICAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIudHJhcEJ1YmJsZWRFdmVudCh0b3BMZXZlbFR5cGVzLnRvcFdoZWVsLCAnRE9NTW91c2VTY3JvbGwnLCBtb3VudEF0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZGVwZW5kZW5jeSA9PT0gdG9wTGV2ZWxUeXBlcy50b3BTY3JvbGwpIHtcblxuICAgICAgICAgIGlmIChpc0V2ZW50U3VwcG9ydGVkKCdzY3JvbGwnLCB0cnVlKSkge1xuICAgICAgICAgICAgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLlJlYWN0RXZlbnRMaXN0ZW5lci50cmFwQ2FwdHVyZWRFdmVudCh0b3BMZXZlbFR5cGVzLnRvcFNjcm9sbCwgJ3Njcm9sbCcsIG1vdW50QXQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBCdWJibGVkRXZlbnQodG9wTGV2ZWxUeXBlcy50b3BTY3JvbGwsICdzY3JvbGwnLCBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLldJTkRPV19IQU5ETEUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChkZXBlbmRlbmN5ID09PSB0b3BMZXZlbFR5cGVzLnRvcEZvY3VzIHx8IGRlcGVuZGVuY3kgPT09IHRvcExldmVsVHlwZXMudG9wQmx1cikge1xuXG4gICAgICAgICAgaWYgKGlzRXZlbnRTdXBwb3J0ZWQoJ2ZvY3VzJywgdHJ1ZSkpIHtcbiAgICAgICAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIudHJhcENhcHR1cmVkRXZlbnQodG9wTGV2ZWxUeXBlcy50b3BGb2N1cywgJ2ZvY3VzJywgbW91bnRBdCk7XG4gICAgICAgICAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBDYXB0dXJlZEV2ZW50KHRvcExldmVsVHlwZXMudG9wQmx1ciwgJ2JsdXInLCBtb3VudEF0KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzRXZlbnRTdXBwb3J0ZWQoJ2ZvY3VzaW4nKSkge1xuICAgICAgICAgICAgLy8gSUUgaGFzIGBmb2N1c2luYCBhbmQgYGZvY3Vzb3V0YCBldmVudHMgd2hpY2ggYnViYmxlLlxuICAgICAgICAgICAgLy8gQHNlZSBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2Jsb2cvYXJjaGl2ZXMvMjAwOC8wNC9kZWxlZ2F0aW5nX3RoZS5odG1sXG4gICAgICAgICAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBCdWJibGVkRXZlbnQodG9wTGV2ZWxUeXBlcy50b3BGb2N1cywgJ2ZvY3VzaW4nLCBtb3VudEF0KTtcbiAgICAgICAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIudHJhcEJ1YmJsZWRFdmVudCh0b3BMZXZlbFR5cGVzLnRvcEJsdXIsICdmb2N1c291dCcsIG1vdW50QXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHRvIG1ha2Ugc3VyZSBibHVyIGFuZCBmb2N1cyBldmVudCBsaXN0ZW5lcnMgYXJlIG9ubHkgYXR0YWNoZWQgb25jZVxuICAgICAgICAgIGlzTGlzdGVuaW5nW3RvcExldmVsVHlwZXMudG9wQmx1cl0gPSB0cnVlO1xuICAgICAgICAgIGlzTGlzdGVuaW5nW3RvcExldmVsVHlwZXMudG9wRm9jdXNdID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmICh0b3BFdmVudE1hcHBpbmcuaGFzT3duUHJvcGVydHkoZGVwZW5kZW5jeSkpIHtcbiAgICAgICAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBCdWJibGVkRXZlbnQoZGVwZW5kZW5jeSwgdG9wRXZlbnRNYXBwaW5nW2RlcGVuZGVuY3ldLCBtb3VudEF0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlzTGlzdGVuaW5nW2RlcGVuZGVuY3ldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdHJhcEJ1YmJsZWRFdmVudDogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgaGFuZGxlckJhc2VOYW1lLCBoYW5kbGUpIHtcbiAgICByZXR1cm4gUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLlJlYWN0RXZlbnRMaXN0ZW5lci50cmFwQnViYmxlZEV2ZW50KHRvcExldmVsVHlwZSwgaGFuZGxlckJhc2VOYW1lLCBoYW5kbGUpO1xuICB9LFxuXG4gIHRyYXBDYXB0dXJlZEV2ZW50OiBmdW5jdGlvbiAodG9wTGV2ZWxUeXBlLCBoYW5kbGVyQmFzZU5hbWUsIGhhbmRsZSkge1xuICAgIHJldHVybiBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuUmVhY3RFdmVudExpc3RlbmVyLnRyYXBDYXB0dXJlZEV2ZW50KHRvcExldmVsVHlwZSwgaGFuZGxlckJhc2VOYW1lLCBoYW5kbGUpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBMaXN0ZW5zIHRvIHdpbmRvdyBzY3JvbGwgYW5kIHJlc2l6ZSBldmVudHMuIFdlIGNhY2hlIHNjcm9sbCB2YWx1ZXMgc28gdGhhdFxuICAgKiBhcHBsaWNhdGlvbiBjb2RlIGNhbiBhY2Nlc3MgdGhlbSB3aXRob3V0IHRyaWdnZXJpbmcgcmVmbG93cy5cbiAgICpcbiAgICogTk9URTogU2Nyb2xsIGV2ZW50cyBkbyBub3QgYnViYmxlLlxuICAgKlxuICAgKiBAc2VlIGh0dHA6Ly93d3cucXVpcmtzbW9kZS5vcmcvZG9tL2V2ZW50cy9zY3JvbGwuaHRtbFxuICAgKi9cbiAgZW5zdXJlU2Nyb2xsVmFsdWVNb25pdG9yaW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFpc01vbml0b3JpbmdTY3JvbGxWYWx1ZSkge1xuICAgICAgdmFyIHJlZnJlc2ggPSBWaWV3cG9ydE1ldHJpY3MucmVmcmVzaFNjcm9sbFZhbHVlcztcbiAgICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5SZWFjdEV2ZW50TGlzdGVuZXIubW9uaXRvclNjcm9sbFZhbHVlKHJlZnJlc2gpO1xuICAgICAgaXNNb25pdG9yaW5nU2Nyb2xsVmFsdWUgPSB0cnVlO1xuICAgIH1cbiAgfSxcblxuICBldmVudE5hbWVEaXNwYXRjaENvbmZpZ3M6IEV2ZW50UGx1Z2luSHViLmV2ZW50TmFtZURpc3BhdGNoQ29uZmlncyxcblxuICByZWdpc3RyYXRpb25OYW1lTW9kdWxlczogRXZlbnRQbHVnaW5IdWIucmVnaXN0cmF0aW9uTmFtZU1vZHVsZXMsXG5cbiAgcHV0TGlzdGVuZXI6IEV2ZW50UGx1Z2luSHViLnB1dExpc3RlbmVyLFxuXG4gIGdldExpc3RlbmVyOiBFdmVudFBsdWdpbkh1Yi5nZXRMaXN0ZW5lcixcblxuICBkZWxldGVMaXN0ZW5lcjogRXZlbnRQbHVnaW5IdWIuZGVsZXRlTGlzdGVuZXIsXG5cbiAgZGVsZXRlQWxsTGlzdGVuZXJzOiBFdmVudFBsdWdpbkh1Yi5kZWxldGVBbGxMaXN0ZW5lcnNcblxufSk7XG5cblJlYWN0UGVyZi5tZWFzdXJlTWV0aG9kcyhSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIsICdSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXInLCB7XG4gIHB1dExpc3RlbmVyOiAncHV0TGlzdGVuZXInLFxuICBkZWxldGVMaXN0ZW5lcjogJ2RlbGV0ZUxpc3RlbmVyJ1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdENoaWxkUmVjb25jaWxlclxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFJlY29uY2lsZXIgPSByZXF1aXJlKCcuL1JlYWN0UmVjb25jaWxlcicpO1xuXG52YXIgaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudCA9IHJlcXVpcmUoJy4vaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudCcpO1xudmFyIHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50ID0gcmVxdWlyZSgnLi9zaG91bGRVcGRhdGVSZWFjdENvbXBvbmVudCcpO1xudmFyIHRyYXZlcnNlQWxsQ2hpbGRyZW4gPSByZXF1aXJlKCcuL3RyYXZlcnNlQWxsQ2hpbGRyZW4nKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG5mdW5jdGlvbiBpbnN0YW50aWF0ZUNoaWxkKGNoaWxkSW5zdGFuY2VzLCBjaGlsZCwgbmFtZSkge1xuICAvLyBXZSBmb3VuZCBhIGNvbXBvbmVudCBpbnN0YW5jZS5cbiAgdmFyIGtleVVuaXF1ZSA9IGNoaWxkSW5zdGFuY2VzW25hbWVdID09PSB1bmRlZmluZWQ7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoa2V5VW5pcXVlLCAnZmxhdHRlbkNoaWxkcmVuKC4uLik6IEVuY291bnRlcmVkIHR3byBjaGlsZHJlbiB3aXRoIHRoZSBzYW1lIGtleSwgJyArICdgJXNgLiBDaGlsZCBrZXlzIG11c3QgYmUgdW5pcXVlOyB3aGVuIHR3byBjaGlsZHJlbiBzaGFyZSBhIGtleSwgb25seSAnICsgJ3RoZSBmaXJzdCBjaGlsZCB3aWxsIGJlIHVzZWQuJywgbmFtZSkgOiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKGNoaWxkICE9IG51bGwgJiYga2V5VW5pcXVlKSB7XG4gICAgY2hpbGRJbnN0YW5jZXNbbmFtZV0gPSBpbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50KGNoaWxkLCBudWxsKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlYWN0Q2hpbGRSZWNvbmNpbGVyIHByb3ZpZGVzIGhlbHBlcnMgZm9yIGluaXRpYWxpemluZyBvciB1cGRhdGluZyBhIHNldCBvZlxuICogY2hpbGRyZW4uIEl0cyBvdXRwdXQgaXMgc3VpdGFibGUgZm9yIHBhc3NpbmcgaXQgb250byBSZWFjdE11bHRpQ2hpbGQgd2hpY2hcbiAqIGRvZXMgZGlmZmVkIHJlb3JkZXJpbmcgYW5kIGluc2VydGlvbi5cbiAqL1xudmFyIFJlYWN0Q2hpbGRSZWNvbmNpbGVyID0ge1xuICAvKipcbiAgICogR2VuZXJhdGVzIGEgXCJtb3VudCBpbWFnZVwiIGZvciBlYWNoIG9mIHRoZSBzdXBwbGllZCBjaGlsZHJlbi4gSW4gdGhlIGNhc2VcbiAgICogb2YgYFJlYWN0RE9NQ29tcG9uZW50YCwgYSBtb3VudCBpbWFnZSBpcyBhIHN0cmluZyBvZiBtYXJrdXAuXG4gICAqXG4gICAqIEBwYXJhbSB7P29iamVjdH0gbmVzdGVkQ2hpbGROb2RlcyBOZXN0ZWQgY2hpbGQgbWFwcy5cbiAgICogQHJldHVybiB7P29iamVjdH0gQSBzZXQgb2YgY2hpbGQgaW5zdGFuY2VzLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGluc3RhbnRpYXRlQ2hpbGRyZW46IGZ1bmN0aW9uIChuZXN0ZWRDaGlsZE5vZGVzLCB0cmFuc2FjdGlvbiwgY29udGV4dCkge1xuICAgIGlmIChuZXN0ZWRDaGlsZE5vZGVzID09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgY2hpbGRJbnN0YW5jZXMgPSB7fTtcbiAgICB0cmF2ZXJzZUFsbENoaWxkcmVuKG5lc3RlZENoaWxkTm9kZXMsIGluc3RhbnRpYXRlQ2hpbGQsIGNoaWxkSW5zdGFuY2VzKTtcbiAgICByZXR1cm4gY2hpbGRJbnN0YW5jZXM7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIHJlbmRlcmVkIGNoaWxkcmVuIGFuZCByZXR1cm5zIGEgbmV3IHNldCBvZiBjaGlsZHJlbi5cbiAgICpcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBwcmV2Q2hpbGRyZW4gUHJldmlvdXNseSBpbml0aWFsaXplZCBzZXQgb2YgY2hpbGRyZW4uXG4gICAqIEBwYXJhbSB7P29iamVjdH0gbmV4dENoaWxkcmVuIEZsYXQgY2hpbGQgZWxlbWVudCBtYXBzLlxuICAgKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0XG4gICAqIEByZXR1cm4gez9vYmplY3R9IEEgbmV3IHNldCBvZiBjaGlsZCBpbnN0YW5jZXMuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdXBkYXRlQ2hpbGRyZW46IGZ1bmN0aW9uIChwcmV2Q2hpbGRyZW4sIG5leHRDaGlsZHJlbiwgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICAvLyBXZSBjdXJyZW50bHkgZG9uJ3QgaGF2ZSBhIHdheSB0byB0cmFjayBtb3ZlcyBoZXJlIGJ1dCBpZiB3ZSB1c2UgaXRlcmF0b3JzXG4gICAgLy8gaW5zdGVhZCBvZiBmb3IuLmluIHdlIGNhbiB6aXAgdGhlIGl0ZXJhdG9ycyBhbmQgY2hlY2sgaWYgYW4gaXRlbSBoYXNcbiAgICAvLyBtb3ZlZC5cbiAgICAvLyBUT0RPOiBJZiBub3RoaW5nIGhhcyBjaGFuZ2VkLCByZXR1cm4gdGhlIHByZXZDaGlsZHJlbiBvYmplY3Qgc28gdGhhdCB3ZVxuICAgIC8vIGNhbiBxdWlja2x5IGJhaWxvdXQgaWYgbm90aGluZyBoYXMgY2hhbmdlZC5cbiAgICBpZiAoIW5leHRDaGlsZHJlbiAmJiAhcHJldkNoaWxkcmVuKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIG5hbWU7XG4gICAgZm9yIChuYW1lIGluIG5leHRDaGlsZHJlbikge1xuICAgICAgaWYgKCFuZXh0Q2hpbGRyZW4uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB2YXIgcHJldkNoaWxkID0gcHJldkNoaWxkcmVuICYmIHByZXZDaGlsZHJlbltuYW1lXTtcbiAgICAgIHZhciBwcmV2RWxlbWVudCA9IHByZXZDaGlsZCAmJiBwcmV2Q2hpbGQuX2N1cnJlbnRFbGVtZW50O1xuICAgICAgdmFyIG5leHRFbGVtZW50ID0gbmV4dENoaWxkcmVuW25hbWVdO1xuICAgICAgaWYgKHByZXZDaGlsZCAhPSBudWxsICYmIHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50KHByZXZFbGVtZW50LCBuZXh0RWxlbWVudCkpIHtcbiAgICAgICAgUmVhY3RSZWNvbmNpbGVyLnJlY2VpdmVDb21wb25lbnQocHJldkNoaWxkLCBuZXh0RWxlbWVudCwgdHJhbnNhY3Rpb24sIGNvbnRleHQpO1xuICAgICAgICBuZXh0Q2hpbGRyZW5bbmFtZV0gPSBwcmV2Q2hpbGQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocHJldkNoaWxkKSB7XG4gICAgICAgICAgUmVhY3RSZWNvbmNpbGVyLnVubW91bnRDb21wb25lbnQocHJldkNoaWxkLCBuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgY2hpbGQgbXVzdCBiZSBpbnN0YW50aWF0ZWQgYmVmb3JlIGl0J3MgbW91bnRlZC5cbiAgICAgICAgdmFyIG5leHRDaGlsZEluc3RhbmNlID0gaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudChuZXh0RWxlbWVudCwgbnVsbCk7XG4gICAgICAgIG5leHRDaGlsZHJlbltuYW1lXSA9IG5leHRDaGlsZEluc3RhbmNlO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBVbm1vdW50IGNoaWxkcmVuIHRoYXQgYXJlIG5vIGxvbmdlciBwcmVzZW50LlxuICAgIGZvciAobmFtZSBpbiBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgIGlmIChwcmV2Q2hpbGRyZW4uaGFzT3duUHJvcGVydHkobmFtZSkgJiYgIShuZXh0Q2hpbGRyZW4gJiYgbmV4dENoaWxkcmVuLmhhc093blByb3BlcnR5KG5hbWUpKSkge1xuICAgICAgICBSZWFjdFJlY29uY2lsZXIudW5tb3VudENvbXBvbmVudChwcmV2Q2hpbGRyZW5bbmFtZV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV4dENoaWxkcmVuO1xuICB9LFxuXG4gIC8qKlxuICAgKiBVbm1vdW50cyBhbGwgcmVuZGVyZWQgY2hpbGRyZW4uIFRoaXMgc2hvdWxkIGJlIHVzZWQgdG8gY2xlYW4gdXAgY2hpbGRyZW5cbiAgICogd2hlbiB0aGlzIGNvbXBvbmVudCBpcyB1bm1vdW50ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7P29iamVjdH0gcmVuZGVyZWRDaGlsZHJlbiBQcmV2aW91c2x5IGluaXRpYWxpemVkIHNldCBvZiBjaGlsZHJlbi5cbiAgICogQGludGVybmFsXG4gICAqL1xuICB1bm1vdW50Q2hpbGRyZW46IGZ1bmN0aW9uIChyZW5kZXJlZENoaWxkcmVuKSB7XG4gICAgZm9yICh2YXIgbmFtZSBpbiByZW5kZXJlZENoaWxkcmVuKSB7XG4gICAgICBpZiAocmVuZGVyZWRDaGlsZHJlbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICB2YXIgcmVuZGVyZWRDaGlsZCA9IHJlbmRlcmVkQ2hpbGRyZW5bbmFtZV07XG4gICAgICAgIFJlYWN0UmVjb25jaWxlci51bm1vdW50Q29tcG9uZW50KHJlbmRlcmVkQ2hpbGQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0Q2hpbGRSZWNvbmNpbGVyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdENoaWxkcmVuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9vbGVkQ2xhc3MgPSByZXF1aXJlKCcuL1Bvb2xlZENsYXNzJyk7XG52YXIgUmVhY3RFbGVtZW50ID0gcmVxdWlyZSgnLi9SZWFjdEVsZW1lbnQnKTtcblxudmFyIGVtcHR5RnVuY3Rpb24gPSByZXF1aXJlKCdmYmpzL2xpYi9lbXB0eUZ1bmN0aW9uJyk7XG52YXIgdHJhdmVyc2VBbGxDaGlsZHJlbiA9IHJlcXVpcmUoJy4vdHJhdmVyc2VBbGxDaGlsZHJlbicpO1xuXG52YXIgdHdvQXJndW1lbnRQb29sZXIgPSBQb29sZWRDbGFzcy50d29Bcmd1bWVudFBvb2xlcjtcbnZhciBmb3VyQXJndW1lbnRQb29sZXIgPSBQb29sZWRDbGFzcy5mb3VyQXJndW1lbnRQb29sZXI7XG5cbnZhciB1c2VyUHJvdmlkZWRLZXlFc2NhcGVSZWdleCA9IC9cXC8oPyFcXC8pL2c7XG5mdW5jdGlvbiBlc2NhcGVVc2VyUHJvdmlkZWRLZXkodGV4dCkge1xuICByZXR1cm4gKCcnICsgdGV4dCkucmVwbGFjZSh1c2VyUHJvdmlkZWRLZXlFc2NhcGVSZWdleCwgJy8vJyk7XG59XG5cbi8qKlxuICogUG9vbGVkQ2xhc3MgcmVwcmVzZW50aW5nIHRoZSBib29ra2VlcGluZyBhc3NvY2lhdGVkIHdpdGggcGVyZm9ybWluZyBhIGNoaWxkXG4gKiB0cmF2ZXJzYWwuIEFsbG93cyBhdm9pZGluZyBiaW5kaW5nIGNhbGxiYWNrcy5cbiAqXG4gKiBAY29uc3RydWN0b3IgRm9yRWFjaEJvb2tLZWVwaW5nXG4gKiBAcGFyYW0geyFmdW5jdGlvbn0gZm9yRWFjaEZ1bmN0aW9uIEZ1bmN0aW9uIHRvIHBlcmZvcm0gdHJhdmVyc2FsIHdpdGguXG4gKiBAcGFyYW0gez8qfSBmb3JFYWNoQ29udGV4dCBDb250ZXh0IHRvIHBlcmZvcm0gY29udGV4dCB3aXRoLlxuICovXG5mdW5jdGlvbiBGb3JFYWNoQm9va0tlZXBpbmcoZm9yRWFjaEZ1bmN0aW9uLCBmb3JFYWNoQ29udGV4dCkge1xuICB0aGlzLmZ1bmMgPSBmb3JFYWNoRnVuY3Rpb247XG4gIHRoaXMuY29udGV4dCA9IGZvckVhY2hDb250ZXh0O1xuICB0aGlzLmNvdW50ID0gMDtcbn1cbkZvckVhY2hCb29rS2VlcGluZy5wcm90b3R5cGUuZGVzdHJ1Y3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mdW5jID0gbnVsbDtcbiAgdGhpcy5jb250ZXh0ID0gbnVsbDtcbiAgdGhpcy5jb3VudCA9IDA7XG59O1xuUG9vbGVkQ2xhc3MuYWRkUG9vbGluZ1RvKEZvckVhY2hCb29rS2VlcGluZywgdHdvQXJndW1lbnRQb29sZXIpO1xuXG5mdW5jdGlvbiBmb3JFYWNoU2luZ2xlQ2hpbGQoYm9va0tlZXBpbmcsIGNoaWxkLCBuYW1lKSB7XG4gIHZhciBmdW5jID0gYm9va0tlZXBpbmcuZnVuYztcbiAgdmFyIGNvbnRleHQgPSBib29rS2VlcGluZy5jb250ZXh0O1xuXG4gIGZ1bmMuY2FsbChjb250ZXh0LCBjaGlsZCwgYm9va0tlZXBpbmcuY291bnQrKyk7XG59XG5cbi8qKlxuICogSXRlcmF0ZXMgdGhyb3VnaCBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAuXG4gKlxuICogVGhlIHByb3ZpZGVkIGZvckVhY2hGdW5jKGNoaWxkLCBpbmRleCkgd2lsbCBiZSBjYWxsZWQgZm9yIGVhY2hcbiAqIGxlYWYgY2hpbGQuXG4gKlxuICogQHBhcmFtIHs/Kn0gY2hpbGRyZW4gQ2hpbGRyZW4gdHJlZSBjb250YWluZXIuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosIGludCl9IGZvckVhY2hGdW5jXG4gKiBAcGFyYW0geyp9IGZvckVhY2hDb250ZXh0IENvbnRleHQgZm9yIGZvckVhY2hDb250ZXh0LlxuICovXG5mdW5jdGlvbiBmb3JFYWNoQ2hpbGRyZW4oY2hpbGRyZW4sIGZvckVhY2hGdW5jLCBmb3JFYWNoQ29udGV4dCkge1xuICBpZiAoY2hpbGRyZW4gPT0gbnVsbCkge1xuICAgIHJldHVybiBjaGlsZHJlbjtcbiAgfVxuICB2YXIgdHJhdmVyc2VDb250ZXh0ID0gRm9yRWFjaEJvb2tLZWVwaW5nLmdldFBvb2xlZChmb3JFYWNoRnVuYywgZm9yRWFjaENvbnRleHQpO1xuICB0cmF2ZXJzZUFsbENoaWxkcmVuKGNoaWxkcmVuLCBmb3JFYWNoU2luZ2xlQ2hpbGQsIHRyYXZlcnNlQ29udGV4dCk7XG4gIEZvckVhY2hCb29rS2VlcGluZy5yZWxlYXNlKHRyYXZlcnNlQ29udGV4dCk7XG59XG5cbi8qKlxuICogUG9vbGVkQ2xhc3MgcmVwcmVzZW50aW5nIHRoZSBib29ra2VlcGluZyBhc3NvY2lhdGVkIHdpdGggcGVyZm9ybWluZyBhIGNoaWxkXG4gKiBtYXBwaW5nLiBBbGxvd3MgYXZvaWRpbmcgYmluZGluZyBjYWxsYmFja3MuXG4gKlxuICogQGNvbnN0cnVjdG9yIE1hcEJvb2tLZWVwaW5nXG4gKiBAcGFyYW0geyEqfSBtYXBSZXN1bHQgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIG9yZGVyZWQgbWFwIG9mIHJlc3VsdHMuXG4gKiBAcGFyYW0geyFmdW5jdGlvbn0gbWFwRnVuY3Rpb24gRnVuY3Rpb24gdG8gcGVyZm9ybSBtYXBwaW5nIHdpdGguXG4gKiBAcGFyYW0gez8qfSBtYXBDb250ZXh0IENvbnRleHQgdG8gcGVyZm9ybSBtYXBwaW5nIHdpdGguXG4gKi9cbmZ1bmN0aW9uIE1hcEJvb2tLZWVwaW5nKG1hcFJlc3VsdCwga2V5UHJlZml4LCBtYXBGdW5jdGlvbiwgbWFwQ29udGV4dCkge1xuICB0aGlzLnJlc3VsdCA9IG1hcFJlc3VsdDtcbiAgdGhpcy5rZXlQcmVmaXggPSBrZXlQcmVmaXg7XG4gIHRoaXMuZnVuYyA9IG1hcEZ1bmN0aW9uO1xuICB0aGlzLmNvbnRleHQgPSBtYXBDb250ZXh0O1xuICB0aGlzLmNvdW50ID0gMDtcbn1cbk1hcEJvb2tLZWVwaW5nLnByb3RvdHlwZS5kZXN0cnVjdG9yID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnJlc3VsdCA9IG51bGw7XG4gIHRoaXMua2V5UHJlZml4ID0gbnVsbDtcbiAgdGhpcy5mdW5jID0gbnVsbDtcbiAgdGhpcy5jb250ZXh0ID0gbnVsbDtcbiAgdGhpcy5jb3VudCA9IDA7XG59O1xuUG9vbGVkQ2xhc3MuYWRkUG9vbGluZ1RvKE1hcEJvb2tLZWVwaW5nLCBmb3VyQXJndW1lbnRQb29sZXIpO1xuXG5mdW5jdGlvbiBtYXBTaW5nbGVDaGlsZEludG9Db250ZXh0KGJvb2tLZWVwaW5nLCBjaGlsZCwgY2hpbGRLZXkpIHtcbiAgdmFyIHJlc3VsdCA9IGJvb2tLZWVwaW5nLnJlc3VsdDtcbiAgdmFyIGtleVByZWZpeCA9IGJvb2tLZWVwaW5nLmtleVByZWZpeDtcbiAgdmFyIGZ1bmMgPSBib29rS2VlcGluZy5mdW5jO1xuICB2YXIgY29udGV4dCA9IGJvb2tLZWVwaW5nLmNvbnRleHQ7XG5cbiAgdmFyIG1hcHBlZENoaWxkID0gZnVuYy5jYWxsKGNvbnRleHQsIGNoaWxkLCBib29rS2VlcGluZy5jb3VudCsrKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkobWFwcGVkQ2hpbGQpKSB7XG4gICAgbWFwSW50b1dpdGhLZXlQcmVmaXhJbnRlcm5hbChtYXBwZWRDaGlsZCwgcmVzdWx0LCBjaGlsZEtleSwgZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc0FyZ3VtZW50KTtcbiAgfSBlbHNlIGlmIChtYXBwZWRDaGlsZCAhPSBudWxsKSB7XG4gICAgaWYgKFJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChtYXBwZWRDaGlsZCkpIHtcbiAgICAgIG1hcHBlZENoaWxkID0gUmVhY3RFbGVtZW50LmNsb25lQW5kUmVwbGFjZUtleShtYXBwZWRDaGlsZCxcbiAgICAgIC8vIEtlZXAgYm90aCB0aGUgKG1hcHBlZCkgYW5kIG9sZCBrZXlzIGlmIHRoZXkgZGlmZmVyLCBqdXN0IGFzXG4gICAgICAvLyB0cmF2ZXJzZUFsbENoaWxkcmVuIHVzZWQgdG8gZG8gZm9yIG9iamVjdHMgYXMgY2hpbGRyZW5cbiAgICAgIGtleVByZWZpeCArIChtYXBwZWRDaGlsZCAhPT0gY2hpbGQgPyBlc2NhcGVVc2VyUHJvdmlkZWRLZXkobWFwcGVkQ2hpbGQua2V5IHx8ICcnKSArICcvJyA6ICcnKSArIGNoaWxkS2V5KTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2gobWFwcGVkQ2hpbGQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcEludG9XaXRoS2V5UHJlZml4SW50ZXJuYWwoY2hpbGRyZW4sIGFycmF5LCBwcmVmaXgsIGZ1bmMsIGNvbnRleHQpIHtcbiAgdmFyIGVzY2FwZWRQcmVmaXggPSAnJztcbiAgaWYgKHByZWZpeCAhPSBudWxsKSB7XG4gICAgZXNjYXBlZFByZWZpeCA9IGVzY2FwZVVzZXJQcm92aWRlZEtleShwcmVmaXgpICsgJy8nO1xuICB9XG4gIHZhciB0cmF2ZXJzZUNvbnRleHQgPSBNYXBCb29rS2VlcGluZy5nZXRQb29sZWQoYXJyYXksIGVzY2FwZWRQcmVmaXgsIGZ1bmMsIGNvbnRleHQpO1xuICB0cmF2ZXJzZUFsbENoaWxkcmVuKGNoaWxkcmVuLCBtYXBTaW5nbGVDaGlsZEludG9Db250ZXh0LCB0cmF2ZXJzZUNvbnRleHQpO1xuICBNYXBCb29rS2VlcGluZy5yZWxlYXNlKHRyYXZlcnNlQ29udGV4dCk7XG59XG5cbi8qKlxuICogTWFwcyBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAuXG4gKlxuICogVGhlIHByb3ZpZGVkIG1hcEZ1bmN0aW9uKGNoaWxkLCBrZXksIGluZGV4KSB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaFxuICogbGVhZiBjaGlsZC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIGNvbnRhaW5lci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgaW50KX0gZnVuYyBUaGUgbWFwIGZ1bmN0aW9uLlxuICogQHBhcmFtIHsqfSBjb250ZXh0IENvbnRleHQgZm9yIG1hcEZ1bmN0aW9uLlxuICogQHJldHVybiB7b2JqZWN0fSBPYmplY3QgY29udGFpbmluZyB0aGUgb3JkZXJlZCBtYXAgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmMsIGNvbnRleHQpIHtcbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHtcbiAgICByZXR1cm4gY2hpbGRyZW47XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBtYXBJbnRvV2l0aEtleVByZWZpeEludGVybmFsKGNoaWxkcmVuLCByZXN1bHQsIG51bGwsIGZ1bmMsIGNvbnRleHQpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoU2luZ2xlQ2hpbGREdW1teSh0cmF2ZXJzZUNvbnRleHQsIGNoaWxkLCBuYW1lKSB7XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIENvdW50IHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gdGhhdCBhcmUgdHlwaWNhbGx5IHNwZWNpZmllZCBhc1xuICogYHByb3BzLmNoaWxkcmVuYC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIGNvbnRhaW5lci5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbi5cbiAqL1xuZnVuY3Rpb24gY291bnRDaGlsZHJlbihjaGlsZHJlbiwgY29udGV4dCkge1xuICByZXR1cm4gdHJhdmVyc2VBbGxDaGlsZHJlbihjaGlsZHJlbiwgZm9yRWFjaFNpbmdsZUNoaWxkRHVtbXksIG51bGwpO1xufVxuXG4vKipcbiAqIEZsYXR0ZW4gYSBjaGlsZHJlbiBvYmplY3QgKHR5cGljYWxseSBzcGVjaWZpZWQgYXMgYHByb3BzLmNoaWxkcmVuYCkgYW5kXG4gKiByZXR1cm4gYW4gYXJyYXkgd2l0aCBhcHByb3ByaWF0ZWx5IHJlLWtleWVkIGNoaWxkcmVuLlxuICovXG5mdW5jdGlvbiB0b0FycmF5KGNoaWxkcmVuKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgbWFwSW50b1dpdGhLZXlQcmVmaXhJbnRlcm5hbChjaGlsZHJlbiwgcmVzdWx0LCBudWxsLCBlbXB0eUZ1bmN0aW9uLnRoYXRSZXR1cm5zQXJndW1lbnQpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG52YXIgUmVhY3RDaGlsZHJlbiA9IHtcbiAgZm9yRWFjaDogZm9yRWFjaENoaWxkcmVuLFxuICBtYXA6IG1hcENoaWxkcmVuLFxuICBtYXBJbnRvV2l0aEtleVByZWZpeEludGVybmFsOiBtYXBJbnRvV2l0aEtleVByZWZpeEludGVybmFsLFxuICBjb3VudDogY291bnRDaGlsZHJlbixcbiAgdG9BcnJheTogdG9BcnJheVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdENoaWxkcmVuOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdENsYXNzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RDb21wb25lbnQgPSByZXF1aXJlKCcuL1JlYWN0Q29tcG9uZW50Jyk7XG52YXIgUmVhY3RFbGVtZW50ID0gcmVxdWlyZSgnLi9SZWFjdEVsZW1lbnQnKTtcbnZhciBSZWFjdFByb3BUeXBlTG9jYXRpb25zID0gcmVxdWlyZSgnLi9SZWFjdFByb3BUeXBlTG9jYXRpb25zJyk7XG52YXIgUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXMgPSByZXF1aXJlKCcuL1JlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzJyk7XG52YXIgUmVhY3ROb29wVXBkYXRlUXVldWUgPSByZXF1aXJlKCcuL1JlYWN0Tm9vcFVwZGF0ZVF1ZXVlJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBlbXB0eU9iamVjdCA9IHJlcXVpcmUoJ2ZianMvbGliL2VtcHR5T2JqZWN0Jyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIga2V5TWlycm9yID0gcmVxdWlyZSgnZmJqcy9saWIva2V5TWlycm9yJyk7XG52YXIga2V5T2YgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlPZicpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciBNSVhJTlNfS0VZID0ga2V5T2YoeyBtaXhpbnM6IG51bGwgfSk7XG5cbi8qKlxuICogUG9saWNpZXMgdGhhdCBkZXNjcmliZSBtZXRob2RzIGluIGBSZWFjdENsYXNzSW50ZXJmYWNlYC5cbiAqL1xudmFyIFNwZWNQb2xpY3kgPSBrZXlNaXJyb3Ioe1xuICAvKipcbiAgICogVGhlc2UgbWV0aG9kcyBtYXkgYmUgZGVmaW5lZCBvbmx5IG9uY2UgYnkgdGhlIGNsYXNzIHNwZWNpZmljYXRpb24gb3IgbWl4aW4uXG4gICAqL1xuICBERUZJTkVfT05DRTogbnVsbCxcbiAgLyoqXG4gICAqIFRoZXNlIG1ldGhvZHMgbWF5IGJlIGRlZmluZWQgYnkgYm90aCB0aGUgY2xhc3Mgc3BlY2lmaWNhdGlvbiBhbmQgbWl4aW5zLlxuICAgKiBTdWJzZXF1ZW50IGRlZmluaXRpb25zIHdpbGwgYmUgY2hhaW5lZC4gVGhlc2UgbWV0aG9kcyBtdXN0IHJldHVybiB2b2lkLlxuICAgKi9cbiAgREVGSU5FX01BTlk6IG51bGwsXG4gIC8qKlxuICAgKiBUaGVzZSBtZXRob2RzIGFyZSBvdmVycmlkaW5nIHRoZSBiYXNlIGNsYXNzLlxuICAgKi9cbiAgT1ZFUlJJREVfQkFTRTogbnVsbCxcbiAgLyoqXG4gICAqIFRoZXNlIG1ldGhvZHMgYXJlIHNpbWlsYXIgdG8gREVGSU5FX01BTlksIGV4Y2VwdCB3ZSBhc3N1bWUgdGhleSByZXR1cm5cbiAgICogb2JqZWN0cy4gV2UgdHJ5IHRvIG1lcmdlIHRoZSBrZXlzIG9mIHRoZSByZXR1cm4gdmFsdWVzIG9mIGFsbCB0aGUgbWl4ZWQgaW5cbiAgICogZnVuY3Rpb25zLiBJZiB0aGVyZSBpcyBhIGtleSBjb25mbGljdCB3ZSB0aHJvdy5cbiAgICovXG4gIERFRklORV9NQU5ZX01FUkdFRDogbnVsbFxufSk7XG5cbnZhciBpbmplY3RlZE1peGlucyA9IFtdO1xuXG52YXIgd2FybmVkU2V0UHJvcHMgPSBmYWxzZTtcbmZ1bmN0aW9uIHdhcm5TZXRQcm9wcygpIHtcbiAgaWYgKCF3YXJuZWRTZXRQcm9wcykge1xuICAgIHdhcm5lZFNldFByb3BzID0gdHJ1ZTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ3NldFByb3BzKC4uLikgYW5kIHJlcGxhY2VQcm9wcyguLi4pIGFyZSBkZXByZWNhdGVkLiAnICsgJ0luc3RlYWQsIGNhbGwgcmVuZGVyIGFnYWluIGF0IHRoZSB0b3AgbGV2ZWwuJykgOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBDb21wb3NpdGUgY29tcG9uZW50cyBhcmUgaGlnaGVyLWxldmVsIGNvbXBvbmVudHMgdGhhdCBjb21wb3NlIG90aGVyIGNvbXBvc2l0ZVxuICogb3IgbmF0aXZlIGNvbXBvbmVudHMuXG4gKlxuICogVG8gY3JlYXRlIGEgbmV3IHR5cGUgb2YgYFJlYWN0Q2xhc3NgLCBwYXNzIGEgc3BlY2lmaWNhdGlvbiBvZlxuICogeW91ciBuZXcgY2xhc3MgdG8gYFJlYWN0LmNyZWF0ZUNsYXNzYC4gVGhlIG9ubHkgcmVxdWlyZW1lbnQgb2YgeW91ciBjbGFzc1xuICogc3BlY2lmaWNhdGlvbiBpcyB0aGF0IHlvdSBpbXBsZW1lbnQgYSBgcmVuZGVyYCBtZXRob2QuXG4gKlxuICogICB2YXIgTXlDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gKiAgICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAqICAgICAgIHJldHVybiA8ZGl2PkhlbGxvIFdvcmxkPC9kaXY+O1xuICogICAgIH1cbiAqICAgfSk7XG4gKlxuICogVGhlIGNsYXNzIHNwZWNpZmljYXRpb24gc3VwcG9ydHMgYSBzcGVjaWZpYyBwcm90b2NvbCBvZiBtZXRob2RzIHRoYXQgaGF2ZVxuICogc3BlY2lhbCBtZWFuaW5nIChlLmcuIGByZW5kZXJgKS4gU2VlIGBSZWFjdENsYXNzSW50ZXJmYWNlYCBmb3JcbiAqIG1vcmUgdGhlIGNvbXByZWhlbnNpdmUgcHJvdG9jb2wuIEFueSBvdGhlciBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzIGluIHRoZVxuICogY2xhc3Mgc3BlY2lmaWNhdGlvbiB3aWxsIGJlIGF2YWlsYWJsZSBvbiB0aGUgcHJvdG90eXBlLlxuICpcbiAqIEBpbnRlcmZhY2UgUmVhY3RDbGFzc0ludGVyZmFjZVxuICogQGludGVybmFsXG4gKi9cbnZhciBSZWFjdENsYXNzSW50ZXJmYWNlID0ge1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBNaXhpbiBvYmplY3RzIHRvIGluY2x1ZGUgd2hlbiBkZWZpbmluZyB5b3VyIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHR5cGUge2FycmF5fVxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIG1peGluczogU3BlY1BvbGljeS5ERUZJTkVfTUFOWSxcblxuICAvKipcbiAgICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcyBhbmQgbWV0aG9kcyB0aGF0IHNob3VsZCBiZSBkZWZpbmVkIG9uXG4gICAqIHRoZSBjb21wb25lbnQncyBjb25zdHJ1Y3RvciBpbnN0ZWFkIG9mIGl0cyBwcm90b3R5cGUgKHN0YXRpYyBtZXRob2RzKS5cbiAgICpcbiAgICogQHR5cGUge29iamVjdH1cbiAgICogQG9wdGlvbmFsXG4gICAqL1xuICBzdGF0aWNzOiBTcGVjUG9saWN5LkRFRklORV9NQU5ZLFxuXG4gIC8qKlxuICAgKiBEZWZpbml0aW9uIG9mIHByb3AgdHlwZXMgZm9yIHRoaXMgY29tcG9uZW50LlxuICAgKlxuICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIHByb3BUeXBlczogU3BlY1BvbGljeS5ERUZJTkVfTUFOWSxcblxuICAvKipcbiAgICogRGVmaW5pdGlvbiBvZiBjb250ZXh0IHR5cGVzIGZvciB0aGlzIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHR5cGUge29iamVjdH1cbiAgICogQG9wdGlvbmFsXG4gICAqL1xuICBjb250ZXh0VHlwZXM6IFNwZWNQb2xpY3kuREVGSU5FX01BTlksXG5cbiAgLyoqXG4gICAqIERlZmluaXRpb24gb2YgY29udGV4dCB0eXBlcyB0aGlzIGNvbXBvbmVudCBzZXRzIGZvciBpdHMgY2hpbGRyZW4uXG4gICAqXG4gICAqIEB0eXBlIHtvYmplY3R9XG4gICAqIEBvcHRpb25hbFxuICAgKi9cbiAgY2hpbGRDb250ZXh0VHlwZXM6IFNwZWNQb2xpY3kuREVGSU5FX01BTlksXG5cbiAgLy8gPT09PSBEZWZpbml0aW9uIG1ldGhvZHMgPT09PVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBtb3VudGVkLiBWYWx1ZXMgaW4gdGhlIG1hcHBpbmcgd2lsbCBiZSBzZXQgb25cbiAgICogYHRoaXMucHJvcHNgIGlmIHRoYXQgcHJvcCBpcyBub3Qgc3BlY2lmaWVkIChpLmUuIHVzaW5nIGFuIGBpbmAgY2hlY2spLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBpbnZva2VkIGJlZm9yZSBgZ2V0SW5pdGlhbFN0YXRlYCBhbmQgdGhlcmVmb3JlIGNhbm5vdCByZWx5XG4gICAqIG9uIGB0aGlzLnN0YXRlYCBvciB1c2UgYHRoaXMuc2V0U3RhdGVgLlxuICAgKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAqIEBvcHRpb25hbFxuICAgKi9cbiAgZ2V0RGVmYXVsdFByb3BzOiBTcGVjUG9saWN5LkRFRklORV9NQU5ZX01FUkdFRCxcblxuICAvKipcbiAgICogSW52b2tlZCBvbmNlIGJlZm9yZSB0aGUgY29tcG9uZW50IGlzIG1vdW50ZWQuIFRoZSByZXR1cm4gdmFsdWUgd2lsbCBiZSB1c2VkXG4gICAqIGFzIHRoZSBpbml0aWFsIHZhbHVlIG9mIGB0aGlzLnN0YXRlYC5cbiAgICpcbiAgICogICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uKCkge1xuICAgKiAgICAgcmV0dXJuIHtcbiAgICogICAgICAgaXNPbjogZmFsc2UsXG4gICAqICAgICAgIGZvb0JhejogbmV3IEJhekZvbygpXG4gICAqICAgICB9XG4gICAqICAgfVxuICAgKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAqIEBvcHRpb25hbFxuICAgKi9cbiAgZ2V0SW5pdGlhbFN0YXRlOiBTcGVjUG9saWN5LkRFRklORV9NQU5ZX01FUkdFRCxcblxuICAvKipcbiAgICogQHJldHVybiB7b2JqZWN0fVxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIGdldENoaWxkQ29udGV4dDogU3BlY1BvbGljeS5ERUZJTkVfTUFOWV9NRVJHRUQsXG5cbiAgLyoqXG4gICAqIFVzZXMgcHJvcHMgZnJvbSBgdGhpcy5wcm9wc2AgYW5kIHN0YXRlIGZyb20gYHRoaXMuc3RhdGVgIHRvIHJlbmRlciB0aGVcbiAgICogc3RydWN0dXJlIG9mIHRoZSBjb21wb25lbnQuXG4gICAqXG4gICAqIE5vIGd1YXJhbnRlZXMgYXJlIG1hZGUgYWJvdXQgd2hlbiBvciBob3cgb2Z0ZW4gdGhpcyBtZXRob2QgaXMgaW52b2tlZCwgc29cbiAgICogaXQgbXVzdCBub3QgaGF2ZSBzaWRlIGVmZmVjdHMuXG4gICAqXG4gICAqICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICogICAgIHZhciBuYW1lID0gdGhpcy5wcm9wcy5uYW1lO1xuICAgKiAgICAgcmV0dXJuIDxkaXY+SGVsbG8sIHtuYW1lfSE8L2Rpdj47XG4gICAqICAgfVxuICAgKlxuICAgKiBAcmV0dXJuIHtSZWFjdENvbXBvbmVudH1cbiAgICogQG5vc2lkZWVmZmVjdHNcbiAgICogQHJlcXVpcmVkXG4gICAqL1xuICByZW5kZXI6IFNwZWNQb2xpY3kuREVGSU5FX09OQ0UsXG5cbiAgLy8gPT09PSBEZWxlZ2F0ZSBtZXRob2RzID09PT1cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgaW5pdGlhbGx5IGNyZWF0ZWQgYW5kIGFib3V0IHRvIGJlIG1vdW50ZWQuXG4gICAqIFRoaXMgbWF5IGhhdmUgc2lkZSBlZmZlY3RzLCBidXQgYW55IGV4dGVybmFsIHN1YnNjcmlwdGlvbnMgb3IgZGF0YSBjcmVhdGVkXG4gICAqIGJ5IHRoaXMgbWV0aG9kIG11c3QgYmUgY2xlYW5lZCB1cCBpbiBgY29tcG9uZW50V2lsbFVubW91bnRgLlxuICAgKlxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIGNvbXBvbmVudFdpbGxNb3VudDogU3BlY1BvbGljeS5ERUZJTkVfTUFOWSxcblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gbW91bnRlZCBhbmQgaGFzIGEgRE9NIHJlcHJlc2VudGF0aW9uLlxuICAgKiBIb3dldmVyLCB0aGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCB0aGUgRE9NIG5vZGUgaXMgaW4gdGhlIGRvY3VtZW50LlxuICAgKlxuICAgKiBVc2UgdGhpcyBhcyBhbiBvcHBvcnR1bml0eSB0byBvcGVyYXRlIG9uIHRoZSBET00gd2hlbiB0aGUgY29tcG9uZW50IGhhc1xuICAgKiBiZWVuIG1vdW50ZWQgKGluaXRpYWxpemVkIGFuZCByZW5kZXJlZCkgZm9yIHRoZSBmaXJzdCB0aW1lLlxuICAgKlxuICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IHJvb3ROb2RlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgY29tcG9uZW50LlxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIGNvbXBvbmVudERpZE1vdW50OiBTcGVjUG9saWN5LkRFRklORV9NQU5ZLFxuXG4gIC8qKlxuICAgKiBJbnZva2VkIGJlZm9yZSB0aGUgY29tcG9uZW50IHJlY2VpdmVzIG5ldyBwcm9wcy5cbiAgICpcbiAgICogVXNlIHRoaXMgYXMgYW4gb3Bwb3J0dW5pdHkgdG8gcmVhY3QgdG8gYSBwcm9wIHRyYW5zaXRpb24gYnkgdXBkYXRpbmcgdGhlXG4gICAqIHN0YXRlIHVzaW5nIGB0aGlzLnNldFN0YXRlYC4gQ3VycmVudCBwcm9wcyBhcmUgYWNjZXNzZWQgdmlhIGB0aGlzLnByb3BzYC5cbiAgICpcbiAgICogICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbihuZXh0UHJvcHMsIG5leHRDb250ZXh0KSB7XG4gICAqICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICogICAgICAgbGlrZXNJbmNyZWFzaW5nOiBuZXh0UHJvcHMubGlrZUNvdW50ID4gdGhpcy5wcm9wcy5saWtlQ291bnRcbiAgICogICAgIH0pO1xuICAgKiAgIH1cbiAgICpcbiAgICogTk9URTogVGhlcmUgaXMgbm8gZXF1aXZhbGVudCBgY29tcG9uZW50V2lsbFJlY2VpdmVTdGF0ZWAuIEFuIGluY29taW5nIHByb3BcbiAgICogdHJhbnNpdGlvbiBtYXkgY2F1c2UgYSBzdGF0ZSBjaGFuZ2UsIGJ1dCB0aGUgb3Bwb3NpdGUgaXMgbm90IHRydWUuIElmIHlvdVxuICAgKiBuZWVkIGl0LCB5b3UgYXJlIHByb2JhYmx5IGxvb2tpbmcgZm9yIGBjb21wb25lbnRXaWxsVXBkYXRlYC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG5leHRQcm9wc1xuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IFNwZWNQb2xpY3kuREVGSU5FX01BTlksXG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hpbGUgZGVjaWRpbmcgaWYgdGhlIGNvbXBvbmVudCBzaG91bGQgYmUgdXBkYXRlZCBhcyBhIHJlc3VsdCBvZlxuICAgKiByZWNlaXZpbmcgbmV3IHByb3BzLCBzdGF0ZSBhbmQvb3IgY29udGV4dC5cbiAgICpcbiAgICogVXNlIHRoaXMgYXMgYW4gb3Bwb3J0dW5pdHkgdG8gYHJldHVybiBmYWxzZWAgd2hlbiB5b3UncmUgY2VydGFpbiB0aGF0IHRoZVxuICAgKiB0cmFuc2l0aW9uIHRvIHRoZSBuZXcgcHJvcHMvc3RhdGUvY29udGV4dCB3aWxsIG5vdCByZXF1aXJlIGEgY29tcG9uZW50XG4gICAqIHVwZGF0ZS5cbiAgICpcbiAgICogICBzaG91bGRDb21wb25lbnRVcGRhdGU6IGZ1bmN0aW9uKG5leHRQcm9wcywgbmV4dFN0YXRlLCBuZXh0Q29udGV4dCkge1xuICAgKiAgICAgcmV0dXJuICFlcXVhbChuZXh0UHJvcHMsIHRoaXMucHJvcHMpIHx8XG4gICAqICAgICAgICFlcXVhbChuZXh0U3RhdGUsIHRoaXMuc3RhdGUpIHx8XG4gICAqICAgICAgICFlcXVhbChuZXh0Q29udGV4dCwgdGhpcy5jb250ZXh0KTtcbiAgICogICB9XG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBuZXh0UHJvcHNcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBuZXh0U3RhdGVcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBuZXh0Q29udGV4dFxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBjb21wb25lbnQgc2hvdWxkIHVwZGF0ZS5cbiAgICogQG9wdGlvbmFsXG4gICAqL1xuICBzaG91bGRDb21wb25lbnRVcGRhdGU6IFNwZWNQb2xpY3kuREVGSU5FX09OQ0UsXG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIGFib3V0IHRvIHVwZGF0ZSBkdWUgdG8gYSB0cmFuc2l0aW9uIGZyb21cbiAgICogYHRoaXMucHJvcHNgLCBgdGhpcy5zdGF0ZWAgYW5kIGB0aGlzLmNvbnRleHRgIHRvIGBuZXh0UHJvcHNgLCBgbmV4dFN0YXRlYFxuICAgKiBhbmQgYG5leHRDb250ZXh0YC5cbiAgICpcbiAgICogVXNlIHRoaXMgYXMgYW4gb3Bwb3J0dW5pdHkgdG8gcGVyZm9ybSBwcmVwYXJhdGlvbiBiZWZvcmUgYW4gdXBkYXRlIG9jY3Vycy5cbiAgICpcbiAgICogTk9URTogWW91ICoqY2Fubm90KiogdXNlIGB0aGlzLnNldFN0YXRlKClgIGluIHRoaXMgbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmV4dFByb3BzXG4gICAqIEBwYXJhbSB7P29iamVjdH0gbmV4dFN0YXRlXG4gICAqIEBwYXJhbSB7P29iamVjdH0gbmV4dENvbnRleHRcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAb3B0aW9uYWxcbiAgICovXG4gIGNvbXBvbmVudFdpbGxVcGRhdGU6IFNwZWNQb2xpY3kuREVGSU5FX01BTlksXG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiB0aGUgY29tcG9uZW50J3MgRE9NIHJlcHJlc2VudGF0aW9uIGhhcyBiZWVuIHVwZGF0ZWQuXG4gICAqXG4gICAqIFVzZSB0aGlzIGFzIGFuIG9wcG9ydHVuaXR5IHRvIG9wZXJhdGUgb24gdGhlIERPTSB3aGVuIHRoZSBjb21wb25lbnQgaGFzXG4gICAqIGJlZW4gdXBkYXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IHByZXZQcm9wc1xuICAgKiBAcGFyYW0gez9vYmplY3R9IHByZXZTdGF0ZVxuICAgKiBAcGFyYW0gez9vYmplY3R9IHByZXZDb250ZXh0XG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gcm9vdE5vZGUgRE9NIGVsZW1lbnQgcmVwcmVzZW50aW5nIHRoZSBjb21wb25lbnQuXG4gICAqIEBvcHRpb25hbFxuICAgKi9cbiAgY29tcG9uZW50RGlkVXBkYXRlOiBTcGVjUG9saWN5LkRFRklORV9NQU5ZLFxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBhYm91dCB0byBiZSByZW1vdmVkIGZyb20gaXRzIHBhcmVudCBhbmQgaGF2ZVxuICAgKiBpdHMgRE9NIHJlcHJlc2VudGF0aW9uIGRlc3Ryb3llZC5cbiAgICpcbiAgICogVXNlIHRoaXMgYXMgYW4gb3Bwb3J0dW5pdHkgdG8gZGVhbGxvY2F0ZSBhbnkgZXh0ZXJuYWwgcmVzb3VyY2VzLlxuICAgKlxuICAgKiBOT1RFOiBUaGVyZSBpcyBubyBgY29tcG9uZW50RGlkVW5tb3VudGAgc2luY2UgeW91ciBjb21wb25lbnQgd2lsbCBoYXZlIGJlZW5cbiAgICogZGVzdHJveWVkIGJ5IHRoYXQgcG9pbnQuXG4gICAqXG4gICAqIEBvcHRpb25hbFxuICAgKi9cbiAgY29tcG9uZW50V2lsbFVubW91bnQ6IFNwZWNQb2xpY3kuREVGSU5FX01BTlksXG5cbiAgLy8gPT09PSBBZHZhbmNlZCBtZXRob2RzID09PT1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgY29tcG9uZW50J3MgY3VycmVudGx5IG1vdW50ZWQgRE9NIHJlcHJlc2VudGF0aW9uLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCB0aGlzIGltcGxlbWVudHMgUmVhY3QncyByZW5kZXJpbmcgYW5kIHJlY29uY2lsaWF0aW9uIGFsZ29yaXRobS5cbiAgICogU29waGlzdGljYXRlZCBjbGllbnRzIG1heSB3aXNoIHRvIG92ZXJyaWRlIHRoaXMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQGludGVybmFsXG4gICAqIEBvdmVycmlkYWJsZVxuICAgKi9cbiAgdXBkYXRlQ29tcG9uZW50OiBTcGVjUG9saWN5Lk9WRVJSSURFX0JBU0VcblxufTtcblxuLyoqXG4gKiBNYXBwaW5nIGZyb20gY2xhc3Mgc3BlY2lmaWNhdGlvbiBrZXlzIHRvIHNwZWNpYWwgcHJvY2Vzc2luZyBmdW5jdGlvbnMuXG4gKlxuICogQWx0aG91Z2ggdGhlc2UgYXJlIGRlY2xhcmVkIGxpa2UgaW5zdGFuY2UgcHJvcGVydGllcyBpbiB0aGUgc3BlY2lmaWNhdGlvblxuICogd2hlbiBkZWZpbmluZyBjbGFzc2VzIHVzaW5nIGBSZWFjdC5jcmVhdGVDbGFzc2AsIHRoZXkgYXJlIGFjdHVhbGx5IHN0YXRpY1xuICogYW5kIGFyZSBhY2Nlc3NpYmxlIG9uIHRoZSBjb25zdHJ1Y3RvciBpbnN0ZWFkIG9mIHRoZSBwcm90b3R5cGUuIERlc3BpdGVcbiAqIGJlaW5nIHN0YXRpYywgdGhleSBtdXN0IGJlIGRlZmluZWQgb3V0c2lkZSBvZiB0aGUgXCJzdGF0aWNzXCIga2V5IHVuZGVyXG4gKiB3aGljaCBhbGwgb3RoZXIgc3RhdGljIG1ldGhvZHMgYXJlIGRlZmluZWQuXG4gKi9cbnZhciBSRVNFUlZFRF9TUEVDX0tFWVMgPSB7XG4gIGRpc3BsYXlOYW1lOiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIGRpc3BsYXlOYW1lKSB7XG4gICAgQ29uc3RydWN0b3IuZGlzcGxheU5hbWUgPSBkaXNwbGF5TmFtZTtcbiAgfSxcbiAgbWl4aW5zOiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIG1peGlucykge1xuICAgIGlmIChtaXhpbnMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWl4aW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG1peFNwZWNJbnRvQ29tcG9uZW50KENvbnN0cnVjdG9yLCBtaXhpbnNbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgY2hpbGRDb250ZXh0VHlwZXM6IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgY2hpbGRDb250ZXh0VHlwZXMpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgdmFsaWRhdGVUeXBlRGVmKENvbnN0cnVjdG9yLCBjaGlsZENvbnRleHRUeXBlcywgUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5jaGlsZENvbnRleHQpO1xuICAgIH1cbiAgICBDb25zdHJ1Y3Rvci5jaGlsZENvbnRleHRUeXBlcyA9IGFzc2lnbih7fSwgQ29uc3RydWN0b3IuY2hpbGRDb250ZXh0VHlwZXMsIGNoaWxkQ29udGV4dFR5cGVzKTtcbiAgfSxcbiAgY29udGV4dFR5cGVzOiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIGNvbnRleHRUeXBlcykge1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB2YWxpZGF0ZVR5cGVEZWYoQ29uc3RydWN0b3IsIGNvbnRleHRUeXBlcywgUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5jb250ZXh0KTtcbiAgICB9XG4gICAgQ29uc3RydWN0b3IuY29udGV4dFR5cGVzID0gYXNzaWduKHt9LCBDb25zdHJ1Y3Rvci5jb250ZXh0VHlwZXMsIGNvbnRleHRUeXBlcyk7XG4gIH0sXG4gIC8qKlxuICAgKiBTcGVjaWFsIGNhc2UgZ2V0RGVmYXVsdFByb3BzIHdoaWNoIHNob3VsZCBtb3ZlIGludG8gc3RhdGljcyBidXQgcmVxdWlyZXNcbiAgICogYXV0b21hdGljIG1lcmdpbmcuXG4gICAqL1xuICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgZ2V0RGVmYXVsdFByb3BzKSB7XG4gICAgaWYgKENvbnN0cnVjdG9yLmdldERlZmF1bHRQcm9wcykge1xuICAgICAgQ29uc3RydWN0b3IuZ2V0RGVmYXVsdFByb3BzID0gY3JlYXRlTWVyZ2VkUmVzdWx0RnVuY3Rpb24oQ29uc3RydWN0b3IuZ2V0RGVmYXVsdFByb3BzLCBnZXREZWZhdWx0UHJvcHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBDb25zdHJ1Y3Rvci5nZXREZWZhdWx0UHJvcHMgPSBnZXREZWZhdWx0UHJvcHM7XG4gICAgfVxuICB9LFxuICBwcm9wVHlwZXM6IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvcFR5cGVzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhbGlkYXRlVHlwZURlZihDb25zdHJ1Y3RvciwgcHJvcFR5cGVzLCBSZWFjdFByb3BUeXBlTG9jYXRpb25zLnByb3ApO1xuICAgIH1cbiAgICBDb25zdHJ1Y3Rvci5wcm9wVHlwZXMgPSBhc3NpZ24oe30sIENvbnN0cnVjdG9yLnByb3BUeXBlcywgcHJvcFR5cGVzKTtcbiAgfSxcbiAgc3RhdGljczogZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBzdGF0aWNzKSB7XG4gICAgbWl4U3RhdGljU3BlY0ludG9Db21wb25lbnQoQ29uc3RydWN0b3IsIHN0YXRpY3MpO1xuICB9LFxuICBhdXRvYmluZDogZnVuY3Rpb24gKCkge30gfTtcblxuLy8gbm9vcFxuZnVuY3Rpb24gdmFsaWRhdGVUeXBlRGVmKENvbnN0cnVjdG9yLCB0eXBlRGVmLCBsb2NhdGlvbikge1xuICBmb3IgKHZhciBwcm9wTmFtZSBpbiB0eXBlRGVmKSB7XG4gICAgaWYgKHR5cGVEZWYuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAvLyB1c2UgYSB3YXJuaW5nIGluc3RlYWQgb2YgYW4gaW52YXJpYW50IHNvIGNvbXBvbmVudHNcbiAgICAgIC8vIGRvbid0IHNob3cgdXAgaW4gcHJvZCBidXQgbm90IGluIF9fREVWX19cbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHR5cGVvZiB0eXBlRGVmW3Byb3BOYW1lXSA9PT0gJ2Z1bmN0aW9uJywgJyVzOiAlcyB0eXBlIGAlc2AgaXMgaW52YWxpZDsgaXQgbXVzdCBiZSBhIGZ1bmN0aW9uLCB1c3VhbGx5IGZyb20gJyArICdSZWFjdC5Qcm9wVHlwZXMuJywgQ29uc3RydWN0b3IuZGlzcGxheU5hbWUgfHwgJ1JlYWN0Q2xhc3MnLCBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lc1tsb2NhdGlvbl0sIHByb3BOYW1lKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVNZXRob2RPdmVycmlkZShwcm90bywgbmFtZSkge1xuICB2YXIgc3BlY1BvbGljeSA9IFJlYWN0Q2xhc3NJbnRlcmZhY2UuaGFzT3duUHJvcGVydHkobmFtZSkgPyBSZWFjdENsYXNzSW50ZXJmYWNlW25hbWVdIDogbnVsbDtcblxuICAvLyBEaXNhbGxvdyBvdmVycmlkaW5nIG9mIGJhc2UgY2xhc3MgbWV0aG9kcyB1bmxlc3MgZXhwbGljaXRseSBhbGxvd2VkLlxuICBpZiAoUmVhY3RDbGFzc01peGluLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgIShzcGVjUG9saWN5ID09PSBTcGVjUG9saWN5Lk9WRVJSSURFX0JBU0UpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0Q2xhc3NJbnRlcmZhY2U6IFlvdSBhcmUgYXR0ZW1wdGluZyB0byBvdmVycmlkZSAnICsgJ2Alc2AgZnJvbSB5b3VyIGNsYXNzIHNwZWNpZmljYXRpb24uIEVuc3VyZSB0aGF0IHlvdXIgbWV0aG9kIG5hbWVzICcgKyAnZG8gbm90IG92ZXJsYXAgd2l0aCBSZWFjdCBtZXRob2RzLicsIG5hbWUpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIERpc2FsbG93IGRlZmluaW5nIG1ldGhvZHMgbW9yZSB0aGFuIG9uY2UgdW5sZXNzIGV4cGxpY2l0bHkgYWxsb3dlZC5cbiAgaWYgKHByb3RvLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgIShzcGVjUG9saWN5ID09PSBTcGVjUG9saWN5LkRFRklORV9NQU5ZIHx8IHNwZWNQb2xpY3kgPT09IFNwZWNQb2xpY3kuREVGSU5FX01BTllfTUVSR0VEKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdENsYXNzSW50ZXJmYWNlOiBZb3UgYXJlIGF0dGVtcHRpbmcgdG8gZGVmaW5lICcgKyAnYCVzYCBvbiB5b3VyIGNvbXBvbmVudCBtb3JlIHRoYW4gb25jZS4gVGhpcyBjb25mbGljdCBtYXkgYmUgZHVlICcgKyAndG8gYSBtaXhpbi4nLCBuYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBNaXhpbiBoZWxwZXIgd2hpY2ggaGFuZGxlcyBwb2xpY3kgdmFsaWRhdGlvbiBhbmQgcmVzZXJ2ZWRcbiAqIHNwZWNpZmljYXRpb24ga2V5cyB3aGVuIGJ1aWxkaW5nIFJlYWN0IGNsYXNzc2VzLlxuICovXG5mdW5jdGlvbiBtaXhTcGVjSW50b0NvbXBvbmVudChDb25zdHJ1Y3Rvciwgc3BlYykge1xuICBpZiAoIXNwZWMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAhKHR5cGVvZiBzcGVjICE9PSAnZnVuY3Rpb24nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdENsYXNzOiBZb3VcXCdyZSBhdHRlbXB0aW5nIHRvICcgKyAndXNlIGEgY29tcG9uZW50IGNsYXNzIGFzIGEgbWl4aW4uIEluc3RlYWQsIGp1c3QgdXNlIGEgcmVndWxhciBvYmplY3QuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAhIVJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChzcGVjKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdENsYXNzOiBZb3VcXCdyZSBhdHRlbXB0aW5nIHRvICcgKyAndXNlIGEgY29tcG9uZW50IGFzIGEgbWl4aW4uIEluc3RlYWQsIGp1c3QgdXNlIGEgcmVndWxhciBvYmplY3QuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gIHZhciBwcm90byA9IENvbnN0cnVjdG9yLnByb3RvdHlwZTtcblxuICAvLyBCeSBoYW5kbGluZyBtaXhpbnMgYmVmb3JlIGFueSBvdGhlciBwcm9wZXJ0aWVzLCB3ZSBlbnN1cmUgdGhlIHNhbWVcbiAgLy8gY2hhaW5pbmcgb3JkZXIgaXMgYXBwbGllZCB0byBtZXRob2RzIHdpdGggREVGSU5FX01BTlkgcG9saWN5LCB3aGV0aGVyXG4gIC8vIG1peGlucyBhcmUgbGlzdGVkIGJlZm9yZSBvciBhZnRlciB0aGVzZSBtZXRob2RzIGluIHRoZSBzcGVjLlxuICBpZiAoc3BlYy5oYXNPd25Qcm9wZXJ0eShNSVhJTlNfS0VZKSkge1xuICAgIFJFU0VSVkVEX1NQRUNfS0VZUy5taXhpbnMoQ29uc3RydWN0b3IsIHNwZWMubWl4aW5zKTtcbiAgfVxuXG4gIGZvciAodmFyIG5hbWUgaW4gc3BlYykge1xuICAgIGlmICghc3BlYy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgPT09IE1JWElOU19LRVkpIHtcbiAgICAgIC8vIFdlIGhhdmUgYWxyZWFkeSBoYW5kbGVkIG1peGlucyBpbiBhIHNwZWNpYWwgY2FzZSBhYm92ZS5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBwcm9wZXJ0eSA9IHNwZWNbbmFtZV07XG4gICAgdmFsaWRhdGVNZXRob2RPdmVycmlkZShwcm90bywgbmFtZSk7XG5cbiAgICBpZiAoUkVTRVJWRURfU1BFQ19LRVlTLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICBSRVNFUlZFRF9TUEVDX0tFWVNbbmFtZV0oQ29uc3RydWN0b3IsIHByb3BlcnR5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2V0dXAgbWV0aG9kcyBvbiBwcm90b3R5cGU6XG4gICAgICAvLyBUaGUgZm9sbG93aW5nIG1lbWJlciBtZXRob2RzIHNob3VsZCBub3QgYmUgYXV0b21hdGljYWxseSBib3VuZDpcbiAgICAgIC8vIDEuIEV4cGVjdGVkIFJlYWN0Q2xhc3MgbWV0aG9kcyAoaW4gdGhlIFwiaW50ZXJmYWNlXCIpLlxuICAgICAgLy8gMi4gT3ZlcnJpZGRlbiBtZXRob2RzICh0aGF0IHdlcmUgbWl4ZWQgaW4pLlxuICAgICAgdmFyIGlzUmVhY3RDbGFzc01ldGhvZCA9IFJlYWN0Q2xhc3NJbnRlcmZhY2UuaGFzT3duUHJvcGVydHkobmFtZSk7XG4gICAgICB2YXIgaXNBbHJlYWR5RGVmaW5lZCA9IHByb3RvLmhhc093blByb3BlcnR5KG5hbWUpO1xuICAgICAgdmFyIGlzRnVuY3Rpb24gPSB0eXBlb2YgcHJvcGVydHkgPT09ICdmdW5jdGlvbic7XG4gICAgICB2YXIgc2hvdWxkQXV0b0JpbmQgPSBpc0Z1bmN0aW9uICYmICFpc1JlYWN0Q2xhc3NNZXRob2QgJiYgIWlzQWxyZWFkeURlZmluZWQgJiYgc3BlYy5hdXRvYmluZCAhPT0gZmFsc2U7XG5cbiAgICAgIGlmIChzaG91bGRBdXRvQmluZCkge1xuICAgICAgICBpZiAoIXByb3RvLl9fcmVhY3RBdXRvQmluZE1hcCkge1xuICAgICAgICAgIHByb3RvLl9fcmVhY3RBdXRvQmluZE1hcCA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHByb3RvLl9fcmVhY3RBdXRvQmluZE1hcFtuYW1lXSA9IHByb3BlcnR5O1xuICAgICAgICBwcm90b1tuYW1lXSA9IHByb3BlcnR5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzQWxyZWFkeURlZmluZWQpIHtcbiAgICAgICAgICB2YXIgc3BlY1BvbGljeSA9IFJlYWN0Q2xhc3NJbnRlcmZhY2VbbmFtZV07XG5cbiAgICAgICAgICAvLyBUaGVzZSBjYXNlcyBzaG91bGQgYWxyZWFkeSBiZSBjYXVnaHQgYnkgdmFsaWRhdGVNZXRob2RPdmVycmlkZS5cbiAgICAgICAgICAhKGlzUmVhY3RDbGFzc01ldGhvZCAmJiAoc3BlY1BvbGljeSA9PT0gU3BlY1BvbGljeS5ERUZJTkVfTUFOWV9NRVJHRUQgfHwgc3BlY1BvbGljeSA9PT0gU3BlY1BvbGljeS5ERUZJTkVfTUFOWSkpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0Q2xhc3M6IFVuZXhwZWN0ZWQgc3BlYyBwb2xpY3kgJXMgZm9yIGtleSAlcyAnICsgJ3doZW4gbWl4aW5nIGluIGNvbXBvbmVudCBzcGVjcy4nLCBzcGVjUG9saWN5LCBuYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAvLyBGb3IgbWV0aG9kcyB3aGljaCBhcmUgZGVmaW5lZCBtb3JlIHRoYW4gb25jZSwgY2FsbCB0aGUgZXhpc3RpbmdcbiAgICAgICAgICAvLyBtZXRob2RzIGJlZm9yZSBjYWxsaW5nIHRoZSBuZXcgcHJvcGVydHksIG1lcmdpbmcgaWYgYXBwcm9wcmlhdGUuXG4gICAgICAgICAgaWYgKHNwZWNQb2xpY3kgPT09IFNwZWNQb2xpY3kuREVGSU5FX01BTllfTUVSR0VEKSB7XG4gICAgICAgICAgICBwcm90b1tuYW1lXSA9IGNyZWF0ZU1lcmdlZFJlc3VsdEZ1bmN0aW9uKHByb3RvW25hbWVdLCBwcm9wZXJ0eSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzcGVjUG9saWN5ID09PSBTcGVjUG9saWN5LkRFRklORV9NQU5ZKSB7XG4gICAgICAgICAgICBwcm90b1tuYW1lXSA9IGNyZWF0ZUNoYWluZWRGdW5jdGlvbihwcm90b1tuYW1lXSwgcHJvcGVydHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm90b1tuYW1lXSA9IHByb3BlcnR5O1xuICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBBZGQgdmVyYm9zZSBkaXNwbGF5TmFtZSB0byB0aGUgZnVuY3Rpb24sIHdoaWNoIGhlbHBzIHdoZW4gbG9va2luZ1xuICAgICAgICAgICAgLy8gYXQgcHJvZmlsaW5nIHRvb2xzLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ2Z1bmN0aW9uJyAmJiBzcGVjLmRpc3BsYXlOYW1lKSB7XG4gICAgICAgICAgICAgIHByb3RvW25hbWVdLmRpc3BsYXlOYW1lID0gc3BlYy5kaXNwbGF5TmFtZSArICdfJyArIG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1peFN0YXRpY1NwZWNJbnRvQ29tcG9uZW50KENvbnN0cnVjdG9yLCBzdGF0aWNzKSB7XG4gIGlmICghc3RhdGljcykge1xuICAgIHJldHVybjtcbiAgfVxuICBmb3IgKHZhciBuYW1lIGluIHN0YXRpY3MpIHtcbiAgICB2YXIgcHJvcGVydHkgPSBzdGF0aWNzW25hbWVdO1xuICAgIGlmICghc3RhdGljcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGlzUmVzZXJ2ZWQgPSAobmFtZSBpbiBSRVNFUlZFRF9TUEVDX0tFWVMpO1xuICAgICEhaXNSZXNlcnZlZCA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdENsYXNzOiBZb3UgYXJlIGF0dGVtcHRpbmcgdG8gZGVmaW5lIGEgcmVzZXJ2ZWQgJyArICdwcm9wZXJ0eSwgYCVzYCwgdGhhdCBzaG91bGRuXFwndCBiZSBvbiB0aGUgXCJzdGF0aWNzXCIga2V5LiBEZWZpbmUgaXQgJyArICdhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBpbnN0ZWFkOyBpdCB3aWxsIHN0aWxsIGJlIGFjY2Vzc2libGUgb24gdGhlICcgKyAnY29uc3RydWN0b3IuJywgbmFtZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgdmFyIGlzSW5oZXJpdGVkID0gKG5hbWUgaW4gQ29uc3RydWN0b3IpO1xuICAgICEhaXNJbmhlcml0ZWQgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnUmVhY3RDbGFzczogWW91IGFyZSBhdHRlbXB0aW5nIHRvIGRlZmluZSAnICsgJ2Alc2Agb24geW91ciBjb21wb25lbnQgbW9yZSB0aGFuIG9uY2UuIFRoaXMgY29uZmxpY3QgbWF5IGJlICcgKyAnZHVlIHRvIGEgbWl4aW4uJywgbmFtZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIENvbnN0cnVjdG9yW25hbWVdID0gcHJvcGVydHk7XG4gIH1cbn1cblxuLyoqXG4gKiBNZXJnZSB0d28gb2JqZWN0cywgYnV0IHRocm93IGlmIGJvdGggY29udGFpbiB0aGUgc2FtZSBrZXkuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9uZSBUaGUgZmlyc3Qgb2JqZWN0LCB3aGljaCBpcyBtdXRhdGVkLlxuICogQHBhcmFtIHtvYmplY3R9IHR3byBUaGUgc2Vjb25kIG9iamVjdFxuICogQHJldHVybiB7b2JqZWN0fSBvbmUgYWZ0ZXIgaXQgaGFzIGJlZW4gbXV0YXRlZCB0byBjb250YWluIGV2ZXJ5dGhpbmcgaW4gdHdvLlxuICovXG5mdW5jdGlvbiBtZXJnZUludG9XaXRoTm9EdXBsaWNhdGVLZXlzKG9uZSwgdHdvKSB7XG4gICEob25lICYmIHR3byAmJiB0eXBlb2Ygb25lID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdHdvID09PSAnb2JqZWN0JykgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnbWVyZ2VJbnRvV2l0aE5vRHVwbGljYXRlS2V5cygpOiBDYW5ub3QgbWVyZ2Ugbm9uLW9iamVjdHMuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gIGZvciAodmFyIGtleSBpbiB0d28pIHtcbiAgICBpZiAodHdvLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICEob25lW2tleV0gPT09IHVuZGVmaW5lZCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnbWVyZ2VJbnRvV2l0aE5vRHVwbGljYXRlS2V5cygpOiAnICsgJ1RyaWVkIHRvIG1lcmdlIHR3byBvYmplY3RzIHdpdGggdGhlIHNhbWUga2V5OiBgJXNgLiBUaGlzIGNvbmZsaWN0ICcgKyAnbWF5IGJlIGR1ZSB0byBhIG1peGluOyBpbiBwYXJ0aWN1bGFyLCB0aGlzIG1heSBiZSBjYXVzZWQgYnkgdHdvICcgKyAnZ2V0SW5pdGlhbFN0YXRlKCkgb3IgZ2V0RGVmYXVsdFByb3BzKCkgbWV0aG9kcyByZXR1cm5pbmcgb2JqZWN0cyAnICsgJ3dpdGggY2xhc2hpbmcga2V5cy4nLCBrZXkpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgIG9uZVtrZXldID0gdHdvW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvbmU7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyB0d28gZnVuY3Rpb25zIGFuZCBtZXJnZXMgdGhlaXIgcmV0dXJuIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBvbmUgRnVuY3Rpb24gdG8gaW52b2tlIGZpcnN0LlxuICogQHBhcmFtIHtmdW5jdGlvbn0gdHdvIEZ1bmN0aW9uIHRvIGludm9rZSBzZWNvbmQuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbn0gRnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSB0d28gYXJndW1lbnQgZnVuY3Rpb25zLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlTWVyZ2VkUmVzdWx0RnVuY3Rpb24ob25lLCB0d28pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG1lcmdlZFJlc3VsdCgpIHtcbiAgICB2YXIgYSA9IG9uZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHZhciBiID0gdHdvLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKGEgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGI7XG4gICAgfSBlbHNlIGlmIChiID09IG51bGwpIHtcbiAgICAgIHJldHVybiBhO1xuICAgIH1cbiAgICB2YXIgYyA9IHt9O1xuICAgIG1lcmdlSW50b1dpdGhOb0R1cGxpY2F0ZUtleXMoYywgYSk7XG4gICAgbWVyZ2VJbnRvV2l0aE5vRHVwbGljYXRlS2V5cyhjLCBiKTtcbiAgICByZXR1cm4gYztcbiAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHR3byBmdW5jdGlvbnMgYW5kIGlnbm9yZXMgdGhlaXIgcmV0dXJuIHZhbGVzLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG9uZSBGdW5jdGlvbiB0byBpbnZva2UgZmlyc3QuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSB0d28gRnVuY3Rpb24gdG8gaW52b2tlIHNlY29uZC5cbiAqIEByZXR1cm4ge2Z1bmN0aW9ufSBGdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIHR3byBhcmd1bWVudCBmdW5jdGlvbnMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjcmVhdGVDaGFpbmVkRnVuY3Rpb24ob25lLCB0d28pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGNoYWluZWRGdW5jdGlvbigpIHtcbiAgICBvbmUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0d28uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBCaW5kcyBhIG1ldGhvZCB0byB0aGUgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb21wb25lbnQgQ29tcG9uZW50IHdob3NlIG1ldGhvZCBpcyBnb2luZyB0byBiZSBib3VuZC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG1ldGhvZCBNZXRob2QgdG8gYmUgYm91bmQuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbn0gVGhlIGJvdW5kIG1ldGhvZC5cbiAqL1xuZnVuY3Rpb24gYmluZEF1dG9CaW5kTWV0aG9kKGNvbXBvbmVudCwgbWV0aG9kKSB7XG4gIHZhciBib3VuZE1ldGhvZCA9IG1ldGhvZC5iaW5kKGNvbXBvbmVudCk7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgYm91bmRNZXRob2QuX19yZWFjdEJvdW5kQ29udGV4dCA9IGNvbXBvbmVudDtcbiAgICBib3VuZE1ldGhvZC5fX3JlYWN0Qm91bmRNZXRob2QgPSBtZXRob2Q7XG4gICAgYm91bmRNZXRob2QuX19yZWFjdEJvdW5kQXJndW1lbnRzID0gbnVsbDtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5kaXNwbGF5TmFtZTtcbiAgICB2YXIgX2JpbmQgPSBib3VuZE1ldGhvZC5iaW5kO1xuICAgIC8qIGVzbGludC1kaXNhYmxlIGJsb2NrLXNjb3BlZC12YXIsIG5vLXVuZGVmICovXG4gICAgYm91bmRNZXRob2QuYmluZCA9IGZ1bmN0aW9uIChuZXdUaGlzKSB7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIC8vIFVzZXIgaXMgdHJ5aW5nIHRvIGJpbmQoKSBhbiBhdXRvYm91bmQgbWV0aG9kOyB3ZSBlZmZlY3RpdmVseSB3aWxsXG4gICAgICAvLyBpZ25vcmUgdGhlIHZhbHVlIG9mIFwidGhpc1wiIHRoYXQgdGhlIHVzZXIgaXMgdHJ5aW5nIHRvIHVzZSwgc29cbiAgICAgIC8vIGxldCdzIHdhcm4uXG4gICAgICBpZiAobmV3VGhpcyAhPT0gY29tcG9uZW50ICYmIG5ld1RoaXMgIT09IG51bGwpIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdiaW5kKCk6IFJlYWN0IGNvbXBvbmVudCBtZXRob2RzIG1heSBvbmx5IGJlIGJvdW5kIHRvIHRoZSAnICsgJ2NvbXBvbmVudCBpbnN0YW5jZS4gU2VlICVzJywgY29tcG9uZW50TmFtZSkgOiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2UgaWYgKCFhcmdzLmxlbmd0aCkge1xuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ2JpbmQoKTogWW91IGFyZSBiaW5kaW5nIGEgY29tcG9uZW50IG1ldGhvZCB0byB0aGUgY29tcG9uZW50LiAnICsgJ1JlYWN0IGRvZXMgdGhpcyBmb3IgeW91IGF1dG9tYXRpY2FsbHkgaW4gYSBoaWdoLXBlcmZvcm1hbmNlICcgKyAnd2F5LCBzbyB5b3UgY2FuIHNhZmVseSByZW1vdmUgdGhpcyBjYWxsLiBTZWUgJXMnLCBjb21wb25lbnROYW1lKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIGJvdW5kTWV0aG9kO1xuICAgICAgfVxuICAgICAgdmFyIHJlYm91bmRNZXRob2QgPSBfYmluZC5hcHBseShib3VuZE1ldGhvZCwgYXJndW1lbnRzKTtcbiAgICAgIHJlYm91bmRNZXRob2QuX19yZWFjdEJvdW5kQ29udGV4dCA9IGNvbXBvbmVudDtcbiAgICAgIHJlYm91bmRNZXRob2QuX19yZWFjdEJvdW5kTWV0aG9kID0gbWV0aG9kO1xuICAgICAgcmVib3VuZE1ldGhvZC5fX3JlYWN0Qm91bmRBcmd1bWVudHMgPSBhcmdzO1xuICAgICAgcmV0dXJuIHJlYm91bmRNZXRob2Q7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlICovXG4gICAgfTtcbiAgfVxuICByZXR1cm4gYm91bmRNZXRob2Q7XG59XG5cbi8qKlxuICogQmluZHMgYWxsIGF1dG8tYm91bmQgbWV0aG9kcyBpbiBhIGNvbXBvbmVudC5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gY29tcG9uZW50IENvbXBvbmVudCB3aG9zZSBtZXRob2QgaXMgZ29pbmcgdG8gYmUgYm91bmQuXG4gKi9cbmZ1bmN0aW9uIGJpbmRBdXRvQmluZE1ldGhvZHMoY29tcG9uZW50KSB7XG4gIGZvciAodmFyIGF1dG9CaW5kS2V5IGluIGNvbXBvbmVudC5fX3JlYWN0QXV0b0JpbmRNYXApIHtcbiAgICBpZiAoY29tcG9uZW50Ll9fcmVhY3RBdXRvQmluZE1hcC5oYXNPd25Qcm9wZXJ0eShhdXRvQmluZEtleSkpIHtcbiAgICAgIHZhciBtZXRob2QgPSBjb21wb25lbnQuX19yZWFjdEF1dG9CaW5kTWFwW2F1dG9CaW5kS2V5XTtcbiAgICAgIGNvbXBvbmVudFthdXRvQmluZEtleV0gPSBiaW5kQXV0b0JpbmRNZXRob2QoY29tcG9uZW50LCBtZXRob2QpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFkZCBtb3JlIHRvIHRoZSBSZWFjdENsYXNzIGJhc2UgY2xhc3MuIFRoZXNlIGFyZSBhbGwgbGVnYWN5IGZlYXR1cmVzIGFuZFxuICogdGhlcmVmb3JlIG5vdCBhbHJlYWR5IHBhcnQgb2YgdGhlIG1vZGVybiBSZWFjdENvbXBvbmVudC5cbiAqL1xudmFyIFJlYWN0Q2xhc3NNaXhpbiA9IHtcblxuICAvKipcbiAgICogVE9ETzogVGhpcyB3aWxsIGJlIGRlcHJlY2F0ZWQgYmVjYXVzZSBzdGF0ZSBzaG91bGQgYWx3YXlzIGtlZXAgYSBjb25zaXN0ZW50XG4gICAqIHR5cGUgc2lnbmF0dXJlIGFuZCB0aGUgb25seSB1c2UgY2FzZSBmb3IgdGhpcywgaXMgdG8gYXZvaWQgdGhhdC5cbiAgICovXG4gIHJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKG5ld1N0YXRlLCBjYWxsYmFjaykge1xuICAgIHRoaXMudXBkYXRlci5lbnF1ZXVlUmVwbGFjZVN0YXRlKHRoaXMsIG5ld1N0YXRlKTtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIHRoaXMudXBkYXRlci5lbnF1ZXVlQ2FsbGJhY2sodGhpcywgY2FsbGJhY2spO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoaXMgY29tcG9zaXRlIGNvbXBvbmVudCBpcyBtb3VudGVkLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG1vdW50ZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAZmluYWxcbiAgICovXG4gIGlzTW91bnRlZDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZXIuaXNNb3VudGVkKHRoaXMpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBTZXRzIGEgc3Vic2V0IG9mIHRoZSBwcm9wcy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IHBhcnRpYWxQcm9wcyBTdWJzZXQgb2YgdGhlIG5leHQgcHJvcHMuXG4gICAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgYWZ0ZXIgcHJvcHMgYXJlIHVwZGF0ZWQuXG4gICAqIEBmaW5hbFxuICAgKiBAcHVibGljXG4gICAqIEBkZXByZWNhdGVkXG4gICAqL1xuICBzZXRQcm9wczogZnVuY3Rpb24gKHBhcnRpYWxQcm9wcywgY2FsbGJhY2spIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgd2FyblNldFByb3BzKCk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlci5lbnF1ZXVlU2V0UHJvcHModGhpcywgcGFydGlhbFByb3BzKTtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIHRoaXMudXBkYXRlci5lbnF1ZXVlQ2FsbGJhY2sodGhpcywgY2FsbGJhY2spO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmVwbGFjZSBhbGwgdGhlIHByb3BzLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmV3UHJvcHMgU3Vic2V0IG9mIHRoZSBuZXh0IHByb3BzLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHByb3BzIGFyZSB1cGRhdGVkLlxuICAgKiBAZmluYWxcbiAgICogQHB1YmxpY1xuICAgKiBAZGVwcmVjYXRlZFxuICAgKi9cbiAgcmVwbGFjZVByb3BzOiBmdW5jdGlvbiAobmV3UHJvcHMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHdhcm5TZXRQcm9wcygpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZVJlcGxhY2VQcm9wcyh0aGlzLCBuZXdQcm9wcyk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUNhbGxiYWNrKHRoaXMsIGNhbGxiYWNrKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBSZWFjdENsYXNzQ29tcG9uZW50ID0gZnVuY3Rpb24gKCkge307XG5hc3NpZ24oUmVhY3RDbGFzc0NvbXBvbmVudC5wcm90b3R5cGUsIFJlYWN0Q29tcG9uZW50LnByb3RvdHlwZSwgUmVhY3RDbGFzc01peGluKTtcblxuLyoqXG4gKiBNb2R1bGUgZm9yIGNyZWF0aW5nIGNvbXBvc2l0ZSBjb21wb25lbnRzLlxuICpcbiAqIEBjbGFzcyBSZWFjdENsYXNzXG4gKi9cbnZhciBSZWFjdENsYXNzID0ge1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgY29tcG9zaXRlIGNvbXBvbmVudCBjbGFzcyBnaXZlbiBhIGNsYXNzIHNwZWNpZmljYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBzcGVjIENsYXNzIHNwZWNpZmljYXRpb24gKHdoaWNoIG11c3QgZGVmaW5lIGByZW5kZXJgKS5cbiAgICogQHJldHVybiB7ZnVuY3Rpb259IENvbXBvbmVudCBjb25zdHJ1Y3RvciBmdW5jdGlvbi5cbiAgICogQHB1YmxpY1xuICAgKi9cbiAgY3JlYXRlQ2xhc3M6IGZ1bmN0aW9uIChzcGVjKSB7XG4gICAgdmFyIENvbnN0cnVjdG9yID0gZnVuY3Rpb24gKHByb3BzLCBjb250ZXh0LCB1cGRhdGVyKSB7XG4gICAgICAvLyBUaGlzIGNvbnN0cnVjdG9yIGlzIG92ZXJyaWRkZW4gYnkgbW9ja3MuIFRoZSBhcmd1bWVudCBpcyB1c2VkXG4gICAgICAvLyBieSBtb2NrcyB0byBhc3NlcnQgb24gd2hhdCBnZXRzIG1vdW50ZWQuXG5cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHRoaXMgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvciwgJ1NvbWV0aGluZyBpcyBjYWxsaW5nIGEgUmVhY3QgY29tcG9uZW50IGRpcmVjdGx5LiBVc2UgYSBmYWN0b3J5IG9yICcgKyAnSlNYIGluc3RlYWQuIFNlZTogaHR0cHM6Ly9mYi5tZS9yZWFjdC1sZWdhY3lmYWN0b3J5JykgOiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFdpcmUgdXAgYXV0by1iaW5kaW5nXG4gICAgICBpZiAodGhpcy5fX3JlYWN0QXV0b0JpbmRNYXApIHtcbiAgICAgICAgYmluZEF1dG9CaW5kTWV0aG9kcyh0aGlzKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgIHRoaXMucmVmcyA9IGVtcHR5T2JqZWN0O1xuICAgICAgdGhpcy51cGRhdGVyID0gdXBkYXRlciB8fCBSZWFjdE5vb3BVcGRhdGVRdWV1ZTtcblxuICAgICAgdGhpcy5zdGF0ZSA9IG51bGw7XG5cbiAgICAgIC8vIFJlYWN0Q2xhc3NlcyBkb2Vzbid0IGhhdmUgY29uc3RydWN0b3JzLiBJbnN0ZWFkLCB0aGV5IHVzZSB0aGVcbiAgICAgIC8vIGdldEluaXRpYWxTdGF0ZSBhbmQgY29tcG9uZW50V2lsbE1vdW50IG1ldGhvZHMgZm9yIGluaXRpYWxpemF0aW9uLlxuXG4gICAgICB2YXIgaW5pdGlhbFN0YXRlID0gdGhpcy5nZXRJbml0aWFsU3RhdGUgPyB0aGlzLmdldEluaXRpYWxTdGF0ZSgpIDogbnVsbDtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIC8vIFdlIGFsbG93IGF1dG8tbW9ja3MgdG8gcHJvY2VlZCBhcyBpZiB0aGV5J3JlIHJldHVybmluZyBudWxsLlxuICAgICAgICBpZiAodHlwZW9mIGluaXRpYWxTdGF0ZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5nZXRJbml0aWFsU3RhdGUuX2lzTW9ja0Z1bmN0aW9uKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBwcm9iYWJseSBiYWQgcHJhY3RpY2UuIENvbnNpZGVyIHdhcm5pbmcgaGVyZSBhbmRcbiAgICAgICAgICAvLyBkZXByZWNhdGluZyB0aGlzIGNvbnZlbmllbmNlLlxuICAgICAgICAgIGluaXRpYWxTdGF0ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgICEodHlwZW9mIGluaXRpYWxTdGF0ZSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkoaW5pdGlhbFN0YXRlKSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnJXMuZ2V0SW5pdGlhbFN0YXRlKCk6IG11c3QgcmV0dXJuIGFuIG9iamVjdCBvciBudWxsJywgQ29uc3RydWN0b3IuZGlzcGxheU5hbWUgfHwgJ1JlYWN0Q29tcG9zaXRlQ29tcG9uZW50JykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgICB0aGlzLnN0YXRlID0gaW5pdGlhbFN0YXRlO1xuICAgIH07XG4gICAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gbmV3IFJlYWN0Q2xhc3NDb21wb25lbnQoKTtcbiAgICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb25zdHJ1Y3RvcjtcblxuICAgIGluamVjdGVkTWl4aW5zLmZvckVhY2gobWl4U3BlY0ludG9Db21wb25lbnQuYmluZChudWxsLCBDb25zdHJ1Y3RvcikpO1xuXG4gICAgbWl4U3BlY0ludG9Db21wb25lbnQoQ29uc3RydWN0b3IsIHNwZWMpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgZGVmYXVsdFByb3BzIHByb3BlcnR5IGFmdGVyIGFsbCBtaXhpbnMgaGF2ZSBiZWVuIG1lcmdlZC5cbiAgICBpZiAoQ29uc3RydWN0b3IuZ2V0RGVmYXVsdFByb3BzKSB7XG4gICAgICBDb25zdHJ1Y3Rvci5kZWZhdWx0UHJvcHMgPSBDb25zdHJ1Y3Rvci5nZXREZWZhdWx0UHJvcHMoKTtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgLy8gVGhpcyBpcyBhIHRhZyB0byBpbmRpY2F0ZSB0aGF0IHRoZSB1c2Ugb2YgdGhlc2UgbWV0aG9kIG5hbWVzIGlzIG9rLFxuICAgICAgLy8gc2luY2UgaXQncyB1c2VkIHdpdGggY3JlYXRlQ2xhc3MuIElmIGl0J3Mgbm90LCB0aGVuIGl0J3MgbGlrZWx5IGFcbiAgICAgIC8vIG1pc3Rha2Ugc28gd2UnbGwgd2FybiB5b3UgdG8gdXNlIHRoZSBzdGF0aWMgcHJvcGVydHksIHByb3BlcnR5XG4gICAgICAvLyBpbml0aWFsaXplciBvciBjb25zdHJ1Y3RvciByZXNwZWN0aXZlbHkuXG4gICAgICBpZiAoQ29uc3RydWN0b3IuZ2V0RGVmYXVsdFByb3BzKSB7XG4gICAgICAgIENvbnN0cnVjdG9yLmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCA9IHt9O1xuICAgICAgfVxuICAgICAgaWYgKENvbnN0cnVjdG9yLnByb3RvdHlwZS5nZXRJbml0aWFsU3RhdGUpIHtcbiAgICAgICAgQ29uc3RydWN0b3IucHJvdG90eXBlLmdldEluaXRpYWxTdGF0ZS5pc1JlYWN0Q2xhc3NBcHByb3ZlZCA9IHt9O1xuICAgICAgfVxuICAgIH1cblxuICAgICFDb25zdHJ1Y3Rvci5wcm90b3R5cGUucmVuZGVyID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2NyZWF0ZUNsYXNzKC4uLik6IENsYXNzIHNwZWNpZmljYXRpb24gbXVzdCBpbXBsZW1lbnQgYSBgcmVuZGVyYCBtZXRob2QuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFDb25zdHJ1Y3Rvci5wcm90b3R5cGUuY29tcG9uZW50U2hvdWxkVXBkYXRlLCAnJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudFNob3VsZFVwZGF0ZSgpLiBEaWQgeW91IG1lYW4gc2hvdWxkQ29tcG9uZW50VXBkYXRlKCk/ICcgKyAnVGhlIG5hbWUgaXMgcGhyYXNlZCBhcyBhIHF1ZXN0aW9uIGJlY2F1c2UgdGhlIGZ1bmN0aW9uIGlzICcgKyAnZXhwZWN0ZWQgdG8gcmV0dXJuIGEgdmFsdWUuJywgc3BlYy5kaXNwbGF5TmFtZSB8fCAnQSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFDb25zdHJ1Y3Rvci5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcywgJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzKCkuIERpZCB5b3UgbWVhbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCk/Jywgc3BlYy5kaXNwbGF5TmFtZSB8fCAnQSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBSZWR1Y2UgdGltZSBzcGVudCBkb2luZyBsb29rdXBzIGJ5IHNldHRpbmcgdGhlc2Ugb24gdGhlIHByb3RvdHlwZS5cbiAgICBmb3IgKHZhciBtZXRob2ROYW1lIGluIFJlYWN0Q2xhc3NJbnRlcmZhY2UpIHtcbiAgICAgIGlmICghQ29uc3RydWN0b3IucHJvdG90eXBlW21ldGhvZE5hbWVdKSB7XG4gICAgICAgIENvbnN0cnVjdG9yLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIENvbnN0cnVjdG9yO1xuICB9LFxuXG4gIGluamVjdGlvbjoge1xuICAgIGluamVjdE1peGluOiBmdW5jdGlvbiAobWl4aW4pIHtcbiAgICAgIGluamVjdGVkTWl4aW5zLnB1c2gobWl4aW4pO1xuICAgIH1cbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0Q2xhc3M7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0Q29tcG9uZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3ROb29wVXBkYXRlUXVldWUgPSByZXF1aXJlKCcuL1JlYWN0Tm9vcFVwZGF0ZVF1ZXVlJyk7XG5cbnZhciBjYW5EZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vY2FuRGVmaW5lUHJvcGVydHknKTtcbnZhciBlbXB0eU9iamVjdCA9IHJlcXVpcmUoJ2ZianMvbGliL2VtcHR5T2JqZWN0Jyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxuLyoqXG4gKiBCYXNlIGNsYXNzIGhlbHBlcnMgZm9yIHRoZSB1cGRhdGluZyBzdGF0ZSBvZiBhIGNvbXBvbmVudC5cbiAqL1xuZnVuY3Rpb24gUmVhY3RDb21wb25lbnQocHJvcHMsIGNvbnRleHQsIHVwZGF0ZXIpIHtcbiAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLnJlZnMgPSBlbXB0eU9iamVjdDtcbiAgLy8gV2UgaW5pdGlhbGl6ZSB0aGUgZGVmYXVsdCB1cGRhdGVyIGJ1dCB0aGUgcmVhbCBvbmUgZ2V0cyBpbmplY3RlZCBieSB0aGVcbiAgLy8gcmVuZGVyZXIuXG4gIHRoaXMudXBkYXRlciA9IHVwZGF0ZXIgfHwgUmVhY3ROb29wVXBkYXRlUXVldWU7XG59XG5cblJlYWN0Q29tcG9uZW50LnByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50ID0ge307XG5cbi8qKlxuICogU2V0cyBhIHN1YnNldCBvZiB0aGUgc3RhdGUuIEFsd2F5cyB1c2UgdGhpcyB0byBtdXRhdGVcbiAqIHN0YXRlLiBZb3Ugc2hvdWxkIHRyZWF0IGB0aGlzLnN0YXRlYCBhcyBpbW11dGFibGUuXG4gKlxuICogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgYHRoaXMuc3RhdGVgIHdpbGwgYmUgaW1tZWRpYXRlbHkgdXBkYXRlZCwgc29cbiAqIGFjY2Vzc2luZyBgdGhpcy5zdGF0ZWAgYWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCBtYXkgcmV0dXJuIHRoZSBvbGQgdmFsdWUuXG4gKlxuICogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgY2FsbHMgdG8gYHNldFN0YXRlYCB3aWxsIHJ1biBzeW5jaHJvbm91c2x5LFxuICogYXMgdGhleSBtYXkgZXZlbnR1YWxseSBiZSBiYXRjaGVkIHRvZ2V0aGVyLiAgWW91IGNhbiBwcm92aWRlIGFuIG9wdGlvbmFsXG4gKiBjYWxsYmFjayB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgd2hlbiB0aGUgY2FsbCB0byBzZXRTdGF0ZSBpcyBhY3R1YWxseVxuICogY29tcGxldGVkLlxuICpcbiAqIFdoZW4gYSBmdW5jdGlvbiBpcyBwcm92aWRlZCB0byBzZXRTdGF0ZSwgaXQgd2lsbCBiZSBjYWxsZWQgYXQgc29tZSBwb2ludCBpblxuICogdGhlIGZ1dHVyZSAobm90IHN5bmNocm9ub3VzbHkpLiBJdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSB1cCB0byBkYXRlXG4gKiBjb21wb25lbnQgYXJndW1lbnRzIChzdGF0ZSwgcHJvcHMsIGNvbnRleHQpLiBUaGVzZSB2YWx1ZXMgY2FuIGJlIGRpZmZlcmVudFxuICogZnJvbSB0aGlzLiogYmVjYXVzZSB5b3VyIGZ1bmN0aW9uIG1heSBiZSBjYWxsZWQgYWZ0ZXIgcmVjZWl2ZVByb3BzIGJ1dCBiZWZvcmVcbiAqIHNob3VsZENvbXBvbmVudFVwZGF0ZSwgYW5kIHRoaXMgbmV3IHN0YXRlLCBwcm9wcywgYW5kIGNvbnRleHQgd2lsbCBub3QgeWV0IGJlXG4gKiBhc3NpZ25lZCB0byB0aGlzLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fGZ1bmN0aW9ufSBwYXJ0aWFsU3RhdGUgTmV4dCBwYXJ0aWFsIHN0YXRlIG9yIGZ1bmN0aW9uIHRvXG4gKiAgICAgICAgcHJvZHVjZSBuZXh0IHBhcnRpYWwgc3RhdGUgdG8gYmUgbWVyZ2VkIHdpdGggY3VycmVudCBzdGF0ZS5cbiAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgYWZ0ZXIgc3RhdGUgaXMgdXBkYXRlZC5cbiAqIEBmaW5hbFxuICogQHByb3RlY3RlZFxuICovXG5SZWFjdENvbXBvbmVudC5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAocGFydGlhbFN0YXRlLCBjYWxsYmFjaykge1xuICAhKHR5cGVvZiBwYXJ0aWFsU3RhdGUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBwYXJ0aWFsU3RhdGUgPT09ICdmdW5jdGlvbicgfHwgcGFydGlhbFN0YXRlID09IG51bGwpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ3NldFN0YXRlKC4uLik6IHRha2VzIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMgdG8gdXBkYXRlIG9yIGEgJyArICdmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHBhcnRpYWxTdGF0ZSAhPSBudWxsLCAnc2V0U3RhdGUoLi4uKTogWW91IHBhc3NlZCBhbiB1bmRlZmluZWQgb3IgbnVsbCBzdGF0ZSBvYmplY3Q7ICcgKyAnaW5zdGVhZCwgdXNlIGZvcmNlVXBkYXRlKCkuJykgOiB1bmRlZmluZWQ7XG4gIH1cbiAgdGhpcy51cGRhdGVyLmVucXVldWVTZXRTdGF0ZSh0aGlzLCBwYXJ0aWFsU3RhdGUpO1xuICBpZiAoY2FsbGJhY2spIHtcbiAgICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUNhbGxiYWNrKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGb3JjZXMgYW4gdXBkYXRlLiBUaGlzIHNob3VsZCBvbmx5IGJlIGludm9rZWQgd2hlbiBpdCBpcyBrbm93biB3aXRoXG4gKiBjZXJ0YWludHkgdGhhdCB3ZSBhcmUgKipub3QqKiBpbiBhIERPTSB0cmFuc2FjdGlvbi5cbiAqXG4gKiBZb3UgbWF5IHdhbnQgdG8gY2FsbCB0aGlzIHdoZW4geW91IGtub3cgdGhhdCBzb21lIGRlZXBlciBhc3BlY3Qgb2YgdGhlXG4gKiBjb21wb25lbnQncyBzdGF0ZSBoYXMgY2hhbmdlZCBidXQgYHNldFN0YXRlYCB3YXMgbm90IGNhbGxlZC5cbiAqXG4gKiBUaGlzIHdpbGwgbm90IGludm9rZSBgc2hvdWxkQ29tcG9uZW50VXBkYXRlYCwgYnV0IGl0IHdpbGwgaW52b2tlXG4gKiBgY29tcG9uZW50V2lsbFVwZGF0ZWAgYW5kIGBjb21wb25lbnREaWRVcGRhdGVgLlxuICpcbiAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgYWZ0ZXIgdXBkYXRlIGlzIGNvbXBsZXRlLlxuICogQGZpbmFsXG4gKiBAcHJvdGVjdGVkXG4gKi9cblJlYWN0Q29tcG9uZW50LnByb3RvdHlwZS5mb3JjZVVwZGF0ZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUZvcmNlVXBkYXRlKHRoaXMpO1xuICBpZiAoY2FsbGJhY2spIHtcbiAgICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUNhbGxiYWNrKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBEZXByZWNhdGVkIEFQSXMuIFRoZXNlIEFQSXMgdXNlZCB0byBleGlzdCBvbiBjbGFzc2ljIFJlYWN0IGNsYXNzZXMgYnV0IHNpbmNlXG4gKiB3ZSB3b3VsZCBsaWtlIHRvIGRlcHJlY2F0ZSB0aGVtLCB3ZSdyZSBub3QgZ29pbmcgdG8gbW92ZSB0aGVtIG92ZXIgdG8gdGhpc1xuICogbW9kZXJuIGJhc2UgY2xhc3MuIEluc3RlYWQsIHdlIGRlZmluZSBhIGdldHRlciB0aGF0IHdhcm5zIGlmIGl0J3MgYWNjZXNzZWQuXG4gKi9cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhciBkZXByZWNhdGVkQVBJcyA9IHtcbiAgICBnZXRET01Ob2RlOiBbJ2dldERPTU5vZGUnLCAnVXNlIFJlYWN0RE9NLmZpbmRET01Ob2RlKGNvbXBvbmVudCkgaW5zdGVhZC4nXSxcbiAgICBpc01vdW50ZWQ6IFsnaXNNb3VudGVkJywgJ0luc3RlYWQsIG1ha2Ugc3VyZSB0byBjbGVhbiB1cCBzdWJzY3JpcHRpb25zIGFuZCBwZW5kaW5nIHJlcXVlc3RzIGluICcgKyAnY29tcG9uZW50V2lsbFVubW91bnQgdG8gcHJldmVudCBtZW1vcnkgbGVha3MuJ10sXG4gICAgcmVwbGFjZVByb3BzOiBbJ3JlcGxhY2VQcm9wcycsICdJbnN0ZWFkLCBjYWxsIHJlbmRlciBhZ2FpbiBhdCB0aGUgdG9wIGxldmVsLiddLFxuICAgIHJlcGxhY2VTdGF0ZTogWydyZXBsYWNlU3RhdGUnLCAnUmVmYWN0b3IgeW91ciBjb2RlIHRvIHVzZSBzZXRTdGF0ZSBpbnN0ZWFkIChzZWUgJyArICdodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzMyMzYpLiddLFxuICAgIHNldFByb3BzOiBbJ3NldFByb3BzJywgJ0luc3RlYWQsIGNhbGwgcmVuZGVyIGFnYWluIGF0IHRoZSB0b3AgbGV2ZWwuJ11cbiAgfTtcbiAgdmFyIGRlZmluZURlcHJlY2F0aW9uV2FybmluZyA9IGZ1bmN0aW9uIChtZXRob2ROYW1lLCBpbmZvKSB7XG4gICAgaWYgKGNhbkRlZmluZVByb3BlcnR5KSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhY3RDb21wb25lbnQucHJvdG90eXBlLCBtZXRob2ROYW1lLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnJXMoLi4uKSBpcyBkZXByZWNhdGVkIGluIHBsYWluIEphdmFTY3JpcHQgUmVhY3QgY2xhc3Nlcy4gJXMnLCBpbmZvWzBdLCBpbmZvWzFdKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG4gIGZvciAodmFyIGZuTmFtZSBpbiBkZXByZWNhdGVkQVBJcykge1xuICAgIGlmIChkZXByZWNhdGVkQVBJcy5oYXNPd25Qcm9wZXJ0eShmbk5hbWUpKSB7XG4gICAgICBkZWZpbmVEZXByZWNhdGlvbldhcm5pbmcoZm5OYW1lLCBkZXByZWNhdGVkQVBJc1tmbk5hbWVdKTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdENvbXBvbmVudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RDb21wb25lbnRCcm93c2VyRW52aXJvbm1lbnRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdERPTUlET3BlcmF0aW9ucyA9IHJlcXVpcmUoJy4vUmVhY3RET01JRE9wZXJhdGlvbnMnKTtcbnZhciBSZWFjdE1vdW50ID0gcmVxdWlyZSgnLi9SZWFjdE1vdW50Jyk7XG5cbi8qKlxuICogQWJzdHJhY3RzIGF3YXkgYWxsIGZ1bmN0aW9uYWxpdHkgb2YgdGhlIHJlY29uY2lsZXIgdGhhdCByZXF1aXJlcyBrbm93bGVkZ2Ugb2ZcbiAqIHRoZSBicm93c2VyIGNvbnRleHQuIFRPRE86IFRoZXNlIGNhbGxlcnMgc2hvdWxkIGJlIHJlZmFjdG9yZWQgdG8gYXZvaWQgdGhlXG4gKiBuZWVkIGZvciB0aGlzIGluamVjdGlvbi5cbiAqL1xudmFyIFJlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50ID0ge1xuXG4gIHByb2Nlc3NDaGlsZHJlblVwZGF0ZXM6IFJlYWN0RE9NSURPcGVyYXRpb25zLmRhbmdlcm91c2x5UHJvY2Vzc0NoaWxkcmVuVXBkYXRlcyxcblxuICByZXBsYWNlTm9kZVdpdGhNYXJrdXBCeUlEOiBSZWFjdERPTUlET3BlcmF0aW9ucy5kYW5nZXJvdXNseVJlcGxhY2VOb2RlV2l0aE1hcmt1cEJ5SUQsXG5cbiAgLyoqXG4gICAqIElmIGEgcGFydGljdWxhciBlbnZpcm9ubWVudCByZXF1aXJlcyB0aGF0IHNvbWUgcmVzb3VyY2VzIGJlIGNsZWFuZWQgdXAsXG4gICAqIHNwZWNpZnkgdGhpcyBpbiB0aGUgaW5qZWN0ZWQgTWl4aW4uIEluIHRoZSBET00sIHdlIHdvdWxkIGxpa2VseSB3YW50IHRvXG4gICAqIHB1cmdlIGFueSBjYWNoZWQgbm9kZSBJRCBsb29rdXBzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdW5tb3VudElERnJvbUVudmlyb25tZW50OiBmdW5jdGlvbiAocm9vdE5vZGVJRCkge1xuICAgIFJlYWN0TW91bnQucHVyZ2VJRChyb290Tm9kZUlEKTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdENvbXBvbmVudEVudmlyb25tZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG5cbnZhciBpbmplY3RlZCA9IGZhbHNlO1xuXG52YXIgUmVhY3RDb21wb25lbnRFbnZpcm9ubWVudCA9IHtcblxuICAvKipcbiAgICogT3B0aW9uYWxseSBpbmplY3RhYmxlIGVudmlyb25tZW50IGRlcGVuZGVudCBjbGVhbnVwIGhvb2suIChzZXJ2ZXIgdnMuXG4gICAqIGJyb3dzZXIgZXRjKS4gRXhhbXBsZTogQSBicm93c2VyIHN5c3RlbSBjYWNoZXMgRE9NIG5vZGVzIGJhc2VkIG9uIGNvbXBvbmVudFxuICAgKiBJRCBhbmQgbXVzdCByZW1vdmUgdGhhdCBjYWNoZSBlbnRyeSB3aGVuIHRoaXMgaW5zdGFuY2UgaXMgdW5tb3VudGVkLlxuICAgKi9cbiAgdW5tb3VudElERnJvbUVudmlyb25tZW50OiBudWxsLFxuXG4gIC8qKlxuICAgKiBPcHRpb25hbGx5IGluamVjdGFibGUgaG9vayBmb3Igc3dhcHBpbmcgb3V0IG1vdW50IGltYWdlcyBpbiB0aGUgbWlkZGxlIG9mXG4gICAqIHRoZSB0cmVlLlxuICAgKi9cbiAgcmVwbGFjZU5vZGVXaXRoTWFya3VwQnlJRDogbnVsbCxcblxuICAvKipcbiAgICogT3B0aW9uYWxseSBpbmplY3RhYmxlIGhvb2sgZm9yIHByb2Nlc3NpbmcgYSBxdWV1ZSBvZiBjaGlsZCB1cGRhdGVzLiBXaWxsXG4gICAqIGxhdGVyIG1vdmUgaW50byBNdWx0aUNoaWxkQ29tcG9uZW50cy5cbiAgICovXG4gIHByb2Nlc3NDaGlsZHJlblVwZGF0ZXM6IG51bGwsXG5cbiAgaW5qZWN0aW9uOiB7XG4gICAgaW5qZWN0RW52aXJvbm1lbnQ6IGZ1bmN0aW9uIChlbnZpcm9ubWVudCkge1xuICAgICAgISFpbmplY3RlZCA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdENvbXBvc2l0ZUNvbXBvbmVudDogaW5qZWN0RW52aXJvbm1lbnQoKSBjYW4gb25seSBiZSBjYWxsZWQgb25jZS4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgICBSZWFjdENvbXBvbmVudEVudmlyb25tZW50LnVubW91bnRJREZyb21FbnZpcm9ubWVudCA9IGVudmlyb25tZW50LnVubW91bnRJREZyb21FbnZpcm9ubWVudDtcbiAgICAgIFJlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQucmVwbGFjZU5vZGVXaXRoTWFya3VwQnlJRCA9IGVudmlyb25tZW50LnJlcGxhY2VOb2RlV2l0aE1hcmt1cEJ5SUQ7XG4gICAgICBSZWFjdENvbXBvbmVudEVudmlyb25tZW50LnByb2Nlc3NDaGlsZHJlblVwZGF0ZXMgPSBlbnZpcm9ubWVudC5wcm9jZXNzQ2hpbGRyZW5VcGRhdGVzO1xuICAgICAgaW5qZWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0Q29tcG9zaXRlQ29tcG9uZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RDb21wb25lbnRFbnZpcm9ubWVudCA9IHJlcXVpcmUoJy4vUmVhY3RDb21wb25lbnRFbnZpcm9ubWVudCcpO1xudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG52YXIgUmVhY3RJbnN0YW5jZU1hcCA9IHJlcXVpcmUoJy4vUmVhY3RJbnN0YW5jZU1hcCcpO1xudmFyIFJlYWN0UGVyZiA9IHJlcXVpcmUoJy4vUmVhY3RQZXJmJyk7XG52YXIgUmVhY3RQcm9wVHlwZUxvY2F0aW9ucyA9IHJlcXVpcmUoJy4vUmVhY3RQcm9wVHlwZUxvY2F0aW9ucycpO1xudmFyIFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzID0gcmVxdWlyZSgnLi9SZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcycpO1xudmFyIFJlYWN0UmVjb25jaWxlciA9IHJlcXVpcmUoJy4vUmVhY3RSZWNvbmNpbGVyJyk7XG52YXIgUmVhY3RVcGRhdGVRdWV1ZSA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVRdWV1ZScpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgZW1wdHlPYmplY3QgPSByZXF1aXJlKCdmYmpzL2xpYi9lbXB0eU9iamVjdCcpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50ID0gcmVxdWlyZSgnLi9zaG91bGRVcGRhdGVSZWFjdENvbXBvbmVudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbmZ1bmN0aW9uIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShjb21wb25lbnQpIHtcbiAgdmFyIG93bmVyID0gY29tcG9uZW50Ll9jdXJyZW50RWxlbWVudC5fb3duZXIgfHwgbnVsbDtcbiAgaWYgKG93bmVyKSB7XG4gICAgdmFyIG5hbWUgPSBvd25lci5nZXROYW1lKCk7XG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIHJldHVybiAnIENoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgbmFtZSArICdgLic7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gU3RhdGVsZXNzQ29tcG9uZW50KENvbXBvbmVudCkge31cblN0YXRlbGVzc0NvbXBvbmVudC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgQ29tcG9uZW50ID0gUmVhY3RJbnN0YW5jZU1hcC5nZXQodGhpcykuX2N1cnJlbnRFbGVtZW50LnR5cGU7XG4gIHJldHVybiBDb21wb25lbnQodGhpcy5wcm9wcywgdGhpcy5jb250ZXh0LCB0aGlzLnVwZGF0ZXIpO1xufTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0gVGhlIExpZmUtQ3ljbGUgb2YgYSBDb21wb3NpdGUgQ29tcG9uZW50IC0tLS0tLS0tLS0tLS0tLS0tLVxuICpcbiAqIC0gY29uc3RydWN0b3I6IEluaXRpYWxpemF0aW9uIG9mIHN0YXRlLiBUaGUgaW5zdGFuY2UgaXMgbm93IHJldGFpbmVkLlxuICogICAtIGNvbXBvbmVudFdpbGxNb3VudFxuICogICAtIHJlbmRlclxuICogICAtIFtjaGlsZHJlbidzIGNvbnN0cnVjdG9yc11cbiAqICAgICAtIFtjaGlsZHJlbidzIGNvbXBvbmVudFdpbGxNb3VudCBhbmQgcmVuZGVyXVxuICogICAgIC0gW2NoaWxkcmVuJ3MgY29tcG9uZW50RGlkTW91bnRdXG4gKiAgICAgLSBjb21wb25lbnREaWRNb3VudFxuICpcbiAqICAgICAgIFVwZGF0ZSBQaGFzZXM6XG4gKiAgICAgICAtIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG9ubHkgY2FsbGVkIGlmIHBhcmVudCB1cGRhdGVkKVxuICogICAgICAgLSBzaG91bGRDb21wb25lbnRVcGRhdGVcbiAqICAgICAgICAgLSBjb21wb25lbnRXaWxsVXBkYXRlXG4gKiAgICAgICAgICAgLSByZW5kZXJcbiAqICAgICAgICAgICAtIFtjaGlsZHJlbidzIGNvbnN0cnVjdG9ycyBvciByZWNlaXZlIHByb3BzIHBoYXNlc11cbiAqICAgICAgICAgLSBjb21wb25lbnREaWRVcGRhdGVcbiAqXG4gKiAgICAgLSBjb21wb25lbnRXaWxsVW5tb3VudFxuICogICAgIC0gW2NoaWxkcmVuJ3MgY29tcG9uZW50V2lsbFVubW91bnRdXG4gKiAgIC0gW2NoaWxkcmVuIGRlc3Ryb3llZF1cbiAqIC0gKGRlc3Ryb3llZCk6IFRoZSBpbnN0YW5jZSBpcyBub3cgYmxhbmssIHJlbGVhc2VkIGJ5IFJlYWN0IGFuZCByZWFkeSBmb3IgR0MuXG4gKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG4vKipcbiAqIEFuIGluY3JlbWVudGluZyBJRCBhc3NpZ25lZCB0byBlYWNoIGNvbXBvbmVudCB3aGVuIGl0IGlzIG1vdW50ZWQuIFRoaXMgaXNcbiAqIHVzZWQgdG8gZW5mb3JjZSB0aGUgb3JkZXIgaW4gd2hpY2ggYFJlYWN0VXBkYXRlc2AgdXBkYXRlcyBkaXJ0eSBjb21wb25lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbnZhciBuZXh0TW91bnRJRCA9IDE7XG5cbi8qKlxuICogQGxlbmRzIHtSZWFjdENvbXBvc2l0ZUNvbXBvbmVudC5wcm90b3R5cGV9XG4gKi9cbnZhciBSZWFjdENvbXBvc2l0ZUNvbXBvbmVudE1peGluID0ge1xuXG4gIC8qKlxuICAgKiBCYXNlIGNvbnN0cnVjdG9yIGZvciBhbGwgY29tcG9zaXRlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQGZpbmFsXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHRoaXMuX2N1cnJlbnRFbGVtZW50ID0gZWxlbWVudDtcbiAgICB0aGlzLl9yb290Tm9kZUlEID0gbnVsbDtcbiAgICB0aGlzLl9pbnN0YW5jZSA9IG51bGw7XG5cbiAgICAvLyBTZWUgUmVhY3RVcGRhdGVRdWV1ZVxuICAgIHRoaXMuX3BlbmRpbmdFbGVtZW50ID0gbnVsbDtcbiAgICB0aGlzLl9wZW5kaW5nU3RhdGVRdWV1ZSA9IG51bGw7XG4gICAgdGhpcy5fcGVuZGluZ1JlcGxhY2VTdGF0ZSA9IGZhbHNlO1xuICAgIHRoaXMuX3BlbmRpbmdGb3JjZVVwZGF0ZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5fcmVuZGVyZWRDb21wb25lbnQgPSBudWxsO1xuXG4gICAgdGhpcy5fY29udGV4dCA9IG51bGw7XG4gICAgdGhpcy5fbW91bnRPcmRlciA9IDA7XG4gICAgdGhpcy5fdG9wTGV2ZWxXcmFwcGVyID0gbnVsbDtcblxuICAgIC8vIFNlZSBSZWFjdFVwZGF0ZXMgYW5kIFJlYWN0VXBkYXRlUXVldWUuXG4gICAgdGhpcy5fcGVuZGluZ0NhbGxiYWNrcyA9IG51bGw7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBjb21wb25lbnQsIHJlbmRlcnMgbWFya3VwLCBhbmQgcmVnaXN0ZXJzIGV2ZW50IGxpc3RlbmVycy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb3RJRCBET00gSUQgb2YgdGhlIHJvb3Qgbm9kZS5cbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEByZXR1cm4gez9zdHJpbmd9IFJlbmRlcmVkIG1hcmt1cCB0byBiZSBpbnNlcnRlZCBpbnRvIHRoZSBET00uXG4gICAqIEBmaW5hbFxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIG1vdW50Q29tcG9uZW50OiBmdW5jdGlvbiAocm9vdElELCB0cmFuc2FjdGlvbiwgY29udGV4dCkge1xuICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICAgIHRoaXMuX21vdW50T3JkZXIgPSBuZXh0TW91bnRJRCsrO1xuICAgIHRoaXMuX3Jvb3ROb2RlSUQgPSByb290SUQ7XG5cbiAgICB2YXIgcHVibGljUHJvcHMgPSB0aGlzLl9wcm9jZXNzUHJvcHModGhpcy5fY3VycmVudEVsZW1lbnQucHJvcHMpO1xuICAgIHZhciBwdWJsaWNDb250ZXh0ID0gdGhpcy5fcHJvY2Vzc0NvbnRleHQoY29udGV4dCk7XG5cbiAgICB2YXIgQ29tcG9uZW50ID0gdGhpcy5fY3VycmVudEVsZW1lbnQudHlwZTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIHB1YmxpYyBjbGFzc1xuICAgIHZhciBpbnN0O1xuICAgIHZhciByZW5kZXJlZEVsZW1lbnQ7XG5cbiAgICAvLyBUaGlzIGlzIGEgd2F5IHRvIGRldGVjdCBpZiBDb21wb25lbnQgaXMgYSBzdGF0ZWxlc3MgYXJyb3cgZnVuY3Rpb25cbiAgICAvLyBjb21wb25lbnQsIHdoaWNoIGlzIG5vdCBuZXdhYmxlLiBJdCBtaWdodCBub3QgYmUgMTAwJSByZWxpYWJsZSBidXQgaXNcbiAgICAvLyBzb21ldGhpbmcgd2UgY2FuIGRvIHVudGlsIHdlIHN0YXJ0IGRldGVjdGluZyB0aGF0IENvbXBvbmVudCBleHRlbmRzXG4gICAgLy8gUmVhY3QuQ29tcG9uZW50LiBXZSBhbHJlYWR5IGFzc3VtZSB0aGF0IHR5cGVvZiBDb21wb25lbnQgPT09ICdmdW5jdGlvbicuXG4gICAgdmFyIGNhbkluc3RhbnRpYXRlID0gKCdwcm90b3R5cGUnIGluIENvbXBvbmVudCk7XG5cbiAgICBpZiAoY2FuSW5zdGFudGlhdGUpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgPSB0aGlzO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGluc3QgPSBuZXcgQ29tcG9uZW50KHB1YmxpY1Byb3BzLCBwdWJsaWNDb250ZXh0LCBSZWFjdFVwZGF0ZVF1ZXVlKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5zdCA9IG5ldyBDb21wb25lbnQocHVibGljUHJvcHMsIHB1YmxpY0NvbnRleHQsIFJlYWN0VXBkYXRlUXVldWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY2FuSW5zdGFudGlhdGUgfHwgaW5zdCA9PT0gbnVsbCB8fCBpbnN0ID09PSBmYWxzZSB8fCBSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQoaW5zdCkpIHtcbiAgICAgIHJlbmRlcmVkRWxlbWVudCA9IGluc3Q7XG4gICAgICBpbnN0ID0gbmV3IFN0YXRlbGVzc0NvbXBvbmVudChDb21wb25lbnQpO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgbGF0ZXIgaW4gX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudCwgYnV0IGFkZCBhbiBlYXJseVxuICAgICAgLy8gd2FybmluZyBub3cgdG8gaGVscCBkZWJ1Z2dpbmdcbiAgICAgIGlmIChpbnN0LnJlbmRlciA9PSBudWxsKSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnJXMoLi4uKTogTm8gYHJlbmRlcmAgbWV0aG9kIGZvdW5kIG9uIHRoZSByZXR1cm5lZCBjb21wb25lbnQgJyArICdpbnN0YW5jZTogeW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBkZWZpbmUgYHJlbmRlcmAsIHJldHVybmVkICcgKyAnbnVsbC9mYWxzZSBmcm9tIGEgc3RhdGVsZXNzIGNvbXBvbmVudCwgb3IgdHJpZWQgdG8gcmVuZGVyIGFuICcgKyAnZWxlbWVudCB3aG9zZSB0eXBlIGlzIGEgZnVuY3Rpb24gdGhhdCBpc25cXCd0IGEgUmVhY3QgY29tcG9uZW50LicsIENvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBDb21wb25lbnQubmFtZSB8fCAnQ29tcG9uZW50JykgOiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXZSBzdXBwb3J0IEVTNiBpbmhlcml0aW5nIGZyb20gUmVhY3QuQ29tcG9uZW50LCB0aGUgbW9kdWxlIHBhdHRlcm4sXG4gICAgICAgIC8vIGFuZCBzdGF0ZWxlc3MgY29tcG9uZW50cywgYnV0IG5vdCBFUzYgY2xhc3NlcyB0aGF0IGRvbid0IGV4dGVuZFxuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhDb21wb25lbnQucHJvdG90eXBlICYmIENvbXBvbmVudC5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudCB8fCAhY2FuSW5zdGFudGlhdGUgfHwgIShpbnN0IGluc3RhbmNlb2YgQ29tcG9uZW50KSwgJyVzKC4uLik6IFJlYWN0IGNvbXBvbmVudCBjbGFzc2VzIG11c3QgZXh0ZW5kIFJlYWN0LkNvbXBvbmVudC4nLCBDb21wb25lbnQuZGlzcGxheU5hbWUgfHwgQ29tcG9uZW50Lm5hbWUgfHwgJ0NvbXBvbmVudCcpIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoZXNlIHNob3VsZCBiZSBzZXQgdXAgaW4gdGhlIGNvbnN0cnVjdG9yLCBidXQgYXMgYSBjb252ZW5pZW5jZSBmb3JcbiAgICAvLyBzaW1wbGVyIGNsYXNzIGFic3RyYWN0aW9ucywgd2Ugc2V0IHRoZW0gdXAgYWZ0ZXIgdGhlIGZhY3QuXG4gICAgaW5zdC5wcm9wcyA9IHB1YmxpY1Byb3BzO1xuICAgIGluc3QuY29udGV4dCA9IHB1YmxpY0NvbnRleHQ7XG4gICAgaW5zdC5yZWZzID0gZW1wdHlPYmplY3Q7XG4gICAgaW5zdC51cGRhdGVyID0gUmVhY3RVcGRhdGVRdWV1ZTtcblxuICAgIHRoaXMuX2luc3RhbmNlID0gaW5zdDtcblxuICAgIC8vIFN0b3JlIGEgcmVmZXJlbmNlIGZyb20gdGhlIGluc3RhbmNlIGJhY2sgdG8gdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uXG4gICAgUmVhY3RJbnN0YW5jZU1hcC5zZXQoaW5zdCwgdGhpcyk7XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgLy8gU2luY2UgcGxhaW4gSlMgY2xhc3NlcyBhcmUgZGVmaW5lZCB3aXRob3V0IGFueSBzcGVjaWFsIGluaXRpYWxpemF0aW9uXG4gICAgICAvLyBsb2dpYywgd2UgY2FuIG5vdCBjYXRjaCBjb21tb24gZXJyb3JzIGVhcmx5LiBUaGVyZWZvcmUsIHdlIGhhdmUgdG9cbiAgICAgIC8vIGNhdGNoIHRoZW0gaGVyZSwgYXQgaW5pdGlhbGl6YXRpb24gdGltZSwgaW5zdGVhZC5cbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFpbnN0LmdldEluaXRpYWxTdGF0ZSB8fCBpbnN0LmdldEluaXRpYWxTdGF0ZS5pc1JlYWN0Q2xhc3NBcHByb3ZlZCwgJ2dldEluaXRpYWxTdGF0ZSB3YXMgZGVmaW5lZCBvbiAlcywgYSBwbGFpbiBKYXZhU2NyaXB0IGNsYXNzLiAnICsgJ1RoaXMgaXMgb25seSBzdXBwb3J0ZWQgZm9yIGNsYXNzZXMgY3JlYXRlZCB1c2luZyBSZWFjdC5jcmVhdGVDbGFzcy4gJyArICdEaWQgeW91IG1lYW4gdG8gZGVmaW5lIGEgc3RhdGUgcHJvcGVydHkgaW5zdGVhZD8nLCB0aGlzLmdldE5hbWUoKSB8fCAnYSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFpbnN0LmdldERlZmF1bHRQcm9wcyB8fCBpbnN0LmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCwgJ2dldERlZmF1bHRQcm9wcyB3YXMgZGVmaW5lZCBvbiAlcywgYSBwbGFpbiBKYXZhU2NyaXB0IGNsYXNzLiAnICsgJ1RoaXMgaXMgb25seSBzdXBwb3J0ZWQgZm9yIGNsYXNzZXMgY3JlYXRlZCB1c2luZyBSZWFjdC5jcmVhdGVDbGFzcy4gJyArICdVc2UgYSBzdGF0aWMgcHJvcGVydHkgdG8gZGVmaW5lIGRlZmF1bHRQcm9wcyBpbnN0ZWFkLicsIHRoaXMuZ2V0TmFtZSgpIHx8ICdhIGNvbXBvbmVudCcpIDogdW5kZWZpbmVkO1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoIWluc3QucHJvcFR5cGVzLCAncHJvcFR5cGVzIHdhcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIHByb3BlcnR5IG9uICVzLiBVc2UgYSBzdGF0aWMgJyArICdwcm9wZXJ0eSB0byBkZWZpbmUgcHJvcFR5cGVzIGluc3RlYWQuJywgdGhpcy5nZXROYW1lKCkgfHwgJ2EgY29tcG9uZW50JykgOiB1bmRlZmluZWQ7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyghaW5zdC5jb250ZXh0VHlwZXMsICdjb250ZXh0VHlwZXMgd2FzIGRlZmluZWQgYXMgYW4gaW5zdGFuY2UgcHJvcGVydHkgb24gJXMuIFVzZSBhICcgKyAnc3RhdGljIHByb3BlcnR5IHRvIGRlZmluZSBjb250ZXh0VHlwZXMgaW5zdGVhZC4nLCB0aGlzLmdldE5hbWUoKSB8fCAnYSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHR5cGVvZiBpbnN0LmNvbXBvbmVudFNob3VsZFVwZGF0ZSAhPT0gJ2Z1bmN0aW9uJywgJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnRTaG91bGRVcGRhdGUoKS4gRGlkIHlvdSBtZWFuIHNob3VsZENvbXBvbmVudFVwZGF0ZSgpPyAnICsgJ1RoZSBuYW1lIGlzIHBocmFzZWQgYXMgYSBxdWVzdGlvbiBiZWNhdXNlIHRoZSBmdW5jdGlvbiBpcyAnICsgJ2V4cGVjdGVkIHRvIHJldHVybiBhIHZhbHVlLicsIHRoaXMuZ2V0TmFtZSgpIHx8ICdBIGNvbXBvbmVudCcpIDogdW5kZWZpbmVkO1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcodHlwZW9mIGluc3QuY29tcG9uZW50RGlkVW5tb3VudCAhPT0gJ2Z1bmN0aW9uJywgJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnREaWRVbm1vdW50KCkuIEJ1dCB0aGVyZSBpcyBubyBzdWNoIGxpZmVjeWNsZSBtZXRob2QuICcgKyAnRGlkIHlvdSBtZWFuIGNvbXBvbmVudFdpbGxVbm1vdW50KCk/JywgdGhpcy5nZXROYW1lKCkgfHwgJ0EgY29tcG9uZW50JykgOiB1bmRlZmluZWQ7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyh0eXBlb2YgaW5zdC5jb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzICE9PSAnZnVuY3Rpb24nLCAnJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudFdpbGxSZWNpZXZlUHJvcHMoKS4gRGlkIHlvdSBtZWFuIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKT8nLCB0aGlzLmdldE5hbWUoKSB8fCAnQSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB2YXIgaW5pdGlhbFN0YXRlID0gaW5zdC5zdGF0ZTtcbiAgICBpZiAoaW5pdGlhbFN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGluc3Quc3RhdGUgPSBpbml0aWFsU3RhdGUgPSBudWxsO1xuICAgIH1cbiAgICAhKHR5cGVvZiBpbml0aWFsU3RhdGUgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KGluaXRpYWxTdGF0ZSkpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJyVzLnN0YXRlOiBtdXN0IGJlIHNldCB0byBhbiBvYmplY3Qgb3IgbnVsbCcsIHRoaXMuZ2V0TmFtZSgpIHx8ICdSZWFjdENvbXBvc2l0ZUNvbXBvbmVudCcpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIHRoaXMuX3BlbmRpbmdTdGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB0aGlzLl9wZW5kaW5nUmVwbGFjZVN0YXRlID0gZmFsc2U7XG4gICAgdGhpcy5fcGVuZGluZ0ZvcmNlVXBkYXRlID0gZmFsc2U7XG5cbiAgICBpZiAoaW5zdC5jb21wb25lbnRXaWxsTW91bnQpIHtcbiAgICAgIGluc3QuY29tcG9uZW50V2lsbE1vdW50KCk7XG4gICAgICAvLyBXaGVuIG1vdW50aW5nLCBjYWxscyB0byBgc2V0U3RhdGVgIGJ5IGBjb21wb25lbnRXaWxsTW91bnRgIHdpbGwgc2V0XG4gICAgICAvLyBgdGhpcy5fcGVuZGluZ1N0YXRlUXVldWVgIHdpdGhvdXQgdHJpZ2dlcmluZyBhIHJlLXJlbmRlci5cbiAgICAgIGlmICh0aGlzLl9wZW5kaW5nU3RhdGVRdWV1ZSkge1xuICAgICAgICBpbnN0LnN0YXRlID0gdGhpcy5fcHJvY2Vzc1BlbmRpbmdTdGF0ZShpbnN0LnByb3BzLCBpbnN0LmNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vdCBhIHN0YXRlbGVzcyBjb21wb25lbnQsIHdlIG5vdyByZW5kZXJcbiAgICBpZiAocmVuZGVyZWRFbGVtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlbmRlcmVkRWxlbWVudCA9IHRoaXMuX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudCgpO1xuICAgIH1cblxuICAgIHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50ID0gdGhpcy5faW5zdGFudGlhdGVSZWFjdENvbXBvbmVudChyZW5kZXJlZEVsZW1lbnQpO1xuXG4gICAgdmFyIG1hcmt1cCA9IFJlYWN0UmVjb25jaWxlci5tb3VudENvbXBvbmVudCh0aGlzLl9yZW5kZXJlZENvbXBvbmVudCwgcm9vdElELCB0cmFuc2FjdGlvbiwgdGhpcy5fcHJvY2Vzc0NoaWxkQ29udGV4dChjb250ZXh0KSk7XG4gICAgaWYgKGluc3QuY29tcG9uZW50RGlkTW91bnQpIHtcbiAgICAgIHRyYW5zYWN0aW9uLmdldFJlYWN0TW91bnRSZWFkeSgpLmVucXVldWUoaW5zdC5jb21wb25lbnREaWRNb3VudCwgaW5zdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcmt1cDtcbiAgfSxcblxuICAvKipcbiAgICogUmVsZWFzZXMgYW55IHJlc291cmNlcyBhbGxvY2F0ZWQgYnkgYG1vdW50Q29tcG9uZW50YC5cbiAgICpcbiAgICogQGZpbmFsXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdW5tb3VudENvbXBvbmVudDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBpbnN0ID0gdGhpcy5faW5zdGFuY2U7XG5cbiAgICBpZiAoaW5zdC5jb21wb25lbnRXaWxsVW5tb3VudCkge1xuICAgICAgaW5zdC5jb21wb25lbnRXaWxsVW5tb3VudCgpO1xuICAgIH1cblxuICAgIFJlYWN0UmVjb25jaWxlci51bm1vdW50Q29tcG9uZW50KHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50KTtcbiAgICB0aGlzLl9yZW5kZXJlZENvbXBvbmVudCA9IG51bGw7XG4gICAgdGhpcy5faW5zdGFuY2UgPSBudWxsO1xuXG4gICAgLy8gUmVzZXQgcGVuZGluZyBmaWVsZHNcbiAgICAvLyBFdmVuIGlmIHRoaXMgY29tcG9uZW50IGlzIHNjaGVkdWxlZCBmb3IgYW5vdGhlciB1cGRhdGUgaW4gUmVhY3RVcGRhdGVzLFxuICAgIC8vIGl0IHdvdWxkIHN0aWxsIGJlIGlnbm9yZWQgYmVjYXVzZSB0aGVzZSBmaWVsZHMgYXJlIHJlc2V0LlxuICAgIHRoaXMuX3BlbmRpbmdTdGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB0aGlzLl9wZW5kaW5nUmVwbGFjZVN0YXRlID0gZmFsc2U7XG4gICAgdGhpcy5fcGVuZGluZ0ZvcmNlVXBkYXRlID0gZmFsc2U7XG4gICAgdGhpcy5fcGVuZGluZ0NhbGxiYWNrcyA9IG51bGw7XG4gICAgdGhpcy5fcGVuZGluZ0VsZW1lbnQgPSBudWxsO1xuXG4gICAgLy8gVGhlc2UgZmllbGRzIGRvIG5vdCByZWFsbHkgbmVlZCB0byBiZSByZXNldCBzaW5jZSB0aGlzIG9iamVjdCBpcyBub1xuICAgIC8vIGxvbmdlciBhY2Nlc3NpYmxlLlxuICAgIHRoaXMuX2NvbnRleHQgPSBudWxsO1xuICAgIHRoaXMuX3Jvb3ROb2RlSUQgPSBudWxsO1xuICAgIHRoaXMuX3RvcExldmVsV3JhcHBlciA9IG51bGw7XG5cbiAgICAvLyBEZWxldGUgdGhlIHJlZmVyZW5jZSBmcm9tIHRoZSBpbnN0YW5jZSB0byB0aGlzIGludGVybmFsIHJlcHJlc2VudGF0aW9uXG4gICAgLy8gd2hpY2ggYWxsb3cgdGhlIGludGVybmFscyB0byBiZSBwcm9wZXJseSBjbGVhbmVkIHVwIGV2ZW4gaWYgdGhlIHVzZXJcbiAgICAvLyBsZWFrcyBhIHJlZmVyZW5jZSB0byB0aGUgcHVibGljIGluc3RhbmNlLlxuICAgIFJlYWN0SW5zdGFuY2VNYXAucmVtb3ZlKGluc3QpO1xuXG4gICAgLy8gU29tZSBleGlzdGluZyBjb21wb25lbnRzIHJlbHkgb24gaW5zdC5wcm9wcyBldmVuIGFmdGVyIHRoZXkndmUgYmVlblxuICAgIC8vIGRlc3Ryb3llZCAoaW4gZXZlbnQgaGFuZGxlcnMpLlxuICAgIC8vIFRPRE86IGluc3QucHJvcHMgPSBudWxsO1xuICAgIC8vIFRPRE86IGluc3Quc3RhdGUgPSBudWxsO1xuICAgIC8vIFRPRE86IGluc3QuY29udGV4dCA9IG51bGw7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgdGhlIGNvbnRleHQgb2JqZWN0IHRvIG9ubHkgY29udGFpbiBrZXlzIHNwZWNpZmllZCBpblxuICAgKiBgY29udGV4dFR5cGVzYFxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX21hc2tDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBtYXNrZWRDb250ZXh0ID0gbnVsbDtcbiAgICB2YXIgQ29tcG9uZW50ID0gdGhpcy5fY3VycmVudEVsZW1lbnQudHlwZTtcbiAgICB2YXIgY29udGV4dFR5cGVzID0gQ29tcG9uZW50LmNvbnRleHRUeXBlcztcbiAgICBpZiAoIWNvbnRleHRUeXBlcykge1xuICAgICAgcmV0dXJuIGVtcHR5T2JqZWN0O1xuICAgIH1cbiAgICBtYXNrZWRDb250ZXh0ID0ge307XG4gICAgZm9yICh2YXIgY29udGV4dE5hbWUgaW4gY29udGV4dFR5cGVzKSB7XG4gICAgICBtYXNrZWRDb250ZXh0W2NvbnRleHROYW1lXSA9IGNvbnRleHRbY29udGV4dE5hbWVdO1xuICAgIH1cbiAgICByZXR1cm4gbWFza2VkQ29udGV4dDtcbiAgfSxcblxuICAvKipcbiAgICogRmlsdGVycyB0aGUgY29udGV4dCBvYmplY3QgdG8gb25seSBjb250YWluIGtleXMgc3BlY2lmaWVkIGluXG4gICAqIGBjb250ZXh0VHlwZXNgLCBhbmQgYXNzZXJ0cyB0aGF0IHRoZXkgYXJlIHZhbGlkLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX3Byb2Nlc3NDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBtYXNrZWRDb250ZXh0ID0gdGhpcy5fbWFza0NvbnRleHQoY29udGV4dCk7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhciBDb21wb25lbnQgPSB0aGlzLl9jdXJyZW50RWxlbWVudC50eXBlO1xuICAgICAgaWYgKENvbXBvbmVudC5jb250ZXh0VHlwZXMpIHtcbiAgICAgICAgdGhpcy5fY2hlY2tQcm9wVHlwZXMoQ29tcG9uZW50LmNvbnRleHRUeXBlcywgbWFza2VkQ29udGV4dCwgUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5jb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hc2tlZENvbnRleHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjdXJyZW50Q29udGV4dFxuICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfcHJvY2Vzc0NoaWxkQ29udGV4dDogZnVuY3Rpb24gKGN1cnJlbnRDb250ZXh0KSB7XG4gICAgdmFyIENvbXBvbmVudCA9IHRoaXMuX2N1cnJlbnRFbGVtZW50LnR5cGU7XG4gICAgdmFyIGluc3QgPSB0aGlzLl9pbnN0YW5jZTtcbiAgICB2YXIgY2hpbGRDb250ZXh0ID0gaW5zdC5nZXRDaGlsZENvbnRleHQgJiYgaW5zdC5nZXRDaGlsZENvbnRleHQoKTtcbiAgICBpZiAoY2hpbGRDb250ZXh0KSB7XG4gICAgICAhKHR5cGVvZiBDb21wb25lbnQuY2hpbGRDb250ZXh0VHlwZXMgPT09ICdvYmplY3QnKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICclcy5nZXRDaGlsZENvbnRleHQoKTogY2hpbGRDb250ZXh0VHlwZXMgbXVzdCBiZSBkZWZpbmVkIGluIG9yZGVyIHRvICcgKyAndXNlIGdldENoaWxkQ29udGV4dCgpLicsIHRoaXMuZ2V0TmFtZSgpIHx8ICdSZWFjdENvbXBvc2l0ZUNvbXBvbmVudCcpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHRoaXMuX2NoZWNrUHJvcFR5cGVzKENvbXBvbmVudC5jaGlsZENvbnRleHRUeXBlcywgY2hpbGRDb250ZXh0LCBSZWFjdFByb3BUeXBlTG9jYXRpb25zLmNoaWxkQ29udGV4dCk7XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBuYW1lIGluIGNoaWxkQ29udGV4dCkge1xuICAgICAgICAhKG5hbWUgaW4gQ29tcG9uZW50LmNoaWxkQ29udGV4dFR5cGVzKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICclcy5nZXRDaGlsZENvbnRleHQoKToga2V5IFwiJXNcIiBpcyBub3QgZGVmaW5lZCBpbiBjaGlsZENvbnRleHRUeXBlcy4nLCB0aGlzLmdldE5hbWUoKSB8fCAnUmVhY3RDb21wb3NpdGVDb21wb25lbnQnLCBuYW1lKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXNzaWduKHt9LCBjdXJyZW50Q29udGV4dCwgY2hpbGRDb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRDb250ZXh0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgcHJvcHMgYnkgc2V0dGluZyBkZWZhdWx0IHZhbHVlcyBmb3IgdW5zcGVjaWZpZWQgcHJvcHMgYW5kXG4gICAqIGFzc2VydGluZyB0aGF0IHRoZSBwcm9wcyBhcmUgdmFsaWQuIERvZXMgbm90IG11dGF0ZSBpdHMgYXJndW1lbnQ7IHJldHVybnNcbiAgICogYSBuZXcgcHJvcHMgb2JqZWN0IHdpdGggZGVmYXVsdHMgbWVyZ2VkIGluLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmV3UHJvcHNcbiAgICogQHJldHVybiB7b2JqZWN0fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX3Byb2Nlc3NQcm9wczogZnVuY3Rpb24gKG5ld1Byb3BzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhciBDb21wb25lbnQgPSB0aGlzLl9jdXJyZW50RWxlbWVudC50eXBlO1xuICAgICAgaWYgKENvbXBvbmVudC5wcm9wVHlwZXMpIHtcbiAgICAgICAgdGhpcy5fY2hlY2tQcm9wVHlwZXMoQ29tcG9uZW50LnByb3BUeXBlcywgbmV3UHJvcHMsIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnMucHJvcCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXdQcm9wcztcbiAgfSxcblxuICAvKipcbiAgICogQXNzZXJ0IHRoYXQgdGhlIHByb3BzIGFyZSB2YWxpZFxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gcHJvcFR5cGVzIE1hcCBvZiBwcm9wIG5hbWUgdG8gYSBSZWFjdFByb3BUeXBlXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwcm9wc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYXRpb24gZS5nLiBcInByb3BcIiwgXCJjb250ZXh0XCIsIFwiY2hpbGQgY29udGV4dFwiXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfY2hlY2tQcm9wVHlwZXM6IGZ1bmN0aW9uIChwcm9wVHlwZXMsIHByb3BzLCBsb2NhdGlvbikge1xuICAgIC8vIFRPRE86IFN0b3AgdmFsaWRhdGluZyBwcm9wIHR5cGVzIGhlcmUgYW5kIG9ubHkgdXNlIHRoZSBlbGVtZW50XG4gICAgLy8gdmFsaWRhdGlvbi5cbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IHRoaXMuZ2V0TmFtZSgpO1xuICAgIGZvciAodmFyIHByb3BOYW1lIGluIHByb3BUeXBlcykge1xuICAgICAgaWYgKHByb3BUeXBlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhbiBpbnZhcmlhbnQgdGhhdCBnZXRzIGNhdWdodC4gSXQncyB0aGUgc2FtZVxuICAgICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgICAhKHR5cGVvZiBwcm9wVHlwZXNbcHJvcE5hbWVdID09PSAnZnVuY3Rpb24nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICclczogJXMgdHlwZSBgJXNgIGlzIGludmFsaWQ7IGl0IG11c3QgYmUgYSBmdW5jdGlvbiwgdXN1YWxseSAnICsgJ2Zyb20gUmVhY3QuUHJvcFR5cGVzLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXNbbG9jYXRpb25dLCBwcm9wTmFtZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICAgICAgIGVycm9yID0gcHJvcFR5cGVzW3Byb3BOYW1lXShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciA9IGV4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgLy8gV2UgbWF5IHdhbnQgdG8gZXh0ZW5kIHRoaXMgbG9naWMgZm9yIHNpbWlsYXIgZXJyb3JzIGluXG4gICAgICAgICAgLy8gdG9wLWxldmVsIHJlbmRlciBjYWxscywgc28gSSdtIGFic3RyYWN0aW5nIGl0IGF3YXkgaW50b1xuICAgICAgICAgIC8vIGEgZnVuY3Rpb24gdG8gbWluaW1pemUgcmVmYWN0b3JpbmcgaW4gdGhlIGZ1dHVyZVxuICAgICAgICAgIHZhciBhZGRlbmR1bSA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSh0aGlzKTtcblxuICAgICAgICAgIGlmIChsb2NhdGlvbiA9PT0gUmVhY3RQcm9wVHlwZUxvY2F0aW9ucy5wcm9wKSB7XG4gICAgICAgICAgICAvLyBQcmVmYWNlIGdpdmVzIHVzIHNvbWV0aGluZyB0byBibGFja2xpc3QgaW4gd2FybmluZyBtb2R1bGVcbiAgICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnRmFpbGVkIENvbXBvc2l0ZSBwcm9wVHlwZTogJXMlcycsIGVycm9yLm1lc3NhZ2UsIGFkZGVuZHVtKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdGYWlsZWQgQ29udGV4dCBUeXBlczogJXMlcycsIGVycm9yLm1lc3NhZ2UsIGFkZGVuZHVtKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgcmVjZWl2ZUNvbXBvbmVudDogZnVuY3Rpb24gKG5leHRFbGVtZW50LCB0cmFuc2FjdGlvbiwgbmV4dENvbnRleHQpIHtcbiAgICB2YXIgcHJldkVsZW1lbnQgPSB0aGlzLl9jdXJyZW50RWxlbWVudDtcbiAgICB2YXIgcHJldkNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuXG4gICAgdGhpcy5fcGVuZGluZ0VsZW1lbnQgPSBudWxsO1xuXG4gICAgdGhpcy51cGRhdGVDb21wb25lbnQodHJhbnNhY3Rpb24sIHByZXZFbGVtZW50LCBuZXh0RWxlbWVudCwgcHJldkNvbnRleHQsIG5leHRDb250ZXh0KTtcbiAgfSxcblxuICAvKipcbiAgICogSWYgYW55IG9mIGBfcGVuZGluZ0VsZW1lbnRgLCBgX3BlbmRpbmdTdGF0ZVF1ZXVlYCwgb3IgYF9wZW5kaW5nRm9yY2VVcGRhdGVgXG4gICAqIGlzIHNldCwgdXBkYXRlIHRoZSBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwZXJmb3JtVXBkYXRlSWZOZWNlc3Nhcnk6IGZ1bmN0aW9uICh0cmFuc2FjdGlvbikge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nRWxlbWVudCAhPSBudWxsKSB7XG4gICAgICBSZWFjdFJlY29uY2lsZXIucmVjZWl2ZUNvbXBvbmVudCh0aGlzLCB0aGlzLl9wZW5kaW5nRWxlbWVudCB8fCB0aGlzLl9jdXJyZW50RWxlbWVudCwgdHJhbnNhY3Rpb24sIHRoaXMuX2NvbnRleHQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9wZW5kaW5nU3RhdGVRdWV1ZSAhPT0gbnVsbCB8fCB0aGlzLl9wZW5kaW5nRm9yY2VVcGRhdGUpIHtcbiAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50KHRyYW5zYWN0aW9uLCB0aGlzLl9jdXJyZW50RWxlbWVudCwgdGhpcy5fY3VycmVudEVsZW1lbnQsIHRoaXMuX2NvbnRleHQsIHRoaXMuX2NvbnRleHQpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUGVyZm9ybSBhbiB1cGRhdGUgdG8gYSBtb3VudGVkIGNvbXBvbmVudC4gVGhlIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgYW5kXG4gICAqIHNob3VsZENvbXBvbmVudFVwZGF0ZSBtZXRob2RzIGFyZSBjYWxsZWQsIHRoZW4gKGFzc3VtaW5nIHRoZSB1cGRhdGUgaXNuJ3RcbiAgICogc2tpcHBlZCkgdGhlIHJlbWFpbmluZyB1cGRhdGUgbGlmZWN5Y2xlIG1ldGhvZHMgYXJlIGNhbGxlZCBhbmQgdGhlIERPTVxuICAgKiByZXByZXNlbnRhdGlvbiBpcyB1cGRhdGVkLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCB0aGlzIGltcGxlbWVudHMgUmVhY3QncyByZW5kZXJpbmcgYW5kIHJlY29uY2lsaWF0aW9uIGFsZ29yaXRobS5cbiAgICogU29waGlzdGljYXRlZCBjbGllbnRzIG1heSB3aXNoIHRvIG92ZXJyaWRlIHRoaXMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IHByZXZQYXJlbnRFbGVtZW50XG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0UGFyZW50RWxlbWVudFxuICAgKiBAaW50ZXJuYWxcbiAgICogQG92ZXJyaWRhYmxlXG4gICAqL1xuICB1cGRhdGVDb21wb25lbnQ6IGZ1bmN0aW9uICh0cmFuc2FjdGlvbiwgcHJldlBhcmVudEVsZW1lbnQsIG5leHRQYXJlbnRFbGVtZW50LCBwcmV2VW5tYXNrZWRDb250ZXh0LCBuZXh0VW5tYXNrZWRDb250ZXh0KSB7XG4gICAgdmFyIGluc3QgPSB0aGlzLl9pbnN0YW5jZTtcblxuICAgIHZhciBuZXh0Q29udGV4dCA9IHRoaXMuX2NvbnRleHQgPT09IG5leHRVbm1hc2tlZENvbnRleHQgPyBpbnN0LmNvbnRleHQgOiB0aGlzLl9wcm9jZXNzQ29udGV4dChuZXh0VW5tYXNrZWRDb250ZXh0KTtcbiAgICB2YXIgbmV4dFByb3BzO1xuXG4gICAgLy8gRGlzdGluZ3Vpc2ggYmV0d2VlbiBhIHByb3BzIHVwZGF0ZSB2ZXJzdXMgYSBzaW1wbGUgc3RhdGUgdXBkYXRlXG4gICAgaWYgKHByZXZQYXJlbnRFbGVtZW50ID09PSBuZXh0UGFyZW50RWxlbWVudCkge1xuICAgICAgLy8gU2tpcCBjaGVja2luZyBwcm9wIHR5cGVzIGFnYWluIC0tIHdlIGRvbid0IHJlYWQgaW5zdC5wcm9wcyB0byBhdm9pZFxuICAgICAgLy8gd2FybmluZyBmb3IgRE9NIGNvbXBvbmVudCBwcm9wcyBpbiB0aGlzIHVwZ3JhZGVcbiAgICAgIG5leHRQcm9wcyA9IG5leHRQYXJlbnRFbGVtZW50LnByb3BzO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0UHJvcHMgPSB0aGlzLl9wcm9jZXNzUHJvcHMobmV4dFBhcmVudEVsZW1lbnQucHJvcHMpO1xuICAgICAgLy8gQW4gdXBkYXRlIGhlcmUgd2lsbCBzY2hlZHVsZSBhbiB1cGRhdGUgYnV0IGltbWVkaWF0ZWx5IHNldFxuICAgICAgLy8gX3BlbmRpbmdTdGF0ZVF1ZXVlIHdoaWNoIHdpbGwgZW5zdXJlIHRoYXQgYW55IHN0YXRlIHVwZGF0ZXMgZ2V0c1xuICAgICAgLy8gaW1tZWRpYXRlbHkgcmVjb25jaWxlZCBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIHRoZSBuZXh0IGJhdGNoLlxuXG4gICAgICBpZiAoaW5zdC5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKSB7XG4gICAgICAgIGluc3QuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMsIG5leHRDb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbmV4dFN0YXRlID0gdGhpcy5fcHJvY2Vzc1BlbmRpbmdTdGF0ZShuZXh0UHJvcHMsIG5leHRDb250ZXh0KTtcblxuICAgIHZhciBzaG91bGRVcGRhdGUgPSB0aGlzLl9wZW5kaW5nRm9yY2VVcGRhdGUgfHwgIWluc3Quc2hvdWxkQ29tcG9uZW50VXBkYXRlIHx8IGluc3Quc2hvdWxkQ29tcG9uZW50VXBkYXRlKG5leHRQcm9wcywgbmV4dFN0YXRlLCBuZXh0Q29udGV4dCk7XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcodHlwZW9mIHNob3VsZFVwZGF0ZSAhPT0gJ3VuZGVmaW5lZCcsICclcy5zaG91bGRDb21wb25lbnRVcGRhdGUoKTogUmV0dXJuZWQgdW5kZWZpbmVkIGluc3RlYWQgb2YgYSAnICsgJ2Jvb2xlYW4gdmFsdWUuIE1ha2Ugc3VyZSB0byByZXR1cm4gdHJ1ZSBvciBmYWxzZS4nLCB0aGlzLmdldE5hbWUoKSB8fCAnUmVhY3RDb21wb3NpdGVDb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkVXBkYXRlKSB7XG4gICAgICB0aGlzLl9wZW5kaW5nRm9yY2VVcGRhdGUgPSBmYWxzZTtcbiAgICAgIC8vIFdpbGwgc2V0IGB0aGlzLnByb3BzYCwgYHRoaXMuc3RhdGVgIGFuZCBgdGhpcy5jb250ZXh0YC5cbiAgICAgIHRoaXMuX3BlcmZvcm1Db21wb25lbnRVcGRhdGUobmV4dFBhcmVudEVsZW1lbnQsIG5leHRQcm9wcywgbmV4dFN0YXRlLCBuZXh0Q29udGV4dCwgdHJhbnNhY3Rpb24sIG5leHRVbm1hc2tlZENvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBpdCdzIGRldGVybWluZWQgdGhhdCBhIGNvbXBvbmVudCBzaG91bGQgbm90IHVwZGF0ZSwgd2Ugc3RpbGwgd2FudFxuICAgICAgLy8gdG8gc2V0IHByb3BzIGFuZCBzdGF0ZSBidXQgd2Ugc2hvcnRjdXQgdGhlIHJlc3Qgb2YgdGhlIHVwZGF0ZS5cbiAgICAgIHRoaXMuX2N1cnJlbnRFbGVtZW50ID0gbmV4dFBhcmVudEVsZW1lbnQ7XG4gICAgICB0aGlzLl9jb250ZXh0ID0gbmV4dFVubWFza2VkQ29udGV4dDtcbiAgICAgIGluc3QucHJvcHMgPSBuZXh0UHJvcHM7XG4gICAgICBpbnN0LnN0YXRlID0gbmV4dFN0YXRlO1xuICAgICAgaW5zdC5jb250ZXh0ID0gbmV4dENvbnRleHQ7XG4gICAgfVxuICB9LFxuXG4gIF9wcm9jZXNzUGVuZGluZ1N0YXRlOiBmdW5jdGlvbiAocHJvcHMsIGNvbnRleHQpIHtcbiAgICB2YXIgaW5zdCA9IHRoaXMuX2luc3RhbmNlO1xuICAgIHZhciBxdWV1ZSA9IHRoaXMuX3BlbmRpbmdTdGF0ZVF1ZXVlO1xuICAgIHZhciByZXBsYWNlID0gdGhpcy5fcGVuZGluZ1JlcGxhY2VTdGF0ZTtcbiAgICB0aGlzLl9wZW5kaW5nUmVwbGFjZVN0YXRlID0gZmFsc2U7XG4gICAgdGhpcy5fcGVuZGluZ1N0YXRlUXVldWUgPSBudWxsO1xuXG4gICAgaWYgKCFxdWV1ZSkge1xuICAgICAgcmV0dXJuIGluc3Quc3RhdGU7XG4gICAgfVxuXG4gICAgaWYgKHJlcGxhY2UgJiYgcXVldWUubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gcXVldWVbMF07XG4gICAgfVxuXG4gICAgdmFyIG5leHRTdGF0ZSA9IGFzc2lnbih7fSwgcmVwbGFjZSA/IHF1ZXVlWzBdIDogaW5zdC5zdGF0ZSk7XG4gICAgZm9yICh2YXIgaSA9IHJlcGxhY2UgPyAxIDogMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcGFydGlhbCA9IHF1ZXVlW2ldO1xuICAgICAgYXNzaWduKG5leHRTdGF0ZSwgdHlwZW9mIHBhcnRpYWwgPT09ICdmdW5jdGlvbicgPyBwYXJ0aWFsLmNhbGwoaW5zdCwgbmV4dFN0YXRlLCBwcm9wcywgY29udGV4dCkgOiBwYXJ0aWFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV4dFN0YXRlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBNZXJnZXMgbmV3IHByb3BzIGFuZCBzdGF0ZSwgbm90aWZpZXMgZGVsZWdhdGUgbWV0aG9kcyBvZiB1cGRhdGUgYW5kXG4gICAqIHBlcmZvcm1zIHVwZGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IG5leHRFbGVtZW50IE5leHQgZWxlbWVudFxuICAgKiBAcGFyYW0ge29iamVjdH0gbmV4dFByb3BzIE5leHQgcHVibGljIG9iamVjdCB0byBzZXQgYXMgcHJvcGVydGllcy5cbiAgICogQHBhcmFtIHs/b2JqZWN0fSBuZXh0U3RhdGUgTmV4dCBvYmplY3QgdG8gc2V0IGFzIHN0YXRlLlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG5leHRDb250ZXh0IE5leHQgcHVibGljIG9iamVjdCB0byBzZXQgYXMgY29udGV4dC5cbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gez9vYmplY3R9IHVubWFza2VkQ29udGV4dFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX3BlcmZvcm1Db21wb25lbnRVcGRhdGU6IGZ1bmN0aW9uIChuZXh0RWxlbWVudCwgbmV4dFByb3BzLCBuZXh0U3RhdGUsIG5leHRDb250ZXh0LCB0cmFuc2FjdGlvbiwgdW5tYXNrZWRDb250ZXh0KSB7XG4gICAgdmFyIGluc3QgPSB0aGlzLl9pbnN0YW5jZTtcblxuICAgIHZhciBoYXNDb21wb25lbnREaWRVcGRhdGUgPSBCb29sZWFuKGluc3QuY29tcG9uZW50RGlkVXBkYXRlKTtcbiAgICB2YXIgcHJldlByb3BzO1xuICAgIHZhciBwcmV2U3RhdGU7XG4gICAgdmFyIHByZXZDb250ZXh0O1xuICAgIGlmIChoYXNDb21wb25lbnREaWRVcGRhdGUpIHtcbiAgICAgIHByZXZQcm9wcyA9IGluc3QucHJvcHM7XG4gICAgICBwcmV2U3RhdGUgPSBpbnN0LnN0YXRlO1xuICAgICAgcHJldkNvbnRleHQgPSBpbnN0LmNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKGluc3QuY29tcG9uZW50V2lsbFVwZGF0ZSkge1xuICAgICAgaW5zdC5jb21wb25lbnRXaWxsVXBkYXRlKG5leHRQcm9wcywgbmV4dFN0YXRlLCBuZXh0Q29udGV4dCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudEVsZW1lbnQgPSBuZXh0RWxlbWVudDtcbiAgICB0aGlzLl9jb250ZXh0ID0gdW5tYXNrZWRDb250ZXh0O1xuICAgIGluc3QucHJvcHMgPSBuZXh0UHJvcHM7XG4gICAgaW5zdC5zdGF0ZSA9IG5leHRTdGF0ZTtcbiAgICBpbnN0LmNvbnRleHQgPSBuZXh0Q29udGV4dDtcblxuICAgIHRoaXMuX3VwZGF0ZVJlbmRlcmVkQ29tcG9uZW50KHRyYW5zYWN0aW9uLCB1bm1hc2tlZENvbnRleHQpO1xuXG4gICAgaWYgKGhhc0NvbXBvbmVudERpZFVwZGF0ZSkge1xuICAgICAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShpbnN0LmNvbXBvbmVudERpZFVwZGF0ZS5iaW5kKGluc3QsIHByZXZQcm9wcywgcHJldlN0YXRlLCBwcmV2Q29udGV4dCksIGluc3QpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQ2FsbCB0aGUgY29tcG9uZW50J3MgYHJlbmRlcmAgbWV0aG9kIGFuZCB1cGRhdGUgdGhlIERPTSBhY2NvcmRpbmdseS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF91cGRhdGVSZW5kZXJlZENvbXBvbmVudDogZnVuY3Rpb24gKHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgdmFyIHByZXZDb21wb25lbnRJbnN0YW5jZSA9IHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50O1xuICAgIHZhciBwcmV2UmVuZGVyZWRFbGVtZW50ID0gcHJldkNvbXBvbmVudEluc3RhbmNlLl9jdXJyZW50RWxlbWVudDtcbiAgICB2YXIgbmV4dFJlbmRlcmVkRWxlbWVudCA9IHRoaXMuX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudCgpO1xuICAgIGlmIChzaG91bGRVcGRhdGVSZWFjdENvbXBvbmVudChwcmV2UmVuZGVyZWRFbGVtZW50LCBuZXh0UmVuZGVyZWRFbGVtZW50KSkge1xuICAgICAgUmVhY3RSZWNvbmNpbGVyLnJlY2VpdmVDb21wb25lbnQocHJldkNvbXBvbmVudEluc3RhbmNlLCBuZXh0UmVuZGVyZWRFbGVtZW50LCB0cmFuc2FjdGlvbiwgdGhpcy5fcHJvY2Vzc0NoaWxkQ29udGV4dChjb250ZXh0KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZXNlIHR3byBJRHMgYXJlIGFjdHVhbGx5IHRoZSBzYW1lISBCdXQgbm90aGluZyBzaG91bGQgcmVseSBvbiB0aGF0LlxuICAgICAgdmFyIHRoaXNJRCA9IHRoaXMuX3Jvb3ROb2RlSUQ7XG4gICAgICB2YXIgcHJldkNvbXBvbmVudElEID0gcHJldkNvbXBvbmVudEluc3RhbmNlLl9yb290Tm9kZUlEO1xuICAgICAgUmVhY3RSZWNvbmNpbGVyLnVubW91bnRDb21wb25lbnQocHJldkNvbXBvbmVudEluc3RhbmNlKTtcblxuICAgICAgdGhpcy5fcmVuZGVyZWRDb21wb25lbnQgPSB0aGlzLl9pbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50KG5leHRSZW5kZXJlZEVsZW1lbnQpO1xuICAgICAgdmFyIG5leHRNYXJrdXAgPSBSZWFjdFJlY29uY2lsZXIubW91bnRDb21wb25lbnQodGhpcy5fcmVuZGVyZWRDb21wb25lbnQsIHRoaXNJRCwgdHJhbnNhY3Rpb24sIHRoaXMuX3Byb2Nlc3NDaGlsZENvbnRleHQoY29udGV4dCkpO1xuICAgICAgdGhpcy5fcmVwbGFjZU5vZGVXaXRoTWFya3VwQnlJRChwcmV2Q29tcG9uZW50SUQsIG5leHRNYXJrdXApO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgX3JlcGxhY2VOb2RlV2l0aE1hcmt1cEJ5SUQ6IGZ1bmN0aW9uIChwcmV2Q29tcG9uZW50SUQsIG5leHRNYXJrdXApIHtcbiAgICBSZWFjdENvbXBvbmVudEVudmlyb25tZW50LnJlcGxhY2VOb2RlV2l0aE1hcmt1cEJ5SUQocHJldkNvbXBvbmVudElELCBuZXh0TWFya3VwKTtcbiAgfSxcblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudFdpdGhvdXRPd25lck9yQ29udGV4dDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBpbnN0ID0gdGhpcy5faW5zdGFuY2U7XG4gICAgdmFyIHJlbmRlcmVkQ29tcG9uZW50ID0gaW5zdC5yZW5kZXIoKTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgLy8gV2UgYWxsb3cgYXV0by1tb2NrcyB0byBwcm9jZWVkIGFzIGlmIHRoZXkncmUgcmV0dXJuaW5nIG51bGwuXG4gICAgICBpZiAodHlwZW9mIHJlbmRlcmVkQ29tcG9uZW50ID09PSAndW5kZWZpbmVkJyAmJiBpbnN0LnJlbmRlci5faXNNb2NrRnVuY3Rpb24pIHtcbiAgICAgICAgLy8gVGhpcyBpcyBwcm9iYWJseSBiYWQgcHJhY3RpY2UuIENvbnNpZGVyIHdhcm5pbmcgaGVyZSBhbmRcbiAgICAgICAgLy8gZGVwcmVjYXRpbmcgdGhpcyBjb252ZW5pZW5jZS5cbiAgICAgICAgcmVuZGVyZWRDb21wb25lbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZW5kZXJlZENvbXBvbmVudDtcbiAgfSxcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9yZW5kZXJWYWxpZGF0ZWRDb21wb25lbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVuZGVyZWRDb21wb25lbnQ7XG4gICAgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCA9IHRoaXM7XG4gICAgdHJ5IHtcbiAgICAgIHJlbmRlcmVkQ29tcG9uZW50ID0gdGhpcy5fcmVuZGVyVmFsaWRhdGVkQ29tcG9uZW50V2l0aG91dE93bmVyT3JDb250ZXh0KCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgPSBudWxsO1xuICAgIH1cbiAgICAhKFxuICAgIC8vIFRPRE86IEFuIGBpc1ZhbGlkTm9kZWAgZnVuY3Rpb24gd291bGQgcHJvYmFibHkgYmUgbW9yZSBhcHByb3ByaWF0ZVxuICAgIHJlbmRlcmVkQ29tcG9uZW50ID09PSBudWxsIHx8IHJlbmRlcmVkQ29tcG9uZW50ID09PSBmYWxzZSB8fCBSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQocmVuZGVyZWRDb21wb25lbnQpKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICclcy5yZW5kZXIoKTogQSB2YWxpZCBSZWFjdENvbXBvbmVudCBtdXN0IGJlIHJldHVybmVkLiBZb3UgbWF5IGhhdmUgJyArICdyZXR1cm5lZCB1bmRlZmluZWQsIGFuIGFycmF5IG9yIHNvbWUgb3RoZXIgaW52YWxpZCBvYmplY3QuJywgdGhpcy5nZXROYW1lKCkgfHwgJ1JlYWN0Q29tcG9zaXRlQ29tcG9uZW50JykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiByZW5kZXJlZENvbXBvbmVudDtcbiAgfSxcblxuICAvKipcbiAgICogTGF6aWx5IGFsbG9jYXRlcyB0aGUgcmVmcyBvYmplY3QgYW5kIHN0b3JlcyBgY29tcG9uZW50YCBhcyBgcmVmYC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlZiBSZWZlcmVuY2UgbmFtZS5cbiAgICogQHBhcmFtIHtjb21wb25lbnR9IGNvbXBvbmVudCBDb21wb25lbnQgdG8gc3RvcmUgYXMgYHJlZmAuXG4gICAqIEBmaW5hbFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgYXR0YWNoUmVmOiBmdW5jdGlvbiAocmVmLCBjb21wb25lbnQpIHtcbiAgICB2YXIgaW5zdCA9IHRoaXMuZ2V0UHVibGljSW5zdGFuY2UoKTtcbiAgICAhKGluc3QgIT0gbnVsbCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnU3RhdGVsZXNzIGZ1bmN0aW9uIGNvbXBvbmVudHMgY2Fubm90IGhhdmUgcmVmcy4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHB1YmxpY0NvbXBvbmVudEluc3RhbmNlID0gY29tcG9uZW50LmdldFB1YmxpY0luc3RhbmNlKCk7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gY29tcG9uZW50ICYmIGNvbXBvbmVudC5nZXROYW1lID8gY29tcG9uZW50LmdldE5hbWUoKSA6ICdhIGNvbXBvbmVudCc7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhwdWJsaWNDb21wb25lbnRJbnN0YW5jZSAhPSBudWxsLCAnU3RhdGVsZXNzIGZ1bmN0aW9uIGNvbXBvbmVudHMgY2Fubm90IGJlIGdpdmVuIHJlZnMgJyArICcoU2VlIHJlZiBcIiVzXCIgaW4gJXMgY3JlYXRlZCBieSAlcykuICcgKyAnQXR0ZW1wdHMgdG8gYWNjZXNzIHRoaXMgcmVmIHdpbGwgZmFpbC4nLCByZWYsIGNvbXBvbmVudE5hbWUsIHRoaXMuZ2V0TmFtZSgpKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIHJlZnMgPSBpbnN0LnJlZnMgPT09IGVtcHR5T2JqZWN0ID8gaW5zdC5yZWZzID0ge30gOiBpbnN0LnJlZnM7XG4gICAgcmVmc1tyZWZdID0gcHVibGljQ29tcG9uZW50SW5zdGFuY2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERldGFjaGVzIGEgcmVmZXJlbmNlIG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWYgTmFtZSB0byBkZXJlZmVyZW5jZS5cbiAgICogQGZpbmFsXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZXRhY2hSZWY6IGZ1bmN0aW9uIChyZWYpIHtcbiAgICB2YXIgcmVmcyA9IHRoaXMuZ2V0UHVibGljSW5zdGFuY2UoKS5yZWZzO1xuICAgIGRlbGV0ZSByZWZzW3JlZl07XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIHRleHQgZGVzY3JpcHRpb24gb2YgdGhlIGNvbXBvbmVudCB0aGF0IGNhbiBiZSB1c2VkIHRvIGlkZW50aWZ5IGl0XG4gICAqIGluIGVycm9yIG1lc3NhZ2VzLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBuYW1lIG9yIG51bGwuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZ2V0TmFtZTogZnVuY3Rpb24gKCkge1xuICAgIHZhciB0eXBlID0gdGhpcy5fY3VycmVudEVsZW1lbnQudHlwZTtcbiAgICB2YXIgY29uc3RydWN0b3IgPSB0aGlzLl9pbnN0YW5jZSAmJiB0aGlzLl9pbnN0YW5jZS5jb25zdHJ1Y3RvcjtcbiAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCBjb25zdHJ1Y3RvciAmJiBjb25zdHJ1Y3Rvci5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IubmFtZSB8fCBudWxsO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHB1YmxpY2x5IGFjY2Vzc2libGUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb21wb25lbnQgLSBpLmUuIHdoYXRcbiAgICogaXMgZXhwb3NlZCBieSByZWZzIGFuZCByZXR1cm5lZCBieSByZW5kZXIuIENhbiBiZSBudWxsIGZvciBzdGF0ZWxlc3NcbiAgICogY29tcG9uZW50cy5cbiAgICpcbiAgICogQHJldHVybiB7UmVhY3RDb21wb25lbnR9IHRoZSBwdWJsaWMgY29tcG9uZW50IGluc3RhbmNlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldFB1YmxpY0luc3RhbmNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGluc3QgPSB0aGlzLl9pbnN0YW5jZTtcbiAgICBpZiAoaW5zdCBpbnN0YW5jZW9mIFN0YXRlbGVzc0NvbXBvbmVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBpbnN0O1xuICB9LFxuXG4gIC8vIFN0dWJcbiAgX2luc3RhbnRpYXRlUmVhY3RDb21wb25lbnQ6IG51bGxcblxufTtcblxuUmVhY3RQZXJmLm1lYXN1cmVNZXRob2RzKFJlYWN0Q29tcG9zaXRlQ29tcG9uZW50TWl4aW4sICdSZWFjdENvbXBvc2l0ZUNvbXBvbmVudCcsIHtcbiAgbW91bnRDb21wb25lbnQ6ICdtb3VudENvbXBvbmVudCcsXG4gIHVwZGF0ZUNvbXBvbmVudDogJ3VwZGF0ZUNvbXBvbmVudCcsXG4gIF9yZW5kZXJWYWxpZGF0ZWRDb21wb25lbnQ6ICdfcmVuZGVyVmFsaWRhdGVkQ29tcG9uZW50J1xufSk7XG5cbnZhciBSZWFjdENvbXBvc2l0ZUNvbXBvbmVudCA9IHtcblxuICBNaXhpbjogUmVhY3RDb21wb3NpdGVDb21wb25lbnRNaXhpblxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0Q29tcG9zaXRlQ29tcG9uZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEN1cnJlbnRPd25lclxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBvd25lci5cbiAqXG4gKiBUaGUgY3VycmVudCBvd25lciBpcyB0aGUgY29tcG9uZW50IHdobyBzaG91bGQgb3duIGFueSBjb21wb25lbnRzIHRoYXQgYXJlXG4gKiBjdXJyZW50bHkgYmVpbmcgY29uc3RydWN0ZWQuXG4gKi9cbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IHtcblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqIEB0eXBlIHtSZWFjdENvbXBvbmVudH1cbiAgICovXG4gIGN1cnJlbnQ6IG51bGxcblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEN1cnJlbnRPd25lcjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RET01cbiAqL1xuXG4vKiBnbG9iYWxzIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0RE9NVGV4dENvbXBvbmVudCA9IHJlcXVpcmUoJy4vUmVhY3RET01UZXh0Q29tcG9uZW50Jyk7XG52YXIgUmVhY3REZWZhdWx0SW5qZWN0aW9uID0gcmVxdWlyZSgnLi9SZWFjdERlZmF1bHRJbmplY3Rpb24nKTtcbnZhciBSZWFjdEluc3RhbmNlSGFuZGxlcyA9IHJlcXVpcmUoJy4vUmVhY3RJbnN0YW5jZUhhbmRsZXMnKTtcbnZhciBSZWFjdE1vdW50ID0gcmVxdWlyZSgnLi9SZWFjdE1vdW50Jyk7XG52YXIgUmVhY3RQZXJmID0gcmVxdWlyZSgnLi9SZWFjdFBlcmYnKTtcbnZhciBSZWFjdFJlY29uY2lsZXIgPSByZXF1aXJlKCcuL1JlYWN0UmVjb25jaWxlcicpO1xudmFyIFJlYWN0VXBkYXRlcyA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVzJyk7XG52YXIgUmVhY3RWZXJzaW9uID0gcmVxdWlyZSgnLi9SZWFjdFZlcnNpb24nKTtcblxudmFyIGZpbmRET01Ob2RlID0gcmVxdWlyZSgnLi9maW5kRE9NTm9kZScpO1xudmFyIHJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyID0gcmVxdWlyZSgnLi9yZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcicpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cblJlYWN0RGVmYXVsdEluamVjdGlvbi5pbmplY3QoKTtcblxudmFyIHJlbmRlciA9IFJlYWN0UGVyZi5tZWFzdXJlKCdSZWFjdCcsICdyZW5kZXInLCBSZWFjdE1vdW50LnJlbmRlcik7XG5cbnZhciBSZWFjdCA9IHtcbiAgZmluZERPTU5vZGU6IGZpbmRET01Ob2RlLFxuICByZW5kZXI6IHJlbmRlcixcbiAgdW5tb3VudENvbXBvbmVudEF0Tm9kZTogUmVhY3RNb3VudC51bm1vdW50Q29tcG9uZW50QXROb2RlLFxuICB2ZXJzaW9uOiBSZWFjdFZlcnNpb24sXG5cbiAgLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4gIHVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzOiBSZWFjdFVwZGF0ZXMuYmF0Y2hlZFVwZGF0ZXMsXG4gIHVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyOiByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lclxufTtcblxuLy8gSW5qZWN0IHRoZSBydW50aW1lIGludG8gYSBkZXZ0b29scyBnbG9iYWwgaG9vayByZWdhcmRsZXNzIG9mIGJyb3dzZXIuXG4vLyBBbGxvd3MgZm9yIGRlYnVnZ2luZyB3aGVuIHRoZSBob29rIGlzIGluamVjdGVkIG9uIHRoZSBwYWdlLlxuLyogZXNsaW50LWVuYWJsZSBjYW1lbGNhc2UgKi9cbmlmICh0eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLmluamVjdCA9PT0gJ2Z1bmN0aW9uJykge1xuICBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18uaW5qZWN0KHtcbiAgICBDdXJyZW50T3duZXI6IFJlYWN0Q3VycmVudE93bmVyLFxuICAgIEluc3RhbmNlSGFuZGxlczogUmVhY3RJbnN0YW5jZUhhbmRsZXMsXG4gICAgTW91bnQ6IFJlYWN0TW91bnQsXG4gICAgUmVjb25jaWxlcjogUmVhY3RSZWNvbmNpbGVyLFxuICAgIFRleHRDb21wb25lbnQ6IFJlYWN0RE9NVGV4dENvbXBvbmVudFxuICB9KTtcbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgdmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnZmJqcy9saWIvRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcbiAgaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSAmJiB3aW5kb3cudG9wID09PSB3aW5kb3cuc2VsZikge1xuXG4gICAgLy8gRmlyc3QgY2hlY2sgaWYgZGV2dG9vbHMgaXMgbm90IGluc3RhbGxlZFxuICAgIGlmICh0eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fID09PSAndW5kZWZpbmVkJykge1xuICAgICAgLy8gSWYgd2UncmUgaW4gQ2hyb21lIG9yIEZpcmVmb3gsIHByb3ZpZGUgYSBkb3dubG9hZCBsaW5rIGlmIG5vdCBpbnN0YWxsZWQuXG4gICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdDaHJvbWUnKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpID09PSAtMSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSA+IC0xKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0Rvd25sb2FkIHRoZSBSZWFjdCBEZXZUb29scyBmb3IgYSBiZXR0ZXIgZGV2ZWxvcG1lbnQgZXhwZXJpZW5jZTogJyArICdodHRwczovL2ZiLm1lL3JlYWN0LWRldnRvb2xzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgd2UncmUgaW4gSUU4LCBjaGVjayB0byBzZWUgaWYgd2UgYXJlIGluIGNvbXBhdGliaWxpdHkgbW9kZSBhbmQgcHJvdmlkZVxuICAgIC8vIGluZm9ybWF0aW9uIG9uIHByZXZlbnRpbmcgY29tcGF0aWJpbGl0eSBtb2RlXG4gICAgdmFyIGllQ29tcGF0aWJpbGl0eU1vZGUgPSBkb2N1bWVudC5kb2N1bWVudE1vZGUgJiYgZG9jdW1lbnQuZG9jdW1lbnRNb2RlIDwgODtcblxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFpZUNvbXBhdGliaWxpdHlNb2RlLCAnSW50ZXJuZXQgRXhwbG9yZXIgaXMgcnVubmluZyBpbiBjb21wYXRpYmlsaXR5IG1vZGU7IHBsZWFzZSBhZGQgdGhlICcgKyAnZm9sbG93aW5nIHRhZyB0byB5b3VyIEhUTUwgdG8gcHJldmVudCB0aGlzIGZyb20gaGFwcGVuaW5nOiAnICsgJzxtZXRhIGh0dHAtZXF1aXY9XCJYLVVBLUNvbXBhdGlibGVcIiBjb250ZW50PVwiSUU9ZWRnZVwiIC8+JykgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgZXhwZWN0ZWRGZWF0dXJlcyA9IFtcbiAgICAvLyBzaGltc1xuICAgIEFycmF5LmlzQXJyYXksIEFycmF5LnByb3RvdHlwZS5ldmVyeSwgQXJyYXkucHJvdG90eXBlLmZvckVhY2gsIEFycmF5LnByb3RvdHlwZS5pbmRleE9mLCBBcnJheS5wcm90b3R5cGUubWFwLCBEYXRlLm5vdywgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQsIE9iamVjdC5rZXlzLCBTdHJpbmcucHJvdG90eXBlLnNwbGl0LCBTdHJpbmcucHJvdG90eXBlLnRyaW0sXG5cbiAgICAvLyBzaGFtc1xuICAgIE9iamVjdC5jcmVhdGUsIE9iamVjdC5mcmVlemVdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHBlY3RlZEZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIWV4cGVjdGVkRmVhdHVyZXNbaV0pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignT25lIG9yIG1vcmUgRVM1IHNoaW0vc2hhbXMgZXhwZWN0ZWQgYnkgUmVhY3QgYXJlIG5vdCBhdmFpbGFibGU6ICcgKyAnaHR0cHM6Ly9mYi5tZS9yZWFjdC13YXJuaW5nLXBvbHlmaWxscycpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RET01CdXR0b25cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBtb3VzZUxpc3RlbmVyTmFtZXMgPSB7XG4gIG9uQ2xpY2s6IHRydWUsXG4gIG9uRG91YmxlQ2xpY2s6IHRydWUsXG4gIG9uTW91c2VEb3duOiB0cnVlLFxuICBvbk1vdXNlTW92ZTogdHJ1ZSxcbiAgb25Nb3VzZVVwOiB0cnVlLFxuXG4gIG9uQ2xpY2tDYXB0dXJlOiB0cnVlLFxuICBvbkRvdWJsZUNsaWNrQ2FwdHVyZTogdHJ1ZSxcbiAgb25Nb3VzZURvd25DYXB0dXJlOiB0cnVlLFxuICBvbk1vdXNlTW92ZUNhcHR1cmU6IHRydWUsXG4gIG9uTW91c2VVcENhcHR1cmU6IHRydWVcbn07XG5cbi8qKlxuICogSW1wbGVtZW50cyBhIDxidXR0b24+IG5hdGl2ZSBjb21wb25lbnQgdGhhdCBkb2VzIG5vdCByZWNlaXZlIG1vdXNlIGV2ZW50c1xuICogd2hlbiBgZGlzYWJsZWRgIGlzIHNldC5cbiAqL1xudmFyIFJlYWN0RE9NQnV0dG9uID0ge1xuICBnZXROYXRpdmVQcm9wczogZnVuY3Rpb24gKGluc3QsIHByb3BzLCBjb250ZXh0KSB7XG4gICAgaWYgKCFwcm9wcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuIHByb3BzO1xuICAgIH1cblxuICAgIC8vIENvcHkgdGhlIHByb3BzLCBleGNlcHQgdGhlIG1vdXNlIGxpc3RlbmVyc1xuICAgIHZhciBuYXRpdmVQcm9wcyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgaWYgKHByb3BzLmhhc093blByb3BlcnR5KGtleSkgJiYgIW1vdXNlTGlzdGVuZXJOYW1lc1trZXldKSB7XG4gICAgICAgIG5hdGl2ZVByb3BzW2tleV0gPSBwcm9wc1trZXldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuYXRpdmVQcm9wcztcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdERPTUJ1dHRvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RET01Db21wb25lbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuLyogZ2xvYmFsIGhhc093blByb3BlcnR5OnRydWUgKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgQXV0b0ZvY3VzVXRpbHMgPSByZXF1aXJlKCcuL0F1dG9Gb2N1c1V0aWxzJyk7XG52YXIgQ1NTUHJvcGVydHlPcGVyYXRpb25zID0gcmVxdWlyZSgnLi9DU1NQcm9wZXJ0eU9wZXJhdGlvbnMnKTtcbnZhciBET01Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRE9NUHJvcGVydHknKTtcbnZhciBET01Qcm9wZXJ0eU9wZXJhdGlvbnMgPSByZXF1aXJlKCcuL0RPTVByb3BlcnR5T3BlcmF0aW9ucycpO1xudmFyIEV2ZW50Q29uc3RhbnRzID0gcmVxdWlyZSgnLi9FdmVudENvbnN0YW50cycpO1xudmFyIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyJyk7XG52YXIgUmVhY3RDb21wb25lbnRCcm93c2VyRW52aXJvbm1lbnQgPSByZXF1aXJlKCcuL1JlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50Jyk7XG52YXIgUmVhY3RET01CdXR0b24gPSByZXF1aXJlKCcuL1JlYWN0RE9NQnV0dG9uJyk7XG52YXIgUmVhY3RET01JbnB1dCA9IHJlcXVpcmUoJy4vUmVhY3RET01JbnB1dCcpO1xudmFyIFJlYWN0RE9NT3B0aW9uID0gcmVxdWlyZSgnLi9SZWFjdERPTU9wdGlvbicpO1xudmFyIFJlYWN0RE9NU2VsZWN0ID0gcmVxdWlyZSgnLi9SZWFjdERPTVNlbGVjdCcpO1xudmFyIFJlYWN0RE9NVGV4dGFyZWEgPSByZXF1aXJlKCcuL1JlYWN0RE9NVGV4dGFyZWEnKTtcbnZhciBSZWFjdE1vdW50ID0gcmVxdWlyZSgnLi9SZWFjdE1vdW50Jyk7XG52YXIgUmVhY3RNdWx0aUNoaWxkID0gcmVxdWlyZSgnLi9SZWFjdE11bHRpQ2hpbGQnKTtcbnZhciBSZWFjdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0UGVyZicpO1xudmFyIFJlYWN0VXBkYXRlUXVldWUgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlUXVldWUnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGNhbkRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9jYW5EZWZpbmVQcm9wZXJ0eScpO1xudmFyIGVzY2FwZVRleHRDb250ZW50Rm9yQnJvd3NlciA9IHJlcXVpcmUoJy4vZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyJyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIgaXNFdmVudFN1cHBvcnRlZCA9IHJlcXVpcmUoJy4vaXNFdmVudFN1cHBvcnRlZCcpO1xudmFyIGtleU9mID0gcmVxdWlyZSgnZmJqcy9saWIva2V5T2YnKTtcbnZhciBzZXRJbm5lckhUTUwgPSByZXF1aXJlKCcuL3NldElubmVySFRNTCcpO1xudmFyIHNldFRleHRDb250ZW50ID0gcmVxdWlyZSgnLi9zZXRUZXh0Q29udGVudCcpO1xudmFyIHNoYWxsb3dFcXVhbCA9IHJlcXVpcmUoJ2ZianMvbGliL3NoYWxsb3dFcXVhbCcpO1xudmFyIHZhbGlkYXRlRE9NTmVzdGluZyA9IHJlcXVpcmUoJy4vdmFsaWRhdGVET01OZXN0aW5nJyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxudmFyIGRlbGV0ZUxpc3RlbmVyID0gUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLmRlbGV0ZUxpc3RlbmVyO1xudmFyIGxpc3RlblRvID0gUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLmxpc3RlblRvO1xudmFyIHJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzID0gUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLnJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzO1xuXG4vLyBGb3IgcXVpY2tseSBtYXRjaGluZyBjaGlsZHJlbiB0eXBlLCB0byB0ZXN0IGlmIGNhbiBiZSB0cmVhdGVkIGFzIGNvbnRlbnQuXG52YXIgQ09OVEVOVF9UWVBFUyA9IHsgJ3N0cmluZyc6IHRydWUsICdudW1iZXInOiB0cnVlIH07XG5cbnZhciBDSElMRFJFTiA9IGtleU9mKHsgY2hpbGRyZW46IG51bGwgfSk7XG52YXIgU1RZTEUgPSBrZXlPZih7IHN0eWxlOiBudWxsIH0pO1xudmFyIEhUTUwgPSBrZXlPZih7IF9faHRtbDogbnVsbCB9KTtcblxudmFyIEVMRU1FTlRfTk9ERV9UWVBFID0gMTtcblxuZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKGludGVybmFsSW5zdGFuY2UpIHtcbiAgaWYgKGludGVybmFsSW5zdGFuY2UpIHtcbiAgICB2YXIgb3duZXIgPSBpbnRlcm5hbEluc3RhbmNlLl9jdXJyZW50RWxlbWVudC5fb3duZXIgfHwgbnVsbDtcbiAgICBpZiAob3duZXIpIHtcbiAgICAgIHZhciBuYW1lID0gb3duZXIuZ2V0TmFtZSgpO1xuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuICcgVGhpcyBET00gbm9kZSB3YXMgcmVuZGVyZWQgYnkgYCcgKyBuYW1lICsgJ2AuJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG52YXIgbGVnYWN5UHJvcHNEZXNjcmlwdG9yO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgbGVnYWN5UHJvcHNEZXNjcmlwdG9yID0ge1xuICAgIHByb3BzOiB7XG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5fcmVhY3RJbnRlcm5hbENvbXBvbmVudDtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdSZWFjdERPTUNvbXBvbmVudDogRG8gbm90IGFjY2VzcyAucHJvcHMgb2YgYSBET00gbm9kZTsgaW5zdGVhZCwgJyArICdyZWNyZWF0ZSB0aGUgcHJvcHMgYXMgYHJlbmRlcmAgZGlkIG9yaWdpbmFsbHkgb3IgcmVhZCB0aGUgRE9NICcgKyAncHJvcGVydGllcy9hdHRyaWJ1dGVzIGRpcmVjdGx5IGZyb20gdGhpcyBub2RlIChlLmcuLCAnICsgJ3RoaXMucmVmcy5ib3guY2xhc3NOYW1lKS4lcycsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShjb21wb25lbnQpKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudC5fY3VycmVudEVsZW1lbnQucHJvcHM7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBsZWdhY3lHZXRET01Ob2RlKCkge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLl9yZWFjdEludGVybmFsQ29tcG9uZW50O1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnUmVhY3RET01Db21wb25lbnQ6IERvIG5vdCBhY2Nlc3MgLmdldERPTU5vZGUoKSBvZiBhIERPTSBub2RlOyAnICsgJ2luc3RlYWQsIHVzZSB0aGUgbm9kZSBkaXJlY3RseS4lcycsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShjb21wb25lbnQpKSA6IHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gbGVnYWN5SXNNb3VudGVkKCkge1xuICB2YXIgY29tcG9uZW50ID0gdGhpcy5fcmVhY3RJbnRlcm5hbENvbXBvbmVudDtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ1JlYWN0RE9NQ29tcG9uZW50OiBEbyBub3QgYWNjZXNzIC5pc01vdW50ZWQoKSBvZiBhIERPTSBub2RlLiVzJywgZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKGNvbXBvbmVudCkpIDogdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiAhIWNvbXBvbmVudDtcbn1cblxuZnVuY3Rpb24gbGVnYWN5U2V0U3RhdGVFdGMoKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuX3JlYWN0SW50ZXJuYWxDb21wb25lbnQ7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdSZWFjdERPTUNvbXBvbmVudDogRG8gbm90IGFjY2VzcyAuc2V0U3RhdGUoKSwgLnJlcGxhY2VTdGF0ZSgpLCBvciAnICsgJy5mb3JjZVVwZGF0ZSgpIG9mIGEgRE9NIG5vZGUuIFRoaXMgaXMgYSBuby1vcC4lcycsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShjb21wb25lbnQpKSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBsZWdhY3lTZXRQcm9wcyhwYXJ0aWFsUHJvcHMsIGNhbGxiYWNrKSB7XG4gIHZhciBjb21wb25lbnQgPSB0aGlzLl9yZWFjdEludGVybmFsQ29tcG9uZW50O1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnUmVhY3RET01Db21wb25lbnQ6IERvIG5vdCBhY2Nlc3MgLnNldFByb3BzKCkgb2YgYSBET00gbm9kZS4gJyArICdJbnN0ZWFkLCBjYWxsIFJlYWN0RE9NLnJlbmRlciBhZ2FpbiBhdCB0aGUgdG9wIGxldmVsLiVzJywgZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKGNvbXBvbmVudCkpIDogdW5kZWZpbmVkO1xuICB9XG4gIGlmICghY29tcG9uZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIFJlYWN0VXBkYXRlUXVldWUuZW5xdWV1ZVNldFByb3BzSW50ZXJuYWwoY29tcG9uZW50LCBwYXJ0aWFsUHJvcHMpO1xuICBpZiAoY2FsbGJhY2spIHtcbiAgICBSZWFjdFVwZGF0ZVF1ZXVlLmVucXVldWVDYWxsYmFja0ludGVybmFsKGNvbXBvbmVudCwgY2FsbGJhY2spO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxlZ2FjeVJlcGxhY2VQcm9wcyhwYXJ0aWFsUHJvcHMsIGNhbGxiYWNrKSB7XG4gIHZhciBjb21wb25lbnQgPSB0aGlzLl9yZWFjdEludGVybmFsQ29tcG9uZW50O1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnUmVhY3RET01Db21wb25lbnQ6IERvIG5vdCBhY2Nlc3MgLnJlcGxhY2VQcm9wcygpIG9mIGEgRE9NIG5vZGUuICcgKyAnSW5zdGVhZCwgY2FsbCBSZWFjdERPTS5yZW5kZXIgYWdhaW4gYXQgdGhlIHRvcCBsZXZlbC4lcycsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShjb21wb25lbnQpKSA6IHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoIWNvbXBvbmVudCkge1xuICAgIHJldHVybjtcbiAgfVxuICBSZWFjdFVwZGF0ZVF1ZXVlLmVucXVldWVSZXBsYWNlUHJvcHNJbnRlcm5hbChjb21wb25lbnQsIHBhcnRpYWxQcm9wcyk7XG4gIGlmIChjYWxsYmFjaykge1xuICAgIFJlYWN0VXBkYXRlUXVldWUuZW5xdWV1ZUNhbGxiYWNrSW50ZXJuYWwoY29tcG9uZW50LCBjYWxsYmFjayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZnJpZW5kbHlTdHJpbmdpZnkob2JqKSB7XG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgIHJldHVybiAnWycgKyBvYmoubWFwKGZyaWVuZGx5U3RyaW5naWZ5KS5qb2luKCcsICcpICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcGFpcnMgPSBbXTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgICB2YXIga2V5RXNjYXBlZCA9IC9eW2EteiRfXVtcXHckX10qJC9pLnRlc3Qoa2V5KSA/IGtleSA6IEpTT04uc3RyaW5naWZ5KGtleSk7XG4gICAgICAgICAgcGFpcnMucHVzaChrZXlFc2NhcGVkICsgJzogJyArIGZyaWVuZGx5U3RyaW5naWZ5KG9ialtrZXldKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAneycgKyBwYWlycy5qb2luKCcsICcpICsgJ30nO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShvYmopO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gJ1tmdW5jdGlvbiBvYmplY3RdJztcbiAgfVxuICAvLyBEaWZmZXJzIGZyb20gSlNPTi5zdHJpbmdpZnkgaW4gdGhhdCB1bmRlZmluZWQgYmVjYXVzZXMgdW5kZWZpbmVkIGFuZCB0aGF0XG4gIC8vIGluZiBhbmQgbmFuIGRvbid0IGJlY29tZSBudWxsXG4gIHJldHVybiBTdHJpbmcob2JqKTtcbn1cblxudmFyIHN0eWxlTXV0YXRpb25XYXJuaW5nID0ge307XG5cbmZ1bmN0aW9uIGNoZWNrQW5kV2FybkZvck11dGF0ZWRTdHlsZShzdHlsZTEsIHN0eWxlMiwgY29tcG9uZW50KSB7XG4gIGlmIChzdHlsZTEgPT0gbnVsbCB8fCBzdHlsZTIgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoc2hhbGxvd0VxdWFsKHN0eWxlMSwgc3R5bGUyKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjb21wb25lbnROYW1lID0gY29tcG9uZW50Ll90YWc7XG4gIHZhciBvd25lciA9IGNvbXBvbmVudC5fY3VycmVudEVsZW1lbnQuX293bmVyO1xuICB2YXIgb3duZXJOYW1lO1xuICBpZiAob3duZXIpIHtcbiAgICBvd25lck5hbWUgPSBvd25lci5nZXROYW1lKCk7XG4gIH1cblxuICB2YXIgaGFzaCA9IG93bmVyTmFtZSArICd8JyArIGNvbXBvbmVudE5hbWU7XG5cbiAgaWYgKHN0eWxlTXV0YXRpb25XYXJuaW5nLmhhc093blByb3BlcnR5KGhhc2gpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3R5bGVNdXRhdGlvbldhcm5pbmdbaGFzaF0gPSB0cnVlO1xuXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnYCVzYCB3YXMgcGFzc2VkIGEgc3R5bGUgb2JqZWN0IHRoYXQgaGFzIHByZXZpb3VzbHkgYmVlbiBtdXRhdGVkLiAnICsgJ011dGF0aW5nIGBzdHlsZWAgaXMgZGVwcmVjYXRlZC4gQ29uc2lkZXIgY2xvbmluZyBpdCBiZWZvcmVoYW5kLiBDaGVjayAnICsgJ3RoZSBgcmVuZGVyYCAlcy4gUHJldmlvdXMgc3R5bGU6ICVzLiBNdXRhdGVkIHN0eWxlOiAlcy4nLCBjb21wb25lbnROYW1lLCBvd25lciA/ICdvZiBgJyArIG93bmVyTmFtZSArICdgJyA6ICd1c2luZyA8JyArIGNvbXBvbmVudE5hbWUgKyAnPicsIGZyaWVuZGx5U3RyaW5naWZ5KHN0eWxlMSksIGZyaWVuZGx5U3RyaW5naWZ5KHN0eWxlMikpIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb21wb25lbnRcbiAqIEBwYXJhbSB7P29iamVjdH0gcHJvcHNcbiAqL1xuZnVuY3Rpb24gYXNzZXJ0VmFsaWRQcm9wcyhjb21wb25lbnQsIHByb3BzKSB7XG4gIGlmICghcHJvcHMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gTm90ZSB0aGUgdXNlIG9mIGA9PWAgd2hpY2ggY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZC5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBpZiAodm9pZEVsZW1lbnRUYWdzW2NvbXBvbmVudC5fdGFnXSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcocHJvcHMuY2hpbGRyZW4gPT0gbnVsbCAmJiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCA9PSBudWxsLCAnJXMgaXMgYSB2b2lkIGVsZW1lbnQgdGFnIGFuZCBtdXN0IG5vdCBoYXZlIGBjaGlsZHJlbmAgb3IgJyArICd1c2UgYHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4lcycsIGNvbXBvbmVudC5fdGFnLCBjb21wb25lbnQuX2N1cnJlbnRFbGVtZW50Ll9vd25lciA/ICcgQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgJyArIGNvbXBvbmVudC5fY3VycmVudEVsZW1lbnQuX293bmVyLmdldE5hbWUoKSArICcuJyA6ICcnKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICAhKHByb3BzLmNoaWxkcmVuID09IG51bGwpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ0NhbiBvbmx5IHNldCBvbmUgb2YgYGNoaWxkcmVuYCBvciBgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxgLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAhKHR5cGVvZiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCA9PT0gJ29iamVjdCcgJiYgSFRNTCBpbiBwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnYHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYCBtdXN0IGJlIGluIHRoZSBmb3JtIGB7X19odG1sOiAuLi59YC4gJyArICdQbGVhc2UgdmlzaXQgaHR0cHM6Ly9mYi5tZS9yZWFjdC1pbnZhcmlhbnQtZGFuZ2Vyb3VzbHktc2V0LWlubmVyLWh0bWwgJyArICdmb3IgbW9yZSBpbmZvcm1hdGlvbi4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhwcm9wcy5pbm5lckhUTUwgPT0gbnVsbCwgJ0RpcmVjdGx5IHNldHRpbmcgcHJvcGVydHkgYGlubmVySFRNTGAgaXMgbm90IHBlcm1pdHRlZC4gJyArICdGb3IgbW9yZSBpbmZvcm1hdGlvbiwgbG9va3VwIGRvY3VtZW50YXRpb24gb24gYGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4nKSA6IHVuZGVmaW5lZDtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyghcHJvcHMuY29udGVudEVkaXRhYmxlIHx8IHByb3BzLmNoaWxkcmVuID09IG51bGwsICdBIGNvbXBvbmVudCBpcyBgY29udGVudEVkaXRhYmxlYCBhbmQgY29udGFpbnMgYGNoaWxkcmVuYCBtYW5hZ2VkIGJ5ICcgKyAnUmVhY3QuIEl0IGlzIG5vdyB5b3VyIHJlc3BvbnNpYmlsaXR5IHRvIGd1YXJhbnRlZSB0aGF0IG5vbmUgb2YgJyArICd0aG9zZSBub2RlcyBhcmUgdW5leHBlY3RlZGx5IG1vZGlmaWVkIG9yIGR1cGxpY2F0ZWQuIFRoaXMgaXMgJyArICdwcm9iYWJseSBub3QgaW50ZW50aW9uYWwuJykgOiB1bmRlZmluZWQ7XG4gIH1cbiAgIShwcm9wcy5zdHlsZSA9PSBudWxsIHx8IHR5cGVvZiBwcm9wcy5zdHlsZSA9PT0gJ29iamVjdCcpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1RoZSBgc3R5bGVgIHByb3AgZXhwZWN0cyBhIG1hcHBpbmcgZnJvbSBzdHlsZSBwcm9wZXJ0aWVzIHRvIHZhbHVlcywgJyArICdub3QgYSBzdHJpbmcuIEZvciBleGFtcGxlLCBzdHlsZT17e21hcmdpblJpZ2h0OiBzcGFjaW5nICsgXFwnZW1cXCd9fSB3aGVuICcgKyAndXNpbmcgSlNYLiVzJywgZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKGNvbXBvbmVudCkpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZW5xdWV1ZVB1dExpc3RlbmVyKGlkLCByZWdpc3RyYXRpb25OYW1lLCBsaXN0ZW5lciwgdHJhbnNhY3Rpb24pIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBJRTggaGFzIG5vIEFQSSBmb3IgZXZlbnQgY2FwdHVyaW5nIGFuZCB0aGUgYG9uU2Nyb2xsYCBldmVudCBkb2Vzbid0XG4gICAgLy8gYnViYmxlLlxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHJlZ2lzdHJhdGlvbk5hbWUgIT09ICdvblNjcm9sbCcgfHwgaXNFdmVudFN1cHBvcnRlZCgnc2Nyb2xsJywgdHJ1ZSksICdUaGlzIGJyb3dzZXIgZG9lc25cXCd0IHN1cHBvcnQgdGhlIGBvblNjcm9sbGAgZXZlbnQnKSA6IHVuZGVmaW5lZDtcbiAgfVxuICB2YXIgY29udGFpbmVyID0gUmVhY3RNb3VudC5maW5kUmVhY3RDb250YWluZXJGb3JJRChpZCk7XG4gIGlmIChjb250YWluZXIpIHtcbiAgICB2YXIgZG9jID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREVfVFlQRSA/IGNvbnRhaW5lci5vd25lckRvY3VtZW50IDogY29udGFpbmVyO1xuICAgIGxpc3RlblRvKHJlZ2lzdHJhdGlvbk5hbWUsIGRvYyk7XG4gIH1cbiAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShwdXRMaXN0ZW5lciwge1xuICAgIGlkOiBpZCxcbiAgICByZWdpc3RyYXRpb25OYW1lOiByZWdpc3RyYXRpb25OYW1lLFxuICAgIGxpc3RlbmVyOiBsaXN0ZW5lclxuICB9KTtcbn1cblxuZnVuY3Rpb24gcHV0TGlzdGVuZXIoKSB7XG4gIHZhciBsaXN0ZW5lclRvUHV0ID0gdGhpcztcbiAgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLnB1dExpc3RlbmVyKGxpc3RlbmVyVG9QdXQuaWQsIGxpc3RlbmVyVG9QdXQucmVnaXN0cmF0aW9uTmFtZSwgbGlzdGVuZXJUb1B1dC5saXN0ZW5lcik7XG59XG5cbi8vIFRoZXJlIGFyZSBzbyBtYW55IG1lZGlhIGV2ZW50cywgaXQgbWFrZXMgc2Vuc2UgdG8ganVzdFxuLy8gbWFpbnRhaW4gYSBsaXN0IHJhdGhlciB0aGFuIGNyZWF0ZSBhIGB0cmFwQnViYmxlZEV2ZW50YCBmb3IgZWFjaFxudmFyIG1lZGlhRXZlbnRzID0ge1xuICB0b3BBYm9ydDogJ2Fib3J0JyxcbiAgdG9wQ2FuUGxheTogJ2NhbnBsYXknLFxuICB0b3BDYW5QbGF5VGhyb3VnaDogJ2NhbnBsYXl0aHJvdWdoJyxcbiAgdG9wRHVyYXRpb25DaGFuZ2U6ICdkdXJhdGlvbmNoYW5nZScsXG4gIHRvcEVtcHRpZWQ6ICdlbXB0aWVkJyxcbiAgdG9wRW5jcnlwdGVkOiAnZW5jcnlwdGVkJyxcbiAgdG9wRW5kZWQ6ICdlbmRlZCcsXG4gIHRvcEVycm9yOiAnZXJyb3InLFxuICB0b3BMb2FkZWREYXRhOiAnbG9hZGVkZGF0YScsXG4gIHRvcExvYWRlZE1ldGFkYXRhOiAnbG9hZGVkbWV0YWRhdGEnLFxuICB0b3BMb2FkU3RhcnQ6ICdsb2Fkc3RhcnQnLFxuICB0b3BQYXVzZTogJ3BhdXNlJyxcbiAgdG9wUGxheTogJ3BsYXknLFxuICB0b3BQbGF5aW5nOiAncGxheWluZycsXG4gIHRvcFByb2dyZXNzOiAncHJvZ3Jlc3MnLFxuICB0b3BSYXRlQ2hhbmdlOiAncmF0ZWNoYW5nZScsXG4gIHRvcFNlZWtlZDogJ3NlZWtlZCcsXG4gIHRvcFNlZWtpbmc6ICdzZWVraW5nJyxcbiAgdG9wU3RhbGxlZDogJ3N0YWxsZWQnLFxuICB0b3BTdXNwZW5kOiAnc3VzcGVuZCcsXG4gIHRvcFRpbWVVcGRhdGU6ICd0aW1ldXBkYXRlJyxcbiAgdG9wVm9sdW1lQ2hhbmdlOiAndm9sdW1lY2hhbmdlJyxcbiAgdG9wV2FpdGluZzogJ3dhaXRpbmcnXG59O1xuXG5mdW5jdGlvbiB0cmFwQnViYmxlZEV2ZW50c0xvY2FsKCkge1xuICB2YXIgaW5zdCA9IHRoaXM7XG4gIC8vIElmIGEgY29tcG9uZW50IHJlbmRlcnMgdG8gbnVsbCBvciBpZiBhbm90aGVyIGNvbXBvbmVudCBmYXRhbHMgYW5kIGNhdXNlc1xuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHRyZWUgdG8gYmUgY29ycnVwdGVkLCBgbm9kZWAgaGVyZSBjYW4gYmUgbnVsbC5cbiAgIWluc3QuX3Jvb3ROb2RlSUQgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnTXVzdCBiZSBtb3VudGVkIHRvIHRyYXAgZXZlbnRzJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICB2YXIgbm9kZSA9IFJlYWN0TW91bnQuZ2V0Tm9kZShpbnN0Ll9yb290Tm9kZUlEKTtcbiAgIW5vZGUgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAndHJhcEJ1YmJsZWRFdmVudCguLi4pOiBSZXF1aXJlcyBub2RlIHRvIGJlIHJlbmRlcmVkLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICBzd2l0Y2ggKGluc3QuX3RhZykge1xuICAgIGNhc2UgJ2lmcmFtZSc6XG4gICAgICBpbnN0Ll93cmFwcGVyU3RhdGUubGlzdGVuZXJzID0gW1JlYWN0QnJvd3NlckV2ZW50RW1pdHRlci50cmFwQnViYmxlZEV2ZW50KEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXMudG9wTG9hZCwgJ2xvYWQnLCBub2RlKV07XG4gICAgICBicmVhaztcbiAgICBjYXNlICd2aWRlbyc6XG4gICAgY2FzZSAnYXVkaW8nOlxuXG4gICAgICBpbnN0Ll93cmFwcGVyU3RhdGUubGlzdGVuZXJzID0gW107XG4gICAgICAvLyBjcmVhdGUgbGlzdGVuZXIgZm9yIGVhY2ggbWVkaWEgZXZlbnRcbiAgICAgIGZvciAodmFyIGV2ZW50IGluIG1lZGlhRXZlbnRzKSB7XG4gICAgICAgIGlmIChtZWRpYUV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICBpbnN0Ll93cmFwcGVyU3RhdGUubGlzdGVuZXJzLnB1c2goUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLnRyYXBCdWJibGVkRXZlbnQoRXZlbnRDb25zdGFudHMudG9wTGV2ZWxUeXBlc1tldmVudF0sIG1lZGlhRXZlbnRzW2V2ZW50XSwgbm9kZSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2ltZyc6XG4gICAgICBpbnN0Ll93cmFwcGVyU3RhdGUubGlzdGVuZXJzID0gW1JlYWN0QnJvd3NlckV2ZW50RW1pdHRlci50cmFwQnViYmxlZEV2ZW50KEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXMudG9wRXJyb3IsICdlcnJvcicsIG5vZGUpLCBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIudHJhcEJ1YmJsZWRFdmVudChFdmVudENvbnN0YW50cy50b3BMZXZlbFR5cGVzLnRvcExvYWQsICdsb2FkJywgbm9kZSldO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZm9ybSc6XG4gICAgICBpbnN0Ll93cmFwcGVyU3RhdGUubGlzdGVuZXJzID0gW1JlYWN0QnJvd3NlckV2ZW50RW1pdHRlci50cmFwQnViYmxlZEV2ZW50KEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXMudG9wUmVzZXQsICdyZXNldCcsIG5vZGUpLCBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIudHJhcEJ1YmJsZWRFdmVudChFdmVudENvbnN0YW50cy50b3BMZXZlbFR5cGVzLnRvcFN1Ym1pdCwgJ3N1Ym1pdCcsIG5vZGUpXTtcbiAgICAgIGJyZWFrO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50UmVhZHlJbnB1dFdyYXBwZXIoKSB7XG4gIFJlYWN0RE9NSW5wdXQubW91bnRSZWFkeVdyYXBwZXIodGhpcyk7XG59XG5cbmZ1bmN0aW9uIHBvc3RVcGRhdGVTZWxlY3RXcmFwcGVyKCkge1xuICBSZWFjdERPTVNlbGVjdC5wb3N0VXBkYXRlV3JhcHBlcih0aGlzKTtcbn1cblxuLy8gRm9yIEhUTUwsIGNlcnRhaW4gdGFncyBzaG91bGQgb21pdCB0aGVpciBjbG9zZSB0YWcuIFdlIGtlZXAgYSB3aGl0ZWxpc3QgZm9yXG4vLyB0aG9zZSBzcGVjaWFsIGNhc2VkIHRhZ3MuXG5cbnZhciBvbWl0dGVkQ2xvc2VUYWdzID0ge1xuICAnYXJlYSc6IHRydWUsXG4gICdiYXNlJzogdHJ1ZSxcbiAgJ2JyJzogdHJ1ZSxcbiAgJ2NvbCc6IHRydWUsXG4gICdlbWJlZCc6IHRydWUsXG4gICdocic6IHRydWUsXG4gICdpbWcnOiB0cnVlLFxuICAnaW5wdXQnOiB0cnVlLFxuICAna2V5Z2VuJzogdHJ1ZSxcbiAgJ2xpbmsnOiB0cnVlLFxuICAnbWV0YSc6IHRydWUsXG4gICdwYXJhbSc6IHRydWUsXG4gICdzb3VyY2UnOiB0cnVlLFxuICAndHJhY2snOiB0cnVlLFxuICAnd2JyJzogdHJ1ZVxufTtcblxuLy8gTk9URTogbWVudWl0ZW0ncyBjbG9zZSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQsIGJ1dCB0aGF0IGNhdXNlcyBwcm9ibGVtcy5cbnZhciBuZXdsaW5lRWF0aW5nVGFncyA9IHtcbiAgJ2xpc3RpbmcnOiB0cnVlLFxuICAncHJlJzogdHJ1ZSxcbiAgJ3RleHRhcmVhJzogdHJ1ZVxufTtcblxuLy8gRm9yIEhUTUwsIGNlcnRhaW4gdGFncyBjYW5ub3QgaGF2ZSBjaGlsZHJlbi4gVGhpcyBoYXMgdGhlIHNhbWUgcHVycG9zZSBhc1xuLy8gYG9taXR0ZWRDbG9zZVRhZ3NgIGV4Y2VwdCB0aGF0IGBtZW51aXRlbWAgc2hvdWxkIHN0aWxsIGhhdmUgaXRzIGNsb3NpbmcgdGFnLlxuXG52YXIgdm9pZEVsZW1lbnRUYWdzID0gYXNzaWduKHtcbiAgJ21lbnVpdGVtJzogdHJ1ZVxufSwgb21pdHRlZENsb3NlVGFncyk7XG5cbi8vIFdlIGFjY2VwdCBhbnkgdGFnIHRvIGJlIHJlbmRlcmVkIGJ1dCBzaW5jZSB0aGlzIGdldHMgaW5qZWN0ZWQgaW50byBhcmJpdHJhcnlcbi8vIEhUTUwsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQgaXQncyBhIHNhZmUgdGFnLlxuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLXhtbC8jTlQtTmFtZVxuXG52YXIgVkFMSURfVEFHX1JFR0VYID0gL15bYS16QS1aXVthLXpBLVo6X1xcLlxcLVxcZF0qJC87IC8vIFNpbXBsaWZpZWQgc3Vic2V0XG52YXIgdmFsaWRhdGVkVGFnQ2FjaGUgPSB7fTtcbnZhciBoYXNPd25Qcm9wZXJ0eSA9ICh7fSkuaGFzT3duUHJvcGVydHk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlRGFuZ2Vyb3VzVGFnKHRhZykge1xuICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwodmFsaWRhdGVkVGFnQ2FjaGUsIHRhZykpIHtcbiAgICAhVkFMSURfVEFHX1JFR0VYLnRlc3QodGFnKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdJbnZhbGlkIHRhZzogJXMnLCB0YWcpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICB2YWxpZGF0ZWRUYWdDYWNoZVt0YWddID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQ2hpbGRDb250ZXh0RGV2KGNvbnRleHQsIGluc3QpIHtcbiAgLy8gUGFzcyBkb3duIG91ciB0YWcgbmFtZSB0byBjaGlsZCBjb21wb25lbnRzIGZvciB2YWxpZGF0aW9uIHB1cnBvc2VzXG4gIGNvbnRleHQgPSBhc3NpZ24oe30sIGNvbnRleHQpO1xuICB2YXIgaW5mbyA9IGNvbnRleHRbdmFsaWRhdGVET01OZXN0aW5nLmFuY2VzdG9ySW5mb0NvbnRleHRLZXldO1xuICBjb250ZXh0W3ZhbGlkYXRlRE9NTmVzdGluZy5hbmNlc3RvckluZm9Db250ZXh0S2V5XSA9IHZhbGlkYXRlRE9NTmVzdGluZy51cGRhdGVkQW5jZXN0b3JJbmZvKGluZm8sIGluc3QuX3RhZywgaW5zdCk7XG4gIHJldHVybiBjb250ZXh0O1xufVxuXG5mdW5jdGlvbiBpc0N1c3RvbUNvbXBvbmVudCh0YWdOYW1lLCBwcm9wcykge1xuICByZXR1cm4gdGFnTmFtZS5pbmRleE9mKCctJykgPj0gMCB8fCBwcm9wcy5pcyAhPSBudWxsO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgUmVhY3QgY2xhc3MgdGhhdCBpcyBpZGVtcG90ZW50IGFuZCBjYXBhYmxlIG9mIGNvbnRhaW5pbmcgb3RoZXJcbiAqIFJlYWN0IGNvbXBvbmVudHMuIEl0IGFjY2VwdHMgZXZlbnQgbGlzdGVuZXJzIGFuZCBET00gcHJvcGVydGllcyB0aGF0IGFyZVxuICogdmFsaWQgYWNjb3JkaW5nIHRvIGBET01Qcm9wZXJ0eWAuXG4gKlxuICogIC0gRXZlbnQgbGlzdGVuZXJzOiBgb25DbGlja2AsIGBvbk1vdXNlRG93bmAsIGV0Yy5cbiAqICAtIERPTSBwcm9wZXJ0aWVzOiBgY2xhc3NOYW1lYCwgYG5hbWVgLCBgdGl0bGVgLCBldGMuXG4gKlxuICogVGhlIGBzdHlsZWAgcHJvcGVydHkgZnVuY3Rpb25zIGRpZmZlcmVudGx5IGZyb20gdGhlIERPTSBBUEkuIEl0IGFjY2VwdHMgYW5cbiAqIG9iamVjdCBtYXBwaW5nIG9mIHN0eWxlIHByb3BlcnRpZXMgdG8gdmFsdWVzLlxuICpcbiAqIEBjb25zdHJ1Y3RvciBSZWFjdERPTUNvbXBvbmVudFxuICogQGV4dGVuZHMgUmVhY3RNdWx0aUNoaWxkXG4gKi9cbmZ1bmN0aW9uIFJlYWN0RE9NQ29tcG9uZW50KHRhZykge1xuICB2YWxpZGF0ZURhbmdlcm91c1RhZyh0YWcpO1xuICB0aGlzLl90YWcgPSB0YWcudG9Mb3dlckNhc2UoKTtcbiAgdGhpcy5fcmVuZGVyZWRDaGlsZHJlbiA9IG51bGw7XG4gIHRoaXMuX3ByZXZpb3VzU3R5bGUgPSBudWxsO1xuICB0aGlzLl9wcmV2aW91c1N0eWxlQ29weSA9IG51bGw7XG4gIHRoaXMuX3Jvb3ROb2RlSUQgPSBudWxsO1xuICB0aGlzLl93cmFwcGVyU3RhdGUgPSBudWxsO1xuICB0aGlzLl90b3BMZXZlbFdyYXBwZXIgPSBudWxsO1xuICB0aGlzLl9ub2RlV2l0aExlZ2FjeVByb3BlcnRpZXMgPSBudWxsO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHRoaXMuX3VucHJvY2Vzc2VkQ29udGV4dERldiA9IG51bGw7XG4gICAgdGhpcy5fcHJvY2Vzc2VkQ29udGV4dERldiA9IG51bGw7XG4gIH1cbn1cblxuUmVhY3RET01Db21wb25lbnQuZGlzcGxheU5hbWUgPSAnUmVhY3RET01Db21wb25lbnQnO1xuXG5SZWFjdERPTUNvbXBvbmVudC5NaXhpbiA9IHtcblxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgdGhpcy5fY3VycmVudEVsZW1lbnQgPSBlbGVtZW50O1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgcm9vdCB0YWcgbWFya3VwIHRoZW4gcmVjdXJzZXMuIFRoaXMgbWV0aG9kIGhhcyBzaWRlIGVmZmVjdHMgYW5kXG4gICAqIGlzIG5vdCBpZGVtcG90ZW50LlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb3RJRCBUaGUgcm9vdCBET00gSUQgZm9yIHRoaXMgbm9kZS5cbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0XG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbXB1dGVkIG1hcmt1cC5cbiAgICovXG4gIG1vdW50Q29tcG9uZW50OiBmdW5jdGlvbiAocm9vdElELCB0cmFuc2FjdGlvbiwgY29udGV4dCkge1xuICAgIHRoaXMuX3Jvb3ROb2RlSUQgPSByb290SUQ7XG5cbiAgICB2YXIgcHJvcHMgPSB0aGlzLl9jdXJyZW50RWxlbWVudC5wcm9wcztcblxuICAgIHN3aXRjaCAodGhpcy5fdGFnKSB7XG4gICAgICBjYXNlICdpZnJhbWUnOlxuICAgICAgY2FzZSAnaW1nJzpcbiAgICAgIGNhc2UgJ2Zvcm0nOlxuICAgICAgY2FzZSAndmlkZW8nOlxuICAgICAgY2FzZSAnYXVkaW8nOlxuICAgICAgICB0aGlzLl93cmFwcGVyU3RhdGUgPSB7XG4gICAgICAgICAgbGlzdGVuZXJzOiBudWxsXG4gICAgICAgIH07XG4gICAgICAgIHRyYW5zYWN0aW9uLmdldFJlYWN0TW91bnRSZWFkeSgpLmVucXVldWUodHJhcEJ1YmJsZWRFdmVudHNMb2NhbCwgdGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgcHJvcHMgPSBSZWFjdERPTUJ1dHRvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5wdXQnOlxuICAgICAgICBSZWFjdERPTUlucHV0Lm1vdW50V3JhcHBlcih0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHByb3BzID0gUmVhY3RET01JbnB1dC5nZXROYXRpdmVQcm9wcyh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgICAgUmVhY3RET01PcHRpb24ubW91bnRXcmFwcGVyKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgcHJvcHMgPSBSZWFjdERPTU9wdGlvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgUmVhY3RET01TZWxlY3QubW91bnRXcmFwcGVyKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgcHJvcHMgPSBSZWFjdERPTVNlbGVjdC5nZXROYXRpdmVQcm9wcyh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIGNvbnRleHQgPSBSZWFjdERPTVNlbGVjdC5wcm9jZXNzQ2hpbGRDb250ZXh0KHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICAgIFJlYWN0RE9NVGV4dGFyZWEubW91bnRXcmFwcGVyKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgcHJvcHMgPSBSZWFjdERPTVRleHRhcmVhLmdldE5hdGl2ZVByb3BzKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgYXNzZXJ0VmFsaWRQcm9wcyh0aGlzLCBwcm9wcyk7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmIChjb250ZXh0W3ZhbGlkYXRlRE9NTmVzdGluZy5hbmNlc3RvckluZm9Db250ZXh0S2V5XSkge1xuICAgICAgICB2YWxpZGF0ZURPTU5lc3RpbmcodGhpcy5fdGFnLCB0aGlzLCBjb250ZXh0W3ZhbGlkYXRlRE9NTmVzdGluZy5hbmNlc3RvckluZm9Db250ZXh0S2V5XSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHRoaXMuX3VucHJvY2Vzc2VkQ29udGV4dERldiA9IGNvbnRleHQ7XG4gICAgICB0aGlzLl9wcm9jZXNzZWRDb250ZXh0RGV2ID0gcHJvY2Vzc0NoaWxkQ29udGV4dERldihjb250ZXh0LCB0aGlzKTtcbiAgICAgIGNvbnRleHQgPSB0aGlzLl9wcm9jZXNzZWRDb250ZXh0RGV2O1xuICAgIH1cblxuICAgIHZhciBtb3VudEltYWdlO1xuICAgIGlmICh0cmFuc2FjdGlvbi51c2VDcmVhdGVFbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXJEb2N1bWVudCA9IGNvbnRleHRbUmVhY3RNb3VudC5vd25lckRvY3VtZW50Q29udGV4dEtleV07XG4gICAgICB2YXIgZWwgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGhpcy5fY3VycmVudEVsZW1lbnQudHlwZSk7XG4gICAgICBET01Qcm9wZXJ0eU9wZXJhdGlvbnMuc2V0QXR0cmlidXRlRm9ySUQoZWwsIHRoaXMuX3Jvb3ROb2RlSUQpO1xuICAgICAgLy8gUG9wdWxhdGUgbm9kZSBjYWNoZVxuICAgICAgUmVhY3RNb3VudC5nZXRJRChlbCk7XG4gICAgICB0aGlzLl91cGRhdGVET01Qcm9wZXJ0aWVzKHt9LCBwcm9wcywgdHJhbnNhY3Rpb24sIGVsKTtcbiAgICAgIHRoaXMuX2NyZWF0ZUluaXRpYWxDaGlsZHJlbih0cmFuc2FjdGlvbiwgcHJvcHMsIGNvbnRleHQsIGVsKTtcbiAgICAgIG1vdW50SW1hZ2UgPSBlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHRhZ09wZW4gPSB0aGlzLl9jcmVhdGVPcGVuVGFnTWFya3VwQW5kUHV0TGlzdGVuZXJzKHRyYW5zYWN0aW9uLCBwcm9wcyk7XG4gICAgICB2YXIgdGFnQ29udGVudCA9IHRoaXMuX2NyZWF0ZUNvbnRlbnRNYXJrdXAodHJhbnNhY3Rpb24sIHByb3BzLCBjb250ZXh0KTtcbiAgICAgIGlmICghdGFnQ29udGVudCAmJiBvbWl0dGVkQ2xvc2VUYWdzW3RoaXMuX3RhZ10pIHtcbiAgICAgICAgbW91bnRJbWFnZSA9IHRhZ09wZW4gKyAnLz4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbW91bnRJbWFnZSA9IHRhZ09wZW4gKyAnPicgKyB0YWdDb250ZW50ICsgJzwvJyArIHRoaXMuX2N1cnJlbnRFbGVtZW50LnR5cGUgKyAnPic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl90YWcpIHtcbiAgICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgICAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShtb3VudFJlYWR5SW5wdXRXcmFwcGVyLCB0aGlzKTtcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgICBpZiAocHJvcHMuYXV0b0ZvY3VzKSB7XG4gICAgICAgICAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShBdXRvRm9jdXNVdGlscy5mb2N1c0RPTUNvbXBvbmVudCwgdGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vdW50SW1hZ2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgbWFya3VwIGZvciB0aGUgb3BlbiB0YWcgYW5kIGFsbCBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBoYXMgc2lkZSBlZmZlY3RzIGJlY2F1c2UgZXZlbnRzIGdldCByZWdpc3RlcmVkLlxuICAgKlxuICAgKiBJdGVyYXRpbmcgb3ZlciBvYmplY3QgcHJvcGVydGllcyBpcyBmYXN0ZXIgdGhhbiBpdGVyYXRpbmcgb3ZlciBhcnJheXMuXG4gICAqIEBzZWUgaHR0cDovL2pzcGVyZi5jb20vb2JqLXZzLWFyci1pdGVyYXRpb25cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwcm9wc1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9IE1hcmt1cCBvZiBvcGVuaW5nIHRhZy5cbiAgICovXG4gIF9jcmVhdGVPcGVuVGFnTWFya3VwQW5kUHV0TGlzdGVuZXJzOiBmdW5jdGlvbiAodHJhbnNhY3Rpb24sIHByb3BzKSB7XG4gICAgdmFyIHJldCA9ICc8JyArIHRoaXMuX2N1cnJlbnRFbGVtZW50LnR5cGU7XG5cbiAgICBmb3IgKHZhciBwcm9wS2V5IGluIHByb3BzKSB7XG4gICAgICBpZiAoIXByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BLZXldO1xuICAgICAgaWYgKHByb3BWYWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICAgIGlmIChwcm9wVmFsdWUpIHtcbiAgICAgICAgICBlbnF1ZXVlUHV0TGlzdGVuZXIodGhpcy5fcm9vdE5vZGVJRCwgcHJvcEtleSwgcHJvcFZhbHVlLCB0cmFuc2FjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAgICAgIGlmIChwcm9wVmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgICAgIC8vIFNlZSBgX3VwZGF0ZURPTVByb3BlcnRpZXNgLiBzdHlsZSBibG9ja1xuICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c1N0eWxlID0gcHJvcFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJvcFZhbHVlID0gdGhpcy5fcHJldmlvdXNTdHlsZUNvcHkgPSBhc3NpZ24oe30sIHByb3BzLnN0eWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJvcFZhbHVlID0gQ1NTUHJvcGVydHlPcGVyYXRpb25zLmNyZWF0ZU1hcmt1cEZvclN0eWxlcyhwcm9wVmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXJrdXAgPSBudWxsO1xuICAgICAgICBpZiAodGhpcy5fdGFnICE9IG51bGwgJiYgaXNDdXN0b21Db21wb25lbnQodGhpcy5fdGFnLCBwcm9wcykpIHtcbiAgICAgICAgICBpZiAocHJvcEtleSAhPT0gQ0hJTERSRU4pIHtcbiAgICAgICAgICAgIG1hcmt1cCA9IERPTVByb3BlcnR5T3BlcmF0aW9ucy5jcmVhdGVNYXJrdXBGb3JDdXN0b21BdHRyaWJ1dGUocHJvcEtleSwgcHJvcFZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWFya3VwID0gRE9NUHJvcGVydHlPcGVyYXRpb25zLmNyZWF0ZU1hcmt1cEZvclByb3BlcnR5KHByb3BLZXksIHByb3BWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hcmt1cCkge1xuICAgICAgICAgIHJldCArPSAnICcgKyBtYXJrdXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGb3Igc3RhdGljIHBhZ2VzLCBubyBuZWVkIHRvIHB1dCBSZWFjdCBJRCBhbmQgY2hlY2tzdW0uIFNhdmVzIGxvdHMgb2ZcbiAgICAvLyBieXRlcy5cbiAgICBpZiAodHJhbnNhY3Rpb24ucmVuZGVyVG9TdGF0aWNNYXJrdXApIHtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hcmt1cEZvcklEID0gRE9NUHJvcGVydHlPcGVyYXRpb25zLmNyZWF0ZU1hcmt1cEZvcklEKHRoaXMuX3Jvb3ROb2RlSUQpO1xuICAgIHJldHVybiByZXQgKyAnICcgKyBtYXJrdXBGb3JJRDtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBtYXJrdXAgZm9yIHRoZSBjb250ZW50IGJldHdlZW4gdGhlIHRhZ3MuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbnxSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gcHJvcHNcbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAgICogQHJldHVybiB7c3RyaW5nfSBDb250ZW50IG1hcmt1cC5cbiAgICovXG4gIF9jcmVhdGVDb250ZW50TWFya3VwOiBmdW5jdGlvbiAodHJhbnNhY3Rpb24sIHByb3BzLCBjb250ZXh0KSB7XG4gICAgdmFyIHJldCA9ICcnO1xuXG4gICAgLy8gSW50ZW50aW9uYWwgdXNlIG9mICE9IHRvIGF2b2lkIGNhdGNoaW5nIHplcm8vZmFsc2UuXG4gICAgdmFyIGlubmVySFRNTCA9IHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MO1xuICAgIGlmIChpbm5lckhUTUwgIT0gbnVsbCkge1xuICAgICAgaWYgKGlubmVySFRNTC5fX2h0bWwgIT0gbnVsbCkge1xuICAgICAgICByZXQgPSBpbm5lckhUTUwuX19odG1sO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY29udGVudFRvVXNlID0gQ09OVEVOVF9UWVBFU1t0eXBlb2YgcHJvcHMuY2hpbGRyZW5dID8gcHJvcHMuY2hpbGRyZW4gOiBudWxsO1xuICAgICAgdmFyIGNoaWxkcmVuVG9Vc2UgPSBjb250ZW50VG9Vc2UgIT0gbnVsbCA/IG51bGwgOiBwcm9wcy5jaGlsZHJlbjtcbiAgICAgIGlmIChjb250ZW50VG9Vc2UgIT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBWYWxpZGF0ZSB0aGF0IHRleHQgaXMgYWxsb3dlZCBhcyBhIGNoaWxkIG9mIHRoaXMgbm9kZVxuICAgICAgICByZXQgPSBlc2NhcGVUZXh0Q29udGVudEZvckJyb3dzZXIoY29udGVudFRvVXNlKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hpbGRyZW5Ub1VzZSAhPSBudWxsKSB7XG4gICAgICAgIHZhciBtb3VudEltYWdlcyA9IHRoaXMubW91bnRDaGlsZHJlbihjaGlsZHJlblRvVXNlLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgICAgIHJldCA9IG1vdW50SW1hZ2VzLmpvaW4oJycpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobmV3bGluZUVhdGluZ1RhZ3NbdGhpcy5fdGFnXSAmJiByZXQuY2hhckF0KDApID09PSAnXFxuJykge1xuICAgICAgLy8gdGV4dC9odG1sIGlnbm9yZXMgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGVzZSB0YWdzIGlmIGl0J3MgYSBuZXdsaW5lXG4gICAgICAvLyBQcmVmZXIgdG8gYnJlYWsgYXBwbGljYXRpb24veG1sIG92ZXIgdGV4dC9odG1sIChmb3Igbm93KSBieSBhZGRpbmdcbiAgICAgIC8vIGEgbmV3bGluZSBzcGVjaWZpY2FsbHkgdG8gZ2V0IGVhdGVuIGJ5IHRoZSBwYXJzZXIuIChBbHRlcm5hdGVseSBmb3JcbiAgICAgIC8vIHRleHRhcmVhcywgcmVwbGFjaW5nIFwiXlxcblwiIHdpdGggXCJcXHJcXG5cIiBkb2Vzbid0IGdldCBlYXRlbiwgYW5kIHRoZSBmaXJzdFxuICAgICAgLy8gXFxyIGlzIG5vcm1hbGl6ZWQgb3V0IGJ5IEhUTUxUZXh0QXJlYUVsZW1lbnQjdmFsdWUuKVxuICAgICAgLy8gU2VlOiA8aHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC1wb2x5Z2xvdC8jbmV3bGluZXMtaW4tdGV4dGFyZWEtYW5kLXByZT5cbiAgICAgIC8vIFNlZTogPGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L3N5bnRheC5odG1sI2VsZW1lbnQtcmVzdHJpY3Rpb25zPlxuICAgICAgLy8gU2VlOiA8aHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvc3ludGF4Lmh0bWwjbmV3bGluZXM+XG4gICAgICAvLyBTZWU6IFBhcnNpbmcgb2YgXCJ0ZXh0YXJlYVwiIFwibGlzdGluZ1wiIGFuZCBcInByZVwiIGVsZW1lbnRzXG4gICAgICAvLyAgZnJvbSA8aHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluYm9keT5cbiAgICAgIHJldHVybiAnXFxuJyArIHJldDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gIH0sXG5cbiAgX2NyZWF0ZUluaXRpYWxDaGlsZHJlbjogZnVuY3Rpb24gKHRyYW5zYWN0aW9uLCBwcm9wcywgY29udGV4dCwgZWwpIHtcbiAgICAvLyBJbnRlbnRpb25hbCB1c2Ugb2YgIT0gdG8gYXZvaWQgY2F0Y2hpbmcgemVyby9mYWxzZS5cbiAgICB2YXIgaW5uZXJIVE1MID0gcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw7XG4gICAgaWYgKGlubmVySFRNTCAhPSBudWxsKSB7XG4gICAgICBpZiAoaW5uZXJIVE1MLl9faHRtbCAhPSBudWxsKSB7XG4gICAgICAgIHNldElubmVySFRNTChlbCwgaW5uZXJIVE1MLl9faHRtbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBjb250ZW50VG9Vc2UgPSBDT05URU5UX1RZUEVTW3R5cGVvZiBwcm9wcy5jaGlsZHJlbl0gPyBwcm9wcy5jaGlsZHJlbiA6IG51bGw7XG4gICAgICB2YXIgY2hpbGRyZW5Ub1VzZSA9IGNvbnRlbnRUb1VzZSAhPSBudWxsID8gbnVsbCA6IHByb3BzLmNoaWxkcmVuO1xuICAgICAgaWYgKGNvbnRlbnRUb1VzZSAhPSBudWxsKSB7XG4gICAgICAgIC8vIFRPRE86IFZhbGlkYXRlIHRoYXQgdGV4dCBpcyBhbGxvd2VkIGFzIGEgY2hpbGQgb2YgdGhpcyBub2RlXG4gICAgICAgIHNldFRleHRDb250ZW50KGVsLCBjb250ZW50VG9Vc2UpO1xuICAgICAgfSBlbHNlIGlmIChjaGlsZHJlblRvVXNlICE9IG51bGwpIHtcbiAgICAgICAgdmFyIG1vdW50SW1hZ2VzID0gdGhpcy5tb3VudENoaWxkcmVuKGNoaWxkcmVuVG9Vc2UsIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb3VudEltYWdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGVsLmFwcGVuZENoaWxkKG1vdW50SW1hZ2VzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmVjZWl2ZXMgYSBuZXh0IGVsZW1lbnQgYW5kIHVwZGF0ZXMgdGhlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0RWxlbWVudFxuICAgKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb258UmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRcbiAgICovXG4gIHJlY2VpdmVDb21wb25lbnQ6IGZ1bmN0aW9uIChuZXh0RWxlbWVudCwgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICB2YXIgcHJldkVsZW1lbnQgPSB0aGlzLl9jdXJyZW50RWxlbWVudDtcbiAgICB0aGlzLl9jdXJyZW50RWxlbWVudCA9IG5leHRFbGVtZW50O1xuICAgIHRoaXMudXBkYXRlQ29tcG9uZW50KHRyYW5zYWN0aW9uLCBwcmV2RWxlbWVudCwgbmV4dEVsZW1lbnQsIGNvbnRleHQpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIGEgbmF0aXZlIERPTSBjb21wb25lbnQgYWZ0ZXIgaXQgaGFzIGFscmVhZHkgYmVlbiBhbGxvY2F0ZWQgYW5kXG4gICAqIGF0dGFjaGVkIHRvIHRoZSBET00uIFJlY29uY2lsZXMgdGhlIHJvb3QgRE9NIG5vZGUsIHRoZW4gcmVjdXJzZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IHByZXZFbGVtZW50XG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0RWxlbWVudFxuICAgKiBAaW50ZXJuYWxcbiAgICogQG92ZXJyaWRhYmxlXG4gICAqL1xuICB1cGRhdGVDb21wb25lbnQ6IGZ1bmN0aW9uICh0cmFuc2FjdGlvbiwgcHJldkVsZW1lbnQsIG5leHRFbGVtZW50LCBjb250ZXh0KSB7XG4gICAgdmFyIGxhc3RQcm9wcyA9IHByZXZFbGVtZW50LnByb3BzO1xuICAgIHZhciBuZXh0UHJvcHMgPSB0aGlzLl9jdXJyZW50RWxlbWVudC5wcm9wcztcblxuICAgIHN3aXRjaCAodGhpcy5fdGFnKSB7XG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICBsYXN0UHJvcHMgPSBSZWFjdERPTUJ1dHRvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBsYXN0UHJvcHMpO1xuICAgICAgICBuZXh0UHJvcHMgPSBSZWFjdERPTUJ1dHRvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBuZXh0UHJvcHMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgICAgUmVhY3RET01JbnB1dC51cGRhdGVXcmFwcGVyKHRoaXMpO1xuICAgICAgICBsYXN0UHJvcHMgPSBSZWFjdERPTUlucHV0LmdldE5hdGl2ZVByb3BzKHRoaXMsIGxhc3RQcm9wcyk7XG4gICAgICAgIG5leHRQcm9wcyA9IFJlYWN0RE9NSW5wdXQuZ2V0TmF0aXZlUHJvcHModGhpcywgbmV4dFByb3BzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdvcHRpb24nOlxuICAgICAgICBsYXN0UHJvcHMgPSBSZWFjdERPTU9wdGlvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBsYXN0UHJvcHMpO1xuICAgICAgICBuZXh0UHJvcHMgPSBSZWFjdERPTU9wdGlvbi5nZXROYXRpdmVQcm9wcyh0aGlzLCBuZXh0UHJvcHMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAgIGxhc3RQcm9wcyA9IFJlYWN0RE9NU2VsZWN0LmdldE5hdGl2ZVByb3BzKHRoaXMsIGxhc3RQcm9wcyk7XG4gICAgICAgIG5leHRQcm9wcyA9IFJlYWN0RE9NU2VsZWN0LmdldE5hdGl2ZVByb3BzKHRoaXMsIG5leHRQcm9wcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgICBSZWFjdERPTVRleHRhcmVhLnVwZGF0ZVdyYXBwZXIodGhpcyk7XG4gICAgICAgIGxhc3RQcm9wcyA9IFJlYWN0RE9NVGV4dGFyZWEuZ2V0TmF0aXZlUHJvcHModGhpcywgbGFzdFByb3BzKTtcbiAgICAgICAgbmV4dFByb3BzID0gUmVhY3RET01UZXh0YXJlYS5nZXROYXRpdmVQcm9wcyh0aGlzLCBuZXh0UHJvcHMpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgLy8gSWYgdGhlIGNvbnRleHQgaXMgcmVmZXJlbmNlLWVxdWFsIHRvIHRoZSBvbGQgb25lLCBwYXNzIGRvd24gdGhlIHNhbWVcbiAgICAgIC8vIHByb2Nlc3NlZCBvYmplY3Qgc28gdGhlIHVwZGF0ZSBiYWlsb3V0IGluIFJlYWN0UmVjb25jaWxlciBiZWhhdmVzXG4gICAgICAvLyBjb3JyZWN0bHkgKGFuZCBpZGVudGljYWxseSBpbiBkZXYgYW5kIHByb2QpLiBTZWUgIzUwMDUuXG4gICAgICBpZiAodGhpcy5fdW5wcm9jZXNzZWRDb250ZXh0RGV2ICE9PSBjb250ZXh0KSB7XG4gICAgICAgIHRoaXMuX3VucHJvY2Vzc2VkQ29udGV4dERldiA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuX3Byb2Nlc3NlZENvbnRleHREZXYgPSBwcm9jZXNzQ2hpbGRDb250ZXh0RGV2KGNvbnRleHQsIHRoaXMpO1xuICAgICAgfVxuICAgICAgY29udGV4dCA9IHRoaXMuX3Byb2Nlc3NlZENvbnRleHREZXY7XG4gICAgfVxuXG4gICAgYXNzZXJ0VmFsaWRQcm9wcyh0aGlzLCBuZXh0UHJvcHMpO1xuICAgIHRoaXMuX3VwZGF0ZURPTVByb3BlcnRpZXMobGFzdFByb3BzLCBuZXh0UHJvcHMsIHRyYW5zYWN0aW9uLCBudWxsKTtcbiAgICB0aGlzLl91cGRhdGVET01DaGlsZHJlbihsYXN0UHJvcHMsIG5leHRQcm9wcywgdHJhbnNhY3Rpb24sIGNvbnRleHQpO1xuXG4gICAgaWYgKCFjYW5EZWZpbmVQcm9wZXJ0eSAmJiB0aGlzLl9ub2RlV2l0aExlZ2FjeVByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuX25vZGVXaXRoTGVnYWN5UHJvcGVydGllcy5wcm9wcyA9IG5leHRQcm9wcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fdGFnID09PSAnc2VsZWN0Jykge1xuICAgICAgLy8gPHNlbGVjdD4gdmFsdWUgdXBkYXRlIG5lZWRzIHRvIG9jY3VyIGFmdGVyIDxvcHRpb24+IGNoaWxkcmVuXG4gICAgICAvLyByZWNvbmNpbGlhdGlvblxuICAgICAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShwb3N0VXBkYXRlU2VsZWN0V3JhcHBlciwgdGhpcyk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNvbmNpbGVzIHRoZSBwcm9wZXJ0aWVzIGJ5IGRldGVjdGluZyBkaWZmZXJlbmNlcyBpbiBwcm9wZXJ0eSB2YWx1ZXMgYW5kXG4gICAqIHVwZGF0aW5nIHRoZSBET00gYXMgbmVjZXNzYXJ5LiBUaGlzIGZ1bmN0aW9uIGlzIHByb2JhYmx5IHRoZSBzaW5nbGUgbW9zdFxuICAgKiBjcml0aWNhbCBwYXRoIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24uXG4gICAqXG4gICAqIFRPRE86IEJlbmNobWFyayB3aGV0aGVyIGNoZWNraW5nIGZvciBjaGFuZ2VkIHZhbHVlcyBpbiBtZW1vcnkgYWN0dWFsbHlcbiAgICogICAgICAgaW1wcm92ZXMgcGVyZm9ybWFuY2UgKGVzcGVjaWFsbHkgc3RhdGljYWxseSBwb3NpdGlvbmVkIGVsZW1lbnRzKS5cbiAgICogVE9ETzogQmVuY2htYXJrIHRoZSBlZmZlY3RzIG9mIHB1dHRpbmcgdGhpcyBhdCB0aGUgdG9wIHNpbmNlIDk5JSBvZiBwcm9wc1xuICAgKiAgICAgICBkbyBub3QgY2hhbmdlIGZvciBhIGdpdmVuIHJlY29uY2lsaWF0aW9uLlxuICAgKiBUT0RPOiBCZW5jaG1hcmsgYXJlYXMgdGhhdCBjYW4gYmUgaW1wcm92ZWQgd2l0aCBjYWNoaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge29iamVjdH0gbGFzdFByb3BzXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBuZXh0UHJvcHNcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gez9ET01FbGVtZW50fSBub2RlXG4gICAqL1xuICBfdXBkYXRlRE9NUHJvcGVydGllczogZnVuY3Rpb24gKGxhc3RQcm9wcywgbmV4dFByb3BzLCB0cmFuc2FjdGlvbiwgbm9kZSkge1xuICAgIHZhciBwcm9wS2V5O1xuICAgIHZhciBzdHlsZU5hbWU7XG4gICAgdmFyIHN0eWxlVXBkYXRlcztcbiAgICBmb3IgKHByb3BLZXkgaW4gbGFzdFByb3BzKSB7XG4gICAgICBpZiAobmV4dFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpIHx8ICFsYXN0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocHJvcEtleSA9PT0gU1RZTEUpIHtcbiAgICAgICAgdmFyIGxhc3RTdHlsZSA9IHRoaXMuX3ByZXZpb3VzU3R5bGVDb3B5O1xuICAgICAgICBmb3IgKHN0eWxlTmFtZSBpbiBsYXN0U3R5bGUpIHtcbiAgICAgICAgICBpZiAobGFzdFN0eWxlLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpIHtcbiAgICAgICAgICAgIHN0eWxlVXBkYXRlcyA9IHN0eWxlVXBkYXRlcyB8fCB7fTtcbiAgICAgICAgICAgIHN0eWxlVXBkYXRlc1tzdHlsZU5hbWVdID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzU3R5bGVDb3B5ID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAocmVnaXN0cmF0aW9uTmFtZU1vZHVsZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgICAgaWYgKGxhc3RQcm9wc1twcm9wS2V5XSkge1xuICAgICAgICAgIC8vIE9ubHkgY2FsbCBkZWxldGVMaXN0ZW5lciBpZiB0aGVyZSB3YXMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IG9yXG4gICAgICAgICAgLy8gZWxzZSB3aWxsRGVsZXRlTGlzdGVuZXIgZ2V0cyBjYWxsZWQgd2hlbiB0aGVyZSB3YXNuJ3QgYWN0dWFsbHkgYVxuICAgICAgICAgIC8vIGxpc3RlbmVyIChlLmcuLCBvbkNsaWNrPXtudWxsfSlcbiAgICAgICAgICBkZWxldGVMaXN0ZW5lcih0aGlzLl9yb290Tm9kZUlELCBwcm9wS2V5KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChET01Qcm9wZXJ0eS5wcm9wZXJ0aWVzW3Byb3BLZXldIHx8IERPTVByb3BlcnR5LmlzQ3VzdG9tQXR0cmlidXRlKHByb3BLZXkpKSB7XG4gICAgICAgIGlmICghbm9kZSkge1xuICAgICAgICAgIG5vZGUgPSBSZWFjdE1vdW50LmdldE5vZGUodGhpcy5fcm9vdE5vZGVJRCk7XG4gICAgICAgIH1cbiAgICAgICAgRE9NUHJvcGVydHlPcGVyYXRpb25zLmRlbGV0ZVZhbHVlRm9yUHJvcGVydHkobm9kZSwgcHJvcEtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAocHJvcEtleSBpbiBuZXh0UHJvcHMpIHtcbiAgICAgIHZhciBuZXh0UHJvcCA9IG5leHRQcm9wc1twcm9wS2V5XTtcbiAgICAgIHZhciBsYXN0UHJvcCA9IHByb3BLZXkgPT09IFNUWUxFID8gdGhpcy5fcHJldmlvdXNTdHlsZUNvcHkgOiBsYXN0UHJvcHNbcHJvcEtleV07XG4gICAgICBpZiAoIW5leHRQcm9wcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSB8fCBuZXh0UHJvcCA9PT0gbGFzdFByb3ApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocHJvcEtleSA9PT0gU1RZTEUpIHtcbiAgICAgICAgaWYgKG5leHRQcm9wKSB7XG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICAgIGNoZWNrQW5kV2FybkZvck11dGF0ZWRTdHlsZSh0aGlzLl9wcmV2aW91c1N0eWxlQ29weSwgdGhpcy5fcHJldmlvdXNTdHlsZSwgdGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9wcmV2aW91c1N0eWxlID0gbmV4dFByb3A7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5leHRQcm9wID0gdGhpcy5fcHJldmlvdXNTdHlsZUNvcHkgPSBhc3NpZ24oe30sIG5leHRQcm9wKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9wcmV2aW91c1N0eWxlQ29weSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhc3RQcm9wKSB7XG4gICAgICAgICAgLy8gVW5zZXQgc3R5bGVzIG9uIGBsYXN0UHJvcGAgYnV0IG5vdCBvbiBgbmV4dFByb3BgLlxuICAgICAgICAgIGZvciAoc3R5bGVOYW1lIGluIGxhc3RQcm9wKSB7XG4gICAgICAgICAgICBpZiAobGFzdFByb3AuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSAmJiAoIW5leHRQcm9wIHx8ICFuZXh0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpKSkge1xuICAgICAgICAgICAgICBzdHlsZVVwZGF0ZXMgPSBzdHlsZVVwZGF0ZXMgfHwge307XG4gICAgICAgICAgICAgIHN0eWxlVXBkYXRlc1tzdHlsZU5hbWVdID0gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFVwZGF0ZSBzdHlsZXMgdGhhdCBjaGFuZ2VkIHNpbmNlIGBsYXN0UHJvcGAuXG4gICAgICAgICAgZm9yIChzdHlsZU5hbWUgaW4gbmV4dFByb3ApIHtcbiAgICAgICAgICAgIGlmIChuZXh0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpICYmIGxhc3RQcm9wW3N0eWxlTmFtZV0gIT09IG5leHRQcm9wW3N0eWxlTmFtZV0pIHtcbiAgICAgICAgICAgICAgc3R5bGVVcGRhdGVzID0gc3R5bGVVcGRhdGVzIHx8IHt9O1xuICAgICAgICAgICAgICBzdHlsZVVwZGF0ZXNbc3R5bGVOYW1lXSA9IG5leHRQcm9wW3N0eWxlTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFJlbGllcyBvbiBgdXBkYXRlU3R5bGVzQnlJRGAgbm90IG11dGF0aW5nIGBzdHlsZVVwZGF0ZXNgLlxuICAgICAgICAgIHN0eWxlVXBkYXRlcyA9IG5leHRQcm9wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVNb2R1bGVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICAgIGlmIChuZXh0UHJvcCkge1xuICAgICAgICAgIGVucXVldWVQdXRMaXN0ZW5lcih0aGlzLl9yb290Tm9kZUlELCBwcm9wS2V5LCBuZXh0UHJvcCwgdHJhbnNhY3Rpb24pO1xuICAgICAgICB9IGVsc2UgaWYgKGxhc3RQcm9wKSB7XG4gICAgICAgICAgZGVsZXRlTGlzdGVuZXIodGhpcy5fcm9vdE5vZGVJRCwgcHJvcEtleSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNDdXN0b21Db21wb25lbnQodGhpcy5fdGFnLCBuZXh0UHJvcHMpKSB7XG4gICAgICAgIGlmICghbm9kZSkge1xuICAgICAgICAgIG5vZGUgPSBSZWFjdE1vdW50LmdldE5vZGUodGhpcy5fcm9vdE5vZGVJRCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICAgICAgbmV4dFByb3AgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIERPTVByb3BlcnR5T3BlcmF0aW9ucy5zZXRWYWx1ZUZvckF0dHJpYnV0ZShub2RlLCBwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgICB9IGVsc2UgaWYgKERPTVByb3BlcnR5LnByb3BlcnRpZXNbcHJvcEtleV0gfHwgRE9NUHJvcGVydHkuaXNDdXN0b21BdHRyaWJ1dGUocHJvcEtleSkpIHtcbiAgICAgICAgaWYgKCFub2RlKSB7XG4gICAgICAgICAgbm9kZSA9IFJlYWN0TW91bnQuZ2V0Tm9kZSh0aGlzLl9yb290Tm9kZUlEKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB3ZSdyZSB1cGRhdGluZyB0byBudWxsIG9yIHVuZGVmaW5lZCwgd2Ugc2hvdWxkIHJlbW92ZSB0aGUgcHJvcGVydHlcbiAgICAgICAgLy8gZnJvbSB0aGUgRE9NIG5vZGUgaW5zdGVhZCBvZiBpbmFkdmVydGFudGx5IHNldHRpbmcgdG8gYSBzdHJpbmcuIFRoaXNcbiAgICAgICAgLy8gYnJpbmdzIHVzIGluIGxpbmUgd2l0aCB0aGUgc2FtZSBiZWhhdmlvciB3ZSBoYXZlIG9uIGluaXRpYWwgcmVuZGVyLlxuICAgICAgICBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgICAgIERPTVByb3BlcnR5T3BlcmF0aW9ucy5zZXRWYWx1ZUZvclByb3BlcnR5KG5vZGUsIHByb3BLZXksIG5leHRQcm9wKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBET01Qcm9wZXJ0eU9wZXJhdGlvbnMuZGVsZXRlVmFsdWVGb3JQcm9wZXJ0eShub2RlLCBwcm9wS2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc3R5bGVVcGRhdGVzKSB7XG4gICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgbm9kZSA9IFJlYWN0TW91bnQuZ2V0Tm9kZSh0aGlzLl9yb290Tm9kZUlEKTtcbiAgICAgIH1cbiAgICAgIENTU1Byb3BlcnR5T3BlcmF0aW9ucy5zZXRWYWx1ZUZvclN0eWxlcyhub2RlLCBzdHlsZVVwZGF0ZXMpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmVjb25jaWxlcyB0aGUgY2hpbGRyZW4gd2l0aCB0aGUgdmFyaW91cyBwcm9wZXJ0aWVzIHRoYXQgYWZmZWN0IHRoZVxuICAgKiBjaGlsZHJlbiBjb250ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gbGFzdFByb3BzXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBuZXh0UHJvcHNcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICAgKi9cbiAgX3VwZGF0ZURPTUNoaWxkcmVuOiBmdW5jdGlvbiAobGFzdFByb3BzLCBuZXh0UHJvcHMsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgdmFyIGxhc3RDb250ZW50ID0gQ09OVEVOVF9UWVBFU1t0eXBlb2YgbGFzdFByb3BzLmNoaWxkcmVuXSA/IGxhc3RQcm9wcy5jaGlsZHJlbiA6IG51bGw7XG4gICAgdmFyIG5leHRDb250ZW50ID0gQ09OVEVOVF9UWVBFU1t0eXBlb2YgbmV4dFByb3BzLmNoaWxkcmVuXSA/IG5leHRQcm9wcy5jaGlsZHJlbiA6IG51bGw7XG5cbiAgICB2YXIgbGFzdEh0bWwgPSBsYXN0UHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgJiYgbGFzdFByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbDtcbiAgICB2YXIgbmV4dEh0bWwgPSBuZXh0UHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgJiYgbmV4dFByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbDtcblxuICAgIC8vIE5vdGUgdGhlIHVzZSBvZiBgIT1gIHdoaWNoIGNoZWNrcyBmb3IgbnVsbCBvciB1bmRlZmluZWQuXG4gICAgdmFyIGxhc3RDaGlsZHJlbiA9IGxhc3RDb250ZW50ICE9IG51bGwgPyBudWxsIDogbGFzdFByb3BzLmNoaWxkcmVuO1xuICAgIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0Q29udGVudCAhPSBudWxsID8gbnVsbCA6IG5leHRQcm9wcy5jaGlsZHJlbjtcblxuICAgIC8vIElmIHdlJ3JlIHN3aXRjaGluZyBmcm9tIGNoaWxkcmVuIHRvIGNvbnRlbnQvaHRtbCBvciB2aWNlIHZlcnNhLCByZW1vdmVcbiAgICAvLyB0aGUgb2xkIGNvbnRlbnRcbiAgICB2YXIgbGFzdEhhc0NvbnRlbnRPckh0bWwgPSBsYXN0Q29udGVudCAhPSBudWxsIHx8IGxhc3RIdG1sICE9IG51bGw7XG4gICAgdmFyIG5leHRIYXNDb250ZW50T3JIdG1sID0gbmV4dENvbnRlbnQgIT0gbnVsbCB8fCBuZXh0SHRtbCAhPSBudWxsO1xuICAgIGlmIChsYXN0Q2hpbGRyZW4gIT0gbnVsbCAmJiBuZXh0Q2hpbGRyZW4gPT0gbnVsbCkge1xuICAgICAgdGhpcy51cGRhdGVDaGlsZHJlbihudWxsLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChsYXN0SGFzQ29udGVudE9ySHRtbCAmJiAhbmV4dEhhc0NvbnRlbnRPckh0bWwpIHtcbiAgICAgIHRoaXMudXBkYXRlVGV4dENvbnRlbnQoJycpO1xuICAgIH1cblxuICAgIGlmIChuZXh0Q29udGVudCAhPSBudWxsKSB7XG4gICAgICBpZiAobGFzdENvbnRlbnQgIT09IG5leHRDb250ZW50KSB7XG4gICAgICAgIHRoaXMudXBkYXRlVGV4dENvbnRlbnQoJycgKyBuZXh0Q29udGVudCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChuZXh0SHRtbCAhPSBudWxsKSB7XG4gICAgICBpZiAobGFzdEh0bWwgIT09IG5leHRIdG1sKSB7XG4gICAgICAgIHRoaXMudXBkYXRlTWFya3VwKCcnICsgbmV4dEh0bWwpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobmV4dENoaWxkcmVuICE9IG51bGwpIHtcbiAgICAgIHRoaXMudXBkYXRlQ2hpbGRyZW4obmV4dENoaWxkcmVuLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyBhbGwgZXZlbnQgcmVnaXN0cmF0aW9ucyBmb3IgdGhpcyBpbnN0YW5jZS4gRG9lcyBub3QgcmVtb3ZlIGZyb21cbiAgICogdGhlIERPTS4gVGhhdCBtdXN0IGJlIGRvbmUgYnkgdGhlIHBhcmVudC5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICB1bm1vdW50Q29tcG9uZW50OiBmdW5jdGlvbiAoKSB7XG4gICAgc3dpdGNoICh0aGlzLl90YWcpIHtcbiAgICAgIGNhc2UgJ2lmcmFtZSc6XG4gICAgICBjYXNlICdpbWcnOlxuICAgICAgY2FzZSAnZm9ybSc6XG4gICAgICBjYXNlICd2aWRlbyc6XG4gICAgICBjYXNlICdhdWRpbyc6XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl93cmFwcGVyU3RhdGUubGlzdGVuZXJzO1xuICAgICAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5yZW1vdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnB1dCc6XG4gICAgICAgIFJlYWN0RE9NSW5wdXQudW5tb3VudFdyYXBwZXIodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgIGNhc2UgJ2JvZHknOlxuICAgICAgICAvKipcbiAgICAgICAgICogQ29tcG9uZW50cyBsaWtlIDxodG1sPiA8aGVhZD4gYW5kIDxib2R5PiBjYW4ndCBiZSByZW1vdmVkIG9yIGFkZGVkXG4gICAgICAgICAqIGVhc2lseSBpbiBhIGNyb3NzLWJyb3dzZXIgd2F5LCBob3dldmVyIGl0J3MgdmFsdWFibGUgdG8gYmUgYWJsZSB0b1xuICAgICAgICAgKiB0YWtlIGFkdmFudGFnZSBvZiBSZWFjdCdzIHJlY29uY2lsaWF0aW9uIGZvciBzdHlsaW5nIGFuZCA8dGl0bGU+XG4gICAgICAgICAqIG1hbmFnZW1lbnQuIFNvIHdlIGp1c3QgZG9jdW1lbnQgaXQgYW5kIHRocm93IGluIGRhbmdlcm91cyBjYXNlcy5cbiAgICAgICAgICovXG4gICAgICAgICFmYWxzZSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICc8JXM+IHRyaWVkIHRvIHVubW91bnQuIEJlY2F1c2Ugb2YgY3Jvc3MtYnJvd3NlciBxdWlya3MgaXQgaXMgJyArICdpbXBvc3NpYmxlIHRvIHVubW91bnQgc29tZSB0b3AtbGV2ZWwgY29tcG9uZW50cyAoZWcgPGh0bWw+LCAnICsgJzxoZWFkPiwgYW5kIDxib2R5PikgcmVsaWFibHkgYW5kIGVmZmljaWVudGx5LiBUbyBmaXggdGhpcywgaGF2ZSBhICcgKyAnc2luZ2xlIHRvcC1sZXZlbCBjb21wb25lbnQgdGhhdCBuZXZlciB1bm1vdW50cyByZW5kZXIgdGhlc2UgJyArICdlbGVtZW50cy4nLCB0aGlzLl90YWcpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy51bm1vdW50Q2hpbGRyZW4oKTtcbiAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuZGVsZXRlQWxsTGlzdGVuZXJzKHRoaXMuX3Jvb3ROb2RlSUQpO1xuICAgIFJlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50LnVubW91bnRJREZyb21FbnZpcm9ubWVudCh0aGlzLl9yb290Tm9kZUlEKTtcbiAgICB0aGlzLl9yb290Tm9kZUlEID0gbnVsbDtcbiAgICB0aGlzLl93cmFwcGVyU3RhdGUgPSBudWxsO1xuICAgIGlmICh0aGlzLl9ub2RlV2l0aExlZ2FjeVByb3BlcnRpZXMpIHtcbiAgICAgIHZhciBub2RlID0gdGhpcy5fbm9kZVdpdGhMZWdhY3lQcm9wZXJ0aWVzO1xuICAgICAgbm9kZS5fcmVhY3RJbnRlcm5hbENvbXBvbmVudCA9IG51bGw7XG4gICAgICB0aGlzLl9ub2RlV2l0aExlZ2FjeVByb3BlcnRpZXMgPSBudWxsO1xuICAgIH1cbiAgfSxcblxuICBnZXRQdWJsaWNJbnN0YW5jZTogZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5fbm9kZVdpdGhMZWdhY3lQcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgbm9kZSA9IFJlYWN0TW91bnQuZ2V0Tm9kZSh0aGlzLl9yb290Tm9kZUlEKTtcblxuICAgICAgbm9kZS5fcmVhY3RJbnRlcm5hbENvbXBvbmVudCA9IHRoaXM7XG4gICAgICBub2RlLmdldERPTU5vZGUgPSBsZWdhY3lHZXRET01Ob2RlO1xuICAgICAgbm9kZS5pc01vdW50ZWQgPSBsZWdhY3lJc01vdW50ZWQ7XG4gICAgICBub2RlLnNldFN0YXRlID0gbGVnYWN5U2V0U3RhdGVFdGM7XG4gICAgICBub2RlLnJlcGxhY2VTdGF0ZSA9IGxlZ2FjeVNldFN0YXRlRXRjO1xuICAgICAgbm9kZS5mb3JjZVVwZGF0ZSA9IGxlZ2FjeVNldFN0YXRlRXRjO1xuICAgICAgbm9kZS5zZXRQcm9wcyA9IGxlZ2FjeVNldFByb3BzO1xuICAgICAgbm9kZS5yZXBsYWNlUHJvcHMgPSBsZWdhY3lSZXBsYWNlUHJvcHM7XG5cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGlmIChjYW5EZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG5vZGUsIGxlZ2FjeVByb3BzRGVzY3JpcHRvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlQ29tcG9uZW50IHdpbGwgdXBkYXRlIHRoaXMgcHJvcGVydHkgb24gc3Vic2VxdWVudCByZW5kZXJzXG4gICAgICAgICAgbm9kZS5wcm9wcyA9IHRoaXMuX2N1cnJlbnRFbGVtZW50LnByb3BzO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB1cGRhdGVDb21wb25lbnQgd2lsbCB1cGRhdGUgdGhpcyBwcm9wZXJ0eSBvbiBzdWJzZXF1ZW50IHJlbmRlcnNcbiAgICAgICAgbm9kZS5wcm9wcyA9IHRoaXMuX2N1cnJlbnRFbGVtZW50LnByb3BzO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9ub2RlV2l0aExlZ2FjeVByb3BlcnRpZXMgPSBub2RlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbm9kZVdpdGhMZWdhY3lQcm9wZXJ0aWVzO1xuICB9XG5cbn07XG5cblJlYWN0UGVyZi5tZWFzdXJlTWV0aG9kcyhSZWFjdERPTUNvbXBvbmVudCwgJ1JlYWN0RE9NQ29tcG9uZW50Jywge1xuICBtb3VudENvbXBvbmVudDogJ21vdW50Q29tcG9uZW50JyxcbiAgdXBkYXRlQ29tcG9uZW50OiAndXBkYXRlQ29tcG9uZW50J1xufSk7XG5cbmFzc2lnbihSZWFjdERPTUNvbXBvbmVudC5wcm90b3R5cGUsIFJlYWN0RE9NQ29tcG9uZW50Lk1peGluLCBSZWFjdE11bHRpQ2hpbGQuTWl4aW4pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RE9NQ29tcG9uZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERPTUZhY3Rvcmllc1xuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdEVsZW1lbnQgPSByZXF1aXJlKCcuL1JlYWN0RWxlbWVudCcpO1xudmFyIFJlYWN0RWxlbWVudFZhbGlkYXRvciA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50VmFsaWRhdG9yJyk7XG5cbnZhciBtYXBPYmplY3QgPSByZXF1aXJlKCdmYmpzL2xpYi9tYXBPYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBmYWN0b3J5IHRoYXQgY3JlYXRlcyBIVE1MIHRhZyBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRhZyBuYW1lIChlLmcuIGBkaXZgKS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURPTUZhY3RvcnkodGFnKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgcmV0dXJuIFJlYWN0RWxlbWVudFZhbGlkYXRvci5jcmVhdGVGYWN0b3J5KHRhZyk7XG4gIH1cbiAgcmV0dXJuIFJlYWN0RWxlbWVudC5jcmVhdGVGYWN0b3J5KHRhZyk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hcHBpbmcgZnJvbSBzdXBwb3J0ZWQgSFRNTCB0YWdzIHRvIGBSZWFjdERPTUNvbXBvbmVudGAgY2xhc3Nlcy5cbiAqIFRoaXMgaXMgYWxzbyBhY2Nlc3NpYmxlIHZpYSBgUmVhY3QuRE9NYC5cbiAqXG4gKiBAcHVibGljXG4gKi9cbnZhciBSZWFjdERPTUZhY3RvcmllcyA9IG1hcE9iamVjdCh7XG4gIGE6ICdhJyxcbiAgYWJicjogJ2FiYnInLFxuICBhZGRyZXNzOiAnYWRkcmVzcycsXG4gIGFyZWE6ICdhcmVhJyxcbiAgYXJ0aWNsZTogJ2FydGljbGUnLFxuICBhc2lkZTogJ2FzaWRlJyxcbiAgYXVkaW86ICdhdWRpbycsXG4gIGI6ICdiJyxcbiAgYmFzZTogJ2Jhc2UnLFxuICBiZGk6ICdiZGknLFxuICBiZG86ICdiZG8nLFxuICBiaWc6ICdiaWcnLFxuICBibG9ja3F1b3RlOiAnYmxvY2txdW90ZScsXG4gIGJvZHk6ICdib2R5JyxcbiAgYnI6ICdicicsXG4gIGJ1dHRvbjogJ2J1dHRvbicsXG4gIGNhbnZhczogJ2NhbnZhcycsXG4gIGNhcHRpb246ICdjYXB0aW9uJyxcbiAgY2l0ZTogJ2NpdGUnLFxuICBjb2RlOiAnY29kZScsXG4gIGNvbDogJ2NvbCcsXG4gIGNvbGdyb3VwOiAnY29sZ3JvdXAnLFxuICBkYXRhOiAnZGF0YScsXG4gIGRhdGFsaXN0OiAnZGF0YWxpc3QnLFxuICBkZDogJ2RkJyxcbiAgZGVsOiAnZGVsJyxcbiAgZGV0YWlsczogJ2RldGFpbHMnLFxuICBkZm46ICdkZm4nLFxuICBkaWFsb2c6ICdkaWFsb2cnLFxuICBkaXY6ICdkaXYnLFxuICBkbDogJ2RsJyxcbiAgZHQ6ICdkdCcsXG4gIGVtOiAnZW0nLFxuICBlbWJlZDogJ2VtYmVkJyxcbiAgZmllbGRzZXQ6ICdmaWVsZHNldCcsXG4gIGZpZ2NhcHRpb246ICdmaWdjYXB0aW9uJyxcbiAgZmlndXJlOiAnZmlndXJlJyxcbiAgZm9vdGVyOiAnZm9vdGVyJyxcbiAgZm9ybTogJ2Zvcm0nLFxuICBoMTogJ2gxJyxcbiAgaDI6ICdoMicsXG4gIGgzOiAnaDMnLFxuICBoNDogJ2g0JyxcbiAgaDU6ICdoNScsXG4gIGg2OiAnaDYnLFxuICBoZWFkOiAnaGVhZCcsXG4gIGhlYWRlcjogJ2hlYWRlcicsXG4gIGhncm91cDogJ2hncm91cCcsXG4gIGhyOiAnaHInLFxuICBodG1sOiAnaHRtbCcsXG4gIGk6ICdpJyxcbiAgaWZyYW1lOiAnaWZyYW1lJyxcbiAgaW1nOiAnaW1nJyxcbiAgaW5wdXQ6ICdpbnB1dCcsXG4gIGluczogJ2lucycsXG4gIGtiZDogJ2tiZCcsXG4gIGtleWdlbjogJ2tleWdlbicsXG4gIGxhYmVsOiAnbGFiZWwnLFxuICBsZWdlbmQ6ICdsZWdlbmQnLFxuICBsaTogJ2xpJyxcbiAgbGluazogJ2xpbmsnLFxuICBtYWluOiAnbWFpbicsXG4gIG1hcDogJ21hcCcsXG4gIG1hcms6ICdtYXJrJyxcbiAgbWVudTogJ21lbnUnLFxuICBtZW51aXRlbTogJ21lbnVpdGVtJyxcbiAgbWV0YTogJ21ldGEnLFxuICBtZXRlcjogJ21ldGVyJyxcbiAgbmF2OiAnbmF2JyxcbiAgbm9zY3JpcHQ6ICdub3NjcmlwdCcsXG4gIG9iamVjdDogJ29iamVjdCcsXG4gIG9sOiAnb2wnLFxuICBvcHRncm91cDogJ29wdGdyb3VwJyxcbiAgb3B0aW9uOiAnb3B0aW9uJyxcbiAgb3V0cHV0OiAnb3V0cHV0JyxcbiAgcDogJ3AnLFxuICBwYXJhbTogJ3BhcmFtJyxcbiAgcGljdHVyZTogJ3BpY3R1cmUnLFxuICBwcmU6ICdwcmUnLFxuICBwcm9ncmVzczogJ3Byb2dyZXNzJyxcbiAgcTogJ3EnLFxuICBycDogJ3JwJyxcbiAgcnQ6ICdydCcsXG4gIHJ1Ynk6ICdydWJ5JyxcbiAgczogJ3MnLFxuICBzYW1wOiAnc2FtcCcsXG4gIHNjcmlwdDogJ3NjcmlwdCcsXG4gIHNlY3Rpb246ICdzZWN0aW9uJyxcbiAgc2VsZWN0OiAnc2VsZWN0JyxcbiAgc21hbGw6ICdzbWFsbCcsXG4gIHNvdXJjZTogJ3NvdXJjZScsXG4gIHNwYW46ICdzcGFuJyxcbiAgc3Ryb25nOiAnc3Ryb25nJyxcbiAgc3R5bGU6ICdzdHlsZScsXG4gIHN1YjogJ3N1YicsXG4gIHN1bW1hcnk6ICdzdW1tYXJ5JyxcbiAgc3VwOiAnc3VwJyxcbiAgdGFibGU6ICd0YWJsZScsXG4gIHRib2R5OiAndGJvZHknLFxuICB0ZDogJ3RkJyxcbiAgdGV4dGFyZWE6ICd0ZXh0YXJlYScsXG4gIHRmb290OiAndGZvb3QnLFxuICB0aDogJ3RoJyxcbiAgdGhlYWQ6ICd0aGVhZCcsXG4gIHRpbWU6ICd0aW1lJyxcbiAgdGl0bGU6ICd0aXRsZScsXG4gIHRyOiAndHInLFxuICB0cmFjazogJ3RyYWNrJyxcbiAgdTogJ3UnLFxuICB1bDogJ3VsJyxcbiAgJ3Zhcic6ICd2YXInLFxuICB2aWRlbzogJ3ZpZGVvJyxcbiAgd2JyOiAnd2JyJyxcblxuICAvLyBTVkdcbiAgY2lyY2xlOiAnY2lyY2xlJyxcbiAgY2xpcFBhdGg6ICdjbGlwUGF0aCcsXG4gIGRlZnM6ICdkZWZzJyxcbiAgZWxsaXBzZTogJ2VsbGlwc2UnLFxuICBnOiAnZycsXG4gIGltYWdlOiAnaW1hZ2UnLFxuICBsaW5lOiAnbGluZScsXG4gIGxpbmVhckdyYWRpZW50OiAnbGluZWFyR3JhZGllbnQnLFxuICBtYXNrOiAnbWFzaycsXG4gIHBhdGg6ICdwYXRoJyxcbiAgcGF0dGVybjogJ3BhdHRlcm4nLFxuICBwb2x5Z29uOiAncG9seWdvbicsXG4gIHBvbHlsaW5lOiAncG9seWxpbmUnLFxuICByYWRpYWxHcmFkaWVudDogJ3JhZGlhbEdyYWRpZW50JyxcbiAgcmVjdDogJ3JlY3QnLFxuICBzdG9wOiAnc3RvcCcsXG4gIHN2ZzogJ3N2ZycsXG4gIHRleHQ6ICd0ZXh0JyxcbiAgdHNwYW46ICd0c3BhbidcblxufSwgY3JlYXRlRE9NRmFjdG9yeSk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RET01GYWN0b3JpZXM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0RE9NRmVhdHVyZUZsYWdzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RET01GZWF0dXJlRmxhZ3MgPSB7XG4gIHVzZUNyZWF0ZUVsZW1lbnQ6IGZhbHNlXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RE9NRmVhdHVyZUZsYWdzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERPTUlET3BlcmF0aW9uc1xuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBET01DaGlsZHJlbk9wZXJhdGlvbnMgPSByZXF1aXJlKCcuL0RPTUNoaWxkcmVuT3BlcmF0aW9ucycpO1xudmFyIERPTVByb3BlcnR5T3BlcmF0aW9ucyA9IHJlcXVpcmUoJy4vRE9NUHJvcGVydHlPcGVyYXRpb25zJyk7XG52YXIgUmVhY3RNb3VudCA9IHJlcXVpcmUoJy4vUmVhY3RNb3VudCcpO1xudmFyIFJlYWN0UGVyZiA9IHJlcXVpcmUoJy4vUmVhY3RQZXJmJyk7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBFcnJvcnMgZm9yIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgbm90IGJlIHVwZGF0ZWQgd2l0aCBgdXBkYXRlUHJvcGVydHlCeUlEKClgLlxuICpcbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAcHJpdmF0ZVxuICovXG52YXIgSU5WQUxJRF9QUk9QRVJUWV9FUlJPUlMgPSB7XG4gIGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MOiAnYGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYCBtdXN0IGJlIHNldCB1c2luZyBgdXBkYXRlSW5uZXJIVE1MQnlJRCgpYC4nLFxuICBzdHlsZTogJ2BzdHlsZWAgbXVzdCBiZSBzZXQgdXNpbmcgYHVwZGF0ZVN0eWxlc0J5SUQoKWAuJ1xufTtcblxuLyoqXG4gKiBPcGVyYXRpb25zIHVzZWQgdG8gcHJvY2VzcyB1cGRhdGVzIHRvIERPTSBub2Rlcy5cbiAqL1xudmFyIFJlYWN0RE9NSURPcGVyYXRpb25zID0ge1xuXG4gIC8qKlxuICAgKiBVcGRhdGVzIGEgRE9NIG5vZGUgd2l0aCBuZXcgcHJvcGVydHkgdmFsdWVzLiBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgdG9cbiAgICogdXBkYXRlIERPTSBwcm9wZXJ0aWVzIGluIGBET01Qcm9wZXJ0eWAuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBvZiB0aGUgbm9kZSB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEEgdmFsaWQgcHJvcGVydHkgbmFtZSwgc2VlIGBET01Qcm9wZXJ0eWAuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgTmV3IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICB1cGRhdGVQcm9wZXJ0eUJ5SUQ6IGZ1bmN0aW9uIChpZCwgbmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgbm9kZSA9IFJlYWN0TW91bnQuZ2V0Tm9kZShpZCk7XG4gICAgISFJTlZBTElEX1BST1BFUlRZX0VSUk9SUy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICd1cGRhdGVQcm9wZXJ0eUJ5SUQoLi4uKTogJXMnLCBJTlZBTElEX1BST1BFUlRZX0VSUk9SU1tuYW1lXSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gSWYgd2UncmUgdXBkYXRpbmcgdG8gbnVsbCBvciB1bmRlZmluZWQsIHdlIHNob3VsZCByZW1vdmUgdGhlIHByb3BlcnR5XG4gICAgLy8gZnJvbSB0aGUgRE9NIG5vZGUgaW5zdGVhZCBvZiBpbmFkdmVydGFudGx5IHNldHRpbmcgdG8gYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBicmluZ3MgdXMgaW4gbGluZSB3aXRoIHRoZSBzYW1lIGJlaGF2aW9yIHdlIGhhdmUgb24gaW5pdGlhbCByZW5kZXIuXG4gICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgIERPTVByb3BlcnR5T3BlcmF0aW9ucy5zZXRWYWx1ZUZvclByb3BlcnR5KG5vZGUsIG5hbWUsIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgRE9NUHJvcGVydHlPcGVyYXRpb25zLmRlbGV0ZVZhbHVlRm9yUHJvcGVydHkobm9kZSwgbmFtZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhIERPTSBub2RlIHRoYXQgZXhpc3RzIGluIHRoZSBkb2N1bWVudCB3aXRoIG1hcmt1cC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIG9mIGNoaWxkIHRvIGJlIHJlcGxhY2VkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIERhbmdlcm91cyBtYXJrdXAgdG8gaW5qZWN0IGluIHBsYWNlIG9mIGNoaWxkLlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHNlZSB7RGFuZ2VyLmRhbmdlcm91c2x5UmVwbGFjZU5vZGVXaXRoTWFya3VwfVxuICAgKi9cbiAgZGFuZ2Vyb3VzbHlSZXBsYWNlTm9kZVdpdGhNYXJrdXBCeUlEOiBmdW5jdGlvbiAoaWQsIG1hcmt1cCkge1xuICAgIHZhciBub2RlID0gUmVhY3RNb3VudC5nZXROb2RlKGlkKTtcbiAgICBET01DaGlsZHJlbk9wZXJhdGlvbnMuZGFuZ2Vyb3VzbHlSZXBsYWNlTm9kZVdpdGhNYXJrdXAobm9kZSwgbWFya3VwKTtcbiAgfSxcblxuICAvKipcbiAgICogVXBkYXRlcyBhIGNvbXBvbmVudCdzIGNoaWxkcmVuIGJ5IHByb2Nlc3NpbmcgYSBzZXJpZXMgb2YgdXBkYXRlcy5cbiAgICpcbiAgICogQHBhcmFtIHthcnJheTxvYmplY3Q+fSB1cGRhdGVzIExpc3Qgb2YgdXBkYXRlIGNvbmZpZ3VyYXRpb25zLlxuICAgKiBAcGFyYW0ge2FycmF5PHN0cmluZz59IG1hcmt1cCBMaXN0IG9mIG1hcmt1cCBzdHJpbmdzLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGRhbmdlcm91c2x5UHJvY2Vzc0NoaWxkcmVuVXBkYXRlczogZnVuY3Rpb24gKHVwZGF0ZXMsIG1hcmt1cCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXBkYXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdXBkYXRlc1tpXS5wYXJlbnROb2RlID0gUmVhY3RNb3VudC5nZXROb2RlKHVwZGF0ZXNbaV0ucGFyZW50SUQpO1xuICAgIH1cbiAgICBET01DaGlsZHJlbk9wZXJhdGlvbnMucHJvY2Vzc1VwZGF0ZXModXBkYXRlcywgbWFya3VwKTtcbiAgfVxufTtcblxuUmVhY3RQZXJmLm1lYXN1cmVNZXRob2RzKFJlYWN0RE9NSURPcGVyYXRpb25zLCAnUmVhY3RET01JRE9wZXJhdGlvbnMnLCB7XG4gIGRhbmdlcm91c2x5UmVwbGFjZU5vZGVXaXRoTWFya3VwQnlJRDogJ2Rhbmdlcm91c2x5UmVwbGFjZU5vZGVXaXRoTWFya3VwQnlJRCcsXG4gIGRhbmdlcm91c2x5UHJvY2Vzc0NoaWxkcmVuVXBkYXRlczogJ2Rhbmdlcm91c2x5UHJvY2Vzc0NoaWxkcmVuVXBkYXRlcydcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RE9NSURPcGVyYXRpb25zOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERPTUlucHV0XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RET01JRE9wZXJhdGlvbnMgPSByZXF1aXJlKCcuL1JlYWN0RE9NSURPcGVyYXRpb25zJyk7XG52YXIgTGlua2VkVmFsdWVVdGlscyA9IHJlcXVpcmUoJy4vTGlua2VkVmFsdWVVdGlscycpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcbnZhciBSZWFjdFVwZGF0ZXMgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlcycpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG5cbnZhciBpbnN0YW5jZXNCeVJlYWN0SUQgPSB7fTtcblxuZnVuY3Rpb24gZm9yY2VVcGRhdGVJZk1vdW50ZWQoKSB7XG4gIGlmICh0aGlzLl9yb290Tm9kZUlEKSB7XG4gICAgLy8gRE9NIGNvbXBvbmVudCBpcyBzdGlsbCBtb3VudGVkOyB1cGRhdGVcbiAgICBSZWFjdERPTUlucHV0LnVwZGF0ZVdyYXBwZXIodGhpcyk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIGFuIDxpbnB1dD4gbmF0aXZlIGNvbXBvbmVudCB0aGF0IGFsbG93cyBzZXR0aW5nIHRoZXNlIG9wdGlvbmFsXG4gKiBwcm9wczogYGNoZWNrZWRgLCBgdmFsdWVgLCBgZGVmYXVsdENoZWNrZWRgLCBhbmQgYGRlZmF1bHRWYWx1ZWAuXG4gKlxuICogSWYgYGNoZWNrZWRgIG9yIGB2YWx1ZWAgYXJlIG5vdCBzdXBwbGllZCAob3IgbnVsbC91bmRlZmluZWQpLCB1c2VyIGFjdGlvbnNcbiAqIHRoYXQgYWZmZWN0IHRoZSBjaGVja2VkIHN0YXRlIG9yIHZhbHVlIHdpbGwgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIElmIHRoZXkgYXJlIHN1cHBsaWVkIChhbmQgbm90IG51bGwvdW5kZWZpbmVkKSwgdGhlIHJlbmRlcmVkIGVsZW1lbnQgd2lsbCBub3RcbiAqIHRyaWdnZXIgdXBkYXRlcyB0byB0aGUgZWxlbWVudC4gSW5zdGVhZCwgdGhlIHByb3BzIG11c3QgY2hhbmdlIGluIG9yZGVyIGZvclxuICogdGhlIHJlbmRlcmVkIGVsZW1lbnQgdG8gYmUgdXBkYXRlZC5cbiAqXG4gKiBUaGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsIGJlIGluaXRpYWxpemVkIGFzIHVuY2hlY2tlZCAob3IgYGRlZmF1bHRDaGVja2VkYClcbiAqIHdpdGggYW4gZW1wdHkgdmFsdWUgKG9yIGBkZWZhdWx0VmFsdWVgKS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTIvV0QtaHRtbDUtMjAxMjEwMjUvdGhlLWlucHV0LWVsZW1lbnQuaHRtbFxuICovXG52YXIgUmVhY3RET01JbnB1dCA9IHtcbiAgZ2V0TmF0aXZlUHJvcHM6IGZ1bmN0aW9uIChpbnN0LCBwcm9wcywgY29udGV4dCkge1xuICAgIHZhciB2YWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZ2V0VmFsdWUocHJvcHMpO1xuICAgIHZhciBjaGVja2VkID0gTGlua2VkVmFsdWVVdGlscy5nZXRDaGVja2VkKHByb3BzKTtcblxuICAgIHZhciBuYXRpdmVQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgIGRlZmF1bHRDaGVja2VkOiB1bmRlZmluZWQsXG4gICAgICBkZWZhdWx0VmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIHZhbHVlOiB2YWx1ZSAhPSBudWxsID8gdmFsdWUgOiBpbnN0Ll93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlLFxuICAgICAgY2hlY2tlZDogY2hlY2tlZCAhPSBudWxsID8gY2hlY2tlZCA6IGluc3QuX3dyYXBwZXJTdGF0ZS5pbml0aWFsQ2hlY2tlZCxcbiAgICAgIG9uQ2hhbmdlOiBpbnN0Ll93cmFwcGVyU3RhdGUub25DaGFuZ2VcbiAgICB9KTtcblxuICAgIHJldHVybiBuYXRpdmVQcm9wcztcbiAgfSxcblxuICBtb3VudFdyYXBwZXI6IGZ1bmN0aW9uIChpbnN0LCBwcm9wcykge1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBMaW5rZWRWYWx1ZVV0aWxzLmNoZWNrUHJvcFR5cGVzKCdpbnB1dCcsIHByb3BzLCBpbnN0Ll9jdXJyZW50RWxlbWVudC5fb3duZXIpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0VmFsdWUgPSBwcm9wcy5kZWZhdWx0VmFsdWU7XG4gICAgaW5zdC5fd3JhcHBlclN0YXRlID0ge1xuICAgICAgaW5pdGlhbENoZWNrZWQ6IHByb3BzLmRlZmF1bHRDaGVja2VkIHx8IGZhbHNlLFxuICAgICAgaW5pdGlhbFZhbHVlOiBkZWZhdWx0VmFsdWUgIT0gbnVsbCA/IGRlZmF1bHRWYWx1ZSA6IG51bGwsXG4gICAgICBvbkNoYW5nZTogX2hhbmRsZUNoYW5nZS5iaW5kKGluc3QpXG4gICAgfTtcbiAgfSxcblxuICBtb3VudFJlYWR5V3JhcHBlcjogZnVuY3Rpb24gKGluc3QpIHtcbiAgICAvLyBDYW4ndCBiZSBpbiBtb3VudFdyYXBwZXIgb3IgZWxzZSBzZXJ2ZXIgcmVuZGVyaW5nIGxlYWtzLlxuICAgIGluc3RhbmNlc0J5UmVhY3RJRFtpbnN0Ll9yb290Tm9kZUlEXSA9IGluc3Q7XG4gIH0sXG5cbiAgdW5tb3VudFdyYXBwZXI6IGZ1bmN0aW9uIChpbnN0KSB7XG4gICAgZGVsZXRlIGluc3RhbmNlc0J5UmVhY3RJRFtpbnN0Ll9yb290Tm9kZUlEXTtcbiAgfSxcblxuICB1cGRhdGVXcmFwcGVyOiBmdW5jdGlvbiAoaW5zdCkge1xuICAgIHZhciBwcm9wcyA9IGluc3QuX2N1cnJlbnRFbGVtZW50LnByb3BzO1xuXG4gICAgLy8gVE9ETzogU2hvdWxkbid0IHRoaXMgYmUgZ2V0Q2hlY2tlZChwcm9wcyk/XG4gICAgdmFyIGNoZWNrZWQgPSBwcm9wcy5jaGVja2VkO1xuICAgIGlmIChjaGVja2VkICE9IG51bGwpIHtcbiAgICAgIFJlYWN0RE9NSURPcGVyYXRpb25zLnVwZGF0ZVByb3BlcnR5QnlJRChpbnN0Ll9yb290Tm9kZUlELCAnY2hlY2tlZCcsIGNoZWNrZWQgfHwgZmFsc2UpO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZ2V0VmFsdWUocHJvcHMpO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAvLyBDYXN0IGB2YWx1ZWAgdG8gYSBzdHJpbmcgdG8gZW5zdXJlIHRoZSB2YWx1ZSBpcyBzZXQgY29ycmVjdGx5LiBXaGlsZVxuICAgICAgLy8gYnJvd3NlcnMgdHlwaWNhbGx5IGRvIHRoaXMgYXMgbmVjZXNzYXJ5LCBqc2RvbSBkb2Vzbid0LlxuICAgICAgUmVhY3RET01JRE9wZXJhdGlvbnMudXBkYXRlUHJvcGVydHlCeUlEKGluc3QuX3Jvb3ROb2RlSUQsICd2YWx1ZScsICcnICsgdmFsdWUpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gX2hhbmRsZUNoYW5nZShldmVudCkge1xuICB2YXIgcHJvcHMgPSB0aGlzLl9jdXJyZW50RWxlbWVudC5wcm9wcztcblxuICB2YXIgcmV0dXJuVmFsdWUgPSBMaW5rZWRWYWx1ZVV0aWxzLmV4ZWN1dGVPbkNoYW5nZShwcm9wcywgZXZlbnQpO1xuXG4gIC8vIEhlcmUgd2UgdXNlIGFzYXAgdG8gd2FpdCB1bnRpbCBhbGwgdXBkYXRlcyBoYXZlIHByb3BhZ2F0ZWQsIHdoaWNoXG4gIC8vIGlzIGltcG9ydGFudCB3aGVuIHVzaW5nIGNvbnRyb2xsZWQgY29tcG9uZW50cyB3aXRoaW4gbGF5ZXJzOlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE2OThcbiAgUmVhY3RVcGRhdGVzLmFzYXAoZm9yY2VVcGRhdGVJZk1vdW50ZWQsIHRoaXMpO1xuXG4gIHZhciBuYW1lID0gcHJvcHMubmFtZTtcbiAgaWYgKHByb3BzLnR5cGUgPT09ICdyYWRpbycgJiYgbmFtZSAhPSBudWxsKSB7XG4gICAgdmFyIHJvb3ROb2RlID0gUmVhY3RNb3VudC5nZXROb2RlKHRoaXMuX3Jvb3ROb2RlSUQpO1xuICAgIHZhciBxdWVyeVJvb3QgPSByb290Tm9kZTtcblxuICAgIHdoaWxlIChxdWVyeVJvb3QucGFyZW50Tm9kZSkge1xuICAgICAgcXVlcnlSb290ID0gcXVlcnlSb290LnBhcmVudE5vZGU7XG4gICAgfVxuXG4gICAgLy8gSWYgYHJvb3ROb2RlLmZvcm1gIHdhcyBub24tbnVsbCwgdGhlbiB3ZSBjb3VsZCB0cnkgYGZvcm0uZWxlbWVudHNgLFxuICAgIC8vIGJ1dCB0aGF0IHNvbWV0aW1lcyBiZWhhdmVzIHN0cmFuZ2VseSBpbiBJRTguIFdlIGNvdWxkIGFsc28gdHJ5IHVzaW5nXG4gICAgLy8gYGZvcm0uZ2V0RWxlbWVudHNCeU5hbWVgLCBidXQgdGhhdCB3aWxsIG9ubHkgcmV0dXJuIGRpcmVjdCBjaGlsZHJlblxuICAgIC8vIGFuZCB3b24ndCBpbmNsdWRlIGlucHV0cyB0aGF0IHVzZSB0aGUgSFRNTDUgYGZvcm09YCBhdHRyaWJ1dGUuIFNpbmNlXG4gICAgLy8gdGhlIGlucHV0IG1pZ2h0IG5vdCBldmVuIGJlIGluIGEgZm9ybSwgbGV0J3MganVzdCB1c2UgdGhlIGdsb2JhbFxuICAgIC8vIGBxdWVyeVNlbGVjdG9yQWxsYCB0byBlbnN1cmUgd2UgZG9uJ3QgbWlzcyBhbnl0aGluZy5cbiAgICB2YXIgZ3JvdXAgPSBxdWVyeVJvb3QucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbbmFtZT0nICsgSlNPTi5zdHJpbmdpZnkoJycgKyBuYW1lKSArICddW3R5cGU9XCJyYWRpb1wiXScpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG90aGVyTm9kZSA9IGdyb3VwW2ldO1xuICAgICAgaWYgKG90aGVyTm9kZSA9PT0gcm9vdE5vZGUgfHwgb3RoZXJOb2RlLmZvcm0gIT09IHJvb3ROb2RlLmZvcm0pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgaWYgcmFkaW8gYnV0dG9ucyByZW5kZXJlZCBieSBkaWZmZXJlbnQgY29waWVzIG9mIFJlYWN0XG4gICAgICAvLyBhbmQgdGhlIHNhbWUgbmFtZSBhcmUgcmVuZGVyZWQgaW50byB0aGUgc2FtZSBmb3JtIChzYW1lIGFzICMxOTM5KS5cbiAgICAgIC8vIFRoYXQncyBwcm9iYWJseSBva2F5OyB3ZSBkb24ndCBzdXBwb3J0IGl0IGp1c3QgYXMgd2UgZG9uJ3Qgc3VwcG9ydFxuICAgICAgLy8gbWl4aW5nIFJlYWN0IHdpdGggbm9uLVJlYWN0LlxuICAgICAgdmFyIG90aGVySUQgPSBSZWFjdE1vdW50LmdldElEKG90aGVyTm9kZSk7XG4gICAgICAhb3RoZXJJRCA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdERPTUlucHV0OiBNaXhpbmcgUmVhY3QgYW5kIG5vbi1SZWFjdCByYWRpbyBpbnB1dHMgd2l0aCB0aGUgJyArICdzYW1lIGBuYW1lYCBpcyBub3Qgc3VwcG9ydGVkLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciBvdGhlckluc3RhbmNlID0gaW5zdGFuY2VzQnlSZWFjdElEW290aGVySURdO1xuICAgICAgIW90aGVySW5zdGFuY2UgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnUmVhY3RET01JbnB1dDogVW5rbm93biByYWRpbyBidXR0b24gSUQgJXMuJywgb3RoZXJJRCkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICAgLy8gSWYgdGhpcyBpcyBhIGNvbnRyb2xsZWQgcmFkaW8gYnV0dG9uIGdyb3VwLCBmb3JjaW5nIHRoZSBpbnB1dCB0aGF0XG4gICAgICAvLyB3YXMgcHJldmlvdXNseSBjaGVja2VkIHRvIHVwZGF0ZSB3aWxsIGNhdXNlIGl0IHRvIGJlIGNvbWUgcmUtY2hlY2tlZFxuICAgICAgLy8gYXMgYXBwcm9wcmlhdGUuXG4gICAgICBSZWFjdFVwZGF0ZXMuYXNhcChmb3JjZVVwZGF0ZUlmTW91bnRlZCwgb3RoZXJJbnN0YW5jZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldHVyblZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RE9NSW5wdXQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0RE9NT3B0aW9uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RDaGlsZHJlbiA9IHJlcXVpcmUoJy4vUmVhY3RDaGlsZHJlbicpO1xudmFyIFJlYWN0RE9NU2VsZWN0ID0gcmVxdWlyZSgnLi9SZWFjdERPTVNlbGVjdCcpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxudmFyIHZhbHVlQ29udGV4dEtleSA9IFJlYWN0RE9NU2VsZWN0LnZhbHVlQ29udGV4dEtleTtcblxuLyoqXG4gKiBJbXBsZW1lbnRzIGFuIDxvcHRpb24+IG5hdGl2ZSBjb21wb25lbnQgdGhhdCB3YXJucyB3aGVuIGBzZWxlY3RlZGAgaXMgc2V0LlxuICovXG52YXIgUmVhY3RET01PcHRpb24gPSB7XG4gIG1vdW50V3JhcHBlcjogZnVuY3Rpb24gKGluc3QsIHByb3BzLCBjb250ZXh0KSB7XG4gICAgLy8gVE9ETyAoeXVuZ3N0ZXJzKTogUmVtb3ZlIHN1cHBvcnQgZm9yIGBzZWxlY3RlZGAgaW4gPG9wdGlvbj4uXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKHByb3BzLnNlbGVjdGVkID09IG51bGwsICdVc2UgdGhlIGBkZWZhdWx0VmFsdWVgIG9yIGB2YWx1ZWAgcHJvcHMgb24gPHNlbGVjdD4gaW5zdGVhZCBvZiAnICsgJ3NldHRpbmcgYHNlbGVjdGVkYCBvbiA8b3B0aW9uPi4nKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBMb29rIHVwIHdoZXRoZXIgdGhpcyBvcHRpb24gaXMgJ3NlbGVjdGVkJyB2aWEgY29udGV4dFxuICAgIHZhciBzZWxlY3RWYWx1ZSA9IGNvbnRleHRbdmFsdWVDb250ZXh0S2V5XTtcblxuICAgIC8vIElmIGNvbnRleHQga2V5IGlzIG51bGwgKGUuZy4sIG5vIHNwZWNpZmllZCB2YWx1ZSBvciBhZnRlciBpbml0aWFsIG1vdW50KVxuICAgIC8vIG9yIG1pc3NpbmcgKGUuZy4sIGZvciA8ZGF0YWxpc3Q+KSwgd2UgZG9uJ3QgY2hhbmdlIHByb3BzLnNlbGVjdGVkXG4gICAgdmFyIHNlbGVjdGVkID0gbnVsbDtcbiAgICBpZiAoc2VsZWN0VmFsdWUgIT0gbnVsbCkge1xuICAgICAgc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGVjdFZhbHVlKSkge1xuICAgICAgICAvLyBtdWx0aXBsZVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdFZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKCcnICsgc2VsZWN0VmFsdWVbaV0gPT09ICcnICsgcHJvcHMudmFsdWUpIHtcbiAgICAgICAgICAgIHNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZWN0ZWQgPSAnJyArIHNlbGVjdFZhbHVlID09PSAnJyArIHByb3BzLnZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGluc3QuX3dyYXBwZXJTdGF0ZSA9IHsgc2VsZWN0ZWQ6IHNlbGVjdGVkIH07XG4gIH0sXG5cbiAgZ2V0TmF0aXZlUHJvcHM6IGZ1bmN0aW9uIChpbnN0LCBwcm9wcywgY29udGV4dCkge1xuICAgIHZhciBuYXRpdmVQcm9wcyA9IGFzc2lnbih7IHNlbGVjdGVkOiB1bmRlZmluZWQsIGNoaWxkcmVuOiB1bmRlZmluZWQgfSwgcHJvcHMpO1xuXG4gICAgLy8gUmVhZCBzdGF0ZSBvbmx5IGZyb20gaW5pdGlhbCBtb3VudCBiZWNhdXNlIDxzZWxlY3Q+IHVwZGF0ZXMgdmFsdWVcbiAgICAvLyBtYW51YWxseTsgd2UgbmVlZCB0aGUgaW5pdGlhbCBzdGF0ZSBvbmx5IGZvciBzZXJ2ZXIgcmVuZGVyaW5nXG4gICAgaWYgKGluc3QuX3dyYXBwZXJTdGF0ZS5zZWxlY3RlZCAhPSBudWxsKSB7XG4gICAgICBuYXRpdmVQcm9wcy5zZWxlY3RlZCA9IGluc3QuX3dyYXBwZXJTdGF0ZS5zZWxlY3RlZDtcbiAgICB9XG5cbiAgICB2YXIgY29udGVudCA9ICcnO1xuXG4gICAgLy8gRmxhdHRlbiBjaGlsZHJlbiBhbmQgd2FybiBpZiB0aGV5IGFyZW4ndCBzdHJpbmdzIG9yIG51bWJlcnM7XG4gICAgLy8gaW52YWxpZCB0eXBlcyBhcmUgaWdub3JlZC5cbiAgICBSZWFjdENoaWxkcmVuLmZvckVhY2gocHJvcHMuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjaGlsZCA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGNoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgICBjb250ZW50ICs9IGNoaWxkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdPbmx5IHN0cmluZ3MgYW5kIG51bWJlcnMgYXJlIHN1cHBvcnRlZCBhcyA8b3B0aW9uPiBjaGlsZHJlbi4nKSA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChjb250ZW50KSB7XG4gICAgICBuYXRpdmVQcm9wcy5jaGlsZHJlbiA9IGNvbnRlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hdGl2ZVByb3BzO1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RET01PcHRpb247IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0RE9NU2VsZWN0XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgTGlua2VkVmFsdWVVdGlscyA9IHJlcXVpcmUoJy4vTGlua2VkVmFsdWVVdGlscycpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcbnZhciBSZWFjdFVwZGF0ZXMgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlcycpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxudmFyIHZhbHVlQ29udGV4dEtleSA9ICdfX1JlYWN0RE9NU2VsZWN0X3ZhbHVlJCcgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcblxuZnVuY3Rpb24gdXBkYXRlT3B0aW9uc0lmUGVuZGluZ1VwZGF0ZUFuZE1vdW50ZWQoKSB7XG4gIGlmICh0aGlzLl9yb290Tm9kZUlEICYmIHRoaXMuX3dyYXBwZXJTdGF0ZS5wZW5kaW5nVXBkYXRlKSB7XG4gICAgdGhpcy5fd3JhcHBlclN0YXRlLnBlbmRpbmdVcGRhdGUgPSBmYWxzZTtcblxuICAgIHZhciBwcm9wcyA9IHRoaXMuX2N1cnJlbnRFbGVtZW50LnByb3BzO1xuICAgIHZhciB2YWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZ2V0VmFsdWUocHJvcHMpO1xuXG4gICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgIHVwZGF0ZU9wdGlvbnModGhpcywgQm9vbGVhbihwcm9wcy5tdWx0aXBsZSksIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKG93bmVyKSB7XG4gIGlmIChvd25lcikge1xuICAgIHZhciBuYW1lID0gb3duZXIuZ2V0TmFtZSgpO1xuICAgIGlmIChuYW1lKSB7XG4gICAgICByZXR1cm4gJyBDaGVjayB0aGUgcmVuZGVyIG1ldGhvZCBvZiBgJyArIG5hbWUgKyAnYC4nO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbnZhciB2YWx1ZVByb3BOYW1lcyA9IFsndmFsdWUnLCAnZGVmYXVsdFZhbHVlJ107XG5cbi8qKlxuICogVmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgYHZhbHVlYCBhbmQgYGRlZmF1bHRWYWx1ZWAuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjaGVja1NlbGVjdFByb3BUeXBlcyhpbnN0LCBwcm9wcykge1xuICB2YXIgb3duZXIgPSBpbnN0Ll9jdXJyZW50RWxlbWVudC5fb3duZXI7XG4gIExpbmtlZFZhbHVlVXRpbHMuY2hlY2tQcm9wVHlwZXMoJ3NlbGVjdCcsIHByb3BzLCBvd25lcik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZVByb3BOYW1lcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwcm9wTmFtZSA9IHZhbHVlUHJvcE5hbWVzW2ldO1xuICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChwcm9wcy5tdWx0aXBsZSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoQXJyYXkuaXNBcnJheShwcm9wc1twcm9wTmFtZV0pLCAnVGhlIGAlc2AgcHJvcCBzdXBwbGllZCB0byA8c2VsZWN0PiBtdXN0IGJlIGFuIGFycmF5IGlmICcgKyAnYG11bHRpcGxlYCBpcyB0cnVlLiVzJywgcHJvcE5hbWUsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShvd25lcikpIDogdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyghQXJyYXkuaXNBcnJheShwcm9wc1twcm9wTmFtZV0pLCAnVGhlIGAlc2AgcHJvcCBzdXBwbGllZCB0byA8c2VsZWN0PiBtdXN0IGJlIGEgc2NhbGFyICcgKyAndmFsdWUgaWYgYG11bHRpcGxlYCBpcyBmYWxzZS4lcycsIHByb3BOYW1lLCBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0ob3duZXIpKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1JlYWN0RE9NQ29tcG9uZW50fSBpbnN0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IG11bHRpcGxlXG4gKiBAcGFyYW0geyp9IHByb3BWYWx1ZSBBIHN0cmluZ2FibGUgKHdpdGggYG11bHRpcGxlYCwgYSBsaXN0IG9mIHN0cmluZ2FibGVzKS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZU9wdGlvbnMoaW5zdCwgbXVsdGlwbGUsIHByb3BWYWx1ZSkge1xuICB2YXIgc2VsZWN0ZWRWYWx1ZSwgaTtcbiAgdmFyIG9wdGlvbnMgPSBSZWFjdE1vdW50LmdldE5vZGUoaW5zdC5fcm9vdE5vZGVJRCkub3B0aW9ucztcblxuICBpZiAobXVsdGlwbGUpIHtcbiAgICBzZWxlY3RlZFZhbHVlID0ge307XG4gICAgZm9yIChpID0gMDsgaSA8IHByb3BWYWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgc2VsZWN0ZWRWYWx1ZVsnJyArIHByb3BWYWx1ZVtpXV0gPSB0cnVlO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNlbGVjdGVkID0gc2VsZWN0ZWRWYWx1ZS5oYXNPd25Qcm9wZXJ0eShvcHRpb25zW2ldLnZhbHVlKTtcbiAgICAgIGlmIChvcHRpb25zW2ldLnNlbGVjdGVkICE9PSBzZWxlY3RlZCkge1xuICAgICAgICBvcHRpb25zW2ldLnNlbGVjdGVkID0gc2VsZWN0ZWQ7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIERvIG5vdCBzZXQgYHNlbGVjdC52YWx1ZWAgYXMgZXhhY3QgYmVoYXZpb3IgaXNuJ3QgY29uc2lzdGVudCBhY3Jvc3MgYWxsXG4gICAgLy8gYnJvd3NlcnMgZm9yIGFsbCBjYXNlcy5cbiAgICBzZWxlY3RlZFZhbHVlID0gJycgKyBwcm9wVmFsdWU7XG4gICAgZm9yIChpID0gMDsgaSA8IG9wdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChvcHRpb25zW2ldLnZhbHVlID09PSBzZWxlY3RlZFZhbHVlKSB7XG4gICAgICAgIG9wdGlvbnNbaV0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxlbmd0aCkge1xuICAgICAgb3B0aW9uc1swXS5zZWxlY3RlZCA9IHRydWU7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBhIDxzZWxlY3Q+IG5hdGl2ZSBjb21wb25lbnQgdGhhdCBhbGxvd3Mgb3B0aW9uYWxseSBzZXR0aW5nIHRoZVxuICogcHJvcHMgYHZhbHVlYCBhbmQgYGRlZmF1bHRWYWx1ZWAuIElmIGBtdWx0aXBsZWAgaXMgZmFsc2UsIHRoZSBwcm9wIG11c3QgYmUgYVxuICogc3RyaW5nYWJsZS4gSWYgYG11bHRpcGxlYCBpcyB0cnVlLCB0aGUgcHJvcCBtdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ2FibGVzLlxuICpcbiAqIElmIGB2YWx1ZWAgaXMgbm90IHN1cHBsaWVkIChvciBudWxsL3VuZGVmaW5lZCksIHVzZXIgYWN0aW9ucyB0aGF0IGNoYW5nZSB0aGVcbiAqIHNlbGVjdGVkIG9wdGlvbiB3aWxsIHRyaWdnZXIgdXBkYXRlcyB0byB0aGUgcmVuZGVyZWQgb3B0aW9ucy5cbiAqXG4gKiBJZiBpdCBpcyBzdXBwbGllZCAoYW5kIG5vdCBudWxsL3VuZGVmaW5lZCksIHRoZSByZW5kZXJlZCBvcHRpb25zIHdpbGwgbm90XG4gKiB1cGRhdGUgaW4gcmVzcG9uc2UgdG8gdXNlciBhY3Rpb25zLiBJbnN0ZWFkLCB0aGUgYHZhbHVlYCBwcm9wIG11c3QgY2hhbmdlIGluXG4gKiBvcmRlciBmb3IgdGhlIHJlbmRlcmVkIG9wdGlvbnMgdG8gdXBkYXRlLlxuICpcbiAqIElmIGBkZWZhdWx0VmFsdWVgIGlzIHByb3ZpZGVkLCBhbnkgb3B0aW9ucyB3aXRoIHRoZSBzdXBwbGllZCB2YWx1ZXMgd2lsbCBiZVxuICogc2VsZWN0ZWQuXG4gKi9cbnZhciBSZWFjdERPTVNlbGVjdCA9IHtcbiAgdmFsdWVDb250ZXh0S2V5OiB2YWx1ZUNvbnRleHRLZXksXG5cbiAgZ2V0TmF0aXZlUHJvcHM6IGZ1bmN0aW9uIChpbnN0LCBwcm9wcywgY29udGV4dCkge1xuICAgIHJldHVybiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICBvbkNoYW5nZTogaW5zdC5fd3JhcHBlclN0YXRlLm9uQ2hhbmdlLFxuICAgICAgdmFsdWU6IHVuZGVmaW5lZFxuICAgIH0pO1xuICB9LFxuXG4gIG1vdW50V3JhcHBlcjogZnVuY3Rpb24gKGluc3QsIHByb3BzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGNoZWNrU2VsZWN0UHJvcFR5cGVzKGluc3QsIHByb3BzKTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSBMaW5rZWRWYWx1ZVV0aWxzLmdldFZhbHVlKHByb3BzKTtcbiAgICBpbnN0Ll93cmFwcGVyU3RhdGUgPSB7XG4gICAgICBwZW5kaW5nVXBkYXRlOiBmYWxzZSxcbiAgICAgIGluaXRpYWxWYWx1ZTogdmFsdWUgIT0gbnVsbCA/IHZhbHVlIDogcHJvcHMuZGVmYXVsdFZhbHVlLFxuICAgICAgb25DaGFuZ2U6IF9oYW5kbGVDaGFuZ2UuYmluZChpbnN0KSxcbiAgICAgIHdhc011bHRpcGxlOiBCb29sZWFuKHByb3BzLm11bHRpcGxlKVxuICAgIH07XG4gIH0sXG5cbiAgcHJvY2Vzc0NoaWxkQ29udGV4dDogZnVuY3Rpb24gKGluc3QsIHByb3BzLCBjb250ZXh0KSB7XG4gICAgLy8gUGFzcyBkb3duIGluaXRpYWwgdmFsdWUgc28gaW5pdGlhbCBnZW5lcmF0ZWQgbWFya3VwIGhhcyBjb3JyZWN0XG4gICAgLy8gYHNlbGVjdGVkYCBhdHRyaWJ1dGVzXG4gICAgdmFyIGNoaWxkQ29udGV4dCA9IGFzc2lnbih7fSwgY29udGV4dCk7XG4gICAgY2hpbGRDb250ZXh0W3ZhbHVlQ29udGV4dEtleV0gPSBpbnN0Ll93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlO1xuICAgIHJldHVybiBjaGlsZENvbnRleHQ7XG4gIH0sXG5cbiAgcG9zdFVwZGF0ZVdyYXBwZXI6IGZ1bmN0aW9uIChpbnN0KSB7XG4gICAgdmFyIHByb3BzID0gaW5zdC5fY3VycmVudEVsZW1lbnQucHJvcHM7XG5cbiAgICAvLyBBZnRlciB0aGUgaW5pdGlhbCBtb3VudCwgd2UgY29udHJvbCBzZWxlY3RlZC1uZXNzIG1hbnVhbGx5IHNvIGRvbid0IHBhc3NcbiAgICAvLyB0aGUgY29udGV4dCB2YWx1ZSBkb3duXG4gICAgaW5zdC5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSA9IHVuZGVmaW5lZDtcblxuICAgIHZhciB3YXNNdWx0aXBsZSA9IGluc3QuX3dyYXBwZXJTdGF0ZS53YXNNdWx0aXBsZTtcbiAgICBpbnN0Ll93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGUgPSBCb29sZWFuKHByb3BzLm11bHRpcGxlKTtcblxuICAgIHZhciB2YWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZ2V0VmFsdWUocHJvcHMpO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICBpbnN0Ll93cmFwcGVyU3RhdGUucGVuZGluZ1VwZGF0ZSA9IGZhbHNlO1xuICAgICAgdXBkYXRlT3B0aW9ucyhpbnN0LCBCb29sZWFuKHByb3BzLm11bHRpcGxlKSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAod2FzTXVsdGlwbGUgIT09IEJvb2xlYW4ocHJvcHMubXVsdGlwbGUpKSB7XG4gICAgICAvLyBGb3Igc2ltcGxpY2l0eSwgcmVhcHBseSBgZGVmYXVsdFZhbHVlYCBpZiBgbXVsdGlwbGVgIGlzIHRvZ2dsZWQuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgdXBkYXRlT3B0aW9ucyhpbnN0LCBCb29sZWFuKHByb3BzLm11bHRpcGxlKSwgcHJvcHMuZGVmYXVsdFZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJldmVydCB0aGUgc2VsZWN0IGJhY2sgdG8gaXRzIGRlZmF1bHQgdW5zZWxlY3RlZCBzdGF0ZS5cbiAgICAgICAgdXBkYXRlT3B0aW9ucyhpbnN0LCBCb29sZWFuKHByb3BzLm11bHRpcGxlKSwgcHJvcHMubXVsdGlwbGUgPyBbXSA6ICcnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9oYW5kbGVDaGFuZ2UoZXZlbnQpIHtcbiAgdmFyIHByb3BzID0gdGhpcy5fY3VycmVudEVsZW1lbnQucHJvcHM7XG4gIHZhciByZXR1cm5WYWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZXhlY3V0ZU9uQ2hhbmdlKHByb3BzLCBldmVudCk7XG5cbiAgdGhpcy5fd3JhcHBlclN0YXRlLnBlbmRpbmdVcGRhdGUgPSB0cnVlO1xuICBSZWFjdFVwZGF0ZXMuYXNhcCh1cGRhdGVPcHRpb25zSWZQZW5kaW5nVXBkYXRlQW5kTW91bnRlZCwgdGhpcyk7XG4gIHJldHVybiByZXR1cm5WYWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdERPTVNlbGVjdDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RET01TZWxlY3Rpb25cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJ2ZianMvbGliL0V4ZWN1dGlvbkVudmlyb25tZW50Jyk7XG5cbnZhciBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0ID0gcmVxdWlyZSgnLi9nZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0Jyk7XG52YXIgZ2V0VGV4dENvbnRlbnRBY2Nlc3NvciA9IHJlcXVpcmUoJy4vZ2V0VGV4dENvbnRlbnRBY2Nlc3NvcicpO1xuXG4vKipcbiAqIFdoaWxlIGBpc0NvbGxhcHNlZGAgaXMgYXZhaWxhYmxlIG9uIHRoZSBTZWxlY3Rpb24gb2JqZWN0IGFuZCBgY29sbGFwc2VkYFxuICogaXMgYXZhaWxhYmxlIG9uIHRoZSBSYW5nZSBvYmplY3QsIElFMTEgc29tZXRpbWVzIGdldHMgdGhlbSB3cm9uZy5cbiAqIElmIHRoZSBhbmNob3IvZm9jdXMgbm9kZXMgYW5kIG9mZnNldHMgYXJlIHRoZSBzYW1lLCB0aGUgcmFuZ2UgaXMgY29sbGFwc2VkLlxuICovXG5mdW5jdGlvbiBpc0NvbGxhcHNlZChhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpIHtcbiAgcmV0dXJuIGFuY2hvck5vZGUgPT09IGZvY3VzTm9kZSAmJiBhbmNob3JPZmZzZXQgPT09IGZvY3VzT2Zmc2V0O1xufVxuXG4vKipcbiAqIEdldCB0aGUgYXBwcm9wcmlhdGUgYW5jaG9yIGFuZCBmb2N1cyBub2RlL29mZnNldCBwYWlycyBmb3IgSUUuXG4gKlxuICogVGhlIGNhdGNoIGhlcmUgaXMgdGhhdCBJRSdzIHNlbGVjdGlvbiBBUEkgZG9lc24ndCBwcm92aWRlIGluZm9ybWF0aW9uXG4gKiBhYm91dCB3aGV0aGVyIHRoZSBzZWxlY3Rpb24gaXMgZm9yd2FyZCBvciBiYWNrd2FyZCwgc28gd2UgaGF2ZSB0b1xuICogYmVoYXZlIGFzIHRob3VnaCBpdCdzIGFsd2F5cyBmb3J3YXJkLlxuICpcbiAqIElFIHRleHQgZGlmZmVycyBmcm9tIG1vZGVybiBzZWxlY3Rpb24gaW4gdGhhdCBpdCBiZWhhdmVzIGFzIHRob3VnaFxuICogYmxvY2sgZWxlbWVudHMgZW5kIHdpdGggYSBuZXcgbGluZS4gVGhpcyBtZWFucyBjaGFyYWN0ZXIgb2Zmc2V0cyB3aWxsXG4gKiBkaWZmZXIgYmV0d2VlbiB0aGUgdHdvIEFQSXMuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGdldElFT2Zmc2V0cyhub2RlKSB7XG4gIHZhciBzZWxlY3Rpb24gPSBkb2N1bWVudC5zZWxlY3Rpb247XG4gIHZhciBzZWxlY3RlZFJhbmdlID0gc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7XG4gIHZhciBzZWxlY3RlZExlbmd0aCA9IHNlbGVjdGVkUmFuZ2UudGV4dC5sZW5ndGg7XG5cbiAgLy8gRHVwbGljYXRlIHNlbGVjdGlvbiBzbyB3ZSBjYW4gbW92ZSByYW5nZSB3aXRob3V0IGJyZWFraW5nIHVzZXIgc2VsZWN0aW9uLlxuICB2YXIgZnJvbVN0YXJ0ID0gc2VsZWN0ZWRSYW5nZS5kdXBsaWNhdGUoKTtcbiAgZnJvbVN0YXJ0Lm1vdmVUb0VsZW1lbnRUZXh0KG5vZGUpO1xuICBmcm9tU3RhcnQuc2V0RW5kUG9pbnQoJ0VuZFRvU3RhcnQnLCBzZWxlY3RlZFJhbmdlKTtcblxuICB2YXIgc3RhcnRPZmZzZXQgPSBmcm9tU3RhcnQudGV4dC5sZW5ndGg7XG4gIHZhciBlbmRPZmZzZXQgPSBzdGFydE9mZnNldCArIHNlbGVjdGVkTGVuZ3RoO1xuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IHN0YXJ0T2Zmc2V0LFxuICAgIGVuZDogZW5kT2Zmc2V0XG4gIH07XG59XG5cbi8qKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcmV0dXJuIHs/b2JqZWN0fVxuICovXG5mdW5jdGlvbiBnZXRNb2Rlcm5PZmZzZXRzKG5vZGUpIHtcbiAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24gJiYgd2luZG93LmdldFNlbGVjdGlvbigpO1xuXG4gIGlmICghc2VsZWN0aW9uIHx8IHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgYW5jaG9yTm9kZSA9IHNlbGVjdGlvbi5hbmNob3JOb2RlO1xuICB2YXIgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldDtcbiAgdmFyIGZvY3VzTm9kZSA9IHNlbGVjdGlvbi5mb2N1c05vZGU7XG4gIHZhciBmb2N1c09mZnNldCA9IHNlbGVjdGlvbi5mb2N1c09mZnNldDtcblxuICB2YXIgY3VycmVudFJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG5cbiAgLy8gSW4gRmlyZWZveCwgcmFuZ2Uuc3RhcnRDb250YWluZXIgYW5kIHJhbmdlLmVuZENvbnRhaW5lciBjYW4gYmUgXCJhbm9ueW1vdXNcbiAgLy8gZGl2c1wiLCBlLmcuIHRoZSB1cC9kb3duIGJ1dHRvbnMgb24gYW4gPGlucHV0IHR5cGU9XCJudW1iZXJcIj4uIEFub255bW91c1xuICAvLyBkaXZzIGRvIG5vdCBzZWVtIHRvIGV4cG9zZSBwcm9wZXJ0aWVzLCB0cmlnZ2VyaW5nIGEgXCJQZXJtaXNzaW9uIGRlbmllZFxuICAvLyBlcnJvclwiIGlmIGFueSBvZiBpdHMgcHJvcGVydGllcyBhcmUgYWNjZXNzZWQuIFRoZSBvbmx5IHNlZW1pbmdseSBwb3NzaWJsZVxuICAvLyB3YXkgdG8gYXZvaWQgZXJyb3JpbmcgaXMgdG8gYWNjZXNzIGEgcHJvcGVydHkgdGhhdCB0eXBpY2FsbHkgd29ya3MgZm9yXG4gIC8vIG5vbi1hbm9ueW1vdXMgZGl2cyBhbmQgY2F0Y2ggYW55IGVycm9yIHRoYXQgbWF5IG90aGVyd2lzZSBhcmlzZS4gU2VlXG4gIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTIwODQyN1xuICB0cnkge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC1leHByZXNzaW9ucyAqL1xuICAgIGN1cnJlbnRSYW5nZS5zdGFydENvbnRhaW5lci5ub2RlVHlwZTtcbiAgICBjdXJyZW50UmFuZ2UuZW5kQ29udGFpbmVyLm5vZGVUeXBlO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLWV4cHJlc3Npb25zICovXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIElmIHRoZSBub2RlIGFuZCBvZmZzZXQgdmFsdWVzIGFyZSB0aGUgc2FtZSwgdGhlIHNlbGVjdGlvbiBpcyBjb2xsYXBzZWQuXG4gIC8vIGBTZWxlY3Rpb24uaXNDb2xsYXBzZWRgIGlzIGF2YWlsYWJsZSBuYXRpdmVseSwgYnV0IElFIHNvbWV0aW1lcyBnZXRzXG4gIC8vIHRoaXMgdmFsdWUgd3JvbmcuXG4gIHZhciBpc1NlbGVjdGlvbkNvbGxhcHNlZCA9IGlzQ29sbGFwc2VkKHNlbGVjdGlvbi5hbmNob3JOb2RlLCBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LCBzZWxlY3Rpb24uZm9jdXNOb2RlLCBzZWxlY3Rpb24uZm9jdXNPZmZzZXQpO1xuXG4gIHZhciByYW5nZUxlbmd0aCA9IGlzU2VsZWN0aW9uQ29sbGFwc2VkID8gMCA6IGN1cnJlbnRSYW5nZS50b1N0cmluZygpLmxlbmd0aDtcblxuICB2YXIgdGVtcFJhbmdlID0gY3VycmVudFJhbmdlLmNsb25lUmFuZ2UoKTtcbiAgdGVtcFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhub2RlKTtcbiAgdGVtcFJhbmdlLnNldEVuZChjdXJyZW50UmFuZ2Uuc3RhcnRDb250YWluZXIsIGN1cnJlbnRSYW5nZS5zdGFydE9mZnNldCk7XG5cbiAgdmFyIGlzVGVtcFJhbmdlQ29sbGFwc2VkID0gaXNDb2xsYXBzZWQodGVtcFJhbmdlLnN0YXJ0Q29udGFpbmVyLCB0ZW1wUmFuZ2Uuc3RhcnRPZmZzZXQsIHRlbXBSYW5nZS5lbmRDb250YWluZXIsIHRlbXBSYW5nZS5lbmRPZmZzZXQpO1xuXG4gIHZhciBzdGFydCA9IGlzVGVtcFJhbmdlQ29sbGFwc2VkID8gMCA6IHRlbXBSYW5nZS50b1N0cmluZygpLmxlbmd0aDtcbiAgdmFyIGVuZCA9IHN0YXJ0ICsgcmFuZ2VMZW5ndGg7XG5cbiAgLy8gRGV0ZWN0IHdoZXRoZXIgdGhlIHNlbGVjdGlvbiBpcyBiYWNrd2FyZC5cbiAgdmFyIGRldGVjdGlvblJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgZGV0ZWN0aW9uUmFuZ2Uuc2V0U3RhcnQoYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0KTtcbiAgZGV0ZWN0aW9uUmFuZ2Uuc2V0RW5kKGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpO1xuICB2YXIgaXNCYWNrd2FyZCA9IGRldGVjdGlvblJhbmdlLmNvbGxhcHNlZDtcblxuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBpc0JhY2t3YXJkID8gZW5kIDogc3RhcnQsXG4gICAgZW5kOiBpc0JhY2t3YXJkID8gc3RhcnQgOiBlbmRcbiAgfTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9IG5vZGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBvZmZzZXRzXG4gKi9cbmZ1bmN0aW9uIHNldElFT2Zmc2V0cyhub2RlLCBvZmZzZXRzKSB7XG4gIHZhciByYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpLmR1cGxpY2F0ZSgpO1xuICB2YXIgc3RhcnQsIGVuZDtcblxuICBpZiAodHlwZW9mIG9mZnNldHMuZW5kID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0YXJ0ID0gb2Zmc2V0cy5zdGFydDtcbiAgICBlbmQgPSBzdGFydDtcbiAgfSBlbHNlIGlmIChvZmZzZXRzLnN0YXJ0ID4gb2Zmc2V0cy5lbmQpIHtcbiAgICBzdGFydCA9IG9mZnNldHMuZW5kO1xuICAgIGVuZCA9IG9mZnNldHMuc3RhcnQ7XG4gIH0gZWxzZSB7XG4gICAgc3RhcnQgPSBvZmZzZXRzLnN0YXJ0O1xuICAgIGVuZCA9IG9mZnNldHMuZW5kO1xuICB9XG5cbiAgcmFuZ2UubW92ZVRvRWxlbWVudFRleHQobm9kZSk7XG4gIHJhbmdlLm1vdmVTdGFydCgnY2hhcmFjdGVyJywgc3RhcnQpO1xuICByYW5nZS5zZXRFbmRQb2ludCgnRW5kVG9TdGFydCcsIHJhbmdlKTtcbiAgcmFuZ2UubW92ZUVuZCgnY2hhcmFjdGVyJywgZW5kIC0gc3RhcnQpO1xuICByYW5nZS5zZWxlY3QoKTtcbn1cblxuLyoqXG4gKiBJbiBtb2Rlcm4gbm9uLUlFIGJyb3dzZXJzLCB3ZSBjYW4gc3VwcG9ydCBib3RoIGZvcndhcmQgYW5kIGJhY2t3YXJkXG4gKiBzZWxlY3Rpb25zLlxuICpcbiAqIE5vdGU6IElFMTArIHN1cHBvcnRzIHRoZSBTZWxlY3Rpb24gb2JqZWN0LCBidXQgaXQgZG9lcyBub3Qgc3VwcG9ydFxuICogdGhlIGBleHRlbmRgIG1ldGhvZCwgd2hpY2ggbWVhbnMgdGhhdCBldmVuIGluIG1vZGVybiBJRSwgaXQncyBub3QgcG9zc2libGVcbiAqIHRvIHByb2dyYW1hdGljYWxseSBjcmVhdGUgYSBiYWNrd2FyZCBzZWxlY3Rpb24uIFRodXMsIGZvciBhbGwgSUVcbiAqIHZlcnNpb25zLCB3ZSB1c2UgdGhlIG9sZCBJRSBBUEkgdG8gY3JlYXRlIG91ciBzZWxlY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtvYmplY3R9IG9mZnNldHNcbiAqL1xuZnVuY3Rpb24gc2V0TW9kZXJuT2Zmc2V0cyhub2RlLCBvZmZzZXRzKSB7XG4gIGlmICghd2luZG93LmdldFNlbGVjdGlvbikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gIHZhciBsZW5ndGggPSBub2RlW2dldFRleHRDb250ZW50QWNjZXNzb3IoKV0ubGVuZ3RoO1xuICB2YXIgc3RhcnQgPSBNYXRoLm1pbihvZmZzZXRzLnN0YXJ0LCBsZW5ndGgpO1xuICB2YXIgZW5kID0gdHlwZW9mIG9mZnNldHMuZW5kID09PSAndW5kZWZpbmVkJyA/IHN0YXJ0IDogTWF0aC5taW4ob2Zmc2V0cy5lbmQsIGxlbmd0aCk7XG5cbiAgLy8gSUUgMTEgdXNlcyBtb2Rlcm4gc2VsZWN0aW9uLCBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBleHRlbmQgbWV0aG9kLlxuICAvLyBGbGlwIGJhY2t3YXJkIHNlbGVjdGlvbnMsIHNvIHdlIGNhbiBzZXQgd2l0aCBhIHNpbmdsZSByYW5nZS5cbiAgaWYgKCFzZWxlY3Rpb24uZXh0ZW5kICYmIHN0YXJ0ID4gZW5kKSB7XG4gICAgdmFyIHRlbXAgPSBlbmQ7XG4gICAgZW5kID0gc3RhcnQ7XG4gICAgc3RhcnQgPSB0ZW1wO1xuICB9XG5cbiAgdmFyIHN0YXJ0TWFya2VyID0gZ2V0Tm9kZUZvckNoYXJhY3Rlck9mZnNldChub2RlLCBzdGFydCk7XG4gIHZhciBlbmRNYXJrZXIgPSBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0KG5vZGUsIGVuZCk7XG5cbiAgaWYgKHN0YXJ0TWFya2VyICYmIGVuZE1hcmtlcikge1xuICAgIHZhciByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnRNYXJrZXIubm9kZSwgc3RhcnRNYXJrZXIub2Zmc2V0KTtcbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG5cbiAgICBpZiAoc3RhcnQgPiBlbmQpIHtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgICBzZWxlY3Rpb24uZXh0ZW5kKGVuZE1hcmtlci5ub2RlLCBlbmRNYXJrZXIub2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmFuZ2Uuc2V0RW5kKGVuZE1hcmtlci5ub2RlLCBlbmRNYXJrZXIub2Zmc2V0KTtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgfVxuICB9XG59XG5cbnZhciB1c2VJRU9mZnNldHMgPSBFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00gJiYgJ3NlbGVjdGlvbicgaW4gZG9jdW1lbnQgJiYgISgnZ2V0U2VsZWN0aW9uJyBpbiB3aW5kb3cpO1xuXG52YXIgUmVhY3RET01TZWxlY3Rpb24gPSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG5vZGVcbiAgICovXG4gIGdldE9mZnNldHM6IHVzZUlFT2Zmc2V0cyA/IGdldElFT2Zmc2V0cyA6IGdldE1vZGVybk9mZnNldHMsXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICAgKiBAcGFyYW0ge29iamVjdH0gb2Zmc2V0c1xuICAgKi9cbiAgc2V0T2Zmc2V0czogdXNlSUVPZmZzZXRzID8gc2V0SUVPZmZzZXRzIDogc2V0TW9kZXJuT2Zmc2V0c1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdERPTVNlbGVjdGlvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RET01TZXJ2ZXJcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdERlZmF1bHRJbmplY3Rpb24gPSByZXF1aXJlKCcuL1JlYWN0RGVmYXVsdEluamVjdGlvbicpO1xudmFyIFJlYWN0U2VydmVyUmVuZGVyaW5nID0gcmVxdWlyZSgnLi9SZWFjdFNlcnZlclJlbmRlcmluZycpO1xudmFyIFJlYWN0VmVyc2lvbiA9IHJlcXVpcmUoJy4vUmVhY3RWZXJzaW9uJyk7XG5cblJlYWN0RGVmYXVsdEluamVjdGlvbi5pbmplY3QoKTtcblxudmFyIFJlYWN0RE9NU2VydmVyID0ge1xuICByZW5kZXJUb1N0cmluZzogUmVhY3RTZXJ2ZXJSZW5kZXJpbmcucmVuZGVyVG9TdHJpbmcsXG4gIHJlbmRlclRvU3RhdGljTWFya3VwOiBSZWFjdFNlcnZlclJlbmRlcmluZy5yZW5kZXJUb1N0YXRpY01hcmt1cCxcbiAgdmVyc2lvbjogUmVhY3RWZXJzaW9uXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RE9NU2VydmVyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERPTVRleHRDb21wb25lbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRE9NQ2hpbGRyZW5PcGVyYXRpb25zID0gcmVxdWlyZSgnLi9ET01DaGlsZHJlbk9wZXJhdGlvbnMnKTtcbnZhciBET01Qcm9wZXJ0eU9wZXJhdGlvbnMgPSByZXF1aXJlKCcuL0RPTVByb3BlcnR5T3BlcmF0aW9ucycpO1xudmFyIFJlYWN0Q29tcG9uZW50QnJvd3NlckVudmlyb25tZW50ID0gcmVxdWlyZSgnLi9SZWFjdENvbXBvbmVudEJyb3dzZXJFbnZpcm9ubWVudCcpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGVzY2FwZVRleHRDb250ZW50Rm9yQnJvd3NlciA9IHJlcXVpcmUoJy4vZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyJyk7XG52YXIgc2V0VGV4dENvbnRlbnQgPSByZXF1aXJlKCcuL3NldFRleHRDb250ZW50Jyk7XG52YXIgdmFsaWRhdGVET01OZXN0aW5nID0gcmVxdWlyZSgnLi92YWxpZGF0ZURPTU5lc3RpbmcnKTtcblxuLyoqXG4gKiBUZXh0IG5vZGVzIHZpb2xhdGUgYSBjb3VwbGUgYXNzdW1wdGlvbnMgdGhhdCBSZWFjdCBtYWtlcyBhYm91dCBjb21wb25lbnRzOlxuICpcbiAqICAtIFdoZW4gbW91bnRpbmcgdGV4dCBpbnRvIHRoZSBET00sIGFkamFjZW50IHRleHQgbm9kZXMgYXJlIG1lcmdlZC5cbiAqICAtIFRleHQgbm9kZXMgY2Fubm90IGJlIGFzc2lnbmVkIGEgUmVhY3Qgcm9vdCBJRC5cbiAqXG4gKiBUaGlzIGNvbXBvbmVudCBpcyB1c2VkIHRvIHdyYXAgc3RyaW5ncyBpbiBlbGVtZW50cyBzbyB0aGF0IHRoZXkgY2FuIHVuZGVyZ29cbiAqIHRoZSBzYW1lIHJlY29uY2lsaWF0aW9uIHRoYXQgaXMgYXBwbGllZCB0byBlbGVtZW50cy5cbiAqXG4gKiBUT0RPOiBJbnZlc3RpZ2F0ZSByZXByZXNlbnRpbmcgUmVhY3QgY29tcG9uZW50cyBpbiB0aGUgRE9NIHdpdGggdGV4dCBub2Rlcy5cbiAqXG4gKiBAY2xhc3MgUmVhY3RET01UZXh0Q29tcG9uZW50XG4gKiBAZXh0ZW5kcyBSZWFjdENvbXBvbmVudFxuICogQGludGVybmFsXG4gKi9cbnZhciBSZWFjdERPTVRleHRDb21wb25lbnQgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgLy8gVGhpcyBjb25zdHJ1Y3RvciBhbmQgaXRzIGFyZ3VtZW50IGlzIGN1cnJlbnRseSB1c2VkIGJ5IG1vY2tzLlxufTtcblxuYXNzaWduKFJlYWN0RE9NVGV4dENvbXBvbmVudC5wcm90b3R5cGUsIHtcblxuICAvKipcbiAgICogQHBhcmFtIHtSZWFjdFRleHR9IHRleHRcbiAgICogQGludGVybmFsXG4gICAqL1xuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgLy8gVE9ETzogVGhpcyBpcyByZWFsbHkgYSBSZWFjdFRleHQgKFJlYWN0Tm9kZSksIG5vdCBhIFJlYWN0RWxlbWVudFxuICAgIHRoaXMuX2N1cnJlbnRFbGVtZW50ID0gdGV4dDtcbiAgICB0aGlzLl9zdHJpbmdUZXh0ID0gJycgKyB0ZXh0O1xuXG4gICAgLy8gUHJvcGVydGllc1xuICAgIHRoaXMuX3Jvb3ROb2RlSUQgPSBudWxsO1xuICAgIHRoaXMuX21vdW50SW5kZXggPSAwO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBtYXJrdXAgZm9yIHRoaXMgdGV4dCBub2RlLiBUaGlzIG5vZGUgaXMgbm90IGludGVuZGVkIHRvIGhhdmVcbiAgICogYW55IGZlYXR1cmVzIGJlc2lkZXMgY29udGFpbmluZyB0ZXh0IGNvbnRlbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb290SUQgRE9NIElEIG9mIHRoZSByb290IG5vZGUuXG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbnxSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IE1hcmt1cCBmb3IgdGhpcyB0ZXh0IG5vZGUuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgbW91bnRDb21wb25lbnQ6IGZ1bmN0aW9uIChyb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmIChjb250ZXh0W3ZhbGlkYXRlRE9NTmVzdGluZy5hbmNlc3RvckluZm9Db250ZXh0S2V5XSkge1xuICAgICAgICB2YWxpZGF0ZURPTU5lc3RpbmcoJ3NwYW4nLCBudWxsLCBjb250ZXh0W3ZhbGlkYXRlRE9NTmVzdGluZy5hbmNlc3RvckluZm9Db250ZXh0S2V5XSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fcm9vdE5vZGVJRCA9IHJvb3RJRDtcbiAgICBpZiAodHJhbnNhY3Rpb24udXNlQ3JlYXRlRWxlbWVudCkge1xuICAgICAgdmFyIG93bmVyRG9jdW1lbnQgPSBjb250ZXh0W1JlYWN0TW91bnQub3duZXJEb2N1bWVudENvbnRleHRLZXldO1xuICAgICAgdmFyIGVsID0gb3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBET01Qcm9wZXJ0eU9wZXJhdGlvbnMuc2V0QXR0cmlidXRlRm9ySUQoZWwsIHJvb3RJRCk7XG4gICAgICAvLyBQb3B1bGF0ZSBub2RlIGNhY2hlXG4gICAgICBSZWFjdE1vdW50LmdldElEKGVsKTtcbiAgICAgIHNldFRleHRDb250ZW50KGVsLCB0aGlzLl9zdHJpbmdUZXh0KTtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGVzY2FwZWRUZXh0ID0gZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyKHRoaXMuX3N0cmluZ1RleHQpO1xuXG4gICAgICBpZiAodHJhbnNhY3Rpb24ucmVuZGVyVG9TdGF0aWNNYXJrdXApIHtcbiAgICAgICAgLy8gTm9ybWFsbHkgd2UnZCB3cmFwIHRoaXMgaW4gYSBgc3BhbmAgZm9yIHRoZSByZWFzb25zIHN0YXRlZCBhYm92ZSwgYnV0XG4gICAgICAgIC8vIHNpbmNlIHRoaXMgaXMgYSBzaXR1YXRpb24gd2hlcmUgUmVhY3Qgd29uJ3QgdGFrZSBvdmVyIChzdGF0aWMgcGFnZXMpLFxuICAgICAgICAvLyB3ZSBjYW4gc2ltcGx5IHJldHVybiB0aGUgdGV4dCBhcyBpdCBpcy5cbiAgICAgICAgcmV0dXJuIGVzY2FwZWRUZXh0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJzxzcGFuICcgKyBET01Qcm9wZXJ0eU9wZXJhdGlvbnMuY3JlYXRlTWFya3VwRm9ySUQocm9vdElEKSArICc+JyArIGVzY2FwZWRUZXh0ICsgJzwvc3Bhbj4nO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogVXBkYXRlcyB0aGlzIGNvbXBvbmVudCBieSB1cGRhdGluZyB0aGUgdGV4dCBjb250ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1JlYWN0VGV4dH0gbmV4dFRleHQgVGhlIG5leHQgdGV4dCBjb250ZW50XG4gICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQGludGVybmFsXG4gICAqL1xuICByZWNlaXZlQ29tcG9uZW50OiBmdW5jdGlvbiAobmV4dFRleHQsIHRyYW5zYWN0aW9uKSB7XG4gICAgaWYgKG5leHRUZXh0ICE9PSB0aGlzLl9jdXJyZW50RWxlbWVudCkge1xuICAgICAgdGhpcy5fY3VycmVudEVsZW1lbnQgPSBuZXh0VGV4dDtcbiAgICAgIHZhciBuZXh0U3RyaW5nVGV4dCA9ICcnICsgbmV4dFRleHQ7XG4gICAgICBpZiAobmV4dFN0cmluZ1RleHQgIT09IHRoaXMuX3N0cmluZ1RleHQpIHtcbiAgICAgICAgLy8gVE9ETzogU2F2ZSB0aGlzIGFzIHBlbmRpbmcgcHJvcHMgYW5kIHVzZSBwZXJmb3JtVXBkYXRlSWZOZWNlc3NhcnlcbiAgICAgICAgLy8gYW5kL29yIHVwZGF0ZUNvbXBvbmVudCB0byBkbyB0aGUgYWN0dWFsIHVwZGF0ZSBmb3IgY29uc2lzdGVuY3kgd2l0aFxuICAgICAgICAvLyBvdGhlciBjb21wb25lbnQgdHlwZXM/XG4gICAgICAgIHRoaXMuX3N0cmluZ1RleHQgPSBuZXh0U3RyaW5nVGV4dDtcbiAgICAgICAgdmFyIG5vZGUgPSBSZWFjdE1vdW50LmdldE5vZGUodGhpcy5fcm9vdE5vZGVJRCk7XG4gICAgICAgIERPTUNoaWxkcmVuT3BlcmF0aW9ucy51cGRhdGVUZXh0Q29udGVudChub2RlLCBuZXh0U3RyaW5nVGV4dCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVubW91bnRDb21wb25lbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBSZWFjdENvbXBvbmVudEJyb3dzZXJFbnZpcm9ubWVudC51bm1vdW50SURGcm9tRW52aXJvbm1lbnQodGhpcy5fcm9vdE5vZGVJRCk7XG4gIH1cblxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RET01UZXh0Q29tcG9uZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERPTVRleHRhcmVhXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgTGlua2VkVmFsdWVVdGlscyA9IHJlcXVpcmUoJy4vTGlua2VkVmFsdWVVdGlscycpO1xudmFyIFJlYWN0RE9NSURPcGVyYXRpb25zID0gcmVxdWlyZSgnLi9SZWFjdERPTUlET3BlcmF0aW9ucycpO1xudmFyIFJlYWN0VXBkYXRlcyA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVzJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG5mdW5jdGlvbiBmb3JjZVVwZGF0ZUlmTW91bnRlZCgpIHtcbiAgaWYgKHRoaXMuX3Jvb3ROb2RlSUQpIHtcbiAgICAvLyBET00gY29tcG9uZW50IGlzIHN0aWxsIG1vdW50ZWQ7IHVwZGF0ZVxuICAgIFJlYWN0RE9NVGV4dGFyZWEudXBkYXRlV3JhcHBlcih0aGlzKTtcbiAgfVxufVxuXG4vKipcbiAqIEltcGxlbWVudHMgYSA8dGV4dGFyZWE+IG5hdGl2ZSBjb21wb25lbnQgdGhhdCBhbGxvd3Mgc2V0dGluZyBgdmFsdWVgLCBhbmRcbiAqIGBkZWZhdWx0VmFsdWVgLiBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgdHJhZGl0aW9uYWwgRE9NIEFQSSBiZWNhdXNlIHZhbHVlIGlzXG4gKiB1c3VhbGx5IHNldCBhcyBQQ0RBVEEgY2hpbGRyZW4uXG4gKlxuICogSWYgYHZhbHVlYCBpcyBub3Qgc3VwcGxpZWQgKG9yIG51bGwvdW5kZWZpbmVkKSwgdXNlciBhY3Rpb25zIHRoYXQgYWZmZWN0IHRoZVxuICogdmFsdWUgd2lsbCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgYHZhbHVlYCBpcyBzdXBwbGllZCAoYW5kIG5vdCBudWxsL3VuZGVmaW5lZCksIHRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGxcbiAqIG5vdCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuIEluc3RlYWQsIHRoZSBgdmFsdWVgIHByb3AgbXVzdCBjaGFuZ2UgaW5cbiAqIG9yZGVyIGZvciB0aGUgcmVuZGVyZWQgZWxlbWVudCB0byBiZSB1cGRhdGVkLlxuICpcbiAqIFRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGwgYmUgaW5pdGlhbGl6ZWQgd2l0aCBhbiBlbXB0eSB2YWx1ZSwgdGhlIHByb3BcbiAqIGBkZWZhdWx0VmFsdWVgIGlmIHNwZWNpZmllZCwgb3IgdGhlIGNoaWxkcmVuIGNvbnRlbnQgKGRlcHJlY2F0ZWQpLlxuICovXG52YXIgUmVhY3RET01UZXh0YXJlYSA9IHtcbiAgZ2V0TmF0aXZlUHJvcHM6IGZ1bmN0aW9uIChpbnN0LCBwcm9wcywgY29udGV4dCkge1xuICAgICEocHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgPT0gbnVsbCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnYGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYCBkb2VzIG5vdCBtYWtlIHNlbnNlIG9uIDx0ZXh0YXJlYT4uJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gQWx3YXlzIHNldCBjaGlsZHJlbiB0byB0aGUgc2FtZSB0aGluZy4gSW4gSUU5LCB0aGUgc2VsZWN0aW9uIHJhbmdlIHdpbGxcbiAgICAvLyBnZXQgcmVzZXQgaWYgYHRleHRDb250ZW50YCBpcyBtdXRhdGVkLlxuICAgIHZhciBuYXRpdmVQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgIGRlZmF1bHRWYWx1ZTogdW5kZWZpbmVkLFxuICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIGNoaWxkcmVuOiBpbnN0Ll93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlLFxuICAgICAgb25DaGFuZ2U6IGluc3QuX3dyYXBwZXJTdGF0ZS5vbkNoYW5nZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5hdGl2ZVByb3BzO1xuICB9LFxuXG4gIG1vdW50V3JhcHBlcjogZnVuY3Rpb24gKGluc3QsIHByb3BzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIExpbmtlZFZhbHVlVXRpbHMuY2hlY2tQcm9wVHlwZXMoJ3RleHRhcmVhJywgcHJvcHMsIGluc3QuX2N1cnJlbnRFbGVtZW50Ll9vd25lcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZTtcbiAgICAvLyBUT0RPICh5dW5nc3RlcnMpOiBSZW1vdmUgc3VwcG9ydCBmb3IgY2hpbGRyZW4gY29udGVudCBpbiA8dGV4dGFyZWE+LlxuICAgIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuO1xuICAgIGlmIChjaGlsZHJlbiAhPSBudWxsKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ1VzZSB0aGUgYGRlZmF1bHRWYWx1ZWAgb3IgYHZhbHVlYCBwcm9wcyBpbnN0ZWFkIG9mIHNldHRpbmcgJyArICdjaGlsZHJlbiBvbiA8dGV4dGFyZWE+LicpIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgIShkZWZhdWx0VmFsdWUgPT0gbnVsbCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnSWYgeW91IHN1cHBseSBgZGVmYXVsdFZhbHVlYCBvbiBhIDx0ZXh0YXJlYT4sIGRvIG5vdCBwYXNzIGNoaWxkcmVuLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICAhKGNoaWxkcmVuLmxlbmd0aCA8PSAxKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICc8dGV4dGFyZWE+IGNhbiBvbmx5IGhhdmUgYXQgbW9zdCBvbmUgY2hpbGQuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuWzBdO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJyArIGNoaWxkcmVuO1xuICAgIH1cbiAgICBpZiAoZGVmYXVsdFZhbHVlID09IG51bGwpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZSA9ICcnO1xuICAgIH1cbiAgICB2YXIgdmFsdWUgPSBMaW5rZWRWYWx1ZVV0aWxzLmdldFZhbHVlKHByb3BzKTtcblxuICAgIGluc3QuX3dyYXBwZXJTdGF0ZSA9IHtcbiAgICAgIC8vIFdlIHNhdmUgdGhlIGluaXRpYWwgdmFsdWUgc28gdGhhdCBgUmVhY3RET01Db21wb25lbnRgIGRvZXNuJ3QgdXBkYXRlXG4gICAgICAvLyBgdGV4dENvbnRlbnRgICh1bm5lY2Vzc2FyeSBzaW5jZSB3ZSB1cGRhdGUgdmFsdWUpLlxuICAgICAgLy8gVGhlIGluaXRpYWwgdmFsdWUgY2FuIGJlIGEgYm9vbGVhbiBvciBvYmplY3Qgc28gdGhhdCdzIHdoeSBpdCdzXG4gICAgICAvLyBmb3JjZWQgdG8gYmUgYSBzdHJpbmcuXG4gICAgICBpbml0aWFsVmFsdWU6ICcnICsgKHZhbHVlICE9IG51bGwgPyB2YWx1ZSA6IGRlZmF1bHRWYWx1ZSksXG4gICAgICBvbkNoYW5nZTogX2hhbmRsZUNoYW5nZS5iaW5kKGluc3QpXG4gICAgfTtcbiAgfSxcblxuICB1cGRhdGVXcmFwcGVyOiBmdW5jdGlvbiAoaW5zdCkge1xuICAgIHZhciBwcm9wcyA9IGluc3QuX2N1cnJlbnRFbGVtZW50LnByb3BzO1xuICAgIHZhciB2YWx1ZSA9IExpbmtlZFZhbHVlVXRpbHMuZ2V0VmFsdWUocHJvcHMpO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAvLyBDYXN0IGB2YWx1ZWAgdG8gYSBzdHJpbmcgdG8gZW5zdXJlIHRoZSB2YWx1ZSBpcyBzZXQgY29ycmVjdGx5LiBXaGlsZVxuICAgICAgLy8gYnJvd3NlcnMgdHlwaWNhbGx5IGRvIHRoaXMgYXMgbmVjZXNzYXJ5LCBqc2RvbSBkb2Vzbid0LlxuICAgICAgUmVhY3RET01JRE9wZXJhdGlvbnMudXBkYXRlUHJvcGVydHlCeUlEKGluc3QuX3Jvb3ROb2RlSUQsICd2YWx1ZScsICcnICsgdmFsdWUpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gX2hhbmRsZUNoYW5nZShldmVudCkge1xuICB2YXIgcHJvcHMgPSB0aGlzLl9jdXJyZW50RWxlbWVudC5wcm9wcztcbiAgdmFyIHJldHVyblZhbHVlID0gTGlua2VkVmFsdWVVdGlscy5leGVjdXRlT25DaGFuZ2UocHJvcHMsIGV2ZW50KTtcbiAgUmVhY3RVcGRhdGVzLmFzYXAoZm9yY2VVcGRhdGVJZk1vdW50ZWQsIHRoaXMpO1xuICByZXR1cm4gcmV0dXJuVmFsdWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RET01UZXh0YXJlYTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0VXBkYXRlcyA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVzJyk7XG52YXIgVHJhbnNhY3Rpb24gPSByZXF1aXJlKCcuL1RyYW5zYWN0aW9uJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlGdW5jdGlvbicpO1xuXG52YXIgUkVTRVRfQkFUQ0hFRF9VUERBVEVTID0ge1xuICBpbml0aWFsaXplOiBlbXB0eUZ1bmN0aW9uLFxuICBjbG9zZTogZnVuY3Rpb24gKCkge1xuICAgIFJlYWN0RGVmYXVsdEJhdGNoaW5nU3RyYXRlZ3kuaXNCYXRjaGluZ1VwZGF0ZXMgPSBmYWxzZTtcbiAgfVxufTtcblxudmFyIEZMVVNIX0JBVENIRURfVVBEQVRFUyA9IHtcbiAgaW5pdGlhbGl6ZTogZW1wdHlGdW5jdGlvbixcbiAgY2xvc2U6IFJlYWN0VXBkYXRlcy5mbHVzaEJhdGNoZWRVcGRhdGVzLmJpbmQoUmVhY3RVcGRhdGVzKVxufTtcblxudmFyIFRSQU5TQUNUSU9OX1dSQVBQRVJTID0gW0ZMVVNIX0JBVENIRURfVVBEQVRFUywgUkVTRVRfQkFUQ0hFRF9VUERBVEVTXTtcblxuZnVuY3Rpb24gUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneVRyYW5zYWN0aW9uKCkge1xuICB0aGlzLnJlaW5pdGlhbGl6ZVRyYW5zYWN0aW9uKCk7XG59XG5cbmFzc2lnbihSZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5VHJhbnNhY3Rpb24ucHJvdG90eXBlLCBUcmFuc2FjdGlvbi5NaXhpbiwge1xuICBnZXRUcmFuc2FjdGlvbldyYXBwZXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFRSQU5TQUNUSU9OX1dSQVBQRVJTO1xuICB9XG59KTtcblxudmFyIHRyYW5zYWN0aW9uID0gbmV3IFJlYWN0RGVmYXVsdEJhdGNoaW5nU3RyYXRlZ3lUcmFuc2FjdGlvbigpO1xuXG52YXIgUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneSA9IHtcbiAgaXNCYXRjaGluZ1VwZGF0ZXM6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBDYWxsIHRoZSBwcm92aWRlZCBmdW5jdGlvbiBpbiBhIGNvbnRleHQgd2l0aGluIHdoaWNoIGNhbGxzIHRvIGBzZXRTdGF0ZWBcbiAgICogYW5kIGZyaWVuZHMgYXJlIGJhdGNoZWQgc3VjaCB0aGF0IGNvbXBvbmVudHMgYXJlbid0IHVwZGF0ZWQgdW5uZWNlc3NhcmlseS5cbiAgICovXG4gIGJhdGNoZWRVcGRhdGVzOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGEsIGIsIGMsIGQsIGUpIHtcbiAgICB2YXIgYWxyZWFkeUJhdGNoaW5nVXBkYXRlcyA9IFJlYWN0RGVmYXVsdEJhdGNoaW5nU3RyYXRlZ3kuaXNCYXRjaGluZ1VwZGF0ZXM7XG5cbiAgICBSZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5LmlzQmF0Y2hpbmdVcGRhdGVzID0gdHJ1ZTtcblxuICAgIC8vIFRoZSBjb2RlIGlzIHdyaXR0ZW4gdGhpcyB3YXkgdG8gYXZvaWQgZXh0cmEgYWxsb2NhdGlvbnNcbiAgICBpZiAoYWxyZWFkeUJhdGNoaW5nVXBkYXRlcykge1xuICAgICAgY2FsbGJhY2soYSwgYiwgYywgZCwgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYW5zYWN0aW9uLnBlcmZvcm0oY2FsbGJhY2ssIG51bGwsIGEsIGIsIGMsIGQsIGUpO1xuICAgIH1cbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERlZmF1bHRJbmplY3Rpb25cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBCZWZvcmVJbnB1dEV2ZW50UGx1Z2luID0gcmVxdWlyZSgnLi9CZWZvcmVJbnB1dEV2ZW50UGx1Z2luJyk7XG52YXIgQ2hhbmdlRXZlbnRQbHVnaW4gPSByZXF1aXJlKCcuL0NoYW5nZUV2ZW50UGx1Z2luJyk7XG52YXIgQ2xpZW50UmVhY3RSb290SW5kZXggPSByZXF1aXJlKCcuL0NsaWVudFJlYWN0Um9vdEluZGV4Jyk7XG52YXIgRGVmYXVsdEV2ZW50UGx1Z2luT3JkZXIgPSByZXF1aXJlKCcuL0RlZmF1bHRFdmVudFBsdWdpbk9yZGVyJyk7XG52YXIgRW50ZXJMZWF2ZUV2ZW50UGx1Z2luID0gcmVxdWlyZSgnLi9FbnRlckxlYXZlRXZlbnRQbHVnaW4nKTtcbnZhciBFeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJ2ZianMvbGliL0V4ZWN1dGlvbkVudmlyb25tZW50Jyk7XG52YXIgSFRNTERPTVByb3BlcnR5Q29uZmlnID0gcmVxdWlyZSgnLi9IVE1MRE9NUHJvcGVydHlDb25maWcnKTtcbnZhciBSZWFjdEJyb3dzZXJDb21wb25lbnRNaXhpbiA9IHJlcXVpcmUoJy4vUmVhY3RCcm93c2VyQ29tcG9uZW50TWl4aW4nKTtcbnZhciBSZWFjdENvbXBvbmVudEJyb3dzZXJFbnZpcm9ubWVudCA9IHJlcXVpcmUoJy4vUmVhY3RDb21wb25lbnRCcm93c2VyRW52aXJvbm1lbnQnKTtcbnZhciBSZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5ID0gcmVxdWlyZSgnLi9SZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5Jyk7XG52YXIgUmVhY3RET01Db21wb25lbnQgPSByZXF1aXJlKCcuL1JlYWN0RE9NQ29tcG9uZW50Jyk7XG52YXIgUmVhY3RET01UZXh0Q29tcG9uZW50ID0gcmVxdWlyZSgnLi9SZWFjdERPTVRleHRDb21wb25lbnQnKTtcbnZhciBSZWFjdEV2ZW50TGlzdGVuZXIgPSByZXF1aXJlKCcuL1JlYWN0RXZlbnRMaXN0ZW5lcicpO1xudmFyIFJlYWN0SW5qZWN0aW9uID0gcmVxdWlyZSgnLi9SZWFjdEluamVjdGlvbicpO1xudmFyIFJlYWN0SW5zdGFuY2VIYW5kbGVzID0gcmVxdWlyZSgnLi9SZWFjdEluc3RhbmNlSGFuZGxlcycpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcbnZhciBSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uID0gcmVxdWlyZSgnLi9SZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uJyk7XG52YXIgU2VsZWN0RXZlbnRQbHVnaW4gPSByZXF1aXJlKCcuL1NlbGVjdEV2ZW50UGx1Z2luJyk7XG52YXIgU2VydmVyUmVhY3RSb290SW5kZXggPSByZXF1aXJlKCcuL1NlcnZlclJlYWN0Um9vdEluZGV4Jyk7XG52YXIgU2ltcGxlRXZlbnRQbHVnaW4gPSByZXF1aXJlKCcuL1NpbXBsZUV2ZW50UGx1Z2luJyk7XG52YXIgU1ZHRE9NUHJvcGVydHlDb25maWcgPSByZXF1aXJlKCcuL1NWR0RPTVByb3BlcnR5Q29uZmlnJyk7XG5cbnZhciBhbHJlYWR5SW5qZWN0ZWQgPSBmYWxzZTtcblxuZnVuY3Rpb24gaW5qZWN0KCkge1xuICBpZiAoYWxyZWFkeUluamVjdGVkKSB7XG4gICAgLy8gVE9ETzogVGhpcyBpcyBjdXJyZW50bHkgdHJ1ZSBiZWNhdXNlIHRoZXNlIGluamVjdGlvbnMgYXJlIHNoYXJlZCBiZXR3ZWVuXG4gICAgLy8gdGhlIGNsaWVudCBhbmQgdGhlIHNlcnZlciBwYWNrYWdlLiBUaGV5IHNob3VsZCBiZSBidWlsdCBpbmRlcGVuZGVudGx5XG4gICAgLy8gYW5kIG5vdCBzaGFyZSBhbnkgaW5qZWN0aW9uIHN0YXRlLiBUaGVuIHRoaXMgcHJvYmxlbSB3aWxsIGJlIHNvbHZlZC5cbiAgICByZXR1cm47XG4gIH1cbiAgYWxyZWFkeUluamVjdGVkID0gdHJ1ZTtcblxuICBSZWFjdEluamVjdGlvbi5FdmVudEVtaXR0ZXIuaW5qZWN0UmVhY3RFdmVudExpc3RlbmVyKFJlYWN0RXZlbnRMaXN0ZW5lcik7XG5cbiAgLyoqXG4gICAqIEluamVjdCBtb2R1bGVzIGZvciByZXNvbHZpbmcgRE9NIGhpZXJhcmNoeSBhbmQgcGx1Z2luIG9yZGVyaW5nLlxuICAgKi9cbiAgUmVhY3RJbmplY3Rpb24uRXZlbnRQbHVnaW5IdWIuaW5qZWN0RXZlbnRQbHVnaW5PcmRlcihEZWZhdWx0RXZlbnRQbHVnaW5PcmRlcik7XG4gIFJlYWN0SW5qZWN0aW9uLkV2ZW50UGx1Z2luSHViLmluamVjdEluc3RhbmNlSGFuZGxlKFJlYWN0SW5zdGFuY2VIYW5kbGVzKTtcbiAgUmVhY3RJbmplY3Rpb24uRXZlbnRQbHVnaW5IdWIuaW5qZWN0TW91bnQoUmVhY3RNb3VudCk7XG5cbiAgLyoqXG4gICAqIFNvbWUgaW1wb3J0YW50IGV2ZW50IHBsdWdpbnMgaW5jbHVkZWQgYnkgZGVmYXVsdCAod2l0aG91dCBoYXZpbmcgdG8gcmVxdWlyZVxuICAgKiB0aGVtKS5cbiAgICovXG4gIFJlYWN0SW5qZWN0aW9uLkV2ZW50UGx1Z2luSHViLmluamVjdEV2ZW50UGx1Z2luc0J5TmFtZSh7XG4gICAgU2ltcGxlRXZlbnRQbHVnaW46IFNpbXBsZUV2ZW50UGx1Z2luLFxuICAgIEVudGVyTGVhdmVFdmVudFBsdWdpbjogRW50ZXJMZWF2ZUV2ZW50UGx1Z2luLFxuICAgIENoYW5nZUV2ZW50UGx1Z2luOiBDaGFuZ2VFdmVudFBsdWdpbixcbiAgICBTZWxlY3RFdmVudFBsdWdpbjogU2VsZWN0RXZlbnRQbHVnaW4sXG4gICAgQmVmb3JlSW5wdXRFdmVudFBsdWdpbjogQmVmb3JlSW5wdXRFdmVudFBsdWdpblxuICB9KTtcblxuICBSZWFjdEluamVjdGlvbi5OYXRpdmVDb21wb25lbnQuaW5qZWN0R2VuZXJpY0NvbXBvbmVudENsYXNzKFJlYWN0RE9NQ29tcG9uZW50KTtcblxuICBSZWFjdEluamVjdGlvbi5OYXRpdmVDb21wb25lbnQuaW5qZWN0VGV4dENvbXBvbmVudENsYXNzKFJlYWN0RE9NVGV4dENvbXBvbmVudCk7XG5cbiAgUmVhY3RJbmplY3Rpb24uQ2xhc3MuaW5qZWN0TWl4aW4oUmVhY3RCcm93c2VyQ29tcG9uZW50TWl4aW4pO1xuXG4gIFJlYWN0SW5qZWN0aW9uLkRPTVByb3BlcnR5LmluamVjdERPTVByb3BlcnR5Q29uZmlnKEhUTUxET01Qcm9wZXJ0eUNvbmZpZyk7XG4gIFJlYWN0SW5qZWN0aW9uLkRPTVByb3BlcnR5LmluamVjdERPTVByb3BlcnR5Q29uZmlnKFNWR0RPTVByb3BlcnR5Q29uZmlnKTtcblxuICBSZWFjdEluamVjdGlvbi5FbXB0eUNvbXBvbmVudC5pbmplY3RFbXB0eUNvbXBvbmVudCgnbm9zY3JpcHQnKTtcblxuICBSZWFjdEluamVjdGlvbi5VcGRhdGVzLmluamVjdFJlY29uY2lsZVRyYW5zYWN0aW9uKFJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24pO1xuICBSZWFjdEluamVjdGlvbi5VcGRhdGVzLmluamVjdEJhdGNoaW5nU3RyYXRlZ3koUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneSk7XG5cbiAgUmVhY3RJbmplY3Rpb24uUm9vdEluZGV4LmluamVjdENyZWF0ZVJlYWN0Um9vdEluZGV4KEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSA/IENsaWVudFJlYWN0Um9vdEluZGV4LmNyZWF0ZVJlYWN0Um9vdEluZGV4IDogU2VydmVyUmVhY3RSb290SW5kZXguY3JlYXRlUmVhY3RSb290SW5kZXgpO1xuXG4gIFJlYWN0SW5qZWN0aW9uLkNvbXBvbmVudC5pbmplY3RFbnZpcm9ubWVudChSZWFjdENvbXBvbmVudEJyb3dzZXJFbnZpcm9ubWVudCk7XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YXIgdXJsID0gRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NICYmIHdpbmRvdy5sb2NhdGlvbi5ocmVmIHx8ICcnO1xuICAgIGlmICgvWz8mXXJlYWN0X3BlcmZcXGIvLnRlc3QodXJsKSkge1xuICAgICAgdmFyIFJlYWN0RGVmYXVsdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0RGVmYXVsdFBlcmYnKTtcbiAgICAgIFJlYWN0RGVmYXVsdFBlcmYuc3RhcnQoKTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluamVjdDogaW5qZWN0XG59OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdERlZmF1bHRQZXJmXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIERPTVByb3BlcnR5ID0gcmVxdWlyZSgnLi9ET01Qcm9wZXJ0eScpO1xudmFyIFJlYWN0RGVmYXVsdFBlcmZBbmFseXNpcyA9IHJlcXVpcmUoJy4vUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzJyk7XG52YXIgUmVhY3RNb3VudCA9IHJlcXVpcmUoJy4vUmVhY3RNb3VudCcpO1xudmFyIFJlYWN0UGVyZiA9IHJlcXVpcmUoJy4vUmVhY3RQZXJmJyk7XG5cbnZhciBwZXJmb3JtYW5jZU5vdyA9IHJlcXVpcmUoJ2ZianMvbGliL3BlcmZvcm1hbmNlTm93Jyk7XG5cbmZ1bmN0aW9uIHJvdW5kRmxvYXQodmFsKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKHZhbCAqIDEwMCkgLyAxMDA7XG59XG5cbmZ1bmN0aW9uIGFkZFZhbHVlKG9iaiwga2V5LCB2YWwpIHtcbiAgb2JqW2tleV0gPSAob2JqW2tleV0gfHwgMCkgKyB2YWw7XG59XG5cbnZhciBSZWFjdERlZmF1bHRQZXJmID0ge1xuICBfYWxsTWVhc3VyZW1lbnRzOiBbXSwgLy8gbGFzdCBpdGVtIGluIHRoZSBsaXN0IGlzIHRoZSBjdXJyZW50IG9uZVxuICBfbW91bnRTdGFjazogWzBdLFxuICBfaW5qZWN0ZWQ6IGZhbHNlLFxuXG4gIHN0YXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFSZWFjdERlZmF1bHRQZXJmLl9pbmplY3RlZCkge1xuICAgICAgUmVhY3RQZXJmLmluamVjdGlvbi5pbmplY3RNZWFzdXJlKFJlYWN0RGVmYXVsdFBlcmYubWVhc3VyZSk7XG4gICAgfVxuXG4gICAgUmVhY3REZWZhdWx0UGVyZi5fYWxsTWVhc3VyZW1lbnRzLmxlbmd0aCA9IDA7XG4gICAgUmVhY3RQZXJmLmVuYWJsZU1lYXN1cmUgPSB0cnVlO1xuICB9LFxuXG4gIHN0b3A6IGZ1bmN0aW9uICgpIHtcbiAgICBSZWFjdFBlcmYuZW5hYmxlTWVhc3VyZSA9IGZhbHNlO1xuICB9LFxuXG4gIGdldExhc3RNZWFzdXJlbWVudHM6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gUmVhY3REZWZhdWx0UGVyZi5fYWxsTWVhc3VyZW1lbnRzO1xuICB9LFxuXG4gIHByaW50RXhjbHVzaXZlOiBmdW5jdGlvbiAobWVhc3VyZW1lbnRzKSB7XG4gICAgbWVhc3VyZW1lbnRzID0gbWVhc3VyZW1lbnRzIHx8IFJlYWN0RGVmYXVsdFBlcmYuX2FsbE1lYXN1cmVtZW50cztcbiAgICB2YXIgc3VtbWFyeSA9IFJlYWN0RGVmYXVsdFBlcmZBbmFseXNpcy5nZXRFeGNsdXNpdmVTdW1tYXJ5KG1lYXN1cmVtZW50cyk7XG4gICAgY29uc29sZS50YWJsZShzdW1tYXJ5Lm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgJ0NvbXBvbmVudCBjbGFzcyBuYW1lJzogaXRlbS5jb21wb25lbnROYW1lLFxuICAgICAgICAnVG90YWwgaW5jbHVzaXZlIHRpbWUgKG1zKSc6IHJvdW5kRmxvYXQoaXRlbS5pbmNsdXNpdmUpLFxuICAgICAgICAnRXhjbHVzaXZlIG1vdW50IHRpbWUgKG1zKSc6IHJvdW5kRmxvYXQoaXRlbS5leGNsdXNpdmUpLFxuICAgICAgICAnRXhjbHVzaXZlIHJlbmRlciB0aW1lIChtcyknOiByb3VuZEZsb2F0KGl0ZW0ucmVuZGVyKSxcbiAgICAgICAgJ01vdW50IHRpbWUgcGVyIGluc3RhbmNlIChtcyknOiByb3VuZEZsb2F0KGl0ZW0uZXhjbHVzaXZlIC8gaXRlbS5jb3VudCksXG4gICAgICAgICdSZW5kZXIgdGltZSBwZXIgaW5zdGFuY2UgKG1zKSc6IHJvdW5kRmxvYXQoaXRlbS5yZW5kZXIgLyBpdGVtLmNvdW50KSxcbiAgICAgICAgJ0luc3RhbmNlcyc6IGl0ZW0uY291bnRcbiAgICAgIH07XG4gICAgfSkpO1xuICAgIC8vIFRPRE86IFJlYWN0RGVmYXVsdFBlcmZBbmFseXNpcy5nZXRUb3RhbFRpbWUoKSBkb2VzIG5vdCByZXR1cm4gdGhlIGNvcnJlY3RcbiAgICAvLyBudW1iZXIuXG4gIH0sXG5cbiAgcHJpbnRJbmNsdXNpdmU6IGZ1bmN0aW9uIChtZWFzdXJlbWVudHMpIHtcbiAgICBtZWFzdXJlbWVudHMgPSBtZWFzdXJlbWVudHMgfHwgUmVhY3REZWZhdWx0UGVyZi5fYWxsTWVhc3VyZW1lbnRzO1xuICAgIHZhciBzdW1tYXJ5ID0gUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzLmdldEluY2x1c2l2ZVN1bW1hcnkobWVhc3VyZW1lbnRzKTtcbiAgICBjb25zb2xlLnRhYmxlKHN1bW1hcnkubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAnT3duZXIgPiBjb21wb25lbnQnOiBpdGVtLmNvbXBvbmVudE5hbWUsXG4gICAgICAgICdJbmNsdXNpdmUgdGltZSAobXMpJzogcm91bmRGbG9hdChpdGVtLnRpbWUpLFxuICAgICAgICAnSW5zdGFuY2VzJzogaXRlbS5jb3VudFxuICAgICAgfTtcbiAgICB9KSk7XG4gICAgY29uc29sZS5sb2coJ1RvdGFsIHRpbWU6JywgUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzLmdldFRvdGFsVGltZShtZWFzdXJlbWVudHMpLnRvRml4ZWQoMikgKyAnIG1zJyk7XG4gIH0sXG5cbiAgZ2V0TWVhc3VyZW1lbnRzU3VtbWFyeU1hcDogZnVuY3Rpb24gKG1lYXN1cmVtZW50cykge1xuICAgIHZhciBzdW1tYXJ5ID0gUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzLmdldEluY2x1c2l2ZVN1bW1hcnkobWVhc3VyZW1lbnRzLCB0cnVlKTtcbiAgICByZXR1cm4gc3VtbWFyeS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgICdPd25lciA+IGNvbXBvbmVudCc6IGl0ZW0uY29tcG9uZW50TmFtZSxcbiAgICAgICAgJ1dhc3RlZCB0aW1lIChtcyknOiBpdGVtLnRpbWUsXG4gICAgICAgICdJbnN0YW5jZXMnOiBpdGVtLmNvdW50XG4gICAgICB9O1xuICAgIH0pO1xuICB9LFxuXG4gIHByaW50V2FzdGVkOiBmdW5jdGlvbiAobWVhc3VyZW1lbnRzKSB7XG4gICAgbWVhc3VyZW1lbnRzID0gbWVhc3VyZW1lbnRzIHx8IFJlYWN0RGVmYXVsdFBlcmYuX2FsbE1lYXN1cmVtZW50cztcbiAgICBjb25zb2xlLnRhYmxlKFJlYWN0RGVmYXVsdFBlcmYuZ2V0TWVhc3VyZW1lbnRzU3VtbWFyeU1hcChtZWFzdXJlbWVudHMpKTtcbiAgICBjb25zb2xlLmxvZygnVG90YWwgdGltZTonLCBSZWFjdERlZmF1bHRQZXJmQW5hbHlzaXMuZ2V0VG90YWxUaW1lKG1lYXN1cmVtZW50cykudG9GaXhlZCgyKSArICcgbXMnKTtcbiAgfSxcblxuICBwcmludERPTTogZnVuY3Rpb24gKG1lYXN1cmVtZW50cykge1xuICAgIG1lYXN1cmVtZW50cyA9IG1lYXN1cmVtZW50cyB8fCBSZWFjdERlZmF1bHRQZXJmLl9hbGxNZWFzdXJlbWVudHM7XG4gICAgdmFyIHN1bW1hcnkgPSBSZWFjdERlZmF1bHRQZXJmQW5hbHlzaXMuZ2V0RE9NU3VtbWFyeShtZWFzdXJlbWVudHMpO1xuICAgIGNvbnNvbGUudGFibGUoc3VtbWFyeS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIHJlc3VsdFtET01Qcm9wZXJ0eS5JRF9BVFRSSUJVVEVfTkFNRV0gPSBpdGVtLmlkO1xuICAgICAgcmVzdWx0LnR5cGUgPSBpdGVtLnR5cGU7XG4gICAgICByZXN1bHQuYXJncyA9IEpTT04uc3RyaW5naWZ5KGl0ZW0uYXJncyk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pKTtcbiAgICBjb25zb2xlLmxvZygnVG90YWwgdGltZTonLCBSZWFjdERlZmF1bHRQZXJmQW5hbHlzaXMuZ2V0VG90YWxUaW1lKG1lYXN1cmVtZW50cykudG9GaXhlZCgyKSArICcgbXMnKTtcbiAgfSxcblxuICBfcmVjb3JkV3JpdGU6IGZ1bmN0aW9uIChpZCwgZm5OYW1lLCB0b3RhbFRpbWUsIGFyZ3MpIHtcbiAgICAvLyBUT0RPOiB0b3RhbFRpbWUgaXNuJ3QgdGhhdCB1c2VmdWwgc2luY2UgaXQgZG9lc24ndCBjb3VudCBwYWludHMvcmVmbG93c1xuICAgIHZhciB3cml0ZXMgPSBSZWFjdERlZmF1bHRQZXJmLl9hbGxNZWFzdXJlbWVudHNbUmVhY3REZWZhdWx0UGVyZi5fYWxsTWVhc3VyZW1lbnRzLmxlbmd0aCAtIDFdLndyaXRlcztcbiAgICB3cml0ZXNbaWRdID0gd3JpdGVzW2lkXSB8fCBbXTtcbiAgICB3cml0ZXNbaWRdLnB1c2goe1xuICAgICAgdHlwZTogZm5OYW1lLFxuICAgICAgdGltZTogdG90YWxUaW1lLFxuICAgICAgYXJnczogYXJnc1xuICAgIH0pO1xuICB9LFxuXG4gIG1lYXN1cmU6IGZ1bmN0aW9uIChtb2R1bGVOYW1lLCBmbk5hbWUsIGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRvdGFsVGltZTtcbiAgICAgIHZhciBydjtcbiAgICAgIHZhciBzdGFydDtcblxuICAgICAgaWYgKGZuTmFtZSA9PT0gJ19yZW5kZXJOZXdSb290Q29tcG9uZW50JyB8fCBmbk5hbWUgPT09ICdmbHVzaEJhdGNoZWRVcGRhdGVzJykge1xuICAgICAgICAvLyBBIFwibWVhc3VyZW1lbnRcIiBpcyBhIHNldCBvZiBtZXRyaWNzIHJlY29yZGVkIGZvciBlYWNoIGZsdXNoLiBXZSB3YW50XG4gICAgICAgIC8vIHRvIGdyb3VwIHRoZSBtZXRyaWNzIGZvciBhIGdpdmVuIGZsdXNoIHRvZ2V0aGVyIHNvIHdlIGNhbiBsb29rIGF0IHRoZVxuICAgICAgICAvLyBjb21wb25lbnRzIHRoYXQgcmVuZGVyZWQgYW5kIHRoZSBET00gb3BlcmF0aW9ucyB0aGF0IGFjdHVhbGx5XG4gICAgICAgIC8vIGhhcHBlbmVkIHRvIGRldGVybWluZSB0aGUgYW1vdW50IG9mIFwid2FzdGVkIHdvcmtcIiBwZXJmb3JtZWQuXG4gICAgICAgIFJlYWN0RGVmYXVsdFBlcmYuX2FsbE1lYXN1cmVtZW50cy5wdXNoKHtcbiAgICAgICAgICBleGNsdXNpdmU6IHt9LFxuICAgICAgICAgIGluY2x1c2l2ZToge30sXG4gICAgICAgICAgcmVuZGVyOiB7fSxcbiAgICAgICAgICBjb3VudHM6IHt9LFxuICAgICAgICAgIHdyaXRlczoge30sXG4gICAgICAgICAgZGlzcGxheU5hbWVzOiB7fSxcbiAgICAgICAgICB0b3RhbFRpbWU6IDAsXG4gICAgICAgICAgY3JlYXRlZDoge31cbiAgICAgICAgfSk7XG4gICAgICAgIHN0YXJ0ID0gcGVyZm9ybWFuY2VOb3coKTtcbiAgICAgICAgcnYgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBSZWFjdERlZmF1bHRQZXJmLl9hbGxNZWFzdXJlbWVudHNbUmVhY3REZWZhdWx0UGVyZi5fYWxsTWVhc3VyZW1lbnRzLmxlbmd0aCAtIDFdLnRvdGFsVGltZSA9IHBlcmZvcm1hbmNlTm93KCkgLSBzdGFydDtcbiAgICAgICAgcmV0dXJuIHJ2O1xuICAgICAgfSBlbHNlIGlmIChmbk5hbWUgPT09ICdfbW91bnRJbWFnZUludG9Ob2RlJyB8fCBtb2R1bGVOYW1lID09PSAnUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyJyB8fCBtb2R1bGVOYW1lID09PSAnUmVhY3RET01JRE9wZXJhdGlvbnMnIHx8IG1vZHVsZU5hbWUgPT09ICdDU1NQcm9wZXJ0eU9wZXJhdGlvbnMnIHx8IG1vZHVsZU5hbWUgPT09ICdET01DaGlsZHJlbk9wZXJhdGlvbnMnIHx8IG1vZHVsZU5hbWUgPT09ICdET01Qcm9wZXJ0eU9wZXJhdGlvbnMnKSB7XG4gICAgICAgIHN0YXJ0ID0gcGVyZm9ybWFuY2VOb3coKTtcbiAgICAgICAgcnYgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB0b3RhbFRpbWUgPSBwZXJmb3JtYW5jZU5vdygpIC0gc3RhcnQ7XG5cbiAgICAgICAgaWYgKGZuTmFtZSA9PT0gJ19tb3VudEltYWdlSW50b05vZGUnKSB7XG4gICAgICAgICAgdmFyIG1vdW50SUQgPSBSZWFjdE1vdW50LmdldElEKGFyZ3NbMV0pO1xuICAgICAgICAgIFJlYWN0RGVmYXVsdFBlcmYuX3JlY29yZFdyaXRlKG1vdW50SUQsIGZuTmFtZSwgdG90YWxUaW1lLCBhcmdzWzBdKTtcbiAgICAgICAgfSBlbHNlIGlmIChmbk5hbWUgPT09ICdkYW5nZXJvdXNseVByb2Nlc3NDaGlsZHJlblVwZGF0ZXMnKSB7XG4gICAgICAgICAgLy8gc3BlY2lhbCBmb3JtYXRcbiAgICAgICAgICBhcmdzWzBdLmZvckVhY2goZnVuY3Rpb24gKHVwZGF0ZSkge1xuICAgICAgICAgICAgdmFyIHdyaXRlQXJncyA9IHt9O1xuICAgICAgICAgICAgaWYgKHVwZGF0ZS5mcm9tSW5kZXggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgd3JpdGVBcmdzLmZyb21JbmRleCA9IHVwZGF0ZS5mcm9tSW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXBkYXRlLnRvSW5kZXggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgd3JpdGVBcmdzLnRvSW5kZXggPSB1cGRhdGUudG9JbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1cGRhdGUudGV4dENvbnRlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgd3JpdGVBcmdzLnRleHRDb250ZW50ID0gdXBkYXRlLnRleHRDb250ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHVwZGF0ZS5tYXJrdXBJbmRleCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB3cml0ZUFyZ3MubWFya3VwID0gYXJnc1sxXVt1cGRhdGUubWFya3VwSW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgUmVhY3REZWZhdWx0UGVyZi5fcmVjb3JkV3JpdGUodXBkYXRlLnBhcmVudElELCB1cGRhdGUudHlwZSwgdG90YWxUaW1lLCB3cml0ZUFyZ3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGJhc2ljIGZvcm1hdFxuICAgICAgICAgIHZhciBpZCA9IGFyZ3NbMF07XG4gICAgICAgICAgaWYgKHR5cGVvZiBpZCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlkID0gUmVhY3RNb3VudC5nZXRJRChhcmdzWzBdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgUmVhY3REZWZhdWx0UGVyZi5fcmVjb3JkV3JpdGUoaWQsIGZuTmFtZSwgdG90YWxUaW1lLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJ2O1xuICAgICAgfSBlbHNlIGlmIChtb2R1bGVOYW1lID09PSAnUmVhY3RDb21wb3NpdGVDb21wb25lbnQnICYmIChmbk5hbWUgPT09ICdtb3VudENvbXBvbmVudCcgfHwgZm5OYW1lID09PSAndXBkYXRlQ29tcG9uZW50JyB8fCAvLyBUT0RPOiByZWNlaXZlQ29tcG9uZW50KCk/XG4gICAgICBmbk5hbWUgPT09ICdfcmVuZGVyVmFsaWRhdGVkQ29tcG9uZW50JykpIHtcblxuICAgICAgICBpZiAodGhpcy5fY3VycmVudEVsZW1lbnQudHlwZSA9PT0gUmVhY3RNb3VudC5Ub3BMZXZlbFdyYXBwZXIpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByb290Tm9kZUlEID0gZm5OYW1lID09PSAnbW91bnRDb21wb25lbnQnID8gYXJnc1swXSA6IHRoaXMuX3Jvb3ROb2RlSUQ7XG4gICAgICAgIHZhciBpc1JlbmRlciA9IGZuTmFtZSA9PT0gJ19yZW5kZXJWYWxpZGF0ZWRDb21wb25lbnQnO1xuICAgICAgICB2YXIgaXNNb3VudCA9IGZuTmFtZSA9PT0gJ21vdW50Q29tcG9uZW50JztcblxuICAgICAgICB2YXIgbW91bnRTdGFjayA9IFJlYWN0RGVmYXVsdFBlcmYuX21vdW50U3RhY2s7XG4gICAgICAgIHZhciBlbnRyeSA9IFJlYWN0RGVmYXVsdFBlcmYuX2FsbE1lYXN1cmVtZW50c1tSZWFjdERlZmF1bHRQZXJmLl9hbGxNZWFzdXJlbWVudHMubGVuZ3RoIC0gMV07XG5cbiAgICAgICAgaWYgKGlzUmVuZGVyKSB7XG4gICAgICAgICAgYWRkVmFsdWUoZW50cnkuY291bnRzLCByb290Tm9kZUlELCAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc01vdW50KSB7XG4gICAgICAgICAgZW50cnkuY3JlYXRlZFtyb290Tm9kZUlEXSA9IHRydWU7XG4gICAgICAgICAgbW91bnRTdGFjay5wdXNoKDApO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhcnQgPSBwZXJmb3JtYW5jZU5vdygpO1xuICAgICAgICBydiA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIHRvdGFsVGltZSA9IHBlcmZvcm1hbmNlTm93KCkgLSBzdGFydDtcblxuICAgICAgICBpZiAoaXNSZW5kZXIpIHtcbiAgICAgICAgICBhZGRWYWx1ZShlbnRyeS5yZW5kZXIsIHJvb3ROb2RlSUQsIHRvdGFsVGltZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNNb3VudCkge1xuICAgICAgICAgIHZhciBzdWJNb3VudFRpbWUgPSBtb3VudFN0YWNrLnBvcCgpO1xuICAgICAgICAgIG1vdW50U3RhY2tbbW91bnRTdGFjay5sZW5ndGggLSAxXSArPSB0b3RhbFRpbWU7XG4gICAgICAgICAgYWRkVmFsdWUoZW50cnkuZXhjbHVzaXZlLCByb290Tm9kZUlELCB0b3RhbFRpbWUgLSBzdWJNb3VudFRpbWUpO1xuICAgICAgICAgIGFkZFZhbHVlKGVudHJ5LmluY2x1c2l2ZSwgcm9vdE5vZGVJRCwgdG90YWxUaW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRWYWx1ZShlbnRyeS5pbmNsdXNpdmUsIHJvb3ROb2RlSUQsIHRvdGFsVGltZSk7XG4gICAgICAgIH1cblxuICAgICAgICBlbnRyeS5kaXNwbGF5TmFtZXNbcm9vdE5vZGVJRF0gPSB7XG4gICAgICAgICAgY3VycmVudDogdGhpcy5nZXROYW1lKCksXG4gICAgICAgICAgb3duZXI6IHRoaXMuX2N1cnJlbnRFbGVtZW50Ll9vd25lciA/IHRoaXMuX2N1cnJlbnRFbGVtZW50Ll9vd25lci5nZXROYW1lKCkgOiAnPHJvb3Q+J1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBydjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3REZWZhdWx0UGVyZjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3REZWZhdWx0UGVyZkFuYWx5c2lzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG5cbi8vIERvbid0IHRyeSB0byBzYXZlIHVzZXJzIGxlc3MgdGhhbiAxLjJtcyAoYSBudW1iZXIgSSBtYWRlIHVwKVxudmFyIERPTlRfQ0FSRV9USFJFU0hPTEQgPSAxLjI7XG52YXIgRE9NX09QRVJBVElPTl9UWVBFUyA9IHtcbiAgJ19tb3VudEltYWdlSW50b05vZGUnOiAnc2V0IGlubmVySFRNTCcsXG4gIElOU0VSVF9NQVJLVVA6ICdzZXQgaW5uZXJIVE1MJyxcbiAgTU9WRV9FWElTVElORzogJ21vdmUnLFxuICBSRU1PVkVfTk9ERTogJ3JlbW92ZScsXG4gIFNFVF9NQVJLVVA6ICdzZXQgaW5uZXJIVE1MJyxcbiAgVEVYVF9DT05URU5UOiAnc2V0IHRleHRDb250ZW50JyxcbiAgJ3NldFZhbHVlRm9yUHJvcGVydHknOiAndXBkYXRlIGF0dHJpYnV0ZScsXG4gICdzZXRWYWx1ZUZvckF0dHJpYnV0ZSc6ICd1cGRhdGUgYXR0cmlidXRlJyxcbiAgJ2RlbGV0ZVZhbHVlRm9yUHJvcGVydHknOiAncmVtb3ZlIGF0dHJpYnV0ZScsXG4gICdzZXRWYWx1ZUZvclN0eWxlcyc6ICd1cGRhdGUgc3R5bGVzJyxcbiAgJ3JlcGxhY2VOb2RlV2l0aE1hcmt1cCc6ICdyZXBsYWNlJyxcbiAgJ3VwZGF0ZVRleHRDb250ZW50JzogJ3NldCB0ZXh0Q29udGVudCdcbn07XG5cbmZ1bmN0aW9uIGdldFRvdGFsVGltZShtZWFzdXJlbWVudHMpIHtcbiAgLy8gVE9ETzogcmV0dXJuIG51bWJlciBvZiBET00gb3BzPyBjb3VsZCBiZSBtaXNsZWFkaW5nLlxuICAvLyBUT0RPOiBtZWFzdXJlIGRyb3BwZWQgZnJhbWVzIGFmdGVyIHJlY29uY2lsZT9cbiAgLy8gVE9ETzogbG9nIHRvdGFsIHRpbWUgb2YgZWFjaCByZWNvbmNpbGUgYW5kIHRoZSB0b3AtbGV2ZWwgY29tcG9uZW50XG4gIC8vIGNsYXNzIHRoYXQgdHJpZ2dlcmVkIGl0LlxuICB2YXIgdG90YWxUaW1lID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZWFzdXJlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbWVhc3VyZW1lbnQgPSBtZWFzdXJlbWVudHNbaV07XG4gICAgdG90YWxUaW1lICs9IG1lYXN1cmVtZW50LnRvdGFsVGltZTtcbiAgfVxuICByZXR1cm4gdG90YWxUaW1lO1xufVxuXG5mdW5jdGlvbiBnZXRET01TdW1tYXJ5KG1lYXN1cmVtZW50cykge1xuICB2YXIgaXRlbXMgPSBbXTtcbiAgbWVhc3VyZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKG1lYXN1cmVtZW50KSB7XG4gICAgT2JqZWN0LmtleXMobWVhc3VyZW1lbnQud3JpdGVzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZCkge1xuICAgICAgbWVhc3VyZW1lbnQud3JpdGVzW2lkXS5mb3JFYWNoKGZ1bmN0aW9uICh3cml0ZSkge1xuICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgdHlwZTogRE9NX09QRVJBVElPTl9UWVBFU1t3cml0ZS50eXBlXSB8fCB3cml0ZS50eXBlLFxuICAgICAgICAgIGFyZ3M6IHdyaXRlLmFyZ3NcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBpdGVtcztcbn1cblxuZnVuY3Rpb24gZ2V0RXhjbHVzaXZlU3VtbWFyeShtZWFzdXJlbWVudHMpIHtcbiAgdmFyIGNhbmRpZGF0ZXMgPSB7fTtcbiAgdmFyIGRpc3BsYXlOYW1lO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbWVhc3VyZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG1lYXN1cmVtZW50ID0gbWVhc3VyZW1lbnRzW2ldO1xuICAgIHZhciBhbGxJRHMgPSBhc3NpZ24oe30sIG1lYXN1cmVtZW50LmV4Y2x1c2l2ZSwgbWVhc3VyZW1lbnQuaW5jbHVzaXZlKTtcblxuICAgIGZvciAodmFyIGlkIGluIGFsbElEcykge1xuICAgICAgZGlzcGxheU5hbWUgPSBtZWFzdXJlbWVudC5kaXNwbGF5TmFtZXNbaWRdLmN1cnJlbnQ7XG5cbiAgICAgIGNhbmRpZGF0ZXNbZGlzcGxheU5hbWVdID0gY2FuZGlkYXRlc1tkaXNwbGF5TmFtZV0gfHwge1xuICAgICAgICBjb21wb25lbnROYW1lOiBkaXNwbGF5TmFtZSxcbiAgICAgICAgaW5jbHVzaXZlOiAwLFxuICAgICAgICBleGNsdXNpdmU6IDAsXG4gICAgICAgIHJlbmRlcjogMCxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH07XG4gICAgICBpZiAobWVhc3VyZW1lbnQucmVuZGVyW2lkXSkge1xuICAgICAgICBjYW5kaWRhdGVzW2Rpc3BsYXlOYW1lXS5yZW5kZXIgKz0gbWVhc3VyZW1lbnQucmVuZGVyW2lkXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZWFzdXJlbWVudC5leGNsdXNpdmVbaWRdKSB7XG4gICAgICAgIGNhbmRpZGF0ZXNbZGlzcGxheU5hbWVdLmV4Y2x1c2l2ZSArPSBtZWFzdXJlbWVudC5leGNsdXNpdmVbaWRdO1xuICAgICAgfVxuICAgICAgaWYgKG1lYXN1cmVtZW50LmluY2x1c2l2ZVtpZF0pIHtcbiAgICAgICAgY2FuZGlkYXRlc1tkaXNwbGF5TmFtZV0uaW5jbHVzaXZlICs9IG1lYXN1cmVtZW50LmluY2x1c2l2ZVtpZF07XG4gICAgICB9XG4gICAgICBpZiAobWVhc3VyZW1lbnQuY291bnRzW2lkXSkge1xuICAgICAgICBjYW5kaWRhdGVzW2Rpc3BsYXlOYW1lXS5jb3VudCArPSBtZWFzdXJlbWVudC5jb3VudHNbaWRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIE5vdyBtYWtlIGEgc29ydGVkIGFycmF5IHdpdGggdGhlIHJlc3VsdHMuXG4gIHZhciBhcnIgPSBbXTtcbiAgZm9yIChkaXNwbGF5TmFtZSBpbiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKGNhbmRpZGF0ZXNbZGlzcGxheU5hbWVdLmV4Y2x1c2l2ZSA+PSBET05UX0NBUkVfVEhSRVNIT0xEKSB7XG4gICAgICBhcnIucHVzaChjYW5kaWRhdGVzW2Rpc3BsYXlOYW1lXSk7XG4gICAgfVxuICB9XG5cbiAgYXJyLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYi5leGNsdXNpdmUgLSBhLmV4Y2x1c2l2ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gZ2V0SW5jbHVzaXZlU3VtbWFyeShtZWFzdXJlbWVudHMsIG9ubHlDbGVhbikge1xuICB2YXIgY2FuZGlkYXRlcyA9IHt9O1xuICB2YXIgaW5jbHVzaXZlS2V5O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbWVhc3VyZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG1lYXN1cmVtZW50ID0gbWVhc3VyZW1lbnRzW2ldO1xuICAgIHZhciBhbGxJRHMgPSBhc3NpZ24oe30sIG1lYXN1cmVtZW50LmV4Y2x1c2l2ZSwgbWVhc3VyZW1lbnQuaW5jbHVzaXZlKTtcbiAgICB2YXIgY2xlYW5Db21wb25lbnRzO1xuXG4gICAgaWYgKG9ubHlDbGVhbikge1xuICAgICAgY2xlYW5Db21wb25lbnRzID0gZ2V0VW5jaGFuZ2VkQ29tcG9uZW50cyhtZWFzdXJlbWVudCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaWQgaW4gYWxsSURzKSB7XG4gICAgICBpZiAob25seUNsZWFuICYmICFjbGVhbkNvbXBvbmVudHNbaWRdKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgZGlzcGxheU5hbWUgPSBtZWFzdXJlbWVudC5kaXNwbGF5TmFtZXNbaWRdO1xuXG4gICAgICAvLyBJbmNsdXNpdmUgdGltZSBpcyBub3QgdXNlZnVsIGZvciBtYW55IGNvbXBvbmVudHMgd2l0aG91dCBrbm93aW5nIHdoZXJlXG4gICAgICAvLyB0aGV5IGFyZSBpbnN0YW50aWF0ZWQuIFNvIHdlIGFnZ3JlZ2F0ZSBpbmNsdXNpdmUgdGltZSB3aXRoIGJvdGggdGhlXG4gICAgICAvLyBvd25lciBhbmQgY3VycmVudCBkaXNwbGF5TmFtZSBhcyB0aGUga2V5LlxuICAgICAgaW5jbHVzaXZlS2V5ID0gZGlzcGxheU5hbWUub3duZXIgKyAnID4gJyArIGRpc3BsYXlOYW1lLmN1cnJlbnQ7XG5cbiAgICAgIGNhbmRpZGF0ZXNbaW5jbHVzaXZlS2V5XSA9IGNhbmRpZGF0ZXNbaW5jbHVzaXZlS2V5XSB8fCB7XG4gICAgICAgIGNvbXBvbmVudE5hbWU6IGluY2x1c2l2ZUtleSxcbiAgICAgICAgdGltZTogMCxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH07XG5cbiAgICAgIGlmIChtZWFzdXJlbWVudC5pbmNsdXNpdmVbaWRdKSB7XG4gICAgICAgIGNhbmRpZGF0ZXNbaW5jbHVzaXZlS2V5XS50aW1lICs9IG1lYXN1cmVtZW50LmluY2x1c2l2ZVtpZF07XG4gICAgICB9XG4gICAgICBpZiAobWVhc3VyZW1lbnQuY291bnRzW2lkXSkge1xuICAgICAgICBjYW5kaWRhdGVzW2luY2x1c2l2ZUtleV0uY291bnQgKz0gbWVhc3VyZW1lbnQuY291bnRzW2lkXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBOb3cgbWFrZSBhIHNvcnRlZCBhcnJheSB3aXRoIHRoZSByZXN1bHRzLlxuICB2YXIgYXJyID0gW107XG4gIGZvciAoaW5jbHVzaXZlS2V5IGluIGNhbmRpZGF0ZXMpIHtcbiAgICBpZiAoY2FuZGlkYXRlc1tpbmNsdXNpdmVLZXldLnRpbWUgPj0gRE9OVF9DQVJFX1RIUkVTSE9MRCkge1xuICAgICAgYXJyLnB1c2goY2FuZGlkYXRlc1tpbmNsdXNpdmVLZXldKTtcbiAgICB9XG4gIH1cblxuICBhcnIuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBiLnRpbWUgLSBhLnRpbWU7XG4gIH0pO1xuXG4gIHJldHVybiBhcnI7XG59XG5cbmZ1bmN0aW9uIGdldFVuY2hhbmdlZENvbXBvbmVudHMobWVhc3VyZW1lbnQpIHtcbiAgLy8gRm9yIGEgZ2l2ZW4gcmVjb25jaWxlLCBsb29rIGF0IHdoaWNoIGNvbXBvbmVudHMgZGlkIG5vdCBhY3R1YWxseVxuICAvLyByZW5kZXIgYW55dGhpbmcgdG8gdGhlIERPTSBhbmQgcmV0dXJuIGEgbWFwcGluZyBvZiB0aGVpciBJRCB0b1xuICAvLyB0aGUgYW1vdW50IG9mIHRpbWUgaXQgdG9vayB0byByZW5kZXIgdGhlIGVudGlyZSBzdWJ0cmVlLlxuICB2YXIgY2xlYW5Db21wb25lbnRzID0ge307XG4gIHZhciBkaXJ0eUxlYWZJRHMgPSBPYmplY3Qua2V5cyhtZWFzdXJlbWVudC53cml0ZXMpO1xuICB2YXIgYWxsSURzID0gYXNzaWduKHt9LCBtZWFzdXJlbWVudC5leGNsdXNpdmUsIG1lYXN1cmVtZW50LmluY2x1c2l2ZSk7XG5cbiAgZm9yICh2YXIgaWQgaW4gYWxsSURzKSB7XG4gICAgdmFyIGlzRGlydHkgPSBmYWxzZTtcbiAgICAvLyBGb3IgZWFjaCBjb21wb25lbnQgdGhhdCByZW5kZXJlZCwgc2VlIGlmIGEgY29tcG9uZW50IHRoYXQgdHJpZ2dlcmVkXG4gICAgLy8gYSBET00gb3AgaXMgaW4gaXRzIHN1YnRyZWUuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXJ0eUxlYWZJRHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChkaXJ0eUxlYWZJRHNbaV0uaW5kZXhPZihpZCkgPT09IDApIHtcbiAgICAgICAgaXNEaXJ0eSA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjaGVjayBpZiBjb21wb25lbnQgbmV3bHkgY3JlYXRlZFxuICAgIGlmIChtZWFzdXJlbWVudC5jcmVhdGVkW2lkXSkge1xuICAgICAgaXNEaXJ0eSA9IHRydWU7XG4gICAgfVxuICAgIGlmICghaXNEaXJ0eSAmJiBtZWFzdXJlbWVudC5jb3VudHNbaWRdID4gMCkge1xuICAgICAgY2xlYW5Db21wb25lbnRzW2lkXSA9IHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBjbGVhbkNvbXBvbmVudHM7XG59XG5cbnZhciBSZWFjdERlZmF1bHRQZXJmQW5hbHlzaXMgPSB7XG4gIGdldEV4Y2x1c2l2ZVN1bW1hcnk6IGdldEV4Y2x1c2l2ZVN1bW1hcnksXG4gIGdldEluY2x1c2l2ZVN1bW1hcnk6IGdldEluY2x1c2l2ZVN1bW1hcnksXG4gIGdldERPTVN1bW1hcnk6IGdldERPTVN1bW1hcnksXG4gIGdldFRvdGFsVGltZTogZ2V0VG90YWxUaW1lXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0RGVmYXVsdFBlcmZBbmFseXNpczsiLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RFbGVtZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSByZXF1aXJlKCcuL1JlYWN0Q3VycmVudE93bmVyJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBjYW5EZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vY2FuRGVmaW5lUHJvcGVydHknKTtcblxuLy8gVGhlIFN5bWJvbCB1c2VkIHRvIHRhZyB0aGUgUmVhY3RFbGVtZW50IHR5cGUuIElmIHRoZXJlIGlzIG5vIG5hdGl2ZSBTeW1ib2xcbi8vIG5vciBwb2x5ZmlsbCwgdGhlbiBhIHBsYWluIG51bWJlciBpcyB1c2VkIGZvciBwZXJmb3JtYW5jZS5cbnZhciBSRUFDVF9FTEVNRU5UX1RZUEUgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIFN5bWJvbFsnZm9yJ10gJiYgU3ltYm9sWydmb3InXSgncmVhY3QuZWxlbWVudCcpIHx8IDB4ZWFjNztcblxudmFyIFJFU0VSVkVEX1BST1BTID0ge1xuICBrZXk6IHRydWUsXG4gIHJlZjogdHJ1ZSxcbiAgX19zZWxmOiB0cnVlLFxuICBfX3NvdXJjZTogdHJ1ZVxufTtcblxuLyoqXG4gKiBCYXNlIGNvbnN0cnVjdG9yIGZvciBhbGwgUmVhY3QgZWxlbWVudHMuIFRoaXMgaXMgb25seSB1c2VkIHRvIG1ha2UgdGhpc1xuICogd29yayB3aXRoIGEgZHluYW1pYyBpbnN0YW5jZW9mIGNoZWNrLiBOb3RoaW5nIHNob3VsZCBsaXZlIG9uIHRoaXMgcHJvdG90eXBlLlxuICpcbiAqIEBwYXJhbSB7Kn0gdHlwZVxuICogQHBhcmFtIHsqfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gcmVmXG4gKiBAcGFyYW0geyp9IHNlbGYgQSAqdGVtcG9yYXJ5KiBoZWxwZXIgdG8gZGV0ZWN0IHBsYWNlcyB3aGVyZSBgdGhpc2AgaXNcbiAqIGRpZmZlcmVudCBmcm9tIHRoZSBgb3duZXJgIHdoZW4gUmVhY3QuY3JlYXRlRWxlbWVudCBpcyBjYWxsZWQsIHNvIHRoYXQgd2VcbiAqIGNhbiB3YXJuLiBXZSB3YW50IHRvIGdldCByaWQgb2Ygb3duZXIgYW5kIHJlcGxhY2Ugc3RyaW5nIGByZWZgcyB3aXRoIGFycm93XG4gKiBmdW5jdGlvbnMsIGFuZCBhcyBsb25nIGFzIGB0aGlzYCBhbmQgb3duZXIgYXJlIHRoZSBzYW1lLCB0aGVyZSB3aWxsIGJlIG5vXG4gKiBjaGFuZ2UgaW4gYmVoYXZpb3IuXG4gKiBAcGFyYW0geyp9IHNvdXJjZSBBbiBhbm5vdGF0aW9uIG9iamVjdCAoYWRkZWQgYnkgYSB0cmFuc3BpbGVyIG9yIG90aGVyd2lzZSlcbiAqIGluZGljYXRpbmcgZmlsZW5hbWUsIGxpbmUgbnVtYmVyLCBhbmQvb3Igb3RoZXIgaW5mb3JtYXRpb24uXG4gKiBAcGFyYW0geyp9IG93bmVyXG4gKiBAcGFyYW0geyp9IHByb3BzXG4gKiBAaW50ZXJuYWxcbiAqL1xudmFyIFJlYWN0RWxlbWVudCA9IGZ1bmN0aW9uICh0eXBlLCBrZXksIHJlZiwgc2VsZiwgc291cmNlLCBvd25lciwgcHJvcHMpIHtcbiAgdmFyIGVsZW1lbnQgPSB7XG4gICAgLy8gVGhpcyB0YWcgYWxsb3cgdXMgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcyBhcyBhIFJlYWN0IEVsZW1lbnRcbiAgICAkJHR5cGVvZjogUkVBQ1RfRUxFTUVOVF9UWVBFLFxuXG4gICAgLy8gQnVpbHQtaW4gcHJvcGVydGllcyB0aGF0IGJlbG9uZyBvbiB0aGUgZWxlbWVudFxuICAgIHR5cGU6IHR5cGUsXG4gICAga2V5OiBrZXksXG4gICAgcmVmOiByZWYsXG4gICAgcHJvcHM6IHByb3BzLFxuXG4gICAgLy8gUmVjb3JkIHRoZSBjb21wb25lbnQgcmVzcG9uc2libGUgZm9yIGNyZWF0aW5nIHRoaXMgZWxlbWVudC5cbiAgICBfb3duZXI6IG93bmVyXG4gIH07XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGUgdmFsaWRhdGlvbiBmbGFnIGlzIGN1cnJlbnRseSBtdXRhdGl2ZS4gV2UgcHV0IGl0IG9uXG4gICAgLy8gYW4gZXh0ZXJuYWwgYmFja2luZyBzdG9yZSBzbyB0aGF0IHdlIGNhbiBmcmVlemUgdGhlIHdob2xlIG9iamVjdC5cbiAgICAvLyBUaGlzIGNhbiBiZSByZXBsYWNlZCB3aXRoIGEgV2Vha01hcCBvbmNlIHRoZXkgYXJlIGltcGxlbWVudGVkIGluXG4gICAgLy8gY29tbW9ubHkgdXNlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudHMuXG4gICAgZWxlbWVudC5fc3RvcmUgPSB7fTtcblxuICAgIC8vIFRvIG1ha2UgY29tcGFyaW5nIFJlYWN0RWxlbWVudHMgZWFzaWVyIGZvciB0ZXN0aW5nIHB1cnBvc2VzLCB3ZSBtYWtlXG4gICAgLy8gdGhlIHZhbGlkYXRpb24gZmxhZyBub24tZW51bWVyYWJsZSAod2hlcmUgcG9zc2libGUsIHdoaWNoIHNob3VsZFxuICAgIC8vIGluY2x1ZGUgZXZlcnkgZW52aXJvbm1lbnQgd2UgcnVuIHRlc3RzIGluKSwgc28gdGhlIHRlc3QgZnJhbWV3b3JrXG4gICAgLy8gaWdub3JlcyBpdC5cbiAgICBpZiAoY2FuRGVmaW5lUHJvcGVydHkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50Ll9zdG9yZSwgJ3ZhbGlkYXRlZCcsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogZmFsc2VcbiAgICAgIH0pO1xuICAgICAgLy8gc2VsZiBhbmQgc291cmNlIGFyZSBERVYgb25seSBwcm9wZXJ0aWVzLlxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc2VsZicsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IHNlbGZcbiAgICAgIH0pO1xuICAgICAgLy8gVHdvIGVsZW1lbnRzIGNyZWF0ZWQgaW4gdHdvIGRpZmZlcmVudCBwbGFjZXMgc2hvdWxkIGJlIGNvbnNpZGVyZWRcbiAgICAgIC8vIGVxdWFsIGZvciB0ZXN0aW5nIHB1cnBvc2VzIGFuZCB0aGVyZWZvcmUgd2UgaGlkZSBpdCBmcm9tIGVudW1lcmF0aW9uLlxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc291cmNlJywge1xuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogc291cmNlXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5fc3RvcmUudmFsaWRhdGVkID0gZmFsc2U7XG4gICAgICBlbGVtZW50Ll9zZWxmID0gc2VsZjtcbiAgICAgIGVsZW1lbnQuX3NvdXJjZSA9IHNvdXJjZTtcbiAgICB9XG4gICAgT2JqZWN0LmZyZWV6ZShlbGVtZW50LnByb3BzKTtcbiAgICBPYmplY3QuZnJlZXplKGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG5SZWFjdEVsZW1lbnQuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uICh0eXBlLCBjb25maWcsIGNoaWxkcmVuKSB7XG4gIHZhciBwcm9wTmFtZTtcblxuICAvLyBSZXNlcnZlZCBuYW1lcyBhcmUgZXh0cmFjdGVkXG4gIHZhciBwcm9wcyA9IHt9O1xuXG4gIHZhciBrZXkgPSBudWxsO1xuICB2YXIgcmVmID0gbnVsbDtcbiAgdmFyIHNlbGYgPSBudWxsO1xuICB2YXIgc291cmNlID0gbnVsbDtcblxuICBpZiAoY29uZmlnICE9IG51bGwpIHtcbiAgICByZWYgPSBjb25maWcucmVmID09PSB1bmRlZmluZWQgPyBudWxsIDogY29uZmlnLnJlZjtcbiAgICBrZXkgPSBjb25maWcua2V5ID09PSB1bmRlZmluZWQgPyBudWxsIDogJycgKyBjb25maWcua2V5O1xuICAgIHNlbGYgPSBjb25maWcuX19zZWxmID09PSB1bmRlZmluZWQgPyBudWxsIDogY29uZmlnLl9fc2VsZjtcbiAgICBzb3VyY2UgPSBjb25maWcuX19zb3VyY2UgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb25maWcuX19zb3VyY2U7XG4gICAgLy8gUmVtYWluaW5nIHByb3BlcnRpZXMgYXJlIGFkZGVkIHRvIGEgbmV3IHByb3BzIG9iamVjdFxuICAgIGZvciAocHJvcE5hbWUgaW4gY29uZmlnKSB7XG4gICAgICBpZiAoY29uZmlnLmhhc093blByb3BlcnR5KHByb3BOYW1lKSAmJiAhUkVTRVJWRURfUFJPUFMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGNvbmZpZ1twcm9wTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hpbGRyZW4gY2FuIGJlIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQsIGFuZCB0aG9zZSBhcmUgdHJhbnNmZXJyZWQgb250b1xuICAvLyB0aGUgbmV3bHkgYWxsb2NhdGVkIHByb3BzIG9iamVjdC5cbiAgdmFyIGNoaWxkcmVuTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCAtIDI7XG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBBcnJheShjaGlsZHJlbkxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbkxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGlsZEFycmF5W2ldID0gYXJndW1lbnRzW2kgKyAyXTtcbiAgICB9XG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9XG5cbiAgLy8gUmVzb2x2ZSBkZWZhdWx0IHByb3BzXG4gIGlmICh0eXBlICYmIHR5cGUuZGVmYXVsdFByb3BzKSB7XG4gICAgdmFyIGRlZmF1bHRQcm9wcyA9IHR5cGUuZGVmYXVsdFByb3BzO1xuICAgIGZvciAocHJvcE5hbWUgaW4gZGVmYXVsdFByb3BzKSB7XG4gICAgICBpZiAodHlwZW9mIHByb3BzW3Byb3BOYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcHJvcHNbcHJvcE5hbWVdID0gZGVmYXVsdFByb3BzW3Byb3BOYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gUmVhY3RFbGVtZW50KHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQsIHByb3BzKTtcbn07XG5cblJlYWN0RWxlbWVudC5jcmVhdGVGYWN0b3J5ID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgdmFyIGZhY3RvcnkgPSBSZWFjdEVsZW1lbnQuY3JlYXRlRWxlbWVudC5iaW5kKG51bGwsIHR5cGUpO1xuICAvLyBFeHBvc2UgdGhlIHR5cGUgb24gdGhlIGZhY3RvcnkgYW5kIHRoZSBwcm90b3R5cGUgc28gdGhhdCBpdCBjYW4gYmVcbiAgLy8gZWFzaWx5IGFjY2Vzc2VkIG9uIGVsZW1lbnRzLiBFLmcuIGA8Rm9vIC8+LnR5cGUgPT09IEZvb2AuXG4gIC8vIFRoaXMgc2hvdWxkIG5vdCBiZSBuYW1lZCBgY29uc3RydWN0b3JgIHNpbmNlIHRoaXMgbWF5IG5vdCBiZSB0aGUgZnVuY3Rpb25cbiAgLy8gdGhhdCBjcmVhdGVkIHRoZSBlbGVtZW50LCBhbmQgaXQgbWF5IG5vdCBldmVuIGJlIGEgY29uc3RydWN0b3IuXG4gIC8vIExlZ2FjeSBob29rIFRPRE86IFdhcm4gaWYgdGhpcyBpcyBhY2Nlc3NlZFxuICBmYWN0b3J5LnR5cGUgPSB0eXBlO1xuICByZXR1cm4gZmFjdG9yeTtcbn07XG5cblJlYWN0RWxlbWVudC5jbG9uZUFuZFJlcGxhY2VLZXkgPSBmdW5jdGlvbiAob2xkRWxlbWVudCwgbmV3S2V5KSB7XG4gIHZhciBuZXdFbGVtZW50ID0gUmVhY3RFbGVtZW50KG9sZEVsZW1lbnQudHlwZSwgbmV3S2V5LCBvbGRFbGVtZW50LnJlZiwgb2xkRWxlbWVudC5fc2VsZiwgb2xkRWxlbWVudC5fc291cmNlLCBvbGRFbGVtZW50Ll9vd25lciwgb2xkRWxlbWVudC5wcm9wcyk7XG5cbiAgcmV0dXJuIG5ld0VsZW1lbnQ7XG59O1xuXG5SZWFjdEVsZW1lbnQuY2xvbmVBbmRSZXBsYWNlUHJvcHMgPSBmdW5jdGlvbiAob2xkRWxlbWVudCwgbmV3UHJvcHMpIHtcbiAgdmFyIG5ld0VsZW1lbnQgPSBSZWFjdEVsZW1lbnQob2xkRWxlbWVudC50eXBlLCBvbGRFbGVtZW50LmtleSwgb2xkRWxlbWVudC5yZWYsIG9sZEVsZW1lbnQuX3NlbGYsIG9sZEVsZW1lbnQuX3NvdXJjZSwgb2xkRWxlbWVudC5fb3duZXIsIG5ld1Byb3BzKTtcblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIC8vIElmIHRoZSBrZXkgb24gdGhlIG9yaWdpbmFsIGlzIHZhbGlkLCB0aGVuIHRoZSBjbG9uZSBpcyB2YWxpZFxuICAgIG5ld0VsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZCA9IG9sZEVsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZDtcbiAgfVxuXG4gIHJldHVybiBuZXdFbGVtZW50O1xufTtcblxuUmVhY3RFbGVtZW50LmNsb25lRWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCBjb25maWcsIGNoaWxkcmVuKSB7XG4gIHZhciBwcm9wTmFtZTtcblxuICAvLyBPcmlnaW5hbCBwcm9wcyBhcmUgY29waWVkXG4gIHZhciBwcm9wcyA9IGFzc2lnbih7fSwgZWxlbWVudC5wcm9wcyk7XG5cbiAgLy8gUmVzZXJ2ZWQgbmFtZXMgYXJlIGV4dHJhY3RlZFxuICB2YXIga2V5ID0gZWxlbWVudC5rZXk7XG4gIHZhciByZWYgPSBlbGVtZW50LnJlZjtcbiAgLy8gU2VsZiBpcyBwcmVzZXJ2ZWQgc2luY2UgdGhlIG93bmVyIGlzIHByZXNlcnZlZC5cbiAgdmFyIHNlbGYgPSBlbGVtZW50Ll9zZWxmO1xuICAvLyBTb3VyY2UgaXMgcHJlc2VydmVkIHNpbmNlIGNsb25lRWxlbWVudCBpcyB1bmxpa2VseSB0byBiZSB0YXJnZXRlZCBieSBhXG4gIC8vIHRyYW5zcGlsZXIsIGFuZCB0aGUgb3JpZ2luYWwgc291cmNlIGlzIHByb2JhYmx5IGEgYmV0dGVyIGluZGljYXRvciBvZiB0aGVcbiAgLy8gdHJ1ZSBvd25lci5cbiAgdmFyIHNvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcblxuICAvLyBPd25lciB3aWxsIGJlIHByZXNlcnZlZCwgdW5sZXNzIHJlZiBpcyBvdmVycmlkZGVuXG4gIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuXG4gIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgIGlmIChjb25maWcucmVmICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFNpbGVudGx5IHN0ZWFsIHRoZSByZWYgZnJvbSB0aGUgcGFyZW50LlxuICAgICAgcmVmID0gY29uZmlnLnJlZjtcbiAgICAgIG93bmVyID0gUmVhY3RDdXJyZW50T3duZXIuY3VycmVudDtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy5rZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAga2V5ID0gJycgKyBjb25maWcua2V5O1xuICAgIH1cbiAgICAvLyBSZW1haW5pbmcgcHJvcGVydGllcyBvdmVycmlkZSBleGlzdGluZyBwcm9wc1xuICAgIGZvciAocHJvcE5hbWUgaW4gY29uZmlnKSB7XG4gICAgICBpZiAoY29uZmlnLmhhc093blByb3BlcnR5KHByb3BOYW1lKSAmJiAhUkVTRVJWRURfUFJPUFMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGNvbmZpZ1twcm9wTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hpbGRyZW4gY2FuIGJlIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQsIGFuZCB0aG9zZSBhcmUgdHJhbnNmZXJyZWQgb250b1xuICAvLyB0aGUgbmV3bHkgYWxsb2NhdGVkIHByb3BzIG9iamVjdC5cbiAgdmFyIGNoaWxkcmVuTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCAtIDI7XG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBBcnJheShjaGlsZHJlbkxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbkxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGlsZEFycmF5W2ldID0gYXJndW1lbnRzW2kgKyAyXTtcbiAgICB9XG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9XG5cbiAgcmV0dXJuIFJlYWN0RWxlbWVudChlbGVtZW50LnR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcyk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7P29iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGBvYmplY3RgIGlzIGEgdmFsaWQgY29tcG9uZW50LlxuICogQGZpbmFsXG4gKi9cblJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudCA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmIG9iamVjdCAhPT0gbnVsbCAmJiBvYmplY3QuJCR0eXBlb2YgPT09IFJFQUNUX0VMRU1FTlRfVFlQRTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RFbGVtZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEVsZW1lbnRWYWxpZGF0b3JcbiAqL1xuXG4vKipcbiAqIFJlYWN0RWxlbWVudFZhbGlkYXRvciBwcm92aWRlcyBhIHdyYXBwZXIgYXJvdW5kIGEgZWxlbWVudCBmYWN0b3J5XG4gKiB3aGljaCB2YWxpZGF0ZXMgdGhlIHByb3BzIHBhc3NlZCB0byB0aGUgZWxlbWVudC4gVGhpcyBpcyBpbnRlbmRlZCB0byBiZVxuICogdXNlZCBvbmx5IGluIERFViBhbmQgY291bGQgYmUgcmVwbGFjZWQgYnkgYSBzdGF0aWMgdHlwZSBjaGVja2VyIGZvciBsYW5ndWFnZXNcbiAqIHRoYXQgc3VwcG9ydCBpdC5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdEVsZW1lbnQgPSByZXF1aXJlKCcuL1JlYWN0RWxlbWVudCcpO1xudmFyIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnMgPSByZXF1aXJlKCcuL1JlYWN0UHJvcFR5cGVMb2NhdGlvbnMnKTtcbnZhciBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcyA9IHJlcXVpcmUoJy4vUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXMnKTtcbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IHJlcXVpcmUoJy4vUmVhY3RDdXJyZW50T3duZXInKTtcblxudmFyIGNhbkRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9jYW5EZWZpbmVQcm9wZXJ0eScpO1xudmFyIGdldEl0ZXJhdG9yRm4gPSByZXF1aXJlKCcuL2dldEl0ZXJhdG9yRm4nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG5mdW5jdGlvbiBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSB7XG4gIGlmIChSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50KSB7XG4gICAgdmFyIG5hbWUgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LmdldE5hbWUoKTtcbiAgICBpZiAobmFtZSkge1xuICAgICAgcmV0dXJuICcgQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBuYW1lICsgJ2AuJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG4vKipcbiAqIFdhcm4gaWYgdGhlcmUncyBubyBrZXkgZXhwbGljaXRseSBzZXQgb24gZHluYW1pYyBhcnJheXMgb2YgY2hpbGRyZW4gb3JcbiAqIG9iamVjdCBrZXlzIGFyZSBub3QgdmFsaWQuIFRoaXMgYWxsb3dzIHVzIHRvIGtlZXAgdHJhY2sgb2YgY2hpbGRyZW4gYmV0d2VlblxuICogdXBkYXRlcy5cbiAqL1xudmFyIG93bmVySGFzS2V5VXNlV2FybmluZyA9IHt9O1xuXG52YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG5cbi8qKlxuICogV2FybiBpZiB0aGUgZWxlbWVudCBkb2Vzbid0IGhhdmUgYW4gZXhwbGljaXQga2V5IGFzc2lnbmVkIHRvIGl0LlxuICogVGhpcyBlbGVtZW50IGlzIGluIGFuIGFycmF5LiBUaGUgYXJyYXkgY291bGQgZ3JvdyBhbmQgc2hyaW5rIG9yIGJlXG4gKiByZW9yZGVyZWQuIEFsbCBjaGlsZHJlbiB0aGF0IGhhdmVuJ3QgYWxyZWFkeSBiZWVuIHZhbGlkYXRlZCBhcmUgcmVxdWlyZWQgdG9cbiAqIGhhdmUgYSBcImtleVwiIHByb3BlcnR5IGFzc2lnbmVkIHRvIGl0LlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudCB0aGF0IHJlcXVpcmVzIGEga2V5LlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIGVsZW1lbnQncyBwYXJlbnQncyB0eXBlLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUV4cGxpY2l0S2V5KGVsZW1lbnQsIHBhcmVudFR5cGUpIHtcbiAgaWYgKCFlbGVtZW50Ll9zdG9yZSB8fCBlbGVtZW50Ll9zdG9yZS52YWxpZGF0ZWQgfHwgZWxlbWVudC5rZXkgIT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBlbGVtZW50Ll9zdG9yZS52YWxpZGF0ZWQgPSB0cnVlO1xuXG4gIHZhciBhZGRlbmRhID0gZ2V0QWRkZW5kYUZvcktleVVzZSgndW5pcXVlS2V5JywgZWxlbWVudCwgcGFyZW50VHlwZSk7XG4gIGlmIChhZGRlbmRhID09PSBudWxsKSB7XG4gICAgLy8gd2UgYWxyZWFkeSBzaG93ZWQgdGhlIHdhcm5pbmdcbiAgICByZXR1cm47XG4gIH1cbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdFYWNoIGNoaWxkIGluIGFuIGFycmF5IG9yIGl0ZXJhdG9yIHNob3VsZCBoYXZlIGEgdW5pcXVlIFwia2V5XCIgcHJvcC4nICsgJyVzJXMlcycsIGFkZGVuZGEucGFyZW50T3JPd25lciB8fCAnJywgYWRkZW5kYS5jaGlsZE93bmVyIHx8ICcnLCBhZGRlbmRhLnVybCB8fCAnJykgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogU2hhcmVkIHdhcm5pbmcgYW5kIG1vbml0b3JpbmcgY29kZSBmb3IgdGhlIGtleSB3YXJuaW5ncy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlVHlwZSBBIGtleSB1c2VkIGZvciBkZS1kdXBpbmcgd2FybmluZ3MuXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudCBDb21wb25lbnQgdGhhdCByZXF1aXJlcyBhIGtleS5cbiAqIEBwYXJhbSB7Kn0gcGFyZW50VHlwZSBlbGVtZW50J3MgcGFyZW50J3MgdHlwZS5cbiAqIEByZXR1cm5zIHs/b2JqZWN0fSBBIHNldCBvZiBhZGRlbmRhIHRvIHVzZSBpbiB0aGUgd2FybmluZyBtZXNzYWdlLCBvciBudWxsXG4gKiBpZiB0aGUgd2FybmluZyBoYXMgYWxyZWFkeSBiZWVuIHNob3duIGJlZm9yZSAoYW5kIHNob3VsZG4ndCBiZSBzaG93biBhZ2FpbikuXG4gKi9cbmZ1bmN0aW9uIGdldEFkZGVuZGFGb3JLZXlVc2UobWVzc2FnZVR5cGUsIGVsZW1lbnQsIHBhcmVudFR5cGUpIHtcbiAgdmFyIGFkZGVuZHVtID0gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCk7XG4gIGlmICghYWRkZW5kdW0pIHtcbiAgICB2YXIgcGFyZW50TmFtZSA9IHR5cGVvZiBwYXJlbnRUeXBlID09PSAnc3RyaW5nJyA/IHBhcmVudFR5cGUgOiBwYXJlbnRUeXBlLmRpc3BsYXlOYW1lIHx8IHBhcmVudFR5cGUubmFtZTtcbiAgICBpZiAocGFyZW50TmFtZSkge1xuICAgICAgYWRkZW5kdW0gPSAnIENoZWNrIHRoZSB0b3AtbGV2ZWwgcmVuZGVyIGNhbGwgdXNpbmcgPCcgKyBwYXJlbnROYW1lICsgJz4uJztcbiAgICB9XG4gIH1cblxuICB2YXIgbWVtb2l6ZXIgPSBvd25lckhhc0tleVVzZVdhcm5pbmdbbWVzc2FnZVR5cGVdIHx8IChvd25lckhhc0tleVVzZVdhcm5pbmdbbWVzc2FnZVR5cGVdID0ge30pO1xuICBpZiAobWVtb2l6ZXJbYWRkZW5kdW1dKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgbWVtb2l6ZXJbYWRkZW5kdW1dID0gdHJ1ZTtcblxuICB2YXIgYWRkZW5kYSA9IHtcbiAgICBwYXJlbnRPck93bmVyOiBhZGRlbmR1bSxcbiAgICB1cmw6ICcgU2VlIGh0dHBzOi8vZmIubWUvcmVhY3Qtd2FybmluZy1rZXlzIGZvciBtb3JlIGluZm9ybWF0aW9uLicsXG4gICAgY2hpbGRPd25lcjogbnVsbFxuICB9O1xuXG4gIC8vIFVzdWFsbHkgdGhlIGN1cnJlbnQgb3duZXIgaXMgdGhlIG9mZmVuZGVyLCBidXQgaWYgaXQgYWNjZXB0cyBjaGlsZHJlbiBhcyBhXG4gIC8vIHByb3BlcnR5LCBpdCBtYXkgYmUgdGhlIGNyZWF0b3Igb2YgdGhlIGNoaWxkIHRoYXQncyByZXNwb25zaWJsZSBmb3JcbiAgLy8gYXNzaWduaW5nIGl0IGEga2V5LlxuICBpZiAoZWxlbWVudCAmJiBlbGVtZW50Ll9vd25lciAmJiBlbGVtZW50Ll9vd25lciAhPT0gUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCkge1xuICAgIC8vIEdpdmUgdGhlIGNvbXBvbmVudCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGlzIGNoaWxkLlxuICAgIGFkZGVuZGEuY2hpbGRPd25lciA9ICcgSXQgd2FzIHBhc3NlZCBhIGNoaWxkIGZyb20gJyArIGVsZW1lbnQuX293bmVyLmdldE5hbWUoKSArICcuJztcbiAgfVxuXG4gIHJldHVybiBhZGRlbmRhO1xufVxuXG4vKipcbiAqIEVuc3VyZSB0aGF0IGV2ZXJ5IGVsZW1lbnQgZWl0aGVyIGlzIHBhc3NlZCBpbiBhIHN0YXRpYyBsb2NhdGlvbiwgaW4gYW5cbiAqIGFycmF5IHdpdGggYW4gZXhwbGljaXQga2V5cyBwcm9wZXJ0eSBkZWZpbmVkLCBvciBpbiBhbiBvYmplY3QgbGl0ZXJhbFxuICogd2l0aCB2YWxpZCBrZXkgcHJvcGVydHkuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0ge1JlYWN0Tm9kZX0gbm9kZSBTdGF0aWNhbGx5IHBhc3NlZCBjaGlsZCBvZiBhbnkgdHlwZS5cbiAqIEBwYXJhbSB7Kn0gcGFyZW50VHlwZSBub2RlJ3MgcGFyZW50J3MgdHlwZS5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDaGlsZEtleXMobm9kZSwgcGFyZW50VHlwZSkge1xuICBpZiAodHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KG5vZGUpKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGQgPSBub2RlW2ldO1xuICAgICAgaWYgKFJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgICAgdmFsaWRhdGVFeHBsaWNpdEtleShjaGlsZCwgcGFyZW50VHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKFJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChub2RlKSkge1xuICAgIC8vIFRoaXMgZWxlbWVudCB3YXMgcGFzc2VkIGluIGEgdmFsaWQgbG9jYXRpb24uXG4gICAgaWYgKG5vZGUuX3N0b3JlKSB7XG4gICAgICBub2RlLl9zdG9yZS52YWxpZGF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIGlmIChub2RlKSB7XG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKG5vZGUpO1xuICAgIC8vIEVudHJ5IGl0ZXJhdG9ycyBwcm92aWRlIGltcGxpY2l0IGtleXMuXG4gICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAgICAgIGlmIChpdGVyYXRvckZuICE9PSBub2RlLmVudHJpZXMpIHtcbiAgICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKG5vZGUpO1xuICAgICAgICB2YXIgc3RlcDtcbiAgICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICAgIGlmIChSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlRXhwbGljaXRLZXkoc3RlcC52YWx1ZSwgcGFyZW50VHlwZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIHByb3BzIGFyZSB2YWxpZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21wb25lbnROYW1lIE5hbWUgb2YgdGhlIGNvbXBvbmVudCBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcFR5cGVzIE1hcCBvZiBwcm9wIG5hbWUgdG8gYSBSZWFjdFByb3BUeXBlXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhdGlvbiBlLmcuIFwicHJvcFwiLCBcImNvbnRleHRcIiwgXCJjaGlsZCBjb250ZXh0XCJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNoZWNrUHJvcFR5cGVzKGNvbXBvbmVudE5hbWUsIHByb3BUeXBlcywgcHJvcHMsIGxvY2F0aW9uKSB7XG4gIGZvciAodmFyIHByb3BOYW1lIGluIHByb3BUeXBlcykge1xuICAgIGlmIChwcm9wVHlwZXMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICB2YXIgZXJyb3I7XG4gICAgICAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgLy8gZmFpbCB0aGUgcmVuZGVyIHBoYXNlIHdoZXJlIGl0IGRpZG4ndCBmYWlsIGJlZm9yZS4gU28gd2UgbG9nIGl0LlxuICAgICAgLy8gQWZ0ZXIgdGhlc2UgaGF2ZSBiZWVuIGNsZWFuZWQgdXAsIHdlJ2xsIGxldCB0aGVtIHRocm93LlxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGFuIGludmFyaWFudCB0aGF0IGdldHMgY2F1Z2h0LiBJdCdzIHRoZSBzYW1lXG4gICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgISh0eXBlb2YgcHJvcFR5cGVzW3Byb3BOYW1lXSA9PT0gJ2Z1bmN0aW9uJykgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnJXM6ICVzIHR5cGUgYCVzYCBpcyBpbnZhbGlkOyBpdCBtdXN0IGJlIGEgZnVuY3Rpb24sIHVzdWFsbHkgZnJvbSAnICsgJ1JlYWN0LlByb3BUeXBlcy4nLCBjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycsIFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzW2xvY2F0aW9uXSwgcHJvcE5hbWUpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgZXJyb3IgPSBwcm9wVHlwZXNbcHJvcE5hbWVdKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIG51bGwsICdTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRCcpO1xuICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgZXJyb3IgPSBleDtcbiAgICAgIH1cbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFlcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIEVycm9yLCAnJXM6IHR5cGUgc3BlY2lmaWNhdGlvbiBvZiAlcyBgJXNgIGlzIGludmFsaWQ7IHRoZSB0eXBlIGNoZWNrZXIgJyArICdmdW5jdGlvbiBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gYEVycm9yYCBidXQgcmV0dXJuZWQgYSAlcy4gJyArICdZb3UgbWF5IGhhdmUgZm9yZ290dGVuIHRvIHBhc3MgYW4gYXJndW1lbnQgdG8gdGhlIHR5cGUgY2hlY2tlciAnICsgJ2NyZWF0b3IgKGFycmF5T2YsIGluc3RhbmNlT2YsIG9iamVjdE9mLCBvbmVPZiwgb25lT2ZUeXBlLCBhbmQgJyArICdzaGFwZSBhbGwgcmVxdWlyZSBhbiBhcmd1bWVudCkuJywgY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnLCBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lc1tsb2NhdGlvbl0sIHByb3BOYW1lLCB0eXBlb2YgZXJyb3IpIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgIShlcnJvci5tZXNzYWdlIGluIGxvZ2dlZFR5cGVGYWlsdXJlcykpIHtcbiAgICAgICAgLy8gT25seSBtb25pdG9yIHRoaXMgZmFpbHVyZSBvbmNlIGJlY2F1c2UgdGhlcmUgdGVuZHMgdG8gYmUgYSBsb3Qgb2YgdGhlXG4gICAgICAgIC8vIHNhbWUgZXJyb3IuXG4gICAgICAgIGxvZ2dlZFR5cGVGYWlsdXJlc1tlcnJvci5tZXNzYWdlXSA9IHRydWU7XG5cbiAgICAgICAgdmFyIGFkZGVuZHVtID0gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCk7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnRmFpbGVkIHByb3BUeXBlOiAlcyVzJywgZXJyb3IubWVzc2FnZSwgYWRkZW5kdW0pIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEdpdmVuIGFuIGVsZW1lbnQsIHZhbGlkYXRlIHRoYXQgaXRzIHByb3BzIGZvbGxvdyB0aGUgcHJvcFR5cGVzIGRlZmluaXRpb24sXG4gKiBwcm92aWRlZCBieSB0aGUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BUeXBlcyhlbGVtZW50KSB7XG4gIHZhciBjb21wb25lbnRDbGFzcyA9IGVsZW1lbnQudHlwZTtcbiAgaWYgKHR5cGVvZiBjb21wb25lbnRDbGFzcyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbmFtZSA9IGNvbXBvbmVudENsYXNzLmRpc3BsYXlOYW1lIHx8IGNvbXBvbmVudENsYXNzLm5hbWU7XG4gIGlmIChjb21wb25lbnRDbGFzcy5wcm9wVHlwZXMpIHtcbiAgICBjaGVja1Byb3BUeXBlcyhuYW1lLCBjb21wb25lbnRDbGFzcy5wcm9wVHlwZXMsIGVsZW1lbnQucHJvcHMsIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnMucHJvcCk7XG4gIH1cbiAgaWYgKHR5cGVvZiBjb21wb25lbnRDbGFzcy5nZXREZWZhdWx0UHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhjb21wb25lbnRDbGFzcy5nZXREZWZhdWx0UHJvcHMuaXNSZWFjdENsYXNzQXBwcm92ZWQsICdnZXREZWZhdWx0UHJvcHMgaXMgb25seSB1c2VkIG9uIGNsYXNzaWMgUmVhY3QuY3JlYXRlQ2xhc3MgJyArICdkZWZpbml0aW9ucy4gVXNlIGEgc3RhdGljIHByb3BlcnR5IG5hbWVkIGBkZWZhdWx0UHJvcHNgIGluc3RlYWQuJykgOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxudmFyIFJlYWN0RWxlbWVudFZhbGlkYXRvciA9IHtcblxuICBjcmVhdGVFbGVtZW50OiBmdW5jdGlvbiAodHlwZSwgcHJvcHMsIGNoaWxkcmVuKSB7XG4gICAgdmFyIHZhbGlkVHlwZSA9IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJztcbiAgICAvLyBXZSB3YXJuIGluIHRoaXMgY2FzZSBidXQgZG9uJ3QgdGhyb3cuIFdlIGV4cGVjdCB0aGUgZWxlbWVudCBjcmVhdGlvbiB0b1xuICAgIC8vIHN1Y2NlZWQgYW5kIHRoZXJlIHdpbGwgbGlrZWx5IGJlIGVycm9ycyBpbiByZW5kZXIuXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcodmFsaWRUeXBlLCAnUmVhY3QuY3JlYXRlRWxlbWVudDogdHlwZSBzaG91bGQgbm90IGJlIG51bGwsIHVuZGVmaW5lZCwgYm9vbGVhbiwgb3IgJyArICdudW1iZXIuIEl0IHNob3VsZCBiZSBhIHN0cmluZyAoZm9yIERPTSBlbGVtZW50cykgb3IgYSBSZWFjdENsYXNzICcgKyAnKGZvciBjb21wb3NpdGUgY29tcG9uZW50cykuJXMnLCBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSkgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgZWxlbWVudCA9IFJlYWN0RWxlbWVudC5jcmVhdGVFbGVtZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvLyBUaGUgcmVzdWx0IGNhbiBiZSBudWxsaXNoIGlmIGEgbW9jayBvciBhIGN1c3RvbSBmdW5jdGlvbiBpcyB1c2VkLlxuICAgIC8vIFRPRE86IERyb3AgdGhpcyB3aGVuIHRoZXNlIGFyZSBubyBsb25nZXIgYWxsb3dlZCBhcyB0aGUgdHlwZSBhcmd1bWVudC5cbiAgICBpZiAoZWxlbWVudCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvLyBTa2lwIGtleSB3YXJuaW5nIGlmIHRoZSB0eXBlIGlzbid0IHZhbGlkIHNpbmNlIG91ciBrZXkgdmFsaWRhdGlvbiBsb2dpY1xuICAgIC8vIGRvZXNuJ3QgZXhwZWN0IGEgbm9uLXN0cmluZy9mdW5jdGlvbiB0eXBlIGFuZCBjYW4gdGhyb3cgY29uZnVzaW5nIGVycm9ycy5cbiAgICAvLyBXZSBkb24ndCB3YW50IGV4Y2VwdGlvbiBiZWhhdmlvciB0byBkaWZmZXIgYmV0d2VlbiBkZXYgYW5kIHByb2QuXG4gICAgLy8gKFJlbmRlcmluZyB3aWxsIHRocm93IHdpdGggYSBoZWxwZnVsIG1lc3NhZ2UgYW5kIGFzIHNvb24gYXMgdGhlIHR5cGUgaXNcbiAgICAvLyBmaXhlZCwgdGhlIGtleSB3YXJuaW5ncyB3aWxsIGFwcGVhci4pXG4gICAgaWYgKHZhbGlkVHlwZSkge1xuICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsaWRhdGVDaGlsZEtleXMoYXJndW1lbnRzW2ldLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YWxpZGF0ZVByb3BUeXBlcyhlbGVtZW50KTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9LFxuXG4gIGNyZWF0ZUZhY3Rvcnk6IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgdmFyIHZhbGlkYXRlZEZhY3RvcnkgPSBSZWFjdEVsZW1lbnRWYWxpZGF0b3IuY3JlYXRlRWxlbWVudC5iaW5kKG51bGwsIHR5cGUpO1xuICAgIC8vIExlZ2FjeSBob29rIFRPRE86IFdhcm4gaWYgdGhpcyBpcyBhY2Nlc3NlZFxuICAgIHZhbGlkYXRlZEZhY3RvcnkudHlwZSA9IHR5cGU7XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKGNhbkRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh2YWxpZGF0ZWRGYWN0b3J5LCAndHlwZScsIHtcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAnRmFjdG9yeS50eXBlIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB0aGUgY2xhc3MgZGlyZWN0bHkgJyArICdiZWZvcmUgcGFzc2luZyBpdCB0byBjcmVhdGVGYWN0b3J5LicpIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0eXBlJywge1xuICAgICAgICAgICAgICB2YWx1ZTogdHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdHlwZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWxpZGF0ZWRGYWN0b3J5O1xuICB9LFxuXG4gIGNsb25lRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnQsIHByb3BzLCBjaGlsZHJlbikge1xuICAgIHZhciBuZXdFbGVtZW50ID0gUmVhY3RFbGVtZW50LmNsb25lRWxlbWVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWxpZGF0ZUNoaWxkS2V5cyhhcmd1bWVudHNbaV0sIG5ld0VsZW1lbnQudHlwZSk7XG4gICAgfVxuICAgIHZhbGlkYXRlUHJvcFR5cGVzKG5ld0VsZW1lbnQpO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RFbGVtZW50VmFsaWRhdG9yOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEVtcHR5Q29tcG9uZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RFbGVtZW50ID0gcmVxdWlyZSgnLi9SZWFjdEVsZW1lbnQnKTtcbnZhciBSZWFjdEVtcHR5Q29tcG9uZW50UmVnaXN0cnkgPSByZXF1aXJlKCcuL1JlYWN0RW1wdHlDb21wb25lbnRSZWdpc3RyeScpO1xudmFyIFJlYWN0UmVjb25jaWxlciA9IHJlcXVpcmUoJy4vUmVhY3RSZWNvbmNpbGVyJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcblxudmFyIHBsYWNlaG9sZGVyRWxlbWVudDtcblxudmFyIFJlYWN0RW1wdHlDb21wb25lbnRJbmplY3Rpb24gPSB7XG4gIGluamVjdEVtcHR5Q29tcG9uZW50OiBmdW5jdGlvbiAoY29tcG9uZW50KSB7XG4gICAgcGxhY2Vob2xkZXJFbGVtZW50ID0gUmVhY3RFbGVtZW50LmNyZWF0ZUVsZW1lbnQoY29tcG9uZW50KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJOdWxsQ29tcG9uZW50SUQoKSB7XG4gIFJlYWN0RW1wdHlDb21wb25lbnRSZWdpc3RyeS5yZWdpc3Rlck51bGxDb21wb25lbnRJRCh0aGlzLl9yb290Tm9kZUlEKTtcbn1cblxudmFyIFJlYWN0RW1wdHlDb21wb25lbnQgPSBmdW5jdGlvbiAoaW5zdGFudGlhdGUpIHtcbiAgdGhpcy5fY3VycmVudEVsZW1lbnQgPSBudWxsO1xuICB0aGlzLl9yb290Tm9kZUlEID0gbnVsbDtcbiAgdGhpcy5fcmVuZGVyZWRDb21wb25lbnQgPSBpbnN0YW50aWF0ZShwbGFjZWhvbGRlckVsZW1lbnQpO1xufTtcbmFzc2lnbihSZWFjdEVtcHR5Q29tcG9uZW50LnByb3RvdHlwZSwge1xuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChlbGVtZW50KSB7fSxcbiAgbW91bnRDb21wb25lbnQ6IGZ1bmN0aW9uIChyb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgdHJhbnNhY3Rpb24uZ2V0UmVhY3RNb3VudFJlYWR5KCkuZW5xdWV1ZShyZWdpc3Rlck51bGxDb21wb25lbnRJRCwgdGhpcyk7XG4gICAgdGhpcy5fcm9vdE5vZGVJRCA9IHJvb3RJRDtcbiAgICByZXR1cm4gUmVhY3RSZWNvbmNpbGVyLm1vdW50Q29tcG9uZW50KHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50LCByb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgfSxcbiAgcmVjZWl2ZUNvbXBvbmVudDogZnVuY3Rpb24gKCkge30sXG4gIHVubW91bnRDb21wb25lbnQ6IGZ1bmN0aW9uIChyb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgUmVhY3RSZWNvbmNpbGVyLnVubW91bnRDb21wb25lbnQodGhpcy5fcmVuZGVyZWRDb21wb25lbnQpO1xuICAgIFJlYWN0RW1wdHlDb21wb25lbnRSZWdpc3RyeS5kZXJlZ2lzdGVyTnVsbENvbXBvbmVudElEKHRoaXMuX3Jvb3ROb2RlSUQpO1xuICAgIHRoaXMuX3Jvb3ROb2RlSUQgPSBudWxsO1xuICAgIHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50ID0gbnVsbDtcbiAgfVxufSk7XG5cblJlYWN0RW1wdHlDb21wb25lbnQuaW5qZWN0aW9uID0gUmVhY3RFbXB0eUNvbXBvbmVudEluamVjdGlvbjtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEVtcHR5Q29tcG9uZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTQtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEVtcHR5Q29tcG9uZW50UmVnaXN0cnlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbi8vIFRoaXMgcmVnaXN0cnkga2VlcHMgdHJhY2sgb2YgdGhlIFJlYWN0IElEcyBvZiB0aGUgY29tcG9uZW50cyB0aGF0IHJlbmRlcmVkIHRvXG4vLyBgbnVsbGAgKGluIHJlYWxpdHkgYSBwbGFjZWhvbGRlciBzdWNoIGFzIGBub3NjcmlwdGApXG52YXIgbnVsbENvbXBvbmVudElEc1JlZ2lzdHJ5ID0ge307XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGlkIENvbXBvbmVudCdzIGBfcm9vdE5vZGVJRGAuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBjb21wb25lbnQgaXMgcmVuZGVyZWQgdG8gbnVsbC5cbiAqL1xuZnVuY3Rpb24gaXNOdWxsQ29tcG9uZW50SUQoaWQpIHtcbiAgcmV0dXJuICEhbnVsbENvbXBvbmVudElEc1JlZ2lzdHJ5W2lkXTtcbn1cblxuLyoqXG4gKiBNYXJrIHRoZSBjb21wb25lbnQgYXMgaGF2aW5nIHJlbmRlcmVkIHRvIG51bGwuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgQ29tcG9uZW50J3MgYF9yb290Tm9kZUlEYC5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJOdWxsQ29tcG9uZW50SUQoaWQpIHtcbiAgbnVsbENvbXBvbmVudElEc1JlZ2lzdHJ5W2lkXSA9IHRydWU7XG59XG5cbi8qKlxuICogVW5tYXJrIHRoZSBjb21wb25lbnQgYXMgaGF2aW5nIHJlbmRlcmVkIHRvIG51bGw6IGl0IHJlbmRlcnMgdG8gc29tZXRoaW5nIG5vdy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCBDb21wb25lbnQncyBgX3Jvb3ROb2RlSURgLlxuICovXG5mdW5jdGlvbiBkZXJlZ2lzdGVyTnVsbENvbXBvbmVudElEKGlkKSB7XG4gIGRlbGV0ZSBudWxsQ29tcG9uZW50SURzUmVnaXN0cnlbaWRdO1xufVxuXG52YXIgUmVhY3RFbXB0eUNvbXBvbmVudFJlZ2lzdHJ5ID0ge1xuICBpc051bGxDb21wb25lbnRJRDogaXNOdWxsQ29tcG9uZW50SUQsXG4gIHJlZ2lzdGVyTnVsbENvbXBvbmVudElEOiByZWdpc3Rlck51bGxDb21wb25lbnRJRCxcbiAgZGVyZWdpc3Rlck51bGxDb21wb25lbnRJRDogZGVyZWdpc3Rlck51bGxDb21wb25lbnRJRFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEVtcHR5Q29tcG9uZW50UmVnaXN0cnk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0RXJyb3JVdGlsc1xuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBjYXVnaHRFcnJvciA9IG51bGw7XG5cbi8qKlxuICogQ2FsbCBhIGZ1bmN0aW9uIHdoaWxlIGd1YXJkaW5nIGFnYWluc3QgZXJyb3JzIHRoYXQgaGFwcGVucyB3aXRoaW4gaXQuXG4gKlxuICogQHBhcmFtIHs/U3RyaW5nfSBuYW1lIG9mIHRoZSBndWFyZCB0byB1c2UgZm9yIGxvZ2dpbmcgb3IgZGVidWdnaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2VcbiAqIEBwYXJhbSB7Kn0gYSBGaXJzdCBhcmd1bWVudFxuICogQHBhcmFtIHsqfSBiIFNlY29uZCBhcmd1bWVudFxuICovXG5mdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobmFtZSwgZnVuYywgYSwgYikge1xuICB0cnkge1xuICAgIHJldHVybiBmdW5jKGEsIGIpO1xuICB9IGNhdGNoICh4KSB7XG4gICAgaWYgKGNhdWdodEVycm9yID09PSBudWxsKSB7XG4gICAgICBjYXVnaHRFcnJvciA9IHg7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxudmFyIFJlYWN0RXJyb3JVdGlscyA9IHtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrOiBpbnZva2VHdWFyZGVkQ2FsbGJhY2ssXG5cbiAgLyoqXG4gICAqIEludm9rZWQgYnkgUmVhY3RUZXN0VXRpbHMuU2ltdWxhdGUgc28gdGhhdCBhbnkgZXJyb3JzIHRocm93biBieSB0aGUgZXZlbnRcbiAgICogaGFuZGxlciBhcmUgc3VyZSB0byBiZSByZXRocm93biBieSByZXRocm93Q2F1Z2h0RXJyb3IuXG4gICAqL1xuICBpbnZva2VHdWFyZGVkQ2FsbGJhY2tXaXRoQ2F0Y2g6IGludm9rZUd1YXJkZWRDYWxsYmFjayxcblxuICAvKipcbiAgICogRHVyaW5nIGV4ZWN1dGlvbiBvZiBndWFyZGVkIGZ1bmN0aW9ucyB3ZSB3aWxsIGNhcHR1cmUgdGhlIGZpcnN0IGVycm9yIHdoaWNoXG4gICAqIHdlIHdpbGwgcmV0aHJvdyB0byBiZSBoYW5kbGVkIGJ5IHRoZSB0b3AgbGV2ZWwgZXJyb3IgaGFuZGxlci5cbiAgICovXG4gIHJldGhyb3dDYXVnaHRFcnJvcjogZnVuY3Rpb24gKCkge1xuICAgIGlmIChjYXVnaHRFcnJvcikge1xuICAgICAgdmFyIGVycm9yID0gY2F1Z2h0RXJyb3I7XG4gICAgICBjYXVnaHRFcnJvciA9IG51bGw7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbn07XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIC8qKlxuICAgKiBUbyBoZWxwIGRldmVsb3BtZW50IHdlIGNhbiBnZXQgYmV0dGVyIGRldnRvb2xzIGludGVncmF0aW9uIGJ5IHNpbXVsYXRpbmcgYVxuICAgKiByZWFsIGJyb3dzZXIgZXZlbnQuXG4gICAqL1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHdpbmRvdy5kaXNwYXRjaEV2ZW50ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIGZha2VOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncmVhY3QnKTtcbiAgICBSZWFjdEVycm9yVXRpbHMuaW52b2tlR3VhcmRlZENhbGxiYWNrID0gZnVuY3Rpb24gKG5hbWUsIGZ1bmMsIGEsIGIpIHtcbiAgICAgIHZhciBib3VuZEZ1bmMgPSBmdW5jLmJpbmQobnVsbCwgYSwgYik7XG4gICAgICB2YXIgZXZ0VHlwZSA9ICdyZWFjdC0nICsgbmFtZTtcbiAgICAgIGZha2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoZXZ0VHlwZSwgYm91bmRGdW5jLCBmYWxzZSk7XG4gICAgICB2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgICBldnQuaW5pdEV2ZW50KGV2dFR5cGUsIGZhbHNlLCBmYWxzZSk7XG4gICAgICBmYWtlTm9kZS5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gICAgICBmYWtlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGV2dFR5cGUsIGJvdW5kRnVuYywgZmFsc2UpO1xuICAgIH07XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEVycm9yVXRpbHM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0RXZlbnRFbWl0dGVyTWl4aW5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFdmVudFBsdWdpbkh1YiA9IHJlcXVpcmUoJy4vRXZlbnRQbHVnaW5IdWInKTtcblxuZnVuY3Rpb24gcnVuRXZlbnRRdWV1ZUluQmF0Y2goZXZlbnRzKSB7XG4gIEV2ZW50UGx1Z2luSHViLmVucXVldWVFdmVudHMoZXZlbnRzKTtcbiAgRXZlbnRQbHVnaW5IdWIucHJvY2Vzc0V2ZW50UXVldWUoZmFsc2UpO1xufVxuXG52YXIgUmVhY3RFdmVudEVtaXR0ZXJNaXhpbiA9IHtcblxuICAvKipcbiAgICogU3RyZWFtcyBhIGZpcmVkIHRvcC1sZXZlbCBldmVudCB0byBgRXZlbnRQbHVnaW5IdWJgIHdoZXJlIHBsdWdpbnMgaGF2ZSB0aGVcbiAgICogb3Bwb3J0dW5pdHkgdG8gY3JlYXRlIGBSZWFjdEV2ZW50YHMgdG8gYmUgZGlzcGF0Y2hlZC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVHlwZSBSZWNvcmQgZnJvbSBgRXZlbnRDb25zdGFudHNgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUYXJnZXRJRCBJRCBvZiBgdG9wTGV2ZWxUYXJnZXRgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGVudmlyb25tZW50IGV2ZW50LlxuICAgKi9cbiAgaGFuZGxlVG9wTGV2ZWw6IGZ1bmN0aW9uICh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElELCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICB2YXIgZXZlbnRzID0gRXZlbnRQbHVnaW5IdWIuZXh0cmFjdEV2ZW50cyh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElELCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIHJ1bkV2ZW50UXVldWVJbkJhdGNoKGV2ZW50cyk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RFdmVudEVtaXR0ZXJNaXhpbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RFdmVudExpc3RlbmVyXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV2ZW50TGlzdGVuZXIgPSByZXF1aXJlKCdmYmpzL2xpYi9FdmVudExpc3RlbmVyJyk7XG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xudmFyIFBvb2xlZENsYXNzID0gcmVxdWlyZSgnLi9Qb29sZWRDbGFzcycpO1xudmFyIFJlYWN0SW5zdGFuY2VIYW5kbGVzID0gcmVxdWlyZSgnLi9SZWFjdEluc3RhbmNlSGFuZGxlcycpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcbnZhciBSZWFjdFVwZGF0ZXMgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlcycpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgZ2V0RXZlbnRUYXJnZXQgPSByZXF1aXJlKCcuL2dldEV2ZW50VGFyZ2V0Jyk7XG52YXIgZ2V0VW5ib3VuZGVkU2Nyb2xsUG9zaXRpb24gPSByZXF1aXJlKCdmYmpzL2xpYi9nZXRVbmJvdW5kZWRTY3JvbGxQb3NpdGlvbicpO1xuXG52YXIgRE9DVU1FTlRfRlJBR01FTlRfTk9ERV9UWVBFID0gMTE7XG5cbi8qKlxuICogRmluZHMgdGhlIHBhcmVudCBSZWFjdCBjb21wb25lbnQgb2YgYG5vZGVgLlxuICpcbiAqIEBwYXJhbSB7Kn0gbm9kZVxuICogQHJldHVybiB7P0RPTUV2ZW50VGFyZ2V0fSBQYXJlbnQgY29udGFpbmVyLCBvciBgbnVsbGAgaWYgdGhlIHNwZWNpZmllZCBub2RlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCBuZXN0ZWQuXG4gKi9cbmZ1bmN0aW9uIGZpbmRQYXJlbnQobm9kZSkge1xuICAvLyBUT0RPOiBJdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gY2FjaGUgdGhpcyB0byBwcmV2ZW50IHVubmVjZXNzYXJ5IERPTVxuICAvLyB0cmF2ZXJzYWwsIGJ1dCBjYWNoaW5nIGlzIGRpZmZpY3VsdCB0byBkbyBjb3JyZWN0bHkgd2l0aG91dCB1c2luZyBhXG4gIC8vIG11dGF0aW9uIG9ic2VydmVyIHRvIGxpc3RlbiBmb3IgYWxsIERPTSBjaGFuZ2VzLlxuICB2YXIgbm9kZUlEID0gUmVhY3RNb3VudC5nZXRJRChub2RlKTtcbiAgdmFyIHJvb3RJRCA9IFJlYWN0SW5zdGFuY2VIYW5kbGVzLmdldFJlYWN0Um9vdElERnJvbU5vZGVJRChub2RlSUQpO1xuICB2YXIgY29udGFpbmVyID0gUmVhY3RNb3VudC5maW5kUmVhY3RDb250YWluZXJGb3JJRChyb290SUQpO1xuICB2YXIgcGFyZW50ID0gUmVhY3RNb3VudC5nZXRGaXJzdFJlYWN0RE9NKGNvbnRhaW5lcik7XG4gIHJldHVybiBwYXJlbnQ7XG59XG5cbi8vIFVzZWQgdG8gc3RvcmUgYW5jZXN0b3IgaGllcmFyY2h5IGluIHRvcCBsZXZlbCBjYWxsYmFja1xuZnVuY3Rpb24gVG9wTGV2ZWxDYWxsYmFja0Jvb2tLZWVwaW5nKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpIHtcbiAgdGhpcy50b3BMZXZlbFR5cGUgPSB0b3BMZXZlbFR5cGU7XG4gIHRoaXMubmF0aXZlRXZlbnQgPSBuYXRpdmVFdmVudDtcbiAgdGhpcy5hbmNlc3RvcnMgPSBbXTtcbn1cbmFzc2lnbihUb3BMZXZlbENhbGxiYWNrQm9va0tlZXBpbmcucHJvdG90eXBlLCB7XG4gIGRlc3RydWN0b3I6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRvcExldmVsVHlwZSA9IG51bGw7XG4gICAgdGhpcy5uYXRpdmVFdmVudCA9IG51bGw7XG4gICAgdGhpcy5hbmNlc3RvcnMubGVuZ3RoID0gMDtcbiAgfVxufSk7XG5Qb29sZWRDbGFzcy5hZGRQb29saW5nVG8oVG9wTGV2ZWxDYWxsYmFja0Jvb2tLZWVwaW5nLCBQb29sZWRDbGFzcy50d29Bcmd1bWVudFBvb2xlcik7XG5cbmZ1bmN0aW9uIGhhbmRsZVRvcExldmVsSW1wbChib29rS2VlcGluZykge1xuICAvLyBUT0RPOiBSZS1lbmFibGUgZXZlbnQucGF0aCBoYW5kbGluZ1xuICAvL1xuICAvLyBpZiAoYm9va0tlZXBpbmcubmF0aXZlRXZlbnQucGF0aCAmJiBib29rS2VlcGluZy5uYXRpdmVFdmVudC5wYXRoLmxlbmd0aCA+IDEpIHtcbiAgLy8gICAvLyBOZXcgYnJvd3NlcnMgaGF2ZSBhIHBhdGggYXR0cmlidXRlIG9uIG5hdGl2ZSBldmVudHNcbiAgLy8gICBoYW5kbGVUb3BMZXZlbFdpdGhQYXRoKGJvb2tLZWVwaW5nKTtcbiAgLy8gfSBlbHNlIHtcbiAgLy8gICAvLyBMZWdhY3kgYnJvd3NlcnMgZG9uJ3QgaGF2ZSBhIHBhdGggYXR0cmlidXRlIG9uIG5hdGl2ZSBldmVudHNcbiAgLy8gICBoYW5kbGVUb3BMZXZlbFdpdGhvdXRQYXRoKGJvb2tLZWVwaW5nKTtcbiAgLy8gfVxuXG4gIHZvaWQgaGFuZGxlVG9wTGV2ZWxXaXRoUGF0aDsgLy8gdGVtcG9yYXJpbHkgdW51c2VkXG4gIGhhbmRsZVRvcExldmVsV2l0aG91dFBhdGgoYm9va0tlZXBpbmcpO1xufVxuXG4vLyBMZWdhY3kgYnJvd3NlcnMgZG9uJ3QgaGF2ZSBhIHBhdGggYXR0cmlidXRlIG9uIG5hdGl2ZSBldmVudHNcbmZ1bmN0aW9uIGhhbmRsZVRvcExldmVsV2l0aG91dFBhdGgoYm9va0tlZXBpbmcpIHtcbiAgdmFyIHRvcExldmVsVGFyZ2V0ID0gUmVhY3RNb3VudC5nZXRGaXJzdFJlYWN0RE9NKGdldEV2ZW50VGFyZ2V0KGJvb2tLZWVwaW5nLm5hdGl2ZUV2ZW50KSkgfHwgd2luZG93O1xuXG4gIC8vIExvb3AgdGhyb3VnaCB0aGUgaGllcmFyY2h5LCBpbiBjYXNlIHRoZXJlJ3MgYW55IG5lc3RlZCBjb21wb25lbnRzLlxuICAvLyBJdCdzIGltcG9ydGFudCB0aGF0IHdlIGJ1aWxkIHRoZSBhcnJheSBvZiBhbmNlc3RvcnMgYmVmb3JlIGNhbGxpbmcgYW55XG4gIC8vIGV2ZW50IGhhbmRsZXJzLCBiZWNhdXNlIGV2ZW50IGhhbmRsZXJzIGNhbiBtb2RpZnkgdGhlIERPTSwgbGVhZGluZyB0b1xuICAvLyBpbmNvbnNpc3RlbmNpZXMgd2l0aCBSZWFjdE1vdW50J3Mgbm9kZSBjYWNoZS4gU2VlICMxMTA1LlxuICB2YXIgYW5jZXN0b3IgPSB0b3BMZXZlbFRhcmdldDtcbiAgd2hpbGUgKGFuY2VzdG9yKSB7XG4gICAgYm9va0tlZXBpbmcuYW5jZXN0b3JzLnB1c2goYW5jZXN0b3IpO1xuICAgIGFuY2VzdG9yID0gZmluZFBhcmVudChhbmNlc3Rvcik7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGJvb2tLZWVwaW5nLmFuY2VzdG9ycy5sZW5ndGg7IGkrKykge1xuICAgIHRvcExldmVsVGFyZ2V0ID0gYm9va0tlZXBpbmcuYW5jZXN0b3JzW2ldO1xuICAgIHZhciB0b3BMZXZlbFRhcmdldElEID0gUmVhY3RNb3VudC5nZXRJRCh0b3BMZXZlbFRhcmdldCkgfHwgJyc7XG4gICAgUmVhY3RFdmVudExpc3RlbmVyLl9oYW5kbGVUb3BMZXZlbChib29rS2VlcGluZy50b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElELCBib29rS2VlcGluZy5uYXRpdmVFdmVudCwgZ2V0RXZlbnRUYXJnZXQoYm9va0tlZXBpbmcubmF0aXZlRXZlbnQpKTtcbiAgfVxufVxuXG4vLyBOZXcgYnJvd3NlcnMgaGF2ZSBhIHBhdGggYXR0cmlidXRlIG9uIG5hdGl2ZSBldmVudHNcbmZ1bmN0aW9uIGhhbmRsZVRvcExldmVsV2l0aFBhdGgoYm9va0tlZXBpbmcpIHtcbiAgdmFyIHBhdGggPSBib29rS2VlcGluZy5uYXRpdmVFdmVudC5wYXRoO1xuICB2YXIgY3VycmVudE5hdGl2ZVRhcmdldCA9IHBhdGhbMF07XG4gIHZhciBldmVudHNGaXJlZCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBjdXJyZW50UGF0aEVsZW1lbnQgPSBwYXRoW2ldO1xuICAgIGlmIChjdXJyZW50UGF0aEVsZW1lbnQubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREVfVFlQRSkge1xuICAgICAgY3VycmVudE5hdGl2ZVRhcmdldCA9IHBhdGhbaSArIDFdO1xuICAgIH1cbiAgICAvLyBUT0RPOiBzbG93XG4gICAgdmFyIHJlYWN0UGFyZW50ID0gUmVhY3RNb3VudC5nZXRGaXJzdFJlYWN0RE9NKGN1cnJlbnRQYXRoRWxlbWVudCk7XG4gICAgaWYgKHJlYWN0UGFyZW50ID09PSBjdXJyZW50UGF0aEVsZW1lbnQpIHtcbiAgICAgIHZhciBjdXJyZW50UGF0aEVsZW1lbnRJRCA9IFJlYWN0TW91bnQuZ2V0SUQoY3VycmVudFBhdGhFbGVtZW50KTtcbiAgICAgIHZhciBuZXdSb290SUQgPSBSZWFjdEluc3RhbmNlSGFuZGxlcy5nZXRSZWFjdFJvb3RJREZyb21Ob2RlSUQoY3VycmVudFBhdGhFbGVtZW50SUQpO1xuICAgICAgYm9va0tlZXBpbmcuYW5jZXN0b3JzLnB1c2goY3VycmVudFBhdGhFbGVtZW50KTtcblxuICAgICAgdmFyIHRvcExldmVsVGFyZ2V0SUQgPSBSZWFjdE1vdW50LmdldElEKGN1cnJlbnRQYXRoRWxlbWVudCkgfHwgJyc7XG4gICAgICBldmVudHNGaXJlZCsrO1xuICAgICAgUmVhY3RFdmVudExpc3RlbmVyLl9oYW5kbGVUb3BMZXZlbChib29rS2VlcGluZy50b3BMZXZlbFR5cGUsIGN1cnJlbnRQYXRoRWxlbWVudCwgdG9wTGV2ZWxUYXJnZXRJRCwgYm9va0tlZXBpbmcubmF0aXZlRXZlbnQsIGN1cnJlbnROYXRpdmVUYXJnZXQpO1xuXG4gICAgICAvLyBKdW1wIHRvIHRoZSByb290IG9mIHRoaXMgUmVhY3QgcmVuZGVyIHRyZWVcbiAgICAgIHdoaWxlIChjdXJyZW50UGF0aEVsZW1lbnRJRCAhPT0gbmV3Um9vdElEKSB7XG4gICAgICAgIGkrKztcbiAgICAgICAgY3VycmVudFBhdGhFbGVtZW50ID0gcGF0aFtpXTtcbiAgICAgICAgY3VycmVudFBhdGhFbGVtZW50SUQgPSBSZWFjdE1vdW50LmdldElEKGN1cnJlbnRQYXRoRWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChldmVudHNGaXJlZCA9PT0gMCkge1xuICAgIFJlYWN0RXZlbnRMaXN0ZW5lci5faGFuZGxlVG9wTGV2ZWwoYm9va0tlZXBpbmcudG9wTGV2ZWxUeXBlLCB3aW5kb3csICcnLCBib29rS2VlcGluZy5uYXRpdmVFdmVudCwgZ2V0RXZlbnRUYXJnZXQoYm9va0tlZXBpbmcubmF0aXZlRXZlbnQpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzY3JvbGxWYWx1ZU1vbml0b3IoY2IpIHtcbiAgdmFyIHNjcm9sbFBvc2l0aW9uID0gZ2V0VW5ib3VuZGVkU2Nyb2xsUG9zaXRpb24od2luZG93KTtcbiAgY2Ioc2Nyb2xsUG9zaXRpb24pO1xufVxuXG52YXIgUmVhY3RFdmVudExpc3RlbmVyID0ge1xuICBfZW5hYmxlZDogdHJ1ZSxcbiAgX2hhbmRsZVRvcExldmVsOiBudWxsLFxuXG4gIFdJTkRPV19IQU5ETEU6IEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSA/IHdpbmRvdyA6IG51bGwsXG5cbiAgc2V0SGFuZGxlVG9wTGV2ZWw6IGZ1bmN0aW9uIChoYW5kbGVUb3BMZXZlbCkge1xuICAgIFJlYWN0RXZlbnRMaXN0ZW5lci5faGFuZGxlVG9wTGV2ZWwgPSBoYW5kbGVUb3BMZXZlbDtcbiAgfSxcblxuICBzZXRFbmFibGVkOiBmdW5jdGlvbiAoZW5hYmxlZCkge1xuICAgIFJlYWN0RXZlbnRMaXN0ZW5lci5fZW5hYmxlZCA9ICEhZW5hYmxlZDtcbiAgfSxcblxuICBpc0VuYWJsZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gUmVhY3RFdmVudExpc3RlbmVyLl9lbmFibGVkO1xuICB9LFxuXG4gIC8qKlxuICAgKiBUcmFwcyB0b3AtbGV2ZWwgZXZlbnRzIGJ5IHVzaW5nIGV2ZW50IGJ1YmJsaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUeXBlIFJlY29yZCBmcm9tIGBFdmVudENvbnN0YW50c2AuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBoYW5kbGVyQmFzZU5hbWUgRXZlbnQgbmFtZSAoZS5nLiBcImNsaWNrXCIpLlxuICAgKiBAcGFyYW0ge29iamVjdH0gaGFuZGxlIEVsZW1lbnQgb24gd2hpY2ggdG8gYXR0YWNoIGxpc3RlbmVyLlxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBhIHJlbW92ZSBmdW5jdGlvbiB3aGljaCB3aWxsIGZvcmNlZnVsbHlcbiAgICogICAgICAgICAgICAgICAgICByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHRyYXBCdWJibGVkRXZlbnQ6IGZ1bmN0aW9uICh0b3BMZXZlbFR5cGUsIGhhbmRsZXJCYXNlTmFtZSwgaGFuZGxlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBoYW5kbGU7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIEV2ZW50TGlzdGVuZXIubGlzdGVuKGVsZW1lbnQsIGhhbmRsZXJCYXNlTmFtZSwgUmVhY3RFdmVudExpc3RlbmVyLmRpc3BhdGNoRXZlbnQuYmluZChudWxsLCB0b3BMZXZlbFR5cGUpKTtcbiAgfSxcblxuICAvKipcbiAgICogVHJhcHMgYSB0b3AtbGV2ZWwgZXZlbnQgYnkgdXNpbmcgZXZlbnQgY2FwdHVyaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUeXBlIFJlY29yZCBmcm9tIGBFdmVudENvbnN0YW50c2AuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBoYW5kbGVyQmFzZU5hbWUgRXZlbnQgbmFtZSAoZS5nLiBcImNsaWNrXCIpLlxuICAgKiBAcGFyYW0ge29iamVjdH0gaGFuZGxlIEVsZW1lbnQgb24gd2hpY2ggdG8gYXR0YWNoIGxpc3RlbmVyLlxuICAgKiBAcmV0dXJuIHs/b2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBhIHJlbW92ZSBmdW5jdGlvbiB3aGljaCB3aWxsIGZvcmNlZnVsbHlcbiAgICogICAgICAgICAgICAgICAgICByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHRyYXBDYXB0dXJlZEV2ZW50OiBmdW5jdGlvbiAodG9wTGV2ZWxUeXBlLCBoYW5kbGVyQmFzZU5hbWUsIGhhbmRsZSkge1xuICAgIHZhciBlbGVtZW50ID0gaGFuZGxlO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBFdmVudExpc3RlbmVyLmNhcHR1cmUoZWxlbWVudCwgaGFuZGxlckJhc2VOYW1lLCBSZWFjdEV2ZW50TGlzdGVuZXIuZGlzcGF0Y2hFdmVudC5iaW5kKG51bGwsIHRvcExldmVsVHlwZSkpO1xuICB9LFxuXG4gIG1vbml0b3JTY3JvbGxWYWx1ZTogZnVuY3Rpb24gKHJlZnJlc2gpIHtcbiAgICB2YXIgY2FsbGJhY2sgPSBzY3JvbGxWYWx1ZU1vbml0b3IuYmluZChudWxsLCByZWZyZXNoKTtcbiAgICBFdmVudExpc3RlbmVyLmxpc3Rlbih3aW5kb3csICdzY3JvbGwnLCBjYWxsYmFjayk7XG4gIH0sXG5cbiAgZGlzcGF0Y2hFdmVudDogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgbmF0aXZlRXZlbnQpIHtcbiAgICBpZiAoIVJlYWN0RXZlbnRMaXN0ZW5lci5fZW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBib29rS2VlcGluZyA9IFRvcExldmVsQ2FsbGJhY2tCb29rS2VlcGluZy5nZXRQb29sZWQodG9wTGV2ZWxUeXBlLCBuYXRpdmVFdmVudCk7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEV2ZW50IHF1ZXVlIGJlaW5nIHByb2Nlc3NlZCBpbiB0aGUgc2FtZSBjeWNsZSBhbGxvd3NcbiAgICAgIC8vIGBwcmV2ZW50RGVmYXVsdGAuXG4gICAgICBSZWFjdFVwZGF0ZXMuYmF0Y2hlZFVwZGF0ZXMoaGFuZGxlVG9wTGV2ZWxJbXBsLCBib29rS2VlcGluZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIFRvcExldmVsQ2FsbGJhY2tCb29rS2VlcGluZy5yZWxlYXNlKGJvb2tLZWVwaW5nKTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RFdmVudExpc3RlbmVyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEluamVjdGlvblxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIERPTVByb3BlcnR5ID0gcmVxdWlyZSgnLi9ET01Qcm9wZXJ0eScpO1xudmFyIEV2ZW50UGx1Z2luSHViID0gcmVxdWlyZSgnLi9FdmVudFBsdWdpbkh1YicpO1xudmFyIFJlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQgPSByZXF1aXJlKCcuL1JlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQnKTtcbnZhciBSZWFjdENsYXNzID0gcmVxdWlyZSgnLi9SZWFjdENsYXNzJyk7XG52YXIgUmVhY3RFbXB0eUNvbXBvbmVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbXB0eUNvbXBvbmVudCcpO1xudmFyIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyJyk7XG52YXIgUmVhY3ROYXRpdmVDb21wb25lbnQgPSByZXF1aXJlKCcuL1JlYWN0TmF0aXZlQ29tcG9uZW50Jyk7XG52YXIgUmVhY3RQZXJmID0gcmVxdWlyZSgnLi9SZWFjdFBlcmYnKTtcbnZhciBSZWFjdFJvb3RJbmRleCA9IHJlcXVpcmUoJy4vUmVhY3RSb290SW5kZXgnKTtcbnZhciBSZWFjdFVwZGF0ZXMgPSByZXF1aXJlKCcuL1JlYWN0VXBkYXRlcycpO1xuXG52YXIgUmVhY3RJbmplY3Rpb24gPSB7XG4gIENvbXBvbmVudDogUmVhY3RDb21wb25lbnRFbnZpcm9ubWVudC5pbmplY3Rpb24sXG4gIENsYXNzOiBSZWFjdENsYXNzLmluamVjdGlvbixcbiAgRE9NUHJvcGVydHk6IERPTVByb3BlcnR5LmluamVjdGlvbixcbiAgRW1wdHlDb21wb25lbnQ6IFJlYWN0RW1wdHlDb21wb25lbnQuaW5qZWN0aW9uLFxuICBFdmVudFBsdWdpbkh1YjogRXZlbnRQbHVnaW5IdWIuaW5qZWN0aW9uLFxuICBFdmVudEVtaXR0ZXI6IFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5pbmplY3Rpb24sXG4gIE5hdGl2ZUNvbXBvbmVudDogUmVhY3ROYXRpdmVDb21wb25lbnQuaW5qZWN0aW9uLFxuICBQZXJmOiBSZWFjdFBlcmYuaW5qZWN0aW9uLFxuICBSb290SW5kZXg6IFJlYWN0Um9vdEluZGV4LmluamVjdGlvbixcbiAgVXBkYXRlczogUmVhY3RVcGRhdGVzLmluamVjdGlvblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEluamVjdGlvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RJbnB1dFNlbGVjdGlvblxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0RE9NU2VsZWN0aW9uID0gcmVxdWlyZSgnLi9SZWFjdERPTVNlbGVjdGlvbicpO1xuXG52YXIgY29udGFpbnNOb2RlID0gcmVxdWlyZSgnZmJqcy9saWIvY29udGFpbnNOb2RlJyk7XG52YXIgZm9jdXNOb2RlID0gcmVxdWlyZSgnZmJqcy9saWIvZm9jdXNOb2RlJyk7XG52YXIgZ2V0QWN0aXZlRWxlbWVudCA9IHJlcXVpcmUoJ2ZianMvbGliL2dldEFjdGl2ZUVsZW1lbnQnKTtcblxuZnVuY3Rpb24gaXNJbkRvY3VtZW50KG5vZGUpIHtcbiAgcmV0dXJuIGNvbnRhaW5zTm9kZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIG5vZGUpO1xufVxuXG4vKipcbiAqIEBSZWFjdElucHV0U2VsZWN0aW9uOiBSZWFjdCBpbnB1dCBzZWxlY3Rpb24gbW9kdWxlLiBCYXNlZCBvbiBTZWxlY3Rpb24uanMsXG4gKiBidXQgbW9kaWZpZWQgdG8gYmUgc3VpdGFibGUgZm9yIHJlYWN0IGFuZCBoYXMgYSBjb3VwbGUgb2YgYnVnIGZpeGVzIChkb2Vzbid0XG4gKiBhc3N1bWUgYnV0dG9ucyBoYXZlIHJhbmdlIHNlbGVjdGlvbnMgYWxsb3dlZCkuXG4gKiBJbnB1dCBzZWxlY3Rpb24gbW9kdWxlIGZvciBSZWFjdC5cbiAqL1xudmFyIFJlYWN0SW5wdXRTZWxlY3Rpb24gPSB7XG5cbiAgaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzOiBmdW5jdGlvbiAoZWxlbSkge1xuICAgIHZhciBub2RlTmFtZSA9IGVsZW0gJiYgZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIG5vZGVOYW1lICYmIChub2RlTmFtZSA9PT0gJ2lucHV0JyAmJiBlbGVtLnR5cGUgPT09ICd0ZXh0JyB8fCBub2RlTmFtZSA9PT0gJ3RleHRhcmVhJyB8fCBlbGVtLmNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnKTtcbiAgfSxcblxuICBnZXRTZWxlY3Rpb25JbmZvcm1hdGlvbjogZnVuY3Rpb24gKCkge1xuICAgIHZhciBmb2N1c2VkRWxlbSA9IGdldEFjdGl2ZUVsZW1lbnQoKTtcbiAgICByZXR1cm4ge1xuICAgICAgZm9jdXNlZEVsZW06IGZvY3VzZWRFbGVtLFxuICAgICAgc2VsZWN0aW9uUmFuZ2U6IFJlYWN0SW5wdXRTZWxlY3Rpb24uaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzKGZvY3VzZWRFbGVtKSA/IFJlYWN0SW5wdXRTZWxlY3Rpb24uZ2V0U2VsZWN0aW9uKGZvY3VzZWRFbGVtKSA6IG51bGxcbiAgICB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcmVzdG9yZVNlbGVjdGlvbjogSWYgYW55IHNlbGVjdGlvbiBpbmZvcm1hdGlvbiB3YXMgcG90ZW50aWFsbHkgbG9zdCxcbiAgICogcmVzdG9yZSBpdC4gVGhpcyBpcyB1c2VmdWwgd2hlbiBwZXJmb3JtaW5nIG9wZXJhdGlvbnMgdGhhdCBjb3VsZCByZW1vdmUgZG9tXG4gICAqIG5vZGVzIGFuZCBwbGFjZSB0aGVtIGJhY2sgaW4sIHJlc3VsdGluZyBpbiBmb2N1cyBiZWluZyBsb3N0LlxuICAgKi9cbiAgcmVzdG9yZVNlbGVjdGlvbjogZnVuY3Rpb24gKHByaW9yU2VsZWN0aW9uSW5mb3JtYXRpb24pIHtcbiAgICB2YXIgY3VyRm9jdXNlZEVsZW0gPSBnZXRBY3RpdmVFbGVtZW50KCk7XG4gICAgdmFyIHByaW9yRm9jdXNlZEVsZW0gPSBwcmlvclNlbGVjdGlvbkluZm9ybWF0aW9uLmZvY3VzZWRFbGVtO1xuICAgIHZhciBwcmlvclNlbGVjdGlvblJhbmdlID0gcHJpb3JTZWxlY3Rpb25JbmZvcm1hdGlvbi5zZWxlY3Rpb25SYW5nZTtcbiAgICBpZiAoY3VyRm9jdXNlZEVsZW0gIT09IHByaW9yRm9jdXNlZEVsZW0gJiYgaXNJbkRvY3VtZW50KHByaW9yRm9jdXNlZEVsZW0pKSB7XG4gICAgICBpZiAoUmVhY3RJbnB1dFNlbGVjdGlvbi5oYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXMocHJpb3JGb2N1c2VkRWxlbSkpIHtcbiAgICAgICAgUmVhY3RJbnB1dFNlbGVjdGlvbi5zZXRTZWxlY3Rpb24ocHJpb3JGb2N1c2VkRWxlbSwgcHJpb3JTZWxlY3Rpb25SYW5nZSk7XG4gICAgICB9XG4gICAgICBmb2N1c05vZGUocHJpb3JGb2N1c2VkRWxlbSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBAZ2V0U2VsZWN0aW9uOiBHZXRzIHRoZSBzZWxlY3Rpb24gYm91bmRzIG9mIGEgZm9jdXNlZCB0ZXh0YXJlYSwgaW5wdXQgb3JcbiAgICogY29udGVudEVkaXRhYmxlIG5vZGUuXG4gICAqIC1AaW5wdXQ6IExvb2sgdXAgc2VsZWN0aW9uIGJvdW5kcyBvZiB0aGlzIGlucHV0XG4gICAqIC1AcmV0dXJuIHtzdGFydDogc2VsZWN0aW9uU3RhcnQsIGVuZDogc2VsZWN0aW9uRW5kfVxuICAgKi9cbiAgZ2V0U2VsZWN0aW9uOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICB2YXIgc2VsZWN0aW9uO1xuXG4gICAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gaW5wdXQpIHtcbiAgICAgIC8vIE1vZGVybiBicm93c2VyIHdpdGggaW5wdXQgb3IgdGV4dGFyZWEuXG4gICAgICBzZWxlY3Rpb24gPSB7XG4gICAgICAgIHN0YXJ0OiBpbnB1dC5zZWxlY3Rpb25TdGFydCxcbiAgICAgICAgZW5kOiBpbnB1dC5zZWxlY3Rpb25FbmRcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudC5zZWxlY3Rpb24gJiYgKGlucHV0Lm5vZGVOYW1lICYmIGlucHV0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCcpKSB7XG4gICAgICAvLyBJRTggaW5wdXQuXG4gICAgICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcbiAgICAgIC8vIFRoZXJlIGNhbiBvbmx5IGJlIG9uZSBzZWxlY3Rpb24gcGVyIGRvY3VtZW50IGluIElFLCBzbyBpdCBtdXN0XG4gICAgICAvLyBiZSBpbiBvdXIgZWxlbWVudC5cbiAgICAgIGlmIChyYW5nZS5wYXJlbnRFbGVtZW50KCkgPT09IGlucHV0KSB7XG4gICAgICAgIHNlbGVjdGlvbiA9IHtcbiAgICAgICAgICBzdGFydDogLXJhbmdlLm1vdmVTdGFydCgnY2hhcmFjdGVyJywgLWlucHV0LnZhbHVlLmxlbmd0aCksXG4gICAgICAgICAgZW5kOiAtcmFuZ2UubW92ZUVuZCgnY2hhcmFjdGVyJywgLWlucHV0LnZhbHVlLmxlbmd0aClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ29udGVudCBlZGl0YWJsZSBvciBvbGQgSUUgdGV4dGFyZWEuXG4gICAgICBzZWxlY3Rpb24gPSBSZWFjdERPTVNlbGVjdGlvbi5nZXRPZmZzZXRzKGlucHV0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZWN0aW9uIHx8IHsgc3RhcnQ6IDAsIGVuZDogMCB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBAc2V0U2VsZWN0aW9uOiBTZXRzIHRoZSBzZWxlY3Rpb24gYm91bmRzIG9mIGEgdGV4dGFyZWEgb3IgaW5wdXQgYW5kIGZvY3VzZXNcbiAgICogdGhlIGlucHV0LlxuICAgKiAtQGlucHV0ICAgICBTZXQgc2VsZWN0aW9uIGJvdW5kcyBvZiB0aGlzIGlucHV0IG9yIHRleHRhcmVhXG4gICAqIC1Ab2Zmc2V0cyAgIE9iamVjdCBvZiBzYW1lIGZvcm0gdGhhdCBpcyByZXR1cm5lZCBmcm9tIGdldCpcbiAgICovXG4gIHNldFNlbGVjdGlvbjogZnVuY3Rpb24gKGlucHV0LCBvZmZzZXRzKSB7XG4gICAgdmFyIHN0YXJ0ID0gb2Zmc2V0cy5zdGFydDtcbiAgICB2YXIgZW5kID0gb2Zmc2V0cy5lbmQ7XG4gICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBlbmQgPSBzdGFydDtcbiAgICB9XG5cbiAgICBpZiAoJ3NlbGVjdGlvblN0YXJ0JyBpbiBpbnB1dCkge1xuICAgICAgaW5wdXQuc2VsZWN0aW9uU3RhcnQgPSBzdGFydDtcbiAgICAgIGlucHV0LnNlbGVjdGlvbkVuZCA9IE1hdGgubWluKGVuZCwgaW5wdXQudmFsdWUubGVuZ3RoKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50LnNlbGVjdGlvbiAmJiAoaW5wdXQubm9kZU5hbWUgJiYgaW5wdXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JykpIHtcbiAgICAgIHZhciByYW5nZSA9IGlucHV0LmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG4gICAgICByYW5nZS5tb3ZlU3RhcnQoJ2NoYXJhY3RlcicsIHN0YXJ0KTtcbiAgICAgIHJhbmdlLm1vdmVFbmQoJ2NoYXJhY3RlcicsIGVuZCAtIHN0YXJ0KTtcbiAgICAgIHJhbmdlLnNlbGVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERPTVNlbGVjdGlvbi5zZXRPZmZzZXRzKGlucHV0LCBvZmZzZXRzKTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RJbnB1dFNlbGVjdGlvbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RJbnN0YW5jZUhhbmRsZXNcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RSb290SW5kZXggPSByZXF1aXJlKCcuL1JlYWN0Um9vdEluZGV4Jyk7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxudmFyIFNFUEFSQVRPUiA9ICcuJztcbnZhciBTRVBBUkFUT1JfTEVOR1RIID0gU0VQQVJBVE9SLmxlbmd0aDtcblxuLyoqXG4gKiBNYXhpbXVtIGRlcHRoIG9mIHRyYXZlcnNhbHMgYmVmb3JlIHdlIGNvbnNpZGVyIHRoZSBwb3NzaWJpbGl0eSBvZiBhIGJhZCBJRC5cbiAqL1xudmFyIE1BWF9UUkVFX0RFUFRIID0gMTAwMDA7XG5cbi8qKlxuICogQ3JlYXRlcyBhIERPTSBJRCBwcmVmaXggdG8gdXNlIHdoZW4gbW91bnRpbmcgUmVhY3QgY29tcG9uZW50cy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggQSB1bmlxdWUgaW50ZWdlclxuICogQHJldHVybiB7c3RyaW5nfSBSZWFjdCByb290IElELlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGdldFJlYWN0Um9vdElEU3RyaW5nKGluZGV4KSB7XG4gIHJldHVybiBTRVBBUkFUT1IgKyBpbmRleC50b1N0cmluZygzNik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgY2hhcmFjdGVyIGluIHRoZSBzdXBwbGllZCBJRCBpcyBhIHNlcGFyYXRvciBvciB0aGUgZW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCBBIFJlYWN0IERPTSBJRC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIHRvIGNoZWNrLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGlzIGEgc2VwYXJhdG9yIG9yIGVuZCBvZiB0aGUgSUQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBpc0JvdW5kYXJ5KGlkLCBpbmRleCkge1xuICByZXR1cm4gaWQuY2hhckF0KGluZGV4KSA9PT0gU0VQQVJBVE9SIHx8IGluZGV4ID09PSBpZC5sZW5ndGg7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBzdXBwbGllZCBzdHJpbmcgaXMgYSB2YWxpZCBSZWFjdCBET00gSUQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlkIEEgUmVhY3QgRE9NIElELCBtYXliZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIFJlYWN0IERPTSBJRC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGlzVmFsaWRJRChpZCkge1xuICByZXR1cm4gaWQgPT09ICcnIHx8IGlkLmNoYXJBdCgwKSA9PT0gU0VQQVJBVE9SICYmIGlkLmNoYXJBdChpZC5sZW5ndGggLSAxKSAhPT0gU0VQQVJBVE9SO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZmlyc3QgSUQgaXMgYW4gYW5jZXN0b3Igb2Ygb3IgZXF1YWwgdG8gdGhlIHNlY29uZCBJRC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYW5jZXN0b3JJRFxuICogQHBhcmFtIHtzdHJpbmd9IGRlc2NlbmRhbnRJRFxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBgYW5jZXN0b3JJRGAgaXMgYW4gYW5jZXN0b3Igb2YgYGRlc2NlbmRhbnRJRGAuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gaXNBbmNlc3RvcklET2YoYW5jZXN0b3JJRCwgZGVzY2VuZGFudElEKSB7XG4gIHJldHVybiBkZXNjZW5kYW50SUQuaW5kZXhPZihhbmNlc3RvcklEKSA9PT0gMCAmJiBpc0JvdW5kYXJ5KGRlc2NlbmRhbnRJRCwgYW5jZXN0b3JJRC5sZW5ndGgpO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIHBhcmVudCBJRCBvZiB0aGUgc3VwcGxpZWQgUmVhY3QgRE9NIElELCBgaWRgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBvZiBhIGNvbXBvbmVudC5cbiAqIEByZXR1cm4ge3N0cmluZ30gSUQgb2YgdGhlIHBhcmVudCwgb3IgYW4gZW1wdHkgc3RyaW5nLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0UGFyZW50SUQoaWQpIHtcbiAgcmV0dXJuIGlkID8gaWQuc3Vic3RyKDAsIGlkLmxhc3RJbmRleE9mKFNFUEFSQVRPUikpIDogJyc7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmV4dCBET00gSUQgb24gdGhlIHRyZWUgcGF0aCBmcm9tIHRoZSBzdXBwbGllZCBgYW5jZXN0b3JJRGAgdG8gdGhlXG4gKiBzdXBwbGllZCBgZGVzdGluYXRpb25JRGAuIElmIHRoZXkgYXJlIGVxdWFsLCB0aGUgSUQgaXMgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFuY2VzdG9ySUQgSUQgb2YgYW4gYW5jZXN0b3Igbm9kZSBvZiBgZGVzdGluYXRpb25JRGAuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzdGluYXRpb25JRCBJRCBvZiB0aGUgZGVzdGluYXRpb24gbm9kZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gTmV4dCBJRCBvbiB0aGUgcGF0aCBmcm9tIGBhbmNlc3RvcklEYCB0byBgZGVzdGluYXRpb25JRGAuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXROZXh0RGVzY2VuZGFudElEKGFuY2VzdG9ySUQsIGRlc3RpbmF0aW9uSUQpIHtcbiAgIShpc1ZhbGlkSUQoYW5jZXN0b3JJRCkgJiYgaXNWYWxpZElEKGRlc3RpbmF0aW9uSUQpKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdnZXROZXh0RGVzY2VuZGFudElEKCVzLCAlcyk6IFJlY2VpdmVkIGFuIGludmFsaWQgUmVhY3QgRE9NIElELicsIGFuY2VzdG9ySUQsIGRlc3RpbmF0aW9uSUQpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgIWlzQW5jZXN0b3JJRE9mKGFuY2VzdG9ySUQsIGRlc3RpbmF0aW9uSUQpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2dldE5leHREZXNjZW5kYW50SUQoLi4uKTogUmVhY3QgaGFzIG1hZGUgYW4gaW52YWxpZCBhc3N1bXB0aW9uIGFib3V0ICcgKyAndGhlIERPTSBoaWVyYXJjaHkuIEV4cGVjdGVkIGAlc2AgdG8gYmUgYW4gYW5jZXN0b3Igb2YgYCVzYC4nLCBhbmNlc3RvcklELCBkZXN0aW5hdGlvbklEKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIGlmIChhbmNlc3RvcklEID09PSBkZXN0aW5hdGlvbklEKSB7XG4gICAgcmV0dXJuIGFuY2VzdG9ySUQ7XG4gIH1cbiAgLy8gU2tpcCBvdmVyIHRoZSBhbmNlc3RvciBhbmQgdGhlIGltbWVkaWF0ZSBzZXBhcmF0b3IuIFRyYXZlcnNlIHVudGlsIHdlIGhpdFxuICAvLyBhbm90aGVyIHNlcGFyYXRvciBvciB3ZSByZWFjaCB0aGUgZW5kIG9mIGBkZXN0aW5hdGlvbklEYC5cbiAgdmFyIHN0YXJ0ID0gYW5jZXN0b3JJRC5sZW5ndGggKyBTRVBBUkFUT1JfTEVOR1RIO1xuICB2YXIgaTtcbiAgZm9yIChpID0gc3RhcnQ7IGkgPCBkZXN0aW5hdGlvbklELmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlzQm91bmRhcnkoZGVzdGluYXRpb25JRCwgaSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVzdGluYXRpb25JRC5zdWJzdHIoMCwgaSk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmVhcmVzdCBjb21tb24gYW5jZXN0b3IgSUQgb2YgdHdvIElEcy5cbiAqXG4gKiBVc2luZyB0aGlzIElEIHNjaGVtZSwgdGhlIG5lYXJlc3QgY29tbW9uIGFuY2VzdG9yIElEIGlzIHRoZSBsb25nZXN0IGNvbW1vblxuICogcHJlZml4IG9mIHRoZSB0d28gSURzIHRoYXQgaW1tZWRpYXRlbHkgcHJlY2VkZWQgYSBcIm1hcmtlclwiIGluIGJvdGggc3RyaW5ncy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gb25lSURcbiAqIEBwYXJhbSB7c3RyaW5nfSB0d29JRFxuICogQHJldHVybiB7c3RyaW5nfSBOZWFyZXN0IGNvbW1vbiBhbmNlc3RvciBJRCwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBub25lLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0Rmlyc3RDb21tb25BbmNlc3RvcklEKG9uZUlELCB0d29JRCkge1xuICB2YXIgbWluTGVuZ3RoID0gTWF0aC5taW4ob25lSUQubGVuZ3RoLCB0d29JRC5sZW5ndGgpO1xuICBpZiAobWluTGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIHZhciBsYXN0Q29tbW9uTWFya2VySW5kZXggPSAwO1xuICAvLyBVc2UgYDw9YCB0byB0cmF2ZXJzZSB1bnRpbCB0aGUgXCJFT0xcIiBvZiB0aGUgc2hvcnRlciBzdHJpbmcuXG4gIGZvciAodmFyIGkgPSAwOyBpIDw9IG1pbkxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlzQm91bmRhcnkob25lSUQsIGkpICYmIGlzQm91bmRhcnkodHdvSUQsIGkpKSB7XG4gICAgICBsYXN0Q29tbW9uTWFya2VySW5kZXggPSBpO1xuICAgIH0gZWxzZSBpZiAob25lSUQuY2hhckF0KGkpICE9PSB0d29JRC5jaGFyQXQoaSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICB2YXIgbG9uZ2VzdENvbW1vbklEID0gb25lSUQuc3Vic3RyKDAsIGxhc3RDb21tb25NYXJrZXJJbmRleCk7XG4gICFpc1ZhbGlkSUQobG9uZ2VzdENvbW1vbklEKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdnZXRGaXJzdENvbW1vbkFuY2VzdG9ySUQoJXMsICVzKTogRXhwZWN0ZWQgYSB2YWxpZCBSZWFjdCBET00gSUQ6ICVzJywgb25lSUQsIHR3b0lELCBsb25nZXN0Q29tbW9uSUQpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGxvbmdlc3RDb21tb25JRDtcbn1cblxuLyoqXG4gKiBUcmF2ZXJzZXMgdGhlIHBhcmVudCBwYXRoIGJldHdlZW4gdHdvIElEcyAoZWl0aGVyIHVwIG9yIGRvd24pLiBUaGUgSURzIG11c3RcbiAqIG5vdCBiZSB0aGUgc2FtZSwgYW5kIHRoZXJlIG11c3QgZXhpc3QgYSBwYXJlbnQgcGF0aCBiZXR3ZWVuIHRoZW0uIElmIHRoZVxuICogY2FsbGJhY2sgcmV0dXJucyBgZmFsc2VgLCB0cmF2ZXJzYWwgaXMgc3RvcHBlZC5cbiAqXG4gKiBAcGFyYW0gez9zdHJpbmd9IHN0YXJ0IElEIGF0IHdoaWNoIHRvIHN0YXJ0IHRyYXZlcnNhbC5cbiAqIEBwYXJhbSB7P3N0cmluZ30gc3RvcCBJRCBhdCB3aGljaCB0byBlbmQgdHJhdmVyc2FsLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2IgQ2FsbGJhY2sgdG8gaW52b2tlIGVhY2ggSUQgd2l0aC5cbiAqIEBwYXJhbSB7Kn0gYXJnIEFyZ3VtZW50IHRvIGludm9rZSB0aGUgY2FsbGJhY2sgd2l0aC5cbiAqIEBwYXJhbSB7P2Jvb2xlYW59IHNraXBGaXJzdCBXaGV0aGVyIG9yIG5vdCB0byBza2lwIHRoZSBmaXJzdCBub2RlLlxuICogQHBhcmFtIHs/Ym9vbGVhbn0gc2tpcExhc3QgV2hldGhlciBvciBub3QgdG8gc2tpcCB0aGUgbGFzdCBub2RlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJhdmVyc2VQYXJlbnRQYXRoKHN0YXJ0LCBzdG9wLCBjYiwgYXJnLCBza2lwRmlyc3QsIHNraXBMYXN0KSB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgJyc7XG4gIHN0b3AgPSBzdG9wIHx8ICcnO1xuICAhKHN0YXJ0ICE9PSBzdG9wKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICd0cmF2ZXJzZVBhcmVudFBhdGgoLi4uKTogQ2Fubm90IHRyYXZlcnNlIGZyb20gYW5kIHRvIHRoZSBzYW1lIElELCBgJXNgLicsIHN0YXJ0KSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIHZhciB0cmF2ZXJzZVVwID0gaXNBbmNlc3RvcklET2Yoc3RvcCwgc3RhcnQpO1xuICAhKHRyYXZlcnNlVXAgfHwgaXNBbmNlc3RvcklET2Yoc3RhcnQsIHN0b3ApKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICd0cmF2ZXJzZVBhcmVudFBhdGgoJXMsICVzLCAuLi4pOiBDYW5ub3QgdHJhdmVyc2UgZnJvbSB0d28gSURzIHRoYXQgZG8gJyArICdub3QgaGF2ZSBhIHBhcmVudCBwYXRoLicsIHN0YXJ0LCBzdG9wKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIC8vIFRyYXZlcnNlIGZyb20gYHN0YXJ0YCB0byBgc3RvcGAgb25lIGRlcHRoIGF0IGEgdGltZS5cbiAgdmFyIGRlcHRoID0gMDtcbiAgdmFyIHRyYXZlcnNlID0gdHJhdmVyc2VVcCA/IGdldFBhcmVudElEIDogZ2V0TmV4dERlc2NlbmRhbnRJRDtcbiAgZm9yICh2YXIgaWQgPSBzdGFydDs7IC8qIHVudGlsIGJyZWFrICovaWQgPSB0cmF2ZXJzZShpZCwgc3RvcCkpIHtcbiAgICB2YXIgcmV0O1xuICAgIGlmICgoIXNraXBGaXJzdCB8fCBpZCAhPT0gc3RhcnQpICYmICghc2tpcExhc3QgfHwgaWQgIT09IHN0b3ApKSB7XG4gICAgICByZXQgPSBjYihpZCwgdHJhdmVyc2VVcCwgYXJnKTtcbiAgICB9XG4gICAgaWYgKHJldCA9PT0gZmFsc2UgfHwgaWQgPT09IHN0b3ApIHtcbiAgICAgIC8vIE9ubHkgYnJlYWsgLy9hZnRlci8vIHZpc2l0aW5nIGBzdG9wYC5cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICAhKGRlcHRoKysgPCBNQVhfVFJFRV9ERVBUSCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAndHJhdmVyc2VQYXJlbnRQYXRoKCVzLCAlcywgLi4uKTogRGV0ZWN0ZWQgYW4gaW5maW5pdGUgbG9vcCB3aGlsZSAnICsgJ3RyYXZlcnNpbmcgdGhlIFJlYWN0IERPTSBJRCB0cmVlLiBUaGlzIG1heSBiZSBkdWUgdG8gbWFsZm9ybWVkIElEczogJXMnLCBzdGFydCwgc3RvcCwgaWQpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIE1hbmFnZXMgdGhlIElEcyBhc3NpZ25lZCB0byBET00gcmVwcmVzZW50YXRpb25zIG9mIFJlYWN0IGNvbXBvbmVudHMuIFRoaXNcbiAqIHVzZXMgYSBzcGVjaWZpYyBzY2hlbWUgaW4gb3JkZXIgdG8gdHJhdmVyc2UgdGhlIERPTSBlZmZpY2llbnRseSAoZS5nLiBpblxuICogb3JkZXIgdG8gc2ltdWxhdGUgZXZlbnRzKS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xudmFyIFJlYWN0SW5zdGFuY2VIYW5kbGVzID0ge1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgUmVhY3Qgcm9vdCBJRFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IEEgUmVhY3Qgcm9vdCBJRC5cbiAgICovXG4gIGNyZWF0ZVJlYWN0Um9vdElEOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGdldFJlYWN0Um9vdElEU3RyaW5nKFJlYWN0Um9vdEluZGV4LmNyZWF0ZVJlYWN0Um9vdEluZGV4KCkpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgUmVhY3QgSUQgYnkgam9pbmluZyBhIHJvb3QgSUQgd2l0aCBhIG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb290SUQgUm9vdCBJRCBvZiBhIHBhcmVudCBjb21wb25lbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEEgY29tcG9uZW50J3MgbmFtZSAoYXMgZmxhdHRlbmVkIGNoaWxkcmVuKS5cbiAgICogQHJldHVybiB7c3RyaW5nfSBBIFJlYWN0IElELlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGNyZWF0ZVJlYWN0SUQ6IGZ1bmN0aW9uIChyb290SUQsIG5hbWUpIHtcbiAgICByZXR1cm4gcm9vdElEICsgbmFtZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0cyB0aGUgRE9NIElEIG9mIHRoZSBSZWFjdCBjb21wb25lbnQgdGhhdCBpcyB0aGUgcm9vdCBvZiB0aGUgdHJlZSB0aGF0XG4gICAqIGNvbnRhaW5zIHRoZSBSZWFjdCBjb21wb25lbnQgd2l0aCB0aGUgc3VwcGxpZWQgRE9NIElELlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgRE9NIElEIG9mIGEgUmVhY3QgY29tcG9uZW50LlxuICAgKiBAcmV0dXJuIHs/c3RyaW5nfSBET00gSUQgb2YgdGhlIFJlYWN0IGNvbXBvbmVudCB0aGF0IGlzIHRoZSByb290LlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldFJlYWN0Um9vdElERnJvbU5vZGVJRDogZnVuY3Rpb24gKGlkKSB7XG4gICAgaWYgKGlkICYmIGlkLmNoYXJBdCgwKSA9PT0gU0VQQVJBVE9SICYmIGlkLmxlbmd0aCA+IDEpIHtcbiAgICAgIHZhciBpbmRleCA9IGlkLmluZGV4T2YoU0VQQVJBVE9SLCAxKTtcbiAgICAgIHJldHVybiBpbmRleCA+IC0xID8gaWQuc3Vic3RyKDAsIGluZGV4KSA6IGlkO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICAvKipcbiAgICogVHJhdmVyc2VzIHRoZSBJRCBoaWVyYXJjaHkgYW5kIGludm9rZXMgdGhlIHN1cHBsaWVkIGBjYmAgb24gYW55IElEcyB0aGF0XG4gICAqIHNob3VsZCB3b3VsZCByZWNlaXZlIGEgYG1vdXNlRW50ZXJgIG9yIGBtb3VzZUxlYXZlYCBldmVudC5cbiAgICpcbiAgICogTk9URTogRG9lcyBub3QgaW52b2tlIHRoZSBjYWxsYmFjayBvbiB0aGUgbmVhcmVzdCBjb21tb24gYW5jZXN0b3IgYmVjYXVzZVxuICAgKiBub3RoaW5nIFwiZW50ZXJlZFwiIG9yIFwibGVmdFwiIHRoYXQgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxlYXZlSUQgSUQgYmVpbmcgbGVmdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGVudGVySUQgSUQgYmVpbmcgZW50ZXJlZC5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2IgQ2FsbGJhY2sgdG8gaW52b2tlIG9uIGVhY2ggZW50ZXJlZC9sZWZ0IElELlxuICAgKiBAcGFyYW0geyp9IHVwQXJnIEFyZ3VtZW50IHRvIGludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBvbiBsZWZ0IElEcy5cbiAgICogQHBhcmFtIHsqfSBkb3duQXJnIEFyZ3VtZW50IHRvIGludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBvbiBlbnRlcmVkIElEcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICB0cmF2ZXJzZUVudGVyTGVhdmU6IGZ1bmN0aW9uIChsZWF2ZUlELCBlbnRlcklELCBjYiwgdXBBcmcsIGRvd25BcmcpIHtcbiAgICB2YXIgYW5jZXN0b3JJRCA9IGdldEZpcnN0Q29tbW9uQW5jZXN0b3JJRChsZWF2ZUlELCBlbnRlcklEKTtcbiAgICBpZiAoYW5jZXN0b3JJRCAhPT0gbGVhdmVJRCkge1xuICAgICAgdHJhdmVyc2VQYXJlbnRQYXRoKGxlYXZlSUQsIGFuY2VzdG9ySUQsIGNiLCB1cEFyZywgZmFsc2UsIHRydWUpO1xuICAgIH1cbiAgICBpZiAoYW5jZXN0b3JJRCAhPT0gZW50ZXJJRCkge1xuICAgICAgdHJhdmVyc2VQYXJlbnRQYXRoKGFuY2VzdG9ySUQsIGVudGVySUQsIGNiLCBkb3duQXJnLCB0cnVlLCBmYWxzZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTaW11bGF0ZXMgdGhlIHRyYXZlcnNhbCBvZiBhIHR3by1waGFzZSwgY2FwdHVyZS9idWJibGUgZXZlbnQgZGlzcGF0Y2guXG4gICAqXG4gICAqIE5PVEU6IFRoaXMgdHJhdmVyc2FsIGhhcHBlbnMgb24gSURzIHdpdGhvdXQgdG91Y2hpbmcgdGhlIERPTS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhcmdldElEIElEIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2IgQ2FsbGJhY2sgdG8gaW52b2tlLlxuICAgKiBAcGFyYW0geyp9IGFyZyBBcmd1bWVudCB0byBpbnZva2UgdGhlIGNhbGxiYWNrIHdpdGguXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdHJhdmVyc2VUd29QaGFzZTogZnVuY3Rpb24gKHRhcmdldElELCBjYiwgYXJnKSB7XG4gICAgaWYgKHRhcmdldElEKSB7XG4gICAgICB0cmF2ZXJzZVBhcmVudFBhdGgoJycsIHRhcmdldElELCBjYiwgYXJnLCB0cnVlLCBmYWxzZSk7XG4gICAgICB0cmF2ZXJzZVBhcmVudFBhdGgodGFyZ2V0SUQsICcnLCBjYiwgYXJnLCBmYWxzZSwgdHJ1ZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTYW1lIGFzIGB0cmF2ZXJzZVR3b1BoYXNlYCBidXQgc2tpcHMgdGhlIGB0YXJnZXRJRGAuXG4gICAqL1xuICB0cmF2ZXJzZVR3b1BoYXNlU2tpcFRhcmdldDogZnVuY3Rpb24gKHRhcmdldElELCBjYiwgYXJnKSB7XG4gICAgaWYgKHRhcmdldElEKSB7XG4gICAgICB0cmF2ZXJzZVBhcmVudFBhdGgoJycsIHRhcmdldElELCBjYiwgYXJnLCB0cnVlLCB0cnVlKTtcbiAgICAgIHRyYXZlcnNlUGFyZW50UGF0aCh0YXJnZXRJRCwgJycsIGNiLCBhcmcsIHRydWUsIHRydWUpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogVHJhdmVyc2UgYSBub2RlIElELCBjYWxsaW5nIHRoZSBzdXBwbGllZCBgY2JgIGZvciBlYWNoIGFuY2VzdG9yIElELiBGb3JcbiAgICogZXhhbXBsZSwgcGFzc2luZyBgLjAuJHJvdy0wLjFgIHdvdWxkIHJlc3VsdCBpbiBgY2JgIGdldHRpbmcgY2FsbGVkXG4gICAqIHdpdGggYC4wYCwgYC4wLiRyb3ctMGAsIGFuZCBgLjAuJHJvdy0wLjFgLlxuICAgKlxuICAgKiBOT1RFOiBUaGlzIHRyYXZlcnNhbCBoYXBwZW5zIG9uIElEcyB3aXRob3V0IHRvdWNoaW5nIHRoZSBET00uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXRJRCBJRCBvZiB0aGUgdGFyZ2V0IG5vZGUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNiIENhbGxiYWNrIHRvIGludm9rZS5cbiAgICogQHBhcmFtIHsqfSBhcmcgQXJndW1lbnQgdG8gaW52b2tlIHRoZSBjYWxsYmFjayB3aXRoLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHRyYXZlcnNlQW5jZXN0b3JzOiBmdW5jdGlvbiAodGFyZ2V0SUQsIGNiLCBhcmcpIHtcbiAgICB0cmF2ZXJzZVBhcmVudFBhdGgoJycsIHRhcmdldElELCBjYiwgYXJnLCB0cnVlLCBmYWxzZSk7XG4gIH0sXG5cbiAgZ2V0Rmlyc3RDb21tb25BbmNlc3RvcklEOiBnZXRGaXJzdENvbW1vbkFuY2VzdG9ySUQsXG5cbiAgLyoqXG4gICAqIEV4cG9zZWQgZm9yIHVuaXQgdGVzdGluZy5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9nZXROZXh0RGVzY2VuZGFudElEOiBnZXROZXh0RGVzY2VuZGFudElELFxuXG4gIGlzQW5jZXN0b3JJRE9mOiBpc0FuY2VzdG9ySURPZixcblxuICBTRVBBUkFUT1I6IFNFUEFSQVRPUlxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0SW5zdGFuY2VIYW5kbGVzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdEluc3RhbmNlTWFwXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBSZWFjdEluc3RhbmNlTWFwYCBtYWludGFpbnMgYSBtYXBwaW5nIGZyb20gYSBwdWJsaWMgZmFjaW5nIHN0YXRlZnVsXG4gKiBpbnN0YW5jZSAoa2V5KSBhbmQgdGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uICh2YWx1ZSkuIFRoaXMgYWxsb3dzIHB1YmxpY1xuICogbWV0aG9kcyB0byBhY2NlcHQgdGhlIHVzZXIgZmFjaW5nIGluc3RhbmNlIGFzIGFuIGFyZ3VtZW50IGFuZCBtYXAgdGhlbSBiYWNrXG4gKiB0byBpbnRlcm5hbCBtZXRob2RzLlxuICovXG5cbi8vIFRPRE86IFJlcGxhY2UgdGhpcyB3aXRoIEVTNjogdmFyIFJlYWN0SW5zdGFuY2VNYXAgPSBuZXcgTWFwKCk7XG52YXIgUmVhY3RJbnN0YW5jZU1hcCA9IHtcblxuICAvKipcbiAgICogVGhpcyBBUEkgc2hvdWxkIGJlIGNhbGxlZCBgZGVsZXRlYCBidXQgd2UnZCBoYXZlIHRvIG1ha2Ugc3VyZSB0byBhbHdheXNcbiAgICogdHJhbnNmb3JtIHRoZXNlIHRvIHN0cmluZ3MgZm9yIElFIHN1cHBvcnQuIFdoZW4gdGhpcyB0cmFuc2Zvcm0gaXMgZnVsbHlcbiAgICogc3VwcG9ydGVkIHdlIGNhbiByZW5hbWUgaXQuXG4gICAqL1xuICByZW1vdmU6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBrZXkuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgfSxcblxuICBnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4ga2V5Ll9yZWFjdEludGVybmFsSW5zdGFuY2U7XG4gIH0sXG5cbiAgaGFzOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGtleS5fcmVhY3RJbnRlcm5hbEluc3RhbmNlICE9PSB1bmRlZmluZWQ7XG4gIH0sXG5cbiAgc2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIGtleS5fcmVhY3RJbnRlcm5hbEluc3RhbmNlID0gdmFsdWU7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdEluc3RhbmNlTWFwOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdElzb21vcnBoaWNcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdENoaWxkcmVuID0gcmVxdWlyZSgnLi9SZWFjdENoaWxkcmVuJyk7XG52YXIgUmVhY3RDb21wb25lbnQgPSByZXF1aXJlKCcuL1JlYWN0Q29tcG9uZW50Jyk7XG52YXIgUmVhY3RDbGFzcyA9IHJlcXVpcmUoJy4vUmVhY3RDbGFzcycpO1xudmFyIFJlYWN0RE9NRmFjdG9yaWVzID0gcmVxdWlyZSgnLi9SZWFjdERPTUZhY3RvcmllcycpO1xudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG52YXIgUmVhY3RFbGVtZW50VmFsaWRhdG9yID0gcmVxdWlyZSgnLi9SZWFjdEVsZW1lbnRWYWxpZGF0b3InKTtcbnZhciBSZWFjdFByb3BUeXBlcyA9IHJlcXVpcmUoJy4vUmVhY3RQcm9wVHlwZXMnKTtcbnZhciBSZWFjdFZlcnNpb24gPSByZXF1aXJlKCcuL1JlYWN0VmVyc2lvbicpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgb25seUNoaWxkID0gcmVxdWlyZSgnLi9vbmx5Q2hpbGQnKTtcblxudmFyIGNyZWF0ZUVsZW1lbnQgPSBSZWFjdEVsZW1lbnQuY3JlYXRlRWxlbWVudDtcbnZhciBjcmVhdGVGYWN0b3J5ID0gUmVhY3RFbGVtZW50LmNyZWF0ZUZhY3Rvcnk7XG52YXIgY2xvbmVFbGVtZW50ID0gUmVhY3RFbGVtZW50LmNsb25lRWxlbWVudDtcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgY3JlYXRlRWxlbWVudCA9IFJlYWN0RWxlbWVudFZhbGlkYXRvci5jcmVhdGVFbGVtZW50O1xuICBjcmVhdGVGYWN0b3J5ID0gUmVhY3RFbGVtZW50VmFsaWRhdG9yLmNyZWF0ZUZhY3Rvcnk7XG4gIGNsb25lRWxlbWVudCA9IFJlYWN0RWxlbWVudFZhbGlkYXRvci5jbG9uZUVsZW1lbnQ7XG59XG5cbnZhciBSZWFjdCA9IHtcblxuICAvLyBNb2Rlcm5cblxuICBDaGlsZHJlbjoge1xuICAgIG1hcDogUmVhY3RDaGlsZHJlbi5tYXAsXG4gICAgZm9yRWFjaDogUmVhY3RDaGlsZHJlbi5mb3JFYWNoLFxuICAgIGNvdW50OiBSZWFjdENoaWxkcmVuLmNvdW50LFxuICAgIHRvQXJyYXk6IFJlYWN0Q2hpbGRyZW4udG9BcnJheSxcbiAgICBvbmx5OiBvbmx5Q2hpbGRcbiAgfSxcblxuICBDb21wb25lbnQ6IFJlYWN0Q29tcG9uZW50LFxuXG4gIGNyZWF0ZUVsZW1lbnQ6IGNyZWF0ZUVsZW1lbnQsXG4gIGNsb25lRWxlbWVudDogY2xvbmVFbGVtZW50LFxuICBpc1ZhbGlkRWxlbWVudDogUmVhY3RFbGVtZW50LmlzVmFsaWRFbGVtZW50LFxuXG4gIC8vIENsYXNzaWNcblxuICBQcm9wVHlwZXM6IFJlYWN0UHJvcFR5cGVzLFxuICBjcmVhdGVDbGFzczogUmVhY3RDbGFzcy5jcmVhdGVDbGFzcyxcbiAgY3JlYXRlRmFjdG9yeTogY3JlYXRlRmFjdG9yeSxcbiAgY3JlYXRlTWl4aW46IGZ1bmN0aW9uIChtaXhpbikge1xuICAgIC8vIEN1cnJlbnRseSBhIG5vb3AuIFdpbGwgYmUgdXNlZCB0byB2YWxpZGF0ZSBhbmQgdHJhY2UgbWl4aW5zLlxuICAgIHJldHVybiBtaXhpbjtcbiAgfSxcblxuICAvLyBUaGlzIGxvb2tzIERPTSBzcGVjaWZpYyBidXQgdGhlc2UgYXJlIGFjdHVhbGx5IGlzb21vcnBoaWMgaGVscGVyc1xuICAvLyBzaW5jZSB0aGV5IGFyZSBqdXN0IGdlbmVyYXRpbmcgRE9NIHN0cmluZ3MuXG4gIERPTTogUmVhY3RET01GYWN0b3JpZXMsXG5cbiAgdmVyc2lvbjogUmVhY3RWZXJzaW9uLFxuXG4gIC8vIEhvb2sgZm9yIEpTWCBzcHJlYWQsIGRvbid0IHVzZSB0aGlzIGZvciBhbnl0aGluZyBlbHNlLlxuICBfX3NwcmVhZDogYXNzaWduXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdE1hcmt1cENoZWNrc3VtXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWRsZXIzMiA9IHJlcXVpcmUoJy4vYWRsZXIzMicpO1xuXG52YXIgVEFHX0VORCA9IC9cXC8/Pi87XG5cbnZhciBSZWFjdE1hcmt1cENoZWNrc3VtID0ge1xuICBDSEVDS1NVTV9BVFRSX05BTUU6ICdkYXRhLXJlYWN0LWNoZWNrc3VtJyxcblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1hcmt1cCBNYXJrdXAgc3RyaW5nXG4gICAqIEByZXR1cm4ge3N0cmluZ30gTWFya3VwIHN0cmluZyB3aXRoIGNoZWNrc3VtIGF0dHJpYnV0ZSBhdHRhY2hlZFxuICAgKi9cbiAgYWRkQ2hlY2tzdW1Ub01hcmt1cDogZnVuY3Rpb24gKG1hcmt1cCkge1xuICAgIHZhciBjaGVja3N1bSA9IGFkbGVyMzIobWFya3VwKTtcblxuICAgIC8vIEFkZCBjaGVja3N1bSAoaGFuZGxlIGJvdGggcGFyZW50IHRhZ3MgYW5kIHNlbGYtY2xvc2luZyB0YWdzKVxuICAgIHJldHVybiBtYXJrdXAucmVwbGFjZShUQUdfRU5ELCAnICcgKyBSZWFjdE1hcmt1cENoZWNrc3VtLkNIRUNLU1VNX0FUVFJfTkFNRSArICc9XCInICsgY2hlY2tzdW0gKyAnXCIkJicpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIHRvIHVzZVxuICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGVsZW1lbnQgcm9vdCBSZWFjdCBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtib29sZWFufSB3aGV0aGVyIG9yIG5vdCB0aGUgbWFya3VwIGlzIHRoZSBzYW1lXG4gICAqL1xuICBjYW5SZXVzZU1hcmt1cDogZnVuY3Rpb24gKG1hcmt1cCwgZWxlbWVudCkge1xuICAgIHZhciBleGlzdGluZ0NoZWNrc3VtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoUmVhY3RNYXJrdXBDaGVja3N1bS5DSEVDS1NVTV9BVFRSX05BTUUpO1xuICAgIGV4aXN0aW5nQ2hlY2tzdW0gPSBleGlzdGluZ0NoZWNrc3VtICYmIHBhcnNlSW50KGV4aXN0aW5nQ2hlY2tzdW0sIDEwKTtcbiAgICB2YXIgbWFya3VwQ2hlY2tzdW0gPSBhZGxlcjMyKG1hcmt1cCk7XG4gICAgcmV0dXJuIG1hcmt1cENoZWNrc3VtID09PSBleGlzdGluZ0NoZWNrc3VtO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0TWFya3VwQ2hlY2tzdW07IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0TW91bnRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBET01Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRE9NUHJvcGVydHknKTtcbnZhciBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL1JlYWN0QnJvd3NlckV2ZW50RW1pdHRlcicpO1xudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0RE9NRmVhdHVyZUZsYWdzID0gcmVxdWlyZSgnLi9SZWFjdERPTUZlYXR1cmVGbGFncycpO1xudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG52YXIgUmVhY3RFbXB0eUNvbXBvbmVudFJlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9SZWFjdEVtcHR5Q29tcG9uZW50UmVnaXN0cnknKTtcbnZhciBSZWFjdEluc3RhbmNlSGFuZGxlcyA9IHJlcXVpcmUoJy4vUmVhY3RJbnN0YW5jZUhhbmRsZXMnKTtcbnZhciBSZWFjdEluc3RhbmNlTWFwID0gcmVxdWlyZSgnLi9SZWFjdEluc3RhbmNlTWFwJyk7XG52YXIgUmVhY3RNYXJrdXBDaGVja3N1bSA9IHJlcXVpcmUoJy4vUmVhY3RNYXJrdXBDaGVja3N1bScpO1xudmFyIFJlYWN0UGVyZiA9IHJlcXVpcmUoJy4vUmVhY3RQZXJmJyk7XG52YXIgUmVhY3RSZWNvbmNpbGVyID0gcmVxdWlyZSgnLi9SZWFjdFJlY29uY2lsZXInKTtcbnZhciBSZWFjdFVwZGF0ZVF1ZXVlID0gcmVxdWlyZSgnLi9SZWFjdFVwZGF0ZVF1ZXVlJyk7XG52YXIgUmVhY3RVcGRhdGVzID0gcmVxdWlyZSgnLi9SZWFjdFVwZGF0ZXMnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGVtcHR5T2JqZWN0ID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlPYmplY3QnKTtcbnZhciBjb250YWluc05vZGUgPSByZXF1aXJlKCdmYmpzL2xpYi9jb250YWluc05vZGUnKTtcbnZhciBpbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50ID0gcmVxdWlyZSgnLi9pbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50Jyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIgc2V0SW5uZXJIVE1MID0gcmVxdWlyZSgnLi9zZXRJbm5lckhUTUwnKTtcbnZhciBzaG91bGRVcGRhdGVSZWFjdENvbXBvbmVudCA9IHJlcXVpcmUoJy4vc2hvdWxkVXBkYXRlUmVhY3RDb21wb25lbnQnKTtcbnZhciB2YWxpZGF0ZURPTU5lc3RpbmcgPSByZXF1aXJlKCcuL3ZhbGlkYXRlRE9NTmVzdGluZycpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciBBVFRSX05BTUUgPSBET01Qcm9wZXJ0eS5JRF9BVFRSSUJVVEVfTkFNRTtcbnZhciBub2RlQ2FjaGUgPSB7fTtcblxudmFyIEVMRU1FTlRfTk9ERV9UWVBFID0gMTtcbnZhciBET0NfTk9ERV9UWVBFID0gOTtcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFX1RZUEUgPSAxMTtcblxudmFyIG93bmVyRG9jdW1lbnRDb250ZXh0S2V5ID0gJ19fUmVhY3RNb3VudF9vd25lckRvY3VtZW50JCcgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcblxuLyoqIE1hcHBpbmcgZnJvbSByZWFjdFJvb3RJRCB0byBSZWFjdCBjb21wb25lbnQgaW5zdGFuY2UuICovXG52YXIgaW5zdGFuY2VzQnlSZWFjdFJvb3RJRCA9IHt9O1xuXG4vKiogTWFwcGluZyBmcm9tIHJlYWN0Um9vdElEIHRvIGBjb250YWluZXJgIG5vZGVzLiAqL1xudmFyIGNvbnRhaW5lcnNCeVJlYWN0Um9vdElEID0ge307XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIC8qKiBfX0RFVl9fLW9ubHkgbWFwcGluZyBmcm9tIHJlYWN0Um9vdElEIHRvIHJvb3QgZWxlbWVudHMuICovXG4gIHZhciByb290RWxlbWVudHNCeVJlYWN0Um9vdElEID0ge307XG59XG5cbi8vIFVzZWQgdG8gc3RvcmUgYnJlYWR0aC1maXJzdCBzZWFyY2ggc3RhdGUgaW4gZmluZENvbXBvbmVudFJvb3QuXG52YXIgZmluZENvbXBvbmVudFJvb3RSZXVzYWJsZUFycmF5ID0gW107XG5cbi8qKlxuICogRmluZHMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXJcbiAqIHRoYXQncyBub3QgY29tbW9uIGJldHdlZW4gdGhlIHR3byBnaXZlbiBzdHJpbmdzLlxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgd2hlcmUgdGhlIHN0cmluZ3MgZGl2ZXJnZVxuICovXG5mdW5jdGlvbiBmaXJzdERpZmZlcmVuY2VJbmRleChzdHJpbmcxLCBzdHJpbmcyKSB7XG4gIHZhciBtaW5MZW4gPSBNYXRoLm1pbihzdHJpbmcxLmxlbmd0aCwgc3RyaW5nMi5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1pbkxlbjsgaSsrKSB7XG4gICAgaWYgKHN0cmluZzEuY2hhckF0KGkpICE9PSBzdHJpbmcyLmNoYXJBdChpKSkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHJpbmcxLmxlbmd0aCA9PT0gc3RyaW5nMi5sZW5ndGggPyAtMSA6IG1pbkxlbjtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NRG9jdW1lbnR9IGNvbnRhaW5lciBET00gZWxlbWVudCB0aGF0IG1heSBjb250YWluXG4gKiBhIFJlYWN0IGNvbXBvbmVudFxuICogQHJldHVybiB7Pyp9IERPTSBlbGVtZW50IHRoYXQgbWF5IGhhdmUgdGhlIHJlYWN0Um9vdCBJRCwgb3IgbnVsbC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmVhY3RSb290RWxlbWVudEluQ29udGFpbmVyKGNvbnRhaW5lcikge1xuICBpZiAoIWNvbnRhaW5lcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRE9DX05PREVfVFlQRSkge1xuICAgIHJldHVybiBjb250YWluZXIuZG9jdW1lbnRFbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb250YWluZXIuZmlyc3RDaGlsZDtcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIERPTSBlbGVtZW50IHRoYXQgbWF5IGNvbnRhaW4gYSBSZWFjdCBjb21wb25lbnQuXG4gKiBAcmV0dXJuIHs/c3RyaW5nfSBBIFwicmVhY3RSb290XCIgSUQsIGlmIGEgUmVhY3QgY29tcG9uZW50IGlzIHJlbmRlcmVkLlxuICovXG5mdW5jdGlvbiBnZXRSZWFjdFJvb3RJRChjb250YWluZXIpIHtcbiAgdmFyIHJvb3RFbGVtZW50ID0gZ2V0UmVhY3RSb290RWxlbWVudEluQ29udGFpbmVyKGNvbnRhaW5lcik7XG4gIHJldHVybiByb290RWxlbWVudCAmJiBSZWFjdE1vdW50LmdldElEKHJvb3RFbGVtZW50KTtcbn1cblxuLyoqXG4gKiBBY2Nlc3Npbmcgbm9kZVtBVFRSX05BTUVdIG9yIGNhbGxpbmcgZ2V0QXR0cmlidXRlKEFUVFJfTkFNRSkgb24gYSBmb3JtXG4gKiBlbGVtZW50IGNhbiByZXR1cm4gaXRzIGNvbnRyb2wgd2hvc2UgbmFtZSBvciBJRCBlcXVhbHMgQVRUUl9OQU1FLiBBbGxcbiAqIERPTSBub2RlcyBzdXBwb3J0IGBnZXRBdHRyaWJ1dGVOb2RlYCBidXQgdGhpcyBjYW4gYWxzbyBnZXQgY2FsbGVkIG9uXG4gKiBvdGhlciBvYmplY3RzIHNvIGp1c3QgcmV0dXJuICcnIGlmIHdlJ3JlIGdpdmVuIHNvbWV0aGluZyBvdGhlciB0aGFuIGFcbiAqIERPTSBub2RlIChzdWNoIGFzIHdpbmRvdykuXG4gKlxuICogQHBhcmFtIHs/RE9NRWxlbWVudHxET01XaW5kb3d8RE9NRG9jdW1lbnR8RE9NVGV4dE5vZGV9IG5vZGUgRE9NIG5vZGUuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IElEIG9mIHRoZSBzdXBwbGllZCBgZG9tTm9kZWAuXG4gKi9cbmZ1bmN0aW9uIGdldElEKG5vZGUpIHtcbiAgdmFyIGlkID0gaW50ZXJuYWxHZXRJRChub2RlKTtcbiAgaWYgKGlkKSB7XG4gICAgaWYgKG5vZGVDYWNoZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICAgIHZhciBjYWNoZWQgPSBub2RlQ2FjaGVbaWRdO1xuICAgICAgaWYgKGNhY2hlZCAhPT0gbm9kZSkge1xuICAgICAgICAhIWlzVmFsaWQoY2FjaGVkLCBpZCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnUmVhY3RNb3VudDogVHdvIHZhbGlkIGJ1dCB1bmVxdWFsIG5vZGVzIHdpdGggdGhlIHNhbWUgYCVzYDogJXMnLCBBVFRSX05BTUUsIGlkKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgbm9kZUNhY2hlW2lkXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGVDYWNoZVtpZF0gPSBub2RlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpZDtcbn1cblxuZnVuY3Rpb24gaW50ZXJuYWxHZXRJRChub2RlKSB7XG4gIC8vIElmIG5vZGUgaXMgc29tZXRoaW5nIGxpa2UgYSB3aW5kb3csIGRvY3VtZW50LCBvciB0ZXh0IG5vZGUsIG5vbmUgb2ZcbiAgLy8gd2hpY2ggc3VwcG9ydCBhdHRyaWJ1dGVzIG9yIGEgLmdldEF0dHJpYnV0ZSBtZXRob2QsIGdyYWNlZnVsbHkgcmV0dXJuXG4gIC8vIHRoZSBlbXB0eSBzdHJpbmcsIGFzIGlmIHRoZSBhdHRyaWJ1dGUgd2VyZSBtaXNzaW5nLlxuICByZXR1cm4gbm9kZSAmJiBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShBVFRSX05BTUUpIHx8ICcnO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIFJlYWN0LXNwZWNpZmljIElEIG9mIHRoZSBnaXZlbiBub2RlLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZSBUaGUgRE9NIG5vZGUgd2hvc2UgSUQgd2lsbCBiZSBzZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIHZhbHVlIG9mIHRoZSBJRCBhdHRyaWJ1dGUuXG4gKi9cbmZ1bmN0aW9uIHNldElEKG5vZGUsIGlkKSB7XG4gIHZhciBvbGRJRCA9IGludGVybmFsR2V0SUQobm9kZSk7XG4gIGlmIChvbGRJRCAhPT0gaWQpIHtcbiAgICBkZWxldGUgbm9kZUNhY2hlW29sZElEXTtcbiAgfVxuICBub2RlLnNldEF0dHJpYnV0ZShBVFRSX05BTUUsIGlkKTtcbiAgbm9kZUNhY2hlW2lkXSA9IG5vZGU7XG59XG5cbi8qKlxuICogRmluZHMgdGhlIG5vZGUgd2l0aCB0aGUgc3VwcGxpZWQgUmVhY3QtZ2VuZXJhdGVkIERPTSBJRC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgQSBSZWFjdC1nZW5lcmF0ZWQgRE9NIElELlxuICogQHJldHVybiB7RE9NRWxlbWVudH0gRE9NIG5vZGUgd2l0aCB0aGUgc3VwcGxlZCBgaWRgLlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGdldE5vZGUoaWQpIHtcbiAgaWYgKCFub2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaWQpIHx8ICFpc1ZhbGlkKG5vZGVDYWNoZVtpZF0sIGlkKSkge1xuICAgIG5vZGVDYWNoZVtpZF0gPSBSZWFjdE1vdW50LmZpbmRSZWFjdE5vZGVCeUlEKGlkKTtcbiAgfVxuICByZXR1cm4gbm9kZUNhY2hlW2lkXTtcbn1cblxuLyoqXG4gKiBGaW5kcyB0aGUgbm9kZSB3aXRoIHRoZSBzdXBwbGllZCBwdWJsaWMgUmVhY3QgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHsqfSBpbnN0YW5jZSBBIHB1YmxpYyBSZWFjdCBpbnN0YW5jZS5cbiAqIEByZXR1cm4gez9ET01FbGVtZW50fSBET00gbm9kZSB3aXRoIHRoZSBzdXBwbGVkIGBpZGAuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gZ2V0Tm9kZUZyb21JbnN0YW5jZShpbnN0YW5jZSkge1xuICB2YXIgaWQgPSBSZWFjdEluc3RhbmNlTWFwLmdldChpbnN0YW5jZSkuX3Jvb3ROb2RlSUQ7XG4gIGlmIChSZWFjdEVtcHR5Q29tcG9uZW50UmVnaXN0cnkuaXNOdWxsQ29tcG9uZW50SUQoaWQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKCFub2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaWQpIHx8ICFpc1ZhbGlkKG5vZGVDYWNoZVtpZF0sIGlkKSkge1xuICAgIG5vZGVDYWNoZVtpZF0gPSBSZWFjdE1vdW50LmZpbmRSZWFjdE5vZGVCeUlEKGlkKTtcbiAgfVxuICByZXR1cm4gbm9kZUNhY2hlW2lkXTtcbn1cblxuLyoqXG4gKiBBIG5vZGUgaXMgXCJ2YWxpZFwiIGlmIGl0IGlzIGNvbnRhaW5lZCBieSBhIGN1cnJlbnRseSBtb3VudGVkIGNvbnRhaW5lci5cbiAqXG4gKiBUaGlzIG1lYW5zIHRoYXQgdGhlIG5vZGUgZG9lcyBub3QgaGF2ZSB0byBiZSBjb250YWluZWQgYnkgYSBkb2N1bWVudCBpblxuICogb3JkZXIgdG8gYmUgY29uc2lkZXJlZCB2YWxpZC5cbiAqXG4gKiBAcGFyYW0gez9ET01FbGVtZW50fSBub2RlIFRoZSBjYW5kaWRhdGUgRE9NIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIGV4cGVjdGVkIElEIG9mIHRoZSBub2RlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBjb250YWluZWQgYnkgYSBtb3VudGVkIGNvbnRhaW5lci5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZChub2RlLCBpZCkge1xuICBpZiAobm9kZSkge1xuICAgICEoaW50ZXJuYWxHZXRJRChub2RlKSA9PT0gaWQpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0TW91bnQ6IFVuZXhwZWN0ZWQgbW9kaWZpY2F0aW9uIG9mIGAlc2AnLCBBVFRSX05BTUUpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIHZhciBjb250YWluZXIgPSBSZWFjdE1vdW50LmZpbmRSZWFjdENvbnRhaW5lckZvcklEKGlkKTtcbiAgICBpZiAoY29udGFpbmVyICYmIGNvbnRhaW5zTm9kZShjb250YWluZXIsIG5vZGUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2F1c2VzIHRoZSBjYWNoZSB0byBmb3JnZXQgYWJvdXQgb25lIFJlYWN0LXNwZWNpZmljIElELlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCBUaGUgSUQgdG8gZm9yZ2V0LlxuICovXG5mdW5jdGlvbiBwdXJnZUlEKGlkKSB7XG4gIGRlbGV0ZSBub2RlQ2FjaGVbaWRdO1xufVxuXG52YXIgZGVlcGVzdE5vZGVTb0ZhciA9IG51bGw7XG5mdW5jdGlvbiBmaW5kRGVlcGVzdENhY2hlZEFuY2VzdG9ySW1wbChhbmNlc3RvcklEKSB7XG4gIHZhciBhbmNlc3RvciA9IG5vZGVDYWNoZVthbmNlc3RvcklEXTtcbiAgaWYgKGFuY2VzdG9yICYmIGlzVmFsaWQoYW5jZXN0b3IsIGFuY2VzdG9ySUQpKSB7XG4gICAgZGVlcGVzdE5vZGVTb0ZhciA9IGFuY2VzdG9yO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgbm9kZSBpc24ndCBwb3B1bGF0ZWQgaW4gdGhlIGNhY2hlLCBzbyBwcmVzdW1hYmx5IG5vbmUgb2YgaXRzXG4gICAgLy8gZGVzY2VuZGFudHMgYXJlLiBCcmVhayBvdXQgb2YgdGhlIGxvb3AuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBkZWVwZXN0IGNhY2hlZCBub2RlIHdob3NlIElEIGlzIGEgcHJlZml4IG9mIGB0YXJnZXRJRGAuXG4gKi9cbmZ1bmN0aW9uIGZpbmREZWVwZXN0Q2FjaGVkQW5jZXN0b3IodGFyZ2V0SUQpIHtcbiAgZGVlcGVzdE5vZGVTb0ZhciA9IG51bGw7XG4gIFJlYWN0SW5zdGFuY2VIYW5kbGVzLnRyYXZlcnNlQW5jZXN0b3JzKHRhcmdldElELCBmaW5kRGVlcGVzdENhY2hlZEFuY2VzdG9ySW1wbCk7XG5cbiAgdmFyIGZvdW5kTm9kZSA9IGRlZXBlc3ROb2RlU29GYXI7XG4gIGRlZXBlc3ROb2RlU29GYXIgPSBudWxsO1xuICByZXR1cm4gZm91bmROb2RlO1xufVxuXG4vKipcbiAqIE1vdW50cyB0aGlzIGNvbXBvbmVudCBhbmQgaW5zZXJ0cyBpdCBpbnRvIHRoZSBET00uXG4gKlxuICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY29tcG9uZW50SW5zdGFuY2UgVGhlIGluc3RhbmNlIHRvIG1vdW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHJvb3RJRCBET00gSUQgb2YgdGhlIHJvb3Qgbm9kZS5cbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIERPTSBlbGVtZW50IHRvIG1vdW50IGludG8uXG4gKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFJldXNlTWFya3VwIElmIHRydWUsIGRvIG5vdCBpbnNlcnQgbWFya3VwXG4gKi9cbmZ1bmN0aW9uIG1vdW50Q29tcG9uZW50SW50b05vZGUoY29tcG9uZW50SW5zdGFuY2UsIHJvb3RJRCwgY29udGFpbmVyLCB0cmFuc2FjdGlvbiwgc2hvdWxkUmV1c2VNYXJrdXAsIGNvbnRleHQpIHtcbiAgaWYgKFJlYWN0RE9NRmVhdHVyZUZsYWdzLnVzZUNyZWF0ZUVsZW1lbnQpIHtcbiAgICBjb250ZXh0ID0gYXNzaWduKHt9LCBjb250ZXh0KTtcbiAgICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NfTk9ERV9UWVBFKSB7XG4gICAgICBjb250ZXh0W293bmVyRG9jdW1lbnRDb250ZXh0S2V5XSA9IGNvbnRhaW5lcjtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dFtvd25lckRvY3VtZW50Q29udGV4dEtleV0gPSBjb250YWluZXIub3duZXJEb2N1bWVudDtcbiAgICB9XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBpZiAoY29udGV4dCA9PT0gZW1wdHlPYmplY3QpIHtcbiAgICAgIGNvbnRleHQgPSB7fTtcbiAgICB9XG4gICAgdmFyIHRhZyA9IGNvbnRhaW5lci5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnRleHRbdmFsaWRhdGVET01OZXN0aW5nLmFuY2VzdG9ySW5mb0NvbnRleHRLZXldID0gdmFsaWRhdGVET01OZXN0aW5nLnVwZGF0ZWRBbmNlc3RvckluZm8obnVsbCwgdGFnLCBudWxsKTtcbiAgfVxuICB2YXIgbWFya3VwID0gUmVhY3RSZWNvbmNpbGVyLm1vdW50Q29tcG9uZW50KGNvbXBvbmVudEluc3RhbmNlLCByb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgY29tcG9uZW50SW5zdGFuY2UuX3JlbmRlcmVkQ29tcG9uZW50Ll90b3BMZXZlbFdyYXBwZXIgPSBjb21wb25lbnRJbnN0YW5jZTtcbiAgUmVhY3RNb3VudC5fbW91bnRJbWFnZUludG9Ob2RlKG1hcmt1cCwgY29udGFpbmVyLCBzaG91bGRSZXVzZU1hcmt1cCwgdHJhbnNhY3Rpb24pO1xufVxuXG4vKipcbiAqIEJhdGNoZWQgbW91bnQuXG4gKlxuICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY29tcG9uZW50SW5zdGFuY2UgVGhlIGluc3RhbmNlIHRvIG1vdW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHJvb3RJRCBET00gSUQgb2YgdGhlIHJvb3Qgbm9kZS5cbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIERPTSBlbGVtZW50IHRvIG1vdW50IGludG8uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFJldXNlTWFya3VwIElmIHRydWUsIGRvIG5vdCBpbnNlcnQgbWFya3VwXG4gKi9cbmZ1bmN0aW9uIGJhdGNoZWRNb3VudENvbXBvbmVudEludG9Ob2RlKGNvbXBvbmVudEluc3RhbmNlLCByb290SUQsIGNvbnRhaW5lciwgc2hvdWxkUmV1c2VNYXJrdXAsIGNvbnRleHQpIHtcbiAgdmFyIHRyYW5zYWN0aW9uID0gUmVhY3RVcGRhdGVzLlJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24uZ2V0UG9vbGVkKFxuICAvKiBmb3JjZUhUTUwgKi9zaG91bGRSZXVzZU1hcmt1cCk7XG4gIHRyYW5zYWN0aW9uLnBlcmZvcm0obW91bnRDb21wb25lbnRJbnRvTm9kZSwgbnVsbCwgY29tcG9uZW50SW5zdGFuY2UsIHJvb3RJRCwgY29udGFpbmVyLCB0cmFuc2FjdGlvbiwgc2hvdWxkUmV1c2VNYXJrdXAsIGNvbnRleHQpO1xuICBSZWFjdFVwZGF0ZXMuUmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbi5yZWxlYXNlKHRyYW5zYWN0aW9uKTtcbn1cblxuLyoqXG4gKiBVbm1vdW50cyBhIGNvbXBvbmVudCBhbmQgcmVtb3ZlcyBpdCBmcm9tIHRoZSBET00uXG4gKlxuICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gaW5zdGFuY2UgUmVhY3QgY29tcG9uZW50IGluc3RhbmNlLlxuICogQHBhcmFtIHtET01FbGVtZW50fSBjb250YWluZXIgRE9NIGVsZW1lbnQgdG8gdW5tb3VudCBmcm9tLlxuICogQGZpbmFsXG4gKiBAaW50ZXJuYWxcbiAqIEBzZWUge1JlYWN0TW91bnQudW5tb3VudENvbXBvbmVudEF0Tm9kZX1cbiAqL1xuZnVuY3Rpb24gdW5tb3VudENvbXBvbmVudEZyb21Ob2RlKGluc3RhbmNlLCBjb250YWluZXIpIHtcbiAgUmVhY3RSZWNvbmNpbGVyLnVubW91bnRDb21wb25lbnQoaW5zdGFuY2UpO1xuXG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IERPQ19OT0RFX1RZUEUpIHtcbiAgICBjb250YWluZXIgPSBjb250YWluZXIuZG9jdW1lbnRFbGVtZW50O1xuICB9XG5cbiAgLy8gaHR0cDovL2pzcGVyZi5jb20vZW1wdHlpbmctYS1ub2RlXG4gIHdoaWxlIChjb250YWluZXIubGFzdENoaWxkKSB7XG4gICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKGNvbnRhaW5lci5sYXN0Q2hpbGQpO1xuICB9XG59XG5cbi8qKlxuICogVHJ1ZSBpZiB0aGUgc3VwcGxpZWQgRE9NIG5vZGUgaGFzIGEgZGlyZWN0IFJlYWN0LXJlbmRlcmVkIGNoaWxkIHRoYXQgaXNcbiAqIG5vdCBhIFJlYWN0IHJvb3QgZWxlbWVudC4gVXNlZnVsIGZvciB3YXJuaW5nIGluIGByZW5kZXJgLFxuICogYHVubW91bnRDb21wb25lbnRBdE5vZGVgLCBldGMuXG4gKlxuICogQHBhcmFtIHs/RE9NRWxlbWVudH0gbm9kZSBUaGUgY2FuZGlkYXRlIERPTSBub2RlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgRE9NIGVsZW1lbnQgY29udGFpbnMgYSBkaXJlY3QgY2hpbGQgdGhhdCB3YXNcbiAqIHJlbmRlcmVkIGJ5IFJlYWN0IGJ1dCBpcyBub3QgYSByb290IGVsZW1lbnQuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gaGFzTm9uUm9vdFJlYWN0Q2hpbGQobm9kZSkge1xuICB2YXIgcmVhY3RSb290SUQgPSBnZXRSZWFjdFJvb3RJRChub2RlKTtcbiAgcmV0dXJuIHJlYWN0Um9vdElEID8gcmVhY3RSb290SUQgIT09IFJlYWN0SW5zdGFuY2VIYW5kbGVzLmdldFJlYWN0Um9vdElERnJvbU5vZGVJRChyZWFjdFJvb3RJRCkgOiBmYWxzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCAoZGVlcGVzdCkgYW5jZXN0b3Igb2YgYSBub2RlIHdoaWNoIGlzIHJlbmRlcmVkIGJ5IHRoaXMgY29weVxuICogb2YgUmVhY3QuXG4gKi9cbmZ1bmN0aW9uIGZpbmRGaXJzdFJlYWN0RE9NSW1wbChub2RlKSB7XG4gIC8vIFRoaXMgbm9kZSBtaWdodCBiZSBmcm9tIGFub3RoZXIgUmVhY3QgaW5zdGFuY2UsIHNvIHdlIG1ha2Ugc3VyZSBub3QgdG9cbiAgLy8gZXhhbWluZSB0aGUgbm9kZSBjYWNoZSBoZXJlXG4gIGZvciAoOyBub2RlICYmIG5vZGUucGFyZW50Tm9kZSAhPT0gbm9kZTsgbm9kZSA9IG5vZGUucGFyZW50Tm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSAxKSB7XG4gICAgICAvLyBOb3QgYSBET01FbGVtZW50LCB0aGVyZWZvcmUgbm90IGEgUmVhY3QgY29tcG9uZW50XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIG5vZGVJRCA9IGludGVybmFsR2V0SUQobm9kZSk7XG4gICAgaWYgKCFub2RlSUQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgcmVhY3RSb290SUQgPSBSZWFjdEluc3RhbmNlSGFuZGxlcy5nZXRSZWFjdFJvb3RJREZyb21Ob2RlSUQobm9kZUlEKTtcblxuICAgIC8vIElmIGNvbnRhaW5lcnNCeVJlYWN0Um9vdElEIGNvbnRhaW5zIHRoZSBjb250YWluZXIgd2UgZmluZCBieSBjcmF3bGluZyB1cFxuICAgIC8vIHRoZSB0cmVlLCB3ZSBrbm93IHRoYXQgdGhpcyBpbnN0YW5jZSBvZiBSZWFjdCByZW5kZXJlZCB0aGUgbm9kZS5cbiAgICAvLyBuYi4gaXNWYWxpZCdzIHN0cmF0ZWd5ICh3aXRoIGNvbnRhaW5zTm9kZSkgZG9lcyBub3Qgd29yayBiZWNhdXNlIHJlbmRlclxuICAgIC8vIHRyZWVzIG1heSBiZSBuZXN0ZWQgYW5kIHdlIGRvbid0IHdhbnQgYSBmYWxzZSBwb3NpdGl2ZSBpbiB0aGF0IGNhc2UuXG4gICAgdmFyIGN1cnJlbnQgPSBub2RlO1xuICAgIHZhciBsYXN0SUQ7XG4gICAgZG8ge1xuICAgICAgbGFzdElEID0gaW50ZXJuYWxHZXRJRChjdXJyZW50KTtcbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudE5vZGU7XG4gICAgICBpZiAoY3VycmVudCA9PSBudWxsKSB7XG4gICAgICAgIC8vIFRoZSBwYXNzZWQtaW4gbm9kZSBoYXMgYmVlbiBkZXRhY2hlZCBmcm9tIHRoZSBjb250YWluZXIgaXQgd2FzXG4gICAgICAgIC8vIG9yaWdpbmFsbHkgcmVuZGVyZWQgaW50by5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSB3aGlsZSAobGFzdElEICE9PSByZWFjdFJvb3RJRCk7XG5cbiAgICBpZiAoY3VycmVudCA9PT0gY29udGFpbmVyc0J5UmVhY3RSb290SURbcmVhY3RSb290SURdKSB7XG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogVGVtcG9yYXJ5ICg/KSBoYWNrIHNvIHRoYXQgd2UgY2FuIHN0b3JlIGFsbCB0b3AtbGV2ZWwgcGVuZGluZyB1cGRhdGVzIG9uXG4gKiBjb21wb3NpdGVzIGluc3RlYWQgb2YgaGF2aW5nIHRvIHdvcnJ5IGFib3V0IGRpZmZlcmVudCB0eXBlcyBvZiBjb21wb25lbnRzXG4gKiBoZXJlLlxuICovXG52YXIgVG9wTGV2ZWxXcmFwcGVyID0gZnVuY3Rpb24gKCkge307XG5Ub3BMZXZlbFdyYXBwZXIucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQgPSB7fTtcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIFRvcExldmVsV3JhcHBlci5kaXNwbGF5TmFtZSA9ICdUb3BMZXZlbFdyYXBwZXInO1xufVxuVG9wTGV2ZWxXcmFwcGVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHRoaXMucHJvcHMgaXMgYWN0dWFsbHkgYSBSZWFjdEVsZW1lbnRcbiAgcmV0dXJuIHRoaXMucHJvcHM7XG59O1xuXG4vKipcbiAqIE1vdW50aW5nIGlzIHRoZSBwcm9jZXNzIG9mIGluaXRpYWxpemluZyBhIFJlYWN0IGNvbXBvbmVudCBieSBjcmVhdGluZyBpdHNcbiAqIHJlcHJlc2VudGF0aXZlIERPTSBlbGVtZW50cyBhbmQgaW5zZXJ0aW5nIHRoZW0gaW50byBhIHN1cHBsaWVkIGBjb250YWluZXJgLlxuICogQW55IHByaW9yIGNvbnRlbnQgaW5zaWRlIGBjb250YWluZXJgIGlzIGRlc3Ryb3llZCBpbiB0aGUgcHJvY2Vzcy5cbiAqXG4gKiAgIFJlYWN0TW91bnQucmVuZGVyKFxuICogICAgIGNvbXBvbmVudCxcbiAqICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udGFpbmVyJylcbiAqICAgKTtcbiAqXG4gKiAgIDxkaXYgaWQ9XCJjb250YWluZXJcIj4gICAgICAgICAgICAgICAgICAgPC0tIFN1cHBsaWVkIGBjb250YWluZXJgLlxuICogICAgIDxkaXYgZGF0YS1yZWFjdGlkPVwiLjNcIj4gICAgICAgICAgICAgIDwtLSBSZW5kZXJlZCByZWFjdFJvb3Qgb2YgUmVhY3RcbiAqICAgICAgIC8vIC4uLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudC5cbiAqICAgICA8L2Rpdj5cbiAqICAgPC9kaXY+XG4gKlxuICogSW5zaWRlIG9mIGBjb250YWluZXJgLCB0aGUgZmlyc3QgZWxlbWVudCByZW5kZXJlZCBpcyB0aGUgXCJyZWFjdFJvb3RcIi5cbiAqL1xudmFyIFJlYWN0TW91bnQgPSB7XG5cbiAgVG9wTGV2ZWxXcmFwcGVyOiBUb3BMZXZlbFdyYXBwZXIsXG5cbiAgLyoqIEV4cG9zZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlcyAqKi9cbiAgX2luc3RhbmNlc0J5UmVhY3RSb290SUQ6IGluc3RhbmNlc0J5UmVhY3RSb290SUQsXG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBob29rIHByb3ZpZGVkIHRvIHN1cHBvcnQgcmVuZGVyaW5nIFJlYWN0IGNvbXBvbmVudHMgd2hpbGVcbiAgICogZW5zdXJpbmcgdGhhdCB0aGUgYXBwYXJlbnQgc2Nyb2xsIHBvc2l0aW9uIG9mIGl0cyBgY29udGFpbmVyYCBkb2VzIG5vdFxuICAgKiBjaGFuZ2UuXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIFRoZSBgY29udGFpbmVyYCBiZWluZyByZW5kZXJlZCBpbnRvLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSByZW5kZXJDYWxsYmFjayBUaGlzIG11c3QgYmUgY2FsbGVkIG9uY2UgdG8gZG8gdGhlIHJlbmRlci5cbiAgICovXG4gIHNjcm9sbE1vbml0b3I6IGZ1bmN0aW9uIChjb250YWluZXIsIHJlbmRlckNhbGxiYWNrKSB7XG4gICAgcmVuZGVyQ2FsbGJhY2soKTtcbiAgfSxcblxuICAvKipcbiAgICogVGFrZSBhIGNvbXBvbmVudCB0aGF0J3MgYWxyZWFkeSBtb3VudGVkIGludG8gdGhlIERPTSBhbmQgcmVwbGFjZSBpdHMgcHJvcHNcbiAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gcHJldkNvbXBvbmVudCBjb21wb25lbnQgaW5zdGFuY2UgYWxyZWFkeSBpbiB0aGUgRE9NXG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0RWxlbWVudCBjb21wb25lbnQgaW5zdGFuY2UgdG8gcmVuZGVyXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIGNvbnRhaW5lciB0byByZW5kZXIgaW50b1xuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24gdHJpZ2dlcmVkIG9uIGNvbXBsZXRpb25cbiAgICovXG4gIF91cGRhdGVSb290Q29tcG9uZW50OiBmdW5jdGlvbiAocHJldkNvbXBvbmVudCwgbmV4dEVsZW1lbnQsIGNvbnRhaW5lciwgY2FsbGJhY2spIHtcbiAgICBSZWFjdE1vdW50LnNjcm9sbE1vbml0b3IoY29udGFpbmVyLCBmdW5jdGlvbiAoKSB7XG4gICAgICBSZWFjdFVwZGF0ZVF1ZXVlLmVucXVldWVFbGVtZW50SW50ZXJuYWwocHJldkNvbXBvbmVudCwgbmV4dEVsZW1lbnQpO1xuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIFJlYWN0VXBkYXRlUXVldWUuZW5xdWV1ZUNhbGxiYWNrSW50ZXJuYWwocHJldkNvbXBvbmVudCwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIC8vIFJlY29yZCB0aGUgcm9vdCBlbGVtZW50IGluIGNhc2UgaXQgbGF0ZXIgZ2V0cyB0cmFuc3BsYW50ZWQuXG4gICAgICByb290RWxlbWVudHNCeVJlYWN0Um9vdElEW2dldFJlYWN0Um9vdElEKGNvbnRhaW5lcildID0gZ2V0UmVhY3RSb290RWxlbWVudEluQ29udGFpbmVyKGNvbnRhaW5lcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByZXZDb21wb25lbnQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY29tcG9uZW50IGludG8gdGhlIGluc3RhbmNlIG1hcCBhbmQgc3RhcnRzIHNjcm9sbCB2YWx1ZVxuICAgKiBtb25pdG9yaW5nXG4gICAqIEBwYXJhbSB7UmVhY3RDb21wb25lbnR9IG5leHRDb21wb25lbnQgY29tcG9uZW50IGluc3RhbmNlIHRvIHJlbmRlclxuICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGNvbnRhaW5lciBjb250YWluZXIgdG8gcmVuZGVyIGludG9cbiAgICogQHJldHVybiB7c3RyaW5nfSByZWFjdFJvb3QgSUQgcHJlZml4XG4gICAqL1xuICBfcmVnaXN0ZXJDb21wb25lbnQ6IGZ1bmN0aW9uIChuZXh0Q29tcG9uZW50LCBjb250YWluZXIpIHtcbiAgICAhKGNvbnRhaW5lciAmJiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREVfVFlQRSB8fCBjb250YWluZXIubm9kZVR5cGUgPT09IERPQ19OT0RFX1RZUEUgfHwgY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFX1RZUEUpKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdfcmVnaXN0ZXJDb21wb25lbnQoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuZW5zdXJlU2Nyb2xsVmFsdWVNb25pdG9yaW5nKCk7XG5cbiAgICB2YXIgcmVhY3RSb290SUQgPSBSZWFjdE1vdW50LnJlZ2lzdGVyQ29udGFpbmVyKGNvbnRhaW5lcik7XG4gICAgaW5zdGFuY2VzQnlSZWFjdFJvb3RJRFtyZWFjdFJvb3RJRF0gPSBuZXh0Q29tcG9uZW50O1xuICAgIHJldHVybiByZWFjdFJvb3RJRDtcbiAgfSxcblxuICAvKipcbiAgICogUmVuZGVyIGEgbmV3IGNvbXBvbmVudCBpbnRvIHRoZSBET00uXG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0RWxlbWVudCBlbGVtZW50IHRvIHJlbmRlclxuICAgKiBAcGFyYW0ge0RPTUVsZW1lbnR9IGNvbnRhaW5lciBjb250YWluZXIgdG8gcmVuZGVyIGludG9cbiAgICogQHBhcmFtIHtib29sZWFufSBzaG91bGRSZXVzZU1hcmt1cCBpZiB3ZSBzaG91bGQgc2tpcCB0aGUgbWFya3VwIGluc2VydGlvblxuICAgKiBAcmV0dXJuIHtSZWFjdENvbXBvbmVudH0gbmV4dENvbXBvbmVudFxuICAgKi9cbiAgX3JlbmRlck5ld1Jvb3RDb21wb25lbnQ6IGZ1bmN0aW9uIChuZXh0RWxlbWVudCwgY29udGFpbmVyLCBzaG91bGRSZXVzZU1hcmt1cCwgY29udGV4dCkge1xuICAgIC8vIFZhcmlvdXMgcGFydHMgb2Ygb3VyIGNvZGUgKHN1Y2ggYXMgUmVhY3RDb21wb3NpdGVDb21wb25lbnQnc1xuICAgIC8vIF9yZW5kZXJWYWxpZGF0ZWRDb21wb25lbnQpIGFzc3VtZSB0aGF0IGNhbGxzIHRvIHJlbmRlciBhcmVuJ3QgbmVzdGVkO1xuICAgIC8vIHZlcmlmeSB0aGF0IHRoYXQncyB0aGUgY2FzZS5cbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50ID09IG51bGwsICdfcmVuZGVyTmV3Um9vdENvbXBvbmVudCgpOiBSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uICcgKyAnb2YgcHJvcHMgYW5kIHN0YXRlOyB0cmlnZ2VyaW5nIG5lc3RlZCBjb21wb25lbnQgdXBkYXRlcyBmcm9tICcgKyAncmVuZGVyIGlzIG5vdCBhbGxvd2VkLiBJZiBuZWNlc3NhcnksIHRyaWdnZXIgbmVzdGVkIHVwZGF0ZXMgaW4gJyArICdjb21wb25lbnREaWRVcGRhdGUuIENoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mICVzLicsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudC5nZXROYW1lKCkgfHwgJ1JlYWN0Q29tcG9zaXRlQ29tcG9uZW50JykgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSBpbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50KG5leHRFbGVtZW50LCBudWxsKTtcbiAgICB2YXIgcmVhY3RSb290SUQgPSBSZWFjdE1vdW50Ll9yZWdpc3RlckNvbXBvbmVudChjb21wb25lbnRJbnN0YW5jZSwgY29udGFpbmVyKTtcblxuICAgIC8vIFRoZSBpbml0aWFsIHJlbmRlciBpcyBzeW5jaHJvbm91cyBidXQgYW55IHVwZGF0ZXMgdGhhdCBoYXBwZW4gZHVyaW5nXG4gICAgLy8gcmVuZGVyaW5nLCBpbiBjb21wb25lbnRXaWxsTW91bnQgb3IgY29tcG9uZW50RGlkTW91bnQsIHdpbGwgYmUgYmF0Y2hlZFxuICAgIC8vIGFjY29yZGluZyB0byB0aGUgY3VycmVudCBiYXRjaGluZyBzdHJhdGVneS5cblxuICAgIFJlYWN0VXBkYXRlcy5iYXRjaGVkVXBkYXRlcyhiYXRjaGVkTW91bnRDb21wb25lbnRJbnRvTm9kZSwgY29tcG9uZW50SW5zdGFuY2UsIHJlYWN0Um9vdElELCBjb250YWluZXIsIHNob3VsZFJldXNlTWFya3VwLCBjb250ZXh0KTtcblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAvLyBSZWNvcmQgdGhlIHJvb3QgZWxlbWVudCBpbiBjYXNlIGl0IGxhdGVyIGdldHMgdHJhbnNwbGFudGVkLlxuICAgICAgcm9vdEVsZW1lbnRzQnlSZWFjdFJvb3RJRFtyZWFjdFJvb3RJRF0gPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcG9uZW50SW5zdGFuY2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgYSBSZWFjdCBjb21wb25lbnQgaW50byB0aGUgRE9NIGluIHRoZSBzdXBwbGllZCBgY29udGFpbmVyYC5cbiAgICpcbiAgICogSWYgdGhlIFJlYWN0IGNvbXBvbmVudCB3YXMgcHJldmlvdXNseSByZW5kZXJlZCBpbnRvIGBjb250YWluZXJgLCB0aGlzIHdpbGxcbiAgICogcGVyZm9ybSBhbiB1cGRhdGUgb24gaXQgYW5kIG9ubHkgbXV0YXRlIHRoZSBET00gYXMgbmVjZXNzYXJ5IHRvIHJlZmxlY3QgdGhlXG4gICAqIGxhdGVzdCBSZWFjdCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDb21wb25lbnR9IHBhcmVudENvbXBvbmVudCBUaGUgY29uY2VwdHVhbCBwYXJlbnQgb2YgdGhpcyByZW5kZXIgdHJlZS5cbiAgICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IG5leHRFbGVtZW50IENvbXBvbmVudCBlbGVtZW50IHRvIHJlbmRlci5cbiAgICogQHBhcmFtIHtET01FbGVtZW50fSBjb250YWluZXIgRE9NIGVsZW1lbnQgdG8gcmVuZGVyIGludG8uXG4gICAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbiB0cmlnZ2VyZWQgb24gY29tcGxldGlvblxuICAgKiBAcmV0dXJuIHtSZWFjdENvbXBvbmVudH0gQ29tcG9uZW50IGluc3RhbmNlIHJlbmRlcmVkIGluIGBjb250YWluZXJgLlxuICAgKi9cbiAgcmVuZGVyU3VidHJlZUludG9Db250YWluZXI6IGZ1bmN0aW9uIChwYXJlbnRDb21wb25lbnQsIG5leHRFbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgIShwYXJlbnRDb21wb25lbnQgIT0gbnVsbCAmJiBwYXJlbnRDb21wb25lbnQuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZSAhPSBudWxsKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdwYXJlbnRDb21wb25lbnQgbXVzdCBiZSBhIHZhbGlkIFJlYWN0IENvbXBvbmVudCcpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gUmVhY3RNb3VudC5fcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBuZXh0RWxlbWVudCwgY29udGFpbmVyLCBjYWxsYmFjayk7XG4gIH0sXG5cbiAgX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyOiBmdW5jdGlvbiAocGFyZW50Q29tcG9uZW50LCBuZXh0RWxlbWVudCwgY29udGFpbmVyLCBjYWxsYmFjaykge1xuICAgICFSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQobmV4dEVsZW1lbnQpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0RE9NLnJlbmRlcigpOiBJbnZhbGlkIGNvbXBvbmVudCBlbGVtZW50LiVzJywgdHlwZW9mIG5leHRFbGVtZW50ID09PSAnc3RyaW5nJyA/ICcgSW5zdGVhZCBvZiBwYXNzaW5nIGFuIGVsZW1lbnQgc3RyaW5nLCBtYWtlIHN1cmUgdG8gaW5zdGFudGlhdGUgJyArICdpdCBieSBwYXNzaW5nIGl0IHRvIFJlYWN0LmNyZWF0ZUVsZW1lbnQuJyA6IHR5cGVvZiBuZXh0RWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyA/ICcgSW5zdGVhZCBvZiBwYXNzaW5nIGEgY29tcG9uZW50IGNsYXNzLCBtYWtlIHN1cmUgdG8gaW5zdGFudGlhdGUgJyArICdpdCBieSBwYXNzaW5nIGl0IHRvIFJlYWN0LmNyZWF0ZUVsZW1lbnQuJyA6XG4gICAgLy8gQ2hlY2sgaWYgaXQgcXVhY2tzIGxpa2UgYW4gZWxlbWVudFxuICAgIG5leHRFbGVtZW50ICE9IG51bGwgJiYgbmV4dEVsZW1lbnQucHJvcHMgIT09IHVuZGVmaW5lZCA/ICcgVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IHVuaW50ZW50aW9uYWxseSBsb2FkaW5nIHR3byBpbmRlcGVuZGVudCAnICsgJ2NvcGllcyBvZiBSZWFjdC4nIDogJycpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFjb250YWluZXIgfHwgIWNvbnRhaW5lci50YWdOYW1lIHx8IGNvbnRhaW5lci50YWdOYW1lLnRvVXBwZXJDYXNlKCkgIT09ICdCT0RZJywgJ3JlbmRlcigpOiBSZW5kZXJpbmcgY29tcG9uZW50cyBkaXJlY3RseSBpbnRvIGRvY3VtZW50LmJvZHkgaXMgJyArICdkaXNjb3VyYWdlZCwgc2luY2UgaXRzIGNoaWxkcmVuIGFyZSBvZnRlbiBtYW5pcHVsYXRlZCBieSB0aGlyZC1wYXJ0eSAnICsgJ3NjcmlwdHMgYW5kIGJyb3dzZXIgZXh0ZW5zaW9ucy4gVGhpcyBtYXkgbGVhZCB0byBzdWJ0bGUgJyArICdyZWNvbmNpbGlhdGlvbiBpc3N1ZXMuIFRyeSByZW5kZXJpbmcgaW50byBhIGNvbnRhaW5lciBlbGVtZW50IGNyZWF0ZWQgJyArICdmb3IgeW91ciBhcHAuJykgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgbmV4dFdyYXBwZWRFbGVtZW50ID0gbmV3IFJlYWN0RWxlbWVudChUb3BMZXZlbFdyYXBwZXIsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG5leHRFbGVtZW50KTtcblxuICAgIHZhciBwcmV2Q29tcG9uZW50ID0gaW5zdGFuY2VzQnlSZWFjdFJvb3RJRFtnZXRSZWFjdFJvb3RJRChjb250YWluZXIpXTtcblxuICAgIGlmIChwcmV2Q29tcG9uZW50KSB7XG4gICAgICB2YXIgcHJldldyYXBwZWRFbGVtZW50ID0gcHJldkNvbXBvbmVudC5fY3VycmVudEVsZW1lbnQ7XG4gICAgICB2YXIgcHJldkVsZW1lbnQgPSBwcmV2V3JhcHBlZEVsZW1lbnQucHJvcHM7XG4gICAgICBpZiAoc2hvdWxkVXBkYXRlUmVhY3RDb21wb25lbnQocHJldkVsZW1lbnQsIG5leHRFbGVtZW50KSkge1xuICAgICAgICB2YXIgcHVibGljSW5zdCA9IHByZXZDb21wb25lbnQuX3JlbmRlcmVkQ29tcG9uZW50LmdldFB1YmxpY0luc3RhbmNlKCk7XG4gICAgICAgIHZhciB1cGRhdGVkQ2FsbGJhY2sgPSBjYWxsYmFjayAmJiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY2FsbGJhY2suY2FsbChwdWJsaWNJbnN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgUmVhY3RNb3VudC5fdXBkYXRlUm9vdENvbXBvbmVudChwcmV2Q29tcG9uZW50LCBuZXh0V3JhcHBlZEVsZW1lbnQsIGNvbnRhaW5lciwgdXBkYXRlZENhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHB1YmxpY0luc3Q7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBSZWFjdE1vdW50LnVubW91bnRDb21wb25lbnRBdE5vZGUoY29udGFpbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVhY3RSb290RWxlbWVudCA9IGdldFJlYWN0Um9vdEVsZW1lbnRJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgIHZhciBjb250YWluZXJIYXNSZWFjdE1hcmt1cCA9IHJlYWN0Um9vdEVsZW1lbnQgJiYgISFpbnRlcm5hbEdldElEKHJlYWN0Um9vdEVsZW1lbnQpO1xuICAgIHZhciBjb250YWluZXJIYXNOb25Sb290UmVhY3RDaGlsZCA9IGhhc05vblJvb3RSZWFjdENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoIWNvbnRhaW5lckhhc05vblJvb3RSZWFjdENoaWxkLCAncmVuZGVyKC4uLik6IFJlcGxhY2luZyBSZWFjdC1yZW5kZXJlZCBjaGlsZHJlbiB3aXRoIGEgbmV3IHJvb3QgJyArICdjb21wb25lbnQuIElmIHlvdSBpbnRlbmRlZCB0byB1cGRhdGUgdGhlIGNoaWxkcmVuIG9mIHRoaXMgbm9kZSwgJyArICd5b3Ugc2hvdWxkIGluc3RlYWQgaGF2ZSB0aGUgZXhpc3RpbmcgY2hpbGRyZW4gdXBkYXRlIHRoZWlyIHN0YXRlICcgKyAnYW5kIHJlbmRlciB0aGUgbmV3IGNvbXBvbmVudHMgaW5zdGVhZCBvZiBjYWxsaW5nIFJlYWN0RE9NLnJlbmRlci4nKSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKCFjb250YWluZXJIYXNSZWFjdE1hcmt1cCB8fCByZWFjdFJvb3RFbGVtZW50Lm5leHRTaWJsaW5nKSB7XG4gICAgICAgIHZhciByb290RWxlbWVudFNpYmxpbmcgPSByZWFjdFJvb3RFbGVtZW50O1xuICAgICAgICB3aGlsZSAocm9vdEVsZW1lbnRTaWJsaW5nKSB7XG4gICAgICAgICAgaWYgKGludGVybmFsR2V0SUQocm9vdEVsZW1lbnRTaWJsaW5nKSkge1xuICAgICAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdyZW5kZXIoKTogVGFyZ2V0IG5vZGUgaGFzIG1hcmt1cCByZW5kZXJlZCBieSBSZWFjdCwgYnV0IHRoZXJlICcgKyAnYXJlIHVucmVsYXRlZCBub2RlcyBhcyB3ZWxsLiBUaGlzIGlzIG1vc3QgY29tbW9ubHkgY2F1c2VkIGJ5ICcgKyAnd2hpdGUtc3BhY2UgaW5zZXJ0ZWQgYXJvdW5kIHNlcnZlci1yZW5kZXJlZCBtYXJrdXAuJykgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgcm9vdEVsZW1lbnRTaWJsaW5nID0gcm9vdEVsZW1lbnRTaWJsaW5nLm5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNob3VsZFJldXNlTWFya3VwID0gY29udGFpbmVySGFzUmVhY3RNYXJrdXAgJiYgIXByZXZDb21wb25lbnQgJiYgIWNvbnRhaW5lckhhc05vblJvb3RSZWFjdENoaWxkO1xuICAgIHZhciBjb21wb25lbnQgPSBSZWFjdE1vdW50Ll9yZW5kZXJOZXdSb290Q29tcG9uZW50KG5leHRXcmFwcGVkRWxlbWVudCwgY29udGFpbmVyLCBzaG91bGRSZXVzZU1hcmt1cCwgcGFyZW50Q29tcG9uZW50ICE9IG51bGwgPyBwYXJlbnRDb21wb25lbnQuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZS5fcHJvY2Vzc0NoaWxkQ29udGV4dChwYXJlbnRDb21wb25lbnQuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZS5fY29udGV4dCkgOiBlbXB0eU9iamVjdCkuX3JlbmRlcmVkQ29tcG9uZW50LmdldFB1YmxpY0luc3RhbmNlKCk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjay5jYWxsKGNvbXBvbmVudCk7XG4gICAgfVxuICAgIHJldHVybiBjb21wb25lbnQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgYSBSZWFjdCBjb21wb25lbnQgaW50byB0aGUgRE9NIGluIHRoZSBzdXBwbGllZCBgY29udGFpbmVyYC5cbiAgICpcbiAgICogSWYgdGhlIFJlYWN0IGNvbXBvbmVudCB3YXMgcHJldmlvdXNseSByZW5kZXJlZCBpbnRvIGBjb250YWluZXJgLCB0aGlzIHdpbGxcbiAgICogcGVyZm9ybSBhbiB1cGRhdGUgb24gaXQgYW5kIG9ubHkgbXV0YXRlIHRoZSBET00gYXMgbmVjZXNzYXJ5IHRvIHJlZmxlY3QgdGhlXG4gICAqIGxhdGVzdCBSZWFjdCBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBuZXh0RWxlbWVudCBDb21wb25lbnQgZWxlbWVudCB0byByZW5kZXIuXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIERPTSBlbGVtZW50IHRvIHJlbmRlciBpbnRvLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24gdHJpZ2dlcmVkIG9uIGNvbXBsZXRpb25cbiAgICogQHJldHVybiB7UmVhY3RDb21wb25lbnR9IENvbXBvbmVudCBpbnN0YW5jZSByZW5kZXJlZCBpbiBgY29udGFpbmVyYC5cbiAgICovXG4gIHJlbmRlcjogZnVuY3Rpb24gKG5leHRFbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFJlYWN0TW91bnQuX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIG5leHRFbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgY29udGFpbmVyIG5vZGUgaW50byB3aGljaCBSZWFjdCBjb21wb25lbnRzIHdpbGwgYmUgcmVuZGVyZWQuXG4gICAqIFRoaXMgYWxzbyBjcmVhdGVzIHRoZSBcInJlYWN0Um9vdFwiIElEIHRoYXQgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGUgZWxlbWVudFxuICAgKiByZW5kZXJlZCB3aXRoaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7RE9NRWxlbWVudH0gY29udGFpbmVyIERPTSBlbGVtZW50IHRvIHJlZ2lzdGVyIGFzIGEgY29udGFpbmVyLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBcInJlYWN0Um9vdFwiIElEIG9mIGVsZW1lbnRzIHJlbmRlcmVkIHdpdGhpbi5cbiAgICovXG4gIHJlZ2lzdGVyQ29udGFpbmVyOiBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgdmFyIHJlYWN0Um9vdElEID0gZ2V0UmVhY3RSb290SUQoY29udGFpbmVyKTtcbiAgICBpZiAocmVhY3RSb290SUQpIHtcbiAgICAgIC8vIElmIG9uZSBleGlzdHMsIG1ha2Ugc3VyZSBpdCBpcyBhIHZhbGlkIFwicmVhY3RSb290XCIgSUQuXG4gICAgICByZWFjdFJvb3RJRCA9IFJlYWN0SW5zdGFuY2VIYW5kbGVzLmdldFJlYWN0Um9vdElERnJvbU5vZGVJRChyZWFjdFJvb3RJRCk7XG4gICAgfVxuICAgIGlmICghcmVhY3RSb290SUQpIHtcbiAgICAgIC8vIE5vIHZhbGlkIFwicmVhY3RSb290XCIgSUQgZm91bmQsIGNyZWF0ZSBvbmUuXG4gICAgICByZWFjdFJvb3RJRCA9IFJlYWN0SW5zdGFuY2VIYW5kbGVzLmNyZWF0ZVJlYWN0Um9vdElEKCk7XG4gICAgfVxuICAgIGNvbnRhaW5lcnNCeVJlYWN0Um9vdElEW3JlYWN0Um9vdElEXSA9IGNvbnRhaW5lcjtcbiAgICByZXR1cm4gcmVhY3RSb290SUQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVubW91bnRzIGFuZCBkZXN0cm95cyB0aGUgUmVhY3QgY29tcG9uZW50IHJlbmRlcmVkIGluIHRoZSBgY29udGFpbmVyYC5cbiAgICpcbiAgICogQHBhcmFtIHtET01FbGVtZW50fSBjb250YWluZXIgRE9NIGVsZW1lbnQgY29udGFpbmluZyBhIFJlYWN0IGNvbXBvbmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhIGNvbXBvbmVudCB3YXMgZm91bmQgaW4gYW5kIHVubW91bnRlZCBmcm9tXG4gICAqICAgICAgICAgICAgICAgICAgIGBjb250YWluZXJgXG4gICAqL1xuICB1bm1vdW50Q29tcG9uZW50QXROb2RlOiBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgLy8gVmFyaW91cyBwYXJ0cyBvZiBvdXIgY29kZSAoc3VjaCBhcyBSZWFjdENvbXBvc2l0ZUNvbXBvbmVudCdzXG4gICAgLy8gX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudCkgYXNzdW1lIHRoYXQgY2FsbHMgdG8gcmVuZGVyIGFyZW4ndCBuZXN0ZWQ7XG4gICAgLy8gdmVyaWZ5IHRoYXQgdGhhdCdzIHRoZSBjYXNlLiAoU3RyaWN0bHkgc3BlYWtpbmcsIHVubW91bnRpbmcgd29uJ3QgY2F1c2UgYVxuICAgIC8vIHJlbmRlciBidXQgd2Ugc3RpbGwgZG9uJ3QgZXhwZWN0IHRvIGJlIGluIGEgcmVuZGVyIGNhbGwgaGVyZS4pXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCA9PSBudWxsLCAndW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uICcgKyAnb2YgcHJvcHMgYW5kIHN0YXRlOyB0cmlnZ2VyaW5nIG5lc3RlZCBjb21wb25lbnQgdXBkYXRlcyBmcm9tIHJlbmRlciAnICsgJ2lzIG5vdCBhbGxvd2VkLiBJZiBuZWNlc3NhcnksIHRyaWdnZXIgbmVzdGVkIHVwZGF0ZXMgaW4gJyArICdjb21wb25lbnREaWRVcGRhdGUuIENoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mICVzLicsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudC5nZXROYW1lKCkgfHwgJ1JlYWN0Q29tcG9zaXRlQ29tcG9uZW50JykgOiB1bmRlZmluZWQ7XG5cbiAgICAhKGNvbnRhaW5lciAmJiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREVfVFlQRSB8fCBjb250YWluZXIubm9kZVR5cGUgPT09IERPQ19OT0RFX1RZUEUgfHwgY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFX1RZUEUpKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICd1bm1vdW50Q29tcG9uZW50QXROb2RlKC4uLik6IFRhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgdmFyIHJlYWN0Um9vdElEID0gZ2V0UmVhY3RSb290SUQoY29udGFpbmVyKTtcbiAgICB2YXIgY29tcG9uZW50ID0gaW5zdGFuY2VzQnlSZWFjdFJvb3RJRFtyZWFjdFJvb3RJRF07XG4gICAgaWYgKCFjb21wb25lbnQpIHtcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBub2RlIGJlaW5nIHVubW91bnRlZCB3YXMgcmVuZGVyZWQgYnkgUmVhY3QsIGJ1dCBpc24ndCBhXG4gICAgICAvLyByb290IG5vZGUuXG4gICAgICB2YXIgY29udGFpbmVySGFzTm9uUm9vdFJlYWN0Q2hpbGQgPSBoYXNOb25Sb290UmVhY3RDaGlsZChjb250YWluZXIpO1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgY29udGFpbmVyIGl0c2VsZiBpcyBhIFJlYWN0IHJvb3Qgbm9kZS5cbiAgICAgIHZhciBjb250YWluZXJJRCA9IGludGVybmFsR2V0SUQoY29udGFpbmVyKTtcbiAgICAgIHZhciBpc0NvbnRhaW5lclJlYWN0Um9vdCA9IGNvbnRhaW5lcklEICYmIGNvbnRhaW5lcklEID09PSBSZWFjdEluc3RhbmNlSGFuZGxlcy5nZXRSZWFjdFJvb3RJREZyb21Ob2RlSUQoY29udGFpbmVySUQpO1xuXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyghY29udGFpbmVySGFzTm9uUm9vdFJlYWN0Q2hpbGQsICd1bm1vdW50Q29tcG9uZW50QXROb2RlKCk6IFRoZSBub2RlIHlvdVxcJ3JlIGF0dGVtcHRpbmcgdG8gdW5tb3VudCAnICsgJ3dhcyByZW5kZXJlZCBieSBSZWFjdCBhbmQgaXMgbm90IGEgdG9wLWxldmVsIGNvbnRhaW5lci4gJXMnLCBpc0NvbnRhaW5lclJlYWN0Um9vdCA/ICdZb3UgbWF5IGhhdmUgYWNjaWRlbnRhbGx5IHBhc3NlZCBpbiBhIFJlYWN0IHJvb3Qgbm9kZSBpbnN0ZWFkICcgKyAnb2YgaXRzIGNvbnRhaW5lci4nIDogJ0luc3RlYWQsIGhhdmUgdGhlIHBhcmVudCBjb21wb25lbnQgdXBkYXRlIGl0cyBzdGF0ZSBhbmQgJyArICdyZXJlbmRlciBpbiBvcmRlciB0byByZW1vdmUgdGhpcyBjb21wb25lbnQuJykgOiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgUmVhY3RVcGRhdGVzLmJhdGNoZWRVcGRhdGVzKHVubW91bnRDb21wb25lbnRGcm9tTm9kZSwgY29tcG9uZW50LCBjb250YWluZXIpO1xuICAgIGRlbGV0ZSBpbnN0YW5jZXNCeVJlYWN0Um9vdElEW3JlYWN0Um9vdElEXTtcbiAgICBkZWxldGUgY29udGFpbmVyc0J5UmVhY3RSb290SURbcmVhY3RSb290SURdO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBkZWxldGUgcm9vdEVsZW1lbnRzQnlSZWFjdFJvb3RJRFtyZWFjdFJvb3RJRF07XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgY29udGFpbmVyIERPTSBlbGVtZW50IHRoYXQgY29udGFpbnMgUmVhY3QgY29tcG9uZW50IHRvIHdoaWNoIHRoZVxuICAgKiBzdXBwbGllZCBET00gYGlkYCBiZWxvbmdzLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgVGhlIElEIG9mIGFuIGVsZW1lbnQgcmVuZGVyZWQgYnkgYSBSZWFjdCBjb21wb25lbnQuXG4gICAqIEByZXR1cm4gez9ET01FbGVtZW50fSBET00gZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBgaWRgLlxuICAgKi9cbiAgZmluZFJlYWN0Q29udGFpbmVyRm9ySUQ6IGZ1bmN0aW9uIChpZCkge1xuICAgIHZhciByZWFjdFJvb3RJRCA9IFJlYWN0SW5zdGFuY2VIYW5kbGVzLmdldFJlYWN0Um9vdElERnJvbU5vZGVJRChpZCk7XG4gICAgdmFyIGNvbnRhaW5lciA9IGNvbnRhaW5lcnNCeVJlYWN0Um9vdElEW3JlYWN0Um9vdElEXTtcblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB2YXIgcm9vdEVsZW1lbnQgPSByb290RWxlbWVudHNCeVJlYWN0Um9vdElEW3JlYWN0Um9vdElEXTtcbiAgICAgIGlmIChyb290RWxlbWVudCAmJiByb290RWxlbWVudC5wYXJlbnROb2RlICE9PSBjb250YWluZXIpIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoXG4gICAgICAgIC8vIENhbGwgaW50ZXJuYWxHZXRJRCBoZXJlIGJlY2F1c2UgZ2V0SUQgY2FsbHMgaXNWYWxpZCB3aGljaCBjYWxsc1xuICAgICAgICAvLyBmaW5kUmVhY3RDb250YWluZXJGb3JJRCAodGhpcyBmdW5jdGlvbikuXG4gICAgICAgIGludGVybmFsR2V0SUQocm9vdEVsZW1lbnQpID09PSByZWFjdFJvb3RJRCwgJ1JlYWN0TW91bnQ6IFJvb3QgZWxlbWVudCBJRCBkaWZmZXJlZCBmcm9tIHJlYWN0Um9vdElELicpIDogdW5kZWZpbmVkO1xuICAgICAgICB2YXIgY29udGFpbmVyQ2hpbGQgPSBjb250YWluZXIuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKGNvbnRhaW5lckNoaWxkICYmIHJlYWN0Um9vdElEID09PSBpbnRlcm5hbEdldElEKGNvbnRhaW5lckNoaWxkKSkge1xuICAgICAgICAgIC8vIElmIHRoZSBjb250YWluZXIgaGFzIGEgbmV3IGNoaWxkIHdpdGggdGhlIHNhbWUgSUQgYXMgdGhlIG9sZFxuICAgICAgICAgIC8vIHJvb3QgZWxlbWVudCwgdGhlbiByb290RWxlbWVudHNCeVJlYWN0Um9vdElEW3JlYWN0Um9vdElEXSBpc1xuICAgICAgICAgIC8vIGp1c3Qgc3RhbGUgYW5kIG5lZWRzIHRvIGJlIHVwZGF0ZWQuIFRoZSBjYXNlIHRoYXQgZGVzZXJ2ZXMgYVxuICAgICAgICAgIC8vIHdhcm5pbmcgaXMgd2hlbiB0aGUgY29udGFpbmVyIGlzIGVtcHR5LlxuICAgICAgICAgIHJvb3RFbGVtZW50c0J5UmVhY3RSb290SURbcmVhY3RSb290SURdID0gY29udGFpbmVyQ2hpbGQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICdSZWFjdE1vdW50OiBSb290IGVsZW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIGl0cyBvcmlnaW5hbCAnICsgJ2NvbnRhaW5lci4gTmV3IGNvbnRhaW5lcjogJXMnLCByb290RWxlbWVudC5wYXJlbnROb2RlKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb250YWluZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEZpbmRzIGFuIGVsZW1lbnQgcmVuZGVyZWQgYnkgUmVhY3Qgd2l0aCB0aGUgc3VwcGxpZWQgSUQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBvZiBhIERPTSBub2RlIGluIHRoZSBSZWFjdCBjb21wb25lbnQuXG4gICAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IFJvb3QgRE9NIG5vZGUgb2YgdGhlIFJlYWN0IGNvbXBvbmVudC5cbiAgICovXG4gIGZpbmRSZWFjdE5vZGVCeUlEOiBmdW5jdGlvbiAoaWQpIHtcbiAgICB2YXIgcmVhY3RSb290ID0gUmVhY3RNb3VudC5maW5kUmVhY3RDb250YWluZXJGb3JJRChpZCk7XG4gICAgcmV0dXJuIFJlYWN0TW91bnQuZmluZENvbXBvbmVudFJvb3QocmVhY3RSb290LCBpZCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyB1cCB0aGUgYW5jZXN0b3JzIG9mIHRoZSBzdXBwbGllZCBub2RlIHRvIGZpbmQgYSBub2RlIHRoYXQgaXMgYVxuICAgKiBET00gcmVwcmVzZW50YXRpb24gb2YgYSBSZWFjdCBjb21wb25lbnQgcmVuZGVyZWQgYnkgdGhpcyBjb3B5IG9mIFJlYWN0LlxuICAgKlxuICAgKiBAcGFyYW0geyp9IG5vZGVcbiAgICogQHJldHVybiB7P0RPTUV2ZW50VGFyZ2V0fVxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldEZpcnN0UmVhY3RET006IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIGZpbmRGaXJzdFJlYWN0RE9NSW1wbChub2RlKTtcbiAgfSxcblxuICAvKipcbiAgICogRmluZHMgYSBub2RlIHdpdGggdGhlIHN1cHBsaWVkIGB0YXJnZXRJRGAgaW5zaWRlIG9mIHRoZSBzdXBwbGllZFxuICAgKiBgYW5jZXN0b3JOb2RlYC4gIEV4cGxvaXRzIHRoZSBJRCBuYW1pbmcgc2NoZW1lIHRvIHBlcmZvcm0gdGhlIHNlYXJjaFxuICAgKiBxdWlja2x5LlxuICAgKlxuICAgKiBAcGFyYW0ge0RPTUV2ZW50VGFyZ2V0fSBhbmNlc3Rvck5vZGUgU2VhcmNoIGZyb20gdGhpcyByb290LlxuICAgKiBAcGFyYXJtIHtzdHJpbmd9IHRhcmdldElEIElEIG9mIHRoZSBET00gcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbXBvbmVudC5cbiAgICogQHJldHVybiB7RE9NRXZlbnRUYXJnZXR9IERPTSBub2RlIHdpdGggdGhlIHN1cHBsaWVkIGB0YXJnZXRJRGAuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZmluZENvbXBvbmVudFJvb3Q6IGZ1bmN0aW9uIChhbmNlc3Rvck5vZGUsIHRhcmdldElEKSB7XG4gICAgdmFyIGZpcnN0Q2hpbGRyZW4gPSBmaW5kQ29tcG9uZW50Um9vdFJldXNhYmxlQXJyYXk7XG4gICAgdmFyIGNoaWxkSW5kZXggPSAwO1xuXG4gICAgdmFyIGRlZXBlc3RBbmNlc3RvciA9IGZpbmREZWVwZXN0Q2FjaGVkQW5jZXN0b3IodGFyZ2V0SUQpIHx8IGFuY2VzdG9yTm9kZTtcblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgb24gdGhlIG5leHQgbGluZTsgZ2l2ZSBhbiBlYXJseSB3YXJuaW5nXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhkZWVwZXN0QW5jZXN0b3IgIT0gbnVsbCwgJ1JlYWN0IGNhblxcJ3QgZmluZCB0aGUgcm9vdCBjb21wb25lbnQgbm9kZSBmb3IgZGF0YS1yZWFjdGlkIHZhbHVlICcgKyAnYCVzYC4gSWYgeW91XFwncmUgc2VlaW5nIHRoaXMgbWVzc2FnZSwgaXQgcHJvYmFibHkgbWVhbnMgdGhhdCAnICsgJ3lvdVxcJ3ZlIGxvYWRlZCB0d28gY29waWVzIG9mIFJlYWN0IG9uIHRoZSBwYWdlLiBBdCB0aGlzIHRpbWUsIG9ubHkgJyArICdhIHNpbmdsZSBjb3B5IG9mIFJlYWN0IGNhbiBiZSBsb2FkZWQgYXQgYSB0aW1lLicsIHRhcmdldElEKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmaXJzdENoaWxkcmVuWzBdID0gZGVlcGVzdEFuY2VzdG9yLmZpcnN0Q2hpbGQ7XG4gICAgZmlyc3RDaGlsZHJlbi5sZW5ndGggPSAxO1xuXG4gICAgd2hpbGUgKGNoaWxkSW5kZXggPCBmaXJzdENoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgdmFyIGNoaWxkID0gZmlyc3RDaGlsZHJlbltjaGlsZEluZGV4KytdO1xuICAgICAgdmFyIHRhcmdldENoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgdmFyIGNoaWxkSUQgPSBSZWFjdE1vdW50LmdldElEKGNoaWxkKTtcbiAgICAgICAgaWYgKGNoaWxkSUQpIHtcbiAgICAgICAgICAvLyBFdmVuIGlmIHdlIGZpbmQgdGhlIG5vZGUgd2UncmUgbG9va2luZyBmb3IsIHdlIGZpbmlzaCBsb29waW5nXG4gICAgICAgICAgLy8gdGhyb3VnaCBpdHMgc2libGluZ3MgdG8gZW5zdXJlIHRoZXkncmUgY2FjaGVkIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZVxuICAgICAgICAgIC8vIHRvIHJldmlzaXQgdGhpcyBub2RlIGFnYWluLiBPdGhlcndpc2UsIHdlIG1ha2Ugbl4yIGNhbGxzIHRvIGdldElEXG4gICAgICAgICAgLy8gd2hlbiB2aXNpdGluZyB0aGUgbWFueSBjaGlsZHJlbiBvZiBhIHNpbmdsZSBub2RlIGluIG9yZGVyLlxuXG4gICAgICAgICAgaWYgKHRhcmdldElEID09PSBjaGlsZElEKSB7XG4gICAgICAgICAgICB0YXJnZXRDaGlsZCA9IGNoaWxkO1xuICAgICAgICAgIH0gZWxzZSBpZiAoUmVhY3RJbnN0YW5jZUhhbmRsZXMuaXNBbmNlc3RvcklET2YoY2hpbGRJRCwgdGFyZ2V0SUQpKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBmaW5kIGEgY2hpbGQgd2hvc2UgSUQgaXMgYW4gYW5jZXN0b3Igb2YgdGhlIGdpdmVuIElELFxuICAgICAgICAgICAgLy8gdGhlbiB3ZSBjYW4gYmUgc3VyZSB0aGF0IHdlIG9ubHkgd2FudCB0byBzZWFyY2ggdGhlIHN1YnRyZWVcbiAgICAgICAgICAgIC8vIHJvb3RlZCBhdCB0aGlzIGNoaWxkLCBzbyB3ZSBjYW4gdGhyb3cgb3V0IHRoZSByZXN0IG9mIHRoZVxuICAgICAgICAgICAgLy8gc2VhcmNoIHN0YXRlLlxuICAgICAgICAgICAgZmlyc3RDaGlsZHJlbi5sZW5ndGggPSBjaGlsZEluZGV4ID0gMDtcbiAgICAgICAgICAgIGZpcnN0Q2hpbGRyZW4ucHVzaChjaGlsZC5maXJzdENoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyBjaGlsZCBoYWQgbm8gSUQsIHRoZW4gdGhlcmUncyBhIGNoYW5jZSB0aGF0IGl0IHdhc1xuICAgICAgICAgIC8vIGluamVjdGVkIGF1dG9tYXRpY2FsbHkgYnkgdGhlIGJyb3dzZXIsIGFzIHdoZW4gYSBgPHRhYmxlPmBcbiAgICAgICAgICAvLyBlbGVtZW50IHNwcm91dHMgYW4gZXh0cmEgYDx0Ym9keT5gIGNoaWxkIGFzIGEgc2lkZSBlZmZlY3Qgb2ZcbiAgICAgICAgICAvLyBgLmlubmVySFRNTGAgcGFyc2luZy4gT3B0aW1pc3RpY2FsbHkgY29udGludWUgZG93biB0aGlzXG4gICAgICAgICAgLy8gYnJhbmNoLCBidXQgbm90IGJlZm9yZSBleGFtaW5pbmcgdGhlIG90aGVyIHNpYmxpbmdzLlxuICAgICAgICAgIGZpcnN0Q2hpbGRyZW4ucHVzaChjaGlsZC5maXJzdENoaWxkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXRDaGlsZCkge1xuICAgICAgICAvLyBFbXB0eWluZyBmaXJzdENoaWxkcmVuL2ZpbmRDb21wb25lbnRSb290UmV1c2FibGVBcnJheSBpc1xuICAgICAgICAvLyBub3QgbmVjZXNzYXJ5IGZvciBjb3JyZWN0bmVzcywgYnV0IGl0IGhlbHBzIHRoZSBHQyByZWNsYWltXG4gICAgICAgIC8vIGFueSBub2RlcyB0aGF0IHdlcmUgbGVmdCBhdCB0aGUgZW5kIG9mIHRoZSBzZWFyY2guXG4gICAgICAgIGZpcnN0Q2hpbGRyZW4ubGVuZ3RoID0gMDtcblxuICAgICAgICByZXR1cm4gdGFyZ2V0Q2hpbGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmlyc3RDaGlsZHJlbi5sZW5ndGggPSAwO1xuXG4gICAgIWZhbHNlID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2ZpbmRDb21wb25lbnRSb290KC4uLiwgJXMpOiBVbmFibGUgdG8gZmluZCBlbGVtZW50LiBUaGlzIHByb2JhYmx5ICcgKyAnbWVhbnMgdGhlIERPTSB3YXMgdW5leHBlY3RlZGx5IG11dGF0ZWQgKGUuZy4sIGJ5IHRoZSBicm93c2VyKSwgJyArICd1c3VhbGx5IGR1ZSB0byBmb3JnZXR0aW5nIGEgPHRib2R5PiB3aGVuIHVzaW5nIHRhYmxlcywgbmVzdGluZyB0YWdzICcgKyAnbGlrZSA8Zm9ybT4sIDxwPiwgb3IgPGE+LCBvciB1c2luZyBub24tU1ZHIGVsZW1lbnRzIGluIGFuIDxzdmc+ICcgKyAncGFyZW50LiAnICsgJ1RyeSBpbnNwZWN0aW5nIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUgZWxlbWVudCB3aXRoIFJlYWN0IElEIGAlc2AuJywgdGFyZ2V0SUQsIFJlYWN0TW91bnQuZ2V0SUQoYW5jZXN0b3JOb2RlKSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICB9LFxuXG4gIF9tb3VudEltYWdlSW50b05vZGU6IGZ1bmN0aW9uIChtYXJrdXAsIGNvbnRhaW5lciwgc2hvdWxkUmV1c2VNYXJrdXAsIHRyYW5zYWN0aW9uKSB7XG4gICAgIShjb250YWluZXIgJiYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFX1RZUEUgfHwgY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NfTk9ERV9UWVBFIHx8IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfRlJBR01FTlRfTk9ERV9UWVBFKSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnbW91bnRDb21wb25lbnRJbnRvTm9kZSguLi4pOiBUYXJnZXQgY29udGFpbmVyIGlzIG5vdCB2YWxpZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoc2hvdWxkUmV1c2VNYXJrdXApIHtcbiAgICAgIHZhciByb290RWxlbWVudCA9IGdldFJlYWN0Um9vdEVsZW1lbnRJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgICAgaWYgKFJlYWN0TWFya3VwQ2hlY2tzdW0uY2FuUmV1c2VNYXJrdXAobWFya3VwLCByb290RWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGNoZWNrc3VtID0gcm9vdEVsZW1lbnQuZ2V0QXR0cmlidXRlKFJlYWN0TWFya3VwQ2hlY2tzdW0uQ0hFQ0tTVU1fQVRUUl9OQU1FKTtcbiAgICAgICAgcm9vdEVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFJlYWN0TWFya3VwQ2hlY2tzdW0uQ0hFQ0tTVU1fQVRUUl9OQU1FKTtcblxuICAgICAgICB2YXIgcm9vdE1hcmt1cCA9IHJvb3RFbGVtZW50Lm91dGVySFRNTDtcbiAgICAgICAgcm9vdEVsZW1lbnQuc2V0QXR0cmlidXRlKFJlYWN0TWFya3VwQ2hlY2tzdW0uQ0hFQ0tTVU1fQVRUUl9OQU1FLCBjaGVja3N1bSk7XG5cbiAgICAgICAgdmFyIG5vcm1hbGl6ZWRNYXJrdXAgPSBtYXJrdXA7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgLy8gYmVjYXVzZSByb290TWFya3VwIGlzIHJldHJpZXZlZCBmcm9tIHRoZSBET00sIHZhcmlvdXMgbm9ybWFsaXphdGlvbnNcbiAgICAgICAgICAvLyB3aWxsIGhhdmUgb2NjdXJyZWQgd2hpY2ggd2lsbCBub3QgYmUgcHJlc2VudCBpbiBgbWFya3VwYC4gSGVyZSxcbiAgICAgICAgICAvLyBpbnNlcnQgbWFya3VwIGludG8gYSA8ZGl2PiBvciA8aWZyYW1lPiBkZXBlbmRpbmcgb24gdGhlIGNvbnRhaW5lclxuICAgICAgICAgIC8vIHR5cGUgdG8gcGVyZm9ybSB0aGUgc2FtZSBub3JtYWxpemF0aW9ucyBiZWZvcmUgY29tcGFyaW5nLlxuICAgICAgICAgIHZhciBub3JtYWxpemVyO1xuICAgICAgICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERV9UWVBFKSB7XG4gICAgICAgICAgICBub3JtYWxpemVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBub3JtYWxpemVyLmlubmVySFRNTCA9IG1hcmt1cDtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRNYXJrdXAgPSBub3JtYWxpemVyLmlubmVySFRNTDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9ybWFsaXplciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChub3JtYWxpemVyKTtcbiAgICAgICAgICAgIG5vcm1hbGl6ZXIuY29udGVudERvY3VtZW50LndyaXRlKG1hcmt1cCk7XG4gICAgICAgICAgICBub3JtYWxpemVkTWFya3VwID0gbm9ybWFsaXplci5jb250ZW50RG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm91dGVySFRNTDtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobm9ybWFsaXplcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRpZmZJbmRleCA9IGZpcnN0RGlmZmVyZW5jZUluZGV4KG5vcm1hbGl6ZWRNYXJrdXAsIHJvb3RNYXJrdXApO1xuICAgICAgICB2YXIgZGlmZmVyZW5jZSA9ICcgKGNsaWVudCkgJyArIG5vcm1hbGl6ZWRNYXJrdXAuc3Vic3RyaW5nKGRpZmZJbmRleCAtIDIwLCBkaWZmSW5kZXggKyAyMCkgKyAnXFxuIChzZXJ2ZXIpICcgKyByb290TWFya3VwLnN1YnN0cmluZyhkaWZmSW5kZXggLSAyMCwgZGlmZkluZGV4ICsgMjApO1xuXG4gICAgICAgICEoY29udGFpbmVyLm5vZGVUeXBlICE9PSBET0NfTk9ERV9UWVBFKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdZb3VcXCdyZSB0cnlpbmcgdG8gcmVuZGVyIGEgY29tcG9uZW50IHRvIHRoZSBkb2N1bWVudCB1c2luZyAnICsgJ3NlcnZlciByZW5kZXJpbmcgYnV0IHRoZSBjaGVja3N1bSB3YXMgaW52YWxpZC4gVGhpcyB1c3VhbGx5ICcgKyAnbWVhbnMgeW91IHJlbmRlcmVkIGEgZGlmZmVyZW50IGNvbXBvbmVudCB0eXBlIG9yIHByb3BzIG9uICcgKyAndGhlIGNsaWVudCBmcm9tIHRoZSBvbmUgb24gdGhlIHNlcnZlciwgb3IgeW91ciByZW5kZXIoKSAnICsgJ21ldGhvZHMgYXJlIGltcHVyZS4gUmVhY3QgY2Fubm90IGhhbmRsZSB0aGlzIGNhc2UgZHVlIHRvICcgKyAnY3Jvc3MtYnJvd3NlciBxdWlya3MgYnkgcmVuZGVyaW5nIGF0IHRoZSBkb2N1bWVudCByb290LiBZb3UgJyArICdzaG91bGQgbG9vayBmb3IgZW52aXJvbm1lbnQgZGVwZW5kZW50IGNvZGUgaW4geW91ciBjb21wb25lbnRzICcgKyAnYW5kIGVuc3VyZSB0aGUgcHJvcHMgYXJlIHRoZSBzYW1lIGNsaWVudCBhbmQgc2VydmVyIHNpZGU6XFxuJXMnLCBkaWZmZXJlbmNlKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ1JlYWN0IGF0dGVtcHRlZCB0byByZXVzZSBtYXJrdXAgaW4gYSBjb250YWluZXIgYnV0IHRoZSAnICsgJ2NoZWNrc3VtIHdhcyBpbnZhbGlkLiBUaGlzIGdlbmVyYWxseSBtZWFucyB0aGF0IHlvdSBhcmUgJyArICd1c2luZyBzZXJ2ZXIgcmVuZGVyaW5nIGFuZCB0aGUgbWFya3VwIGdlbmVyYXRlZCBvbiB0aGUgJyArICdzZXJ2ZXIgd2FzIG5vdCB3aGF0IHRoZSBjbGllbnQgd2FzIGV4cGVjdGluZy4gUmVhY3QgaW5qZWN0ZWQgJyArICduZXcgbWFya3VwIHRvIGNvbXBlbnNhdGUgd2hpY2ggd29ya3MgYnV0IHlvdSBoYXZlIGxvc3QgbWFueSAnICsgJ29mIHRoZSBiZW5lZml0cyBvZiBzZXJ2ZXIgcmVuZGVyaW5nLiBJbnN0ZWFkLCBmaWd1cmUgb3V0ICcgKyAnd2h5IHRoZSBtYXJrdXAgYmVpbmcgZ2VuZXJhdGVkIGlzIGRpZmZlcmVudCBvbiB0aGUgY2xpZW50ICcgKyAnb3Igc2VydmVyOlxcbiVzJywgZGlmZmVyZW5jZSkgOiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAhKGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gRE9DX05PREVfVFlQRSkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnWW91XFwncmUgdHJ5aW5nIHRvIHJlbmRlciBhIGNvbXBvbmVudCB0byB0aGUgZG9jdW1lbnQgYnV0ICcgKyAneW91IGRpZG5cXCd0IHVzZSBzZXJ2ZXIgcmVuZGVyaW5nLiBXZSBjYW5cXCd0IGRvIHRoaXMgJyArICd3aXRob3V0IHVzaW5nIHNlcnZlciByZW5kZXJpbmcgZHVlIHRvIGNyb3NzLWJyb3dzZXIgcXVpcmtzLiAnICsgJ1NlZSBSZWFjdERPTVNlcnZlci5yZW5kZXJUb1N0cmluZygpIGZvciBzZXJ2ZXIgcmVuZGVyaW5nLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIGlmICh0cmFuc2FjdGlvbi51c2VDcmVhdGVFbGVtZW50KSB7XG4gICAgICB3aGlsZSAoY29udGFpbmVyLmxhc3RDaGlsZCkge1xuICAgICAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY29udGFpbmVyLmxhc3RDaGlsZCk7XG4gICAgICB9XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobWFya3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2V0SW5uZXJIVE1MKGNvbnRhaW5lciwgbWFya3VwKTtcbiAgICB9XG4gIH0sXG5cbiAgb3duZXJEb2N1bWVudENvbnRleHRLZXk6IG93bmVyRG9jdW1lbnRDb250ZXh0S2V5LFxuXG4gIC8qKlxuICAgKiBSZWFjdCBJRCB1dGlsaXRpZXMuXG4gICAqL1xuXG4gIGdldFJlYWN0Um9vdElEOiBnZXRSZWFjdFJvb3RJRCxcblxuICBnZXRJRDogZ2V0SUQsXG5cbiAgc2V0SUQ6IHNldElELFxuXG4gIGdldE5vZGU6IGdldE5vZGUsXG5cbiAgZ2V0Tm9kZUZyb21JbnN0YW5jZTogZ2V0Tm9kZUZyb21JbnN0YW5jZSxcblxuICBpc1ZhbGlkOiBpc1ZhbGlkLFxuXG4gIHB1cmdlSUQ6IHB1cmdlSURcbn07XG5cblJlYWN0UGVyZi5tZWFzdXJlTWV0aG9kcyhSZWFjdE1vdW50LCAnUmVhY3RNb3VudCcsIHtcbiAgX3JlbmRlck5ld1Jvb3RDb21wb25lbnQ6ICdfcmVuZGVyTmV3Um9vdENvbXBvbmVudCcsXG4gIF9tb3VudEltYWdlSW50b05vZGU6ICdfbW91bnRJbWFnZUludG9Ob2RlJ1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RNb3VudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RNdWx0aUNoaWxkXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQgPSByZXF1aXJlKCcuL1JlYWN0Q29tcG9uZW50RW52aXJvbm1lbnQnKTtcbnZhciBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcyA9IHJlcXVpcmUoJy4vUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMnKTtcblxudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0UmVjb25jaWxlciA9IHJlcXVpcmUoJy4vUmVhY3RSZWNvbmNpbGVyJyk7XG52YXIgUmVhY3RDaGlsZFJlY29uY2lsZXIgPSByZXF1aXJlKCcuL1JlYWN0Q2hpbGRSZWNvbmNpbGVyJyk7XG5cbnZhciBmbGF0dGVuQ2hpbGRyZW4gPSByZXF1aXJlKCcuL2ZsYXR0ZW5DaGlsZHJlbicpO1xuXG4vKipcbiAqIFVwZGF0aW5nIGNoaWxkcmVuIG9mIGEgY29tcG9uZW50IG1heSB0cmlnZ2VyIHJlY3Vyc2l2ZSB1cGRhdGVzLiBUaGUgZGVwdGggaXNcbiAqIHVzZWQgdG8gYmF0Y2ggcmVjdXJzaXZlIHVwZGF0ZXMgdG8gcmVuZGVyIG1hcmt1cCBtb3JlIGVmZmljaWVudGx5LlxuICpcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG52YXIgdXBkYXRlRGVwdGggPSAwO1xuXG4vKipcbiAqIFF1ZXVlIG9mIHVwZGF0ZSBjb25maWd1cmF0aW9uIG9iamVjdHMuXG4gKlxuICogRWFjaCBvYmplY3QgaGFzIGEgYHR5cGVgIHByb3BlcnR5IHRoYXQgaXMgaW4gYFJlYWN0TXVsdGlDaGlsZFVwZGF0ZVR5cGVzYC5cbiAqXG4gKiBAdHlwZSB7YXJyYXk8b2JqZWN0Pn1cbiAqIEBwcml2YXRlXG4gKi9cbnZhciB1cGRhdGVRdWV1ZSA9IFtdO1xuXG4vKipcbiAqIFF1ZXVlIG9mIG1hcmt1cCB0byBiZSByZW5kZXJlZC5cbiAqXG4gKiBAdHlwZSB7YXJyYXk8c3RyaW5nPn1cbiAqIEBwcml2YXRlXG4gKi9cbnZhciBtYXJrdXBRdWV1ZSA9IFtdO1xuXG4vKipcbiAqIEVucXVldWVzIG1hcmt1cCB0byBiZSByZW5kZXJlZCBhbmQgaW5zZXJ0ZWQgYXQgYSBzdXBwbGllZCBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50SUQgSUQgb2YgdGhlIHBhcmVudCBjb21wb25lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIE1hcmt1cCB0aGF0IHJlbmRlcnMgaW50byBhbiBlbGVtZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHRvSW5kZXggRGVzdGluYXRpb24gaW5kZXguXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBlbnF1ZXVlSW5zZXJ0TWFya3VwKHBhcmVudElELCBtYXJrdXAsIHRvSW5kZXgpIHtcbiAgLy8gTk9URTogTnVsbCB2YWx1ZXMgcmVkdWNlIGhpZGRlbiBjbGFzc2VzLlxuICB1cGRhdGVRdWV1ZS5wdXNoKHtcbiAgICBwYXJlbnRJRDogcGFyZW50SUQsXG4gICAgcGFyZW50Tm9kZTogbnVsbCxcbiAgICB0eXBlOiBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5JTlNFUlRfTUFSS1VQLFxuICAgIG1hcmt1cEluZGV4OiBtYXJrdXBRdWV1ZS5wdXNoKG1hcmt1cCkgLSAxLFxuICAgIGNvbnRlbnQ6IG51bGwsXG4gICAgZnJvbUluZGV4OiBudWxsLFxuICAgIHRvSW5kZXg6IHRvSW5kZXhcbiAgfSk7XG59XG5cbi8qKlxuICogRW5xdWV1ZXMgbW92aW5nIGFuIGV4aXN0aW5nIGVsZW1lbnQgdG8gYW5vdGhlciBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50SUQgSUQgb2YgdGhlIHBhcmVudCBjb21wb25lbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFNvdXJjZSBpbmRleCBvZiB0aGUgZXhpc3RpbmcgZWxlbWVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b0luZGV4IERlc3RpbmF0aW9uIGluZGV4IG9mIHRoZSBlbGVtZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZU1vdmUocGFyZW50SUQsIGZyb21JbmRleCwgdG9JbmRleCkge1xuICAvLyBOT1RFOiBOdWxsIHZhbHVlcyByZWR1Y2UgaGlkZGVuIGNsYXNzZXMuXG4gIHVwZGF0ZVF1ZXVlLnB1c2goe1xuICAgIHBhcmVudElEOiBwYXJlbnRJRCxcbiAgICBwYXJlbnROb2RlOiBudWxsLFxuICAgIHR5cGU6IFJlYWN0TXVsdGlDaGlsZFVwZGF0ZVR5cGVzLk1PVkVfRVhJU1RJTkcsXG4gICAgbWFya3VwSW5kZXg6IG51bGwsXG4gICAgY29udGVudDogbnVsbCxcbiAgICBmcm9tSW5kZXg6IGZyb21JbmRleCxcbiAgICB0b0luZGV4OiB0b0luZGV4XG4gIH0pO1xufVxuXG4vKipcbiAqIEVucXVldWVzIHJlbW92aW5nIGFuIGVsZW1lbnQgYXQgYW4gaW5kZXguXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudElEIElEIG9mIHRoZSBwYXJlbnQgY29tcG9uZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBJbmRleCBvZiB0aGUgZWxlbWVudCB0byByZW1vdmUuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBlbnF1ZXVlUmVtb3ZlKHBhcmVudElELCBmcm9tSW5kZXgpIHtcbiAgLy8gTk9URTogTnVsbCB2YWx1ZXMgcmVkdWNlIGhpZGRlbiBjbGFzc2VzLlxuICB1cGRhdGVRdWV1ZS5wdXNoKHtcbiAgICBwYXJlbnRJRDogcGFyZW50SUQsXG4gICAgcGFyZW50Tm9kZTogbnVsbCxcbiAgICB0eXBlOiBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlcy5SRU1PVkVfTk9ERSxcbiAgICBtYXJrdXBJbmRleDogbnVsbCxcbiAgICBjb250ZW50OiBudWxsLFxuICAgIGZyb21JbmRleDogZnJvbUluZGV4LFxuICAgIHRvSW5kZXg6IG51bGxcbiAgfSk7XG59XG5cbi8qKlxuICogRW5xdWV1ZXMgc2V0dGluZyB0aGUgbWFya3VwIG9mIGEgbm9kZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50SUQgSUQgb2YgdGhlIHBhcmVudCBjb21wb25lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIE1hcmt1cCB0aGF0IHJlbmRlcnMgaW50byBhbiBlbGVtZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZVNldE1hcmt1cChwYXJlbnRJRCwgbWFya3VwKSB7XG4gIC8vIE5PVEU6IE51bGwgdmFsdWVzIHJlZHVjZSBoaWRkZW4gY2xhc3Nlcy5cbiAgdXBkYXRlUXVldWUucHVzaCh7XG4gICAgcGFyZW50SUQ6IHBhcmVudElELFxuICAgIHBhcmVudE5vZGU6IG51bGwsXG4gICAgdHlwZTogUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMuU0VUX01BUktVUCxcbiAgICBtYXJrdXBJbmRleDogbnVsbCxcbiAgICBjb250ZW50OiBtYXJrdXAsXG4gICAgZnJvbUluZGV4OiBudWxsLFxuICAgIHRvSW5kZXg6IG51bGxcbiAgfSk7XG59XG5cbi8qKlxuICogRW5xdWV1ZXMgc2V0dGluZyB0aGUgdGV4dCBjb250ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXJlbnRJRCBJRCBvZiB0aGUgcGFyZW50IGNvbXBvbmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0Q29udGVudCBUZXh0IGNvbnRlbnQgdG8gc2V0LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZVRleHRDb250ZW50KHBhcmVudElELCB0ZXh0Q29udGVudCkge1xuICAvLyBOT1RFOiBOdWxsIHZhbHVlcyByZWR1Y2UgaGlkZGVuIGNsYXNzZXMuXG4gIHVwZGF0ZVF1ZXVlLnB1c2goe1xuICAgIHBhcmVudElEOiBwYXJlbnRJRCxcbiAgICBwYXJlbnROb2RlOiBudWxsLFxuICAgIHR5cGU6IFJlYWN0TXVsdGlDaGlsZFVwZGF0ZVR5cGVzLlRFWFRfQ09OVEVOVCxcbiAgICBtYXJrdXBJbmRleDogbnVsbCxcbiAgICBjb250ZW50OiB0ZXh0Q29udGVudCxcbiAgICBmcm9tSW5kZXg6IG51bGwsXG4gICAgdG9JbmRleDogbnVsbFxuICB9KTtcbn1cblxuLyoqXG4gKiBQcm9jZXNzZXMgYW55IGVucXVldWVkIHVwZGF0ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcHJvY2Vzc1F1ZXVlKCkge1xuICBpZiAodXBkYXRlUXVldWUubGVuZ3RoKSB7XG4gICAgUmVhY3RDb21wb25lbnRFbnZpcm9ubWVudC5wcm9jZXNzQ2hpbGRyZW5VcGRhdGVzKHVwZGF0ZVF1ZXVlLCBtYXJrdXBRdWV1ZSk7XG4gICAgY2xlYXJRdWV1ZSgpO1xuICB9XG59XG5cbi8qKlxuICogQ2xlYXJzIGFueSBlbnF1ZXVlZCB1cGRhdGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNsZWFyUXVldWUoKSB7XG4gIHVwZGF0ZVF1ZXVlLmxlbmd0aCA9IDA7XG4gIG1hcmt1cFF1ZXVlLmxlbmd0aCA9IDA7XG59XG5cbi8qKlxuICogUmVhY3RNdWx0aUNoaWxkIGFyZSBjYXBhYmxlIG9mIHJlY29uY2lsaW5nIG11bHRpcGxlIGNoaWxkcmVuLlxuICpcbiAqIEBjbGFzcyBSZWFjdE11bHRpQ2hpbGRcbiAqIEBpbnRlcm5hbFxuICovXG52YXIgUmVhY3RNdWx0aUNoaWxkID0ge1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBjb21tb24gZnVuY3Rpb25hbGl0eSBmb3IgY29tcG9uZW50cyB0aGF0IG11c3QgcmVjb25jaWxlIG11bHRpcGxlXG4gICAqIGNoaWxkcmVuLiBUaGlzIGlzIHVzZWQgYnkgYFJlYWN0RE9NQ29tcG9uZW50YCB0byBtb3VudCwgdXBkYXRlLCBhbmRcbiAgICogdW5tb3VudCBjaGlsZCBjb21wb25lbnRzLlxuICAgKlxuICAgKiBAbGVuZHMge1JlYWN0TXVsdGlDaGlsZC5wcm90b3R5cGV9XG4gICAqL1xuICBNaXhpbjoge1xuXG4gICAgX3JlY29uY2lsZXJJbnN0YW50aWF0ZUNoaWxkcmVuOiBmdW5jdGlvbiAobmVzdGVkQ2hpbGRyZW4sIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCA9IHRoaXMuX2N1cnJlbnRFbGVtZW50Ll9vd25lcjtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdENoaWxkUmVjb25jaWxlci5pbnN0YW50aWF0ZUNoaWxkcmVuKG5lc3RlZENoaWxkcmVuLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIFJlYWN0Q2hpbGRSZWNvbmNpbGVyLmluc3RhbnRpYXRlQ2hpbGRyZW4obmVzdGVkQ2hpbGRyZW4sIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgX3JlY29uY2lsZXJVcGRhdGVDaGlsZHJlbjogZnVuY3Rpb24gKHByZXZDaGlsZHJlbiwgbmV4dE5lc3RlZENoaWxkcmVuRWxlbWVudHMsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICB2YXIgbmV4dENoaWxkcmVuO1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgPSB0aGlzLl9jdXJyZW50RWxlbWVudC5fb3duZXI7XG4gICAgICAgICAgICBuZXh0Q2hpbGRyZW4gPSBmbGF0dGVuQ2hpbGRyZW4obmV4dE5lc3RlZENoaWxkcmVuRWxlbWVudHMpO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFJlYWN0Q2hpbGRSZWNvbmNpbGVyLnVwZGF0ZUNoaWxkcmVuKHByZXZDaGlsZHJlbiwgbmV4dENoaWxkcmVuLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG5leHRDaGlsZHJlbiA9IGZsYXR0ZW5DaGlsZHJlbihuZXh0TmVzdGVkQ2hpbGRyZW5FbGVtZW50cyk7XG4gICAgICByZXR1cm4gUmVhY3RDaGlsZFJlY29uY2lsZXIudXBkYXRlQ2hpbGRyZW4ocHJldkNoaWxkcmVuLCBuZXh0Q2hpbGRyZW4sIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgXCJtb3VudCBpbWFnZVwiIGZvciBlYWNoIG9mIHRoZSBzdXBwbGllZCBjaGlsZHJlbi4gSW4gdGhlIGNhc2VcbiAgICAgKiBvZiBgUmVhY3RET01Db21wb25lbnRgLCBhIG1vdW50IGltYWdlIGlzIGEgc3RyaW5nIG9mIG1hcmt1cC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7P29iamVjdH0gbmVzdGVkQ2hpbGRyZW4gTmVzdGVkIGNoaWxkIG1hcHMuXG4gICAgICogQHJldHVybiB7YXJyYXl9IEFuIGFycmF5IG9mIG1vdW50ZWQgcmVwcmVzZW50YXRpb25zLlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIG1vdW50Q2hpbGRyZW46IGZ1bmN0aW9uIChuZXN0ZWRDaGlsZHJlbiwgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX3JlY29uY2lsZXJJbnN0YW50aWF0ZUNoaWxkcmVuKG5lc3RlZENoaWxkcmVuLCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgICB0aGlzLl9yZW5kZXJlZENoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgICB2YXIgbW91bnRJbWFnZXMgPSBbXTtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIGNoaWxkcmVuKSB7XG4gICAgICAgIGlmIChjaGlsZHJlbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW25hbWVdO1xuICAgICAgICAgIC8vIElubGluZWQgZm9yIHBlcmZvcm1hbmNlLCBzZWUgYFJlYWN0SW5zdGFuY2VIYW5kbGVzLmNyZWF0ZVJlYWN0SURgLlxuICAgICAgICAgIHZhciByb290SUQgPSB0aGlzLl9yb290Tm9kZUlEICsgbmFtZTtcbiAgICAgICAgICB2YXIgbW91bnRJbWFnZSA9IFJlYWN0UmVjb25jaWxlci5tb3VudENvbXBvbmVudChjaGlsZCwgcm9vdElELCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgICAgICAgY2hpbGQuX21vdW50SW5kZXggPSBpbmRleCsrO1xuICAgICAgICAgIG1vdW50SW1hZ2VzLnB1c2gobW91bnRJbWFnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtb3VudEltYWdlcztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZXMgYW55IHJlbmRlcmVkIGNoaWxkcmVuIHdpdGggYSB0ZXh0IGNvbnRlbnQgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5leHRDb250ZW50IFN0cmluZyBvZiBjb250ZW50LlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHVwZGF0ZVRleHRDb250ZW50OiBmdW5jdGlvbiAobmV4dENvbnRlbnQpIHtcbiAgICAgIHVwZGF0ZURlcHRoKys7XG4gICAgICB2YXIgZXJyb3JUaHJvd24gPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHByZXZDaGlsZHJlbiA9IHRoaXMuX3JlbmRlcmVkQ2hpbGRyZW47XG4gICAgICAgIC8vIFJlbW92ZSBhbnkgcmVuZGVyZWQgY2hpbGRyZW4uXG4gICAgICAgIFJlYWN0Q2hpbGRSZWNvbmNpbGVyLnVubW91bnRDaGlsZHJlbihwcmV2Q2hpbGRyZW4pO1xuICAgICAgICAvLyBUT0RPOiBUaGUgc2V0VGV4dENvbnRlbnQgb3BlcmF0aW9uIHNob3VsZCBiZSBlbm91Z2hcbiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgICAgICBpZiAocHJldkNoaWxkcmVuLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLl91bm1vdW50Q2hpbGQocHJldkNoaWxkcmVuW25hbWVdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2V0IG5ldyB0ZXh0IGNvbnRlbnQuXG4gICAgICAgIHRoaXMuc2V0VGV4dENvbnRlbnQobmV4dENvbnRlbnQpO1xuICAgICAgICBlcnJvclRocm93biA9IGZhbHNlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdXBkYXRlRGVwdGgtLTtcbiAgICAgICAgaWYgKCF1cGRhdGVEZXB0aCkge1xuICAgICAgICAgIGlmIChlcnJvclRocm93bikge1xuICAgICAgICAgICAgY2xlYXJRdWV1ZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9jZXNzUXVldWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZXMgYW55IHJlbmRlcmVkIGNoaWxkcmVuIHdpdGggYSBtYXJrdXAgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5leHRNYXJrdXAgU3RyaW5nIG9mIG1hcmt1cC5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICB1cGRhdGVNYXJrdXA6IGZ1bmN0aW9uIChuZXh0TWFya3VwKSB7XG4gICAgICB1cGRhdGVEZXB0aCsrO1xuICAgICAgdmFyIGVycm9yVGhyb3duID0gdHJ1ZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBwcmV2Q2hpbGRyZW4gPSB0aGlzLl9yZW5kZXJlZENoaWxkcmVuO1xuICAgICAgICAvLyBSZW1vdmUgYW55IHJlbmRlcmVkIGNoaWxkcmVuLlxuICAgICAgICBSZWFjdENoaWxkUmVjb25jaWxlci51bm1vdW50Q2hpbGRyZW4ocHJldkNoaWxkcmVuKTtcbiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgICAgICBpZiAocHJldkNoaWxkcmVuLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLl91bm1vdW50Q2hpbGRCeU5hbWUocHJldkNoaWxkcmVuW25hbWVdLCBuYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRNYXJrdXAobmV4dE1hcmt1cCk7XG4gICAgICAgIGVycm9yVGhyb3duID0gZmFsc2U7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB1cGRhdGVEZXB0aC0tO1xuICAgICAgICBpZiAoIXVwZGF0ZURlcHRoKSB7XG4gICAgICAgICAgaWYgKGVycm9yVGhyb3duKSB7XG4gICAgICAgICAgICBjbGVhclF1ZXVlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb2Nlc3NRdWV1ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSByZW5kZXJlZCBjaGlsZHJlbiB3aXRoIG5ldyBjaGlsZHJlbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7P29iamVjdH0gbmV4dE5lc3RlZENoaWxkcmVuRWxlbWVudHMgTmVzdGVkIGNoaWxkIGVsZW1lbnQgbWFwcy5cbiAgICAgKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgdXBkYXRlQ2hpbGRyZW46IGZ1bmN0aW9uIChuZXh0TmVzdGVkQ2hpbGRyZW5FbGVtZW50cywgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICAgIHVwZGF0ZURlcHRoKys7XG4gICAgICB2YXIgZXJyb3JUaHJvd24gPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fdXBkYXRlQ2hpbGRyZW4obmV4dE5lc3RlZENoaWxkcmVuRWxlbWVudHMsIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgICAgICAgZXJyb3JUaHJvd24gPSBmYWxzZTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHVwZGF0ZURlcHRoLS07XG4gICAgICAgIGlmICghdXBkYXRlRGVwdGgpIHtcbiAgICAgICAgICBpZiAoZXJyb3JUaHJvd24pIHtcbiAgICAgICAgICAgIGNsZWFyUXVldWUoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJvY2Vzc1F1ZXVlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEltcHJvdmUgcGVyZm9ybWFuY2UgYnkgaXNvbGF0aW5nIHRoaXMgaG90IGNvZGUgcGF0aCBmcm9tIHRoZSB0cnkvY2F0Y2hcbiAgICAgKiBibG9jayBpbiBgdXBkYXRlQ2hpbGRyZW5gLlxuICAgICAqXG4gICAgICogQHBhcmFtIHs/b2JqZWN0fSBuZXh0TmVzdGVkQ2hpbGRyZW5FbGVtZW50cyBOZXN0ZWQgY2hpbGQgZWxlbWVudCBtYXBzLlxuICAgICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICAgKiBAZmluYWxcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICovXG4gICAgX3VwZGF0ZUNoaWxkcmVuOiBmdW5jdGlvbiAobmV4dE5lc3RlZENoaWxkcmVuRWxlbWVudHMsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcHJldkNoaWxkcmVuID0gdGhpcy5fcmVuZGVyZWRDaGlsZHJlbjtcbiAgICAgIHZhciBuZXh0Q2hpbGRyZW4gPSB0aGlzLl9yZWNvbmNpbGVyVXBkYXRlQ2hpbGRyZW4ocHJldkNoaWxkcmVuLCBuZXh0TmVzdGVkQ2hpbGRyZW5FbGVtZW50cywgdHJhbnNhY3Rpb24sIGNvbnRleHQpO1xuICAgICAgdGhpcy5fcmVuZGVyZWRDaGlsZHJlbiA9IG5leHRDaGlsZHJlbjtcbiAgICAgIGlmICghbmV4dENoaWxkcmVuICYmICFwcmV2Q2hpbGRyZW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmFyIG5hbWU7XG4gICAgICAvLyBgbmV4dEluZGV4YCB3aWxsIGluY3JlbWVudCBmb3IgZWFjaCBjaGlsZCBpbiBgbmV4dENoaWxkcmVuYCwgYnV0XG4gICAgICAvLyBgbGFzdEluZGV4YCB3aWxsIGJlIHRoZSBsYXN0IGluZGV4IHZpc2l0ZWQgaW4gYHByZXZDaGlsZHJlbmAuXG4gICAgICB2YXIgbGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBuZXh0SW5kZXggPSAwO1xuICAgICAgZm9yIChuYW1lIGluIG5leHRDaGlsZHJlbikge1xuICAgICAgICBpZiAoIW5leHRDaGlsZHJlbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmV2Q2hpbGQgPSBwcmV2Q2hpbGRyZW4gJiYgcHJldkNoaWxkcmVuW25hbWVdO1xuICAgICAgICB2YXIgbmV4dENoaWxkID0gbmV4dENoaWxkcmVuW25hbWVdO1xuICAgICAgICBpZiAocHJldkNoaWxkID09PSBuZXh0Q2hpbGQpIHtcbiAgICAgICAgICB0aGlzLm1vdmVDaGlsZChwcmV2Q2hpbGQsIG5leHRJbmRleCwgbGFzdEluZGV4KTtcbiAgICAgICAgICBsYXN0SW5kZXggPSBNYXRoLm1heChwcmV2Q2hpbGQuX21vdW50SW5kZXgsIGxhc3RJbmRleCk7XG4gICAgICAgICAgcHJldkNoaWxkLl9tb3VudEluZGV4ID0gbmV4dEluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChwcmV2Q2hpbGQpIHtcbiAgICAgICAgICAgIC8vIFVwZGF0ZSBgbGFzdEluZGV4YCBiZWZvcmUgYF9tb3VudEluZGV4YCBnZXRzIHVuc2V0IGJ5IHVubW91bnRpbmcuXG4gICAgICAgICAgICBsYXN0SW5kZXggPSBNYXRoLm1heChwcmV2Q2hpbGQuX21vdW50SW5kZXgsIGxhc3RJbmRleCk7XG4gICAgICAgICAgICB0aGlzLl91bm1vdW50Q2hpbGQocHJldkNoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIGNoaWxkIG11c3QgYmUgaW5zdGFudGlhdGVkIGJlZm9yZSBpdCdzIG1vdW50ZWQuXG4gICAgICAgICAgdGhpcy5fbW91bnRDaGlsZEJ5TmFtZUF0SW5kZXgobmV4dENoaWxkLCBuYW1lLCBuZXh0SW5kZXgsIHRyYW5zYWN0aW9uLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0SW5kZXgrKztcbiAgICAgIH1cbiAgICAgIC8vIFJlbW92ZSBjaGlsZHJlbiB0aGF0IGFyZSBubyBsb25nZXIgcHJlc2VudC5cbiAgICAgIGZvciAobmFtZSBpbiBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgICAgaWYgKHByZXZDaGlsZHJlbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiAhKG5leHRDaGlsZHJlbiAmJiBuZXh0Q2hpbGRyZW4uaGFzT3duUHJvcGVydHkobmFtZSkpKSB7XG4gICAgICAgICAgdGhpcy5fdW5tb3VudENoaWxkKHByZXZDaGlsZHJlbltuYW1lXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVW5tb3VudHMgYWxsIHJlbmRlcmVkIGNoaWxkcmVuLiBUaGlzIHNob3VsZCBiZSB1c2VkIHRvIGNsZWFuIHVwIGNoaWxkcmVuXG4gICAgICogd2hlbiB0aGlzIGNvbXBvbmVudCBpcyB1bm1vdW50ZWQuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICB1bm1vdW50Q2hpbGRyZW46IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciByZW5kZXJlZENoaWxkcmVuID0gdGhpcy5fcmVuZGVyZWRDaGlsZHJlbjtcbiAgICAgIFJlYWN0Q2hpbGRSZWNvbmNpbGVyLnVubW91bnRDaGlsZHJlbihyZW5kZXJlZENoaWxkcmVuKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVkQ2hpbGRyZW4gPSBudWxsO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBNb3ZlcyBhIGNoaWxkIGNvbXBvbmVudCB0byB0aGUgc3VwcGxpZWQgaW5kZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1JlYWN0Q29tcG9uZW50fSBjaGlsZCBDb21wb25lbnQgdG8gbW92ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdG9JbmRleCBEZXN0aW5hdGlvbiBpbmRleCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGFzdEluZGV4IExhc3QgaW5kZXggdmlzaXRlZCBvZiB0aGUgc2libGluZ3Mgb2YgYGNoaWxkYC5cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICovXG4gICAgbW92ZUNoaWxkOiBmdW5jdGlvbiAoY2hpbGQsIHRvSW5kZXgsIGxhc3RJbmRleCkge1xuICAgICAgLy8gSWYgdGhlIGluZGV4IG9mIGBjaGlsZGAgaXMgbGVzcyB0aGFuIGBsYXN0SW5kZXhgLCB0aGVuIGl0IG5lZWRzIHRvXG4gICAgICAvLyBiZSBtb3ZlZC4gT3RoZXJ3aXNlLCB3ZSBkbyBub3QgbmVlZCB0byBtb3ZlIGl0IGJlY2F1c2UgYSBjaGlsZCB3aWxsIGJlXG4gICAgICAvLyBpbnNlcnRlZCBvciBtb3ZlZCBiZWZvcmUgYGNoaWxkYC5cbiAgICAgIGlmIChjaGlsZC5fbW91bnRJbmRleCA8IGxhc3RJbmRleCkge1xuICAgICAgICBlbnF1ZXVlTW92ZSh0aGlzLl9yb290Tm9kZUlELCBjaGlsZC5fbW91bnRJbmRleCwgdG9JbmRleCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjaGlsZCBjb21wb25lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1JlYWN0Q29tcG9uZW50fSBjaGlsZCBDb21wb25lbnQgdG8gY3JlYXRlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtb3VudEltYWdlIE1hcmt1cCB0byBpbnNlcnQuXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuICAgIGNyZWF0ZUNoaWxkOiBmdW5jdGlvbiAoY2hpbGQsIG1vdW50SW1hZ2UpIHtcbiAgICAgIGVucXVldWVJbnNlcnRNYXJrdXAodGhpcy5fcm9vdE5vZGVJRCwgbW91bnRJbWFnZSwgY2hpbGQuX21vdW50SW5kZXgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgY2hpbGQgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY2hpbGQgQ2hpbGQgdG8gcmVtb3ZlLlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cbiAgICByZW1vdmVDaGlsZDogZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICBlbnF1ZXVlUmVtb3ZlKHRoaXMuX3Jvb3ROb2RlSUQsIGNoaWxkLl9tb3VudEluZGV4KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGlzIHRleHQgY29udGVudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dENvbnRlbnQgVGV4dCBjb250ZW50IHRvIHNldC5cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICovXG4gICAgc2V0VGV4dENvbnRlbnQ6IGZ1bmN0aW9uICh0ZXh0Q29udGVudCkge1xuICAgICAgZW5xdWV1ZVRleHRDb250ZW50KHRoaXMuX3Jvb3ROb2RlSUQsIHRleHRDb250ZW50KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGlzIG1hcmt1cCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya3VwIE1hcmt1cCB0byBzZXQuXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuICAgIHNldE1hcmt1cDogZnVuY3Rpb24gKG1hcmt1cCkge1xuICAgICAgZW5xdWV1ZVNldE1hcmt1cCh0aGlzLl9yb290Tm9kZUlELCBtYXJrdXApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBNb3VudHMgYSBjaGlsZCB3aXRoIHRoZSBzdXBwbGllZCBuYW1lLlxuICAgICAqXG4gICAgICogTk9URTogVGhpcyBpcyBwYXJ0IG9mIGB1cGRhdGVDaGlsZHJlbmAgYW5kIGlzIGhlcmUgZm9yIHJlYWRhYmlsaXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY2hpbGQgQ29tcG9uZW50IHRvIG1vdW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIGNoaWxkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleCBhdCB3aGljaCB0byBpbnNlcnQgdGhlIGNoaWxkLlxuICAgICAqIEBwYXJhbSB7UmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9tb3VudENoaWxkQnlOYW1lQXRJbmRleDogZnVuY3Rpb24gKGNoaWxkLCBuYW1lLCBpbmRleCwgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICAgIC8vIElubGluZWQgZm9yIHBlcmZvcm1hbmNlLCBzZWUgYFJlYWN0SW5zdGFuY2VIYW5kbGVzLmNyZWF0ZVJlYWN0SURgLlxuICAgICAgdmFyIHJvb3RJRCA9IHRoaXMuX3Jvb3ROb2RlSUQgKyBuYW1lO1xuICAgICAgdmFyIG1vdW50SW1hZ2UgPSBSZWFjdFJlY29uY2lsZXIubW91bnRDb21wb25lbnQoY2hpbGQsIHJvb3RJRCwgdHJhbnNhY3Rpb24sIGNvbnRleHQpO1xuICAgICAgY2hpbGQuX21vdW50SW5kZXggPSBpbmRleDtcbiAgICAgIHRoaXMuY3JlYXRlQ2hpbGQoY2hpbGQsIG1vdW50SW1hZ2UpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBVbm1vdW50cyBhIHJlbmRlcmVkIGNoaWxkLlxuICAgICAqXG4gICAgICogTk9URTogVGhpcyBpcyBwYXJ0IG9mIGB1cGRhdGVDaGlsZHJlbmAgYW5kIGlzIGhlcmUgZm9yIHJlYWRhYmlsaXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY2hpbGQgQ29tcG9uZW50IHRvIHVubW91bnQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdW5tb3VudENoaWxkOiBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgIHRoaXMucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICAgICAgY2hpbGQuX21vdW50SW5kZXggPSBudWxsO1xuICAgIH1cblxuICB9XG5cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RNdWx0aUNoaWxkOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGtleU1pcnJvciA9IHJlcXVpcmUoJ2ZianMvbGliL2tleU1pcnJvcicpO1xuXG4vKipcbiAqIFdoZW4gYSBjb21wb25lbnQncyBjaGlsZHJlbiBhcmUgdXBkYXRlZCwgYSBzZXJpZXMgb2YgdXBkYXRlIGNvbmZpZ3VyYXRpb25cbiAqIG9iamVjdHMgYXJlIGNyZWF0ZWQgaW4gb3JkZXIgdG8gYmF0Y2ggYW5kIHNlcmlhbGl6ZSB0aGUgcmVxdWlyZWQgY2hhbmdlcy5cbiAqXG4gKiBFbnVtZXJhdGVzIGFsbCB0aGUgcG9zc2libGUgdHlwZXMgb2YgdXBkYXRlIGNvbmZpZ3VyYXRpb25zLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG52YXIgUmVhY3RNdWx0aUNoaWxkVXBkYXRlVHlwZXMgPSBrZXlNaXJyb3Ioe1xuICBJTlNFUlRfTUFSS1VQOiBudWxsLFxuICBNT1ZFX0VYSVNUSU5HOiBudWxsLFxuICBSRU1PVkVfTk9ERTogbnVsbCxcbiAgU0VUX01BUktVUDogbnVsbCxcbiAgVEVYVF9DT05URU5UOiBudWxsXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdE11bHRpQ2hpbGRVcGRhdGVUeXBlczsiLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3ROYXRpdmVDb21wb25lbnRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxudmFyIGF1dG9HZW5lcmF0ZVdyYXBwZXJDbGFzcyA9IG51bGw7XG52YXIgZ2VuZXJpY0NvbXBvbmVudENsYXNzID0gbnVsbDtcbi8vIFRoaXMgcmVnaXN0cnkga2VlcHMgdHJhY2sgb2Ygd3JhcHBlciBjbGFzc2VzIGFyb3VuZCBuYXRpdmUgdGFncy5cbnZhciB0YWdUb0NvbXBvbmVudENsYXNzID0ge307XG52YXIgdGV4dENvbXBvbmVudENsYXNzID0gbnVsbDtcblxudmFyIFJlYWN0TmF0aXZlQ29tcG9uZW50SW5qZWN0aW9uID0ge1xuICAvLyBUaGlzIGFjY2VwdHMgYSBjbGFzcyB0aGF0IHJlY2VpdmVzIHRoZSB0YWcgc3RyaW5nLiBUaGlzIGlzIGEgY2F0Y2ggYWxsXG4gIC8vIHRoYXQgY2FuIHJlbmRlciBhbnkga2luZCBvZiB0YWcuXG4gIGluamVjdEdlbmVyaWNDb21wb25lbnRDbGFzczogZnVuY3Rpb24gKGNvbXBvbmVudENsYXNzKSB7XG4gICAgZ2VuZXJpY0NvbXBvbmVudENsYXNzID0gY29tcG9uZW50Q2xhc3M7XG4gIH0sXG4gIC8vIFRoaXMgYWNjZXB0cyBhIHRleHQgY29tcG9uZW50IGNsYXNzIHRoYXQgdGFrZXMgdGhlIHRleHQgc3RyaW5nIHRvIGJlXG4gIC8vIHJlbmRlcmVkIGFzIHByb3BzLlxuICBpbmplY3RUZXh0Q29tcG9uZW50Q2xhc3M6IGZ1bmN0aW9uIChjb21wb25lbnRDbGFzcykge1xuICAgIHRleHRDb21wb25lbnRDbGFzcyA9IGNvbXBvbmVudENsYXNzO1xuICB9LFxuICAvLyBUaGlzIGFjY2VwdHMgYSBrZXllZCBvYmplY3Qgd2l0aCBjbGFzc2VzIGFzIHZhbHVlcy4gRWFjaCBrZXkgcmVwcmVzZW50cyBhXG4gIC8vIHRhZy4gVGhhdCBwYXJ0aWN1bGFyIHRhZyB3aWxsIHVzZSB0aGlzIGNsYXNzIGluc3RlYWQgb2YgdGhlIGdlbmVyaWMgb25lLlxuICBpbmplY3RDb21wb25lbnRDbGFzc2VzOiBmdW5jdGlvbiAoY29tcG9uZW50Q2xhc3Nlcykge1xuICAgIGFzc2lnbih0YWdUb0NvbXBvbmVudENsYXNzLCBjb21wb25lbnRDbGFzc2VzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgYSBjb21wb3NpdGUgY29tcG9uZW50IHdyYXBwZXIgY2xhc3MgZm9yIGEgc3BlY2lmaWMgdGFnLlxuICpcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBlbGVtZW50IFRoZSB0YWcgZm9yIHdoaWNoIHRvIGdldCB0aGUgY2xhc3MuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbn0gVGhlIFJlYWN0IGNsYXNzIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBnZXRDb21wb25lbnRDbGFzc0ZvckVsZW1lbnQoZWxlbWVudCkge1xuICBpZiAodHlwZW9mIGVsZW1lbnQudHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbGVtZW50LnR5cGU7XG4gIH1cbiAgdmFyIHRhZyA9IGVsZW1lbnQudHlwZTtcbiAgdmFyIGNvbXBvbmVudENsYXNzID0gdGFnVG9Db21wb25lbnRDbGFzc1t0YWddO1xuICBpZiAoY29tcG9uZW50Q2xhc3MgPT0gbnVsbCkge1xuICAgIHRhZ1RvQ29tcG9uZW50Q2xhc3NbdGFnXSA9IGNvbXBvbmVudENsYXNzID0gYXV0b0dlbmVyYXRlV3JhcHBlckNsYXNzKHRhZyk7XG4gIH1cbiAgcmV0dXJuIGNvbXBvbmVudENsYXNzO1xufVxuXG4vKipcbiAqIEdldCBhIG5hdGl2ZSBpbnRlcm5hbCBjb21wb25lbnQgY2xhc3MgZm9yIGEgc3BlY2lmaWMgdGFnLlxuICpcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIGNyZWF0ZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9ufSBUaGUgaW50ZXJuYWwgY2xhc3MgY29uc3RydWN0b3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUludGVybmFsQ29tcG9uZW50KGVsZW1lbnQpIHtcbiAgIWdlbmVyaWNDb21wb25lbnRDbGFzcyA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdUaGVyZSBpcyBubyByZWdpc3RlcmVkIGNvbXBvbmVudCBmb3IgdGhlIHRhZyAlcycsIGVsZW1lbnQudHlwZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICByZXR1cm4gbmV3IGdlbmVyaWNDb21wb25lbnRDbGFzcyhlbGVtZW50LnR5cGUsIGVsZW1lbnQucHJvcHMpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7UmVhY3RUZXh0fSB0ZXh0XG4gKiBAcmV0dXJuIHtSZWFjdENvbXBvbmVudH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2VGb3JUZXh0KHRleHQpIHtcbiAgcmV0dXJuIG5ldyB0ZXh0Q29tcG9uZW50Q2xhc3ModGV4dCk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gY29tcG9uZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc1RleHRDb21wb25lbnQoY29tcG9uZW50KSB7XG4gIHJldHVybiBjb21wb25lbnQgaW5zdGFuY2VvZiB0ZXh0Q29tcG9uZW50Q2xhc3M7XG59XG5cbnZhciBSZWFjdE5hdGl2ZUNvbXBvbmVudCA9IHtcbiAgZ2V0Q29tcG9uZW50Q2xhc3NGb3JFbGVtZW50OiBnZXRDb21wb25lbnRDbGFzc0ZvckVsZW1lbnQsXG4gIGNyZWF0ZUludGVybmFsQ29tcG9uZW50OiBjcmVhdGVJbnRlcm5hbENvbXBvbmVudCxcbiAgY3JlYXRlSW5zdGFuY2VGb3JUZXh0OiBjcmVhdGVJbnN0YW5jZUZvclRleHQsXG4gIGlzVGV4dENvbXBvbmVudDogaXNUZXh0Q29tcG9uZW50LFxuICBpbmplY3Rpb246IFJlYWN0TmF0aXZlQ29tcG9uZW50SW5qZWN0aW9uXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0TmF0aXZlQ29tcG9uZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3ROb29wVXBkYXRlUXVldWVcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG5mdW5jdGlvbiB3YXJuVERaKHB1YmxpY0luc3RhbmNlLCBjYWxsZXJOYW1lKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcoZmFsc2UsICclcyguLi4pOiBDYW4gb25seSB1cGRhdGUgYSBtb3VudGVkIG9yIG1vdW50aW5nIGNvbXBvbmVudC4gJyArICdUaGlzIHVzdWFsbHkgbWVhbnMgeW91IGNhbGxlZCAlcygpIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuICcgKyAnVGhpcyBpcyBhIG5vLW9wLiBQbGVhc2UgY2hlY2sgdGhlIGNvZGUgZm9yIHRoZSAlcyBjb21wb25lbnQuJywgY2FsbGVyTmFtZSwgY2FsbGVyTmFtZSwgcHVibGljSW5zdGFuY2UuY29uc3RydWN0b3IgJiYgcHVibGljSW5zdGFuY2UuY29uc3RydWN0b3IuZGlzcGxheU5hbWUgfHwgJycpIDogdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgYWJzdHJhY3QgQVBJIGZvciBhbiB1cGRhdGUgcXVldWUuXG4gKi9cbnZhciBSZWFjdE5vb3BVcGRhdGVRdWV1ZSA9IHtcblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoaXMgY29tcG9zaXRlIGNvbXBvbmVudCBpcyBtb3VudGVkLlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB3ZSB3YW50IHRvIHRlc3QuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbW91bnRlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBmaW5hbFxuICAgKi9cbiAgaXNNb3VudGVkOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEVucXVldWUgYSBjYWxsYmFjayB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgYWZ0ZXIgYWxsIHRoZSBwZW5kaW5nIHVwZGF0ZXNcbiAgICogaGF2ZSBwcm9jZXNzZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRvIHVzZSBhcyBgdGhpc2AgY29udGV4dC5cbiAgICogQHBhcmFtIHs/ZnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCBhZnRlciBzdGF0ZSBpcyB1cGRhdGVkLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVDYWxsYmFjazogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBjYWxsYmFjaykge30sXG5cbiAgLyoqXG4gICAqIEZvcmNlcyBhbiB1cGRhdGUuIFRoaXMgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB3aGVuIGl0IGlzIGtub3duIHdpdGhcbiAgICogY2VydGFpbnR5IHRoYXQgd2UgYXJlICoqbm90KiogaW4gYSBET00gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFlvdSBtYXkgd2FudCB0byBjYWxsIHRoaXMgd2hlbiB5b3Uga25vdyB0aGF0IHNvbWUgZGVlcGVyIGFzcGVjdCBvZiB0aGVcbiAgICogY29tcG9uZW50J3Mgc3RhdGUgaGFzIGNoYW5nZWQgYnV0IGBzZXRTdGF0ZWAgd2FzIG5vdCBjYWxsZWQuXG4gICAqXG4gICAqIFRoaXMgd2lsbCBub3QgaW52b2tlIGBzaG91bGRDb21wb25lbnRVcGRhdGVgLCBidXQgaXQgd2lsbCBpbnZva2VcbiAgICogYGNvbXBvbmVudFdpbGxVcGRhdGVgIGFuZCBgY29tcG9uZW50RGlkVXBkYXRlYC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZUZvcmNlVXBkYXRlOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UpIHtcbiAgICB3YXJuVERaKHB1YmxpY0luc3RhbmNlLCAnZm9yY2VVcGRhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIG9mIHRoZSBzdGF0ZS4gQWx3YXlzIHVzZSB0aGlzIG9yIGBzZXRTdGF0ZWAgdG8gbXV0YXRlIHN0YXRlLlxuICAgKiBZb3Ugc2hvdWxkIHRyZWF0IGB0aGlzLnN0YXRlYCBhcyBpbW11dGFibGUuXG4gICAqXG4gICAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGB0aGlzLnN0YXRlYCB3aWxsIGJlIGltbWVkaWF0ZWx5IHVwZGF0ZWQsIHNvXG4gICAqIGFjY2Vzc2luZyBgdGhpcy5zdGF0ZWAgYWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCBtYXkgcmV0dXJuIHRoZSBvbGQgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29tcGxldGVTdGF0ZSBOZXh0IHN0YXRlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVSZXBsYWNlU3RhdGU6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSwgY29tcGxldGVTdGF0ZSkge1xuICAgIHdhcm5URFoocHVibGljSW5zdGFuY2UsICdyZXBsYWNlU3RhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgc3RhdGUuIFRoaXMgb25seSBleGlzdHMgYmVjYXVzZSBfcGVuZGluZ1N0YXRlIGlzXG4gICAqIGludGVybmFsLiBUaGlzIHByb3ZpZGVzIGEgbWVyZ2luZyBzdHJhdGVneSB0aGF0IGlzIG5vdCBhdmFpbGFibGUgdG8gZGVlcFxuICAgKiBwcm9wZXJ0aWVzIHdoaWNoIGlzIGNvbmZ1c2luZy4gVE9ETzogRXhwb3NlIHBlbmRpbmdTdGF0ZSBvciBkb24ndCB1c2UgaXRcbiAgICogZHVyaW5nIHRoZSBtZXJnZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXJ0aWFsU3RhdGUgTmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIHN0YXRlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVTZXRTdGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBwYXJ0aWFsU3RhdGUpIHtcbiAgICB3YXJuVERaKHB1YmxpY0luc3RhbmNlLCAnc2V0U3RhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgcHJvcHMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGFydGlhbFByb3BzIFN1YnNldCBvZiB0aGUgbmV4dCBwcm9wcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlU2V0UHJvcHM6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSwgcGFydGlhbFByb3BzKSB7XG4gICAgd2FyblREWihwdWJsaWNJbnN0YW5jZSwgJ3NldFByb3BzJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBvZiB0aGUgcHJvcHMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcHJvcHMgTmV3IHByb3BzLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVSZXBsYWNlUHJvcHM6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSwgcHJvcHMpIHtcbiAgICB3YXJuVERaKHB1YmxpY0luc3RhbmNlLCAncmVwbGFjZVByb3BzJyk7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdE5vb3BVcGRhdGVRdWV1ZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RPd25lclxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xuXG4vKipcbiAqIFJlYWN0T3duZXJzIGFyZSBjYXBhYmxlIG9mIHN0b3JpbmcgcmVmZXJlbmNlcyB0byBvd25lZCBjb21wb25lbnRzLlxuICpcbiAqIEFsbCBjb21wb25lbnRzIGFyZSBjYXBhYmxlIG9mIC8vYmVpbmcvLyByZWZlcmVuY2VkIGJ5IG93bmVyIGNvbXBvbmVudHMsIGJ1dFxuICogb25seSBSZWFjdE93bmVyIGNvbXBvbmVudHMgYXJlIGNhcGFibGUgb2YgLy9yZWZlcmVuY2luZy8vIG93bmVkIGNvbXBvbmVudHMuXG4gKiBUaGUgbmFtZWQgcmVmZXJlbmNlIGlzIGtub3duIGFzIGEgXCJyZWZcIi5cbiAqXG4gKiBSZWZzIGFyZSBhdmFpbGFibGUgd2hlbiBtb3VudGVkIGFuZCB1cGRhdGVkIGR1cmluZyByZWNvbmNpbGlhdGlvbi5cbiAqXG4gKiAgIHZhciBNeUNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAqICAgICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICogICAgICAgcmV0dXJuIChcbiAqICAgICAgICAgPGRpdiBvbkNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrfT5cbiAqICAgICAgICAgICA8Q3VzdG9tQ29tcG9uZW50IHJlZj1cImN1c3RvbVwiIC8+XG4gKiAgICAgICAgIDwvZGl2PlxuICogICAgICAgKTtcbiAqICAgICB9LFxuICogICAgIGhhbmRsZUNsaWNrOiBmdW5jdGlvbigpIHtcbiAqICAgICAgIHRoaXMucmVmcy5jdXN0b20uaGFuZGxlQ2xpY2soKTtcbiAqICAgICB9LFxuICogICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbigpIHtcbiAqICAgICAgIHRoaXMucmVmcy5jdXN0b20uaW5pdGlhbGl6ZSgpO1xuICogICAgIH1cbiAqICAgfSk7XG4gKlxuICogUmVmcyBzaG91bGQgcmFyZWx5IGJlIHVzZWQuIFdoZW4gcmVmcyBhcmUgdXNlZCwgdGhleSBzaG91bGQgb25seSBiZSBkb25lIHRvXG4gKiBjb250cm9sIGRhdGEgdGhhdCBpcyBub3QgaGFuZGxlZCBieSBSZWFjdCdzIGRhdGEgZmxvdy5cbiAqXG4gKiBAY2xhc3MgUmVhY3RPd25lclxuICovXG52YXIgUmVhY3RPd25lciA9IHtcblxuICAvKipcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBvYmplY3RcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBgb2JqZWN0YCBpcyBhIHZhbGlkIG93bmVyLlxuICAgKiBAZmluYWxcbiAgICovXG4gIGlzVmFsaWRPd25lcjogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiAhIShvYmplY3QgJiYgdHlwZW9mIG9iamVjdC5hdHRhY2hSZWYgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iamVjdC5kZXRhY2hSZWYgPT09ICdmdW5jdGlvbicpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBBZGRzIGEgY29tcG9uZW50IGJ5IHJlZiB0byBhbiBvd25lciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDb21wb25lbnR9IGNvbXBvbmVudCBDb21wb25lbnQgdG8gcmVmZXJlbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVmIE5hbWUgYnkgd2hpY2ggdG8gcmVmZXIgdG8gdGhlIGNvbXBvbmVudC5cbiAgICogQHBhcmFtIHtSZWFjdE93bmVyfSBvd25lciBDb21wb25lbnQgb24gd2hpY2ggdG8gcmVjb3JkIHRoZSByZWYuXG4gICAqIEBmaW5hbFxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGFkZENvbXBvbmVudEFzUmVmVG86IGZ1bmN0aW9uIChjb21wb25lbnQsIHJlZiwgb3duZXIpIHtcbiAgICAhUmVhY3RPd25lci5pc1ZhbGlkT3duZXIob3duZXIpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2FkZENvbXBvbmVudEFzUmVmVG8oLi4uKTogT25seSBhIFJlYWN0T3duZXIgY2FuIGhhdmUgcmVmcy4gWW91IG1pZ2h0ICcgKyAnYmUgYWRkaW5nIGEgcmVmIHRvIGEgY29tcG9uZW50IHRoYXQgd2FzIG5vdCBjcmVhdGVkIGluc2lkZSBhIGNvbXBvbmVudFxcJ3MgJyArICdgcmVuZGVyYCBtZXRob2QsIG9yIHlvdSBoYXZlIG11bHRpcGxlIGNvcGllcyBvZiBSZWFjdCBsb2FkZWQgJyArICcoZGV0YWlsczogaHR0cHM6Ly9mYi5tZS9yZWFjdC1yZWZzLW11c3QtaGF2ZS1vd25lcikuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIG93bmVyLmF0dGFjaFJlZihyZWYsIGNvbXBvbmVudCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBjb21wb25lbnQgYnkgcmVmIGZyb20gYW4gb3duZXIgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1JlYWN0Q29tcG9uZW50fSBjb21wb25lbnQgQ29tcG9uZW50IHRvIGRlcmVmZXJlbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVmIE5hbWUgb2YgdGhlIHJlZiB0byByZW1vdmUuXG4gICAqIEBwYXJhbSB7UmVhY3RPd25lcn0gb3duZXIgQ29tcG9uZW50IG9uIHdoaWNoIHRoZSByZWYgaXMgcmVjb3JkZWQuXG4gICAqIEBmaW5hbFxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHJlbW92ZUNvbXBvbmVudEFzUmVmRnJvbTogZnVuY3Rpb24gKGNvbXBvbmVudCwgcmVmLCBvd25lcikge1xuICAgICFSZWFjdE93bmVyLmlzVmFsaWRPd25lcihvd25lcikgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAncmVtb3ZlQ29tcG9uZW50QXNSZWZGcm9tKC4uLik6IE9ubHkgYSBSZWFjdE93bmVyIGNhbiBoYXZlIHJlZnMuIFlvdSBtaWdodCAnICsgJ2JlIHJlbW92aW5nIGEgcmVmIHRvIGEgY29tcG9uZW50IHRoYXQgd2FzIG5vdCBjcmVhdGVkIGluc2lkZSBhIGNvbXBvbmVudFxcJ3MgJyArICdgcmVuZGVyYCBtZXRob2QsIG9yIHlvdSBoYXZlIG11bHRpcGxlIGNvcGllcyBvZiBSZWFjdCBsb2FkZWQgJyArICcoZGV0YWlsczogaHR0cHM6Ly9mYi5tZS9yZWFjdC1yZWZzLW11c3QtaGF2ZS1vd25lcikuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIC8vIENoZWNrIHRoYXQgYGNvbXBvbmVudGAgaXMgc3RpbGwgdGhlIGN1cnJlbnQgcmVmIGJlY2F1c2Ugd2UgZG8gbm90IHdhbnQgdG9cbiAgICAvLyBkZXRhY2ggdGhlIHJlZiBpZiBhbm90aGVyIGNvbXBvbmVudCBzdG9sZSBpdC5cbiAgICBpZiAob3duZXIuZ2V0UHVibGljSW5zdGFuY2UoKS5yZWZzW3JlZl0gPT09IGNvbXBvbmVudC5nZXRQdWJsaWNJbnN0YW5jZSgpKSB7XG4gICAgICBvd25lci5kZXRhY2hSZWYocmVmKTtcbiAgICB9XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdE93bmVyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdFBlcmZcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFJlYWN0UGVyZiBpcyBhIGdlbmVyYWwgQU9QIHN5c3RlbSBkZXNpZ25lZCB0byBtZWFzdXJlIHBlcmZvcm1hbmNlLiBUaGlzXG4gKiBtb2R1bGUgb25seSBoYXMgdGhlIGhvb2tzOiBzZWUgUmVhY3REZWZhdWx0UGVyZiBmb3IgdGhlIGFuYWx5c2lzIHRvb2wuXG4gKi9cbnZhciBSZWFjdFBlcmYgPSB7XG4gIC8qKlxuICAgKiBCb29sZWFuIHRvIGVuYWJsZS9kaXNhYmxlIG1lYXN1cmVtZW50LiBTZXQgdG8gZmFsc2UgYnkgZGVmYXVsdCB0byBwcmV2ZW50XG4gICAqIGFjY2lkZW50YWwgbG9nZ2luZyBhbmQgcGVyZiBsb3NzLlxuICAgKi9cbiAgZW5hYmxlTWVhc3VyZTogZmFsc2UsXG5cbiAgLyoqXG4gICAqIEhvbGRzIG9udG8gdGhlIG1lYXN1cmUgZnVuY3Rpb24gaW4gdXNlLiBCeSBkZWZhdWx0LCBkb24ndCBtZWFzdXJlXG4gICAqIGFueXRoaW5nLCBidXQgd2UnbGwgb3ZlcnJpZGUgdGhpcyBpZiB3ZSBpbmplY3QgYSBtZWFzdXJlIGZ1bmN0aW9uLlxuICAgKi9cbiAgc3RvcmVkTWVhc3VyZTogX25vTWVhc3VyZSxcblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gb2JqZWN0TmFtZVxuICAgKiBAcGFyYW0ge29iamVjdDxzdHJpbmc+fSBtZXRob2ROYW1lc1xuICAgKi9cbiAgbWVhc3VyZU1ldGhvZHM6IGZ1bmN0aW9uIChvYmplY3QsIG9iamVjdE5hbWUsIG1ldGhvZE5hbWVzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBtZXRob2ROYW1lcykge1xuICAgICAgICBpZiAoIW1ldGhvZE5hbWVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3Rba2V5XSA9IFJlYWN0UGVyZi5tZWFzdXJlKG9iamVjdE5hbWUsIG1ldGhvZE5hbWVzW2tleV0sIG9iamVjdFtrZXldKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVzZSB0aGlzIHRvIHdyYXAgbWV0aG9kcyB5b3Ugd2FudCB0byBtZWFzdXJlLiBaZXJvIG92ZXJoZWFkIGluIHByb2R1Y3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvYmpOYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbk5hbWVcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gZnVuY1xuICAgKiBAcmV0dXJuIHtmdW5jdGlvbn1cbiAgICovXG4gIG1lYXN1cmU6IGZ1bmN0aW9uIChvYmpOYW1lLCBmbk5hbWUsIGZ1bmMpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgdmFyIG1lYXN1cmVkRnVuYyA9IG51bGw7XG4gICAgICB2YXIgd3JhcHBlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKFJlYWN0UGVyZi5lbmFibGVNZWFzdXJlKSB7XG4gICAgICAgICAgaWYgKCFtZWFzdXJlZEZ1bmMpIHtcbiAgICAgICAgICAgIG1lYXN1cmVkRnVuYyA9IFJlYWN0UGVyZi5zdG9yZWRNZWFzdXJlKG9iak5hbWUsIGZuTmFtZSwgZnVuYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtZWFzdXJlZEZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICAgIHdyYXBwZXIuZGlzcGxheU5hbWUgPSBvYmpOYW1lICsgJ18nICsgZm5OYW1lO1xuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuICAgIHJldHVybiBmdW5jO1xuICB9LFxuXG4gIGluamVjdGlvbjoge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IG1lYXN1cmVcbiAgICAgKi9cbiAgICBpbmplY3RNZWFzdXJlOiBmdW5jdGlvbiAobWVhc3VyZSkge1xuICAgICAgUmVhY3RQZXJmLnN0b3JlZE1lYXN1cmUgPSBtZWFzdXJlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBTaW1wbHkgcGFzc2VzIHRocm91Z2ggdGhlIG1lYXN1cmVkIGZ1bmN0aW9uLCB3aXRob3V0IG1lYXN1cmluZyBpdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gb2JqTmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IGZuTmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gZnVuY1xuICogQHJldHVybiB7ZnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIF9ub01lYXN1cmUob2JqTmFtZSwgZm5OYW1lLCBmdW5jKSB7XG4gIHJldHVybiBmdW5jO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0UGVyZjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXNcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcyA9IHt9O1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcyA9IHtcbiAgICBwcm9wOiAncHJvcCcsXG4gICAgY29udGV4dDogJ2NvbnRleHQnLFxuICAgIGNoaWxkQ29udGV4dDogJ2NoaWxkIGNvbnRleHQnXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnNcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBrZXlNaXJyb3IgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlNaXJyb3InKTtcblxudmFyIFJlYWN0UHJvcFR5cGVMb2NhdGlvbnMgPSBrZXlNaXJyb3Ioe1xuICBwcm9wOiBudWxsLFxuICBjb250ZXh0OiBudWxsLFxuICBjaGlsZENvbnRleHQ6IG51bGxcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0UHJvcFR5cGVMb2NhdGlvbnM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0UHJvcFR5cGVzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RFbGVtZW50ID0gcmVxdWlyZSgnLi9SZWFjdEVsZW1lbnQnKTtcbnZhciBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lcyA9IHJlcXVpcmUoJy4vUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXMnKTtcblxudmFyIGVtcHR5RnVuY3Rpb24gPSByZXF1aXJlKCdmYmpzL2xpYi9lbXB0eUZ1bmN0aW9uJyk7XG52YXIgZ2V0SXRlcmF0b3JGbiA9IHJlcXVpcmUoJy4vZ2V0SXRlcmF0b3JGbicpO1xuXG4vKipcbiAqIENvbGxlY3Rpb24gb2YgbWV0aG9kcyB0aGF0IGFsbG93IGRlY2xhcmF0aW9uIGFuZCB2YWxpZGF0aW9uIG9mIHByb3BzIHRoYXQgYXJlXG4gKiBzdXBwbGllZCB0byBSZWFjdCBjb21wb25lbnRzLiBFeGFtcGxlIHVzYWdlOlxuICpcbiAqICAgdmFyIFByb3BzID0gcmVxdWlyZSgnUmVhY3RQcm9wVHlwZXMnKTtcbiAqICAgdmFyIE15QXJ0aWNsZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAqICAgICBwcm9wVHlwZXM6IHtcbiAqICAgICAgIC8vIEFuIG9wdGlvbmFsIHN0cmluZyBwcm9wIG5hbWVkIFwiZGVzY3JpcHRpb25cIi5cbiAqICAgICAgIGRlc2NyaXB0aW9uOiBQcm9wcy5zdHJpbmcsXG4gKlxuICogICAgICAgLy8gQSByZXF1aXJlZCBlbnVtIHByb3AgbmFtZWQgXCJjYXRlZ29yeVwiLlxuICogICAgICAgY2F0ZWdvcnk6IFByb3BzLm9uZU9mKFsnTmV3cycsJ1Bob3RvcyddKS5pc1JlcXVpcmVkLFxuICpcbiAqICAgICAgIC8vIEEgcHJvcCBuYW1lZCBcImRpYWxvZ1wiIHRoYXQgcmVxdWlyZXMgYW4gaW5zdGFuY2Ugb2YgRGlhbG9nLlxuICogICAgICAgZGlhbG9nOiBQcm9wcy5pbnN0YW5jZU9mKERpYWxvZykuaXNSZXF1aXJlZFxuICogICAgIH0sXG4gKiAgICAgcmVuZGVyOiBmdW5jdGlvbigpIHsgLi4uIH1cbiAqICAgfSk7XG4gKlxuICogQSBtb3JlIGZvcm1hbCBzcGVjaWZpY2F0aW9uIG9mIGhvdyB0aGVzZSBtZXRob2RzIGFyZSB1c2VkOlxuICpcbiAqICAgdHlwZSA6PSBhcnJheXxib29sfGZ1bmN8b2JqZWN0fG51bWJlcnxzdHJpbmd8b25lT2YoWy4uLl0pfGluc3RhbmNlT2YoLi4uKVxuICogICBkZWNsIDo9IFJlYWN0UHJvcFR5cGVzLnt0eXBlfSguaXNSZXF1aXJlZCk/XG4gKlxuICogRWFjaCBhbmQgZXZlcnkgZGVjbGFyYXRpb24gcHJvZHVjZXMgYSBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZS4gVGhpc1xuICogYWxsb3dzIHRoZSBjcmVhdGlvbiBvZiBjdXN0b20gdmFsaWRhdGlvbiBmdW5jdGlvbnMuIEZvciBleGFtcGxlOlxuICpcbiAqICB2YXIgTXlMaW5rID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICogICAgcHJvcFR5cGVzOiB7XG4gKiAgICAgIC8vIEFuIG9wdGlvbmFsIHN0cmluZyBvciBVUkkgcHJvcCBuYW1lZCBcImhyZWZcIi5cbiAqICAgICAgaHJlZjogZnVuY3Rpb24ocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gKiAgICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAqICAgICAgICBpZiAocHJvcFZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHByb3BWYWx1ZSAhPT0gJ3N0cmluZycgJiZcbiAqICAgICAgICAgICAgIShwcm9wVmFsdWUgaW5zdGFuY2VvZiBVUkkpKSB7XG4gKiAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKFxuICogICAgICAgICAgICAnRXhwZWN0ZWQgYSBzdHJpbmcgb3IgYW4gVVJJIGZvciAnICsgcHJvcE5hbWUgKyAnIGluICcgK1xuICogICAgICAgICAgICBjb21wb25lbnROYW1lXG4gKiAgICAgICAgICApO1xuICogICAgICAgIH1cbiAqICAgICAgfVxuICogICAgfSxcbiAqICAgIHJlbmRlcjogZnVuY3Rpb24oKSB7Li4ufVxuICogIH0pO1xuICpcbiAqIEBpbnRlcm5hbFxuICovXG5cbnZhciBBTk9OWU1PVVMgPSAnPDxhbm9ueW1vdXM+Pic7XG5cbnZhciBSZWFjdFByb3BUeXBlcyA9IHtcbiAgYXJyYXk6IGNyZWF0ZVByaW1pdGl2ZVR5cGVDaGVja2VyKCdhcnJheScpLFxuICBib29sOiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignYm9vbGVhbicpLFxuICBmdW5jOiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignZnVuY3Rpb24nKSxcbiAgbnVtYmVyOiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignbnVtYmVyJyksXG4gIG9iamVjdDogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ29iamVjdCcpLFxuICBzdHJpbmc6IGNyZWF0ZVByaW1pdGl2ZVR5cGVDaGVja2VyKCdzdHJpbmcnKSxcblxuICBhbnk6IGNyZWF0ZUFueVR5cGVDaGVja2VyKCksXG4gIGFycmF5T2Y6IGNyZWF0ZUFycmF5T2ZUeXBlQ2hlY2tlcixcbiAgZWxlbWVudDogY3JlYXRlRWxlbWVudFR5cGVDaGVja2VyKCksXG4gIGluc3RhbmNlT2Y6IGNyZWF0ZUluc3RhbmNlVHlwZUNoZWNrZXIsXG4gIG5vZGU6IGNyZWF0ZU5vZGVDaGVja2VyKCksXG4gIG9iamVjdE9mOiBjcmVhdGVPYmplY3RPZlR5cGVDaGVja2VyLFxuICBvbmVPZjogY3JlYXRlRW51bVR5cGVDaGVja2VyLFxuICBvbmVPZlR5cGU6IGNyZWF0ZVVuaW9uVHlwZUNoZWNrZXIsXG4gIHNoYXBlOiBjcmVhdGVTaGFwZVR5cGVDaGVja2VyXG59O1xuXG5mdW5jdGlvbiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSkge1xuICBmdW5jdGlvbiBjaGVja1R5cGUoaXNSZXF1aXJlZCwgcHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgY29tcG9uZW50TmFtZSA9IGNvbXBvbmVudE5hbWUgfHwgQU5PTllNT1VTO1xuICAgIHByb3BGdWxsTmFtZSA9IHByb3BGdWxsTmFtZSB8fCBwcm9wTmFtZTtcbiAgICBpZiAocHJvcHNbcHJvcE5hbWVdID09IG51bGwpIHtcbiAgICAgIHZhciBsb2NhdGlvbk5hbWUgPSBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lc1tsb2NhdGlvbl07XG4gICAgICBpZiAoaXNSZXF1aXJlZCkge1xuICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdSZXF1aXJlZCAnICsgbG9jYXRpb25OYW1lICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIHdhcyBub3Qgc3BlY2lmaWVkIGluICcgKyAoJ2AnICsgY29tcG9uZW50TmFtZSArICdgLicpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKTtcbiAgICB9XG4gIH1cblxuICB2YXIgY2hhaW5lZENoZWNrVHlwZSA9IGNoZWNrVHlwZS5iaW5kKG51bGwsIGZhbHNlKTtcbiAgY2hhaW5lZENoZWNrVHlwZS5pc1JlcXVpcmVkID0gY2hlY2tUeXBlLmJpbmQobnVsbCwgdHJ1ZSk7XG5cbiAgcmV0dXJuIGNoYWluZWRDaGVja1R5cGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVByaW1pdGl2ZVR5cGVDaGVja2VyKGV4cGVjdGVkVHlwZSkge1xuICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgaWYgKHByb3BUeXBlICE9PSBleHBlY3RlZFR5cGUpIHtcbiAgICAgIHZhciBsb2NhdGlvbk5hbWUgPSBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lc1tsb2NhdGlvbl07XG4gICAgICAvLyBgcHJvcFZhbHVlYCBiZWluZyBpbnN0YW5jZSBvZiwgc2F5LCBkYXRlL3JlZ2V4cCwgcGFzcyB0aGUgJ29iamVjdCdcbiAgICAgIC8vIGNoZWNrLCBidXQgd2UgY2FuIG9mZmVyIGEgbW9yZSBwcmVjaXNlIGVycm9yIG1lc3NhZ2UgaGVyZSByYXRoZXIgdGhhblxuICAgICAgLy8gJ29mIHR5cGUgYG9iamVjdGAnLlxuICAgICAgdmFyIHByZWNpc2VUeXBlID0gZ2V0UHJlY2lzZVR5cGUocHJvcFZhbHVlKTtcblxuICAgICAgcmV0dXJuIG5ldyBFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb25OYW1lICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgJyArICgnYCcgKyBwcmVjaXNlVHlwZSArICdgIHN1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCAnKSArICgnYCcgKyBleHBlY3RlZFR5cGUgKyAnYC4nKSk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUFueVR5cGVDaGVja2VyKCkge1xuICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIoZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJucyhudWxsKSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUFycmF5T2ZUeXBlQ2hlY2tlcih0eXBlQ2hlY2tlcikge1xuICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9wVmFsdWUpKSB7XG4gICAgICB2YXIgbG9jYXRpb25OYW1lID0gUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXNbbG9jYXRpb25dO1xuICAgICAgdmFyIHByb3BUeXBlID0gZ2V0UHJvcFR5cGUocHJvcFZhbHVlKTtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uTmFtZSArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgcHJvcFR5cGUgKyAnYCBzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYW4gYXJyYXkuJykpO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BWYWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGVycm9yID0gdHlwZUNoZWNrZXIocHJvcFZhbHVlLCBpLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lICsgJ1snICsgaSArICddJywgJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJyk7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRUeXBlQ2hlY2tlcigpIHtcbiAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgaWYgKCFSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQocHJvcHNbcHJvcE5hbWVdKSkge1xuICAgICAgdmFyIGxvY2F0aW9uTmFtZSA9IFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzW2xvY2F0aW9uXTtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uTmFtZSArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBzdXBwbGllZCB0byAnICsgKCdgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYSBzaW5nbGUgUmVhY3RFbGVtZW50LicpKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2VUeXBlQ2hlY2tlcihleHBlY3RlZENsYXNzKSB7XG4gIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgIGlmICghKHByb3BzW3Byb3BOYW1lXSBpbnN0YW5jZW9mIGV4cGVjdGVkQ2xhc3MpKSB7XG4gICAgICB2YXIgbG9jYXRpb25OYW1lID0gUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXNbbG9jYXRpb25dO1xuICAgICAgdmFyIGV4cGVjdGVkQ2xhc3NOYW1lID0gZXhwZWN0ZWRDbGFzcy5uYW1lIHx8IEFOT05ZTU9VUztcbiAgICAgIHZhciBhY3R1YWxDbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocHJvcHNbcHJvcE5hbWVdKTtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uTmFtZSArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgYWN0dWFsQ2xhc3NOYW1lICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkICcpICsgKCdpbnN0YW5jZSBvZiBgJyArIGV4cGVjdGVkQ2xhc3NOYW1lICsgJ2AuJykpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIodmFsaWRhdGUpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVFbnVtVHlwZUNoZWNrZXIoZXhwZWN0ZWRWYWx1ZXMpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGV4cGVjdGVkVmFsdWVzKSkge1xuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IHN1cHBsaWVkIHRvIG9uZU9mLCBleHBlY3RlZCBhbiBpbnN0YW5jZSBvZiBhcnJheS4nKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgIHZhciBwcm9wVmFsdWUgPSBwcm9wc1twcm9wTmFtZV07XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHBlY3RlZFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHByb3BWYWx1ZSA9PT0gZXhwZWN0ZWRWYWx1ZXNbaV0pIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGxvY2F0aW9uTmFtZSA9IFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzW2xvY2F0aW9uXTtcbiAgICB2YXIgdmFsdWVzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWRWYWx1ZXMpO1xuICAgIHJldHVybiBuZXcgRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uTmFtZSArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB2YWx1ZSBgJyArIHByb3BWYWx1ZSArICdgICcgKyAoJ3N1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBvbmUgb2YgJyArIHZhbHVlc1N0cmluZyArICcuJykpO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9iamVjdE9mVHlwZUNoZWNrZXIodHlwZUNoZWNrZXIpIHtcbiAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgIGlmIChwcm9wVHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHZhciBsb2NhdGlvbk5hbWUgPSBSZWFjdFByb3BUeXBlTG9jYXRpb25OYW1lc1tsb2NhdGlvbl07XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbk5hbWUgKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgdHlwZSAnICsgKCdgJyArIHByb3BUeXBlICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkIGFuIG9iamVjdC4nKSk7XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiBwcm9wVmFsdWUpIHtcbiAgICAgIGlmIChwcm9wVmFsdWUuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICB2YXIgZXJyb3IgPSB0eXBlQ2hlY2tlcihwcm9wVmFsdWUsIGtleSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSArICcuJyArIGtleSwgJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJyk7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVVuaW9uVHlwZUNoZWNrZXIoYXJyYXlPZlR5cGVDaGVja2Vycykge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXlPZlR5cGVDaGVja2VycykpIHtcbiAgICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudCBzdXBwbGllZCB0byBvbmVPZlR5cGUsIGV4cGVjdGVkIGFuIGluc3RhbmNlIG9mIGFycmF5LicpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdmFsaWRhdGUocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheU9mVHlwZUNoZWNrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hlY2tlciA9IGFycmF5T2ZUeXBlQ2hlY2tlcnNbaV07XG4gICAgICBpZiAoY2hlY2tlcihwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUsICdTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRCcpID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGxvY2F0aW9uTmFtZSA9IFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzW2xvY2F0aW9uXTtcbiAgICByZXR1cm4gbmV3IEVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbk5hbWUgKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agc3VwcGxpZWQgdG8gJyArICgnYCcgKyBjb21wb25lbnROYW1lICsgJ2AuJykpO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU5vZGVDaGVja2VyKCkge1xuICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICBpZiAoIWlzTm9kZShwcm9wc1twcm9wTmFtZV0pKSB7XG4gICAgICB2YXIgbG9jYXRpb25OYW1lID0gUmVhY3RQcm9wVHlwZUxvY2F0aW9uTmFtZXNbbG9jYXRpb25dO1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb25OYW1lICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIHN1cHBsaWVkIHRvICcgKyAoJ2AnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBhIFJlYWN0Tm9kZS4nKSk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNoYXBlVHlwZUNoZWNrZXIoc2hhcGVUeXBlcykge1xuICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgaWYgKHByb3BUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGxvY2F0aW9uTmFtZSA9IFJlYWN0UHJvcFR5cGVMb2NhdGlvbk5hbWVzW2xvY2F0aW9uXTtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uTmFtZSArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlIGAnICsgcHJvcFR5cGUgKyAnYCAnICsgKCdzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYG9iamVjdGAuJykpO1xuICAgIH1cbiAgICBmb3IgKHZhciBrZXkgaW4gc2hhcGVUeXBlcykge1xuICAgICAgdmFyIGNoZWNrZXIgPSBzaGFwZVR5cGVzW2tleV07XG4gICAgICBpZiAoIWNoZWNrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB2YXIgZXJyb3IgPSBjaGVja2VyKHByb3BWYWx1ZSwga2V5LCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lICsgJy4nICsga2V5LCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZShwcm9wVmFsdWUpIHtcbiAgc3dpdGNoICh0eXBlb2YgcHJvcFZhbHVlKSB7XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiAhcHJvcFZhbHVlO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShwcm9wVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBwcm9wVmFsdWUuZXZlcnkoaXNOb2RlKTtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9wVmFsdWUgPT09IG51bGwgfHwgUmVhY3RFbGVtZW50LmlzVmFsaWRFbGVtZW50KHByb3BWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBpdGVyYXRvckZuID0gZ2V0SXRlcmF0b3JGbihwcm9wVmFsdWUpO1xuICAgICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAgICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKHByb3BWYWx1ZSk7XG4gICAgICAgIHZhciBzdGVwO1xuICAgICAgICBpZiAoaXRlcmF0b3JGbiAhPT0gcHJvcFZhbHVlLmVudHJpZXMpIHtcbiAgICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgICBpZiAoIWlzTm9kZShzdGVwLnZhbHVlKSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEl0ZXJhdG9yIHdpbGwgcHJvdmlkZSBlbnRyeSBbayx2XSB0dXBsZXMgcmF0aGVyIHRoYW4gdmFsdWVzLlxuICAgICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgaWYgKCFpc05vZGUoZW50cnlbMV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLy8gRXF1aXZhbGVudCBvZiBgdHlwZW9mYCBidXQgd2l0aCBzcGVjaWFsIGhhbmRsaW5nIGZvciBhcnJheSBhbmQgcmVnZXhwLlxuZnVuY3Rpb24gZ2V0UHJvcFR5cGUocHJvcFZhbHVlKSB7XG4gIHZhciBwcm9wVHlwZSA9IHR5cGVvZiBwcm9wVmFsdWU7XG4gIGlmIChBcnJheS5pc0FycmF5KHByb3BWYWx1ZSkpIHtcbiAgICByZXR1cm4gJ2FycmF5JztcbiAgfVxuICBpZiAocHJvcFZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgLy8gT2xkIHdlYmtpdHMgKGF0IGxlYXN0IHVudGlsIEFuZHJvaWQgNC4wKSByZXR1cm4gJ2Z1bmN0aW9uJyByYXRoZXIgdGhhblxuICAgIC8vICdvYmplY3QnIGZvciB0eXBlb2YgYSBSZWdFeHAuIFdlJ2xsIG5vcm1hbGl6ZSB0aGlzIGhlcmUgc28gdGhhdCAvYmxhL1xuICAgIC8vIHBhc3NlcyBQcm9wVHlwZXMub2JqZWN0LlxuICAgIHJldHVybiAnb2JqZWN0JztcbiAgfVxuICByZXR1cm4gcHJvcFR5cGU7XG59XG5cbi8vIFRoaXMgaGFuZGxlcyBtb3JlIHR5cGVzIHRoYW4gYGdldFByb3BUeXBlYC4gT25seSB1c2VkIGZvciBlcnJvciBtZXNzYWdlcy5cbi8vIFNlZSBgY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXJgLlxuZnVuY3Rpb24gZ2V0UHJlY2lzZVR5cGUocHJvcFZhbHVlKSB7XG4gIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gIGlmIChwcm9wVHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAocHJvcFZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgcmV0dXJuICdkYXRlJztcbiAgICB9IGVsc2UgaWYgKHByb3BWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgcmV0dXJuICdyZWdleHAnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcHJvcFR5cGU7XG59XG5cbi8vIFJldHVybnMgY2xhc3MgbmFtZSBvZiB0aGUgb2JqZWN0LCBpZiBhbnkuXG5mdW5jdGlvbiBnZXRDbGFzc05hbWUocHJvcFZhbHVlKSB7XG4gIGlmICghcHJvcFZhbHVlLmNvbnN0cnVjdG9yIHx8ICFwcm9wVmFsdWUuY29uc3RydWN0b3IubmFtZSkge1xuICAgIHJldHVybiAnPDxhbm9ueW1vdXM+Pic7XG4gIH1cbiAgcmV0dXJuIHByb3BWYWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0UHJvcFR5cGVzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIENhbGxiYWNrUXVldWUgPSByZXF1aXJlKCcuL0NhbGxiYWNrUXVldWUnKTtcbnZhciBQb29sZWRDbGFzcyA9IHJlcXVpcmUoJy4vUG9vbGVkQ2xhc3MnKTtcbnZhciBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL1JlYWN0QnJvd3NlckV2ZW50RW1pdHRlcicpO1xudmFyIFJlYWN0RE9NRmVhdHVyZUZsYWdzID0gcmVxdWlyZSgnLi9SZWFjdERPTUZlYXR1cmVGbGFncycpO1xudmFyIFJlYWN0SW5wdXRTZWxlY3Rpb24gPSByZXF1aXJlKCcuL1JlYWN0SW5wdXRTZWxlY3Rpb24nKTtcbnZhciBUcmFuc2FjdGlvbiA9IHJlcXVpcmUoJy4vVHJhbnNhY3Rpb24nKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCwgd2hlbiBwb3NzaWJsZSwgdGhlIHNlbGVjdGlvbiByYW5nZSAoY3VycmVudGx5IHNlbGVjdGVkIHRleHRcbiAqIGlucHV0KSBpcyBub3QgZGlzdHVyYmVkIGJ5IHBlcmZvcm1pbmcgdGhlIHRyYW5zYWN0aW9uLlxuICovXG52YXIgU0VMRUNUSU9OX1JFU1RPUkFUSU9OID0ge1xuICAvKipcbiAgICogQHJldHVybiB7U2VsZWN0aW9ufSBTZWxlY3Rpb24gaW5mb3JtYXRpb24uXG4gICAqL1xuICBpbml0aWFsaXplOiBSZWFjdElucHV0U2VsZWN0aW9uLmdldFNlbGVjdGlvbkluZm9ybWF0aW9uLFxuICAvKipcbiAgICogQHBhcmFtIHtTZWxlY3Rpb259IHNlbCBTZWxlY3Rpb24gaW5mb3JtYXRpb24gcmV0dXJuZWQgZnJvbSBgaW5pdGlhbGl6ZWAuXG4gICAqL1xuICBjbG9zZTogUmVhY3RJbnB1dFNlbGVjdGlvbi5yZXN0b3JlU2VsZWN0aW9uXG59O1xuXG4vKipcbiAqIFN1cHByZXNzZXMgZXZlbnRzIChibHVyL2ZvY3VzKSB0aGF0IGNvdWxkIGJlIGluYWR2ZXJ0ZW50bHkgZGlzcGF0Y2hlZCBkdWUgdG9cbiAqIGhpZ2ggbGV2ZWwgRE9NIG1hbmlwdWxhdGlvbnMgKGxpa2UgdGVtcG9yYXJpbHkgcmVtb3ZpbmcgYSB0ZXh0IGlucHV0IGZyb20gdGhlXG4gKiBET00pLlxuICovXG52YXIgRVZFTlRfU1VQUFJFU1NJT04gPSB7XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgZW5hYmxlZCBzdGF0dXMgb2YgYFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlcmAgYmVmb3JlXG4gICAqIHRoZSByZWNvbmNpbGlhdGlvbi5cbiAgICovXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY3VycmVudGx5RW5hYmxlZCA9IFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5pc0VuYWJsZWQoKTtcbiAgICBSZWFjdEJyb3dzZXJFdmVudEVtaXR0ZXIuc2V0RW5hYmxlZChmYWxzZSk7XG4gICAgcmV0dXJuIGN1cnJlbnRseUVuYWJsZWQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcHJldmlvdXNseUVuYWJsZWQgRW5hYmxlZCBzdGF0dXMgb2ZcbiAgICogICBgUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyYCBiZWZvcmUgdGhlIHJlY29uY2lsaWF0aW9uIG9jY3VycmVkLiBgY2xvc2VgXG4gICAqICAgcmVzdG9yZXMgdGhlIHByZXZpb3VzIHZhbHVlLlxuICAgKi9cbiAgY2xvc2U6IGZ1bmN0aW9uIChwcmV2aW91c2x5RW5hYmxlZCkge1xuICAgIFJlYWN0QnJvd3NlckV2ZW50RW1pdHRlci5zZXRFbmFibGVkKHByZXZpb3VzbHlFbmFibGVkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQcm92aWRlcyBhIHF1ZXVlIGZvciBjb2xsZWN0aW5nIGBjb21wb25lbnREaWRNb3VudGAgYW5kXG4gKiBgY29tcG9uZW50RGlkVXBkYXRlYCBjYWxsYmFja3MgZHVyaW5nIHRoZSB0aGUgdHJhbnNhY3Rpb24uXG4gKi9cbnZhciBPTl9ET01fUkVBRFlfUVVFVUVJTkcgPSB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgaW50ZXJuYWwgYG9uRE9NUmVhZHlgIHF1ZXVlLlxuICAgKi9cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVhY3RNb3VudFJlYWR5LnJlc2V0KCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEFmdGVyIERPTSBpcyBmbHVzaGVkLCBpbnZva2UgYWxsIHJlZ2lzdGVyZWQgYG9uRE9NUmVhZHlgIGNhbGxiYWNrcy5cbiAgICovXG4gIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZWFjdE1vdW50UmVhZHkubm90aWZ5QWxsKCk7XG4gIH1cbn07XG5cbi8qKlxuICogRXhlY3V0ZWQgd2l0aGluIHRoZSBzY29wZSBvZiB0aGUgYFRyYW5zYWN0aW9uYCBpbnN0YW5jZS4gQ29uc2lkZXIgdGhlc2UgYXNcbiAqIGJlaW5nIG1lbWJlciBtZXRob2RzLCBidXQgd2l0aCBhbiBpbXBsaWVkIG9yZGVyaW5nIHdoaWxlIGJlaW5nIGlzb2xhdGVkIGZyb21cbiAqIGVhY2ggb3RoZXIuXG4gKi9cbnZhciBUUkFOU0FDVElPTl9XUkFQUEVSUyA9IFtTRUxFQ1RJT05fUkVTVE9SQVRJT04sIEVWRU5UX1NVUFBSRVNTSU9OLCBPTl9ET01fUkVBRFlfUVVFVUVJTkddO1xuXG4vKipcbiAqIEN1cnJlbnRseTpcbiAqIC0gVGhlIG9yZGVyIHRoYXQgdGhlc2UgYXJlIGxpc3RlZCBpbiB0aGUgdHJhbnNhY3Rpb24gaXMgY3JpdGljYWw6XG4gKiAtIFN1cHByZXNzZXMgZXZlbnRzLlxuICogLSBSZXN0b3JlcyBzZWxlY3Rpb24gcmFuZ2UuXG4gKlxuICogRnV0dXJlOlxuICogLSBSZXN0b3JlIGRvY3VtZW50L292ZXJmbG93IHNjcm9sbCBwb3NpdGlvbnMgdGhhdCB3ZXJlIHVuaW50ZW50aW9uYWxseVxuICogICBtb2RpZmllZCB2aWEgRE9NIGluc2VydGlvbnMgYWJvdmUgdGhlIHRvcCB2aWV3cG9ydCBib3VuZGFyeS5cbiAqIC0gSW1wbGVtZW50L2ludGVncmF0ZSB3aXRoIGN1c3RvbWl6ZWQgY29uc3RyYWludCBiYXNlZCBsYXlvdXQgc3lzdGVtIGFuZCBrZWVwXG4gKiAgIHRyYWNrIG9mIHdoaWNoIGRpbWVuc2lvbnMgbXVzdCBiZSByZW1lYXN1cmVkLlxuICpcbiAqIEBjbGFzcyBSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uXG4gKi9cbmZ1bmN0aW9uIFJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24oZm9yY2VIVE1MKSB7XG4gIHRoaXMucmVpbml0aWFsaXplVHJhbnNhY3Rpb24oKTtcbiAgLy8gT25seSBzZXJ2ZXItc2lkZSByZW5kZXJpbmcgcmVhbGx5IG5lZWRzIHRoaXMgb3B0aW9uIChzZWVcbiAgLy8gYFJlYWN0U2VydmVyUmVuZGVyaW5nYCksIGJ1dCBzZXJ2ZXItc2lkZSB1c2VzXG4gIC8vIGBSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9uYCBpbnN0ZWFkLiBUaGlzIG9wdGlvbiBpcyBoZXJlIHNvIHRoYXQgaXQnc1xuICAvLyBhY2Nlc3NpYmxlIGFuZCBkZWZhdWx0cyB0byBmYWxzZSB3aGVuIGBSZWFjdERPTUNvbXBvbmVudGAgYW5kXG4gIC8vIGBSZWFjdFRleHRDb21wb25lbnRgIGNoZWNrcyBpdCBpbiBgbW91bnRDb21wb25lbnRgLmBcbiAgdGhpcy5yZW5kZXJUb1N0YXRpY01hcmt1cCA9IGZhbHNlO1xuICB0aGlzLnJlYWN0TW91bnRSZWFkeSA9IENhbGxiYWNrUXVldWUuZ2V0UG9vbGVkKG51bGwpO1xuICB0aGlzLnVzZUNyZWF0ZUVsZW1lbnQgPSAhZm9yY2VIVE1MICYmIFJlYWN0RE9NRmVhdHVyZUZsYWdzLnVzZUNyZWF0ZUVsZW1lbnQ7XG59XG5cbnZhciBNaXhpbiA9IHtcbiAgLyoqXG4gICAqIEBzZWUgVHJhbnNhY3Rpb25cbiAgICogQGFic3RyYWN0XG4gICAqIEBmaW5hbFxuICAgKiBAcmV0dXJuIHthcnJheTxvYmplY3Q+fSBMaXN0IG9mIG9wZXJhdGlvbiB3cmFwIHByb2NlZHVyZXMuXG4gICAqICAgVE9ETzogY29udmVydCB0byBhcnJheTxUcmFuc2FjdGlvbldyYXBwZXI+XG4gICAqL1xuICBnZXRUcmFuc2FjdGlvbldyYXBwZXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFRSQU5TQUNUSU9OX1dSQVBQRVJTO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9IFRoZSBxdWV1ZSB0byBjb2xsZWN0IGBvbkRPTVJlYWR5YCBjYWxsYmFja3Mgd2l0aC5cbiAgICovXG4gIGdldFJlYWN0TW91bnRSZWFkeTogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlYWN0TW91bnRSZWFkeTtcbiAgfSxcblxuICAvKipcbiAgICogYFBvb2xlZENsYXNzYCBsb29rcyBmb3IgdGhpcywgYW5kIHdpbGwgaW52b2tlIHRoaXMgYmVmb3JlIGFsbG93aW5nIHRoaXNcbiAgICogaW5zdGFuY2UgdG8gYmUgcmV1c2VkLlxuICAgKi9cbiAgZGVzdHJ1Y3RvcjogZnVuY3Rpb24gKCkge1xuICAgIENhbGxiYWNrUXVldWUucmVsZWFzZSh0aGlzLnJlYWN0TW91bnRSZWFkeSk7XG4gICAgdGhpcy5yZWFjdE1vdW50UmVhZHkgPSBudWxsO1xuICB9XG59O1xuXG5hc3NpZ24oUmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbi5wcm90b3R5cGUsIFRyYW5zYWN0aW9uLk1peGluLCBNaXhpbik7XG5cblBvb2xlZENsYXNzLmFkZFBvb2xpbmdUbyhSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uKTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdFJlY29uY2lsZXJcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFJlZiA9IHJlcXVpcmUoJy4vUmVhY3RSZWYnKTtcblxuLyoqXG4gKiBIZWxwZXIgdG8gY2FsbCBSZWFjdFJlZi5hdHRhY2hSZWZzIHdpdGggdGhpcyBjb21wb3NpdGUgY29tcG9uZW50LCBzcGxpdCBvdXRcbiAqIHRvIGF2b2lkIGFsbG9jYXRpb25zIGluIHRoZSB0cmFuc2FjdGlvbiBtb3VudC1yZWFkeSBxdWV1ZS5cbiAqL1xuZnVuY3Rpb24gYXR0YWNoUmVmcygpIHtcbiAgUmVhY3RSZWYuYXR0YWNoUmVmcyh0aGlzLCB0aGlzLl9jdXJyZW50RWxlbWVudCk7XG59XG5cbnZhciBSZWFjdFJlY29uY2lsZXIgPSB7XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBjb21wb25lbnQsIHJlbmRlcnMgbWFya3VwLCBhbmQgcmVnaXN0ZXJzIGV2ZW50IGxpc3RlbmVycy5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gaW50ZXJuYWxJbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9vdElEIERPTSBJRCBvZiB0aGUgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb258UmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHJldHVybiB7P3N0cmluZ30gUmVuZGVyZWQgbWFya3VwIHRvIGJlIGluc2VydGVkIGludG8gdGhlIERPTS5cbiAgICogQGZpbmFsXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgbW91bnRDb21wb25lbnQ6IGZ1bmN0aW9uIChpbnRlcm5hbEluc3RhbmNlLCByb290SUQsIHRyYW5zYWN0aW9uLCBjb250ZXh0KSB7XG4gICAgdmFyIG1hcmt1cCA9IGludGVybmFsSW5zdGFuY2UubW91bnRDb21wb25lbnQocm9vdElELCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG4gICAgaWYgKGludGVybmFsSW5zdGFuY2UuX2N1cnJlbnRFbGVtZW50ICYmIGludGVybmFsSW5zdGFuY2UuX2N1cnJlbnRFbGVtZW50LnJlZiAhPSBudWxsKSB7XG4gICAgICB0cmFuc2FjdGlvbi5nZXRSZWFjdE1vdW50UmVhZHkoKS5lbnF1ZXVlKGF0dGFjaFJlZnMsIGludGVybmFsSW5zdGFuY2UpO1xuICAgIH1cbiAgICByZXR1cm4gbWFya3VwO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWxlYXNlcyBhbnkgcmVzb3VyY2VzIGFsbG9jYXRlZCBieSBgbW91bnRDb21wb25lbnRgLlxuICAgKlxuICAgKiBAZmluYWxcbiAgICogQGludGVybmFsXG4gICAqL1xuICB1bm1vdW50Q29tcG9uZW50OiBmdW5jdGlvbiAoaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgIFJlYWN0UmVmLmRldGFjaFJlZnMoaW50ZXJuYWxJbnN0YW5jZSwgaW50ZXJuYWxJbnN0YW5jZS5fY3VycmVudEVsZW1lbnQpO1xuICAgIGludGVybmFsSW5zdGFuY2UudW5tb3VudENvbXBvbmVudCgpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYSBjb21wb25lbnQgdXNpbmcgYSBuZXcgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gaW50ZXJuYWxJbnN0YW5jZVxuICAgKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gbmV4dEVsZW1lbnRcbiAgICogQHBhcmFtIHtSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gY29udGV4dFxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHJlY2VpdmVDb21wb25lbnQ6IGZ1bmN0aW9uIChpbnRlcm5hbEluc3RhbmNlLCBuZXh0RWxlbWVudCwgdHJhbnNhY3Rpb24sIGNvbnRleHQpIHtcbiAgICB2YXIgcHJldkVsZW1lbnQgPSBpbnRlcm5hbEluc3RhbmNlLl9jdXJyZW50RWxlbWVudDtcblxuICAgIGlmIChuZXh0RWxlbWVudCA9PT0gcHJldkVsZW1lbnQgJiYgY29udGV4dCA9PT0gaW50ZXJuYWxJbnN0YW5jZS5fY29udGV4dCkge1xuICAgICAgLy8gU2luY2UgZWxlbWVudHMgYXJlIGltbXV0YWJsZSBhZnRlciB0aGUgb3duZXIgaXMgcmVuZGVyZWQsXG4gICAgICAvLyB3ZSBjYW4gZG8gYSBjaGVhcCBpZGVudGl0eSBjb21wYXJlIGhlcmUgdG8gZGV0ZXJtaW5lIGlmIHRoaXMgaXMgYVxuICAgICAgLy8gc3VwZXJmbHVvdXMgcmVjb25jaWxlLiBJdCdzIHBvc3NpYmxlIGZvciBzdGF0ZSB0byBiZSBtdXRhYmxlIGJ1dCBzdWNoXG4gICAgICAvLyBjaGFuZ2Ugc2hvdWxkIHRyaWdnZXIgYW4gdXBkYXRlIG9mIHRoZSBvd25lciB3aGljaCB3b3VsZCByZWNyZWF0ZVxuICAgICAgLy8gdGhlIGVsZW1lbnQuIFdlIGV4cGxpY2l0bHkgY2hlY2sgZm9yIHRoZSBleGlzdGVuY2Ugb2YgYW4gb3duZXIgc2luY2VcbiAgICAgIC8vIGl0J3MgcG9zc2libGUgZm9yIGFuIGVsZW1lbnQgY3JlYXRlZCBvdXRzaWRlIGEgY29tcG9zaXRlIHRvIGJlXG4gICAgICAvLyBkZWVwbHkgbXV0YXRlZCBhbmQgcmV1c2VkLlxuXG4gICAgICAvLyBUT0RPOiBCYWlsaW5nIG91dCBlYXJseSBpcyBqdXN0IGEgcGVyZiBvcHRpbWl6YXRpb24gcmlnaHQ/XG4gICAgICAvLyBUT0RPOiBSZW1vdmluZyB0aGUgcmV0dXJuIHN0YXRlbWVudCBzaG91bGQgYWZmZWN0IGNvcnJlY3RuZXNzP1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByZWZzQ2hhbmdlZCA9IFJlYWN0UmVmLnNob3VsZFVwZGF0ZVJlZnMocHJldkVsZW1lbnQsIG5leHRFbGVtZW50KTtcblxuICAgIGlmIChyZWZzQ2hhbmdlZCkge1xuICAgICAgUmVhY3RSZWYuZGV0YWNoUmVmcyhpbnRlcm5hbEluc3RhbmNlLCBwcmV2RWxlbWVudCk7XG4gICAgfVxuXG4gICAgaW50ZXJuYWxJbnN0YW5jZS5yZWNlaXZlQ29tcG9uZW50KG5leHRFbGVtZW50LCB0cmFuc2FjdGlvbiwgY29udGV4dCk7XG5cbiAgICBpZiAocmVmc0NoYW5nZWQgJiYgaW50ZXJuYWxJbnN0YW5jZS5fY3VycmVudEVsZW1lbnQgJiYgaW50ZXJuYWxJbnN0YW5jZS5fY3VycmVudEVsZW1lbnQucmVmICE9IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0aW9uLmdldFJlYWN0TW91bnRSZWFkeSgpLmVucXVldWUoYXR0YWNoUmVmcywgaW50ZXJuYWxJbnN0YW5jZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBGbHVzaCBhbnkgZGlydHkgY2hhbmdlcyBpbiBhIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENvbXBvbmVudH0gaW50ZXJuYWxJbnN0YW5jZVxuICAgKiBAcGFyYW0ge1JlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcGVyZm9ybVVwZGF0ZUlmTmVjZXNzYXJ5OiBmdW5jdGlvbiAoaW50ZXJuYWxJbnN0YW5jZSwgdHJhbnNhY3Rpb24pIHtcbiAgICBpbnRlcm5hbEluc3RhbmNlLnBlcmZvcm1VcGRhdGVJZk5lY2Vzc2FyeSh0cmFuc2FjdGlvbik7XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFJlY29uY2lsZXI7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0UmVmXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RPd25lciA9IHJlcXVpcmUoJy4vUmVhY3RPd25lcicpO1xuXG52YXIgUmVhY3RSZWYgPSB7fTtcblxuZnVuY3Rpb24gYXR0YWNoUmVmKHJlZiwgY29tcG9uZW50LCBvd25lcikge1xuICBpZiAodHlwZW9mIHJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJlZihjb21wb25lbnQuZ2V0UHVibGljSW5zdGFuY2UoKSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTGVnYWN5IHJlZlxuICAgIFJlYWN0T3duZXIuYWRkQ29tcG9uZW50QXNSZWZUbyhjb21wb25lbnQsIHJlZiwgb3duZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRldGFjaFJlZihyZWYsIGNvbXBvbmVudCwgb3duZXIpIHtcbiAgaWYgKHR5cGVvZiByZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZWYobnVsbCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTGVnYWN5IHJlZlxuICAgIFJlYWN0T3duZXIucmVtb3ZlQ29tcG9uZW50QXNSZWZGcm9tKGNvbXBvbmVudCwgcmVmLCBvd25lcik7XG4gIH1cbn1cblxuUmVhY3RSZWYuYXR0YWNoUmVmcyA9IGZ1bmN0aW9uIChpbnN0YW5jZSwgZWxlbWVudCkge1xuICBpZiAoZWxlbWVudCA9PT0gbnVsbCB8fCBlbGVtZW50ID09PSBmYWxzZSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgcmVmID0gZWxlbWVudC5yZWY7XG4gIGlmIChyZWYgIT0gbnVsbCkge1xuICAgIGF0dGFjaFJlZihyZWYsIGluc3RhbmNlLCBlbGVtZW50Ll9vd25lcik7XG4gIH1cbn07XG5cblJlYWN0UmVmLnNob3VsZFVwZGF0ZVJlZnMgPSBmdW5jdGlvbiAocHJldkVsZW1lbnQsIG5leHRFbGVtZW50KSB7XG4gIC8vIElmIGVpdGhlciB0aGUgb3duZXIgb3IgYSBgcmVmYCBoYXMgY2hhbmdlZCwgbWFrZSBzdXJlIHRoZSBuZXdlc3Qgb3duZXJcbiAgLy8gaGFzIHN0b3JlZCBhIHJlZmVyZW5jZSB0byBgdGhpc2AsIGFuZCB0aGUgcHJldmlvdXMgb3duZXIgKGlmIGRpZmZlcmVudClcbiAgLy8gaGFzIGZvcmdvdHRlbiB0aGUgcmVmZXJlbmNlIHRvIGB0aGlzYC4gV2UgdXNlIHRoZSBlbGVtZW50IGluc3RlYWRcbiAgLy8gb2YgdGhlIHB1YmxpYyB0aGlzLnByb3BzIGJlY2F1c2UgdGhlIHBvc3QgcHJvY2Vzc2luZyBjYW5ub3QgZGV0ZXJtaW5lXG4gIC8vIGEgcmVmLiBUaGUgcmVmIGNvbmNlcHR1YWxseSBsaXZlcyBvbiB0aGUgZWxlbWVudC5cblxuICAvLyBUT0RPOiBTaG91bGQgdGhpcyBldmVuIGJlIHBvc3NpYmxlPyBUaGUgb3duZXIgY2Fubm90IGNoYW5nZSBiZWNhdXNlXG4gIC8vIGl0J3MgZm9yYmlkZGVuIGJ5IHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50LiBUaGUgcmVmIGNhbiBjaGFuZ2VcbiAgLy8gaWYgeW91IHN3YXAgdGhlIGtleXMgb2YgYnV0IG5vdCB0aGUgcmVmcy4gUmVjb25zaWRlciB3aGVyZSB0aGlzIGNoZWNrXG4gIC8vIGlzIG1hZGUuIEl0IHByb2JhYmx5IGJlbG9uZ3Mgd2hlcmUgdGhlIGtleSBjaGVja2luZyBhbmRcbiAgLy8gaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudCBpcyBkb25lLlxuXG4gIHZhciBwcmV2RW1wdHkgPSBwcmV2RWxlbWVudCA9PT0gbnVsbCB8fCBwcmV2RWxlbWVudCA9PT0gZmFsc2U7XG4gIHZhciBuZXh0RW1wdHkgPSBuZXh0RWxlbWVudCA9PT0gbnVsbCB8fCBuZXh0RWxlbWVudCA9PT0gZmFsc2U7XG5cbiAgcmV0dXJuKFxuICAgIC8vIFRoaXMgaGFzIGEgZmV3IGZhbHNlIHBvc2l0aXZlcyB3L3IvdCBlbXB0eSBjb21wb25lbnRzLlxuICAgIHByZXZFbXB0eSB8fCBuZXh0RW1wdHkgfHwgbmV4dEVsZW1lbnQuX293bmVyICE9PSBwcmV2RWxlbWVudC5fb3duZXIgfHwgbmV4dEVsZW1lbnQucmVmICE9PSBwcmV2RWxlbWVudC5yZWZcbiAgKTtcbn07XG5cblJlYWN0UmVmLmRldGFjaFJlZnMgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQgPT09IG51bGwgfHwgZWxlbWVudCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIHJlZiA9IGVsZW1lbnQucmVmO1xuICBpZiAocmVmICE9IG51bGwpIHtcbiAgICBkZXRhY2hSZWYocmVmLCBpbnN0YW5jZSwgZWxlbWVudC5fb3duZXIpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0UmVmOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBSZWFjdFJvb3RJbmRleFxuICogQHR5cGVjaGVja3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFJvb3RJbmRleEluamVjdGlvbiA9IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IF9jcmVhdGVSZWFjdFJvb3RJbmRleFxuICAgKi9cbiAgaW5qZWN0Q3JlYXRlUmVhY3RSb290SW5kZXg6IGZ1bmN0aW9uIChfY3JlYXRlUmVhY3RSb290SW5kZXgpIHtcbiAgICBSZWFjdFJvb3RJbmRleC5jcmVhdGVSZWFjdFJvb3RJbmRleCA9IF9jcmVhdGVSZWFjdFJvb3RJbmRleDtcbiAgfVxufTtcblxudmFyIFJlYWN0Um9vdEluZGV4ID0ge1xuICBjcmVhdGVSZWFjdFJvb3RJbmRleDogbnVsbCxcbiAgaW5qZWN0aW9uOiBSZWFjdFJvb3RJbmRleEluamVjdGlvblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFJvb3RJbmRleDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RTZXJ2ZXJCYXRjaGluZ1N0cmF0ZWd5XG4gKiBAdHlwZWNoZWNrc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0U2VydmVyQmF0Y2hpbmdTdHJhdGVneSA9IHtcbiAgaXNCYXRjaGluZ1VwZGF0ZXM6IGZhbHNlLFxuICBiYXRjaGVkVXBkYXRlczogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaGVyZS4gRHVyaW5nIHRoZSBzZXJ2ZXIgcmVuZGVyaW5nIHdlIGRvbid0IHdhbnQgdG9cbiAgICAvLyBzY2hlZHVsZSBhbnkgdXBkYXRlcy4gV2Ugd2lsbCBzaW1wbHkgaWdub3JlIHRoZW0uXG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3RTZXJ2ZXJCYXRjaGluZ1N0cmF0ZWd5OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RTZXJ2ZXJSZW5kZXJpbmdcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneSA9IHJlcXVpcmUoJy4vUmVhY3REZWZhdWx0QmF0Y2hpbmdTdHJhdGVneScpO1xudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG52YXIgUmVhY3RJbnN0YW5jZUhhbmRsZXMgPSByZXF1aXJlKCcuL1JlYWN0SW5zdGFuY2VIYW5kbGVzJyk7XG52YXIgUmVhY3RNYXJrdXBDaGVja3N1bSA9IHJlcXVpcmUoJy4vUmVhY3RNYXJrdXBDaGVja3N1bScpO1xudmFyIFJlYWN0U2VydmVyQmF0Y2hpbmdTdHJhdGVneSA9IHJlcXVpcmUoJy4vUmVhY3RTZXJ2ZXJCYXRjaGluZ1N0cmF0ZWd5Jyk7XG52YXIgUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbiA9IHJlcXVpcmUoJy4vUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbicpO1xudmFyIFJlYWN0VXBkYXRlcyA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVzJyk7XG5cbnZhciBlbXB0eU9iamVjdCA9IHJlcXVpcmUoJ2ZianMvbGliL2VtcHR5T2JqZWN0Jyk7XG52YXIgaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudCA9IHJlcXVpcmUoJy4vaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudCcpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xuXG4vKipcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBIVE1MIG1hcmt1cFxuICovXG5mdW5jdGlvbiByZW5kZXJUb1N0cmluZyhlbGVtZW50KSB7XG4gICFSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQoZWxlbWVudCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAncmVuZGVyVG9TdHJpbmcoKTogWW91IG11c3QgcGFzcyBhIHZhbGlkIFJlYWN0RWxlbWVudC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgdmFyIHRyYW5zYWN0aW9uO1xuICB0cnkge1xuICAgIFJlYWN0VXBkYXRlcy5pbmplY3Rpb24uaW5qZWN0QmF0Y2hpbmdTdHJhdGVneShSZWFjdFNlcnZlckJhdGNoaW5nU3RyYXRlZ3kpO1xuXG4gICAgdmFyIGlkID0gUmVhY3RJbnN0YW5jZUhhbmRsZXMuY3JlYXRlUmVhY3RSb290SUQoKTtcbiAgICB0cmFuc2FjdGlvbiA9IFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb24uZ2V0UG9vbGVkKGZhbHNlKTtcblxuICAgIHJldHVybiB0cmFuc2FjdGlvbi5wZXJmb3JtKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjb21wb25lbnRJbnN0YW5jZSA9IGluc3RhbnRpYXRlUmVhY3RDb21wb25lbnQoZWxlbWVudCwgbnVsbCk7XG4gICAgICB2YXIgbWFya3VwID0gY29tcG9uZW50SW5zdGFuY2UubW91bnRDb21wb25lbnQoaWQsIHRyYW5zYWN0aW9uLCBlbXB0eU9iamVjdCk7XG4gICAgICByZXR1cm4gUmVhY3RNYXJrdXBDaGVja3N1bS5hZGRDaGVja3N1bVRvTWFya3VwKG1hcmt1cCk7XG4gICAgfSwgbnVsbCk7XG4gIH0gZmluYWxseSB7XG4gICAgUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbi5yZWxlYXNlKHRyYW5zYWN0aW9uKTtcbiAgICAvLyBSZXZlcnQgdG8gdGhlIERPTSBiYXRjaGluZyBzdHJhdGVneSBzaW5jZSB0aGVzZSB0d28gcmVuZGVyZXJzXG4gICAgLy8gY3VycmVudGx5IHNoYXJlIHRoZXNlIHN0YXRlZnVsIG1vZHVsZXMuXG4gICAgUmVhY3RVcGRhdGVzLmluamVjdGlvbi5pbmplY3RCYXRjaGluZ1N0cmF0ZWd5KFJlYWN0RGVmYXVsdEJhdGNoaW5nU3RyYXRlZ3kpO1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIEhUTUwgbWFya3VwLCB3aXRob3V0IHRoZSBleHRyYSBSZWFjdCBJRCBhbmQgY2hlY2tzdW1cbiAqIChmb3IgZ2VuZXJhdGluZyBzdGF0aWMgcGFnZXMpXG4gKi9cbmZ1bmN0aW9uIHJlbmRlclRvU3RhdGljTWFya3VwKGVsZW1lbnQpIHtcbiAgIVJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChlbGVtZW50KSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdyZW5kZXJUb1N0YXRpY01hcmt1cCgpOiBZb3UgbXVzdCBwYXNzIGEgdmFsaWQgUmVhY3RFbGVtZW50LicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICB2YXIgdHJhbnNhY3Rpb247XG4gIHRyeSB7XG4gICAgUmVhY3RVcGRhdGVzLmluamVjdGlvbi5pbmplY3RCYXRjaGluZ1N0cmF0ZWd5KFJlYWN0U2VydmVyQmF0Y2hpbmdTdHJhdGVneSk7XG5cbiAgICB2YXIgaWQgPSBSZWFjdEluc3RhbmNlSGFuZGxlcy5jcmVhdGVSZWFjdFJvb3RJRCgpO1xuICAgIHRyYW5zYWN0aW9uID0gUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbi5nZXRQb29sZWQodHJ1ZSk7XG5cbiAgICByZXR1cm4gdHJhbnNhY3Rpb24ucGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgY29tcG9uZW50SW5zdGFuY2UgPSBpbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50KGVsZW1lbnQsIG51bGwpO1xuICAgICAgcmV0dXJuIGNvbXBvbmVudEluc3RhbmNlLm1vdW50Q29tcG9uZW50KGlkLCB0cmFuc2FjdGlvbiwgZW1wdHlPYmplY3QpO1xuICAgIH0sIG51bGwpO1xuICB9IGZpbmFsbHkge1xuICAgIFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb24ucmVsZWFzZSh0cmFuc2FjdGlvbik7XG4gICAgLy8gUmV2ZXJ0IHRvIHRoZSBET00gYmF0Y2hpbmcgc3RyYXRlZ3kgc2luY2UgdGhlc2UgdHdvIHJlbmRlcmVyc1xuICAgIC8vIGN1cnJlbnRseSBzaGFyZSB0aGVzZSBzdGF0ZWZ1bCBtb2R1bGVzLlxuICAgIFJlYWN0VXBkYXRlcy5pbmplY3Rpb24uaW5qZWN0QmF0Y2hpbmdTdHJhdGVneShSZWFjdERlZmF1bHRCYXRjaGluZ1N0cmF0ZWd5KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmVuZGVyVG9TdHJpbmc6IHJlbmRlclRvU3RyaW5nLFxuICByZW5kZXJUb1N0YXRpY01hcmt1cDogcmVuZGVyVG9TdGF0aWNNYXJrdXBcbn07IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxNC0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0U2VydmVyUmVuZGVyaW5nVHJhbnNhY3Rpb25cbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9vbGVkQ2xhc3MgPSByZXF1aXJlKCcuL1Bvb2xlZENsYXNzJyk7XG52YXIgQ2FsbGJhY2tRdWV1ZSA9IHJlcXVpcmUoJy4vQ2FsbGJhY2tRdWV1ZScpO1xudmFyIFRyYW5zYWN0aW9uID0gcmVxdWlyZSgnLi9UcmFuc2FjdGlvbicpO1xuXG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9PYmplY3QuYXNzaWduJyk7XG52YXIgZW1wdHlGdW5jdGlvbiA9IHJlcXVpcmUoJ2ZianMvbGliL2VtcHR5RnVuY3Rpb24nKTtcblxuLyoqXG4gKiBQcm92aWRlcyBhIGBDYWxsYmFja1F1ZXVlYCBxdWV1ZSBmb3IgY29sbGVjdGluZyBgb25ET01SZWFkeWAgY2FsbGJhY2tzXG4gKiBkdXJpbmcgdGhlIHBlcmZvcm1pbmcgb2YgdGhlIHRyYW5zYWN0aW9uLlxuICovXG52YXIgT05fRE9NX1JFQURZX1FVRVVFSU5HID0ge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgdGhlIGludGVybmFsIGBvbkRPTVJlYWR5YCBxdWV1ZS5cbiAgICovXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlYWN0TW91bnRSZWFkeS5yZXNldCgpO1xuICB9LFxuXG4gIGNsb3NlOiBlbXB0eUZ1bmN0aW9uXG59O1xuXG4vKipcbiAqIEV4ZWN1dGVkIHdpdGhpbiB0aGUgc2NvcGUgb2YgdGhlIGBUcmFuc2FjdGlvbmAgaW5zdGFuY2UuIENvbnNpZGVyIHRoZXNlIGFzXG4gKiBiZWluZyBtZW1iZXIgbWV0aG9kcywgYnV0IHdpdGggYW4gaW1wbGllZCBvcmRlcmluZyB3aGlsZSBiZWluZyBpc29sYXRlZCBmcm9tXG4gKiBlYWNoIG90aGVyLlxuICovXG52YXIgVFJBTlNBQ1RJT05fV1JBUFBFUlMgPSBbT05fRE9NX1JFQURZX1FVRVVFSU5HXTtcblxuLyoqXG4gKiBAY2xhc3MgUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvblxuICogQHBhcmFtIHtib29sZWFufSByZW5kZXJUb1N0YXRpY01hcmt1cFxuICovXG5mdW5jdGlvbiBSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9uKHJlbmRlclRvU3RhdGljTWFya3VwKSB7XG4gIHRoaXMucmVpbml0aWFsaXplVHJhbnNhY3Rpb24oKTtcbiAgdGhpcy5yZW5kZXJUb1N0YXRpY01hcmt1cCA9IHJlbmRlclRvU3RhdGljTWFya3VwO1xuICB0aGlzLnJlYWN0TW91bnRSZWFkeSA9IENhbGxiYWNrUXVldWUuZ2V0UG9vbGVkKG51bGwpO1xuICB0aGlzLnVzZUNyZWF0ZUVsZW1lbnQgPSBmYWxzZTtcbn1cblxudmFyIE1peGluID0ge1xuICAvKipcbiAgICogQHNlZSBUcmFuc2FjdGlvblxuICAgKiBAYWJzdHJhY3RcbiAgICogQGZpbmFsXG4gICAqIEByZXR1cm4ge2FycmF5fSBFbXB0eSBsaXN0IG9mIG9wZXJhdGlvbiB3cmFwIHByb2NlZHVyZXMuXG4gICAqL1xuICBnZXRUcmFuc2FjdGlvbldyYXBwZXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFRSQU5TQUNUSU9OX1dSQVBQRVJTO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9IFRoZSBxdWV1ZSB0byBjb2xsZWN0IGBvbkRPTVJlYWR5YCBjYWxsYmFja3Mgd2l0aC5cbiAgICovXG4gIGdldFJlYWN0TW91bnRSZWFkeTogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlYWN0TW91bnRSZWFkeTtcbiAgfSxcblxuICAvKipcbiAgICogYFBvb2xlZENsYXNzYCBsb29rcyBmb3IgdGhpcywgYW5kIHdpbGwgaW52b2tlIHRoaXMgYmVmb3JlIGFsbG93aW5nIHRoaXNcbiAgICogaW5zdGFuY2UgdG8gYmUgcmV1c2VkLlxuICAgKi9cbiAgZGVzdHJ1Y3RvcjogZnVuY3Rpb24gKCkge1xuICAgIENhbGxiYWNrUXVldWUucmVsZWFzZSh0aGlzLnJlYWN0TW91bnRSZWFkeSk7XG4gICAgdGhpcy5yZWFjdE1vdW50UmVhZHkgPSBudWxsO1xuICB9XG59O1xuXG5hc3NpZ24oUmVhY3RTZXJ2ZXJSZW5kZXJpbmdUcmFuc2FjdGlvbi5wcm90b3R5cGUsIFRyYW5zYWN0aW9uLk1peGluLCBNaXhpbik7XG5cblBvb2xlZENsYXNzLmFkZFBvb2xpbmdUbyhSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9uKTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFNlcnZlclJlbmRlcmluZ1RyYW5zYWN0aW9uOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgUmVhY3RVcGRhdGVRdWV1ZVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG52YXIgUmVhY3RJbnN0YW5jZU1hcCA9IHJlcXVpcmUoJy4vUmVhY3RJbnN0YW5jZU1hcCcpO1xudmFyIFJlYWN0VXBkYXRlcyA9IHJlcXVpcmUoJy4vUmVhY3RVcGRhdGVzJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG5mdW5jdGlvbiBlbnF1ZXVlVXBkYXRlKGludGVybmFsSW5zdGFuY2UpIHtcbiAgUmVhY3RVcGRhdGVzLmVucXVldWVVcGRhdGUoaW50ZXJuYWxJbnN0YW5jZSk7XG59XG5cbmZ1bmN0aW9uIGdldEludGVybmFsSW5zdGFuY2VSZWFkeUZvclVwZGF0ZShwdWJsaWNJbnN0YW5jZSwgY2FsbGVyTmFtZSkge1xuICB2YXIgaW50ZXJuYWxJbnN0YW5jZSA9IFJlYWN0SW5zdGFuY2VNYXAuZ2V0KHB1YmxpY0luc3RhbmNlKTtcbiAgaWYgKCFpbnRlcm5hbEluc3RhbmNlKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIC8vIE9ubHkgd2FybiB3aGVuIHdlIGhhdmUgYSBjYWxsZXJOYW1lLiBPdGhlcndpc2Ugd2Ugc2hvdWxkIGJlIHNpbGVudC5cbiAgICAgIC8vIFdlJ3JlIHByb2JhYmx5IGNhbGxpbmcgZnJvbSBlbnF1ZXVlQ2FsbGJhY2suIFdlIGRvbid0IHdhbnQgdG8gd2FyblxuICAgICAgLy8gdGhlcmUgYmVjYXVzZSB3ZSBhbHJlYWR5IHdhcm5lZCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgbGlmZWN5Y2xlIG1ldGhvZC5cbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKCFjYWxsZXJOYW1lLCAnJXMoLi4uKTogQ2FuIG9ubHkgdXBkYXRlIGEgbW91bnRlZCBvciBtb3VudGluZyBjb21wb25lbnQuICcgKyAnVGhpcyB1c3VhbGx5IG1lYW5zIHlvdSBjYWxsZWQgJXMoKSBvbiBhbiB1bm1vdW50ZWQgY29tcG9uZW50LiAnICsgJ1RoaXMgaXMgYSBuby1vcC4gUGxlYXNlIGNoZWNrIHRoZSBjb2RlIGZvciB0aGUgJXMgY29tcG9uZW50LicsIGNhbGxlck5hbWUsIGNhbGxlck5hbWUsIHB1YmxpY0luc3RhbmNlLmNvbnN0cnVjdG9yLmRpc3BsYXlOYW1lKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQgPT0gbnVsbCwgJyVzKC4uLik6IENhbm5vdCB1cGRhdGUgZHVyaW5nIGFuIGV4aXN0aW5nIHN0YXRlIHRyYW5zaXRpb24gJyArICcoc3VjaCBhcyB3aXRoaW4gYHJlbmRlcmApLiBSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uICcgKyAnb2YgcHJvcHMgYW5kIHN0YXRlLicsIGNhbGxlck5hbWUpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIGludGVybmFsSW5zdGFuY2U7XG59XG5cbi8qKlxuICogUmVhY3RVcGRhdGVRdWV1ZSBhbGxvd3MgZm9yIHN0YXRlIHVwZGF0ZXMgdG8gYmUgc2NoZWR1bGVkIGludG8gYSBsYXRlclxuICogcmVjb25jaWxpYXRpb24gc3RlcC5cbiAqL1xudmFyIFJlYWN0VXBkYXRlUXVldWUgPSB7XG5cbiAgLyoqXG4gICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCB0aGlzIGNvbXBvc2l0ZSBjb21wb25lbnQgaXMgbW91bnRlZC5cbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2Ugd2Ugd2FudCB0byB0ZXN0LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG1vdW50ZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAZmluYWxcbiAgICovXG4gIGlzTW91bnRlZDogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhciBvd25lciA9IFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQ7XG4gICAgICBpZiAob3duZXIgIT09IG51bGwpIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcob3duZXIuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyLCAnJXMgaXMgYWNjZXNzaW5nIGlzTW91bnRlZCBpbnNpZGUgaXRzIHJlbmRlcigpIGZ1bmN0aW9uLiAnICsgJ3JlbmRlcigpIHNob3VsZCBiZSBhIHB1cmUgZnVuY3Rpb24gb2YgcHJvcHMgYW5kIHN0YXRlLiBJdCBzaG91bGQgJyArICduZXZlciBhY2Nlc3Mgc29tZXRoaW5nIHRoYXQgcmVxdWlyZXMgc3RhbGUgZGF0YSBmcm9tIHRoZSBwcmV2aW91cyAnICsgJ3JlbmRlciwgc3VjaCBhcyByZWZzLiBNb3ZlIHRoaXMgbG9naWMgdG8gY29tcG9uZW50RGlkTW91bnQgYW5kICcgKyAnY29tcG9uZW50RGlkVXBkYXRlIGluc3RlYWQuJywgb3duZXIuZ2V0TmFtZSgpIHx8ICdBIGNvbXBvbmVudCcpIDogdW5kZWZpbmVkO1xuICAgICAgICBvd25lci5fd2FybmVkQWJvdXRSZWZzSW5SZW5kZXIgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgaW50ZXJuYWxJbnN0YW5jZSA9IFJlYWN0SW5zdGFuY2VNYXAuZ2V0KHB1YmxpY0luc3RhbmNlKTtcbiAgICBpZiAoaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgICAgLy8gRHVyaW5nIGNvbXBvbmVudFdpbGxNb3VudCBhbmQgcmVuZGVyIHRoaXMgd2lsbCBzdGlsbCBiZSBudWxsIGJ1dCBhZnRlclxuICAgICAgLy8gdGhhdCB3aWxsIGFsd2F5cyByZW5kZXIgdG8gc29tZXRoaW5nLiBBdCBsZWFzdCBmb3Igbm93LiBTbyB3ZSBjYW4gdXNlXG4gICAgICAvLyB0aGlzIGhhY2suXG4gICAgICByZXR1cm4gISFpbnRlcm5hbEluc3RhbmNlLl9yZW5kZXJlZENvbXBvbmVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogRW5xdWV1ZSBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciBhbGwgdGhlIHBlbmRpbmcgdXBkYXRlc1xuICAgKiBoYXZlIHByb2Nlc3NlZC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdG8gdXNlIGFzIGB0aGlzYCBjb250ZXh0LlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHN0YXRlIGlzIHVwZGF0ZWQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZUNhbGxiYWNrOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIGNhbGxiYWNrKSB7XG4gICAgISh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ2VucXVldWVDYWxsYmFjayguLi4pOiBZb3UgY2FsbGVkIGBzZXRQcm9wc2AsIGByZXBsYWNlUHJvcHNgLCAnICsgJ2BzZXRTdGF0ZWAsIGByZXBsYWNlU3RhdGVgLCBvciBgZm9yY2VVcGRhdGVgIHdpdGggYSBjYWxsYmFjayB0aGF0ICcgKyAnaXNuXFwndCBjYWxsYWJsZS4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnRlcm5hbEluc3RhbmNlUmVhZHlGb3JVcGRhdGUocHVibGljSW5zdGFuY2UpO1xuXG4gICAgLy8gUHJldmlvdXNseSB3ZSB3b3VsZCB0aHJvdyBhbiBlcnJvciBpZiB3ZSBkaWRuJ3QgaGF2ZSBhbiBpbnRlcm5hbFxuICAgIC8vIGluc3RhbmNlLiBTaW5jZSB3ZSB3YW50IHRvIG1ha2UgaXQgYSBuby1vcCBpbnN0ZWFkLCB3ZSBtaXJyb3IgdGhlIHNhbWVcbiAgICAvLyBiZWhhdmlvciB3ZSBoYXZlIGluIG90aGVyIGVucXVldWUqIG1ldGhvZHMuXG4gICAgLy8gV2UgYWxzbyBuZWVkIHRvIGlnbm9yZSBjYWxsYmFja3MgaW4gY29tcG9uZW50V2lsbE1vdW50LiBTZWVcbiAgICAvLyBlbnF1ZXVlVXBkYXRlcy5cbiAgICBpZiAoIWludGVybmFsSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzKSB7XG4gICAgICBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzID0gW2NhbGxiYWNrXTtcbiAgICB9XG4gICAgLy8gVE9ETzogVGhlIGNhbGxiYWNrIGhlcmUgaXMgaWdub3JlZCB3aGVuIHNldFN0YXRlIGlzIGNhbGxlZCBmcm9tXG4gICAgLy8gY29tcG9uZW50V2lsbE1vdW50LiBFaXRoZXIgZml4IGl0IG9yIGRpc2FsbG93IGRvaW5nIHNvIGNvbXBsZXRlbHkgaW5cbiAgICAvLyBmYXZvciBvZiBnZXRJbml0aWFsU3RhdGUuIEFsdGVybmF0aXZlbHksIHdlIGNhbiBkaXNhbGxvd1xuICAgIC8vIGNvbXBvbmVudFdpbGxNb3VudCBkdXJpbmcgc2VydmVyLXNpZGUgcmVuZGVyaW5nLlxuICAgIGVucXVldWVVcGRhdGUoaW50ZXJuYWxJbnN0YW5jZSk7XG4gIH0sXG5cbiAgZW5xdWV1ZUNhbGxiYWNrSW50ZXJuYWw6IGZ1bmN0aW9uIChpbnRlcm5hbEluc3RhbmNlLCBjYWxsYmFjaykge1xuICAgICEodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdlbnF1ZXVlQ2FsbGJhY2soLi4uKTogWW91IGNhbGxlZCBgc2V0UHJvcHNgLCBgcmVwbGFjZVByb3BzYCwgJyArICdgc2V0U3RhdGVgLCBgcmVwbGFjZVN0YXRlYCwgb3IgYGZvcmNlVXBkYXRlYCB3aXRoIGEgY2FsbGJhY2sgdGhhdCAnICsgJ2lzblxcJ3QgY2FsbGFibGUuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIGlmIChpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzKSB7XG4gICAgICBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nQ2FsbGJhY2tzID0gW2NhbGxiYWNrXTtcbiAgICB9XG4gICAgZW5xdWV1ZVVwZGF0ZShpbnRlcm5hbEluc3RhbmNlKTtcbiAgfSxcblxuICAvKipcbiAgICogRm9yY2VzIGFuIHVwZGF0ZS4gVGhpcyBzaG91bGQgb25seSBiZSBpbnZva2VkIHdoZW4gaXQgaXMga25vd24gd2l0aFxuICAgKiBjZXJ0YWludHkgdGhhdCB3ZSBhcmUgKipub3QqKiBpbiBhIERPTSB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogWW91IG1heSB3YW50IHRvIGNhbGwgdGhpcyB3aGVuIHlvdSBrbm93IHRoYXQgc29tZSBkZWVwZXIgYXNwZWN0IG9mIHRoZVxuICAgKiBjb21wb25lbnQncyBzdGF0ZSBoYXMgY2hhbmdlZCBidXQgYHNldFN0YXRlYCB3YXMgbm90IGNhbGxlZC5cbiAgICpcbiAgICogVGhpcyB3aWxsIG5vdCBpbnZva2UgYHNob3VsZENvbXBvbmVudFVwZGF0ZWAsIGJ1dCBpdCB3aWxsIGludm9rZVxuICAgKiBgY29tcG9uZW50V2lsbFVwZGF0ZWAgYW5kIGBjb21wb25lbnREaWRVcGRhdGVgLlxuICAgKlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB0aGF0IHNob3VsZCByZXJlbmRlci5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlRm9yY2VVcGRhdGU6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSkge1xuICAgIHZhciBpbnRlcm5hbEluc3RhbmNlID0gZ2V0SW50ZXJuYWxJbnN0YW5jZVJlYWR5Rm9yVXBkYXRlKHB1YmxpY0luc3RhbmNlLCAnZm9yY2VVcGRhdGUnKTtcblxuICAgIGlmICghaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGludGVybmFsSW5zdGFuY2UuX3BlbmRpbmdGb3JjZVVwZGF0ZSA9IHRydWU7XG5cbiAgICBlbnF1ZXVlVXBkYXRlKGludGVybmFsSW5zdGFuY2UpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgb2YgdGhlIHN0YXRlLiBBbHdheXMgdXNlIHRoaXMgb3IgYHNldFN0YXRlYCB0byBtdXRhdGUgc3RhdGUuXG4gICAqIFlvdSBzaG91bGQgdHJlYXQgYHRoaXMuc3RhdGVgIGFzIGltbXV0YWJsZS5cbiAgICpcbiAgICogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgYHRoaXMuc3RhdGVgIHdpbGwgYmUgaW1tZWRpYXRlbHkgdXBkYXRlZCwgc29cbiAgICogYWNjZXNzaW5nIGB0aGlzLnN0YXRlYCBhZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kIG1heSByZXR1cm4gdGhlIG9sZCB2YWx1ZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjb21wbGV0ZVN0YXRlIE5leHQgc3RhdGUuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZVJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBjb21wbGV0ZVN0YXRlKSB7XG4gICAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnRlcm5hbEluc3RhbmNlUmVhZHlGb3JVcGRhdGUocHVibGljSW5zdGFuY2UsICdyZXBsYWNlU3RhdGUnKTtcblxuICAgIGlmICghaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGludGVybmFsSW5zdGFuY2UuX3BlbmRpbmdTdGF0ZVF1ZXVlID0gW2NvbXBsZXRlU3RhdGVdO1xuICAgIGludGVybmFsSW5zdGFuY2UuX3BlbmRpbmdSZXBsYWNlU3RhdGUgPSB0cnVlO1xuXG4gICAgZW5xdWV1ZVVwZGF0ZShpbnRlcm5hbEluc3RhbmNlKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgc3RhdGUuIFRoaXMgb25seSBleGlzdHMgYmVjYXVzZSBfcGVuZGluZ1N0YXRlIGlzXG4gICAqIGludGVybmFsLiBUaGlzIHByb3ZpZGVzIGEgbWVyZ2luZyBzdHJhdGVneSB0aGF0IGlzIG5vdCBhdmFpbGFibGUgdG8gZGVlcFxuICAgKiBwcm9wZXJ0aWVzIHdoaWNoIGlzIGNvbmZ1c2luZy4gVE9ETzogRXhwb3NlIHBlbmRpbmdTdGF0ZSBvciBkb24ndCB1c2UgaXRcbiAgICogZHVyaW5nIHRoZSBtZXJnZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXJ0aWFsU3RhdGUgTmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIHN0YXRlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVTZXRTdGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBwYXJ0aWFsU3RhdGUpIHtcbiAgICB2YXIgaW50ZXJuYWxJbnN0YW5jZSA9IGdldEludGVybmFsSW5zdGFuY2VSZWFkeUZvclVwZGF0ZShwdWJsaWNJbnN0YW5jZSwgJ3NldFN0YXRlJyk7XG5cbiAgICBpZiAoIWludGVybmFsSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcXVldWUgPSBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nU3RhdGVRdWV1ZSB8fCAoaW50ZXJuYWxJbnN0YW5jZS5fcGVuZGluZ1N0YXRlUXVldWUgPSBbXSk7XG4gICAgcXVldWUucHVzaChwYXJ0aWFsU3RhdGUpO1xuXG4gICAgZW5xdWV1ZVVwZGF0ZShpbnRlcm5hbEluc3RhbmNlKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgcHJvcHMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGFydGlhbFByb3BzIFN1YnNldCBvZiB0aGUgbmV4dCBwcm9wcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlU2V0UHJvcHM6IGZ1bmN0aW9uIChwdWJsaWNJbnN0YW5jZSwgcGFydGlhbFByb3BzKSB7XG4gICAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnRlcm5hbEluc3RhbmNlUmVhZHlGb3JVcGRhdGUocHVibGljSW5zdGFuY2UsICdzZXRQcm9wcycpO1xuICAgIGlmICghaW50ZXJuYWxJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBSZWFjdFVwZGF0ZVF1ZXVlLmVucXVldWVTZXRQcm9wc0ludGVybmFsKGludGVybmFsSW5zdGFuY2UsIHBhcnRpYWxQcm9wcyk7XG4gIH0sXG5cbiAgZW5xdWV1ZVNldFByb3BzSW50ZXJuYWw6IGZ1bmN0aW9uIChpbnRlcm5hbEluc3RhbmNlLCBwYXJ0aWFsUHJvcHMpIHtcbiAgICB2YXIgdG9wTGV2ZWxXcmFwcGVyID0gaW50ZXJuYWxJbnN0YW5jZS5fdG9wTGV2ZWxXcmFwcGVyO1xuICAgICF0b3BMZXZlbFdyYXBwZXIgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnc2V0UHJvcHMoLi4uKTogWW91IGNhbGxlZCBgc2V0UHJvcHNgIG9uIGEgJyArICdjb21wb25lbnQgd2l0aCBhIHBhcmVudC4gVGhpcyBpcyBhbiBhbnRpLXBhdHRlcm4gc2luY2UgcHJvcHMgd2lsbCAnICsgJ2dldCByZWFjdGl2ZWx5IHVwZGF0ZWQgd2hlbiByZW5kZXJlZC4gSW5zdGVhZCwgY2hhbmdlIHRoZSBvd25lclxcJ3MgJyArICdgcmVuZGVyYCBtZXRob2QgdG8gcGFzcyB0aGUgY29ycmVjdCB2YWx1ZSBhcyBwcm9wcyB0byB0aGUgY29tcG9uZW50ICcgKyAnd2hlcmUgaXQgaXMgY3JlYXRlZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBNZXJnZSB3aXRoIHRoZSBwZW5kaW5nIGVsZW1lbnQgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2Ugd2l0aCBleGlzdGluZ1xuICAgIC8vIGVsZW1lbnQgcHJvcHMuXG4gICAgdmFyIHdyYXBFbGVtZW50ID0gdG9wTGV2ZWxXcmFwcGVyLl9wZW5kaW5nRWxlbWVudCB8fCB0b3BMZXZlbFdyYXBwZXIuX2N1cnJlbnRFbGVtZW50O1xuICAgIHZhciBlbGVtZW50ID0gd3JhcEVsZW1lbnQucHJvcHM7XG4gICAgdmFyIHByb3BzID0gYXNzaWduKHt9LCBlbGVtZW50LnByb3BzLCBwYXJ0aWFsUHJvcHMpO1xuICAgIHRvcExldmVsV3JhcHBlci5fcGVuZGluZ0VsZW1lbnQgPSBSZWFjdEVsZW1lbnQuY2xvbmVBbmRSZXBsYWNlUHJvcHMod3JhcEVsZW1lbnQsIFJlYWN0RWxlbWVudC5jbG9uZUFuZFJlcGxhY2VQcm9wcyhlbGVtZW50LCBwcm9wcykpO1xuXG4gICAgZW5xdWV1ZVVwZGF0ZSh0b3BMZXZlbFdyYXBwZXIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgb2YgdGhlIHByb3BzLlxuICAgKlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB0aGF0IHNob3VsZCByZXJlbmRlci5cbiAgICogQHBhcmFtIHtvYmplY3R9IHByb3BzIE5ldyBwcm9wcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlUmVwbGFjZVByb3BzOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIHByb3BzKSB7XG4gICAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnRlcm5hbEluc3RhbmNlUmVhZHlGb3JVcGRhdGUocHVibGljSW5zdGFuY2UsICdyZXBsYWNlUHJvcHMnKTtcbiAgICBpZiAoIWludGVybmFsSW5zdGFuY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgUmVhY3RVcGRhdGVRdWV1ZS5lbnF1ZXVlUmVwbGFjZVByb3BzSW50ZXJuYWwoaW50ZXJuYWxJbnN0YW5jZSwgcHJvcHMpO1xuICB9LFxuXG4gIGVucXVldWVSZXBsYWNlUHJvcHNJbnRlcm5hbDogZnVuY3Rpb24gKGludGVybmFsSW5zdGFuY2UsIHByb3BzKSB7XG4gICAgdmFyIHRvcExldmVsV3JhcHBlciA9IGludGVybmFsSW5zdGFuY2UuX3RvcExldmVsV3JhcHBlcjtcbiAgICAhdG9wTGV2ZWxXcmFwcGVyID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ3JlcGxhY2VQcm9wcyguLi4pOiBZb3UgY2FsbGVkIGByZXBsYWNlUHJvcHNgIG9uIGEgJyArICdjb21wb25lbnQgd2l0aCBhIHBhcmVudC4gVGhpcyBpcyBhbiBhbnRpLXBhdHRlcm4gc2luY2UgcHJvcHMgd2lsbCAnICsgJ2dldCByZWFjdGl2ZWx5IHVwZGF0ZWQgd2hlbiByZW5kZXJlZC4gSW5zdGVhZCwgY2hhbmdlIHRoZSBvd25lclxcJ3MgJyArICdgcmVuZGVyYCBtZXRob2QgdG8gcGFzcyB0aGUgY29ycmVjdCB2YWx1ZSBhcyBwcm9wcyB0byB0aGUgY29tcG9uZW50ICcgKyAnd2hlcmUgaXQgaXMgY3JlYXRlZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBNZXJnZSB3aXRoIHRoZSBwZW5kaW5nIGVsZW1lbnQgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2Ugd2l0aCBleGlzdGluZ1xuICAgIC8vIGVsZW1lbnQgcHJvcHMuXG4gICAgdmFyIHdyYXBFbGVtZW50ID0gdG9wTGV2ZWxXcmFwcGVyLl9wZW5kaW5nRWxlbWVudCB8fCB0b3BMZXZlbFdyYXBwZXIuX2N1cnJlbnRFbGVtZW50O1xuICAgIHZhciBlbGVtZW50ID0gd3JhcEVsZW1lbnQucHJvcHM7XG4gICAgdG9wTGV2ZWxXcmFwcGVyLl9wZW5kaW5nRWxlbWVudCA9IFJlYWN0RWxlbWVudC5jbG9uZUFuZFJlcGxhY2VQcm9wcyh3cmFwRWxlbWVudCwgUmVhY3RFbGVtZW50LmNsb25lQW5kUmVwbGFjZVByb3BzKGVsZW1lbnQsIHByb3BzKSk7XG5cbiAgICBlbnF1ZXVlVXBkYXRlKHRvcExldmVsV3JhcHBlcik7XG4gIH0sXG5cbiAgZW5xdWV1ZUVsZW1lbnRJbnRlcm5hbDogZnVuY3Rpb24gKGludGVybmFsSW5zdGFuY2UsIG5ld0VsZW1lbnQpIHtcbiAgICBpbnRlcm5hbEluc3RhbmNlLl9wZW5kaW5nRWxlbWVudCA9IG5ld0VsZW1lbnQ7XG4gICAgZW5xdWV1ZVVwZGF0ZShpbnRlcm5hbEluc3RhbmNlKTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0VXBkYXRlUXVldWU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0VXBkYXRlc1xuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIENhbGxiYWNrUXVldWUgPSByZXF1aXJlKCcuL0NhbGxiYWNrUXVldWUnKTtcbnZhciBQb29sZWRDbGFzcyA9IHJlcXVpcmUoJy4vUG9vbGVkQ2xhc3MnKTtcbnZhciBSZWFjdFBlcmYgPSByZXF1aXJlKCcuL1JlYWN0UGVyZicpO1xudmFyIFJlYWN0UmVjb25jaWxlciA9IHJlcXVpcmUoJy4vUmVhY3RSZWNvbmNpbGVyJyk7XG52YXIgVHJhbnNhY3Rpb24gPSByZXF1aXJlKCcuL1RyYW5zYWN0aW9uJyk7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxudmFyIGRpcnR5Q29tcG9uZW50cyA9IFtdO1xudmFyIGFzYXBDYWxsYmFja1F1ZXVlID0gQ2FsbGJhY2tRdWV1ZS5nZXRQb29sZWQoKTtcbnZhciBhc2FwRW5xdWV1ZWQgPSBmYWxzZTtcblxudmFyIGJhdGNoaW5nU3RyYXRlZ3kgPSBudWxsO1xuXG5mdW5jdGlvbiBlbnN1cmVJbmplY3RlZCgpIHtcbiAgIShSZWFjdFVwZGF0ZXMuUmVhY3RSZWNvbmNpbGVUcmFuc2FjdGlvbiAmJiBiYXRjaGluZ1N0cmF0ZWd5KSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdFVwZGF0ZXM6IG11c3QgaW5qZWN0IGEgcmVjb25jaWxlIHRyYW5zYWN0aW9uIGNsYXNzIGFuZCBiYXRjaGluZyAnICsgJ3N0cmF0ZWd5JykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xufVxuXG52YXIgTkVTVEVEX1VQREFURVMgPSB7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRpcnR5Q29tcG9uZW50c0xlbmd0aCA9IGRpcnR5Q29tcG9uZW50cy5sZW5ndGg7XG4gIH0sXG4gIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuZGlydHlDb21wb25lbnRzTGVuZ3RoICE9PSBkaXJ0eUNvbXBvbmVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBBZGRpdGlvbmFsIHVwZGF0ZXMgd2VyZSBlbnF1ZXVlZCBieSBjb21wb25lbnREaWRVcGRhdGUgaGFuZGxlcnMgb3JcbiAgICAgIC8vIHNpbWlsYXI7IGJlZm9yZSBvdXIgb3duIFVQREFURV9RVUVVRUlORyB3cmFwcGVyIGNsb3Nlcywgd2Ugd2FudCB0byBydW5cbiAgICAgIC8vIHRoZXNlIG5ldyB1cGRhdGVzIHNvIHRoYXQgaWYgQSdzIGNvbXBvbmVudERpZFVwZGF0ZSBjYWxscyBzZXRTdGF0ZSBvblxuICAgICAgLy8gQiwgQiB3aWxsIHVwZGF0ZSBiZWZvcmUgdGhlIGNhbGxiYWNrIEEncyB1cGRhdGVyIHByb3ZpZGVkIHdoZW4gY2FsbGluZ1xuICAgICAgLy8gc2V0U3RhdGUuXG4gICAgICBkaXJ0eUNvbXBvbmVudHMuc3BsaWNlKDAsIHRoaXMuZGlydHlDb21wb25lbnRzTGVuZ3RoKTtcbiAgICAgIGZsdXNoQmF0Y2hlZFVwZGF0ZXMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlydHlDb21wb25lbnRzLmxlbmd0aCA9IDA7XG4gICAgfVxuICB9XG59O1xuXG52YXIgVVBEQVRFX1FVRVVFSU5HID0ge1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jYWxsYmFja1F1ZXVlLnJlc2V0KCk7XG4gIH0sXG4gIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jYWxsYmFja1F1ZXVlLm5vdGlmeUFsbCgpO1xuICB9XG59O1xuXG52YXIgVFJBTlNBQ1RJT05fV1JBUFBFUlMgPSBbTkVTVEVEX1VQREFURVMsIFVQREFURV9RVUVVRUlOR107XG5cbmZ1bmN0aW9uIFJlYWN0VXBkYXRlc0ZsdXNoVHJhbnNhY3Rpb24oKSB7XG4gIHRoaXMucmVpbml0aWFsaXplVHJhbnNhY3Rpb24oKTtcbiAgdGhpcy5kaXJ0eUNvbXBvbmVudHNMZW5ndGggPSBudWxsO1xuICB0aGlzLmNhbGxiYWNrUXVldWUgPSBDYWxsYmFja1F1ZXVlLmdldFBvb2xlZCgpO1xuICB0aGlzLnJlY29uY2lsZVRyYW5zYWN0aW9uID0gUmVhY3RVcGRhdGVzLlJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24uZ2V0UG9vbGVkKCAvKiBmb3JjZUhUTUwgKi9mYWxzZSk7XG59XG5cbmFzc2lnbihSZWFjdFVwZGF0ZXNGbHVzaFRyYW5zYWN0aW9uLnByb3RvdHlwZSwgVHJhbnNhY3Rpb24uTWl4aW4sIHtcbiAgZ2V0VHJhbnNhY3Rpb25XcmFwcGVyczogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBUUkFOU0FDVElPTl9XUkFQUEVSUztcbiAgfSxcblxuICBkZXN0cnVjdG9yOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kaXJ0eUNvbXBvbmVudHNMZW5ndGggPSBudWxsO1xuICAgIENhbGxiYWNrUXVldWUucmVsZWFzZSh0aGlzLmNhbGxiYWNrUXVldWUpO1xuICAgIHRoaXMuY2FsbGJhY2tRdWV1ZSA9IG51bGw7XG4gICAgUmVhY3RVcGRhdGVzLlJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb24ucmVsZWFzZSh0aGlzLnJlY29uY2lsZVRyYW5zYWN0aW9uKTtcbiAgICB0aGlzLnJlY29uY2lsZVRyYW5zYWN0aW9uID0gbnVsbDtcbiAgfSxcblxuICBwZXJmb3JtOiBmdW5jdGlvbiAobWV0aG9kLCBzY29wZSwgYSkge1xuICAgIC8vIEVzc2VudGlhbGx5IGNhbGxzIGB0aGlzLnJlY29uY2lsZVRyYW5zYWN0aW9uLnBlcmZvcm0obWV0aG9kLCBzY29wZSwgYSlgXG4gICAgLy8gd2l0aCB0aGlzIHRyYW5zYWN0aW9uJ3Mgd3JhcHBlcnMgYXJvdW5kIGl0LlxuICAgIHJldHVybiBUcmFuc2FjdGlvbi5NaXhpbi5wZXJmb3JtLmNhbGwodGhpcywgdGhpcy5yZWNvbmNpbGVUcmFuc2FjdGlvbi5wZXJmb3JtLCB0aGlzLnJlY29uY2lsZVRyYW5zYWN0aW9uLCBtZXRob2QsIHNjb3BlLCBhKTtcbiAgfVxufSk7XG5cblBvb2xlZENsYXNzLmFkZFBvb2xpbmdUbyhSZWFjdFVwZGF0ZXNGbHVzaFRyYW5zYWN0aW9uKTtcblxuZnVuY3Rpb24gYmF0Y2hlZFVwZGF0ZXMoY2FsbGJhY2ssIGEsIGIsIGMsIGQsIGUpIHtcbiAgZW5zdXJlSW5qZWN0ZWQoKTtcbiAgYmF0Y2hpbmdTdHJhdGVneS5iYXRjaGVkVXBkYXRlcyhjYWxsYmFjaywgYSwgYiwgYywgZCwgZSk7XG59XG5cbi8qKlxuICogQXJyYXkgY29tcGFyYXRvciBmb3IgUmVhY3RDb21wb25lbnRzIGJ5IG1vdW50IG9yZGVyaW5nLlxuICpcbiAqIEBwYXJhbSB7UmVhY3RDb21wb25lbnR9IGMxIGZpcnN0IGNvbXBvbmVudCB5b3UncmUgY29tcGFyaW5nXG4gKiBAcGFyYW0ge1JlYWN0Q29tcG9uZW50fSBjMiBzZWNvbmQgY29tcG9uZW50IHlvdSdyZSBjb21wYXJpbmdcbiAqIEByZXR1cm4ge251bWJlcn0gUmV0dXJuIHZhbHVlIHVzYWJsZSBieSBBcnJheS5wcm90b3R5cGUuc29ydCgpLlxuICovXG5mdW5jdGlvbiBtb3VudE9yZGVyQ29tcGFyYXRvcihjMSwgYzIpIHtcbiAgcmV0dXJuIGMxLl9tb3VudE9yZGVyIC0gYzIuX21vdW50T3JkZXI7XG59XG5cbmZ1bmN0aW9uIHJ1bkJhdGNoZWRVcGRhdGVzKHRyYW5zYWN0aW9uKSB7XG4gIHZhciBsZW4gPSB0cmFuc2FjdGlvbi5kaXJ0eUNvbXBvbmVudHNMZW5ndGg7XG4gICEobGVuID09PSBkaXJ0eUNvbXBvbmVudHMubGVuZ3RoKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdFeHBlY3RlZCBmbHVzaCB0cmFuc2FjdGlvblxcJ3Mgc3RvcmVkIGRpcnR5LWNvbXBvbmVudHMgbGVuZ3RoICglcykgdG8gJyArICdtYXRjaCBkaXJ0eS1jb21wb25lbnRzIGFycmF5IGxlbmd0aCAoJXMpLicsIGxlbiwgZGlydHlDb21wb25lbnRzLmxlbmd0aCkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuXG4gIC8vIFNpbmNlIHJlY29uY2lsaW5nIGEgY29tcG9uZW50IGhpZ2hlciBpbiB0aGUgb3duZXIgaGllcmFyY2h5IHVzdWFsbHkgKG5vdFxuICAvLyBhbHdheXMgLS0gc2VlIHNob3VsZENvbXBvbmVudFVwZGF0ZSgpKSB3aWxsIHJlY29uY2lsZSBjaGlsZHJlbiwgcmVjb25jaWxlXG4gIC8vIHRoZW0gYmVmb3JlIHRoZWlyIGNoaWxkcmVuIGJ5IHNvcnRpbmcgdGhlIGFycmF5LlxuICBkaXJ0eUNvbXBvbmVudHMuc29ydChtb3VudE9yZGVyQ29tcGFyYXRvcik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIC8vIElmIGEgY29tcG9uZW50IGlzIHVubW91bnRlZCBiZWZvcmUgcGVuZGluZyBjaGFuZ2VzIGFwcGx5LCBpdCB3aWxsIHN0aWxsXG4gICAgLy8gYmUgaGVyZSwgYnV0IHdlIGFzc3VtZSB0aGF0IGl0IGhhcyBjbGVhcmVkIGl0cyBfcGVuZGluZ0NhbGxiYWNrcyBhbmRcbiAgICAvLyB0aGF0IHBlcmZvcm1VcGRhdGVJZk5lY2Vzc2FyeSBpcyBhIG5vb3AuXG4gICAgdmFyIGNvbXBvbmVudCA9IGRpcnR5Q29tcG9uZW50c1tpXTtcblxuICAgIC8vIElmIHBlcmZvcm1VcGRhdGVJZk5lY2Vzc2FyeSBoYXBwZW5zIHRvIGVucXVldWUgYW55IG5ldyB1cGRhdGVzLCB3ZVxuICAgIC8vIHNob3VsZG4ndCBleGVjdXRlIHRoZSBjYWxsYmFja3MgdW50aWwgdGhlIG5leHQgcmVuZGVyIGhhcHBlbnMsIHNvXG4gICAgLy8gc3Rhc2ggdGhlIGNhbGxiYWNrcyBmaXJzdFxuICAgIHZhciBjYWxsYmFja3MgPSBjb21wb25lbnQuX3BlbmRpbmdDYWxsYmFja3M7XG4gICAgY29tcG9uZW50Ll9wZW5kaW5nQ2FsbGJhY2tzID0gbnVsbDtcblxuICAgIFJlYWN0UmVjb25jaWxlci5wZXJmb3JtVXBkYXRlSWZOZWNlc3NhcnkoY29tcG9uZW50LCB0cmFuc2FjdGlvbi5yZWNvbmNpbGVUcmFuc2FjdGlvbik7XG5cbiAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNhbGxiYWNrcy5sZW5ndGg7IGorKykge1xuICAgICAgICB0cmFuc2FjdGlvbi5jYWxsYmFja1F1ZXVlLmVucXVldWUoY2FsbGJhY2tzW2pdLCBjb21wb25lbnQuZ2V0UHVibGljSW5zdGFuY2UoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBmbHVzaEJhdGNoZWRVcGRhdGVzID0gZnVuY3Rpb24gKCkge1xuICAvLyBSZWFjdFVwZGF0ZXNGbHVzaFRyYW5zYWN0aW9uJ3Mgd3JhcHBlcnMgd2lsbCBjbGVhciB0aGUgZGlydHlDb21wb25lbnRzXG4gIC8vIGFycmF5IGFuZCBwZXJmb3JtIGFueSB1cGRhdGVzIGVucXVldWVkIGJ5IG1vdW50LXJlYWR5IGhhbmRsZXJzIChpLmUuLFxuICAvLyBjb21wb25lbnREaWRVcGRhdGUpIGJ1dCB3ZSBuZWVkIHRvIGNoZWNrIGhlcmUgdG9vIGluIG9yZGVyIHRvIGNhdGNoXG4gIC8vIHVwZGF0ZXMgZW5xdWV1ZWQgYnkgc2V0U3RhdGUgY2FsbGJhY2tzIGFuZCBhc2FwIGNhbGxzLlxuICB3aGlsZSAoZGlydHlDb21wb25lbnRzLmxlbmd0aCB8fCBhc2FwRW5xdWV1ZWQpIHtcbiAgICBpZiAoZGlydHlDb21wb25lbnRzLmxlbmd0aCkge1xuICAgICAgdmFyIHRyYW5zYWN0aW9uID0gUmVhY3RVcGRhdGVzRmx1c2hUcmFuc2FjdGlvbi5nZXRQb29sZWQoKTtcbiAgICAgIHRyYW5zYWN0aW9uLnBlcmZvcm0ocnVuQmF0Y2hlZFVwZGF0ZXMsIG51bGwsIHRyYW5zYWN0aW9uKTtcbiAgICAgIFJlYWN0VXBkYXRlc0ZsdXNoVHJhbnNhY3Rpb24ucmVsZWFzZSh0cmFuc2FjdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKGFzYXBFbnF1ZXVlZCkge1xuICAgICAgYXNhcEVucXVldWVkID0gZmFsc2U7XG4gICAgICB2YXIgcXVldWUgPSBhc2FwQ2FsbGJhY2tRdWV1ZTtcbiAgICAgIGFzYXBDYWxsYmFja1F1ZXVlID0gQ2FsbGJhY2tRdWV1ZS5nZXRQb29sZWQoKTtcbiAgICAgIHF1ZXVlLm5vdGlmeUFsbCgpO1xuICAgICAgQ2FsbGJhY2tRdWV1ZS5yZWxlYXNlKHF1ZXVlKTtcbiAgICB9XG4gIH1cbn07XG5mbHVzaEJhdGNoZWRVcGRhdGVzID0gUmVhY3RQZXJmLm1lYXN1cmUoJ1JlYWN0VXBkYXRlcycsICdmbHVzaEJhdGNoZWRVcGRhdGVzJywgZmx1c2hCYXRjaGVkVXBkYXRlcyk7XG5cbi8qKlxuICogTWFyayBhIGNvbXBvbmVudCBhcyBuZWVkaW5nIGEgcmVyZW5kZXIsIGFkZGluZyBhbiBvcHRpb25hbCBjYWxsYmFjayB0byBhXG4gKiBsaXN0IG9mIGZ1bmN0aW9ucyB3aGljaCB3aWxsIGJlIGV4ZWN1dGVkIG9uY2UgdGhlIHJlcmVuZGVyIG9jY3Vycy5cbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZVVwZGF0ZShjb21wb25lbnQpIHtcbiAgZW5zdXJlSW5qZWN0ZWQoKTtcblxuICAvLyBWYXJpb3VzIHBhcnRzIG9mIG91ciBjb2RlIChzdWNoIGFzIFJlYWN0Q29tcG9zaXRlQ29tcG9uZW50J3NcbiAgLy8gX3JlbmRlclZhbGlkYXRlZENvbXBvbmVudCkgYXNzdW1lIHRoYXQgY2FsbHMgdG8gcmVuZGVyIGFyZW4ndCBuZXN0ZWQ7XG4gIC8vIHZlcmlmeSB0aGF0IHRoYXQncyB0aGUgY2FzZS4gKFRoaXMgaXMgY2FsbGVkIGJ5IGVhY2ggdG9wLWxldmVsIHVwZGF0ZVxuICAvLyBmdW5jdGlvbiwgbGlrZSBzZXRQcm9wcywgc2V0U3RhdGUsIGZvcmNlVXBkYXRlLCBldGMuOyBjcmVhdGlvbiBhbmRcbiAgLy8gZGVzdHJ1Y3Rpb24gb2YgdG9wLWxldmVsIGNvbXBvbmVudHMgaXMgZ3VhcmRlZCBpbiBSZWFjdE1vdW50LilcblxuICBpZiAoIWJhdGNoaW5nU3RyYXRlZ3kuaXNCYXRjaGluZ1VwZGF0ZXMpIHtcbiAgICBiYXRjaGluZ1N0cmF0ZWd5LmJhdGNoZWRVcGRhdGVzKGVucXVldWVVcGRhdGUsIGNvbXBvbmVudCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZGlydHlDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbn1cblxuLyoqXG4gKiBFbnF1ZXVlIGEgY2FsbGJhY2sgdG8gYmUgcnVuIGF0IHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgYmF0Y2hpbmcgY3ljbGUuIFRocm93c1xuICogaWYgbm8gdXBkYXRlcyBhcmUgY3VycmVudGx5IGJlaW5nIHBlcmZvcm1lZC5cbiAqL1xuZnVuY3Rpb24gYXNhcChjYWxsYmFjaywgY29udGV4dCkge1xuICAhYmF0Y2hpbmdTdHJhdGVneS5pc0JhdGNoaW5nVXBkYXRlcyA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdFVwZGF0ZXMuYXNhcDogQ2FuXFwndCBlbnF1ZXVlIGFuIGFzYXAgY2FsbGJhY2sgaW4gYSBjb250ZXh0IHdoZXJlJyArICd1cGRhdGVzIGFyZSBub3QgYmVpbmcgYmF0Y2hlZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIGFzYXBDYWxsYmFja1F1ZXVlLmVucXVldWUoY2FsbGJhY2ssIGNvbnRleHQpO1xuICBhc2FwRW5xdWV1ZWQgPSB0cnVlO1xufVxuXG52YXIgUmVhY3RVcGRhdGVzSW5qZWN0aW9uID0ge1xuICBpbmplY3RSZWNvbmNpbGVUcmFuc2FjdGlvbjogZnVuY3Rpb24gKFJlY29uY2lsZVRyYW5zYWN0aW9uKSB7XG4gICAgIVJlY29uY2lsZVRyYW5zYWN0aW9uID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0VXBkYXRlczogbXVzdCBwcm92aWRlIGEgcmVjb25jaWxlIHRyYW5zYWN0aW9uIGNsYXNzJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIFJlYWN0VXBkYXRlcy5SZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uID0gUmVjb25jaWxlVHJhbnNhY3Rpb247XG4gIH0sXG5cbiAgaW5qZWN0QmF0Y2hpbmdTdHJhdGVneTogZnVuY3Rpb24gKF9iYXRjaGluZ1N0cmF0ZWd5KSB7XG4gICAgIV9iYXRjaGluZ1N0cmF0ZWd5ID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0VXBkYXRlczogbXVzdCBwcm92aWRlIGEgYmF0Y2hpbmcgc3RyYXRlZ3knKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgISh0eXBlb2YgX2JhdGNoaW5nU3RyYXRlZ3kuYmF0Y2hlZFVwZGF0ZXMgPT09ICdmdW5jdGlvbicpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGludmFyaWFudChmYWxzZSwgJ1JlYWN0VXBkYXRlczogbXVzdCBwcm92aWRlIGEgYmF0Y2hlZFVwZGF0ZXMoKSBmdW5jdGlvbicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICAhKHR5cGVvZiBfYmF0Y2hpbmdTdHJhdGVneS5pc0JhdGNoaW5nVXBkYXRlcyA9PT0gJ2Jvb2xlYW4nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdSZWFjdFVwZGF0ZXM6IG11c3QgcHJvdmlkZSBhbiBpc0JhdGNoaW5nVXBkYXRlcyBib29sZWFuIGF0dHJpYnV0ZScpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICBiYXRjaGluZ1N0cmF0ZWd5ID0gX2JhdGNoaW5nU3RyYXRlZ3k7XG4gIH1cbn07XG5cbnZhciBSZWFjdFVwZGF0ZXMgPSB7XG4gIC8qKlxuICAgKiBSZWFjdCByZWZlcmVuY2VzIGBSZWFjdFJlY29uY2lsZVRyYW5zYWN0aW9uYCB1c2luZyB0aGlzIHByb3BlcnR5IGluIG9yZGVyXG4gICAqIHRvIGFsbG93IGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIFJlYWN0UmVjb25jaWxlVHJhbnNhY3Rpb246IG51bGwsXG5cbiAgYmF0Y2hlZFVwZGF0ZXM6IGJhdGNoZWRVcGRhdGVzLFxuICBlbnF1ZXVlVXBkYXRlOiBlbnF1ZXVlVXBkYXRlLFxuICBmbHVzaEJhdGNoZWRVcGRhdGVzOiBmbHVzaEJhdGNoZWRVcGRhdGVzLFxuICBpbmplY3Rpb246IFJlYWN0VXBkYXRlc0luamVjdGlvbixcbiAgYXNhcDogYXNhcFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFVwZGF0ZXM7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFJlYWN0VmVyc2lvblxuICovXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSAnMC4xNC45JzsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgU1ZHRE9NUHJvcGVydHlDb25maWdcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBET01Qcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRE9NUHJvcGVydHknKTtcblxudmFyIE1VU1RfVVNFX0FUVFJJQlVURSA9IERPTVByb3BlcnR5LmluamVjdGlvbi5NVVNUX1VTRV9BVFRSSUJVVEU7XG5cbnZhciBOUyA9IHtcbiAgeGxpbms6ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJyxcbiAgeG1sOiAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJ1xufTtcblxudmFyIFNWR0RPTVByb3BlcnR5Q29uZmlnID0ge1xuICBQcm9wZXJ0aWVzOiB7XG4gICAgY2xpcFBhdGg6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBjeDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGN5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgZDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGR4OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgZHk6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBmaWxsOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgZmlsbE9wYWNpdHk6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBmb250RmFtaWx5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgZm9udFNpemU6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBmeDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIGZ5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgZ3JhZGllbnRUcmFuc2Zvcm06IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBncmFkaWVudFVuaXRzOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgbWFya2VyRW5kOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgbWFya2VyTWlkOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgbWFya2VyU3RhcnQ6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBvZmZzZXQ6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBvcGFjaXR5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgcGF0dGVybkNvbnRlbnRVbml0czogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHBhdHRlcm5Vbml0czogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHBvaW50czogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICByOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgcng6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICByeTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHNwcmVhZE1ldGhvZDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHN0b3BDb2xvcjogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHN0b3BPcGFjaXR5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgc3Ryb2tlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgc3Ryb2tlRGFzaGFycmF5OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgc3Ryb2tlTGluZWNhcDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHN0cm9rZU9wYWNpdHk6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICBzdHJva2VXaWR0aDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHRleHRBbmNob3I6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB0cmFuc2Zvcm06IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB2ZXJzaW9uOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgdmlld0JveDogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHgxOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeDI6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB4OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtBY3R1YXRlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtBcmNyb2xlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtIcmVmOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtSb2xlOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtTaG93OiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeGxpbmtUaXRsZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHhsaW5rVHlwZTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHhtbEJhc2U6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB4bWxMYW5nOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeG1sU3BhY2U6IE1VU1RfVVNFX0FUVFJJQlVURSxcbiAgICB5MTogTVVTVF9VU0VfQVRUUklCVVRFLFxuICAgIHkyOiBNVVNUX1VTRV9BVFRSSUJVVEUsXG4gICAgeTogTVVTVF9VU0VfQVRUUklCVVRFXG4gIH0sXG4gIERPTUF0dHJpYnV0ZU5hbWVzcGFjZXM6IHtcbiAgICB4bGlua0FjdHVhdGU6IE5TLnhsaW5rLFxuICAgIHhsaW5rQXJjcm9sZTogTlMueGxpbmssXG4gICAgeGxpbmtIcmVmOiBOUy54bGluayxcbiAgICB4bGlua1JvbGU6IE5TLnhsaW5rLFxuICAgIHhsaW5rU2hvdzogTlMueGxpbmssXG4gICAgeGxpbmtUaXRsZTogTlMueGxpbmssXG4gICAgeGxpbmtUeXBlOiBOUy54bGluayxcbiAgICB4bWxCYXNlOiBOUy54bWwsXG4gICAgeG1sTGFuZzogTlMueG1sLFxuICAgIHhtbFNwYWNlOiBOUy54bWxcbiAgfSxcbiAgRE9NQXR0cmlidXRlTmFtZXM6IHtcbiAgICBjbGlwUGF0aDogJ2NsaXAtcGF0aCcsXG4gICAgZmlsbE9wYWNpdHk6ICdmaWxsLW9wYWNpdHknLFxuICAgIGZvbnRGYW1pbHk6ICdmb250LWZhbWlseScsXG4gICAgZm9udFNpemU6ICdmb250LXNpemUnLFxuICAgIGdyYWRpZW50VHJhbnNmb3JtOiAnZ3JhZGllbnRUcmFuc2Zvcm0nLFxuICAgIGdyYWRpZW50VW5pdHM6ICdncmFkaWVudFVuaXRzJyxcbiAgICBtYXJrZXJFbmQ6ICdtYXJrZXItZW5kJyxcbiAgICBtYXJrZXJNaWQ6ICdtYXJrZXItbWlkJyxcbiAgICBtYXJrZXJTdGFydDogJ21hcmtlci1zdGFydCcsXG4gICAgcGF0dGVybkNvbnRlbnRVbml0czogJ3BhdHRlcm5Db250ZW50VW5pdHMnLFxuICAgIHBhdHRlcm5Vbml0czogJ3BhdHRlcm5Vbml0cycsXG4gICAgcHJlc2VydmVBc3BlY3RSYXRpbzogJ3ByZXNlcnZlQXNwZWN0UmF0aW8nLFxuICAgIHNwcmVhZE1ldGhvZDogJ3NwcmVhZE1ldGhvZCcsXG4gICAgc3RvcENvbG9yOiAnc3RvcC1jb2xvcicsXG4gICAgc3RvcE9wYWNpdHk6ICdzdG9wLW9wYWNpdHknLFxuICAgIHN0cm9rZURhc2hhcnJheTogJ3N0cm9rZS1kYXNoYXJyYXknLFxuICAgIHN0cm9rZUxpbmVjYXA6ICdzdHJva2UtbGluZWNhcCcsXG4gICAgc3Ryb2tlT3BhY2l0eTogJ3N0cm9rZS1vcGFjaXR5JyxcbiAgICBzdHJva2VXaWR0aDogJ3N0cm9rZS13aWR0aCcsXG4gICAgdGV4dEFuY2hvcjogJ3RleHQtYW5jaG9yJyxcbiAgICB2aWV3Qm94OiAndmlld0JveCcsXG4gICAgeGxpbmtBY3R1YXRlOiAneGxpbms6YWN0dWF0ZScsXG4gICAgeGxpbmtBcmNyb2xlOiAneGxpbms6YXJjcm9sZScsXG4gICAgeGxpbmtIcmVmOiAneGxpbms6aHJlZicsXG4gICAgeGxpbmtSb2xlOiAneGxpbms6cm9sZScsXG4gICAgeGxpbmtTaG93OiAneGxpbms6c2hvdycsXG4gICAgeGxpbmtUaXRsZTogJ3hsaW5rOnRpdGxlJyxcbiAgICB4bGlua1R5cGU6ICd4bGluazp0eXBlJyxcbiAgICB4bWxCYXNlOiAneG1sOmJhc2UnLFxuICAgIHhtbExhbmc6ICd4bWw6bGFuZycsXG4gICAgeG1sU3BhY2U6ICd4bWw6c3BhY2UnXG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU1ZHRE9NUHJvcGVydHlDb25maWc7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFNlbGVjdEV2ZW50UGx1Z2luXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnRDb25zdGFudHMgPSByZXF1aXJlKCcuL0V2ZW50Q29uc3RhbnRzJyk7XG52YXIgRXZlbnRQcm9wYWdhdG9ycyA9IHJlcXVpcmUoJy4vRXZlbnRQcm9wYWdhdG9ycycpO1xudmFyIEV4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnZmJqcy9saWIvRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcbnZhciBSZWFjdElucHV0U2VsZWN0aW9uID0gcmVxdWlyZSgnLi9SZWFjdElucHV0U2VsZWN0aW9uJyk7XG52YXIgU3ludGhldGljRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0V2ZW50Jyk7XG5cbnZhciBnZXRBY3RpdmVFbGVtZW50ID0gcmVxdWlyZSgnZmJqcy9saWIvZ2V0QWN0aXZlRWxlbWVudCcpO1xudmFyIGlzVGV4dElucHV0RWxlbWVudCA9IHJlcXVpcmUoJy4vaXNUZXh0SW5wdXRFbGVtZW50Jyk7XG52YXIga2V5T2YgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlPZicpO1xudmFyIHNoYWxsb3dFcXVhbCA9IHJlcXVpcmUoJ2ZianMvbGliL3NoYWxsb3dFcXVhbCcpO1xuXG52YXIgdG9wTGV2ZWxUeXBlcyA9IEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXM7XG5cbnZhciBza2lwU2VsZWN0aW9uQ2hhbmdlRXZlbnQgPSBFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00gJiYgJ2RvY3VtZW50TW9kZScgaW4gZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRNb2RlIDw9IDExO1xuXG52YXIgZXZlbnRUeXBlcyA9IHtcbiAgc2VsZWN0OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25TZWxlY3Q6IG51bGwgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblNlbGVjdENhcHR1cmU6IG51bGwgfSlcbiAgICB9LFxuICAgIGRlcGVuZGVuY2llczogW3RvcExldmVsVHlwZXMudG9wQmx1ciwgdG9wTGV2ZWxUeXBlcy50b3BDb250ZXh0TWVudSwgdG9wTGV2ZWxUeXBlcy50b3BGb2N1cywgdG9wTGV2ZWxUeXBlcy50b3BLZXlEb3duLCB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlRG93biwgdG9wTGV2ZWxUeXBlcy50b3BNb3VzZVVwLCB0b3BMZXZlbFR5cGVzLnRvcFNlbGVjdGlvbkNoYW5nZV1cbiAgfVxufTtcblxudmFyIGFjdGl2ZUVsZW1lbnQgPSBudWxsO1xudmFyIGFjdGl2ZUVsZW1lbnRJRCA9IG51bGw7XG52YXIgbGFzdFNlbGVjdGlvbiA9IG51bGw7XG52YXIgbW91c2VEb3duID0gZmFsc2U7XG5cbi8vIFRyYWNrIHdoZXRoZXIgYSBsaXN0ZW5lciBleGlzdHMgZm9yIHRoaXMgcGx1Z2luLiBJZiBub25lIGV4aXN0LCB3ZSBkb1xuLy8gbm90IGV4dHJhY3QgZXZlbnRzLlxudmFyIGhhc0xpc3RlbmVyID0gZmFsc2U7XG52YXIgT05fU0VMRUNUX0tFWSA9IGtleU9mKHsgb25TZWxlY3Q6IG51bGwgfSk7XG5cbi8qKlxuICogR2V0IGFuIG9iamVjdCB3aGljaCBpcyBhIHVuaXF1ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCBzZWxlY3Rpb24uXG4gKlxuICogVGhlIHJldHVybiB2YWx1ZSB3aWxsIG5vdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBub2RlcyBvciBicm93c2VycywgYnV0XG4gKiB0d28gaWRlbnRpY2FsIHNlbGVjdGlvbnMgb24gdGhlIHNhbWUgbm9kZSB3aWxsIHJldHVybiBpZGVudGljYWwgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG5vZGVcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqL1xuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uKG5vZGUpIHtcbiAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gbm9kZSAmJiBSZWFjdElucHV0U2VsZWN0aW9uLmhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhub2RlKSkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcbiAgICAgIGVuZDogbm9kZS5zZWxlY3Rpb25FbmRcbiAgICB9O1xuICB9IGVsc2UgaWYgKHdpbmRvdy5nZXRTZWxlY3Rpb24pIHtcbiAgICB2YXIgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIHJldHVybiB7XG4gICAgICBhbmNob3JOb2RlOiBzZWxlY3Rpb24uYW5jaG9yTm9kZSxcbiAgICAgIGFuY2hvck9mZnNldDogc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgIGZvY3VzTm9kZTogc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgIGZvY3VzT2Zmc2V0OiBzZWxlY3Rpb24uZm9jdXNPZmZzZXRcbiAgICB9O1xuICB9IGVsc2UgaWYgKGRvY3VtZW50LnNlbGVjdGlvbikge1xuICAgIHZhciByYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO1xuICAgIHJldHVybiB7XG4gICAgICBwYXJlbnRFbGVtZW50OiByYW5nZS5wYXJlbnRFbGVtZW50KCksXG4gICAgICB0ZXh0OiByYW5nZS50ZXh0LFxuICAgICAgdG9wOiByYW5nZS5ib3VuZGluZ1RvcCxcbiAgICAgIGxlZnQ6IHJhbmdlLmJvdW5kaW5nTGVmdFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBQb2xsIHNlbGVjdGlvbiB0byBzZWUgd2hldGhlciBpdCdzIGNoYW5nZWQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcmV0dXJuIHs/U3ludGhldGljRXZlbnR9XG4gKi9cbmZ1bmN0aW9uIGNvbnN0cnVjdFNlbGVjdEV2ZW50KG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAvLyBFbnN1cmUgd2UgaGF2ZSB0aGUgcmlnaHQgZWxlbWVudCwgYW5kIHRoYXQgdGhlIHVzZXIgaXMgbm90IGRyYWdnaW5nIGFcbiAgLy8gc2VsZWN0aW9uICh0aGlzIG1hdGNoZXMgbmF0aXZlIGBzZWxlY3RgIGV2ZW50IGJlaGF2aW9yKS4gSW4gSFRNTDUsIHNlbGVjdFxuICAvLyBmaXJlcyBvbmx5IG9uIGlucHV0IGFuZCB0ZXh0YXJlYSB0aHVzIGlmIHRoZXJlJ3Mgbm8gZm9jdXNlZCBlbGVtZW50IHdlXG4gIC8vIHdvbid0IGRpc3BhdGNoLlxuICBpZiAobW91c2VEb3duIHx8IGFjdGl2ZUVsZW1lbnQgPT0gbnVsbCB8fCBhY3RpdmVFbGVtZW50ICE9PSBnZXRBY3RpdmVFbGVtZW50KCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIE9ubHkgZmlyZSB3aGVuIHNlbGVjdGlvbiBoYXMgYWN0dWFsbHkgY2hhbmdlZC5cbiAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb24oYWN0aXZlRWxlbWVudCk7XG4gIGlmICghbGFzdFNlbGVjdGlvbiB8fCAhc2hhbGxvd0VxdWFsKGxhc3RTZWxlY3Rpb24sIGN1cnJlbnRTZWxlY3Rpb24pKSB7XG4gICAgbGFzdFNlbGVjdGlvbiA9IGN1cnJlbnRTZWxlY3Rpb247XG5cbiAgICB2YXIgc3ludGhldGljRXZlbnQgPSBTeW50aGV0aWNFdmVudC5nZXRQb29sZWQoZXZlbnRUeXBlcy5zZWxlY3QsIGFjdGl2ZUVsZW1lbnRJRCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICAgIHN5bnRoZXRpY0V2ZW50LnR5cGUgPSAnc2VsZWN0JztcbiAgICBzeW50aGV0aWNFdmVudC50YXJnZXQgPSBhY3RpdmVFbGVtZW50O1xuXG4gICAgRXZlbnRQcm9wYWdhdG9ycy5hY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzKHN5bnRoZXRpY0V2ZW50KTtcblxuICAgIHJldHVybiBzeW50aGV0aWNFdmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFRoaXMgcGx1Z2luIGNyZWF0ZXMgYW4gYG9uU2VsZWN0YCBldmVudCB0aGF0IG5vcm1hbGl6ZXMgc2VsZWN0IGV2ZW50c1xuICogYWNyb3NzIGZvcm0gZWxlbWVudHMuXG4gKlxuICogU3VwcG9ydGVkIGVsZW1lbnRzIGFyZTpcbiAqIC0gaW5wdXQgKHNlZSBgaXNUZXh0SW5wdXRFbGVtZW50YClcbiAqIC0gdGV4dGFyZWFcbiAqIC0gY29udGVudEVkaXRhYmxlXG4gKlxuICogVGhpcyBkaWZmZXJzIGZyb20gbmF0aXZlIGJyb3dzZXIgaW1wbGVtZW50YXRpb25zIGluIHRoZSBmb2xsb3dpbmcgd2F5czpcbiAqIC0gRmlyZXMgb24gY29udGVudEVkaXRhYmxlIGZpZWxkcyBhcyB3ZWxsIGFzIGlucHV0cy5cbiAqIC0gRmlyZXMgZm9yIGNvbGxhcHNlZCBzZWxlY3Rpb24uXG4gKiAtIEZpcmVzIGFmdGVyIHVzZXIgaW5wdXQuXG4gKi9cbnZhciBTZWxlY3RFdmVudFBsdWdpbiA9IHtcblxuICBldmVudFR5cGVzOiBldmVudFR5cGVzLFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUeXBlIFJlY29yZCBmcm9tIGBFdmVudENvbnN0YW50c2AuXG4gICAqIEBwYXJhbSB7RE9NRXZlbnRUYXJnZXR9IHRvcExldmVsVGFyZ2V0IFRoZSBsaXN0ZW5pbmcgY29tcG9uZW50IHJvb3Qgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcExldmVsVGFyZ2V0SUQgSUQgb2YgYHRvcExldmVsVGFyZ2V0YC5cbiAgICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICAgKiBAcmV0dXJuIHsqfSBBbiBhY2N1bXVsYXRpb24gb2Ygc3ludGhldGljIGV2ZW50cy5cbiAgICogQHNlZSB7RXZlbnRQbHVnaW5IdWIuZXh0cmFjdEV2ZW50c31cbiAgICovXG4gIGV4dHJhY3RFdmVudHM6IGZ1bmN0aW9uICh0b3BMZXZlbFR5cGUsIHRvcExldmVsVGFyZ2V0LCB0b3BMZXZlbFRhcmdldElELCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICBpZiAoIWhhc0xpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRvcExldmVsVHlwZSkge1xuICAgICAgLy8gVHJhY2sgdGhlIGlucHV0IG5vZGUgdGhhdCBoYXMgZm9jdXMuXG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRm9jdXM6XG4gICAgICAgIGlmIChpc1RleHRJbnB1dEVsZW1lbnQodG9wTGV2ZWxUYXJnZXQpIHx8IHRvcExldmVsVGFyZ2V0LmNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgYWN0aXZlRWxlbWVudCA9IHRvcExldmVsVGFyZ2V0O1xuICAgICAgICAgIGFjdGl2ZUVsZW1lbnRJRCA9IHRvcExldmVsVGFyZ2V0SUQ7XG4gICAgICAgICAgbGFzdFNlbGVjdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQmx1cjpcbiAgICAgICAgYWN0aXZlRWxlbWVudCA9IG51bGw7XG4gICAgICAgIGFjdGl2ZUVsZW1lbnRJRCA9IG51bGw7XG4gICAgICAgIGxhc3RTZWxlY3Rpb24gPSBudWxsO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gRG9uJ3QgZmlyZSB0aGUgZXZlbnQgd2hpbGUgdGhlIHVzZXIgaXMgZHJhZ2dpbmcuIFRoaXMgbWF0Y2hlcyB0aGVcbiAgICAgIC8vIHNlbWFudGljcyBvZiB0aGUgbmF0aXZlIHNlbGVjdCBldmVudC5cbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BNb3VzZURvd246XG4gICAgICAgIG1vdXNlRG93biA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcENvbnRleHRNZW51OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlVXA6XG4gICAgICAgIG1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gY29uc3RydWN0U2VsZWN0RXZlbnQobmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICAgICAgLy8gQ2hyb21lIGFuZCBJRSBmaXJlIG5vbi1zdGFuZGFyZCBldmVudCB3aGVuIHNlbGVjdGlvbiBpcyBjaGFuZ2VkIChhbmRcbiAgICAgIC8vIHNvbWV0aW1lcyB3aGVuIGl0IGhhc24ndCkuIElFJ3MgZXZlbnQgZmlyZXMgb3V0IG9mIG9yZGVyIHdpdGggcmVzcGVjdFxuICAgICAgLy8gdG8ga2V5IGFuZCBpbnB1dCBldmVudHMgb24gZGVsZXRpb24sIHNvIHdlIGRpc2NhcmQgaXQuXG4gICAgICAvL1xuICAgICAgLy8gRmlyZWZveCBkb2Vzbid0IHN1cHBvcnQgc2VsZWN0aW9uY2hhbmdlLCBzbyBjaGVjayBzZWxlY3Rpb24gc3RhdHVzXG4gICAgICAvLyBhZnRlciBlYWNoIGtleSBlbnRyeS4gVGhlIHNlbGVjdGlvbiBjaGFuZ2VzIGFmdGVyIGtleWRvd24gYW5kIGJlZm9yZVxuICAgICAgLy8ga2V5dXAsIGJ1dCB3ZSBjaGVjayBvbiBrZXlkb3duIGFzIHdlbGwgaW4gdGhlIGNhc2Ugb2YgaG9sZGluZyBkb3duIGFcbiAgICAgIC8vIGtleSwgd2hlbiBtdWx0aXBsZSBrZXlkb3duIGV2ZW50cyBhcmUgZmlyZWQgYnV0IG9ubHkgb25lIGtleXVwIGlzLlxuICAgICAgLy8gVGhpcyBpcyBhbHNvIG91ciBhcHByb2FjaCBmb3IgSUUgaGFuZGxpbmcsIGZvciB0aGUgcmVhc29uIGFib3ZlLlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFNlbGVjdGlvbkNoYW5nZTpcbiAgICAgICAgaWYgKHNraXBTZWxlY3Rpb25DaGFuZ2VFdmVudCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wS2V5RG93bjpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BLZXlVcDpcbiAgICAgICAgcmV0dXJuIGNvbnN0cnVjdFNlbGVjdEV2ZW50KG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG5cbiAgZGlkUHV0TGlzdGVuZXI6IGZ1bmN0aW9uIChpZCwgcmVnaXN0cmF0aW9uTmFtZSwgbGlzdGVuZXIpIHtcbiAgICBpZiAocmVnaXN0cmF0aW9uTmFtZSA9PT0gT05fU0VMRUNUX0tFWSkge1xuICAgICAgaGFzTGlzdGVuZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTZWxlY3RFdmVudFBsdWdpbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgU2VydmVyUmVhY3RSb290SW5kZXhcbiAqIEB0eXBlY2hlY2tzXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFNpemUgb2YgdGhlIHJlYWN0Um9vdCBJRCBzcGFjZS4gV2UgZ2VuZXJhdGUgcmFuZG9tIG51bWJlcnMgZm9yIFJlYWN0IHJvb3RcbiAqIElEcyBhbmQgaWYgdGhlcmUncyBhIGNvbGxpc2lvbiB0aGUgZXZlbnRzIGFuZCBET00gdXBkYXRlIHN5c3RlbSB3aWxsXG4gKiBnZXQgY29uZnVzZWQuIEluIHRoZSBmdXR1cmUgd2UgbmVlZCBhIHdheSB0byBnZW5lcmF0ZSBHVUlEcyBidXQgZm9yXG4gKiBub3cgdGhpcyB3aWxsIHdvcmsgb24gYSBzbWFsbGVyIHNjYWxlLlxuICovXG52YXIgR0xPQkFMX01PVU5UX1BPSU5UX01BWCA9IE1hdGgucG93KDIsIDUzKTtcblxudmFyIFNlcnZlclJlYWN0Um9vdEluZGV4ID0ge1xuICBjcmVhdGVSZWFjdFJvb3RJbmRleDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwoTWF0aC5yYW5kb20oKSAqIEdMT0JBTF9NT1VOVF9QT0lOVF9NQVgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcnZlclJlYWN0Um9vdEluZGV4OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBTaW1wbGVFdmVudFBsdWdpblxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIEV2ZW50Q29uc3RhbnRzID0gcmVxdWlyZSgnLi9FdmVudENvbnN0YW50cycpO1xudmFyIEV2ZW50TGlzdGVuZXIgPSByZXF1aXJlKCdmYmpzL2xpYi9FdmVudExpc3RlbmVyJyk7XG52YXIgRXZlbnRQcm9wYWdhdG9ycyA9IHJlcXVpcmUoJy4vRXZlbnRQcm9wYWdhdG9ycycpO1xudmFyIFJlYWN0TW91bnQgPSByZXF1aXJlKCcuL1JlYWN0TW91bnQnKTtcbnZhciBTeW50aGV0aWNDbGlwYm9hcmRFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljQ2xpcGJvYXJkRXZlbnQnKTtcbnZhciBTeW50aGV0aWNFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljRXZlbnQnKTtcbnZhciBTeW50aGV0aWNGb2N1c0V2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNGb2N1c0V2ZW50Jyk7XG52YXIgU3ludGhldGljS2V5Ym9hcmRFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljS2V5Ym9hcmRFdmVudCcpO1xudmFyIFN5bnRoZXRpY01vdXNlRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY01vdXNlRXZlbnQnKTtcbnZhciBTeW50aGV0aWNEcmFnRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0RyYWdFdmVudCcpO1xudmFyIFN5bnRoZXRpY1RvdWNoRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY1RvdWNoRXZlbnQnKTtcbnZhciBTeW50aGV0aWNVSUV2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNVSUV2ZW50Jyk7XG52YXIgU3ludGhldGljV2hlZWxFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljV2hlZWxFdmVudCcpO1xuXG52YXIgZW1wdHlGdW5jdGlvbiA9IHJlcXVpcmUoJ2ZianMvbGliL2VtcHR5RnVuY3Rpb24nKTtcbnZhciBnZXRFdmVudENoYXJDb2RlID0gcmVxdWlyZSgnLi9nZXRFdmVudENoYXJDb2RlJyk7XG52YXIgaW52YXJpYW50ID0gcmVxdWlyZSgnZmJqcy9saWIvaW52YXJpYW50Jyk7XG52YXIga2V5T2YgPSByZXF1aXJlKCdmYmpzL2xpYi9rZXlPZicpO1xuXG52YXIgdG9wTGV2ZWxUeXBlcyA9IEV2ZW50Q29uc3RhbnRzLnRvcExldmVsVHlwZXM7XG5cbnZhciBldmVudFR5cGVzID0ge1xuICBhYm9ydDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uQWJvcnQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkFib3J0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgYmx1cjoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uQmx1cjogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uQmx1ckNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGNhblBsYXk6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkNhblBsYXk6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkNhblBsYXlDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBjYW5QbGF5VGhyb3VnaDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uQ2FuUGxheVRocm91Z2g6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkNhblBsYXlUaHJvdWdoQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgY2xpY2s6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkNsaWNrOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25DbGlja0NhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGNvbnRleHRNZW51OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Db250ZXh0TWVudTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uQ29udGV4dE1lbnVDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBjb3B5OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Db3B5OiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Db3B5Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgY3V0OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25DdXQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkN1dENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGRvdWJsZUNsaWNrOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Eb3VibGVDbGljazogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRG91YmxlQ2xpY2tDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBkcmFnOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25EcmFnOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25EcmFnQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgZHJhZ0VuZDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uRHJhZ0VuZDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRHJhZ0VuZENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGRyYWdFbnRlcjoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uRHJhZ0VudGVyOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25EcmFnRW50ZXJDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBkcmFnRXhpdDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uRHJhZ0V4aXQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkRyYWdFeGl0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgZHJhZ0xlYXZlOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25EcmFnTGVhdmU6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkRyYWdMZWF2ZUNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGRyYWdPdmVyOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25EcmFnT3ZlcjogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRHJhZ092ZXJDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBkcmFnU3RhcnQ6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkRyYWdTdGFydDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRHJhZ1N0YXJ0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgZHJvcDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uRHJvcDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRHJvcENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGR1cmF0aW9uQ2hhbmdlOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25EdXJhdGlvbkNoYW5nZTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRHVyYXRpb25DaGFuZ2VDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBlbXB0aWVkOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25FbXB0aWVkOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25FbXB0aWVkQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgZW5jcnlwdGVkOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25FbmNyeXB0ZWQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkVuY3J5cHRlZENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGVuZGVkOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25FbmRlZDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uRW5kZWRDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBlcnJvcjoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uRXJyb3I6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbkVycm9yQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgZm9jdXM6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkZvY3VzOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Gb2N1c0NhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGlucHV0OiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25JbnB1dDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uSW5wdXRDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBrZXlEb3duOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25LZXlEb3duOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25LZXlEb3duQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAga2V5UHJlc3M6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbktleVByZXNzOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25LZXlQcmVzc0NhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGtleVVwOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25LZXlVcDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uS2V5VXBDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBsb2FkOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Mb2FkOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Mb2FkQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgbG9hZGVkRGF0YToge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uTG9hZGVkRGF0YTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uTG9hZGVkRGF0YUNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIGxvYWRlZE1ldGFkYXRhOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Mb2FkZWRNZXRhZGF0YTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uTG9hZGVkTWV0YWRhdGFDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBsb2FkU3RhcnQ6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbkxvYWRTdGFydDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uTG9hZFN0YXJ0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgLy8gTm90ZTogV2UgZG8gbm90IGFsbG93IGxpc3RlbmluZyB0byBtb3VzZU92ZXIgZXZlbnRzLiBJbnN0ZWFkLCB1c2UgdGhlXG4gIC8vIG9uTW91c2VFbnRlci9vbk1vdXNlTGVhdmUgY3JlYXRlZCBieSBgRW50ZXJMZWF2ZUV2ZW50UGx1Z2luYC5cbiAgbW91c2VEb3duOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Nb3VzZURvd246IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbk1vdXNlRG93bkNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIG1vdXNlTW92ZToge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uTW91c2VNb3ZlOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Nb3VzZU1vdmVDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBtb3VzZU91dDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uTW91c2VPdXQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbk1vdXNlT3V0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgbW91c2VPdmVyOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Nb3VzZU92ZXI6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbk1vdXNlT3ZlckNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIG1vdXNlVXA6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvbk1vdXNlVXA6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvbk1vdXNlVXBDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBwYXN0ZToge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uUGFzdGU6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblBhc3RlQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgcGF1c2U6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblBhdXNlOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25QYXVzZUNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHBsYXk6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblBsYXk6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblBsYXlDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBwbGF5aW5nOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25QbGF5aW5nOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25QbGF5aW5nQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgcHJvZ3Jlc3M6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblByb2dyZXNzOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25Qcm9ncmVzc0NhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHJhdGVDaGFuZ2U6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblJhdGVDaGFuZ2U6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblJhdGVDaGFuZ2VDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICByZXNldDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uUmVzZXQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblJlc2V0Q2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgc2Nyb2xsOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25TY3JvbGw6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblNjcm9sbENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHNlZWtlZDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uU2Vla2VkOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25TZWVrZWRDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBzZWVraW5nOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25TZWVraW5nOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25TZWVraW5nQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgc3RhbGxlZDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uU3RhbGxlZDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uU3RhbGxlZENhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHN1Ym1pdDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uU3VibWl0OiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25TdWJtaXRDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICBzdXNwZW5kOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25TdXNwZW5kOiB0cnVlIH0pLFxuICAgICAgY2FwdHVyZWQ6IGtleU9mKHsgb25TdXNwZW5kQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgdGltZVVwZGF0ZToge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uVGltZVVwZGF0ZTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uVGltZVVwZGF0ZUNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHRvdWNoQ2FuY2VsOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Ub3VjaENhbmNlbDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uVG91Y2hDYW5jZWxDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICB0b3VjaEVuZDoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uVG91Y2hFbmQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblRvdWNoRW5kQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgdG91Y2hNb3ZlOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25Ub3VjaE1vdmU6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblRvdWNoTW92ZUNhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHRvdWNoU3RhcnQ6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblRvdWNoU3RhcnQ6IHRydWUgfSksXG4gICAgICBjYXB0dXJlZDoga2V5T2YoeyBvblRvdWNoU3RhcnRDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9LFxuICB2b2x1bWVDaGFuZ2U6IHtcbiAgICBwaGFzZWRSZWdpc3RyYXRpb25OYW1lczoge1xuICAgICAgYnViYmxlZDoga2V5T2YoeyBvblZvbHVtZUNoYW5nZTogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uVm9sdW1lQ2hhbmdlQ2FwdHVyZTogdHJ1ZSB9KVxuICAgIH1cbiAgfSxcbiAgd2FpdGluZzoge1xuICAgIHBoYXNlZFJlZ2lzdHJhdGlvbk5hbWVzOiB7XG4gICAgICBidWJibGVkOiBrZXlPZih7IG9uV2FpdGluZzogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uV2FpdGluZ0NhcHR1cmU6IHRydWUgfSlcbiAgICB9XG4gIH0sXG4gIHdoZWVsOiB7XG4gICAgcGhhc2VkUmVnaXN0cmF0aW9uTmFtZXM6IHtcbiAgICAgIGJ1YmJsZWQ6IGtleU9mKHsgb25XaGVlbDogdHJ1ZSB9KSxcbiAgICAgIGNhcHR1cmVkOiBrZXlPZih7IG9uV2hlZWxDYXB0dXJlOiB0cnVlIH0pXG4gICAgfVxuICB9XG59O1xuXG52YXIgdG9wTGV2ZWxFdmVudHNUb0Rpc3BhdGNoQ29uZmlnID0ge1xuICB0b3BBYm9ydDogZXZlbnRUeXBlcy5hYm9ydCxcbiAgdG9wQmx1cjogZXZlbnRUeXBlcy5ibHVyLFxuICB0b3BDYW5QbGF5OiBldmVudFR5cGVzLmNhblBsYXksXG4gIHRvcENhblBsYXlUaHJvdWdoOiBldmVudFR5cGVzLmNhblBsYXlUaHJvdWdoLFxuICB0b3BDbGljazogZXZlbnRUeXBlcy5jbGljayxcbiAgdG9wQ29udGV4dE1lbnU6IGV2ZW50VHlwZXMuY29udGV4dE1lbnUsXG4gIHRvcENvcHk6IGV2ZW50VHlwZXMuY29weSxcbiAgdG9wQ3V0OiBldmVudFR5cGVzLmN1dCxcbiAgdG9wRG91YmxlQ2xpY2s6IGV2ZW50VHlwZXMuZG91YmxlQ2xpY2ssXG4gIHRvcERyYWc6IGV2ZW50VHlwZXMuZHJhZyxcbiAgdG9wRHJhZ0VuZDogZXZlbnRUeXBlcy5kcmFnRW5kLFxuICB0b3BEcmFnRW50ZXI6IGV2ZW50VHlwZXMuZHJhZ0VudGVyLFxuICB0b3BEcmFnRXhpdDogZXZlbnRUeXBlcy5kcmFnRXhpdCxcbiAgdG9wRHJhZ0xlYXZlOiBldmVudFR5cGVzLmRyYWdMZWF2ZSxcbiAgdG9wRHJhZ092ZXI6IGV2ZW50VHlwZXMuZHJhZ092ZXIsXG4gIHRvcERyYWdTdGFydDogZXZlbnRUeXBlcy5kcmFnU3RhcnQsXG4gIHRvcERyb3A6IGV2ZW50VHlwZXMuZHJvcCxcbiAgdG9wRHVyYXRpb25DaGFuZ2U6IGV2ZW50VHlwZXMuZHVyYXRpb25DaGFuZ2UsXG4gIHRvcEVtcHRpZWQ6IGV2ZW50VHlwZXMuZW1wdGllZCxcbiAgdG9wRW5jcnlwdGVkOiBldmVudFR5cGVzLmVuY3J5cHRlZCxcbiAgdG9wRW5kZWQ6IGV2ZW50VHlwZXMuZW5kZWQsXG4gIHRvcEVycm9yOiBldmVudFR5cGVzLmVycm9yLFxuICB0b3BGb2N1czogZXZlbnRUeXBlcy5mb2N1cyxcbiAgdG9wSW5wdXQ6IGV2ZW50VHlwZXMuaW5wdXQsXG4gIHRvcEtleURvd246IGV2ZW50VHlwZXMua2V5RG93bixcbiAgdG9wS2V5UHJlc3M6IGV2ZW50VHlwZXMua2V5UHJlc3MsXG4gIHRvcEtleVVwOiBldmVudFR5cGVzLmtleVVwLFxuICB0b3BMb2FkOiBldmVudFR5cGVzLmxvYWQsXG4gIHRvcExvYWRlZERhdGE6IGV2ZW50VHlwZXMubG9hZGVkRGF0YSxcbiAgdG9wTG9hZGVkTWV0YWRhdGE6IGV2ZW50VHlwZXMubG9hZGVkTWV0YWRhdGEsXG4gIHRvcExvYWRTdGFydDogZXZlbnRUeXBlcy5sb2FkU3RhcnQsXG4gIHRvcE1vdXNlRG93bjogZXZlbnRUeXBlcy5tb3VzZURvd24sXG4gIHRvcE1vdXNlTW92ZTogZXZlbnRUeXBlcy5tb3VzZU1vdmUsXG4gIHRvcE1vdXNlT3V0OiBldmVudFR5cGVzLm1vdXNlT3V0LFxuICB0b3BNb3VzZU92ZXI6IGV2ZW50VHlwZXMubW91c2VPdmVyLFxuICB0b3BNb3VzZVVwOiBldmVudFR5cGVzLm1vdXNlVXAsXG4gIHRvcFBhc3RlOiBldmVudFR5cGVzLnBhc3RlLFxuICB0b3BQYXVzZTogZXZlbnRUeXBlcy5wYXVzZSxcbiAgdG9wUGxheTogZXZlbnRUeXBlcy5wbGF5LFxuICB0b3BQbGF5aW5nOiBldmVudFR5cGVzLnBsYXlpbmcsXG4gIHRvcFByb2dyZXNzOiBldmVudFR5cGVzLnByb2dyZXNzLFxuICB0b3BSYXRlQ2hhbmdlOiBldmVudFR5cGVzLnJhdGVDaGFuZ2UsXG4gIHRvcFJlc2V0OiBldmVudFR5cGVzLnJlc2V0LFxuICB0b3BTY3JvbGw6IGV2ZW50VHlwZXMuc2Nyb2xsLFxuICB0b3BTZWVrZWQ6IGV2ZW50VHlwZXMuc2Vla2VkLFxuICB0b3BTZWVraW5nOiBldmVudFR5cGVzLnNlZWtpbmcsXG4gIHRvcFN0YWxsZWQ6IGV2ZW50VHlwZXMuc3RhbGxlZCxcbiAgdG9wU3VibWl0OiBldmVudFR5cGVzLnN1Ym1pdCxcbiAgdG9wU3VzcGVuZDogZXZlbnRUeXBlcy5zdXNwZW5kLFxuICB0b3BUaW1lVXBkYXRlOiBldmVudFR5cGVzLnRpbWVVcGRhdGUsXG4gIHRvcFRvdWNoQ2FuY2VsOiBldmVudFR5cGVzLnRvdWNoQ2FuY2VsLFxuICB0b3BUb3VjaEVuZDogZXZlbnRUeXBlcy50b3VjaEVuZCxcbiAgdG9wVG91Y2hNb3ZlOiBldmVudFR5cGVzLnRvdWNoTW92ZSxcbiAgdG9wVG91Y2hTdGFydDogZXZlbnRUeXBlcy50b3VjaFN0YXJ0LFxuICB0b3BWb2x1bWVDaGFuZ2U6IGV2ZW50VHlwZXMudm9sdW1lQ2hhbmdlLFxuICB0b3BXYWl0aW5nOiBldmVudFR5cGVzLndhaXRpbmcsXG4gIHRvcFdoZWVsOiBldmVudFR5cGVzLndoZWVsXG59O1xuXG5mb3IgKHZhciB0eXBlIGluIHRvcExldmVsRXZlbnRzVG9EaXNwYXRjaENvbmZpZykge1xuICB0b3BMZXZlbEV2ZW50c1RvRGlzcGF0Y2hDb25maWdbdHlwZV0uZGVwZW5kZW5jaWVzID0gW3R5cGVdO1xufVxuXG52YXIgT05fQ0xJQ0tfS0VZID0ga2V5T2YoeyBvbkNsaWNrOiBudWxsIH0pO1xudmFyIG9uQ2xpY2tMaXN0ZW5lcnMgPSB7fTtcblxudmFyIFNpbXBsZUV2ZW50UGx1Z2luID0ge1xuXG4gIGV2ZW50VHlwZXM6IGV2ZW50VHlwZXMsXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZXZlbFR5cGUgUmVjb3JkIGZyb20gYEV2ZW50Q29uc3RhbnRzYC5cbiAgICogQHBhcmFtIHtET01FdmVudFRhcmdldH0gdG9wTGV2ZWxUYXJnZXQgVGhlIGxpc3RlbmluZyBjb21wb25lbnQgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9wTGV2ZWxUYXJnZXRJRCBJRCBvZiBgdG9wTGV2ZWxUYXJnZXRgLlxuICAgKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4geyp9IEFuIGFjY3VtdWxhdGlvbiBvZiBzeW50aGV0aWMgZXZlbnRzLlxuICAgKiBAc2VlIHtFdmVudFBsdWdpbkh1Yi5leHRyYWN0RXZlbnRzfVxuICAgKi9cbiAgZXh0cmFjdEV2ZW50czogZnVuY3Rpb24gKHRvcExldmVsVHlwZSwgdG9wTGV2ZWxUYXJnZXQsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIHZhciBkaXNwYXRjaENvbmZpZyA9IHRvcExldmVsRXZlbnRzVG9EaXNwYXRjaENvbmZpZ1t0b3BMZXZlbFR5cGVdO1xuICAgIGlmICghZGlzcGF0Y2hDb25maWcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgRXZlbnRDb25zdHJ1Y3RvcjtcbiAgICBzd2l0Y2ggKHRvcExldmVsVHlwZSkge1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcEFib3J0OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcENhblBsYXk6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ2FuUGxheVRocm91Z2g6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRHVyYXRpb25DaGFuZ2U6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRW1wdGllZDpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BFbmNyeXB0ZWQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRW5kZWQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRXJyb3I6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wSW5wdXQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wTG9hZDpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BMb2FkZWREYXRhOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcExvYWRlZE1ldGFkYXRhOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcExvYWRTdGFydDpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BQYXVzZTpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BQbGF5OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFBsYXlpbmc6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wUHJvZ3Jlc3M6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wUmF0ZUNoYW5nZTpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BSZXNldDpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BTZWVrZWQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wU2Vla2luZzpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BTdGFsbGVkOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFN1Ym1pdDpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BTdXNwZW5kOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFRpbWVVcGRhdGU6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wVm9sdW1lQ2hhbmdlOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFdhaXRpbmc6XG4gICAgICAgIC8vIEhUTUwgRXZlbnRzXG4gICAgICAgIC8vIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvaW5kZXguaHRtbCNldmVudHMtMFxuICAgICAgICBFdmVudENvbnN0cnVjdG9yID0gU3ludGhldGljRXZlbnQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcEtleVByZXNzOlxuICAgICAgICAvLyBGaXJlRm94IGNyZWF0ZXMgYSBrZXlwcmVzcyBldmVudCBmb3IgZnVuY3Rpb24ga2V5cyB0b28uIFRoaXMgcmVtb3Zlc1xuICAgICAgICAvLyB0aGUgdW53YW50ZWQga2V5cHJlc3MgZXZlbnRzLiBFbnRlciBpcyBob3dldmVyIGJvdGggcHJpbnRhYmxlIGFuZFxuICAgICAgICAvLyBub24tcHJpbnRhYmxlLiBPbmUgd291bGQgZXhwZWN0IFRhYiB0byBiZSBhcyB3ZWxsIChidXQgaXQgaXNuJ3QpLlxuICAgICAgICBpZiAoZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCkgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcEtleURvd246XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wS2V5VXA6XG4gICAgICAgIEV2ZW50Q29uc3RydWN0b3IgPSBTeW50aGV0aWNLZXlib2FyZEV2ZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BCbHVyOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcEZvY3VzOlxuICAgICAgICBFdmVudENvbnN0cnVjdG9yID0gU3ludGhldGljRm9jdXNFdmVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ2xpY2s6XG4gICAgICAgIC8vIEZpcmVmb3ggY3JlYXRlcyBhIGNsaWNrIGV2ZW50IG9uIHJpZ2h0IG1vdXNlIGNsaWNrcy4gVGhpcyByZW1vdmVzIHRoZVxuICAgICAgICAvLyB1bndhbnRlZCBjbGljayBldmVudHMuXG4gICAgICAgIGlmIChuYXRpdmVFdmVudC5idXR0b24gPT09IDIpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcENvbnRleHRNZW51OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcERvdWJsZUNsaWNrOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlRG93bjpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BNb3VzZU1vdmU6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wTW91c2VPdXQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wTW91c2VPdmVyOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcE1vdXNlVXA6XG4gICAgICAgIEV2ZW50Q29uc3RydWN0b3IgPSBTeW50aGV0aWNNb3VzZUV2ZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BEcmFnOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcERyYWdFbmQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRHJhZ0VudGVyOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcERyYWdFeGl0OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcERyYWdMZWF2ZTpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BEcmFnT3ZlcjpcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BEcmFnU3RhcnQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wRHJvcDpcbiAgICAgICAgRXZlbnRDb25zdHJ1Y3RvciA9IFN5bnRoZXRpY0RyYWdFdmVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wVG91Y2hDYW5jZWw6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wVG91Y2hFbmQ6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wVG91Y2hNb3ZlOlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFRvdWNoU3RhcnQ6XG4gICAgICAgIEV2ZW50Q29uc3RydWN0b3IgPSBTeW50aGV0aWNUb3VjaEV2ZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BTY3JvbGw6XG4gICAgICAgIEV2ZW50Q29uc3RydWN0b3IgPSBTeW50aGV0aWNVSUV2ZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdG9wTGV2ZWxUeXBlcy50b3BXaGVlbDpcbiAgICAgICAgRXZlbnRDb25zdHJ1Y3RvciA9IFN5bnRoZXRpY1doZWVsRXZlbnQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcENvcHk6XG4gICAgICBjYXNlIHRvcExldmVsVHlwZXMudG9wQ3V0OlxuICAgICAgY2FzZSB0b3BMZXZlbFR5cGVzLnRvcFBhc3RlOlxuICAgICAgICBFdmVudENvbnN0cnVjdG9yID0gU3ludGhldGljQ2xpcGJvYXJkRXZlbnQ7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICAhRXZlbnRDb25zdHJ1Y3RvciA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdTaW1wbGVFdmVudFBsdWdpbjogVW5oYW5kbGVkIGV2ZW50IHR5cGUsIGAlc2AuJywgdG9wTGV2ZWxUeXBlKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIGV2ZW50ID0gRXZlbnRDb25zdHJ1Y3Rvci5nZXRQb29sZWQoZGlzcGF0Y2hDb25maWcsIHRvcExldmVsVGFyZ2V0SUQsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgRXZlbnRQcm9wYWdhdG9ycy5hY2N1bXVsYXRlVHdvUGhhc2VEaXNwYXRjaGVzKGV2ZW50KTtcbiAgICByZXR1cm4gZXZlbnQ7XG4gIH0sXG5cbiAgZGlkUHV0TGlzdGVuZXI6IGZ1bmN0aW9uIChpZCwgcmVnaXN0cmF0aW9uTmFtZSwgbGlzdGVuZXIpIHtcbiAgICAvLyBNb2JpbGUgU2FmYXJpIGRvZXMgbm90IGZpcmUgcHJvcGVybHkgYnViYmxlIGNsaWNrIGV2ZW50cyBvblxuICAgIC8vIG5vbi1pbnRlcmFjdGl2ZSBlbGVtZW50cywgd2hpY2ggbWVhbnMgZGVsZWdhdGVkIGNsaWNrIGxpc3RlbmVycyBkbyBub3RcbiAgICAvLyBmaXJlLiBUaGUgd29ya2Fyb3VuZCBmb3IgdGhpcyBidWcgaW52b2x2ZXMgYXR0YWNoaW5nIGFuIGVtcHR5IGNsaWNrXG4gICAgLy8gbGlzdGVuZXIgb24gdGhlIHRhcmdldCBub2RlLlxuICAgIGlmIChyZWdpc3RyYXRpb25OYW1lID09PSBPTl9DTElDS19LRVkpIHtcbiAgICAgIHZhciBub2RlID0gUmVhY3RNb3VudC5nZXROb2RlKGlkKTtcbiAgICAgIGlmICghb25DbGlja0xpc3RlbmVyc1tpZF0pIHtcbiAgICAgICAgb25DbGlja0xpc3RlbmVyc1tpZF0gPSBFdmVudExpc3RlbmVyLmxpc3Rlbihub2RlLCAnY2xpY2snLCBlbXB0eUZ1bmN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgd2lsbERlbGV0ZUxpc3RlbmVyOiBmdW5jdGlvbiAoaWQsIHJlZ2lzdHJhdGlvbk5hbWUpIHtcbiAgICBpZiAocmVnaXN0cmF0aW9uTmFtZSA9PT0gT05fQ0xJQ0tfS0VZKSB7XG4gICAgICBvbkNsaWNrTGlzdGVuZXJzW2lkXS5yZW1vdmUoKTtcbiAgICAgIGRlbGV0ZSBvbkNsaWNrTGlzdGVuZXJzW2lkXTtcbiAgICB9XG4gIH1cblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTaW1wbGVFdmVudFBsdWdpbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgU3ludGhldGljQ2xpcGJvYXJkRXZlbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3ludGhldGljRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0V2ZW50Jyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9jbGlwYm9hcmQtYXBpcy9cbiAqL1xudmFyIENsaXBib2FyZEV2ZW50SW50ZXJmYWNlID0ge1xuICBjbGlwYm9hcmREYXRhOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gJ2NsaXBib2FyZERhdGEnIGluIGV2ZW50ID8gZXZlbnQuY2xpcGJvYXJkRGF0YSA6IHdpbmRvdy5jbGlwYm9hcmREYXRhO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBkaXNwYXRjaENvbmZpZyBDb25maWd1cmF0aW9uIHVzZWQgdG8gZGlzcGF0Y2ggdGhpcyBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXNwYXRjaE1hcmtlciBNYXJrZXIgaWRlbnRpZnlpbmcgdGhlIGV2ZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEBleHRlbmRzIHtTeW50aGV0aWNVSUV2ZW50fVxuICovXG5mdW5jdGlvbiBTeW50aGV0aWNDbGlwYm9hcmRFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNFdmVudC5jYWxsKHRoaXMsIGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbn1cblxuU3ludGhldGljRXZlbnQuYXVnbWVudENsYXNzKFN5bnRoZXRpY0NsaXBib2FyZEV2ZW50LCBDbGlwYm9hcmRFdmVudEludGVyZmFjZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ludGhldGljQ2xpcGJvYXJkRXZlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3ludGhldGljRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0V2ZW50Jyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1jb21wb3NpdGlvbmV2ZW50c1xuICovXG52YXIgQ29tcG9zaXRpb25FdmVudEludGVyZmFjZSA9IHtcbiAgZGF0YTogbnVsbFxufTtcblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgQ29uZmlndXJhdGlvbiB1c2VkIHRvIGRpc3BhdGNoIHRoaXMgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGF0Y2hNYXJrZXIgTWFya2VyIGlkZW50aWZ5aW5nIHRoZSBldmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAZXh0ZW5kcyB7U3ludGhldGljVUlFdmVudH1cbiAqL1xuZnVuY3Rpb24gU3ludGhldGljQ29tcG9zaXRpb25FdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNFdmVudC5jYWxsKHRoaXMsIGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbn1cblxuU3ludGhldGljRXZlbnQuYXVnbWVudENsYXNzKFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQsIENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFN5bnRoZXRpY0RyYWdFdmVudFxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTeW50aGV0aWNNb3VzZUV2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNNb3VzZUV2ZW50Jyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBEcmFnRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzL1xuICovXG52YXIgRHJhZ0V2ZW50SW50ZXJmYWNlID0ge1xuICBkYXRhVHJhbnNmZXI6IG51bGxcbn07XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IGRpc3BhdGNoQ29uZmlnIENvbmZpZ3VyYXRpb24gdXNlZCB0byBkaXNwYXRjaCB0aGlzIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGRpc3BhdGNoTWFya2VyIE1hcmtlciBpZGVudGlmeWluZyB0aGUgZXZlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQGV4dGVuZHMge1N5bnRoZXRpY1VJRXZlbnR9XG4gKi9cbmZ1bmN0aW9uIFN5bnRoZXRpY0RyYWdFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNNb3VzZUV2ZW50LmNhbGwodGhpcywgZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG5TeW50aGV0aWNNb3VzZUV2ZW50LmF1Z21lbnRDbGFzcyhTeW50aGV0aWNEcmFnRXZlbnQsIERyYWdFdmVudEludGVyZmFjZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ludGhldGljRHJhZ0V2ZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBTeW50aGV0aWNFdmVudFxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBQb29sZWRDbGFzcyA9IHJlcXVpcmUoJy4vUG9vbGVkQ2xhc3MnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGVtcHR5RnVuY3Rpb24gPSByZXF1aXJlKCdmYmpzL2xpYi9lbXB0eUZ1bmN0aW9uJyk7XG52YXIgd2FybmluZyA9IHJlcXVpcmUoJ2ZianMvbGliL3dhcm5pbmcnKTtcblxuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xudmFyIEV2ZW50SW50ZXJmYWNlID0ge1xuICB0eXBlOiBudWxsLFxuICB0YXJnZXQ6IG51bGwsXG4gIC8vIGN1cnJlbnRUYXJnZXQgaXMgc2V0IHdoZW4gZGlzcGF0Y2hpbmc7IG5vIHVzZSBpbiBjb3B5aW5nIGl0IGhlcmVcbiAgY3VycmVudFRhcmdldDogZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc051bGwsXG4gIGV2ZW50UGhhc2U6IG51bGwsXG4gIGJ1YmJsZXM6IG51bGwsXG4gIGNhbmNlbGFibGU6IG51bGwsXG4gIHRpbWVTdGFtcDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpO1xuICB9LFxuICBkZWZhdWx0UHJldmVudGVkOiBudWxsLFxuICBpc1RydXN0ZWQ6IG51bGxcbn07XG5cbi8qKlxuICogU3ludGhldGljIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZCBieSBldmVudCBwbHVnaW5zLCB0eXBpY2FsbHkgaW4gcmVzcG9uc2UgdG8gYVxuICogdG9wLWxldmVsIGV2ZW50IGRlbGVnYXRpb24gaGFuZGxlci5cbiAqXG4gKiBUaGVzZSBzeXN0ZW1zIHNob3VsZCBnZW5lcmFsbHkgdXNlIHBvb2xpbmcgdG8gcmVkdWNlIHRoZSBmcmVxdWVuY3kgb2YgZ2FyYmFnZVxuICogY29sbGVjdGlvbi4gVGhlIHN5c3RlbSBzaG91bGQgY2hlY2sgYGlzUGVyc2lzdGVudGAgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlXG4gKiBldmVudCBzaG91bGQgYmUgcmVsZWFzZWQgaW50byB0aGUgcG9vbCBhZnRlciBiZWluZyBkaXNwYXRjaGVkLiBVc2VycyB0aGF0XG4gKiBuZWVkIGEgcGVyc2lzdGVkIGV2ZW50IHNob3VsZCBpbnZva2UgYHBlcnNpc3RgLlxuICpcbiAqIFN5bnRoZXRpYyBldmVudHMgKGFuZCBzdWJjbGFzc2VzKSBpbXBsZW1lbnQgdGhlIERPTSBMZXZlbCAzIEV2ZW50cyBBUEkgYnlcbiAqIG5vcm1hbGl6aW5nIGJyb3dzZXIgcXVpcmtzLiBTdWJjbGFzc2VzIGRvIG5vdCBuZWNlc3NhcmlseSBoYXZlIHRvIGltcGxlbWVudCBhXG4gKiBET00gaW50ZXJmYWNlOyBjdXN0b20gYXBwbGljYXRpb24tc3BlY2lmaWMgZXZlbnRzIGNhbiBhbHNvIHN1YmNsYXNzIHRoaXMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IGRpc3BhdGNoQ29uZmlnIENvbmZpZ3VyYXRpb24gdXNlZCB0byBkaXNwYXRjaCB0aGlzIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGRpc3BhdGNoTWFya2VyIE1hcmtlciBpZGVudGlmeWluZyB0aGUgZXZlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICovXG5mdW5jdGlvbiBTeW50aGV0aWNFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICB0aGlzLmRpc3BhdGNoQ29uZmlnID0gZGlzcGF0Y2hDb25maWc7XG4gIHRoaXMuZGlzcGF0Y2hNYXJrZXIgPSBkaXNwYXRjaE1hcmtlcjtcbiAgdGhpcy5uYXRpdmVFdmVudCA9IG5hdGl2ZUV2ZW50O1xuXG4gIHZhciBJbnRlcmZhY2UgPSB0aGlzLmNvbnN0cnVjdG9yLkludGVyZmFjZTtcbiAgZm9yICh2YXIgcHJvcE5hbWUgaW4gSW50ZXJmYWNlKSB7XG4gICAgaWYgKCFJbnRlcmZhY2UuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIG5vcm1hbGl6ZSA9IEludGVyZmFjZVtwcm9wTmFtZV07XG4gICAgaWYgKG5vcm1hbGl6ZSkge1xuICAgICAgdGhpc1twcm9wTmFtZV0gPSBub3JtYWxpemUobmF0aXZlRXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocHJvcE5hbWUgPT09ICd0YXJnZXQnKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gbmF0aXZlRXZlbnRUYXJnZXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzW3Byb3BOYW1lXSA9IG5hdGl2ZUV2ZW50W3Byb3BOYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgZGVmYXVsdFByZXZlbnRlZCA9IG5hdGl2ZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgIT0gbnVsbCA/IG5hdGl2ZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgOiBuYXRpdmVFdmVudC5yZXR1cm5WYWx1ZSA9PT0gZmFsc2U7XG4gIGlmIChkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBlbXB0eUZ1bmN0aW9uLnRoYXRSZXR1cm5zVHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNGYWxzZTtcbiAgfVxuICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc0ZhbHNlO1xufVxuXG5hc3NpZ24oU3ludGhldGljRXZlbnQucHJvdG90eXBlLCB7XG5cbiAgcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgIHZhciBldmVudCA9IHRoaXMubmF0aXZlRXZlbnQ7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGV2ZW50LCAnVGhpcyBzeW50aGV0aWMgZXZlbnQgaXMgcmV1c2VkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLiBJZiB5b3VcXCdyZSAnICsgJ3NlZWluZyB0aGlzLCB5b3VcXCdyZSBjYWxsaW5nIGBwcmV2ZW50RGVmYXVsdGAgb24gYSAnICsgJ3JlbGVhc2VkL251bGxpZmllZCBzeW50aGV0aWMgZXZlbnQuIFRoaXMgaXMgYSBuby1vcC4gU2VlICcgKyAnaHR0cHM6Ly9mYi5tZS9yZWFjdC1ldmVudC1wb29saW5nIGZvciBtb3JlIGluZm9ybWF0aW9uLicpIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNUcnVlO1xuICB9LFxuXG4gIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24gKCkge1xuICAgIHZhciBldmVudCA9IHRoaXMubmF0aXZlRXZlbnQ7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGV2ZW50LCAnVGhpcyBzeW50aGV0aWMgZXZlbnQgaXMgcmV1c2VkIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLiBJZiB5b3VcXCdyZSAnICsgJ3NlZWluZyB0aGlzLCB5b3VcXCdyZSBjYWxsaW5nIGBzdG9wUHJvcGFnYXRpb25gIG9uIGEgJyArICdyZWxlYXNlZC9udWxsaWZpZWQgc3ludGhldGljIGV2ZW50LiBUaGlzIGlzIGEgbm8tb3AuIFNlZSAnICsgJ2h0dHBzOi8vZmIubWUvcmVhY3QtZXZlbnQtcG9vbGluZyBmb3IgbW9yZSBpbmZvcm1hdGlvbi4nKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKCFldmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZW1wdHlGdW5jdGlvbi50aGF0UmV0dXJuc1RydWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdlIHJlbGVhc2UgYWxsIGRpc3BhdGNoZWQgYFN5bnRoZXRpY0V2ZW50YHMgYWZ0ZXIgZWFjaCBldmVudCBsb29wLCBhZGRpbmdcbiAgICogdGhlbSBiYWNrIGludG8gdGhlIHBvb2wuIFRoaXMgYWxsb3dzIGEgd2F5IHRvIGhvbGQgb250byBhIHJlZmVyZW5jZSB0aGF0XG4gICAqIHdvbid0IGJlIGFkZGVkIGJhY2sgaW50byB0aGUgcG9vbC5cbiAgICovXG4gIHBlcnNpc3Q6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmlzUGVyc2lzdGVudCA9IGVtcHR5RnVuY3Rpb24udGhhdFJldHVybnNUcnVlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBldmVudCBzaG91bGQgYmUgcmVsZWFzZWQgYmFjayBpbnRvIHRoZSBwb29sLlxuICAgKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoaXMgc2hvdWxkIG5vdCBiZSByZWxlYXNlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNQZXJzaXN0ZW50OiBlbXB0eUZ1bmN0aW9uLnRoYXRSZXR1cm5zRmFsc2UsXG5cbiAgLyoqXG4gICAqIGBQb29sZWRDbGFzc2AgbG9va3MgZm9yIGBkZXN0cnVjdG9yYCBvbiBlYWNoIGluc3RhbmNlIGl0IHJlbGVhc2VzLlxuICAgKi9cbiAgZGVzdHJ1Y3RvcjogZnVuY3Rpb24gKCkge1xuICAgIHZhciBJbnRlcmZhY2UgPSB0aGlzLmNvbnN0cnVjdG9yLkludGVyZmFjZTtcbiAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBJbnRlcmZhY2UpIHtcbiAgICAgIHRoaXNbcHJvcE5hbWVdID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5kaXNwYXRjaENvbmZpZyA9IG51bGw7XG4gICAgdGhpcy5kaXNwYXRjaE1hcmtlciA9IG51bGw7XG4gICAgdGhpcy5uYXRpdmVFdmVudCA9IG51bGw7XG4gIH1cblxufSk7XG5cblN5bnRoZXRpY0V2ZW50LkludGVyZmFjZSA9IEV2ZW50SW50ZXJmYWNlO1xuXG4vKipcbiAqIEhlbHBlciB0byByZWR1Y2UgYm9pbGVycGxhdGUgd2hlbiBjcmVhdGluZyBzdWJjbGFzc2VzLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IENsYXNzXG4gKiBAcGFyYW0gez9vYmplY3R9IEludGVyZmFjZVxuICovXG5TeW50aGV0aWNFdmVudC5hdWdtZW50Q2xhc3MgPSBmdW5jdGlvbiAoQ2xhc3MsIEludGVyZmFjZSkge1xuICB2YXIgU3VwZXIgPSB0aGlzO1xuXG4gIHZhciBwcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN1cGVyLnByb3RvdHlwZSk7XG4gIGFzc2lnbihwcm90b3R5cGUsIENsYXNzLnByb3RvdHlwZSk7XG4gIENsYXNzLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgQ2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ2xhc3M7XG5cbiAgQ2xhc3MuSW50ZXJmYWNlID0gYXNzaWduKHt9LCBTdXBlci5JbnRlcmZhY2UsIEludGVyZmFjZSk7XG4gIENsYXNzLmF1Z21lbnRDbGFzcyA9IFN1cGVyLmF1Z21lbnRDbGFzcztcblxuICBQb29sZWRDbGFzcy5hZGRQb29saW5nVG8oQ2xhc3MsIFBvb2xlZENsYXNzLmZvdXJBcmd1bWVudFBvb2xlcik7XG59O1xuXG5Qb29sZWRDbGFzcy5hZGRQb29saW5nVG8oU3ludGhldGljRXZlbnQsIFBvb2xlZENsYXNzLmZvdXJBcmd1bWVudFBvb2xlcik7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ludGhldGljRXZlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFN5bnRoZXRpY0ZvY3VzRXZlbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3ludGhldGljVUlFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljVUlFdmVudCcpO1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgRm9jdXNFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cbnZhciBGb2N1c0V2ZW50SW50ZXJmYWNlID0ge1xuICByZWxhdGVkVGFyZ2V0OiBudWxsXG59O1xuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBkaXNwYXRjaENvbmZpZyBDb25maWd1cmF0aW9uIHVzZWQgdG8gZGlzcGF0Y2ggdGhpcyBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXNwYXRjaE1hcmtlciBNYXJrZXIgaWRlbnRpZnlpbmcgdGhlIGV2ZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEBleHRlbmRzIHtTeW50aGV0aWNVSUV2ZW50fVxuICovXG5mdW5jdGlvbiBTeW50aGV0aWNGb2N1c0V2ZW50KGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIFN5bnRoZXRpY1VJRXZlbnQuY2FsbCh0aGlzLCBkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG59XG5cblN5bnRoZXRpY1VJRXZlbnQuYXVnbWVudENsYXNzKFN5bnRoZXRpY0ZvY3VzRXZlbnQsIEZvY3VzRXZlbnRJbnRlcmZhY2UpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFN5bnRoZXRpY0lucHV0RXZlbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3ludGhldGljRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY0V2ZW50Jyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDEzMTEwNVxuICogICAgICAvI2V2ZW50cy1pbnB1dGV2ZW50c1xuICovXG52YXIgSW5wdXRFdmVudEludGVyZmFjZSA9IHtcbiAgZGF0YTogbnVsbFxufTtcblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgQ29uZmlndXJhdGlvbiB1c2VkIHRvIGRpc3BhdGNoIHRoaXMgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGF0Y2hNYXJrZXIgTWFya2VyIGlkZW50aWZ5aW5nIHRoZSBldmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAZXh0ZW5kcyB7U3ludGhldGljVUlFdmVudH1cbiAqL1xuZnVuY3Rpb24gU3ludGhldGljSW5wdXRFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNFdmVudC5jYWxsKHRoaXMsIGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbn1cblxuU3ludGhldGljRXZlbnQuYXVnbWVudENsYXNzKFN5bnRoZXRpY0lucHV0RXZlbnQsIElucHV0RXZlbnRJbnRlcmZhY2UpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bnRoZXRpY0lucHV0RXZlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIFN5bnRoZXRpY0tleWJvYXJkRXZlbnRcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3ludGhldGljVUlFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljVUlFdmVudCcpO1xuXG52YXIgZ2V0RXZlbnRDaGFyQ29kZSA9IHJlcXVpcmUoJy4vZ2V0RXZlbnRDaGFyQ29kZScpO1xudmFyIGdldEV2ZW50S2V5ID0gcmVxdWlyZSgnLi9nZXRFdmVudEtleScpO1xudmFyIGdldEV2ZW50TW9kaWZpZXJTdGF0ZSA9IHJlcXVpcmUoJy4vZ2V0RXZlbnRNb2RpZmllclN0YXRlJyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBLZXlib2FyZEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xudmFyIEtleWJvYXJkRXZlbnRJbnRlcmZhY2UgPSB7XG4gIGtleTogZ2V0RXZlbnRLZXksXG4gIGxvY2F0aW9uOiBudWxsLFxuICBjdHJsS2V5OiBudWxsLFxuICBzaGlmdEtleTogbnVsbCxcbiAgYWx0S2V5OiBudWxsLFxuICBtZXRhS2V5OiBudWxsLFxuICByZXBlYXQ6IG51bGwsXG4gIGxvY2FsZTogbnVsbCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICAvLyBMZWdhY3kgSW50ZXJmYWNlXG4gIGNoYXJDb2RlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAvLyBgY2hhckNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlQcmVzcyBldmVudCBhbmQgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2ZcbiAgICAvLyB0aGUgYWN0dWFsIHByaW50YWJsZSBjaGFyYWN0ZXIuXG5cbiAgICAvLyBLZXlQcmVzcyBpcyBkZXByZWNhdGVkLCBidXQgaXRzIHJlcGxhY2VtZW50IGlzIG5vdCB5ZXQgZmluYWwgYW5kIG5vdFxuICAgIC8vIGltcGxlbWVudGVkIGluIGFueSBtYWpvciBicm93c2VyLiBPbmx5IEtleVByZXNzIGhhcyBjaGFyQ29kZS5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleXByZXNzJykge1xuICAgICAgcmV0dXJuIGdldEV2ZW50Q2hhckNvZGUoZXZlbnQpO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfSxcbiAga2V5Q29kZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYGtleUNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlEb3duL1VwIGV2ZW50IGFuZCByZXByZXNlbnRzIHRoZSB2YWx1ZSBvZlxuICAgIC8vIHBoeXNpY2FsIGtleWJvYXJkIGtleS5cblxuICAgIC8vIFRoZSBhY3R1YWwgbWVhbmluZyBvZiB0aGUgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdXNlcnMnIGtleWJvYXJkIGxheW91dFxuICAgIC8vIHdoaWNoIGNhbm5vdCBiZSBkZXRlY3RlZC4gQXNzdW1pbmcgdGhhdCBpdCBpcyBhIFVTIGtleWJvYXJkIGxheW91dFxuICAgIC8vIHByb3ZpZGVzIGEgc3VycHJpc2luZ2x5IGFjY3VyYXRlIG1hcHBpbmcgZm9yIFVTIGFuZCBFdXJvcGVhbiB1c2Vycy5cbiAgICAvLyBEdWUgdG8gdGhpcywgaXQgaXMgbGVmdCB0byB0aGUgdXNlciB0byBpbXBsZW1lbnQgYXQgdGhpcyB0aW1lLlxuICAgIGlmIChldmVudC50eXBlID09PSAna2V5ZG93bicgfHwgZXZlbnQudHlwZSA9PT0gJ2tleXVwJykge1xuICAgICAgcmV0dXJuIGV2ZW50LmtleUNvZGU7XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9LFxuICB3aGljaDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYHdoaWNoYCBpcyBhbiBhbGlhcyBmb3IgZWl0aGVyIGBrZXlDb2RlYCBvciBgY2hhckNvZGVgIGRlcGVuZGluZyBvbiB0aGVcbiAgICAvLyB0eXBlIG9mIHRoZSBldmVudC5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleXByZXNzJykge1xuICAgICAgcmV0dXJuIGdldEV2ZW50Q2hhckNvZGUoZXZlbnQpO1xuICAgIH1cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleWRvd24nIHx8IGV2ZW50LnR5cGUgPT09ICdrZXl1cCcpIHtcbiAgICAgIHJldHVybiBldmVudC5rZXlDb2RlO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgQ29uZmlndXJhdGlvbiB1c2VkIHRvIGRpc3BhdGNoIHRoaXMgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGF0Y2hNYXJrZXIgTWFya2VyIGlkZW50aWZ5aW5nIHRoZSBldmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAZXh0ZW5kcyB7U3ludGhldGljVUlFdmVudH1cbiAqL1xuZnVuY3Rpb24gU3ludGhldGljS2V5Ym9hcmRFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNVSUV2ZW50LmNhbGwodGhpcywgZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG5TeW50aGV0aWNVSUV2ZW50LmF1Z21lbnRDbGFzcyhTeW50aGV0aWNLZXlib2FyZEV2ZW50LCBLZXlib2FyZEV2ZW50SW50ZXJmYWNlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW50aGV0aWNLZXlib2FyZEV2ZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBTeW50aGV0aWNNb3VzZUV2ZW50XG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFN5bnRoZXRpY1VJRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY1VJRXZlbnQnKTtcbnZhciBWaWV3cG9ydE1ldHJpY3MgPSByZXF1aXJlKCcuL1ZpZXdwb3J0TWV0cmljcycpO1xuXG52YXIgZ2V0RXZlbnRNb2RpZmllclN0YXRlID0gcmVxdWlyZSgnLi9nZXRFdmVudE1vZGlmaWVyU3RhdGUnKTtcblxuLyoqXG4gKiBAaW50ZXJmYWNlIE1vdXNlRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzL1xuICovXG52YXIgTW91c2VFdmVudEludGVyZmFjZSA9IHtcbiAgc2NyZWVuWDogbnVsbCxcbiAgc2NyZWVuWTogbnVsbCxcbiAgY2xpZW50WDogbnVsbCxcbiAgY2xpZW50WTogbnVsbCxcbiAgY3RybEtleTogbnVsbCxcbiAgc2hpZnRLZXk6IG51bGwsXG4gIGFsdEtleTogbnVsbCxcbiAgbWV0YUtleTogbnVsbCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICBidXR0b246IGZ1bmN0aW9uIChldmVudCkge1xuICAgIC8vIFdlYmtpdCwgRmlyZWZveCwgSUU5K1xuICAgIC8vIHdoaWNoOiAgMSAyIDNcbiAgICAvLyBidXR0b246IDAgMSAyIChzdGFuZGFyZClcbiAgICB2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xuICAgIGlmICgnd2hpY2gnIGluIGV2ZW50KSB7XG4gICAgICByZXR1cm4gYnV0dG9uO1xuICAgIH1cbiAgICAvLyBJRTw5XG4gICAgLy8gd2hpY2g6ICB1bmRlZmluZWRcbiAgICAvLyBidXR0b246IDAgMCAwXG4gICAgLy8gYnV0dG9uOiAxIDQgMiAob25tb3VzZXVwKVxuICAgIHJldHVybiBidXR0b24gPT09IDIgPyAyIDogYnV0dG9uID09PSA0ID8gMSA6IDA7XG4gIH0sXG4gIGJ1dHRvbnM6IG51bGwsXG4gIHJlbGF0ZWRUYXJnZXQ6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiBldmVudC5yZWxhdGVkVGFyZ2V0IHx8IChldmVudC5mcm9tRWxlbWVudCA9PT0gZXZlbnQuc3JjRWxlbWVudCA/IGV2ZW50LnRvRWxlbWVudCA6IGV2ZW50LmZyb21FbGVtZW50KTtcbiAgfSxcbiAgLy8gXCJQcm9wcmlldGFyeVwiIEludGVyZmFjZS5cbiAgcGFnZVg6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiAncGFnZVgnIGluIGV2ZW50ID8gZXZlbnQucGFnZVggOiBldmVudC5jbGllbnRYICsgVmlld3BvcnRNZXRyaWNzLmN1cnJlbnRTY3JvbGxMZWZ0O1xuICB9LFxuICBwYWdlWTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuICdwYWdlWScgaW4gZXZlbnQgPyBldmVudC5wYWdlWSA6IGV2ZW50LmNsaWVudFkgKyBWaWV3cG9ydE1ldHJpY3MuY3VycmVudFNjcm9sbFRvcDtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgQ29uZmlndXJhdGlvbiB1c2VkIHRvIGRpc3BhdGNoIHRoaXMgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGF0Y2hNYXJrZXIgTWFya2VyIGlkZW50aWZ5aW5nIHRoZSBldmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAZXh0ZW5kcyB7U3ludGhldGljVUlFdmVudH1cbiAqL1xuZnVuY3Rpb24gU3ludGhldGljTW91c2VFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNVSUV2ZW50LmNhbGwodGhpcywgZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG5TeW50aGV0aWNVSUV2ZW50LmF1Z21lbnRDbGFzcyhTeW50aGV0aWNNb3VzZUV2ZW50LCBNb3VzZUV2ZW50SW50ZXJmYWNlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW50aGV0aWNNb3VzZUV2ZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBTeW50aGV0aWNUb3VjaEV2ZW50XG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFN5bnRoZXRpY1VJRXZlbnQgPSByZXF1aXJlKCcuL1N5bnRoZXRpY1VJRXZlbnQnKTtcblxudmFyIGdldEV2ZW50TW9kaWZpZXJTdGF0ZSA9IHJlcXVpcmUoJy4vZ2V0RXZlbnRNb2RpZmllclN0YXRlJyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBUb3VjaEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3RvdWNoLWV2ZW50cy9cbiAqL1xudmFyIFRvdWNoRXZlbnRJbnRlcmZhY2UgPSB7XG4gIHRvdWNoZXM6IG51bGwsXG4gIHRhcmdldFRvdWNoZXM6IG51bGwsXG4gIGNoYW5nZWRUb3VjaGVzOiBudWxsLFxuICBhbHRLZXk6IG51bGwsXG4gIG1ldGFLZXk6IG51bGwsXG4gIGN0cmxLZXk6IG51bGwsXG4gIHNoaWZ0S2V5OiBudWxsLFxuICBnZXRNb2RpZmllclN0YXRlOiBnZXRFdmVudE1vZGlmaWVyU3RhdGVcbn07XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IGRpc3BhdGNoQ29uZmlnIENvbmZpZ3VyYXRpb24gdXNlZCB0byBkaXNwYXRjaCB0aGlzIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGRpc3BhdGNoTWFya2VyIE1hcmtlciBpZGVudGlmeWluZyB0aGUgZXZlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQGV4dGVuZHMge1N5bnRoZXRpY1VJRXZlbnR9XG4gKi9cbmZ1bmN0aW9uIFN5bnRoZXRpY1RvdWNoRXZlbnQoZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgU3ludGhldGljVUlFdmVudC5jYWxsKHRoaXMsIGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbn1cblxuU3ludGhldGljVUlFdmVudC5hdWdtZW50Q2xhc3MoU3ludGhldGljVG91Y2hFdmVudCwgVG91Y2hFdmVudEludGVyZmFjZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ludGhldGljVG91Y2hFdmVudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgU3ludGhldGljVUlFdmVudFxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTeW50aGV0aWNFdmVudCA9IHJlcXVpcmUoJy4vU3ludGhldGljRXZlbnQnKTtcblxudmFyIGdldEV2ZW50VGFyZ2V0ID0gcmVxdWlyZSgnLi9nZXRFdmVudFRhcmdldCcpO1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgVUlFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cbnZhciBVSUV2ZW50SW50ZXJmYWNlID0ge1xuICB2aWV3OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudmlldykge1xuICAgICAgcmV0dXJuIGV2ZW50LnZpZXc7XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldCA9IGdldEV2ZW50VGFyZ2V0KGV2ZW50KTtcbiAgICBpZiAodGFyZ2V0ICE9IG51bGwgJiYgdGFyZ2V0LndpbmRvdyA9PT0gdGFyZ2V0KSB7XG4gICAgICAvLyB0YXJnZXQgaXMgYSB3aW5kb3cgb2JqZWN0XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHZhciBkb2MgPSB0YXJnZXQub3duZXJEb2N1bWVudDtcbiAgICAvLyBUT0RPOiBGaWd1cmUgb3V0IHdoeSBgb3duZXJEb2N1bWVudGAgaXMgc29tZXRpbWVzIHVuZGVmaW5lZCBpbiBJRTguXG4gICAgaWYgKGRvYykge1xuICAgICAgcmV0dXJuIGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gd2luZG93O1xuICAgIH1cbiAgfSxcbiAgZGV0YWlsOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuZGV0YWlsIHx8IDA7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IGRpc3BhdGNoQ29uZmlnIENvbmZpZ3VyYXRpb24gdXNlZCB0byBkaXNwYXRjaCB0aGlzIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGRpc3BhdGNoTWFya2VyIE1hcmtlciBpZGVudGlmeWluZyB0aGUgZXZlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50IE5hdGl2ZSBicm93c2VyIGV2ZW50LlxuICogQGV4dGVuZHMge1N5bnRoZXRpY0V2ZW50fVxuICovXG5mdW5jdGlvbiBTeW50aGV0aWNVSUV2ZW50KGRpc3BhdGNoQ29uZmlnLCBkaXNwYXRjaE1hcmtlciwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIFN5bnRoZXRpY0V2ZW50LmNhbGwodGhpcywgZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG5TeW50aGV0aWNFdmVudC5hdWdtZW50Q2xhc3MoU3ludGhldGljVUlFdmVudCwgVUlFdmVudEludGVyZmFjZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gU3ludGhldGljVUlFdmVudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgU3ludGhldGljV2hlZWxFdmVudFxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTeW50aGV0aWNNb3VzZUV2ZW50ID0gcmVxdWlyZSgnLi9TeW50aGV0aWNNb3VzZUV2ZW50Jyk7XG5cbi8qKlxuICogQGludGVyZmFjZSBXaGVlbEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xudmFyIFdoZWVsRXZlbnRJbnRlcmZhY2UgPSB7XG4gIGRlbHRhWDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuICdkZWx0YVgnIGluIGV2ZW50ID8gZXZlbnQuZGVsdGFYIDpcbiAgICAvLyBGYWxsYmFjayB0byBgd2hlZWxEZWx0YVhgIGZvciBXZWJraXQgYW5kIG5vcm1hbGl6ZSAocmlnaHQgaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhWCcgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YVggOiAwO1xuICB9LFxuICBkZWx0YVk6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiAnZGVsdGFZJyBpbiBldmVudCA/IGV2ZW50LmRlbHRhWSA6XG4gICAgLy8gRmFsbGJhY2sgdG8gYHdoZWVsRGVsdGFZYCBmb3IgV2Via2l0IGFuZCBub3JtYWxpemUgKGRvd24gaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhWScgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YVkgOlxuICAgIC8vIEZhbGxiYWNrIHRvIGB3aGVlbERlbHRhYCBmb3IgSUU8OSBhbmQgbm9ybWFsaXplIChkb3duIGlzIHBvc2l0aXZlKS5cbiAgICAnd2hlZWxEZWx0YScgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YSA6IDA7XG4gIH0sXG4gIGRlbHRhWjogbnVsbCxcblxuICAvLyBCcm93c2VycyB3aXRob3V0IFwiZGVsdGFNb2RlXCIgaXMgcmVwb3J0aW5nIGluIHJhdyB3aGVlbCBkZWx0YSB3aGVyZSBvbmVcbiAgLy8gbm90Y2ggb24gdGhlIHNjcm9sbCBpcyBhbHdheXMgKy8tIDEyMCwgcm91Z2hseSBlcXVpdmFsZW50IHRvIHBpeGVscy5cbiAgLy8gQSBnb29kIGFwcHJveGltYXRpb24gb2YgRE9NX0RFTFRBX0xJTkUgKDEpIGlzIDUlIG9mIHZpZXdwb3J0IHNpemUgb3JcbiAgLy8gfjQwIHBpeGVscywgZm9yIERPTV9ERUxUQV9TQ1JFRU4gKDIpIGl0IGlzIDg3LjUlIG9mIHZpZXdwb3J0IHNpemUuXG4gIGRlbHRhTW9kZTogbnVsbFxufTtcblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gZGlzcGF0Y2hDb25maWcgQ29uZmlndXJhdGlvbiB1c2VkIHRvIGRpc3BhdGNoIHRoaXMgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlzcGF0Y2hNYXJrZXIgTWFya2VyIGlkZW50aWZ5aW5nIHRoZSBldmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAZXh0ZW5kcyB7U3ludGhldGljTW91c2VFdmVudH1cbiAqL1xuZnVuY3Rpb24gU3ludGhldGljV2hlZWxFdmVudChkaXNwYXRjaENvbmZpZywgZGlzcGF0Y2hNYXJrZXIsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICBTeW50aGV0aWNNb3VzZUV2ZW50LmNhbGwodGhpcywgZGlzcGF0Y2hDb25maWcsIGRpc3BhdGNoTWFya2VyLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG5TeW50aGV0aWNNb3VzZUV2ZW50LmF1Z21lbnRDbGFzcyhTeW50aGV0aWNXaGVlbEV2ZW50LCBXaGVlbEV2ZW50SW50ZXJmYWNlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW50aGV0aWNXaGVlbEV2ZW50OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBUcmFuc2FjdGlvblxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xuXG4vKipcbiAqIGBUcmFuc2FjdGlvbmAgY3JlYXRlcyBhIGJsYWNrIGJveCB0aGF0IGlzIGFibGUgdG8gd3JhcCBhbnkgbWV0aG9kIHN1Y2ggdGhhdFxuICogY2VydGFpbiBpbnZhcmlhbnRzIGFyZSBtYWludGFpbmVkIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIG1ldGhvZCBpcyBpbnZva2VkXG4gKiAoRXZlbiBpZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIHdoaWxlIGludm9raW5nIHRoZSB3cmFwcGVkIG1ldGhvZCkuIFdob2V2ZXJcbiAqIGluc3RhbnRpYXRlcyBhIHRyYW5zYWN0aW9uIGNhbiBwcm92aWRlIGVuZm9yY2VycyBvZiB0aGUgaW52YXJpYW50cyBhdFxuICogY3JlYXRpb24gdGltZS4gVGhlIGBUcmFuc2FjdGlvbmAgY2xhc3MgaXRzZWxmIHdpbGwgc3VwcGx5IG9uZSBhZGRpdGlvbmFsXG4gKiBhdXRvbWF0aWMgaW52YXJpYW50IGZvciB5b3UgLSB0aGUgaW52YXJpYW50IHRoYXQgYW55IHRyYW5zYWN0aW9uIGluc3RhbmNlXG4gKiBzaG91bGQgbm90IGJlIHJ1biB3aGlsZSBpdCBpcyBhbHJlYWR5IGJlaW5nIHJ1bi4gWW91IHdvdWxkIHR5cGljYWxseSBjcmVhdGUgYVxuICogc2luZ2xlIGluc3RhbmNlIG9mIGEgYFRyYW5zYWN0aW9uYCBmb3IgcmV1c2UgbXVsdGlwbGUgdGltZXMsIHRoYXQgcG90ZW50aWFsbHlcbiAqIGlzIHVzZWQgdG8gd3JhcCBzZXZlcmFsIGRpZmZlcmVudCBtZXRob2RzLiBXcmFwcGVycyBhcmUgZXh0cmVtZWx5IHNpbXBsZSAtXG4gKiB0aGV5IG9ubHkgcmVxdWlyZSBpbXBsZW1lbnRpbmcgdHdvIG1ldGhvZHMuXG4gKlxuICogPHByZT5cbiAqICAgICAgICAgICAgICAgICAgICAgICB3cmFwcGVycyAoaW5qZWN0ZWQgYXQgY3JlYXRpb24gdGltZSlcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICAgICAgICArXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLXwtLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB2ICAgICAgICB8ICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgfCAgICAgICstLS0tLS0tLS0tLS0tLS0rICAgfCAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgIHwgICArLS18ICAgIHdyYXBwZXIxICAgfC0tLXwtLS0tKyAgICAgICAgIHxcbiAqICAgICAgICAgICAgICAgICAgICB8ICAgfCAgKy0tLS0tLS0tLS0tLS0tLSsgICB2ICAgIHwgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgKy0tLS0tLS0tLS0tLS0rICB8ICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgIHwgICB8ICAgICArLS0tLXwgICB3cmFwcGVyMiAgfC0tLS0tLS0tKyAgIHxcbiAqICAgICAgICAgICAgICAgICAgICB8ICAgfCAgICAgfCAgICArLS0tLS0tLS0tLS0tLSsgIHwgICAgIHwgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICB8ICAgfFxuICogICAgICAgICAgICAgICAgICAgIHwgICB2ICAgICB2ICAgICAgICAgICAgICAgICAgICAgdiAgICAgdiAgIHwgd3JhcHBlclxuICogICAgICAgICAgICAgICAgICAgIHwgKy0tLSsgKy0tLSsgICArLS0tLS0tLS0tKyAgICstLS0rICstLS0rIHwgaW52YXJpYW50c1xuICogcGVyZm9ybShhbnlNZXRob2QpIHwgfCAgIHwgfCAgIHwgICB8ICAgICAgICAgfCAgIHwgICB8IHwgICB8IHwgbWFpbnRhaW5lZFxuICogKy0tLS0tLS0tLS0tLS0tLS0tPnwtfC0tLXwtfC0tLXwtLT58YW55TWV0aG9kfC0tLXwtLS18LXwtLS18LXwtLS0tLS0tLT5cbiAqICAgICAgICAgICAgICAgICAgICB8IHwgICB8IHwgICB8ICAgfCAgICAgICAgIHwgICB8ICAgfCB8ICAgfCB8XG4gKiAgICAgICAgICAgICAgICAgICAgfCB8ICAgfCB8ICAgfCAgIHwgICAgICAgICB8ICAgfCAgIHwgfCAgIHwgfFxuICogICAgICAgICAgICAgICAgICAgIHwgfCAgIHwgfCAgIHwgICB8ICAgICAgICAgfCAgIHwgICB8IHwgICB8IHxcbiAqICAgICAgICAgICAgICAgICAgICB8ICstLS0rICstLS0rICAgKy0tLS0tLS0tLSsgICArLS0tKyArLS0tKyB8XG4gKiAgICAgICAgICAgICAgICAgICAgfCAgaW5pdGlhbGl6ZSAgICAgICAgICAgICAgICAgICAgY2xvc2UgICAgfFxuICogICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIDwvcHJlPlxuICpcbiAqIFVzZSBjYXNlczpcbiAqIC0gUHJlc2VydmluZyB0aGUgaW5wdXQgc2VsZWN0aW9uIHJhbmdlcyBiZWZvcmUvYWZ0ZXIgcmVjb25jaWxpYXRpb24uXG4gKiAgIFJlc3RvcmluZyBzZWxlY3Rpb24gZXZlbiBpbiB0aGUgZXZlbnQgb2YgYW4gdW5leHBlY3RlZCBlcnJvci5cbiAqIC0gRGVhY3RpdmF0aW5nIGV2ZW50cyB3aGlsZSByZWFycmFuZ2luZyB0aGUgRE9NLCBwcmV2ZW50aW5nIGJsdXJzL2ZvY3VzZXMsXG4gKiAgIHdoaWxlIGd1YXJhbnRlZWluZyB0aGF0IGFmdGVyd2FyZHMsIHRoZSBldmVudCBzeXN0ZW0gaXMgcmVhY3RpdmF0ZWQuXG4gKiAtIEZsdXNoaW5nIGEgcXVldWUgb2YgY29sbGVjdGVkIERPTSBtdXRhdGlvbnMgdG8gdGhlIG1haW4gVUkgdGhyZWFkIGFmdGVyIGFcbiAqICAgcmVjb25jaWxpYXRpb24gdGFrZXMgcGxhY2UgaW4gYSB3b3JrZXIgdGhyZWFkLlxuICogLSBJbnZva2luZyBhbnkgY29sbGVjdGVkIGBjb21wb25lbnREaWRVcGRhdGVgIGNhbGxiYWNrcyBhZnRlciByZW5kZXJpbmcgbmV3XG4gKiAgIGNvbnRlbnQuXG4gKiAtIChGdXR1cmUgdXNlIGNhc2UpOiBXcmFwcGluZyBwYXJ0aWN1bGFyIGZsdXNoZXMgb2YgdGhlIGBSZWFjdFdvcmtlcmAgcXVldWVcbiAqICAgdG8gcHJlc2VydmUgdGhlIGBzY3JvbGxUb3BgIChhbiBhdXRvbWF0aWMgc2Nyb2xsIGF3YXJlIERPTSkuXG4gKiAtIChGdXR1cmUgdXNlIGNhc2UpOiBMYXlvdXQgY2FsY3VsYXRpb25zIGJlZm9yZSBhbmQgYWZ0ZXIgRE9NIHVwZGF0ZXMuXG4gKlxuICogVHJhbnNhY3Rpb25hbCBwbHVnaW4gQVBJOlxuICogLSBBIG1vZHVsZSB0aGF0IGhhcyBhbiBgaW5pdGlhbGl6ZWAgbWV0aG9kIHRoYXQgcmV0dXJucyBhbnkgcHJlY29tcHV0YXRpb24uXG4gKiAtIGFuZCBhIGBjbG9zZWAgbWV0aG9kIHRoYXQgYWNjZXB0cyB0aGUgcHJlY29tcHV0YXRpb24uIGBjbG9zZWAgaXMgaW52b2tlZFxuICogICB3aGVuIHRoZSB3cmFwcGVkIHByb2Nlc3MgaXMgY29tcGxldGVkLCBvciBoYXMgZmFpbGVkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8VHJhbnNhY3Rpb25hbFdyYXBwZXI+fSB0cmFuc2FjdGlvbldyYXBwZXIgV3JhcHBlciBtb2R1bGVzXG4gKiB0aGF0IGltcGxlbWVudCBgaW5pdGlhbGl6ZWAgYW5kIGBjbG9zZWAuXG4gKiBAcmV0dXJuIHtUcmFuc2FjdGlvbn0gU2luZ2xlIHRyYW5zYWN0aW9uIGZvciByZXVzZSBpbiB0aHJlYWQuXG4gKlxuICogQGNsYXNzIFRyYW5zYWN0aW9uXG4gKi9cbnZhciBNaXhpbiA9IHtcbiAgLyoqXG4gICAqIFNldHMgdXAgdGhpcyBpbnN0YW5jZSBzbyB0aGF0IGl0IGlzIHByZXBhcmVkIGZvciBjb2xsZWN0aW5nIG1ldHJpY3MuIERvZXNcbiAgICogc28gc3VjaCB0aGF0IHRoaXMgc2V0dXAgbWV0aG9kIG1heSBiZSB1c2VkIG9uIGFuIGluc3RhbmNlIHRoYXQgaXMgYWxyZWFkeVxuICAgKiBpbml0aWFsaXplZCwgaW4gYSB3YXkgdGhhdCBkb2VzIG5vdCBjb25zdW1lIGFkZGl0aW9uYWwgbWVtb3J5IHVwb24gcmV1c2UuXG4gICAqIFRoYXQgY2FuIGJlIHVzZWZ1bCBpZiB5b3UgZGVjaWRlIHRvIG1ha2UgeW91ciBzdWJjbGFzcyBvZiB0aGlzIG1peGluIGFcbiAgICogXCJQb29sZWRDbGFzc1wiLlxuICAgKi9cbiAgcmVpbml0aWFsaXplVHJhbnNhY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uV3JhcHBlcnMgPSB0aGlzLmdldFRyYW5zYWN0aW9uV3JhcHBlcnMoKTtcbiAgICBpZiAodGhpcy53cmFwcGVySW5pdERhdGEpIHtcbiAgICAgIHRoaXMud3JhcHBlckluaXREYXRhLmxlbmd0aCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud3JhcHBlckluaXREYXRhID0gW107XG4gICAgfVxuICAgIHRoaXMuX2lzSW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICB9LFxuXG4gIF9pc0luVHJhbnNhY3Rpb246IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7QXJyYXk8VHJhbnNhY3Rpb25XcmFwcGVyPn0gQXJyYXkgb2YgdHJhbnNhY3Rpb24gd3JhcHBlcnMuXG4gICAqL1xuICBnZXRUcmFuc2FjdGlvbldyYXBwZXJzOiBudWxsLFxuXG4gIGlzSW5UcmFuc2FjdGlvbjogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIXRoaXMuX2lzSW5UcmFuc2FjdGlvbjtcbiAgfSxcblxuICAvKipcbiAgICogRXhlY3V0ZXMgdGhlIGZ1bmN0aW9uIHdpdGhpbiBhIHNhZmV0eSB3aW5kb3cuIFVzZSB0aGlzIGZvciB0aGUgdG9wIGxldmVsXG4gICAqIG1ldGhvZHMgdGhhdCByZXN1bHQgaW4gbGFyZ2UgYW1vdW50cyBvZiBjb21wdXRhdGlvbi9tdXRhdGlvbnMgdGhhdCB3b3VsZFxuICAgKiBuZWVkIHRvIGJlIHNhZmV0eSBjaGVja2VkLiBUaGUgb3B0aW9uYWwgYXJndW1lbnRzIGhlbHBzIHByZXZlbnQgdGhlIG5lZWRcbiAgICogdG8gYmluZCBpbiBtYW55IGNhc2VzLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBtZXRob2QgTWVtYmVyIG9mIHNjb3BlIHRvIGNhbGwuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBzY29wZSBTY29wZSB0byBpbnZva2UgZnJvbS5cbiAgICogQHBhcmFtIHtPYmplY3Q/PX0gYSBBcmd1bWVudCB0byBwYXNzIHRvIHRoZSBtZXRob2QuXG4gICAqIEBwYXJhbSB7T2JqZWN0Pz19IGIgQXJndW1lbnQgdG8gcGFzcyB0byB0aGUgbWV0aG9kLlxuICAgKiBAcGFyYW0ge09iamVjdD89fSBjIEFyZ3VtZW50IHRvIHBhc3MgdG8gdGhlIG1ldGhvZC5cbiAgICogQHBhcmFtIHtPYmplY3Q/PX0gZCBBcmd1bWVudCB0byBwYXNzIHRvIHRoZSBtZXRob2QuXG4gICAqIEBwYXJhbSB7T2JqZWN0Pz19IGUgQXJndW1lbnQgdG8gcGFzcyB0byB0aGUgbWV0aG9kLlxuICAgKiBAcGFyYW0ge09iamVjdD89fSBmIEFyZ3VtZW50IHRvIHBhc3MgdG8gdGhlIG1ldGhvZC5cbiAgICpcbiAgICogQHJldHVybiB7Kn0gUmV0dXJuIHZhbHVlIGZyb20gYG1ldGhvZGAuXG4gICAqL1xuICBwZXJmb3JtOiBmdW5jdGlvbiAobWV0aG9kLCBzY29wZSwgYSwgYiwgYywgZCwgZSwgZikge1xuICAgICEhdGhpcy5pc0luVHJhbnNhY3Rpb24oKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdUcmFuc2FjdGlvbi5wZXJmb3JtKC4uLik6IENhbm5vdCBpbml0aWFsaXplIGEgdHJhbnNhY3Rpb24gd2hlbiB0aGVyZSAnICsgJ2lzIGFscmVhZHkgYW4gb3V0c3RhbmRpbmcgdHJhbnNhY3Rpb24uJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAgIHZhciBlcnJvclRocm93bjtcbiAgICB2YXIgcmV0O1xuICAgIHRyeSB7XG4gICAgICB0aGlzLl9pc0luVHJhbnNhY3Rpb24gPSB0cnVlO1xuICAgICAgLy8gQ2F0Y2hpbmcgZXJyb3JzIG1ha2VzIGRlYnVnZ2luZyBtb3JlIGRpZmZpY3VsdCwgc28gd2Ugc3RhcnQgd2l0aFxuICAgICAgLy8gZXJyb3JUaHJvd24gc2V0IHRvIHRydWUgYmVmb3JlIHNldHRpbmcgaXQgdG8gZmFsc2UgYWZ0ZXIgY2FsbGluZ1xuICAgICAgLy8gY2xvc2UgLS0gaWYgaXQncyBzdGlsbCBzZXQgdG8gdHJ1ZSBpbiB0aGUgZmluYWxseSBibG9jaywgaXQgbWVhbnNcbiAgICAgIC8vIG9uZSBvZiB0aGVzZSBjYWxscyB0aHJldy5cbiAgICAgIGVycm9yVGhyb3duID0gdHJ1ZTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUFsbCgwKTtcbiAgICAgIHJldCA9IG1ldGhvZC5jYWxsKHNjb3BlLCBhLCBiLCBjLCBkLCBlLCBmKTtcbiAgICAgIGVycm9yVGhyb3duID0gZmFsc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChlcnJvclRocm93bikge1xuICAgICAgICAgIC8vIElmIGBtZXRob2RgIHRocm93cywgcHJlZmVyIHRvIHNob3cgdGhhdCBzdGFjayB0cmFjZSBvdmVyIGFueSB0aHJvd25cbiAgICAgICAgICAvLyBieSBpbnZva2luZyBgY2xvc2VBbGxgLlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlQWxsKDApO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge31cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBTaW5jZSBgbWV0aG9kYCBkaWRuJ3QgdGhyb3csIHdlIGRvbid0IHdhbnQgdG8gc2lsZW5jZSB0aGUgZXhjZXB0aW9uXG4gICAgICAgICAgLy8gaGVyZS5cbiAgICAgICAgICB0aGlzLmNsb3NlQWxsKDApO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLl9pc0luVHJhbnNhY3Rpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfSxcblxuICBpbml0aWFsaXplQWxsOiBmdW5jdGlvbiAoc3RhcnRJbmRleCkge1xuICAgIHZhciB0cmFuc2FjdGlvbldyYXBwZXJzID0gdGhpcy50cmFuc2FjdGlvbldyYXBwZXJzO1xuICAgIGZvciAodmFyIGkgPSBzdGFydEluZGV4OyBpIDwgdHJhbnNhY3Rpb25XcmFwcGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHdyYXBwZXIgPSB0cmFuc2FjdGlvbldyYXBwZXJzW2ldO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQ2F0Y2hpbmcgZXJyb3JzIG1ha2VzIGRlYnVnZ2luZyBtb3JlIGRpZmZpY3VsdCwgc28gd2Ugc3RhcnQgd2l0aCB0aGVcbiAgICAgICAgLy8gT0JTRVJWRURfRVJST1Igc3RhdGUgYmVmb3JlIG92ZXJ3cml0aW5nIGl0IHdpdGggdGhlIHJlYWwgcmV0dXJuIHZhbHVlXG4gICAgICAgIC8vIG9mIGluaXRpYWxpemUgLS0gaWYgaXQncyBzdGlsbCBzZXQgdG8gT0JTRVJWRURfRVJST1IgaW4gdGhlIGZpbmFsbHlcbiAgICAgICAgLy8gYmxvY2ssIGl0IG1lYW5zIHdyYXBwZXIuaW5pdGlhbGl6ZSB0aHJldy5cbiAgICAgICAgdGhpcy53cmFwcGVySW5pdERhdGFbaV0gPSBUcmFuc2FjdGlvbi5PQlNFUlZFRF9FUlJPUjtcbiAgICAgICAgdGhpcy53cmFwcGVySW5pdERhdGFbaV0gPSB3cmFwcGVyLmluaXRpYWxpemUgPyB3cmFwcGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKSA6IG51bGw7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAodGhpcy53cmFwcGVySW5pdERhdGFbaV0gPT09IFRyYW5zYWN0aW9uLk9CU0VSVkVEX0VSUk9SKSB7XG4gICAgICAgICAgLy8gVGhlIGluaXRpYWxpemVyIGZvciB3cmFwcGVyIGkgdGhyZXcgYW4gZXJyb3I7IGluaXRpYWxpemUgdGhlXG4gICAgICAgICAgLy8gcmVtYWluaW5nIHdyYXBwZXJzIGJ1dCBzaWxlbmNlIGFueSBleGNlcHRpb25zIGZyb20gdGhlbSB0byBlbnN1cmVcbiAgICAgICAgICAvLyB0aGF0IHRoZSBmaXJzdCBlcnJvciBpcyB0aGUgb25lIHRvIGJ1YmJsZSB1cC5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplQWxsKGkgKyAxKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHt9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEludm9rZXMgZWFjaCBvZiBgdGhpcy50cmFuc2FjdGlvbldyYXBwZXJzLmNsb3NlW2ldYCBmdW5jdGlvbnMsIHBhc3NpbmcgaW50b1xuICAgKiB0aGVtIHRoZSByZXNwZWN0aXZlIHJldHVybiB2YWx1ZXMgb2YgYHRoaXMudHJhbnNhY3Rpb25XcmFwcGVycy5pbml0W2ldYFxuICAgKiAoYGNsb3NlYHJzIHRoYXQgY29ycmVzcG9uZCB0byBpbml0aWFsaXplcnMgdGhhdCBmYWlsZWQgd2lsbCBub3QgYmVcbiAgICogaW52b2tlZCkuXG4gICAqL1xuICBjbG9zZUFsbDogZnVuY3Rpb24gKHN0YXJ0SW5kZXgpIHtcbiAgICAhdGhpcy5pc0luVHJhbnNhY3Rpb24oKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdUcmFuc2FjdGlvbi5jbG9zZUFsbCgpOiBDYW5ub3QgY2xvc2UgdHJhbnNhY3Rpb24gd2hlbiBub25lIGFyZSBvcGVuLicpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgdHJhbnNhY3Rpb25XcmFwcGVycyA9IHRoaXMudHJhbnNhY3Rpb25XcmFwcGVycztcbiAgICBmb3IgKHZhciBpID0gc3RhcnRJbmRleDsgaSA8IHRyYW5zYWN0aW9uV3JhcHBlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3cmFwcGVyID0gdHJhbnNhY3Rpb25XcmFwcGVyc1tpXTtcbiAgICAgIHZhciBpbml0RGF0YSA9IHRoaXMud3JhcHBlckluaXREYXRhW2ldO1xuICAgICAgdmFyIGVycm9yVGhyb3duO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQ2F0Y2hpbmcgZXJyb3JzIG1ha2VzIGRlYnVnZ2luZyBtb3JlIGRpZmZpY3VsdCwgc28gd2Ugc3RhcnQgd2l0aFxuICAgICAgICAvLyBlcnJvclRocm93biBzZXQgdG8gdHJ1ZSBiZWZvcmUgc2V0dGluZyBpdCB0byBmYWxzZSBhZnRlciBjYWxsaW5nXG4gICAgICAgIC8vIGNsb3NlIC0tIGlmIGl0J3Mgc3RpbGwgc2V0IHRvIHRydWUgaW4gdGhlIGZpbmFsbHkgYmxvY2ssIGl0IG1lYW5zXG4gICAgICAgIC8vIHdyYXBwZXIuY2xvc2UgdGhyZXcuXG4gICAgICAgIGVycm9yVGhyb3duID0gdHJ1ZTtcbiAgICAgICAgaWYgKGluaXREYXRhICE9PSBUcmFuc2FjdGlvbi5PQlNFUlZFRF9FUlJPUiAmJiB3cmFwcGVyLmNsb3NlKSB7XG4gICAgICAgICAgd3JhcHBlci5jbG9zZS5jYWxsKHRoaXMsIGluaXREYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlcnJvclRocm93biA9IGZhbHNlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKGVycm9yVGhyb3duKSB7XG4gICAgICAgICAgLy8gVGhlIGNsb3NlciBmb3Igd3JhcHBlciBpIHRocmV3IGFuIGVycm9yOyBjbG9zZSB0aGUgcmVtYWluaW5nXG4gICAgICAgICAgLy8gd3JhcHBlcnMgYnV0IHNpbGVuY2UgYW55IGV4Y2VwdGlvbnMgZnJvbSB0aGVtIHRvIGVuc3VyZSB0aGF0IHRoZVxuICAgICAgICAgIC8vIGZpcnN0IGVycm9yIGlzIHRoZSBvbmUgdG8gYnViYmxlIHVwLlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlQWxsKGkgKyAxKTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMud3JhcHBlckluaXREYXRhLmxlbmd0aCA9IDA7XG4gIH1cbn07XG5cbnZhciBUcmFuc2FjdGlvbiA9IHtcblxuICBNaXhpbjogTWl4aW4sXG5cbiAgLyoqXG4gICAqIFRva2VuIHRvIGxvb2sgZm9yIHRvIGRldGVybWluZSBpZiBhbiBlcnJvciBvY2N1cnJlZC5cbiAgICovXG4gIE9CU0VSVkVEX0VSUk9SOiB7fVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zYWN0aW9uOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBWaWV3cG9ydE1ldHJpY3NcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBWaWV3cG9ydE1ldHJpY3MgPSB7XG5cbiAgY3VycmVudFNjcm9sbExlZnQ6IDAsXG5cbiAgY3VycmVudFNjcm9sbFRvcDogMCxcblxuICByZWZyZXNoU2Nyb2xsVmFsdWVzOiBmdW5jdGlvbiAoc2Nyb2xsUG9zaXRpb24pIHtcbiAgICBWaWV3cG9ydE1ldHJpY3MuY3VycmVudFNjcm9sbExlZnQgPSBzY3JvbGxQb3NpdGlvbi54O1xuICAgIFZpZXdwb3J0TWV0cmljcy5jdXJyZW50U2Nyb2xsVG9wID0gc2Nyb2xsUG9zaXRpb24ueTtcbiAgfVxuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXdwb3J0TWV0cmljczsiLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgYWNjdW11bGF0ZUludG9cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKlxuICogQWNjdW11bGF0ZXMgaXRlbXMgdGhhdCBtdXN0IG5vdCBiZSBudWxsIG9yIHVuZGVmaW5lZCBpbnRvIHRoZSBmaXJzdCBvbmUuIFRoaXNcbiAqIGlzIHVzZWQgdG8gY29uc2VydmUgbWVtb3J5IGJ5IGF2b2lkaW5nIGFycmF5IGFsbG9jYXRpb25zLCBhbmQgdGh1cyBzYWNyaWZpY2VzXG4gKiBBUEkgY2xlYW5uZXNzLiBTaW5jZSBgY3VycmVudGAgY2FuIGJlIG51bGwgYmVmb3JlIGJlaW5nIHBhc3NlZCBpbiBhbmQgbm90XG4gKiBudWxsIGFmdGVyIHRoaXMgZnVuY3Rpb24sIG1ha2Ugc3VyZSB0byBhc3NpZ24gaXQgYmFjayB0byBgY3VycmVudGA6XG4gKlxuICogYGEgPSBhY2N1bXVsYXRlSW50byhhLCBiKTtgXG4gKlxuICogVGhpcyBBUEkgc2hvdWxkIGJlIHNwYXJpbmdseSB1c2VkLiBUcnkgYGFjY3VtdWxhdGVgIGZvciBzb21ldGhpbmcgY2xlYW5lci5cbiAqXG4gKiBAcmV0dXJuIHsqfGFycmF5PCo+fSBBbiBhY2N1bXVsYXRpb24gb2YgaXRlbXMuXG4gKi9cblxuZnVuY3Rpb24gYWNjdW11bGF0ZUludG8oY3VycmVudCwgbmV4dCkge1xuICAhKG5leHQgIT0gbnVsbCkgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnYWNjdW11bGF0ZUludG8oLi4uKTogQWNjdW11bGF0ZWQgaXRlbXMgbXVzdCBub3QgYmUgbnVsbCBvciB1bmRlZmluZWQuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICBpZiAoY3VycmVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG5leHQ7XG4gIH1cblxuICAvLyBCb3RoIGFyZSBub3QgZW1wdHkuIFdhcm5pbmc6IE5ldmVyIGNhbGwgeC5jb25jYXQoeSkgd2hlbiB5b3UgYXJlIG5vdFxuICAvLyBjZXJ0YWluIHRoYXQgeCBpcyBhbiBBcnJheSAoeCBjb3VsZCBiZSBhIHN0cmluZyB3aXRoIGNvbmNhdCBtZXRob2QpLlxuICB2YXIgY3VycmVudElzQXJyYXkgPSBBcnJheS5pc0FycmF5KGN1cnJlbnQpO1xuICB2YXIgbmV4dElzQXJyYXkgPSBBcnJheS5pc0FycmF5KG5leHQpO1xuXG4gIGlmIChjdXJyZW50SXNBcnJheSAmJiBuZXh0SXNBcnJheSkge1xuICAgIGN1cnJlbnQucHVzaC5hcHBseShjdXJyZW50LCBuZXh0KTtcbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuXG4gIGlmIChjdXJyZW50SXNBcnJheSkge1xuICAgIGN1cnJlbnQucHVzaChuZXh0KTtcbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuXG4gIGlmIChuZXh0SXNBcnJheSkge1xuICAgIC8vIEEgYml0IHRvbyBkYW5nZXJvdXMgdG8gbXV0YXRlIGBuZXh0YC5cbiAgICByZXR1cm4gW2N1cnJlbnRdLmNvbmNhdChuZXh0KTtcbiAgfVxuXG4gIHJldHVybiBbY3VycmVudCwgbmV4dF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYWNjdW11bGF0ZUludG87IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGFkbGVyMzJcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBNT0QgPSA2NTUyMTtcblxuLy8gYWRsZXIzMiBpcyBub3QgY3J5cHRvZ3JhcGhpY2FsbHkgc3Ryb25nLCBhbmQgaXMgb25seSB1c2VkIHRvIHNhbml0eSBjaGVjayB0aGF0XG4vLyBtYXJrdXAgZ2VuZXJhdGVkIG9uIHRoZSBzZXJ2ZXIgbWF0Y2hlcyB0aGUgbWFya3VwIGdlbmVyYXRlZCBvbiB0aGUgY2xpZW50LlxuLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiAoYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBTaGVldEpTIHZlcnNpb24pIGhhcyBiZWVuIG9wdGltaXplZFxuLy8gZm9yIG91ciB1c2UgY2FzZSwgYXQgdGhlIGV4cGVuc2Ugb2YgY29uZm9ybWluZyB0byB0aGUgYWRsZXIzMiBzcGVjaWZpY2F0aW9uXG4vLyBmb3Igbm9uLWFzY2lpIGlucHV0cy5cbmZ1bmN0aW9uIGFkbGVyMzIoZGF0YSkge1xuICB2YXIgYSA9IDE7XG4gIHZhciBiID0gMDtcbiAgdmFyIGkgPSAwO1xuICB2YXIgbCA9IGRhdGEubGVuZ3RoO1xuICB2YXIgbSA9IGwgJiB+MHgzO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBmb3IgKDsgaSA8IE1hdGgubWluKGkgKyA0MDk2LCBtKTsgaSArPSA0KSB7XG4gICAgICBiICs9IChhICs9IGRhdGEuY2hhckNvZGVBdChpKSkgKyAoYSArPSBkYXRhLmNoYXJDb2RlQXQoaSArIDEpKSArIChhICs9IGRhdGEuY2hhckNvZGVBdChpICsgMikpICsgKGEgKz0gZGF0YS5jaGFyQ29kZUF0KGkgKyAzKSk7XG4gICAgfVxuICAgIGEgJT0gTU9EO1xuICAgIGIgJT0gTU9EO1xuICB9XG4gIGZvciAoOyBpIDwgbDsgaSsrKSB7XG4gICAgYiArPSBhICs9IGRhdGEuY2hhckNvZGVBdChpKTtcbiAgfVxuICBhICU9IE1PRDtcbiAgYiAlPSBNT0Q7XG4gIHJldHVybiBhIHwgYiA8PCAxNjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhZGxlcjMyOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBjYW5EZWZpbmVQcm9wZXJ0eVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGNhbkRlZmluZVByb3BlcnR5ID0gZmFsc2U7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ3gnLCB7IGdldDogZnVuY3Rpb24gKCkge30gfSk7XG4gICAgY2FuRGVmaW5lUHJvcGVydHkgPSB0cnVlO1xuICB9IGNhdGNoICh4KSB7XG4gICAgLy8gSUUgd2lsbCBmYWlsIG9uIGRlZmluZVByb3BlcnR5XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYW5EZWZpbmVQcm9wZXJ0eTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZGFuZ2Vyb3VzU3R5bGVWYWx1ZVxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBDU1NQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vQ1NTUHJvcGVydHknKTtcblxudmFyIGlzVW5pdGxlc3NOdW1iZXIgPSBDU1NQcm9wZXJ0eS5pc1VuaXRsZXNzTnVtYmVyO1xuXG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIHRoZSBwcm9wZXIgY3NzIHdyaXRhYmxlIHZhbHVlLiBUaGUgc3R5bGUgbmFtZSBgbmFtZWBcbiAqIHNob3VsZCBiZSBsb2dpY2FsIChubyBoeXBoZW5zKSwgYXMgc3BlY2lmaWVkXG4gKiBpbiBgQ1NTUHJvcGVydHkuaXNVbml0bGVzc051bWJlcmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgQ1NTIHByb3BlcnR5IG5hbWUgc3VjaCBhcyBgdG9wTWFyZ2luYC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQ1NTIHByb3BlcnR5IHZhbHVlIHN1Y2ggYXMgYDEwcHhgLlxuICogQHJldHVybiB7c3RyaW5nfSBOb3JtYWxpemVkIHN0eWxlIHZhbHVlIHdpdGggZGltZW5zaW9ucyBhcHBsaWVkLlxuICovXG5mdW5jdGlvbiBkYW5nZXJvdXNTdHlsZVZhbHVlKG5hbWUsIHZhbHVlKSB7XG4gIC8vIE5vdGUgdGhhdCB3ZSd2ZSByZW1vdmVkIGVzY2FwZVRleHRGb3JCcm93c2VyKCkgY2FsbHMgaGVyZSBzaW5jZSB0aGVcbiAgLy8gd2hvbGUgc3RyaW5nIHdpbGwgYmUgZXNjYXBlZCB3aGVuIHRoZSBhdHRyaWJ1dGUgaXMgaW5qZWN0ZWQgaW50b1xuICAvLyB0aGUgbWFya3VwLiBJZiB5b3UgcHJvdmlkZSB1bnNhZmUgdXNlciBkYXRhIGhlcmUgdGhleSBjYW4gaW5qZWN0XG4gIC8vIGFyYml0cmFyeSBDU1Mgd2hpY2ggbWF5IGJlIHByb2JsZW1hdGljIChJIGNvdWxkbid0IHJlcHJvIHRoaXMpOlxuICAvLyBodHRwczovL3d3dy5vd2FzcC5vcmcvaW5kZXgucGhwL1hTU19GaWx0ZXJfRXZhc2lvbl9DaGVhdF9TaGVldFxuICAvLyBodHRwOi8vd3d3LnRoZXNwYW5uZXIuY28udWsvMjAwNy8xMS8yNi91bHRpbWF0ZS14c3MtY3NzLWluamVjdGlvbi9cbiAgLy8gVGhpcyBpcyBub3QgYW4gWFNTIGhvbGUgYnV0IGluc3RlYWQgYSBwb3RlbnRpYWwgQ1NTIGluamVjdGlvbiBpc3N1ZVxuICAvLyB3aGljaCBoYXMgbGVhZCB0byBhIGdyZWF0ZXIgZGlzY3Vzc2lvbiBhYm91dCBob3cgd2UncmUgZ29pbmcgdG9cbiAgLy8gdHJ1c3QgVVJMcyBtb3ZpbmcgZm9yd2FyZC4gU2VlICMyMTE1OTAxXG5cbiAgdmFyIGlzRW1wdHkgPSB2YWx1ZSA9PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09PSAnJztcbiAgaWYgKGlzRW1wdHkpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICB2YXIgaXNOb25OdW1lcmljID0gaXNOYU4odmFsdWUpO1xuICBpZiAoaXNOb25OdW1lcmljIHx8IHZhbHVlID09PSAwIHx8IGlzVW5pdGxlc3NOdW1iZXIuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgaXNVbml0bGVzc051bWJlcltuYW1lXSkge1xuICAgIHJldHVybiAnJyArIHZhbHVlOyAvLyBjYXN0IHRvIHN0cmluZ1xuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKTtcbiAgfVxuICByZXR1cm4gdmFsdWUgKyAncHgnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRhbmdlcm91c1N0eWxlVmFsdWU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGRlcHJlY2F0ZWRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG4vKipcbiAqIFRoaXMgd2lsbCBsb2cgYSBzaW5nbGUgZGVwcmVjYXRpb24gbm90aWNlIHBlciBmdW5jdGlvbiBhbmQgZm9yd2FyZCB0aGUgY2FsbFxuICogb24gdG8gdGhlIG5ldyBBUEkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZuTmFtZSBUaGUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBuZXdNb2R1bGUgVGhlIG1vZHVsZSB0aGF0IGZuIHdpbGwgZXhpc3QgaW5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuZXdQYWNrYWdlIFRoZSBtb2R1bGUgdGhhdCBmbiB3aWxsIGV4aXN0IGluXG4gKiBAcGFyYW0geyp9IGN0eCBUaGUgY29udGV4dCB0aGlzIGZvcndhcmRlZCBjYWxsIHNob3VsZCBydW4gaW5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBmb3J3YXJkIG9uIHRvXG4gKiBAcmV0dXJuIHtmdW5jdGlvbn0gVGhlIGZ1bmN0aW9uIHRoYXQgd2lsbCB3YXJuIG9uY2UgYW5kIHRoZW4gY2FsbCBmblxuICovXG5mdW5jdGlvbiBkZXByZWNhdGVkKGZuTmFtZSwgbmV3TW9kdWxlLCBuZXdQYWNrYWdlLCBjdHgsIGZuKSB7XG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YXIgbmV3Rm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyh3YXJuZWQsXG4gICAgICAvLyBSZXF1aXJlIGV4YW1wbGVzIGluIHRoaXMgc3RyaW5nIG11c3QgYmUgc3BsaXQgdG8gcHJldmVudCBSZWFjdCdzXG4gICAgICAvLyBidWlsZCB0b29scyBmcm9tIG1pc3Rha2luZyB0aGVtIGZvciByZWFsIHJlcXVpcmVzLlxuICAgICAgLy8gT3RoZXJ3aXNlIHRoZSBidWlsZCB0b29scyB3aWxsIGF0dGVtcHQgdG8gYnVpbGQgYSAnJXMnIG1vZHVsZS5cbiAgICAgICdSZWFjdC4lcyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlICVzLiVzIGZyb20gcmVxdWlyZScgKyAnKFxcJyVzXFwnKSAnICsgJ2luc3RlYWQuJywgZm5OYW1lLCBuZXdNb2R1bGUsIGZuTmFtZSwgbmV3UGFja2FnZSkgOiB1bmRlZmluZWQ7XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGZuLmFwcGx5KGN0eCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIC8vIFdlIG5lZWQgdG8gbWFrZSBzdXJlIGFsbCBwcm9wZXJ0aWVzIG9mIHRoZSBvcmlnaW5hbCBmbiBhcmUgY29waWVkIG92ZXIuXG4gICAgLy8gSW4gcGFydGljdWxhciwgdGhpcyBpcyBuZWVkZWQgdG8gc3VwcG9ydCBQcm9wVHlwZXNcbiAgICByZXR1cm4gYXNzaWduKG5ld0ZuLCBmbik7XG4gIH1cblxuICByZXR1cm4gZm47XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlZDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRVNDQVBFX0xPT0tVUCA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPic6ICcmZ3Q7JyxcbiAgJzwnOiAnJmx0OycsXG4gICdcIic6ICcmcXVvdDsnLFxuICAnXFwnJzogJyYjeDI3Oydcbn07XG5cbnZhciBFU0NBUEVfUkVHRVggPSAvWyY+PFwiJ10vZztcblxuZnVuY3Rpb24gZXNjYXBlcihtYXRjaCkge1xuICByZXR1cm4gRVNDQVBFX0xPT0tVUFttYXRjaF07XG59XG5cbi8qKlxuICogRXNjYXBlcyB0ZXh0IHRvIHByZXZlbnQgc2NyaXB0aW5nIGF0dGFja3MuXG4gKlxuICogQHBhcmFtIHsqfSB0ZXh0IFRleHQgdmFsdWUgdG8gZXNjYXBlLlxuICogQHJldHVybiB7c3RyaW5nfSBBbiBlc2NhcGVkIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyKHRleHQpIHtcbiAgcmV0dXJuICgnJyArIHRleHQpLnJlcGxhY2UoRVNDQVBFX1JFR0VYLCBlc2NhcGVyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlc2NhcGVUZXh0Q29udGVudEZvckJyb3dzZXI7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGZpbmRET01Ob2RlXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0Q3VycmVudE93bmVyID0gcmVxdWlyZSgnLi9SZWFjdEN1cnJlbnRPd25lcicpO1xudmFyIFJlYWN0SW5zdGFuY2VNYXAgPSByZXF1aXJlKCcuL1JlYWN0SW5zdGFuY2VNYXAnKTtcbnZhciBSZWFjdE1vdW50ID0gcmVxdWlyZSgnLi9SZWFjdE1vdW50Jyk7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcbnZhciB3YXJuaW5nID0gcmVxdWlyZSgnZmJqcy9saWIvd2FybmluZycpO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIERPTSBub2RlIHJlbmRlcmVkIGJ5IHRoaXMgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge1JlYWN0Q29tcG9uZW50fERPTUVsZW1lbnR9IGNvbXBvbmVudE9yRWxlbWVudFxuICogQHJldHVybiB7P0RPTUVsZW1lbnR9IFRoZSByb290IG5vZGUgb2YgdGhpcyBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBmaW5kRE9NTm9kZShjb21wb25lbnRPckVsZW1lbnQpIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YXIgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50O1xuICAgIGlmIChvd25lciAhPT0gbnVsbCkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IHdhcm5pbmcob3duZXIuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyLCAnJXMgaXMgYWNjZXNzaW5nIGdldERPTU5vZGUgb3IgZmluZERPTU5vZGUgaW5zaWRlIGl0cyByZW5kZXIoKS4gJyArICdyZW5kZXIoKSBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4gSXQgc2hvdWxkICcgKyAnbmV2ZXIgYWNjZXNzIHNvbWV0aGluZyB0aGF0IHJlcXVpcmVzIHN0YWxlIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgJyArICdyZW5kZXIsIHN1Y2ggYXMgcmVmcy4gTW92ZSB0aGlzIGxvZ2ljIHRvIGNvbXBvbmVudERpZE1vdW50IGFuZCAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZSBpbnN0ZWFkLicsIG93bmVyLmdldE5hbWUoKSB8fCAnQSBjb21wb25lbnQnKSA6IHVuZGVmaW5lZDtcbiAgICAgIG93bmVyLl93YXJuZWRBYm91dFJlZnNJblJlbmRlciA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmIChjb21wb25lbnRPckVsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChjb21wb25lbnRPckVsZW1lbnQubm9kZVR5cGUgPT09IDEpIHtcbiAgICByZXR1cm4gY29tcG9uZW50T3JFbGVtZW50O1xuICB9XG4gIGlmIChSZWFjdEluc3RhbmNlTWFwLmhhcyhjb21wb25lbnRPckVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIFJlYWN0TW91bnQuZ2V0Tm9kZUZyb21JbnN0YW5jZShjb21wb25lbnRPckVsZW1lbnQpO1xuICB9XG4gICEoY29tcG9uZW50T3JFbGVtZW50LnJlbmRlciA9PSBudWxsIHx8IHR5cGVvZiBjb21wb25lbnRPckVsZW1lbnQucmVuZGVyICE9PSAnZnVuY3Rpb24nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdmaW5kRE9NTm9kZSB3YXMgY2FsbGVkIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJykgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICAhZmFsc2UgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRWxlbWVudCBhcHBlYXJzIHRvIGJlIG5laXRoZXIgUmVhY3RDb21wb25lbnQgbm9yIERPTU5vZGUgKGtleXM6ICVzKScsIE9iamVjdC5rZXlzKGNvbXBvbmVudE9yRWxlbWVudCkpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmaW5kRE9NTm9kZTsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZmxhdHRlbkNoaWxkcmVuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgdHJhdmVyc2VBbGxDaGlsZHJlbiA9IHJlcXVpcmUoJy4vdHJhdmVyc2VBbGxDaGlsZHJlbicpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbi8qKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gdHJhdmVyc2VDb250ZXh0IENvbnRleHQgcGFzc2VkIHRocm91Z2ggdHJhdmVyc2FsLlxuICogQHBhcmFtIHs/UmVhY3RDb21wb25lbnR9IGNoaWxkIFJlYWN0IGNoaWxkIGNvbXBvbmVudC5cbiAqIEBwYXJhbSB7IXN0cmluZ30gbmFtZSBTdHJpbmcgbmFtZSBvZiBrZXkgcGF0aCB0byBjaGlsZC5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlblNpbmdsZUNoaWxkSW50b0NvbnRleHQodHJhdmVyc2VDb250ZXh0LCBjaGlsZCwgbmFtZSkge1xuICAvLyBXZSBmb3VuZCBhIGNvbXBvbmVudCBpbnN0YW5jZS5cbiAgdmFyIHJlc3VsdCA9IHRyYXZlcnNlQ29udGV4dDtcbiAgdmFyIGtleVVuaXF1ZSA9IHJlc3VsdFtuYW1lXSA9PT0gdW5kZWZpbmVkO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGtleVVuaXF1ZSwgJ2ZsYXR0ZW5DaGlsZHJlbiguLi4pOiBFbmNvdW50ZXJlZCB0d28gY2hpbGRyZW4gd2l0aCB0aGUgc2FtZSBrZXksICcgKyAnYCVzYC4gQ2hpbGQga2V5cyBtdXN0IGJlIHVuaXF1ZTsgd2hlbiB0d28gY2hpbGRyZW4gc2hhcmUgYSBrZXksIG9ubHkgJyArICd0aGUgZmlyc3QgY2hpbGQgd2lsbCBiZSB1c2VkLicsIG5hbWUpIDogdW5kZWZpbmVkO1xuICB9XG4gIGlmIChrZXlVbmlxdWUgJiYgY2hpbGQgIT0gbnVsbCkge1xuICAgIHJlc3VsdFtuYW1lXSA9IGNoaWxkO1xuICB9XG59XG5cbi8qKlxuICogRmxhdHRlbnMgY2hpbGRyZW4gdGhhdCBhcmUgdHlwaWNhbGx5IHNwZWNpZmllZCBhcyBgcHJvcHMuY2hpbGRyZW5gLiBBbnkgbnVsbFxuICogY2hpbGRyZW4gd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdGluZyBvYmplY3QuXG4gKiBAcmV0dXJuIHshb2JqZWN0fSBmbGF0dGVuZWQgY2hpbGRyZW4ga2V5ZWQgYnkgbmFtZS5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbkNoaWxkcmVuKGNoaWxkcmVuKSB7XG4gIGlmIChjaGlsZHJlbiA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGNoaWxkcmVuO1xuICB9XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgdHJhdmVyc2VBbGxDaGlsZHJlbihjaGlsZHJlbiwgZmxhdHRlblNpbmdsZUNoaWxkSW50b0NvbnRleHQsIHJlc3VsdCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZmxhdHRlbkNoaWxkcmVuOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBmb3JFYWNoQWNjdW11bGF0ZWRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQHBhcmFtIHthcnJheX0gYXJyIGFuIFwiYWNjdW11bGF0aW9uXCIgb2YgaXRlbXMgd2hpY2ggaXMgZWl0aGVyIGFuIEFycmF5IG9yXG4gKiBhIHNpbmdsZSBpdGVtLiBVc2VmdWwgd2hlbiBwYWlyZWQgd2l0aCB0aGUgYGFjY3VtdWxhdGVgIG1vZHVsZS4gVGhpcyBpcyBhXG4gKiBzaW1wbGUgdXRpbGl0eSB0aGF0IGFsbG93cyB1cyB0byByZWFzb24gYWJvdXQgYSBjb2xsZWN0aW9uIG9mIGl0ZW1zLCBidXRcbiAqIGhhbmRsaW5nIHRoZSBjYXNlIHdoZW4gdGhlcmUgaXMgZXhhY3RseSBvbmUgaXRlbSAoYW5kIHdlIGRvIG5vdCBuZWVkIHRvXG4gKiBhbGxvY2F0ZSBhbiBhcnJheSkuXG4gKi9cbnZhciBmb3JFYWNoQWNjdW11bGF0ZWQgPSBmdW5jdGlvbiAoYXJyLCBjYiwgc2NvcGUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIGFyci5mb3JFYWNoKGNiLCBzY29wZSk7XG4gIH0gZWxzZSBpZiAoYXJyKSB7XG4gICAgY2IuY2FsbChzY29wZSwgYXJyKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoQWNjdW11bGF0ZWQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGdldEV2ZW50Q2hhckNvZGVcbiAqIEB0eXBlY2hlY2tzIHN0YXRpYy1vbmx5XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBjaGFyQ29kZWAgcmVwcmVzZW50cyB0aGUgYWN0dWFsIFwiY2hhcmFjdGVyIGNvZGVcIiBhbmQgaXMgc2FmZSB0byB1c2Ugd2l0aFxuICogYFN0cmluZy5mcm9tQ2hhckNvZGVgLiBBcyBzdWNoLCBvbmx5IGtleXMgdGhhdCBjb3JyZXNwb25kIHRvIHByaW50YWJsZVxuICogY2hhcmFjdGVycyBwcm9kdWNlIGEgdmFsaWQgYGNoYXJDb2RlYCwgdGhlIG9ubHkgZXhjZXB0aW9uIHRvIHRoaXMgaXMgRW50ZXIuXG4gKiBUaGUgVGFiLWtleSBpcyBjb25zaWRlcmVkIG5vbi1wcmludGFibGUgYW5kIGRvZXMgbm90IGhhdmUgYSBgY2hhckNvZGVgLFxuICogcHJlc3VtYWJseSBiZWNhdXNlIGl0IGRvZXMgbm90IHByb2R1Y2UgYSB0YWItY2hhcmFjdGVyIGluIGJyb3dzZXJzLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gTm9ybWFsaXplZCBgY2hhckNvZGVgIHByb3BlcnR5LlxuICovXG5mdW5jdGlvbiBnZXRFdmVudENoYXJDb2RlKG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBjaGFyQ29kZTtcbiAgdmFyIGtleUNvZGUgPSBuYXRpdmVFdmVudC5rZXlDb2RlO1xuXG4gIGlmICgnY2hhckNvZGUnIGluIG5hdGl2ZUV2ZW50KSB7XG4gICAgY2hhckNvZGUgPSBuYXRpdmVFdmVudC5jaGFyQ29kZTtcblxuICAgIC8vIEZGIGRvZXMgbm90IHNldCBgY2hhckNvZGVgIGZvciB0aGUgRW50ZXIta2V5LCBjaGVjayBhZ2FpbnN0IGBrZXlDb2RlYC5cbiAgICBpZiAoY2hhckNvZGUgPT09IDAgJiYga2V5Q29kZSA9PT0gMTMpIHtcbiAgICAgIGNoYXJDb2RlID0gMTM7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElFOCBkb2VzIG5vdCBpbXBsZW1lbnQgYGNoYXJDb2RlYCwgYnV0IGBrZXlDb2RlYCBoYXMgdGhlIGNvcnJlY3QgdmFsdWUuXG4gICAgY2hhckNvZGUgPSBrZXlDb2RlO1xuICB9XG5cbiAgLy8gU29tZSBub24tcHJpbnRhYmxlIGtleXMgYXJlIHJlcG9ydGVkIGluIGBjaGFyQ29kZWAvYGtleUNvZGVgLCBkaXNjYXJkIHRoZW0uXG4gIC8vIE11c3Qgbm90IGRpc2NhcmQgdGhlIChub24tKXByaW50YWJsZSBFbnRlci1rZXkuXG4gIGlmIChjaGFyQ29kZSA+PSAzMiB8fCBjaGFyQ29kZSA9PT0gMTMpIHtcbiAgICByZXR1cm4gY2hhckNvZGU7XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRFdmVudENoYXJDb2RlOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBnZXRFdmVudEtleVxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBnZXRFdmVudENoYXJDb2RlID0gcmVxdWlyZSgnLi9nZXRFdmVudENoYXJDb2RlJyk7XG5cbi8qKlxuICogTm9ybWFsaXphdGlvbiBvZiBkZXByZWNhdGVkIEhUTUw1IGBrZXlgIHZhbHVlc1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvS2V5Ym9hcmRFdmVudCNLZXlfbmFtZXNcbiAqL1xudmFyIG5vcm1hbGl6ZUtleSA9IHtcbiAgJ0VzYyc6ICdFc2NhcGUnLFxuICAnU3BhY2ViYXInOiAnICcsXG4gICdMZWZ0JzogJ0Fycm93TGVmdCcsXG4gICdVcCc6ICdBcnJvd1VwJyxcbiAgJ1JpZ2h0JzogJ0Fycm93UmlnaHQnLFxuICAnRG93bic6ICdBcnJvd0Rvd24nLFxuICAnRGVsJzogJ0RlbGV0ZScsXG4gICdXaW4nOiAnT1MnLFxuICAnTWVudSc6ICdDb250ZXh0TWVudScsXG4gICdBcHBzJzogJ0NvbnRleHRNZW51JyxcbiAgJ1Njcm9sbCc6ICdTY3JvbGxMb2NrJyxcbiAgJ01velByaW50YWJsZUtleSc6ICdVbmlkZW50aWZpZWQnXG59O1xuXG4vKipcbiAqIFRyYW5zbGF0aW9uIGZyb20gbGVnYWN5IGBrZXlDb2RlYCB0byBIVE1MNSBga2V5YFxuICogT25seSBzcGVjaWFsIGtleXMgc3VwcG9ydGVkLCBhbGwgb3RoZXJzIGRlcGVuZCBvbiBrZXlib2FyZCBsYXlvdXQgb3IgYnJvd3NlclxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvS2V5Ym9hcmRFdmVudCNLZXlfbmFtZXNcbiAqL1xudmFyIHRyYW5zbGF0ZVRvS2V5ID0ge1xuICA4OiAnQmFja3NwYWNlJyxcbiAgOTogJ1RhYicsXG4gIDEyOiAnQ2xlYXInLFxuICAxMzogJ0VudGVyJyxcbiAgMTY6ICdTaGlmdCcsXG4gIDE3OiAnQ29udHJvbCcsXG4gIDE4OiAnQWx0JyxcbiAgMTk6ICdQYXVzZScsXG4gIDIwOiAnQ2Fwc0xvY2snLFxuICAyNzogJ0VzY2FwZScsXG4gIDMyOiAnICcsXG4gIDMzOiAnUGFnZVVwJyxcbiAgMzQ6ICdQYWdlRG93bicsXG4gIDM1OiAnRW5kJyxcbiAgMzY6ICdIb21lJyxcbiAgMzc6ICdBcnJvd0xlZnQnLFxuICAzODogJ0Fycm93VXAnLFxuICAzOTogJ0Fycm93UmlnaHQnLFxuICA0MDogJ0Fycm93RG93bicsXG4gIDQ1OiAnSW5zZXJ0JyxcbiAgNDY6ICdEZWxldGUnLFxuICAxMTI6ICdGMScsIDExMzogJ0YyJywgMTE0OiAnRjMnLCAxMTU6ICdGNCcsIDExNjogJ0Y1JywgMTE3OiAnRjYnLFxuICAxMTg6ICdGNycsIDExOTogJ0Y4JywgMTIwOiAnRjknLCAxMjE6ICdGMTAnLCAxMjI6ICdGMTEnLCAxMjM6ICdGMTInLFxuICAxNDQ6ICdOdW1Mb2NrJyxcbiAgMTQ1OiAnU2Nyb2xsTG9jaycsXG4gIDIyNDogJ01ldGEnXG59O1xuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge3N0cmluZ30gTm9ybWFsaXplZCBga2V5YCBwcm9wZXJ0eS5cbiAqL1xuZnVuY3Rpb24gZ2V0RXZlbnRLZXkobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LmtleSkge1xuICAgIC8vIE5vcm1hbGl6ZSBpbmNvbnNpc3RlbnQgdmFsdWVzIHJlcG9ydGVkIGJ5IGJyb3dzZXJzIGR1ZSB0b1xuICAgIC8vIGltcGxlbWVudGF0aW9ucyBvZiBhIHdvcmtpbmcgZHJhZnQgc3BlY2lmaWNhdGlvbi5cblxuICAgIC8vIEZpcmVGb3ggaW1wbGVtZW50cyBga2V5YCBidXQgcmV0dXJucyBgTW96UHJpbnRhYmxlS2V5YCBmb3IgYWxsXG4gICAgLy8gcHJpbnRhYmxlIGNoYXJhY3RlcnMgKG5vcm1hbGl6ZWQgdG8gYFVuaWRlbnRpZmllZGApLCBpZ25vcmUgaXQuXG4gICAgdmFyIGtleSA9IG5vcm1hbGl6ZUtleVtuYXRpdmVFdmVudC5rZXldIHx8IG5hdGl2ZUV2ZW50LmtleTtcbiAgICBpZiAoa2V5ICE9PSAnVW5pZGVudGlmaWVkJykge1xuICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gIH1cblxuICAvLyBCcm93c2VyIGRvZXMgbm90IGltcGxlbWVudCBga2V5YCwgcG9seWZpbGwgYXMgbXVjaCBvZiBpdCBhcyB3ZSBjYW4uXG4gIGlmIChuYXRpdmVFdmVudC50eXBlID09PSAna2V5cHJlc3MnKSB7XG4gICAgdmFyIGNoYXJDb2RlID0gZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCk7XG5cbiAgICAvLyBUaGUgZW50ZXIta2V5IGlzIHRlY2huaWNhbGx5IGJvdGggcHJpbnRhYmxlIGFuZCBub24tcHJpbnRhYmxlIGFuZCBjYW5cbiAgICAvLyB0aHVzIGJlIGNhcHR1cmVkIGJ5IGBrZXlwcmVzc2AsIG5vIG90aGVyIG5vbi1wcmludGFibGUga2V5IHNob3VsZC5cbiAgICByZXR1cm4gY2hhckNvZGUgPT09IDEzID8gJ0VudGVyJyA6IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUpO1xuICB9XG4gIGlmIChuYXRpdmVFdmVudC50eXBlID09PSAna2V5ZG93bicgfHwgbmF0aXZlRXZlbnQudHlwZSA9PT0gJ2tleXVwJykge1xuICAgIC8vIFdoaWxlIHVzZXIga2V5Ym9hcmQgbGF5b3V0IGRldGVybWluZXMgdGhlIGFjdHVhbCBtZWFuaW5nIG9mIGVhY2hcbiAgICAvLyBga2V5Q29kZWAgdmFsdWUsIGFsbW9zdCBhbGwgZnVuY3Rpb24ga2V5cyBoYXZlIGEgdW5pdmVyc2FsIHZhbHVlLlxuICAgIHJldHVybiB0cmFuc2xhdGVUb0tleVtuYXRpdmVFdmVudC5rZXlDb2RlXSB8fCAnVW5pZGVudGlmaWVkJztcbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RXZlbnRLZXk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGdldEV2ZW50TW9kaWZpZXJTdGF0ZVxuICogQHR5cGVjaGVja3Mgc3RhdGljLW9ubHlcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICogVHJhbnNsYXRpb24gZnJvbSBtb2RpZmllciBrZXkgdG8gdGhlIGFzc29jaWF0ZWQgcHJvcGVydHkgaW4gdGhlIGV2ZW50LlxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2tleXMtTW9kaWZpZXJzXG4gKi9cblxudmFyIG1vZGlmaWVyS2V5VG9Qcm9wID0ge1xuICAnQWx0JzogJ2FsdEtleScsXG4gICdDb250cm9sJzogJ2N0cmxLZXknLFxuICAnTWV0YSc6ICdtZXRhS2V5JyxcbiAgJ1NoaWZ0JzogJ3NoaWZ0S2V5J1xufTtcblxuLy8gSUU4IGRvZXMgbm90IGltcGxlbWVudCBnZXRNb2RpZmllclN0YXRlIHNvIHdlIHNpbXBseSBtYXAgaXQgdG8gdGhlIG9ubHlcbi8vIG1vZGlmaWVyIGtleXMgZXhwb3NlZCBieSB0aGUgZXZlbnQgaXRzZWxmLCBkb2VzIG5vdCBzdXBwb3J0IExvY2sta2V5cy5cbi8vIEN1cnJlbnRseSwgYWxsIG1ham9yIGJyb3dzZXJzIGV4Y2VwdCBDaHJvbWUgc2VlbXMgdG8gc3VwcG9ydCBMb2NrLWtleXMuXG5mdW5jdGlvbiBtb2RpZmllclN0YXRlR2V0dGVyKGtleUFyZykge1xuICB2YXIgc3ludGhldGljRXZlbnQgPSB0aGlzO1xuICB2YXIgbmF0aXZlRXZlbnQgPSBzeW50aGV0aWNFdmVudC5uYXRpdmVFdmVudDtcbiAgaWYgKG5hdGl2ZUV2ZW50LmdldE1vZGlmaWVyU3RhdGUpIHtcbiAgICByZXR1cm4gbmF0aXZlRXZlbnQuZ2V0TW9kaWZpZXJTdGF0ZShrZXlBcmcpO1xuICB9XG4gIHZhciBrZXlQcm9wID0gbW9kaWZpZXJLZXlUb1Byb3Bba2V5QXJnXTtcbiAgcmV0dXJuIGtleVByb3AgPyAhIW5hdGl2ZUV2ZW50W2tleVByb3BdIDogZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldEV2ZW50TW9kaWZpZXJTdGF0ZShuYXRpdmVFdmVudCkge1xuICByZXR1cm4gbW9kaWZpZXJTdGF0ZUdldHRlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRFdmVudE1vZGlmaWVyU3RhdGU7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGdldEV2ZW50VGFyZ2V0XG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBHZXRzIHRoZSB0YXJnZXQgbm9kZSBmcm9tIGEgbmF0aXZlIGJyb3dzZXIgZXZlbnQgYnkgYWNjb3VudGluZyBmb3JcbiAqIGluY29uc2lzdGVuY2llcyBpbiBicm93c2VyIERPTSBBUElzLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudCBOYXRpdmUgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge0RPTUV2ZW50VGFyZ2V0fSBUYXJnZXQgbm9kZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpIHtcbiAgdmFyIHRhcmdldCA9IG5hdGl2ZUV2ZW50LnRhcmdldCB8fCBuYXRpdmVFdmVudC5zcmNFbGVtZW50IHx8IHdpbmRvdztcbiAgLy8gU2FmYXJpIG1heSBmaXJlIGV2ZW50cyBvbiB0ZXh0IG5vZGVzIChOb2RlLlRFWFRfTk9ERSBpcyAzKS5cbiAgLy8gQHNlZSBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2pzL2V2ZW50c19wcm9wZXJ0aWVzLmh0bWxcbiAgcmV0dXJuIHRhcmdldC5ub2RlVHlwZSA9PT0gMyA/IHRhcmdldC5wYXJlbnROb2RlIDogdGFyZ2V0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEV2ZW50VGFyZ2V0OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBnZXRJdGVyYXRvckZuXG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyogZ2xvYmFsIFN5bWJvbCAqL1xudmFyIElURVJBVE9SX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLml0ZXJhdG9yO1xudmFyIEZBVVhfSVRFUkFUT1JfU1lNQk9MID0gJ0BAaXRlcmF0b3InOyAvLyBCZWZvcmUgU3ltYm9sIHNwZWMuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgaXRlcmF0b3IgbWV0aG9kIGZ1bmN0aW9uIGNvbnRhaW5lZCBvbiB0aGUgaXRlcmFibGUgb2JqZWN0LlxuICpcbiAqIEJlIHN1cmUgdG8gaW52b2tlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBpdGVyYWJsZSBhcyBjb250ZXh0OlxuICpcbiAqICAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4obXlJdGVyYWJsZSk7XG4gKiAgICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAqICAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhdG9yRm4uY2FsbChteUl0ZXJhYmxlKTtcbiAqICAgICAgIC4uLlxuICogICAgIH1cbiAqXG4gKiBAcGFyYW0gez9vYmplY3R9IG1heWJlSXRlcmFibGVcbiAqIEByZXR1cm4gez9mdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gZ2V0SXRlcmF0b3JGbihtYXliZUl0ZXJhYmxlKSB7XG4gIHZhciBpdGVyYXRvckZuID0gbWF5YmVJdGVyYWJsZSAmJiAoSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXSk7XG4gIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpdGVyYXRvckZuO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0SXRlcmF0b3JGbjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgZ2V0Tm9kZUZvckNoYXJhY3Rlck9mZnNldFxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBHaXZlbiBhbnkgbm9kZSByZXR1cm4gdGhlIGZpcnN0IGxlYWYgbm9kZSB3aXRob3V0IGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHJldHVybiB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX1cbiAqL1xuZnVuY3Rpb24gZ2V0TGVhZk5vZGUobm9kZSkge1xuICB3aGlsZSAobm9kZSAmJiBub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICBub2RlID0gbm9kZS5maXJzdENoaWxkO1xuICB9XG4gIHJldHVybiBub2RlO1xufVxuXG4vKipcbiAqIEdldCB0aGUgbmV4dCBzaWJsaW5nIHdpdGhpbiBhIGNvbnRhaW5lci4gVGhpcyB3aWxsIHdhbGsgdXAgdGhlXG4gKiBET00gaWYgYSBub2RlJ3Mgc2libGluZ3MgaGF2ZSBiZWVuIGV4aGF1c3RlZC5cbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9IG5vZGVcbiAqIEByZXR1cm4gez9ET01FbGVtZW50fERPTVRleHROb2RlfVxuICovXG5mdW5jdGlvbiBnZXRTaWJsaW5nTm9kZShub2RlKSB7XG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICAgIHJldHVybiBub2RlLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG59XG5cbi8qKlxuICogR2V0IG9iamVjdCBkZXNjcmliaW5nIHRoZSBub2RlcyB3aGljaCBjb250YWluIGNoYXJhY3RlcnMgYXQgb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gcm9vdFxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybiB7P29iamVjdH1cbiAqL1xuZnVuY3Rpb24gZ2V0Tm9kZUZvckNoYXJhY3Rlck9mZnNldChyb290LCBvZmZzZXQpIHtcbiAgdmFyIG5vZGUgPSBnZXRMZWFmTm9kZShyb290KTtcbiAgdmFyIG5vZGVTdGFydCA9IDA7XG4gIHZhciBub2RlRW5kID0gMDtcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7XG4gICAgICBub2RlRW5kID0gbm9kZVN0YXJ0ICsgbm9kZS50ZXh0Q29udGVudC5sZW5ndGg7XG5cbiAgICAgIGlmIChub2RlU3RhcnQgPD0gb2Zmc2V0ICYmIG5vZGVFbmQgPj0gb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbm9kZTogbm9kZSxcbiAgICAgICAgICBvZmZzZXQ6IG9mZnNldCAtIG5vZGVTdGFydFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBub2RlU3RhcnQgPSBub2RlRW5kO1xuICAgIH1cblxuICAgIG5vZGUgPSBnZXRMZWFmTm9kZShnZXRTaWJsaW5nTm9kZShub2RlKSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0OyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBnZXRUZXh0Q29udGVudEFjY2Vzc29yXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgY29udGVudEtleSA9IG51bGw7XG5cbi8qKlxuICogR2V0cyB0aGUga2V5IHVzZWQgdG8gYWNjZXNzIHRleHQgY29udGVudCBvbiBhIERPTSBub2RlLlxuICpcbiAqIEByZXR1cm4gez9zdHJpbmd9IEtleSB1c2VkIHRvIGFjY2VzcyB0ZXh0IGNvbnRlbnQuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gZ2V0VGV4dENvbnRlbnRBY2Nlc3NvcigpIHtcbiAgaWYgKCFjb250ZW50S2V5ICYmIEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICAgIC8vIFByZWZlciB0ZXh0Q29udGVudCB0byBpbm5lclRleHQgYmVjYXVzZSBtYW55IGJyb3dzZXJzIHN1cHBvcnQgYm90aCBidXRcbiAgICAvLyBTVkcgPHRleHQ+IGVsZW1lbnRzIGRvbid0IHN1cHBvcnQgaW5uZXJUZXh0IGV2ZW4gd2hlbiA8ZGl2PiBkb2VzLlxuICAgIGNvbnRlbnRLZXkgPSAndGV4dENvbnRlbnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCA/ICd0ZXh0Q29udGVudCcgOiAnaW5uZXJUZXh0JztcbiAgfVxuICByZXR1cm4gY29udGVudEtleTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRUZXh0Q29udGVudEFjY2Vzc29yOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSBpbnN0YW50aWF0ZVJlYWN0Q29tcG9uZW50XG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0Q29tcG9zaXRlQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9SZWFjdENvbXBvc2l0ZUNvbXBvbmVudCcpO1xudmFyIFJlYWN0RW1wdHlDb21wb25lbnQgPSByZXF1aXJlKCcuL1JlYWN0RW1wdHlDb21wb25lbnQnKTtcbnZhciBSZWFjdE5hdGl2ZUNvbXBvbmVudCA9IHJlcXVpcmUoJy4vUmVhY3ROYXRpdmVDb21wb25lbnQnKTtcblxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vT2JqZWN0LmFzc2lnbicpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbi8vIFRvIGF2b2lkIGEgY3ljbGljIGRlcGVuZGVuY3ksIHdlIGNyZWF0ZSB0aGUgZmluYWwgY2xhc3MgaW4gdGhpcyBtb2R1bGVcbnZhciBSZWFjdENvbXBvc2l0ZUNvbXBvbmVudFdyYXBwZXIgPSBmdW5jdGlvbiAoKSB7fTtcbmFzc2lnbihSZWFjdENvbXBvc2l0ZUNvbXBvbmVudFdyYXBwZXIucHJvdG90eXBlLCBSZWFjdENvbXBvc2l0ZUNvbXBvbmVudC5NaXhpbiwge1xuICBfaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudDogaW5zdGFudGlhdGVSZWFjdENvbXBvbmVudFxufSk7XG5cbmZ1bmN0aW9uIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShvd25lcikge1xuICBpZiAob3duZXIpIHtcbiAgICB2YXIgbmFtZSA9IG93bmVyLmdldE5hbWUoKTtcbiAgICBpZiAobmFtZSkge1xuICAgICAgcmV0dXJuICcgQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBuYW1lICsgJ2AuJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSB0eXBlIHJlZmVyZW5jZSBpcyBhIGtub3duIGludGVybmFsIHR5cGUuIEkuZS4gbm90IGEgdXNlclxuICogcHJvdmlkZWQgY29tcG9zaXRlIHR5cGUuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gdHlwZVxuICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSB2YWxpZCBpbnRlcm5hbCB0eXBlLlxuICovXG5mdW5jdGlvbiBpc0ludGVybmFsQ29tcG9uZW50VHlwZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdHlwZS5wcm90b3R5cGUgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB0eXBlLnByb3RvdHlwZS5tb3VudENvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdHlwZS5wcm90b3R5cGUucmVjZWl2ZUNvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBHaXZlbiBhIFJlYWN0Tm9kZSwgY3JlYXRlIGFuIGluc3RhbmNlIHRoYXQgd2lsbCBhY3R1YWxseSBiZSBtb3VudGVkLlxuICpcbiAqIEBwYXJhbSB7UmVhY3ROb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtvYmplY3R9IEEgbmV3IGluc3RhbmNlIG9mIHRoZSBlbGVtZW50J3MgY29uc3RydWN0b3IuXG4gKiBAcHJvdGVjdGVkXG4gKi9cbmZ1bmN0aW9uIGluc3RhbnRpYXRlUmVhY3RDb21wb25lbnQobm9kZSkge1xuICB2YXIgaW5zdGFuY2U7XG5cbiAgaWYgKG5vZGUgPT09IG51bGwgfHwgbm9kZSA9PT0gZmFsc2UpIHtcbiAgICBpbnN0YW5jZSA9IG5ldyBSZWFjdEVtcHR5Q29tcG9uZW50KGluc3RhbnRpYXRlUmVhY3RDb21wb25lbnQpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBub2RlID09PSAnb2JqZWN0Jykge1xuICAgIHZhciBlbGVtZW50ID0gbm9kZTtcbiAgICAhKGVsZW1lbnQgJiYgKHR5cGVvZiBlbGVtZW50LnR5cGUgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGVsZW1lbnQudHlwZSA9PT0gJ3N0cmluZycpKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdFbGVtZW50IHR5cGUgaXMgaW52YWxpZDogZXhwZWN0ZWQgYSBzdHJpbmcgKGZvciBidWlsdC1pbiBjb21wb25lbnRzKSAnICsgJ29yIGEgY2xhc3MvZnVuY3Rpb24gKGZvciBjb21wb3NpdGUgY29tcG9uZW50cykgYnV0IGdvdDogJXMuJXMnLCBlbGVtZW50LnR5cGUgPT0gbnVsbCA/IGVsZW1lbnQudHlwZSA6IHR5cGVvZiBlbGVtZW50LnR5cGUsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bShlbGVtZW50Ll9vd25lcikpIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFNwZWNpYWwgY2FzZSBzdHJpbmcgdmFsdWVzXG4gICAgaWYgKHR5cGVvZiBlbGVtZW50LnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpbnN0YW5jZSA9IFJlYWN0TmF0aXZlQ29tcG9uZW50LmNyZWF0ZUludGVybmFsQ29tcG9uZW50KGVsZW1lbnQpO1xuICAgIH0gZWxzZSBpZiAoaXNJbnRlcm5hbENvbXBvbmVudFR5cGUoZWxlbWVudC50eXBlKSkge1xuICAgICAgLy8gVGhpcyBpcyB0ZW1wb3JhcmlseSBhdmFpbGFibGUgZm9yIGN1c3RvbSBjb21wb25lbnRzIHRoYXQgYXJlIG5vdCBzdHJpbmdcbiAgICAgIC8vIHJlcHJlc2VudGF0aW9ucy4gSS5lLiBBUlQuIE9uY2UgdGhvc2UgYXJlIHVwZGF0ZWQgdG8gdXNlIHRoZSBzdHJpbmdcbiAgICAgIC8vIHJlcHJlc2VudGF0aW9uLCB3ZSBjYW4gZHJvcCB0aGlzIGNvZGUgcGF0aC5cbiAgICAgIGluc3RhbmNlID0gbmV3IGVsZW1lbnQudHlwZShlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5zdGFuY2UgPSBuZXcgUmVhY3RDb21wb3NpdGVDb21wb25lbnRXcmFwcGVyKCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBub2RlID09PSAnc3RyaW5nJyB8fCB0eXBlb2Ygbm9kZSA9PT0gJ251bWJlcicpIHtcbiAgICBpbnN0YW5jZSA9IFJlYWN0TmF0aXZlQ29tcG9uZW50LmNyZWF0ZUluc3RhbmNlRm9yVGV4dChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICAhZmFsc2UgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnRW5jb3VudGVyZWQgaW52YWxpZCBSZWFjdCBub2RlIG9mIHR5cGUgJXMnLCB0eXBlb2Ygbm9kZSkgOiBpbnZhcmlhbnQoZmFsc2UpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyh0eXBlb2YgaW5zdGFuY2UuY29uc3RydWN0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBpbnN0YW5jZS5tb3VudENvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgaW5zdGFuY2UucmVjZWl2ZUNvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgaW5zdGFuY2UudW5tb3VudENvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJywgJ09ubHkgUmVhY3QgQ29tcG9uZW50cyBjYW4gYmUgbW91bnRlZC4nKSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFNldHMgdXAgdGhlIGluc3RhbmNlLiBUaGlzIGNhbiBwcm9iYWJseSBqdXN0IG1vdmUgaW50byB0aGUgY29uc3RydWN0b3Igbm93LlxuICBpbnN0YW5jZS5jb25zdHJ1Y3Qobm9kZSk7XG5cbiAgLy8gVGhlc2UgdHdvIGZpZWxkcyBhcmUgdXNlZCBieSB0aGUgRE9NIGFuZCBBUlQgZGlmZmluZyBhbGdvcml0aG1zXG4gIC8vIHJlc3BlY3RpdmVseS4gSW5zdGVhZCBvZiB1c2luZyBleHBhbmRvcyBvbiBjb21wb25lbnRzLCB3ZSBzaG91bGQgYmVcbiAgLy8gc3RvcmluZyB0aGUgc3RhdGUgbmVlZGVkIGJ5IHRoZSBkaWZmaW5nIGFsZ29yaXRobXMgZWxzZXdoZXJlLlxuICBpbnN0YW5jZS5fbW91bnRJbmRleCA9IDA7XG4gIGluc3RhbmNlLl9tb3VudEltYWdlID0gbnVsbDtcblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGluc3RhbmNlLl9pc093bmVyTmVjZXNzYXJ5ID0gZmFsc2U7XG4gICAgaW5zdGFuY2UuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyID0gZmFsc2U7XG4gIH1cblxuICAvLyBJbnRlcm5hbCBpbnN0YW5jZXMgc2hvdWxkIGZ1bGx5IGNvbnN0cnVjdGVkIGF0IHRoaXMgcG9pbnQsIHNvIHRoZXkgc2hvdWxkXG4gIC8vIG5vdCBnZXQgYW55IG5ldyBmaWVsZHMgYWRkZWQgdG8gdGhlbSBhdCB0aGlzIHBvaW50LlxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGlmIChPYmplY3QucHJldmVudEV4dGVuc2lvbnMpIHtcbiAgICAgIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyhpbnN0YW5jZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluc3RhbnRpYXRlUmVhY3RDb21wb25lbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIGlzRXZlbnRTdXBwb3J0ZWRcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJ2ZianMvbGliL0V4ZWN1dGlvbkVudmlyb25tZW50Jyk7XG5cbnZhciB1c2VIYXNGZWF0dXJlO1xuaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICB1c2VIYXNGZWF0dXJlID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24gJiYgZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZSAmJlxuICAvLyBhbHdheXMgcmV0dXJucyB0cnVlIGluIG5ld2VyIGJyb3dzZXJzIGFzIHBlciB0aGUgc3RhbmRhcmQuXG4gIC8vIEBzZWUgaHR0cDovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2RvbS1kb21pbXBsZW1lbnRhdGlvbi1oYXNmZWF0dXJlXG4gIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmhhc0ZlYXR1cmUoJycsICcnKSAhPT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYW4gZXZlbnQgaXMgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBlbnZpcm9ubWVudC5cbiAqXG4gKiBOT1RFOiBUaGlzIHdpbGwgbm90IHdvcmsgY29ycmVjdGx5IGZvciBub24tZ2VuZXJpYyBldmVudHMgc3VjaCBhcyBgY2hhbmdlYCxcbiAqIGByZXNldGAsIGBsb2FkYCwgYGVycm9yYCwgYW5kIGBzZWxlY3RgLlxuICpcbiAqIEJvcnJvd3MgZnJvbSBNb2Rlcm5penIuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVN1ZmZpeCBFdmVudCBuYW1lLCBlLmcuIFwiY2xpY2tcIi5cbiAqIEBwYXJhbSB7P2Jvb2xlYW59IGNhcHR1cmUgQ2hlY2sgaWYgdGhlIGNhcHR1cmUgcGhhc2UgaXMgc3VwcG9ydGVkLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgc3VwcG9ydGVkLlxuICogQGludGVybmFsXG4gKiBAbGljZW5zZSBNb2Rlcm5penIgMy4wLjBwcmUgKEN1c3RvbSBCdWlsZCkgfCBNSVRcbiAqL1xuZnVuY3Rpb24gaXNFdmVudFN1cHBvcnRlZChldmVudE5hbWVTdWZmaXgsIGNhcHR1cmUpIHtcbiAgaWYgKCFFeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00gfHwgY2FwdHVyZSAmJiAhKCdhZGRFdmVudExpc3RlbmVyJyBpbiBkb2N1bWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgZXZlbnROYW1lID0gJ29uJyArIGV2ZW50TmFtZVN1ZmZpeDtcbiAgdmFyIGlzU3VwcG9ydGVkID0gKGV2ZW50TmFtZSBpbiBkb2N1bWVudCk7XG5cbiAgaWYgKCFpc1N1cHBvcnRlZCkge1xuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoZXZlbnROYW1lLCAncmV0dXJuOycpO1xuICAgIGlzU3VwcG9ydGVkID0gdHlwZW9mIGVsZW1lbnRbZXZlbnROYW1lXSA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIGlmICghaXNTdXBwb3J0ZWQgJiYgdXNlSGFzRmVhdHVyZSAmJiBldmVudE5hbWVTdWZmaXggPT09ICd3aGVlbCcpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBvbmx5IHdheSB0byB0ZXN0IHN1cHBvcnQgZm9yIHRoZSBgd2hlZWxgIGV2ZW50IGluIElFOSsuXG4gICAgaXNTdXBwb3J0ZWQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKCdFdmVudHMud2hlZWwnLCAnMy4wJyk7XG4gIH1cblxuICByZXR1cm4gaXNTdXBwb3J0ZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNFdmVudFN1cHBvcnRlZDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgaXNUZXh0SW5wdXRFbGVtZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEBzZWUgaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvdGhlLWlucHV0LWVsZW1lbnQuaHRtbCNpbnB1dC10eXBlLWF0dHItc3VtbWFyeVxuICovXG52YXIgc3VwcG9ydGVkSW5wdXRUeXBlcyA9IHtcbiAgJ2NvbG9yJzogdHJ1ZSxcbiAgJ2RhdGUnOiB0cnVlLFxuICAnZGF0ZXRpbWUnOiB0cnVlLFxuICAnZGF0ZXRpbWUtbG9jYWwnOiB0cnVlLFxuICAnZW1haWwnOiB0cnVlLFxuICAnbW9udGgnOiB0cnVlLFxuICAnbnVtYmVyJzogdHJ1ZSxcbiAgJ3Bhc3N3b3JkJzogdHJ1ZSxcbiAgJ3JhbmdlJzogdHJ1ZSxcbiAgJ3NlYXJjaCc6IHRydWUsXG4gICd0ZWwnOiB0cnVlLFxuICAndGV4dCc6IHRydWUsXG4gICd0aW1lJzogdHJ1ZSxcbiAgJ3VybCc6IHRydWUsXG4gICd3ZWVrJzogdHJ1ZVxufTtcblxuZnVuY3Rpb24gaXNUZXh0SW5wdXRFbGVtZW50KGVsZW0pIHtcbiAgdmFyIG5vZGVOYW1lID0gZWxlbSAmJiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIG5vZGVOYW1lICYmIChub2RlTmFtZSA9PT0gJ2lucHV0JyAmJiBzdXBwb3J0ZWRJbnB1dFR5cGVzW2VsZW0udHlwZV0gfHwgbm9kZU5hbWUgPT09ICd0ZXh0YXJlYScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVGV4dElucHV0RWxlbWVudDsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4gKiBAcHJvdmlkZXNNb2R1bGUgb25seUNoaWxkXG4gKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0RWxlbWVudCA9IHJlcXVpcmUoJy4vUmVhY3RFbGVtZW50Jyk7XG5cbnZhciBpbnZhcmlhbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9pbnZhcmlhbnQnKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBpbiBhIGNvbGxlY3Rpb24gb2YgY2hpbGRyZW4gYW5kIHZlcmlmaWVzIHRoYXQgdGhlcmVcbiAqIGlzIG9ubHkgb25lIGNoaWxkIGluIHRoZSBjb2xsZWN0aW9uLiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzXG4gKiBmdW5jdGlvbiBhc3N1bWVzIHRoYXQgYSBzaW5nbGUgY2hpbGQgZ2V0cyBwYXNzZWQgd2l0aG91dCBhIHdyYXBwZXIsIGJ1dCB0aGVcbiAqIHB1cnBvc2Ugb2YgdGhpcyBoZWxwZXIgZnVuY3Rpb24gaXMgdG8gYWJzdHJhY3QgYXdheSB0aGUgcGFydGljdWxhciBzdHJ1Y3R1cmVcbiAqIG9mIGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSB7P29iamVjdH0gY2hpbGRyZW4gQ2hpbGQgY29sbGVjdGlvbiBzdHJ1Y3R1cmUuXG4gKiBAcmV0dXJuIHtSZWFjdENvbXBvbmVudH0gVGhlIGZpcnN0IGFuZCBvbmx5IGBSZWFjdENvbXBvbmVudGAgY29udGFpbmVkIGluIHRoZVxuICogc3RydWN0dXJlLlxuICovXG5mdW5jdGlvbiBvbmx5Q2hpbGQoY2hpbGRyZW4pIHtcbiAgIVJlYWN0RWxlbWVudC5pc1ZhbGlkRWxlbWVudChjaGlsZHJlbikgPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gaW52YXJpYW50KGZhbHNlLCAnb25seUNoaWxkIG11c3QgYmUgcGFzc2VkIGEgY2hpbGRyZW4gd2l0aCBleGFjdGx5IG9uZSBjaGlsZC4nKSA6IGludmFyaWFudChmYWxzZSkgOiB1bmRlZmluZWQ7XG4gIHJldHVybiBjaGlsZHJlbjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvbmx5Q2hpbGQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHF1b3RlQXR0cmlidXRlVmFsdWVGb3JCcm93c2VyXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyID0gcmVxdWlyZSgnLi9lc2NhcGVUZXh0Q29udGVudEZvckJyb3dzZXInKTtcblxuLyoqXG4gKiBFc2NhcGVzIGF0dHJpYnV0ZSB2YWx1ZSB0byBwcmV2ZW50IHNjcmlwdGluZyBhdHRhY2tzLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gZXNjYXBlLlxuICogQHJldHVybiB7c3RyaW5nfSBBbiBlc2NhcGVkIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gcXVvdGVBdHRyaWJ1dGVWYWx1ZUZvckJyb3dzZXIodmFsdWUpIHtcbiAgcmV0dXJuICdcIicgKyBlc2NhcGVUZXh0Q29udGVudEZvckJyb3dzZXIodmFsdWUpICsgJ1wiJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBxdW90ZUF0dHJpYnV0ZVZhbHVlRm9yQnJvd3NlcjsiLCIvKipcbiAqIENvcHlyaWdodCAyMDEzLTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqXG4qIEBwcm92aWRlc01vZHVsZSByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lclxuKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3RNb3VudCA9IHJlcXVpcmUoJy4vUmVhY3RNb3VudCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0TW91bnQucmVuZGVyU3VidHJlZUludG9Db250YWluZXI7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHNldElubmVySFRNTFxuICovXG5cbi8qIGdsb2JhbHMgTVNBcHAgKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgV0hJVEVTUEFDRV9URVNUID0gL15bIFxcclxcblxcdFxcZl0vO1xudmFyIE5PTlZJU0lCTEVfVEVTVCA9IC88KCEtLXxsaW5rfG5vc2NyaXB0fG1ldGF8c2NyaXB0fHN0eWxlKVsgXFxyXFxuXFx0XFxmXFwvPl0vO1xuXG4vKipcbiAqIFNldCB0aGUgaW5uZXJIVE1MIHByb3BlcnR5IG9mIGEgbm9kZSwgZW5zdXJpbmcgdGhhdCB3aGl0ZXNwYWNlIGlzIHByZXNlcnZlZFxuICogZXZlbiBpbiBJRTguXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbFxuICogQGludGVybmFsXG4gKi9cbnZhciBzZXRJbm5lckhUTUwgPSBmdW5jdGlvbiAobm9kZSwgaHRtbCkge1xuICBub2RlLmlubmVySFRNTCA9IGh0bWw7XG59O1xuXG4vLyBXaW44IGFwcHM6IEFsbG93IGFsbCBodG1sIHRvIGJlIGluc2VydGVkXG5pZiAodHlwZW9mIE1TQXBwICE9PSAndW5kZWZpbmVkJyAmJiBNU0FwcC5leGVjVW5zYWZlTG9jYWxGdW5jdGlvbikge1xuICBzZXRJbm5lckhUTUwgPSBmdW5jdGlvbiAobm9kZSwgaHRtbCkge1xuICAgIE1TQXBwLmV4ZWNVbnNhZmVMb2NhbEZ1bmN0aW9uKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vZGUuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9KTtcbiAgfTtcbn1cblxuaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICAvLyBJRTg6IFdoZW4gdXBkYXRpbmcgYSBqdXN0IGNyZWF0ZWQgbm9kZSB3aXRoIGlubmVySFRNTCBvbmx5IGxlYWRpbmdcbiAgLy8gd2hpdGVzcGFjZSBpcyByZW1vdmVkLiBXaGVuIHVwZGF0aW5nIGFuIGV4aXN0aW5nIG5vZGUgd2l0aCBpbm5lckhUTUxcbiAgLy8gd2hpdGVzcGFjZSBpbiByb290IFRleHROb2RlcyBpcyBhbHNvIGNvbGxhcHNlZC5cbiAgLy8gQHNlZSBxdWlya3Ntb2RlLm9yZy9idWdyZXBvcnRzL2FyY2hpdmVzLzIwMDQvMTEvaW5uZXJodG1sX2FuZF90Lmh0bWxcblxuICAvLyBGZWF0dXJlIGRldGVjdGlvbjsgb25seSBJRTggaXMga25vd24gdG8gYmVoYXZlIGltcHJvcGVybHkgbGlrZSB0aGlzLlxuICB2YXIgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgdGVzdEVsZW1lbnQuaW5uZXJIVE1MID0gJyAnO1xuICBpZiAodGVzdEVsZW1lbnQuaW5uZXJIVE1MID09PSAnJykge1xuICAgIHNldElubmVySFRNTCA9IGZ1bmN0aW9uIChub2RlLCBodG1sKSB7XG4gICAgICAvLyBNYWdpYyB0aGVvcnk6IElFOCBzdXBwb3NlZGx5IGRpZmZlcmVudGlhdGVzIGJldHdlZW4gYWRkZWQgYW5kIHVwZGF0ZWRcbiAgICAgIC8vIG5vZGVzIHdoZW4gcHJvY2Vzc2luZyBpbm5lckhUTUwsIGlubmVySFRNTCBvbiB1cGRhdGVkIG5vZGVzIHN1ZmZlcnNcbiAgICAgIC8vIGZyb20gd29yc2Ugd2hpdGVzcGFjZSBiZWhhdmlvci4gUmUtYWRkaW5nIGEgbm9kZSBsaWtlIHRoaXMgdHJpZ2dlcnNcbiAgICAgIC8vIHRoZSBpbml0aWFsIGFuZCBtb3JlIGZhdm9yYWJsZSB3aGl0ZXNwYWNlIGJlaGF2aW9yLlxuICAgICAgLy8gVE9ETzogV2hhdCB0byBkbyBvbiBhIGRldGFjaGVkIG5vZGU/XG4gICAgICBpZiAobm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICAgIG5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobm9kZSwgbm9kZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdlIGFsc28gaW1wbGVtZW50IGEgd29ya2Fyb3VuZCBmb3Igbm9uLXZpc2libGUgdGFncyBkaXNhcHBlYXJpbmcgaW50b1xuICAgICAgLy8gdGhpbiBhaXIgb24gSUU4LCB0aGlzIG9ubHkgaGFwcGVucyBpZiB0aGVyZSBpcyBubyB2aXNpYmxlIHRleHRcbiAgICAgIC8vIGluLWZyb250IG9mIHRoZSBub24tdmlzaWJsZSB0YWdzLiBQaWdneWJhY2sgb24gdGhlIHdoaXRlc3BhY2UgZml4XG4gICAgICAvLyBhbmQgc2ltcGx5IGNoZWNrIGlmIGFueSBub24tdmlzaWJsZSB0YWdzIGFwcGVhciBpbiB0aGUgc291cmNlLlxuICAgICAgaWYgKFdISVRFU1BBQ0VfVEVTVC50ZXN0KGh0bWwpIHx8IGh0bWxbMF0gPT09ICc8JyAmJiBOT05WSVNJQkxFX1RFU1QudGVzdChodG1sKSkge1xuICAgICAgICAvLyBSZWNvdmVyIGxlYWRpbmcgd2hpdGVzcGFjZSBieSB0ZW1wb3JhcmlseSBwcmVwZW5kaW5nIGFueSBjaGFyYWN0ZXIuXG4gICAgICAgIC8vIFxcdUZFRkYgaGFzIHRoZSBwb3RlbnRpYWwgYWR2YW50YWdlIG9mIGJlaW5nIHplcm8td2lkdGgvaW52aXNpYmxlLlxuICAgICAgICAvLyBVZ2xpZnlKUyBkcm9wcyBVK0ZFRkYgY2hhcnMgd2hlbiBwYXJzaW5nLCBzbyB1c2UgU3RyaW5nLmZyb21DaGFyQ29kZVxuICAgICAgICAvLyBpbiBob3BlcyB0aGF0IHRoaXMgaXMgcHJlc2VydmVkIGV2ZW4gaWYgXCJcXHVGRUZGXCIgaXMgdHJhbnNmb3JtZWQgdG9cbiAgICAgICAgLy8gdGhlIGFjdHVhbCBVbmljb2RlIGNoYXJhY3RlciAoYnkgQmFiZWwsIGZvciBleGFtcGxlKS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21pc2hvby9VZ2xpZnlKUzIvYmxvYi92Mi40LjIwL2xpYi9wYXJzZS5qcyNMMjE2XG4gICAgICAgIG5vZGUuaW5uZXJIVE1MID0gU3RyaW5nLmZyb21DaGFyQ29kZSgweEZFRkYpICsgaHRtbDtcblxuICAgICAgICAvLyBkZWxldGVEYXRhIGxlYXZlcyBhbiBlbXB0eSBgVGV4dE5vZGVgIHdoaWNoIG9mZnNldHMgdGhlIGluZGV4IG9mIGFsbFxuICAgICAgICAvLyBjaGlsZHJlbi4gRGVmaW5pdGVseSB3YW50IHRvIGF2b2lkIHRoaXMuXG4gICAgICAgIHZhciB0ZXh0Tm9kZSA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKHRleHROb2RlLmRhdGEubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgbm9kZS5yZW1vdmVDaGlsZCh0ZXh0Tm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dE5vZGUuZGVsZXRlRGF0YSgwLCAxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9kZS5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRJbm5lckhUTUw7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHNldFRleHRDb250ZW50XG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCdmYmpzL2xpYi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xudmFyIGVzY2FwZVRleHRDb250ZW50Rm9yQnJvd3NlciA9IHJlcXVpcmUoJy4vZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyJyk7XG52YXIgc2V0SW5uZXJIVE1MID0gcmVxdWlyZSgnLi9zZXRJbm5lckhUTUwnKTtcblxuLyoqXG4gKiBTZXQgdGhlIHRleHRDb250ZW50IHByb3BlcnR5IG9mIGEgbm9kZSwgZW5zdXJpbmcgdGhhdCB3aGl0ZXNwYWNlIGlzIHByZXNlcnZlZFxuICogZXZlbiBpbiBJRTguIGlubmVyVGV4dCBpcyBhIHBvb3Igc3Vic3RpdHV0ZSBmb3IgdGV4dENvbnRlbnQgYW5kLCBhbW9uZyBtYW55XG4gKiBpc3N1ZXMsIGluc2VydHMgPGJyPiBpbnN0ZWFkIG9mIHRoZSBsaXRlcmFsIG5ld2xpbmUgY2hhcnMuIGlubmVySFRNTCBiZWhhdmVzXG4gKiBhcyBpdCBzaG91bGQuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQGludGVybmFsXG4gKi9cbnZhciBzZXRUZXh0Q29udGVudCA9IGZ1bmN0aW9uIChub2RlLCB0ZXh0KSB7XG4gIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xufTtcblxuaWYgKEV4ZWN1dGlvbkVudmlyb25tZW50LmNhblVzZURPTSkge1xuICBpZiAoISgndGV4dENvbnRlbnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkpIHtcbiAgICBzZXRUZXh0Q29udGVudCA9IGZ1bmN0aW9uIChub2RlLCB0ZXh0KSB7XG4gICAgICBzZXRJbm5lckhUTUwobm9kZSwgZXNjYXBlVGV4dENvbnRlbnRGb3JCcm93c2VyKHRleHQpKTtcbiAgICB9O1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0VGV4dENvbnRlbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50XG4gKiBAdHlwZWNoZWNrcyBzdGF0aWMtb25seVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBHaXZlbiBhIGBwcmV2RWxlbWVudGAgYW5kIGBuZXh0RWxlbWVudGAsIGRldGVybWluZXMgaWYgdGhlIGV4aXN0aW5nXG4gKiBpbnN0YW5jZSBzaG91bGQgYmUgdXBkYXRlZCBhcyBvcHBvc2VkIHRvIGJlaW5nIGRlc3Ryb3llZCBvciByZXBsYWNlZCBieSBhIG5ld1xuICogaW5zdGFuY2UuIEJvdGggYXJndW1lbnRzIGFyZSBlbGVtZW50cy4gVGhpcyBlbnN1cmVzIHRoYXQgdGhpcyBsb2dpYyBjYW5cbiAqIG9wZXJhdGUgb24gc3RhdGVsZXNzIHRyZWVzIHdpdGhvdXQgYW55IGJhY2tpbmcgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHs/b2JqZWN0fSBwcmV2RWxlbWVudFxuICogQHBhcmFtIHs/b2JqZWN0fSBuZXh0RWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXhpc3RpbmcgaW5zdGFuY2Ugc2hvdWxkIGJlIHVwZGF0ZWQuXG4gKiBAcHJvdGVjdGVkXG4gKi9cbmZ1bmN0aW9uIHNob3VsZFVwZGF0ZVJlYWN0Q29tcG9uZW50KHByZXZFbGVtZW50LCBuZXh0RWxlbWVudCkge1xuICB2YXIgcHJldkVtcHR5ID0gcHJldkVsZW1lbnQgPT09IG51bGwgfHwgcHJldkVsZW1lbnQgPT09IGZhbHNlO1xuICB2YXIgbmV4dEVtcHR5ID0gbmV4dEVsZW1lbnQgPT09IG51bGwgfHwgbmV4dEVsZW1lbnQgPT09IGZhbHNlO1xuICBpZiAocHJldkVtcHR5IHx8IG5leHRFbXB0eSkge1xuICAgIHJldHVybiBwcmV2RW1wdHkgPT09IG5leHRFbXB0eTtcbiAgfVxuXG4gIHZhciBwcmV2VHlwZSA9IHR5cGVvZiBwcmV2RWxlbWVudDtcbiAgdmFyIG5leHRUeXBlID0gdHlwZW9mIG5leHRFbGVtZW50O1xuICBpZiAocHJldlR5cGUgPT09ICdzdHJpbmcnIHx8IHByZXZUeXBlID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBuZXh0VHlwZSA9PT0gJ3N0cmluZycgfHwgbmV4dFR5cGUgPT09ICdudW1iZXInO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgcHJldkVsZW1lbnQudHlwZSA9PT0gbmV4dEVsZW1lbnQudHlwZSAmJiBwcmV2RWxlbWVudC5rZXkgPT09IG5leHRFbGVtZW50LmtleTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hvdWxkVXBkYXRlUmVhY3RDb21wb25lbnQ7IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxMy0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0Qtc3R5bGUgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogb2YgcGF0ZW50IHJpZ2h0cyBjYW4gYmUgZm91bmQgaW4gdGhlIFBBVEVOVFMgZmlsZSBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKlxuICogQHByb3ZpZGVzTW9kdWxlIHRyYXZlcnNlQWxsQ2hpbGRyZW5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IHJlcXVpcmUoJy4vUmVhY3RDdXJyZW50T3duZXInKTtcbnZhciBSZWFjdEVsZW1lbnQgPSByZXF1aXJlKCcuL1JlYWN0RWxlbWVudCcpO1xudmFyIFJlYWN0SW5zdGFuY2VIYW5kbGVzID0gcmVxdWlyZSgnLi9SZWFjdEluc3RhbmNlSGFuZGxlcycpO1xuXG52YXIgZ2V0SXRlcmF0b3JGbiA9IHJlcXVpcmUoJy4vZ2V0SXRlcmF0b3JGbicpO1xudmFyIGludmFyaWFudCA9IHJlcXVpcmUoJ2ZianMvbGliL2ludmFyaWFudCcpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciBTRVBBUkFUT1IgPSBSZWFjdEluc3RhbmNlSGFuZGxlcy5TRVBBUkFUT1I7XG52YXIgU1VCU0VQQVJBVE9SID0gJzonO1xuXG4vKipcbiAqIFRPRE86IFRlc3QgdGhhdCBhIHNpbmdsZSBjaGlsZCBhbmQgYW4gYXJyYXkgd2l0aCBvbmUgaXRlbSBoYXZlIHRoZSBzYW1lIGtleVxuICogcGF0dGVybi5cbiAqL1xuXG52YXIgdXNlclByb3ZpZGVkS2V5RXNjYXBlckxvb2t1cCA9IHtcbiAgJz0nOiAnPTAnLFxuICAnLic6ICc9MScsXG4gICc6JzogJz0yJ1xufTtcblxudmFyIHVzZXJQcm92aWRlZEtleUVzY2FwZVJlZ2V4ID0gL1s9LjpdL2c7XG5cbnZhciBkaWRXYXJuQWJvdXRNYXBzID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHVzZXJQcm92aWRlZEtleUVzY2FwZXIobWF0Y2gpIHtcbiAgcmV0dXJuIHVzZXJQcm92aWRlZEtleUVzY2FwZXJMb29rdXBbbWF0Y2hdO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEga2V5IHN0cmluZyB0aGF0IGlkZW50aWZpZXMgYSBjb21wb25lbnQgd2l0aGluIGEgc2V0LlxuICpcbiAqIEBwYXJhbSB7Kn0gY29tcG9uZW50IEEgY29tcG9uZW50IHRoYXQgY291bGQgY29udGFpbiBhIG1hbnVhbCBrZXkuXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXggdGhhdCBpcyB1c2VkIGlmIGEgbWFudWFsIGtleSBpcyBub3QgcHJvdmlkZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGdldENvbXBvbmVudEtleShjb21wb25lbnQsIGluZGV4KSB7XG4gIGlmIChjb21wb25lbnQgJiYgY29tcG9uZW50LmtleSAhPSBudWxsKSB7XG4gICAgLy8gRXhwbGljaXQga2V5XG4gICAgcmV0dXJuIHdyYXBVc2VyUHJvdmlkZWRLZXkoY29tcG9uZW50LmtleSk7XG4gIH1cbiAgLy8gSW1wbGljaXQga2V5IGRldGVybWluZWQgYnkgdGhlIGluZGV4IGluIHRoZSBzZXRcbiAgcmV0dXJuIGluZGV4LnRvU3RyaW5nKDM2KTtcbn1cblxuLyoqXG4gKiBFc2NhcGUgYSBjb21wb25lbnQga2V5IHNvIHRoYXQgaXQgaXMgc2FmZSB0byB1c2UgaW4gYSByZWFjdGlkLlxuICpcbiAqIEBwYXJhbSB7Kn0gdGV4dCBDb21wb25lbnQga2V5IHRvIGJlIGVzY2FwZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEFuIGVzY2FwZWQgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBlc2NhcGVVc2VyUHJvdmlkZWRLZXkodGV4dCkge1xuICByZXR1cm4gKCcnICsgdGV4dCkucmVwbGFjZSh1c2VyUHJvdmlkZWRLZXlFc2NhcGVSZWdleCwgdXNlclByb3ZpZGVkS2V5RXNjYXBlcik7XG59XG5cbi8qKlxuICogV3JhcCBhIGBrZXlgIHZhbHVlIGV4cGxpY2l0bHkgcHJvdmlkZWQgYnkgdGhlIHVzZXIgdG8gZGlzdGluZ3Vpc2ggaXQgZnJvbVxuICogaW1wbGljaXRseS1nZW5lcmF0ZWQga2V5cyBnZW5lcmF0ZWQgYnkgYSBjb21wb25lbnQncyBpbmRleCBpbiBpdHMgcGFyZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVmFsdWUgb2YgYSB1c2VyLXByb3ZpZGVkIGBrZXlgIGF0dHJpYnV0ZVxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiB3cmFwVXNlclByb3ZpZGVkS2V5KGtleSkge1xuICByZXR1cm4gJyQnICsgZXNjYXBlVXNlclByb3ZpZGVkS2V5KGtleSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHs/Kn0gY2hpbGRyZW4gQ2hpbGRyZW4gdHJlZSBjb250YWluZXIuXG4gKiBAcGFyYW0geyFzdHJpbmd9IG5hbWVTb0ZhciBOYW1lIG9mIHRoZSBrZXkgcGF0aCBzbyBmYXIuXG4gKiBAcGFyYW0geyFmdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZWFjaCBjaGlsZCBmb3VuZC5cbiAqIEBwYXJhbSB7Pyp9IHRyYXZlcnNlQ29udGV4dCBVc2VkIHRvIHBhc3MgaW5mb3JtYXRpb24gdGhyb3VnaG91dCB0aGUgdHJhdmVyc2FsXG4gKiBwcm9jZXNzLlxuICogQHJldHVybiB7IW51bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbiBpbiB0aGlzIHN1YnRyZWUuXG4gKi9cbmZ1bmN0aW9uIHRyYXZlcnNlQWxsQ2hpbGRyZW5JbXBsKGNoaWxkcmVuLCBuYW1lU29GYXIsIGNhbGxiYWNrLCB0cmF2ZXJzZUNvbnRleHQpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgY2hpbGRyZW47XG5cbiAgaWYgKHR5cGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIC8vIEFsbCBvZiB0aGUgYWJvdmUgYXJlIHBlcmNlaXZlZCBhcyBudWxsLlxuICAgIGNoaWxkcmVuID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaGlsZHJlbiA9PT0gbnVsbCB8fCB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlID09PSAnbnVtYmVyJyB8fCBSZWFjdEVsZW1lbnQuaXNWYWxpZEVsZW1lbnQoY2hpbGRyZW4pKSB7XG4gICAgY2FsbGJhY2sodHJhdmVyc2VDb250ZXh0LCBjaGlsZHJlbixcbiAgICAvLyBJZiBpdCdzIHRoZSBvbmx5IGNoaWxkLCB0cmVhdCB0aGUgbmFtZSBhcyBpZiBpdCB3YXMgd3JhcHBlZCBpbiBhbiBhcnJheVxuICAgIC8vIHNvIHRoYXQgaXQncyBjb25zaXN0ZW50IGlmIHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gZ3Jvd3MuXG4gICAgbmFtZVNvRmFyID09PSAnJyA/IFNFUEFSQVRPUiArIGdldENvbXBvbmVudEtleShjaGlsZHJlbiwgMCkgOiBuYW1lU29GYXIpO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgdmFyIGNoaWxkO1xuICB2YXIgbmV4dE5hbWU7XG4gIHZhciBzdWJ0cmVlQ291bnQgPSAwOyAvLyBDb3VudCBvZiBjaGlsZHJlbiBmb3VuZCBpbiB0aGUgY3VycmVudCBzdWJ0cmVlLlxuICB2YXIgbmV4dE5hbWVQcmVmaXggPSBuYW1lU29GYXIgPT09ICcnID8gU0VQQVJBVE9SIDogbmFtZVNvRmFyICsgU1VCU0VQQVJBVE9SO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICBuZXh0TmFtZSA9IG5leHROYW1lUHJlZml4ICsgZ2V0Q29tcG9uZW50S2V5KGNoaWxkLCBpKTtcbiAgICAgIHN1YnRyZWVDb3VudCArPSB0cmF2ZXJzZUFsbENoaWxkcmVuSW1wbChjaGlsZCwgbmV4dE5hbWUsIGNhbGxiYWNrLCB0cmF2ZXJzZUNvbnRleHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuICAgIGlmIChpdGVyYXRvckZuKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwoY2hpbGRyZW4pO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICBpZiAoaXRlcmF0b3JGbiAhPT0gY2hpbGRyZW4uZW50cmllcykge1xuICAgICAgICB2YXIgaWkgPSAwO1xuICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgY2hpbGQgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIG5leHROYW1lID0gbmV4dE5hbWVQcmVmaXggKyBnZXRDb21wb25lbnRLZXkoY2hpbGQsIGlpKyspO1xuICAgICAgICAgIHN1YnRyZWVDb3VudCArPSB0cmF2ZXJzZUFsbENoaWxkcmVuSW1wbChjaGlsZCwgbmV4dE5hbWUsIGNhbGxiYWNrLCB0cmF2ZXJzZUNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGRpZFdhcm5BYm91dE1hcHMsICdVc2luZyBNYXBzIGFzIGNoaWxkcmVuIGlzIG5vdCB5ZXQgZnVsbHkgc3VwcG9ydGVkLiBJdCBpcyBhbiAnICsgJ2V4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWlnaHQgYmUgcmVtb3ZlZC4gQ29udmVydCBpdCB0byBhICcgKyAnc2VxdWVuY2UgLyBpdGVyYWJsZSBvZiBrZXllZCBSZWFjdEVsZW1lbnRzIGluc3RlYWQuJykgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgZGlkV2FybkFib3V0TWFwcyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSXRlcmF0b3Igd2lsbCBwcm92aWRlIGVudHJ5IFtrLHZdIHR1cGxlcyByYXRoZXIgdGhhbiB2YWx1ZXMuXG4gICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICB2YXIgZW50cnkgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgICAgY2hpbGQgPSBlbnRyeVsxXTtcbiAgICAgICAgICAgIG5leHROYW1lID0gbmV4dE5hbWVQcmVmaXggKyB3cmFwVXNlclByb3ZpZGVkS2V5KGVudHJ5WzBdKSArIFNVQlNFUEFSQVRPUiArIGdldENvbXBvbmVudEtleShjaGlsZCwgMCk7XG4gICAgICAgICAgICBzdWJ0cmVlQ291bnQgKz0gdHJhdmVyc2VBbGxDaGlsZHJlbkltcGwoY2hpbGQsIG5leHROYW1lLCBjYWxsYmFjaywgdHJhdmVyc2VDb250ZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICB2YXIgYWRkZW5kdW0gPSAnJztcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGFkZGVuZHVtID0gJyBJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiwgdXNlIGFuIGFycmF5ICcgKyAnaW5zdGVhZCBvciB3cmFwIHRoZSBvYmplY3QgdXNpbmcgY3JlYXRlRnJhZ21lbnQob2JqZWN0KSBmcm9tIHRoZSAnICsgJ1JlYWN0IGFkZC1vbnMuJztcbiAgICAgICAgaWYgKGNoaWxkcmVuLl9pc1JlYWN0RWxlbWVudCkge1xuICAgICAgICAgIGFkZGVuZHVtID0gJyBJdCBsb29rcyBsaWtlIHlvdVxcJ3JlIHVzaW5nIGFuIGVsZW1lbnQgY3JlYXRlZCBieSBhIGRpZmZlcmVudCAnICsgJ3ZlcnNpb24gb2YgUmVhY3QuIE1ha2Ugc3VyZSB0byB1c2Ugb25seSBvbmUgY29weSBvZiBSZWFjdC4nO1xuICAgICAgICB9XG4gICAgICAgIGlmIChSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50KSB7XG4gICAgICAgICAgdmFyIG5hbWUgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LmdldE5hbWUoKTtcbiAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgYWRkZW5kdW0gKz0gJyBDaGVjayB0aGUgcmVuZGVyIG1ldGhvZCBvZiBgJyArIG5hbWUgKyAnYC4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIGNoaWxkcmVuU3RyaW5nID0gU3RyaW5nKGNoaWxkcmVuKTtcbiAgICAgICFmYWxzZSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBpbnZhcmlhbnQoZmFsc2UsICdPYmplY3RzIGFyZSBub3QgdmFsaWQgYXMgYSBSZWFjdCBjaGlsZCAoZm91bmQ6ICVzKS4lcycsIGNoaWxkcmVuU3RyaW5nID09PSAnW29iamVjdCBPYmplY3RdJyA/ICdvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMoY2hpbGRyZW4pLmpvaW4oJywgJykgKyAnfScgOiBjaGlsZHJlblN0cmluZywgYWRkZW5kdW0pIDogaW52YXJpYW50KGZhbHNlKSA6IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3VidHJlZUNvdW50O1xufVxuXG4vKipcbiAqIFRyYXZlcnNlcyBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAsIGJ1dFxuICogbWlnaHQgYWxzbyBiZSBzcGVjaWZpZWQgdGhyb3VnaCBhdHRyaWJ1dGVzOlxuICpcbiAqIC0gYHRyYXZlcnNlQWxsQ2hpbGRyZW4odGhpcy5wcm9wcy5jaGlsZHJlbiwgLi4uKWBcbiAqIC0gYHRyYXZlcnNlQWxsQ2hpbGRyZW4odGhpcy5wcm9wcy5sZWZ0UGFuZWxDaGlsZHJlbiwgLi4uKWBcbiAqXG4gKiBUaGUgYHRyYXZlcnNlQ29udGV4dGAgaXMgYW4gb3B0aW9uYWwgYXJndW1lbnQgdGhhdCBpcyBwYXNzZWQgdGhyb3VnaCB0aGVcbiAqIGVudGlyZSB0cmF2ZXJzYWwuIEl0IGNhbiBiZSB1c2VkIHRvIHN0b3JlIGFjY3VtdWxhdGlvbnMgb3IgYW55dGhpbmcgZWxzZSB0aGF0XG4gKiB0aGUgY2FsbGJhY2sgbWlnaHQgZmluZCByZWxldmFudC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIG9iamVjdC5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9ufSBjYWxsYmFjayBUbyBpbnZva2UgdXBvbiB0cmF2ZXJzaW5nIGVhY2ggY2hpbGQuXG4gKiBAcGFyYW0gez8qfSB0cmF2ZXJzZUNvbnRleHQgQ29udGV4dCBmb3IgdHJhdmVyc2FsLlxuICogQHJldHVybiB7IW51bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbiBpbiB0aGlzIHN1YnRyZWUuXG4gKi9cbmZ1bmN0aW9uIHRyYXZlcnNlQWxsQ2hpbGRyZW4oY2hpbGRyZW4sIGNhbGxiYWNrLCB0cmF2ZXJzZUNvbnRleHQpIHtcbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHJldHVybiB0cmF2ZXJzZUFsbENoaWxkcmVuSW1wbChjaGlsZHJlbiwgJycsIGNhbGxiYWNrLCB0cmF2ZXJzZUNvbnRleHQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRyYXZlcnNlQWxsQ2hpbGRyZW47IiwiLyoqXG4gKiBDb3B5cmlnaHQgMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICpcbiAqIEBwcm92aWRlc01vZHVsZSB2YWxpZGF0ZURPTU5lc3RpbmdcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCcuL09iamVjdC5hc3NpZ24nKTtcbnZhciBlbXB0eUZ1bmN0aW9uID0gcmVxdWlyZSgnZmJqcy9saWIvZW1wdHlGdW5jdGlvbicpO1xudmFyIHdhcm5pbmcgPSByZXF1aXJlKCdmYmpzL2xpYi93YXJuaW5nJyk7XG5cbnZhciB2YWxpZGF0ZURPTU5lc3RpbmcgPSBlbXB0eUZ1bmN0aW9uO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAvLyBUaGlzIHZhbGlkYXRpb24gY29kZSB3YXMgd3JpdHRlbiBiYXNlZCBvbiB0aGUgSFRNTDUgcGFyc2luZyBzcGVjOlxuICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1zY29wZVxuICAvL1xuICAvLyBOb3RlOiB0aGlzIGRvZXMgbm90IGNhdGNoIGFsbCBpbnZhbGlkIG5lc3RpbmcsIG5vciBkb2VzIGl0IHRyeSB0byAoYXMgaXQnc1xuICAvLyBub3QgY2xlYXIgd2hhdCBwcmFjdGljYWwgYmVuZWZpdCBkb2luZyBzbyBwcm92aWRlcyk7IGluc3RlYWQsIHdlIHdhcm4gb25seVxuICAvLyBmb3IgY2FzZXMgd2hlcmUgdGhlIHBhcnNlciB3aWxsIGdpdmUgYSBwYXJzZSB0cmVlIGRpZmZlcmluZyBmcm9tIHdoYXQgUmVhY3RcbiAgLy8gaW50ZW5kZWQuIEZvciBleGFtcGxlLCA8Yj48ZGl2PjwvZGl2PjwvYj4gaXMgaW52YWxpZCBidXQgd2UgZG9uJ3Qgd2FyblxuICAvLyBiZWNhdXNlIGl0IHN0aWxsIHBhcnNlcyBjb3JyZWN0bHk7IHdlIGRvIHdhcm4gZm9yIG90aGVyIGNhc2VzIGxpa2UgbmVzdGVkXG4gIC8vIDxwPiB0YWdzIHdoZXJlIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlY29uZCBlbGVtZW50IGltcGxpY2l0bHkgY2xvc2VzIHRoZVxuICAvLyBmaXJzdCwgY2F1c2luZyBhIGNvbmZ1c2luZyBtZXNzLlxuXG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3NwZWNpYWxcbiAgdmFyIHNwZWNpYWxUYWdzID0gWydhZGRyZXNzJywgJ2FwcGxldCcsICdhcmVhJywgJ2FydGljbGUnLCAnYXNpZGUnLCAnYmFzZScsICdiYXNlZm9udCcsICdiZ3NvdW5kJywgJ2Jsb2NrcXVvdGUnLCAnYm9keScsICdicicsICdidXR0b24nLCAnY2FwdGlvbicsICdjZW50ZXInLCAnY29sJywgJ2NvbGdyb3VwJywgJ2RkJywgJ2RldGFpbHMnLCAnZGlyJywgJ2RpdicsICdkbCcsICdkdCcsICdlbWJlZCcsICdmaWVsZHNldCcsICdmaWdjYXB0aW9uJywgJ2ZpZ3VyZScsICdmb290ZXInLCAnZm9ybScsICdmcmFtZScsICdmcmFtZXNldCcsICdoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNicsICdoZWFkJywgJ2hlYWRlcicsICdoZ3JvdXAnLCAnaHInLCAnaHRtbCcsICdpZnJhbWUnLCAnaW1nJywgJ2lucHV0JywgJ2lzaW5kZXgnLCAnbGknLCAnbGluaycsICdsaXN0aW5nJywgJ21haW4nLCAnbWFycXVlZScsICdtZW51JywgJ21lbnVpdGVtJywgJ21ldGEnLCAnbmF2JywgJ25vZW1iZWQnLCAnbm9mcmFtZXMnLCAnbm9zY3JpcHQnLCAnb2JqZWN0JywgJ29sJywgJ3AnLCAncGFyYW0nLCAncGxhaW50ZXh0JywgJ3ByZScsICdzY3JpcHQnLCAnc2VjdGlvbicsICdzZWxlY3QnLCAnc291cmNlJywgJ3N0eWxlJywgJ3N1bW1hcnknLCAndGFibGUnLCAndGJvZHknLCAndGQnLCAndGVtcGxhdGUnLCAndGV4dGFyZWEnLCAndGZvb3QnLCAndGgnLCAndGhlYWQnLCAndGl0bGUnLCAndHInLCAndHJhY2snLCAndWwnLCAnd2JyJywgJ3htcCddO1xuXG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2hhcy1hbi1lbGVtZW50LWluLXNjb3BlXG4gIHZhciBpblNjb3BlVGFncyA9IFsnYXBwbGV0JywgJ2NhcHRpb24nLCAnaHRtbCcsICd0YWJsZScsICd0ZCcsICd0aCcsICdtYXJxdWVlJywgJ29iamVjdCcsICd0ZW1wbGF0ZScsXG5cbiAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaHRtbC1pbnRlZ3JhdGlvbi1wb2ludFxuICAvLyBUT0RPOiBEaXN0aW5ndWlzaCBieSBuYW1lc3BhY2UgaGVyZSAtLSBmb3IgPHRpdGxlPiwgaW5jbHVkaW5nIGl0IGhlcmVcbiAgLy8gZXJycyBvbiB0aGUgc2lkZSBvZiBmZXdlciB3YXJuaW5nc1xuICAnZm9yZWlnbk9iamVjdCcsICdkZXNjJywgJ3RpdGxlJ107XG5cbiAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaGFzLWFuLWVsZW1lbnQtaW4tYnV0dG9uLXNjb3BlXG4gIHZhciBidXR0b25TY29wZVRhZ3MgPSBpblNjb3BlVGFncy5jb25jYXQoWydidXR0b24nXSk7XG5cbiAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjZ2VuZXJhdGUtaW1wbGllZC1lbmQtdGFnc1xuICB2YXIgaW1wbGllZEVuZFRhZ3MgPSBbJ2RkJywgJ2R0JywgJ2xpJywgJ29wdGlvbicsICdvcHRncm91cCcsICdwJywgJ3JwJywgJ3J0J107XG5cbiAgdmFyIGVtcHR5QW5jZXN0b3JJbmZvID0ge1xuICAgIHBhcmVudFRhZzogbnVsbCxcblxuICAgIGZvcm1UYWc6IG51bGwsXG4gICAgYVRhZ0luU2NvcGU6IG51bGwsXG4gICAgYnV0dG9uVGFnSW5TY29wZTogbnVsbCxcbiAgICBub2JyVGFnSW5TY29wZTogbnVsbCxcbiAgICBwVGFnSW5CdXR0b25TY29wZTogbnVsbCxcblxuICAgIGxpc3RJdGVtVGFnQXV0b2Nsb3Npbmc6IG51bGwsXG4gICAgZGxJdGVtVGFnQXV0b2Nsb3Npbmc6IG51bGxcbiAgfTtcblxuICB2YXIgdXBkYXRlZEFuY2VzdG9ySW5mbyA9IGZ1bmN0aW9uIChvbGRJbmZvLCB0YWcsIGluc3RhbmNlKSB7XG4gICAgdmFyIGFuY2VzdG9ySW5mbyA9IGFzc2lnbih7fSwgb2xkSW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbyk7XG4gICAgdmFyIGluZm8gPSB7IHRhZzogdGFnLCBpbnN0YW5jZTogaW5zdGFuY2UgfTtcblxuICAgIGlmIChpblNjb3BlVGFncy5pbmRleE9mKHRhZykgIT09IC0xKSB7XG4gICAgICBhbmNlc3RvckluZm8uYVRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLm5vYnJUYWdJblNjb3BlID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKGJ1dHRvblNjb3BlVGFncy5pbmRleE9mKHRhZykgIT09IC0xKSB7XG4gICAgICBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGUgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIFNlZSBydWxlcyBmb3IgJ2xpJywgJ2RkJywgJ2R0JyBzdGFydCB0YWdzIGluXG4gICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluYm9keVxuICAgIGlmIChzcGVjaWFsVGFncy5pbmRleE9mKHRhZykgIT09IC0xICYmIHRhZyAhPT0gJ2FkZHJlc3MnICYmIHRhZyAhPT0gJ2RpdicgJiYgdGFnICE9PSAncCcpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5saXN0SXRlbVRhZ0F1dG9jbG9zaW5nID0gbnVsbDtcbiAgICAgIGFuY2VzdG9ySW5mby5kbEl0ZW1UYWdBdXRvY2xvc2luZyA9IG51bGw7XG4gICAgfVxuXG4gICAgYW5jZXN0b3JJbmZvLnBhcmVudFRhZyA9IGluZm87XG5cbiAgICBpZiAodGFnID09PSAnZm9ybScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5mb3JtVGFnID0gaW5mbztcbiAgICB9XG4gICAgaWYgKHRhZyA9PT0gJ2EnKSB7XG4gICAgICBhbmNlc3RvckluZm8uYVRhZ0luU2NvcGUgPSBpbmZvO1xuICAgIH1cbiAgICBpZiAodGFnID09PSAnYnV0dG9uJykge1xuICAgICAgYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGUgPSBpbmZvO1xuICAgIH1cbiAgICBpZiAodGFnID09PSAnbm9icicpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuICAgIGlmICh0YWcgPT09ICdwJykge1xuICAgICAgYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlID0gaW5mbztcbiAgICB9XG4gICAgaWYgKHRhZyA9PT0gJ2xpJykge1xuICAgICAgYW5jZXN0b3JJbmZvLmxpc3RJdGVtVGFnQXV0b2Nsb3NpbmcgPSBpbmZvO1xuICAgIH1cbiAgICBpZiAodGFnID09PSAnZGQnIHx8IHRhZyA9PT0gJ2R0Jykge1xuICAgICAgYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nID0gaW5mbztcbiAgICB9XG5cbiAgICByZXR1cm4gYW5jZXN0b3JJbmZvO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXJcbiAgICovXG4gIHZhciBpc1RhZ1ZhbGlkV2l0aFBhcmVudCA9IGZ1bmN0aW9uICh0YWcsIHBhcmVudFRhZykge1xuICAgIC8vIEZpcnN0LCBsZXQncyBjaGVjayBpZiB3ZSdyZSBpbiBhbiB1bnVzdWFsIHBhcnNpbmcgbW9kZS4uLlxuICAgIHN3aXRjaCAocGFyZW50VGFnKSB7XG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5zZWxlY3RcbiAgICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdvcHRpb24nIHx8IHRhZyA9PT0gJ29wdGdyb3VwJyB8fCB0YWcgPT09ICcjdGV4dCc7XG4gICAgICBjYXNlICdvcHRncm91cCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdvcHRpb24nIHx8IHRhZyA9PT0gJyN0ZXh0JztcbiAgICAgIC8vIFN0cmljdGx5IHNwZWFraW5nLCBzZWVpbmcgYW4gPG9wdGlvbj4gZG9lc24ndCBtZWFuIHdlJ3JlIGluIGEgPHNlbGVjdD5cbiAgICAgIC8vIGJ1dFxuICAgICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJyN0ZXh0JztcblxuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWludGRcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmNhcHRpb25cbiAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3Igc2luY2UgdGhlc2UgcnVsZXMgZmFsbCBiYWNrIHRvIFwiaW4gYm9keVwiIG1vZGUgZm9yXG4gICAgICAvLyBhbGwgZXhjZXB0IHNwZWNpYWwgdGFibGUgbm9kZXMgd2hpY2ggY2F1c2UgYmFkIHBhcnNpbmcgYmVoYXZpb3IgYW55d2F5LlxuXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW50clxuICAgICAgY2FzZSAndHInOlxuICAgICAgICByZXR1cm4gdGFnID09PSAndGgnIHx8IHRhZyA9PT0gJ3RkJyB8fCB0YWcgPT09ICdzdHlsZScgfHwgdGFnID09PSAnc2NyaXB0JyB8fCB0YWcgPT09ICd0ZW1wbGF0ZSc7XG5cbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRib2R5XG4gICAgICBjYXNlICd0Ym9keSc6XG4gICAgICBjYXNlICd0aGVhZCc6XG4gICAgICBjYXNlICd0Zm9vdCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICd0cicgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5jb2xncm91cFxuICAgICAgY2FzZSAnY29sZ3JvdXAnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnY29sJyB8fCB0YWcgPT09ICd0ZW1wbGF0ZSc7XG5cbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRhYmxlXG4gICAgICBjYXNlICd0YWJsZSc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdjYXB0aW9uJyB8fCB0YWcgPT09ICdjb2xncm91cCcgfHwgdGFnID09PSAndGJvZHknIHx8IHRhZyA9PT0gJ3Rmb290JyB8fCB0YWcgPT09ICd0aGVhZCcgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5oZWFkXG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2Jhc2UnIHx8IHRhZyA9PT0gJ2Jhc2Vmb250JyB8fCB0YWcgPT09ICdiZ3NvdW5kJyB8fCB0YWcgPT09ICdsaW5rJyB8fCB0YWcgPT09ICdtZXRhJyB8fCB0YWcgPT09ICd0aXRsZScgfHwgdGFnID09PSAnbm9zY3JpcHQnIHx8IHRhZyA9PT0gJ25vZnJhbWVzJyB8fCB0YWcgPT09ICdzdHlsZScgfHwgdGFnID09PSAnc2NyaXB0JyB8fCB0YWcgPT09ICd0ZW1wbGF0ZSc7XG5cbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NlbWFudGljcy5odG1sI3RoZS1odG1sLWVsZW1lbnRcbiAgICAgIGNhc2UgJ2h0bWwnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnaGVhZCcgfHwgdGFnID09PSAnYm9keSc7XG4gICAgfVxuXG4gICAgLy8gUHJvYmFibHkgaW4gdGhlIFwiaW4gYm9keVwiIHBhcnNpbmcgbW9kZSwgc28gd2Ugb3V0bGF3IG9ubHkgdGFnIGNvbWJvc1xuICAgIC8vIHdoZXJlIHRoZSBwYXJzaW5nIHJ1bGVzIGNhdXNlIGltcGxpY2l0IG9wZW5zIG9yIGNsb3NlcyB0byBiZSBhZGRlZC5cbiAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5ib2R5XG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgJ2gxJzpcbiAgICAgIGNhc2UgJ2gyJzpcbiAgICAgIGNhc2UgJ2gzJzpcbiAgICAgIGNhc2UgJ2g0JzpcbiAgICAgIGNhc2UgJ2g1JzpcbiAgICAgIGNhc2UgJ2g2JzpcbiAgICAgICAgcmV0dXJuIHBhcmVudFRhZyAhPT0gJ2gxJyAmJiBwYXJlbnRUYWcgIT09ICdoMicgJiYgcGFyZW50VGFnICE9PSAnaDMnICYmIHBhcmVudFRhZyAhPT0gJ2g0JyAmJiBwYXJlbnRUYWcgIT09ICdoNScgJiYgcGFyZW50VGFnICE9PSAnaDYnO1xuXG4gICAgICBjYXNlICdycCc6XG4gICAgICBjYXNlICdydCc6XG4gICAgICAgIHJldHVybiBpbXBsaWVkRW5kVGFncy5pbmRleE9mKHBhcmVudFRhZykgPT09IC0xO1xuXG4gICAgICBjYXNlICdjYXB0aW9uJzpcbiAgICAgIGNhc2UgJ2NvbCc6XG4gICAgICBjYXNlICdjb2xncm91cCc6XG4gICAgICBjYXNlICdmcmFtZSc6XG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgIGNhc2UgJ3Rib2R5JzpcbiAgICAgIGNhc2UgJ3RkJzpcbiAgICAgIGNhc2UgJ3Rmb290JzpcbiAgICAgIGNhc2UgJ3RoJzpcbiAgICAgIGNhc2UgJ3RoZWFkJzpcbiAgICAgIGNhc2UgJ3RyJzpcbiAgICAgICAgLy8gVGhlc2UgdGFncyBhcmUgb25seSB2YWxpZCB3aXRoIGEgZmV3IHBhcmVudHMgdGhhdCBoYXZlIHNwZWNpYWwgY2hpbGRcbiAgICAgICAgLy8gcGFyc2luZyBydWxlcyAtLSBpZiB3ZSdyZSBkb3duIGhlcmUsIHRoZW4gbm9uZSBvZiB0aG9zZSBtYXRjaGVkIGFuZFxuICAgICAgICAvLyBzbyB3ZSBhbGxvdyBpdCBvbmx5IGlmIHdlIGRvbid0IGtub3cgd2hhdCB0aGUgcGFyZW50IGlzLCBhcyBhbGwgb3RoZXJcbiAgICAgICAgLy8gY2FzZXMgYXJlIGludmFsaWQuXG4gICAgICAgIHJldHVybiBwYXJlbnRUYWcgPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyXG4gICAqL1xuICB2YXIgZmluZEludmFsaWRBbmNlc3RvckZvclRhZyA9IGZ1bmN0aW9uICh0YWcsIGFuY2VzdG9ySW5mbykge1xuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlICdhZGRyZXNzJzpcbiAgICAgIGNhc2UgJ2FydGljbGUnOlxuICAgICAgY2FzZSAnYXNpZGUnOlxuICAgICAgY2FzZSAnYmxvY2txdW90ZSc6XG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgY2FzZSAnZGV0YWlscyc6XG4gICAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgY2FzZSAnZGlyJzpcbiAgICAgIGNhc2UgJ2Rpdic6XG4gICAgICBjYXNlICdkbCc6XG4gICAgICBjYXNlICdmaWVsZHNldCc6XG4gICAgICBjYXNlICdmaWdjYXB0aW9uJzpcbiAgICAgIGNhc2UgJ2ZpZ3VyZSc6XG4gICAgICBjYXNlICdmb290ZXInOlxuICAgICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgIGNhc2UgJ2hncm91cCc6XG4gICAgICBjYXNlICdtYWluJzpcbiAgICAgIGNhc2UgJ21lbnUnOlxuICAgICAgY2FzZSAnbmF2JzpcbiAgICAgIGNhc2UgJ29sJzpcbiAgICAgIGNhc2UgJ3AnOlxuICAgICAgY2FzZSAnc2VjdGlvbic6XG4gICAgICBjYXNlICdzdW1tYXJ5JzpcbiAgICAgIGNhc2UgJ3VsJzpcblxuICAgICAgY2FzZSAncHJlJzpcbiAgICAgIGNhc2UgJ2xpc3RpbmcnOlxuXG4gICAgICBjYXNlICd0YWJsZSc6XG5cbiAgICAgIGNhc2UgJ2hyJzpcblxuICAgICAgY2FzZSAneG1wJzpcblxuICAgICAgY2FzZSAnaDEnOlxuICAgICAgY2FzZSAnaDInOlxuICAgICAgY2FzZSAnaDMnOlxuICAgICAgY2FzZSAnaDQnOlxuICAgICAgY2FzZSAnaDUnOlxuICAgICAgY2FzZSAnaDYnOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlO1xuXG4gICAgICBjYXNlICdmb3JtJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5mb3JtVGFnIHx8IGFuY2VzdG9ySW5mby5wVGFnSW5CdXR0b25TY29wZTtcblxuICAgICAgY2FzZSAnbGknOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmxpc3RJdGVtVGFnQXV0b2Nsb3Npbmc7XG5cbiAgICAgIGNhc2UgJ2RkJzpcbiAgICAgIGNhc2UgJ2R0JzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5kbEl0ZW1UYWdBdXRvY2xvc2luZztcblxuICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5idXR0b25UYWdJblNjb3BlO1xuXG4gICAgICBjYXNlICdhJzpcbiAgICAgICAgLy8gU3BlYyBzYXlzIHNvbWV0aGluZyBhYm91dCBzdG9yaW5nIGEgbGlzdCBvZiBtYXJrZXJzLCBidXQgaXQgc291bmRzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gdGhpcyBjaGVjay5cbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5hVGFnSW5TY29wZTtcblxuICAgICAgY2FzZSAnbm9icic6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ubm9iclRhZ0luU2NvcGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdpdmVuIGEgUmVhY3RDb21wb3NpdGVDb21wb25lbnQgaW5zdGFuY2UsIHJldHVybiBhIGxpc3Qgb2YgaXRzIHJlY3Vyc2l2ZVxuICAgKiBvd25lcnMsIHN0YXJ0aW5nIGF0IHRoZSByb290IGFuZCBlbmRpbmcgd2l0aCB0aGUgaW5zdGFuY2UgaXRzZWxmLlxuICAgKi9cbiAgdmFyIGZpbmRPd25lclN0YWNrID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHZhciBzdGFjayA9IFtdO1xuICAgIC8qZXNsaW50LWRpc2FibGUgc3BhY2UtYWZ0ZXIta2V5d29yZHMgKi9cbiAgICBkbyB7XG4gICAgICAvKmVzbGludC1lbmFibGUgc3BhY2UtYWZ0ZXIta2V5d29yZHMgKi9cbiAgICAgIHN0YWNrLnB1c2goaW5zdGFuY2UpO1xuICAgIH0gd2hpbGUgKGluc3RhbmNlID0gaW5zdGFuY2UuX2N1cnJlbnRFbGVtZW50Ll9vd25lcik7XG4gICAgc3RhY2sucmV2ZXJzZSgpO1xuICAgIHJldHVybiBzdGFjaztcbiAgfTtcblxuICB2YXIgZGlkV2FybiA9IHt9O1xuXG4gIHZhbGlkYXRlRE9NTmVzdGluZyA9IGZ1bmN0aW9uIChjaGlsZFRhZywgY2hpbGRJbnN0YW5jZSwgYW5jZXN0b3JJbmZvKSB7XG4gICAgYW5jZXN0b3JJbmZvID0gYW5jZXN0b3JJbmZvIHx8IGVtcHR5QW5jZXN0b3JJbmZvO1xuICAgIHZhciBwYXJlbnRJbmZvID0gYW5jZXN0b3JJbmZvLnBhcmVudFRhZztcbiAgICB2YXIgcGFyZW50VGFnID0gcGFyZW50SW5mbyAmJiBwYXJlbnRJbmZvLnRhZztcblxuICAgIHZhciBpbnZhbGlkUGFyZW50ID0gaXNUYWdWYWxpZFdpdGhQYXJlbnQoY2hpbGRUYWcsIHBhcmVudFRhZykgPyBudWxsIDogcGFyZW50SW5mbztcbiAgICB2YXIgaW52YWxpZEFuY2VzdG9yID0gaW52YWxpZFBhcmVudCA/IG51bGwgOiBmaW5kSW52YWxpZEFuY2VzdG9yRm9yVGFnKGNoaWxkVGFnLCBhbmNlc3RvckluZm8pO1xuICAgIHZhciBwcm9ibGVtYXRpYyA9IGludmFsaWRQYXJlbnQgfHwgaW52YWxpZEFuY2VzdG9yO1xuXG4gICAgaWYgKHByb2JsZW1hdGljKSB7XG4gICAgICB2YXIgYW5jZXN0b3JUYWcgPSBwcm9ibGVtYXRpYy50YWc7XG4gICAgICB2YXIgYW5jZXN0b3JJbnN0YW5jZSA9IHByb2JsZW1hdGljLmluc3RhbmNlO1xuXG4gICAgICB2YXIgY2hpbGRPd25lciA9IGNoaWxkSW5zdGFuY2UgJiYgY2hpbGRJbnN0YW5jZS5fY3VycmVudEVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIGFuY2VzdG9yT3duZXIgPSBhbmNlc3Rvckluc3RhbmNlICYmIGFuY2VzdG9ySW5zdGFuY2UuX2N1cnJlbnRFbGVtZW50Ll9vd25lcjtcblxuICAgICAgdmFyIGNoaWxkT3duZXJzID0gZmluZE93bmVyU3RhY2soY2hpbGRPd25lcik7XG4gICAgICB2YXIgYW5jZXN0b3JPd25lcnMgPSBmaW5kT3duZXJTdGFjayhhbmNlc3Rvck93bmVyKTtcblxuICAgICAgdmFyIG1pblN0YWNrTGVuID0gTWF0aC5taW4oY2hpbGRPd25lcnMubGVuZ3RoLCBhbmNlc3Rvck93bmVycy5sZW5ndGgpO1xuICAgICAgdmFyIGk7XG5cbiAgICAgIHZhciBkZWVwZXN0Q29tbW9uID0gLTE7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbWluU3RhY2tMZW47IGkrKykge1xuICAgICAgICBpZiAoY2hpbGRPd25lcnNbaV0gPT09IGFuY2VzdG9yT3duZXJzW2ldKSB7XG4gICAgICAgICAgZGVlcGVzdENvbW1vbiA9IGk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIFVOS05PV04gPSAnKHVua25vd24pJztcbiAgICAgIHZhciBjaGlsZE93bmVyTmFtZXMgPSBjaGlsZE93bmVycy5zbGljZShkZWVwZXN0Q29tbW9uICsgMSkubWFwKGZ1bmN0aW9uIChpbnN0KSB7XG4gICAgICAgIHJldHVybiBpbnN0LmdldE5hbWUoKSB8fCBVTktOT1dOO1xuICAgICAgfSk7XG4gICAgICB2YXIgYW5jZXN0b3JPd25lck5hbWVzID0gYW5jZXN0b3JPd25lcnMuc2xpY2UoZGVlcGVzdENvbW1vbiArIDEpLm1hcChmdW5jdGlvbiAoaW5zdCkge1xuICAgICAgICByZXR1cm4gaW5zdC5nZXROYW1lKCkgfHwgVU5LTk9XTjtcbiAgICAgIH0pO1xuICAgICAgdmFyIG93bmVySW5mbyA9IFtdLmNvbmNhdChcbiAgICAgIC8vIElmIHRoZSBwYXJlbnQgYW5kIGNoaWxkIGluc3RhbmNlcyBoYXZlIGEgY29tbW9uIG93bmVyIGFuY2VzdG9yLCBzdGFydFxuICAgICAgLy8gd2l0aCB0aGF0IC0tIG90aGVyd2lzZSB3ZSBqdXN0IHN0YXJ0IHdpdGggdGhlIHBhcmVudCdzIG93bmVycy5cbiAgICAgIGRlZXBlc3RDb21tb24gIT09IC0xID8gY2hpbGRPd25lcnNbZGVlcGVzdENvbW1vbl0uZ2V0TmFtZSgpIHx8IFVOS05PV04gOiBbXSwgYW5jZXN0b3JPd25lck5hbWVzLCBhbmNlc3RvclRhZyxcbiAgICAgIC8vIElmIHdlJ3JlIHdhcm5pbmcgYWJvdXQgYW4gaW52YWxpZCAobm9uLXBhcmVudCkgYW5jZXN0cnksIGFkZCAnLi4uJ1xuICAgICAgaW52YWxpZEFuY2VzdG9yID8gWycuLi4nXSA6IFtdLCBjaGlsZE93bmVyTmFtZXMsIGNoaWxkVGFnKS5qb2luKCcgPiAnKTtcblxuICAgICAgdmFyIHdhcm5LZXkgPSAhIWludmFsaWRQYXJlbnQgKyAnfCcgKyBjaGlsZFRhZyArICd8JyArIGFuY2VzdG9yVGFnICsgJ3wnICsgb3duZXJJbmZvO1xuICAgICAgaWYgKGRpZFdhcm5bd2FybktleV0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGlkV2Fyblt3YXJuS2V5XSA9IHRydWU7XG5cbiAgICAgIGlmIChpbnZhbGlkUGFyZW50KSB7XG4gICAgICAgIHZhciBpbmZvID0gJyc7XG4gICAgICAgIGlmIChhbmNlc3RvclRhZyA9PT0gJ3RhYmxlJyAmJiBjaGlsZFRhZyA9PT0gJ3RyJykge1xuICAgICAgICAgIGluZm8gKz0gJyBBZGQgYSA8dGJvZHk+IHRvIHlvdXIgY29kZSB0byBtYXRjaCB0aGUgRE9NIHRyZWUgZ2VuZXJhdGVkIGJ5ICcgKyAndGhlIGJyb3dzZXIuJztcbiAgICAgICAgfVxuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gd2FybmluZyhmYWxzZSwgJ3ZhbGlkYXRlRE9NTmVzdGluZyguLi4pOiA8JXM+IGNhbm5vdCBhcHBlYXIgYXMgYSBjaGlsZCBvZiA8JXM+LiAnICsgJ1NlZSAlcy4lcycsIGNoaWxkVGFnLCBhbmNlc3RvclRhZywgb3duZXJJbmZvLCBpbmZvKSA6IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyB3YXJuaW5nKGZhbHNlLCAndmFsaWRhdGVET01OZXN0aW5nKC4uLik6IDwlcz4gY2Fubm90IGFwcGVhciBhcyBhIGRlc2NlbmRhbnQgb2YgJyArICc8JXM+LiBTZWUgJXMuJywgY2hpbGRUYWcsIGFuY2VzdG9yVGFnLCBvd25lckluZm8pIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YWxpZGF0ZURPTU5lc3RpbmcuYW5jZXN0b3JJbmZvQ29udGV4dEtleSA9ICdfX3ZhbGlkYXRlRE9NTmVzdGluZ19hbmNlc3RvckluZm8kJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpO1xuXG4gIHZhbGlkYXRlRE9NTmVzdGluZy51cGRhdGVkQW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbztcblxuICAvLyBGb3IgdGVzdGluZ1xuICB2YWxpZGF0ZURPTU5lc3RpbmcuaXNUYWdWYWxpZEluQ29udGV4dCA9IGZ1bmN0aW9uICh0YWcsIGFuY2VzdG9ySW5mbykge1xuICAgIGFuY2VzdG9ySW5mbyA9IGFuY2VzdG9ySW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbztcbiAgICB2YXIgcGFyZW50SW5mbyA9IGFuY2VzdG9ySW5mby5wYXJlbnRUYWc7XG4gICAgdmFyIHBhcmVudFRhZyA9IHBhcmVudEluZm8gJiYgcGFyZW50SW5mby50YWc7XG4gICAgcmV0dXJuIGlzVGFnVmFsaWRXaXRoUGFyZW50KHRhZywgcGFyZW50VGFnKSAmJiAhZmluZEludmFsaWRBbmNlc3RvckZvclRhZyh0YWcsIGFuY2VzdG9ySW5mbyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmFsaWRhdGVET01OZXN0aW5nOyIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9SZWFjdCcpO1xuIiwiXG4vKipcbiAqIFJlZHVjZSBgYXJyYCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFxuICpcbiAqIFRPRE86IGNvbWJhdGlibGUgZXJyb3IgaGFuZGxpbmc/XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIGZuLCBpbml0aWFsKXsgIFxuICB2YXIgaWR4ID0gMDtcbiAgdmFyIGxlbiA9IGFyci5sZW5ndGg7XG4gIHZhciBjdXJyID0gYXJndW1lbnRzLmxlbmd0aCA9PSAzXG4gICAgPyBpbml0aWFsXG4gICAgOiBhcnJbaWR4KytdO1xuXG4gIHdoaWxlIChpZHggPCBsZW4pIHtcbiAgICBjdXJyID0gZm4uY2FsbChudWxsLCBjdXJyLCBhcnJbaWR4XSwgKytpZHgsIGFycik7XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyO1xufTsiLCIvKipcbiAqIEEgbW9kdWxlIG9mIG1ldGhvZHMgdGhhdCB5b3Ugd2FudCB0byBpbmNsdWRlIGluIGFsbCBhY3Rpb25zLlxuICogVGhpcyBtb2R1bGUgaXMgY29uc3VtZWQgYnkgYGNyZWF0ZUFjdGlvbmAuXG4gKi9cblwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHt9OyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLmNyZWF0ZWRTdG9yZXMgPSBbXTtcblxuZXhwb3J0cy5jcmVhdGVkQWN0aW9ucyA9IFtdO1xuXG5leHBvcnRzLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHdoaWxlIChleHBvcnRzLmNyZWF0ZWRTdG9yZXMubGVuZ3RoKSB7XG4gICAgICAgIGV4cG9ydHMuY3JlYXRlZFN0b3Jlcy5wb3AoKTtcbiAgICB9XG4gICAgd2hpbGUgKGV4cG9ydHMuY3JlYXRlZEFjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIGV4cG9ydHMuY3JlYXRlZEFjdGlvbnMucG9wKCk7XG4gICAgfVxufTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF8gPSByZXF1aXJlKFwiLi91dGlsc1wiKSxcbiAgICBtYWtlciA9IHJlcXVpcmUoXCIuL2pvaW5zXCIpLmluc3RhbmNlSm9pbkNyZWF0b3I7XG5cbi8qKlxuICogRXh0cmFjdCBjaGlsZCBsaXN0ZW5hYmxlcyBmcm9tIGEgcGFyZW50IGZyb20gdGhlaXJcbiAqIGNoaWxkcmVuIHByb3BlcnR5IGFuZCByZXR1cm4gdGhlbSBpbiBhIGtleWVkIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaXN0ZW5hYmxlIFRoZSBwYXJlbnQgbGlzdGVuYWJsZVxuICovXG52YXIgbWFwQ2hpbGRMaXN0ZW5hYmxlcyA9IGZ1bmN0aW9uIG1hcENoaWxkTGlzdGVuYWJsZXMobGlzdGVuYWJsZSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgY2hpbGRyZW4gPSB7fSxcbiAgICAgICAgY2hpbGROYW1lO1xuICAgIGZvciAoOyBpIDwgKGxpc3RlbmFibGUuY2hpbGRyZW4gfHwgW10pLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNoaWxkTmFtZSA9IGxpc3RlbmFibGUuY2hpbGRyZW5baV07XG4gICAgICAgIGlmIChsaXN0ZW5hYmxlW2NoaWxkTmFtZV0pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuW2NoaWxkTmFtZV0gPSBsaXN0ZW5hYmxlW2NoaWxkTmFtZV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkcmVuO1xufTtcblxuLyoqXG4gKiBNYWtlIGEgZmxhdCBkaWN0aW9uYXJ5IG9mIGFsbCBsaXN0ZW5hYmxlcyBpbmNsdWRpbmcgdGhlaXJcbiAqIHBvc3NpYmxlIGNoaWxkcmVuIChyZWN1cnNpdmVseSksIGNvbmNhdGVuYXRpbmcgbmFtZXMgaW4gY2FtZWxDYXNlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaXN0ZW5hYmxlcyBUaGUgdG9wLWxldmVsIGxpc3RlbmFibGVzXG4gKi9cbnZhciBmbGF0dGVuTGlzdGVuYWJsZXMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuYWJsZXMobGlzdGVuYWJsZXMpIHtcbiAgICB2YXIgZmxhdHRlbmVkID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIGxpc3RlbmFibGVzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5hYmxlID0gbGlzdGVuYWJsZXNba2V5XTtcbiAgICAgICAgdmFyIGNoaWxkTWFwID0gbWFwQ2hpbGRMaXN0ZW5hYmxlcyhsaXN0ZW5hYmxlKTtcblxuICAgICAgICAvLyByZWN1cnNpdmVseSBmbGF0dGVuIGNoaWxkcmVuXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IGZsYXR0ZW5MaXN0ZW5hYmxlcyhjaGlsZE1hcCk7XG5cbiAgICAgICAgLy8gYWRkIHRoZSBwcmltYXJ5IGxpc3RlbmFibGUgYW5kIGNoaWxyZW5cbiAgICAgICAgZmxhdHRlbmVkW2tleV0gPSBsaXN0ZW5hYmxlO1xuICAgICAgICBmb3IgKHZhciBjaGlsZEtleSBpbiBjaGlsZHJlbikge1xuICAgICAgICAgICAgdmFyIGNoaWxkTGlzdGVuYWJsZSA9IGNoaWxkcmVuW2NoaWxkS2V5XTtcbiAgICAgICAgICAgIGZsYXR0ZW5lZFtrZXkgKyBfLmNhcGl0YWxpemUoY2hpbGRLZXkpXSA9IGNoaWxkTGlzdGVuYWJsZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmbGF0dGVuZWQ7XG59O1xuXG4vKipcbiAqIEEgbW9kdWxlIG9mIG1ldGhvZHMgcmVsYXRlZCB0byBsaXN0ZW5pbmcuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gICAgLyoqXG4gICAgICogQW4gaW50ZXJuYWwgdXRpbGl0eSBmdW5jdGlvbiB1c2VkIGJ5IGB2YWxpZGF0ZUxpc3RlbmluZ2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7QWN0aW9ufFN0b3JlfSBsaXN0ZW5hYmxlIFRoZSBsaXN0ZW5hYmxlIHdlIHdhbnQgdG8gc2VhcmNoIGZvclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufSBUaGUgcmVzdWx0IG9mIGEgcmVjdXJzaXZlIHNlYXJjaCBhbW9uZyBgdGhpcy5zdWJzY3JpcHRpb25zYFxuICAgICAqL1xuICAgIGhhc0xpc3RlbmVyOiBmdW5jdGlvbiBoYXNMaXN0ZW5lcihsaXN0ZW5hYmxlKSB7XG4gICAgICAgIHZhciBpID0gMCxcbiAgICAgICAgICAgIGosXG4gICAgICAgICAgICBsaXN0ZW5lcixcbiAgICAgICAgICAgIGxpc3RlbmFibGVzO1xuICAgICAgICBmb3IgKDsgaSA8ICh0aGlzLnN1YnNjcmlwdGlvbnMgfHwgW10pLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBsaXN0ZW5hYmxlcyA9IFtdLmNvbmNhdCh0aGlzLnN1YnNjcmlwdGlvbnNbaV0ubGlzdGVuYWJsZSk7XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGlzdGVuYWJsZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lciA9IGxpc3RlbmFibGVzW2pdO1xuICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lciA9PT0gbGlzdGVuYWJsZSB8fCBsaXN0ZW5lci5oYXNMaXN0ZW5lciAmJiBsaXN0ZW5lci5oYXNMaXN0ZW5lcihsaXN0ZW5hYmxlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIGNvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGxpc3RlbnMgdG8gYWxsIGxpc3RlbmFibGVzIGluIHRoZSBnaXZlbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gbGlzdGVuYWJsZXMgQW4gb2JqZWN0IG9mIGxpc3RlbmFibGVzLiBLZXlzIHdpbGwgYmUgdXNlZCBhcyBjYWxsYmFjayBtZXRob2QgbmFtZXMuXG4gICAgICovXG4gICAgbGlzdGVuVG9NYW55OiBmdW5jdGlvbiBsaXN0ZW5Ub01hbnkobGlzdGVuYWJsZXMpIHtcbiAgICAgICAgdmFyIGFsbExpc3RlbmFibGVzID0gZmxhdHRlbkxpc3RlbmFibGVzKGxpc3RlbmFibGVzKTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGFsbExpc3RlbmFibGVzKSB7XG4gICAgICAgICAgICB2YXIgY2JuYW1lID0gXy5jYWxsYmFja05hbWUoa2V5KSxcbiAgICAgICAgICAgICAgICBsb2NhbG5hbWUgPSB0aGlzW2NibmFtZV0gPyBjYm5hbWUgOiB0aGlzW2tleV0gPyBrZXkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAobG9jYWxuYW1lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5UbyhhbGxMaXN0ZW5hYmxlc1trZXldLCBsb2NhbG5hbWUsIHRoaXNbY2JuYW1lICsgXCJEZWZhdWx0XCJdIHx8IHRoaXNbbG9jYWxuYW1lICsgXCJEZWZhdWx0XCJdIHx8IGxvY2FsbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGNvbnRleHQgY2FuIGxpc3RlbiB0byB0aGUgc3VwcGxpZWQgbGlzdGVuYWJsZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtBY3Rpb258U3RvcmV9IGxpc3RlbmFibGUgQW4gQWN0aW9uIG9yIFN0b3JlIHRoYXQgc2hvdWxkIGJlXG4gICAgICogIGxpc3RlbmVkIHRvLlxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd8VW5kZWZpbmVkfSBBbiBlcnJvciBtZXNzYWdlLCBvciB1bmRlZmluZWQgaWYgdGhlcmUgd2FzIG5vIHByb2JsZW0uXG4gICAgICovXG4gICAgdmFsaWRhdGVMaXN0ZW5pbmc6IGZ1bmN0aW9uIHZhbGlkYXRlTGlzdGVuaW5nKGxpc3RlbmFibGUpIHtcbiAgICAgICAgaWYgKGxpc3RlbmFibGUgPT09IHRoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBcIkxpc3RlbmVyIGlzIG5vdCBhYmxlIHRvIGxpc3RlbiB0byBpdHNlbGZcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIV8uaXNGdW5jdGlvbihsaXN0ZW5hYmxlLmxpc3RlbikpIHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0ZW5hYmxlICsgXCIgaXMgbWlzc2luZyBhIGxpc3RlbiBtZXRob2RcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGlzdGVuYWJsZS5oYXNMaXN0ZW5lciAmJiBsaXN0ZW5hYmxlLmhhc0xpc3RlbmVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJMaXN0ZW5lciBjYW5ub3QgbGlzdGVuIHRvIHRoaXMgbGlzdGVuYWJsZSBiZWNhdXNlIG9mIGNpcmN1bGFyIGxvb3BcIjtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHVwIGEgc3Vic2NyaXB0aW9uIHRvIHRoZSBnaXZlbiBsaXN0ZW5hYmxlIGZvciB0aGUgY29udGV4dCBvYmplY3RcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7QWN0aW9ufFN0b3JlfSBsaXN0ZW5hYmxlIEFuIEFjdGlvbiBvciBTdG9yZSB0aGF0IHNob3VsZCBiZVxuICAgICAqICBsaXN0ZW5lZCB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIHJlZ2lzdGVyIGFzIGV2ZW50IGhhbmRsZXJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZGVmYXVsdENhbGxiYWNrIFRoZSBjYWxsYmFjayB0byByZWdpc3RlciBhcyBkZWZhdWx0IGhhbmRsZXJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHN1YnNjcmlwdGlvbiBvYmogd2hlcmUgYHN0b3BgIGlzIGFuIHVuc3ViIGZ1bmN0aW9uIGFuZCBgbGlzdGVuYWJsZWAgaXMgdGhlIG9iamVjdCBiZWluZyBsaXN0ZW5lZCB0b1xuICAgICAqL1xuICAgIGxpc3RlblRvOiBmdW5jdGlvbiBsaXN0ZW5UbyhsaXN0ZW5hYmxlLCBjYWxsYmFjaywgZGVmYXVsdENhbGxiYWNrKSB7XG4gICAgICAgIHZhciBkZXN1YixcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlcixcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbm9iaixcbiAgICAgICAgICAgIHN1YnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMgfHwgW107XG4gICAgICAgIF8udGhyb3dJZih0aGlzLnZhbGlkYXRlTGlzdGVuaW5nKGxpc3RlbmFibGUpKTtcbiAgICAgICAgdGhpcy5mZXRjaEluaXRpYWxTdGF0ZShsaXN0ZW5hYmxlLCBkZWZhdWx0Q2FsbGJhY2spO1xuICAgICAgICBkZXN1YiA9IGxpc3RlbmFibGUubGlzdGVuKHRoaXNbY2FsbGJhY2tdIHx8IGNhbGxiYWNrLCB0aGlzKTtcbiAgICAgICAgdW5zdWJzY3JpYmVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gc3Vicy5pbmRleE9mKHN1YnNjcmlwdGlvbm9iaik7XG4gICAgICAgICAgICBfLnRocm93SWYoaW5kZXggPT09IC0xLCBcIlRyaWVkIHRvIHJlbW92ZSBsaXN0ZW4gYWxyZWFkeSBnb25lIGZyb20gc3Vic2NyaXB0aW9ucyBsaXN0IVwiKTtcbiAgICAgICAgICAgIHN1YnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGRlc3ViKCk7XG4gICAgICAgIH07XG4gICAgICAgIHN1YnNjcmlwdGlvbm9iaiA9IHtcbiAgICAgICAgICAgIHN0b3A6IHVuc3Vic2NyaWJlcixcbiAgICAgICAgICAgIGxpc3RlbmFibGU6IGxpc3RlbmFibGVcbiAgICAgICAgfTtcbiAgICAgICAgc3Vicy5wdXNoKHN1YnNjcmlwdGlvbm9iaik7XG4gICAgICAgIHJldHVybiBzdWJzY3JpcHRpb25vYmo7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGxpc3RlbmluZyB0byBhIHNpbmdsZSBsaXN0ZW5hYmxlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0FjdGlvbnxTdG9yZX0gbGlzdGVuYWJsZSBUaGUgYWN0aW9uIG9yIHN0b3JlIHdlIG5vIGxvbmdlciB3YW50IHRvIGxpc3RlbiB0b1xuICAgICAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIGEgc3Vic2NyaXB0aW9uIHdhcyBmb3VuZCBhbmQgcmVtb3ZlZCwgb3RoZXJ3aXNlIGZhbHNlLlxuICAgICAqL1xuICAgIHN0b3BMaXN0ZW5pbmdUbzogZnVuY3Rpb24gc3RvcExpc3RlbmluZ1RvKGxpc3RlbmFibGUpIHtcbiAgICAgICAgdmFyIHN1YixcbiAgICAgICAgICAgIGkgPSAwLFxuICAgICAgICAgICAgc3VicyA9IHRoaXMuc3Vic2NyaXB0aW9ucyB8fCBbXTtcbiAgICAgICAgZm9yICg7IGkgPCBzdWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzdWIgPSBzdWJzW2ldO1xuICAgICAgICAgICAgaWYgKHN1Yi5saXN0ZW5hYmxlID09PSBsaXN0ZW5hYmxlKSB7XG4gICAgICAgICAgICAgICAgc3ViLnN0b3AoKTtcbiAgICAgICAgICAgICAgICBfLnRocm93SWYoc3Vicy5pbmRleE9mKHN1YikgIT09IC0xLCBcIkZhaWxlZCB0byByZW1vdmUgbGlzdGVuIGZyb20gc3Vic2NyaXB0aW9ucyBsaXN0IVwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGFsbCBzdWJzY3JpcHRpb25zIGFuZCBlbXB0aWVzIHN1YnNjcmlwdGlvbnMgYXJyYXlcbiAgICAgKi9cbiAgICBzdG9wTGlzdGVuaW5nVG9BbGw6IGZ1bmN0aW9uIHN0b3BMaXN0ZW5pbmdUb0FsbCgpIHtcbiAgICAgICAgdmFyIHJlbWFpbmluZyxcbiAgICAgICAgICAgIHN1YnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMgfHwgW107XG4gICAgICAgIHdoaWxlIChyZW1haW5pbmcgPSBzdWJzLmxlbmd0aCkge1xuICAgICAgICAgICAgc3Vic1swXS5zdG9wKCk7XG4gICAgICAgICAgICBfLnRocm93SWYoc3Vicy5sZW5ndGggIT09IHJlbWFpbmluZyAtIDEsIFwiRmFpbGVkIHRvIHJlbW92ZSBsaXN0ZW4gZnJvbSBzdWJzY3JpcHRpb25zIGxpc3QhXCIpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFVzZWQgaW4gYGxpc3RlblRvYC4gRmV0Y2hlcyBpbml0aWFsIGRhdGEgZnJvbSBhIHB1Ymxpc2hlciBpZiBpdCBoYXMgYSBgZ2V0SW5pdGlhbFN0YXRlYCBtZXRob2QuXG4gICAgICogQHBhcmFtIHtBY3Rpb258U3RvcmV9IGxpc3RlbmFibGUgVGhlIHB1Ymxpc2hlciB3ZSB3YW50IHRvIGdldCBpbml0aWFsIHN0YXRlIGZyb21cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZGVmYXVsdENhbGxiYWNrIFRoZSBtZXRob2QgdG8gcmVjZWl2ZSB0aGUgZGF0YVxuICAgICAqL1xuICAgIGZldGNoSW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBmZXRjaEluaXRpYWxTdGF0ZShsaXN0ZW5hYmxlLCBkZWZhdWx0Q2FsbGJhY2spIHtcbiAgICAgICAgZGVmYXVsdENhbGxiYWNrID0gZGVmYXVsdENhbGxiYWNrICYmIHRoaXNbZGVmYXVsdENhbGxiYWNrXSB8fCBkZWZhdWx0Q2FsbGJhY2s7XG4gICAgICAgIHZhciBtZSA9IHRoaXM7XG4gICAgICAgIGlmIChfLmlzRnVuY3Rpb24oZGVmYXVsdENhbGxiYWNrKSAmJiBfLmlzRnVuY3Rpb24obGlzdGVuYWJsZS5nZXRJbml0aWFsU3RhdGUpKSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IGxpc3RlbmFibGUuZ2V0SW5pdGlhbFN0YXRlKCk7XG4gICAgICAgICAgICBpZiAoZGF0YSAmJiBfLmlzRnVuY3Rpb24oZGF0YS50aGVuKSkge1xuICAgICAgICAgICAgICAgIGRhdGEudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRDYWxsYmFjay5hcHBseShtZSwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdENhbGxiYWNrLmNhbGwodGhpcywgZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIG9uY2UgYWxsIGxpc3RlbmFibGVzIGhhdmUgdHJpZ2dlcmVkIGF0IGxlYXN0IG9uY2UuXG4gICAgICogSXQgd2lsbCBiZSBpbnZva2VkIHdpdGggdGhlIGxhc3QgZW1pc3Npb24gZnJvbSBlYWNoIGxpc3RlbmFibGUuXG4gICAgICogQHBhcmFtIHsuLi5QdWJsaXNoZXJzfSBwdWJsaXNoZXJzIFB1Ymxpc2hlcnMgdGhhdCBzaG91bGQgYmUgdHJhY2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY2FsbGJhY2sgVGhlIG1ldGhvZCB0byBjYWxsIHdoZW4gYWxsIHB1Ymxpc2hlcnMgaGF2ZSBlbWl0dGVkXG4gICAgICogQHJldHVybnMge09iamVjdH0gQSBzdWJzY3JpcHRpb24gb2JqIHdoZXJlIGBzdG9wYCBpcyBhbiB1bnN1YiBmdW5jdGlvbiBhbmQgYGxpc3RlbmFibGVgIGlzIGFuIGFycmF5IG9mIGxpc3RlbmFibGVzXG4gICAgICovXG4gICAgam9pblRyYWlsaW5nOiBtYWtlcihcImxhc3RcIiksXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgb25jZSBhbGwgbGlzdGVuYWJsZXMgaGF2ZSB0cmlnZ2VyZWQgYXQgbGVhc3Qgb25jZS5cbiAgICAgKiBJdCB3aWxsIGJlIGludm9rZWQgd2l0aCB0aGUgZmlyc3QgZW1pc3Npb24gZnJvbSBlYWNoIGxpc3RlbmFibGUuXG4gICAgICogQHBhcmFtIHsuLi5QdWJsaXNoZXJzfSBwdWJsaXNoZXJzIFB1Ymxpc2hlcnMgdGhhdCBzaG91bGQgYmUgdHJhY2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY2FsbGJhY2sgVGhlIG1ldGhvZCB0byBjYWxsIHdoZW4gYWxsIHB1Ymxpc2hlcnMgaGF2ZSBlbWl0dGVkXG4gICAgICogQHJldHVybnMge09iamVjdH0gQSBzdWJzY3JpcHRpb24gb2JqIHdoZXJlIGBzdG9wYCBpcyBhbiB1bnN1YiBmdW5jdGlvbiBhbmQgYGxpc3RlbmFibGVgIGlzIGFuIGFycmF5IG9mIGxpc3RlbmFibGVzXG4gICAgICovXG4gICAgam9pbkxlYWRpbmc6IG1ha2VyKFwiZmlyc3RcIiksXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgb25jZSBhbGwgbGlzdGVuYWJsZXMgaGF2ZSB0cmlnZ2VyZWQgYXQgbGVhc3Qgb25jZS5cbiAgICAgKiBJdCB3aWxsIGJlIGludm9rZWQgd2l0aCBhbGwgZW1pc3Npb24gZnJvbSBlYWNoIGxpc3RlbmFibGUuXG4gICAgICogQHBhcmFtIHsuLi5QdWJsaXNoZXJzfSBwdWJsaXNoZXJzIFB1Ymxpc2hlcnMgdGhhdCBzaG91bGQgYmUgdHJhY2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY2FsbGJhY2sgVGhlIG1ldGhvZCB0byBjYWxsIHdoZW4gYWxsIHB1Ymxpc2hlcnMgaGF2ZSBlbWl0dGVkXG4gICAgICogQHJldHVybnMge09iamVjdH0gQSBzdWJzY3JpcHRpb24gb2JqIHdoZXJlIGBzdG9wYCBpcyBhbiB1bnN1YiBmdW5jdGlvbiBhbmQgYGxpc3RlbmFibGVgIGlzIGFuIGFycmF5IG9mIGxpc3RlbmFibGVzXG4gICAgICovXG4gICAgam9pbkNvbmNhdDogbWFrZXIoXCJhbGxcIiksXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgb25jZSBhbGwgbGlzdGVuYWJsZXMgaGF2ZSB0cmlnZ2VyZWQuXG4gICAgICogSWYgYSBjYWxsYmFjayB0cmlnZ2VycyB0d2ljZSBiZWZvcmUgdGhhdCBoYXBwZW5zLCBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAgICogQHBhcmFtIHsuLi5QdWJsaXNoZXJzfSBwdWJsaXNoZXJzIFB1Ymxpc2hlcnMgdGhhdCBzaG91bGQgYmUgdHJhY2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY2FsbGJhY2sgVGhlIG1ldGhvZCB0byBjYWxsIHdoZW4gYWxsIHB1Ymxpc2hlcnMgaGF2ZSBlbWl0dGVkXG4gICAgICogQHJldHVybnMge09iamVjdH0gQSBzdWJzY3JpcHRpb24gb2JqIHdoZXJlIGBzdG9wYCBpcyBhbiB1bnN1YiBmdW5jdGlvbiBhbmQgYGxpc3RlbmFibGVgIGlzIGFuIGFycmF5IG9mIGxpc3RlbmFibGVzXG4gICAgICovXG4gICAgam9pblN0cmljdDogbWFrZXIoXCJzdHJpY3RcIilcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbi8qKlxuICogQSBtb2R1bGUgb2YgbWV0aG9kcyBmb3Igb2JqZWN0IHRoYXQgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBsaXN0ZW4gdG8uXG4gKiBUaGlzIG1vZHVsZSBpcyBjb25zdW1lZCBieSBgY3JlYXRlU3RvcmVgIGFuZCBgY3JlYXRlQWN0aW9uYFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAgIC8qKlxuICAgICAqIEhvb2sgdXNlZCBieSB0aGUgcHVibGlzaGVyIHRoYXQgaXMgaW52b2tlZCBiZWZvcmUgZW1pdHRpbmdcbiAgICAgKiBhbmQgYmVmb3JlIGBzaG91bGRFbWl0YC4gVGhlIGFyZ3VtZW50cyBhcmUgdGhlIG9uZXMgdGhhdCB0aGUgYWN0aW9uXG4gICAgICogaXMgaW52b2tlZCB3aXRoLiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgc29tZXRoaW5nIG90aGVyIHRoYW5cbiAgICAgKiB1bmRlZmluZWQsIHRoYXQgd2lsbCBiZSBwYXNzZWQgb24gYXMgYXJndW1lbnRzIGZvciBzaG91bGRFbWl0IGFuZFxuICAgICAqIGVtaXNzaW9uLlxuICAgICAqL1xuICAgIHByZUVtaXQ6IGZ1bmN0aW9uIHByZUVtaXQoKSB7fSxcblxuICAgIC8qKlxuICAgICAqIEhvb2sgdXNlZCBieSB0aGUgcHVibGlzaGVyIGFmdGVyIGBwcmVFbWl0YCB0byBkZXRlcm1pbmUgaWYgdGhlXG4gICAgICogZXZlbnQgc2hvdWxkIGJlIGVtaXR0ZWQgd2l0aCBnaXZlbiBhcmd1bWVudHMuIFRoaXMgbWF5IGJlIG92ZXJyaWRkZW5cbiAgICAgKiBpbiB5b3VyIGFwcGxpY2F0aW9uLCBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGFsd2F5cyByZXR1cm5zIHRydWUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gdHJ1ZSBpZiBldmVudCBzaG91bGQgYmUgZW1pdHRlZFxuICAgICAqL1xuICAgIHNob3VsZEVtaXQ6IGZ1bmN0aW9uIHNob3VsZEVtaXQoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmVzIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYWN0aW9uIHRyaWdnZXJlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIHJlZ2lzdGVyIGFzIGV2ZW50IGhhbmRsZXJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBbb3B0aW9uYWxdIGJpbmRDb250ZXh0IFRoZSBjb250ZXh0IHRvIGJpbmQgdGhlIGNhbGxiYWNrIHdpdGhcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IENhbGxiYWNrIHRoYXQgdW5zdWJzY3JpYmVzIHRoZSByZWdpc3RlcmVkIGV2ZW50IGhhbmRsZXJcbiAgICAgKi9cbiAgICBsaXN0ZW46IGZ1bmN0aW9uIGxpc3RlbihjYWxsYmFjaywgYmluZENvbnRleHQpIHtcbiAgICAgICAgYmluZENvbnRleHQgPSBiaW5kQ29udGV4dCB8fCB0aGlzO1xuICAgICAgICB2YXIgZXZlbnRIYW5kbGVyID0gZnVuY3Rpb24gZXZlbnRIYW5kbGVyKGFyZ3MpIHtcbiAgICAgICAgICAgIGlmIChhYm9ydGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoYmluZENvbnRleHQsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICAgICAgbWUgPSB0aGlzLFxuICAgICAgICAgICAgYWJvcnRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVtaXR0ZXIuYWRkTGlzdGVuZXIodGhpcy5ldmVudExhYmVsLCBldmVudEhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgICAgICAgICBtZS5lbWl0dGVyLnJlbW92ZUxpc3RlbmVyKG1lLmV2ZW50TGFiZWwsIGV2ZW50SGFuZGxlcik7XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyBhbiBldmVudCB1c2luZyBgdGhpcy5lbWl0dGVyYCAoaWYgYHNob3VsZEVtaXRgIGFncmVlcylcbiAgICAgKi9cbiAgICB0cmlnZ2VyOiBmdW5jdGlvbiB0cmlnZ2VyKCkge1xuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIHByZSA9IHRoaXMucHJlRW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgYXJncyA9IHByZSA9PT0gdW5kZWZpbmVkID8gYXJncyA6IF8uaXNBcmd1bWVudHMocHJlKSA/IHByZSA6IFtdLmNvbmNhdChwcmUpO1xuICAgICAgICBpZiAodGhpcy5zaG91bGRFbWl0LmFwcGx5KHRoaXMsIGFyZ3MpKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIuZW1pdCh0aGlzLmV2ZW50TGFiZWwsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIHB1Ymxpc2ggdGhlIGV2ZW50IG9uIHRoZSBuZXh0IHRpY2tcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXN5bmM6IGZ1bmN0aW9uIHRyaWdnZXJBc3luYygpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBtZSA9IHRoaXM7XG4gICAgICAgIF8ubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWUudHJpZ2dlci5hcHBseShtZSwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBXcmFwcyB0aGUgdHJpZ2dlciBtZWNoYW5pc20gd2l0aCBhIGRlZmVycmFsIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdGhlIGRlZmVycmFsIGZ1bmN0aW9uLFxuICAgICAqICAgICAgICBmaXJzdCBhcmd1bWVudCBpcyB0aGUgcmVzb2x2aW5nIGZ1bmN0aW9uIGFuZCB0aGVcbiAgICAgKiAgICAgICAgcmVzdCBhcmUgdGhlIGFyZ3VtZW50cyBwcm92aWRlZCBmcm9tIHRoZSBwcmV2aW91c1xuICAgICAqICAgICAgICB0cmlnZ2VyIGludm9jYXRpb25cbiAgICAgKi9cbiAgICBkZWZlcldpdGg6IGZ1bmN0aW9uIGRlZmVyV2l0aChjYWxsYmFjaykge1xuICAgICAgICB2YXIgb2xkVHJpZ2dlciA9IHRoaXMudHJpZ2dlcixcbiAgICAgICAgICAgIGN0eCA9IHRoaXMsXG4gICAgICAgICAgICByZXNvbHZlciA9IGZ1bmN0aW9uIHJlc29sdmVyKCkge1xuICAgICAgICAgICAgb2xkVHJpZ2dlci5hcHBseShjdHgsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KGN0eCwgW3Jlc29sdmVyXS5jb25jYXQoW10uc3BsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSkpO1xuICAgICAgICB9O1xuICAgIH1cblxufTsiLCIvKipcbiAqIEEgbW9kdWxlIG9mIG1ldGhvZHMgdGhhdCB5b3Ugd2FudCB0byBpbmNsdWRlIGluIGFsbCBzdG9yZXMuXG4gKiBUaGlzIG1vZHVsZSBpcyBjb25zdW1lZCBieSBgY3JlYXRlU3RvcmVgLlxuICovXG5cInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSB7fTsiLCJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc3RvcmUsIGRlZmluaXRpb24pIHtcbiAgICBmb3IgKHZhciBuYW1lIGluIGRlZmluaXRpb24pIHtcbiAgICAgICAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgICAgICB2YXIgcHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihkZWZpbml0aW9uLCBuYW1lKTtcblxuICAgICAgICAgICAgaWYgKCFwcm9wZXJ0eURlc2NyaXB0b3IudmFsdWUgfHwgdHlwZW9mIHByb3BlcnR5RGVzY3JpcHRvci52YWx1ZSAhPT0gXCJmdW5jdGlvblwiIHx8ICFkZWZpbml0aW9uLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0b3JlW25hbWVdID0gZGVmaW5pdGlvbltuYW1lXS5iaW5kKHN0b3JlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eSA9IGRlZmluaXRpb25bbmFtZV07XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgcHJvcGVydHkgIT09IFwiZnVuY3Rpb25cIiB8fCAhZGVmaW5pdGlvbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdG9yZVtuYW1lXSA9IHByb3BlcnR5LmJpbmQoc3RvcmUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0b3JlO1xufTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF8gPSByZXF1aXJlKFwiLi91dGlsc1wiKSxcbiAgICBBY3Rpb25NZXRob2RzID0gcmVxdWlyZShcIi4vQWN0aW9uTWV0aG9kc1wiKSxcbiAgICBQdWJsaXNoZXJNZXRob2RzID0gcmVxdWlyZShcIi4vUHVibGlzaGVyTWV0aG9kc1wiKSxcbiAgICBLZWVwID0gcmVxdWlyZShcIi4vS2VlcFwiKTtcblxudmFyIGFsbG93ZWQgPSB7IHByZUVtaXQ6IDEsIHNob3VsZEVtaXQ6IDEgfTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFjdGlvbiBmdW5jdG9yIG9iamVjdC4gSXQgaXMgbWl4ZWQgaW4gd2l0aCBmdW5jdGlvbnNcbiAqIGZyb20gdGhlIGBQdWJsaXNoZXJNZXRob2RzYCBtaXhpbi4gYHByZUVtaXRgIGFuZCBgc2hvdWxkRW1pdGAgbWF5XG4gKiBiZSBvdmVycmlkZGVuIGluIHRoZSBkZWZpbml0aW9uIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGVmaW5pdGlvbiBUaGUgYWN0aW9uIG9iamVjdCBkZWZpbml0aW9uXG4gKi9cbnZhciBjcmVhdGVBY3Rpb24gPSBmdW5jdGlvbiBjcmVhdGVBY3Rpb24oZGVmaW5pdGlvbikge1xuXG4gICAgZGVmaW5pdGlvbiA9IGRlZmluaXRpb24gfHwge307XG4gICAgaWYgKCFfLmlzT2JqZWN0KGRlZmluaXRpb24pKSB7XG4gICAgICAgIGRlZmluaXRpb24gPSB7IGFjdGlvbk5hbWU6IGRlZmluaXRpb24gfTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBhIGluIEFjdGlvbk1ldGhvZHMpIHtcbiAgICAgICAgaWYgKCFhbGxvd2VkW2FdICYmIFB1Ymxpc2hlck1ldGhvZHNbYV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBvdmVycmlkZSBBUEkgbWV0aG9kIFwiICsgYSArIFwiIGluIFJlZmx1eC5BY3Rpb25NZXRob2RzLiBVc2UgYW5vdGhlciBtZXRob2QgbmFtZSBvciBvdmVycmlkZSBpdCBvbiBSZWZsdXguUHVibGlzaGVyTWV0aG9kcyBpbnN0ZWFkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGQgaW4gZGVmaW5pdGlvbikge1xuICAgICAgICBpZiAoIWFsbG93ZWRbZF0gJiYgUHVibGlzaGVyTWV0aG9kc1tkXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IG92ZXJyaWRlIEFQSSBtZXRob2QgXCIgKyBkICsgXCIgaW4gYWN0aW9uIGNyZWF0aW9uLiBVc2UgYW5vdGhlciBtZXRob2QgbmFtZSBvciBvdmVycmlkZSBpdCBvbiBSZWZsdXguUHVibGlzaGVyTWV0aG9kcyBpbnN0ZWFkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlZmluaXRpb24uY2hpbGRyZW4gPSBkZWZpbml0aW9uLmNoaWxkcmVuIHx8IFtdO1xuICAgIGlmIChkZWZpbml0aW9uLmFzeW5jUmVzdWx0KSB7XG4gICAgICAgIGRlZmluaXRpb24uY2hpbGRyZW4gPSBkZWZpbml0aW9uLmNoaWxkcmVuLmNvbmNhdChbXCJjb21wbGV0ZWRcIiwgXCJmYWlsZWRcIl0pO1xuICAgIH1cblxuICAgIHZhciBpID0gMCxcbiAgICAgICAgY2hpbGRBY3Rpb25zID0ge307XG4gICAgZm9yICg7IGkgPCBkZWZpbml0aW9uLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBuYW1lID0gZGVmaW5pdGlvbi5jaGlsZHJlbltpXTtcbiAgICAgICAgY2hpbGRBY3Rpb25zW25hbWVdID0gY3JlYXRlQWN0aW9uKG5hbWUpO1xuICAgIH1cblxuICAgIHZhciBjb250ZXh0ID0gXy5leHRlbmQoe1xuICAgICAgICBldmVudExhYmVsOiBcImFjdGlvblwiLFxuICAgICAgICBlbWl0dGVyOiBuZXcgXy5FdmVudEVtaXR0ZXIoKSxcbiAgICAgICAgX2lzQWN0aW9uOiB0cnVlXG4gICAgfSwgUHVibGlzaGVyTWV0aG9kcywgQWN0aW9uTWV0aG9kcywgZGVmaW5pdGlvbik7XG5cbiAgICB2YXIgZnVuY3RvciA9IGZ1bmN0aW9uIGZ1bmN0b3IoKSB7XG4gICAgICAgIHZhciB0cmlnZ2VyVHlwZSA9IGZ1bmN0b3Iuc3luYyA/IFwidHJpZ2dlclwiIDogXCJ0cmlnZ2VyQXN5bmNcIjtcbiAgICAgICAgcmV0dXJuIGZ1bmN0b3JbdHJpZ2dlclR5cGVdLmFwcGx5KGZ1bmN0b3IsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIF8uZXh0ZW5kKGZ1bmN0b3IsIGNoaWxkQWN0aW9ucywgY29udGV4dCk7XG5cbiAgICBLZWVwLmNyZWF0ZWRBY3Rpb25zLnB1c2goZnVuY3Rvcik7XG5cbiAgICByZXR1cm4gZnVuY3Rvcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQWN0aW9uOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgXyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpLFxuICAgIEtlZXAgPSByZXF1aXJlKFwiLi9LZWVwXCIpLFxuICAgIG1peGVyID0gcmVxdWlyZShcIi4vbWl4ZXJcIiksXG4gICAgYmluZE1ldGhvZHMgPSByZXF1aXJlKFwiLi9iaW5kTWV0aG9kc1wiKTtcblxudmFyIGFsbG93ZWQgPSB7IHByZUVtaXQ6IDEsIHNob3VsZEVtaXQ6IDEgfTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGV2ZW50IGVtaXR0aW5nIERhdGEgU3RvcmUuIEl0IGlzIG1peGVkIGluIHdpdGggZnVuY3Rpb25zXG4gKiBmcm9tIHRoZSBgTGlzdGVuZXJNZXRob2RzYCBhbmQgYFB1Ymxpc2hlck1ldGhvZHNgIG1peGlucy4gYHByZUVtaXRgXG4gKiBhbmQgYHNob3VsZEVtaXRgIG1heSBiZSBvdmVycmlkZGVuIGluIHRoZSBkZWZpbml0aW9uIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGVmaW5pdGlvbiBUaGUgZGF0YSBzdG9yZSBvYmplY3QgZGVmaW5pdGlvblxuICogQHJldHVybnMge1N0b3JlfSBBIGRhdGEgc3RvcmUgaW5zdGFuY2VcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuXG4gICAgdmFyIFN0b3JlTWV0aG9kcyA9IHJlcXVpcmUoXCIuL1N0b3JlTWV0aG9kc1wiKSxcbiAgICAgICAgUHVibGlzaGVyTWV0aG9kcyA9IHJlcXVpcmUoXCIuL1B1Ymxpc2hlck1ldGhvZHNcIiksXG4gICAgICAgIExpc3RlbmVyTWV0aG9kcyA9IHJlcXVpcmUoXCIuL0xpc3RlbmVyTWV0aG9kc1wiKTtcblxuICAgIGRlZmluaXRpb24gPSBkZWZpbml0aW9uIHx8IHt9O1xuXG4gICAgZm9yICh2YXIgYSBpbiBTdG9yZU1ldGhvZHMpIHtcbiAgICAgICAgaWYgKCFhbGxvd2VkW2FdICYmIChQdWJsaXNoZXJNZXRob2RzW2FdIHx8IExpc3RlbmVyTWV0aG9kc1thXSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBvdmVycmlkZSBBUEkgbWV0aG9kIFwiICsgYSArIFwiIGluIFJlZmx1eC5TdG9yZU1ldGhvZHMuIFVzZSBhbm90aGVyIG1ldGhvZCBuYW1lIG9yIG92ZXJyaWRlIGl0IG9uIFJlZmx1eC5QdWJsaXNoZXJNZXRob2RzIC8gUmVmbHV4Lkxpc3RlbmVyTWV0aG9kcyBpbnN0ZWFkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGQgaW4gZGVmaW5pdGlvbikge1xuICAgICAgICBpZiAoIWFsbG93ZWRbZF0gJiYgKFB1Ymxpc2hlck1ldGhvZHNbZF0gfHwgTGlzdGVuZXJNZXRob2RzW2RdKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IG92ZXJyaWRlIEFQSSBtZXRob2QgXCIgKyBkICsgXCIgaW4gc3RvcmUgY3JlYXRpb24uIFVzZSBhbm90aGVyIG1ldGhvZCBuYW1lIG9yIG92ZXJyaWRlIGl0IG9uIFJlZmx1eC5QdWJsaXNoZXJNZXRob2RzIC8gUmVmbHV4Lkxpc3RlbmVyTWV0aG9kcyBpbnN0ZWFkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlZmluaXRpb24gPSBtaXhlcihkZWZpbml0aW9uKTtcblxuICAgIGZ1bmN0aW9uIFN0b3JlKCkge1xuICAgICAgICB2YXIgaSA9IDAsXG4gICAgICAgICAgICBhcnI7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLmVtaXR0ZXIgPSBuZXcgXy5FdmVudEVtaXR0ZXIoKTtcbiAgICAgICAgdGhpcy5ldmVudExhYmVsID0gXCJjaGFuZ2VcIjtcbiAgICAgICAgYmluZE1ldGhvZHModGhpcywgZGVmaW5pdGlvbik7XG4gICAgICAgIGlmICh0aGlzLmluaXQgJiYgXy5pc0Z1bmN0aW9uKHRoaXMuaW5pdCkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmxpc3RlbmFibGVzKSB7XG4gICAgICAgICAgICBhcnIgPSBbXS5jb25jYXQodGhpcy5saXN0ZW5hYmxlcyk7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuVG9NYW55KGFycltpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfLmV4dGVuZChTdG9yZS5wcm90b3R5cGUsIExpc3RlbmVyTWV0aG9kcywgUHVibGlzaGVyTWV0aG9kcywgU3RvcmVNZXRob2RzLCBkZWZpbml0aW9uKTtcblxuICAgIHZhciBzdG9yZSA9IG5ldyBTdG9yZSgpO1xuICAgIEtlZXAuY3JlYXRlZFN0b3Jlcy5wdXNoKHN0b3JlKTtcblxuICAgIHJldHVybiBzdG9yZTtcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcbnZhciBSZWZsdXggPSB7XG4gICAgdmVyc2lvbjoge1xuICAgICAgICBcInJlZmx1eC1jb3JlXCI6IFwiMC4zLjBcIlxuICAgIH1cbn07XG5cblJlZmx1eC5BY3Rpb25NZXRob2RzID0gcmVxdWlyZShcIi4vQWN0aW9uTWV0aG9kc1wiKTtcblxuUmVmbHV4Lkxpc3RlbmVyTWV0aG9kcyA9IHJlcXVpcmUoXCIuL0xpc3RlbmVyTWV0aG9kc1wiKTtcblxuUmVmbHV4LlB1Ymxpc2hlck1ldGhvZHMgPSByZXF1aXJlKFwiLi9QdWJsaXNoZXJNZXRob2RzXCIpO1xuXG5SZWZsdXguU3RvcmVNZXRob2RzID0gcmVxdWlyZShcIi4vU3RvcmVNZXRob2RzXCIpO1xuXG5SZWZsdXguY3JlYXRlQWN0aW9uID0gcmVxdWlyZShcIi4vY3JlYXRlQWN0aW9uXCIpO1xuXG5SZWZsdXguY3JlYXRlU3RvcmUgPSByZXF1aXJlKFwiLi9jcmVhdGVTdG9yZVwiKTtcblxudmFyIG1ha2VyID0gcmVxdWlyZShcIi4vam9pbnNcIikuc3RhdGljSm9pbkNyZWF0b3I7XG5cblJlZmx1eC5qb2luVHJhaWxpbmcgPSBSZWZsdXguYWxsID0gbWFrZXIoXCJsYXN0XCIpOyAvLyBSZWZsdXguYWxsIGFsaWFzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5cblJlZmx1eC5qb2luTGVhZGluZyA9IG1ha2VyKFwiZmlyc3RcIik7XG5cblJlZmx1eC5qb2luU3RyaWN0ID0gbWFrZXIoXCJzdHJpY3RcIik7XG5cblJlZmx1eC5qb2luQ29uY2F0ID0gbWFrZXIoXCJhbGxcIik7XG5cbnZhciBfID0gUmVmbHV4LnV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cblJlZmx1eC5FdmVudEVtaXR0ZXIgPSBfLkV2ZW50RW1pdHRlcjtcblxuUmVmbHV4LlByb21pc2UgPSBfLlByb21pc2U7XG5cbi8qKlxuICogQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGEgc2V0IG9mIGFjdGlvbnNcbiAqXG4gKiBAcGFyYW0gZGVmaW5pdGlvbnMgdGhlIGRlZmluaXRpb25zIGZvciB0aGUgYWN0aW9ucyB0byBiZSBjcmVhdGVkXG4gKiBAcmV0dXJucyBhbiBvYmplY3Qgd2l0aCBhY3Rpb25zIG9mIGNvcnJlc3BvbmRpbmcgYWN0aW9uIG5hbWVzXG4gKi9cblJlZmx1eC5jcmVhdGVBY3Rpb25zID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVkdWNlciA9IGZ1bmN0aW9uIHJlZHVjZXIoZGVmaW5pdGlvbnMsIGFjdGlvbnMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLmZvckVhY2goZnVuY3Rpb24gKGFjdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIHZhciB2YWwgPSBkZWZpbml0aW9uc1thY3Rpb25OYW1lXTtcbiAgICAgICAgICAgIGFjdGlvbnNbYWN0aW9uTmFtZV0gPSBSZWZsdXguY3JlYXRlQWN0aW9uKHZhbCk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGRlZmluaXRpb25zKSB7XG4gICAgICAgIHZhciBhY3Rpb25zID0ge307XG4gICAgICAgIGlmIChkZWZpbml0aW9ucyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgICBkZWZpbml0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoXy5pc09iamVjdCh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlZHVjZXIodmFsLCBhY3Rpb25zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zW3ZhbF0gPSBSZWZsdXguY3JlYXRlQWN0aW9uKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWR1Y2VyKGRlZmluaXRpb25zLCBhY3Rpb25zKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWN0aW9ucztcbiAgICB9O1xufSkoKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBldmVudG1pdHRlciB0aGF0IFJlZmx1eCB1c2VzXG4gKi9cblJlZmx1eC5zZXRFdmVudEVtaXR0ZXIgPSBmdW5jdGlvbiAoY3R4KSB7XG4gICAgUmVmbHV4LkV2ZW50RW1pdHRlciA9IF8uRXZlbnRFbWl0dGVyID0gY3R4O1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBtZXRob2QgdXNlZCBmb3IgZGVmZXJyaW5nIGFjdGlvbnMgYW5kIHN0b3Jlc1xuICovXG5SZWZsdXgubmV4dFRpY2sgPSBmdW5jdGlvbiAobmV4dFRpY2spIHtcbiAgICBfLm5leHRUaWNrID0gbmV4dFRpY2s7XG59O1xuXG5SZWZsdXgudXNlID0gZnVuY3Rpb24gKHBsdWdpbkNiKSB7XG4gICAgcGx1Z2luQ2IoUmVmbHV4KTtcbn07XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHNldCBvZiBjcmVhdGVkIGFjdGlvbnMgYW5kIHN0b3JlcyBmb3IgaW50cm9zcGVjdGlvblxuICovXG4vKmVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlKi9cblJlZmx1eC5fX2tlZXAgPSByZXF1aXJlKFwiLi9LZWVwXCIpO1xuLyplc2xpbnQtZW5hYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlKi9cblxuLyoqXG4gKiBXYXJuIGlmIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIG5vdCBhdmFpbGFibGVcbiAqL1xuaWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBub3QgYXZhaWxhYmxlLiBcIiArIFwiRVM1IHNoaW0gcmVxdWlyZWQuIFwiICsgXCJodHRwczovL2dpdGh1Yi5jb20vc3BvaWtlL3JlZmx1eGpzI2VzNVwiKTtcbn1cblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBSZWZsdXg7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIi8qKlxuICogSW50ZXJuYWwgbW9kdWxlIHVzZWQgdG8gY3JlYXRlIHN0YXRpYyBhbmQgaW5zdGFuY2Ugam9pbiBtZXRob2RzXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBjcmVhdGVTdG9yZSA9IHJlcXVpcmUoXCIuL2NyZWF0ZVN0b3JlXCIpLFxuICAgIF8gPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLFxuICAgIHN0cmF0ZWd5TWV0aG9kTmFtZXMgPSB7XG4gICAgc3RyaWN0OiBcImpvaW5TdHJpY3RcIixcbiAgICBmaXJzdDogXCJqb2luTGVhZGluZ1wiLFxuICAgIGxhc3Q6IFwiam9pblRyYWlsaW5nXCIsXG4gICAgYWxsOiBcImpvaW5Db25jYXRcIlxufTtcblxuLyoqXG4gKiBVc2VkIGluIGBpbmRleC5qc2AgdG8gY3JlYXRlIHRoZSBzdGF0aWMgam9pbiBtZXRob2RzXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyYXRlZ3kgV2hpY2ggc3RyYXRlZ3kgdG8gdXNlIHdoZW4gdHJhY2tpbmcgbGlzdGVuYWJsZSB0cmlnZ2VyIGFyZ3VtZW50c1xuICogQHJldHVybnMge0Z1bmN0aW9ufSBBIHN0YXRpYyBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGEgc3RvcmUgd2l0aCBhIGpvaW4gbGlzdGVuIG9uIHRoZSBnaXZlbiBsaXN0ZW5hYmxlcyB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3lcbiAqL1xuZXhwb3J0cy5zdGF0aWNKb2luQ3JlYXRvciA9IGZ1bmN0aW9uIChzdHJhdGVneSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSAvKiBsaXN0ZW5hYmxlcy4uLiAqL3tcbiAgICAgICAgdmFyIGxpc3RlbmFibGVzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gY3JlYXRlU3RvcmUoe1xuICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgICAgICAgICAgICB0aGlzW3N0cmF0ZWd5TWV0aG9kTmFtZXNbc3RyYXRlZ3ldXS5hcHBseSh0aGlzLCBsaXN0ZW5hYmxlcy5jb25jYXQoXCJ0cmlnZ2VyQXN5bmNcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBVc2VkIGluIGBMaXN0ZW5lck1ldGhvZHMuanNgIHRvIGNyZWF0ZSB0aGUgaW5zdGFuY2Ugam9pbiBtZXRob2RzXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyYXRlZ3kgV2hpY2ggc3RyYXRlZ3kgdG8gdXNlIHdoZW4gdHJhY2tpbmcgbGlzdGVuYWJsZSB0cmlnZ2VyIGFyZ3VtZW50c1xuICogQHJldHVybnMge0Z1bmN0aW9ufSBBbiBpbnN0YW5jZSBtZXRob2Qgd2hpY2ggc2V0cyB1cCBhIGpvaW4gbGlzdGVuIG9uIHRoZSBnaXZlbiBsaXN0ZW5hYmxlcyB1c2luZyB0aGUgZ2l2ZW4gc3RyYXRlZ3lcbiAqL1xuZXhwb3J0cy5pbnN0YW5jZUpvaW5DcmVhdG9yID0gZnVuY3Rpb24gKHN0cmF0ZWd5KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIC8qIGxpc3RlbmFibGVzLi4uLCBjYWxsYmFjayove1xuICAgICAgICBfLnRocm93SWYoYXJndW1lbnRzLmxlbmd0aCA8IDIsIFwiQ2Fubm90IGNyZWF0ZSBhIGpvaW4gd2l0aCBsZXNzIHRoYW4gMiBsaXN0ZW5hYmxlcyFcIik7XG4gICAgICAgIHZhciBsaXN0ZW5hYmxlcyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzKSxcbiAgICAgICAgICAgIGNhbGxiYWNrID0gbGlzdGVuYWJsZXMucG9wKCksXG4gICAgICAgICAgICBudW1iZXJPZkxpc3RlbmFibGVzID0gbGlzdGVuYWJsZXMubGVuZ3RoLFxuICAgICAgICAgICAgam9pbiA9IHtcbiAgICAgICAgICAgIG51bWJlck9mTGlzdGVuYWJsZXM6IG51bWJlck9mTGlzdGVuYWJsZXMsXG4gICAgICAgICAgICBjYWxsYmFjazogdGhpc1tjYWxsYmFja10gfHwgY2FsbGJhY2ssXG4gICAgICAgICAgICBsaXN0ZW5lcjogdGhpcyxcbiAgICAgICAgICAgIHN0cmF0ZWd5OiBzdHJhdGVneVxuICAgICAgICB9LFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGNhbmNlbHMgPSBbXSxcbiAgICAgICAgICAgIHN1Ym9iajtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWJlck9mTGlzdGVuYWJsZXM7IGkrKykge1xuICAgICAgICAgICAgXy50aHJvd0lmKHRoaXMudmFsaWRhdGVMaXN0ZW5pbmcobGlzdGVuYWJsZXNbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtYmVyT2ZMaXN0ZW5hYmxlczsgaSsrKSB7XG4gICAgICAgICAgICBjYW5jZWxzLnB1c2gobGlzdGVuYWJsZXNbaV0ubGlzdGVuKG5ld0xpc3RlbmVyKGksIGpvaW4pLCB0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzZXQoam9pbik7XG4gICAgICAgIHN1Ym9iaiA9IHsgbGlzdGVuYWJsZTogbGlzdGVuYWJsZXMgfTtcbiAgICAgICAgc3Vib2JqLnN0b3AgPSBtYWtlU3RvcHBlcihzdWJvYmosIGNhbmNlbHMsIHRoaXMpO1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSAodGhpcy5zdWJzY3JpcHRpb25zIHx8IFtdKS5jb25jYXQoc3Vib2JqKTtcbiAgICAgICAgcmV0dXJuIHN1Ym9iajtcbiAgICB9O1xufTtcblxuLy8gLS0tLSBpbnRlcm5hbCBqb2luIGZ1bmN0aW9ucyAtLS0tXG5cbmZ1bmN0aW9uIG1ha2VTdG9wcGVyKHN1Ym9iaiwgY2FuY2VscywgY29udGV4dCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpLFxuICAgICAgICAgICAgc3VicyA9IGNvbnRleHQuc3Vic2NyaXB0aW9ucyxcbiAgICAgICAgICAgIGluZGV4ID0gc3VicyA/IHN1YnMuaW5kZXhPZihzdWJvYmopIDogLTE7XG4gICAgICAgIF8udGhyb3dJZihpbmRleCA9PT0gLTEsIFwiVHJpZWQgdG8gcmVtb3ZlIGpvaW4gYWxyZWFkeSBnb25lIGZyb20gc3Vic2NyaXB0aW9ucyBsaXN0IVwiKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNhbmNlbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNhbmNlbHNbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBzdWJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gcmVzZXQoam9pbikge1xuICAgIGpvaW4ubGlzdGVuYWJsZXNFbWl0dGVkID0gbmV3IEFycmF5KGpvaW4ubnVtYmVyT2ZMaXN0ZW5hYmxlcyk7XG4gICAgam9pbi5hcmdzID0gbmV3IEFycmF5KGpvaW4ubnVtYmVyT2ZMaXN0ZW5hYmxlcyk7XG59XG5cbmZ1bmN0aW9uIG5ld0xpc3RlbmVyKGksIGpvaW4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY2FsbGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgIGlmIChqb2luLmxpc3RlbmFibGVzRW1pdHRlZFtpXSkge1xuICAgICAgICAgICAgc3dpdGNoIChqb2luLnN0cmF0ZWd5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0cmljdFwiOlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdHJpY3Qgam9pbiBmYWlsZWQgYmVjYXVzZSBsaXN0ZW5lciB0cmlnZ2VyZWQgdHdpY2UuXCIpO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJsYXN0XCI6XG4gICAgICAgICAgICAgICAgICAgIGpvaW4uYXJnc1tpXSA9IGNhbGxhcmdzO2JyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJhbGxcIjpcbiAgICAgICAgICAgICAgICAgICAgam9pbi5hcmdzW2ldLnB1c2goY2FsbGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgam9pbi5saXN0ZW5hYmxlc0VtaXR0ZWRbaV0gPSB0cnVlO1xuICAgICAgICAgICAgam9pbi5hcmdzW2ldID0gam9pbi5zdHJhdGVneSA9PT0gXCJhbGxcIiA/IFtjYWxsYXJnc10gOiBjYWxsYXJncztcbiAgICAgICAgfVxuICAgICAgICBlbWl0SWZBbGxMaXN0ZW5hYmxlc0VtaXR0ZWQoam9pbik7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZW1pdElmQWxsTGlzdGVuYWJsZXNFbWl0dGVkKGpvaW4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGpvaW4ubnVtYmVyT2ZMaXN0ZW5hYmxlczsgaSsrKSB7XG4gICAgICAgIGlmICgham9pbi5saXN0ZW5hYmxlc0VtaXR0ZWRbaV0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBqb2luLmNhbGxiYWNrLmFwcGx5KGpvaW4ubGlzdGVuZXIsIGpvaW4uYXJncyk7XG4gICAgcmVzZXQoam9pbik7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWl4KGRlZikge1xuICAgIHZhciBjb21wb3NlZCA9IHtcbiAgICAgICAgaW5pdDogW10sXG4gICAgICAgIHByZUVtaXQ6IFtdLFxuICAgICAgICBzaG91bGRFbWl0OiBbXVxuICAgIH07XG5cbiAgICB2YXIgdXBkYXRlZCA9IChmdW5jdGlvbiBtaXhEZWYobWl4aW4pIHtcbiAgICAgICAgdmFyIG1peGVkID0ge307XG4gICAgICAgIGlmIChtaXhpbi5taXhpbnMpIHtcbiAgICAgICAgICAgIG1peGluLm1peGlucy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJNaXhpbikge1xuICAgICAgICAgICAgICAgIF8uZXh0ZW5kKG1peGVkLCBtaXhEZWYoc3ViTWl4aW4pKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIF8uZXh0ZW5kKG1peGVkLCBtaXhpbik7XG4gICAgICAgIE9iamVjdC5rZXlzKGNvbXBvc2VkKS5mb3JFYWNoKGZ1bmN0aW9uIChjb21wb3NhYmxlKSB7XG4gICAgICAgICAgICBpZiAobWl4aW4uaGFzT3duUHJvcGVydHkoY29tcG9zYWJsZSkpIHtcbiAgICAgICAgICAgICAgICBjb21wb3NlZFtjb21wb3NhYmxlXS5wdXNoKG1peGluW2NvbXBvc2FibGVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtaXhlZDtcbiAgICB9KShkZWYpO1xuXG4gICAgaWYgKGNvbXBvc2VkLmluaXQubGVuZ3RoID4gMSkge1xuICAgICAgICB1cGRhdGVkLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIGNvbXBvc2VkLmluaXQuZm9yRWFjaChmdW5jdGlvbiAoaW5pdCkge1xuICAgICAgICAgICAgICAgIGluaXQuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGNvbXBvc2VkLnByZUVtaXQubGVuZ3RoID4gMSkge1xuICAgICAgICB1cGRhdGVkLnByZUVtaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gY29tcG9zZWQucHJlRW1pdC5yZWR1Y2UoKGZ1bmN0aW9uIChhcmdzLCBwcmVFbWl0KSB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld1ZhbHVlID0gcHJlRW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3VmFsdWUgPT09IHVuZGVmaW5lZCA/IGFyZ3MgOiBbbmV3VmFsdWVdO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGNvbXBvc2VkLnNob3VsZEVtaXQubGVuZ3RoID4gMSkge1xuICAgICAgICB1cGRhdGVkLnNob3VsZEVtaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIHJldHVybiAhY29tcG9zZWQuc2hvdWxkRW1pdC5zb21lKGZ1bmN0aW9uIChzaG91bGRFbWl0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICFzaG91bGRFbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIE9iamVjdC5rZXlzKGNvbXBvc2VkKS5mb3JFYWNoKGZ1bmN0aW9uIChjb21wb3NhYmxlKSB7XG4gICAgICAgIGlmIChjb21wb3NlZFtjb21wb3NhYmxlXS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHVwZGF0ZWRbY29tcG9zYWJsZV0gPSBjb21wb3NlZFtjb21wb3NhYmxlXVswXTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHVwZGF0ZWQ7XG59OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNhcGl0YWxpemUgPSBjYXBpdGFsaXplO1xuZXhwb3J0cy5jYWxsYmFja05hbWUgPSBjYWxsYmFja05hbWU7XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5leHBvcnRzLmV4dGVuZCA9IGV4dGVuZDtcbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5leHBvcnRzLm9iamVjdCA9IG9iamVjdDtcbmV4cG9ydHMuaXNBcmd1bWVudHMgPSBpc0FyZ3VtZW50cztcbmV4cG9ydHMudGhyb3dJZiA9IHRocm93SWY7XG5cbmZ1bmN0aW9uIGNhcGl0YWxpemUoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0cmluZy5zbGljZSgxKTtcbn1cblxuZnVuY3Rpb24gY2FsbGJhY2tOYW1lKHN0cmluZywgcHJlZml4KSB7XG4gICAgcHJlZml4ID0gcHJlZml4IHx8IFwib25cIjtcbiAgICByZXR1cm4gcHJlZml4ICsgZXhwb3J0cy5jYXBpdGFsaXplKHN0cmluZyk7XG59XG5cbi8qXG4gKiBpc09iamVjdCwgZXh0ZW5kLCBpc0Z1bmN0aW9uLCBpc0FyZ3VtZW50cyBhcmUgdGFrZW4gZnJvbSB1bmRlc2NvcmUvbG9kYXNoIGluXG4gKiBvcmRlciB0byByZW1vdmUgdGhlIGRlcGVuZGVuY3lcbiAqL1xuXG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgICB2YXIgdHlwZSA9IHR5cGVvZiBvYmo7XG4gICAgcmV0dXJuIHR5cGUgPT09IFwiZnVuY3Rpb25cIiB8fCB0eXBlID09PSBcIm9iamVjdFwiICYmICEhb2JqO1xufVxuXG5mdW5jdGlvbiBleHRlbmQob2JqKSB7XG4gICAgaWYgKCFpc09iamVjdChvYmopKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIHZhciBzb3VyY2UsIHByb3A7XG4gICAgZm9yICh2YXIgaSA9IDEsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG4gICAgICAgIGZvciAocHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwgcHJvcCk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgcHJvcCwgcHJvcGVydHlEZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb2JqW3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmV4cG9ydHMuRXZlbnRFbWl0dGVyID0gcmVxdWlyZShcImV2ZW50ZW1pdHRlcjNcIik7XG5cbmV4cG9ydHMubmV4dFRpY2sgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCAwKTtcbn07XG5cbmZ1bmN0aW9uIG9iamVjdChrZXlzLCB2YWxzKSB7XG4gICAgdmFyIG8gPSB7fSxcbiAgICAgICAgaSA9IDA7XG4gICAgZm9yICg7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG9ba2V5c1tpXV0gPSB2YWxzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gbztcbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIFwiY2FsbGVlXCIgaW4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gXCJudW1iZXJcIjtcbn1cblxuZnVuY3Rpb24gdGhyb3dJZih2YWwsIG1zZykge1xuICAgIGlmICh2YWwpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IobXNnIHx8IHZhbCk7XG4gICAgfVxufSIsInZhciBfID0gcmVxdWlyZSgncmVmbHV4LWNvcmUvbGliL3V0aWxzJyksXG4gICAgTGlzdGVuZXJNZXRob2RzID0gcmVxdWlyZSgncmVmbHV4LWNvcmUvbGliL0xpc3RlbmVyTWV0aG9kcycpO1xuXG4vKipcbiAqIEEgbW9kdWxlIG1lYW50IHRvIGJlIGNvbnN1bWVkIGFzIGEgbWl4aW4gYnkgYSBSZWFjdCBjb21wb25lbnQuIFN1cHBsaWVzIHRoZSBtZXRob2RzIGZyb21cbiAqIGBMaXN0ZW5lck1ldGhvZHNgIG1peGluIGFuZCB0YWtlcyBjYXJlIG9mIHRlYXJkb3duIG9mIHN1YnNjcmlwdGlvbnMuXG4gKiBOb3RlIHRoYXQgaWYgeW91J3JlIHVzaW5nIHRoZSBgY29ubmVjdGAgbWl4aW4geW91IGRvbid0IG5lZWQgdGhpcyBtaXhpbiwgYXMgY29ubmVjdCB3aWxsXG4gKiBpbXBvcnQgZXZlcnl0aGluZyB0aGlzIG1peGluIGNvbnRhaW5zIVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IF8uZXh0ZW5kKHtcblxuICAgIC8qKlxuICAgICAqIENsZWFucyB1cCBhbGwgbGlzdGVuZXIgcHJldmlvdXNseSByZWdpc3RlcmVkLlxuICAgICAqL1xuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBMaXN0ZW5lck1ldGhvZHMuc3RvcExpc3RlbmluZ1RvQWxsXG5cbn0sIExpc3RlbmVyTWV0aG9kcyk7XG4iLCJ2YXIgTGlzdGVuZXJNZXRob2RzID0gcmVxdWlyZSgncmVmbHV4LWNvcmUvbGliL0xpc3RlbmVyTWV0aG9kcycpLFxuICAgIExpc3RlbmVyTWl4aW4gPSByZXF1aXJlKCcuL0xpc3RlbmVyTWl4aW4nKSxcbiAgICBfID0gcmVxdWlyZSgncmVmbHV4LWNvcmUvbGliL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obGlzdGVuYWJsZSxrZXkpe1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIGlmICghXy5pc0Z1bmN0aW9uKGxpc3RlbmFibGUuZ2V0SW5pdGlhbFN0YXRlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGlzdGVuYWJsZS5nZXRJbml0aWFsU3RhdGUoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF8ub2JqZWN0KFtrZXldLFtsaXN0ZW5hYmxlLmdldEluaXRpYWxTdGF0ZSgpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgXy5leHRlbmQodGhpcyxMaXN0ZW5lck1ldGhvZHMpO1xuICAgICAgICAgICAgdmFyIG1lID0gdGhpcywgY2IgPSAoa2V5ID09PSB1bmRlZmluZWQgPyB0aGlzLnNldFN0YXRlIDogZnVuY3Rpb24odil7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZS5pc01vdW50ZWQgPT09IFwidW5kZWZpbmVkXCIgfHwgbWUuaXNNb3VudGVkKCkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgbWUuc2V0U3RhdGUoXy5vYmplY3QoW2tleV0sW3ZdKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmxpc3RlblRvKGxpc3RlbmFibGUsY2IpO1xuICAgICAgICB9LFxuICAgICAgICBjb21wb25lbnRXaWxsVW5tb3VudDogTGlzdGVuZXJNaXhpbi5jb21wb25lbnRXaWxsVW5tb3VudFxuICAgIH07XG59O1xuIiwidmFyIExpc3RlbmVyTWV0aG9kcyA9IHJlcXVpcmUoJ3JlZmx1eC1jb3JlL2xpYi9MaXN0ZW5lck1ldGhvZHMnKSxcbiAgICBMaXN0ZW5lck1peGluID0gcmVxdWlyZSgnLi9MaXN0ZW5lck1peGluJyksXG4gICAgXyA9IHJlcXVpcmUoJ3JlZmx1eC1jb3JlL2xpYi91dGlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGxpc3RlbmFibGUsIGtleSwgZmlsdGVyRnVuYykge1xuICAgIGZpbHRlckZ1bmMgPSBfLmlzRnVuY3Rpb24oa2V5KSA/IGtleSA6IGZpbHRlckZ1bmM7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmICghXy5pc0Z1bmN0aW9uKGxpc3RlbmFibGUuZ2V0SW5pdGlhbFN0YXRlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXy5pc0Z1bmN0aW9uKGtleSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyRnVuYy5jYWxsKHRoaXMsIGxpc3RlbmFibGUuZ2V0SW5pdGlhbFN0YXRlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBGaWx0ZXIgaW5pdGlhbCBwYXlsb2FkIGZyb20gc3RvcmUuXG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZpbHRlckZ1bmMuY2FsbCh0aGlzLCBsaXN0ZW5hYmxlLmdldEluaXRpYWxTdGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mKHJlc3VsdCkgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF8ub2JqZWN0KFtrZXldLCBbcmVzdWx0XSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgXy5leHRlbmQodGhpcywgTGlzdGVuZXJNZXRob2RzKTtcbiAgICAgICAgICAgIHZhciBtZSA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgY2IgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChfLmlzRnVuY3Rpb24oa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBtZS5zZXRTdGF0ZShmaWx0ZXJGdW5jLmNhbGwobWUsIHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZpbHRlckZ1bmMuY2FsbChtZSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBtZS5zZXRTdGF0ZShfLm9iamVjdChba2V5XSwgW3Jlc3VsdF0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLmxpc3RlblRvKGxpc3RlbmFibGUsIGNiKTtcbiAgICAgICAgfSxcbiAgICAgICAgY29tcG9uZW50V2lsbFVubW91bnQ6IExpc3RlbmVyTWl4aW4uY29tcG9uZW50V2lsbFVubW91bnRcbiAgICB9O1xufTtcblxuIiwidmFyIFJlZmx1eCA9IHJlcXVpcmUoJ3JlZmx1eC1jb3JlJyk7XG5cblJlZmx1eC5jb25uZWN0ID0gcmVxdWlyZSgnLi9jb25uZWN0Jyk7XG5cblJlZmx1eC5jb25uZWN0RmlsdGVyID0gcmVxdWlyZSgnLi9jb25uZWN0RmlsdGVyJyk7XG5cblJlZmx1eC5MaXN0ZW5lck1peGluID0gcmVxdWlyZSgnLi9MaXN0ZW5lck1peGluJyk7XG5cblJlZmx1eC5saXN0ZW5UbyA9IHJlcXVpcmUoJy4vbGlzdGVuVG8nKTtcblxuUmVmbHV4Lmxpc3RlblRvTWFueSA9IHJlcXVpcmUoJy4vbGlzdGVuVG9NYW55Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVmbHV4O1xuIiwidmFyIExpc3RlbmVyTWV0aG9kcyA9IHJlcXVpcmUoJ3JlZmx1eC1jb3JlL2xpYi9MaXN0ZW5lck1ldGhvZHMnKTtcblxuLyoqXG4gKiBBIG1peGluIGZhY3RvcnkgZm9yIGEgUmVhY3QgY29tcG9uZW50LiBNZWFudCBhcyBhIG1vcmUgY29udmVuaWVudCB3YXkgb2YgdXNpbmcgdGhlIGBMaXN0ZW5lck1peGluYCxcbiAqIHdpdGhvdXQgaGF2aW5nIHRvIG1hbnVhbGx5IHNldCBsaXN0ZW5lcnMgaW4gdGhlIGBjb21wb25lbnREaWRNb3VudGAgbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7QWN0aW9ufFN0b3JlfSBsaXN0ZW5hYmxlIEFuIEFjdGlvbiBvciBTdG9yZSB0aGF0IHNob3VsZCBiZVxuICogIGxpc3RlbmVkIHRvLlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byByZWdpc3RlciBhcyBldmVudCBoYW5kbGVyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZGVmYXVsdENhbGxiYWNrIFRoZSBjYWxsYmFjayB0byByZWdpc3RlciBhcyBkZWZhdWx0IGhhbmRsZXJcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCB0byBiZSB1c2VkIGFzIGEgbWl4aW4sIHdoaWNoIHNldHMgdXAgdGhlIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gbGlzdGVuYWJsZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihsaXN0ZW5hYmxlLGNhbGxiYWNrLGluaXRpYWwpe1xuICAgIHJldHVybiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXQgdXAgdGhlIG1peGluIGJlZm9yZSB0aGUgaW5pdGlhbCByZW5kZXJpbmcgb2NjdXJzLiBJbXBvcnQgbWV0aG9kcyBmcm9tIGBMaXN0ZW5lck1ldGhvZHNgXG4gICAgICAgICAqIGFuZCB0aGVuIG1ha2UgdGhlIGNhbGwgdG8gYGxpc3RlblRvYCB3aXRoIHRoZSBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGZhY3RvcnkgZnVuY3Rpb25cbiAgICAgICAgICovXG4gICAgICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGZvcih2YXIgbSBpbiBMaXN0ZW5lck1ldGhvZHMpe1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW21dICE9PSBMaXN0ZW5lck1ldGhvZHNbbV0pe1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1ttXSl7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBcIkNhbid0IGhhdmUgb3RoZXIgcHJvcGVydHkgJ1wiK20rXCInIHdoZW4gdXNpbmcgUmVmbHV4Lmxpc3RlblRvIVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbbV0gPSBMaXN0ZW5lck1ldGhvZHNbbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5saXN0ZW5UbyhsaXN0ZW5hYmxlLGNhbGxiYWNrLGluaXRpYWwpO1xuICAgICAgICB9LFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2xlYW5zIHVwIGFsbCBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQuXG4gICAgICAgICAqL1xuICAgICAgICBjb21wb25lbnRXaWxsVW5tb3VudDogTGlzdGVuZXJNZXRob2RzLnN0b3BMaXN0ZW5pbmdUb0FsbFxuICAgIH07XG59O1xuIiwidmFyIExpc3RlbmVyTWV0aG9kcyA9IHJlcXVpcmUoJ3JlZmx1eC1jb3JlL2xpYi9MaXN0ZW5lck1ldGhvZHMnKTtcblxuLyoqXG4gKiBBIG1peGluIGZhY3RvcnkgZm9yIGEgUmVhY3QgY29tcG9uZW50LiBNZWFudCBhcyBhIG1vcmUgY29udmVuaWVudCB3YXkgb2YgdXNpbmcgdGhlIGBsaXN0ZW5lck1peGluYCxcbiAqIHdpdGhvdXQgaGF2aW5nIHRvIG1hbnVhbGx5IHNldCBsaXN0ZW5lcnMgaW4gdGhlIGBjb21wb25lbnREaWRNb3VudGAgbWV0aG9kLiBUaGlzIHZlcnNpb24gaXMgdXNlZFxuICogdG8gYXV0b21hdGljYWxseSBzZXQgdXAgYSBgbGlzdGVuVG9NYW55YCBjYWxsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaXN0ZW5hYmxlcyBBbiBvYmplY3Qgb2YgbGlzdGVuYWJsZXNcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCB0byBiZSB1c2VkIGFzIGEgbWl4aW4sIHdoaWNoIHNldHMgdXAgdGhlIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGxpc3RlbmFibGVzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGxpc3RlbmFibGVzKXtcbiAgICByZXR1cm4ge1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0IHVwIHRoZSBtaXhpbiBiZWZvcmUgdGhlIGluaXRpYWwgcmVuZGVyaW5nIG9jY3Vycy4gSW1wb3J0IG1ldGhvZHMgZnJvbSBgTGlzdGVuZXJNZXRob2RzYFxuICAgICAgICAgKiBhbmQgdGhlbiBtYWtlIHRoZSBjYWxsIHRvIGBsaXN0ZW5Ub2Agd2l0aCB0aGUgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBmYWN0b3J5IGZ1bmN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmb3IodmFyIG0gaW4gTGlzdGVuZXJNZXRob2RzKXtcbiAgICAgICAgICAgICAgICBpZiAodGhpc1ttXSAhPT0gTGlzdGVuZXJNZXRob2RzW21dKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbbV0pe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJDYW4ndCBoYXZlIG90aGVyIHByb3BlcnR5ICdcIittK1wiJyB3aGVuIHVzaW5nIFJlZmx1eC5saXN0ZW5Ub01hbnkhXCI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpc1ttXSA9IExpc3RlbmVyTWV0aG9kc1ttXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxpc3RlblRvTWFueShsaXN0ZW5hYmxlcyk7XG4gICAgICAgIH0sXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDbGVhbnMgdXAgYWxsIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZC5cbiAgICAgICAgICovXG4gICAgICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBMaXN0ZW5lck1ldGhvZHMuc3RvcExpc3RlbmluZ1RvQWxsXG4gICAgfTtcbn07XG4iLCIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNCwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBodHRwczovL3Jhdy5naXRodWIuY29tL2ZhY2Vib29rL3JlZ2VuZXJhdG9yL21hc3Rlci9MSUNFTlNFIGZpbGUuIEFuXG4gKiBhZGRpdGlvbmFsIGdyYW50IG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW5cbiAqIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4hKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgT3AgPSBPYmplY3QucHJvdG90eXBlO1xuICB2YXIgaGFzT3duID0gT3AuaGFzT3duUHJvcGVydHk7XG4gIHZhciB1bmRlZmluZWQ7IC8vIE1vcmUgY29tcHJlc3NpYmxlIHRoYW4gdm9pZCAwLlxuICB2YXIgJFN5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiA/IFN5bWJvbCA6IHt9O1xuICB2YXIgaXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLml0ZXJhdG9yIHx8IFwiQEBpdGVyYXRvclwiO1xuICB2YXIgYXN5bmNJdGVyYXRvclN5bWJvbCA9ICRTeW1ib2wuYXN5bmNJdGVyYXRvciB8fCBcIkBAYXN5bmNJdGVyYXRvclwiO1xuICB2YXIgdG9TdHJpbmdUYWdTeW1ib2wgPSAkU3ltYm9sLnRvU3RyaW5nVGFnIHx8IFwiQEB0b1N0cmluZ1RhZ1wiO1xuXG4gIHZhciBpbk1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCI7XG4gIHZhciBydW50aW1lID0gZ2xvYmFsLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgaWYgKHJ1bnRpbWUpIHtcbiAgICBpZiAoaW5Nb2R1bGUpIHtcbiAgICAgIC8vIElmIHJlZ2VuZXJhdG9yUnVudGltZSBpcyBkZWZpbmVkIGdsb2JhbGx5IGFuZCB3ZSdyZSBpbiBhIG1vZHVsZSxcbiAgICAgIC8vIG1ha2UgdGhlIGV4cG9ydHMgb2JqZWN0IGlkZW50aWNhbCB0byByZWdlbmVyYXRvclJ1bnRpbWUuXG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IHJ1bnRpbWU7XG4gICAgfVxuICAgIC8vIERvbid0IGJvdGhlciBldmFsdWF0aW5nIHRoZSByZXN0IG9mIHRoaXMgZmlsZSBpZiB0aGUgcnVudGltZSB3YXNcbiAgICAvLyBhbHJlYWR5IGRlZmluZWQgZ2xvYmFsbHkuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRGVmaW5lIHRoZSBydW50aW1lIGdsb2JhbGx5IChhcyBleHBlY3RlZCBieSBnZW5lcmF0ZWQgY29kZSkgYXMgZWl0aGVyXG4gIC8vIG1vZHVsZS5leHBvcnRzIChpZiB3ZSdyZSBpbiBhIG1vZHVsZSkgb3IgYSBuZXcsIGVtcHR5IG9iamVjdC5cbiAgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWUgPSBpbk1vZHVsZSA/IG1vZHVsZS5leHBvcnRzIDoge307XG5cbiAgZnVuY3Rpb24gd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIC8vIElmIG91dGVyRm4gcHJvdmlkZWQgYW5kIG91dGVyRm4ucHJvdG90eXBlIGlzIGEgR2VuZXJhdG9yLCB0aGVuIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yLlxuICAgIHZhciBwcm90b0dlbmVyYXRvciA9IG91dGVyRm4gJiYgb3V0ZXJGbi5wcm90b3R5cGUgaW5zdGFuY2VvZiBHZW5lcmF0b3IgPyBvdXRlckZuIDogR2VuZXJhdG9yO1xuICAgIHZhciBnZW5lcmF0b3IgPSBPYmplY3QuY3JlYXRlKHByb3RvR2VuZXJhdG9yLnByb3RvdHlwZSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCh0cnlMb2NzTGlzdCB8fCBbXSk7XG5cbiAgICAvLyBUaGUgLl9pbnZva2UgbWV0aG9kIHVuaWZpZXMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzLlxuICAgIGdlbmVyYXRvci5faW52b2tlID0gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH1cbiAgcnVudGltZS53cmFwID0gd3JhcDtcblxuICAvLyBUcnkvY2F0Y2ggaGVscGVyIHRvIG1pbmltaXplIGRlb3B0aW1pemF0aW9ucy4gUmV0dXJucyBhIGNvbXBsZXRpb25cbiAgLy8gcmVjb3JkIGxpa2UgY29udGV4dC50cnlFbnRyaWVzW2ldLmNvbXBsZXRpb24uIFRoaXMgaW50ZXJmYWNlIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiAoYW5kIHdhcyBwcmV2aW91c2x5KSBkZXNpZ25lZCB0byB0YWtlIGEgY2xvc3VyZSB0byBiZVxuICAvLyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCBidXQgaW4gYWxsIHRoZSBjYXNlcyB3ZSBjYXJlIGFib3V0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBtZXRob2Qgd2Ugd2FudCB0byBjYWxsLCBzbyB0aGVyZSdzIG5vIG5lZWRcbiAgLy8gdG8gY3JlYXRlIGEgbmV3IGZ1bmN0aW9uIG9iamVjdC4gV2UgY2FuIGV2ZW4gZ2V0IGF3YXkgd2l0aCBhc3N1bWluZ1xuICAvLyB0aGUgbWV0aG9kIHRha2VzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBzaW5jZSB0aGF0IGhhcHBlbnMgdG8gYmUgdHJ1ZVxuICAvLyBpbiBldmVyeSBjYXNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHRvdWNoIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBUaGVcbiAgLy8gb25seSBhZGRpdGlvbmFsIGFsbG9jYXRpb24gcmVxdWlyZWQgaXMgdGhlIGNvbXBsZXRpb24gcmVjb3JkLCB3aGljaFxuICAvLyBoYXMgYSBzdGFibGUgc2hhcGUgYW5kIHNvIGhvcGVmdWxseSBzaG91bGQgYmUgY2hlYXAgdG8gYWxsb2NhdGUuXG4gIGZ1bmN0aW9uIHRyeUNhdGNoKGZuLCBvYmosIGFyZykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcIm5vcm1hbFwiLCBhcmc6IGZuLmNhbGwob2JqLCBhcmcpIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInRocm93XCIsIGFyZzogZXJyIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIEdlblN0YXRlU3VzcGVuZGVkU3RhcnQgPSBcInN1c3BlbmRlZFN0YXJ0XCI7XG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkID0gXCJzdXNwZW5kZWRZaWVsZFwiO1xuICB2YXIgR2VuU3RhdGVFeGVjdXRpbmcgPSBcImV4ZWN1dGluZ1wiO1xuICB2YXIgR2VuU3RhdGVDb21wbGV0ZWQgPSBcImNvbXBsZXRlZFwiO1xuXG4gIC8vIFJldHVybmluZyB0aGlzIG9iamVjdCBmcm9tIHRoZSBpbm5lckZuIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXNcbiAgLy8gYnJlYWtpbmcgb3V0IG9mIHRoZSBkaXNwYXRjaCBzd2l0Y2ggc3RhdGVtZW50LlxuICB2YXIgQ29udGludWVTZW50aW5lbCA9IHt9O1xuXG4gIC8vIER1bW15IGNvbnN0cnVjdG9yIGZ1bmN0aW9ucyB0aGF0IHdlIHVzZSBhcyB0aGUgLmNvbnN0cnVjdG9yIGFuZFxuICAvLyAuY29uc3RydWN0b3IucHJvdG90eXBlIHByb3BlcnRpZXMgZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0cy4gRm9yIGZ1bGwgc3BlYyBjb21wbGlhbmNlLCB5b3UgbWF5IHdpc2ggdG8gY29uZmlndXJlIHlvdXJcbiAgLy8gbWluaWZpZXIgbm90IHRvIG1hbmdsZSB0aGUgbmFtZXMgb2YgdGhlc2UgdHdvIGZ1bmN0aW9ucy5cbiAgZnVuY3Rpb24gR2VuZXJhdG9yKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb24oKSB7fVxuICBmdW5jdGlvbiBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSgpIHt9XG5cbiAgLy8gVGhpcyBpcyBhIHBvbHlmaWxsIGZvciAlSXRlcmF0b3JQcm90b3R5cGUlIGZvciBlbnZpcm9ubWVudHMgdGhhdFxuICAvLyBkb24ndCBuYXRpdmVseSBzdXBwb3J0IGl0LlxuICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcbiAgSXRlcmF0b3JQcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbiAgdmFyIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG8gJiYgZ2V0UHJvdG8oZ2V0UHJvdG8odmFsdWVzKFtdKSkpO1xuICBpZiAoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUgJiZcbiAgICAgIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICE9PSBPcCAmJlxuICAgICAgaGFzT3duLmNhbGwoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUsIGl0ZXJhdG9yU3ltYm9sKSkge1xuICAgIC8vIFRoaXMgZW52aXJvbm1lbnQgaGFzIGEgbmF0aXZlICVJdGVyYXRvclByb3RvdHlwZSU7IHVzZSBpdCBpbnN0ZWFkXG4gICAgLy8gb2YgdGhlIHBvbHlmaWxsLlxuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gTmF0aXZlSXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cblxuICB2YXIgR3AgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZS5wcm90b3R5cGUgPVxuICAgIEdlbmVyYXRvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlKTtcbiAgR2VuZXJhdG9yRnVuY3Rpb24ucHJvdG90eXBlID0gR3AuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvbjtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGVbdG9TdHJpbmdUYWdTeW1ib2xdID1cbiAgICBHZW5lcmF0b3JGdW5jdGlvbi5kaXNwbGF5TmFtZSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcblxuICAvLyBIZWxwZXIgZm9yIGRlZmluaW5nIHRoZSAubmV4dCwgLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzIG9mIHRoZVxuICAvLyBJdGVyYXRvciBpbnRlcmZhY2UgaW4gdGVybXMgb2YgYSBzaW5nbGUgLl9pbnZva2UgbWV0aG9kLlxuICBmdW5jdGlvbiBkZWZpbmVJdGVyYXRvck1ldGhvZHMocHJvdG90eXBlKSB7XG4gICAgW1wibmV4dFwiLCBcInRocm93XCIsIFwicmV0dXJuXCJdLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICBwcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICByZXR1cm4gdGhpcy5faW52b2tlKG1ldGhvZCwgYXJnKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBydW50aW1lLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGlmICghKHRvU3RyaW5nVGFnU3ltYm9sIGluIGdlbkZ1bikpIHtcbiAgICAgICAgZ2VuRnVuW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ2VuRnVuLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoR3ApO1xuICAgIHJldHVybiBnZW5GdW47XG4gIH07XG5cbiAgLy8gV2l0aGluIHRoZSBib2R5IG9mIGFueSBhc3luYyBmdW5jdGlvbiwgYGF3YWl0IHhgIGlzIHRyYW5zZm9ybWVkIHRvXG4gIC8vIGB5aWVsZCByZWdlbmVyYXRvclJ1bnRpbWUuYXdyYXAoeClgLCBzbyB0aGF0IHRoZSBydW50aW1lIGNhbiB0ZXN0XG4gIC8vIGBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpYCB0byBkZXRlcm1pbmUgaWYgdGhlIHlpZWxkZWQgdmFsdWUgaXNcbiAgLy8gbWVhbnQgdG8gYmUgYXdhaXRlZC5cbiAgcnVudGltZS5hd3JhcCA9IGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB7IF9fYXdhaXQ6IGFyZyB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIEFzeW5jSXRlcmF0b3IoZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlLl9fYXdhaXQpLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGludm9rZShcIm5leHRcIiwgdmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJ0aHJvd1wiLCBlcnIsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKGZ1bmN0aW9uKHVud3JhcHBlZCkge1xuICAgICAgICAgIC8vIFdoZW4gYSB5aWVsZGVkIFByb21pc2UgaXMgcmVzb2x2ZWQsIGl0cyBmaW5hbCB2YWx1ZSBiZWNvbWVzXG4gICAgICAgICAgLy8gdGhlIC52YWx1ZSBvZiB0aGUgUHJvbWlzZTx7dmFsdWUsZG9uZX0+IHJlc3VsdCBmb3IgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBpdGVyYXRpb24uIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBob3dldmVyLCB0aGVcbiAgICAgICAgICAvLyByZXN1bHQgZm9yIHRoaXMgaXRlcmF0aW9uIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZVxuICAgICAgICAgIC8vIHJlYXNvbi4gTm90ZSB0aGF0IHJlamVjdGlvbnMgb2YgeWllbGRlZCBQcm9taXNlcyBhcmUgbm90XG4gICAgICAgICAgLy8gdGhyb3duIGJhY2sgaW50byB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uLCBhcyBpcyB0aGUgY2FzZVxuICAgICAgICAgIC8vIHdoZW4gYW4gYXdhaXRlZCBQcm9taXNlIGlzIHJlamVjdGVkLiBUaGlzIGRpZmZlcmVuY2UgaW5cbiAgICAgICAgICAvLyBiZWhhdmlvciBiZXR3ZWVuIHlpZWxkIGFuZCBhd2FpdCBpcyBpbXBvcnRhbnQsIGJlY2F1c2UgaXRcbiAgICAgICAgICAvLyBhbGxvd3MgdGhlIGNvbnN1bWVyIHRvIGRlY2lkZSB3aGF0IHRvIGRvIHdpdGggdGhlIHlpZWxkZWRcbiAgICAgICAgICAvLyByZWplY3Rpb24gKHN3YWxsb3cgaXQgYW5kIGNvbnRpbnVlLCBtYW51YWxseSAudGhyb3cgaXQgYmFja1xuICAgICAgICAgIC8vIGludG8gdGhlIGdlbmVyYXRvciwgYWJhbmRvbiBpdGVyYXRpb24sIHdoYXRldmVyKS4gV2l0aFxuICAgICAgICAgIC8vIGF3YWl0LCBieSBjb250cmFzdCwgdGhlcmUgaXMgbm8gb3Bwb3J0dW5pdHkgdG8gZXhhbWluZSB0aGVcbiAgICAgICAgICAvLyByZWplY3Rpb24gcmVhc29uIG91dHNpZGUgdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgc28gdGhlXG4gICAgICAgICAgLy8gb25seSBvcHRpb24gaXMgdG8gdGhyb3cgaXQgZnJvbSB0aGUgYXdhaXQgZXhwcmVzc2lvbiwgYW5kXG4gICAgICAgICAgLy8gbGV0IHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gaGFuZGxlIHRoZSBleGNlcHRpb24uXG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gdW53cmFwcGVkO1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgIGludm9rZSA9IHByb2Nlc3MuZG9tYWluLmJpbmQoaW52b2tlKTtcbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNQcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gZW5xdWV1ZShtZXRob2QsIGFyZykge1xuICAgICAgZnVuY3Rpb24gY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICBpbnZva2UobWV0aG9kLCBhcmcsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJldmlvdXNQcm9taXNlID1cbiAgICAgICAgLy8gSWYgZW5xdWV1ZSBoYXMgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gd2FpdCB1bnRpbFxuICAgICAgICAvLyBhbGwgcHJldmlvdXMgUHJvbWlzZXMgaGF2ZSBiZWVuIHJlc29sdmVkIGJlZm9yZSBjYWxsaW5nIGludm9rZSxcbiAgICAgICAgLy8gc28gdGhhdCByZXN1bHRzIGFyZSBhbHdheXMgZGVsaXZlcmVkIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBJZlxuICAgICAgICAvLyBlbnF1ZXVlIGhhcyBub3QgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIGl0IGlzIGltcG9ydGFudCB0b1xuICAgICAgICAvLyBjYWxsIGludm9rZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIG9uIGEgY2FsbGJhY2sgdG8gZmlyZSxcbiAgICAgICAgLy8gc28gdGhhdCB0aGUgYXN5bmMgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhcyB0aGUgb3Bwb3J0dW5pdHkgdG8gZG9cbiAgICAgICAgLy8gYW55IG5lY2Vzc2FyeSBzZXR1cCBpbiBhIHByZWRpY3RhYmxlIHdheS4gVGhpcyBwcmVkaWN0YWJpbGl0eVxuICAgICAgICAvLyBpcyB3aHkgdGhlIFByb21pc2UgY29uc3RydWN0b3Igc3luY2hyb25vdXNseSBpbnZva2VzIGl0c1xuICAgICAgICAvLyBleGVjdXRvciBjYWxsYmFjaywgYW5kIHdoeSBhc3luYyBmdW5jdGlvbnMgc3luY2hyb25vdXNseVxuICAgICAgICAvLyBleGVjdXRlIGNvZGUgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdC4gU2luY2Ugd2UgaW1wbGVtZW50IHNpbXBsZVxuICAgICAgICAvLyBhc3luYyBmdW5jdGlvbnMgaW4gdGVybXMgb2YgYXN5bmMgZ2VuZXJhdG9ycywgaXQgaXMgZXNwZWNpYWxseVxuICAgICAgICAvLyBpbXBvcnRhbnQgdG8gZ2V0IHRoaXMgcmlnaHQsIGV2ZW4gdGhvdWdoIGl0IHJlcXVpcmVzIGNhcmUuXG4gICAgICAgIHByZXZpb3VzUHJvbWlzZSA/IHByZXZpb3VzUHJvbWlzZS50aGVuKFxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnLFxuICAgICAgICAgIC8vIEF2b2lkIHByb3BhZ2F0aW5nIGZhaWx1cmVzIHRvIFByb21pc2VzIHJldHVybmVkIGJ5IGxhdGVyXG4gICAgICAgICAgLy8gaW52b2NhdGlvbnMgb2YgdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnXG4gICAgICAgICkgOiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpO1xuICAgIH1cblxuICAgIC8vIERlZmluZSB0aGUgdW5pZmllZCBoZWxwZXIgbWV0aG9kIHRoYXQgaXMgdXNlZCB0byBpbXBsZW1lbnQgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiAoc2VlIGRlZmluZUl0ZXJhdG9yTWV0aG9kcykuXG4gICAgdGhpcy5faW52b2tlID0gZW5xdWV1ZTtcbiAgfVxuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhBc3luY0l0ZXJhdG9yLnByb3RvdHlwZSk7XG4gIEFzeW5jSXRlcmF0b3IucHJvdG90eXBlW2FzeW5jSXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBydW50aW1lLkFzeW5jSXRlcmF0b3IgPSBBc3luY0l0ZXJhdG9yO1xuXG4gIC8vIE5vdGUgdGhhdCBzaW1wbGUgYXN5bmMgZnVuY3Rpb25zIGFyZSBpbXBsZW1lbnRlZCBvbiB0b3Agb2ZcbiAgLy8gQXN5bmNJdGVyYXRvciBvYmplY3RzOyB0aGV5IGp1c3QgcmV0dXJuIGEgUHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9mXG4gIC8vIHRoZSBmaW5hbCByZXN1bHQgcHJvZHVjZWQgYnkgdGhlIGl0ZXJhdG9yLlxuICBydW50aW1lLmFzeW5jID0gZnVuY3Rpb24oaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICB2YXIgaXRlciA9IG5ldyBBc3luY0l0ZXJhdG9yKFxuICAgICAgd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdClcbiAgICApO1xuXG4gICAgcmV0dXJuIHJ1bnRpbWUuaXNHZW5lcmF0b3JGdW5jdGlvbihvdXRlckZuKVxuICAgICAgPyBpdGVyIC8vIElmIG91dGVyRm4gaXMgYSBnZW5lcmF0b3IsIHJldHVybiB0aGUgZnVsbCBpdGVyYXRvci5cbiAgICAgIDogaXRlci5uZXh0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyByZXN1bHQudmFsdWUgOiBpdGVyLm5leHQoKTtcbiAgICAgICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KSB7XG4gICAgdmFyIHN0YXRlID0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydDtcblxuICAgIHJldHVybiBmdW5jdGlvbiBpbnZva2UobWV0aG9kLCBhcmcpIHtcbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVFeGVjdXRpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUNvbXBsZXRlZCkge1xuICAgICAgICBpZiAobWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICB0aHJvdyBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCZSBmb3JnaXZpbmcsIHBlciAyNS4zLjMuMy4zIG9mIHRoZSBzcGVjOlxuICAgICAgICAvLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtZ2VuZXJhdG9ycmVzdW1lXG4gICAgICAgIHJldHVybiBkb25lUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubWV0aG9kID0gbWV0aG9kO1xuICAgICAgY29udGV4dC5hcmcgPSBhcmc7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZSA9IGNvbnRleHQuZGVsZWdhdGU7XG4gICAgICAgIGlmIChkZWxlZ2F0ZSkge1xuICAgICAgICAgIHZhciBkZWxlZ2F0ZVJlc3VsdCA9IG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0ID09PSBDb250aW51ZVNlbnRpbmVsKSBjb250aW51ZTtcbiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZVJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICBjb250ZXh0LnNlbnQgPSBjb250ZXh0Ll9zZW50ID0gY29udGV4dC5hcmc7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0KSB7XG4gICAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgICAgdGhyb3cgY29udGV4dC5hcmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICAgIGNvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGNvbnRleHQuYXJnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlID0gR2VuU3RhdGVFeGVjdXRpbmc7XG5cbiAgICAgICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIpIHtcbiAgICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gaW5uZXJGbiwgd2UgbGVhdmUgc3RhdGUgPT09XG4gICAgICAgICAgLy8gR2VuU3RhdGVFeGVjdXRpbmcgYW5kIGxvb3AgYmFjayBmb3IgYW5vdGhlciBpbnZvY2F0aW9uLlxuICAgICAgICAgIHN0YXRlID0gY29udGV4dC5kb25lXG4gICAgICAgICAgICA/IEdlblN0YXRlQ29tcGxldGVkXG4gICAgICAgICAgICA6IEdlblN0YXRlU3VzcGVuZGVkWWllbGQ7XG5cbiAgICAgICAgICBpZiAocmVjb3JkLmFyZyA9PT0gQ29udGludWVTZW50aW5lbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQuYXJnLFxuICAgICAgICAgICAgZG9uZTogY29udGV4dC5kb25lXG4gICAgICAgICAgfTtcblxuICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBleGNlcHRpb24gYnkgbG9vcGluZyBiYWNrIGFyb3VuZCB0byB0aGVcbiAgICAgICAgICAvLyBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKSBjYWxsIGFib3ZlLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBDYWxsIGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXShjb250ZXh0LmFyZykgYW5kIGhhbmRsZSB0aGVcbiAgLy8gcmVzdWx0LCBlaXRoZXIgYnkgcmV0dXJuaW5nIGEgeyB2YWx1ZSwgZG9uZSB9IHJlc3VsdCBmcm9tIHRoZVxuICAvLyBkZWxlZ2F0ZSBpdGVyYXRvciwgb3IgYnkgbW9kaWZ5aW5nIGNvbnRleHQubWV0aG9kIGFuZCBjb250ZXh0LmFyZyxcbiAgLy8gc2V0dGluZyBjb250ZXh0LmRlbGVnYXRlIHRvIG51bGwsIGFuZCByZXR1cm5pbmcgdGhlIENvbnRpbnVlU2VudGluZWwuXG4gIGZ1bmN0aW9uIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdO1xuICAgIGlmIChtZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQSAudGhyb3cgb3IgLnJldHVybiB3aGVuIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgbm8gLnRocm93XG4gICAgICAvLyBtZXRob2QgYWx3YXlzIHRlcm1pbmF0ZXMgdGhlIHlpZWxkKiBsb29wLlxuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIGlmIChkZWxlZ2F0ZS5pdGVyYXRvci5yZXR1cm4pIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIGEgcmV0dXJuIG1ldGhvZCwgZ2l2ZSBpdCBhXG4gICAgICAgICAgLy8gY2hhbmNlIHRvIGNsZWFuIHVwLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcblxuICAgICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAvLyBJZiBtYXliZUludm9rZURlbGVnYXRlKGNvbnRleHQpIGNoYW5nZWQgY29udGV4dC5tZXRob2QgZnJvbVxuICAgICAgICAgICAgLy8gXCJyZXR1cm5cIiB0byBcInRocm93XCIsIGxldCB0aGF0IG92ZXJyaWRlIHRoZSBUeXBlRXJyb3IgYmVsb3cuXG4gICAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIFwiVGhlIGl0ZXJhdG9yIGRvZXMgbm90IHByb3ZpZGUgYSAndGhyb3cnIG1ldGhvZFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKG1ldGhvZCwgZGVsZWdhdGUuaXRlcmF0b3IsIGNvbnRleHQuYXJnKTtcblxuICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIGluZm8gPSByZWNvcmQuYXJnO1xuXG4gICAgaWYgKCEgaW5mbykge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXCJpdGVyYXRvciByZXN1bHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgaWYgKGluZm8uZG9uZSkge1xuICAgICAgLy8gQXNzaWduIHRoZSByZXN1bHQgb2YgdGhlIGZpbmlzaGVkIGRlbGVnYXRlIHRvIHRoZSB0ZW1wb3JhcnlcbiAgICAgIC8vIHZhcmlhYmxlIHNwZWNpZmllZCBieSBkZWxlZ2F0ZS5yZXN1bHROYW1lIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0W2RlbGVnYXRlLnJlc3VsdE5hbWVdID0gaW5mby52YWx1ZTtcblxuICAgICAgLy8gUmVzdW1lIGV4ZWN1dGlvbiBhdCB0aGUgZGVzaXJlZCBsb2NhdGlvbiAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dC5uZXh0ID0gZGVsZWdhdGUubmV4dExvYztcblxuICAgICAgLy8gSWYgY29udGV4dC5tZXRob2Qgd2FzIFwidGhyb3dcIiBidXQgdGhlIGRlbGVnYXRlIGhhbmRsZWQgdGhlXG4gICAgICAvLyBleGNlcHRpb24sIGxldCB0aGUgb3V0ZXIgZ2VuZXJhdG9yIHByb2NlZWQgbm9ybWFsbHkuIElmXG4gICAgICAvLyBjb250ZXh0Lm1ldGhvZCB3YXMgXCJuZXh0XCIsIGZvcmdldCBjb250ZXh0LmFyZyBzaW5jZSBpdCBoYXMgYmVlblxuICAgICAgLy8gXCJjb25zdW1lZFwiIGJ5IHRoZSBkZWxlZ2F0ZSBpdGVyYXRvci4gSWYgY29udGV4dC5tZXRob2Qgd2FzXG4gICAgICAvLyBcInJldHVyblwiLCBhbGxvdyB0aGUgb3JpZ2luYWwgLnJldHVybiBjYWxsIHRvIGNvbnRpbnVlIGluIHRoZVxuICAgICAgLy8gb3V0ZXIgZ2VuZXJhdG9yLlxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kICE9PSBcInJldHVyblwiKSB7XG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJlLXlpZWxkIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgdGhlIGRlbGVnYXRlIG1ldGhvZC5cbiAgICAgIHJldHVybiBpbmZvO1xuICAgIH1cblxuICAgIC8vIFRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBpcyBmaW5pc2hlZCwgc28gZm9yZ2V0IGl0IGFuZCBjb250aW51ZSB3aXRoXG4gICAgLy8gdGhlIG91dGVyIGdlbmVyYXRvci5cbiAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgfVxuXG4gIC8vIERlZmluZSBHZW5lcmF0b3IucHJvdG90eXBlLntuZXh0LHRocm93LHJldHVybn0gaW4gdGVybXMgb2YgdGhlXG4gIC8vIHVuaWZpZWQgLl9pbnZva2UgaGVscGVyIG1ldGhvZC5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEdwKTtcblxuICBHcFt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvclwiO1xuXG4gIEdwLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFwiW29iamVjdCBHZW5lcmF0b3JdXCI7XG4gIH07XG5cbiAgZnVuY3Rpb24gcHVzaFRyeUVudHJ5KGxvY3MpIHtcbiAgICB2YXIgZW50cnkgPSB7IHRyeUxvYzogbG9jc1swXSB9O1xuXG4gICAgaWYgKDEgaW4gbG9jcykge1xuICAgICAgZW50cnkuY2F0Y2hMb2MgPSBsb2NzWzFdO1xuICAgIH1cblxuICAgIGlmICgyIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmZpbmFsbHlMb2MgPSBsb2NzWzJdO1xuICAgICAgZW50cnkuYWZ0ZXJMb2MgPSBsb2NzWzNdO1xuICAgIH1cblxuICAgIHRoaXMudHJ5RW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0VHJ5RW50cnkoZW50cnkpIHtcbiAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbiB8fCB7fTtcbiAgICByZWNvcmQudHlwZSA9IFwibm9ybWFsXCI7XG4gICAgZGVsZXRlIHJlY29yZC5hcmc7XG4gICAgZW50cnkuY29tcGxldGlvbiA9IHJlY29yZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIENvbnRleHQodHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBUaGUgcm9vdCBlbnRyeSBvYmplY3QgKGVmZmVjdGl2ZWx5IGEgdHJ5IHN0YXRlbWVudCB3aXRob3V0IGEgY2F0Y2hcbiAgICAvLyBvciBhIGZpbmFsbHkgYmxvY2spIGdpdmVzIHVzIGEgcGxhY2UgdG8gc3RvcmUgdmFsdWVzIHRocm93biBmcm9tXG4gICAgLy8gbG9jYXRpb25zIHdoZXJlIHRoZXJlIGlzIG5vIGVuY2xvc2luZyB0cnkgc3RhdGVtZW50LlxuICAgIHRoaXMudHJ5RW50cmllcyA9IFt7IHRyeUxvYzogXCJyb290XCIgfV07XG4gICAgdHJ5TG9jc0xpc3QuZm9yRWFjaChwdXNoVHJ5RW50cnksIHRoaXMpO1xuICAgIHRoaXMucmVzZXQodHJ1ZSk7XG4gIH1cblxuICBydW50aW1lLmtleXMgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBrZXlzLnJldmVyc2UoKTtcblxuICAgIC8vIFJhdGhlciB0aGFuIHJldHVybmluZyBhbiBvYmplY3Qgd2l0aCBhIG5leHQgbWV0aG9kLCB3ZSBrZWVwXG4gICAgLy8gdGhpbmdzIHNpbXBsZSBhbmQgcmV0dXJuIHRoZSBuZXh0IGZ1bmN0aW9uIGl0c2VsZi5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgIHdoaWxlIChrZXlzLmxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0ga2V5cy5wb3AoKTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICBuZXh0LnZhbHVlID0ga2V5O1xuICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRvIGF2b2lkIGNyZWF0aW5nIGFuIGFkZGl0aW9uYWwgb2JqZWN0LCB3ZSBqdXN0IGhhbmcgdGhlIC52YWx1ZVxuICAgICAgLy8gYW5kIC5kb25lIHByb3BlcnRpZXMgb2ZmIHRoZSBuZXh0IGZ1bmN0aW9uIG9iamVjdCBpdHNlbGYuIFRoaXNcbiAgICAgIC8vIGFsc28gZW5zdXJlcyB0aGF0IHRoZSBtaW5pZmllciB3aWxsIG5vdCBhbm9ueW1pemUgdGhlIGZ1bmN0aW9uLlxuICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gdmFsdWVzKGl0ZXJhYmxlKSB7XG4gICAgaWYgKGl0ZXJhYmxlKSB7XG4gICAgICB2YXIgaXRlcmF0b3JNZXRob2QgPSBpdGVyYWJsZVtpdGVyYXRvclN5bWJvbF07XG4gICAgICBpZiAoaXRlcmF0b3JNZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yTWV0aG9kLmNhbGwoaXRlcmFibGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGl0ZXJhYmxlLm5leHQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNOYU4oaXRlcmFibGUubGVuZ3RoKSkge1xuICAgICAgICB2YXIgaSA9IC0xLCBuZXh0ID0gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgaXRlcmFibGUubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duLmNhbGwoaXRlcmFibGUsIGkpKSB7XG4gICAgICAgICAgICAgIG5leHQudmFsdWUgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5leHQudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBuZXh0Lm5leHQgPSBuZXh0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBhbiBpdGVyYXRvciB3aXRoIG5vIHZhbHVlcy5cbiAgICByZXR1cm4geyBuZXh0OiBkb25lUmVzdWx0IH07XG4gIH1cbiAgcnVudGltZS52YWx1ZXMgPSB2YWx1ZXM7XG5cbiAgZnVuY3Rpb24gZG9uZVJlc3VsdCgpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICBDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgICBjb25zdHJ1Y3RvcjogQ29udGV4dCxcblxuICAgIHJlc2V0OiBmdW5jdGlvbihza2lwVGVtcFJlc2V0KSB7XG4gICAgICB0aGlzLnByZXYgPSAwO1xuICAgICAgdGhpcy5uZXh0ID0gMDtcbiAgICAgIC8vIFJlc2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgdGhpcy5zZW50ID0gdGhpcy5fc2VudCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcblxuICAgICAgdGhpcy50cnlFbnRyaWVzLmZvckVhY2gocmVzZXRUcnlFbnRyeSk7XG5cbiAgICAgIGlmICghc2tpcFRlbXBSZXNldCkge1xuICAgICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMpIHtcbiAgICAgICAgICAvLyBOb3Qgc3VyZSBhYm91dCB0aGUgb3B0aW1hbCBvcmRlciBvZiB0aGVzZSBjb25kaXRpb25zOlxuICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgwKSA9PT0gXCJ0XCIgJiZcbiAgICAgICAgICAgICAgaGFzT3duLmNhbGwodGhpcywgbmFtZSkgJiZcbiAgICAgICAgICAgICAgIWlzTmFOKCtuYW1lLnNsaWNlKDEpKSkge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmRvbmUgPSB0cnVlO1xuXG4gICAgICB2YXIgcm9vdEVudHJ5ID0gdGhpcy50cnlFbnRyaWVzWzBdO1xuICAgICAgdmFyIHJvb3RSZWNvcmQgPSByb290RW50cnkuY29tcGxldGlvbjtcbiAgICAgIGlmIChyb290UmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByb290UmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucnZhbDtcbiAgICB9LFxuXG4gICAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuICAgICAgaWYgKHRoaXMuZG9uZSkge1xuICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcztcbiAgICAgIGZ1bmN0aW9uIGhhbmRsZShsb2MsIGNhdWdodCkge1xuICAgICAgICByZWNvcmQudHlwZSA9IFwidGhyb3dcIjtcbiAgICAgICAgcmVjb3JkLmFyZyA9IGV4Y2VwdGlvbjtcbiAgICAgICAgY29udGV4dC5uZXh0ID0gbG9jO1xuXG4gICAgICAgIGlmIChjYXVnaHQpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGlzcGF0Y2hlZCBleGNlcHRpb24gd2FzIGNhdWdodCBieSBhIGNhdGNoIGJsb2NrLFxuICAgICAgICAgIC8vIHRoZW4gbGV0IHRoYXQgY2F0Y2ggYmxvY2sgaGFuZGxlIHRoZSBleGNlcHRpb24gbm9ybWFsbHkuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAhISBjYXVnaHQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSBcInJvb3RcIikge1xuICAgICAgICAgIC8vIEV4Y2VwdGlvbiB0aHJvd24gb3V0c2lkZSBvZiBhbnkgdHJ5IGJsb2NrIHRoYXQgY291bGQgaGFuZGxlXG4gICAgICAgICAgLy8gaXQsIHNvIHNldCB0aGUgY29tcGxldGlvbiB2YWx1ZSBvZiB0aGUgZW50aXJlIGZ1bmN0aW9uIHRvXG4gICAgICAgICAgLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbi5cbiAgICAgICAgICByZXR1cm4gaGFuZGxlKFwiZW5kXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYpIHtcbiAgICAgICAgICB2YXIgaGFzQ2F0Y2ggPSBoYXNPd24uY2FsbChlbnRyeSwgXCJjYXRjaExvY1wiKTtcbiAgICAgICAgICB2YXIgaGFzRmluYWxseSA9IGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIik7XG5cbiAgICAgICAgICBpZiAoaGFzQ2F0Y2ggJiYgaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0NhdGNoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJ5IHN0YXRlbWVudCB3aXRob3V0IGNhdGNoIG9yIGZpbmFsbHlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFicnVwdDogZnVuY3Rpb24odHlwZSwgYXJnKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIikgJiZcbiAgICAgICAgICAgIHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB2YXIgZmluYWxseUVudHJ5ID0gZW50cnk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSAmJlxuICAgICAgICAgICh0eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICAgdHlwZSA9PT0gXCJjb250aW51ZVwiKSAmJlxuICAgICAgICAgIGZpbmFsbHlFbnRyeS50cnlMb2MgPD0gYXJnICYmXG4gICAgICAgICAgYXJnIDw9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgIC8vIElnbm9yZSB0aGUgZmluYWxseSBlbnRyeSBpZiBjb250cm9sIGlzIG5vdCBqdW1waW5nIHRvIGFcbiAgICAgICAgLy8gbG9jYXRpb24gb3V0c2lkZSB0aGUgdHJ5L2NhdGNoIGJsb2NrLlxuICAgICAgICBmaW5hbGx5RW50cnkgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVjb3JkID0gZmluYWxseUVudHJ5ID8gZmluYWxseUVudHJ5LmNvbXBsZXRpb24gOiB7fTtcbiAgICAgIHJlY29yZC50eXBlID0gdHlwZTtcbiAgICAgIHJlY29yZC5hcmcgPSBhcmc7XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2M7XG4gICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZShyZWNvcmQpO1xuICAgIH0sXG5cbiAgICBjb21wbGV0ZTogZnVuY3Rpb24ocmVjb3JkLCBhZnRlckxvYykge1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICByZWNvcmQudHlwZSA9PT0gXCJjb250aW51ZVwiKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IHJlY29yZC5hcmc7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInJldHVyblwiKSB7XG4gICAgICAgIHRoaXMucnZhbCA9IHRoaXMuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICB0aGlzLm5leHQgPSBcImVuZFwiO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIiAmJiBhZnRlckxvYykge1xuICAgICAgICB0aGlzLm5leHQgPSBhZnRlckxvYztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfSxcblxuICAgIGZpbmlzaDogZnVuY3Rpb24oZmluYWxseUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS5maW5hbGx5TG9jID09PSBmaW5hbGx5TG9jKSB7XG4gICAgICAgICAgdGhpcy5jb21wbGV0ZShlbnRyeS5jb21wbGV0aW9uLCBlbnRyeS5hZnRlckxvYyk7XG4gICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgXCJjYXRjaFwiOiBmdW5jdGlvbih0cnlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSB0cnlMb2MpIHtcbiAgICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcbiAgICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgdmFyIHRocm93biA9IHJlY29yZC5hcmc7XG4gICAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRocm93bjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgY29udGV4dC5jYXRjaCBtZXRob2QgbXVzdCBvbmx5IGJlIGNhbGxlZCB3aXRoIGEgbG9jYXRpb25cbiAgICAgIC8vIGFyZ3VtZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBrbm93biBjYXRjaCBibG9jay5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgY2F0Y2ggYXR0ZW1wdFwiKTtcbiAgICB9LFxuXG4gICAgZGVsZWdhdGVZaWVsZDogZnVuY3Rpb24oaXRlcmFibGUsIHJlc3VsdE5hbWUsIG5leHRMb2MpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB7XG4gICAgICAgIGl0ZXJhdG9yOiB2YWx1ZXMoaXRlcmFibGUpLFxuICAgICAgICByZXN1bHROYW1lOiByZXN1bHROYW1lLFxuICAgICAgICBuZXh0TG9jOiBuZXh0TG9jXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgIC8vIERlbGliZXJhdGVseSBmb3JnZXQgdGhlIGxhc3Qgc2VudCB2YWx1ZSBzbyB0aGF0IHdlIGRvbid0XG4gICAgICAgIC8vIGFjY2lkZW50YWxseSBwYXNzIGl0IG9uIHRvIHRoZSBkZWxlZ2F0ZS5cbiAgICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cbiAgfTtcbn0pKFxuICAvLyBBbW9uZyB0aGUgdmFyaW91cyB0cmlja3MgZm9yIG9idGFpbmluZyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsXG4gIC8vIG9iamVjdCwgdGhpcyBzZWVtcyB0byBiZSB0aGUgbW9zdCByZWxpYWJsZSB0ZWNobmlxdWUgdGhhdCBkb2VzIG5vdFxuICAvLyB1c2UgaW5kaXJlY3QgZXZhbCAod2hpY2ggdmlvbGF0ZXMgQ29udGVudCBTZWN1cml0eSBQb2xpY3kpLlxuICB0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiID8gZ2xvYmFsIDpcbiAgdHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIiA/IHdpbmRvdyA6XG4gIHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IHRoaXNcbik7XG4iLCIoZnVuY3Rpb24oZykge1xuXHR2YXIgRk9STUFUX1JFID0gLyh7KykoW146e1xcfH1dKykoXFx8KFteOn1dKykpPyg6KC0/XFxkKikoW2lqXT8pKT8ofSspL2csXG5cdFx0ZGVmaW5lZCA9IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHR5cGVvZiB4ICE9PSAndW5kZWZpbmVkJyB9LFxuXHRcdGZvcm1hdCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRcdHN0ciA9IHRoaXNcblxuXHRcdFx0cmV0dXJuIHRoaXMucmVwbGFjZShGT1JNQVRfUkUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbSA9IGFyZ3VtZW50cyxcblx0XHRcdFx0XHRtYXRjaCA9IG1bMF0sXG5cdFx0XHRcdFx0YnJhY2VzX2luID0gbVsxXSxcblx0XHRcdFx0XHRpZCA9IG1bMl0sXG5cdFx0XHRcdFx0Ly8gaWQgbm90IGFuIGludD8gbmFtZWQhXG5cdFx0XHRcdFx0bmFtZWQgPSAoaWQgJSAxICE9PSAwKSxcblx0XHRcdFx0XHQvLyBpZiBubyBwcm9wZXJ0eSBjaGFpbiBleGlzdCwgZ2V0IHRoZSBuYW1lIGluc3RlYWRcblx0XHRcdFx0XHRwcm9wZXJ0eV9jaGFpbiA9IG1bNF0gfHwgKG5hbWVkICYmIGlkKSxcblx0XHRcdFx0XHRwYWRkaW5nID0gbVs2XSxcblx0XHRcdFx0XHRtb2RpZmllciA9IG1bN10sXG5cdFx0XHRcdFx0YnJhY2VzX291dCA9IG1bOF0sXG5cdFx0XHRcdFx0cHJvcGVydHksXG5cdFx0XHRcdFx0b2JqID0ge30sXG5cdFx0XHRcdFx0YXJnID0gbmFtZWQgPyBhcmdzWzBdIDogYXJnc1tpZF0sXG5cdFx0XHRcdFx0cmVzID0gW11cblxuXHRcdFx0XHQvLyBlc2NhcGVkP1xuXHRcdFx0XHRpZiAoYnJhY2VzX2luLmxlbmd0aCA+IDEgJiYgYnJhY2VzX291dC5sZW5ndGggPiAxKVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaC5zbGljZSgxLCBtYXRjaC5sZW5ndGggLSAxKVxuXG5cdFx0XHRcdC8vIHZpc2l0IHRoZSBwcm9wZXJ0aWVzXG5cdFx0XHRcdHByb3BlcnR5X2NoYWluID0gcHJvcGVydHlfY2hhaW4gJiYgcHJvcGVydHlfY2hhaW4uc3BsaXQoJy4nKSB8fCBbXVxuXHRcdFx0XHR3aGlsZSAoZGVmaW5lZChwcm9wZXJ0eSA9IHByb3BlcnR5X2NoYWluLnNoaWZ0KCkpICYmIGRlZmluZWQoYXJnKSkge1xuXHRcdFx0XHRcdC8vIGV2YWx1YXRlIGFueSBpbnRlcm1lZGlhdGUgZnVuY3Rpb25cblx0XHRcdFx0XHRpZiAodHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJykgYXJnID0gYXJnLmFwcGx5KG9iaiwgW10pXG5cblx0XHRcdFx0XHRvYmogPSBhcmdcblx0XHRcdFx0XHRhcmcgPSBhcmdbcHJvcGVydHldXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBFdmFsdWF0ZSB0aGUgbGVhZiBmdW5jdGlvblxuXHRcdFx0XHRpZiAodHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJykgYXJnID0gYXJnLmFwcGx5KG9iaiwgW10pXG5cblx0XHRcdFx0Ly8gSW50ZWdlciBtb2RpZmllclxuXHRcdFx0XHRpZiAoJ2knID09PSBtb2RpZmllcikgYXJnID0gTWF0aC5yb3VuZChhcmcpXG5cblx0XHRcdFx0Ly8gSlNPTiBtb2RpZmllclxuXHRcdFx0XHRlbHNlIGlmICgnaicgPT09IG1vZGlmaWVyKSBhcmcgPSBKU09OLnN0cmluZ2lmeShhcmcpXG5cblx0XHRcdFx0Ly8gTm90aGluZyBmb3VuZCA6LShcblx0XHRcdFx0aWYgKCFkZWZpbmVkKGFyZykpIHJldHVybiBtYXRjaFxuXG5cdFx0XHRcdC8vIEFwcGx5IHBhZGRpbmcgYW5kIHJldHVyblxuXHRcdFx0XHRhcmcgPSBTdHJpbmcoYXJnKVxuXHRcdFx0XHRpZiAocGFkZGluZyA8IDApIHtcblx0XHRcdFx0XHRyZXMucHVzaChhcmcpXG5cdFx0XHRcdFx0cGFkZGluZyA9IDEgLSBwYWRkaW5nXG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHBhZGRpbmcgPiBhcmcubGVuZ3RoKSByZXMubGVuZ3RoID0gcGFkZGluZyAtIGFyZy5sZW5ndGhcblx0XHRcdFx0aWYgKCFkZWZpbmVkKHJlc1swXSkpIHJlc1tyZXMubGVuZ3RoXSA9IGFyZ1xuXHRcdFx0XHRyZXR1cm4gcmVzLmpvaW4oXCIgXCIpXG5cdFx0XHR9KVxuXHRcdH0sXG5cdFx0bWFpbiA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gQ2FsbCBhcyBhIG1ldGhvZFxuXHRcdFx0cmV0dXJuIGZvcm1hdC5hcHBseShhcmd1bWVudHNbMF0sIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpXG5cdFx0fVxuXG5cdC8vIEluc3RhbGwgYXMgYSBtZXRob2Rcblx0bWFpbi5leHRlbmRTdHJpbmcgPSBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG5cdFx0U3RyaW5nLnByb3RvdHlwZVttZXRob2ROYW1lIHx8ICdmb3JtYXQnXSA9IGZvcm1hdFxuXHR9XG5cblx0Ly8gRXhwb3J0IGFzIHdpbmRvdy5zdHJpbmdmb3JtYXQgKGJyb3dzZXIpIG9yIGFzIGEgbW9kdWxlIChOb2RlKVxuXHRnLnRvcCA/IGcuc3RyaW5nZm9ybWF0ID0gbWFpbiA6IG1vZHVsZS5leHBvcnRzID0gbWFpblxufSkodGhpcylcbiIsIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2VtaXR0ZXInKTtcbnZhciByZWR1Y2UgPSByZXF1aXJlKCdyZWR1Y2UnKTtcbnZhciByZXF1ZXN0QmFzZSA9IHJlcXVpcmUoJy4vcmVxdWVzdC1iYXNlJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIFJvb3QgcmVmZXJlbmNlIGZvciBpZnJhbWVzLlxuICovXG5cbnZhciByb290O1xuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7IC8vIEJyb3dzZXIgd2luZG93XG4gIHJvb3QgPSB3aW5kb3c7XG59IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykgeyAvLyBXZWIgV29ya2VyXG4gIHJvb3QgPSBzZWxmO1xufSBlbHNlIHsgLy8gT3RoZXIgZW52aXJvbm1lbnRzXG4gIHJvb3QgPSB0aGlzO1xufVxuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gbm9vcCgpe307XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYSBob3N0IG9iamVjdCxcbiAqIHdlIGRvbid0IHdhbnQgdG8gc2VyaWFsaXplIHRoZXNlIDopXG4gKlxuICogVE9ETzogZnV0dXJlIHByb29mLCBtb3ZlIHRvIGNvbXBvZW50IGxhbmRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNIb3N0KG9iaikge1xuICB2YXIgc3RyID0ge30udG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIHN3aXRjaCAoc3RyKSB7XG4gICAgY2FzZSAnW29iamVjdCBGaWxlXSc6XG4gICAgY2FzZSAnW29iamVjdCBCbG9iXSc6XG4gICAgY2FzZSAnW29iamVjdCBGb3JtRGF0YV0nOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEV4cG9zZSBgcmVxdWVzdGAuXG4gKi9cblxudmFyIHJlcXVlc3QgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpLmJpbmQobnVsbCwgUmVxdWVzdCk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKG51bGwgIT0gb2JqW2tleV0pIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG4vKipcbiAqIEhlbHBzICdzZXJpYWxpemUnIHdpdGggc2VyaWFsaXppbmcgYXJyYXlzLlxuICogTXV0YXRlcyB0aGUgcGFpcnMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHZhbCkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgcmV0dXJuIHZhbC5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHYpO1xuICAgIH0pO1xuICB9XG4gIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWwpKTtcbn1cblxuLyoqXG4gKiBFeHBvc2Ugc2VyaWFsaXphdGlvbiBtZXRob2QuXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0ID0gc2VyaWFsaXplO1xuXG4gLyoqXG4gICogUGFyc2UgdGhlIGdpdmVuIHgtd3d3LWZvcm0tdXJsZW5jb2RlZCBgc3RyYC5cbiAgKlxuICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICogQGFwaSBwcml2YXRlXG4gICovXG5cbmZ1bmN0aW9uIHBhcnNlU3RyaW5nKHN0cikge1xuICB2YXIgb2JqID0ge307XG4gIHZhciBwYWlycyA9IHN0ci5zcGxpdCgnJicpO1xuICB2YXIgcGFydHM7XG4gIHZhciBwYWlyO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwYXJ0cyA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFydHNbMV0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICByZXR1cm4gL1tcXC8rXWpzb25cXGIvLnRlc3QobWltZSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtaW1lIHR5cGUgZm9yIHRoZSBnaXZlbiBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiB0eXBlKHN0cil7XG4gIHJldHVybiBzdHIuc3BsaXQoLyAqOyAqLykuc2hpZnQoKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhlYWRlciBmaWVsZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcmFtcyhzdHIpe1xuICByZXR1cm4gcmVkdWNlKHN0ci5zcGxpdCgvICo7ICovKSwgZnVuY3Rpb24ob2JqLCBzdHIpe1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvICo9ICovKVxuICAgICAgLCBrZXkgPSBwYXJ0cy5zaGlmdCgpXG4gICAgICAsIHZhbCA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICBpZiAoa2V5ICYmIHZhbCkgb2JqW2tleV0gPSB2YWw7XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXNwb25zZWAgd2l0aCB0aGUgZ2l2ZW4gYHhocmAuXG4gKlxuICogIC0gc2V0IGZsYWdzICgub2ssIC5lcnJvciwgZXRjKVxuICogIC0gcGFyc2UgaGVhZGVyXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogIEFsaWFzaW5nIGBzdXBlcmFnZW50YCBhcyBgcmVxdWVzdGAgaXMgbmljZTpcbiAqXG4gKiAgICAgIHJlcXVlc3QgPSBzdXBlcmFnZW50O1xuICpcbiAqICBXZSBjYW4gdXNlIHRoZSBwcm9taXNlLWxpa2UgQVBJLCBvciBwYXNzIGNhbGxiYWNrczpcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJykuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJywgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgU2VuZGluZyBkYXRhIGNhbiBiZSBjaGFpbmVkOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5zZW5kKClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnBvc3QoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIE9yIGZ1cnRoZXIgcmVkdWNlZCB0byBhIHNpbmdsZSBjYWxsIGZvciBzaW1wbGUgY2FzZXM6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogQHBhcmFtIHtYTUxIVFRQUmVxdWVzdH0geGhyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUmVzcG9uc2UocmVxLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLnJlcSA9IHJlcTtcbiAgdGhpcy54aHIgPSB0aGlzLnJlcS54aHI7XG4gIC8vIHJlc3BvbnNlVGV4dCBpcyBhY2Nlc3NpYmxlIG9ubHkgaWYgcmVzcG9uc2VUeXBlIGlzICcnIG9yICd0ZXh0JyBhbmQgb24gb2xkZXIgYnJvd3NlcnNcbiAgdGhpcy50ZXh0ID0gKCh0aGlzLnJlcS5tZXRob2QgIT0nSEVBRCcgJiYgKHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJycgfHwgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcpKSB8fCB0eXBlb2YgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndW5kZWZpbmVkJylcbiAgICAgPyB0aGlzLnhoci5yZXNwb25zZVRleHRcbiAgICAgOiBudWxsO1xuICB0aGlzLnN0YXR1c1RleHQgPSB0aGlzLnJlcS54aHIuc3RhdHVzVGV4dDtcbiAgdGhpcy5zZXRTdGF0dXNQcm9wZXJ0aWVzKHRoaXMueGhyLnN0YXR1cyk7XG4gIHRoaXMuaGVhZGVyID0gdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXIodGhpcy54aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAvLyBnZXRBbGxSZXNwb25zZUhlYWRlcnMgc29tZXRpbWVzIGZhbHNlbHkgcmV0dXJucyBcIlwiIGZvciBDT1JTIHJlcXVlc3RzLCBidXRcbiAgLy8gZ2V0UmVzcG9uc2VIZWFkZXIgc3RpbGwgd29ya3MuIHNvIHdlIGdldCBjb250ZW50LXR5cGUgZXZlbiBpZiBnZXR0aW5nXG4gIC8vIG90aGVyIGhlYWRlcnMgZmFpbHMuXG4gIHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdjb250ZW50LXR5cGUnKTtcbiAgdGhpcy5zZXRIZWFkZXJQcm9wZXJ0aWVzKHRoaXMuaGVhZGVyKTtcbiAgdGhpcy5ib2R5ID0gdGhpcy5yZXEubWV0aG9kICE9ICdIRUFEJ1xuICAgID8gdGhpcy5wYXJzZUJvZHkodGhpcy50ZXh0ID8gdGhpcy50ZXh0IDogdGhpcy54aHIucmVzcG9uc2UpXG4gICAgOiBudWxsO1xufVxuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGBmaWVsZGAgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLmhlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogU2V0IGhlYWRlciByZWxhdGVkIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGAudHlwZWAgdGhlIGNvbnRlbnQgdHlwZSB3aXRob3V0IHBhcmFtc1xuICpcbiAqIEEgcmVzcG9uc2Ugb2YgXCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLThcIlxuICogd2lsbCBwcm92aWRlIHlvdSB3aXRoIGEgYC50eXBlYCBvZiBcInRleHQvcGxhaW5cIi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaGVhZGVyXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0SGVhZGVyUHJvcGVydGllcyA9IGZ1bmN0aW9uKGhlYWRlcil7XG4gIC8vIGNvbnRlbnQtdHlwZVxuICB2YXIgY3QgPSB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gfHwgJyc7XG4gIHRoaXMudHlwZSA9IHR5cGUoY3QpO1xuXG4gIC8vIHBhcmFtc1xuICB2YXIgb2JqID0gcGFyYW1zKGN0KTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikgdGhpc1trZXldID0gb2JqW2tleV07XG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBib2R5IGBzdHJgLlxuICpcbiAqIFVzZWQgZm9yIGF1dG8tcGFyc2luZyBvZiBib2RpZXMuIFBhcnNlcnNcbiAqIGFyZSBkZWZpbmVkIG9uIHRoZSBgc3VwZXJhZ2VudC5wYXJzZWAgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnBhcnNlQm9keSA9IGZ1bmN0aW9uKHN0cil7XG4gIHZhciBwYXJzZSA9IHJlcXVlc3QucGFyc2VbdGhpcy50eXBlXTtcbiAgaWYgKCFwYXJzZSAmJiBpc0pTT04odGhpcy50eXBlKSkge1xuICAgIHBhcnNlID0gcmVxdWVzdC5wYXJzZVsnYXBwbGljYXRpb24vanNvbiddO1xuICB9XG4gIHJldHVybiBwYXJzZSAmJiBzdHIgJiYgKHN0ci5sZW5ndGggfHwgc3RyIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgID8gcGFyc2Uoc3RyKVxuICAgIDogbnVsbDtcbn07XG5cbi8qKlxuICogU2V0IGZsYWdzIHN1Y2ggYXMgYC5va2AgYmFzZWQgb24gYHN0YXR1c2AuXG4gKlxuICogRm9yIGV4YW1wbGUgYSAyeHggcmVzcG9uc2Ugd2lsbCBnaXZlIHlvdSBhIGAub2tgIG9mIF9fdHJ1ZV9fXG4gKiB3aGVyZWFzIDV4eCB3aWxsIGJlIF9fZmFsc2VfXyBhbmQgYC5lcnJvcmAgd2lsbCBiZSBfX3RydWVfXy4gVGhlXG4gKiBgLmNsaWVudEVycm9yYCBhbmQgYC5zZXJ2ZXJFcnJvcmAgYXJlIGFsc28gYXZhaWxhYmxlIHRvIGJlIG1vcmVcbiAqIHNwZWNpZmljLCBhbmQgYC5zdGF0dXNUeXBlYCBpcyB0aGUgY2xhc3Mgb2YgZXJyb3IgcmFuZ2luZyBmcm9tIDEuLjVcbiAqIHNvbWV0aW1lcyB1c2VmdWwgZm9yIG1hcHBpbmcgcmVzcG9uZCBjb2xvcnMgZXRjLlxuICpcbiAqIFwic3VnYXJcIiBwcm9wZXJ0aWVzIGFyZSBhbHNvIGRlZmluZWQgZm9yIGNvbW1vbiBjYXNlcy4gQ3VycmVudGx5IHByb3ZpZGluZzpcbiAqXG4gKiAgIC0gLm5vQ29udGVudFxuICogICAtIC5iYWRSZXF1ZXN0XG4gKiAgIC0gLnVuYXV0aG9yaXplZFxuICogICAtIC5ub3RBY2NlcHRhYmxlXG4gKiAgIC0gLm5vdEZvdW5kXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXR1c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnNldFN0YXR1c1Byb3BlcnRpZXMgPSBmdW5jdGlvbihzdGF0dXMpe1xuICAvLyBoYW5kbGUgSUU5IGJ1ZzogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDA0Njk3Mi9tc2llLXJldHVybnMtc3RhdHVzLWNvZGUtb2YtMTIyMy1mb3ItYWpheC1yZXF1ZXN0XG4gIGlmIChzdGF0dXMgPT09IDEyMjMpIHtcbiAgICBzdGF0dXMgPSAyMDQ7XG4gIH1cblxuICB2YXIgdHlwZSA9IHN0YXR1cyAvIDEwMCB8IDA7XG5cbiAgLy8gc3RhdHVzIC8gY2xhc3NcbiAgdGhpcy5zdGF0dXMgPSB0aGlzLnN0YXR1c0NvZGUgPSBzdGF0dXM7XG4gIHRoaXMuc3RhdHVzVHlwZSA9IHR5cGU7XG5cbiAgLy8gYmFzaWNzXG4gIHRoaXMuaW5mbyA9IDEgPT0gdHlwZTtcbiAgdGhpcy5vayA9IDIgPT0gdHlwZTtcbiAgdGhpcy5jbGllbnRFcnJvciA9IDQgPT0gdHlwZTtcbiAgdGhpcy5zZXJ2ZXJFcnJvciA9IDUgPT0gdHlwZTtcbiAgdGhpcy5lcnJvciA9ICg0ID09IHR5cGUgfHwgNSA9PSB0eXBlKVxuICAgID8gdGhpcy50b0Vycm9yKClcbiAgICA6IGZhbHNlO1xuXG4gIC8vIHN1Z2FyXG4gIHRoaXMuYWNjZXB0ZWQgPSAyMDIgPT0gc3RhdHVzO1xuICB0aGlzLm5vQ29udGVudCA9IDIwNCA9PSBzdGF0dXM7XG4gIHRoaXMuYmFkUmVxdWVzdCA9IDQwMCA9PSBzdGF0dXM7XG4gIHRoaXMudW5hdXRob3JpemVkID0gNDAxID09IHN0YXR1cztcbiAgdGhpcy5ub3RBY2NlcHRhYmxlID0gNDA2ID09IHN0YXR1cztcbiAgdGhpcy5ub3RGb3VuZCA9IDQwNCA9PSBzdGF0dXM7XG4gIHRoaXMuZm9yYmlkZGVuID0gNDAzID09IHN0YXR1cztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFuIGBFcnJvcmAgcmVwcmVzZW50YXRpdmUgb2YgdGhpcyByZXNwb25zZS5cbiAqXG4gKiBAcmV0dXJuIHtFcnJvcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnRvRXJyb3IgPSBmdW5jdGlvbigpe1xuICB2YXIgcmVxID0gdGhpcy5yZXE7XG4gIHZhciBtZXRob2QgPSByZXEubWV0aG9kO1xuICB2YXIgdXJsID0gcmVxLnVybDtcblxuICB2YXIgbXNnID0gJ2Nhbm5vdCAnICsgbWV0aG9kICsgJyAnICsgdXJsICsgJyAoJyArIHRoaXMuc3RhdHVzICsgJyknO1xuICB2YXIgZXJyID0gbmV3IEVycm9yKG1zZyk7XG4gIGVyci5zdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgZXJyLm1ldGhvZCA9IG1ldGhvZDtcbiAgZXJyLnVybCA9IHVybDtcblxuICByZXR1cm4gZXJyO1xufTtcblxuLyoqXG4gKiBFeHBvc2UgYFJlc3BvbnNlYC5cbiAqL1xuXG5yZXF1ZXN0LlJlc3BvbnNlID0gUmVzcG9uc2U7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVxdWVzdGAgd2l0aCB0aGUgZ2l2ZW4gYG1ldGhvZGAgYW5kIGB1cmxgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gUmVxdWVzdChtZXRob2QsIHVybCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX3F1ZXJ5ID0gdGhpcy5fcXVlcnkgfHwgW107XG4gIHRoaXMubWV0aG9kID0gbWV0aG9kO1xuICB0aGlzLnVybCA9IHVybDtcbiAgdGhpcy5oZWFkZXIgPSB7fTsgLy8gcHJlc2VydmVzIGhlYWRlciBuYW1lIGNhc2VcbiAgdGhpcy5faGVhZGVyID0ge307IC8vIGNvZXJjZXMgaGVhZGVyIG5hbWVzIHRvIGxvd2VyY2FzZVxuICB0aGlzLm9uKCdlbmQnLCBmdW5jdGlvbigpe1xuICAgIHZhciBlcnIgPSBudWxsO1xuICAgIHZhciByZXMgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IG5ldyBSZXNwb25zZShzZWxmKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIGVyciA9IG5ldyBFcnJvcignUGFyc2VyIGlzIHVuYWJsZSB0byBwYXJzZSB0aGUgcmVzcG9uc2UnKTtcbiAgICAgIGVyci5wYXJzZSA9IHRydWU7XG4gICAgICBlcnIub3JpZ2luYWwgPSBlO1xuICAgICAgLy8gaXNzdWUgIzY3NTogcmV0dXJuIHRoZSByYXcgcmVzcG9uc2UgaWYgdGhlIHJlc3BvbnNlIHBhcnNpbmcgZmFpbHNcbiAgICAgIGVyci5yYXdSZXNwb25zZSA9IHNlbGYueGhyICYmIHNlbGYueGhyLnJlc3BvbnNlVGV4dCA/IHNlbGYueGhyLnJlc3BvbnNlVGV4dCA6IG51bGw7XG4gICAgICAvLyBpc3N1ZSAjODc2OiByZXR1cm4gdGhlIGh0dHAgc3RhdHVzIGNvZGUgaWYgdGhlIHJlc3BvbnNlIHBhcnNpbmcgZmFpbHNcbiAgICAgIGVyci5zdGF0dXNDb2RlID0gc2VsZi54aHIgJiYgc2VsZi54aHIuc3RhdHVzID8gc2VsZi54aHIuc3RhdHVzIDogbnVsbDtcbiAgICAgIHJldHVybiBzZWxmLmNhbGxiYWNrKGVycik7XG4gICAgfVxuXG4gICAgc2VsZi5lbWl0KCdyZXNwb25zZScsIHJlcyk7XG5cbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIsIHJlcyk7XG4gICAgfVxuXG4gICAgaWYgKHJlcy5zdGF0dXMgPj0gMjAwICYmIHJlcy5zdGF0dXMgPCAzMDApIHtcbiAgICAgIHJldHVybiBzZWxmLmNhbGxiYWNrKGVyciwgcmVzKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3X2VyciA9IG5ldyBFcnJvcihyZXMuc3RhdHVzVGV4dCB8fCAnVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2UnKTtcbiAgICBuZXdfZXJyLm9yaWdpbmFsID0gZXJyO1xuICAgIG5ld19lcnIucmVzcG9uc2UgPSByZXM7XG4gICAgbmV3X2Vyci5zdGF0dXMgPSByZXMuc3RhdHVzO1xuXG4gICAgc2VsZi5jYWxsYmFjayhuZXdfZXJyLCByZXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBNaXhpbiBgRW1pdHRlcmAgYW5kIGByZXF1ZXN0QmFzZWAuXG4gKi9cblxuRW1pdHRlcihSZXF1ZXN0LnByb3RvdHlwZSk7XG5mb3IgKHZhciBrZXkgaW4gcmVxdWVzdEJhc2UpIHtcbiAgUmVxdWVzdC5wcm90b3R5cGVba2V5XSA9IHJlcXVlc3RCYXNlW2tleV07XG59XG5cbi8qKlxuICogQWJvcnQgdGhlIHJlcXVlc3QsIGFuZCBjbGVhciBwb3RlbnRpYWwgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0aGlzLmFib3J0ZWQpIHJldHVybjtcbiAgdGhpcy5hYm9ydGVkID0gdHJ1ZTtcbiAgdGhpcy54aHIgJiYgdGhpcy54aHIuYWJvcnQoKTtcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgdGhpcy5lbWl0KCdhYm9ydCcpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IENvbnRlbnQtVHlwZSB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy54bWwgPSAnYXBwbGljYXRpb24veG1sJztcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ3htbCcpXG4gKiAgICAgICAgLnNlbmQoeG1sc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgnYXBwbGljYXRpb24veG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50eXBlID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdDb250ZW50LVR5cGUnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHJlc3BvbnNlVHlwZSB0byBgdmFsYC4gUHJlc2VudGx5IHZhbGlkIHJlc3BvbnNlVHlwZXMgYXJlICdibG9iJyBhbmQgXG4gKiAnYXJyYXlidWZmZXInLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnJlc3BvbnNlVHlwZSgnYmxvYicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnJlc3BvbnNlVHlwZSA9IGZ1bmN0aW9uKHZhbCl7XG4gIHRoaXMuX3Jlc3BvbnNlVHlwZSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBY2NlcHQgdG8gYHR5cGVgLCBtYXBwaW5nIHZhbHVlcyBmcm9tIGByZXF1ZXN0LnR5cGVzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMuanNvbiA9ICdhcHBsaWNhdGlvbi9qc29uJztcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2VwdFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKHR5cGUpe1xuICB0aGlzLnNldCgnQWNjZXB0JywgcmVxdWVzdC50eXBlc1t0eXBlXSB8fCB0eXBlKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBdXRob3JpemF0aW9uIGZpZWxkIHZhbHVlIHdpdGggYHVzZXJgIGFuZCBgcGFzc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVzZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB3aXRoICd0eXBlJyBwcm9wZXJ0eSAnYXV0bycgb3IgJ2Jhc2ljJyAoZGVmYXVsdCAnYmFzaWMnKVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzLCBvcHRpb25zKXtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHR5cGU6ICdiYXNpYydcbiAgICB9XG4gIH1cblxuICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgIHZhciBzdHIgPSBidG9hKHVzZXIgKyAnOicgKyBwYXNzKTtcbiAgICAgIHRoaXMuc2V0KCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBzdHIpO1xuICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnYXV0byc6XG4gICAgICB0aGlzLnVzZXJuYW1lID0gdXNlcjtcbiAgICAgIHRoaXMucGFzc3dvcmQgPSBwYXNzO1xuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4qIEFkZCBxdWVyeS1zdHJpbmcgYHZhbGAuXG4qXG4qIEV4YW1wbGVzOlxuKlxuKiAgIHJlcXVlc3QuZ2V0KCcvc2hvZXMnKVxuKiAgICAgLnF1ZXJ5KCdzaXplPTEwJylcbiogICAgIC5xdWVyeSh7IGNvbG9yOiAnYmx1ZScgfSlcbipcbiogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSB2YWxcbiogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4qIEBhcGkgcHVibGljXG4qL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uKHZhbCl7XG4gIGlmICgnc3RyaW5nJyAhPSB0eXBlb2YgdmFsKSB2YWwgPSBzZXJpYWxpemUodmFsKTtcbiAgaWYgKHZhbCkgdGhpcy5fcXVlcnkucHVzaCh2YWwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUXVldWUgdGhlIGdpdmVuIGBmaWxlYCBhcyBhbiBhdHRhY2htZW50IHRvIHRoZSBzcGVjaWZpZWQgYGZpZWxkYCxcbiAqIHdpdGggb3B0aW9uYWwgYGZpbGVuYW1lYC5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5hdHRhY2gobmV3IEJsb2IoWyc8YSBpZD1cImFcIj48YiBpZD1cImJcIj5oZXkhPC9iPjwvYT4nXSwgeyB0eXBlOiBcInRleHQvaHRtbFwifSkpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcGFyYW0ge0Jsb2J8RmlsZX0gZmlsZVxuICogQHBhcmFtIHtTdHJpbmd9IGZpbGVuYW1lXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYXR0YWNoID0gZnVuY3Rpb24oZmllbGQsIGZpbGUsIGZpbGVuYW1lKXtcbiAgdGhpcy5fZ2V0Rm9ybURhdGEoKS5hcHBlbmQoZmllbGQsIGZpbGUsIGZpbGVuYW1lIHx8IGZpbGUubmFtZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuX2dldEZvcm1EYXRhID0gZnVuY3Rpb24oKXtcbiAgaWYgKCF0aGlzLl9mb3JtRGF0YSkge1xuICAgIHRoaXMuX2Zvcm1EYXRhID0gbmV3IHJvb3QuRm9ybURhdGEoKTtcbiAgfVxuICByZXR1cm4gdGhpcy5fZm9ybURhdGE7XG59O1xuXG4vKipcbiAqIFNlbmQgYGRhdGFgIGFzIHRoZSByZXF1ZXN0IGJvZHksIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gbWFudWFsIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnanNvbicpXG4gKiAgICAgICAgIC5zZW5kKCd7XCJuYW1lXCI6XCJ0alwifScpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICAqICAgICAgICAuc2VuZCgnbmFtZT10b2JpJylcbiAgKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAgKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBvYmogPSBpc09iamVjdChkYXRhKTtcbiAgdmFyIHR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuXG4gIC8vIG1lcmdlXG4gIGlmIChvYmogJiYgaXNPYmplY3QodGhpcy5fZGF0YSkpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgdGhpcy5fZGF0YVtrZXldID0gZGF0YVtrZXldO1xuICAgIH1cbiAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgZGF0YSkge1xuICAgIGlmICghdHlwZSkgdGhpcy50eXBlKCdmb3JtJyk7XG4gICAgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgaWYgKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnID09IHR5cGUpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB0aGlzLl9kYXRhXG4gICAgICAgID8gdGhpcy5fZGF0YSArICcmJyArIGRhdGFcbiAgICAgICAgOiBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRhID0gKHRoaXMuX2RhdGEgfHwgJycpICsgZGF0YTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gIH1cblxuICBpZiAoIW9iaiB8fCBpc0hvc3QoZGF0YSkpIHJldHVybiB0aGlzO1xuICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnanNvbicpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuUmVzcG9uc2UucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gc2VyaWFsaXplKGZuKXtcbiAgaWYgKHJvb3QuY29uc29sZSkge1xuICAgIGNvbnNvbGUud2FybihcIkNsaWVudC1zaWRlIHBhcnNlKCkgbWV0aG9kIGhhcyBiZWVuIHJlbmFtZWQgdG8gc2VyaWFsaXplKCkuIFRoaXMgbWV0aG9kIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggc3VwZXJhZ2VudCB2Mi4wXCIpO1xuICB9XG4gIHRoaXMuc2VyaWFsaXplKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBJbnZva2UgdGhlIGNhbGxiYWNrIHdpdGggYGVycmAgYW5kIGByZXNgXG4gKiBhbmQgaGFuZGxlIGFyaXR5IGNoZWNrLlxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVyclxuICogQHBhcmFtIHtSZXNwb25zZX0gcmVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jYWxsYmFjayA9IGZ1bmN0aW9uKGVyciwgcmVzKXtcbiAgdmFyIGZuID0gdGhpcy5fY2FsbGJhY2s7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIGZuKGVyciwgcmVzKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggeC1kb21haW4gZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY3Jvc3NEb21haW5FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIGJlZW4gdGVybWluYXRlZFxcblBvc3NpYmxlIGNhdXNlczogdGhlIG5ldHdvcmsgaXMgb2ZmbGluZSwgT3JpZ2luIGlzIG5vdCBhbGxvd2VkIGJ5IEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbiwgdGhlIHBhZ2UgaXMgYmVpbmcgdW5sb2FkZWQsIGV0Yy4nKTtcbiAgZXJyLmNyb3NzRG9tYWluID0gdHJ1ZTtcblxuICBlcnIuc3RhdHVzID0gdGhpcy5zdGF0dXM7XG4gIGVyci5tZXRob2QgPSB0aGlzLm1ldGhvZDtcbiAgZXJyLnVybCA9IHRoaXMudXJsO1xuXG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggdGltZW91dCBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50aW1lb3V0RXJyb3IgPSBmdW5jdGlvbigpe1xuICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3RpbWVvdXQgb2YgJyArIHRpbWVvdXQgKyAnbXMgZXhjZWVkZWQnKTtcbiAgZXJyLnRpbWVvdXQgPSB0aW1lb3V0O1xuICB0aGlzLmNhbGxiYWNrKGVycik7XG59O1xuXG4vKipcbiAqIEVuYWJsZSB0cmFuc21pc3Npb24gb2YgY29va2llcyB3aXRoIHgtZG9tYWluIHJlcXVlc3RzLlxuICpcbiAqIE5vdGUgdGhhdCBmb3IgdGhpcyB0byB3b3JrIHRoZSBvcmlnaW4gbXVzdCBub3QgYmVcbiAqIHVzaW5nIFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luXCIgd2l0aCBhIHdpbGRjYXJkLFxuICogYW5kIGFsc28gbXVzdCBzZXQgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFsc1wiXG4gKiB0byBcInRydWVcIi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLndpdGhDcmVkZW50aWFscyA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMuX3dpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBJbml0aWF0ZSByZXF1ZXN0LCBpbnZva2luZyBjYWxsYmFjayBgZm4ocmVzKWBcbiAqIHdpdGggYW4gaW5zdGFuY2VvZiBgUmVzcG9uc2VgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciB4aHIgPSB0aGlzLnhociA9IHJlcXVlc3QuZ2V0WEhSKCk7XG4gIHZhciBxdWVyeSA9IHRoaXMuX3F1ZXJ5LmpvaW4oJyYnKTtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZGF0YSA9IHRoaXMuX2Zvcm1EYXRhIHx8IHRoaXMuX2RhdGE7XG5cbiAgLy8gc3RvcmUgY2FsbGJhY2tcbiAgdGhpcy5fY2FsbGJhY2sgPSBmbiB8fCBub29wO1xuXG4gIC8vIHN0YXRlIGNoYW5nZVxuICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKXtcbiAgICBpZiAoNCAhPSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuXG4gICAgLy8gSW4gSUU5LCByZWFkcyB0byBhbnkgcHJvcGVydHkgKGUuZy4gc3RhdHVzKSBvZmYgb2YgYW4gYWJvcnRlZCBYSFIgd2lsbFxuICAgIC8vIHJlc3VsdCBpbiB0aGUgZXJyb3IgXCJDb3VsZCBub3QgY29tcGxldGUgdGhlIG9wZXJhdGlvbiBkdWUgdG8gZXJyb3IgYzAwYzAyM2ZcIlxuICAgIHZhciBzdGF0dXM7XG4gICAgdHJ5IHsgc3RhdHVzID0geGhyLnN0YXR1cyB9IGNhdGNoKGUpIHsgc3RhdHVzID0gMDsgfVxuXG4gICAgaWYgKDAgPT0gc3RhdHVzKSB7XG4gICAgICBpZiAoc2VsZi50aW1lZG91dCkgcmV0dXJuIHNlbGYudGltZW91dEVycm9yKCk7XG4gICAgICBpZiAoc2VsZi5hYm9ydGVkKSByZXR1cm47XG4gICAgICByZXR1cm4gc2VsZi5jcm9zc0RvbWFpbkVycm9yKCk7XG4gICAgfVxuICAgIHNlbGYuZW1pdCgnZW5kJyk7XG4gIH07XG5cbiAgLy8gcHJvZ3Jlc3NcbiAgdmFyIGhhbmRsZVByb2dyZXNzID0gZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUudG90YWwgPiAwKSB7XG4gICAgICBlLnBlcmNlbnQgPSBlLmxvYWRlZCAvIGUudG90YWwgKiAxMDA7XG4gICAgfVxuICAgIGUuZGlyZWN0aW9uID0gJ2Rvd25sb2FkJztcbiAgICBzZWxmLmVtaXQoJ3Byb2dyZXNzJywgZSk7XG4gIH07XG4gIGlmICh0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgIHhoci5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gIH1cbiAgdHJ5IHtcbiAgICBpZiAoeGhyLnVwbG9hZCAmJiB0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgICAgeGhyLnVwbG9hZC5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gICAgfVxuICB9IGNhdGNoKGUpIHtcbiAgICAvLyBBY2Nlc3NpbmcgeGhyLnVwbG9hZCBmYWlscyBpbiBJRSBmcm9tIGEgd2ViIHdvcmtlciwgc28ganVzdCBwcmV0ZW5kIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgLy8gUmVwb3J0ZWQgaGVyZTpcbiAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgzNzI0NS94bWxodHRwcmVxdWVzdC11cGxvYWQtdGhyb3dzLWludmFsaWQtYXJndW1lbnQtd2hlbi11c2VkLWZyb20td2ViLXdvcmtlci1jb250ZXh0XG4gIH1cblxuICAvLyB0aW1lb3V0XG4gIGlmICh0aW1lb3V0ICYmICF0aGlzLl90aW1lcikge1xuICAgIHRoaXMuX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgc2VsZi50aW1lZG91dCA9IHRydWU7XG4gICAgICBzZWxmLmFib3J0KCk7XG4gICAgfSwgdGltZW91dCk7XG4gIH1cblxuICAvLyBxdWVyeXN0cmluZ1xuICBpZiAocXVlcnkpIHtcbiAgICBxdWVyeSA9IHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0KHF1ZXJ5KTtcbiAgICB0aGlzLnVybCArPSB+dGhpcy51cmwuaW5kZXhPZignPycpXG4gICAgICA/ICcmJyArIHF1ZXJ5XG4gICAgICA6ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgLy8gaW5pdGlhdGUgcmVxdWVzdFxuICBpZiAodGhpcy51c2VybmFtZSAmJiB0aGlzLnBhc3N3b3JkKSB7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJsLCB0cnVlLCB0aGlzLnVzZXJuYW1lLCB0aGlzLnBhc3N3b3JkKTtcbiAgfSBlbHNlIHtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHRydWUpO1xuICB9XG5cbiAgLy8gQ09SU1xuICBpZiAodGhpcy5fd2l0aENyZWRlbnRpYWxzKSB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblxuICAvLyBib2R5XG4gIGlmICgnR0VUJyAhPSB0aGlzLm1ldGhvZCAmJiAnSEVBRCcgIT0gdGhpcy5tZXRob2QgJiYgJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgJiYgIWlzSG9zdChkYXRhKSkge1xuICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgdmFyIHNlcmlhbGl6ZSA9IHRoaXMuX3BhcnNlciB8fCByZXF1ZXN0LnNlcmlhbGl6ZVtjb250ZW50VHlwZSA/IGNvbnRlbnRUeXBlLnNwbGl0KCc7JylbMF0gOiAnJ107XG4gICAgaWYgKCFzZXJpYWxpemUgJiYgaXNKU09OKGNvbnRlbnRUeXBlKSkgc2VyaWFsaXplID0gcmVxdWVzdC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgICBpZiAoc2VyaWFsaXplKSBkYXRhID0gc2VyaWFsaXplKGRhdGEpO1xuICB9XG5cbiAgLy8gc2V0IGhlYWRlciBmaWVsZHNcbiAgZm9yICh2YXIgZmllbGQgaW4gdGhpcy5oZWFkZXIpIHtcbiAgICBpZiAobnVsbCA9PSB0aGlzLmhlYWRlcltmaWVsZF0pIGNvbnRpbnVlO1xuICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGZpZWxkLCB0aGlzLmhlYWRlcltmaWVsZF0pO1xuICB9XG5cbiAgaWYgKHRoaXMuX3Jlc3BvbnNlVHlwZSkge1xuICAgIHhoci5yZXNwb25zZVR5cGUgPSB0aGlzLl9yZXNwb25zZVR5cGU7XG4gIH1cblxuICAvLyBzZW5kIHN0dWZmXG4gIHRoaXMuZW1pdCgncmVxdWVzdCcsIHRoaXMpO1xuXG4gIC8vIElFMTEgeGhyLnNlbmQodW5kZWZpbmVkKSBzZW5kcyAndW5kZWZpbmVkJyBzdHJpbmcgYXMgUE9TVCBwYXlsb2FkIChpbnN0ZWFkIG9mIG5vdGhpbmcpXG4gIC8vIFdlIG5lZWQgbnVsbCBoZXJlIGlmIGRhdGEgaXMgdW5kZWZpbmVkXG4gIHhoci5zZW5kKHR5cGVvZiBkYXRhICE9PSAndW5kZWZpbmVkJyA/IGRhdGEgOiBudWxsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogRXhwb3NlIGBSZXF1ZXN0YC5cbiAqL1xuXG5yZXF1ZXN0LlJlcXVlc3QgPSBSZXF1ZXN0O1xuXG4vKipcbiAqIEdFVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBkYXRhIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5nZXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0dFVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnF1ZXJ5KGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBIRUFEIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmhlYWQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0hFQUQnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBERUxFVEUgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlbCh1cmwsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0RFTEVURScsIHVybCk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG5yZXF1ZXN0WydkZWwnXSA9IGRlbDtcbnJlcXVlc3RbJ2RlbGV0ZSddID0gZGVsO1xuXG4vKipcbiAqIFBBVENIIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucGF0Y2ggPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BBVENIJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogUE9TVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBvc3QgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BPU1QnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQVVQgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBkYXRhIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wdXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BVVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuIiwiLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICByZXR1cm4gbnVsbCAhPSBvYmogJiYgJ29iamVjdCcgPT0gdHlwZW9mIG9iajtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogTW9kdWxlIG9mIG1peGVkLWluIGZ1bmN0aW9ucyBzaGFyZWQgYmV0d2VlbiBub2RlIGFuZCBjbGllbnQgY29kZVxuICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIENsZWFyIHByZXZpb3VzIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gX2NsZWFyVGltZW91dCgpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZvcmNlIGdpdmVuIHBhcnNlclxuICpcbiAqIFNldHMgdGhlIGJvZHkgcGFyc2VyIG5vIG1hdHRlciB0eXBlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShmbil7XG4gIHRoaXMuX3BhcnNlciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnRpbWVvdXQgPSBmdW5jdGlvbiB0aW1lb3V0KG1zKXtcbiAgdGhpcy5fdGltZW91dCA9IG1zO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRmF1eCBwcm9taXNlIHN1cHBvcnRcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdWxmaWxsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKi9cblxuZXhwb3J0cy50aGVuID0gZnVuY3Rpb24gdGhlbihmdWxmaWxsLCByZWplY3QpIHtcbiAgcmV0dXJuIHRoaXMuZW5kKGZ1bmN0aW9uKGVyciwgcmVzKSB7XG4gICAgZXJyID8gcmVqZWN0KGVycikgOiBmdWxmaWxsKHJlcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEFsbG93IGZvciBleHRlbnNpb25cbiAqL1xuXG5leHBvcnRzLnVzZSA9IGZ1bmN0aW9uIHVzZShmbikge1xuICBmbih0aGlzKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBHZXQgcmVxdWVzdCBoZWFkZXIgYGZpZWxkYC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZ2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBHZXQgY2FzZS1pbnNlbnNpdGl2ZSBoZWFkZXIgYGZpZWxkYCB2YWx1ZS5cbiAqIFRoaXMgaXMgYSBkZXByZWNhdGVkIGludGVybmFsIEFQSS4gVXNlIGAuZ2V0KGZpZWxkKWAgaW5zdGVhZC5cbiAqXG4gKiAoZ2V0SGVhZGVyIGlzIG5vIGxvbmdlciB1c2VkIGludGVybmFsbHkgYnkgdGhlIHN1cGVyYWdlbnQgY29kZSBiYXNlKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKiBAZGVwcmVjYXRlZFxuICovXG5cbmV4cG9ydHMuZ2V0SGVhZGVyID0gZXhwb3J0cy5nZXQ7XG5cbi8qKlxuICogU2V0IGhlYWRlciBgZmllbGRgIHRvIGB2YWxgLCBvciBtdWx0aXBsZSBmaWVsZHMgd2l0aCBvbmUgb2JqZWN0LlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2V0KCdYLUFQSS1LZXknLCAnZm9vYmFyJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoeyBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJywgJ1gtQVBJLUtleSc6ICdmb29iYXInIH0pXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBmaWVsZFxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuc2V0ID0gZnVuY3Rpb24oZmllbGQsIHZhbCl7XG4gIGlmIChpc09iamVjdChmaWVsZCkpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gZmllbGQpIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgZmllbGRba2V5XSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXSA9IHZhbDtcbiAgdGhpcy5oZWFkZXJbZmllbGRdID0gdmFsO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGhlYWRlciBgZmllbGRgLlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnVuc2V0KCdVc2VyLUFnZW50JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqL1xuZXhwb3J0cy51bnNldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgZGVsZXRlIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbiAgZGVsZXRlIHRoaXMuaGVhZGVyW2ZpZWxkXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFdyaXRlIHRoZSBmaWVsZCBgbmFtZWAgYW5kIGB2YWxgIGZvciBcIm11bHRpcGFydC9mb3JtLWRhdGFcIlxuICogcmVxdWVzdCBib2RpZXMuXG4gKlxuICogYGBgIGpzXG4gKiByZXF1ZXN0LnBvc3QoJy91cGxvYWQnKVxuICogICAuZmllbGQoJ2ZvbycsICdiYXInKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge1N0cmluZ3xCbG9ifEZpbGV8QnVmZmVyfGZzLlJlYWRTdHJlYW19IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5leHBvcnRzLmZpZWxkID0gZnVuY3Rpb24obmFtZSwgdmFsKSB7XG4gIHRoaXMuX2dldEZvcm1EYXRhKCkuYXBwZW5kKG5hbWUsIHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcbiIsIi8vIFRoZSBub2RlIGFuZCBicm93c2VyIG1vZHVsZXMgZXhwb3NlIHZlcnNpb25zIG9mIHRoaXMgd2l0aCB0aGVcbi8vIGFwcHJvcHJpYXRlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIGJvdW5kIGFzIGZpcnN0IGFyZ3VtZW50XG4vKipcbiAqIElzc3VlIGEgcmVxdWVzdDpcbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICByZXF1ZXN0KCdHRVQnLCAnL3VzZXJzJykuZW5kKGNhbGxiYWNrKVxuICogICAgcmVxdWVzdCgnL3VzZXJzJykuZW5kKGNhbGxiYWNrKVxuICogICAgcmVxdWVzdCgnL3VzZXJzJywgY2FsbGJhY2spXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHVybCBvciBjYWxsYmFja1xuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gcmVxdWVzdChSZXF1ZXN0Q29uc3RydWN0b3IsIG1ldGhvZCwgdXJsKSB7XG4gIC8vIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1cmwpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3RDb25zdHJ1Y3RvcignR0VUJywgbWV0aG9kKS5lbmQodXJsKTtcbiAgfVxuXG4gIC8vIHVybCBmaXJzdFxuICBpZiAoMiA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0Q29uc3RydWN0b3IoJ0dFVCcsIG1ldGhvZCk7XG4gIH1cblxuICByZXR1cm4gbmV3IFJlcXVlc3RDb25zdHJ1Y3RvcihtZXRob2QsIHVybCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWVzdDtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90b0RhdGUgPSByZXF1aXJlKCcuL2xpYi90b0RhdGUnKTtcblxudmFyIF90b0RhdGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdG9EYXRlKTtcblxudmFyIF90b0Zsb2F0ID0gcmVxdWlyZSgnLi9saWIvdG9GbG9hdCcpO1xuXG52YXIgX3RvRmxvYXQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdG9GbG9hdCk7XG5cbnZhciBfdG9JbnQgPSByZXF1aXJlKCcuL2xpYi90b0ludCcpO1xuXG52YXIgX3RvSW50MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3RvSW50KTtcblxudmFyIF90b0Jvb2xlYW4gPSByZXF1aXJlKCcuL2xpYi90b0Jvb2xlYW4nKTtcblxudmFyIF90b0Jvb2xlYW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdG9Cb29sZWFuKTtcblxudmFyIF9lcXVhbHMgPSByZXF1aXJlKCcuL2xpYi9lcXVhbHMnKTtcblxudmFyIF9lcXVhbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXF1YWxzKTtcblxudmFyIF9jb250YWlucyA9IHJlcXVpcmUoJy4vbGliL2NvbnRhaW5zJyk7XG5cbnZhciBfY29udGFpbnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY29udGFpbnMpO1xuXG52YXIgX21hdGNoZXMgPSByZXF1aXJlKCcuL2xpYi9tYXRjaGVzJyk7XG5cbnZhciBfbWF0Y2hlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tYXRjaGVzKTtcblxudmFyIF9pc0VtYWlsID0gcmVxdWlyZSgnLi9saWIvaXNFbWFpbCcpO1xuXG52YXIgX2lzRW1haWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNFbWFpbCk7XG5cbnZhciBfaXNVUkwgPSByZXF1aXJlKCcuL2xpYi9pc1VSTCcpO1xuXG52YXIgX2lzVVJMMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzVVJMKTtcblxudmFyIF9pc01BQ0FkZHJlc3MgPSByZXF1aXJlKCcuL2xpYi9pc01BQ0FkZHJlc3MnKTtcblxudmFyIF9pc01BQ0FkZHJlc3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNNQUNBZGRyZXNzKTtcblxudmFyIF9pc0lQID0gcmVxdWlyZSgnLi9saWIvaXNJUCcpO1xuXG52YXIgX2lzSVAyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJUCk7XG5cbnZhciBfaXNGUUROID0gcmVxdWlyZSgnLi9saWIvaXNGUUROJyk7XG5cbnZhciBfaXNGUUROMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzRlFETik7XG5cbnZhciBfaXNCb29sZWFuID0gcmVxdWlyZSgnLi9saWIvaXNCb29sZWFuJyk7XG5cbnZhciBfaXNCb29sZWFuMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzQm9vbGVhbik7XG5cbnZhciBfaXNBbHBoYSA9IHJlcXVpcmUoJy4vbGliL2lzQWxwaGEnKTtcblxudmFyIF9pc0FscGhhMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzQWxwaGEpO1xuXG52YXIgX2lzQWxwaGFudW1lcmljID0gcmVxdWlyZSgnLi9saWIvaXNBbHBoYW51bWVyaWMnKTtcblxudmFyIF9pc0FscGhhbnVtZXJpYzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0FscGhhbnVtZXJpYyk7XG5cbnZhciBfaXNOdW1lcmljID0gcmVxdWlyZSgnLi9saWIvaXNOdW1lcmljJyk7XG5cbnZhciBfaXNOdW1lcmljMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzTnVtZXJpYyk7XG5cbnZhciBfaXNMb3dlcmNhc2UgPSByZXF1aXJlKCcuL2xpYi9pc0xvd2VyY2FzZScpO1xuXG52YXIgX2lzTG93ZXJjYXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzTG93ZXJjYXNlKTtcblxudmFyIF9pc1VwcGVyY2FzZSA9IHJlcXVpcmUoJy4vbGliL2lzVXBwZXJjYXNlJyk7XG5cbnZhciBfaXNVcHBlcmNhc2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNVcHBlcmNhc2UpO1xuXG52YXIgX2lzQXNjaWkgPSByZXF1aXJlKCcuL2xpYi9pc0FzY2lpJyk7XG5cbnZhciBfaXNBc2NpaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0FzY2lpKTtcblxudmFyIF9pc0Z1bGxXaWR0aCA9IHJlcXVpcmUoJy4vbGliL2lzRnVsbFdpZHRoJyk7XG5cbnZhciBfaXNGdWxsV2lkdGgyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNGdWxsV2lkdGgpO1xuXG52YXIgX2lzSGFsZldpZHRoID0gcmVxdWlyZSgnLi9saWIvaXNIYWxmV2lkdGgnKTtcblxudmFyIF9pc0hhbGZXaWR0aDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0hhbGZXaWR0aCk7XG5cbnZhciBfaXNWYXJpYWJsZVdpZHRoID0gcmVxdWlyZSgnLi9saWIvaXNWYXJpYWJsZVdpZHRoJyk7XG5cbnZhciBfaXNWYXJpYWJsZVdpZHRoMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzVmFyaWFibGVXaWR0aCk7XG5cbnZhciBfaXNNdWx0aWJ5dGUgPSByZXF1aXJlKCcuL2xpYi9pc011bHRpYnl0ZScpO1xuXG52YXIgX2lzTXVsdGlieXRlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzTXVsdGlieXRlKTtcblxudmFyIF9pc1N1cnJvZ2F0ZVBhaXIgPSByZXF1aXJlKCcuL2xpYi9pc1N1cnJvZ2F0ZVBhaXInKTtcblxudmFyIF9pc1N1cnJvZ2F0ZVBhaXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNTdXJyb2dhdGVQYWlyKTtcblxudmFyIF9pc0ludCA9IHJlcXVpcmUoJy4vbGliL2lzSW50Jyk7XG5cbnZhciBfaXNJbnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJbnQpO1xuXG52YXIgX2lzRmxvYXQgPSByZXF1aXJlKCcuL2xpYi9pc0Zsb2F0Jyk7XG5cbnZhciBfaXNGbG9hdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0Zsb2F0KTtcblxudmFyIF9pc0RlY2ltYWwgPSByZXF1aXJlKCcuL2xpYi9pc0RlY2ltYWwnKTtcblxudmFyIF9pc0RlY2ltYWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNEZWNpbWFsKTtcblxudmFyIF9pc0hleGFkZWNpbWFsID0gcmVxdWlyZSgnLi9saWIvaXNIZXhhZGVjaW1hbCcpO1xuXG52YXIgX2lzSGV4YWRlY2ltYWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNIZXhhZGVjaW1hbCk7XG5cbnZhciBfaXNEaXZpc2libGVCeSA9IHJlcXVpcmUoJy4vbGliL2lzRGl2aXNpYmxlQnknKTtcblxudmFyIF9pc0RpdmlzaWJsZUJ5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzRGl2aXNpYmxlQnkpO1xuXG52YXIgX2lzSGV4Q29sb3IgPSByZXF1aXJlKCcuL2xpYi9pc0hleENvbG9yJyk7XG5cbnZhciBfaXNIZXhDb2xvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0hleENvbG9yKTtcblxudmFyIF9pc01EID0gcmVxdWlyZSgnLi9saWIvaXNNRDUnKTtcblxudmFyIF9pc01EMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzTUQpO1xuXG52YXIgX2lzSlNPTiA9IHJlcXVpcmUoJy4vbGliL2lzSlNPTicpO1xuXG52YXIgX2lzSlNPTjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0pTT04pO1xuXG52YXIgX2lzRW1wdHkgPSByZXF1aXJlKCcuL2xpYi9pc0VtcHR5Jyk7XG5cbnZhciBfaXNFbXB0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0VtcHR5KTtcblxudmFyIF9pc0xlbmd0aCA9IHJlcXVpcmUoJy4vbGliL2lzTGVuZ3RoJyk7XG5cbnZhciBfaXNMZW5ndGgyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNMZW5ndGgpO1xuXG52YXIgX2lzQnl0ZUxlbmd0aCA9IHJlcXVpcmUoJy4vbGliL2lzQnl0ZUxlbmd0aCcpO1xuXG52YXIgX2lzQnl0ZUxlbmd0aDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0J5dGVMZW5ndGgpO1xuXG52YXIgX2lzVVVJRCA9IHJlcXVpcmUoJy4vbGliL2lzVVVJRCcpO1xuXG52YXIgX2lzVVVJRDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc1VVSUQpO1xuXG52YXIgX2lzTW9uZ29JZCA9IHJlcXVpcmUoJy4vbGliL2lzTW9uZ29JZCcpO1xuXG52YXIgX2lzTW9uZ29JZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc01vbmdvSWQpO1xuXG52YXIgX2lzRGF0ZSA9IHJlcXVpcmUoJy4vbGliL2lzRGF0ZScpO1xuXG52YXIgX2lzRGF0ZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0RhdGUpO1xuXG52YXIgX2lzQWZ0ZXIgPSByZXF1aXJlKCcuL2xpYi9pc0FmdGVyJyk7XG5cbnZhciBfaXNBZnRlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0FmdGVyKTtcblxudmFyIF9pc0JlZm9yZSA9IHJlcXVpcmUoJy4vbGliL2lzQmVmb3JlJyk7XG5cbnZhciBfaXNCZWZvcmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNCZWZvcmUpO1xuXG52YXIgX2lzSW4gPSByZXF1aXJlKCcuL2xpYi9pc0luJyk7XG5cbnZhciBfaXNJbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0luKTtcblxudmFyIF9pc0NyZWRpdENhcmQgPSByZXF1aXJlKCcuL2xpYi9pc0NyZWRpdENhcmQnKTtcblxudmFyIF9pc0NyZWRpdENhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNDcmVkaXRDYXJkKTtcblxudmFyIF9pc0lTSU4gPSByZXF1aXJlKCcuL2xpYi9pc0lTSU4nKTtcblxudmFyIF9pc0lTSU4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJU0lOKTtcblxudmFyIF9pc0lTQk4gPSByZXF1aXJlKCcuL2xpYi9pc0lTQk4nKTtcblxudmFyIF9pc0lTQk4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJU0JOKTtcblxudmFyIF9pc0lTU04gPSByZXF1aXJlKCcuL2xpYi9pc0lTU04nKTtcblxudmFyIF9pc0lTU04yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJU1NOKTtcblxudmFyIF9pc01vYmlsZVBob25lID0gcmVxdWlyZSgnLi9saWIvaXNNb2JpbGVQaG9uZScpO1xuXG52YXIgX2lzTW9iaWxlUGhvbmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNNb2JpbGVQaG9uZSk7XG5cbnZhciBfaXNDdXJyZW5jeSA9IHJlcXVpcmUoJy4vbGliL2lzQ3VycmVuY3knKTtcblxudmFyIF9pc0N1cnJlbmN5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzQ3VycmVuY3kpO1xuXG52YXIgX2lzSVNPID0gcmVxdWlyZSgnLi9saWIvaXNJU084NjAxJyk7XG5cbnZhciBfaXNJU08yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJU08pO1xuXG52YXIgX2lzQmFzZSA9IHJlcXVpcmUoJy4vbGliL2lzQmFzZTY0Jyk7XG5cbnZhciBfaXNCYXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzQmFzZSk7XG5cbnZhciBfaXNEYXRhVVJJID0gcmVxdWlyZSgnLi9saWIvaXNEYXRhVVJJJyk7XG5cbnZhciBfaXNEYXRhVVJJMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzRGF0YVVSSSk7XG5cbnZhciBfbHRyaW0gPSByZXF1aXJlKCcuL2xpYi9sdHJpbScpO1xuXG52YXIgX2x0cmltMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2x0cmltKTtcblxudmFyIF9ydHJpbSA9IHJlcXVpcmUoJy4vbGliL3J0cmltJyk7XG5cbnZhciBfcnRyaW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcnRyaW0pO1xuXG52YXIgX3RyaW0gPSByZXF1aXJlKCcuL2xpYi90cmltJyk7XG5cbnZhciBfdHJpbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90cmltKTtcblxudmFyIF9lc2NhcGUgPSByZXF1aXJlKCcuL2xpYi9lc2NhcGUnKTtcblxudmFyIF9lc2NhcGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXNjYXBlKTtcblxudmFyIF91bmVzY2FwZSA9IHJlcXVpcmUoJy4vbGliL3VuZXNjYXBlJyk7XG5cbnZhciBfdW5lc2NhcGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdW5lc2NhcGUpO1xuXG52YXIgX3N0cmlwTG93ID0gcmVxdWlyZSgnLi9saWIvc3RyaXBMb3cnKTtcblxudmFyIF9zdHJpcExvdzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zdHJpcExvdyk7XG5cbnZhciBfd2hpdGVsaXN0ID0gcmVxdWlyZSgnLi9saWIvd2hpdGVsaXN0Jyk7XG5cbnZhciBfd2hpdGVsaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3doaXRlbGlzdCk7XG5cbnZhciBfYmxhY2tsaXN0ID0gcmVxdWlyZSgnLi9saWIvYmxhY2tsaXN0Jyk7XG5cbnZhciBfYmxhY2tsaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JsYWNrbGlzdCk7XG5cbnZhciBfaXNXaGl0ZWxpc3RlZCA9IHJlcXVpcmUoJy4vbGliL2lzV2hpdGVsaXN0ZWQnKTtcblxudmFyIF9pc1doaXRlbGlzdGVkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzV2hpdGVsaXN0ZWQpO1xuXG52YXIgX25vcm1hbGl6ZUVtYWlsID0gcmVxdWlyZSgnLi9saWIvbm9ybWFsaXplRW1haWwnKTtcblxudmFyIF9ub3JtYWxpemVFbWFpbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9ub3JtYWxpemVFbWFpbCk7XG5cbnZhciBfdG9TdHJpbmcgPSByZXF1aXJlKCcuL2xpYi91dGlsL3RvU3RyaW5nJyk7XG5cbnZhciBfdG9TdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdG9TdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgdmVyc2lvbiA9ICc2LjMuMCc7XG5cbnZhciB2YWxpZGF0b3IgPSB7XG4gIHZlcnNpb246IHZlcnNpb24sXG4gIHRvRGF0ZTogX3RvRGF0ZTIuZGVmYXVsdCxcbiAgdG9GbG9hdDogX3RvRmxvYXQyLmRlZmF1bHQsXG4gIHRvSW50OiBfdG9JbnQyLmRlZmF1bHQsXG4gIHRvQm9vbGVhbjogX3RvQm9vbGVhbjIuZGVmYXVsdCxcbiAgZXF1YWxzOiBfZXF1YWxzMi5kZWZhdWx0LFxuICBjb250YWluczogX2NvbnRhaW5zMi5kZWZhdWx0LFxuICBtYXRjaGVzOiBfbWF0Y2hlczIuZGVmYXVsdCxcbiAgaXNFbWFpbDogX2lzRW1haWwyLmRlZmF1bHQsXG4gIGlzVVJMOiBfaXNVUkwyLmRlZmF1bHQsXG4gIGlzTUFDQWRkcmVzczogX2lzTUFDQWRkcmVzczIuZGVmYXVsdCxcbiAgaXNJUDogX2lzSVAyLmRlZmF1bHQsXG4gIGlzRlFETjogX2lzRlFETjIuZGVmYXVsdCxcbiAgaXNCb29sZWFuOiBfaXNCb29sZWFuMi5kZWZhdWx0LFxuICBpc0FscGhhOiBfaXNBbHBoYTIuZGVmYXVsdCxcbiAgaXNBbHBoYW51bWVyaWM6IF9pc0FscGhhbnVtZXJpYzIuZGVmYXVsdCxcbiAgaXNOdW1lcmljOiBfaXNOdW1lcmljMi5kZWZhdWx0LFxuICBpc0xvd2VyY2FzZTogX2lzTG93ZXJjYXNlMi5kZWZhdWx0LFxuICBpc1VwcGVyY2FzZTogX2lzVXBwZXJjYXNlMi5kZWZhdWx0LFxuICBpc0FzY2lpOiBfaXNBc2NpaTIuZGVmYXVsdCxcbiAgaXNGdWxsV2lkdGg6IF9pc0Z1bGxXaWR0aDIuZGVmYXVsdCxcbiAgaXNIYWxmV2lkdGg6IF9pc0hhbGZXaWR0aDIuZGVmYXVsdCxcbiAgaXNWYXJpYWJsZVdpZHRoOiBfaXNWYXJpYWJsZVdpZHRoMi5kZWZhdWx0LFxuICBpc011bHRpYnl0ZTogX2lzTXVsdGlieXRlMi5kZWZhdWx0LFxuICBpc1N1cnJvZ2F0ZVBhaXI6IF9pc1N1cnJvZ2F0ZVBhaXIyLmRlZmF1bHQsXG4gIGlzSW50OiBfaXNJbnQyLmRlZmF1bHQsXG4gIGlzRmxvYXQ6IF9pc0Zsb2F0Mi5kZWZhdWx0LFxuICBpc0RlY2ltYWw6IF9pc0RlY2ltYWwyLmRlZmF1bHQsXG4gIGlzSGV4YWRlY2ltYWw6IF9pc0hleGFkZWNpbWFsMi5kZWZhdWx0LFxuICBpc0RpdmlzaWJsZUJ5OiBfaXNEaXZpc2libGVCeTIuZGVmYXVsdCxcbiAgaXNIZXhDb2xvcjogX2lzSGV4Q29sb3IyLmRlZmF1bHQsXG4gIGlzTUQ1OiBfaXNNRDIuZGVmYXVsdCxcbiAgaXNKU09OOiBfaXNKU09OMi5kZWZhdWx0LFxuICBpc0VtcHR5OiBfaXNFbXB0eTIuZGVmYXVsdCxcbiAgaXNMZW5ndGg6IF9pc0xlbmd0aDIuZGVmYXVsdCxcbiAgaXNCeXRlTGVuZ3RoOiBfaXNCeXRlTGVuZ3RoMi5kZWZhdWx0LFxuICBpc1VVSUQ6IF9pc1VVSUQyLmRlZmF1bHQsXG4gIGlzTW9uZ29JZDogX2lzTW9uZ29JZDIuZGVmYXVsdCxcbiAgaXNEYXRlOiBfaXNEYXRlMi5kZWZhdWx0LFxuICBpc0FmdGVyOiBfaXNBZnRlcjIuZGVmYXVsdCxcbiAgaXNCZWZvcmU6IF9pc0JlZm9yZTIuZGVmYXVsdCxcbiAgaXNJbjogX2lzSW4yLmRlZmF1bHQsXG4gIGlzQ3JlZGl0Q2FyZDogX2lzQ3JlZGl0Q2FyZDIuZGVmYXVsdCxcbiAgaXNJU0lOOiBfaXNJU0lOMi5kZWZhdWx0LFxuICBpc0lTQk46IF9pc0lTQk4yLmRlZmF1bHQsXG4gIGlzSVNTTjogX2lzSVNTTjIuZGVmYXVsdCxcbiAgaXNNb2JpbGVQaG9uZTogX2lzTW9iaWxlUGhvbmUyLmRlZmF1bHQsXG4gIGlzQ3VycmVuY3k6IF9pc0N1cnJlbmN5Mi5kZWZhdWx0LFxuICBpc0lTTzg2MDE6IF9pc0lTTzIuZGVmYXVsdCxcbiAgaXNCYXNlNjQ6IF9pc0Jhc2UyLmRlZmF1bHQsXG4gIGlzRGF0YVVSSTogX2lzRGF0YVVSSTIuZGVmYXVsdCxcbiAgbHRyaW06IF9sdHJpbTIuZGVmYXVsdCxcbiAgcnRyaW06IF9ydHJpbTIuZGVmYXVsdCxcbiAgdHJpbTogX3RyaW0yLmRlZmF1bHQsXG4gIGVzY2FwZTogX2VzY2FwZTIuZGVmYXVsdCxcbiAgdW5lc2NhcGU6IF91bmVzY2FwZTIuZGVmYXVsdCxcbiAgc3RyaXBMb3c6IF9zdHJpcExvdzIuZGVmYXVsdCxcbiAgd2hpdGVsaXN0OiBfd2hpdGVsaXN0Mi5kZWZhdWx0LFxuICBibGFja2xpc3Q6IF9ibGFja2xpc3QyLmRlZmF1bHQsXG4gIGlzV2hpdGVsaXN0ZWQ6IF9pc1doaXRlbGlzdGVkMi5kZWZhdWx0LFxuICBub3JtYWxpemVFbWFpbDogX25vcm1hbGl6ZUVtYWlsMi5kZWZhdWx0LFxuICB0b1N0cmluZzogX3RvU3RyaW5nMi5kZWZhdWx0XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSB2YWxpZGF0b3I7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG52YXIgYWxwaGEgPSBleHBvcnRzLmFscGhhID0ge1xuICAnZW4tVVMnOiAvXltBLVpdKyQvaSxcbiAgJ2NzLUNaJzogL15bQS1aw4HEjMSOw4nEmsONxYfDk8WYxaDFpMOaxa7DncW9XSskL2ksXG4gICdkYS1ESyc6IC9eW0EtWsOGw5jDhV0rJC9pLFxuICAnZGUtREUnOiAvXltBLVrDhMOWw5zDn10rJC9pLFxuICAnZXMtRVMnOiAvXltBLVrDgcOJw43DkcOTw5rDnF0rJC9pLFxuICAnZnItRlInOiAvXltBLVrDgMOCw4bDh8OJw4jDisOLw4/DjsOUxZLDmcObw5zFuF0rJC9pLFxuICAnbmwtTkwnOiAvXltBLVrDicOLw4/Dk8OWw5xdKyQvaSxcbiAgJ2h1LUhVJzogL15bQS1aw4HDicONw5PDlsWQw5rDnMWwXSskL2ksXG4gICdwbC1QTCc6IC9eW0EtWsSExIbEmMWaxYHFg8OTxbvFuV0rJC9pLFxuICAncHQtUFQnOiAvXltBLVrDg8OBw4DDgsOHw4nDisONw5XDk8OUw5rDnF0rJC9pLFxuICAncnUtUlUnOiAvXlvQkC3Qr9CBXSskL2ksXG4gICdzci1SU0BsYXRpbic6IC9eW0EtWsSMxIbFvcWgxJBdKyQvaSxcbiAgJ3NyLVJTJzogL15b0JAt0K/QgtCI0InQitCL0I9dKyQvaSxcbiAgJ3RyLVRSJzogL15bQS1aw4fEnsSwxLHDlsWew5xdKyQvaSxcbiAgJ3VrLVVBJzogL15b0JAt0K/QhEnQh9KQXSskL2ksXG4gIGFyOiAvXlvYodii2KPYpNil2KbYp9io2KnYqtir2KzYrdiu2K/YsNix2LLYs9i02LXYtti32LjYudi62YHZgtmD2YTZhdmG2YfZiNmJ2YrZi9mM2Y3ZjtmP2ZDZkdmS2bBdKyQvXG59O1xuXG52YXIgYWxwaGFudW1lcmljID0gZXhwb3J0cy5hbHBoYW51bWVyaWMgPSB7XG4gICdlbi1VUyc6IC9eWzAtOUEtWl0rJC9pLFxuICAnY3MtQ1onOiAvXlswLTlBLVrDgcSMxI7DicSaw43Fh8OTxZjFoMWkw5rFrsOdxb1dKyQvaSxcbiAgJ2RhLURLJzogL15bMC05QS1aw4bDmMOFXSQvaSxcbiAgJ2RlLURFJzogL15bMC05QS1aw4TDlsOcw59dKyQvaSxcbiAgJ2VzLUVTJzogL15bMC05QS1aw4HDicONw5HDk8Oaw5xdKyQvaSxcbiAgJ2ZyLUZSJzogL15bMC05QS1aw4DDgsOGw4fDicOIw4rDi8OPw47DlMWSw5nDm8OcxbhdKyQvaSxcbiAgJ2h1LUhVJzogL15bMC05QS1aw4HDicONw5PDlsWQw5rDnMWwXSskL2ksXG4gICdubC1OTCc6IC9eWzAtOUEtWsOJw4vDj8OTw5bDnF0rJC9pLFxuICAncGwtUEwnOiAvXlswLTlBLVrEhMSGxJjFmsWBxYPDk8W7xbldKyQvaSxcbiAgJ3B0LVBUJzogL15bMC05QS1aw4PDgcOAw4LDh8OJw4rDjcOVw5PDlMOaw5xdKyQvaSxcbiAgJ3J1LVJVJzogL15bMC050JAt0K/QgV0rJC9pLFxuICAnc3ItUlNAbGF0aW4nOiAvXlswLTlBLVrEjMSGxb3FoMSQXSskL2ksXG4gICdzci1SUyc6IC9eWzAtOdCQLdCv0ILQiNCJ0IrQi9CPXSskL2ksXG4gICd0ci1UUic6IC9eWzAtOUEtWsOHxJ7EsMSxw5bFnsOcXSskL2ksXG4gICd1ay1VQSc6IC9eWzAtOdCQLdCv0IRJ0IfSkF0rJC9pLFxuICBhcjogL15b2aDZodmi2aPZpNml2abZp9mo2akwLTnYodii2KPYpNil2KbYp9io2KnYqtir2KzYrdiu2K/YsNix2LLYs9i02LXYtti32LjYudi62YHZgtmD2YTZhdmG2YfZiNmJ2YrZi9mM2Y3ZjtmP2ZDZkdmS2bBdKyQvXG59O1xuXG52YXIgZW5nbGlzaExvY2FsZXMgPSBleHBvcnRzLmVuZ2xpc2hMb2NhbGVzID0gWydBVScsICdHQicsICdISycsICdJTicsICdOWicsICdaQScsICdaTSddO1xuXG5mb3IgKHZhciBsb2NhbGUsIGkgPSAwOyBpIDwgZW5nbGlzaExvY2FsZXMubGVuZ3RoOyBpKyspIHtcbiAgbG9jYWxlID0gJ2VuLScgKyBlbmdsaXNoTG9jYWxlc1tpXTtcbiAgYWxwaGFbbG9jYWxlXSA9IGFscGhhWydlbi1VUyddO1xuICBhbHBoYW51bWVyaWNbbG9jYWxlXSA9IGFscGhhbnVtZXJpY1snZW4tVVMnXTtcbn1cblxuYWxwaGFbJ3B0LUJSJ10gPSBhbHBoYVsncHQtUFQnXTtcbmFscGhhbnVtZXJpY1sncHQtQlInXSA9IGFscGhhbnVtZXJpY1sncHQtUFQnXTtcblxuLy8gU291cmNlOiBodHRwOi8vd3d3LmxvY2FsZXBsYW5ldC5jb20vamF2YS9cbnZhciBhcmFiaWNMb2NhbGVzID0gZXhwb3J0cy5hcmFiaWNMb2NhbGVzID0gWydBRScsICdCSCcsICdEWicsICdFRycsICdJUScsICdKTycsICdLVycsICdMQicsICdMWScsICdNQScsICdRTScsICdRQScsICdTQScsICdTRCcsICdTWScsICdUTicsICdZRSddO1xuXG5mb3IgKHZhciBfbG9jYWxlLCBfaSA9IDA7IF9pIDwgYXJhYmljTG9jYWxlcy5sZW5ndGg7IF9pKyspIHtcbiAgX2xvY2FsZSA9ICdhci0nICsgYXJhYmljTG9jYWxlc1tfaV07XG4gIGFscGhhW19sb2NhbGVdID0gYWxwaGEuYXI7XG4gIGFscGhhbnVtZXJpY1tfbG9jYWxlXSA9IGFscGhhbnVtZXJpYy5hcjtcbn0iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBibGFja2xpc3Q7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBibGFja2xpc3Qoc3RyLCBjaGFycykge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKG5ldyBSZWdFeHAoJ1snICsgY2hhcnMgKyAnXSsnLCAnZycpLCAnJyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBjb250YWlucztcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbnZhciBfdG9TdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvdG9TdHJpbmcnKTtcblxudmFyIF90b1N0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90b1N0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIGNvbnRhaW5zKHN0ciwgZWxlbSkge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN0ci5pbmRleE9mKCgwLCBfdG9TdHJpbmcyLmRlZmF1bHQpKGVsZW0pKSA+PSAwO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZXF1YWxzO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gZXF1YWxzKHN0ciwgY29tcGFyaXNvbikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN0ciA9PT0gY29tcGFyaXNvbjtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gICAgICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBlc2NhcGU7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBlc2NhcGUoc3RyKSB7XG4gICAgICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvJi9nLCAnJmFtcDsnKS5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JykucmVwbGFjZSgvJy9nLCAnJiN4Mjc7JykucmVwbGFjZSgvPC9nLCAnJmx0OycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC9cXC8vZywgJyYjeDJGOycpLnJlcGxhY2UoL1xcXFwvZywgJyYjeDVDOycpLnJlcGxhY2UoL2AvZywgJyYjOTY7Jyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0FmdGVyO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF90b0RhdGUgPSByZXF1aXJlKCcuL3RvRGF0ZScpO1xuXG52YXIgX3RvRGF0ZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90b0RhdGUpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc0FmdGVyKHN0cikge1xuICB2YXIgZGF0ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogU3RyaW5nKG5ldyBEYXRlKCkpO1xuXG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICB2YXIgY29tcGFyaXNvbiA9ICgwLCBfdG9EYXRlMi5kZWZhdWx0KShkYXRlKTtcbiAgdmFyIG9yaWdpbmFsID0gKDAsIF90b0RhdGUyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiAhIShvcmlnaW5hbCAmJiBjb21wYXJpc29uICYmIG9yaWdpbmFsID4gY29tcGFyaXNvbik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0FscGhhO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF9hbHBoYSA9IHJlcXVpcmUoJy4vYWxwaGEnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNBbHBoYShzdHIpIHtcbiAgdmFyIGxvY2FsZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJ2VuLVVTJztcblxuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgaWYgKGxvY2FsZSBpbiBfYWxwaGEuYWxwaGEpIHtcbiAgICByZXR1cm4gX2FscGhhLmFscGhhW2xvY2FsZV0udGVzdChzdHIpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBsb2NhbGUgXFwnJyArIGxvY2FsZSArICdcXCcnKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzQWxwaGFudW1lcmljO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF9hbHBoYSA9IHJlcXVpcmUoJy4vYWxwaGEnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNBbHBoYW51bWVyaWMoc3RyKSB7XG4gIHZhciBsb2NhbGUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICdlbi1VUyc7XG5cbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIGlmIChsb2NhbGUgaW4gX2FscGhhLmFscGhhbnVtZXJpYykge1xuICAgIHJldHVybiBfYWxwaGEuYWxwaGFudW1lcmljW2xvY2FsZV0udGVzdChzdHIpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBsb2NhbGUgXFwnJyArIGxvY2FsZSArICdcXCcnKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzQXNjaWk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1jb250cm9sLXJlZ2V4ICovXG52YXIgYXNjaWkgPSAvXltcXHgwMC1cXHg3Rl0rJC87XG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnRyb2wtcmVnZXggKi9cblxuZnVuY3Rpb24gaXNBc2NpaShzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBhc2NpaS50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0Jhc2U2NDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBub3RCYXNlNjQgPSAvW15BLVowLTkrXFwvPV0vaTtcblxuZnVuY3Rpb24gaXNCYXNlNjQoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICB2YXIgbGVuID0gc3RyLmxlbmd0aDtcbiAgaWYgKCFsZW4gfHwgbGVuICUgNCAhPT0gMCB8fCBub3RCYXNlNjQudGVzdChzdHIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBmaXJzdFBhZGRpbmdDaGFyID0gc3RyLmluZGV4T2YoJz0nKTtcbiAgcmV0dXJuIGZpcnN0UGFkZGluZ0NoYXIgPT09IC0xIHx8IGZpcnN0UGFkZGluZ0NoYXIgPT09IGxlbiAtIDEgfHwgZmlyc3RQYWRkaW5nQ2hhciA9PT0gbGVuIC0gMiAmJiBzdHJbbGVuIC0gMV0gPT09ICc9Jztcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzQmVmb3JlO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF90b0RhdGUgPSByZXF1aXJlKCcuL3RvRGF0ZScpO1xuXG52YXIgX3RvRGF0ZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90b0RhdGUpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc0JlZm9yZShzdHIpIHtcbiAgdmFyIGRhdGUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFN0cmluZyhuZXcgRGF0ZSgpKTtcblxuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmFyIGNvbXBhcmlzb24gPSAoMCwgX3RvRGF0ZTIuZGVmYXVsdCkoZGF0ZSk7XG4gIHZhciBvcmlnaW5hbCA9ICgwLCBfdG9EYXRlMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gISEob3JpZ2luYWwgJiYgY29tcGFyaXNvbiAmJiBvcmlnaW5hbCA8IGNvbXBhcmlzb24pO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNCb29sZWFuO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNCb29sZWFuKHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIFsndHJ1ZScsICdmYWxzZScsICcxJywgJzAnXS5pbmRleE9mKHN0cikgPj0gMDtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBpc0J5dGVMZW5ndGg7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBwcmVmZXItcmVzdC1wYXJhbXMgKi9cbmZ1bmN0aW9uIGlzQnl0ZUxlbmd0aChzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciBtaW4gPSB2b2lkIDA7XG4gIHZhciBtYXggPSB2b2lkIDA7XG4gIGlmICgodHlwZW9mIG9wdGlvbnMgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG9wdGlvbnMpKSA9PT0gJ29iamVjdCcpIHtcbiAgICBtaW4gPSBvcHRpb25zLm1pbiB8fCAwO1xuICAgIG1heCA9IG9wdGlvbnMubWF4O1xuICB9IGVsc2Uge1xuICAgIC8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5OiBpc0J5dGVMZW5ndGgoc3RyLCBtaW4gWywgbWF4XSlcbiAgICBtaW4gPSBhcmd1bWVudHNbMV07XG4gICAgbWF4ID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHZhciBsZW4gPSBlbmNvZGVVUkkoc3RyKS5zcGxpdCgvJS4ufC4vKS5sZW5ndGggLSAxO1xuICByZXR1cm4gbGVuID49IG1pbiAmJiAodHlwZW9mIG1heCA9PT0gJ3VuZGVmaW5lZCcgfHwgbGVuIDw9IG1heCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0NyZWRpdENhcmQ7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG52YXIgY3JlZGl0Q2FyZCA9IC9eKD86NFswLTldezEyfSg/OlswLTldezN9KT98NVsxLTVdWzAtOV17MTR9fCgyMjJbMS05XXwyMlszLTldWzAtOV18MlszLTZdWzAtOV17Mn18MjdbMDFdWzAtOV18MjcyMClbMC05XXsxMn18Nig/OjAxMXw1WzAtOV1bMC05XSlbMC05XXsxMn18M1s0N11bMC05XXsxM318Myg/OjBbMC01XXxbNjhdWzAtOV0pWzAtOV17MTF9fCg/OjIxMzF8MTgwMHwzNVxcZHszfSlcXGR7MTF9KXw2MlswLTldezE0fSQvO1xuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG5cbmZ1bmN0aW9uIGlzQ3JlZGl0Q2FyZChzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciBzYW5pdGl6ZWQgPSBzdHIucmVwbGFjZSgvW14wLTldKy9nLCAnJyk7XG4gIGlmICghY3JlZGl0Q2FyZC50ZXN0KHNhbml0aXplZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHN1bSA9IDA7XG4gIHZhciBkaWdpdCA9IHZvaWQgMDtcbiAgdmFyIHRtcE51bSA9IHZvaWQgMDtcbiAgdmFyIHNob3VsZERvdWJsZSA9IHZvaWQgMDtcbiAgZm9yICh2YXIgaSA9IHNhbml0aXplZC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGRpZ2l0ID0gc2FuaXRpemVkLnN1YnN0cmluZyhpLCBpICsgMSk7XG4gICAgdG1wTnVtID0gcGFyc2VJbnQoZGlnaXQsIDEwKTtcbiAgICBpZiAoc2hvdWxkRG91YmxlKSB7XG4gICAgICB0bXBOdW0gKj0gMjtcbiAgICAgIGlmICh0bXBOdW0gPj0gMTApIHtcbiAgICAgICAgc3VtICs9IHRtcE51bSAlIDEwICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1bSArPSB0bXBOdW07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1bSArPSB0bXBOdW07XG4gICAgfVxuICAgIHNob3VsZERvdWJsZSA9ICFzaG91bGREb3VibGU7XG4gIH1cbiAgcmV0dXJuICEhKHN1bSAlIDEwID09PSAwID8gc2FuaXRpemVkIDogZmFsc2UpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNDdXJyZW5jeTtcblxudmFyIF9tZXJnZSA9IHJlcXVpcmUoJy4vdXRpbC9tZXJnZScpO1xuXG52YXIgX21lcmdlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lcmdlKTtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIGN1cnJlbmN5UmVnZXgob3B0aW9ucykge1xuICB2YXIgc3ltYm9sID0gJyhcXFxcJyArIG9wdGlvbnMuc3ltYm9sLnJlcGxhY2UoL1xcLi9nLCAnXFxcXC4nKSArICcpJyArIChvcHRpb25zLnJlcXVpcmVfc3ltYm9sID8gJycgOiAnPycpLFxuICAgICAgbmVnYXRpdmUgPSAnLT8nLFxuICAgICAgd2hvbGVfZG9sbGFyX2Ftb3VudF93aXRob3V0X3NlcCA9ICdbMS05XVxcXFxkKicsXG4gICAgICB3aG9sZV9kb2xsYXJfYW1vdW50X3dpdGhfc2VwID0gJ1sxLTldXFxcXGR7MCwyfShcXFxcJyArIG9wdGlvbnMudGhvdXNhbmRzX3NlcGFyYXRvciArICdcXFxcZHszfSkqJyxcbiAgICAgIHZhbGlkX3dob2xlX2RvbGxhcl9hbW91bnRzID0gWycwJywgd2hvbGVfZG9sbGFyX2Ftb3VudF93aXRob3V0X3NlcCwgd2hvbGVfZG9sbGFyX2Ftb3VudF93aXRoX3NlcF0sXG4gICAgICB3aG9sZV9kb2xsYXJfYW1vdW50ID0gJygnICsgdmFsaWRfd2hvbGVfZG9sbGFyX2Ftb3VudHMuam9pbignfCcpICsgJyk/JyxcbiAgICAgIGRlY2ltYWxfYW1vdW50ID0gJyhcXFxcJyArIG9wdGlvbnMuZGVjaW1hbF9zZXBhcmF0b3IgKyAnXFxcXGR7Mn0pPyc7XG4gIHZhciBwYXR0ZXJuID0gd2hvbGVfZG9sbGFyX2Ftb3VudCArIGRlY2ltYWxfYW1vdW50O1xuXG4gIC8vIGRlZmF1bHQgaXMgbmVnYXRpdmUgc2lnbiBiZWZvcmUgc3ltYm9sLCBidXQgdGhlcmUgYXJlIHR3byBvdGhlciBvcHRpb25zIChiZXNpZGVzIHBhcmVucylcbiAgaWYgKG9wdGlvbnMuYWxsb3dfbmVnYXRpdmVzICYmICFvcHRpb25zLnBhcmVuc19mb3JfbmVnYXRpdmVzKSB7XG4gICAgaWYgKG9wdGlvbnMubmVnYXRpdmVfc2lnbl9hZnRlcl9kaWdpdHMpIHtcbiAgICAgIHBhdHRlcm4gKz0gbmVnYXRpdmU7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLm5lZ2F0aXZlX3NpZ25fYmVmb3JlX2RpZ2l0cykge1xuICAgICAgcGF0dGVybiA9IG5lZ2F0aXZlICsgcGF0dGVybjtcbiAgICB9XG4gIH1cblxuICAvLyBTb3V0aCBBZnJpY2FuIFJhbmQsIGZvciBleGFtcGxlLCB1c2VzIFIgMTIzIChzcGFjZSkgYW5kIFItMTIzIChubyBzcGFjZSlcbiAgaWYgKG9wdGlvbnMuYWxsb3dfbmVnYXRpdmVfc2lnbl9wbGFjZWhvbGRlcikge1xuICAgIHBhdHRlcm4gPSAnKCAoPyFcXFxcLSkpPycgKyBwYXR0ZXJuO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMuYWxsb3dfc3BhY2VfYWZ0ZXJfc3ltYm9sKSB7XG4gICAgcGF0dGVybiA9ICcgPycgKyBwYXR0ZXJuO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMuYWxsb3dfc3BhY2VfYWZ0ZXJfZGlnaXRzKSB7XG4gICAgcGF0dGVybiArPSAnKCAoPyEkKSk/JztcbiAgfVxuXG4gIGlmIChvcHRpb25zLnN5bWJvbF9hZnRlcl9kaWdpdHMpIHtcbiAgICBwYXR0ZXJuICs9IHN5bWJvbDtcbiAgfSBlbHNlIHtcbiAgICBwYXR0ZXJuID0gc3ltYm9sICsgcGF0dGVybjtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmFsbG93X25lZ2F0aXZlcykge1xuICAgIGlmIChvcHRpb25zLnBhcmVuc19mb3JfbmVnYXRpdmVzKSB7XG4gICAgICBwYXR0ZXJuID0gJyhcXFxcKCcgKyBwYXR0ZXJuICsgJ1xcXFwpfCcgKyBwYXR0ZXJuICsgJyknO1xuICAgIH0gZWxzZSBpZiAoIShvcHRpb25zLm5lZ2F0aXZlX3NpZ25fYmVmb3JlX2RpZ2l0cyB8fCBvcHRpb25zLm5lZ2F0aXZlX3NpZ25fYWZ0ZXJfZGlnaXRzKSkge1xuICAgICAgcGF0dGVybiA9IG5lZ2F0aXZlICsgcGF0dGVybjtcbiAgICB9XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZSBwcmVmZXItdGVtcGxhdGUgKi9cbiAgcmV0dXJuIG5ldyBSZWdFeHAoJ14nICtcbiAgLy8gZW5zdXJlIHRoZXJlJ3MgYSBkb2xsYXIgYW5kL29yIGRlY2ltYWwgYW1vdW50LCBhbmQgdGhhdFxuICAvLyBpdCBkb2Vzbid0IHN0YXJ0IHdpdGggYSBzcGFjZSBvciBhIG5lZ2F0aXZlIHNpZ24gZm9sbG93ZWQgYnkgYSBzcGFjZVxuICAnKD8hLT8gKSg/PS4qXFxcXGQpJyArIHBhdHRlcm4gKyAnJCcpO1xuICAvKiBlc2xpbnQtZW5hYmxlIHByZWZlci10ZW1wbGF0ZSAqL1xufVxuXG52YXIgZGVmYXVsdF9jdXJyZW5jeV9vcHRpb25zID0ge1xuICBzeW1ib2w6ICckJyxcbiAgcmVxdWlyZV9zeW1ib2w6IGZhbHNlLFxuICBhbGxvd19zcGFjZV9hZnRlcl9zeW1ib2w6IGZhbHNlLFxuICBzeW1ib2xfYWZ0ZXJfZGlnaXRzOiBmYWxzZSxcbiAgYWxsb3dfbmVnYXRpdmVzOiB0cnVlLFxuICBwYXJlbnNfZm9yX25lZ2F0aXZlczogZmFsc2UsXG4gIG5lZ2F0aXZlX3NpZ25fYmVmb3JlX2RpZ2l0czogZmFsc2UsXG4gIG5lZ2F0aXZlX3NpZ25fYWZ0ZXJfZGlnaXRzOiBmYWxzZSxcbiAgYWxsb3dfbmVnYXRpdmVfc2lnbl9wbGFjZWhvbGRlcjogZmFsc2UsXG4gIHRob3VzYW5kc19zZXBhcmF0b3I6ICcsJyxcbiAgZGVjaW1hbF9zZXBhcmF0b3I6ICcuJyxcbiAgYWxsb3dfc3BhY2VfYWZ0ZXJfZGlnaXRzOiBmYWxzZVxufTtcblxuZnVuY3Rpb24gaXNDdXJyZW5jeShzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIG9wdGlvbnMgPSAoMCwgX21lcmdlMi5kZWZhdWx0KShvcHRpb25zLCBkZWZhdWx0X2N1cnJlbmN5X29wdGlvbnMpO1xuICByZXR1cm4gY3VycmVuY3lSZWdleChvcHRpb25zKS50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0RhdGFVUkk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgZGF0YVVSSSA9IC9eXFxzKmRhdGE6KFthLXpdK1xcL1thLXowLTlcXC1cXCtdKyg7W2EtelxcLV0rPVthLXowLTlcXC1dKyk/KT8oO2Jhc2U2NCk/LFthLXowLTkhXFwkJicsXFwoXFwpXFwqXFwrLDs9XFwtXFwuX346QFxcL1xcPyVcXHNdKlxccyokL2k7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuXG5mdW5jdGlvbiBpc0RhdGFVUkkoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gZGF0YVVSSS50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0RhdGU7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG52YXIgX2lzSVNPID0gcmVxdWlyZSgnLi9pc0lTTzg2MDEnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gZ2V0VGltZXpvbmVPZmZzZXQoc3RyKSB7XG4gIHZhciBpc284NjAxUGFydHMgPSBzdHIubWF0Y2goX2lzSVNPLmlzbzg2MDEpO1xuICB2YXIgdGltZXpvbmUgPSB2b2lkIDAsXG4gICAgICBzaWduID0gdm9pZCAwLFxuICAgICAgaG91cnMgPSB2b2lkIDAsXG4gICAgICBtaW51dGVzID0gdm9pZCAwO1xuICBpZiAoIWlzbzg2MDFQYXJ0cykge1xuICAgIHN0ciA9IHN0ci50b0xvd2VyQ2FzZSgpO1xuICAgIHRpbWV6b25lID0gc3RyLm1hdGNoKC8oPzpcXHN8Z210XFxzKikoLXxcXCspKFxcZHsxLDR9KShcXHN8JCkvKTtcbiAgICBpZiAoIXRpbWV6b25lKSB7XG4gICAgICByZXR1cm4gc3RyLmluZGV4T2YoJ2dtdCcpICE9PSAtMSA/IDAgOiBudWxsO1xuICAgIH1cbiAgICBzaWduID0gdGltZXpvbmVbMV07XG4gICAgdmFyIG9mZnNldCA9IHRpbWV6b25lWzJdO1xuICAgIGlmIChvZmZzZXQubGVuZ3RoID09PSAzKSB7XG4gICAgICBvZmZzZXQgPSAnMCcgKyBvZmZzZXQ7XG4gICAgfVxuICAgIGlmIChvZmZzZXQubGVuZ3RoIDw9IDIpIHtcbiAgICAgIGhvdXJzID0gMDtcbiAgICAgIG1pbnV0ZXMgPSBwYXJzZUludChvZmZzZXQsIDEwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaG91cnMgPSBwYXJzZUludChvZmZzZXQuc2xpY2UoMCwgMiksIDEwKTtcbiAgICAgIG1pbnV0ZXMgPSBwYXJzZUludChvZmZzZXQuc2xpY2UoMiwgNCksIDEwKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGltZXpvbmUgPSBpc284NjAxUGFydHNbMjFdO1xuICAgIGlmICghdGltZXpvbmUpIHtcbiAgICAgIC8vIGlmIG5vIGhvdXIvbWludXRlIHdhcyBwcm92aWRlZCwgdGhlIGRhdGUgaXMgR01UXG4gICAgICByZXR1cm4gIWlzbzg2MDFQYXJ0c1sxMl0gPyAwIDogbnVsbDtcbiAgICB9XG4gICAgaWYgKHRpbWV6b25lID09PSAneicgfHwgdGltZXpvbmUgPT09ICdaJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHNpZ24gPSBpc284NjAxUGFydHNbMjJdO1xuICAgIGlmICh0aW1lem9uZS5pbmRleE9mKCc6JykgIT09IC0xKSB7XG4gICAgICBob3VycyA9IHBhcnNlSW50KGlzbzg2MDFQYXJ0c1syM10sIDEwKTtcbiAgICAgIG1pbnV0ZXMgPSBwYXJzZUludChpc284NjAxUGFydHNbMjRdLCAxMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvdXJzID0gMDtcbiAgICAgIG1pbnV0ZXMgPSBwYXJzZUludChpc284NjAxUGFydHNbMjNdLCAxMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiAoaG91cnMgKiA2MCArIG1pbnV0ZXMpICogKHNpZ24gPT09ICctJyA/IDEgOiAtMSk7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciBub3JtYWxpemVkRGF0ZSA9IG5ldyBEYXRlKERhdGUucGFyc2Uoc3RyKSk7XG4gIGlmIChpc05hTihub3JtYWxpemVkRGF0ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBub3JtYWxpemVkRGF0ZSBpcyBpbiB0aGUgdXNlcidzIHRpbWV6b25lLiBBcHBseSB0aGUgaW5wdXRcbiAgLy8gdGltZXpvbmUgb2Zmc2V0IHRvIHRoZSBkYXRlIHNvIHRoYXQgdGhlIHllYXIgYW5kIGRheSBtYXRjaFxuICAvLyB0aGUgaW5wdXRcbiAgdmFyIHRpbWV6b25lT2Zmc2V0ID0gZ2V0VGltZXpvbmVPZmZzZXQoc3RyKTtcbiAgaWYgKHRpbWV6b25lT2Zmc2V0ICE9PSBudWxsKSB7XG4gICAgdmFyIHRpbWV6b25lRGlmZmVyZW5jZSA9IG5vcm1hbGl6ZWREYXRlLmdldFRpbWV6b25lT2Zmc2V0KCkgLSB0aW1lem9uZU9mZnNldDtcbiAgICBub3JtYWxpemVkRGF0ZSA9IG5ldyBEYXRlKG5vcm1hbGl6ZWREYXRlLmdldFRpbWUoKSArIDYwMDAwICogdGltZXpvbmVEaWZmZXJlbmNlKTtcbiAgfVxuXG4gIHZhciBkYXkgPSBTdHJpbmcobm9ybWFsaXplZERhdGUuZ2V0RGF0ZSgpKTtcbiAgdmFyIGRheU9yWWVhciA9IHZvaWQgMCxcbiAgICAgIGRheU9yWWVhck1hdGNoZXMgPSB2b2lkIDAsXG4gICAgICB5ZWFyID0gdm9pZCAwO1xuICAvLyBjaGVjayBmb3IgdmFsaWQgZG91YmxlIGRpZ2l0cyB0aGF0IGNvdWxkIGJlIGxhdGUgZGF5c1xuICAvLyBjaGVjayBmb3IgYWxsIG1hdGNoZXMgc2luY2UgYSBzdHJpbmcgbGlrZSAnMTIvMjMnIGlzIGEgdmFsaWQgZGF0ZVxuICAvLyBpZ25vcmUgZXZlcnl0aGluZyB3aXRoIG5lYXJieSBjb2xvbnNcbiAgZGF5T3JZZWFyTWF0Y2hlcyA9IHN0ci5tYXRjaCgvKF58W146XFxkXSlbMjNdXFxkKFteVDpcXGRdfCQpL2cpO1xuICBpZiAoIWRheU9yWWVhck1hdGNoZXMpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBkYXlPclllYXIgPSBkYXlPclllYXJNYXRjaGVzLm1hcChmdW5jdGlvbiAoZGlnaXRTdHJpbmcpIHtcbiAgICByZXR1cm4gZGlnaXRTdHJpbmcubWF0Y2goL1xcZCsvZylbMF07XG4gIH0pLmpvaW4oJy8nKTtcblxuICB5ZWFyID0gU3RyaW5nKG5vcm1hbGl6ZWREYXRlLmdldEZ1bGxZZWFyKCkpLnNsaWNlKC0yKTtcbiAgaWYgKGRheU9yWWVhciA9PT0gZGF5IHx8IGRheU9yWWVhciA9PT0geWVhcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGRheU9yWWVhciA9PT0gJycgKyBkYXkgLyB5ZWFyIHx8IGRheU9yWWVhciA9PT0gJycgKyB5ZWFyIC8gZGF5KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNEZWNpbWFsO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGRlY2ltYWwgPSAvXlstK10/KFswLTldK3xcXC5bMC05XSt8WzAtOV0rXFwuWzAtOV0rKSQvO1xuXG5mdW5jdGlvbiBpc0RlY2ltYWwoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gc3RyICE9PSAnJyAmJiBkZWNpbWFsLnRlc3Qoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzRGl2aXNpYmxlQnk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG52YXIgX3RvRmxvYXQgPSByZXF1aXJlKCcuL3RvRmxvYXQnKTtcblxudmFyIF90b0Zsb2F0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3RvRmxvYXQpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc0RpdmlzaWJsZUJ5KHN0ciwgbnVtKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gKDAsIF90b0Zsb2F0Mi5kZWZhdWx0KShzdHIpICUgcGFyc2VJbnQobnVtLCAxMCkgPT09IDA7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0VtYWlsO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF9tZXJnZSA9IHJlcXVpcmUoJy4vdXRpbC9tZXJnZScpO1xuXG52YXIgX21lcmdlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lcmdlKTtcblxudmFyIF9pc0J5dGVMZW5ndGggPSByZXF1aXJlKCcuL2lzQnl0ZUxlbmd0aCcpO1xuXG52YXIgX2lzQnl0ZUxlbmd0aDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0J5dGVMZW5ndGgpO1xuXG52YXIgX2lzRlFETiA9IHJlcXVpcmUoJy4vaXNGUUROJyk7XG5cbnZhciBfaXNGUUROMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzRlFETik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBkZWZhdWx0X2VtYWlsX29wdGlvbnMgPSB7XG4gIGFsbG93X2Rpc3BsYXlfbmFtZTogZmFsc2UsXG4gIHJlcXVpcmVfZGlzcGxheV9uYW1lOiBmYWxzZSxcbiAgYWxsb3dfdXRmOF9sb2NhbF9wYXJ0OiB0cnVlLFxuICByZXF1aXJlX3RsZDogdHJ1ZVxufTtcblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tY29udHJvbC1yZWdleCAqL1xudmFyIGRpc3BsYXlOYW1lID0gL15bYS16XFxkISNcXCQlJidcXCpcXCtcXC1cXC89XFw/XFxeX2B7XFx8fX5cXC5cXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdK1thLXpcXGQhI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9flxcLlxcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRlxcc10qPCguKyk+JC9pO1xudmFyIGVtYWlsVXNlclBhcnQgPSAvXlthLXpcXGQhI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl0rJC9pO1xudmFyIHF1b3RlZEVtYWlsVXNlciA9IC9eKFtcXHNcXHgwMS1cXHgwOFxceDBiXFx4MGNcXHgwZS1cXHgxZlxceDdmXFx4MjFcXHgyMy1cXHg1YlxceDVkLVxceDdlXXwoXFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZC1cXHg3Zl0pKSokL2k7XG52YXIgZW1haWxVc2VyVXRmOFBhcnQgPSAvXlthLXpcXGQhI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9flxcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0rJC9pO1xudmFyIHF1b3RlZEVtYWlsVXNlclV0ZjggPSAvXihbXFxzXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHg3ZlxceDIxXFx4MjMtXFx4NWJcXHg1ZC1cXHg3ZVxcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl18KFxcXFxbXFx4MDEtXFx4MDlcXHgwYlxceDBjXFx4MGQtXFx4N2ZcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSkqJC9pO1xuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnRyb2wtcmVnZXggKi9cblxuZnVuY3Rpb24gaXNFbWFpbChzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIG9wdGlvbnMgPSAoMCwgX21lcmdlMi5kZWZhdWx0KShvcHRpb25zLCBkZWZhdWx0X2VtYWlsX29wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zLnJlcXVpcmVfZGlzcGxheV9uYW1lIHx8IG9wdGlvbnMuYWxsb3dfZGlzcGxheV9uYW1lKSB7XG4gICAgdmFyIGRpc3BsYXlfZW1haWwgPSBzdHIubWF0Y2goZGlzcGxheU5hbWUpO1xuICAgIGlmIChkaXNwbGF5X2VtYWlsKSB7XG4gICAgICBzdHIgPSBkaXNwbGF5X2VtYWlsWzFdO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5yZXF1aXJlX2Rpc3BsYXlfbmFtZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgnQCcpO1xuICB2YXIgZG9tYWluID0gcGFydHMucG9wKCk7XG4gIHZhciB1c2VyID0gcGFydHMuam9pbignQCcpO1xuXG4gIHZhciBsb3dlcl9kb21haW4gPSBkb21haW4udG9Mb3dlckNhc2UoKTtcbiAgaWYgKGxvd2VyX2RvbWFpbiA9PT0gJ2dtYWlsLmNvbScgfHwgbG93ZXJfZG9tYWluID09PSAnZ29vZ2xlbWFpbC5jb20nKSB7XG4gICAgdXNlciA9IHVzZXIucmVwbGFjZSgvXFwuL2csICcnKS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgaWYgKCEoMCwgX2lzQnl0ZUxlbmd0aDIuZGVmYXVsdCkodXNlciwgeyBtYXg6IDY0IH0pIHx8ICEoMCwgX2lzQnl0ZUxlbmd0aDIuZGVmYXVsdCkoZG9tYWluLCB7IG1heDogMjU2IH0pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKCEoMCwgX2lzRlFETjIuZGVmYXVsdCkoZG9tYWluLCB7IHJlcXVpcmVfdGxkOiBvcHRpb25zLnJlcXVpcmVfdGxkIH0pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHVzZXJbMF0gPT09ICdcIicpIHtcbiAgICB1c2VyID0gdXNlci5zbGljZSgxLCB1c2VyLmxlbmd0aCAtIDEpO1xuICAgIHJldHVybiBvcHRpb25zLmFsbG93X3V0ZjhfbG9jYWxfcGFydCA/IHF1b3RlZEVtYWlsVXNlclV0ZjgudGVzdCh1c2VyKSA6IHF1b3RlZEVtYWlsVXNlci50ZXN0KHVzZXIpO1xuICB9XG5cbiAgdmFyIHBhdHRlcm4gPSBvcHRpb25zLmFsbG93X3V0ZjhfbG9jYWxfcGFydCA/IGVtYWlsVXNlclV0ZjhQYXJ0IDogZW1haWxVc2VyUGFydDtcblxuICB2YXIgdXNlcl9wYXJ0cyA9IHVzZXIuc3BsaXQoJy4nKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB1c2VyX3BhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFwYXR0ZXJuLnRlc3QodXNlcl9wYXJ0c1tpXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzRW1wdHk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc0VtcHR5KHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN0ci5sZW5ndGggPT09IDA7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0ZEUU47XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG52YXIgX21lcmdlID0gcmVxdWlyZSgnLi91dGlsL21lcmdlJyk7XG5cbnZhciBfbWVyZ2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWVyZ2UpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgZGVmYXVsdF9mcWRuX29wdGlvbnMgPSB7XG4gIHJlcXVpcmVfdGxkOiB0cnVlLFxuICBhbGxvd191bmRlcnNjb3JlczogZmFsc2UsXG4gIGFsbG93X3RyYWlsaW5nX2RvdDogZmFsc2Vcbn07XG5cbmZ1bmN0aW9uIGlzRkRRTihzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIG9wdGlvbnMgPSAoMCwgX21lcmdlMi5kZWZhdWx0KShvcHRpb25zLCBkZWZhdWx0X2ZxZG5fb3B0aW9ucyk7XG5cbiAgLyogUmVtb3ZlIHRoZSBvcHRpb25hbCB0cmFpbGluZyBkb3QgYmVmb3JlIGNoZWNraW5nIHZhbGlkaXR5ICovXG4gIGlmIChvcHRpb25zLmFsbG93X3RyYWlsaW5nX2RvdCAmJiBzdHJbc3RyLmxlbmd0aCAtIDFdID09PSAnLicpIHtcbiAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKDAsIHN0ci5sZW5ndGggLSAxKTtcbiAgfVxuICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoJy4nKTtcbiAgaWYgKG9wdGlvbnMucmVxdWlyZV90bGQpIHtcbiAgICB2YXIgdGxkID0gcGFydHMucG9wKCk7XG4gICAgaWYgKCFwYXJ0cy5sZW5ndGggfHwgIS9eKFthLXpcXHUwMGExLVxcdWZmZmZdezIsfXx4blthLXowLTktXXsyLH0pJC9pLnRlc3QodGxkKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBmb3IgKHZhciBwYXJ0LCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgcGFydCA9IHBhcnRzW2ldO1xuICAgIGlmIChvcHRpb25zLmFsbG93X3VuZGVyc2NvcmVzKSB7XG4gICAgICBwYXJ0ID0gcGFydC5yZXBsYWNlKC9fL2csICcnKTtcbiAgICB9XG4gICAgaWYgKCEvXlthLXpcXHUwMGExLVxcdWZmZmYwLTktXSskL2kudGVzdChwYXJ0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoL1tcXHVmZjAxLVxcdWZmNWVdLy50ZXN0KHBhcnQpKSB7XG4gICAgICAvLyBkaXNhbGxvdyBmdWxsLXdpZHRoIGNoYXJzXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChwYXJ0WzBdID09PSAnLScgfHwgcGFydFtwYXJ0Lmxlbmd0aCAtIDFdID09PSAnLScpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0Zsb2F0O1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGZsb2F0ID0gL14oPzpbLStdKT8oPzpbMC05XSspPyg/OlxcLlswLTldKik/KD86W2VFXVtcXCtcXC1dPyg/OlswLTldKykpPyQvO1xuXG5mdW5jdGlvbiBpc0Zsb2F0KHN0ciwgb3B0aW9ucykge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmIChzdHIgPT09ICcnIHx8IHN0ciA9PT0gJy4nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBmbG9hdC50ZXN0KHN0cikgJiYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdtaW4nKSB8fCBzdHIgPj0gb3B0aW9ucy5taW4pICYmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnbWF4JykgfHwgc3RyIDw9IG9wdGlvbnMubWF4KSAmJiAoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2x0JykgfHwgc3RyIDwgb3B0aW9ucy5sdCkgJiYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdndCcpIHx8IHN0ciA+IG9wdGlvbnMuZ3QpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5mdWxsV2lkdGggPSB1bmRlZmluZWQ7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0Z1bGxXaWR0aDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBmdWxsV2lkdGggPSBleHBvcnRzLmZ1bGxXaWR0aCA9IC9bXlxcdTAwMjAtXFx1MDA3RVxcdUZGNjEtXFx1RkY5RlxcdUZGQTAtXFx1RkZEQ1xcdUZGRTgtXFx1RkZFRTAtOWEtekEtWl0vO1xuXG5mdW5jdGlvbiBpc0Z1bGxXaWR0aChzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBmdWxsV2lkdGgudGVzdChzdHIpO1xufSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuaGFsZldpZHRoID0gdW5kZWZpbmVkO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNIYWxmV2lkdGg7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgaGFsZldpZHRoID0gZXhwb3J0cy5oYWxmV2lkdGggPSAvW1xcdTAwMjAtXFx1MDA3RVxcdUZGNjEtXFx1RkY5RlxcdUZGQTAtXFx1RkZEQ1xcdUZGRTgtXFx1RkZFRTAtOWEtekEtWl0vO1xuXG5mdW5jdGlvbiBpc0hhbGZXaWR0aChzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBoYWxmV2lkdGgudGVzdChzdHIpO1xufSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzSGV4Q29sb3I7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgaGV4Y29sb3IgPSAvXiM/KFswLTlBLUZdezN9fFswLTlBLUZdezZ9KSQvaTtcblxuZnVuY3Rpb24gaXNIZXhDb2xvcihzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBoZXhjb2xvci50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0hleGFkZWNpbWFsO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGhleGFkZWNpbWFsID0gL15bMC05QS1GXSskL2k7XG5cbmZ1bmN0aW9uIGlzSGV4YWRlY2ltYWwoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gaGV4YWRlY2ltYWwudGVzdChzdHIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNJUDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBpcHY0TWF5YmUgPSAvXihcXGR7MSwzfSlcXC4oXFxkezEsM30pXFwuKFxcZHsxLDN9KVxcLihcXGR7MSwzfSkkLztcbnZhciBpcHY2QmxvY2sgPSAvXlswLTlBLUZdezEsNH0kL2k7XG5cbmZ1bmN0aW9uIGlzSVAoc3RyKSB7XG4gIHZhciB2ZXJzaW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmVyc2lvbiA9IFN0cmluZyh2ZXJzaW9uKTtcbiAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgcmV0dXJuIGlzSVAoc3RyLCA0KSB8fCBpc0lQKHN0ciwgNik7XG4gIH0gZWxzZSBpZiAodmVyc2lvbiA9PT0gJzQnKSB7XG4gICAgaWYgKCFpcHY0TWF5YmUudGVzdChzdHIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgnLicpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgICByZXR1cm4gcGFydHNbM10gPD0gMjU1O1xuICB9IGVsc2UgaWYgKHZlcnNpb24gPT09ICc2Jykge1xuICAgIHZhciBibG9ja3MgPSBzdHIuc3BsaXQoJzonKTtcbiAgICB2YXIgZm91bmRPbWlzc2lvbkJsb2NrID0gZmFsc2U7IC8vIG1hcmtlciB0byBpbmRpY2F0ZSA6OlxuXG4gICAgLy8gQXQgbGVhc3Qgc29tZSBPUyBhY2NlcHQgdGhlIGxhc3QgMzIgYml0cyBvZiBhbiBJUHY2IGFkZHJlc3NcbiAgICAvLyAoaS5lLiAyIG9mIHRoZSBibG9ja3MpIGluIElQdjQgbm90YXRpb24sIGFuZCBSRkMgMzQ5MyBzYXlzXG4gICAgLy8gdGhhdCAnOjpmZmZmOmEuYi5jLmQnIGlzIHZhbGlkIGZvciBJUHY0LW1hcHBlZCBJUHY2IGFkZHJlc3NlcyxcbiAgICAvLyBhbmQgJzo6YS5iLmMuZCcgaXMgZGVwcmVjYXRlZCwgYnV0IGFsc28gdmFsaWQuXG4gICAgdmFyIGZvdW5kSVB2NFRyYW5zaXRpb25CbG9jayA9IGlzSVAoYmxvY2tzW2Jsb2Nrcy5sZW5ndGggLSAxXSwgNCk7XG4gICAgdmFyIGV4cGVjdGVkTnVtYmVyT2ZCbG9ja3MgPSBmb3VuZElQdjRUcmFuc2l0aW9uQmxvY2sgPyA3IDogODtcblxuICAgIGlmIChibG9ja3MubGVuZ3RoID4gZXhwZWN0ZWROdW1iZXJPZkJsb2Nrcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBpbml0aWFsIG9yIGZpbmFsIDo6XG4gICAgaWYgKHN0ciA9PT0gJzo6Jykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmIChzdHIuc3Vic3RyKDAsIDIpID09PSAnOjonKSB7XG4gICAgICBibG9ja3Muc2hpZnQoKTtcbiAgICAgIGJsb2Nrcy5zaGlmdCgpO1xuICAgICAgZm91bmRPbWlzc2lvbkJsb2NrID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHN0ci5zdWJzdHIoc3RyLmxlbmd0aCAtIDIpID09PSAnOjonKSB7XG4gICAgICBibG9ja3MucG9wKCk7XG4gICAgICBibG9ja3MucG9wKCk7XG4gICAgICBmb3VuZE9taXNzaW9uQmxvY2sgPSB0cnVlO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzLmxlbmd0aDsgKytpKSB7XG4gICAgICAvLyB0ZXN0IGZvciBhIDo6IHdoaWNoIGNhbiBub3QgYmUgYXQgdGhlIHN0cmluZyBzdGFydC9lbmRcbiAgICAgIC8vIHNpbmNlIHRob3NlIGNhc2VzIGhhdmUgYmVlbiBoYW5kbGVkIGFib3ZlXG4gICAgICBpZiAoYmxvY2tzW2ldID09PSAnJyAmJiBpID4gMCAmJiBpIDwgYmxvY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgaWYgKGZvdW5kT21pc3Npb25CbG9jaykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbXVsdGlwbGUgOjogaW4gYWRkcmVzc1xuICAgICAgICB9XG4gICAgICAgIGZvdW5kT21pc3Npb25CbG9jayA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGZvdW5kSVB2NFRyYW5zaXRpb25CbG9jayAmJiBpID09PSBibG9ja3MubGVuZ3RoIC0gMSkge1xuICAgICAgICAvLyBpdCBoYXMgYmVlbiBjaGVja2VkIGJlZm9yZSB0aGF0IHRoZSBsYXN0XG4gICAgICAgIC8vIGJsb2NrIGlzIGEgdmFsaWQgSVB2NCBhZGRyZXNzXG4gICAgICB9IGVsc2UgaWYgKCFpcHY2QmxvY2sudGVzdChibG9ja3NbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGZvdW5kT21pc3Npb25CbG9jaykge1xuICAgICAgcmV0dXJuIGJsb2Nrcy5sZW5ndGggPj0gMTtcbiAgICB9XG4gICAgcmV0dXJuIGJsb2Nrcy5sZW5ndGggPT09IGV4cGVjdGVkTnVtYmVyT2ZCbG9ja3M7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNJU0JOO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGlzYm4xME1heWJlID0gL14oPzpbMC05XXs5fVh8WzAtOV17MTB9KSQvO1xudmFyIGlzYm4xM01heWJlID0gL14oPzpbMC05XXsxM30pJC87XG52YXIgZmFjdG9yID0gWzEsIDNdO1xuXG5mdW5jdGlvbiBpc0lTQk4oc3RyKSB7XG4gIHZhciB2ZXJzaW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmVyc2lvbiA9IFN0cmluZyh2ZXJzaW9uKTtcbiAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgcmV0dXJuIGlzSVNCTihzdHIsIDEwKSB8fCBpc0lTQk4oc3RyLCAxMyk7XG4gIH1cbiAgdmFyIHNhbml0aXplZCA9IHN0ci5yZXBsYWNlKC9bXFxzLV0rL2csICcnKTtcbiAgdmFyIGNoZWNrc3VtID0gMDtcbiAgdmFyIGkgPSB2b2lkIDA7XG4gIGlmICh2ZXJzaW9uID09PSAnMTAnKSB7XG4gICAgaWYgKCFpc2JuMTBNYXliZS50ZXN0KHNhbml0aXplZCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IDk7IGkrKykge1xuICAgICAgY2hlY2tzdW0gKz0gKGkgKyAxKSAqIHNhbml0aXplZC5jaGFyQXQoaSk7XG4gICAgfVxuICAgIGlmIChzYW5pdGl6ZWQuY2hhckF0KDkpID09PSAnWCcpIHtcbiAgICAgIGNoZWNrc3VtICs9IDEwICogMTA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoZWNrc3VtICs9IDEwICogc2FuaXRpemVkLmNoYXJBdCg5KTtcbiAgICB9XG4gICAgaWYgKGNoZWNrc3VtICUgMTEgPT09IDApIHtcbiAgICAgIHJldHVybiAhIXNhbml0aXplZDtcbiAgICB9XG4gIH0gZWxzZSBpZiAodmVyc2lvbiA9PT0gJzEzJykge1xuICAgIGlmICghaXNibjEzTWF5YmUudGVzdChzYW5pdGl6ZWQpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICBjaGVja3N1bSArPSBmYWN0b3JbaSAlIDJdICogc2FuaXRpemVkLmNoYXJBdChpKTtcbiAgICB9XG4gICAgaWYgKHNhbml0aXplZC5jaGFyQXQoMTIpIC0gKDEwIC0gY2hlY2tzdW0gJSAxMCkgJSAxMCA9PT0gMCkge1xuICAgICAgcmV0dXJuICEhc2FuaXRpemVkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0lTSU47XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgaXNpbiA9IC9eW0EtWl17Mn1bMC05QS1aXXs5fVswLTldJC87XG5cbmZ1bmN0aW9uIGlzSVNJTihzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIGlmICghaXNpbi50ZXN0KHN0cikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgY2hlY2tzdW1TdHIgPSBzdHIucmVwbGFjZSgvW0EtWl0vZywgZnVuY3Rpb24gKGNoYXJhY3Rlcikge1xuICAgIHJldHVybiBwYXJzZUludChjaGFyYWN0ZXIsIDM2KTtcbiAgfSk7XG5cbiAgdmFyIHN1bSA9IDA7XG4gIHZhciBkaWdpdCA9IHZvaWQgMDtcbiAgdmFyIHRtcE51bSA9IHZvaWQgMDtcbiAgdmFyIHNob3VsZERvdWJsZSA9IHRydWU7XG4gIGZvciAodmFyIGkgPSBjaGVja3N1bVN0ci5sZW5ndGggLSAyOyBpID49IDA7IGktLSkge1xuICAgIGRpZ2l0ID0gY2hlY2tzdW1TdHIuc3Vic3RyaW5nKGksIGkgKyAxKTtcbiAgICB0bXBOdW0gPSBwYXJzZUludChkaWdpdCwgMTApO1xuICAgIGlmIChzaG91bGREb3VibGUpIHtcbiAgICAgIHRtcE51bSAqPSAyO1xuICAgICAgaWYgKHRtcE51bSA+PSAxMCkge1xuICAgICAgICBzdW0gKz0gdG1wTnVtICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1bSArPSB0bXBOdW07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1bSArPSB0bXBOdW07XG4gICAgfVxuICAgIHNob3VsZERvdWJsZSA9ICFzaG91bGREb3VibGU7XG4gIH1cblxuICByZXR1cm4gcGFyc2VJbnQoc3RyLnN1YnN0cihzdHIubGVuZ3RoIC0gMSksIDEwKSA9PT0gKDEwMDAwIC0gc3VtKSAlIDEwO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5pc284NjAxID0gdW5kZWZpbmVkO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gaXNvODYwMS50ZXN0KHN0cik7XG59O1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuLy8gZnJvbSBodHRwOi8vZ29vLmdsLzBlakhIV1xudmFyIGlzbzg2MDEgPSBleHBvcnRzLmlzbzg2MDEgPSAvXihbXFwrLV0/XFxkezR9KD8hXFxkezJ9XFxiKSkoKC0/KSgoMFsxLTldfDFbMC0yXSkoXFwzKFsxMl1cXGR8MFsxLTldfDNbMDFdKSk/fFcoWzAtNF1cXGR8NVswLTJdKSgtP1sxLTddKT98KDAwWzEtOV18MFsxLTldXFxkfFsxMl1cXGR7Mn18MyhbMC01XVxcZHw2WzEtNl0pKSkoW1RcXHNdKCgoWzAxXVxcZHwyWzAtM10pKCg6PylbMC01XVxcZCk/fDI0Oj8wMCkoW1xcLixdXFxkKyg/ITopKT8pPyhcXDE3WzAtNV1cXGQoW1xcLixdXFxkKyk/KT8oW3paXXwoW1xcKy1dKShbMDFdXFxkfDJbMC0zXSk6PyhbMC01XVxcZCk/KT8pPyk/JC87XG4vKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi8iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc0lTU047XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgaXNzbiA9ICdeXFxcXGR7NH0tP1xcXFxkezN9W1xcXFxkWF0kJztcblxuZnVuY3Rpb24gaXNJU1NOKHN0cikge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciB0ZXN0SXNzbiA9IGlzc247XG4gIHRlc3RJc3NuID0gb3B0aW9ucy5yZXF1aXJlX2h5cGhlbiA/IHRlc3RJc3NuLnJlcGxhY2UoJz8nLCAnJykgOiB0ZXN0SXNzbjtcbiAgdGVzdElzc24gPSBvcHRpb25zLmNhc2Vfc2Vuc2l0aXZlID8gbmV3IFJlZ0V4cCh0ZXN0SXNzbikgOiBuZXcgUmVnRXhwKHRlc3RJc3NuLCAnaScpO1xuICBpZiAoIXRlc3RJc3NuLnRlc3Qoc3RyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgaXNzbkRpZ2l0cyA9IHN0ci5yZXBsYWNlKCctJywgJycpO1xuICB2YXIgcG9zaXRpb24gPSA4O1xuICB2YXIgY2hlY2tzdW0gPSAwO1xuICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gIHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlO1xuICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBpc3NuRGlnaXRzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXA7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkge1xuICAgICAgdmFyIGRpZ2l0ID0gX3N0ZXAudmFsdWU7XG5cbiAgICAgIHZhciBkaWdpdFZhbHVlID0gZGlnaXQudG9VcHBlckNhc2UoKSA9PT0gJ1gnID8gMTAgOiArZGlnaXQ7XG4gICAgICBjaGVja3N1bSArPSBkaWdpdFZhbHVlICogcG9zaXRpb247XG4gICAgICAtLXBvc2l0aW9uO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlO1xuICAgIF9pdGVyYXRvckVycm9yID0gZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybikge1xuICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2hlY2tzdW0gJSAxMSA9PT0gMDtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBpc0luO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF90b1N0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC90b1N0cmluZycpO1xuXG52YXIgX3RvU3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3RvU3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNJbihzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciBpID0gdm9pZCAwO1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9wdGlvbnMpID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgZm9yIChpIGluIG9wdGlvbnMpIHtcbiAgICAgIGlmICh7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsIGkpKSB7XG4gICAgICAgIGFycmF5W2ldID0gKDAsIF90b1N0cmluZzIuZGVmYXVsdCkob3B0aW9uc1tpXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheS5pbmRleE9mKHN0cikgPj0gMDtcbiAgfSBlbHNlIGlmICgodHlwZW9mIG9wdGlvbnMgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG9wdGlvbnMpKSA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShzdHIpO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBvcHRpb25zLmluZGV4T2Yoc3RyKSA+PSAwO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzSW50O1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGludCA9IC9eKD86Wy0rXT8oPzowfFsxLTldWzAtOV0qKSkkLztcbnZhciBpbnRMZWFkaW5nWmVyb2VzID0gL15bLStdP1swLTldKyQvO1xuXG5mdW5jdGlvbiBpc0ludChzdHIsIG9wdGlvbnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIEdldCB0aGUgcmVnZXggdG8gdXNlIGZvciB0ZXN0aW5nLCBiYXNlZCBvbiB3aGV0aGVyXG4gIC8vIGxlYWRpbmcgemVyb2VzIGFyZSBhbGxvd2VkIG9yIG5vdC5cbiAgdmFyIHJlZ2V4ID0gb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnYWxsb3dfbGVhZGluZ196ZXJvZXMnKSAmJiAhb3B0aW9ucy5hbGxvd19sZWFkaW5nX3plcm9lcyA/IGludCA6IGludExlYWRpbmdaZXJvZXM7XG5cbiAgLy8gQ2hlY2sgbWluL21heC9sdC9ndFxuICB2YXIgbWluQ2hlY2tQYXNzZWQgPSAhb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnbWluJykgfHwgc3RyID49IG9wdGlvbnMubWluO1xuICB2YXIgbWF4Q2hlY2tQYXNzZWQgPSAhb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnbWF4JykgfHwgc3RyIDw9IG9wdGlvbnMubWF4O1xuICB2YXIgbHRDaGVja1Bhc3NlZCA9ICFvcHRpb25zLmhhc093blByb3BlcnR5KCdsdCcpIHx8IHN0ciA8IG9wdGlvbnMubHQ7XG4gIHZhciBndENoZWNrUGFzc2VkID0gIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2d0JykgfHwgc3RyID4gb3B0aW9ucy5ndDtcblxuICByZXR1cm4gcmVnZXgudGVzdChzdHIpICYmIG1pbkNoZWNrUGFzc2VkICYmIG1heENoZWNrUGFzc2VkICYmIGx0Q2hlY2tQYXNzZWQgJiYgZ3RDaGVja1Bhc3NlZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBpc0pTT047XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc0pTT04oc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICB0cnkge1xuICAgIHZhciBvYmogPSBKU09OLnBhcnNlKHN0cik7XG4gICAgcmV0dXJuICEhb2JqICYmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihvYmopKSA9PT0gJ29iamVjdCc7XG4gIH0gY2F0Y2ggKGUpIHsvKiBpZ25vcmUgKi99XG4gIHJldHVybiBmYWxzZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBpc0xlbmd0aDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8qIGVzbGludC1kaXNhYmxlIHByZWZlci1yZXN0LXBhcmFtcyAqL1xuZnVuY3Rpb24gaXNMZW5ndGgoc3RyLCBvcHRpb25zKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICB2YXIgbWluID0gdm9pZCAwO1xuICB2YXIgbWF4ID0gdm9pZCAwO1xuICBpZiAoKHR5cGVvZiBvcHRpb25zID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihvcHRpb25zKSkgPT09ICdvYmplY3QnKSB7XG4gICAgbWluID0gb3B0aW9ucy5taW4gfHwgMDtcbiAgICBtYXggPSBvcHRpb25zLm1heDtcbiAgfSBlbHNlIHtcbiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogaXNMZW5ndGgoc3RyLCBtaW4gWywgbWF4XSlcbiAgICBtaW4gPSBhcmd1bWVudHNbMV07XG4gICAgbWF4ID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHZhciBzdXJyb2dhdGVQYWlycyA9IHN0ci5tYXRjaCgvW1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXS9nKSB8fCBbXTtcbiAgdmFyIGxlbiA9IHN0ci5sZW5ndGggLSBzdXJyb2dhdGVQYWlycy5sZW5ndGg7XG4gIHJldHVybiBsZW4gPj0gbWluICYmICh0eXBlb2YgbWF4ID09PSAndW5kZWZpbmVkJyB8fCBsZW4gPD0gbWF4KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTG93ZXJjYXNlO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNMb3dlcmNhc2Uoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gc3RyID09PSBzdHIudG9Mb3dlckNhc2UoKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTUFDQWRkcmVzcztcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBtYWNBZGRyZXNzID0gL14oWzAtOWEtZkEtRl1bMC05YS1mQS1GXTopezV9KFswLTlhLWZBLUZdWzAtOWEtZkEtRl0pJC87XG5cbmZ1bmN0aW9uIGlzTUFDQWRkcmVzcyhzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBtYWNBZGRyZXNzLnRlc3Qoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTUQ1O1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIG1kNSA9IC9eW2EtZjAtOV17MzJ9JC87XG5cbmZ1bmN0aW9uIGlzTUQ1KHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIG1kNS50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc01vYmlsZVBob25lO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xudmFyIHBob25lcyA9IHtcbiAgJ2FyLURaJzogL14oXFwrPzIxM3wwKSg1fDZ8NylcXGR7OH0kLyxcbiAgJ2FyLVNZJzogL14oIT8oXFwrPzk2Myl8MCk/OVxcZHs4fSQvLFxuICAnYXItU0EnOiAvXighPyhcXCs/OTY2KXwwKT81XFxkezh9JC8sXG4gICdlbi1VUyc6IC9eKFxcKz8xKT9bMi05XVxcZHsyfVsyLTldKD8hMTEpXFxkezZ9JC8sXG4gICdjcy1DWic6IC9eKFxcKz80MjApPyA/WzEtOV1bMC05XXsyfSA/WzAtOV17M30gP1swLTldezN9JC8sXG4gICdkZS1ERSc6IC9eKFxcKz80OVsgXFwuXFwtXSk/KFtcXChdezF9WzAtOV17MSw2fVtcXCldKT8oWzAtOSBcXC5cXC1cXC9dezMsMjB9KSgoeHxleHR8ZXh0ZW5zaW9uKVsgXT9bMC05XXsxLDR9KT8kLyxcbiAgJ2RhLURLJzogL14oXFwrPzQ1KT8oXFxkezh9KSQvLFxuICAnZWwtR1InOiAvXihcXCs/MzApPyg2OVxcZHs4fSkkLyxcbiAgJ2VuLUFVJzogL14oXFwrPzYxfDApNFxcZHs4fSQvLFxuICAnZW4tR0InOiAvXihcXCs/NDR8MCk3XFxkezl9JC8sXG4gICdlbi1ISyc6IC9eKFxcKz84NTJcXC0/KT9bNTY5XVxcZHszfVxcLT9cXGR7NH0kLyxcbiAgJ2VuLUlOJzogL14oXFwrPzkxfDApP1s3ODldXFxkezl9JC8sXG4gICdlbi1ORyc6IC9eKFxcKz8yMzR8MCk/Wzc4OV1cXGR7OX0kLyxcbiAgJ2VuLU5aJzogL14oXFwrPzY0fDApMlxcZHs3LDl9JC8sXG4gICdlbi1aQSc6IC9eKFxcKz8yN3wwKVxcZHs5fSQvLFxuICAnZW4tWk0nOiAvXihcXCs/MjYpPzA5WzU2N11cXGR7N30kLyxcbiAgJ2VzLUVTJzogL14oXFwrPzM0KT8oNlxcZHsxfXw3WzEyMzRdKVxcZHs3fSQvLFxuICAnZmktRkknOiAvXihcXCs/MzU4fDApXFxzPyg0KDB8MXwyfDR8NSk/fDUwKVxccz8oXFxkXFxzPyl7NCw4fVxcZCQvLFxuICAnZnItRlInOiAvXihcXCs/MzN8MClbNjddXFxkezh9JC8sXG4gICdoZS1JTCc6IC9eKFxcKzk3MnwwKShbMjM0ODldfDVbMDI0OF18NzcpWzEtOV1cXGR7Nn0vLFxuICAnaHUtSFUnOiAvXihcXCs/MzYpKDIwfDMwfDcwKVxcZHs3fSQvLFxuICAnaXQtSVQnOiAvXihcXCs/MzkpP1xccz8zXFxkezJ9ID9cXGR7Niw3fSQvLFxuICAnamEtSlAnOiAvXihcXCs/ODF8MClcXGR7MSw0fVsgXFwtXT9cXGR7MSw0fVsgXFwtXT9cXGR7NH0kLyxcbiAgJ21zLU1ZJzogL14oXFwrPzY/MDEpezF9KChbMTQ1XXsxfShcXC18XFxzKT9cXGR7Nyw4fSl8KFsyMzY3ODldezF9KFxcc3xcXC0pP1xcZHs3fSkpJC8sXG4gICduYi1OTyc6IC9eKFxcKz80Nyk/WzQ5XVxcZHs3fSQvLFxuICAnbmwtQkUnOiAvXihcXCs/MzJ8MCk0P1xcZHs4fSQvLFxuICAnbm4tTk8nOiAvXihcXCs/NDcpP1s0OV1cXGR7N30kLyxcbiAgJ3BsLVBMJzogL14oXFwrPzQ4KT8gP1s1LThdXFxkID9cXGR7M30gP1xcZHsyfSA/XFxkezJ9JC8sXG4gICdwdC1CUic6IC9eKFxcKz81NXwwKVxcLT9bMS05XXsyfVxcLT9bMi05XXsxfVxcZHszLDR9XFwtP1xcZHs0fSQvLFxuICAncHQtUFQnOiAvXihcXCs/MzUxKT85WzEyMzZdXFxkezd9JC8sXG4gICdyby1STyc6IC9eKFxcKz80PzApXFxzPzdcXGR7Mn0oXFwvfFxcc3xcXC58XFwtKT9cXGR7M30oXFxzfFxcLnxcXC0pP1xcZHszfSQvLFxuICAnZW4tUEsnOiAvXigoXFwrOTIpfCgwMDkyKSktezAsMX1cXGR7M30tezAsMX1cXGR7N30kfF5cXGR7MTF9JHxeXFxkezR9LVxcZHs3fSQvLFxuICAncnUtUlUnOiAvXihcXCs/N3w4KT85XFxkezl9JC8sXG4gICdzci1SUyc6IC9eKFxcKzM4MTZ8MDYpWy0gXFxkXXs1LDl9JC8sXG4gICd0ci1UUic6IC9eKFxcKz85MHwwKT81XFxkezl9JC8sXG4gICd2aS1WTic6IC9eKFxcKz84NHwwKT8oKDEoMihbMC05XSl8NihbMi05XSl8ODh8OTkpKXwoOSgoPyE1KVswLTldKSkpKFswLTldezd9KSQvLFxuICAnemgtQ04nOiAvXihcXCs/MD84NlxcLT8pPzFbMzQ1Nzg5XVxcZHs5fSQvLFxuICAnemgtVFcnOiAvXihcXCs/ODg2XFwtP3wwKT85XFxkezh9JC9cbn07XG4vKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cblxuLy8gYWxpYXNlc1xucGhvbmVzWydlbi1DQSddID0gcGhvbmVzWydlbi1VUyddO1xucGhvbmVzWydmci1CRSddID0gcGhvbmVzWydubC1CRSddO1xucGhvbmVzWyd6aC1ISyddID0gcGhvbmVzWydlbi1ISyddO1xuXG5mdW5jdGlvbiBpc01vYmlsZVBob25lKHN0ciwgbG9jYWxlKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICBpZiAobG9jYWxlIGluIHBob25lcykge1xuICAgIHJldHVybiBwaG9uZXNbbG9jYWxlXS50ZXN0KHN0cik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNNb25nb0lkO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxudmFyIF9pc0hleGFkZWNpbWFsID0gcmVxdWlyZSgnLi9pc0hleGFkZWNpbWFsJyk7XG5cbnZhciBfaXNIZXhhZGVjaW1hbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0hleGFkZWNpbWFsKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNNb25nb0lkKHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuICgwLCBfaXNIZXhhZGVjaW1hbDIuZGVmYXVsdCkoc3RyKSAmJiBzdHIubGVuZ3RoID09PSAyNDtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTXVsdGlieXRlO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tY29udHJvbC1yZWdleCAqL1xudmFyIG11bHRpYnl0ZSA9IC9bXlxceDAwLVxceDdGXS87XG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnRyb2wtcmVnZXggKi9cblxuZnVuY3Rpb24gaXNNdWx0aWJ5dGUoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gbXVsdGlieXRlLnRlc3Qoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzTnVtZXJpYztcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBudW1lcmljID0gL15bLStdP1swLTldKyQvO1xuXG5mdW5jdGlvbiBpc051bWVyaWMoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gbnVtZXJpYy50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBpc1N1cnJvZ2F0ZVBhaXI7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgc3Vycm9nYXRlUGFpciA9IC9bXFx1RDgwMC1cXHVEQkZGXVtcXHVEQzAwLVxcdURGRkZdLztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN1cnJvZ2F0ZVBhaXIudGVzdChzdHIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gaXNVUkw7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG52YXIgX2lzRlFETiA9IHJlcXVpcmUoJy4vaXNGUUROJyk7XG5cbnZhciBfaXNGUUROMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzRlFETik7XG5cbnZhciBfaXNJUCA9IHJlcXVpcmUoJy4vaXNJUCcpO1xuXG52YXIgX2lzSVAyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaXNJUCk7XG5cbnZhciBfbWVyZ2UgPSByZXF1aXJlKCcuL3V0aWwvbWVyZ2UnKTtcblxudmFyIF9tZXJnZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tZXJnZSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBkZWZhdWx0X3VybF9vcHRpb25zID0ge1xuICBwcm90b2NvbHM6IFsnaHR0cCcsICdodHRwcycsICdmdHAnXSxcbiAgcmVxdWlyZV90bGQ6IHRydWUsXG4gIHJlcXVpcmVfcHJvdG9jb2w6IGZhbHNlLFxuICByZXF1aXJlX2hvc3Q6IHRydWUsXG4gIHJlcXVpcmVfdmFsaWRfcHJvdG9jb2w6IHRydWUsXG4gIGFsbG93X3VuZGVyc2NvcmVzOiBmYWxzZSxcbiAgYWxsb3dfdHJhaWxpbmdfZG90OiBmYWxzZSxcbiAgYWxsb3dfcHJvdG9jb2xfcmVsYXRpdmVfdXJsczogZmFsc2Vcbn07XG5cbnZhciB3cmFwcGVkX2lwdjYgPSAvXlxcWyhbXlxcXV0rKVxcXSg/OjooWzAtOV0rKSk/JC87XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKG9iaikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuXG5mdW5jdGlvbiBjaGVja0hvc3QoaG9zdCwgbWF0Y2hlcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1hdGNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbWF0Y2ggPSBtYXRjaGVzW2ldO1xuICAgIGlmIChob3N0ID09PSBtYXRjaCB8fCBpc1JlZ0V4cChtYXRjaCkgJiYgbWF0Y2gudGVzdChob3N0KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNVUkwodXJsLCBvcHRpb25zKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KSh1cmwpO1xuICBpZiAoIXVybCB8fCB1cmwubGVuZ3RoID49IDIwODMgfHwgL1tcXHM8Pl0vLnRlc3QodXJsKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodXJsLmluZGV4T2YoJ21haWx0bzonKSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBvcHRpb25zID0gKDAsIF9tZXJnZTIuZGVmYXVsdCkob3B0aW9ucywgZGVmYXVsdF91cmxfb3B0aW9ucyk7XG4gIHZhciBwcm90b2NvbCA9IHZvaWQgMCxcbiAgICAgIGF1dGggPSB2b2lkIDAsXG4gICAgICBob3N0ID0gdm9pZCAwLFxuICAgICAgaG9zdG5hbWUgPSB2b2lkIDAsXG4gICAgICBwb3J0ID0gdm9pZCAwLFxuICAgICAgcG9ydF9zdHIgPSB2b2lkIDAsXG4gICAgICBzcGxpdCA9IHZvaWQgMCxcbiAgICAgIGlwdjYgPSB2b2lkIDA7XG5cbiAgc3BsaXQgPSB1cmwuc3BsaXQoJyMnKTtcbiAgdXJsID0gc3BsaXQuc2hpZnQoKTtcblxuICBzcGxpdCA9IHVybC5zcGxpdCgnPycpO1xuICB1cmwgPSBzcGxpdC5zaGlmdCgpO1xuXG4gIHNwbGl0ID0gdXJsLnNwbGl0KCc6Ly8nKTtcbiAgaWYgKHNwbGl0Lmxlbmd0aCA+IDEpIHtcbiAgICBwcm90b2NvbCA9IHNwbGl0LnNoaWZ0KCk7XG4gICAgaWYgKG9wdGlvbnMucmVxdWlyZV92YWxpZF9wcm90b2NvbCAmJiBvcHRpb25zLnByb3RvY29scy5pbmRleE9mKHByb3RvY29sKSA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5yZXF1aXJlX3Byb3RvY29sKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMuYWxsb3dfcHJvdG9jb2xfcmVsYXRpdmVfdXJscyAmJiB1cmwuc3Vic3RyKDAsIDIpID09PSAnLy8nKSB7XG4gICAgc3BsaXRbMF0gPSB1cmwuc3Vic3RyKDIpO1xuICB9XG4gIHVybCA9IHNwbGl0LmpvaW4oJzovLycpO1xuXG4gIHNwbGl0ID0gdXJsLnNwbGl0KCcvJyk7XG4gIHVybCA9IHNwbGl0LnNoaWZ0KCk7XG5cbiAgaWYgKHVybCA9PT0gJycgJiYgIW9wdGlvbnMucmVxdWlyZV9ob3N0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzcGxpdCA9IHVybC5zcGxpdCgnQCcpO1xuICBpZiAoc3BsaXQubGVuZ3RoID4gMSkge1xuICAgIGF1dGggPSBzcGxpdC5zaGlmdCgpO1xuICAgIGlmIChhdXRoLmluZGV4T2YoJzonKSA+PSAwICYmIGF1dGguc3BsaXQoJzonKS5sZW5ndGggPiAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIGhvc3RuYW1lID0gc3BsaXQuam9pbignQCcpO1xuXG4gIHBvcnRfc3RyID0gaXB2NiA9IG51bGw7XG4gIHZhciBpcHY2X21hdGNoID0gaG9zdG5hbWUubWF0Y2god3JhcHBlZF9pcHY2KTtcbiAgaWYgKGlwdjZfbWF0Y2gpIHtcbiAgICBob3N0ID0gJyc7XG4gICAgaXB2NiA9IGlwdjZfbWF0Y2hbMV07XG4gICAgcG9ydF9zdHIgPSBpcHY2X21hdGNoWzJdIHx8IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgc3BsaXQgPSBob3N0bmFtZS5zcGxpdCgnOicpO1xuICAgIGhvc3QgPSBzcGxpdC5zaGlmdCgpO1xuICAgIGlmIChzcGxpdC5sZW5ndGgpIHtcbiAgICAgIHBvcnRfc3RyID0gc3BsaXQuam9pbignOicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwb3J0X3N0ciAhPT0gbnVsbCkge1xuICAgIHBvcnQgPSBwYXJzZUludChwb3J0X3N0ciwgMTApO1xuICAgIGlmICghL15bMC05XSskLy50ZXN0KHBvcnRfc3RyKSB8fCBwb3J0IDw9IDAgfHwgcG9ydCA+IDY1NTM1KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKCEoMCwgX2lzSVAyLmRlZmF1bHQpKGhvc3QpICYmICEoMCwgX2lzRlFETjIuZGVmYXVsdCkoaG9zdCwgb3B0aW9ucykgJiYgKCFpcHY2IHx8ICEoMCwgX2lzSVAyLmRlZmF1bHQpKGlwdjYsIDYpKSAmJiBob3N0ICE9PSAnbG9jYWxob3N0Jykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGhvc3QgPSBob3N0IHx8IGlwdjY7XG5cbiAgaWYgKG9wdGlvbnMuaG9zdF93aGl0ZWxpc3QgJiYgIWNoZWNrSG9zdChob3N0LCBvcHRpb25zLmhvc3Rfd2hpdGVsaXN0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAob3B0aW9ucy5ob3N0X2JsYWNrbGlzdCAmJiBjaGVja0hvc3QoaG9zdCwgb3B0aW9ucy5ob3N0X2JsYWNrbGlzdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzVVVJRDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciB1dWlkID0ge1xuICAzOiAvXlswLTlBLUZdezh9LVswLTlBLUZdezR9LTNbMC05QS1GXXszfS1bMC05QS1GXXs0fS1bMC05QS1GXXsxMn0kL2ksXG4gIDQ6IC9eWzAtOUEtRl17OH0tWzAtOUEtRl17NH0tNFswLTlBLUZdezN9LVs4OUFCXVswLTlBLUZdezN9LVswLTlBLUZdezEyfSQvaSxcbiAgNTogL15bMC05QS1GXXs4fS1bMC05QS1GXXs0fS01WzAtOUEtRl17M30tWzg5QUJdWzAtOUEtRl17M30tWzAtOUEtRl17MTJ9JC9pLFxuICBhbGw6IC9eWzAtOUEtRl17OH0tWzAtOUEtRl17NH0tWzAtOUEtRl17NH0tWzAtOUEtRl17NH0tWzAtOUEtRl17MTJ9JC9pXG59O1xuXG5mdW5jdGlvbiBpc1VVSUQoc3RyKSB7XG4gIHZhciB2ZXJzaW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnYWxsJztcblxuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmFyIHBhdHRlcm4gPSB1dWlkW3ZlcnNpb25dO1xuICByZXR1cm4gcGF0dGVybiAmJiBwYXR0ZXJuLnRlc3Qoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzVXBwZXJjYXNlO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gaXNVcHBlcmNhc2Uoc3RyKSB7XG4gICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICByZXR1cm4gc3RyID09PSBzdHIudG9VcHBlckNhc2UoKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzVmFyaWFibGVXaWR0aDtcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbnZhciBfaXNGdWxsV2lkdGggPSByZXF1aXJlKCcuL2lzRnVsbFdpZHRoJyk7XG5cbnZhciBfaXNIYWxmV2lkdGggPSByZXF1aXJlKCcuL2lzSGFsZldpZHRoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIGlzVmFyaWFibGVXaWR0aChzdHIpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHJldHVybiBfaXNGdWxsV2lkdGguZnVsbFdpZHRoLnRlc3Qoc3RyKSAmJiBfaXNIYWxmV2lkdGguaGFsZldpZHRoLnRlc3Qoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzV2hpdGVsaXN0ZWQ7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBpc1doaXRlbGlzdGVkKHN0ciwgY2hhcnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIGZvciAodmFyIGkgPSBzdHIubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoY2hhcnMuaW5kZXhPZihzdHJbaV0pID09PSAtMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGx0cmltO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gbHRyaW0oc3RyLCBjaGFycykge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmFyIHBhdHRlcm4gPSBjaGFycyA/IG5ldyBSZWdFeHAoJ15bJyArIGNoYXJzICsgJ10rJywgJ2cnKSA6IC9eXFxzKy9nO1xuICByZXR1cm4gc3RyLnJlcGxhY2UocGF0dGVybiwgJycpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gbWF0Y2hlcztcblxudmFyIF9hc3NlcnRTdHJpbmcgPSByZXF1aXJlKCcuL3V0aWwvYXNzZXJ0U3RyaW5nJyk7XG5cbnZhciBfYXNzZXJ0U3RyaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydFN0cmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIG1hdGNoZXMoc3RyLCBwYXR0ZXJuLCBtb2RpZmllcnMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGF0dGVybikgIT09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcGF0dGVybiA9IG5ldyBSZWdFeHAocGF0dGVybiwgbW9kaWZpZXJzKTtcbiAgfVxuICByZXR1cm4gcGF0dGVybi50ZXN0KHN0cik7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBub3JtYWxpemVFbWFpbDtcblxudmFyIF9pc0VtYWlsID0gcmVxdWlyZSgnLi9pc0VtYWlsJyk7XG5cbnZhciBfaXNFbWFpbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pc0VtYWlsKTtcblxudmFyIF9tZXJnZSA9IHJlcXVpcmUoJy4vdXRpbC9tZXJnZScpO1xuXG52YXIgX21lcmdlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lcmdlKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIGRlZmF1bHRfbm9ybWFsaXplX2VtYWlsX29wdGlvbnMgPSB7XG4gIC8vIFRoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcHBseSB0byBhbGwgZW1haWwgYWRkcmVzc2VzXG4gIC8vIExvd2VyY2FzZXMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIGVtYWlsIGFkZHJlc3MuXG4gIC8vIFBsZWFzZSBub3RlIHRoaXMgbWF5IHZpb2xhdGUgUkZDIDUzMjEgYXMgcGVyIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzk4MDgzMzIvMTkyMDI0KS5cbiAgLy8gVGhlIGRvbWFpbiBpcyBhbHdheXMgbG93ZXJjYXNlZCwgYXMgcGVyIFJGQyAxMDM1XG4gIGFsbF9sb3dlcmNhc2U6IHRydWUsXG5cbiAgLy8gVGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyBhcmUgc3BlY2lmaWMgdG8gR01haWxcbiAgLy8gTG93ZXJjYXNlcyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgR01haWwgYWRkcmVzcyAoa25vd24gdG8gYmUgY2FzZS1pbnNlbnNpdGl2ZSlcbiAgZ21haWxfbG93ZXJjYXNlOiB0cnVlLFxuICAvLyBSZW1vdmVzIGRvdHMgZnJvbSB0aGUgbG9jYWwgcGFydCBvZiB0aGUgZW1haWwgYWRkcmVzcywgYXMgdGhhdCdzIGlnbm9yZWQgYnkgR01haWxcbiAgZ21haWxfcmVtb3ZlX2RvdHM6IHRydWUsXG4gIC8vIFJlbW92ZXMgdGhlIHN1YmFkZHJlc3MgKGUuZy4gXCIrZm9vXCIpIGZyb20gdGhlIGVtYWlsIGFkZHJlc3NcbiAgZ21haWxfcmVtb3ZlX3N1YmFkZHJlc3M6IHRydWUsXG4gIC8vIENvbnZlcnN0cyB0aGUgZ29vZ2xlbWFpbC5jb20gZG9tYWluIHRvIGdtYWlsLmNvbVxuICBnbWFpbF9jb252ZXJ0X2dvb2dsZW1haWxkb3Rjb206IHRydWUsXG5cbiAgLy8gVGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyBhcmUgc3BlY2lmaWMgdG8gT3V0bG9vay5jb20gLyBXaW5kb3dzIExpdmUgLyBIb3RtYWlsXG4gIC8vIExvd2VyY2FzZXMgdGhlIGxvY2FsIHBhcnQgb2YgdGhlIE91dGxvb2suY29tIGFkZHJlc3MgKGtub3duIHRvIGJlIGNhc2UtaW5zZW5zaXRpdmUpXG4gIG91dGxvb2tkb3Rjb21fbG93ZXJjYXNlOiB0cnVlLFxuICAvLyBSZW1vdmVzIHRoZSBzdWJhZGRyZXNzIChlLmcuIFwiK2Zvb1wiKSBmcm9tIHRoZSBlbWFpbCBhZGRyZXNzXG4gIG91dGxvb2tkb3Rjb21fcmVtb3ZlX3N1YmFkZHJlc3M6IHRydWUsXG5cbiAgLy8gVGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyBhcmUgc3BlY2lmaWMgdG8gWWFob29cbiAgLy8gTG93ZXJjYXNlcyB0aGUgbG9jYWwgcGFydCBvZiB0aGUgWWFob28gYWRkcmVzcyAoa25vd24gdG8gYmUgY2FzZS1pbnNlbnNpdGl2ZSlcbiAgeWFob29fbG93ZXJjYXNlOiB0cnVlLFxuICAvLyBSZW1vdmVzIHRoZSBzdWJhZGRyZXNzIChlLmcuIFwiLWZvb1wiKSBmcm9tIHRoZSBlbWFpbCBhZGRyZXNzXG4gIHlhaG9vX3JlbW92ZV9zdWJhZGRyZXNzOiB0cnVlLFxuXG4gIC8vIFRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMgYXJlIHNwZWNpZmljIHRvIGlDbG91ZFxuICAvLyBMb3dlcmNhc2VzIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBpQ2xvdWQgYWRkcmVzcyAoa25vd24gdG8gYmUgY2FzZS1pbnNlbnNpdGl2ZSlcbiAgaWNsb3VkX2xvd2VyY2FzZTogdHJ1ZSxcbiAgLy8gUmVtb3ZlcyB0aGUgc3ViYWRkcmVzcyAoZS5nLiBcIitmb29cIikgZnJvbSB0aGUgZW1haWwgYWRkcmVzc1xuICBpY2xvdWRfcmVtb3ZlX3N1YmFkZHJlc3M6IHRydWVcbn07XG5cbi8vIExpc3Qgb2YgZG9tYWlucyB1c2VkIGJ5IGlDbG91ZFxudmFyIGljbG91ZF9kb21haW5zID0gWydpY2xvdWQuY29tJywgJ21lLmNvbSddO1xuXG4vLyBMaXN0IG9mIGRvbWFpbnMgdXNlZCBieSBPdXRsb29rLmNvbSBhbmQgaXRzIHByZWRlY2Vzc29yc1xuLy8gVGhpcyBsaXN0IGlzIGxpa2VseSBpbmNvbXBsZXRlLlxuLy8gUGFydGlhbCByZWZlcmVuY2U6XG4vLyBodHRwczovL2Jsb2dzLm9mZmljZS5jb20vMjAxMy8wNC8xNy9vdXRsb29rLWNvbS1nZXRzLXR3by1zdGVwLXZlcmlmaWNhdGlvbi1zaWduLWluLWJ5LWFsaWFzLWFuZC1uZXctaW50ZXJuYXRpb25hbC1kb21haW5zL1xudmFyIG91dGxvb2tkb3Rjb21fZG9tYWlucyA9IFsnaG90bWFpbC5hdCcsICdob3RtYWlsLmJlJywgJ2hvdG1haWwuY2EnLCAnaG90bWFpbC5jbCcsICdob3RtYWlsLmNvLmlsJywgJ2hvdG1haWwuY28ubnonLCAnaG90bWFpbC5jby50aCcsICdob3RtYWlsLmNvLnVrJywgJ2hvdG1haWwuY29tJywgJ2hvdG1haWwuY29tLmFyJywgJ2hvdG1haWwuY29tLmF1JywgJ2hvdG1haWwuY29tLmJyJywgJ2hvdG1haWwuY29tLmdyJywgJ2hvdG1haWwuY29tLm14JywgJ2hvdG1haWwuY29tLnBlJywgJ2hvdG1haWwuY29tLnRyJywgJ2hvdG1haWwuY29tLnZuJywgJ2hvdG1haWwuY3onLCAnaG90bWFpbC5kZScsICdob3RtYWlsLmRrJywgJ2hvdG1haWwuZXMnLCAnaG90bWFpbC5mcicsICdob3RtYWlsLmh1JywgJ2hvdG1haWwuaWQnLCAnaG90bWFpbC5pZScsICdob3RtYWlsLmluJywgJ2hvdG1haWwuaXQnLCAnaG90bWFpbC5qcCcsICdob3RtYWlsLmtyJywgJ2hvdG1haWwubHYnLCAnaG90bWFpbC5teScsICdob3RtYWlsLnBoJywgJ2hvdG1haWwucHQnLCAnaG90bWFpbC5zYScsICdob3RtYWlsLnNnJywgJ2hvdG1haWwuc2snLCAnbGl2ZS5iZScsICdsaXZlLmNvLnVrJywgJ2xpdmUuY29tJywgJ2xpdmUuY29tLmFyJywgJ2xpdmUuY29tLm14JywgJ2xpdmUuZGUnLCAnbGl2ZS5lcycsICdsaXZlLmV1JywgJ2xpdmUuZnInLCAnbGl2ZS5pdCcsICdsaXZlLm5sJywgJ21zbi5jb20nLCAnb3V0bG9vay5hdCcsICdvdXRsb29rLmJlJywgJ291dGxvb2suY2wnLCAnb3V0bG9vay5jby5pbCcsICdvdXRsb29rLmNvLm56JywgJ291dGxvb2suY28udGgnLCAnb3V0bG9vay5jb20nLCAnb3V0bG9vay5jb20uYXInLCAnb3V0bG9vay5jb20uYXUnLCAnb3V0bG9vay5jb20uYnInLCAnb3V0bG9vay5jb20uZ3InLCAnb3V0bG9vay5jb20ucGUnLCAnb3V0bG9vay5jb20udHInLCAnb3V0bG9vay5jb20udm4nLCAnb3V0bG9vay5jeicsICdvdXRsb29rLmRlJywgJ291dGxvb2suZGsnLCAnb3V0bG9vay5lcycsICdvdXRsb29rLmZyJywgJ291dGxvb2suaHUnLCAnb3V0bG9vay5pZCcsICdvdXRsb29rLmllJywgJ291dGxvb2suaW4nLCAnb3V0bG9vay5pdCcsICdvdXRsb29rLmpwJywgJ291dGxvb2sua3InLCAnb3V0bG9vay5sdicsICdvdXRsb29rLm15JywgJ291dGxvb2sucGgnLCAnb3V0bG9vay5wdCcsICdvdXRsb29rLnNhJywgJ291dGxvb2suc2cnLCAnb3V0bG9vay5zaycsICdwYXNzcG9ydC5jb20nXTtcblxuLy8gTGlzdCBvZiBkb21haW5zIHVzZWQgYnkgWWFob28gTWFpbFxuLy8gVGhpcyBsaXN0IGlzIGxpa2VseSBpbmNvbXBsZXRlXG52YXIgeWFob29fZG9tYWlucyA9IFsncm9ja2V0bWFpbC5jb20nLCAneWFob28uY2EnLCAneWFob28uY28udWsnLCAneWFob28uY29tJywgJ3lhaG9vLmRlJywgJ3lhaG9vLmZyJywgJ3lhaG9vLmluJywgJ3lhaG9vLml0JywgJ3ltYWlsLmNvbSddO1xuXG5mdW5jdGlvbiBub3JtYWxpemVFbWFpbChlbWFpbCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gKDAsIF9tZXJnZTIuZGVmYXVsdCkob3B0aW9ucywgZGVmYXVsdF9ub3JtYWxpemVfZW1haWxfb3B0aW9ucyk7XG5cbiAgaWYgKCEoMCwgX2lzRW1haWwyLmRlZmF1bHQpKGVtYWlsKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciByYXdfcGFydHMgPSBlbWFpbC5zcGxpdCgnQCcpO1xuICB2YXIgZG9tYWluID0gcmF3X3BhcnRzLnBvcCgpO1xuICB2YXIgdXNlciA9IHJhd19wYXJ0cy5qb2luKCdAJyk7XG4gIHZhciBwYXJ0cyA9IFt1c2VyLCBkb21haW5dO1xuXG4gIC8vIFRoZSBkb21haW4gaXMgYWx3YXlzIGxvd2VyY2FzZWQsIGFzIGl0J3MgY2FzZS1pbnNlbnNpdGl2ZSBwZXIgUkZDIDEwMzVcbiAgcGFydHNbMV0gPSBwYXJ0c1sxXS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChwYXJ0c1sxXSA9PT0gJ2dtYWlsLmNvbScgfHwgcGFydHNbMV0gPT09ICdnb29nbGVtYWlsLmNvbScpIHtcbiAgICAvLyBBZGRyZXNzIGlzIEdNYWlsXG4gICAgaWYgKG9wdGlvbnMuZ21haWxfcmVtb3ZlX3N1YmFkZHJlc3MpIHtcbiAgICAgIHBhcnRzWzBdID0gcGFydHNbMF0uc3BsaXQoJysnKVswXTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuZ21haWxfcmVtb3ZlX2RvdHMpIHtcbiAgICAgIHBhcnRzWzBdID0gcGFydHNbMF0ucmVwbGFjZSgvXFwuL2csICcnKTtcbiAgICB9XG4gICAgaWYgKCFwYXJ0c1swXS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuYWxsX2xvd2VyY2FzZSB8fCBvcHRpb25zLmdtYWlsX2xvd2VyY2FzZSkge1xuICAgICAgcGFydHNbMF0gPSBwYXJ0c1swXS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbiAgICBwYXJ0c1sxXSA9IG9wdGlvbnMuZ21haWxfY29udmVydF9nb29nbGVtYWlsZG90Y29tID8gJ2dtYWlsLmNvbScgOiBwYXJ0c1sxXTtcbiAgfSBlbHNlIGlmICh+aWNsb3VkX2RvbWFpbnMuaW5kZXhPZihwYXJ0c1sxXSkpIHtcbiAgICAvLyBBZGRyZXNzIGlzIGlDbG91ZFxuICAgIGlmIChvcHRpb25zLmljbG91ZF9yZW1vdmVfc3ViYWRkcmVzcykge1xuICAgICAgcGFydHNbMF0gPSBwYXJ0c1swXS5zcGxpdCgnKycpWzBdO1xuICAgIH1cbiAgICBpZiAoIXBhcnRzWzBdLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5hbGxfbG93ZXJjYXNlIHx8IG9wdGlvbnMuaWNsb3VkX2xvd2VyY2FzZSkge1xuICAgICAgcGFydHNbMF0gPSBwYXJ0c1swXS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh+b3V0bG9va2RvdGNvbV9kb21haW5zLmluZGV4T2YocGFydHNbMV0pKSB7XG4gICAgLy8gQWRkcmVzcyBpcyBPdXRsb29rLmNvbVxuICAgIGlmIChvcHRpb25zLm91dGxvb2tkb3Rjb21fcmVtb3ZlX3N1YmFkZHJlc3MpIHtcbiAgICAgIHBhcnRzWzBdID0gcGFydHNbMF0uc3BsaXQoJysnKVswXTtcbiAgICB9XG4gICAgaWYgKCFwYXJ0c1swXS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuYWxsX2xvd2VyY2FzZSB8fCBvcHRpb25zLm91dGxvb2tkb3Rjb21fbG93ZXJjYXNlKSB7XG4gICAgICBwYXJ0c1swXSA9IHBhcnRzWzBdLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKH55YWhvb19kb21haW5zLmluZGV4T2YocGFydHNbMV0pKSB7XG4gICAgLy8gQWRkcmVzcyBpcyBZYWhvb1xuICAgIGlmIChvcHRpb25zLnlhaG9vX3JlbW92ZV9zdWJhZGRyZXNzKSB7XG4gICAgICB2YXIgY29tcG9uZW50cyA9IHBhcnRzWzBdLnNwbGl0KCctJyk7XG4gICAgICBwYXJ0c1swXSA9IGNvbXBvbmVudHMubGVuZ3RoID4gMSA/IGNvbXBvbmVudHMuc2xpY2UoMCwgLTEpLmpvaW4oJy0nKSA6IGNvbXBvbmVudHNbMF07XG4gICAgfVxuICAgIGlmICghcGFydHNbMF0ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmFsbF9sb3dlcmNhc2UgfHwgb3B0aW9ucy55YWhvb19sb3dlcmNhc2UpIHtcbiAgICAgIHBhcnRzWzBdID0gcGFydHNbMF0udG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5hbGxfbG93ZXJjYXNlKSB7XG4gICAgLy8gQW55IG90aGVyIGFkZHJlc3NcbiAgICBwYXJ0c1swXSA9IHBhcnRzWzBdLnRvTG93ZXJDYXNlKCk7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJ0AnKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHJ0cmltO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gcnRyaW0oc3RyLCBjaGFycykge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgdmFyIHBhdHRlcm4gPSBjaGFycyA/IG5ldyBSZWdFeHAoJ1snICsgY2hhcnMgKyAnXScpIDogL1xccy87XG5cbiAgdmFyIGlkeCA9IHN0ci5sZW5ndGggLSAxO1xuICB3aGlsZSAoaWR4ID49IDAgJiYgcGF0dGVybi50ZXN0KHN0cltpZHhdKSkge1xuICAgIGlkeC0tO1xuICB9XG5cbiAgcmV0dXJuIGlkeCA8IHN0ci5sZW5ndGggPyBzdHIuc3Vic3RyKDAsIGlkeCArIDEpIDogc3RyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gc3RyaXBMb3c7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG52YXIgX2JsYWNrbGlzdCA9IHJlcXVpcmUoJy4vYmxhY2tsaXN0Jyk7XG5cbnZhciBfYmxhY2tsaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JsYWNrbGlzdCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHN0cmlwTG93KHN0ciwga2VlcF9uZXdfbGluZXMpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIHZhciBjaGFycyA9IGtlZXBfbmV3X2xpbmVzID8gJ1xcXFx4MDAtXFxcXHgwOVxcXFx4MEJcXFxceDBDXFxcXHgwRS1cXFxceDFGXFxcXHg3RicgOiAnXFxcXHgwMC1cXFxceDFGXFxcXHg3Ric7XG4gIHJldHVybiAoMCwgX2JsYWNrbGlzdDIuZGVmYXVsdCkoc3RyLCBjaGFycyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB0b0Jvb2xlYW47XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB0b0Jvb2xlYW4oc3RyLCBzdHJpY3QpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKHN0cik7XG4gIGlmIChzdHJpY3QpIHtcbiAgICByZXR1cm4gc3RyID09PSAnMScgfHwgc3RyID09PSAndHJ1ZSc7XG4gIH1cbiAgcmV0dXJuIHN0ciAhPT0gJzAnICYmIHN0ciAhPT0gJ2ZhbHNlJyAmJiBzdHIgIT09ICcnO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdG9EYXRlO1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdG9EYXRlKGRhdGUpIHtcbiAgKDAsIF9hc3NlcnRTdHJpbmcyLmRlZmF1bHQpKGRhdGUpO1xuICBkYXRlID0gRGF0ZS5wYXJzZShkYXRlKTtcbiAgcmV0dXJuICFpc05hTihkYXRlKSA/IG5ldyBEYXRlKGRhdGUpIDogbnVsbDtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHRvRmxvYXQ7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB0b0Zsb2F0KHN0cikge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHBhcnNlRmxvYXQoc3RyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHRvSW50O1xuXG52YXIgX2Fzc2VydFN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbC9hc3NlcnRTdHJpbmcnKTtcblxudmFyIF9hc3NlcnRTdHJpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0U3RyaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdG9JbnQoc3RyLCByYWRpeCkge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHBhcnNlSW50KHN0ciwgcmFkaXggfHwgMTApO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdHJpbTtcblxudmFyIF9ydHJpbSA9IHJlcXVpcmUoJy4vcnRyaW0nKTtcblxudmFyIF9ydHJpbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9ydHJpbSk7XG5cbnZhciBfbHRyaW0gPSByZXF1aXJlKCcuL2x0cmltJyk7XG5cbnZhciBfbHRyaW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbHRyaW0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB0cmltKHN0ciwgY2hhcnMpIHtcbiAgcmV0dXJuICgwLCBfcnRyaW0yLmRlZmF1bHQpKCgwLCBfbHRyaW0yLmRlZmF1bHQpKHN0ciwgY2hhcnMpLCBjaGFycyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICAgICAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdW5lc2NhcGU7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB1bmVzY2FwZShzdHIpIHtcbiAgICAgICgwLCBfYXNzZXJ0U3RyaW5nMi5kZWZhdWx0KShzdHIpO1xuICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mYW1wOy9nLCAnJicpLnJlcGxhY2UoLyZxdW90Oy9nLCAnXCInKS5yZXBsYWNlKC8mI3gyNzsvZywgXCInXCIpLnJlcGxhY2UoLyZsdDsvZywgJzwnKS5yZXBsYWNlKC8mZ3Q7L2csICc+JykucmVwbGFjZSgvJiN4MkY7L2csICcvJykucmVwbGFjZSgvJiM5NjsvZywgJ2AnKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGFzc2VydFN0cmluZztcbmZ1bmN0aW9uIGFzc2VydFN0cmluZyhpbnB1dCkge1xuICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgbGlicmFyeSAodmFsaWRhdG9yLmpzKSB2YWxpZGF0ZXMgc3RyaW5ncyBvbmx5Jyk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IG1lcmdlO1xuZnVuY3Rpb24gbWVyZ2UoKSB7XG4gIHZhciBvYmogPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9O1xuICB2YXIgZGVmYXVsdHMgPSBhcmd1bWVudHNbMV07XG5cbiAgZm9yICh2YXIga2V5IGluIGRlZmF1bHRzKSB7XG4gICAgaWYgKHR5cGVvZiBvYmpba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9ialtrZXldID0gZGVmYXVsdHNba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iajtcbn1cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5leHBvcnRzLmRlZmF1bHQgPSB0b1N0cmluZztcbmZ1bmN0aW9uIHRvU3RyaW5nKGlucHV0KSB7XG4gIGlmICgodHlwZW9mIGlucHV0ID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihpbnB1dCkpID09PSAnb2JqZWN0JyAmJiBpbnB1dCAhPT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgaW5wdXQudG9TdHJpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlucHV0ID0gaW5wdXQudG9TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5wdXQgPSAnW29iamVjdCBPYmplY3RdJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoaW5wdXQgPT09IG51bGwgfHwgdHlwZW9mIGlucHV0ID09PSAndW5kZWZpbmVkJyB8fCBpc05hTihpbnB1dCkgJiYgIWlucHV0Lmxlbmd0aCkge1xuICAgIGlucHV0ID0gJyc7XG4gIH1cbiAgcmV0dXJuIFN0cmluZyhpbnB1dCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB3aGl0ZWxpc3Q7XG5cbnZhciBfYXNzZXJ0U3RyaW5nID0gcmVxdWlyZSgnLi91dGlsL2Fzc2VydFN0cmluZycpO1xuXG52YXIgX2Fzc2VydFN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnRTdHJpbmcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB3aGl0ZWxpc3Qoc3RyLCBjaGFycykge1xuICAoMCwgX2Fzc2VydFN0cmluZzIuZGVmYXVsdCkoc3RyKTtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKG5ldyBSZWdFeHAoJ1teJyArIGNoYXJzICsgJ10rJywgJ2cnKSwgJycpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiIWZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiB0LldhdmVzPWUuY2FsbCh0KSx0LldhdmVzfSk6XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9ZS5jYWxsKHQpOnQuV2F2ZXM9ZS5jYWxsKHQpfShcIm9iamVjdFwiPT10eXBlb2YgZ2xvYmFsP2dsb2JhbDp0aGlzLGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gdCh0KXtyZXR1cm4gbnVsbCE9PXQmJnQ9PT10LndpbmRvd31mdW5jdGlvbiBlKGUpe3JldHVybiB0KGUpP2U6OT09PWUubm9kZVR5cGUmJmUuZGVmYXVsdFZpZXd9ZnVuY3Rpb24gbih0KXt2YXIgZT10eXBlb2YgdDtyZXR1cm5cImZ1bmN0aW9uXCI9PT1lfHxcIm9iamVjdFwiPT09ZSYmISF0fWZ1bmN0aW9uIG8odCl7cmV0dXJuIG4odCkmJnQubm9kZVR5cGU+MH1mdW5jdGlvbiBhKHQpe3ZhciBlPWYuY2FsbCh0KTtyZXR1cm5cIltvYmplY3QgU3RyaW5nXVwiPT09ZT9kKHQpOm4odCkmJi9eXFxbb2JqZWN0IChBcnJheXxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdHxPYmplY3QpXFxdJC8udGVzdChlKSYmdC5oYXNPd25Qcm9wZXJ0eShcImxlbmd0aFwiKT90Om8odCk/W3RdOltdfWZ1bmN0aW9uIGkodCl7dmFyIG4sbyxhPXt0b3A6MCxsZWZ0OjB9LGk9dCYmdC5vd25lckRvY3VtZW50O3JldHVybiBuPWkuZG9jdW1lbnRFbGVtZW50LHZvaWQgMCE9PXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0JiYoYT10LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxvPWUoaSkse3RvcDphLnRvcCtvLnBhZ2VZT2Zmc2V0LW4uY2xpZW50VG9wLGxlZnQ6YS5sZWZ0K28ucGFnZVhPZmZzZXQtbi5jbGllbnRMZWZ0fX1mdW5jdGlvbiByKHQpe3ZhciBlPVwiXCI7Zm9yKHZhciBuIGluIHQpdC5oYXNPd25Qcm9wZXJ0eShuKSYmKGUrPW4rXCI6XCIrdFtuXStcIjtcIik7cmV0dXJuIGV9ZnVuY3Rpb24gcyh0LGUsbil7aWYobil7bi5jbGFzc0xpc3QucmVtb3ZlKFwid2F2ZXMtcmlwcGxpbmdcIik7dmFyIG89bi5nZXRBdHRyaWJ1dGUoXCJkYXRhLXhcIiksYT1uLmdldEF0dHJpYnV0ZShcImRhdGEteVwiKSxpPW4uZ2V0QXR0cmlidXRlKFwiZGF0YS1zY2FsZVwiKSxzPW4uZ2V0QXR0cmlidXRlKFwiZGF0YS10cmFuc2xhdGVcIiksdT0zNTAtKERhdGUubm93KCktTnVtYmVyKG4uZ2V0QXR0cmlidXRlKFwiZGF0YS1ob2xkXCIpKSk7dTwwJiYodT0wKSxcIm1vdXNlbW92ZVwiPT09dC50eXBlJiYodT0xNTApO3ZhciBjPVwibW91c2Vtb3ZlXCI9PT10LnR5cGU/MjUwMDp2LmR1cmF0aW9uO3NldFRpbWVvdXQoZnVuY3Rpb24oKXt2YXIgdD17dG9wOmErXCJweFwiLGxlZnQ6bytcInB4XCIsb3BhY2l0eTpcIjBcIixcIi13ZWJraXQtdHJhbnNpdGlvbi1kdXJhdGlvblwiOmMrXCJtc1wiLFwiLW1vei10cmFuc2l0aW9uLWR1cmF0aW9uXCI6YytcIm1zXCIsXCItby10cmFuc2l0aW9uLWR1cmF0aW9uXCI6YytcIm1zXCIsXCJ0cmFuc2l0aW9uLWR1cmF0aW9uXCI6YytcIm1zXCIsXCItd2Via2l0LXRyYW5zZm9ybVwiOmkrXCIgXCIrcyxcIi1tb3otdHJhbnNmb3JtXCI6aStcIiBcIitzLFwiLW1zLXRyYW5zZm9ybVwiOmkrXCIgXCIrcyxcIi1vLXRyYW5zZm9ybVwiOmkrXCIgXCIrcyx0cmFuc2Zvcm06aStcIiBcIitzfTtuLnNldEF0dHJpYnV0ZShcInN0eWxlXCIscih0KSksc2V0VGltZW91dChmdW5jdGlvbigpe3RyeXtlLnJlbW92ZUNoaWxkKG4pfWNhdGNoKHQpe3JldHVybiExfX0sYyl9LHUpfX1mdW5jdGlvbiB1KHQpe2lmKCExPT09aC5hbGxvd0V2ZW50KHQpKXJldHVybiBudWxsO2Zvcih2YXIgZT1udWxsLG49dC50YXJnZXR8fHQuc3JjRWxlbWVudDtuLnBhcmVudEVsZW1lbnQ7KXtpZighKG4gaW5zdGFuY2VvZiBTVkdFbGVtZW50KSYmbi5jbGFzc0xpc3QuY29udGFpbnMoXCJ3YXZlcy1lZmZlY3RcIikpe2U9bjticmVha31uPW4ucGFyZW50RWxlbWVudH1yZXR1cm4gZX1mdW5jdGlvbiBjKHQpe3ZhciBlPXUodCk7aWYobnVsbCE9PWUpe2lmKGUuZGlzYWJsZWR8fGUuZ2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIil8fGUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZGlzYWJsZWRcIikpcmV0dXJuO2lmKGgucmVnaXN0ZXJFdmVudCh0KSxcInRvdWNoc3RhcnRcIj09PXQudHlwZSYmdi5kZWxheSl7dmFyIG49ITEsbz1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bz1udWxsLHYuc2hvdyh0LGUpfSx2LmRlbGF5KSxhPWZ1bmN0aW9uKGEpe28mJihjbGVhclRpbWVvdXQobyksbz1udWxsLHYuc2hvdyh0LGUpKSxufHwobj0hMCx2LmhpZGUoYSxlKSkscigpfSxpPWZ1bmN0aW9uKHQpe28mJihjbGVhclRpbWVvdXQobyksbz1udWxsKSxhKHQpLHIoKX07ZS5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsaSwhMSksZS5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIixhLCExKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLGEsITEpO3ZhciByPWZ1bmN0aW9uKCl7ZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsaSksZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIixhKSxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLGEpfX1lbHNlIHYuc2hvdyh0LGUpLG0mJihlLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLHYuaGlkZSwhMSksZS5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIix2LmhpZGUsITEpKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsdi5oaWRlLCExKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWxlYXZlXCIsdi5oaWRlLCExKX19dmFyIGw9bHx8e30sZD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsLmJpbmQoZG9jdW1lbnQpLGY9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyxtPVwib250b3VjaHN0YXJ0XCJpbiB3aW5kb3csdj17ZHVyYXRpb246NzUwLGRlbGF5OjIwMCxzaG93OmZ1bmN0aW9uKHQsZSxuKXtpZigyPT09dC5idXR0b24pcmV0dXJuITE7ZT1lfHx0aGlzO3ZhciBvPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7by5jbGFzc05hbWU9XCJ3YXZlcy1yaXBwbGUgd2F2ZXMtcmlwcGxpbmdcIixlLmFwcGVuZENoaWxkKG8pO3ZhciBhPWkoZSkscz0wLHU9MDtcInRvdWNoZXNcImluIHQmJnQudG91Y2hlcy5sZW5ndGg/KHM9dC50b3VjaGVzWzBdLnBhZ2VZLWEudG9wLHU9dC50b3VjaGVzWzBdLnBhZ2VYLWEubGVmdCk6KHM9dC5wYWdlWS1hLnRvcCx1PXQucGFnZVgtYS5sZWZ0KSx1PXU+PTA/dTowLHM9cz49MD9zOjA7dmFyIGM9XCJzY2FsZShcIitlLmNsaWVudFdpZHRoLzEwMCozK1wiKVwiLGw9XCJ0cmFuc2xhdGUoMCwwKVwiO24mJihsPVwidHJhbnNsYXRlKFwiK24ueCtcInB4LCBcIituLnkrXCJweClcIiksby5zZXRBdHRyaWJ1dGUoXCJkYXRhLWhvbGRcIixEYXRlLm5vdygpKSxvLnNldEF0dHJpYnV0ZShcImRhdGEteFwiLHUpLG8uc2V0QXR0cmlidXRlKFwiZGF0YS15XCIscyksby5zZXRBdHRyaWJ1dGUoXCJkYXRhLXNjYWxlXCIsYyksby5zZXRBdHRyaWJ1dGUoXCJkYXRhLXRyYW5zbGF0ZVwiLGwpO3ZhciBkPXt0b3A6cytcInB4XCIsbGVmdDp1K1wicHhcIn07by5jbGFzc0xpc3QuYWRkKFwid2F2ZXMtbm90cmFuc2l0aW9uXCIpLG8uc2V0QXR0cmlidXRlKFwic3R5bGVcIixyKGQpKSxvLmNsYXNzTGlzdC5yZW1vdmUoXCJ3YXZlcy1ub3RyYW5zaXRpb25cIiksZFtcIi13ZWJraXQtdHJhbnNmb3JtXCJdPWMrXCIgXCIrbCxkW1wiLW1vei10cmFuc2Zvcm1cIl09YytcIiBcIitsLGRbXCItbXMtdHJhbnNmb3JtXCJdPWMrXCIgXCIrbCxkW1wiLW8tdHJhbnNmb3JtXCJdPWMrXCIgXCIrbCxkLnRyYW5zZm9ybT1jK1wiIFwiK2wsZC5vcGFjaXR5PVwiMVwiO3ZhciBmPVwibW91c2Vtb3ZlXCI9PT10LnR5cGU/MjUwMDp2LmR1cmF0aW9uO2RbXCItd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb25cIl09ZitcIm1zXCIsZFtcIi1tb3otdHJhbnNpdGlvbi1kdXJhdGlvblwiXT1mK1wibXNcIixkW1wiLW8tdHJhbnNpdGlvbi1kdXJhdGlvblwiXT1mK1wibXNcIixkW1widHJhbnNpdGlvbi1kdXJhdGlvblwiXT1mK1wibXNcIixvLnNldEF0dHJpYnV0ZShcInN0eWxlXCIscihkKSl9LGhpZGU6ZnVuY3Rpb24odCxlKXtmb3IodmFyIG49KGU9ZXx8dGhpcykuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcIndhdmVzLXJpcHBsaW5nXCIpLG89MCxhPW4ubGVuZ3RoO288YTtvKyspcyh0LGUsbltvXSk7bSYmKGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsdi5oaWRlKSxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLHYuaGlkZSkpLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIix2LmhpZGUpLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbGVhdmVcIix2LmhpZGUpfX0scD17aW5wdXQ6ZnVuY3Rpb24odCl7dmFyIGU9dC5wYXJlbnROb2RlO2lmKFwiaVwiIT09ZS50YWdOYW1lLnRvTG93ZXJDYXNlKCl8fCFlLmNsYXNzTGlzdC5jb250YWlucyhcIndhdmVzLWVmZmVjdFwiKSl7dmFyIG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlcIik7bi5jbGFzc05hbWU9dC5jbGFzc05hbWUrXCIgd2F2ZXMtaW5wdXQtd3JhcHBlclwiLHQuY2xhc3NOYW1lPVwid2F2ZXMtYnV0dG9uLWlucHV0XCIsZS5yZXBsYWNlQ2hpbGQobix0KSxuLmFwcGVuZENoaWxkKHQpO3ZhciBvPXdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHQsbnVsbCksYT1vLmNvbG9yLGk9by5iYWNrZ3JvdW5kQ29sb3I7bi5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLFwiY29sb3I6XCIrYStcIjtiYWNrZ3JvdW5kOlwiK2kpLHQuc2V0QXR0cmlidXRlKFwic3R5bGVcIixcImJhY2tncm91bmQtY29sb3I6cmdiYSgwLDAsMCwwKTtcIil9fSxpbWc6ZnVuY3Rpb24odCl7dmFyIGU9dC5wYXJlbnROb2RlO2lmKFwiaVwiIT09ZS50YWdOYW1lLnRvTG93ZXJDYXNlKCl8fCFlLmNsYXNzTGlzdC5jb250YWlucyhcIndhdmVzLWVmZmVjdFwiKSl7dmFyIG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlcIik7ZS5yZXBsYWNlQ2hpbGQobix0KSxuLmFwcGVuZENoaWxkKHQpfX19LGg9e3RvdWNoZXM6MCxhbGxvd0V2ZW50OmZ1bmN0aW9uKHQpe3ZhciBlPSEwO3JldHVybi9eKG1vdXNlZG93bnxtb3VzZW1vdmUpJC8udGVzdCh0LnR5cGUpJiZoLnRvdWNoZXMmJihlPSExKSxlfSxyZWdpc3RlckV2ZW50OmZ1bmN0aW9uKHQpe3ZhciBlPXQudHlwZTtcInRvdWNoc3RhcnRcIj09PWU/aC50b3VjaGVzKz0xOi9eKHRvdWNoZW5kfHRvdWNoY2FuY2VsKSQvLnRlc3QoZSkmJnNldFRpbWVvdXQoZnVuY3Rpb24oKXtoLnRvdWNoZXMmJihoLnRvdWNoZXMtPTEpfSw1MDApfX07cmV0dXJuIGwuaW5pdD1mdW5jdGlvbih0KXt2YXIgZT1kb2N1bWVudC5ib2R5O1wiZHVyYXRpb25cImluKHQ9dHx8e30pJiYodi5kdXJhdGlvbj10LmR1cmF0aW9uKSxcImRlbGF5XCJpbiB0JiYodi5kZWxheT10LmRlbGF5KSxtJiYoZS5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLGMsITEpLGUuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsaC5yZWdpc3RlckV2ZW50LCExKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLGgucmVnaXN0ZXJFdmVudCwhMSkpLGUuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLGMsITEpfSxsLmF0dGFjaD1mdW5jdGlvbih0LGUpe3Q9YSh0KSxcIltvYmplY3QgQXJyYXldXCI9PT1mLmNhbGwoZSkmJihlPWUuam9pbihcIiBcIikpLGU9ZT9cIiBcIitlOlwiXCI7Zm9yKHZhciBuLG8saT0wLHI9dC5sZW5ndGg7aTxyO2krKylvPShuPXRbaV0pLnRhZ05hbWUudG9Mb3dlckNhc2UoKSwtMSE9PVtcImlucHV0XCIsXCJpbWdcIl0uaW5kZXhPZihvKSYmKHBbb10obiksbj1uLnBhcmVudEVsZW1lbnQpLC0xPT09bi5jbGFzc05hbWUuaW5kZXhPZihcIndhdmVzLWVmZmVjdFwiKSYmKG4uY2xhc3NOYW1lKz1cIiB3YXZlcy1lZmZlY3RcIitlKX0sbC5yaXBwbGU9ZnVuY3Rpb24odCxlKXt2YXIgbj0odD1hKHQpKS5sZW5ndGg7aWYoZT1lfHx7fSxlLndhaXQ9ZS53YWl0fHwwLGUucG9zaXRpb249ZS5wb3NpdGlvbnx8bnVsbCxuKWZvcih2YXIgbyxyLHMsdT17fSxjPTAsbD17dHlwZTpcIm1vdXNlZG93blwiLGJ1dHRvbjoxfTtjPG47YysrKWlmKG89dFtjXSxyPWUucG9zaXRpb258fHt4Om8uY2xpZW50V2lkdGgvMix5Om8uY2xpZW50SGVpZ2h0LzJ9LHM9aShvKSx1Lng9cy5sZWZ0K3IueCx1Lnk9cy50b3Arci55LGwucGFnZVg9dS54LGwucGFnZVk9dS55LHYuc2hvdyhsLG8pLGUud2FpdD49MCYmbnVsbCE9PWUud2FpdCl7dmFyIGQ9e3R5cGU6XCJtb3VzZXVwXCIsYnV0dG9uOjF9O3NldFRpbWVvdXQoZnVuY3Rpb24odCxlKXtyZXR1cm4gZnVuY3Rpb24oKXt2LmhpZGUodCxlKX19KGQsbyksZS53YWl0KX19LGwuY2FsbT1mdW5jdGlvbih0KXtmb3IodmFyIGU9e3R5cGU6XCJtb3VzZXVwXCIsYnV0dG9uOjF9LG49MCxvPSh0PWEodCkpLmxlbmd0aDtuPG87bisrKXYuaGlkZShlLHRbbl0pfSxsLmRpc3BsYXlFZmZlY3Q9ZnVuY3Rpb24odCl7bC5pbml0KHQpfSxsfSk7XHJcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmVzLm1pbi5qcy5tYXAiLCIvKlxyXG4gKiBqUXVlcnkgRmlsZSBVcGxvYWQgUGx1Z2luXHJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL2pRdWVyeS1GaWxlLVVwbG9hZFxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgMjAxMCwgU2ViYXN0aWFuIFRzY2hhblxyXG4gKiBodHRwczovL2JsdWVpbXAubmV0XHJcbiAqXHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcclxuICogaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcclxuICovXHJcblxyXG4vKiBqc2hpbnQgbm9tZW46ZmFsc2UgKi9cclxuLyogZ2xvYmFsIGRlZmluZSwgcmVxdWlyZSwgd2luZG93LCBkb2N1bWVudCwgbG9jYXRpb24sIEJsb2IsIEZvcm1EYXRhICovXHJcblxyXG4oZnVuY3Rpb24gKGZhY3RvcnkpIHtcclxuICAgICd1c2Ugc3RyaWN0JztcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgICAgICAvLyBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgQU1EIG1vZHVsZTpcclxuICAgICAgICBkZWZpbmUoW1xyXG4gICAgICAgICAgICAnanF1ZXJ5JyxcclxuICAgICAgICAgICAgJ2pxdWVyeS51aS53aWRnZXQnXHJcbiAgICAgICAgXSwgZmFjdG9yeSk7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIC8vIE5vZGUvQ29tbW9uSlM6XHJcbiAgICAgICAgZmFjdG9yeShcclxuICAgICAgICAgICAgcmVxdWlyZSgnanF1ZXJ5JyksXHJcbiAgICAgICAgICAgIHJlcXVpcmUoJy4vdmVuZG9yL2pxdWVyeS51aS53aWRnZXQnKVxyXG4gICAgICAgICk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIEJyb3dzZXIgZ2xvYmFsczpcclxuICAgICAgICBmYWN0b3J5KHdpbmRvdy5qUXVlcnkpO1xyXG4gICAgfVxyXG59KGZ1bmN0aW9uICgkKSB7XHJcbiAgICAndXNlIHN0cmljdCc7XHJcblxyXG4gICAgLy8gRGV0ZWN0IGZpbGUgaW5wdXQgc3VwcG9ydCwgYmFzZWQgb25cclxuICAgIC8vIGh0dHA6Ly92aWxqYW1pcy5jb20vYmxvZy8yMDEyL2ZpbGUtdXBsb2FkLXN1cHBvcnQtb24tbW9iaWxlL1xyXG4gICAgJC5zdXBwb3J0LmZpbGVJbnB1dCA9ICEobmV3IFJlZ0V4cChcclxuICAgICAgICAvLyBIYW5kbGUgZGV2aWNlcyB3aGljaCBnaXZlIGZhbHNlIHBvc2l0aXZlcyBmb3IgdGhlIGZlYXR1cmUgZGV0ZWN0aW9uOlxyXG4gICAgICAgICcoQW5kcm9pZCAoMVxcXFwuWzAxNTZdfDJcXFxcLlswMV0pKScgK1xyXG4gICAgICAgICAgICAnfChXaW5kb3dzIFBob25lIChPUyA3fDhcXFxcLjApKXwoWEJMV1ApfChadW5lV1ApfChXUERlc2t0b3ApJyArXHJcbiAgICAgICAgICAgICd8KHcoZWIpP09TQnJvd3Nlcil8KHdlYk9TKScgK1xyXG4gICAgICAgICAgICAnfChLaW5kbGUvKDFcXFxcLjB8MlxcXFwuWzA1XXwzXFxcXC4wKSknXHJcbiAgICApLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpIHx8XHJcbiAgICAgICAgLy8gRmVhdHVyZSBkZXRlY3Rpb24gZm9yIGFsbCBvdGhlciBkZXZpY2VzOlxyXG4gICAgICAgICQoJzxpbnB1dCB0eXBlPVwiZmlsZVwiPicpLnByb3AoJ2Rpc2FibGVkJykpO1xyXG5cclxuICAgIC8vIFRoZSBGaWxlUmVhZGVyIEFQSSBpcyBub3QgYWN0dWFsbHkgdXNlZCwgYnV0IHdvcmtzIGFzIGZlYXR1cmUgZGV0ZWN0aW9uLFxyXG4gICAgLy8gYXMgc29tZSBTYWZhcmkgdmVyc2lvbnMgKDU/KSBzdXBwb3J0IFhIUiBmaWxlIHVwbG9hZHMgdmlhIHRoZSBGb3JtRGF0YSBBUEksXHJcbiAgICAvLyBidXQgbm90IG5vbi1tdWx0aXBhcnQgWEhSIGZpbGUgdXBsb2Fkcy5cclxuICAgIC8vIHdpbmRvdy5YTUxIdHRwUmVxdWVzdFVwbG9hZCBpcyBub3QgYXZhaWxhYmxlIG9uIElFMTAsIHNvIHdlIGNoZWNrIGZvclxyXG4gICAgLy8gd2luZG93LlByb2dyZXNzRXZlbnQgaW5zdGVhZCB0byBkZXRlY3QgWEhSMiBmaWxlIHVwbG9hZCBjYXBhYmlsaXR5OlxyXG4gICAgJC5zdXBwb3J0LnhockZpbGVVcGxvYWQgPSAhISh3aW5kb3cuUHJvZ3Jlc3NFdmVudCAmJiB3aW5kb3cuRmlsZVJlYWRlcik7XHJcbiAgICAkLnN1cHBvcnQueGhyRm9ybURhdGFGaWxlVXBsb2FkID0gISF3aW5kb3cuRm9ybURhdGE7XHJcblxyXG4gICAgLy8gRGV0ZWN0IHN1cHBvcnQgZm9yIEJsb2Igc2xpY2luZyAocmVxdWlyZWQgZm9yIGNodW5rZWQgdXBsb2Fkcyk6XHJcbiAgICAkLnN1cHBvcnQuYmxvYlNsaWNlID0gd2luZG93LkJsb2IgJiYgKEJsb2IucHJvdG90eXBlLnNsaWNlIHx8XHJcbiAgICAgICAgQmxvYi5wcm90b3R5cGUud2Via2l0U2xpY2UgfHwgQmxvYi5wcm90b3R5cGUubW96U2xpY2UpO1xyXG5cclxuICAgIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgZHJhZyBoYW5kbGVycyBmb3IgZHJhZ292ZXIvZHJhZ2VudGVyL2RyYWdsZWF2ZTpcclxuICAgIGZ1bmN0aW9uIGdldERyYWdIYW5kbGVyKHR5cGUpIHtcclxuICAgICAgICB2YXIgaXNEcmFnT3ZlciA9IHR5cGUgPT09ICdkcmFnb3Zlcic7XHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUuZGF0YVRyYW5zZmVyID0gZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXI7XHJcbiAgICAgICAgICAgIHZhciBkYXRhVHJhbnNmZXIgPSBlLmRhdGFUcmFuc2ZlcjtcclxuICAgICAgICAgICAgaWYgKGRhdGFUcmFuc2ZlciAmJiAkLmluQXJyYXkoJ0ZpbGVzJywgZGF0YVRyYW5zZmVyLnR5cGVzKSAhPT0gLTEgJiZcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAkLkV2ZW50KHR5cGUsIHtkZWxlZ2F0ZWRFdmVudDogZX0pXHJcbiAgICAgICAgICAgICAgICAgICAgKSAhPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGlmIChpc0RyYWdPdmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSAnY29weSc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRoZSBmaWxldXBsb2FkIHdpZGdldCBsaXN0ZW5zIGZvciBjaGFuZ2UgZXZlbnRzIG9uIGZpbGUgaW5wdXQgZmllbGRzIGRlZmluZWRcclxuICAgIC8vIHZpYSBmaWxlSW5wdXQgc2V0dGluZyBhbmQgcGFzdGUgb3IgZHJvcCBldmVudHMgb2YgdGhlIGdpdmVuIGRyb3Bab25lLlxyXG4gICAgLy8gSW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHQgalF1ZXJ5IFdpZGdldCBtZXRob2RzLCB0aGUgZmlsZXVwbG9hZCB3aWRnZXRcclxuICAgIC8vIGV4cG9zZXMgdGhlIFwiYWRkXCIgYW5kIFwic2VuZFwiIG1ldGhvZHMsIHRvIGFkZCBvciBkaXJlY3RseSBzZW5kIGZpbGVzIHVzaW5nXHJcbiAgICAvLyB0aGUgZmlsZXVwbG9hZCBBUEkuXHJcbiAgICAvLyBCeSBkZWZhdWx0LCBmaWxlcyBhZGRlZCB2aWEgZmlsZSBpbnB1dCBzZWxlY3Rpb24sIHBhc3RlLCBkcmFnICYgZHJvcCBvclxyXG4gICAgLy8gXCJhZGRcIiBtZXRob2QgYXJlIHVwbG9hZGVkIGltbWVkaWF0ZWx5LCBidXQgaXQgaXMgcG9zc2libGUgdG8gb3ZlcnJpZGVcclxuICAgIC8vIHRoZSBcImFkZFwiIGNhbGxiYWNrIG9wdGlvbiB0byBxdWV1ZSBmaWxlIHVwbG9hZHMuXHJcbiAgICAkLndpZGdldCgnYmx1ZWltcC5maWxldXBsb2FkJywge1xyXG5cclxuICAgICAgICBvcHRpb25zOiB7XHJcbiAgICAgICAgICAgIC8vIFRoZSBkcm9wIHRhcmdldCBlbGVtZW50KHMpLCBieSB0aGUgZGVmYXVsdCB0aGUgY29tcGxldGUgZG9jdW1lbnQuXHJcbiAgICAgICAgICAgIC8vIFNldCB0byBudWxsIHRvIGRpc2FibGUgZHJhZyAmIGRyb3Agc3VwcG9ydDpcclxuICAgICAgICAgICAgZHJvcFpvbmU6ICQoZG9jdW1lbnQpLFxyXG4gICAgICAgICAgICAvLyBUaGUgcGFzdGUgdGFyZ2V0IGVsZW1lbnQocyksIGJ5IHRoZSBkZWZhdWx0IHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgLy8gU2V0IHRvIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IG9iamVjdCB0byBlbmFibGUgZmlsZSBwYXN0aW5nOlxyXG4gICAgICAgICAgICBwYXN0ZVpvbmU6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgLy8gVGhlIGZpbGUgaW5wdXQgZmllbGQocyksIHRoYXQgYXJlIGxpc3RlbmVkIHRvIGZvciBjaGFuZ2UgZXZlbnRzLlxyXG4gICAgICAgICAgICAvLyBJZiB1bmRlZmluZWQsIGl0IGlzIHNldCB0byB0aGUgZmlsZSBpbnB1dCBmaWVsZHMgaW5zaWRlXHJcbiAgICAgICAgICAgIC8vIG9mIHRoZSB3aWRnZXQgZWxlbWVudCBvbiBwbHVnaW4gaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgIC8vIFNldCB0byBudWxsIHRvIGRpc2FibGUgdGhlIGNoYW5nZSBsaXN0ZW5lci5cclxuICAgICAgICAgICAgZmlsZUlucHV0OiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQsIHRoZSBmaWxlIGlucHV0IGZpZWxkIGlzIHJlcGxhY2VkIHdpdGggYSBjbG9uZSBhZnRlclxyXG4gICAgICAgICAgICAvLyBlYWNoIGlucHV0IGZpZWxkIGNoYW5nZSBldmVudC4gVGhpcyBpcyByZXF1aXJlZCBmb3IgaWZyYW1lIHRyYW5zcG9ydFxyXG4gICAgICAgICAgICAvLyBxdWV1ZXMgYW5kIGFsbG93cyBjaGFuZ2UgZXZlbnRzIHRvIGJlIGZpcmVkIGZvciB0aGUgc2FtZSBmaWxlXHJcbiAgICAgICAgICAgIC8vIHNlbGVjdGlvbiwgYnV0IGNhbiBiZSBkaXNhYmxlZCBieSBzZXR0aW5nIHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIGZhbHNlOlxyXG4gICAgICAgICAgICByZXBsYWNlRmlsZUlucHV0OiB0cnVlLFxyXG4gICAgICAgICAgICAvLyBUaGUgcGFyYW1ldGVyIG5hbWUgZm9yIHRoZSBmaWxlIGZvcm0gZGF0YSAodGhlIHJlcXVlc3QgYXJndW1lbnQgbmFtZSkuXHJcbiAgICAgICAgICAgIC8vIElmIHVuZGVmaW5lZCBvciBlbXB0eSwgdGhlIG5hbWUgcHJvcGVydHkgb2YgdGhlIGZpbGUgaW5wdXQgZmllbGQgaXNcclxuICAgICAgICAgICAgLy8gdXNlZCwgb3IgXCJmaWxlc1tdXCIgaWYgdGhlIGZpbGUgaW5wdXQgbmFtZSBwcm9wZXJ0eSBpcyBhbHNvIGVtcHR5LFxyXG4gICAgICAgICAgICAvLyBjYW4gYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5nczpcclxuICAgICAgICAgICAgcGFyYW1OYW1lOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQsIGVhY2ggZmlsZSBvZiBhIHNlbGVjdGlvbiBpcyB1cGxvYWRlZCB1c2luZyBhbiBpbmRpdmlkdWFsXHJcbiAgICAgICAgICAgIC8vIHJlcXVlc3QgZm9yIFhIUiB0eXBlIHVwbG9hZHMuIFNldCB0byBmYWxzZSB0byB1cGxvYWQgZmlsZVxyXG4gICAgICAgICAgICAvLyBzZWxlY3Rpb25zIGluIG9uZSByZXF1ZXN0IGVhY2g6XHJcbiAgICAgICAgICAgIHNpbmdsZUZpbGVVcGxvYWRzOiB0cnVlLFxyXG4gICAgICAgICAgICAvLyBUbyBsaW1pdCB0aGUgbnVtYmVyIG9mIGZpbGVzIHVwbG9hZGVkIHdpdGggb25lIFhIUiByZXF1ZXN0LFxyXG4gICAgICAgICAgICAvLyBzZXQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8gYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMDpcclxuICAgICAgICAgICAgbGltaXRNdWx0aUZpbGVVcGxvYWRzOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgb3B0aW9uIGxpbWl0cyB0aGUgbnVtYmVyIG9mIGZpbGVzIHVwbG9hZGVkIHdpdGggb25lXHJcbiAgICAgICAgICAgIC8vIFhIUiByZXF1ZXN0IHRvIGtlZXAgdGhlIHJlcXVlc3Qgc2l6ZSB1bmRlciBvciBlcXVhbCB0byB0aGUgZGVmaW5lZFxyXG4gICAgICAgICAgICAvLyBsaW1pdCBpbiBieXRlczpcclxuICAgICAgICAgICAgbGltaXRNdWx0aUZpbGVVcGxvYWRTaXplOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIC8vIE11bHRpcGFydCBmaWxlIHVwbG9hZHMgYWRkIGEgbnVtYmVyIG9mIGJ5dGVzIHRvIGVhY2ggdXBsb2FkZWQgZmlsZSxcclxuICAgICAgICAgICAgLy8gdGhlcmVmb3JlIHRoZSBmb2xsb3dpbmcgb3B0aW9uIGFkZHMgYW4gb3ZlcmhlYWQgZm9yIGVhY2ggZmlsZSB1c2VkXHJcbiAgICAgICAgICAgIC8vIGluIHRoZSBsaW1pdE11bHRpRmlsZVVwbG9hZFNpemUgY29uZmlndXJhdGlvbjpcclxuICAgICAgICAgICAgbGltaXRNdWx0aUZpbGVVcGxvYWRTaXplT3ZlcmhlYWQ6IDUxMixcclxuICAgICAgICAgICAgLy8gU2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIHRydWUgdG8gaXNzdWUgYWxsIGZpbGUgdXBsb2FkIHJlcXVlc3RzXHJcbiAgICAgICAgICAgIC8vIGluIGEgc2VxdWVudGlhbCBvcmRlcjpcclxuICAgICAgICAgICAgc2VxdWVudGlhbFVwbG9hZHM6IGZhbHNlLFxyXG4gICAgICAgICAgICAvLyBUbyBsaW1pdCB0aGUgbnVtYmVyIG9mIGNvbmN1cnJlbnQgdXBsb2FkcyxcclxuICAgICAgICAgICAgLy8gc2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDA6XHJcbiAgICAgICAgICAgIGxpbWl0Q29uY3VycmVudFVwbG9hZHM6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgLy8gU2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIHRydWUgdG8gZm9yY2UgaWZyYW1lIHRyYW5zcG9ydCB1cGxvYWRzOlxyXG4gICAgICAgICAgICBmb3JjZUlmcmFtZVRyYW5zcG9ydDogZmFsc2UsXHJcbiAgICAgICAgICAgIC8vIFNldCB0aGUgZm9sbG93aW5nIG9wdGlvbiB0byB0aGUgbG9jYXRpb24gb2YgYSByZWRpcmVjdCB1cmwgb24gdGhlXHJcbiAgICAgICAgICAgIC8vIG9yaWdpbiBzZXJ2ZXIsIGZvciBjcm9zcy1kb21haW4gaWZyYW1lIHRyYW5zcG9ydCB1cGxvYWRzOlxyXG4gICAgICAgICAgICByZWRpcmVjdDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAvLyBUaGUgcGFyYW1ldGVyIG5hbWUgZm9yIHRoZSByZWRpcmVjdCB1cmwsIHNlbnQgYXMgcGFydCBvZiB0aGUgZm9ybVxyXG4gICAgICAgICAgICAvLyBkYXRhIGFuZCBzZXQgdG8gJ3JlZGlyZWN0JyBpZiB0aGlzIG9wdGlvbiBpcyBlbXB0eTpcclxuICAgICAgICAgICAgcmVkaXJlY3RQYXJhbU5hbWU6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgLy8gU2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIHRoZSBsb2NhdGlvbiBvZiBhIHBvc3RNZXNzYWdlIHdpbmRvdyxcclxuICAgICAgICAgICAgLy8gdG8gZW5hYmxlIHBvc3RNZXNzYWdlIHRyYW5zcG9ydCB1cGxvYWRzOlxyXG4gICAgICAgICAgICBwb3N0TWVzc2FnZTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAvLyBCeSBkZWZhdWx0LCBYSFIgZmlsZSB1cGxvYWRzIGFyZSBzZW50IGFzIG11bHRpcGFydC9mb3JtLWRhdGEuXHJcbiAgICAgICAgICAgIC8vIFRoZSBpZnJhbWUgdHJhbnNwb3J0IGlzIGFsd2F5cyB1c2luZyBtdWx0aXBhcnQvZm9ybS1kYXRhLlxyXG4gICAgICAgICAgICAvLyBTZXQgdG8gZmFsc2UgdG8gZW5hYmxlIG5vbi1tdWx0aXBhcnQgWEhSIHVwbG9hZHM6XHJcbiAgICAgICAgICAgIG11bHRpcGFydDogdHJ1ZSxcclxuICAgICAgICAgICAgLy8gVG8gdXBsb2FkIGxhcmdlIGZpbGVzIGluIHNtYWxsZXIgY2h1bmtzLCBzZXQgdGhlIGZvbGxvd2luZyBvcHRpb25cclxuICAgICAgICAgICAgLy8gdG8gYSBwcmVmZXJyZWQgbWF4aW11bSBjaHVuayBzaXplLiBJZiBzZXQgdG8gMCwgbnVsbCBvciB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIC8vIG9yIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHJlcXVpcmVkIEJsb2IgQVBJLCBmaWxlcyB3aWxsXHJcbiAgICAgICAgICAgIC8vIGJlIHVwbG9hZGVkIGFzIGEgd2hvbGUuXHJcbiAgICAgICAgICAgIG1heENodW5rU2l6ZTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAvLyBXaGVuIGEgbm9uLW11bHRpcGFydCB1cGxvYWQgb3IgYSBjaHVua2VkIG11bHRpcGFydCB1cGxvYWQgaGFzIGJlZW5cclxuICAgICAgICAgICAgLy8gYWJvcnRlZCwgdGhpcyBvcHRpb24gY2FuIGJlIHVzZWQgdG8gcmVzdW1lIHRoZSB1cGxvYWQgYnkgc2V0dGluZ1xyXG4gICAgICAgICAgICAvLyBpdCB0byB0aGUgc2l6ZSBvZiB0aGUgYWxyZWFkeSB1cGxvYWRlZCBieXRlcy4gVGhpcyBvcHRpb24gaXMgbW9zdFxyXG4gICAgICAgICAgICAvLyB1c2VmdWwgd2hlbiBtb2RpZnlpbmcgdGhlIG9wdGlvbnMgb2JqZWN0IGluc2lkZSBvZiB0aGUgXCJhZGRcIiBvclxyXG4gICAgICAgICAgICAvLyBcInNlbmRcIiBjYWxsYmFja3MsIGFzIHRoZSBvcHRpb25zIGFyZSBjbG9uZWQgZm9yIGVhY2ggZmlsZSB1cGxvYWQuXHJcbiAgICAgICAgICAgIHVwbG9hZGVkQnl0ZXM6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgLy8gQnkgZGVmYXVsdCwgZmFpbGVkIChhYm9ydCBvciBlcnJvcikgZmlsZSB1cGxvYWRzIGFyZSByZW1vdmVkIGZyb20gdGhlXHJcbiAgICAgICAgICAgIC8vIGdsb2JhbCBwcm9ncmVzcyBjYWxjdWxhdGlvbi4gU2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIGZhbHNlIHRvXHJcbiAgICAgICAgICAgIC8vIHByZXZlbnQgcmVjYWxjdWxhdGluZyB0aGUgZ2xvYmFsIHByb2dyZXNzIGRhdGE6XHJcbiAgICAgICAgICAgIHJlY2FsY3VsYXRlUHJvZ3Jlc3M6IHRydWUsXHJcbiAgICAgICAgICAgIC8vIEludGVydmFsIGluIG1pbGxpc2Vjb25kcyB0byBjYWxjdWxhdGUgYW5kIHRyaWdnZXIgcHJvZ3Jlc3MgZXZlbnRzOlxyXG4gICAgICAgICAgICBwcm9ncmVzc0ludGVydmFsOiAxMDAsXHJcbiAgICAgICAgICAgIC8vIEludGVydmFsIGluIG1pbGxpc2Vjb25kcyB0byBjYWxjdWxhdGUgcHJvZ3Jlc3MgYml0cmF0ZTpcclxuICAgICAgICAgICAgYml0cmF0ZUludGVydmFsOiA1MDAsXHJcbiAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQsIHVwbG9hZHMgYXJlIHN0YXJ0ZWQgYXV0b21hdGljYWxseSB3aGVuIGFkZGluZyBmaWxlczpcclxuICAgICAgICAgICAgYXV0b1VwbG9hZDogdHJ1ZSxcclxuXHJcbiAgICAgICAgICAgIC8vIEVycm9yIGFuZCBpbmZvIG1lc3NhZ2VzOlxyXG4gICAgICAgICAgICBtZXNzYWdlczoge1xyXG4gICAgICAgICAgICAgICAgdXBsb2FkZWRCeXRlczogJ1VwbG9hZGVkIGJ5dGVzIGV4Y2VlZCBmaWxlIHNpemUnXHJcbiAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAvLyBUcmFuc2xhdGlvbiBmdW5jdGlvbiwgZ2V0cyB0aGUgbWVzc2FnZSBrZXkgdG8gYmUgdHJhbnNsYXRlZFxyXG4gICAgICAgICAgICAvLyBhbmQgYW4gb2JqZWN0IHdpdGggY29udGV4dCBzcGVjaWZpYyBkYXRhIGFzIGFyZ3VtZW50czpcclxuICAgICAgICAgICAgaTE4bjogZnVuY3Rpb24gKG1lc3NhZ2UsIGNvbnRleHQpIHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzW21lc3NhZ2VdIHx8IG1lc3NhZ2UudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb250ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgJC5lYWNoKGNvbnRleHQsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoJ3snICsga2V5ICsgJ30nLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcclxuICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgZm9ybSBkYXRhIHRvIGJlIHNlbnQgYWxvbmcgd2l0aCB0aGUgZmlsZSB1cGxvYWRzIGNhbiBiZSBzZXRcclxuICAgICAgICAgICAgLy8gdXNpbmcgdGhpcyBvcHRpb24sIHdoaWNoIGFjY2VwdHMgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoIG5hbWUgYW5kXHJcbiAgICAgICAgICAgIC8vIHZhbHVlIHByb3BlcnRpZXMsIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHN1Y2ggYW4gYXJyYXksIGEgRm9ybURhdGFcclxuICAgICAgICAgICAgLy8gb2JqZWN0IChmb3IgWEhSIGZpbGUgdXBsb2FkcyksIG9yIGEgc2ltcGxlIG9iamVjdC5cclxuICAgICAgICAgICAgLy8gVGhlIGZvcm0gb2YgdGhlIGZpcnN0IGZpbGVJbnB1dCBpcyBnaXZlbiBhcyBwYXJhbWV0ZXIgdG8gdGhlIGZ1bmN0aW9uOlxyXG4gICAgICAgICAgICBmb3JtRGF0YTogZnVuY3Rpb24gKGZvcm0pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmb3JtLnNlcmlhbGl6ZUFycmF5KCk7XHJcbiAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAvLyBUaGUgYWRkIGNhbGxiYWNrIGlzIGludm9rZWQgYXMgc29vbiBhcyBmaWxlcyBhcmUgYWRkZWQgdG8gdGhlIGZpbGV1cGxvYWRcclxuICAgICAgICAgICAgLy8gd2lkZ2V0ICh2aWEgZmlsZSBpbnB1dCBzZWxlY3Rpb24sIGRyYWcgJiBkcm9wLCBwYXN0ZSBvciBhZGQgQVBJIGNhbGwpLlxyXG4gICAgICAgICAgICAvLyBJZiB0aGUgc2luZ2xlRmlsZVVwbG9hZHMgb3B0aW9uIGlzIGVuYWJsZWQsIHRoaXMgY2FsbGJhY2sgd2lsbCBiZVxyXG4gICAgICAgICAgICAvLyBjYWxsZWQgb25jZSBmb3IgZWFjaCBmaWxlIGluIHRoZSBzZWxlY3Rpb24gZm9yIFhIUiBmaWxlIHVwbG9hZHMsIGVsc2VcclxuICAgICAgICAgICAgLy8gb25jZSBmb3IgZWFjaCBmaWxlIHNlbGVjdGlvbi5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVGhlIHVwbG9hZCBzdGFydHMgd2hlbiB0aGUgc3VibWl0IG1ldGhvZCBpcyBpbnZva2VkIG9uIHRoZSBkYXRhIHBhcmFtZXRlci5cclxuICAgICAgICAgICAgLy8gVGhlIGRhdGEgb2JqZWN0IGNvbnRhaW5zIGEgZmlsZXMgcHJvcGVydHkgaG9sZGluZyB0aGUgYWRkZWQgZmlsZXNcclxuICAgICAgICAgICAgLy8gYW5kIGFsbG93cyB5b3UgdG8gb3ZlcnJpZGUgcGx1Z2luIG9wdGlvbnMgYXMgd2VsbCBhcyBkZWZpbmUgYWpheCBzZXR0aW5ncy5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gTGlzdGVuZXJzIGZvciB0aGlzIGNhbGxiYWNrIGNhbiBhbHNvIGJlIGJvdW5kIHRoZSBmb2xsb3dpbmcgd2F5OlxyXG4gICAgICAgICAgICAvLyAuYmluZCgnZmlsZXVwbG9hZGFkZCcsIGZ1bmMpO1xyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBkYXRhLnN1Ym1pdCgpIHJldHVybnMgYSBQcm9taXNlIG9iamVjdCBhbmQgYWxsb3dzIHRvIGF0dGFjaCBhZGRpdGlvbmFsXHJcbiAgICAgICAgICAgIC8vIGhhbmRsZXJzIHVzaW5nIGpRdWVyeSdzIERlZmVycmVkIGNhbGxiYWNrczpcclxuICAgICAgICAgICAgLy8gZGF0YS5zdWJtaXQoKS5kb25lKGZ1bmMpLmZhaWwoZnVuYykuYWx3YXlzKGZ1bmMpO1xyXG4gICAgICAgICAgICBhZGQ6IGZ1bmN0aW9uIChlLCBkYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLmF1dG9VcGxvYWQgfHwgKGRhdGEuYXV0b1VwbG9hZCAhPT0gZmFsc2UgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5maWxldXBsb2FkKCdvcHRpb24nLCAnYXV0b1VwbG9hZCcpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHJvY2VzcygpLmRvbmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLnN1Ym1pdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgLy8gT3RoZXIgY2FsbGJhY2tzOlxyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIHRoZSBzdWJtaXQgZXZlbnQgb2YgZWFjaCBmaWxlIHVwbG9hZDpcclxuICAgICAgICAgICAgLy8gc3VibWl0OiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2Fkc3VibWl0JywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdGhlIHN0YXJ0IG9mIGVhY2ggZmlsZSB1cGxvYWQgcmVxdWVzdDpcclxuICAgICAgICAgICAgLy8gc2VuZDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZHNlbmQnLCBmdW5jKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBzdWNjZXNzZnVsIHVwbG9hZHM6XHJcbiAgICAgICAgICAgIC8vIGRvbmU6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkb25lJywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgZmFpbGVkIChhYm9ydCBvciBlcnJvcikgdXBsb2FkczpcclxuICAgICAgICAgICAgLy8gZmFpbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGZhaWwnLCBmdW5jKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBjb21wbGV0ZWQgKHN1Y2Nlc3MsIGFib3J0IG9yIGVycm9yKSByZXF1ZXN0czpcclxuICAgICAgICAgICAgLy8gYWx3YXlzOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkYWx3YXlzJywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdXBsb2FkIHByb2dyZXNzIGV2ZW50czpcclxuICAgICAgICAgICAgLy8gcHJvZ3Jlc3M6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRwcm9ncmVzcycsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGdsb2JhbCB1cGxvYWQgcHJvZ3Jlc3MgZXZlbnRzOlxyXG4gICAgICAgICAgICAvLyBwcm9ncmVzc2FsbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZHByb2dyZXNzYWxsJywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdXBsb2FkcyBzdGFydCwgZXF1aXZhbGVudCB0byB0aGUgZ2xvYmFsIGFqYXhTdGFydCBldmVudDpcclxuICAgICAgICAgICAgLy8gc3RhcnQ6IGZ1bmN0aW9uIChlKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRzdGFydCcsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIHVwbG9hZHMgc3RvcCwgZXF1aXZhbGVudCB0byB0aGUgZ2xvYmFsIGFqYXhTdG9wIGV2ZW50OlxyXG4gICAgICAgICAgICAvLyBzdG9wOiBmdW5jdGlvbiAoZSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2Fkc3RvcCcsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGNoYW5nZSBldmVudHMgb2YgdGhlIGZpbGVJbnB1dChzKTpcclxuICAgICAgICAgICAgLy8gY2hhbmdlOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkY2hhbmdlJywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgcGFzdGUgZXZlbnRzIHRvIHRoZSBwYXN0ZVpvbmUocyk6XHJcbiAgICAgICAgICAgIC8vIHBhc3RlOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkcGFzdGUnLCBmdW5jKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBkcm9wIGV2ZW50cyBvZiB0aGUgZHJvcFpvbmUocyk6XHJcbiAgICAgICAgICAgIC8vIGRyb3A6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkcm9wJywgZnVuYyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgZHJhZ292ZXIgZXZlbnRzIG9mIHRoZSBkcm9wWm9uZShzKTpcclxuICAgICAgICAgICAgLy8gZHJhZ292ZXI6IGZ1bmN0aW9uIChlKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkcmFnb3ZlcicsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIHRoZSBzdGFydCBvZiBlYWNoIGNodW5rIHVwbG9hZCByZXF1ZXN0OlxyXG4gICAgICAgICAgICAvLyBjaHVua3NlbmQ6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRjaHVua3NlbmQnLCBmdW5jKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBzdWNjZXNzZnVsIGNodW5rIHVwbG9hZHM6XHJcbiAgICAgICAgICAgIC8vIGNodW5rZG9uZTogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGNodW5rZG9uZScsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGZhaWxlZCAoYWJvcnQgb3IgZXJyb3IpIGNodW5rIHVwbG9hZHM6XHJcbiAgICAgICAgICAgIC8vIGNodW5rZmFpbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGNodW5rZmFpbCcsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGNvbXBsZXRlZCAoc3VjY2VzcywgYWJvcnQgb3IgZXJyb3IpIGNodW5rIHVwbG9hZCByZXF1ZXN0czpcclxuICAgICAgICAgICAgLy8gY2h1bmthbHdheXM6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRjaHVua2Fsd2F5cycsIGZ1bmMpO1xyXG5cclxuICAgICAgICAgICAgLy8gVGhlIHBsdWdpbiBvcHRpb25zIGFyZSB1c2VkIGFzIHNldHRpbmdzIG9iamVjdCBmb3IgdGhlIGFqYXggY2FsbHMuXHJcbiAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIGpRdWVyeSBhamF4IHNldHRpbmdzIHJlcXVpcmVkIGZvciB0aGUgZmlsZSB1cGxvYWRzOlxyXG4gICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsXHJcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSxcclxuICAgICAgICAgICAgY2FjaGU6IGZhbHNlLFxyXG4gICAgICAgICAgICB0aW1lb3V0OiAwXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gQSBsaXN0IG9mIG9wdGlvbnMgdGhhdCByZXF1aXJlIHJlaW5pdGlhbGl6aW5nIGV2ZW50IGxpc3RlbmVycyBhbmQvb3JcclxuICAgICAgICAvLyBzcGVjaWFsIGluaXRpYWxpemF0aW9uIGNvZGU6XHJcbiAgICAgICAgX3NwZWNpYWxPcHRpb25zOiBbXHJcbiAgICAgICAgICAgICdmaWxlSW5wdXQnLFxyXG4gICAgICAgICAgICAnZHJvcFpvbmUnLFxyXG4gICAgICAgICAgICAncGFzdGVab25lJyxcclxuICAgICAgICAgICAgJ211bHRpcGFydCcsXHJcbiAgICAgICAgICAgICdmb3JjZUlmcmFtZVRyYW5zcG9ydCdcclxuICAgICAgICBdLFxyXG5cclxuICAgICAgICBfYmxvYlNsaWNlOiAkLnN1cHBvcnQuYmxvYlNsaWNlICYmIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHNsaWNlID0gdGhpcy5zbGljZSB8fCB0aGlzLndlYmtpdFNsaWNlIHx8IHRoaXMubW96U2xpY2U7XHJcbiAgICAgICAgICAgIHJldHVybiBzbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9CaXRyYXRlVGltZXI6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSAoKERhdGUubm93KSA/IERhdGUubm93KCkgOiAobmV3IERhdGUoKSkuZ2V0VGltZSgpKTtcclxuICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLmJpdHJhdGUgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLmdldEJpdHJhdGUgPSBmdW5jdGlvbiAobm93LCBsb2FkZWQsIGludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGltZURpZmYgPSBub3cgLSB0aGlzLnRpbWVzdGFtcDtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5iaXRyYXRlIHx8ICFpbnRlcnZhbCB8fCB0aW1lRGlmZiA+IGludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iaXRyYXRlID0gKGxvYWRlZCAtIHRoaXMubG9hZGVkKSAqICgxMDAwIC8gdGltZURpZmYpICogODtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IGxvYWRlZDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IG5vdztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJpdHJhdGU7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2lzWEhSVXBsb2FkOiBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICByZXR1cm4gIW9wdGlvbnMuZm9yY2VJZnJhbWVUcmFuc3BvcnQgJiZcclxuICAgICAgICAgICAgICAgICgoIW9wdGlvbnMubXVsdGlwYXJ0ICYmICQuc3VwcG9ydC54aHJGaWxlVXBsb2FkKSB8fFxyXG4gICAgICAgICAgICAgICAgJC5zdXBwb3J0LnhockZvcm1EYXRhRmlsZVVwbG9hZCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2dldEZvcm1EYXRhOiBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgZm9ybURhdGE7XHJcbiAgICAgICAgICAgIGlmICgkLnR5cGUob3B0aW9ucy5mb3JtRGF0YSkgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmZvcm1EYXRhKG9wdGlvbnMuZm9ybSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCQuaXNBcnJheShvcHRpb25zLmZvcm1EYXRhKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZm9ybURhdGE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCQudHlwZShvcHRpb25zLmZvcm1EYXRhKSA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gW107XHJcbiAgICAgICAgICAgICAgICAkLmVhY2gob3B0aW9ucy5mb3JtRGF0YSwgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEucHVzaCh7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmb3JtRGF0YTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2dldFRvdGFsOiBmdW5jdGlvbiAoZmlsZXMpIHtcclxuICAgICAgICAgICAgdmFyIHRvdGFsID0gMDtcclxuICAgICAgICAgICAgJC5lYWNoKGZpbGVzLCBmdW5jdGlvbiAoaW5kZXgsIGZpbGUpIHtcclxuICAgICAgICAgICAgICAgIHRvdGFsICs9IGZpbGUuc2l6ZSB8fCAxO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9pbml0UHJvZ3Jlc3NPYmplY3Q6IGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICAgICAgdmFyIHByb2dyZXNzID0ge1xyXG4gICAgICAgICAgICAgICAgbG9hZGVkOiAwLFxyXG4gICAgICAgICAgICAgICAgdG90YWw6IDAsXHJcbiAgICAgICAgICAgICAgICBiaXRyYXRlOiAwXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGlmIChvYmouX3Byb2dyZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAkLmV4dGVuZChvYmouX3Byb2dyZXNzLCBwcm9ncmVzcyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBvYmouX3Byb2dyZXNzID0gcHJvZ3Jlc3M7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaW5pdFJlc3BvbnNlT2JqZWN0OiBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9wO1xyXG4gICAgICAgICAgICBpZiAob2JqLl9yZXNwb25zZSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChwcm9wIGluIG9iai5fcmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqLl9yZXNwb25zZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqLl9yZXNwb25zZVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBvYmouX3Jlc3BvbnNlID0ge307XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25Qcm9ncmVzczogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKGUubGVuZ3RoQ29tcHV0YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9ICgoRGF0ZS5ub3cpID8gRGF0ZS5ub3coKSA6IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkpLFxyXG4gICAgICAgICAgICAgICAgICAgIGxvYWRlZDtcclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLl90aW1lICYmIGRhdGEucHJvZ3Jlc3NJbnRlcnZhbCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAobm93IC0gZGF0YS5fdGltZSA8IGRhdGEucHJvZ3Jlc3NJbnRlcnZhbCkgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5sb2FkZWQgIT09IGUudG90YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBkYXRhLl90aW1lID0gbm93O1xyXG4gICAgICAgICAgICAgICAgbG9hZGVkID0gTWF0aC5mbG9vcihcclxuICAgICAgICAgICAgICAgICAgICBlLmxvYWRlZCAvIGUudG90YWwgKiAoZGF0YS5jaHVua1NpemUgfHwgZGF0YS5fcHJvZ3Jlc3MudG90YWwpXHJcbiAgICAgICAgICAgICAgICApICsgKGRhdGEudXBsb2FkZWRCeXRlcyB8fCAwKTtcclxuICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBwcmV2aW91c2x5IGxvYWRlZCBzdGF0ZVxyXG4gICAgICAgICAgICAgICAgLy8gdG8gdGhlIGdsb2JhbCBsb2FkZWQgY291bnRlcjpcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLmxvYWRlZCArPSAobG9hZGVkIC0gZGF0YS5fcHJvZ3Jlc3MubG9hZGVkKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLmJpdHJhdGUgPSB0aGlzLl9iaXRyYXRlVGltZXIuZ2V0Qml0cmF0ZShcclxuICAgICAgICAgICAgICAgICAgICBub3csXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuYml0cmF0ZUludGVydmFsXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgZGF0YS5fcHJvZ3Jlc3MubG9hZGVkID0gZGF0YS5sb2FkZWQgPSBsb2FkZWQ7XHJcbiAgICAgICAgICAgICAgICBkYXRhLl9wcm9ncmVzcy5iaXRyYXRlID0gZGF0YS5iaXRyYXRlID0gZGF0YS5fYml0cmF0ZVRpbWVyLmdldEJpdHJhdGUoXHJcbiAgICAgICAgICAgICAgICAgICAgbm93LFxyXG4gICAgICAgICAgICAgICAgICAgIGxvYWRlZCxcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLmJpdHJhdGVJbnRlcnZhbFxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIC8vIFRyaWdnZXIgYSBjdXN0b20gcHJvZ3Jlc3MgZXZlbnQgd2l0aCBhIHRvdGFsIGRhdGEgcHJvcGVydHkgc2V0XHJcbiAgICAgICAgICAgICAgICAvLyB0byB0aGUgZmlsZSBzaXplKHMpIG9mIHRoZSBjdXJyZW50IHVwbG9hZCBhbmQgYSBsb2FkZWQgZGF0YVxyXG4gICAgICAgICAgICAgICAgLy8gcHJvcGVydHkgY2FsY3VsYXRlZCBhY2NvcmRpbmdseTpcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgJ3Byb2dyZXNzJyxcclxuICAgICAgICAgICAgICAgICAgICAkLkV2ZW50KCdwcm9ncmVzcycsIHtkZWxlZ2F0ZWRFdmVudDogZX0pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGFcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGEgZ2xvYmFsIHByb2dyZXNzIGV2ZW50IGZvciBhbGwgY3VycmVudCBmaWxlIHVwbG9hZHMsXHJcbiAgICAgICAgICAgICAgICAvLyBpbmNsdWRpbmcgYWpheCBjYWxscyBxdWV1ZWQgZm9yIHNlcXVlbnRpYWwgZmlsZSB1cGxvYWRzOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlcihcclxuICAgICAgICAgICAgICAgICAgICAncHJvZ3Jlc3NhbGwnLFxyXG4gICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ3Byb2dyZXNzYWxsJywge2RlbGVnYXRlZEV2ZW50OiBlfSksXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaW5pdFByb2dyZXNzTGlzdGVuZXI6IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcclxuICAgICAgICAgICAgICAgIHhociA9IG9wdGlvbnMueGhyID8gb3B0aW9ucy54aHIoKSA6ICQuYWpheFNldHRpbmdzLnhocigpO1xyXG4gICAgICAgICAgICAvLyBBY2Nlc3NzIHRvIHRoZSBuYXRpdmUgWEhSIG9iamVjdCBpcyByZXF1aXJlZCB0byBhZGQgZXZlbnQgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgIC8vIGZvciB0aGUgdXBsb2FkIHByb2dyZXNzIGV2ZW50OlxyXG4gICAgICAgICAgICBpZiAoeGhyLnVwbG9hZCkge1xyXG4gICAgICAgICAgICAgICAgJCh4aHIudXBsb2FkKS5iaW5kKCdwcm9ncmVzcycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9lID0gZS5vcmlnaW5hbEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgcHJvZ3Jlc3MgZXZlbnQgcHJvcGVydGllcyBnZXQgY29waWVkIG92ZXI6XHJcbiAgICAgICAgICAgICAgICAgICAgZS5sZW5ndGhDb21wdXRhYmxlID0gb2UubGVuZ3RoQ29tcHV0YWJsZTtcclxuICAgICAgICAgICAgICAgICAgICBlLmxvYWRlZCA9IG9lLmxvYWRlZDtcclxuICAgICAgICAgICAgICAgICAgICBlLnRvdGFsID0gb2UudG90YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25Qcm9ncmVzcyhlLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy54aHIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhocjtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaXNJbnN0YW5jZU9mOiBmdW5jdGlvbiAodHlwZSwgb2JqKSB7XHJcbiAgICAgICAgICAgIC8vIENyb3NzLWZyYW1lIGluc3RhbmNlb2YgY2hlY2tcclxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCAnICsgdHlwZSArICddJztcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaW5pdFhIUkRhdGE6IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcclxuICAgICAgICAgICAgICAgIGZvcm1EYXRhLFxyXG4gICAgICAgICAgICAgICAgZmlsZSA9IG9wdGlvbnMuZmlsZXNbMF0sXHJcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgbm9uLW11bHRpcGFydCBzZXR0aW5nIGlmIG5vdCBzdXBwb3J0ZWQ6XHJcbiAgICAgICAgICAgICAgICBtdWx0aXBhcnQgPSBvcHRpb25zLm11bHRpcGFydCB8fCAhJC5zdXBwb3J0LnhockZpbGVVcGxvYWQsXHJcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSAkLnR5cGUob3B0aW9ucy5wYXJhbU5hbWUpID09PSAnYXJyYXknID9cclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBhcmFtTmFtZVswXSA6IG9wdGlvbnMucGFyYW1OYW1lO1xyXG4gICAgICAgICAgICBvcHRpb25zLmhlYWRlcnMgPSAkLmV4dGVuZCh7fSwgb3B0aW9ucy5oZWFkZXJzKTtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29udGVudFJhbmdlKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmhlYWRlcnNbJ0NvbnRlbnQtUmFuZ2UnXSA9IG9wdGlvbnMuY29udGVudFJhbmdlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghbXVsdGlwYXJ0IHx8IG9wdGlvbnMuYmxvYiB8fCAhdGhpcy5faXNJbnN0YW5jZU9mKCdGaWxlJywgZmlsZSkpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMuaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddID0gJ2F0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJyArXHJcbiAgICAgICAgICAgICAgICAgICAgZW5jb2RlVVJJKGZpbGUubmFtZSkgKyAnXCInO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghbXVsdGlwYXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvbnRlbnRUeXBlID0gZmlsZS50eXBlIHx8ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nO1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5kYXRhID0gb3B0aW9ucy5ibG9iIHx8IGZpbGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoJC5zdXBwb3J0LnhockZvcm1EYXRhRmlsZVVwbG9hZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucG9zdE1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyB3aW5kb3cucG9zdE1lc3NhZ2UgZG9lcyBub3QgYWxsb3cgc2VuZGluZyBGb3JtRGF0YVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG9iamVjdHMsIHNvIHdlIGp1c3QgYWRkIHRoZSBGaWxlL0Jsb2Igb2JqZWN0cyB0b1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmb3JtRGF0YSBhcnJheSBhbmQgbGV0IHRoZSBwb3N0TWVzc2FnZSB3aW5kb3dcclxuICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIEZvcm1EYXRhIG9iamVjdCBvdXQgb2YgdGhpcyBhcnJheTpcclxuICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YSA9IHRoaXMuX2dldEZvcm1EYXRhKG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmJsb2IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBwYXJhbU5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5ibG9iXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQuZWFjaChvcHRpb25zLmZpbGVzLCBmdW5jdGlvbiAoaW5kZXgsIGZpbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICgkLnR5cGUob3B0aW9ucy5wYXJhbU5hbWUpID09PSAnYXJyYXknICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucGFyYW1OYW1lW2luZGV4XSkgfHwgcGFyYW1OYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5faXNJbnN0YW5jZU9mKCdGb3JtRGF0YScsIG9wdGlvbnMuZm9ybURhdGEpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gb3B0aW9ucy5mb3JtRGF0YTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkLmVhY2godGhpcy5fZ2V0Rm9ybURhdGEob3B0aW9ucyksIGZ1bmN0aW9uIChpbmRleCwgZmllbGQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZChmaWVsZC5uYW1lLCBmaWVsZC52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5ibG9iKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZChwYXJhbU5hbWUsIG9wdGlvbnMuYmxvYiwgZmlsZS5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkLmVhY2gob3B0aW9ucy5maWxlcywgZnVuY3Rpb24gKGluZGV4LCBmaWxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGNoZWNrIGFsbG93cyB0aGUgdGVzdHMgdG8gcnVuIHdpdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1bW15IG9iamVjdHM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5faXNJbnN0YW5jZU9mKCdGaWxlJywgZmlsZSkgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5faXNJbnN0YW5jZU9mKCdCbG9iJywgZmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgkLnR5cGUob3B0aW9ucy5wYXJhbU5hbWUpID09PSAnYXJyYXknICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBhcmFtTmFtZVtpbmRleF0pIHx8IHBhcmFtTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS51cGxvYWROYW1lIHx8IGZpbGUubmFtZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YSA9IGZvcm1EYXRhO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIEJsb2IgcmVmZXJlbmNlIGlzIG5vdCBuZWVkZWQgYW55bW9yZSwgZnJlZSBtZW1vcnk6XHJcbiAgICAgICAgICAgIG9wdGlvbnMuYmxvYiA9IG51bGw7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2luaXRJZnJhbWVTZXR0aW5nczogZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdmFyIHRhcmdldEhvc3QgPSAkKCc8YT48L2E+JykucHJvcCgnaHJlZicsIG9wdGlvbnMudXJsKS5wcm9wKCdob3N0Jyk7XHJcbiAgICAgICAgICAgIC8vIFNldHRpbmcgdGhlIGRhdGFUeXBlIHRvIGlmcmFtZSBlbmFibGVzIHRoZSBpZnJhbWUgdHJhbnNwb3J0OlxyXG4gICAgICAgICAgICBvcHRpb25zLmRhdGFUeXBlID0gJ2lmcmFtZSAnICsgKG9wdGlvbnMuZGF0YVR5cGUgfHwgJycpO1xyXG4gICAgICAgICAgICAvLyBUaGUgaWZyYW1lIHRyYW5zcG9ydCBhY2NlcHRzIGEgc2VyaWFsaXplZCBhcnJheSBhcyBmb3JtIGRhdGE6XHJcbiAgICAgICAgICAgIG9wdGlvbnMuZm9ybURhdGEgPSB0aGlzLl9nZXRGb3JtRGF0YShvcHRpb25zKTtcclxuICAgICAgICAgICAgLy8gQWRkIHJlZGlyZWN0IHVybCB0byBmb3JtIGRhdGEgb24gY3Jvc3MtZG9tYWluIHVwbG9hZHM6XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnJlZGlyZWN0ICYmIHRhcmdldEhvc3QgJiYgdGFyZ2V0SG9zdCAhPT0gbG9jYXRpb24uaG9zdCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtRGF0YS5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBvcHRpb25zLnJlZGlyZWN0UGFyYW1OYW1lIHx8ICdyZWRpcmVjdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVkaXJlY3RcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2luaXREYXRhU2V0dGluZ3M6IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc1hIUlVwbG9hZChvcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9jaHVua2VkVXBsb2FkKG9wdGlvbnMsIHRydWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5pdFhIUkRhdGEob3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2luaXRQcm9ncmVzc0xpc3RlbmVyKG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucG9zdE1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTZXR0aW5nIHRoZSBkYXRhVHlwZSB0byBwb3N0bWVzc2FnZSBlbmFibGVzIHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHBvc3RNZXNzYWdlIHRyYW5zcG9ydDpcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGFUeXBlID0gJ3Bvc3RtZXNzYWdlICcgKyAob3B0aW9ucy5kYXRhVHlwZSB8fCAnJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9pbml0SWZyYW1lU2V0dGluZ3Mob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfZ2V0UGFyYW1OYW1lOiBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgZmlsZUlucHV0ID0gJChvcHRpb25zLmZpbGVJbnB1dCksXHJcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSBvcHRpb25zLnBhcmFtTmFtZTtcclxuICAgICAgICAgICAgaWYgKCFwYXJhbU5hbWUpIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgZmlsZUlucHV0LmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9ICQodGhpcyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBpbnB1dC5wcm9wKCduYW1lJykgfHwgJ2ZpbGVzW10nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpID0gKGlucHV0LnByb3AoJ2ZpbGVzJykgfHwgWzFdKS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lLnB1c2gobmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGkgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGlmICghcGFyYW1OYW1lLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZSA9IFtmaWxlSW5wdXQucHJvcCgnbmFtZScpIHx8ICdmaWxlc1tdJ107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoISQuaXNBcnJheShwYXJhbU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSBbcGFyYW1OYW1lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcGFyYW1OYW1lO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9pbml0Rm9ybVNldHRpbmdzOiBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICAvLyBSZXRyaWV2ZSBtaXNzaW5nIG9wdGlvbnMgZnJvbSB0aGUgaW5wdXQgZmllbGQgYW5kIHRoZVxyXG4gICAgICAgICAgICAvLyBhc3NvY2lhdGVkIGZvcm0sIGlmIGF2YWlsYWJsZTpcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmZvcm0gfHwgIW9wdGlvbnMuZm9ybS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMuZm9ybSA9ICQob3B0aW9ucy5maWxlSW5wdXQucHJvcCgnZm9ybScpKTtcclxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBnaXZlbiBmaWxlIGlucHV0IGRvZXNuJ3QgaGF2ZSBhbiBhc3NvY2lhdGVkIGZvcm0sXHJcbiAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIGRlZmF1bHQgd2lkZ2V0IGZpbGUgaW5wdXQncyBmb3JtOlxyXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmZvcm0ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtID0gJCh0aGlzLm9wdGlvbnMuZmlsZUlucHV0LnByb3AoJ2Zvcm0nKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3B0aW9ucy5wYXJhbU5hbWUgPSB0aGlzLl9nZXRQYXJhbU5hbWUob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy51cmwpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMudXJsID0gb3B0aW9ucy5mb3JtLnByb3AoJ2FjdGlvbicpIHx8IGxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gVGhlIEhUVFAgcmVxdWVzdCBtZXRob2QgbXVzdCBiZSBcIlBPU1RcIiBvciBcIlBVVFwiOlxyXG4gICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAob3B0aW9ucy50eXBlIHx8XHJcbiAgICAgICAgICAgICAgICAoJC50eXBlKG9wdGlvbnMuZm9ybS5wcm9wKCdtZXRob2QnKSkgPT09ICdzdHJpbmcnICYmXHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtLnByb3AoJ21ldGhvZCcpKSB8fCAnJ1xyXG4gICAgICAgICAgICAgICAgKS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy50eXBlICE9PSAnUE9TVCcgJiYgb3B0aW9ucy50eXBlICE9PSAnUFVUJyAmJlxyXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSAhPT0gJ1BBVENIJykge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy50eXBlID0gJ1BPU1QnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5mb3JtQWNjZXB0Q2hhcnNldCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtQWNjZXB0Q2hhcnNldCA9IG9wdGlvbnMuZm9ybS5hdHRyKCdhY2NlcHQtY2hhcnNldCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2dldEFKQVhTZXR0aW5nczogZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zLCBkYXRhKTtcclxuICAgICAgICAgICAgdGhpcy5faW5pdEZvcm1TZXR0aW5ncyhvcHRpb25zKTtcclxuICAgICAgICAgICAgdGhpcy5faW5pdERhdGFTZXR0aW5ncyhvcHRpb25zKTtcclxuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8galF1ZXJ5IDEuNiBkb2Vzbid0IHByb3ZpZGUgLnN0YXRlKCksXHJcbiAgICAgICAgLy8gd2hpbGUgalF1ZXJ5IDEuOCsgcmVtb3ZlZCAuaXNSZWplY3RlZCgpIGFuZCAuaXNSZXNvbHZlZCgpOlxyXG4gICAgICAgIF9nZXREZWZlcnJlZFN0YXRlOiBmdW5jdGlvbiAoZGVmZXJyZWQpIHtcclxuICAgICAgICAgICAgaWYgKGRlZmVycmVkLnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQuc3RhdGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZGVmZXJyZWQuaXNSZXNvbHZlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3Jlc29sdmVkJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZGVmZXJyZWQuaXNSZWplY3RlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3JlamVjdGVkJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gJ3BlbmRpbmcnO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8vIE1hcHMganFYSFIgY2FsbGJhY2tzIHRvIHRoZSBlcXVpdmFsZW50XHJcbiAgICAgICAgLy8gbWV0aG9kcyBvZiB0aGUgZ2l2ZW4gUHJvbWlzZSBvYmplY3Q6XHJcbiAgICAgICAgX2VuaGFuY2VQcm9taXNlOiBmdW5jdGlvbiAocHJvbWlzZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlLnN1Y2Nlc3MgPSBwcm9taXNlLmRvbmU7XHJcbiAgICAgICAgICAgIHByb21pc2UuZXJyb3IgPSBwcm9taXNlLmZhaWw7XHJcbiAgICAgICAgICAgIHByb21pc2UuY29tcGxldGUgPSBwcm9taXNlLmFsd2F5cztcclxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlcyBhbmQgcmV0dXJucyBhIFByb21pc2Ugb2JqZWN0IGVuaGFuY2VkIHdpdGhcclxuICAgICAgICAvLyB0aGUganFYSFIgbWV0aG9kcyBhYm9ydCwgc3VjY2VzcywgZXJyb3IgYW5kIGNvbXBsZXRlOlxyXG4gICAgICAgIF9nZXRYSFJQcm9taXNlOiBmdW5jdGlvbiAocmVzb2x2ZU9yUmVqZWN0LCBjb250ZXh0LCBhcmdzKSB7XHJcbiAgICAgICAgICAgIHZhciBkZmQgPSAkLkRlZmVycmVkKCksXHJcbiAgICAgICAgICAgICAgICBwcm9taXNlID0gZGZkLnByb21pc2UoKTtcclxuICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHQgfHwgdGhpcy5vcHRpb25zLmNvbnRleHQgfHwgcHJvbWlzZTtcclxuICAgICAgICAgICAgaWYgKHJlc29sdmVPclJlamVjdCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgZGZkLnJlc29sdmVXaXRoKGNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc29sdmVPclJlamVjdCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIGRmZC5yZWplY3RXaXRoKGNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHByb21pc2UuYWJvcnQgPSBkZmQucHJvbWlzZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuaGFuY2VQcm9taXNlKHByb21pc2UpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8vIEFkZHMgY29udmVuaWVuY2UgbWV0aG9kcyB0byB0aGUgZGF0YSBjYWxsYmFjayBhcmd1bWVudDpcclxuICAgICAgICBfYWRkQ29udmVuaWVuY2VNZXRob2RzOiBmdW5jdGlvbiAoZSwgZGF0YSkge1xyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBnZXRQcm9taXNlID0gZnVuY3Rpb24gKGFyZ3MpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmVXaXRoKHRoYXQsIGFyZ3MpLnByb21pc2UoKTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGRhdGEucHJvY2VzcyA9IGZ1bmN0aW9uIChyZXNvbHZlRnVuYywgcmVqZWN0RnVuYykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc29sdmVGdW5jIHx8IHJlamVjdEZ1bmMpIHtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLl9wcm9jZXNzUXVldWUgPSB0aGlzLl9wcm9jZXNzUXVldWUgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5fcHJvY2Vzc1F1ZXVlIHx8IGdldFByb21pc2UoW3RoaXNdKSkucGlwZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5lcnJvclRocm93bikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJC5EZWZlcnJlZCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVqZWN0V2l0aCh0aGF0LCBbZGF0YV0pLnByb21pc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFByb21pc2UoYXJndW1lbnRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKS5waXBlKHJlc29sdmVGdW5jLCByZWplY3RGdW5jKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzUXVldWUgfHwgZ2V0UHJvbWlzZShbdGhpc10pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBkYXRhLnN1Ym1pdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlKCkgIT09ICdwZW5kaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuanFYSFIgPSB0aGlzLmpxWEhSID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoYXQuX3RyaWdnZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3VibWl0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ3N1Ym1pdCcsIHtkZWxlZ2F0ZWRFdmVudDogZX0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICApICE9PSBmYWxzZSkgJiYgdGhhdC5fb25TZW5kKGUsIHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanFYSFIgfHwgdGhhdC5fZ2V0WEhSUHJvbWlzZSgpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBkYXRhLmFib3J0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuanFYSFIpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qcVhIUi5hYm9ydCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvclRocm93biA9ICdhYm9ydCc7XHJcbiAgICAgICAgICAgICAgICB0aGF0Ll90cmlnZ2VyKCdmYWlsJywgbnVsbCwgdGhpcyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhhdC5fZ2V0WEhSUHJvbWlzZShmYWxzZSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGRhdGEuc3RhdGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5qcVhIUikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKHRoaXMuanFYSFIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3Byb2Nlc3NRdWV1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKHRoaXMuX3Byb2Nlc3NRdWV1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGRhdGEucHJvY2Vzc2luZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5qcVhIUiAmJiB0aGlzLl9wcm9jZXNzUXVldWUgJiYgdGhhdFxyXG4gICAgICAgICAgICAgICAgICAgIC5fZ2V0RGVmZXJyZWRTdGF0ZSh0aGlzLl9wcm9jZXNzUXVldWUpID09PSAncGVuZGluZyc7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGRhdGEucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvZ3Jlc3M7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGRhdGEucmVzcG9uc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gUGFyc2VzIHRoZSBSYW5nZSBoZWFkZXIgZnJvbSB0aGUgc2VydmVyIHJlc3BvbnNlXHJcbiAgICAgICAgLy8gYW5kIHJldHVybnMgdGhlIHVwbG9hZGVkIGJ5dGVzOlxyXG4gICAgICAgIF9nZXRVcGxvYWRlZEJ5dGVzOiBmdW5jdGlvbiAoanFYSFIpIHtcclxuICAgICAgICAgICAgdmFyIHJhbmdlID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoJ1JhbmdlJyksXHJcbiAgICAgICAgICAgICAgICBwYXJ0cyA9IHJhbmdlICYmIHJhbmdlLnNwbGl0KCctJyksXHJcbiAgICAgICAgICAgICAgICB1cHBlckJ5dGVzUG9zID0gcGFydHMgJiYgcGFydHMubGVuZ3RoID4gMSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KHBhcnRzWzFdLCAxMCk7XHJcbiAgICAgICAgICAgIHJldHVybiB1cHBlckJ5dGVzUG9zICYmIHVwcGVyQnl0ZXNQb3MgKyAxO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8vIFVwbG9hZHMgYSBmaWxlIGluIG11bHRpcGxlLCBzZXF1ZW50aWFsIHJlcXVlc3RzXHJcbiAgICAgICAgLy8gYnkgc3BsaXR0aW5nIHRoZSBmaWxlIHVwIGluIG11bHRpcGxlIGJsb2IgY2h1bmtzLlxyXG4gICAgICAgIC8vIElmIHRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIHRydWUsIG9ubHkgdGVzdHMgaWYgdGhlIGZpbGVcclxuICAgICAgICAvLyBzaG91bGQgYmUgdXBsb2FkZWQgaW4gY2h1bmtzLCBidXQgZG9lcyBub3QgaW52b2tlIGFueVxyXG4gICAgICAgIC8vIHVwbG9hZCByZXF1ZXN0czpcclxuICAgICAgICBfY2h1bmtlZFVwbG9hZDogZnVuY3Rpb24gKG9wdGlvbnMsIHRlc3RPbmx5KSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnMudXBsb2FkZWRCeXRlcyA9IG9wdGlvbnMudXBsb2FkZWRCeXRlcyB8fCAwO1xyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBmaWxlID0gb3B0aW9ucy5maWxlc1swXSxcclxuICAgICAgICAgICAgICAgIGZzID0gZmlsZS5zaXplLFxyXG4gICAgICAgICAgICAgICAgdWIgPSBvcHRpb25zLnVwbG9hZGVkQnl0ZXMsXHJcbiAgICAgICAgICAgICAgICBtY3MgPSBvcHRpb25zLm1heENodW5rU2l6ZSB8fCBmcyxcclxuICAgICAgICAgICAgICAgIHNsaWNlID0gdGhpcy5fYmxvYlNsaWNlLFxyXG4gICAgICAgICAgICAgICAgZGZkID0gJC5EZWZlcnJlZCgpLFxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZSA9IGRmZC5wcm9taXNlKCksXHJcbiAgICAgICAgICAgICAgICBqcVhIUixcclxuICAgICAgICAgICAgICAgIHVwbG9hZDtcclxuICAgICAgICAgICAgaWYgKCEodGhpcy5faXNYSFJVcGxvYWQob3B0aW9ucykgJiYgc2xpY2UgJiYgKHViIHx8IG1jcyA8IGZzKSkgfHxcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGVzdE9ubHkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh1YiA+PSBmcykge1xyXG4gICAgICAgICAgICAgICAgZmlsZS5lcnJvciA9IG9wdGlvbnMuaTE4bigndXBsb2FkZWRCeXRlcycpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFhIUlByb21pc2UoXHJcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5jb250ZXh0LFxyXG4gICAgICAgICAgICAgICAgICAgIFtudWxsLCAnZXJyb3InLCBmaWxlLmVycm9yXVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBUaGUgY2h1bmsgdXBsb2FkIG1ldGhvZDpcclxuICAgICAgICAgICAgdXBsb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gQ2xvbmUgdGhlIG9wdGlvbnMgb2JqZWN0IGZvciBlYWNoIGNodW5rIHVwbG9hZDpcclxuICAgICAgICAgICAgICAgIHZhciBvID0gJC5leHRlbmQoe30sIG9wdGlvbnMpLFxyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMb2FkZWQgPSBvLl9wcm9ncmVzcy5sb2FkZWQ7XHJcbiAgICAgICAgICAgICAgICBvLmJsb2IgPSBzbGljZS5jYWxsKFxyXG4gICAgICAgICAgICAgICAgICAgIGZpbGUsXHJcbiAgICAgICAgICAgICAgICAgICAgdWIsXHJcbiAgICAgICAgICAgICAgICAgICAgdWIgKyBtY3MsXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsZS50eXBlXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIGN1cnJlbnQgY2h1bmsgc2l6ZSwgYXMgdGhlIGJsb2IgaXRzZWxmXHJcbiAgICAgICAgICAgICAgICAvLyB3aWxsIGJlIGRlcmVmZXJlbmNlZCBhZnRlciBkYXRhIHByb2Nlc3Npbmc6XHJcbiAgICAgICAgICAgICAgICBvLmNodW5rU2l6ZSA9IG8uYmxvYi5zaXplO1xyXG4gICAgICAgICAgICAgICAgLy8gRXhwb3NlIHRoZSBjaHVuayBieXRlcyBwb3NpdGlvbiByYW5nZTpcclxuICAgICAgICAgICAgICAgIG8uY29udGVudFJhbmdlID0gJ2J5dGVzICcgKyB1YiArICctJyArXHJcbiAgICAgICAgICAgICAgICAgICAgKHViICsgby5jaHVua1NpemUgLSAxKSArICcvJyArIGZzO1xyXG4gICAgICAgICAgICAgICAgLy8gUHJvY2VzcyB0aGUgdXBsb2FkIGRhdGEgKHRoZSBibG9iIGFuZCBwb3RlbnRpYWwgZm9ybSBkYXRhKTpcclxuICAgICAgICAgICAgICAgIHRoYXQuX2luaXRYSFJEYXRhKG8pO1xyXG4gICAgICAgICAgICAgICAgLy8gQWRkIHByb2dyZXNzIGxpc3RlbmVycyBmb3IgdGhpcyBjaHVuayB1cGxvYWQ6XHJcbiAgICAgICAgICAgICAgICB0aGF0Ll9pbml0UHJvZ3Jlc3NMaXN0ZW5lcihvKTtcclxuICAgICAgICAgICAgICAgIGpxWEhSID0gKCh0aGF0Ll90cmlnZ2VyKCdjaHVua3NlbmQnLCBudWxsLCBvKSAhPT0gZmFsc2UgJiYgJC5hamF4KG8pKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9nZXRYSFJQcm9taXNlKGZhbHNlLCBvLmNvbnRleHQpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5kb25lKGZ1bmN0aW9uIChyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHViID0gdGhhdC5fZ2V0VXBsb2FkZWRCeXRlcyhqcVhIUikgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1YiArIG8uY2h1bmtTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgcHJvZ3Jlc3MgZXZlbnQgaWYgbm8gZmluYWwgcHJvZ3Jlc3MgZXZlbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCBsb2FkZWQgZXF1YWxpbmcgdG90YWwgaGFzIGJlZW4gdHJpZ2dlcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB0aGlzIGNodW5rOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudExvYWRlZCArIG8uY2h1bmtTaXplIC0gby5fcHJvZ3Jlc3MubG9hZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9vblByb2dyZXNzKCQuRXZlbnQoJ3Byb2dyZXNzJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aENvbXB1dGFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkOiB1YiAtIG8udXBsb2FkZWRCeXRlcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbDogdWIgLSBvLnVwbG9hZGVkQnl0ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLCBvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnVwbG9hZGVkQnl0ZXMgPSBvLnVwbG9hZGVkQnl0ZXMgPSB1YjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgby5yZXN1bHQgPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG8udGV4dFN0YXR1cyA9IHRleHRTdGF0dXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG8uanFYSFIgPSBqcVhIUjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdHJpZ2dlcignY2h1bmtkb25lJywgbnVsbCwgbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3RyaWdnZXIoJ2NodW5rYWx3YXlzJywgbnVsbCwgbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1YiA8IGZzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaWxlIHVwbG9hZCBub3QgeWV0IGNvbXBsZXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udGludWUgd2l0aCB0aGUgbmV4dCBjaHVuazpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwbG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmVXaXRoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8uY29udGV4dCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUl1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIC5mYWlsKGZ1bmN0aW9uIChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgby5qcVhIUiA9IGpxWEhSO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvLnRleHRTdGF0dXMgPSB0ZXh0U3RhdHVzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvLmVycm9yVGhyb3duID0gZXJyb3JUaHJvd247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3RyaWdnZXIoJ2NodW5rZmFpbCcsIG51bGwsIG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll90cmlnZ2VyKCdjaHVua2Fsd2F5cycsIG51bGwsIG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZmQucmVqZWN0V2l0aChcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8uY29udGV4dCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd25dXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHRoaXMuX2VuaGFuY2VQcm9taXNlKHByb21pc2UpO1xyXG4gICAgICAgICAgICBwcm9taXNlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGpxWEhSLmFib3J0KCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHVwbG9hZCgpO1xyXG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfYmVmb3JlU2VuZDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIHN0YXJ0IGNhbGxiYWNrIGlzIHRyaWdnZXJlZCB3aGVuIGFuIHVwbG9hZCBzdGFydHNcclxuICAgICAgICAgICAgICAgIC8vIGFuZCBubyBvdGhlciB1cGxvYWRzIGFyZSBjdXJyZW50bHkgcnVubmluZyxcclxuICAgICAgICAgICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gdGhlIGdsb2JhbCBhamF4U3RhcnQgZXZlbnQ6XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyKCdzdGFydCcpO1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IHRpbWVyIGZvciBnbG9iYWwgYml0cmF0ZSBwcm9ncmVzcyBjYWxjdWxhdGlvbjpcclxuICAgICAgICAgICAgICAgIHRoaXMuX2JpdHJhdGVUaW1lciA9IG5ldyB0aGlzLl9CaXRyYXRlVGltZXIoKTtcclxuICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBnbG9iYWwgcHJvZ3Jlc3MgdmFsdWVzOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkID0gdGhpcy5fcHJvZ3Jlc3MudG90YWwgPSAwO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MuYml0cmF0ZSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBjb250YWluZXIgb2JqZWN0cyBmb3IgdGhlIC5yZXNwb25zZSgpIGFuZFxyXG4gICAgICAgICAgICAvLyAucHJvZ3Jlc3MoKSBtZXRob2RzIG9uIHRoZSBkYXRhIG9iamVjdCBhcmUgYXZhaWxhYmxlXHJcbiAgICAgICAgICAgIC8vIGFuZCByZXNldCB0byB0aGVpciBpbml0aWFsIHN0YXRlOlxyXG4gICAgICAgICAgICB0aGlzLl9pbml0UmVzcG9uc2VPYmplY3QoZGF0YSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2luaXRQcm9ncmVzc09iamVjdChkYXRhKTtcclxuICAgICAgICAgICAgZGF0YS5fcHJvZ3Jlc3MubG9hZGVkID0gZGF0YS5sb2FkZWQgPSBkYXRhLnVwbG9hZGVkQnl0ZXMgfHwgMDtcclxuICAgICAgICAgICAgZGF0YS5fcHJvZ3Jlc3MudG90YWwgPSBkYXRhLnRvdGFsID0gdGhpcy5fZ2V0VG90YWwoZGF0YS5maWxlcykgfHwgMTtcclxuICAgICAgICAgICAgZGF0YS5fcHJvZ3Jlc3MuYml0cmF0ZSA9IGRhdGEuYml0cmF0ZSA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZSArPSAxO1xyXG4gICAgICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBnbG9iYWwgcHJvZ3Jlc3MgdmFsdWVzOlxyXG4gICAgICAgICAgICB0aGlzLl9wcm9ncmVzcy5sb2FkZWQgKz0gZGF0YS5sb2FkZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLnRvdGFsICs9IGRhdGEudG90YWw7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX29uRG9uZTogZnVuY3Rpb24gKHJlc3VsdCwgdGV4dFN0YXR1cywganFYSFIsIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdmFyIHRvdGFsID0gb3B0aW9ucy5fcHJvZ3Jlc3MudG90YWwsXHJcbiAgICAgICAgICAgICAgICByZXNwb25zZSA9IG9wdGlvbnMuX3Jlc3BvbnNlO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5fcHJvZ3Jlc3MubG9hZGVkIDwgdG90YWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHByb2dyZXNzIGV2ZW50IGlmIG5vIGZpbmFsIHByb2dyZXNzIGV2ZW50XHJcbiAgICAgICAgICAgICAgICAvLyB3aXRoIGxvYWRlZCBlcXVhbGluZyB0b3RhbCBoYXMgYmVlbiB0cmlnZ2VyZWQ6XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vblByb2dyZXNzKCQuRXZlbnQoJ3Byb2dyZXNzJywge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aENvbXB1dGFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVkOiB0b3RhbCxcclxuICAgICAgICAgICAgICAgICAgICB0b3RhbDogdG90YWxcclxuICAgICAgICAgICAgICAgIH0pLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNwb25zZS5yZXN1bHQgPSBvcHRpb25zLnJlc3VsdCA9IHJlc3VsdDtcclxuICAgICAgICAgICAgcmVzcG9uc2UudGV4dFN0YXR1cyA9IG9wdGlvbnMudGV4dFN0YXR1cyA9IHRleHRTdGF0dXM7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLmpxWEhSID0gb3B0aW9ucy5qcVhIUiA9IGpxWEhSO1xyXG4gICAgICAgICAgICB0aGlzLl90cmlnZ2VyKCdkb25lJywgbnVsbCwgb3B0aW9ucyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX29uRmFpbDogZnVuY3Rpb24gKGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biwgb3B0aW9ucykge1xyXG4gICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBvcHRpb25zLl9yZXNwb25zZTtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucmVjYWxjdWxhdGVQcm9ncmVzcykge1xyXG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBmYWlsZWQgKGVycm9yIG9yIGFib3J0KSBmaWxlIHVwbG9hZCBmcm9tXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgZ2xvYmFsIHByb2dyZXNzIGNhbGN1bGF0aW9uOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkIC09IG9wdGlvbnMuX3Byb2dyZXNzLmxvYWRlZDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLnRvdGFsIC09IG9wdGlvbnMuX3Byb2dyZXNzLnRvdGFsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLmpxWEhSID0gb3B0aW9ucy5qcVhIUiA9IGpxWEhSO1xyXG4gICAgICAgICAgICByZXNwb25zZS50ZXh0U3RhdHVzID0gb3B0aW9ucy50ZXh0U3RhdHVzID0gdGV4dFN0YXR1cztcclxuICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JUaHJvd24gPSBvcHRpb25zLmVycm9yVGhyb3duID0gZXJyb3JUaHJvd247XHJcbiAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoJ2ZhaWwnLCBudWxsLCBvcHRpb25zKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25BbHdheXM6IGZ1bmN0aW9uIChqcVhIUm9yUmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUm9yRXJyb3IsIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgLy8ganFYSFJvclJlc3VsdCwgdGV4dFN0YXR1cyBhbmQganFYSFJvckVycm9yIGFyZSBhZGRlZCB0byB0aGVcclxuICAgICAgICAgICAgLy8gb3B0aW9ucyBvYmplY3QgdmlhIGRvbmUgYW5kIGZhaWwgY2FsbGJhY2tzXHJcbiAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoJ2Fsd2F5cycsIG51bGwsIG9wdGlvbnMpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9vblNlbmQ6IGZ1bmN0aW9uIChlLCBkYXRhKSB7XHJcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWJtaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FkZENvbnZlbmllbmNlTWV0aG9kcyhlLCBkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBqcVhIUixcclxuICAgICAgICAgICAgICAgIGFib3J0ZWQsXHJcbiAgICAgICAgICAgICAgICBzbG90LFxyXG4gICAgICAgICAgICAgICAgcGlwZSxcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB0aGF0Ll9nZXRBSkFYU2V0dGluZ3MoZGF0YSksXHJcbiAgICAgICAgICAgICAgICBzZW5kID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX3NlbmRpbmcgKz0gMTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGltZXIgZm9yIGJpdHJhdGUgcHJvZ3Jlc3MgY2FsY3VsYXRpb246XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5fYml0cmF0ZVRpbWVyID0gbmV3IHRoYXQuX0JpdHJhdGVUaW1lcigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGpxWEhSID0ganFYSFIgfHwgKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoKGFib3J0ZWQgfHwgdGhhdC5fdHJpZ2dlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZW5kJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ3NlbmQnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgKSA9PT0gZmFsc2UpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2dldFhIUlByb21pc2UoZmFsc2UsIG9wdGlvbnMuY29udGV4dCwgYWJvcnRlZCkpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2NodW5rZWRVcGxvYWQob3B0aW9ucykgfHwgJC5hamF4KG9wdGlvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgKS5kb25lKGZ1bmN0aW9uIChyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX29uRG9uZShyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICB9KS5mYWlsKGZ1bmN0aW9uIChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25GYWlsKGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkuYWx3YXlzKGZ1bmN0aW9uIChqcVhIUm9yUmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUm9yRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25BbHdheXMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcVhIUm9yUmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXR1cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpxWEhSb3JFcnJvcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fc2VuZGluZyAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9hY3RpdmUgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubGltaXRDb25jdXJyZW50VXBsb2FkcyAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubGltaXRDb25jdXJyZW50VXBsb2FkcyA+IHRoYXQuX3NlbmRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IHRoZSBuZXh0IHF1ZXVlZCB1cGxvYWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGhhcyBub3QgYmVlbiBhYm9ydGVkOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5leHRTbG90ID0gdGhhdC5fc2xvdHMuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0U2xvdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKG5leHRTbG90KSA9PT0gJ3BlbmRpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTbG90LnJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTbG90ID0gdGhhdC5fc2xvdHMuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5fYWN0aXZlID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgc3RvcCBjYWxsYmFjayBpcyB0cmlnZ2VyZWQgd2hlbiBhbGwgdXBsb2FkcyBoYXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWVuIGNvbXBsZXRlZCwgZXF1aXZhbGVudCB0byB0aGUgZ2xvYmFsIGFqYXhTdG9wIGV2ZW50OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdHJpZ2dlcignc3RvcCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGpxWEhSO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdGhpcy5fYmVmb3JlU2VuZChlLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zZXF1ZW50aWFsVXBsb2FkcyB8fFxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLm9wdGlvbnMubGltaXRDb25jdXJyZW50VXBsb2FkcyAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5saW1pdENvbmN1cnJlbnRVcGxvYWRzIDw9IHRoaXMuX3NlbmRpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxpbWl0Q29uY3VycmVudFVwbG9hZHMgPiAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2xvdCA9ICQuRGVmZXJyZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zbG90cy5wdXNoKHNsb3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBpcGUgPSBzbG90LnBpcGUoc2VuZCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlcXVlbmNlID0gdGhpcy5fc2VxdWVuY2UucGlwZShzZW5kLCBzZW5kKTtcclxuICAgICAgICAgICAgICAgICAgICBwaXBlID0gdGhpcy5fc2VxdWVuY2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gdGhlIHBpcGVkIFByb21pc2Ugb2JqZWN0LCBlbmhhbmNlZCB3aXRoIGFuIGFib3J0IG1ldGhvZCxcclxuICAgICAgICAgICAgICAgIC8vIHdoaWNoIGlzIGRlbGVnYXRlZCB0byB0aGUganFYSFIgb2JqZWN0IG9mIHRoZSBjdXJyZW50IHVwbG9hZCxcclxuICAgICAgICAgICAgICAgIC8vIGFuZCBqcVhIUiBjYWxsYmFja3MgbWFwcGVkIHRvIHRoZSBlcXVpdmFsZW50IFByb21pc2UgbWV0aG9kczpcclxuICAgICAgICAgICAgICAgIHBpcGUuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWJvcnRlZCA9IFt1bmRlZmluZWQsICdhYm9ydCcsICdhYm9ydCddO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghanFYSFIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNsb3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNsb3QucmVqZWN0V2l0aChvcHRpb25zLmNvbnRleHQsIGFib3J0ZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZW5kKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqcVhIUi5hYm9ydCgpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9lbmhhbmNlUHJvbWlzZShwaXBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gc2VuZCgpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9vbkFkZDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zLCBkYXRhKSxcclxuICAgICAgICAgICAgICAgIGZpbGVzID0gZGF0YS5maWxlcyxcclxuICAgICAgICAgICAgICAgIGZpbGVzTGVuZ3RoID0gZmlsZXMubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgbGltaXQgPSBvcHRpb25zLmxpbWl0TXVsdGlGaWxlVXBsb2FkcyxcclxuICAgICAgICAgICAgICAgIGxpbWl0U2l6ZSA9IG9wdGlvbnMubGltaXRNdWx0aUZpbGVVcGxvYWRTaXplLFxyXG4gICAgICAgICAgICAgICAgb3ZlcmhlYWQgPSBvcHRpb25zLmxpbWl0TXVsdGlGaWxlVXBsb2FkU2l6ZU92ZXJoZWFkLFxyXG4gICAgICAgICAgICAgICAgYmF0Y2hTaXplID0gMCxcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZSA9IHRoaXMuX2dldFBhcmFtTmFtZShvcHRpb25zKSxcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNldCxcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlLFxyXG4gICAgICAgICAgICAgICAgZmlsZVNldCxcclxuICAgICAgICAgICAgICAgIGksXHJcbiAgICAgICAgICAgICAgICBqID0gMDtcclxuICAgICAgICAgICAgaWYgKCFmaWxlc0xlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChsaW1pdFNpemUgJiYgZmlsZXNbMF0uc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBsaW1pdFNpemUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCEob3B0aW9ucy5zaW5nbGVGaWxlVXBsb2FkcyB8fCBsaW1pdCB8fCBsaW1pdFNpemUpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgIXRoaXMuX2lzWEhSVXBsb2FkKG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlU2V0ID0gW2ZpbGVzXTtcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNldCA9IFtwYXJhbU5hbWVdO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCEob3B0aW9ucy5zaW5nbGVGaWxlVXBsb2FkcyB8fCBsaW1pdFNpemUpICYmIGxpbWl0KSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlU2V0ID0gW107XHJcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWVTZXQgPSBbXTtcclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBmaWxlc0xlbmd0aDsgaSArPSBsaW1pdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGVTZXQucHVzaChmaWxlcy5zbGljZShpLCBpICsgbGltaXQpKTtcclxuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWVTbGljZSA9IHBhcmFtTmFtZS5zbGljZShpLCBpICsgbGltaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyYW1OYW1lU2xpY2UubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlID0gcGFyYW1OYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWVTZXQucHVzaChwYXJhbU5hbWVTbGljZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMuc2luZ2xlRmlsZVVwbG9hZHMgJiYgbGltaXRTaXplKSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlU2V0ID0gW107XHJcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWVTZXQgPSBbXTtcclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBmaWxlc0xlbmd0aDsgaSA9IGkgKyAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmF0Y2hTaXplICs9IGZpbGVzW2ldLnNpemUgKyBvdmVyaGVhZDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaSArIDEgPT09IGZpbGVzTGVuZ3RoIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGJhdGNoU2l6ZSArIGZpbGVzW2kgKyAxXS5zaXplICsgb3ZlcmhlYWQpID4gbGltaXRTaXplKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpbWl0ICYmIGkgKyAxIC0gaiA+PSBsaW1pdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVNldC5wdXNoKGZpbGVzLnNsaWNlKGosIGkgKyAxKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlID0gcGFyYW1OYW1lLnNsaWNlKGosIGkgKyAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXJhbU5hbWVTbGljZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlID0gcGFyYW1OYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNldC5wdXNoKHBhcmFtTmFtZVNsaWNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYXRjaFNpemUgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNldCA9IHBhcmFtTmFtZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkYXRhLm9yaWdpbmFsRmlsZXMgPSBmaWxlcztcclxuICAgICAgICAgICAgJC5lYWNoKGZpbGVTZXQgfHwgZmlsZXMsIGZ1bmN0aW9uIChpbmRleCwgZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5ld0RhdGEgPSAkLmV4dGVuZCh7fSwgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICBuZXdEYXRhLmZpbGVzID0gZmlsZVNldCA/IGVsZW1lbnQgOiBbZWxlbWVudF07XHJcbiAgICAgICAgICAgICAgICBuZXdEYXRhLnBhcmFtTmFtZSA9IHBhcmFtTmFtZVNldFtpbmRleF07XHJcbiAgICAgICAgICAgICAgICB0aGF0Ll9pbml0UmVzcG9uc2VPYmplY3QobmV3RGF0YSk7XHJcbiAgICAgICAgICAgICAgICB0aGF0Ll9pbml0UHJvZ3Jlc3NPYmplY3QobmV3RGF0YSk7XHJcbiAgICAgICAgICAgICAgICB0aGF0Ll9hZGRDb252ZW5pZW5jZU1ldGhvZHMoZSwgbmV3RGF0YSk7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0Ll90cmlnZ2VyKFxyXG4gICAgICAgICAgICAgICAgICAgICdhZGQnLFxyXG4gICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ2FkZCcsIHtkZWxlZ2F0ZWRFdmVudDogZX0pLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0RhdGFcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfcmVwbGFjZUZpbGVJbnB1dDogZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgdmFyIGlucHV0ID0gZGF0YS5maWxlSW5wdXQsXHJcbiAgICAgICAgICAgICAgICBpbnB1dENsb25lID0gaW5wdXQuY2xvbmUodHJ1ZSksXHJcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXMgPSBpbnB1dC5pcyhkb2N1bWVudC5hY3RpdmVFbGVtZW50KTtcclxuICAgICAgICAgICAgLy8gQWRkIGEgcmVmZXJlbmNlIGZvciB0aGUgbmV3IGNsb25lZCBmaWxlIGlucHV0IHRvIHRoZSBkYXRhIGFyZ3VtZW50OlxyXG4gICAgICAgICAgICBkYXRhLmZpbGVJbnB1dENsb25lID0gaW5wdXRDbG9uZTtcclxuICAgICAgICAgICAgJCgnPGZvcm0+PC9mb3JtPicpLmFwcGVuZChpbnB1dENsb25lKVswXS5yZXNldCgpO1xyXG4gICAgICAgICAgICAvLyBEZXRhY2hpbmcgYWxsb3dzIHRvIGluc2VydCB0aGUgZmlsZUlucHV0IG9uIGFub3RoZXIgZm9ybVxyXG4gICAgICAgICAgICAvLyB3aXRob3V0IGxvb3NpbmcgdGhlIGZpbGUgaW5wdXQgdmFsdWU6XHJcbiAgICAgICAgICAgIGlucHV0LmFmdGVyKGlucHV0Q2xvbmUpLmRldGFjaCgpO1xyXG4gICAgICAgICAgICAvLyBJZiB0aGUgZmlsZUlucHV0IGhhZCBmb2N1cyBiZWZvcmUgaXQgd2FzIGRldGFjaGVkLFxyXG4gICAgICAgICAgICAvLyByZXN0b3JlIGZvY3VzIHRvIHRoZSBpbnB1dENsb25lLlxyXG4gICAgICAgICAgICBpZiAocmVzdG9yZUZvY3VzKSB7XHJcbiAgICAgICAgICAgICAgICBpbnB1dENsb25lLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQXZvaWQgbWVtb3J5IGxlYWtzIHdpdGggdGhlIGRldGFjaGVkIGZpbGUgaW5wdXQ6XHJcbiAgICAgICAgICAgICQuY2xlYW5EYXRhKGlucHV0LnVuYmluZCgncmVtb3ZlJykpO1xyXG4gICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSBvcmlnaW5hbCBmaWxlIGlucHV0IGVsZW1lbnQgaW4gdGhlIGZpbGVJbnB1dFxyXG4gICAgICAgICAgICAvLyBlbGVtZW50cyBzZXQgd2l0aCB0aGUgY2xvbmUsIHdoaWNoIGhhcyBiZWVuIGNvcGllZCBpbmNsdWRpbmdcclxuICAgICAgICAgICAgLy8gZXZlbnQgaGFuZGxlcnM6XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5maWxlSW5wdXQgPSB0aGlzLm9wdGlvbnMuZmlsZUlucHV0Lm1hcChmdW5jdGlvbiAoaSwgZWwpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlbCA9PT0gaW5wdXRbMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRDbG9uZVswXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBlbDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSB3aWRnZXQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgb24gdGhlIGZpbGUgaW5wdXQgaXRzZWxmLFxyXG4gICAgICAgICAgICAvLyBvdmVycmlkZSB0aGlzLmVsZW1lbnQgd2l0aCB0aGUgZmlsZSBpbnB1dCBjbG9uZTpcclxuICAgICAgICAgICAgaWYgKGlucHV0WzBdID09PSB0aGlzLmVsZW1lbnRbMF0pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGlucHV0Q2xvbmU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaGFuZGxlRmlsZVRyZWVFbnRyeTogZnVuY3Rpb24gKGVudHJ5LCBwYXRoKSB7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcclxuICAgICAgICAgICAgICAgIGRmZCA9ICQuRGVmZXJyZWQoKSxcclxuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUgJiYgIWUuZW50cnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5lbnRyeSA9IGVudHJ5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBTaW5jZSAkLndoZW4gcmV0dXJucyBpbW1lZGlhdGVseSBpZiBvbmVcclxuICAgICAgICAgICAgICAgICAgICAvLyBEZWZlcnJlZCBpcyByZWplY3RlZCwgd2UgdXNlIHJlc29sdmUgaW5zdGVhZC5cclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGFsbG93cyB2YWxpZCBmaWxlcyBhbmQgaW52YWxpZCBpdGVtc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRvIGJlIHJldHVybmVkIHRvZ2V0aGVyIGluIG9uZSBzZXQ6XHJcbiAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUoW2VdKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBzdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uIChlbnRyaWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5faGFuZGxlRmlsZVRyZWVFbnRyaWVzKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoICsgZW50cnkubmFtZSArICcvJ1xyXG4gICAgICAgICAgICAgICAgICAgICkuZG9uZShmdW5jdGlvbiAoZmlsZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUoZmlsZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pLmZhaWwoZXJyb3JIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICByZWFkRW50cmllcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBkaXJSZWFkZXIucmVhZEVudHJpZXMoZnVuY3Rpb24gKHJlc3VsdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0hhbmRsZXIoZW50cmllcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzID0gZW50cmllcy5jb25jYXQocmVzdWx0cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkRW50cmllcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgZXJyb3JIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBkaXJSZWFkZXIsIGVudHJpZXMgPSBbXTtcclxuICAgICAgICAgICAgcGF0aCA9IHBhdGggfHwgJyc7XHJcbiAgICAgICAgICAgIGlmIChlbnRyeS5pc0ZpbGUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5fZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIENocm9tZSBidWcgIzE0OTczNVxyXG4gICAgICAgICAgICAgICAgICAgIGVudHJ5Ll9maWxlLnJlbGF0aXZlUGF0aCA9IHBhdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUoZW50cnkuX2ZpbGUpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBlbnRyeS5maWxlKGZ1bmN0aW9uIChmaWxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucmVsYXRpdmVQYXRoID0gcGF0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUoZmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgZXJyb3JIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlbnRyeS5pc0RpcmVjdG9yeSkge1xyXG4gICAgICAgICAgICAgICAgZGlyUmVhZGVyID0gZW50cnkuY3JlYXRlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgICAgICByZWFkRW50cmllcygpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gUmV0dXJuIGFuIGVtcHkgbGlzdCBmb3IgZmlsZSBzeXN0ZW0gaXRlbXNcclxuICAgICAgICAgICAgICAgIC8vIG90aGVyIHRoYW4gZmlsZXMgb3IgZGlyZWN0b3JpZXM6XHJcbiAgICAgICAgICAgICAgICBkZmQucmVzb2x2ZShbXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGRmZC5wcm9taXNlKCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2hhbmRsZUZpbGVUcmVlRW50cmllczogZnVuY3Rpb24gKGVudHJpZXMsIHBhdGgpIHtcclxuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xyXG4gICAgICAgICAgICByZXR1cm4gJC53aGVuLmFwcGx5KFxyXG4gICAgICAgICAgICAgICAgJCxcclxuICAgICAgICAgICAgICAgICQubWFwKGVudHJpZXMsIGZ1bmN0aW9uIChlbnRyeSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9oYW5kbGVGaWxlVHJlZUVudHJ5KGVudHJ5LCBwYXRoKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICkucGlwZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShcclxuICAgICAgICAgICAgICAgICAgICBbXSxcclxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHNcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9nZXREcm9wcGVkRmlsZXM6IGZ1bmN0aW9uIChkYXRhVHJhbnNmZXIpIHtcclxuICAgICAgICAgICAgZGF0YVRyYW5zZmVyID0gZGF0YVRyYW5zZmVyIHx8IHt9O1xyXG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBkYXRhVHJhbnNmZXIuaXRlbXM7XHJcbiAgICAgICAgICAgIGlmIChpdGVtcyAmJiBpdGVtcy5sZW5ndGggJiYgKGl0ZW1zWzBdLndlYmtpdEdldEFzRW50cnkgfHxcclxuICAgICAgICAgICAgICAgICAgICBpdGVtc1swXS5nZXRBc0VudHJ5KSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUZpbGVUcmVlRW50cmllcyhcclxuICAgICAgICAgICAgICAgICAgICAkLm1hcChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVudHJ5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS53ZWJraXRHZXRBc0VudHJ5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSA9IGl0ZW0ud2Via2l0R2V0QXNFbnRyeSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgQ2hyb21lIGJ1ZyAjMTQ5NzM1OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5Ll9maWxlID0gaXRlbS5nZXRBc0ZpbGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS5nZXRBc0VudHJ5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuICQuRGVmZXJyZWQoKS5yZXNvbHZlKFxyXG4gICAgICAgICAgICAgICAgJC5tYWtlQXJyYXkoZGF0YVRyYW5zZmVyLmZpbGVzKVxyXG4gICAgICAgICAgICApLnByb21pc2UoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfZ2V0U2luZ2xlRmlsZUlucHV0RmlsZXM6IGZ1bmN0aW9uIChmaWxlSW5wdXQpIHtcclxuICAgICAgICAgICAgZmlsZUlucHV0ID0gJChmaWxlSW5wdXQpO1xyXG4gICAgICAgICAgICB2YXIgZW50cmllcyA9IGZpbGVJbnB1dC5wcm9wKCd3ZWJraXRFbnRyaWVzJykgfHxcclxuICAgICAgICAgICAgICAgICAgICBmaWxlSW5wdXQucHJvcCgnZW50cmllcycpLFxyXG4gICAgICAgICAgICAgICAgZmlsZXMsXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTtcclxuICAgICAgICAgICAgaWYgKGVudHJpZXMgJiYgZW50cmllcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVGaWxlVHJlZUVudHJpZXMoZW50cmllcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZmlsZXMgPSAkLm1ha2VBcnJheShmaWxlSW5wdXQucHJvcCgnZmlsZXMnKSk7XHJcbiAgICAgICAgICAgIGlmICghZmlsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGZpbGVJbnB1dC5wcm9wKCd2YWx1ZScpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShbXSkucHJvbWlzZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGZpbGVzIHByb3BlcnR5IGlzIG5vdCBhdmFpbGFibGUsIHRoZSBicm93c2VyIGRvZXMgbm90XHJcbiAgICAgICAgICAgICAgICAvLyBzdXBwb3J0IHRoZSBGaWxlIEFQSSBhbmQgd2UgYWRkIGEgcHNldWRvIEZpbGUgb2JqZWN0IHdpdGhcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBpbnB1dCB2YWx1ZSBhcyBuYW1lIHdpdGggcGF0aCBpbmZvcm1hdGlvbiByZW1vdmVkOlxyXG4gICAgICAgICAgICAgICAgZmlsZXMgPSBbe25hbWU6IHZhbHVlLnJlcGxhY2UoL14uKlxcXFwvLCAnJyl9XTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlc1swXS5uYW1lID09PSB1bmRlZmluZWQgJiYgZmlsZXNbMF0uZmlsZU5hbWUpIHtcclxuICAgICAgICAgICAgICAgIC8vIEZpbGUgbm9ybWFsaXphdGlvbiBmb3IgU2FmYXJpIDQgYW5kIEZpcmVmb3ggMzpcclxuICAgICAgICAgICAgICAgICQuZWFjaChmaWxlcywgZnVuY3Rpb24gKGluZGV4LCBmaWxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsZS5uYW1lID0gZmlsZS5maWxlTmFtZTtcclxuICAgICAgICAgICAgICAgICAgICBmaWxlLnNpemUgPSBmaWxlLmZpbGVTaXplO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuICQuRGVmZXJyZWQoKS5yZXNvbHZlKGZpbGVzKS5wcm9taXNlKCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX2dldEZpbGVJbnB1dEZpbGVzOiBmdW5jdGlvbiAoZmlsZUlucHV0KSB7XHJcbiAgICAgICAgICAgIGlmICghKGZpbGVJbnB1dCBpbnN0YW5jZW9mICQpIHx8IGZpbGVJbnB1dC5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRTaW5nbGVGaWxlSW5wdXRGaWxlcyhmaWxlSW5wdXQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiAkLndoZW4uYXBwbHkoXHJcbiAgICAgICAgICAgICAgICAkLFxyXG4gICAgICAgICAgICAgICAgJC5tYXAoZmlsZUlucHV0LCB0aGlzLl9nZXRTaW5nbGVGaWxlSW5wdXRGaWxlcylcclxuICAgICAgICAgICAgKS5waXBlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFxyXG4gICAgICAgICAgICAgICAgICAgIFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50c1xyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX29uQ2hhbmdlOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGVJbnB1dDogJChlLnRhcmdldCksXHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybTogJChlLnRhcmdldC5mb3JtKVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdGhpcy5fZ2V0RmlsZUlucHV0RmlsZXMoZGF0YS5maWxlSW5wdXQpLmFsd2F5cyhmdW5jdGlvbiAoZmlsZXMpIHtcclxuICAgICAgICAgICAgICAgIGRhdGEuZmlsZXMgPSBmaWxlcztcclxuICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMucmVwbGFjZUZpbGVJbnB1dCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX3JlcGxhY2VGaWxlSW5wdXQoZGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhhdC5fdHJpZ2dlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NoYW5nZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ2NoYW5nZScsIHtkZWxlZ2F0ZWRFdmVudDogZX0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhXHJcbiAgICAgICAgICAgICAgICAgICAgKSAhPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9vbkFkZChlLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX29uUGFzdGU6IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIHZhciBpdGVtcyA9IGUub3JpZ2luYWxFdmVudCAmJiBlLm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGUub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhLml0ZW1zLFxyXG4gICAgICAgICAgICAgICAgZGF0YSA9IHtmaWxlczogW119O1xyXG4gICAgICAgICAgICBpZiAoaXRlbXMgJiYgaXRlbXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAkLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaWxlID0gaXRlbS5nZXRBc0ZpbGUgJiYgaXRlbS5nZXRBc0ZpbGUoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmZpbGVzLnB1c2goZmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fdHJpZ2dlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3Bhc3RlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgncGFzdGUnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgICkgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25BZGQoZSwgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25Ecm9wOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBlLmRhdGFUcmFuc2ZlciA9IGUub3JpZ2luYWxFdmVudCAmJiBlLm9yaWdpbmFsRXZlbnQuZGF0YVRyYW5zZmVyO1xyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICBkYXRhVHJhbnNmZXIgPSBlLmRhdGFUcmFuc2ZlcixcclxuICAgICAgICAgICAgICAgIGRhdGEgPSB7fTtcclxuICAgICAgICAgICAgaWYgKGRhdGFUcmFuc2ZlciAmJiBkYXRhVHJhbnNmZXIuZmlsZXMgJiYgZGF0YVRyYW5zZmVyLmZpbGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZ2V0RHJvcHBlZEZpbGVzKGRhdGFUcmFuc2ZlcikuYWx3YXlzKGZ1bmN0aW9uIChmaWxlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuZmlsZXMgPSBmaWxlcztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5fdHJpZ2dlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkcm9wJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ2Ryb3AnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgKSAhPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25BZGQoZSwgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfb25EcmFnT3ZlcjogZ2V0RHJhZ0hhbmRsZXIoJ2RyYWdvdmVyJyksXHJcblxyXG4gICAgICAgIF9vbkRyYWdFbnRlcjogZ2V0RHJhZ0hhbmRsZXIoJ2RyYWdlbnRlcicpLFxyXG5cclxuICAgICAgICBfb25EcmFnTGVhdmU6IGdldERyYWdIYW5kbGVyKCdkcmFnbGVhdmUnKSxcclxuXHJcbiAgICAgICAgX2luaXRFdmVudEhhbmRsZXJzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc1hIUlVwbG9hZCh0aGlzLm9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vbih0aGlzLm9wdGlvbnMuZHJvcFpvbmUsIHtcclxuICAgICAgICAgICAgICAgICAgICBkcmFnb3ZlcjogdGhpcy5fb25EcmFnT3ZlcixcclxuICAgICAgICAgICAgICAgICAgICBkcm9wOiB0aGlzLl9vbkRyb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZXZlbnQucHJldmVudERlZmF1bHQoKSBvbiBkcmFnZW50ZXIgaXMgcmVxdWlyZWQgZm9yIElFMTArOlxyXG4gICAgICAgICAgICAgICAgICAgIGRyYWdlbnRlcjogdGhpcy5fb25EcmFnRW50ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZHJhZ2xlYXZlIGlzIG5vdCByZXF1aXJlZCwgYnV0IGFkZGVkIGZvciBjb21wbGV0ZW5lc3M6XHJcbiAgICAgICAgICAgICAgICAgICAgZHJhZ2xlYXZlOiB0aGlzLl9vbkRyYWdMZWF2ZVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vbih0aGlzLm9wdGlvbnMucGFzdGVab25lLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFzdGU6IHRoaXMuX29uUGFzdGVcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgkLnN1cHBvcnQuZmlsZUlucHV0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vbih0aGlzLm9wdGlvbnMuZmlsZUlucHV0LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hhbmdlOiB0aGlzLl9vbkNoYW5nZVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfZGVzdHJveUV2ZW50SGFuZGxlcnM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5fb2ZmKHRoaXMub3B0aW9ucy5kcm9wWm9uZSwgJ2RyYWdlbnRlciBkcmFnbGVhdmUgZHJhZ292ZXIgZHJvcCcpO1xyXG4gICAgICAgICAgICB0aGlzLl9vZmYodGhpcy5vcHRpb25zLnBhc3RlWm9uZSwgJ3Bhc3RlJyk7XHJcbiAgICAgICAgICAgIHRoaXMuX29mZih0aGlzLm9wdGlvbnMuZmlsZUlucHV0LCAnY2hhbmdlJyk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgX3NldE9wdGlvbjogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgdmFyIHJlaW5pdCA9ICQuaW5BcnJheShrZXksIHRoaXMuX3NwZWNpYWxPcHRpb25zKSAhPT0gLTE7XHJcbiAgICAgICAgICAgIGlmIChyZWluaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fc3VwZXIoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIGlmIChyZWluaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2luaXRTcGVjaWFsT3B0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faW5pdEV2ZW50SGFuZGxlcnMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9pbml0U3BlY2lhbE9wdGlvbnM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmZpbGVJbnB1dCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmZpbGVJbnB1dCA9IHRoaXMuZWxlbWVudC5pcygnaW5wdXRbdHlwZT1cImZpbGVcIl0nKSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA6IHRoaXMuZWxlbWVudC5maW5kKCdpbnB1dFt0eXBlPVwiZmlsZVwiXScpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCEob3B0aW9ucy5maWxlSW5wdXQgaW5zdGFuY2VvZiAkKSkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5maWxlSW5wdXQgPSAkKG9wdGlvbnMuZmlsZUlucHV0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIShvcHRpb25zLmRyb3Bab25lIGluc3RhbmNlb2YgJCkpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMuZHJvcFpvbmUgPSAkKG9wdGlvbnMuZHJvcFpvbmUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghKG9wdGlvbnMucGFzdGVab25lIGluc3RhbmNlb2YgJCkpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnMucGFzdGVab25lID0gJChvcHRpb25zLnBhc3RlWm9uZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfZ2V0UmVnRXhwOiBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgnLycpLFxyXG4gICAgICAgICAgICAgICAgbW9kaWZpZXJzID0gcGFydHMucG9wKCk7XHJcbiAgICAgICAgICAgIHBhcnRzLnNoaWZ0KCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKHBhcnRzLmpvaW4oJy8nKSwgbW9kaWZpZXJzKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfaXNSZWdFeHBPcHRpb246IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkgIT09ICd1cmwnICYmICQudHlwZSh2YWx1ZSkgPT09ICdzdHJpbmcnICYmXHJcbiAgICAgICAgICAgICAgICAvXlxcLy4qXFwvW2lnbV17MCwzfSQvLnRlc3QodmFsdWUpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIF9pbml0RGF0YUF0dHJpYnV0ZXM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxyXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcclxuICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLmVsZW1lbnQuZGF0YSgpO1xyXG4gICAgICAgICAgICAvLyBJbml0aWFsaXplIG9wdGlvbnMgc2V0IHZpYSBIVE1MNSBkYXRhLWF0dHJpYnV0ZXM6XHJcbiAgICAgICAgICAgICQuZWFjaChcclxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudFswXS5hdHRyaWJ1dGVzLFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKGluZGV4LCBhdHRyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IGF0dHIubmFtZS50b0xvd2VyQ2FzZSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoL15kYXRhLS8udGVzdChrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgaHlwaGVuLWF0ZWQga2V5IHRvIGNhbWVsQ2FzZTpcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5LnNsaWNlKDUpLnJlcGxhY2UoLy1bYS16XS9nLCBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyLmNoYXJBdCgxKS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBkYXRhW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Ll9pc1JlZ0V4cE9wdGlvbihrZXksIHZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGF0Ll9nZXRSZWdFeHAodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBfY3JlYXRlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2luaXREYXRhQXR0cmlidXRlcygpO1xyXG4gICAgICAgICAgICB0aGlzLl9pbml0U3BlY2lhbE9wdGlvbnMoKTtcclxuICAgICAgICAgICAgdGhpcy5fc2xvdHMgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5fc2VxdWVuY2UgPSB0aGlzLl9nZXRYSFJQcm9taXNlKHRydWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9zZW5kaW5nID0gdGhpcy5fYWN0aXZlID0gMDtcclxuICAgICAgICAgICAgdGhpcy5faW5pdFByb2dyZXNzT2JqZWN0KHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl9pbml0RXZlbnRIYW5kbGVycygpO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8vIFRoaXMgbWV0aG9kIGlzIGV4cG9zZWQgdG8gdGhlIHdpZGdldCBBUEkgYW5kIGFsbG93cyB0byBxdWVyeVxyXG4gICAgICAgIC8vIHRoZSBudW1iZXIgb2YgYWN0aXZlIHVwbG9hZHM6XHJcbiAgICAgICAgYWN0aXZlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gVGhpcyBtZXRob2QgaXMgZXhwb3NlZCB0byB0aGUgd2lkZ2V0IEFQSSBhbmQgYWxsb3dzIHRvIHF1ZXJ5XHJcbiAgICAgICAgLy8gdGhlIHdpZGdldCB1cGxvYWQgcHJvZ3Jlc3MuXHJcbiAgICAgICAgLy8gSXQgcmV0dXJucyBhbiBvYmplY3Qgd2l0aCBsb2FkZWQsIHRvdGFsIGFuZCBiaXRyYXRlIHByb3BlcnRpZXNcclxuICAgICAgICAvLyBmb3IgdGhlIHJ1bm5pbmcgdXBsb2FkczpcclxuICAgICAgICBwcm9ncmVzczogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvZ3Jlc3M7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gVGhpcyBtZXRob2QgaXMgZXhwb3NlZCB0byB0aGUgd2lkZ2V0IEFQSSBhbmQgYWxsb3dzIGFkZGluZyBmaWxlc1xyXG4gICAgICAgIC8vIHVzaW5nIHRoZSBmaWxldXBsb2FkIEFQSS4gVGhlIGRhdGEgcGFyYW1ldGVyIGFjY2VwdHMgYW4gb2JqZWN0IHdoaWNoXHJcbiAgICAgICAgLy8gbXVzdCBoYXZlIGEgZmlsZXMgcHJvcGVydHkgYW5kIGNhbiBjb250YWluIGFkZGl0aW9uYWwgb3B0aW9uczpcclxuICAgICAgICAvLyAuZmlsZXVwbG9hZCgnYWRkJywge2ZpbGVzOiBmaWxlc0xpc3R9KTtcclxuICAgICAgICBhZGQ6IGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKCFkYXRhIHx8IHRoaXMub3B0aW9ucy5kaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChkYXRhLmZpbGVJbnB1dCAmJiAhZGF0YS5maWxlcykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZ2V0RmlsZUlucHV0RmlsZXMoZGF0YS5maWxlSW5wdXQpLmFsd2F5cyhmdW5jdGlvbiAoZmlsZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLmZpbGVzID0gZmlsZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25BZGQobnVsbCwgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGRhdGEuZmlsZXMgPSAkLm1ha2VBcnJheShkYXRhLmZpbGVzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29uQWRkKG51bGwsIGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLy8gVGhpcyBtZXRob2QgaXMgZXhwb3NlZCB0byB0aGUgd2lkZ2V0IEFQSSBhbmQgYWxsb3dzIHNlbmRpbmcgZmlsZXNcclxuICAgICAgICAvLyB1c2luZyB0aGUgZmlsZXVwbG9hZCBBUEkuIFRoZSBkYXRhIHBhcmFtZXRlciBhY2NlcHRzIGFuIG9iamVjdCB3aGljaFxyXG4gICAgICAgIC8vIG11c3QgaGF2ZSBhIGZpbGVzIG9yIGZpbGVJbnB1dCBwcm9wZXJ0eSBhbmQgY2FuIGNvbnRhaW4gYWRkaXRpb25hbCBvcHRpb25zOlxyXG4gICAgICAgIC8vIC5maWxldXBsb2FkKCdzZW5kJywge2ZpbGVzOiBmaWxlc0xpc3R9KTtcclxuICAgICAgICAvLyBUaGUgbWV0aG9kIHJldHVybnMgYSBQcm9taXNlIG9iamVjdCBmb3IgdGhlIGZpbGUgdXBsb2FkIGNhbGwuXHJcbiAgICAgICAgc2VuZDogZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKGRhdGEgJiYgIXRoaXMub3B0aW9ucy5kaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuZmlsZUlucHV0ICYmICFkYXRhLmZpbGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZmQgPSAkLkRlZmVycmVkKCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2UgPSBkZmQucHJvbWlzZSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBqcVhIUixcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnRlZDtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpxWEhSKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ganFYSFIuYWJvcnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZmQucmVqZWN0KG51bGwsICdhYm9ydCcsICdhYm9ydCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2dldEZpbGVJbnB1dEZpbGVzKGRhdGEuZmlsZUlucHV0KS5hbHdheXMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChmaWxlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFib3J0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmZC5yZWplY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmZpbGVzID0gZmlsZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcVhIUiA9IHRoYXQuX29uU2VuZChudWxsLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpxWEhSLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHJlc3VsdCwgdGV4dFN0YXR1cywganFYSFIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUocmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmZC5yZWplY3QoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZW5oYW5jZVByb21pc2UocHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBkYXRhLmZpbGVzID0gJC5tYWtlQXJyYXkoZGF0YS5maWxlcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5maWxlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb25TZW5kKG51bGwsIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYSFJQcm9taXNlKGZhbHNlLCBkYXRhICYmIGRhdGEuY29udGV4dCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH0pO1xyXG5cclxufSkpO1xyXG4iLCIvKiEgalF1ZXJ5IFVJIC0gdjEuMTEuNCtDb21tb25KUyAtIDIwMTUtMDgtMjhcclxuKiBodHRwOi8vanF1ZXJ5dWkuY29tXHJcbiogSW5jbHVkZXM6IHdpZGdldC5qc1xyXG4qIENvcHlyaWdodCAyMDE1IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnM7IExpY2Vuc2VkIE1JVCAqL1xyXG5cclxuKGZ1bmN0aW9uKCBmYWN0b3J5ICkge1xyXG5cdGlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XHJcblxyXG5cdFx0Ly8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxyXG5cdFx0ZGVmaW5lKFsgXCJqcXVlcnlcIiBdLCBmYWN0b3J5ICk7XHJcblxyXG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiICkge1xyXG5cclxuXHRcdC8vIE5vZGUvQ29tbW9uSlNcclxuXHRcdGZhY3RvcnkoIHJlcXVpcmUoIFwianF1ZXJ5XCIgKSApO1xyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIEJyb3dzZXIgZ2xvYmFsc1xyXG5cdFx0ZmFjdG9yeSggalF1ZXJ5ICk7XHJcblx0fVxyXG59KGZ1bmN0aW9uKCAkICkge1xyXG4vKiFcclxuICogalF1ZXJ5IFVJIFdpZGdldCAxLjExLjRcclxuICogaHR0cDovL2pxdWVyeXVpLmNvbVxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xyXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXHJcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcclxuICpcclxuICogaHR0cDovL2FwaS5qcXVlcnl1aS5jb20valF1ZXJ5LndpZGdldC9cclxuICovXHJcblxyXG5cclxudmFyIHdpZGdldF91dWlkID0gMCxcclxuXHR3aWRnZXRfc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XHJcblxyXG4kLmNsZWFuRGF0YSA9IChmdW5jdGlvbiggb3JpZyApIHtcclxuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW1zICkge1xyXG5cdFx0dmFyIGV2ZW50cywgZWxlbSwgaTtcclxuXHRcdGZvciAoIGkgPSAwOyAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XHJcblx0XHRcdHRyeSB7XHJcblxyXG5cdFx0XHRcdC8vIE9ubHkgdHJpZ2dlciByZW1vdmUgd2hlbiBuZWNlc3NhcnkgdG8gc2F2ZSB0aW1lXHJcblx0XHRcdFx0ZXZlbnRzID0gJC5fZGF0YSggZWxlbSwgXCJldmVudHNcIiApO1xyXG5cdFx0XHRcdGlmICggZXZlbnRzICYmIGV2ZW50cy5yZW1vdmUgKSB7XHJcblx0XHRcdFx0XHQkKCBlbGVtICkudHJpZ2dlckhhbmRsZXIoIFwicmVtb3ZlXCIgKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBodHRwOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC84MjM1XHJcblx0XHRcdH0gY2F0Y2ggKCBlICkge31cclxuXHRcdH1cclxuXHRcdG9yaWcoIGVsZW1zICk7XHJcblx0fTtcclxufSkoICQuY2xlYW5EYXRhICk7XHJcblxyXG4kLndpZGdldCA9IGZ1bmN0aW9uKCBuYW1lLCBiYXNlLCBwcm90b3R5cGUgKSB7XHJcblx0dmFyIGZ1bGxOYW1lLCBleGlzdGluZ0NvbnN0cnVjdG9yLCBjb25zdHJ1Y3RvciwgYmFzZVByb3RvdHlwZSxcclxuXHRcdC8vIHByb3hpZWRQcm90b3R5cGUgYWxsb3dzIHRoZSBwcm92aWRlZCBwcm90b3R5cGUgdG8gcmVtYWluIHVubW9kaWZpZWRcclxuXHRcdC8vIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgYXMgYSBtaXhpbiBmb3IgbXVsdGlwbGUgd2lkZ2V0cyAoIzg4NzYpXHJcblx0XHRwcm94aWVkUHJvdG90eXBlID0ge30sXHJcblx0XHRuYW1lc3BhY2UgPSBuYW1lLnNwbGl0KCBcIi5cIiApWyAwIF07XHJcblxyXG5cdG5hbWUgPSBuYW1lLnNwbGl0KCBcIi5cIiApWyAxIF07XHJcblx0ZnVsbE5hbWUgPSBuYW1lc3BhY2UgKyBcIi1cIiArIG5hbWU7XHJcblxyXG5cdGlmICggIXByb3RvdHlwZSApIHtcclxuXHRcdHByb3RvdHlwZSA9IGJhc2U7XHJcblx0XHRiYXNlID0gJC5XaWRnZXQ7XHJcblx0fVxyXG5cclxuXHQvLyBjcmVhdGUgc2VsZWN0b3IgZm9yIHBsdWdpblxyXG5cdCQuZXhwclsgXCI6XCIgXVsgZnVsbE5hbWUudG9Mb3dlckNhc2UoKSBdID0gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gISEkLmRhdGEoIGVsZW0sIGZ1bGxOYW1lICk7XHJcblx0fTtcclxuXHJcblx0JFsgbmFtZXNwYWNlIF0gPSAkWyBuYW1lc3BhY2UgXSB8fCB7fTtcclxuXHRleGlzdGluZ0NvbnN0cnVjdG9yID0gJFsgbmFtZXNwYWNlIF1bIG5hbWUgXTtcclxuXHRjb25zdHJ1Y3RvciA9ICRbIG5hbWVzcGFjZSBdWyBuYW1lIF0gPSBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHtcclxuXHRcdC8vIGFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCBcIm5ld1wiIGtleXdvcmRcclxuXHRcdGlmICggIXRoaXMuX2NyZWF0ZVdpZGdldCApIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBjb25zdHJ1Y3Rvciggb3B0aW9ucywgZWxlbWVudCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCBpbml0aWFsaXppbmcgZm9yIHNpbXBsZSBpbmhlcml0YW5jZVxyXG5cdFx0Ly8gbXVzdCB1c2UgXCJuZXdcIiBrZXl3b3JkICh0aGUgY29kZSBhYm92ZSBhbHdheXMgcGFzc2VzIGFyZ3MpXHJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XHJcblx0XHRcdHRoaXMuX2NyZWF0ZVdpZGdldCggb3B0aW9ucywgZWxlbWVudCApO1xyXG5cdFx0fVxyXG5cdH07XHJcblx0Ly8gZXh0ZW5kIHdpdGggdGhlIGV4aXN0aW5nIGNvbnN0cnVjdG9yIHRvIGNhcnJ5IG92ZXIgYW55IHN0YXRpYyBwcm9wZXJ0aWVzXHJcblx0JC5leHRlbmQoIGNvbnN0cnVjdG9yLCBleGlzdGluZ0NvbnN0cnVjdG9yLCB7XHJcblx0XHR2ZXJzaW9uOiBwcm90b3R5cGUudmVyc2lvbixcclxuXHRcdC8vIGNvcHkgdGhlIG9iamVjdCB1c2VkIHRvIGNyZWF0ZSB0aGUgcHJvdG90eXBlIGluIGNhc2Ugd2UgbmVlZCB0b1xyXG5cdFx0Ly8gcmVkZWZpbmUgdGhlIHdpZGdldCBsYXRlclxyXG5cdFx0X3Byb3RvOiAkLmV4dGVuZCgge30sIHByb3RvdHlwZSApLFxyXG5cdFx0Ly8gdHJhY2sgd2lkZ2V0cyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIHdpZGdldCBpbiBjYXNlIHRoaXMgd2lkZ2V0IGlzXHJcblx0XHQvLyByZWRlZmluZWQgYWZ0ZXIgYSB3aWRnZXQgaW5oZXJpdHMgZnJvbSBpdFxyXG5cdFx0X2NoaWxkQ29uc3RydWN0b3JzOiBbXVxyXG5cdH0pO1xyXG5cclxuXHRiYXNlUHJvdG90eXBlID0gbmV3IGJhc2UoKTtcclxuXHQvLyB3ZSBuZWVkIHRvIG1ha2UgdGhlIG9wdGlvbnMgaGFzaCBhIHByb3BlcnR5IGRpcmVjdGx5IG9uIHRoZSBuZXcgaW5zdGFuY2VcclxuXHQvLyBvdGhlcndpc2Ugd2UnbGwgbW9kaWZ5IHRoZSBvcHRpb25zIGhhc2ggb24gdGhlIHByb3RvdHlwZSB0aGF0IHdlJ3JlXHJcblx0Ly8gaW5oZXJpdGluZyBmcm9tXHJcblx0YmFzZVByb3RvdHlwZS5vcHRpb25zID0gJC53aWRnZXQuZXh0ZW5kKCB7fSwgYmFzZVByb3RvdHlwZS5vcHRpb25zICk7XHJcblx0JC5lYWNoKCBwcm90b3R5cGUsIGZ1bmN0aW9uKCBwcm9wLCB2YWx1ZSApIHtcclxuXHRcdGlmICggISQuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcclxuXHRcdFx0cHJveGllZFByb3RvdHlwZVsgcHJvcCBdID0gdmFsdWU7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9IChmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIF9zdXBlciA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGJhc2UucHJvdG90eXBlWyBwcm9wIF0uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0X3N1cGVyQXBwbHkgPSBmdW5jdGlvbiggYXJncyApIHtcclxuXHRcdFx0XHRcdHJldHVybiBiYXNlLnByb3RvdHlwZVsgcHJvcCBdLmFwcGx5KCB0aGlzLCBhcmdzICk7XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBfX3N1cGVyID0gdGhpcy5fc3VwZXIsXHJcblx0XHRcdFx0XHRfX3N1cGVyQXBwbHkgPSB0aGlzLl9zdXBlckFwcGx5LFxyXG5cdFx0XHRcdFx0cmV0dXJuVmFsdWU7XHJcblxyXG5cdFx0XHRcdHRoaXMuX3N1cGVyID0gX3N1cGVyO1xyXG5cdFx0XHRcdHRoaXMuX3N1cGVyQXBwbHkgPSBfc3VwZXJBcHBseTtcclxuXHJcblx0XHRcdFx0cmV0dXJuVmFsdWUgPSB2YWx1ZS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XHJcblxyXG5cdFx0XHRcdHRoaXMuX3N1cGVyID0gX19zdXBlcjtcclxuXHRcdFx0XHR0aGlzLl9zdXBlckFwcGx5ID0gX19zdXBlckFwcGx5O1xyXG5cclxuXHRcdFx0XHRyZXR1cm4gcmV0dXJuVmFsdWU7XHJcblx0XHRcdH07XHJcblx0XHR9KSgpO1xyXG5cdH0pO1xyXG5cdGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9ICQud2lkZ2V0LmV4dGVuZCggYmFzZVByb3RvdHlwZSwge1xyXG5cdFx0Ly8gVE9ETzogcmVtb3ZlIHN1cHBvcnQgZm9yIHdpZGdldEV2ZW50UHJlZml4XHJcblx0XHQvLyBhbHdheXMgdXNlIHRoZSBuYW1lICsgYSBjb2xvbiBhcyB0aGUgcHJlZml4LCBlLmcuLCBkcmFnZ2FibGU6c3RhcnRcclxuXHRcdC8vIGRvbid0IHByZWZpeCBmb3Igd2lkZ2V0cyB0aGF0IGFyZW4ndCBET00tYmFzZWRcclxuXHRcdHdpZGdldEV2ZW50UHJlZml4OiBleGlzdGluZ0NvbnN0cnVjdG9yID8gKGJhc2VQcm90b3R5cGUud2lkZ2V0RXZlbnRQcmVmaXggfHwgbmFtZSkgOiBuYW1lXHJcblx0fSwgcHJveGllZFByb3RvdHlwZSwge1xyXG5cdFx0Y29uc3RydWN0b3I6IGNvbnN0cnVjdG9yLFxyXG5cdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2UsXHJcblx0XHR3aWRnZXROYW1lOiBuYW1lLFxyXG5cdFx0d2lkZ2V0RnVsbE5hbWU6IGZ1bGxOYW1lXHJcblx0fSk7XHJcblxyXG5cdC8vIElmIHRoaXMgd2lkZ2V0IGlzIGJlaW5nIHJlZGVmaW5lZCB0aGVuIHdlIG5lZWQgdG8gZmluZCBhbGwgd2lkZ2V0cyB0aGF0XHJcblx0Ly8gYXJlIGluaGVyaXRpbmcgZnJvbSBpdCBhbmQgcmVkZWZpbmUgYWxsIG9mIHRoZW0gc28gdGhhdCB0aGV5IGluaGVyaXQgZnJvbVxyXG5cdC8vIHRoZSBuZXcgdmVyc2lvbiBvZiB0aGlzIHdpZGdldC4gV2UncmUgZXNzZW50aWFsbHkgdHJ5aW5nIHRvIHJlcGxhY2Ugb25lXHJcblx0Ly8gbGV2ZWwgaW4gdGhlIHByb3RvdHlwZSBjaGFpbi5cclxuXHRpZiAoIGV4aXN0aW5nQ29uc3RydWN0b3IgKSB7XHJcblx0XHQkLmVhY2goIGV4aXN0aW5nQ29uc3RydWN0b3IuX2NoaWxkQ29uc3RydWN0b3JzLCBmdW5jdGlvbiggaSwgY2hpbGQgKSB7XHJcblx0XHRcdHZhciBjaGlsZFByb3RvdHlwZSA9IGNoaWxkLnByb3RvdHlwZTtcclxuXHJcblx0XHRcdC8vIHJlZGVmaW5lIHRoZSBjaGlsZCB3aWRnZXQgdXNpbmcgdGhlIHNhbWUgcHJvdG90eXBlIHRoYXQgd2FzXHJcblx0XHRcdC8vIG9yaWdpbmFsbHkgdXNlZCwgYnV0IGluaGVyaXQgZnJvbSB0aGUgbmV3IHZlcnNpb24gb2YgdGhlIGJhc2VcclxuXHRcdFx0JC53aWRnZXQoIGNoaWxkUHJvdG90eXBlLm5hbWVzcGFjZSArIFwiLlwiICsgY2hpbGRQcm90b3R5cGUud2lkZ2V0TmFtZSwgY29uc3RydWN0b3IsIGNoaWxkLl9wcm90byApO1xyXG5cdFx0fSk7XHJcblx0XHQvLyByZW1vdmUgdGhlIGxpc3Qgb2YgZXhpc3RpbmcgY2hpbGQgY29uc3RydWN0b3JzIGZyb20gdGhlIG9sZCBjb25zdHJ1Y3RvclxyXG5cdFx0Ly8gc28gdGhlIG9sZCBjaGlsZCBjb25zdHJ1Y3RvcnMgY2FuIGJlIGdhcmJhZ2UgY29sbGVjdGVkXHJcblx0XHRkZWxldGUgZXhpc3RpbmdDb25zdHJ1Y3Rvci5fY2hpbGRDb25zdHJ1Y3RvcnM7XHJcblx0fSBlbHNlIHtcclxuXHRcdGJhc2UuX2NoaWxkQ29uc3RydWN0b3JzLnB1c2goIGNvbnN0cnVjdG9yICk7XHJcblx0fVxyXG5cclxuXHQkLndpZGdldC5icmlkZ2UoIG5hbWUsIGNvbnN0cnVjdG9yICk7XHJcblxyXG5cdHJldHVybiBjb25zdHJ1Y3RvcjtcclxufTtcclxuXHJcbiQud2lkZ2V0LmV4dGVuZCA9IGZ1bmN0aW9uKCB0YXJnZXQgKSB7XHJcblx0dmFyIGlucHV0ID0gd2lkZ2V0X3NsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApLFxyXG5cdFx0aW5wdXRJbmRleCA9IDAsXHJcblx0XHRpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCxcclxuXHRcdGtleSxcclxuXHRcdHZhbHVlO1xyXG5cdGZvciAoIDsgaW5wdXRJbmRleCA8IGlucHV0TGVuZ3RoOyBpbnB1dEluZGV4KysgKSB7XHJcblx0XHRmb3IgKCBrZXkgaW4gaW5wdXRbIGlucHV0SW5kZXggXSApIHtcclxuXHRcdFx0dmFsdWUgPSBpbnB1dFsgaW5wdXRJbmRleCBdWyBrZXkgXTtcclxuXHRcdFx0aWYgKCBpbnB1dFsgaW5wdXRJbmRleCBdLmhhc093blByb3BlcnR5KCBrZXkgKSAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdC8vIENsb25lIG9iamVjdHNcclxuXHRcdFx0XHRpZiAoICQuaXNQbGFpbk9iamVjdCggdmFsdWUgKSApIHtcclxuXHRcdFx0XHRcdHRhcmdldFsga2V5IF0gPSAkLmlzUGxhaW5PYmplY3QoIHRhcmdldFsga2V5IF0gKSA/XHJcblx0XHRcdFx0XHRcdCQud2lkZ2V0LmV4dGVuZCgge30sIHRhcmdldFsga2V5IF0sIHZhbHVlICkgOlxyXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBleHRlbmQgc3RyaW5ncywgYXJyYXlzLCBldGMuIHdpdGggb2JqZWN0c1xyXG5cdFx0XHRcdFx0XHQkLndpZGdldC5leHRlbmQoIHt9LCB2YWx1ZSApO1xyXG5cdFx0XHRcdC8vIENvcHkgZXZlcnl0aGluZyBlbHNlIGJ5IHJlZmVyZW5jZVxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0YXJnZXRbIGtleSBdID0gdmFsdWU7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiB0YXJnZXQ7XHJcbn07XHJcblxyXG4kLndpZGdldC5icmlkZ2UgPSBmdW5jdGlvbiggbmFtZSwgb2JqZWN0ICkge1xyXG5cdHZhciBmdWxsTmFtZSA9IG9iamVjdC5wcm90b3R5cGUud2lkZ2V0RnVsbE5hbWUgfHwgbmFtZTtcclxuXHQkLmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcclxuXHRcdHZhciBpc01ldGhvZENhbGwgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIixcclxuXHRcdFx0YXJncyA9IHdpZGdldF9zbGljZS5jYWxsKCBhcmd1bWVudHMsIDEgKSxcclxuXHRcdFx0cmV0dXJuVmFsdWUgPSB0aGlzO1xyXG5cclxuXHRcdGlmICggaXNNZXRob2RDYWxsICkge1xyXG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0dmFyIG1ldGhvZFZhbHVlLFxyXG5cdFx0XHRcdFx0aW5zdGFuY2UgPSAkLmRhdGEoIHRoaXMsIGZ1bGxOYW1lICk7XHJcblx0XHRcdFx0aWYgKCBvcHRpb25zID09PSBcImluc3RhbmNlXCIgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IGluc3RhbmNlO1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoICFpbnN0YW5jZSApIHtcclxuXHRcdFx0XHRcdHJldHVybiAkLmVycm9yKCBcImNhbm5vdCBjYWxsIG1ldGhvZHMgb24gXCIgKyBuYW1lICsgXCIgcHJpb3IgdG8gaW5pdGlhbGl6YXRpb247IFwiICtcclxuXHRcdFx0XHRcdFx0XCJhdHRlbXB0ZWQgdG8gY2FsbCBtZXRob2QgJ1wiICsgb3B0aW9ucyArIFwiJ1wiICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggISQuaXNGdW5jdGlvbiggaW5zdGFuY2Vbb3B0aW9uc10gKSB8fCBvcHRpb25zLmNoYXJBdCggMCApID09PSBcIl9cIiApIHtcclxuXHRcdFx0XHRcdHJldHVybiAkLmVycm9yKCBcIm5vIHN1Y2ggbWV0aG9kICdcIiArIG9wdGlvbnMgKyBcIicgZm9yIFwiICsgbmFtZSArIFwiIHdpZGdldCBpbnN0YW5jZVwiICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG1ldGhvZFZhbHVlID0gaW5zdGFuY2VbIG9wdGlvbnMgXS5hcHBseSggaW5zdGFuY2UsIGFyZ3MgKTtcclxuXHRcdFx0XHRpZiAoIG1ldGhvZFZhbHVlICE9PSBpbnN0YW5jZSAmJiBtZXRob2RWYWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSBtZXRob2RWYWx1ZSAmJiBtZXRob2RWYWx1ZS5qcXVlcnkgP1xyXG5cdFx0XHRcdFx0XHRyZXR1cm5WYWx1ZS5wdXNoU3RhY2soIG1ldGhvZFZhbHVlLmdldCgpICkgOlxyXG5cdFx0XHRcdFx0XHRtZXRob2RWYWx1ZTtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIEFsbG93IG11bHRpcGxlIGhhc2hlcyB0byBiZSBwYXNzZWQgb24gaW5pdFxyXG5cdFx0XHRpZiAoIGFyZ3MubGVuZ3RoICkge1xyXG5cdFx0XHRcdG9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQuYXBwbHkoIG51bGwsIFsgb3B0aW9ucyBdLmNvbmNhdChhcmdzKSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0dmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApO1xyXG5cdFx0XHRcdGlmICggaW5zdGFuY2UgKSB7XHJcblx0XHRcdFx0XHRpbnN0YW5jZS5vcHRpb24oIG9wdGlvbnMgfHwge30gKTtcclxuXHRcdFx0XHRcdGlmICggaW5zdGFuY2UuX2luaXQgKSB7XHJcblx0XHRcdFx0XHRcdGluc3RhbmNlLl9pbml0KCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdCQuZGF0YSggdGhpcywgZnVsbE5hbWUsIG5ldyBvYmplY3QoIG9wdGlvbnMsIHRoaXMgKSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJldHVyblZhbHVlO1xyXG5cdH07XHJcbn07XHJcblxyXG4kLldpZGdldCA9IGZ1bmN0aW9uKCAvKiBvcHRpb25zLCBlbGVtZW50ICovICkge307XHJcbiQuV2lkZ2V0Ll9jaGlsZENvbnN0cnVjdG9ycyA9IFtdO1xyXG5cclxuJC5XaWRnZXQucHJvdG90eXBlID0ge1xyXG5cdHdpZGdldE5hbWU6IFwid2lkZ2V0XCIsXHJcblx0d2lkZ2V0RXZlbnRQcmVmaXg6IFwiXCIsXHJcblx0ZGVmYXVsdEVsZW1lbnQ6IFwiPGRpdj5cIixcclxuXHRvcHRpb25zOiB7XHJcblx0XHRkaXNhYmxlZDogZmFsc2UsXHJcblxyXG5cdFx0Ly8gY2FsbGJhY2tzXHJcblx0XHRjcmVhdGU6IG51bGxcclxuXHR9LFxyXG5cdF9jcmVhdGVXaWRnZXQ6IGZ1bmN0aW9uKCBvcHRpb25zLCBlbGVtZW50ICkge1xyXG5cdFx0ZWxlbWVudCA9ICQoIGVsZW1lbnQgfHwgdGhpcy5kZWZhdWx0RWxlbWVudCB8fCB0aGlzIClbIDAgXTtcclxuXHRcdHRoaXMuZWxlbWVudCA9ICQoIGVsZW1lbnQgKTtcclxuXHRcdHRoaXMudXVpZCA9IHdpZGdldF91dWlkKys7XHJcblx0XHR0aGlzLmV2ZW50TmFtZXNwYWNlID0gXCIuXCIgKyB0aGlzLndpZGdldE5hbWUgKyB0aGlzLnV1aWQ7XHJcblxyXG5cdFx0dGhpcy5iaW5kaW5ncyA9ICQoKTtcclxuXHRcdHRoaXMuaG92ZXJhYmxlID0gJCgpO1xyXG5cdFx0dGhpcy5mb2N1c2FibGUgPSAkKCk7XHJcblxyXG5cdFx0aWYgKCBlbGVtZW50ICE9PSB0aGlzICkge1xyXG5cdFx0XHQkLmRhdGEoIGVsZW1lbnQsIHRoaXMud2lkZ2V0RnVsbE5hbWUsIHRoaXMgKTtcclxuXHRcdFx0dGhpcy5fb24oIHRydWUsIHRoaXMuZWxlbWVudCwge1xyXG5cdFx0XHRcdHJlbW92ZTogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRcdFx0aWYgKCBldmVudC50YXJnZXQgPT09IGVsZW1lbnQgKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGVzdHJveSgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHRcdHRoaXMuZG9jdW1lbnQgPSAkKCBlbGVtZW50LnN0eWxlID9cclxuXHRcdFx0XHQvLyBlbGVtZW50IHdpdGhpbiB0aGUgZG9jdW1lbnRcclxuXHRcdFx0XHRlbGVtZW50Lm93bmVyRG9jdW1lbnQgOlxyXG5cdFx0XHRcdC8vIGVsZW1lbnQgaXMgd2luZG93IG9yIGRvY3VtZW50XHJcblx0XHRcdFx0ZWxlbWVudC5kb2N1bWVudCB8fCBlbGVtZW50ICk7XHJcblx0XHRcdHRoaXMud2luZG93ID0gJCggdGhpcy5kb2N1bWVudFswXS5kZWZhdWx0VmlldyB8fCB0aGlzLmRvY3VtZW50WzBdLnBhcmVudFdpbmRvdyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMub3B0aW9ucyA9ICQud2lkZ2V0LmV4dGVuZCgge30sXHJcblx0XHRcdHRoaXMub3B0aW9ucyxcclxuXHRcdFx0dGhpcy5fZ2V0Q3JlYXRlT3B0aW9ucygpLFxyXG5cdFx0XHRvcHRpb25zICk7XHJcblxyXG5cdFx0dGhpcy5fY3JlYXRlKCk7XHJcblx0XHR0aGlzLl90cmlnZ2VyKCBcImNyZWF0ZVwiLCBudWxsLCB0aGlzLl9nZXRDcmVhdGVFdmVudERhdGEoKSApO1xyXG5cdFx0dGhpcy5faW5pdCgpO1xyXG5cdH0sXHJcblx0X2dldENyZWF0ZU9wdGlvbnM6ICQubm9vcCxcclxuXHRfZ2V0Q3JlYXRlRXZlbnREYXRhOiAkLm5vb3AsXHJcblx0X2NyZWF0ZTogJC5ub29wLFxyXG5cdF9pbml0OiAkLm5vb3AsXHJcblxyXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5fZGVzdHJveSgpO1xyXG5cdFx0Ly8gd2UgY2FuIHByb2JhYmx5IHJlbW92ZSB0aGUgdW5iaW5kIGNhbGxzIGluIDIuMFxyXG5cdFx0Ly8gYWxsIGV2ZW50IGJpbmRpbmdzIHNob3VsZCBnbyB0aHJvdWdoIHRoaXMuX29uKClcclxuXHRcdHRoaXMuZWxlbWVudFxyXG5cdFx0XHQudW5iaW5kKCB0aGlzLmV2ZW50TmFtZXNwYWNlIClcclxuXHRcdFx0LnJlbW92ZURhdGEoIHRoaXMud2lkZ2V0RnVsbE5hbWUgKVxyXG5cdFx0XHQvLyBzdXBwb3J0OiBqcXVlcnkgPDEuNi4zXHJcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0Lzk0MTNcclxuXHRcdFx0LnJlbW92ZURhdGEoICQuY2FtZWxDYXNlKCB0aGlzLndpZGdldEZ1bGxOYW1lICkgKTtcclxuXHRcdHRoaXMud2lkZ2V0KClcclxuXHRcdFx0LnVuYmluZCggdGhpcy5ldmVudE5hbWVzcGFjZSApXHJcblx0XHRcdC5yZW1vdmVBdHRyKCBcImFyaWEtZGlzYWJsZWRcIiApXHJcblx0XHRcdC5yZW1vdmVDbGFzcyhcclxuXHRcdFx0XHR0aGlzLndpZGdldEZ1bGxOYW1lICsgXCItZGlzYWJsZWQgXCIgK1xyXG5cdFx0XHRcdFwidWktc3RhdGUtZGlzYWJsZWRcIiApO1xyXG5cclxuXHRcdC8vIGNsZWFuIHVwIGV2ZW50cyBhbmQgc3RhdGVzXHJcblx0XHR0aGlzLmJpbmRpbmdzLnVuYmluZCggdGhpcy5ldmVudE5hbWVzcGFjZSApO1xyXG5cdFx0dGhpcy5ob3ZlcmFibGUucmVtb3ZlQ2xhc3MoIFwidWktc3RhdGUtaG92ZXJcIiApO1xyXG5cdFx0dGhpcy5mb2N1c2FibGUucmVtb3ZlQ2xhc3MoIFwidWktc3RhdGUtZm9jdXNcIiApO1xyXG5cdH0sXHJcblx0X2Rlc3Ryb3k6ICQubm9vcCxcclxuXHJcblx0d2lkZ2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmVsZW1lbnQ7XHJcblx0fSxcclxuXHJcblx0b3B0aW9uOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcclxuXHRcdHZhciBvcHRpb25zID0ga2V5LFxyXG5cdFx0XHRwYXJ0cyxcclxuXHRcdFx0Y3VyT3B0aW9uLFxyXG5cdFx0XHRpO1xyXG5cclxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA9PT0gMCApIHtcclxuXHRcdFx0Ly8gZG9uJ3QgcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSBpbnRlcm5hbCBoYXNoXHJcblx0XHRcdHJldHVybiAkLndpZGdldC5leHRlbmQoIHt9LCB0aGlzLm9wdGlvbnMgKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdC8vIGhhbmRsZSBuZXN0ZWQga2V5cywgZS5nLiwgXCJmb28uYmFyXCIgPT4geyBmb286IHsgYmFyOiBfX18gfSB9XHJcblx0XHRcdG9wdGlvbnMgPSB7fTtcclxuXHRcdFx0cGFydHMgPSBrZXkuc3BsaXQoIFwiLlwiICk7XHJcblx0XHRcdGtleSA9IHBhcnRzLnNoaWZ0KCk7XHJcblx0XHRcdGlmICggcGFydHMubGVuZ3RoICkge1xyXG5cdFx0XHRcdGN1ck9wdGlvbiA9IG9wdGlvbnNbIGtleSBdID0gJC53aWRnZXQuZXh0ZW5kKCB7fSwgdGhpcy5vcHRpb25zWyBrZXkgXSApO1xyXG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrICkge1xyXG5cdFx0XHRcdFx0Y3VyT3B0aW9uWyBwYXJ0c1sgaSBdIF0gPSBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXSB8fCB7fTtcclxuXHRcdFx0XHRcdGN1ck9wdGlvbiA9IGN1ck9wdGlvblsgcGFydHNbIGkgXSBdO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRrZXkgPSBwYXJ0cy5wb3AoKTtcclxuXHRcdFx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gY3VyT3B0aW9uWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGN1ck9wdGlvblsga2V5IF07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGN1ck9wdGlvblsga2V5IF0gPSB2YWx1ZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcHRpb25zWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHRoaXMub3B0aW9uc1sga2V5IF07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG9wdGlvbnNbIGtleSBdID0gdmFsdWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLl9zZXRPcHRpb25zKCBvcHRpb25zICk7XHJcblxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fSxcclxuXHRfc2V0T3B0aW9uczogZnVuY3Rpb24oIG9wdGlvbnMgKSB7XHJcblx0XHR2YXIga2V5O1xyXG5cclxuXHRcdGZvciAoIGtleSBpbiBvcHRpb25zICkge1xyXG5cdFx0XHR0aGlzLl9zZXRPcHRpb24oIGtleSwgb3B0aW9uc1sga2V5IF0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9LFxyXG5cdF9zZXRPcHRpb246IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xyXG5cdFx0dGhpcy5vcHRpb25zWyBrZXkgXSA9IHZhbHVlO1xyXG5cclxuXHRcdGlmICgga2V5ID09PSBcImRpc2FibGVkXCIgKSB7XHJcblx0XHRcdHRoaXMud2lkZ2V0KClcclxuXHRcdFx0XHQudG9nZ2xlQ2xhc3MoIHRoaXMud2lkZ2V0RnVsbE5hbWUgKyBcIi1kaXNhYmxlZFwiLCAhIXZhbHVlICk7XHJcblxyXG5cdFx0XHQvLyBJZiB0aGUgd2lkZ2V0IGlzIGJlY29taW5nIGRpc2FibGVkLCB0aGVuIG5vdGhpbmcgaXMgaW50ZXJhY3RpdmVcclxuXHRcdFx0aWYgKCB2YWx1ZSApIHtcclxuXHRcdFx0XHR0aGlzLmhvdmVyYWJsZS5yZW1vdmVDbGFzcyggXCJ1aS1zdGF0ZS1ob3ZlclwiICk7XHJcblx0XHRcdFx0dGhpcy5mb2N1c2FibGUucmVtb3ZlQ2xhc3MoIFwidWktc3RhdGUtZm9jdXNcIiApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fSxcclxuXHJcblx0ZW5hYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLl9zZXRPcHRpb25zKHsgZGlzYWJsZWQ6IGZhbHNlIH0pO1xyXG5cdH0sXHJcblx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fc2V0T3B0aW9ucyh7IGRpc2FibGVkOiB0cnVlIH0pO1xyXG5cdH0sXHJcblxyXG5cdF9vbjogZnVuY3Rpb24oIHN1cHByZXNzRGlzYWJsZWRDaGVjaywgZWxlbWVudCwgaGFuZGxlcnMgKSB7XHJcblx0XHR2YXIgZGVsZWdhdGVFbGVtZW50LFxyXG5cdFx0XHRpbnN0YW5jZSA9IHRoaXM7XHJcblxyXG5cdFx0Ly8gbm8gc3VwcHJlc3NEaXNhYmxlZENoZWNrIGZsYWcsIHNodWZmbGUgYXJndW1lbnRzXHJcblx0XHRpZiAoIHR5cGVvZiBzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgIT09IFwiYm9vbGVhblwiICkge1xyXG5cdFx0XHRoYW5kbGVycyA9IGVsZW1lbnQ7XHJcblx0XHRcdGVsZW1lbnQgPSBzdXBwcmVzc0Rpc2FibGVkQ2hlY2s7XHJcblx0XHRcdHN1cHByZXNzRGlzYWJsZWRDaGVjayA9IGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIG5vIGVsZW1lbnQgYXJndW1lbnQsIHNodWZmbGUgYW5kIHVzZSB0aGlzLmVsZW1lbnRcclxuXHRcdGlmICggIWhhbmRsZXJzICkge1xyXG5cdFx0XHRoYW5kbGVycyA9IGVsZW1lbnQ7XHJcblx0XHRcdGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XHJcblx0XHRcdGRlbGVnYXRlRWxlbWVudCA9IHRoaXMud2lkZ2V0KCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRlbGVtZW50ID0gZGVsZWdhdGVFbGVtZW50ID0gJCggZWxlbWVudCApO1xyXG5cdFx0XHR0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5hZGQoIGVsZW1lbnQgKTtcclxuXHRcdH1cclxuXHJcblx0XHQkLmVhY2goIGhhbmRsZXJzLCBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXIgKSB7XHJcblx0XHRcdGZ1bmN0aW9uIGhhbmRsZXJQcm94eSgpIHtcclxuXHRcdFx0XHQvLyBhbGxvdyB3aWRnZXRzIHRvIGN1c3RvbWl6ZSB0aGUgZGlzYWJsZWQgaGFuZGxpbmdcclxuXHRcdFx0XHQvLyAtIGRpc2FibGVkIGFzIGFuIGFycmF5IGluc3RlYWQgb2YgYm9vbGVhblxyXG5cdFx0XHRcdC8vIC0gZGlzYWJsZWQgY2xhc3MgYXMgbWV0aG9kIGZvciBkaXNhYmxpbmcgaW5kaXZpZHVhbCBwYXJ0c1xyXG5cdFx0XHRcdGlmICggIXN1cHByZXNzRGlzYWJsZWRDaGVjayAmJlxyXG5cdFx0XHRcdFx0XHQoIGluc3RhbmNlLm9wdGlvbnMuZGlzYWJsZWQgPT09IHRydWUgfHxcclxuXHRcdFx0XHRcdFx0XHQkKCB0aGlzICkuaGFzQ2xhc3MoIFwidWktc3RhdGUtZGlzYWJsZWRcIiApICkgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiAoIHR5cGVvZiBoYW5kbGVyID09PSBcInN0cmluZ1wiID8gaW5zdGFuY2VbIGhhbmRsZXIgXSA6IGhhbmRsZXIgKVxyXG5cdFx0XHRcdFx0LmFwcGx5KCBpbnN0YW5jZSwgYXJndW1lbnRzICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIGNvcHkgdGhlIGd1aWQgc28gZGlyZWN0IHVuYmluZGluZyB3b3Jrc1xyXG5cdFx0XHRpZiAoIHR5cGVvZiBoYW5kbGVyICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRcdGhhbmRsZXJQcm94eS5ndWlkID0gaGFuZGxlci5ndWlkID1cclxuXHRcdFx0XHRcdGhhbmRsZXIuZ3VpZCB8fCBoYW5kbGVyUHJveHkuZ3VpZCB8fCAkLmd1aWQrKztcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIG1hdGNoID0gZXZlbnQubWF0Y2goIC9eKFtcXHc6LV0qKVxccyooLiopJC8gKSxcclxuXHRcdFx0XHRldmVudE5hbWUgPSBtYXRjaFsxXSArIGluc3RhbmNlLmV2ZW50TmFtZXNwYWNlLFxyXG5cdFx0XHRcdHNlbGVjdG9yID0gbWF0Y2hbMl07XHJcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XHJcblx0XHRcdFx0ZGVsZWdhdGVFbGVtZW50LmRlbGVnYXRlKCBzZWxlY3RvciwgZXZlbnROYW1lLCBoYW5kbGVyUHJveHkgKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRlbGVtZW50LmJpbmQoIGV2ZW50TmFtZSwgaGFuZGxlclByb3h5ICk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdF9vZmY6IGZ1bmN0aW9uKCBlbGVtZW50LCBldmVudE5hbWUgKSB7XHJcblx0XHRldmVudE5hbWUgPSAoZXZlbnROYW1lIHx8IFwiXCIpLnNwbGl0KCBcIiBcIiApLmpvaW4oIHRoaXMuZXZlbnROYW1lc3BhY2UgKyBcIiBcIiApICtcclxuXHRcdFx0dGhpcy5ldmVudE5hbWVzcGFjZTtcclxuXHRcdGVsZW1lbnQudW5iaW5kKCBldmVudE5hbWUgKS51bmRlbGVnYXRlKCBldmVudE5hbWUgKTtcclxuXHJcblx0XHQvLyBDbGVhciB0aGUgc3RhY2sgdG8gYXZvaWQgbWVtb3J5IGxlYWtzICgjMTAwNTYpXHJcblx0XHR0aGlzLmJpbmRpbmdzID0gJCggdGhpcy5iaW5kaW5ncy5ub3QoIGVsZW1lbnQgKS5nZXQoKSApO1xyXG5cdFx0dGhpcy5mb2N1c2FibGUgPSAkKCB0aGlzLmZvY3VzYWJsZS5ub3QoIGVsZW1lbnQgKS5nZXQoKSApO1xyXG5cdFx0dGhpcy5ob3ZlcmFibGUgPSAkKCB0aGlzLmhvdmVyYWJsZS5ub3QoIGVsZW1lbnQgKS5nZXQoKSApO1xyXG5cdH0sXHJcblxyXG5cdF9kZWxheTogZnVuY3Rpb24oIGhhbmRsZXIsIGRlbGF5ICkge1xyXG5cdFx0ZnVuY3Rpb24gaGFuZGxlclByb3h5KCkge1xyXG5cdFx0XHRyZXR1cm4gKCB0eXBlb2YgaGFuZGxlciA9PT0gXCJzdHJpbmdcIiA/IGluc3RhbmNlWyBoYW5kbGVyIF0gOiBoYW5kbGVyIClcclxuXHRcdFx0XHQuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTtcclxuXHRcdH1cclxuXHRcdHZhciBpbnN0YW5jZSA9IHRoaXM7XHJcblx0XHRyZXR1cm4gc2V0VGltZW91dCggaGFuZGxlclByb3h5LCBkZWxheSB8fCAwICk7XHJcblx0fSxcclxuXHJcblx0X2hvdmVyYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XHJcblx0XHR0aGlzLmhvdmVyYWJsZSA9IHRoaXMuaG92ZXJhYmxlLmFkZCggZWxlbWVudCApO1xyXG5cdFx0dGhpcy5fb24oIGVsZW1lbnQsIHtcclxuXHRcdFx0bW91c2VlbnRlcjogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRcdCQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKS5hZGRDbGFzcyggXCJ1aS1zdGF0ZS1ob3ZlclwiICk7XHJcblx0XHRcdH0sXHJcblx0XHRcdG1vdXNlbGVhdmU6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0XHQkKCBldmVudC5jdXJyZW50VGFyZ2V0ICkucmVtb3ZlQ2xhc3MoIFwidWktc3RhdGUtaG92ZXJcIiApO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRfZm9jdXNhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHtcclxuXHRcdHRoaXMuZm9jdXNhYmxlID0gdGhpcy5mb2N1c2FibGUuYWRkKCBlbGVtZW50ICk7XHJcblx0XHR0aGlzLl9vbiggZWxlbWVudCwge1xyXG5cdFx0XHRmb2N1c2luOiBmdW5jdGlvbiggZXZlbnQgKSB7XHJcblx0XHRcdFx0JCggZXZlbnQuY3VycmVudFRhcmdldCApLmFkZENsYXNzKCBcInVpLXN0YXRlLWZvY3VzXCIgKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0Zm9jdXNvdXQ6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0XHQkKCBldmVudC5jdXJyZW50VGFyZ2V0ICkucmVtb3ZlQ2xhc3MoIFwidWktc3RhdGUtZm9jdXNcIiApO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRfdHJpZ2dlcjogZnVuY3Rpb24oIHR5cGUsIGV2ZW50LCBkYXRhICkge1xyXG5cdFx0dmFyIHByb3AsIG9yaWcsXHJcblx0XHRcdGNhbGxiYWNrID0gdGhpcy5vcHRpb25zWyB0eXBlIF07XHJcblxyXG5cdFx0ZGF0YSA9IGRhdGEgfHwge307XHJcblx0XHRldmVudCA9ICQuRXZlbnQoIGV2ZW50ICk7XHJcblx0XHRldmVudC50eXBlID0gKCB0eXBlID09PSB0aGlzLndpZGdldEV2ZW50UHJlZml4ID9cclxuXHRcdFx0dHlwZSA6XHJcblx0XHRcdHRoaXMud2lkZ2V0RXZlbnRQcmVmaXggKyB0eXBlICkudG9Mb3dlckNhc2UoKTtcclxuXHRcdC8vIHRoZSBvcmlnaW5hbCBldmVudCBtYXkgY29tZSBmcm9tIGFueSBlbGVtZW50XHJcblx0XHQvLyBzbyB3ZSBuZWVkIHRvIHJlc2V0IHRoZSB0YXJnZXQgb24gdGhlIG5ldyBldmVudFxyXG5cdFx0ZXZlbnQudGFyZ2V0ID0gdGhpcy5lbGVtZW50WyAwIF07XHJcblxyXG5cdFx0Ly8gY29weSBvcmlnaW5hbCBldmVudCBwcm9wZXJ0aWVzIG92ZXIgdG8gdGhlIG5ldyBldmVudFxyXG5cdFx0b3JpZyA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XHJcblx0XHRpZiAoIG9yaWcgKSB7XHJcblx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcclxuXHRcdFx0XHRpZiAoICEoIHByb3AgaW4gZXZlbnQgKSApIHtcclxuXHRcdFx0XHRcdGV2ZW50WyBwcm9wIF0gPSBvcmlnWyBwcm9wIF07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5lbGVtZW50LnRyaWdnZXIoIGV2ZW50LCBkYXRhICk7XHJcblx0XHRyZXR1cm4gISggJC5pc0Z1bmN0aW9uKCBjYWxsYmFjayApICYmXHJcblx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLmVsZW1lbnRbMF0sIFsgZXZlbnQgXS5jb25jYXQoIGRhdGEgKSApID09PSBmYWxzZSB8fFxyXG5cdFx0XHRldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApO1xyXG5cdH1cclxufTtcclxuXHJcbiQuZWFjaCggeyBzaG93OiBcImZhZGVJblwiLCBoaWRlOiBcImZhZGVPdXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBkZWZhdWx0RWZmZWN0ICkge1xyXG5cdCQuV2lkZ2V0LnByb3RvdHlwZVsgXCJfXCIgKyBtZXRob2QgXSA9IGZ1bmN0aW9uKCBlbGVtZW50LCBvcHRpb25zLCBjYWxsYmFjayApIHtcclxuXHRcdGlmICggdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdG9wdGlvbnMgPSB7IGVmZmVjdDogb3B0aW9ucyB9O1xyXG5cdFx0fVxyXG5cdFx0dmFyIGhhc09wdGlvbnMsXHJcblx0XHRcdGVmZmVjdE5hbWUgPSAhb3B0aW9ucyA/XHJcblx0XHRcdFx0bWV0aG9kIDpcclxuXHRcdFx0XHRvcHRpb25zID09PSB0cnVlIHx8IHR5cGVvZiBvcHRpb25zID09PSBcIm51bWJlclwiID9cclxuXHRcdFx0XHRcdGRlZmF1bHRFZmZlY3QgOlxyXG5cdFx0XHRcdFx0b3B0aW9ucy5lZmZlY3QgfHwgZGVmYXVsdEVmZmVjdDtcclxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cdFx0aWYgKCB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJudW1iZXJcIiApIHtcclxuXHRcdFx0b3B0aW9ucyA9IHsgZHVyYXRpb246IG9wdGlvbnMgfTtcclxuXHRcdH1cclxuXHRcdGhhc09wdGlvbnMgPSAhJC5pc0VtcHR5T2JqZWN0KCBvcHRpb25zICk7XHJcblx0XHRvcHRpb25zLmNvbXBsZXRlID0gY2FsbGJhY2s7XHJcblx0XHRpZiAoIG9wdGlvbnMuZGVsYXkgKSB7XHJcblx0XHRcdGVsZW1lbnQuZGVsYXkoIG9wdGlvbnMuZGVsYXkgKTtcclxuXHRcdH1cclxuXHRcdGlmICggaGFzT3B0aW9ucyAmJiAkLmVmZmVjdHMgJiYgJC5lZmZlY3RzLmVmZmVjdFsgZWZmZWN0TmFtZSBdICkge1xyXG5cdFx0XHRlbGVtZW50WyBtZXRob2QgXSggb3B0aW9ucyApO1xyXG5cdFx0fSBlbHNlIGlmICggZWZmZWN0TmFtZSAhPT0gbWV0aG9kICYmIGVsZW1lbnRbIGVmZmVjdE5hbWUgXSApIHtcclxuXHRcdFx0ZWxlbWVudFsgZWZmZWN0TmFtZSBdKCBvcHRpb25zLmR1cmF0aW9uLCBvcHRpb25zLmVhc2luZywgY2FsbGJhY2sgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGVsZW1lbnQucXVldWUoZnVuY3Rpb24oIG5leHQgKSB7XHJcblx0XHRcdFx0JCggdGhpcyApWyBtZXRob2QgXSgpO1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRjYWxsYmFjay5jYWxsKCBlbGVtZW50WyAwIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bmV4dCgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9O1xyXG59KTtcclxuXHJcbnZhciB3aWRnZXQgPSAkLndpZGdldDtcclxuXHJcblxyXG5cclxufSkpO1xyXG4iLCIvKiFcclxuICogY2xpcGJvYXJkLmpzIHYxLjcuMVxyXG4gKiBodHRwczovL3plbm9yb2NoYS5naXRodWIuaW8vY2xpcGJvYXJkLmpzXHJcbiAqXHJcbiAqIExpY2Vuc2VkIE1JVCDCqSBaZW5vIFJvY2hhXHJcbiAqL1xyXG4hZnVuY3Rpb24odCl7aWYoXCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGUpbW9kdWxlLmV4cG9ydHM9dCgpO2Vsc2UgaWYoXCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kKWRlZmluZShbXSx0KTtlbHNle3ZhciBlO2U9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbD9nbG9iYWw6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHNlbGY/c2VsZjp0aGlzLGUuQ2xpcGJvYXJkPXQoKX19KGZ1bmN0aW9uKCl7dmFyIHQsZSxuO3JldHVybiBmdW5jdGlvbiB0KGUsbixvKXtmdW5jdGlvbiBpKGEsYyl7aWYoIW5bYV0pe2lmKCFlW2FdKXt2YXIgbD1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFjJiZsKXJldHVybiBsKGEsITApO2lmKHIpcmV0dXJuIHIoYSwhMCk7dmFyIHM9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIithK1wiJ1wiKTt0aHJvdyBzLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsc312YXIgdT1uW2FdPXtleHBvcnRzOnt9fTtlW2FdWzBdLmNhbGwodS5leHBvcnRzLGZ1bmN0aW9uKHQpe3ZhciBuPWVbYV1bMV1bdF07cmV0dXJuIGkobnx8dCl9LHUsdS5leHBvcnRzLHQsZSxuLG8pfXJldHVybiBuW2FdLmV4cG9ydHN9Zm9yKHZhciByPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsYT0wO2E8by5sZW5ndGg7YSsrKWkob1thXSk7cmV0dXJuIGl9KHsxOltmdW5jdGlvbih0LGUsbil7ZnVuY3Rpb24gbyh0LGUpe2Zvcig7dCYmdC5ub2RlVHlwZSE9PWk7KXtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiB0Lm1hdGNoZXMmJnQubWF0Y2hlcyhlKSlyZXR1cm4gdDt0PXQucGFyZW50Tm9kZX19dmFyIGk9OTtpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgRWxlbWVudCYmIUVsZW1lbnQucHJvdG90eXBlLm1hdGNoZXMpe3ZhciByPUVsZW1lbnQucHJvdG90eXBlO3IubWF0Y2hlcz1yLm1hdGNoZXNTZWxlY3Rvcnx8ci5tb3pNYXRjaGVzU2VsZWN0b3J8fHIubXNNYXRjaGVzU2VsZWN0b3J8fHIub01hdGNoZXNTZWxlY3Rvcnx8ci53ZWJraXRNYXRjaGVzU2VsZWN0b3J9ZS5leHBvcnRzPW99LHt9XSwyOltmdW5jdGlvbih0LGUsbil7ZnVuY3Rpb24gbyh0LGUsbixvLHIpe3ZhciBhPWkuYXBwbHkodGhpcyxhcmd1bWVudHMpO3JldHVybiB0LmFkZEV2ZW50TGlzdGVuZXIobixhLHIpLHtkZXN0cm95OmZ1bmN0aW9uKCl7dC5yZW1vdmVFdmVudExpc3RlbmVyKG4sYSxyKX19fWZ1bmN0aW9uIGkodCxlLG4sbyl7cmV0dXJuIGZ1bmN0aW9uKG4pe24uZGVsZWdhdGVUYXJnZXQ9cihuLnRhcmdldCxlKSxuLmRlbGVnYXRlVGFyZ2V0JiZvLmNhbGwodCxuKX19dmFyIHI9dChcIi4vY2xvc2VzdFwiKTtlLmV4cG9ydHM9b30se1wiLi9jbG9zZXN0XCI6MX1dLDM6W2Z1bmN0aW9uKHQsZSxuKXtuLm5vZGU9ZnVuY3Rpb24odCl7cmV0dXJuIHZvaWQgMCE9PXQmJnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmMT09PXQubm9kZVR5cGV9LG4ubm9kZUxpc3Q9ZnVuY3Rpb24odCl7dmFyIGU9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpO3JldHVybiB2b2lkIDAhPT10JiYoXCJbb2JqZWN0IE5vZGVMaXN0XVwiPT09ZXx8XCJbb2JqZWN0IEhUTUxDb2xsZWN0aW9uXVwiPT09ZSkmJlwibGVuZ3RoXCJpbiB0JiYoMD09PXQubGVuZ3RofHxuLm5vZGUodFswXSkpfSxuLnN0cmluZz1mdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdHx8dCBpbnN0YW5jZW9mIFN0cmluZ30sbi5mbj1mdW5jdGlvbih0KXtyZXR1cm5cIltvYmplY3QgRnVuY3Rpb25dXCI9PT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCl9fSx7fV0sNDpbZnVuY3Rpb24odCxlLG4pe2Z1bmN0aW9uIG8odCxlLG4pe2lmKCF0JiYhZSYmIW4pdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyByZXF1aXJlZCBhcmd1bWVudHNcIik7aWYoIWMuc3RyaW5nKGUpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJTZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBhIFN0cmluZ1wiKTtpZighYy5mbihuKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVGhpcmQgYXJndW1lbnQgbXVzdCBiZSBhIEZ1bmN0aW9uXCIpO2lmKGMubm9kZSh0KSlyZXR1cm4gaSh0LGUsbik7aWYoYy5ub2RlTGlzdCh0KSlyZXR1cm4gcih0LGUsbik7aWYoYy5zdHJpbmcodCkpcmV0dXJuIGEodCxlLG4pO3Rocm93IG5ldyBUeXBlRXJyb3IoXCJGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgU3RyaW5nLCBIVE1MRWxlbWVudCwgSFRNTENvbGxlY3Rpb24sIG9yIE5vZGVMaXN0XCIpfWZ1bmN0aW9uIGkodCxlLG4pe3JldHVybiB0LmFkZEV2ZW50TGlzdGVuZXIoZSxuKSx7ZGVzdHJveTpmdW5jdGlvbigpe3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLG4pfX19ZnVuY3Rpb24gcih0LGUsbil7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwodCxmdW5jdGlvbih0KXt0LmFkZEV2ZW50TGlzdGVuZXIoZSxuKX0pLHtkZXN0cm95OmZ1bmN0aW9uKCl7QXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbCh0LGZ1bmN0aW9uKHQpe3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihlLG4pfSl9fX1mdW5jdGlvbiBhKHQsZSxuKXtyZXR1cm4gbChkb2N1bWVudC5ib2R5LHQsZSxuKX12YXIgYz10KFwiLi9pc1wiKSxsPXQoXCJkZWxlZ2F0ZVwiKTtlLmV4cG9ydHM9b30se1wiLi9pc1wiOjMsZGVsZWdhdGU6Mn1dLDU6W2Z1bmN0aW9uKHQsZSxuKXtmdW5jdGlvbiBvKHQpe3ZhciBlO2lmKFwiU0VMRUNUXCI9PT10Lm5vZGVOYW1lKXQuZm9jdXMoKSxlPXQudmFsdWU7ZWxzZSBpZihcIklOUFVUXCI9PT10Lm5vZGVOYW1lfHxcIlRFWFRBUkVBXCI9PT10Lm5vZGVOYW1lKXt2YXIgbj10Lmhhc0F0dHJpYnV0ZShcInJlYWRvbmx5XCIpO258fHQuc2V0QXR0cmlidXRlKFwicmVhZG9ubHlcIixcIlwiKSx0LnNlbGVjdCgpLHQuc2V0U2VsZWN0aW9uUmFuZ2UoMCx0LnZhbHVlLmxlbmd0aCksbnx8dC5yZW1vdmVBdHRyaWJ1dGUoXCJyZWFkb25seVwiKSxlPXQudmFsdWV9ZWxzZXt0Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKSYmdC5mb2N1cygpO3ZhciBvPXdpbmRvdy5nZXRTZWxlY3Rpb24oKSxpPWRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7aS5zZWxlY3ROb2RlQ29udGVudHModCksby5yZW1vdmVBbGxSYW5nZXMoKSxvLmFkZFJhbmdlKGkpLGU9by50b1N0cmluZygpfXJldHVybiBlfWUuZXhwb3J0cz1vfSx7fV0sNjpbZnVuY3Rpb24odCxlLG4pe2Z1bmN0aW9uIG8oKXt9by5wcm90b3R5cGU9e29uOmZ1bmN0aW9uKHQsZSxuKXt2YXIgbz10aGlzLmV8fCh0aGlzLmU9e30pO3JldHVybihvW3RdfHwob1t0XT1bXSkpLnB1c2goe2ZuOmUsY3R4Om59KSx0aGlzfSxvbmNlOmZ1bmN0aW9uKHQsZSxuKXtmdW5jdGlvbiBvKCl7aS5vZmYodCxvKSxlLmFwcGx5KG4sYXJndW1lbnRzKX12YXIgaT10aGlzO3JldHVybiBvLl89ZSx0aGlzLm9uKHQsbyxuKX0sZW1pdDpmdW5jdGlvbih0KXt2YXIgZT1bXS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKSxuPSgodGhpcy5lfHwodGhpcy5lPXt9KSlbdF18fFtdKS5zbGljZSgpLG89MCxpPW4ubGVuZ3RoO2ZvcihvO288aTtvKyspbltvXS5mbi5hcHBseShuW29dLmN0eCxlKTtyZXR1cm4gdGhpc30sb2ZmOmZ1bmN0aW9uKHQsZSl7dmFyIG49dGhpcy5lfHwodGhpcy5lPXt9KSxvPW5bdF0saT1bXTtpZihvJiZlKWZvcih2YXIgcj0wLGE9by5sZW5ndGg7cjxhO3IrKylvW3JdLmZuIT09ZSYmb1tyXS5mbi5fIT09ZSYmaS5wdXNoKG9bcl0pO3JldHVybiBpLmxlbmd0aD9uW3RdPWk6ZGVsZXRlIG5bdF0sdGhpc319LGUuZXhwb3J0cz1vfSx7fV0sNzpbZnVuY3Rpb24oZSxuLG8peyFmdW5jdGlvbihpLHIpe2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIHQmJnQuYW1kKXQoW1wibW9kdWxlXCIsXCJzZWxlY3RcIl0scik7ZWxzZSBpZih2b2lkIDAhPT1vKXIobixlKFwic2VsZWN0XCIpKTtlbHNle3ZhciBhPXtleHBvcnRzOnt9fTtyKGEsaS5zZWxlY3QpLGkuY2xpcGJvYXJkQWN0aW9uPWEuZXhwb3J0c319KHRoaXMsZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGU/dDp7ZGVmYXVsdDp0fX1mdW5jdGlvbiBvKHQsZSl7aWYoISh0IGluc3RhbmNlb2YgZSkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX12YXIgaT1uKGUpLHI9XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKHQpe3JldHVybiB0eXBlb2YgdH06ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmdC5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmdCE9PVN5bWJvbC5wcm90b3R5cGU/XCJzeW1ib2xcIjp0eXBlb2YgdH0sYT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXtmb3IodmFyIG49MDtuPGUubGVuZ3RoO24rKyl7dmFyIG89ZVtuXTtvLmVudW1lcmFibGU9by5lbnVtZXJhYmxlfHwhMSxvLmNvbmZpZ3VyYWJsZT0hMCxcInZhbHVlXCJpbiBvJiYoby53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsby5rZXksbyl9fXJldHVybiBmdW5jdGlvbihlLG4sbyl7cmV0dXJuIG4mJnQoZS5wcm90b3R5cGUsbiksbyYmdChlLG8pLGV9fSgpLGM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUpe28odGhpcyx0KSx0aGlzLnJlc29sdmVPcHRpb25zKGUpLHRoaXMuaW5pdFNlbGVjdGlvbigpfXJldHVybiBhKHQsW3trZXk6XCJyZXNvbHZlT3B0aW9uc1wiLHZhbHVlOmZ1bmN0aW9uIHQoKXt2YXIgZT1hcmd1bWVudHMubGVuZ3RoPjAmJnZvaWQgMCE9PWFyZ3VtZW50c1swXT9hcmd1bWVudHNbMF06e307dGhpcy5hY3Rpb249ZS5hY3Rpb24sdGhpcy5jb250YWluZXI9ZS5jb250YWluZXIsdGhpcy5lbWl0dGVyPWUuZW1pdHRlcix0aGlzLnRhcmdldD1lLnRhcmdldCx0aGlzLnRleHQ9ZS50ZXh0LHRoaXMudHJpZ2dlcj1lLnRyaWdnZXIsdGhpcy5zZWxlY3RlZFRleHQ9XCJcIn19LHtrZXk6XCJpbml0U2VsZWN0aW9uXCIsdmFsdWU6ZnVuY3Rpb24gdCgpe3RoaXMudGV4dD90aGlzLnNlbGVjdEZha2UoKTp0aGlzLnRhcmdldCYmdGhpcy5zZWxlY3RUYXJnZXQoKX19LHtrZXk6XCJzZWxlY3RGYWtlXCIsdmFsdWU6ZnVuY3Rpb24gdCgpe3ZhciBlPXRoaXMsbj1cInJ0bFwiPT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGlyXCIpO3RoaXMucmVtb3ZlRmFrZSgpLHRoaXMuZmFrZUhhbmRsZXJDYWxsYmFjaz1mdW5jdGlvbigpe3JldHVybiBlLnJlbW92ZUZha2UoKX0sdGhpcy5mYWtlSGFuZGxlcj10aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLmZha2VIYW5kbGVyQ2FsbGJhY2spfHwhMCx0aGlzLmZha2VFbGVtPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZXh0YXJlYVwiKSx0aGlzLmZha2VFbGVtLnN0eWxlLmZvbnRTaXplPVwiMTJwdFwiLHRoaXMuZmFrZUVsZW0uc3R5bGUuYm9yZGVyPVwiMFwiLHRoaXMuZmFrZUVsZW0uc3R5bGUucGFkZGluZz1cIjBcIix0aGlzLmZha2VFbGVtLnN0eWxlLm1hcmdpbj1cIjBcIix0aGlzLmZha2VFbGVtLnN0eWxlLnBvc2l0aW9uPVwiYWJzb2x1dGVcIix0aGlzLmZha2VFbGVtLnN0eWxlW24/XCJyaWdodFwiOlwibGVmdFwiXT1cIi05OTk5cHhcIjt2YXIgbz13aW5kb3cucGFnZVlPZmZzZXR8fGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7dGhpcy5mYWtlRWxlbS5zdHlsZS50b3A9bytcInB4XCIsdGhpcy5mYWtlRWxlbS5zZXRBdHRyaWJ1dGUoXCJyZWFkb25seVwiLFwiXCIpLHRoaXMuZmFrZUVsZW0udmFsdWU9dGhpcy50ZXh0LHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZmFrZUVsZW0pLHRoaXMuc2VsZWN0ZWRUZXh0PSgwLGkuZGVmYXVsdCkodGhpcy5mYWtlRWxlbSksdGhpcy5jb3B5VGV4dCgpfX0se2tleTpcInJlbW92ZUZha2VcIix2YWx1ZTpmdW5jdGlvbiB0KCl7dGhpcy5mYWtlSGFuZGxlciYmKHRoaXMuY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMuZmFrZUhhbmRsZXJDYWxsYmFjayksdGhpcy5mYWtlSGFuZGxlcj1udWxsLHRoaXMuZmFrZUhhbmRsZXJDYWxsYmFjaz1udWxsKSx0aGlzLmZha2VFbGVtJiYodGhpcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy5mYWtlRWxlbSksdGhpcy5mYWtlRWxlbT1udWxsKX19LHtrZXk6XCJzZWxlY3RUYXJnZXRcIix2YWx1ZTpmdW5jdGlvbiB0KCl7dGhpcy5zZWxlY3RlZFRleHQ9KDAsaS5kZWZhdWx0KSh0aGlzLnRhcmdldCksdGhpcy5jb3B5VGV4dCgpfX0se2tleTpcImNvcHlUZXh0XCIsdmFsdWU6ZnVuY3Rpb24gdCgpe3ZhciBlPXZvaWQgMDt0cnl7ZT1kb2N1bWVudC5leGVjQ29tbWFuZCh0aGlzLmFjdGlvbil9Y2F0Y2godCl7ZT0hMX10aGlzLmhhbmRsZVJlc3VsdChlKX19LHtrZXk6XCJoYW5kbGVSZXN1bHRcIix2YWx1ZTpmdW5jdGlvbiB0KGUpe3RoaXMuZW1pdHRlci5lbWl0KGU/XCJzdWNjZXNzXCI6XCJlcnJvclwiLHthY3Rpb246dGhpcy5hY3Rpb24sdGV4dDp0aGlzLnNlbGVjdGVkVGV4dCx0cmlnZ2VyOnRoaXMudHJpZ2dlcixjbGVhclNlbGVjdGlvbjp0aGlzLmNsZWFyU2VsZWN0aW9uLmJpbmQodGhpcyl9KX19LHtrZXk6XCJjbGVhclNlbGVjdGlvblwiLHZhbHVlOmZ1bmN0aW9uIHQoKXt0aGlzLnRyaWdnZXImJnRoaXMudHJpZ2dlci5mb2N1cygpLHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5yZW1vdmVBbGxSYW5nZXMoKX19LHtrZXk6XCJkZXN0cm95XCIsdmFsdWU6ZnVuY3Rpb24gdCgpe3RoaXMucmVtb3ZlRmFrZSgpfX0se2tleTpcImFjdGlvblwiLHNldDpmdW5jdGlvbiB0KCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOlwiY29weVwiO2lmKHRoaXMuX2FjdGlvbj1lLFwiY29weVwiIT09dGhpcy5fYWN0aW9uJiZcImN1dFwiIT09dGhpcy5fYWN0aW9uKXRocm93IG5ldyBFcnJvcignSW52YWxpZCBcImFjdGlvblwiIHZhbHVlLCB1c2UgZWl0aGVyIFwiY29weVwiIG9yIFwiY3V0XCInKX0sZ2V0OmZ1bmN0aW9uIHQoKXtyZXR1cm4gdGhpcy5fYWN0aW9ufX0se2tleTpcInRhcmdldFwiLHNldDpmdW5jdGlvbiB0KGUpe2lmKHZvaWQgMCE9PWUpe2lmKCFlfHxcIm9iamVjdFwiIT09KHZvaWQgMD09PWU/XCJ1bmRlZmluZWRcIjpyKGUpKXx8MSE9PWUubm9kZVR5cGUpdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFwidGFyZ2V0XCIgdmFsdWUsIHVzZSBhIHZhbGlkIEVsZW1lbnQnKTtpZihcImNvcHlcIj09PXRoaXMuYWN0aW9uJiZlLmhhc0F0dHJpYnV0ZShcImRpc2FibGVkXCIpKXRocm93IG5ldyBFcnJvcignSW52YWxpZCBcInRhcmdldFwiIGF0dHJpYnV0ZS4gUGxlYXNlIHVzZSBcInJlYWRvbmx5XCIgaW5zdGVhZCBvZiBcImRpc2FibGVkXCIgYXR0cmlidXRlJyk7aWYoXCJjdXRcIj09PXRoaXMuYWN0aW9uJiYoZS5oYXNBdHRyaWJ1dGUoXCJyZWFkb25seVwiKXx8ZS5oYXNBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSkpdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFwidGFyZ2V0XCIgYXR0cmlidXRlLiBZb3UgY2FuXFwndCBjdXQgdGV4dCBmcm9tIGVsZW1lbnRzIHdpdGggXCJyZWFkb25seVwiIG9yIFwiZGlzYWJsZWRcIiBhdHRyaWJ1dGVzJyk7dGhpcy5fdGFyZ2V0PWV9fSxnZXQ6ZnVuY3Rpb24gdCgpe3JldHVybiB0aGlzLl90YXJnZXR9fV0pLHR9KCk7dC5leHBvcnRzPWN9KX0se3NlbGVjdDo1fV0sODpbZnVuY3Rpb24oZSxuLG8peyFmdW5jdGlvbihpLHIpe2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIHQmJnQuYW1kKXQoW1wibW9kdWxlXCIsXCIuL2NsaXBib2FyZC1hY3Rpb25cIixcInRpbnktZW1pdHRlclwiLFwiZ29vZC1saXN0ZW5lclwiXSxyKTtlbHNlIGlmKHZvaWQgMCE9PW8pcihuLGUoXCIuL2NsaXBib2FyZC1hY3Rpb25cIiksZShcInRpbnktZW1pdHRlclwiKSxlKFwiZ29vZC1saXN0ZW5lclwiKSk7ZWxzZXt2YXIgYT17ZXhwb3J0czp7fX07cihhLGkuY2xpcGJvYXJkQWN0aW9uLGkudGlueUVtaXR0ZXIsaS5nb29kTGlzdGVuZXIpLGkuY2xpcGJvYXJkPWEuZXhwb3J0c319KHRoaXMsZnVuY3Rpb24odCxlLG4sbyl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gaSh0KXtyZXR1cm4gdCYmdC5fX2VzTW9kdWxlP3Q6e2RlZmF1bHQ6dH19ZnVuY3Rpb24gcih0LGUpe2lmKCEodCBpbnN0YW5jZW9mIGUpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIil9ZnVuY3Rpb24gYSh0LGUpe2lmKCF0KXRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtyZXR1cm4hZXx8XCJvYmplY3RcIiE9dHlwZW9mIGUmJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGU/dDplfWZ1bmN0aW9uIGModCxlKXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiBlJiZudWxsIT09ZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIit0eXBlb2YgZSk7dC5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShlJiZlLnByb3RvdHlwZSx7Y29uc3RydWN0b3I6e3ZhbHVlOnQsZW51bWVyYWJsZTohMSx3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9fSksZSYmKE9iamVjdC5zZXRQcm90b3R5cGVPZj9PYmplY3Quc2V0UHJvdG90eXBlT2YodCxlKTp0Ll9fcHJvdG9fXz1lKX1mdW5jdGlvbiBsKHQsZSl7dmFyIG49XCJkYXRhLWNsaXBib2FyZC1cIit0O2lmKGUuaGFzQXR0cmlidXRlKG4pKXJldHVybiBlLmdldEF0dHJpYnV0ZShuKX12YXIgcz1pKGUpLHU9aShuKSxmPWkobyksZD1cImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJlwic3ltYm9sXCI9PXR5cGVvZiBTeW1ib2wuaXRlcmF0b3I/ZnVuY3Rpb24odCl7cmV0dXJuIHR5cGVvZiB0fTpmdW5jdGlvbih0KXtyZXR1cm4gdCYmXCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZ0LmNvbnN0cnVjdG9yPT09U3ltYm9sJiZ0IT09U3ltYm9sLnByb3RvdHlwZT9cInN5bWJvbFwiOnR5cGVvZiB0fSxoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe2Zvcih2YXIgbj0wO248ZS5sZW5ndGg7bisrKXt2YXIgbz1lW25dO28uZW51bWVyYWJsZT1vLmVudW1lcmFibGV8fCExLG8uY29uZmlndXJhYmxlPSEwLFwidmFsdWVcImluIG8mJihvLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodCxvLmtleSxvKX19cmV0dXJuIGZ1bmN0aW9uKGUsbixvKXtyZXR1cm4gbiYmdChlLnByb3RvdHlwZSxuKSxvJiZ0KGUsbyksZX19KCkscD1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKHQsbil7cih0aGlzLGUpO3ZhciBvPWEodGhpcywoZS5fX3Byb3RvX198fE9iamVjdC5nZXRQcm90b3R5cGVPZihlKSkuY2FsbCh0aGlzKSk7cmV0dXJuIG8ucmVzb2x2ZU9wdGlvbnMobiksby5saXN0ZW5DbGljayh0KSxvfXJldHVybiBjKGUsdCksaChlLFt7a2V5OlwicmVzb2x2ZU9wdGlvbnNcIix2YWx1ZTpmdW5jdGlvbiB0KCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOnt9O3RoaXMuYWN0aW9uPVwiZnVuY3Rpb25cIj09dHlwZW9mIGUuYWN0aW9uP2UuYWN0aW9uOnRoaXMuZGVmYXVsdEFjdGlvbix0aGlzLnRhcmdldD1cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLnRhcmdldD9lLnRhcmdldDp0aGlzLmRlZmF1bHRUYXJnZXQsdGhpcy50ZXh0PVwiZnVuY3Rpb25cIj09dHlwZW9mIGUudGV4dD9lLnRleHQ6dGhpcy5kZWZhdWx0VGV4dCx0aGlzLmNvbnRhaW5lcj1cIm9iamVjdFwiPT09ZChlLmNvbnRhaW5lcik/ZS5jb250YWluZXI6ZG9jdW1lbnQuYm9keX19LHtrZXk6XCJsaXN0ZW5DbGlja1wiLHZhbHVlOmZ1bmN0aW9uIHQoZSl7dmFyIG49dGhpczt0aGlzLmxpc3RlbmVyPSgwLGYuZGVmYXVsdCkoZSxcImNsaWNrXCIsZnVuY3Rpb24odCl7cmV0dXJuIG4ub25DbGljayh0KX0pfX0se2tleTpcIm9uQ2xpY2tcIix2YWx1ZTpmdW5jdGlvbiB0KGUpe3ZhciBuPWUuZGVsZWdhdGVUYXJnZXR8fGUuY3VycmVudFRhcmdldDt0aGlzLmNsaXBib2FyZEFjdGlvbiYmKHRoaXMuY2xpcGJvYXJkQWN0aW9uPW51bGwpLHRoaXMuY2xpcGJvYXJkQWN0aW9uPW5ldyBzLmRlZmF1bHQoe2FjdGlvbjp0aGlzLmFjdGlvbihuKSx0YXJnZXQ6dGhpcy50YXJnZXQobiksdGV4dDp0aGlzLnRleHQobiksY29udGFpbmVyOnRoaXMuY29udGFpbmVyLHRyaWdnZXI6bixlbWl0dGVyOnRoaXN9KX19LHtrZXk6XCJkZWZhdWx0QWN0aW9uXCIsdmFsdWU6ZnVuY3Rpb24gdChlKXtyZXR1cm4gbChcImFjdGlvblwiLGUpfX0se2tleTpcImRlZmF1bHRUYXJnZXRcIix2YWx1ZTpmdW5jdGlvbiB0KGUpe3ZhciBuPWwoXCJ0YXJnZXRcIixlKTtpZihuKXJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKG4pfX0se2tleTpcImRlZmF1bHRUZXh0XCIsdmFsdWU6ZnVuY3Rpb24gdChlKXtyZXR1cm4gbChcInRleHRcIixlKX19LHtrZXk6XCJkZXN0cm95XCIsdmFsdWU6ZnVuY3Rpb24gdCgpe3RoaXMubGlzdGVuZXIuZGVzdHJveSgpLHRoaXMuY2xpcGJvYXJkQWN0aW9uJiYodGhpcy5jbGlwYm9hcmRBY3Rpb24uZGVzdHJveSgpLHRoaXMuY2xpcGJvYXJkQWN0aW9uPW51bGwpfX1dLFt7a2V5OlwiaXNTdXBwb3J0ZWRcIix2YWx1ZTpmdW5jdGlvbiB0KCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOltcImNvcHlcIixcImN1dFwiXSxuPVwic3RyaW5nXCI9PXR5cGVvZiBlP1tlXTplLG89ISFkb2N1bWVudC5xdWVyeUNvbW1hbmRTdXBwb3J0ZWQ7cmV0dXJuIG4uZm9yRWFjaChmdW5jdGlvbih0KXtvPW8mJiEhZG9jdW1lbnQucXVlcnlDb21tYW5kU3VwcG9ydGVkKHQpfSksb319XSksZX0odS5kZWZhdWx0KTt0LmV4cG9ydHM9cH0pfSx7XCIuL2NsaXBib2FyZC1hY3Rpb25cIjo3LFwiZ29vZC1saXN0ZW5lclwiOjQsXCJ0aW55LWVtaXR0ZXJcIjo2fV19LHt9LFs4XSkoOCl9KTsiLCIvKiBqc2hpbnQgLVcwNzEsIC1XMDc0ICovXHJcbi8qIGdsb2JhbCBqUXVlcnk6ZmFsc2UgKi9cclxuXHJcbi8qIERpc2FibGVkIG9wdGlvbnMgYXJlOlxyXG4gKiBXMDcxOiBUaGlzIGZ1bmN0aW9uIGhhcyB0b28gbWFueSBzdGF0ZW1lbnRzXHJcbiAqIFcwNzQ6IFRoaXMgZnVuY3Rpb24ncyBjeWNsb21hdGljIGNvbXBsZXhpdHkgaXMgdG9vIGhpZ2hcclxuICovXHJcblxyXG4vKlxyXG4gKlx0alF1ZXJ5IGV6UGx1cyAxLjEuMTFcclxuICpcdERlbW8ncyBhbmQgZG9jdW1lbnRhdGlvbjpcclxuICpcdGh0dHA6Ly9pZ29ybGluby5naXRodWIuaW8vZWxldmF0ZXpvb20tcGx1cy9cclxuICpcclxuICpcdGxpY2Vuc2VkIHVuZGVyIE1JVCBsaWNlbnNlLlxyXG4gKlx0aHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NSVRfTGljZW5zZVxyXG4gKlxyXG4gKi9cclxuXHJcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgT2JqZWN0LmNyZWF0ZSA9IGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICBmdW5jdGlvbiBGKCkge1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgRi5wcm90b3R5cGUgPSBvYmo7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBGKCk7XHJcbiAgICB9O1xyXG59XHJcblxyXG4oZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICAgdmFyIEVaUCA9IHtcclxuICAgICAgICBpbml0OiBmdW5jdGlvbiAob3B0aW9ucywgZWxlbSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHZhciAkZ2FsbGVyaWVzO1xyXG5cclxuICAgICAgICAgICAgc2VsZi5lbGVtID0gZWxlbTtcclxuICAgICAgICAgICAgc2VsZi4kZWxlbSA9ICQoZWxlbSk7XHJcblxyXG4gICAgICAgICAgICBzZWxmLmltYWdlU3JjID0gc2VsZi4kZWxlbS5kYXRhKCd6b29tLWltYWdlJykgPyBzZWxmLiRlbGVtLmRhdGEoJ3pvb20taW1hZ2UnKSA6IHNlbGYuJGVsZW0uYXR0cignc3JjJyk7XHJcblxyXG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJC5mbi5lelBsdXMub3B0aW9ucywgc2VsZi5yZXNwb25zaXZlQ29uZmlnKG9wdGlvbnMgfHwge30pKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghc2VsZi5vcHRpb25zLmVuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9USU5UIE9WRVJSSURFIFNFVFRJTkdTXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLmxlbnNDb2xvdXIgPSAnbm9uZSc7IC8vY29sb3VyIG9mIHRoZSBsZW5zIGJhY2tncm91bmRcclxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5sZW5zT3BhY2l0eSA9ICcxJzsgLy9vcGFjaXR5IG9mIHRoZSBsZW5zXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy9JTk5FUiBPVkVSUklERSBTRVRUSU5HU1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2hvd0xlbnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9VVUlEIFdIRU4gTUlTU0lORyBJREVOVElGSUVSXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbUlkID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnpvb21JZCA9IGdlbmVyYXRlVVVJRCgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgLy9SZW1vdmUgYWx0IG9uIGhvdmVyXHJcblxyXG4gICAgICAgICAgICBzZWxmLiRlbGVtLnBhcmVudCgpLnJlbW92ZUF0dHIoJ3RpdGxlJykucmVtb3ZlQXR0cignYWx0Jyk7XHJcblxyXG4gICAgICAgICAgICBzZWxmLnpvb21JbWFnZSA9IHNlbGYuaW1hZ2VTcmM7XHJcblxyXG4gICAgICAgICAgICBzZWxmLnJlZnJlc2goMSk7XHJcblxyXG4gICAgICAgICAgICAvL0NyZWF0ZSB0aGUgaW1hZ2Ugc3dhcCBmcm9tIHRoZSBnYWxsZXJ5XHJcbiAgICAgICAgICAgICRnYWxsZXJpZXMgPSAkKHNlbGYub3B0aW9ucy5nYWxsZXJ5ID8gKCcjJyArIHNlbGYub3B0aW9ucy5nYWxsZXJ5KSA6IHNlbGYub3B0aW9ucy5nYWxsZXJ5U2VsZWN0b3IpO1xyXG4gICAgICAgICAgICAkZ2FsbGVyaWVzLm9uKCdjbGljay56b29tJywgc2VsZi5vcHRpb25zLmdhbGxlcnlJdGVtLCBmdW5jdGlvbiAoZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vU2V0IGEgY2xhc3Mgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUgZ2FsbGVyeSBpbWFnZVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5nYWxsZXJ5QWN0aXZlQ2xhc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAkKHNlbGYub3B0aW9ucy5nYWxsZXJ5SXRlbSwgJGdhbGxlcmllcykucmVtb3ZlQ2xhc3Moc2VsZi5vcHRpb25zLmdhbGxlcnlBY3RpdmVDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhzZWxmLm9wdGlvbnMuZ2FsbGVyeUFjdGl2ZUNsYXNzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vc3RvcCBhbnkgbGluayBvbiB0aGUgYSB0YWcgZnJvbSB3b3JraW5nXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50YWdOYW1lID09PSAnQScpIHtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jYWxsIHRoZSBzd2FwIGltYWdlIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5kYXRhKCd6b29tLWltYWdlJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21JbWFnZVByZSA9ICQodGhpcykuZGF0YSgnem9vbS1pbWFnZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tSW1hZ2VQcmUgPSAkKHRoaXMpLmRhdGEoJ2ltYWdlJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBzZWxmLnN3YXB0aGVpbWFnZSgkKHRoaXMpLmRhdGEoJ2ltYWdlJyksIHNlbGYuem9vbUltYWdlUHJlKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhZ05hbWUgPT09ICdBJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZVVVSUQoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHV1aWQgPSAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSAoZCArIE1hdGgucmFuZG9tKCkgKiAxNikgJSAxNiB8IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgZCA9IE1hdGguZmxvb3IoZCAvIDE2KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGMgPT0gJ3gnID8gciA6IChyICYgMHgzIHwgMHg4KSkudG9TdHJpbmcoMTYpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdXVpZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcmVmcmVzaDogZnVuY3Rpb24gKGxlbmd0aCkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuZmV0Y2goc2VsZi5pbWFnZVNyYyk7XHJcblxyXG4gICAgICAgICAgICB9LCBsZW5ndGggfHwgc2VsZi5vcHRpb25zLnJlZnJlc2gpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZmV0Y2g6IGZ1bmN0aW9uIChpbWdzcmMpIHtcclxuICAgICAgICAgICAgLy9nZXQgdGhlIGltYWdlXHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgdmFyIG5ld0ltZyA9IG5ldyBJbWFnZSgpO1xyXG4gICAgICAgICAgICBuZXdJbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy9zZXQgdGhlIGxhcmdlIGltYWdlIGRpbWVuc2lvbnMgLSB1c2VkIHRvIGNhbGN1bHRlIHJhdGlvJ3NcclxuICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCA9IG5ld0ltZy53aWR0aDtcclxuICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VIZWlnaHQgPSBuZXdJbWcuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgLy9vbmNlIGltYWdlIGlzIGxvYWRlZCBzdGFydCB0aGUgY2FsbHNcclxuICAgICAgICAgICAgICAgIHNlbGYuc3RhcnRab29tKCk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRJbWFnZSA9IHNlbGYuaW1hZ2VTcmM7XHJcbiAgICAgICAgICAgICAgICAvL2xldCBjYWxsZXIga25vdyBpbWFnZSBoYXMgYmVlbiBsb2FkZWRcclxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5vblpvb21lZEltYWdlTG9hZGVkKHNlbGYuJGVsZW0pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzZWxmLnNldEltYWdlU291cmNlKG5ld0ltZywgaW1nc3JjKTsgLy8gdGhpcyBtdXN0IGJlIGRvbmUgQUZURVIgc2V0dGluZyBvbmxvYWRcclxuXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHNldEltYWdlU291cmNlOiBmdW5jdGlvbiAoaW1hZ2UsIHNyYykge1xyXG4gICAgICAgICAgICAvL3NldHMgYW4gaW1hZ2UncyBzb3VyY2UuXHJcbiAgICAgICAgICAgIGltYWdlLnNyYyA9IHNyYztcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN0YXJ0Wm9vbTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIC8vZ2V0IGRpbWVuc2lvbnMgb2YgdGhlIG5vbiB6b29tZWQgaW1hZ2VcclxuICAgICAgICAgICAgc2VsZi5ueldpZHRoID0gc2VsZi4kZWxlbS53aWR0aCgpO1xyXG4gICAgICAgICAgICBzZWxmLm56SGVpZ2h0ID0gc2VsZi4kZWxlbS5oZWlnaHQoKTtcclxuXHJcbiAgICAgICAgICAgIC8vYWN0aXZhdGVkIGVsZW1lbnRzXHJcbiAgICAgICAgICAgIHNlbGYuaXNXaW5kb3dBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZi5pc0xlbnNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZi5pc1RpbnRBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZi5vdmVyV2luZG93ID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvL0Nyb3NzRmFkZSBXcmFwcGVyXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuaW1hZ2VDcm9zc2ZhZGUpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbVdyYXAgPSBzZWxmLiRlbGVtLndyYXAoJzxkaXYgc3R5bGU9XCJoZWlnaHQ6JyArIHNlbGYubnpIZWlnaHQgKyAncHg7d2lkdGg6JyArIHNlbGYubnpXaWR0aCArICdweDtcIiBjbGFzcz1cInpvb21XcmFwcGVyXCIgLz4nKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0uY3NzKCdwb3NpdGlvbicsICdhYnNvbHV0ZScpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzZWxmLnpvb21Mb2NrID0gMTtcclxuICAgICAgICAgICAgc2VsZi5zY3JvbGxpbmdMb2NrID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHNlbGYuY3VycmVudFpvb21MZXZlbCA9IHNlbGYub3B0aW9ucy56b29tTGV2ZWw7XHJcblxyXG4gICAgICAgICAgICAvL2dldCBvZmZzZXQgb2YgdGhlIG5vbiB6b29tZWQgaW1hZ2VcclxuICAgICAgICAgICAgc2VsZi5uek9mZnNldCA9IHNlbGYuJGVsZW0ub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgIC8vY2FsY3VsYXRlIHRoZSB3aWR0aCByYXRpbyBvZiB0aGUgbGFyZ2Uvc21hbGwgaW1hZ2VcclxuICAgICAgICAgICAgc2VsZi53aWR0aFJhdGlvID0gKHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYuY3VycmVudFpvb21MZXZlbCkgLyBzZWxmLm56V2lkdGg7XHJcbiAgICAgICAgICAgIHNlbGYuaGVpZ2h0UmF0aW8gPSAoc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYuY3VycmVudFpvb21MZXZlbCkgLyBzZWxmLm56SGVpZ2h0O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0V2luZG93Wm9vbVN0eWxlKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdvdmVyZmxvdzogaGlkZGVuOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwcHggMHB4O3RleHQtYWxpZ246Y2VudGVyOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWNvbG9yOiAnICsgU3RyaW5nKHNlbGYub3B0aW9ucy56b29tV2luZG93QmdDb2xvdXIpICsgJzsnICtcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGg6ICcgKyBTdHJpbmcoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCkgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2hlaWdodDogJyArIFN0cmluZyhzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCkgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0OiBsZWZ0OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXNpemU6ICcgKyBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLmN1cnJlbnRab29tTGV2ZWwgKyAncHggJyArIHNlbGYubGFyZ2VIZWlnaHQgLyBzZWxmLmN1cnJlbnRab29tTGV2ZWwgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2Rpc3BsYXk6IG5vbmU7ei1pbmRleDoxMDA7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JvcmRlcjogJyArIFN0cmluZyhzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSkgKyAncHggc29saWQgJyArIHNlbGYub3B0aW9ucy5ib3JkZXJDb2xvdXIgKyAnOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdwb3NpdGlvbjogYWJzb2x1dGU7JztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9pZiB3aW5kb3cgem9vbVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnd2luZG93Jykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93U3R5bGUgPSBnZXRXaW5kb3dab29tU3R5bGUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0SW5uZXJab29tU3R5bGUoKSB7XHJcbiAgICAgICAgICAgICAgICAvL2hhcyBhIGJvcmRlciBiZWVuIHB1dCBvbiB0aGUgaW1hZ2U/IExldHMgY2F0ZXIgZm9yIHRoaXNcclxuICAgICAgICAgICAgICAgIHZhciBib3JkZXJXaWR0aCA9IHNlbGYuJGVsZW0uY3NzKCdib3JkZXItbGVmdC13aWR0aCcpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiAnb3ZlcmZsb3c6IGhpZGRlbjsnICtcclxuICAgICAgICAgICAgICAgICAgICAnbWFyZ2luLWxlZnQ6ICcgKyBTdHJpbmcoYm9yZGVyV2lkdGgpICsgJzsnICtcclxuICAgICAgICAgICAgICAgICAgICAnbWFyZ2luLXRvcDogJyArIFN0cmluZyhib3JkZXJXaWR0aCkgKyAnOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwcHggMHB4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICd3aWR0aDogJyArIFN0cmluZyhzZWxmLm56V2lkdGgpICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdoZWlnaHQ6ICcgKyBTdHJpbmcoc2VsZi5uekhlaWdodCkgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2Zsb2F0OiBsZWZ0OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdkaXNwbGF5OiBub25lOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdjdXJzb3I6JyArIChzZWxmLm9wdGlvbnMuY3Vyc29yKSArICc7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ3B4IHNvbGlkICcgKyBzZWxmLm9wdGlvbnMuYm9yZGVyQ29sb3VyICsgJzsnICtcclxuICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsnICtcclxuICAgICAgICAgICAgICAgICAgICAncG9zaXRpb246IGFic29sdXRlOyc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vaWYgaW5uZXIgIHpvb21cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93U3R5bGUgPSBnZXRJbm5lclpvb21TdHlsZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBnZXRXaW5kb3dMZW5zU3R5bGUoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGVuc0hlaWdodCwgbGVuc1dpZHRoO1xyXG4gICAgICAgICAgICAgICAgLy8gYWRqdXN0IGltYWdlcyBsZXNzIHRoYW4gdGhlIHdpbmRvdyBoZWlnaHRcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5uekhlaWdodCA8IHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0IC8gc2VsZi5oZWlnaHRSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlbnNIZWlnaHQgPSBzZWxmLm56SGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVuc0hlaWdodCA9IFN0cmluZyhzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCAvIHNlbGYuaGVpZ2h0UmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYubGFyZ2VXaWR0aCA8IHNlbGYub3B0aW9ucy56b29tV2luZG93V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5zV2lkdGggPSBzZWxmLm56V2lkdGg7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5zV2lkdGggPSBTdHJpbmcoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwcHggMHB4O3dpZHRoOiAnICsgU3RyaW5nKChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd1dpZHRoKSAvIHNlbGYud2lkdGhSYXRpbykgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2hlaWdodDogJyArIFN0cmluZygoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQpIC8gc2VsZi5oZWlnaHRSYXRpbykgK1xyXG4gICAgICAgICAgICAgICAgICAgICdweDtmbG9hdDogcmlnaHQ7ZGlzcGxheTogbm9uZTsnICtcclxuICAgICAgICAgICAgICAgICAgICAnb3ZlcmZsb3c6IGhpZGRlbjsnICtcclxuICAgICAgICAgICAgICAgICAgICAnei1pbmRleDogOTk5OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdvcGFjaXR5OicgKyAoc2VsZi5vcHRpb25zLmxlbnNPcGFjaXR5KSArICc7ZmlsdGVyOiBhbHBoYShvcGFjaXR5ID0gJyArIChzZWxmLm9wdGlvbnMubGVuc09wYWNpdHkgKiAxMDApICsgJyk7IHpvb206MTsnICtcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGg6JyArIGxlbnNXaWR0aCArICdweDsnICtcclxuICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0OicgKyBsZW5zSGVpZ2h0ICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWNvbG9yOicgKyAoc2VsZi5vcHRpb25zLmxlbnNDb2xvdXIpICsgJzsnICtcclxuICAgICAgICAgICAgICAgICAgICAnY3Vyc29yOicgKyAoc2VsZi5vcHRpb25zLmN1cnNvcikgKyAnOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdib3JkZXI6ICcgKyAoc2VsZi5vcHRpb25zLmxlbnNCb3JkZXJTaXplKSArICdweCcgK1xyXG4gICAgICAgICAgICAgICAgICAgICcgc29saWQgJyArIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlckNvbG91cikgKyAnO2JhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7cG9zaXRpb246IGFic29sdXRlOyc7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vbGVucyBzdHlsZSBmb3Igd2luZG93IHpvb21cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYubGVuc1N0eWxlID0gZ2V0V2luZG93TGVuc1N0eWxlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vdGludCBzdHlsZVxyXG4gICAgICAgICAgICBzZWxmLnRpbnRTdHlsZSA9ICdkaXNwbGF5OiBibG9jazsnICtcclxuICAgICAgICAgICAgICAgICdwb3NpdGlvbjogYWJzb2x1dGU7JyArXHJcbiAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcjogJyArIHNlbGYub3B0aW9ucy50aW50Q29sb3VyICsgJzsnICtcclxuICAgICAgICAgICAgICAgICdmaWx0ZXI6YWxwaGEob3BhY2l0eT0wKTsnICtcclxuICAgICAgICAgICAgICAgICdvcGFjaXR5OiAwOycgK1xyXG4gICAgICAgICAgICAgICAgJ3dpZHRoOiAnICsgc2VsZi5ueldpZHRoICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgJ2hlaWdodDogJyArIHNlbGYubnpIZWlnaHQgKyAncHg7JztcclxuXHJcbiAgICAgICAgICAgIC8vbGVucyBzdHlsZSBmb3IgbGVucyB6b29tIHdpdGggb3B0aW9uYWwgcm91bmQgZm9yIG1vZGVybiBicm93c2Vyc1xyXG4gICAgICAgICAgICBzZWxmLmxlbnNSb3VuZCA9ICcnO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmxlbnNTdHlsZSA9ICdiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwcHggMHB4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdmbG9hdDogbGVmdDtkaXNwbGF5OiBub25lOycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdib3JkZXI6ICcgKyBTdHJpbmcoc2VsZi5vcHRpb25zLmJvcmRlclNpemUpICsgJ3B4IHNvbGlkICcgKyBzZWxmLm9wdGlvbnMuYm9yZGVyQ29sb3VyICsgJzsnICtcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGg6JyArIFN0cmluZyhzZWxmLm9wdGlvbnMubGVuc1NpemUpICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdoZWlnaHQ6JyArIFN0cmluZyhzZWxmLm9wdGlvbnMubGVuc1NpemUpICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O3Bvc2l0aW9uOiBhYnNvbHV0ZTsnO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvL2RvZXMgbm90IHJvdW5kIGluIGFsbCBicm93c2Vyc1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmxlbnNTaGFwZSA9PT0gJ3JvdW5kJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5sZW5zUm91bmQgPSAnYm9yZGVyLXRvcC1sZWZ0LXJhZGl1czogJyArIFN0cmluZyhzZWxmLm9wdGlvbnMubGVuc1NpemUgLyAyICsgc2VsZi5vcHRpb25zLmJvcmRlclNpemUpICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogJyArIFN0cmluZyhzZWxmLm9wdGlvbnMubGVuc1NpemUgLyAyICsgc2VsZi5vcHRpb25zLmJvcmRlclNpemUpICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiAnICsgU3RyaW5nKHNlbGYub3B0aW9ucy5sZW5zU2l6ZSAvIDIgKyBzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSkgKyAncHg7JyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOiAnICsgU3RyaW5nKHNlbGYub3B0aW9ucy5sZW5zU2l6ZSAvIDIgKyBzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSkgKyAncHg7JztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9jcmVhdGUgdGhlIGRpdidzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBcIlwiXHJcbiAgICAgICAgICAgIC8vc2VsZi56b29tQ29udGFpbmVyID0gJCgnPGRpdi8+JykuYWRkQ2xhc3MoJ3pvb21Db250YWluZXInKS5jc3Moe1wicG9zaXRpb25cIjpcInJlbGF0aXZlXCIsIFwiaGVpZ2h0XCI6c2VsZi5uekhlaWdodCwgXCJ3aWR0aFwiOnNlbGYubnpXaWR0aH0pO1xyXG5cclxuICAgICAgICAgICAgc2VsZi56b29tQ29udGFpbmVyID1cclxuICAgICAgICAgICAgICAgICQoJzxkaXYgY2xhc3M9XCJ6b29tQ29udGFpbmVyXCIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ3V1aWQ9XCInICsgc2VsZi5vcHRpb25zLnpvb21JZCArICdcIicgK1xyXG4gICAgICAgICAgICAgICAgICAgICdzdHlsZT1cIicgK1xyXG4gICAgICAgICAgICAgICAgICAgICdwb3NpdGlvbjphYnNvbHV0ZTsnICtcclxuICAgICAgICAgICAgICAgICAgICAnbGVmdDonICsgc2VsZi5uek9mZnNldC5sZWZ0ICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICd0b3A6JyArIHNlbGYubnpPZmZzZXQudG9wICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICdoZWlnaHQ6JyArIHNlbGYubnpIZWlnaHQgKyAncHg7JyArICcnICtcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGg6JyArIHNlbGYubnpXaWR0aCArICdweDsnICtcclxuICAgICAgICAgICAgICAgICAgICAnei1pbmRleDonICsgc2VsZi5vcHRpb25zLnpJbmRleCArICdcIj48L2Rpdj4nKTtcclxuICAgICAgICAgICAgJChzZWxmLm9wdGlvbnMuem9vbUNvbnRhaW5lckFwcGVuZFRvKS5hcHBlbmQoc2VsZi56b29tQ29udGFpbmVyKTtcclxuXHJcbiAgICAgICAgICAgIC8vdGhpcyB3aWxsIGFkZCBvdmVyZmxvdyBoaWRkZW4gYW5kIGNvbnRyYWluIHRoZSBsZW5zIG9uIGxlbnMgbW9kZVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmNvbnRhaW5MZW5zWm9vbSAmJiBzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tQ29udGFpbmVyLmNzcygnb3ZlcmZsb3cnLCAnaGlkZGVuJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tTGVucyA9ICQoJzxkaXYgY2xhc3M9XCJ6b29tTGVuc1wiIHN0eWxlPVwiJyArIHNlbGYubGVuc1N0eWxlICsgc2VsZi5sZW5zUm91bmQgKyAnXCI+Jm5ic3A7PC9kaXY+JylcclxuICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8oc2VsZi56b29tQ29udGFpbmVyKVxyXG4gICAgICAgICAgICAgICAgICAgIC5jbGljayhmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0udHJpZ2dlcignY2xpY2snKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRpbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnRpbnRDb250YWluZXIgPSAkKCc8ZGl2Lz4nKS5hZGRDbGFzcygndGludENvbnRhaW5lcicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnQgPSAkKCc8ZGl2IGNsYXNzPVwiem9vbVRpbnRcIiBzdHlsZT1cIicgKyBzZWxmLnRpbnRTdHlsZSArICdcIj48L2Rpdj4nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy53cmFwKHNlbGYudGludENvbnRhaW5lcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnRjc3MgPSBzZWxmLnpvb21MZW5zLmFmdGVyKHNlbGYuem9vbVRpbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIHRpbnQgZW5hYmxlZCAtIHNldCBhbiBpbWFnZSB0byBzaG93IG92ZXIgdGhlIHRpbnRcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludEltYWdlID0gJCgnPGltZyBzdHlsZT1cIicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAncG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAwcHg7IHRvcDogMHB4OyBtYXgtd2lkdGg6IG5vbmU7ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnd2lkdGg6ICcgKyBzZWxmLm56V2lkdGggKyAncHg7ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0OiAnICsgc2VsZi5uekhlaWdodCArICdweDtcIiAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NyYz1cIicgKyBzZWxmLmltYWdlU3JjICsgJ1wiPicpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhzZWxmLnpvb21MZW5zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2xpY2soZnVuY3Rpb24gKCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0udHJpZ2dlcignY2xpY2snKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciB0YXJnZXRab29tQ29udGFpbmVyID0gaXNOYU4oc2VsZi5vcHRpb25zLnpvb21XaW5kb3dQb3NpdGlvbikgPyAnYm9keScgOiBzZWxmLnpvb21Db250YWluZXI7XHJcbiAgICAgICAgICAgIC8vY3JlYXRlIHpvb20gd2luZG93XHJcbiAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdyA9ICQoJzxkaXYgc3R5bGU9XCJ6LWluZGV4Ojk5OTsnICtcclxuICAgICAgICAgICAgICAgICdsZWZ0OicgKyAoc2VsZi53aW5kb3dPZmZzZXRMZWZ0KSArICdweDsnICtcclxuICAgICAgICAgICAgICAgICd0b3A6JyArIChzZWxmLndpbmRvd09mZnNldFRvcCkgKyAncHg7JyArIHNlbGYuem9vbVdpbmRvd1N0eWxlICsgJ1wiIGNsYXNzPVwiem9vbVdpbmRvd1wiPiZuYnNwOzwvZGl2PicpXHJcbiAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGFyZ2V0Wm9vbUNvbnRhaW5lcikuY2xpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0udHJpZ2dlcignY2xpY2snKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBzZWxmLnpvb21XaW5kb3dDb250YWluZXIgPSAkKCc8ZGl2Lz4nKS5hZGRDbGFzcygnem9vbVdpbmRvd0NvbnRhaW5lcicpLmNzcygnd2lkdGgnLCBzZWxmLm9wdGlvbnMuem9vbVdpbmRvd1dpZHRoKTtcclxuICAgICAgICAgICAgc2VsZi56b29tV2luZG93LndyYXAoc2VsZi56b29tV2luZG93Q29udGFpbmVyKTtcclxuXHJcbiAgICAgICAgICAgIC8vICBzZWxmLmNhcHRpb25TdHlsZSA9IFwidGV4dC1hbGlnbjogbGVmdDtiYWNrZ3JvdW5kLWNvbG9yOiBibGFjazsnK1xyXG4gICAgICAgICAgICAvLyAnY29sb3I6IHdoaXRlO2ZvbnQtd2VpZ2h0OiBib2xkO3BhZGRpbmc6IDEwcHg7Zm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7Zm9udC1zaXplOiAxMXB4XCI7XHJcbiAgICAgICAgICAgIC8vIHNlbGYuem9vbUNhcHRpb24gPSAkKCc8ZGl2IGNsYXNzPVwiZXpwbHVzLWNhcHRpb25cIiAnK1xyXG4gICAgICAgICAgICAvLyAnc3R5bGU9XCInK3NlbGYuY2FwdGlvblN0eWxlKydkaXNwbGF5OiBibG9jazsgd2lkdGg6IDI4MHB4O1wiPklOU0VSVCBBTFQgVEFHPC9kaXY+JykuYXBwZW5kVG8oc2VsZi56b29tV2luZG93LnBhcmVudCgpKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy5jc3MoJ2JhY2tncm91bmQtaW1hZ2UnLCAndXJsKFwiJyArIHNlbGYuaW1hZ2VTcmMgKyAnXCIpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtaW1hZ2UnLCAndXJsKFwiJyArIHNlbGYuaW1hZ2VTcmMgKyAnXCIpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcygnYmFja2dyb3VuZC1pbWFnZScsICd1cmwoXCInICsgc2VsZi5pbWFnZVNyYyArICdcIiknKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tRU5EIFRIRSBaT09NIFdJTkRPVyBBTkQgTEVOUy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRvdWNoRW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgLy90b3VjaCBldmVudHNcclxuICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0uYmluZCgndG91Y2htb3ZlLmV6cHNwYWNlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRvdWNoID0gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0gfHwgZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0UG9zaXRpb24odG91Y2gpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuYmluZCgndG91Y2htb3ZlLmV6cHNwYWNlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVXaW5kb3coJ3Nob3cnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdG91Y2ggPSBlLm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXSB8fCBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRQb3NpdGlvbih0b3VjaCk7XHJcblxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuYmluZCgndG91Y2hlbmQuZXpwc3BhY2UnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVXaW5kb3coJ2hpZGUnKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNob3dMZW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVMZW5zKCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCAmJiBzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zaG93SGlkZVRpbnQoJ2hpZGUnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICBzZWxmLiRlbGVtLmJpbmQoJ3RvdWNoZW5kLmV6cHNwYWNlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlV2luZG93KCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5zaG93TGVucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlTGVucygnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRpbnQgJiYgc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVUaW50KCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNob3dMZW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy5iaW5kKCd0b3VjaG1vdmUuZXpwc3BhY2UnLCBmdW5jdGlvbiAoZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG91Y2ggPSBlLm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXSB8fCBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0UG9zaXRpb24odG91Y2gpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmJpbmQoJ3RvdWNoZW5kLmV6cHNwYWNlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zaG93SGlkZVdpbmRvdygnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNob3dMZW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlTGVucygnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCAmJiBzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVUaW50KCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL05lZWRlZCB0byB3b3JrIGluIElFXHJcbiAgICAgICAgICAgIHNlbGYuJGVsZW0uYmluZCgnbW91c2Vtb3ZlLmV6cHNwYWNlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm92ZXJXaW5kb3cgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRFbGVtZW50cygnc2hvdycpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgb24gb3JpZW50YXRpb24gY2hhbmdlIHRoZSBzZXRwb3NpdGlvbiBpcyBub3QgZmlyZWRcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmxhc3RYICE9PSBlLmNsaWVudFggfHwgc2VsZi5sYXN0WSAhPT0gZS5jbGllbnRZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRQb3NpdGlvbihlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRMb2MgPSBlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgc2VsZi5sYXN0WCA9IGUuY2xpZW50WDtcclxuICAgICAgICAgICAgICAgIHNlbGYubGFzdFkgPSBlLmNsaWVudFk7XHJcblxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuem9vbUNvbnRhaW5lci5iaW5kKCdjbGljay5lenBzcGFjZScsIHNlbGYub3B0aW9ucy5vbkltYWdlQ2xpY2spO1xyXG5cclxuICAgICAgICAgICAgc2VsZi56b29tQ29udGFpbmVyLmJpbmQoJ21vdXNlbW92ZS5lenBzcGFjZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vdmVyV2luZG93ID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0RWxlbWVudHMoJ3Nob3cnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG1vdXNlTW92ZVpvb21IYW5kbGVyKGUpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIG1vdXNlTW92ZVpvb21IYW5kbGVyKGUpIHtcclxuICAgICAgICAgICAgICAgIC8vc2VsZi5vdmVyV2luZG93ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIC8vbWFrZSBzdXJlIG9uIG9yaWVudGF0aW9uIGNoYW5nZSB0aGUgc2V0cG9zaXRpb24gaXMgbm90IGZpcmVkXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5sYXN0WCAhPT0gZS5jbGllbnRYIHx8IHNlbGYubGFzdFkgIT09IGUuY2xpZW50WSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0UG9zaXRpb24oZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TG9jID0gZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHNlbGYubGFzdFggPSBlLmNsaWVudFg7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmxhc3RZID0gZS5jbGllbnRZO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgZWxlbWVudFRvVHJhY2sgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50VG9UcmFjayA9IHNlbGYuem9vbUxlbnM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy50aW50ICYmIHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudFRvVHJhY2sgPSBzZWxmLnpvb21UaW50O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnRUb1RyYWNrID0gc2VsZi56b29tV2luZG93O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvL3JlZ2lzdGVyIHRoZSBtb3VzZSB0cmFja2luZ1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudFRvVHJhY2spIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnRUb1RyYWNrLmJpbmQoJ21vdXNlbW92ZS5lenBzcGFjZScsIG1vdXNlTW92ZVpvb21IYW5kbGVyKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gIGxlbnNGYWRlT3V0OiA1MDAsICB6b29tVGludEZhZGVJblxyXG4gICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuYWRkKHNlbGYuJGVsZW0pLm1vdXNlZW50ZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3ZlcldpbmRvdyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldEVsZW1lbnRzKCdzaG93Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pLm1vdXNlbGVhdmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxmLnNjcm9sbExvY2spIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldEVsZW1lbnRzKCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLm9uRGVzdHJveShzZWxmLiRlbGVtKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIC8vZW5kIG92ZSBpbWFnZVxyXG5cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93Lm1vdXNlZW50ZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYub3ZlcldpbmRvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRFbGVtZW50cygnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgfSkubW91c2VsZWF2ZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5vdmVyV2luZG93ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL2VuZCBvdmUgaW1hZ2VcclxuXHJcbiAgICAgICAgICAgIC8vIHZhciBkZWx0YSA9IHBhcnNlSW50KGUub3JpZ2luYWxFdmVudC53aGVlbERlbHRhIHx8IC1lLm9yaWdpbmFsRXZlbnQuZGV0YWlsKTtcclxuXHJcbiAgICAgICAgICAgIC8vICAgICAgJCh0aGlzKS5lbXB0eSgpO1xyXG4gICAgICAgICAgICAvLyAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvL2ZpeCBmb3IgaW5pdGlhbCB6b29tIHNldHRpbmdcclxuICAgICAgICAgICAgLy9pZiAoc2VsZi5vcHRpb25zLnpvb21MZXZlbCAhPT0gMSkge1xyXG4gICAgICAgICAgICAvLyAgICBcdHNlbGYuY2hhbmdlWm9vbUxldmVsKHNlbGYuY3VycmVudFpvb21MZXZlbCk7XHJcbiAgICAgICAgICAgIC8vfVxyXG4gICAgICAgICAgICAvL3NldCB0aGUgbWluIHpvb21sZXZlbFxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLm1pblpvb21MZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5taW5ab29tTGV2ZWwgPSBzZWxmLm9wdGlvbnMubWluWm9vbUxldmVsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5taW5ab29tTGV2ZWwgPSBzZWxmLm9wdGlvbnMuc2Nyb2xsWm9vbUluY3JlbWVudCAqIDI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2Nyb2xsWm9vbSkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tQ29udGFpbmVyLmFkZChzZWxmLiRlbGVtKS5iaW5kKCd3aGVlbCBET01Nb3VzZVNjcm9sbCBNb3pNb3VzZVBpeGVsU2Nyb2xsJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbiBJRSB0aGVyZSBpcyBpc3N1ZSB3aXRoIGZpcmluZyBvZiBtb3VzZWxlYXZlIC0gU28gY2hlY2sgd2hldGhlciBzdGlsbCBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgb24gbW91c2VsZWF2ZSBjaGVjayBpZiBzY3JvbGxsb2NrXHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zY3JvbGxMb2NrID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoJC5kYXRhKHRoaXMsICd0aW1lcicpKTtcclxuICAgICAgICAgICAgICAgICAgICAkLmRhdGEodGhpcywgJ3RpbWVyJywgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2Nyb2xsTG9jayA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2RvIHNvbWV0aGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIDI1MCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGhlRXZlbnQgPSBlLm9yaWdpbmFsRXZlbnQuZGVsdGFZIHx8IGUub3JpZ2luYWxFdmVudC5kZXRhaWwgKiAtMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLnNjcm9sbFRvcCArPSAoIGRlbHRhIDwgMCA/IDEgOiAtMSApICogMzA7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGVFdmVudCAvIDEyMCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxpbmcgdXBcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY3VycmVudFpvb21MZXZlbCA+PSBzZWxmLm1pblpvb21MZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2Vab29tTGV2ZWwoc2VsZi5jdXJyZW50Wm9vbUxldmVsIC0gc2VsZi5vcHRpb25zLnNjcm9sbFpvb21JbmNyZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGluZyBkb3duXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIGl0IGhhcyB0byBtYWludGFpbiBvcmlnaW5hbCB6b29tIHdpbmRvdyBhc3BlY3QgcmF0aW8gb3Igbm90XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoIXNlbGYuZnVsbGhlaWdodCAmJiAhc2VsZi5mdWxsd2lkdGgpIHx8ICFzZWxmLm9wdGlvbnMubWFudGFpblpvb21Bc3BlY3RSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5tYXhab29tTGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5jdXJyZW50Wm9vbUxldmVsIDw9IHNlbGYub3B0aW9ucy5tYXhab29tTGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2Vab29tTGV2ZWwocGFyc2VGbG9hdChzZWxmLmN1cnJlbnRab29tTGV2ZWwpICsgc2VsZi5vcHRpb25zLnNjcm9sbFpvb21JbmNyZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYW5keVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlWm9vbUxldmVsKHBhcnNlRmxvYXQoc2VsZi5jdXJyZW50Wm9vbUxldmVsKSArIHNlbGYub3B0aW9ucy5zY3JvbGxab29tSW5jcmVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHNlbGYuJGVsZW0udW5iaW5kKCdlenBzcGFjZScpO1xyXG4gICAgICAgICAgICAkKHNlbGYuem9vbUNvbnRhaW5lcikucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIHNlbGYuZGVsZXRlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZ2V0SWRlbnRpZmllcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHJldHVybiBzZWxmLm9wdGlvbnMuem9vbUlkO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc2V0RWxlbWVudHM6IGZ1bmN0aW9uICh0eXBlKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuem9vbUVuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3Nob3cnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pc1dpbmRvd1NldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zaG93SGlkZVdpbmRvdygnc2hvdycpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnd2luZG93Jykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlV2luZG93KCdzaG93Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2hvd0xlbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zaG93SGlkZUxlbnMoJ3Nob3cnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy50aW50ICYmIHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlVGludCgnc2hvdycpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdoaWRlJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlV2luZG93KCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGYub3B0aW9ucy50aW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zaG93SGlkZVdpbmRvdygnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5zaG93TGVucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2hvd0hpZGVMZW5zKCdoaWRlJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRpbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNob3dIaWRlVGludCgnaGlkZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBzZXRQb3NpdGlvbjogZnVuY3Rpb24gKGUpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgICAgICAgIGlmICghc2VsZi5vcHRpb25zLnpvb21FbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vcmVjYWNsYyBvZmZzZXQgZWFjaCB0aW1lIGluIGNhc2UgdGhlIGltYWdlIG1vdmVzXHJcbiAgICAgICAgICAgIC8vdGhpcyBjYW4gYmUgY2F1c2VkIGJ5IG90aGVyIG9uIHBhZ2UgZWxlbWVudHNcclxuICAgICAgICAgICAgc2VsZi5uekhlaWdodCA9IHNlbGYuJGVsZW0uaGVpZ2h0KCk7XHJcbiAgICAgICAgICAgIHNlbGYubnpXaWR0aCA9IHNlbGYuJGVsZW0ud2lkdGgoKTtcclxuICAgICAgICAgICAgc2VsZi5uek9mZnNldCA9IHNlbGYuJGVsZW0ub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRpbnQgJiYgc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50LmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IDBcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vc2V0IHJlc3BvbnNpdmVcclxuICAgICAgICAgICAgLy93aWxsIGNoZWNraW5nIGlmIHRoZSBpbWFnZSBuZWVkcyBjaGFuZ2luZyBiZWZvcmUgcnVubmluZyB0aGlzIGNvZGUgd29yayBmYXN0ZXI/XHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMucmVzcG9uc2l2ZSAmJiAhc2VsZi5vcHRpb25zLnNjcm9sbFpvb20pIHtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2hvd0xlbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGVuc0hlaWdodCwgbGVuc1dpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm56SGVpZ2h0IDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5zSGVpZ2h0ID0gc2VsZi5uekhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbnNIZWlnaHQgPSBTdHJpbmcoKHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0IC8gc2VsZi5oZWlnaHRSYXRpbykpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5sYXJnZVdpZHRoIDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5zV2lkdGggPSBzZWxmLm56V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5zV2lkdGggPSAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYud2lkdGhSYXRpbyA9IHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubnpXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmhlaWdodFJhdGlvID0gc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubnpIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcG9zc2libHkgZG9udCBuZWVkIHRvIGtlZXAgcmVjYWxjYWxjdWxhdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHRoZSBsZW5zIGlzIGhlaWdoZXIgdGhhbiB0aGUgaW1hZ2UsIHRoZW4gc2V0IGxlbnMgc2l6ZSB0byBpbWFnZSBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm56SGVpZ2h0IDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuc0hlaWdodCA9IHNlbGYubnpIZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuc0hlaWdodCA9IFN0cmluZygoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQgLyBzZWxmLmhlaWdodFJhdGlvKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm56V2lkdGggPCBzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCAvIHNlbGYuaGVpZ2h0UmF0aW8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbnNXaWR0aCA9IHNlbGYubnpXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbnNXaWR0aCA9IFN0cmluZygoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbykpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOiBsZW5zV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JzogbGVuc0hlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludEltYWdlLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJzogc2VsZi5ueldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiBzZWxmLm56SGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBTdHJpbmcoc2VsZi5vcHRpb25zLmxlbnNTaXplKSArICdweCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IFN0cmluZyhzZWxmLm9wdGlvbnMubGVuc1NpemUpICsgJ3B4J1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy9lbmQgcmVzcG9uc2l2ZSBpbWFnZSBjaGFuZ2VcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9jb250YWluZXIgZml4XHJcbiAgICAgICAgICAgIHNlbGYuem9vbUNvbnRhaW5lci5jc3Moe1xyXG4gICAgICAgICAgICAgICAgdG9wOiBzZWxmLm56T2Zmc2V0LnRvcCxcclxuICAgICAgICAgICAgICAgIGxlZnQ6IHNlbGYubnpPZmZzZXQubGVmdFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgc2VsZi5tb3VzZUxlZnQgPSBwYXJzZUludChlLnBhZ2VYIC0gc2VsZi5uek9mZnNldC5sZWZ0KTtcclxuICAgICAgICAgICAgc2VsZi5tb3VzZVRvcCA9IHBhcnNlSW50KGUucGFnZVkgLSBzZWxmLm56T2Zmc2V0LnRvcCk7XHJcbiAgICAgICAgICAgIC8vY2FsY3VsYXRlIHRoZSBMb2NhdGlvbiBvZiB0aGUgTGVuc1xyXG5cclxuICAgICAgICAgICAgLy9jYWxjdWxhdGUgdGhlIGJvdW5kIHJlZ2lvbnMgLSBidXQgb25seSBpZiB6b29tIHdpbmRvd1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnd2luZG93Jykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHpvb21MZW5zSGVpZ2h0ID0gc2VsZi56b29tTGVucy5oZWlnaHQoKSAvIDI7XHJcbiAgICAgICAgICAgICAgICB2YXIgem9vbUxlbnNXaWR0aCA9IHNlbGYuem9vbUxlbnMud2lkdGgoKSAvIDI7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkV0b3Bwb3MgPSAoc2VsZi5tb3VzZVRvcCA8IDAgKyB6b29tTGVuc0hlaWdodCk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkVib3Bwb3MgPSAoc2VsZi5tb3VzZVRvcCA+IHNlbGYubnpIZWlnaHQgLSB6b29tTGVuc0hlaWdodCAtIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlclNpemUgKiAyKSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkVsb3Bwb3MgPSAoc2VsZi5tb3VzZUxlZnQgPCAwICsgem9vbUxlbnNXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkVyb3Bwb3MgPSAoc2VsZi5tb3VzZUxlZnQgPiAoc2VsZi5ueldpZHRoIC0gem9vbUxlbnNXaWR0aCAtIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlclNpemUgKiAyKSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vY2FsY3VsYXRlIHRoZSBib3VuZCByZWdpb25zIC0gYnV0IG9ubHkgZm9yIGlubmVyIHpvb21cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5FdG9wcG9zID0gKHNlbGYubW91c2VUb3AgPCAoKHNlbGYubnpIZWlnaHQgLyAyKSAvIHNlbGYuaGVpZ2h0UmF0aW8pKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuRWJvcHBvcyA9IChzZWxmLm1vdXNlVG9wID4gKHNlbGYubnpIZWlnaHQgLSAoKHNlbGYubnpIZWlnaHQgLyAyKSAvIHNlbGYuaGVpZ2h0UmF0aW8pKSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkVsb3Bwb3MgPSAoc2VsZi5tb3VzZUxlZnQgPCAwICsgKCgoc2VsZi5ueldpZHRoIC8gMikgLyBzZWxmLndpZHRoUmF0aW8pKSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLkVyb3Bwb3MgPSAoc2VsZi5tb3VzZUxlZnQgPiAoc2VsZi5ueldpZHRoIC0gKHNlbGYubnpXaWR0aCAvIDIpIC8gc2VsZi53aWR0aFJhdGlvIC0gKHNlbGYub3B0aW9ucy5sZW5zQm9yZGVyU2l6ZSAqIDIpKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBtb3VzZSBwb3NpdGlvbiBvZiB0aGUgc2xpZGVyIGlzIG9uZSBvZiB0aGUgb3V0ZXJib3VuZHMsIHRoZW4gaGlkZSAgd2luZG93IGFuZCBsZW5zXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm1vdXNlTGVmdCA8IDAgfHwgc2VsZi5tb3VzZVRvcCA8IDAgfHwgc2VsZi5tb3VzZUxlZnQgPiBzZWxmLm56V2lkdGggfHwgc2VsZi5tb3VzZVRvcCA+IHNlbGYubnpIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuc2V0RWxlbWVudHMoJ2hpZGUnKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL2Vsc2UgY29udGludWUgd2l0aCBvcGVyYXRpb25zXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy9sZW5zIG9wdGlvbnNcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2hvd0xlbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL1x0XHRzZWxmLnNob3dIaWRlTGVucygnc2hvdycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGJhY2tncm91bmQgcG9zaXRpb24gb2YgbGVuc1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubGVuc0xlZnRQb3MgPSBTdHJpbmcoTWF0aC5mbG9vcihzZWxmLm1vdXNlTGVmdCAtIHNlbGYuem9vbUxlbnMud2lkdGgoKSAvIDIpKTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmxlbnNUb3BQb3MgPSBTdHJpbmcoTWF0aC5mbG9vcihzZWxmLm1vdXNlVG9wIC0gc2VsZi56b29tTGVucy5oZWlnaHQoKSAvIDIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vYWRqdXN0IHRoZSBiYWNrZ3JvdW5kIHBvc2l0aW9uIGlmIHRoZSBtb3VzZSBpcyBpbiBvbmUgb2YgdGhlIG91dGVyIHJlZ2lvbnNcclxuXHJcbiAgICAgICAgICAgICAgICAvL1RvcCByZWdpb25cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLkV0b3Bwb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmxlbnNUb3BQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy9MZWZ0IFJlZ2lvblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuRWxvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93TGVmdFBvcyA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5sZW5zTGVmdFBvcyA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi50aW50cG9zID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vU2V0IGJvdHRvbSBhbmQgcmlnaHQgcmVnaW9uIGZvciB3aW5kb3cgbW9kZVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5FYm9wcG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGVuc1RvcFBvcyA9IE1hdGgubWF4KChzZWxmLm56SGVpZ2h0KSAtIHNlbGYuem9vbUxlbnMuaGVpZ2h0KCkgLSAoc2VsZi5vcHRpb25zLmxlbnNCb3JkZXJTaXplICogMiksIDApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5Fcm9wcG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGVuc0xlZnRQb3MgPSAoc2VsZi5ueldpZHRoIC0gKHNlbGYuem9vbUxlbnMud2lkdGgoKSkgLSAoc2VsZi5vcHRpb25zLmxlbnNCb3JkZXJTaXplICogMikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vU2V0IGJvdHRvbSBhbmQgcmlnaHQgcmVnaW9uIGZvciBpbm5lciBtb2RlXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuRWJvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxlbnNUb3BQb3MgPSBNYXRoLm1heCgoKHNlbGYubnpIZWlnaHQpIC0gKHNlbGYub3B0aW9ucy5sZW5zQm9yZGVyU2l6ZSAqIDIpKSwgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLkVyb3Bwb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sZW5zTGVmdFBvcyA9IChzZWxmLm56V2lkdGggLSAoc2VsZi5ueldpZHRoKSAtIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlclNpemUgKiAyKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy9pZiBsZW5zIHpvb21cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd0xlZnRQb3MgPSBTdHJpbmcoKChlLnBhZ2VYIC0gc2VsZi5uek9mZnNldC5sZWZ0KSAqIHNlbGYud2lkdGhSYXRpbyAtIHNlbGYuem9vbUxlbnMud2lkdGgoKSAvIDIpICogKC0xKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dUb3BQb3MgPSBTdHJpbmcoKChlLnBhZ2VZIC0gc2VsZi5uek9mZnNldC50b3ApICogc2VsZi5oZWlnaHRSYXRpbyAtIHNlbGYuem9vbUxlbnMuaGVpZ2h0KCkgLyAyKSAqICgtMSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKCdiYWNrZ3JvdW5kLXBvc2l0aW9uJywgc2VsZi53aW5kb3dMZWZ0UG9zICsgJ3B4ICcgKyBzZWxmLndpbmRvd1RvcFBvcyArICdweCcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5jaGFuZ2VCZ1NpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYubnpIZWlnaHQgPiBzZWxmLm56V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKCdiYWNrZ3JvdW5kLXNpemUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcygnYmFja2dyb3VuZC1zaXplJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm5ld3ZhbHVld2lkdGggKyAncHggJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldFdpbmRvd1Bvc2l0aW9uKGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy9pZiB0aW50IHpvb21cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCAmJiBzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldFRpbnRQb3NpdGlvbihlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vc2V0IHRoZSBjc3MgYmFja2dyb3VuZCBwb3NpdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldFdpbmRvd1Bvc2l0aW9uKGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0V2luZG93UG9zaXRpb24oZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNob3dMZW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuZnVsbHdpZHRoICYmIHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGVuc0xlZnRQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IHNlbGYubGVuc0xlZnRQb3MgKyAncHgnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IHNlbGYubGVuc1RvcFBvcyArICdweCdcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0gLy9lbmQgZWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc2hvd0hpZGVab29tQ29udGFpbmVyOiBmdW5jdGlvbiAoY2hhbmdlKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKGNoYW5nZSA9PT0gJ3Nob3cnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi56b29tQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tQ29udGFpbmVyLnNob3coKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoY2hhbmdlID09PSAnaGlkZScpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLnpvb21Db250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBzaG93SGlkZVdpbmRvdzogZnVuY3Rpb24gKGNoYW5nZSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICdzaG93Jykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxmLmlzV2luZG93QWN0aXZlICYmIHNlbGYuem9vbVdpbmRvdykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5vblNob3coc2VsZik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tV2luZG93RmFkZUluKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5zdG9wKHRydWUsIHRydWUsIGZhbHNlKS5mYWRlSW4oc2VsZi5vcHRpb25zLnpvb21XaW5kb3dGYWRlSW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pc1dpbmRvd0FjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNoYW5nZSA9PT0gJ2hpZGUnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pc1dpbmRvd0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0ZhZGVPdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LnN0b3AodHJ1ZSwgdHJ1ZSkuZmFkZU91dChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0ZhZGVPdXQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmxvb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3N0b3AgbW92aW5nIHRoZSB6b29tIHdpbmRvdyB3aGVuIHpvb20gd2luZG93IGlzIGZhZGVkIG91dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoc2VsZi5sb29wKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxvb3AgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmlzV2luZG93QWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIHNob3dIaWRlTGVuczogZnVuY3Rpb24gKGNoYW5nZSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICdzaG93Jykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxmLmlzTGVuc0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMubGVuc0ZhZGVJbiAmJiBzZWxmLnpvb21MZW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuc3RvcCh0cnVlLCB0cnVlLCBmYWxzZSkuZmFkZUluKHNlbGYub3B0aW9ucy5sZW5zRmFkZUluKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmlzTGVuc0FjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNoYW5nZSA9PT0gJ2hpZGUnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pc0xlbnNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmxlbnNGYWRlT3V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuc3RvcCh0cnVlLCB0cnVlKS5mYWRlT3V0KHNlbGYub3B0aW9ucy5sZW5zRmFkZU91dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pc0xlbnNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc2hvd0hpZGVUaW50OiBmdW5jdGlvbiAoY2hhbmdlKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKGNoYW5nZSA9PT0gJ3Nob3cnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGYuaXNUaW50QWN0aXZlICYmIHNlbGYuem9vbVRpbnQpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVGludEZhZGVJbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50LmNzcygnb3BhY2l0eScsIHNlbGYub3B0aW9ucy50aW50T3BhY2l0eSkuYW5pbWF0ZSgpLnN0b3AodHJ1ZSwgdHJ1ZSkuZmFkZUluKCdzbG93Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50LmNzcygnb3BhY2l0eScsIHNlbGYub3B0aW9ucy50aW50T3BhY2l0eSkuYW5pbWF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pc1RpbnRBY3RpdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICdoaWRlJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNUaW50QWN0aXZlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVRpbnRGYWRlT3V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnQuc3RvcCh0cnVlLCB0cnVlKS5mYWRlT3V0KHNlbGYub3B0aW9ucy56b29tVGludEZhZGVPdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludC5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaXNUaW50QWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzZXRMZW5zUG9zaXRpb246IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgc2V0V2luZG93UG9zaXRpb246IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIC8vcmV0dXJuIG9iai5zbGljZSggMCwgY291bnQgKTtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpc05hTihzZWxmLm9wdGlvbnMuem9vbVdpbmRvd1Bvc2l0aW9uKSkge1xyXG5cclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dQb3NpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTogLy9kb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0VG9wID0gKHNlbGYub3B0aW9ucy56b29tV2luZG93T2Zmc2V0WSk7Ly9ET05FIC0gMVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoK3NlbGYubnpXaWR0aCk7IC8vRE9ORSAxLCAyLCAzLCA0LCAxNlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCA+IHNlbGYubnpIZWlnaHQpIHsgLy9wb3NpdGl2ZSBtYXJnaW5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldFRvcCA9ICgoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQgLyAyKSAtIChzZWxmLm56SGVpZ2h0IC8gMikpICogKC0xKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9IChzZWxmLm56V2lkdGgpOyAvL0RPTkUgMSwgMiwgMywgNCwgMTZcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsgLy9uZWdhdGl2ZSBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQubm9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzogLy9kb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0VG9wID0gKHNlbGYubnpIZWlnaHQgLSBzZWxmLnpvb21XaW5kb3cuaGVpZ2h0KCkgLSAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSk7IC8vRE9ORSAzLDlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRMZWZ0ID0gKHNlbGYubnpXaWR0aCk7IC8vRE9ORSAxLCAyLCAzLCA0LCAxNlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IC8vZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldFRvcCA9IChzZWxmLm56SGVpZ2h0KTsgLy9ET05FIC0gNCw1LDYsNyw4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9IChzZWxmLm56V2lkdGgpOyAvL0RPTkUgMSwgMiwgMywgNCwgMTZcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiAvL2RvbmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi5uekhlaWdodCk7IC8vRE9ORSAtIDQsNSw2LDcsOFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi5ueldpZHRoIC0gc2VsZi56b29tV2luZG93LndpZHRoKCkgLSAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSk7IC8vRE9ORSAtIDUsMTVcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQgPiBzZWxmLm56SGVpZ2h0KSB7IC8vcG9zaXRpdmUgbWFyZ2luXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldFRvcCA9IChzZWxmLm56SGVpZ2h0KTsgIC8vRE9ORSAtIDQsNSw2LDcsOFxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9ICgoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIDIpIC0gKHNlbGYubnpXaWR0aCAvIDIpICsgKHNlbGYub3B0aW9ucy5ib3JkZXJTaXplICogMikpICogKC0xKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsgLy9uZWdhdGl2ZSBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQubm9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDc6IC8vZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldFRvcCA9IChzZWxmLm56SGVpZ2h0KTsgIC8vRE9ORSAtIDQsNSw2LDcsOFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAwOyAvL0RPTkUgNywgMTNcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA4OiAvL2RvbmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi5uekhlaWdodCk7IC8vRE9ORSAtIDQsNSw2LDcsOFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi56b29tV2luZG93LndpZHRoKCkgKyAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSkgKiAoLTEpOyAgLy9ET05FIDgsOSwxMCwxMSwxMlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDk6ICAvL2RvbmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi5uekhlaWdodCAtIHNlbGYuem9vbVdpbmRvdy5oZWlnaHQoKSAtIChzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSAqIDIpKTsgLy9ET05FIDMsOVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi56b29tV2luZG93LndpZHRoKCkgKyAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSkgKiAoLTEpOyAgLy9ET05FIDgsOSwxMCwxMSwxMlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEwOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQgPiBzZWxmLm56SGVpZ2h0KSB7IC8vcG9zaXRpdmUgbWFyZ2luXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoKHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0IC8gMikgLSAoc2VsZi5uekhlaWdodCAvIDIpKSAqICgtMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi56b29tV2luZG93LndpZHRoKCkgKyAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSkgKiAoLTEpOyAgLy9ET05FIDgsOSwxMCwxMSwxMlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvL25lZ2F0aXZlIG1hcmdpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJC5ub29wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dPZmZzZXRZKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRMZWZ0ID0gKHNlbGYuem9vbVdpbmRvdy53aWR0aCgpICsgKHNlbGYub3B0aW9ucy5ib3JkZXJTaXplICogMikpICogKC0xKTsgIC8vRE9ORSA4LDksMTAsMTEsMTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjogLy9kb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0VG9wID0gKHNlbGYuem9vbVdpbmRvdy5oZWlnaHQoKSArIChzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSAqIDIpKSAqICgtMSk7IC8vRE9ORSAxMiwxMywxNCwxNSwxNlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi56b29tV2luZG93LndpZHRoKCkgKyAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSkgKiAoLTEpOyAgLy9ET05FIDgsOSwxMCwxMSwxMlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOiAvL2RvbmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi56b29tV2luZG93LmhlaWdodCgpICsgKHNlbGYub3B0aW9ucy5ib3JkZXJTaXplICogMikpICogKC0xKTsgLy9ET05FIDEyLDEzLDE0LDE1LDE2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9ICgwKTsgLy9ET05FIDcsIDEzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCA+IHNlbGYubnpIZWlnaHQpIHsgLy9wb3NpdGl2ZSBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0VG9wID0gKHNlbGYuem9vbVdpbmRvdy5oZWlnaHQoKSArIChzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSAqIDIpKSAqICgtMSk7IC8vRE9ORSAxMiwxMywxNCwxNSwxNlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9ICgoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIDIpIC0gKHNlbGYubnpXaWR0aCAvIDIpICsgKHNlbGYub3B0aW9ucy5ib3JkZXJTaXplICogMikpICogKC0xKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsgLy9uZWdhdGl2ZSBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQubm9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTU6Ly9kb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0VG9wID0gKHNlbGYuem9vbVdpbmRvdy5oZWlnaHQoKSArIChzZWxmLm9wdGlvbnMuYm9yZGVyU2l6ZSAqIDIpKSAqICgtMSk7IC8vRE9ORSAxMiwxMywxNCwxNSwxNlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSAoc2VsZi5ueldpZHRoIC0gc2VsZi56b29tV2luZG93LndpZHRoKCkgLSAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSk7IC8vRE9ORSAtIDUsMTVcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjogIC8vZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldFRvcCA9IChzZWxmLnpvb21XaW5kb3cuaGVpZ2h0KCkgKyAoc2VsZi5vcHRpb25zLmJvcmRlclNpemUgKiAyKSkgKiAoLTEpOyAvL0RPTkUgMTIsMTMsMTQsMTUsMTZcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRMZWZ0ID0gKHNlbGYubnpXaWR0aCk7IC8vRE9ORSAxLCAyLCAzLCA0LCAxNlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiAvL2RvbmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSAoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dPZmZzZXRZKTsvL0RPTkUgLSAxXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud2luZG93T2Zmc2V0TGVmdCA9IChzZWxmLm56V2lkdGgpOyAvL0RPTkUgMSwgMiwgMywgNCwgMTZcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSAvL2VuZCBpc05BTlxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIEZvciBCQyBwdXJwb3NlcywgdHJlYXQgcGFzc2VkIGVsZW1lbnQgYXMgSUQgaWYgZWxlbWVudCBub3QgZm91bmRcclxuICAgICAgICAgICAgICAgIHNlbGYuZXh0ZXJuYWxDb250YWluZXIgPSAkKHNlbGYub3B0aW9ucy56b29tV2luZG93UG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWxmLmV4dGVybmFsQ29udGFpbmVyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZXh0ZXJuYWxDb250YWluZXIgPSAkKCcjJyArIHNlbGYub3B0aW9ucy56b29tV2luZG93UG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHNlbGYuZXh0ZXJuYWxDb250YWluZXJXaWR0aCA9IHNlbGYuZXh0ZXJuYWxDb250YWluZXIud2lkdGgoKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuZXh0ZXJuYWxDb250YWluZXJIZWlnaHQgPSBzZWxmLmV4dGVybmFsQ29udGFpbmVyLmhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5leHRlcm5hbENvbnRhaW5lck9mZnNldCA9IHNlbGYuZXh0ZXJuYWxDb250YWluZXIub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSBzZWxmLmV4dGVybmFsQ29udGFpbmVyT2Zmc2V0LnRvcDsvL0RPTkUgLSAxXHJcbiAgICAgICAgICAgICAgICBzZWxmLndpbmRvd09mZnNldExlZnQgPSBzZWxmLmV4dGVybmFsQ29udGFpbmVyT2Zmc2V0LmxlZnQ7IC8vRE9ORSAxLCAyLCAzLCA0LCAxNlxyXG5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZWxmLmlzV2luZG93U2V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRUb3AgPSBzZWxmLndpbmRvd09mZnNldFRvcCArIHNlbGYub3B0aW9ucy56b29tV2luZG93T2Zmc2V0WTtcclxuICAgICAgICAgICAgc2VsZi53aW5kb3dPZmZzZXRMZWZ0ID0gc2VsZi53aW5kb3dPZmZzZXRMZWZ0ICsgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dPZmZzZXRYO1xyXG5cclxuICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcyh7XHJcbiAgICAgICAgICAgICAgICB0b3A6IHNlbGYud2luZG93T2Zmc2V0VG9wLFxyXG4gICAgICAgICAgICAgICAgbGVmdDogc2VsZi53aW5kb3dPZmZzZXRMZWZ0XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IDBcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zID0gU3RyaW5nKCgoZS5wYWdlWCAtIHNlbGYubnpPZmZzZXQubGVmdCkgKiBzZWxmLndpZHRoUmF0aW8gLSBzZWxmLnpvb21XaW5kb3cud2lkdGgoKSAvIDIpICogKC0xKSk7XHJcbiAgICAgICAgICAgIHNlbGYud2luZG93VG9wUG9zID0gU3RyaW5nKCgoZS5wYWdlWSAtIHNlbGYubnpPZmZzZXQudG9wKSAqIHNlbGYuaGVpZ2h0UmF0aW8gLSBzZWxmLnpvb21XaW5kb3cuaGVpZ2h0KCkgLyAyKSAqICgtMSkpO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5FdG9wcG9zKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLndpbmRvd1RvcFBvcyA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYuRWxvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5FYm9wcG9zKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLndpbmRvd1RvcFBvcyA9IChzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5jdXJyZW50Wm9vbUxldmVsIC0gc2VsZi56b29tV2luZG93LmhlaWdodCgpKSAqICgtMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYuRXJvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zID0gKChzZWxmLmxhcmdlV2lkdGggLyBzZWxmLmN1cnJlbnRab29tTGV2ZWwgLSBzZWxmLnpvb21XaW5kb3cud2lkdGgoKSkgKiAoLTEpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9zdG9wcyBtaWNybyBtb3ZlbWVudHNcclxuICAgICAgICAgICAgaWYgKHNlbGYuZnVsbGhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi53aW5kb3dUb3BQb3MgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzZWxmLmZ1bGx3aWR0aCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zID0gMDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9zZXQgdGhlIGNzcyBiYWNrZ3JvdW5kIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICd3aW5kb3cnIHx8IHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLnpvb21Mb2NrID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9vdmVycmlkZXMgZm9yIGltYWdlcyBub3Qgem9vbWFibGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi53aWR0aFJhdGlvIDw9IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuaGVpZ2h0UmF0aW8gPD0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd1RvcFBvcyA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gYWRqdXN0IGltYWdlcyBsZXNzIHRoYW4gdGhlIHdpbmRvdyBoZWlnaHRcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnd2luZG93Jykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmxhcmdlSGVpZ2h0IDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dUb3BQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5sYXJnZVdpZHRoIDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd0xlZnRQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vc2V0IHRoZSB6b29td2luZG93IGJhY2tncm91bmQgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZWFzaW5nKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICBpZihzZWxmLmNoYW5nZVpvb20pe1xyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICBjbGVhckludGVydmFsKHNlbGYubG9vcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgIHNlbGYuY2hhbmdlWm9vbSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICBzZWxmLmxvb3AgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgdGhlIHBvcyB0byAwIGlmIG5vdCBzZXRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNlbGYueHApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi54cCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZi55cCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnlwID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiBsb29wIG5vdCBhbHJlYWR5IHN0YXJ0ZWQsIHRoZW4gcnVuIGl0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxmLmxvb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sb29wID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91c2luZyB6ZW5vJ3MgcGFyYWRveFxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYueHAgKz0gKHNlbGYud2luZG93TGVmdFBvcyAtIHNlbGYueHApIC8gc2VsZi5vcHRpb25zLmVhc2luZ0Ftb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYueXAgKz0gKHNlbGYud2luZG93VG9wUG9zIC0gc2VsZi55cCkgLyBzZWxmLm9wdGlvbnMuZWFzaW5nQW1vdW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuc2Nyb2xsaW5nTG9jaykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHNlbGYubG9vcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi54cCA9IHNlbGYud2luZG93TGVmdFBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnlwID0gc2VsZi53aW5kb3dUb3BQb3M7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYueHAgPSAoKGUucGFnZVggLSBzZWxmLm56T2Zmc2V0LmxlZnQpICogc2VsZi53aWR0aFJhdGlvIC0gc2VsZi56b29tV2luZG93LndpZHRoKCkgLyAyKSAqICgtMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi55cCA9ICgoKGUucGFnZVkgLSBzZWxmLm56T2Zmc2V0LnRvcCkgKiBzZWxmLmhlaWdodFJhdGlvIC0gc2VsZi56b29tV2luZG93LmhlaWdodCgpIC8gMikgKiAoLTEpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuY2hhbmdlQmdTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm56SGVpZ2h0ID4gc2VsZi5ueldpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnbGVucycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcygnYmFja2dyb3VuZC1zaXplJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWVoZWlnaHQgKyAncHgnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWVoZWlnaHQgKyAncHgnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZXdpZHRoICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VIZWlnaHQgLyBzZWxmLm5ld3ZhbHVld2lkdGggKyAncHgnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFzZWxmLmJneHApe3NlbGYuYmd4cCA9IHNlbGYubGFyZ2VXaWR0aC9zZWxmLm5ld3ZhbHVlO31cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFzZWxmLmJneXApe3NlbGYuYmd5cCA9IHNlbGYubGFyZ2VIZWlnaHQvc2VsZi5uZXd2YWx1ZSA7fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxmLmJnbG9vcCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmJnbG9vcCA9IHNldEludGVydmFsKGZ1bmN0aW9uKCl7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5iZ3hwICs9IChzZWxmLmxhcmdlV2lkdGgvc2VsZi5uZXd2YWx1ZSAgLSBzZWxmLmJneHApIC8gc2VsZi5vcHRpb25zLmVhc2luZ0Ftb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYmd5cCArPSAoc2VsZi5sYXJnZUhlaWdodC9zZWxmLm5ld3ZhbHVlICAtIHNlbGYuYmd5cCkgLyBzZWxmLm9wdGlvbnMuZWFzaW5nQW1vdW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsIHNlbGYuYmd4cCArICdweCAnICsgc2VsZi5iZ3lwICsgJ3B4JyApO1xyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAxNik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2VCZ1NpemUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtcG9zaXRpb24nLCBzZWxmLndpbmRvd0xlZnRQb3MgKyAncHggJyArIHNlbGYud2luZG93VG9wUG9zICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zY3JvbGxpbmdMb2NrID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sb29wID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoTWF0aC5yb3VuZChNYXRoLmFicyhzZWxmLnhwIC0gc2VsZi53aW5kb3dMZWZ0UG9zKSArIE1hdGguYWJzKHNlbGYueXAgLSBzZWxmLndpbmRvd1RvcFBvcykpIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RvcHMgbWljcm8gbW92ZW1lbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChzZWxmLmxvb3ApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtcG9zaXRpb24nLCBzZWxmLndpbmRvd0xlZnRQb3MgKyAncHggJyArIHNlbGYud2luZG93VG9wUG9zICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sb29wID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5jaGFuZ2VCZ1NpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYubnpIZWlnaHQgPiBzZWxmLm56V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKCdiYWNrZ3JvdW5kLXNpemUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcygnYmFja2dyb3VuZC1zaXplJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VIZWlnaHQgLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnbGVucycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcygnYmFja2dyb3VuZC1zaXplJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZXdpZHRoICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZXdpZHRoICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuY3NzKCdiYWNrZ3JvdW5kLXNpemUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZXdpZHRoICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2VCZ1NpemUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtcG9zaXRpb24nLCBzZWxmLnhwICsgJ3B4ICcgKyBzZWxmLnlwICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDE2KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5jaGFuZ2VCZ1NpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYubnpIZWlnaHQgPiBzZWxmLm56V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdsZW5zJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKCdiYWNrZ3JvdW5kLXNpemUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZWhlaWdodCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tTGVucy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uZXd2YWx1ZXdpZHRoKSA8IHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubmV3dmFsdWV3aWR0aCArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VXaWR0aCAvIHNlbGYubmV3dmFsdWVoZWlnaHQgKyAncHggJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGFyZ2VIZWlnaHQgLyBzZWxmLm5ld3ZhbHVlaGVpZ2h0ICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuY3NzKCdiYWNrZ3JvdW5kLXBvc2l0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53aW5kb3dMZWZ0UG9zICsgJ3B4ICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpbmRvd1RvcFBvcyArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgc2V0VGludFBvc2l0aW9uOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHZhciB6b29tTGVuc1dpZHRoID0gc2VsZi56b29tTGVucy53aWR0aCgpO1xyXG4gICAgICAgICAgICB2YXIgem9vbUxlbnNIZWlnaHQgPSBzZWxmLnpvb21MZW5zLmhlaWdodCgpO1xyXG4gICAgICAgICAgICBzZWxmLm56T2Zmc2V0ID0gc2VsZi4kZWxlbS5vZmZzZXQoKTtcclxuICAgICAgICAgICAgc2VsZi50aW50cG9zID0gU3RyaW5nKCgoZS5wYWdlWCAtIHNlbGYubnpPZmZzZXQubGVmdCkgLSAoem9vbUxlbnNXaWR0aCAvIDIpKSAqICgtMSkpO1xyXG4gICAgICAgICAgICBzZWxmLnRpbnRwb3N5ID0gU3RyaW5nKCgoZS5wYWdlWSAtIHNlbGYubnpPZmZzZXQudG9wKSAtIHpvb21MZW5zSGVpZ2h0IC8gMikgKiAoLTEpKTtcclxuICAgICAgICAgICAgaWYgKHNlbGYuRXRvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi50aW50cG9zeSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNlbGYuRWxvcHBvcykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi50aW50cG9zID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5FYm9wcG9zKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnRpbnRwb3N5ID0gKHNlbGYubnpIZWlnaHQgLSB6b29tTGVuc0hlaWdodCAtIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlclNpemUgKiAyKSkgKiAoLTEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzZWxmLkVyb3Bwb3MpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYudGludHBvcyA9ICgoc2VsZi5ueldpZHRoIC0gem9vbUxlbnNXaWR0aCAtIChzZWxmLm9wdGlvbnMubGVuc0JvcmRlclNpemUgKiAyKSkgKiAoLTEpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnRpbnQpIHtcclxuICAgICAgICAgICAgICAgIC8vc3RvcHMgbWljcm8gbW92ZW1lbnRzXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5mdWxsaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi50aW50cG9zeSA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuZnVsbHdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi50aW50cG9zID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50SW1hZ2UuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAnbGVmdCc6IHNlbGYudGludHBvcyArICdweCcsXHJcbiAgICAgICAgICAgICAgICAgICAgJ3RvcCc6IHNlbGYudGludHBvc3kgKyAncHgnXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHN3YXB0aGVpbWFnZTogZnVuY3Rpb24gKHNtYWxsaW1hZ2UsIGxhcmdlaW1hZ2UpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICB2YXIgbmV3SW1nID0gbmV3IEltYWdlKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmxvYWRpbmdJY29uKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnNwaW5uZXIgPSAkKCc8ZGl2IHN0eWxlPVwiJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQ6IHVybChcXCcnICsgc2VsZi5vcHRpb25zLmxvYWRpbmdJY29uICsgJ1xcJykgbm8tcmVwZWF0IGNlbnRlcjsnICtcclxuICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0OicgKyBzZWxmLm56SGVpZ2h0ICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICd3aWR0aDonICsgc2VsZi5ueldpZHRoICsgJ3B4OycgK1xyXG4gICAgICAgICAgICAgICAgICAgICd6LWluZGV4OiAyMDAwO3Bvc2l0aW9uOiBhYnNvbHV0ZTsgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciBjZW50ZXI7XCI+PC9kaXY+Jyk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLiRlbGVtLmFmdGVyKHNlbGYuc3Bpbm5lcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5vbkltYWdlU3dhcChzZWxmLiRlbGVtKTtcclxuXHJcbiAgICAgICAgICAgIG5ld0ltZy5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmxhcmdlV2lkdGggPSBuZXdJbWcud2lkdGg7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmxhcmdlSGVpZ2h0ID0gbmV3SW1nLmhlaWdodDtcclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbUltYWdlID0gbGFyZ2VpbWFnZTtcclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoJ2JhY2tncm91bmQtc2l6ZScsIHNlbGYubGFyZ2VXaWR0aCArICdweCAnICsgc2VsZi5sYXJnZUhlaWdodCArICdweCcpO1xyXG5cclxuICAgICAgICAgICAgICAgIHNlbGYuc3dhcEFjdGlvbihzbWFsbGltYWdlLCBsYXJnZWltYWdlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgc2VsZi5zZXRJbWFnZVNvdXJjZShuZXdJbWcsIGxhcmdlaW1hZ2UpOyAgLy8gdGhpcyBtdXN0IGJlIGRvbmUgQUZURVIgc2V0dGluZyBvbmxvYWRcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzd2FwQWN0aW9uOiBmdW5jdGlvbiAoc21hbGxpbWFnZSwgbGFyZ2VpbWFnZSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHZhciBlbGVtV2lkdGggPSBzZWxmLiRlbGVtLndpZHRoKCk7XHJcbiAgICAgICAgICAgIHZhciBlbGVtSGVpZ2h0ID0gc2VsZi4kZWxlbS5oZWlnaHQoKTtcclxuICAgICAgICAgICAgdmFyIG5ld0ltZzIgPSBuZXcgSW1hZ2UoKTtcclxuICAgICAgICAgICAgbmV3SW1nMi5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAvL3JlLWNhbGN1bGF0ZSB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIHNlbGYubnpIZWlnaHQgPSBuZXdJbWcyLmhlaWdodDtcclxuICAgICAgICAgICAgICAgIHNlbGYubnpXaWR0aCA9IG5ld0ltZzIud2lkdGg7XHJcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMub25JbWFnZVN3YXBDb21wbGV0ZShzZWxmLiRlbGVtKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzZWxmLmRvbmVDYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzZWxmLnNldEltYWdlU291cmNlKG5ld0ltZzIsIHNtYWxsaW1hZ2UpO1xyXG5cclxuICAgICAgICAgICAgLy9yZXNldCB0aGUgem9vbWxldmVsIHRvIHRoYXQgaW5pdGlhbGx5IHNldCBpbiBvcHRpb25zXHJcbiAgICAgICAgICAgIHNlbGYuY3VycmVudFpvb21MZXZlbCA9IHNlbGYub3B0aW9ucy56b29tTGV2ZWw7XHJcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5tYXhab29tTGV2ZWwgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIC8vc3dhcHMgdGhlIG1haW4gaW1hZ2VcclxuICAgICAgICAgICAgLy9zZWxmLiRlbGVtLmF0dHIoJ3NyYycsc21hbGxpbWFnZSk7XHJcbiAgICAgICAgICAgIC8vc3dhcHMgdGhlIHpvb20gaW1hZ2VcclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcygnYmFja2dyb3VuZC1pbWFnZScsICd1cmwoXCInICsgbGFyZ2VpbWFnZSArICdcIiknKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnd2luZG93Jykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcygnYmFja2dyb3VuZC1pbWFnZScsICd1cmwoXCInICsgbGFyZ2VpbWFnZSArICdcIiknKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJywgJ3VybChcIicgKyBsYXJnZWltYWdlICsgJ1wiKScpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRJbWFnZSA9IGxhcmdlaW1hZ2U7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmltYWdlQ3Jvc3NmYWRlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2xkSW1nID0gc2VsZi4kZWxlbTtcclxuICAgICAgICAgICAgICAgIHZhciBuZXdJbWcgPSBvbGRJbWcuY2xvbmUoKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0uYXR0cignc3JjJywgc21hbGxpbWFnZSk7XHJcbiAgICAgICAgICAgICAgICBzZWxmLiRlbGVtLmFmdGVyKG5ld0ltZyk7XHJcbiAgICAgICAgICAgICAgICBuZXdJbWcuc3RvcCh0cnVlKS5mYWRlT3V0KHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICQodGhpcykucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBpZihzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdpbm5lcicpe1xyXG4gICAgICAgICAgICAgICAgLy9yZW1vdmUgYW55IGF0dHJpYnV0ZXMgb24gdGhlIGNsb25lZCBpbWFnZSBzbyB3ZSBjYW4gcmVzaXplIGxhdGVyXHJcbiAgICAgICAgICAgICAgICBzZWxmLiRlbGVtLndpZHRoKCdhdXRvJykucmVtb3ZlQXR0cignd2lkdGgnKTtcclxuICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0uaGVpZ2h0KCdhdXRvJykucmVtb3ZlQXR0cignaGVpZ2h0Jyk7XHJcbiAgICAgICAgICAgICAgICAvLyAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBvbGRJbWcuZmFkZUluKHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy50aW50ICYmIHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2xkSW1nVGludCA9IHNlbGYuem9vbVRpbnRJbWFnZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SW1nVGludCA9IG9sZEltZ1RpbnQuY2xvbmUoKTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50SW1hZ2UuYXR0cignc3JjJywgbGFyZ2VpbWFnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludEltYWdlLmFmdGVyKG5ld0ltZ1RpbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0ltZ1RpbnQuc3RvcCh0cnVlKS5mYWRlT3V0KHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBvbGRJbWdUaW50LmZhZGVJbihzZWxmLm9wdGlvbnMuaW1hZ2VDcm9zc2ZhZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NlbGYuem9vbVRpbnRJbWFnZS5hdHRyKCd3aWR0aCcsZWxlbS5kYXRhKCdpbWFnZScpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZXNpemUgdGhlIHRpbnQgd2luZG93XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludC5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGVsZW1IZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBlbGVtV2lkdGhcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JzogZWxlbUhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOiBlbGVtV2lkdGhcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNlbGYub3B0aW9ucy5jb25zdHJhaW5UeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdyYXAucGFyZW50KCkuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiBlbGVtSGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJzogZWxlbVdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tV2luZG93LmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JzogZWxlbUhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IGVsZW1XaWR0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdyYXAuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCc6IGVsZW1IZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IGVsZW1XaWR0aFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2VsZi4kZWxlbS5hdHRyKCdzcmMnLCBzbWFsbGltYWdlKTtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnRJbWFnZS5hdHRyKCdzcmMnLCBsYXJnZWltYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAvL3NlbGYuem9vbVRpbnRJbWFnZS5hdHRyKCd3aWR0aCcsZWxlbS5kYXRhKCdpbWFnZScpKTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21UaW50SW1hZ2UuYXR0cignaGVpZ2h0JywgZWxlbUhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZWxmLnpvb21UaW50SW1hZ2UuYXR0cignc3JjJykgPSBlbGVtLmRhdGEoJ2ltYWdlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludEltYWdlLmNzcygnaGVpZ2h0JywgZWxlbUhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludC5jc3MoJ2hlaWdodCcsIGVsZW1IZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbUNvbnRhaW5lci5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiBlbGVtSGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IGVsZW1XaWR0aFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdyYXAuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCc6IGVsZW1IZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IGVsZW1XaWR0aFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuY29uc3RyYWluVHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vVGhpcyB3aWxsIGNvbnRyYWluIHRoZSBpbWFnZSBwcm9wb3J0aW9uc1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jb25zdHJhaW5UeXBlID09PSAnaGVpZ2h0Jykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1dEaW1lbnNpb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiBzZWxmLm9wdGlvbnMuY29uc3RyYWluU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJzogJ2F1dG8nXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuY3NzKGF1dG9XRGltZW5zaW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XcmFwLmNzcyhhdXRvV0RpbWVuc2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uc3R3aWR0aCA9IHNlbGYuem9vbVdyYXAud2lkdGgoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGVsZW0uY3NzKGF1dG9XRGltZW5zaW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jb25zdHdpZHRoID0gZWxlbVdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0V0RpbSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCc6IHNlbGYub3B0aW9ucy5jb25zdHJhaW5TaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOiBzZWxmLmNvbnN0d2lkdGhcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgPT09ICdpbm5lcicpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdyYXAucGFyZW50KCkuY3NzKGNvbnN0V0RpbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVdpbmRvdy5jc3MoY29uc3RXRGltKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy50aW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGludENvbnRhaW5lci5jc3MoY29uc3RXRGltKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludC5jc3MoY29uc3RXRGltKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVGludEltYWdlLmNzcyhjb25zdFdEaW0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmNvbnN0cmFpblR5cGUgPT09ICd3aWR0aCcpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b0hEaW1lbnNpb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiAnYXV0bycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3aWR0aCc6IHNlbGYub3B0aW9ucy5jb25zdHJhaW5TaXplXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Db250YWluZXIuY3NzKGF1dG9IRGltZW5zaW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5pbWFnZUNyb3NzZmFkZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XcmFwLmNzcyhhdXRvSERpbWVuc2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uc3RoZWlnaHQgPSBzZWxmLnpvb21XcmFwLmhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi4kZWxlbS5jc3MoYXV0b0hEaW1lbnNpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbnN0aGVpZ2h0ID0gZWxlbUhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb25zdEhEaW0gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdoZWlnaHQnOiBzZWxmLmNvbnN0aGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOiBzZWxmLm9wdGlvbnMuY29uc3RyYWluU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XcmFwLnBhcmVudCgpLmNzcyhjb25zdEhEaW0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuY3NzKGNvbnN0SERpbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMudGludCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnRpbnRDb250YWluZXIuY3NzKGNvbnN0SERpbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnQuY3NzKGNvbnN0SERpbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbVRpbnRJbWFnZS5jc3MoY29uc3RIRGltKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBkb25lQ2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmxvYWRpbmdJY29uKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnNwaW5uZXIuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzZWxmLm56T2Zmc2V0ID0gc2VsZi4kZWxlbS5vZmZzZXQoKTtcclxuICAgICAgICAgICAgc2VsZi5ueldpZHRoID0gc2VsZi4kZWxlbS53aWR0aCgpO1xyXG4gICAgICAgICAgICBzZWxmLm56SGVpZ2h0ID0gc2VsZi4kZWxlbS5oZWlnaHQoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHJlc2V0IHRoZSB6b29tbGV2ZWwgYmFjayB0byBkZWZhdWx0XHJcbiAgICAgICAgICAgIHNlbGYuY3VycmVudFpvb21MZXZlbCA9IHNlbGYub3B0aW9ucy56b29tTGV2ZWw7XHJcblxyXG4gICAgICAgICAgICAvL3JhdGlvIG9mIHRoZSBsYXJnZSB0byBzbWFsbCBpbWFnZVxyXG4gICAgICAgICAgICBzZWxmLndpZHRoUmF0aW8gPSBzZWxmLmxhcmdlV2lkdGggLyBzZWxmLm56V2lkdGg7XHJcbiAgICAgICAgICAgIHNlbGYuaGVpZ2h0UmF0aW8gPSBzZWxmLmxhcmdlSGVpZ2h0IC8gc2VsZi5uekhlaWdodDtcclxuXHJcbiAgICAgICAgICAgIC8vTkVFRCBUTyBBREQgVEhFIExFTlMgU0laRSBGT1IgUk9VTkRcclxuICAgICAgICAgICAgLy8gYWRqdXN0IGltYWdlcyBsZXNzIHRoYW4gdGhlIHdpbmRvdyBoZWlnaHRcclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsZW5zSGVpZ2h0LCBsZW5zV2lkdGg7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYubnpIZWlnaHQgPCBzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCAvIHNlbGYuaGVpZ2h0UmF0aW8pIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5zSGVpZ2h0ID0gc2VsZi5uekhlaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBsZW5zSGVpZ2h0ID0gU3RyaW5nKChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCAvIHNlbGYuaGVpZ2h0UmF0aW8pKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5ueldpZHRoIDwgc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlbnNXaWR0aCA9IHNlbGYubnpXaWR0aDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlbnNXaWR0aCA9IChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd1dpZHRoIC8gc2VsZi53aWR0aFJhdGlvKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi56b29tTGVucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJzogbGVuc1dpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JzogbGVuc0hlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZ2V0Q3VycmVudEltYWdlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgcmV0dXJuIHNlbGYuem9vbUltYWdlO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIGdldEdhbGxlcnlMaXN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgLy9sb29wIHRocm91Z2ggdGhlIGdhbGxlcnkgb3B0aW9ucyBhbmQgc2V0IHRoZW0gaW4gbGlzdCBmb3IgZmFuY3lib3hcclxuICAgICAgICAgICAgc2VsZi5nYWxsZXJ5bGlzdCA9IFtdO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmdhbGxlcnkpIHtcclxuICAgICAgICAgICAgICAgICQoJyMnICsgc2VsZi5vcHRpb25zLmdhbGxlcnkgKyAnIGEnKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGltZ1NyYyA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmRhdGEoJ3pvb20taW1hZ2UnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWdTcmMgPSAkKHRoaXMpLmRhdGEoJ3pvb20taW1hZ2UnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoJCh0aGlzKS5kYXRhKCdpbWFnZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NyYyA9ICQodGhpcykuZGF0YSgnaW1hZ2UnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy9wdXQgdGhlIGN1cnJlbnQgaW1hZ2UgYXQgdGhlIHN0YXJ0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGltZ1NyYyA9PT0gc2VsZi56b29tSW1hZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5nYWxsZXJ5bGlzdC51bnNoaWZ0KHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY6ICcnICsgaW1nU3JjICsgJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJCh0aGlzKS5maW5kKCdpbWcnKS5hdHRyKCd0aXRsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5nYWxsZXJ5bGlzdC5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY6ICcnICsgaW1nU3JjICsgJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJCh0aGlzKS5maW5kKCdpbWcnKS5hdHRyKCd0aXRsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vaWYgbm8gZ2FsbGVyeSAtIHJldHVybiBjdXJyZW50IGltYWdlXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5nYWxsZXJ5bGlzdC5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICBocmVmOiAnJyArIHNlbGYuem9vbUltYWdlICsgJycsXHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICQodGhpcykuZmluZCgnaW1nJykuYXR0cigndGl0bGUnKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHNlbGYuZ2FsbGVyeWxpc3Q7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY2hhbmdlWm9vbUxldmVsOiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgLy9mbGFnIGEgem9vbSwgc28gY2FuIGFkanVzdCB0aGUgZWFzaW5nIGR1cmluZyBzZXRQb3NpdGlvblxyXG4gICAgICAgICAgICBzZWxmLnNjcm9sbGluZ0xvY2sgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgLy9yb3VuZCB0byB0d28gZGVjaW1hbCBwbGFjZXNcclxuICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZSA9IHBhcnNlRmxvYXQodmFsdWUpLnRvRml4ZWQoMik7XHJcbiAgICAgICAgICAgIHZhciBuZXd2YWx1ZSA9IHNlbGYubmV3dmFsdWU7XHJcblxyXG4gICAgICAgICAgICAvL21heHdpZHRoICYgTWF4aGVpZ2h0IG9mIHRoZSBpbWFnZVxyXG4gICAgICAgICAgICB2YXIgbWF4aGVpZ2h0bmV3dmFsdWUgPSBzZWxmLmxhcmdlSGVpZ2h0IC8gKChzZWxmLm9wdGlvbnMuem9vbVdpbmRvd0hlaWdodCAvIHNlbGYubnpIZWlnaHQpICogc2VsZi5uekhlaWdodCk7XHJcbiAgICAgICAgICAgIHZhciBtYXh3aWR0aHRuZXd2YWx1ZSA9IHNlbGYubGFyZ2VXaWR0aCAvICgoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYubnpXaWR0aCkgKiBzZWxmLm56V2lkdGgpO1xyXG5cclxuICAgICAgICAgICAgLy9jYWxjdWxhdGUgbmV3IGhlaWdodHJhdGlvXHJcbiAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtYXhoZWlnaHRuZXd2YWx1ZSA8PSBuZXd2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaGVpZ2h0UmF0aW8gPSAoc2VsZi5sYXJnZUhlaWdodCAvIG1heGhlaWdodG5ld3ZhbHVlKSAvIHNlbGYubnpIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZWhlaWdodCA9IG1heGhlaWdodG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbGhlaWdodCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmhlaWdodFJhdGlvID0gKHNlbGYubGFyZ2VIZWlnaHQgLyBuZXd2YWx1ZSkgLyBzZWxmLm56SGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubmV3dmFsdWVoZWlnaHQgPSBuZXd2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmZ1bGxoZWlnaHQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgbmV3IHdpZHRoIHJhdGlvXHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG1heHdpZHRodG5ld3ZhbHVlIDw9IG5ld3ZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi53aWR0aFJhdGlvID0gKHNlbGYubGFyZ2VXaWR0aCAvIG1heHdpZHRodG5ld3ZhbHVlKSAvIHNlbGYubnpXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLm5ld3ZhbHVld2lkdGggPSBtYXh3aWR0aHRuZXd2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmZ1bGx3aWR0aCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLndpZHRoUmF0aW8gPSAoc2VsZi5sYXJnZVdpZHRoIC8gbmV3dmFsdWUpIC8gc2VsZi5ueldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubmV3dmFsdWV3aWR0aCA9IG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbHdpZHRoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnbGVucycpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobWF4aGVpZ2h0bmV3dmFsdWUgPD0gbmV3dmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mdWxsd2lkdGggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm5ld3ZhbHVld2lkdGggPSBtYXhoZWlnaHRuZXd2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndpZHRoUmF0aW8gPSAoc2VsZi5sYXJnZVdpZHRoIC8gbmV3dmFsdWUpIC8gc2VsZi5ueldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm5ld3ZhbHVld2lkdGggPSBuZXd2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbHdpZHRoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBtYXhoZWlnaHRuZXd2YWx1ZSA9IHBhcnNlRmxvYXQoc2VsZi5sYXJnZUhlaWdodCAvIHNlbGYubnpIZWlnaHQpLnRvRml4ZWQoMik7XHJcbiAgICAgICAgICAgICAgICBtYXh3aWR0aHRuZXd2YWx1ZSA9IHBhcnNlRmxvYXQoc2VsZi5sYXJnZVdpZHRoIC8gc2VsZi5ueldpZHRoKS50b0ZpeGVkKDIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ld3ZhbHVlID4gbWF4aGVpZ2h0bmV3dmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXd2YWx1ZSA9IG1heGhlaWdodG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKG5ld3ZhbHVlID4gbWF4d2lkdGh0bmV3dmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXd2YWx1ZSA9IG1heHdpZHRodG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChtYXhoZWlnaHRuZXd2YWx1ZSA8PSBuZXd2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaGVpZ2h0UmF0aW8gPSAoc2VsZi5sYXJnZUhlaWdodCAvIG5ld3ZhbHVlKSAvIHNlbGYubnpIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld3ZhbHVlID4gbWF4aGVpZ2h0bmV3dmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZWhlaWdodCA9IG1heGhlaWdodG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubmV3dmFsdWVoZWlnaHQgPSBuZXd2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5mdWxsaGVpZ2h0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaGVpZ2h0UmF0aW8gPSAoc2VsZi5sYXJnZUhlaWdodCAvIG5ld3ZhbHVlKSAvIHNlbGYubnpIZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXd2YWx1ZSA+IG1heGhlaWdodG5ld3ZhbHVlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm5ld3ZhbHVlaGVpZ2h0ID0gbWF4aGVpZ2h0bmV3dmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZWhlaWdodCA9IG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmZ1bGxoZWlnaHQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAobWF4d2lkdGh0bmV3dmFsdWUgPD0gbmV3dmFsdWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi53aWR0aFJhdGlvID0gKHNlbGYubGFyZ2VXaWR0aCAvIG5ld3ZhbHVlKSAvIHNlbGYubnpXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmV3dmFsdWUgPiBtYXh3aWR0aHRuZXd2YWx1ZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZXdpZHRoID0gbWF4d2lkdGh0bmV3dmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5uZXd2YWx1ZXdpZHRoID0gbmV3dmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmZ1bGx3aWR0aCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLndpZHRoUmF0aW8gPSAoc2VsZi5sYXJnZVdpZHRoIC8gbmV3dmFsdWUpIC8gc2VsZi5ueldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYubmV3dmFsdWV3aWR0aCA9IG5ld3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbHdpZHRoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gLy9lbmQgaW5uZXJcclxuICAgICAgICAgICAgdmFyIHNjcmNvbnRpbnVlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5ueldpZHRoID49IHNlbGYubnpIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5uZXd2YWx1ZXdpZHRoIDw9IG1heHdpZHRodG5ld3ZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmNvbnRpbnVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmNvbnRpbnVlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbGhlaWdodCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZnVsbHdpZHRoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5uekhlaWdodCA+IHNlbGYubnpXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm5ld3ZhbHVld2lkdGggPD0gbWF4d2lkdGh0bmV3dmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2NyY29udGludWUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2NyY29udGludWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mdWxsaGVpZ2h0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mdWxsd2lkdGggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgc2NyY29udGludWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2NyY29udGludWUpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuem9vbUxvY2sgPSAwO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2Vab29tID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2lmIGxlbnMgaGVpZ2h0IGlzIGxlc3MgdGhhbiBpbWFnZSBoZWlnaHRcclxuICAgICAgICAgICAgICAgIGlmICgoKHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0KSAvIHNlbGYuaGVpZ2h0UmF0aW8pIDw9IHNlbGYubnpIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRab29tTGV2ZWwgPSBzZWxmLm5ld3ZhbHVlaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdsZW5zJyAmJiBzZWxmLm9wdGlvbnMuem9vbVR5cGUgIT09ICdpbm5lcicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFuZ2VCZ1NpemUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmNzcygnaGVpZ2h0JywgU3RyaW5nKHNlbGYub3B0aW9ucy56b29tV2luZG93SGVpZ2h0IC8gc2VsZi5oZWlnaHRSYXRpbykgKyAncHgnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2xlbnMnIHx8IHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNoYW5nZUJnU2l6ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICgoc2VsZi5vcHRpb25zLnpvb21XaW5kb3dXaWR0aCAvIHNlbGYud2lkdGhSYXRpbykgPD0gc2VsZi5ueldpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSAhPT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5uZXd2YWx1ZXdpZHRoID4gc2VsZi5uZXd2YWx1ZWhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50Wm9vbUxldmVsID0gc2VsZi5uZXd2YWx1ZXdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnbGVucycgJiYgc2VsZi5vcHRpb25zLnpvb21UeXBlICE9PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuem9vbUxlbnMuY3NzKCd3aWR0aCcsIFN0cmluZyhzZWxmLm9wdGlvbnMuem9vbVdpbmRvd1dpZHRoIC8gc2VsZi53aWR0aFJhdGlvKSArICdweCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnbGVucycgfHwgc2VsZi5vcHRpb25zLnpvb21UeXBlID09PSAnaW5uZXInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy56b29tVHlwZSA9PT0gJ2lubmVyJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhbmdlQmdTaXplID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYubnpXaWR0aCA+IHNlbGYubnpIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5jdXJyZW50Wm9vbUxldmVsID0gc2VsZi5uZXd2YWx1ZXdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5uekhlaWdodCA+IHNlbGYubnpXaWR0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRab29tTGV2ZWwgPSBzZWxmLm5ld3ZhbHVld2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ICAgICAgLy91bmRlclxyXG5cclxuICAgICAgICAgICAgLy9zZXRzIHRoZSBib3VuZHJ5IGNoYW5nZSwgY2FsbGVkIGluIHNldFdpbmRvd1Bvc1xyXG4gICAgICAgICAgICBzZWxmLnNldFBvc2l0aW9uKHNlbGYuY3VycmVudExvYyk7XHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY2xvc2VBbGw6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICBpZiAoc2VsZi56b29tV2luZG93KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21XaW5kb3cuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzZWxmLnpvb21MZW5zKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnpvb21MZW5zLmhpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2VsZi56b29tVGludCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi56b29tVGludC5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBjaGFuZ2VTdGF0ZTogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnZW5hYmxlJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnpvb21FbmFibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdkaXNhYmxlJykge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnpvb21FbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICByZXNwb25zaXZlQ29uZmlnOiBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5yZXNwb25kICYmIG9wdGlvbnMucmVzcG9uZC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIG9wdGlvbnMsIHRoaXMuY29uZmlnQnlTY3JlZW5XaWR0aChvcHRpb25zKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY29uZmlnQnlTY3JlZW5XaWR0aDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdmFyIHNjcmVlbldpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgY29uZmlnID0gJC5ncmVwKG9wdGlvbnMucmVzcG9uZCwgZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IGl0ZW0ucmFuZ2Uuc3BsaXQoJy0nKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoc2NyZWVuV2lkdGggPj0gcmFuZ2VbMF0pICYmIChzY3JlZW5XaWR0aCA8PSByYW5nZVsxXSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvbmZpZy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnWzBdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgICQuZm4uZXpQbHVzID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGVsZXZhdGUgPSBPYmplY3QuY3JlYXRlKEVaUCk7XHJcblxyXG4gICAgICAgICAgICBlbGV2YXRlLmluaXQob3B0aW9ucywgdGhpcyk7XHJcblxyXG4gICAgICAgICAgICAkLmRhdGEodGhpcywgJ2V6UGx1cycsIGVsZXZhdGUpO1xyXG5cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgJC5mbi5lelBsdXMub3B0aW9ucyA9IHtcclxuICAgICAgICBib3JkZXJDb2xvdXI6ICcjODg4JyxcclxuICAgICAgICBib3JkZXJTaXplOiA0LFxyXG4gICAgICAgIGNvbnN0cmFpblNpemU6IGZhbHNlLCAgLy9pbiBwaXhlbHMgdGhlIGRpbWVuc2lvbnMgeW91IHdhbnQgdG8gY29uc3RyYWluIG9uXHJcbiAgICAgICAgY29uc3RyYWluVHlwZTogZmFsc2UsICAvL3dpZHRoIG9yIGhlaWdodFxyXG4gICAgICAgIGNvbnRhaW5MZW5zWm9vbTogZmFsc2UsXHJcbiAgICAgICAgY3Vyc29yOiAnaW5oZXJpdCcsIC8vIHVzZXIgc2hvdWxkIHNldCB0byB3aGF0IHRoZXkgd2FudCB0aGUgY3Vyc29yIGFzLCBpZiB0aGV5IGhhdmUgc2V0IGEgY2xpY2sgZnVuY3Rpb25cclxuICAgICAgICBkZWJ1ZzogZmFsc2UsXHJcbiAgICAgICAgZWFzaW5nOiBmYWxzZSxcclxuICAgICAgICBlYXNpbmdBbW91bnQ6IDEyLFxyXG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXHJcblxyXG4gICAgICAgIGdhbGxlcnk6IGZhbHNlLFxyXG4gICAgICAgIGdhbGxlcnlBY3RpdmVDbGFzczogJ3pvb21HYWxsZXJ5QWN0aXZlJyxcclxuICAgICAgICBnYWxsZXJ5U2VsZWN0b3I6IGZhbHNlLFxyXG4gICAgICAgIGdhbGxlcnlJdGVtOiAnYScsXHJcblxyXG4gICAgICAgIGltYWdlQ3Jvc3NmYWRlOiBmYWxzZSxcclxuXHJcbiAgICAgICAgbGVuc0JvcmRlckNvbG91cjogJyMwMDAnLFxyXG4gICAgICAgIGxlbnNCb3JkZXJTaXplOiAxLFxyXG4gICAgICAgIGxlbnNDb2xvdXI6ICd3aGl0ZScsIC8vY29sb3VyIG9mIHRoZSBsZW5zIGJhY2tncm91bmRcclxuICAgICAgICBsZW5zRmFkZUluOiBmYWxzZSxcclxuICAgICAgICBsZW5zRmFkZU91dDogZmFsc2UsXHJcbiAgICAgICAgbGVuc09wYWNpdHk6IDAuNCwgLy9vcGFjaXR5IG9mIHRoZSBsZW5zXHJcbiAgICAgICAgbGVuc1NoYXBlOiAnc3F1YXJlJywgLy9jYW4gYmUgJ3JvdW5kJ1xyXG4gICAgICAgIGxlbnNTaXplOiAyMDAsXHJcbiAgICAgICAgbGVuc3pvb206IGZhbHNlLFxyXG5cclxuICAgICAgICBsb2FkaW5nSWNvbjogZmFsc2UsIC8vaHR0cDovL3d3dy5leGFtcGxlLmNvbS9zcGlubmVyLmdpZlxyXG5cclxuICAgICAgICAvLyBUaGlzIGNoYW5nZSB3aWxsIGFsbG93IHRvIGRlY2lkZSBpZiB5b3Ugd2FudCB0byBkZWNyZWFzZVxyXG4gICAgICAgIC8vIHpvb20gb2Ygb25lIG9mIHRoZSBkaW1lbnNpb25zIG9uY2UgdGhlIG90aGVyIHJlYWNoZWQgaXQncyB0b3AgdmFsdWUsXHJcbiAgICAgICAgLy8gb3Iga2VlcCB0aGUgYXNwZWN0IHJhdGlvLCBkZWZhdWx0IGJlaGF2aW91ciBzdGlsbCBiZWluZyBhcyBhbHdheXMsXHJcbiAgICAgICAgLy8gYWxsb3cgdG8gY29udGludWUgem9vbWluZyBvdXQsIHNvIGl0IGtlZXBzIHJldHJvY29tcGF0aWJpbGl0eS5cclxuICAgICAgICBtYW50YWluWm9vbUFzcGVjdFJhdGlvOiBmYWxzZSxcclxuICAgICAgICBtYXhab29tTGV2ZWw6IGZhbHNlLFxyXG4gICAgICAgIG1pblpvb21MZXZlbDogZmFsc2UsXHJcblxyXG4gICAgICAgIG9uQ29tcGxldGU6ICQubm9vcCxcclxuICAgICAgICBvbkRlc3Ryb3k6ICQubm9vcCxcclxuICAgICAgICBvbkltYWdlQ2xpY2s6ICQubm9vcCxcclxuICAgICAgICBvbkltYWdlU3dhcDogJC5ub29wLFxyXG4gICAgICAgIG9uSW1hZ2VTd2FwQ29tcGxldGU6ICQubm9vcCxcclxuICAgICAgICBvblNob3c6ICQubm9vcCxcclxuICAgICAgICBvblpvb21lZEltYWdlTG9hZGVkOiAkLm5vb3AsXHJcblxyXG4gICAgICAgIHByZWxvYWRpbmc6IDEsIC8vYnkgZGVmYXVsdCwgbG9hZCBhbGwgdGhlIGltYWdlcywgaWYgMCwgdGhlbiBvbmx5IGxvYWQgaW1hZ2VzIGFmdGVyIGFjdGl2YXRlZCAoUExBQ0VIT0xERVIgRk9SIE5FWFQgVkVSU0lPTilcclxuICAgICAgICByZXNwb25kOiBbXSxcclxuICAgICAgICByZXNwb25zaXZlOiB0cnVlLFxyXG4gICAgICAgIHNjcm9sbFpvb206IGZhbHNlLCAvL2FsbG93IHpvb20gb24gbW91c2V3aGVlbCwgdHJ1ZSB0byBhY3RpdmF0ZVxyXG4gICAgICAgIHNjcm9sbFpvb21JbmNyZW1lbnQ6IDAuMSwgIC8vc3RlcHMgb2YgdGhlIHNjcm9sbHpvb21cclxuICAgICAgICBzaG93TGVuczogdHJ1ZSxcclxuICAgICAgICB0aW50OiBmYWxzZSwgLy9lbmFibGUgdGhlIHRpbnRpbmdcclxuICAgICAgICB0aW50Q29sb3VyOiAnIzMzMycsIC8vZGVmYXVsdCB0aW50IGNvbG9yLCBjYW4gYmUgYW55dGhpbmcsIHJlZCwgI2NjYywgcmdiKDAsMCwwKVxyXG4gICAgICAgIHRpbnRPcGFjaXR5OiAwLjQsIC8vb3BhY2l0eSBvZiB0aGUgdGludFxyXG4gICAgICAgIHRvdWNoRW5hYmxlZDogdHJ1ZSxcclxuXHJcblxyXG4gICAgICAgIHpvb21BY3RpdmF0aW9uOiAnaG92ZXInLCAvLyBDYW4gYWxzbyBiZSBjbGljayAoUExBQ0VIT0xERVIgRk9SIE5FWFQgVkVSU0lPTilcclxuICAgICAgICB6b29tQ29udGFpbmVyQXBwZW5kVG86ICdib2R5JywgLy96b29tIGNvbnRhaW5lciBwYXJlbnQgc2VsZWN0b3JcclxuICAgICAgICB6b29tSWQ6IC0xLCAvLyBpZGVudGlmaWVyIGZvciB0aGUgem9vbSBjb250YWluZXJcclxuICAgICAgICB6b29tTGV2ZWw6IDEsIC8vZGVmYXVsdCB6b29tIGxldmVsIG9mIGltYWdlXHJcbiAgICAgICAgem9vbVRpbnRGYWRlSW46IGZhbHNlLFxyXG4gICAgICAgIHpvb21UaW50RmFkZU91dDogZmFsc2UsXHJcbiAgICAgICAgem9vbVR5cGU6ICd3aW5kb3cnLCAvL3dpbmRvdyBpcyBkZWZhdWx0LCAgYWxzbyAnbGVucycgYXZhaWxhYmxlIC1cclxuICAgICAgICB6b29tV2luZG93QWx3YXlzU2hvdzogZmFsc2UsXHJcbiAgICAgICAgem9vbVdpbmRvd0JnQ29sb3VyOiAnI2ZmZicsXHJcbiAgICAgICAgem9vbVdpbmRvd0ZhZGVJbjogZmFsc2UsXHJcbiAgICAgICAgem9vbVdpbmRvd0ZhZGVPdXQ6IGZhbHNlLFxyXG4gICAgICAgIHpvb21XaW5kb3dIZWlnaHQ6IDQwMCxcclxuICAgICAgICB6b29tV2luZG93T2Zmc2V0WDogMCxcclxuICAgICAgICB6b29tV2luZG93T2Zmc2V0WTogMCxcclxuICAgICAgICB6b29tV2luZG93UG9zaXRpb246IDEsIC8vUG9zc2libGUgdmFsdWVzOiAxLTE2LCBidXQgd2UgY2FuIGFsc28gcG9zaXRpb24gd2l0aCBhIHNlbGVjdG9yIHN0cmluZy5cclxuICAgICAgICB6b29tV2luZG93V2lkdGg6IDQwMCxcclxuICAgICAgICB6b29tRW5hYmxlZDogdHJ1ZSwgLy9mYWxzZSBkaXNhYmxlcyB6b29td2luZG93IGZyb20gc2hvd2luZ1xyXG4gICAgICAgIHpJbmRleDogOTk5XHJcbiAgICB9O1xyXG5cclxufSkoalF1ZXJ5LCB3aW5kb3csIGRvY3VtZW50KTtcclxuIiwiIWZ1bmN0aW9uKGEpe2Z1bmN0aW9uIGIoKXtyZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkoRGF0ZSxhcmd1bWVudHMpKX12YXIgYz1mdW5jdGlvbihiLGMpe3ZhciBmPXRoaXM7dGhpcy5lbGVtZW50PWEoYiksdGhpcy5hdXRvU2hvdz12b2lkIDA9PWMuYXV0b1Nob3d8fGMuYXV0b1Nob3csdGhpcy5hcHBlbmRUbz1jLmFwcGVuZFRvfHxcImJvZHlcIix0aGlzLmNsb3NlQnV0dG9uPWMuY2xvc2VCdXR0b24sdGhpcy5sYW5ndWFnZT1jLmxhbmd1YWdlfHx0aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtbGFuZ3VhZ2VcIil8fFwiZW5cIix0aGlzLmxhbmd1YWdlPXRoaXMubGFuZ3VhZ2UgaW4gZD90aGlzLmxhbmd1YWdlOnRoaXMubGFuZ3VhZ2Uuc3BsaXQoXCItXCIpWzBdLHRoaXMubGFuZ3VhZ2U9dGhpcy5sYW5ndWFnZSBpbiBkP3RoaXMubGFuZ3VhZ2U6XCJlblwiLHRoaXMuaXNSVEw9ZFt0aGlzLmxhbmd1YWdlXS5ydGx8fCExLHRoaXMuZm9ybWF0PWUucGFyc2VGb3JtYXQoYy5mb3JtYXR8fHRoaXMuZWxlbWVudC5kYXRhKFwiZGF0ZS1mb3JtYXRcIil8fGRbdGhpcy5sYW5ndWFnZV0uZm9ybWF0fHxcIm1tL2RkL3l5eXlcIiksdGhpcy5mb3JtYXRUZXh0PWMuZm9ybWF0fHx0aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtZm9ybWF0XCIpfHxkW3RoaXMubGFuZ3VhZ2VdLmZvcm1hdHx8XCJtbS9kZC95eXl5XCIsdGhpcy5pc0lubGluZT0hMSx0aGlzLmlzSW5wdXQ9dGhpcy5lbGVtZW50LmlzKFwiaW5wdXRcIiksdGhpcy5jb21wb25lbnQ9ISF0aGlzLmVsZW1lbnQuaXMoXCIuZGF0ZVwiKSYmdGhpcy5lbGVtZW50LmZpbmQoXCIucHJlZml4LCAucG9zdGZpeFwiKSx0aGlzLmhhc0lucHV0PXRoaXMuY29tcG9uZW50JiZ0aGlzLmVsZW1lbnQuZmluZChcImlucHV0XCIpLmxlbmd0aCx0aGlzLmRpc2FibGVEYmxDbGlja1NlbGVjdGlvbj1jLmRpc2FibGVEYmxDbGlja1NlbGVjdGlvbix0aGlzLm9uUmVuZGVyPWMub25SZW5kZXJ8fGZ1bmN0aW9uKCl7fSx0aGlzLmNvbXBvbmVudCYmMD09PXRoaXMuY29tcG9uZW50Lmxlbmd0aCYmKHRoaXMuY29tcG9uZW50PSExKSx0aGlzLmxpbmtGaWVsZD1jLmxpbmtGaWVsZHx8dGhpcy5lbGVtZW50LmRhdGEoXCJsaW5rLWZpZWxkXCIpfHwhMSx0aGlzLmxpbmtGb3JtYXQ9ZS5wYXJzZUZvcm1hdChjLmxpbmtGb3JtYXR8fHRoaXMuZWxlbWVudC5kYXRhKFwibGluay1mb3JtYXRcIil8fFwieXl5eS1tbS1kZCBoaDppaTpzc1wiKSx0aGlzLm1pbnV0ZVN0ZXA9Yy5taW51dGVTdGVwfHx0aGlzLmVsZW1lbnQuZGF0YShcIm1pbnV0ZS1zdGVwXCIpfHw1LHRoaXMucGlja2VyUG9zaXRpb249Yy5waWNrZXJQb3NpdGlvbnx8dGhpcy5lbGVtZW50LmRhdGEoXCJwaWNrZXItcG9zaXRpb25cIil8fFwiYm90dG9tLXJpZ2h0XCIsdGhpcy5pbml0aWFsRGF0ZT1jLmluaXRpYWxEYXRlfHxudWxsLHRoaXMuZmFDU1NwcmVmaXg9Yy5mYUNTU3ByZWZpeHx8XCJmYVwiLHRoaXMubGVmdEFycm93PWMubGVmdEFycm93fHwnPGkgY2xhc3M9XCInK3RoaXMuZmFDU1NwcmVmaXgrXCIgXCIrdGhpcy5mYUNTU3ByZWZpeCsnLWNoZXZyb24tbGVmdCBmaS1hcnJvdy1sZWZ0XCIvPicsdGhpcy5yaWdodEFycm93PWMucmlnaHRBcnJvd3x8JzxpIGNsYXNzPVwiJyt0aGlzLmZhQ1NTcHJlZml4K1wiIFwiK3RoaXMuZmFDU1NwcmVmaXgrJy1jaGV2cm9uLXJpZ2h0IGZpLWFycm93LXJpZ2h0XCIvPicsdGhpcy5jbG9zZUljb249Yy5jbG9zZUljb258fCc8aSBjbGFzcz1cIicrdGhpcy5mYUNTU3ByZWZpeCtcIiBcIit0aGlzLmZhQ1NTcHJlZml4K1wiLXJlbW92ZSBcIit0aGlzLmZhQ1NTcHJlZml4KyctdGltZXMgZmkteFwiPjwvaT4nLHRoaXMubWluVmlldz0wLFwibWluVmlld1wiaW4gYz90aGlzLm1pblZpZXc9Yy5taW5WaWV3OlwibWluVmlld1wiaW4gdGhpcy5lbGVtZW50LmRhdGEoKSYmKHRoaXMubWluVmlldz10aGlzLmVsZW1lbnQuZGF0YShcIm1pbi12aWV3XCIpKSx0aGlzLm1pblZpZXc9ZS5jb252ZXJ0Vmlld01vZGUodGhpcy5taW5WaWV3KSx0aGlzLm1heFZpZXc9ZS5tb2Rlcy5sZW5ndGgtMSxcIm1heFZpZXdcImluIGM/dGhpcy5tYXhWaWV3PWMubWF4VmlldzpcIm1heFZpZXdcImluIHRoaXMuZWxlbWVudC5kYXRhKCkmJih0aGlzLm1heFZpZXc9dGhpcy5lbGVtZW50LmRhdGEoXCJtYXgtdmlld1wiKSksdGhpcy5tYXhWaWV3PWUuY29udmVydFZpZXdNb2RlKHRoaXMubWF4VmlldyksdGhpcy5zdGFydFZpZXdNb2RlPVwibW9udGhcIixcInN0YXJ0Vmlld1wiaW4gYz90aGlzLnN0YXJ0Vmlld01vZGU9Yy5zdGFydFZpZXc6XCJzdGFydFZpZXdcImluIHRoaXMuZWxlbWVudC5kYXRhKCkmJih0aGlzLnN0YXJ0Vmlld01vZGU9dGhpcy5lbGVtZW50LmRhdGEoXCJzdGFydC12aWV3XCIpKSx0aGlzLnN0YXJ0Vmlld01vZGU9ZS5jb252ZXJ0Vmlld01vZGUodGhpcy5zdGFydFZpZXdNb2RlKSx0aGlzLnZpZXdNb2RlPXRoaXMuc3RhcnRWaWV3TW9kZSxcIm1pblZpZXdcImluIGN8fFwibWF4Vmlld1wiaW4gY3x8dGhpcy5lbGVtZW50LmRhdGEoXCJtaW4tdmlld1wiKSYmIXRoaXMuZWxlbWVudC5kYXRhKFwibWF4LXZpZXdcIil8fCh0aGlzLnBpY2tUaW1lPSExLFwicGlja1RpbWVcImluIGMmJih0aGlzLnBpY2tUaW1lPWMucGlja1RpbWUpLDE9PXRoaXMucGlja1RpbWU/KHRoaXMubWluVmlldz0wLHRoaXMubWF4Vmlldz00KToodGhpcy5taW5WaWV3PTIsdGhpcy5tYXhWaWV3PTQpKSx0aGlzLmZvcmNlUGFyc2U9ITAsXCJmb3JjZVBhcnNlXCJpbiBjP3RoaXMuZm9yY2VQYXJzZT1jLmZvcmNlUGFyc2U6XCJkYXRlRm9yY2VQYXJzZVwiaW4gdGhpcy5lbGVtZW50LmRhdGEoKSYmKHRoaXMuZm9yY2VQYXJzZT10aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtZm9yY2UtcGFyc2VcIikpLHRoaXMucGlja2VyPWEoZS50ZW1wbGF0ZSh0aGlzLmxlZnRBcnJvdyx0aGlzLnJpZ2h0QXJyb3csdGhpcy5jbG9zZUljb24pKS5hcHBlbmRUbyh0aGlzLmlzSW5saW5lP3RoaXMuZWxlbWVudDp0aGlzLmFwcGVuZFRvKS5vbih7Y2xpY2s6YS5wcm94eSh0aGlzLmNsaWNrLHRoaXMpLG1vdXNlZG93bjphLnByb3h5KHRoaXMubW91c2Vkb3duLHRoaXMpfSksdGhpcy5jbG9zZUJ1dHRvbj90aGlzLnBpY2tlci5maW5kKFwiYS5kYXRlcGlja2VyLWNsb3NlXCIpLnNob3coKTp0aGlzLnBpY2tlci5maW5kKFwiYS5kYXRlcGlja2VyLWNsb3NlXCIpLmhpZGUoKSx0aGlzLmlzSW5saW5lP3RoaXMucGlja2VyLmFkZENsYXNzKFwiZGF0ZXBpY2tlci1pbmxpbmVcIik6dGhpcy5waWNrZXIuYWRkQ2xhc3MoXCJkYXRlcGlja2VyLWRyb3Bkb3duIGRyb3Bkb3duLW1lbnVcIiksdGhpcy5pc1JUTCYmKHRoaXMucGlja2VyLmFkZENsYXNzKFwiZGF0ZXBpY2tlci1ydGxcIiksdGhpcy5waWNrZXIuZmluZChcIi5kYXRlLXN3aXRjaFwiKS5lYWNoKGZ1bmN0aW9uKCl7YSh0aGlzKS5wYXJlbnQoKS5wcmVwZW5kKGEodGhpcykuc2libGluZ3MoXCIubmV4dFwiKSksYSh0aGlzKS5wYXJlbnQoKS5hcHBlbmQoYSh0aGlzKS5zaWJsaW5ncyhcIi5wcmV2XCIpKX0pLHRoaXMucGlja2VyLmZpbmQoXCIucHJldiwgLm5leHRcIikudG9nZ2xlQ2xhc3MoXCJwcmV2IG5leHRcIikpLGEoZG9jdW1lbnQpLm9uKFwibW91c2Vkb3duXCIsZnVuY3Rpb24oYil7MD09PWEoYi50YXJnZXQpLmNsb3Nlc3QoXCIuZGF0ZXBpY2tlci5kYXRlcGlja2VyLWlubGluZSwgLmRhdGVwaWNrZXIuZGF0ZXBpY2tlci1kcm9wZG93blwiKS5sZW5ndGgmJmYuaGlkZSgpfSksdGhpcy5hdXRvY2xvc2U9ITAsXCJhdXRvY2xvc2VcImluIGM/dGhpcy5hdXRvY2xvc2U9Yy5hdXRvY2xvc2U6XCJkYXRlQXV0b2Nsb3NlXCJpbiB0aGlzLmVsZW1lbnQuZGF0YSgpJiYodGhpcy5hdXRvY2xvc2U9dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLWF1dG9jbG9zZVwiKSksdGhpcy5rZXlib2FyZE5hdmlnYXRpb249ITAsXCJrZXlib2FyZE5hdmlnYXRpb25cImluIGM/dGhpcy5rZXlib2FyZE5hdmlnYXRpb249Yy5rZXlib2FyZE5hdmlnYXRpb246XCJkYXRlS2V5Ym9hcmROYXZpZ2F0aW9uXCJpbiB0aGlzLmVsZW1lbnQuZGF0YSgpJiYodGhpcy5rZXlib2FyZE5hdmlnYXRpb249dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLWtleWJvYXJkLW5hdmlnYXRpb25cIikpLHRoaXMudG9kYXlCdG49Yy50b2RheUJ0bnx8dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLXRvZGF5LWJ0blwiKXx8ITEsdGhpcy50b2RheUhpZ2hsaWdodD1jLnRvZGF5SGlnaGxpZ2h0fHx0aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtdG9kYXktaGlnaGxpZ2h0XCIpfHwhMSx0aGlzLmNhbGVuZGFyV2Vla3M9ITEsXCJjYWxlbmRhcldlZWtzXCJpbiBjP3RoaXMuY2FsZW5kYXJXZWVrcz1jLmNhbGVuZGFyV2Vla3M6XCJkYXRlQ2FsZW5kYXJXZWVrc1wiaW4gdGhpcy5lbGVtZW50LmRhdGEoKSYmKHRoaXMuY2FsZW5kYXJXZWVrcz10aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtY2FsZW5kYXItd2Vla3NcIikpLHRoaXMuY2FsZW5kYXJXZWVrcyYmdGhpcy5waWNrZXIuZmluZChcInRmb290IHRoLnRvZGF5XCIpLmF0dHIoXCJjb2xzcGFuXCIsZnVuY3Rpb24oYSxiKXtyZXR1cm4gcGFyc2VJbnQoYikrMX0pLHRoaXMud2Vla1N0YXJ0PShjLndlZWtTdGFydHx8dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLXdlZWtzdGFydFwiKXx8ZFt0aGlzLmxhbmd1YWdlXS53ZWVrU3RhcnR8fDApJTcsdGhpcy53ZWVrRW5kPSh0aGlzLndlZWtTdGFydCs2KSU3LHRoaXMuc3RhcnREYXRlPS0oMS8wKSx0aGlzLmVuZERhdGU9MS8wLHRoaXMuZGF5c09mV2Vla0Rpc2FibGVkPVtdLHRoaXMuZGF0ZXNEaXNhYmxlZD1bXSx0aGlzLnNldFN0YXJ0RGF0ZShjLnN0YXJ0RGF0ZXx8dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLXN0YXJ0ZGF0ZVwiKSksdGhpcy5zZXRFbmREYXRlKGMuZW5kRGF0ZXx8dGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlLWVuZGRhdGVcIikpLHRoaXMuc2V0RGF5c09mV2Vla0Rpc2FibGVkKGMuZGF5c09mV2Vla0Rpc2FibGVkfHx0aGlzLmVsZW1lbnQuZGF0YShcImRhdGUtZGF5cy1vZi13ZWVrLWRpc2FibGVkXCIpKSx0aGlzLnNldERhdGVzRGlzYWJsZWQoYy5kYXRlc0Rpc2FibGVkfHx0aGlzLmVsZW1lbnQuZGF0YShcImRhdGVzLWRpc2FibGVkXCIpKSx0aGlzLmZpbGxEb3coKSx0aGlzLmZpbGxNb250aHMoKSx0aGlzLnVwZGF0ZSgpLHRoaXMuc2hvd01vZGUoKSx0aGlzLmlzSW5saW5lJiZ0aGlzLnNob3coKSx0aGlzLl9hdHRhY2hFdmVudHMoKX07Yy5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOmMsX2V2ZW50czpbXSxfYXR0YWNoRXZlbnRzOmZ1bmN0aW9uKCl7dGhpcy5fZGV0YWNoRXZlbnRzKCksdGhpcy5pc0lucHV0P3RoaXMua2V5Ym9hcmROYXZpZ2F0aW9uP3RoaXMuX2V2ZW50cz1bW3RoaXMuZWxlbWVudCx7Zm9jdXM6dGhpcy5hdXRvU2hvdz9hLnByb3h5KHRoaXMuc2hvdyx0aGlzKTpmdW5jdGlvbigpe30sa2V5dXA6YS5wcm94eSh0aGlzLnVwZGF0ZSx0aGlzKSxrZXlkb3duOmEucHJveHkodGhpcy5rZXlkb3duLHRoaXMpLGNsaWNrOnRoaXMuZWxlbWVudC5hdHRyKFwicmVhZG9ubHlcIik/YS5wcm94eSh0aGlzLnNob3csdGhpcyk6ZnVuY3Rpb24oKXt9fV1dOnRoaXMuX2V2ZW50cz1bW3RoaXMuZWxlbWVudCx7Zm9jdXM6dGhpcy5hdXRvU2hvdz9hLnByb3h5KHRoaXMuc2hvdyx0aGlzKTpmdW5jdGlvbigpe319XV06dGhpcy5jb21wb25lbnQmJnRoaXMuaGFzSW5wdXQ/dGhpcy5fZXZlbnRzPVtbdGhpcy5lbGVtZW50LmZpbmQoXCJpbnB1dFwiKSx7Zm9jdXM6dGhpcy5hdXRvU2hvdz9hLnByb3h5KHRoaXMuc2hvdyx0aGlzKTpmdW5jdGlvbigpe30sa2V5dXA6YS5wcm94eSh0aGlzLnVwZGF0ZSx0aGlzKSxrZXlkb3duOmEucHJveHkodGhpcy5rZXlkb3duLHRoaXMpfV0sW3RoaXMuY29tcG9uZW50LHtjbGljazphLnByb3h5KHRoaXMuc2hvdyx0aGlzKX1dXTp0aGlzLmVsZW1lbnQuaXMoXCJkaXZcIik/dGhpcy5pc0lubGluZT0hMDp0aGlzLl9ldmVudHM9W1t0aGlzLmVsZW1lbnQse2NsaWNrOmEucHJveHkodGhpcy5zaG93LHRoaXMpfV1dLHRoaXMuZGlzYWJsZURibENsaWNrU2VsZWN0aW9uJiYodGhpcy5fZXZlbnRzW3RoaXMuX2V2ZW50cy5sZW5ndGhdPVt0aGlzLmVsZW1lbnQse2RibGNsaWNrOmZ1bmN0aW9uKGIpe2IucHJldmVudERlZmF1bHQoKSxiLnN0b3BQcm9wYWdhdGlvbigpLGEodGhpcykuYmx1cigpfX1dKTtmb3IodmFyIGIsYyxkPTA7ZDx0aGlzLl9ldmVudHMubGVuZ3RoO2QrKyliPXRoaXMuX2V2ZW50c1tkXVswXSxjPXRoaXMuX2V2ZW50c1tkXVsxXSxiLm9uKGMpfSxfZGV0YWNoRXZlbnRzOmZ1bmN0aW9uKCl7Zm9yKHZhciBhLGIsYz0wO2M8dGhpcy5fZXZlbnRzLmxlbmd0aDtjKyspYT10aGlzLl9ldmVudHNbY11bMF0sYj10aGlzLl9ldmVudHNbY11bMV0sYS5vZmYoYik7dGhpcy5fZXZlbnRzPVtdfSxzaG93OmZ1bmN0aW9uKGIpe3RoaXMucGlja2VyLnNob3coKSx0aGlzLmhlaWdodD10aGlzLmNvbXBvbmVudD90aGlzLmNvbXBvbmVudC5vdXRlckhlaWdodCgpOnRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpLHRoaXMudXBkYXRlKCksdGhpcy5wbGFjZSgpLGEod2luZG93KS5vbihcInJlc2l6ZVwiLGEucHJveHkodGhpcy5wbGFjZSx0aGlzKSksYiYmKGIuc3RvcFByb3BhZ2F0aW9uKCksYi5wcmV2ZW50RGVmYXVsdCgpKSx0aGlzLmVsZW1lbnQudHJpZ2dlcih7dHlwZTpcInNob3dcIixkYXRlOnRoaXMuZGF0ZX0pfSxoaWRlOmZ1bmN0aW9uKGIpe3RoaXMuaXNJbmxpbmV8fHRoaXMucGlja2VyLmlzKFwiOnZpc2libGVcIikmJih0aGlzLnBpY2tlci5oaWRlKCksYSh3aW5kb3cpLm9mZihcInJlc2l6ZVwiLHRoaXMucGxhY2UpLHRoaXMudmlld01vZGU9dGhpcy5zdGFydFZpZXdNb2RlLHRoaXMuc2hvd01vZGUoKSx0aGlzLmlzSW5wdXR8fGEoZG9jdW1lbnQpLm9mZihcIm1vdXNlZG93blwiLHRoaXMuaGlkZSksdGhpcy5mb3JjZVBhcnNlJiYodGhpcy5pc0lucHV0JiZ0aGlzLmVsZW1lbnQudmFsKCl8fHRoaXMuaGFzSW5wdXQmJnRoaXMuZWxlbWVudC5maW5kKFwiaW5wdXRcIikudmFsKCkpJiZ0aGlzLnNldFZhbHVlKCksdGhpcy5lbGVtZW50LnRyaWdnZXIoe3R5cGU6XCJoaWRlXCIsZGF0ZTp0aGlzLmRhdGV9KSl9LHJlbW92ZTpmdW5jdGlvbigpe3RoaXMuX2RldGFjaEV2ZW50cygpLHRoaXMucGlja2VyLnJlbW92ZSgpLGRlbGV0ZSB0aGlzLmVsZW1lbnQuZGF0YSgpLmRhdGVwaWNrZXJ9LGdldERhdGU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmdldFVUQ0RhdGUoKTtyZXR1cm4gbmV3IERhdGUoYS5nZXRUaW1lKCkrNmU0KmEuZ2V0VGltZXpvbmVPZmZzZXQoKSl9LGdldFVUQ0RhdGU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kYXRlfSxzZXREYXRlOmZ1bmN0aW9uKGEpe3RoaXMuc2V0VVRDRGF0ZShuZXcgRGF0ZShhLmdldFRpbWUoKS02ZTQqYS5nZXRUaW1lem9uZU9mZnNldCgpKSl9LHNldFVUQ0RhdGU6ZnVuY3Rpb24oYSl7dGhpcy5kYXRlPWEsdGhpcy5zZXRWYWx1ZSgpfSxzZXRWYWx1ZTpmdW5jdGlvbigpe3ZhciBhPXRoaXMuZ2V0Rm9ybWF0dGVkRGF0ZSgpO3RoaXMuaXNJbnB1dD90aGlzLmVsZW1lbnQudmFsKGEpOih0aGlzLmNvbXBvbmVudCYmdGhpcy5lbGVtZW50LmZpbmQoXCJpbnB1dFwiKS52YWwoYSksdGhpcy5lbGVtZW50LmRhdGEoXCJkYXRlXCIsYSkpfSxnZXRGb3JtYXR0ZWREYXRlOmZ1bmN0aW9uKGEpe3JldHVybiB2b2lkIDA9PT1hJiYoYT10aGlzLmZvcm1hdCksZS5mb3JtYXREYXRlKHRoaXMuZGF0ZSxhLHRoaXMubGFuZ3VhZ2UpfSxzZXRTdGFydERhdGU6ZnVuY3Rpb24oYSl7dGhpcy5zdGFydERhdGU9YXx8LSgxLzApLHRoaXMuc3RhcnREYXRlIT09LSgxLzApJiYodGhpcy5zdGFydERhdGU9ZS5wYXJzZURhdGUodGhpcy5zdGFydERhdGUsdGhpcy5mb3JtYXQsdGhpcy5sYW5ndWFnZSkpLHRoaXMudXBkYXRlKCksdGhpcy51cGRhdGVOYXZBcnJvd3MoKX0sc2V0RW5kRGF0ZTpmdW5jdGlvbihhKXt0aGlzLmVuZERhdGU9YXx8MS8wLHRoaXMuZW5kRGF0ZSE9PTEvMCYmKHRoaXMuZW5kRGF0ZT1lLnBhcnNlRGF0ZSh0aGlzLmVuZERhdGUsdGhpcy5mb3JtYXQsdGhpcy5sYW5ndWFnZSkpLHRoaXMudXBkYXRlKCksdGhpcy51cGRhdGVOYXZBcnJvd3MoKX0sc2V0RGF5c09mV2Vla0Rpc2FibGVkOmZ1bmN0aW9uKGIpe3RoaXMuZGF5c09mV2Vla0Rpc2FibGVkPWJ8fFtdLGEuaXNBcnJheSh0aGlzLmRheXNPZldlZWtEaXNhYmxlZCl8fCh0aGlzLmRheXNPZldlZWtEaXNhYmxlZD10aGlzLmRheXNPZldlZWtEaXNhYmxlZC5zcGxpdCgvLFxccyovKSksdGhpcy5kYXlzT2ZXZWVrRGlzYWJsZWQ9YS5tYXAodGhpcy5kYXlzT2ZXZWVrRGlzYWJsZWQsZnVuY3Rpb24oYSl7cmV0dXJuIHBhcnNlSW50KGEsMTApfSksdGhpcy51cGRhdGUoKSx0aGlzLnVwZGF0ZU5hdkFycm93cygpfSxzZXREYXRlc0Rpc2FibGVkOmZ1bmN0aW9uKGIpe3RoaXMuZGF0ZXNEaXNhYmxlZD1ifHxbXSxhLmlzQXJyYXkodGhpcy5kYXRlc0Rpc2FibGVkKXx8KHRoaXMuZGF0ZXNEaXNhYmxlZD10aGlzLmRhdGVzRGlzYWJsZWQuc3BsaXQoLyxcXHMqLykpLHRoaXMuZGF0ZXNEaXNhYmxlZD1hLm1hcCh0aGlzLmRhdGVzRGlzYWJsZWQsZnVuY3Rpb24oYSl7cmV0dXJuIGUucGFyc2VEYXRlKGEsdGhpcy5mb3JtYXQsdGhpcy5sYW5ndWFnZSkudmFsdWVPZigpfSksdGhpcy51cGRhdGUoKSx0aGlzLnVwZGF0ZU5hdkFycm93cygpfSxwbGFjZTpmdW5jdGlvbigpe2lmKCF0aGlzLmlzSW5saW5lKXt2YXIgYj1wYXJzZUludCh0aGlzLmVsZW1lbnQucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpe3JldHVyblwiYXV0b1wiIT1hKHRoaXMpLmNzcyhcInotaW5kZXhcIil9KS5maXJzdCgpLmNzcyhcInotaW5kZXhcIikpKzEwLGM9dGhpcy5jb21wb25lbnQ/dGhpcy5jb21wb25lbnQ6dGhpcy5lbGVtZW50LGQ9Yy5vZmZzZXQoKSxlPWMub3V0ZXJIZWlnaHQoKStwYXJzZUludChjLmNzcyhcIm1hcmdpbi10b3BcIikpLGY9Yy5vdXRlcldpZHRoKCkrcGFyc2VJbnQoYy5jc3MoXCJtYXJnaW4tbGVmdFwiKSksZz1kLnRvcCtlLGg9ZC5sZWZ0O3RoaXMucGlja2VyLnJlbW92ZUNsYXNzKFwiZGF0ZXBpY2tlci10b3AgZGF0ZXBpY2tlci1ib3R0b21cIiksZyt0aGlzLnBpY2tlci5vdXRlckhlaWdodCgpPj1hKHdpbmRvdykuc2Nyb2xsVG9wKCkrYSh3aW5kb3cpLmhlaWdodCgpPyhnPWQudG9wLXRoaXMucGlja2VyLm91dGVySGVpZ2h0KCksdGhpcy5waWNrZXIuYWRkQ2xhc3MoXCJkYXRlcGlja2VyLXRvcFwiKSk6dGhpcy5waWNrZXIuYWRkQ2xhc3MoXCJkYXRlcGlja2VyLWJvdHRvbVwiKSxkLmxlZnQrdGhpcy5waWNrZXIud2lkdGgoKT49YSh3aW5kb3cpLndpZHRoKCkmJihoPWQubGVmdCtmLXRoaXMucGlja2VyLndpZHRoKCkpLHRoaXMucGlja2VyLmNzcyh7dG9wOmcsbGVmdDpoLHpJbmRleDpifSl9fSx1cGRhdGU6ZnVuY3Rpb24oKXt2YXIgYixjPSExLGQ9dGhpcy5pc0lucHV0P3RoaXMuZWxlbWVudC52YWwoKTp0aGlzLmVsZW1lbnQuZGF0YShcImRhdGVcIil8fHRoaXMuZWxlbWVudC5maW5kKFwiaW5wdXRcIikudmFsKCk7cmV0dXJuIGFyZ3VtZW50cyYmYXJndW1lbnRzLmxlbmd0aCYmKFwic3RyaW5nXCI9PXR5cGVvZiBhcmd1bWVudHNbMF18fGFyZ3VtZW50c1swXWluc3RhbmNlb2YgRGF0ZSk/KGI9YXJndW1lbnRzWzBdLGM9ITApOmI9ZHx8bnVsbD09dGhpcy5pbml0aWFsRGF0ZT90aGlzLmlzSW5wdXQ/dGhpcy5lbGVtZW50LnZhbCgpOnRoaXMuZWxlbWVudC5kYXRhKFwiZGF0ZVwiKXx8dGhpcy5lbGVtZW50LmZpbmQoXCJpbnB1dFwiKS52YWwoKTp0aGlzLmluaXRpYWxEYXRlLGIubGVuZ3RoPnRoaXMuZm9ybWF0VGV4dC5sZW5ndGg/KGEodGhpcy5waWNrZXIpLmFkZENsYXNzKFwiaXMtaW52YWxpZFwiKSx2b2lkIGEodGhpcy5lbGVtZW50KS5hZGRDbGFzcyhcImlzLWludmFsaWQtaW5wdXRcIikpOihhKHRoaXMucGlja2VyKS5yZW1vdmVDbGFzcyhcImlzLWludmFsaWRcIiksYSh0aGlzLmVsZW1lbnQpLnJlbW92ZUNsYXNzKFwiaXMtaW52YWxpZC1pbnB1dFwiKSx0aGlzLmRhdGU9ZS5wYXJzZURhdGUoYix0aGlzLmZvcm1hdCx0aGlzLmxhbmd1YWdlKSwoY3x8bnVsbCE9dGhpcy5pbml0aWFsRGF0ZSkmJnRoaXMuc2V0VmFsdWUoKSx0aGlzLmRhdGU8dGhpcy5zdGFydERhdGU/dGhpcy52aWV3RGF0ZT1uZXcgRGF0ZSh0aGlzLnN0YXJ0RGF0ZS52YWx1ZU9mKCkpOnRoaXMuZGF0ZT50aGlzLmVuZERhdGU/dGhpcy52aWV3RGF0ZT1uZXcgRGF0ZSh0aGlzLmVuZERhdGUudmFsdWVPZigpKTp0aGlzLnZpZXdEYXRlPW5ldyBEYXRlKHRoaXMuZGF0ZS52YWx1ZU9mKCkpLHZvaWQgdGhpcy5maWxsKCkpfSxmaWxsRG93OmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy53ZWVrU3RhcnQsYj1cIjx0cj5cIjtpZih0aGlzLmNhbGVuZGFyV2Vla3Mpe3ZhciBjPSc8dGggY2xhc3M9XCJjd1wiPiZuYnNwOzwvdGg+JztiKz1jLHRoaXMucGlja2VyLmZpbmQoXCIuZGF0ZXBpY2tlci1kYXlzIHRoZWFkIHRyOmZpcnN0LWNoaWxkXCIpLnByZXBlbmQoYyl9Zm9yKDthPHRoaXMud2Vla1N0YXJ0Kzc7KWIrPSc8dGggY2xhc3M9XCJkb3dcIj4nK2RbdGhpcy5sYW5ndWFnZV0uZGF5c01pblthKyslN10rXCI8L3RoPlwiO2IrPVwiPC90cj5cIix0aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXItZGF5cyB0aGVhZFwiKS5hcHBlbmQoYil9LGZpbGxNb250aHM6ZnVuY3Rpb24oKXtmb3IodmFyIGE9XCJcIixiPTA7YjwxMjspYSs9JzxzcGFuIGNsYXNzPVwibW9udGhcIj4nK2RbdGhpcy5sYW5ndWFnZV0ubW9udGhzU2hvcnRbYisrXStcIjwvc3Bhbj5cIjt0aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXItbW9udGhzIHRkXCIpLmh0bWwoYSl9LGZpbGw6ZnVuY3Rpb24oKXtpZihudWxsIT10aGlzLmRhdGUmJm51bGwhPXRoaXMudmlld0RhdGUpe3ZhciBjPW5ldyBEYXRlKHRoaXMudmlld0RhdGUudmFsdWVPZigpKSxmPWMuZ2V0VVRDRnVsbFllYXIoKSxnPWMuZ2V0VVRDTW9udGgoKSxoPWMuZ2V0VVRDRGF0ZSgpLGk9Yy5nZXRVVENIb3VycygpLGo9Yy5nZXRVVENNaW51dGVzKCksaz10aGlzLnN0YXJ0RGF0ZSE9PS0oMS8wKT90aGlzLnN0YXJ0RGF0ZS5nZXRVVENGdWxsWWVhcigpOi0oMS8wKSxsPXRoaXMuc3RhcnREYXRlIT09LSgxLzApP3RoaXMuc3RhcnREYXRlLmdldFVUQ01vbnRoKCk6LSgxLzApLG09dGhpcy5lbmREYXRlIT09MS8wP3RoaXMuZW5kRGF0ZS5nZXRVVENGdWxsWWVhcigpOjEvMCxuPXRoaXMuZW5kRGF0ZSE9PTEvMD90aGlzLmVuZERhdGUuZ2V0VVRDTW9udGgoKToxLzAsbz10aGlzLmRhdGUmJmIodGhpcy5kYXRlLmdldFVUQ0Z1bGxZZWFyKCksdGhpcy5kYXRlLmdldFVUQ01vbnRoKCksdGhpcy5kYXRlLmdldFVUQ0RhdGUoKSkudmFsdWVPZigpLHA9bmV3IERhdGU7ZFt0aGlzLmxhbmd1YWdlXS50aXRsZUZvcm1hdHx8ZC5lbi50aXRsZUZvcm1hdDt0aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXItZGF5cyB0aGVhZCB0aDplcSgxKVwiKS50ZXh0KGRbdGhpcy5sYW5ndWFnZV0ubW9udGhzW2ddK1wiIFwiK2YpLHRoaXMucGlja2VyLmZpbmQoXCIuZGF0ZXBpY2tlci1ob3VycyB0aGVhZCB0aDplcSgxKVwiKS50ZXh0KGgrXCIgXCIrZFt0aGlzLmxhbmd1YWdlXS5tb250aHNbZ10rXCIgXCIrZiksdGhpcy5waWNrZXIuZmluZChcIi5kYXRlcGlja2VyLW1pbnV0ZXMgdGhlYWQgdGg6ZXEoMSlcIikudGV4dChoK1wiIFwiK2RbdGhpcy5sYW5ndWFnZV0ubW9udGhzW2ddK1wiIFwiK2YpLHRoaXMucGlja2VyLmZpbmQoXCJ0Zm9vdCB0aC50b2RheVwiKS50ZXh0KGRbdGhpcy5sYW5ndWFnZV0udG9kYXkpLnRvZ2dsZSh0aGlzLnRvZGF5QnRuIT09ITEpLHRoaXMudXBkYXRlTmF2QXJyb3dzKCksdGhpcy5maWxsTW9udGhzKCk7dmFyIHE9YihmLGctMSwyOCwwLDAsMCwwKSxyPWUuZ2V0RGF5c0luTW9udGgocS5nZXRVVENGdWxsWWVhcigpLHEuZ2V0VVRDTW9udGgoKSk7cS5zZXRVVENEYXRlKHIpLHEuc2V0VVRDRGF0ZShyLShxLmdldFVUQ0RheSgpLXRoaXMud2Vla1N0YXJ0KzcpJTcpO3ZhciBzPW5ldyBEYXRlKHEudmFsdWVPZigpKTtzLnNldFVUQ0RhdGUocy5nZXRVVENEYXRlKCkrNDIpLHM9cy52YWx1ZU9mKCk7Zm9yKHZhciB0LHU9W107cS52YWx1ZU9mKCk8czspe2lmKHEuZ2V0VVRDRGF5KCk9PXRoaXMud2Vla1N0YXJ0JiYodS5wdXNoKFwiPHRyPlwiKSx0aGlzLmNhbGVuZGFyV2Vla3MpKXt2YXIgdj1uZXcgRGF0ZShxLmdldFVUQ0Z1bGxZZWFyKCkscS5nZXRVVENNb250aCgpLHEuZ2V0VVRDRGF0ZSgpLXEuZ2V0RGF5KCkrMTAtKHRoaXMud2Vla1N0YXJ0JiZ0aGlzLndlZWtTdGFydCU3PDUmJjcpKSx3PW5ldyBEYXRlKHYuZ2V0RnVsbFllYXIoKSwwLDQpLHg9fn4oKHYtdykvODY0ZTUvNysxLjUpO3UucHVzaCgnPHRkIGNsYXNzPVwiY3dcIj4nK3grXCI8L3RkPlwiKX10PVwiIFwiK3RoaXMub25SZW5kZXIocSkrXCIgXCIscS5nZXRVVENGdWxsWWVhcigpPGZ8fHEuZ2V0VVRDRnVsbFllYXIoKT09ZiYmcS5nZXRVVENNb250aCgpPGc/dCs9XCIgb2xkXCI6KHEuZ2V0VVRDRnVsbFllYXIoKT5mfHxxLmdldFVUQ0Z1bGxZZWFyKCk9PWYmJnEuZ2V0VVRDTW9udGgoKT5nKSYmKHQrPVwiIG5ld1wiKSx0aGlzLnRvZGF5SGlnaGxpZ2h0JiZxLmdldFVUQ0Z1bGxZZWFyKCk9PXAuZ2V0RnVsbFllYXIoKSYmcS5nZXRVVENNb250aCgpPT1wLmdldE1vbnRoKCkmJnEuZ2V0VVRDRGF0ZSgpPT1wLmdldERhdGUoKSYmKHQrPVwiIHRvZGF5XCIpLG8mJnEudmFsdWVPZigpPT1vJiYodCs9XCIgYWN0aXZlXCIpLChxLnZhbHVlT2YoKTx0aGlzLnN0YXJ0RGF0ZXx8cS52YWx1ZU9mKCk+dGhpcy5lbmREYXRlfHxhLmluQXJyYXkocS5nZXRVVENEYXkoKSx0aGlzLmRheXNPZldlZWtEaXNhYmxlZCkhPT0tMXx8YS5pbkFycmF5KHEudmFsdWVPZigpLHRoaXMuZGF0ZXNEaXNhYmxlZCkhPT0tMSkmJih0Kz1cIiBkaXNhYmxlZFwiKSx1LnB1c2goJzx0ZCBjbGFzcz1cImRheScrdCsnXCI+JytxLmdldFVUQ0RhdGUoKStcIjwvdGQ+XCIpLHEuZ2V0VVRDRGF5KCk9PXRoaXMud2Vla0VuZCYmdS5wdXNoKFwiPC90cj5cIikscS5zZXRVVENEYXRlKHEuZ2V0VVRDRGF0ZSgpKzEpfXRoaXMucGlja2VyLmZpbmQoXCIuZGF0ZXBpY2tlci1kYXlzIHRib2R5XCIpLmVtcHR5KCkuYXBwZW5kKHUuam9pbihcIlwiKSksdT1bXTtmb3IodmFyIHk9MDt5PDI0O3krKyl7dmFyIHo9YihmLGcsaCx5KTt0PVwiXCIsei52YWx1ZU9mKCkrMzZlNTx0aGlzLnN0YXJ0RGF0ZXx8ei52YWx1ZU9mKCk+dGhpcy5lbmREYXRlP3QrPVwiIGRpc2FibGVkXCI6aT09eSYmKHQrPVwiIGFjdGl2ZVwiKSx1LnB1c2goJzxzcGFuIGNsYXNzPVwiaG91cicrdCsnXCI+Jyt5K1wiOjAwPC9zcGFuPlwiKX10aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXItaG91cnMgdGRcIikuaHRtbCh1LmpvaW4oXCJcIikpLHU9W107Zm9yKHZhciB5PTA7eTw2MDt5Kz10aGlzLm1pbnV0ZVN0ZXApe3ZhciB6PWIoZixnLGgsaSx5KTt0PVwiXCIsei52YWx1ZU9mKCk8dGhpcy5zdGFydERhdGV8fHoudmFsdWVPZigpPnRoaXMuZW5kRGF0ZT90Kz1cIiBkaXNhYmxlZFwiOk1hdGguZmxvb3Ioai90aGlzLm1pbnV0ZVN0ZXApPT1NYXRoLmZsb29yKHkvdGhpcy5taW51dGVTdGVwKSYmKHQrPVwiIGFjdGl2ZVwiKSx1LnB1c2goJzxzcGFuIGNsYXNzPVwibWludXRlJyt0KydcIj4nK2krXCI6XCIrKHk8MTA/XCIwXCIreTp5KStcIjwvc3Bhbj5cIil9dGhpcy5waWNrZXIuZmluZChcIi5kYXRlcGlja2VyLW1pbnV0ZXMgdGRcIikuaHRtbCh1LmpvaW4oXCJcIikpO3ZhciBBPXRoaXMuZGF0ZSYmdGhpcy5kYXRlLmdldFVUQ0Z1bGxZZWFyKCksQj10aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXItbW9udGhzXCIpLmZpbmQoXCJ0aDplcSgxKVwiKS50ZXh0KGYpLmVuZCgpLmZpbmQoXCJzcGFuXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlXCIpO0EmJkE9PWYmJkIuZXEodGhpcy5kYXRlLmdldFVUQ01vbnRoKCkpLmFkZENsYXNzKFwiYWN0aXZlXCIpLChmPGt8fGY+bSkmJkIuYWRkQ2xhc3MoXCJkaXNhYmxlZFwiKSxmPT1rJiZCLnNsaWNlKDAsbCkuYWRkQ2xhc3MoXCJkaXNhYmxlZFwiKSxmPT1tJiZCLnNsaWNlKG4rMSkuYWRkQ2xhc3MoXCJkaXNhYmxlZFwiKSx1PVwiXCIsZj0xMCpwYXJzZUludChmLzEwLDEwKTt2YXIgQz10aGlzLnBpY2tlci5maW5kKFwiLmRhdGVwaWNrZXIteWVhcnNcIikuZmluZChcInRoOmVxKDEpXCIpLnRleHQoZitcIi1cIisoZis5KSkuZW5kKCkuZmluZChcInRkXCIpO2YtPTE7Zm9yKHZhciB5PS0xO3k8MTE7eSsrKXUrPSc8c3BhbiBjbGFzcz1cInllYXInKyh5PT0tMXx8MTA9PXk/XCIgb2xkXCI6XCJcIikrKEE9PWY/XCIgYWN0aXZlXCI6XCJcIikrKGY8a3x8Zj5tP1wiIGRpc2FibGVkXCI6XCJcIikrJ1wiPicrZitcIjwvc3Bhbj5cIixmKz0xO0MuaHRtbCh1KX19LHVwZGF0ZU5hdkFycm93czpmdW5jdGlvbigpe3ZhciBhPW5ldyBEYXRlKHRoaXMudmlld0RhdGUpLGI9YS5nZXRVVENGdWxsWWVhcigpLGM9YS5nZXRVVENNb250aCgpLGQ9YS5nZXRVVENEYXRlKCksZT1hLmdldFVUQ0hvdXJzKCk7c3dpdGNoKHRoaXMudmlld01vZGUpe2Nhc2UgMDp0aGlzLnN0YXJ0RGF0ZSE9PS0oMS8wKSYmYjw9dGhpcy5zdGFydERhdGUuZ2V0VVRDRnVsbFllYXIoKSYmYzw9dGhpcy5zdGFydERhdGUuZ2V0VVRDTW9udGgoKSYmZDw9dGhpcy5zdGFydERhdGUuZ2V0VVRDRGF0ZSgpJiZlPD10aGlzLnN0YXJ0RGF0ZS5nZXRVVENIb3VycygpP3RoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJoaWRkZW5cIn0pOnRoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJ2aXNpYmxlXCJ9KSx0aGlzLmVuZERhdGUhPT0xLzAmJmI+PXRoaXMuZW5kRGF0ZS5nZXRVVENGdWxsWWVhcigpJiZjPj10aGlzLmVuZERhdGUuZ2V0VVRDTW9udGgoKSYmZD49dGhpcy5lbmREYXRlLmdldFVUQ0RhdGUoKSYmZT49dGhpcy5lbmREYXRlLmdldFVUQ0hvdXJzKCk/dGhpcy5waWNrZXIuZmluZChcIi5uZXh0XCIpLmNzcyh7dmlzaWJpbGl0eTpcImhpZGRlblwifSk6dGhpcy5waWNrZXIuZmluZChcIi5uZXh0XCIpLmNzcyh7dmlzaWJpbGl0eTpcInZpc2libGVcIn0pO2JyZWFrO2Nhc2UgMTp0aGlzLnN0YXJ0RGF0ZSE9PS0oMS8wKSYmYjw9dGhpcy5zdGFydERhdGUuZ2V0VVRDRnVsbFllYXIoKSYmYzw9dGhpcy5zdGFydERhdGUuZ2V0VVRDTW9udGgoKSYmZDw9dGhpcy5zdGFydERhdGUuZ2V0VVRDRGF0ZSgpP3RoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJoaWRkZW5cIn0pOnRoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJ2aXNpYmxlXCJ9KSx0aGlzLmVuZERhdGUhPT0xLzAmJmI+PXRoaXMuZW5kRGF0ZS5nZXRVVENGdWxsWWVhcigpJiZjPj10aGlzLmVuZERhdGUuZ2V0VVRDTW9udGgoKSYmZD49dGhpcy5lbmREYXRlLmdldFVUQ0RhdGUoKT90aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwiaGlkZGVuXCJ9KTp0aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwidmlzaWJsZVwifSk7YnJlYWs7Y2FzZSAyOnRoaXMuc3RhcnREYXRlIT09LSgxLzApJiZiPD10aGlzLnN0YXJ0RGF0ZS5nZXRVVENGdWxsWWVhcigpJiZjPD10aGlzLnN0YXJ0RGF0ZS5nZXRVVENNb250aCgpP3RoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJoaWRkZW5cIn0pOnRoaXMucGlja2VyLmZpbmQoXCIucHJldlwiKS5jc3Moe3Zpc2liaWxpdHk6XCJ2aXNpYmxlXCJ9KSx0aGlzLmVuZERhdGUhPT0xLzAmJmI+PXRoaXMuZW5kRGF0ZS5nZXRVVENGdWxsWWVhcigpJiZjPj10aGlzLmVuZERhdGUuZ2V0VVRDTW9udGgoKT90aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwiaGlkZGVuXCJ9KTp0aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwidmlzaWJsZVwifSk7YnJlYWs7Y2FzZSAzOmNhc2UgNDp0aGlzLnN0YXJ0RGF0ZSE9PS0oMS8wKSYmYjw9dGhpcy5zdGFydERhdGUuZ2V0VVRDRnVsbFllYXIoKT90aGlzLnBpY2tlci5maW5kKFwiLnByZXZcIikuY3NzKHt2aXNpYmlsaXR5OlwiaGlkZGVuXCJ9KTp0aGlzLnBpY2tlci5maW5kKFwiLnByZXZcIikuY3NzKHt2aXNpYmlsaXR5OlwidmlzaWJsZVwifSksdGhpcy5lbmREYXRlIT09MS8wJiZiPj10aGlzLmVuZERhdGUuZ2V0VVRDRnVsbFllYXIoKT90aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwiaGlkZGVuXCJ9KTp0aGlzLnBpY2tlci5maW5kKFwiLm5leHRcIikuY3NzKHt2aXNpYmlsaXR5OlwidmlzaWJsZVwifSl9fSxjbGljazpmdW5jdGlvbihjKXtjLnN0b3BQcm9wYWdhdGlvbigpLGMucHJldmVudERlZmF1bHQoKSwoYShjLnRhcmdldCkuaGFzQ2xhc3MoXCJkYXRlcGlja2VyLWNsb3NlXCIpfHxhKGMudGFyZ2V0KS5wYXJlbnQoKS5oYXNDbGFzcyhcImRhdGVwaWNrZXItY2xvc2VcIikpJiZ0aGlzLmhpZGUoKTt2YXIgZD1hKGMudGFyZ2V0KS5jbG9zZXN0KFwic3BhbiwgdGQsIHRoXCIpO2lmKDE9PWQubGVuZ3RoKXtpZihkLmlzKFwiLmRpc2FibGVkXCIpKXJldHVybiB2b2lkIHRoaXMuZWxlbWVudC50cmlnZ2VyKHt0eXBlOlwib3V0T2ZSYW5nZVwiLGRhdGU6dGhpcy52aWV3RGF0ZSxzdGFydERhdGU6dGhpcy5zdGFydERhdGUsZW5kRGF0ZTp0aGlzLmVuZERhdGV9KTtzd2l0Y2goZFswXS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKXtjYXNlXCJ0aFwiOnN3aXRjaChkWzBdLmNsYXNzTmFtZSl7Y2FzZVwiZGF0ZS1zd2l0Y2hcIjp0aGlzLnNob3dNb2RlKDEpO2JyZWFrO2Nhc2VcInByZXZcIjpjYXNlXCJuZXh0XCI6dmFyIGY9ZS5tb2Rlc1t0aGlzLnZpZXdNb2RlXS5uYXZTdGVwKihcInByZXZcIj09ZFswXS5jbGFzc05hbWU/LTE6MSk7c3dpdGNoKHRoaXMudmlld01vZGUpe2Nhc2UgMDp0aGlzLnZpZXdEYXRlPXRoaXMubW92ZUhvdXIodGhpcy52aWV3RGF0ZSxmKTticmVhaztjYXNlIDE6dGhpcy52aWV3RGF0ZT10aGlzLm1vdmVEYXRlKHRoaXMudmlld0RhdGUsZik7YnJlYWs7Y2FzZSAyOnRoaXMudmlld0RhdGU9dGhpcy5tb3ZlTW9udGgodGhpcy52aWV3RGF0ZSxmKTticmVhaztjYXNlIDM6Y2FzZSA0OnRoaXMudmlld0RhdGU9dGhpcy5tb3ZlWWVhcih0aGlzLnZpZXdEYXRlLGYpfXRoaXMuZmlsbCgpO2JyZWFrO2Nhc2VcInRvZGF5XCI6dmFyIGc9bmV3IERhdGU7Zz1iKGcuZ2V0RnVsbFllYXIoKSxnLmdldE1vbnRoKCksZy5nZXREYXRlKCksZy5nZXRIb3VycygpLGcuZ2V0TWludXRlcygpLGcuZ2V0U2Vjb25kcygpKSx0aGlzLnZpZXdNb2RlPXRoaXMuc3RhcnRWaWV3TW9kZSx0aGlzLnNob3dNb2RlKDApLHRoaXMuX3NldERhdGUoZyl9YnJlYWs7Y2FzZVwic3BhblwiOmlmKCFkLmlzKFwiLmRpc2FibGVkXCIpKXtpZihkLmlzKFwiLm1vbnRoXCIpKWlmKDM9PT10aGlzLm1pblZpZXcpe3ZhciBoPWQucGFyZW50KCkuZmluZChcInNwYW5cIikuaW5kZXgoZCl8fDAsaT10aGlzLnZpZXdEYXRlLmdldFVUQ0Z1bGxZZWFyKCksaj0xLGs9dGhpcy52aWV3RGF0ZS5nZXRVVENIb3VycygpLGw9dGhpcy52aWV3RGF0ZS5nZXRVVENNaW51dGVzKCksbT10aGlzLnZpZXdEYXRlLmdldFVUQ1NlY29uZHMoKTt0aGlzLl9zZXREYXRlKGIoaSxoLGosayxsLG0sMCkpfWVsc2V7dGhpcy52aWV3RGF0ZS5zZXRVVENEYXRlKDEpO3ZhciBoPWQucGFyZW50KCkuZmluZChcInNwYW5cIikuaW5kZXgoZCk7dGhpcy52aWV3RGF0ZS5zZXRVVENNb250aChoKSx0aGlzLmVsZW1lbnQudHJpZ2dlcih7dHlwZTpcImNoYW5nZU1vbnRoXCIsZGF0ZTp0aGlzLnZpZXdEYXRlfSl9ZWxzZSBpZihkLmlzKFwiLnllYXJcIikpaWYoND09PXRoaXMubWluVmlldyl7dmFyIGk9cGFyc2VJbnQoZC50ZXh0KCksMTApfHwwLGg9MCxqPTEsaz10aGlzLnZpZXdEYXRlLmdldFVUQ0hvdXJzKCksbD10aGlzLnZpZXdEYXRlLmdldFVUQ01pbnV0ZXMoKSxtPXRoaXMudmlld0RhdGUuZ2V0VVRDU2Vjb25kcygpO3RoaXMuX3NldERhdGUoYihpLGgsaixrLGwsbSwwKSl9ZWxzZXt0aGlzLnZpZXdEYXRlLnNldFVUQ0RhdGUoMSk7dmFyIGk9cGFyc2VJbnQoZC50ZXh0KCksMTApfHwwO3RoaXMudmlld0RhdGUuc2V0VVRDRnVsbFllYXIoaSksdGhpcy5lbGVtZW50LnRyaWdnZXIoe3R5cGU6XCJjaGFuZ2VZZWFyXCIsZGF0ZTp0aGlzLnZpZXdEYXRlfSl9ZWxzZSBpZihkLmlzKFwiLmhvdXJcIikpe3ZhciBrPXBhcnNlSW50KGQudGV4dCgpLDEwKXx8MCxpPXRoaXMudmlld0RhdGUuZ2V0VVRDRnVsbFllYXIoKSxoPXRoaXMudmlld0RhdGUuZ2V0VVRDTW9udGgoKSxqPXRoaXMudmlld0RhdGUuZ2V0VVRDRGF0ZSgpLGw9dGhpcy52aWV3RGF0ZS5nZXRVVENNaW51dGVzKCksbT10aGlzLnZpZXdEYXRlLmdldFVUQ1NlY29uZHMoKTt0aGlzLl9zZXREYXRlKGIoaSxoLGosayxsLG0sMCkpfWVsc2UgaWYoZC5pcyhcIi5taW51dGVcIikpe3ZhciBsPXBhcnNlSW50KGQudGV4dCgpLnN1YnN0cihkLnRleHQoKS5pbmRleE9mKFwiOlwiKSsxKSwxMCl8fDAsaT10aGlzLnZpZXdEYXRlLmdldFVUQ0Z1bGxZZWFyKCksaD10aGlzLnZpZXdEYXRlLmdldFVUQ01vbnRoKCksaj10aGlzLnZpZXdEYXRlLmdldFVUQ0RhdGUoKSxrPXRoaXMudmlld0RhdGUuZ2V0VVRDSG91cnMoKSxtPXRoaXMudmlld0RhdGUuZ2V0VVRDU2Vjb25kcygpO3RoaXMuX3NldERhdGUoYihpLGgsaixrLGwsbSwwKSl9aWYoMCE9dGhpcy52aWV3TW9kZSl7dmFyIG49dGhpcy52aWV3TW9kZTt0aGlzLnNob3dNb2RlKC0xKSx0aGlzLmZpbGwoKSxuPT10aGlzLnZpZXdNb2RlJiZ0aGlzLmF1dG9jbG9zZSYmdGhpcy5oaWRlKCl9ZWxzZSB0aGlzLmZpbGwoKSx0aGlzLmF1dG9jbG9zZSYmdGhpcy5oaWRlKCl9YnJlYWs7Y2FzZVwidGRcIjppZihkLmlzKFwiLmRheVwiKSYmIWQuaXMoXCIuZGlzYWJsZWRcIikpe3ZhciBqPXBhcnNlSW50KGQudGV4dCgpLDEwKXx8MSxpPXRoaXMudmlld0RhdGUuZ2V0VVRDRnVsbFllYXIoKSxoPXRoaXMudmlld0RhdGUuZ2V0VVRDTW9udGgoKSxrPXRoaXMudmlld0RhdGUuZ2V0VVRDSG91cnMoKSxsPXRoaXMudmlld0RhdGUuZ2V0VVRDTWludXRlcygpLG09dGhpcy52aWV3RGF0ZS5nZXRVVENTZWNvbmRzKCk7ZC5pcyhcIi5vbGRcIik/MD09PWg/KGg9MTEsaS09MSk6aC09MTpkLmlzKFwiLm5ld1wiKSYmKDExPT1oPyhoPTAsaSs9MSk6aCs9MSksdGhpcy5fc2V0RGF0ZShiKGksaCxqLGssbCxtLDApKX12YXIgbj10aGlzLnZpZXdNb2RlO3RoaXMuc2hvd01vZGUoLTEpLHRoaXMuZmlsbCgpLG49PXRoaXMudmlld01vZGUmJnRoaXMuYXV0b2Nsb3NlJiZ0aGlzLmhpZGUoKX19fSxfc2V0RGF0ZTpmdW5jdGlvbihhLGIpe2ImJlwiZGF0ZVwiIT1ifHwodGhpcy5kYXRlPWEpLGImJlwidmlld1wiIT1ifHwodGhpcy52aWV3RGF0ZT1hKSx0aGlzLmZpbGwoKSx0aGlzLnNldFZhbHVlKCksdGhpcy5lbGVtZW50LnRyaWdnZXIoe3R5cGU6XCJjaGFuZ2VEYXRlXCIsZGF0ZTp0aGlzLmRhdGV9KTt2YXIgYzt0aGlzLmlzSW5wdXQ/Yz10aGlzLmVsZW1lbnQ6dGhpcy5jb21wb25lbnQmJihjPXRoaXMuZWxlbWVudC5maW5kKFwiaW5wdXRcIikpLGMmJihjLmNoYW5nZSgpLHRoaXMuYXV0b2Nsb3NlJiYoIWJ8fFwiZGF0ZVwiPT1iKSl9LG1vdmVIb3VyOmZ1bmN0aW9uKGEsYil7aWYoIWIpcmV0dXJuIGE7dmFyIGM9bmV3IERhdGUoYS52YWx1ZU9mKCkpO3JldHVybiBiPWI+MD8xOi0xLGMuc2V0VVRDSG91cnMoYy5nZXRVVENIb3VycygpK2IpLGN9LG1vdmVEYXRlOmZ1bmN0aW9uKGEsYil7aWYoIWIpcmV0dXJuIGE7dmFyIGM9bmV3IERhdGUoYS52YWx1ZU9mKCkpO3JldHVybiBiPWI+MD8xOi0xLGMuc2V0VVRDRGF0ZShjLmdldFVUQ0RhdGUoKStiKSxjfSxtb3ZlTW9udGg6ZnVuY3Rpb24oYSxiKXtpZighYilyZXR1cm4gYTt2YXIgYyxkLGU9bmV3IERhdGUoYS52YWx1ZU9mKCkpLGY9ZS5nZXRVVENEYXRlKCksZz1lLmdldFVUQ01vbnRoKCksaD1NYXRoLmFicyhiKTtpZihiPWI+MD8xOi0xLDE9PWgpZD1iPT0tMT9mdW5jdGlvbigpe3JldHVybiBlLmdldFVUQ01vbnRoKCk9PWd9OmZ1bmN0aW9uKCl7cmV0dXJuIGUuZ2V0VVRDTW9udGgoKSE9Y30sYz1nK2IsZS5zZXRVVENNb250aChjKSwoYzwwfHxjPjExKSYmKGM9KGMrMTIpJTEyKTtlbHNle2Zvcih2YXIgaT0wO2k8aDtpKyspZT10aGlzLm1vdmVNb250aChlLGIpO2M9ZS5nZXRVVENNb250aCgpLGUuc2V0VVRDRGF0ZShmKSxkPWZ1bmN0aW9uKCl7cmV0dXJuIGMhPWUuZ2V0VVRDTW9udGgoKX19Zm9yKDtkKCk7KWUuc2V0VVRDRGF0ZSgtLWYpLGUuc2V0VVRDTW9udGgoYyk7cmV0dXJuIGV9LG1vdmVZZWFyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMubW92ZU1vbnRoKGEsMTIqYil9LGRhdGVXaXRoaW5SYW5nZTpmdW5jdGlvbihhKXtyZXR1cm4gYT49dGhpcy5zdGFydERhdGUmJmE8PXRoaXMuZW5kRGF0ZX0sa2V5ZG93bjpmdW5jdGlvbihhKXtpZighdGhpcy5rZXlib2FyZE5hdmlnYXRpb24pcmV0dXJuITA7aWYodGhpcy5waWNrZXIuaXMoXCI6bm90KDp2aXNpYmxlKVwiKSlyZXR1cm4gdm9pZCgyNz09YS5rZXlDb2RlJiZ0aGlzLnNob3coKSk7dmFyIGIsYyxkLGU9ITE7c3dpdGNoKGEua2V5Q29kZSl7Y2FzZSAyNzp0aGlzLmhpZGUoKSxhLnByZXZlbnREZWZhdWx0KCk7YnJlYWs7Y2FzZSAzNzpjYXNlIDM5OmlmKCF0aGlzLmtleWJvYXJkTmF2aWdhdGlvbilicmVhaztiPTM3PT1hLmtleUNvZGU/LTE6MSxhLmN0cmxLZXk/KGM9dGhpcy5tb3ZlWWVhcih0aGlzLmRhdGUsYiksZD10aGlzLm1vdmVZZWFyKHRoaXMudmlld0RhdGUsYikpOmEuc2hpZnRLZXk/KGM9dGhpcy5tb3ZlTW9udGgodGhpcy5kYXRlLGIpLGQ9dGhpcy5tb3ZlTW9udGgodGhpcy52aWV3RGF0ZSxiKSk6KGM9bmV3IERhdGUodGhpcy5kYXRlLnZhbHVlT2YoKSksYy5zZXRVVENEYXRlKHRoaXMuZGF0ZS5nZXRVVENEYXRlKCkrYiksZD1uZXcgRGF0ZSh0aGlzLnZpZXdEYXRlLnZhbHVlT2YoKSksZC5zZXRVVENEYXRlKHRoaXMudmlld0RhdGUuZ2V0VVRDRGF0ZSgpK2IpKSx0aGlzLmRhdGVXaXRoaW5SYW5nZShjKSYmKHRoaXMuZGF0ZT1jLHRoaXMudmlld0RhdGU9ZCx0aGlzLnNldFZhbHVlKCksdGhpcy51cGRhdGUoKSxhLnByZXZlbnREZWZhdWx0KCksZT0hMCk7YnJlYWs7Y2FzZSAzODpjYXNlIDQwOmlmKCF0aGlzLmtleWJvYXJkTmF2aWdhdGlvbilicmVhaztiPTM4PT1hLmtleUNvZGU/LTE6MSxhLmN0cmxLZXk/KGM9dGhpcy5tb3ZlWWVhcih0aGlzLmRhdGUsYiksZD10aGlzLm1vdmVZZWFyKHRoaXMudmlld0RhdGUsYikpOmEuc2hpZnRLZXk/KGM9dGhpcy5tb3ZlTW9udGgodGhpcy5kYXRlLGIpLGQ9dGhpcy5tb3ZlTW9udGgodGhpcy52aWV3RGF0ZSxiKSk6KGM9bmV3IERhdGUodGhpcy5kYXRlLnZhbHVlT2YoKSksYy5zZXRVVENEYXRlKHRoaXMuZGF0ZS5nZXRVVENEYXRlKCkrNypiKSxkPW5ldyBEYXRlKHRoaXMudmlld0RhdGUudmFsdWVPZigpKSxkLnNldFVUQ0RhdGUodGhpcy52aWV3RGF0ZS5nZXRVVENEYXRlKCkrNypiKSksdGhpcy5kYXRlV2l0aGluUmFuZ2UoYykmJih0aGlzLmRhdGU9Yyx0aGlzLnZpZXdEYXRlPWQsdGhpcy5zZXRWYWx1ZSgpLHRoaXMudXBkYXRlKCksYS5wcmV2ZW50RGVmYXVsdCgpLGU9ITApO2JyZWFrO2Nhc2UgMTM6dGhpcy5oaWRlKCksYS5wcmV2ZW50RGVmYXVsdCgpO2JyZWFrO2Nhc2UgOTp0aGlzLmhpZGUoKX1pZihlKXt0aGlzLmVsZW1lbnQudHJpZ2dlcih7dHlwZTpcImNoYW5nZURhdGVcIixkYXRlOnRoaXMuZGF0ZX0pO3ZhciBmO3RoaXMuaXNJbnB1dD9mPXRoaXMuZWxlbWVudDp0aGlzLmNvbXBvbmVudCYmKGY9dGhpcy5lbGVtZW50LmZpbmQoXCJpbnB1dFwiKSksZiYmZi5jaGFuZ2UoKX19LHNob3dNb2RlOmZ1bmN0aW9uKGEpe2lmKGEpe3ZhciBiPU1hdGgubWF4KDAsTWF0aC5taW4oZS5tb2Rlcy5sZW5ndGgtMSx0aGlzLnZpZXdNb2RlK2EpKTtiPj10aGlzLm1pblZpZXcmJmI8PXRoaXMubWF4VmlldyYmKHRoaXMudmlld01vZGU9Yil9dGhpcy5waWNrZXIuZmluZChcIj5kaXZcIikuaGlkZSgpLmZpbHRlcihcIi5kYXRlcGlja2VyLVwiK2UubW9kZXNbdGhpcy52aWV3TW9kZV0uY2xzTmFtZSkuY3NzKFwiZGlzcGxheVwiLFwiYmxvY2tcIiksdGhpcy51cGRhdGVOYXZBcnJvd3MoKX0scmVzZXQ6ZnVuY3Rpb24oYSl7dGhpcy5fc2V0RGF0ZShudWxsLFwiZGF0ZVwiKX19LGEuZm4uZmRhdGVwaWNrZXI9ZnVuY3Rpb24oYil7dmFyIGQ9QXJyYXkuYXBwbHkobnVsbCxhcmd1bWVudHMpO3JldHVybiBkLnNoaWZ0KCksdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9YSh0aGlzKSxmPWUuZGF0YShcImRhdGVwaWNrZXJcIiksZz1cIm9iamVjdFwiPT10eXBlb2YgYiYmYjtmfHxlLmRhdGEoXCJkYXRlcGlja2VyXCIsZj1uZXcgYyh0aGlzLGEuZXh0ZW5kKHt9LGEuZm4uZmRhdGVwaWNrZXIuZGVmYXVsdHMsZykpKSxcInN0cmluZ1wiPT10eXBlb2YgYiYmXCJmdW5jdGlvblwiPT10eXBlb2YgZltiXSYmZltiXS5hcHBseShmLGQpfSl9LGEuZm4uZmRhdGVwaWNrZXIuZGVmYXVsdHM9e29uUmVuZGVyOmZ1bmN0aW9uKGEpe3JldHVyblwiXCJ9fSxhLmZuLmZkYXRlcGlja2VyLkNvbnN0cnVjdG9yPWM7dmFyIGQ9YS5mbi5mZGF0ZXBpY2tlci5kYXRlcz17ZW46e2RheXM6W1wiU3VuZGF5XCIsXCJNb25kYXlcIixcIlR1ZXNkYXlcIixcIldlZG5lc2RheVwiLFwiVGh1cnNkYXlcIixcIkZyaWRheVwiLFwiU2F0dXJkYXlcIixcIlN1bmRheVwiXSxkYXlzU2hvcnQ6W1wiU3VuXCIsXCJNb25cIixcIlR1ZVwiLFwiV2VkXCIsXCJUaHVcIixcIkZyaVwiLFwiU2F0XCIsXCJTdW5cIl0sZGF5c01pbjpbXCJTdVwiLFwiTW9cIixcIlR1XCIsXCJXZVwiLFwiVGhcIixcIkZyXCIsXCJTYVwiLFwiU3VcIl0sbW9udGhzOltcIkphbnVhcnlcIixcIkZlYnJ1YXJ5XCIsXCJNYXJjaFwiLFwiQXByaWxcIixcIk1heVwiLFwiSnVuZVwiLFwiSnVseVwiLFwiQXVndXN0XCIsXCJTZXB0ZW1iZXJcIixcIk9jdG9iZXJcIixcIk5vdmVtYmVyXCIsXCJEZWNlbWJlclwiXSxtb250aHNTaG9ydDpbXCJKYW5cIixcIkZlYlwiLFwiTWFyXCIsXCJBcHJcIixcIk1heVwiLFwiSnVuXCIsXCJKdWxcIixcIkF1Z1wiLFwiU2VwXCIsXCJPY3RcIixcIk5vdlwiLFwiRGVjXCJdLHRvZGF5OlwiVG9kYXlcIix0aXRsZUZvcm1hdDpcIk1NIHl5eXlcIn19LGU9e21vZGVzOlt7Y2xzTmFtZTpcIm1pbnV0ZXNcIixuYXZGbmM6XCJIb3Vyc1wiLG5hdlN0ZXA6MX0se2Nsc05hbWU6XCJob3Vyc1wiLG5hdkZuYzpcIkRhdGVcIixuYXZTdGVwOjF9LHtjbHNOYW1lOlwiZGF5c1wiLG5hdkZuYzpcIk1vbnRoXCIsbmF2U3RlcDoxfSx7Y2xzTmFtZTpcIm1vbnRoc1wiLG5hdkZuYzpcIkZ1bGxZZWFyXCIsbmF2U3RlcDoxfSx7Y2xzTmFtZTpcInllYXJzXCIsbmF2Rm5jOlwiRnVsbFllYXJcIixuYXZTdGVwOjEwfV0saXNMZWFwWWVhcjpmdW5jdGlvbihhKXtyZXR1cm4gYSU0PT09MCYmYSUxMDAhPT0wfHxhJTQwMD09PTB9LGdldERheXNJbk1vbnRoOmZ1bmN0aW9uKGEsYil7cmV0dXJuWzMxLGUuaXNMZWFwWWVhcihhKT8yOToyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV1bYl19LHZhbGlkUGFydHM6L2hoP3xpaT98c3M/fGRkP3xtbT98TU0/fHl5KD86eXkpPy9nLG5vbnB1bmN0dWF0aW9uOi9bXiAtXFwvOi1AXFxbXFx1MzQwMC1cXHU5ZmZmLWB7LX5cXHRcXG5cXHJdKy9nLHBhcnNlRm9ybWF0OmZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZSh0aGlzLnZhbGlkUGFydHMsXCJcXDBcIikuc3BsaXQoXCJcXDBcIiksYz1hLm1hdGNoKHRoaXMudmFsaWRQYXJ0cyk7aWYoIWJ8fCFiLmxlbmd0aHx8IWN8fDA9PT1jLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGRhdGUgZm9ybWF0LlwiKTtyZXR1cm4gdGhpcy5mb3JtYXRUZXh0PWEse3NlcGFyYXRvcnM6YixwYXJ0czpjfX0scGFyc2VEYXRlOmZ1bmN0aW9uKGMsZSxmKXtpZihjIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gbmV3IERhdGUoYy52YWx1ZU9mKCktNmU0KmMuZ2V0VGltZXpvbmVPZmZzZXQoKSk7aWYoL15cXGR7NH1cXC1cXGR7MSwyfVxcLVxcZHsxLDJ9JC8udGVzdChjKSYmKGU9dGhpcy5wYXJzZUZvcm1hdChcInl5eXktbW0tZGRcIikpLC9eXFxkezR9XFwtXFxkezEsMn1cXC1cXGR7MSwyfVtUIF1cXGR7MSwyfVxcOlxcZHsxLDJ9JC8udGVzdChjKSYmKGU9dGhpcy5wYXJzZUZvcm1hdChcInl5eXktbW0tZGQgaGg6aWlcIikpLC9eXFxkezR9XFwtXFxkezEsMn1cXC1cXGR7MSwyfVtUIF1cXGR7MSwyfVxcOlxcZHsxLDJ9XFw6XFxkezEsMn1bWl17MCwxfSQvLnRlc3QoYykmJihlPXRoaXMucGFyc2VGb3JtYXQoXCJ5eXl5LW1tLWRkIGhoOmlpOnNzXCIpKSwvXlstK11cXGQrW2Rtd3ldKFtcXHMsXStbLStdXFxkK1tkbXd5XSkqJC8udGVzdChjKSl7dmFyIGcsaCxpPS8oWy0rXVxcZCspKFtkbXd5XSkvLGo9Yy5tYXRjaCgvKFstK11cXGQrKShbZG13eV0pL2cpO2M9bmV3IERhdGU7Zm9yKHZhciBrPTA7azxqLmxlbmd0aDtrKyspc3dpdGNoKGc9aS5leGVjKGpba10pLGg9cGFyc2VJbnQoZ1sxXSksZ1syXSl7Y2FzZVwiZFwiOmMuc2V0VVRDRGF0ZShjLmdldFVUQ0RhdGUoKStoKTticmVhaztjYXNlXCJtXCI6Yz1EYXRldGltZXBpY2tlci5wcm90b3R5cGUubW92ZU1vbnRoLmNhbGwoRGF0ZXRpbWVwaWNrZXIucHJvdG90eXBlLGMsaCk7YnJlYWs7Y2FzZVwid1wiOmMuc2V0VVRDRGF0ZShjLmdldFVUQ0RhdGUoKSs3KmgpO2JyZWFrO2Nhc2VcInlcIjpjPURhdGV0aW1lcGlja2VyLnByb3RvdHlwZS5tb3ZlWWVhci5jYWxsKERhdGV0aW1lcGlja2VyLnByb3RvdHlwZSxjLGgpfXJldHVybiBiKGMuZ2V0VVRDRnVsbFllYXIoKSxjLmdldFVUQ01vbnRoKCksYy5nZXRVVENEYXRlKCksYy5nZXRVVENIb3VycygpLGMuZ2V0VVRDTWludXRlcygpLGMuZ2V0VVRDU2Vjb25kcygpKX12YXIgbCxtLGcsaj1jJiZjLm1hdGNoKHRoaXMubm9ucHVuY3R1YXRpb24pfHxbXSxjPW5ldyBEYXRlLG49e30sbz1bXCJoaFwiLFwiaFwiLFwiaWlcIixcImlcIixcInNzXCIsXCJzXCIsXCJ5eXl5XCIsXCJ5eVwiLFwiTVwiLFwiTU1cIixcIm1cIixcIm1tXCIsXCJkXCIsXCJkZFwiXSxwPXtoaDpmdW5jdGlvbihhLGIpe3JldHVybiBhLnNldFVUQ0hvdXJzKGIpfSxoOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuc2V0VVRDSG91cnMoYil9LGlpOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuc2V0VVRDTWludXRlcyhiKX0saTpmdW5jdGlvbihhLGIpe3JldHVybiBhLnNldFVUQ01pbnV0ZXMoYil9LHNzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuc2V0VVRDU2Vjb25kcyhiKX0sczpmdW5jdGlvbihhLGIpe3JldHVybiBhLnNldFVUQ1NlY29uZHMoYil9LHl5eXk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5zZXRVVENGdWxsWWVhcihiKX0seXk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5zZXRVVENGdWxsWWVhcigyZTMrYil9LG06ZnVuY3Rpb24oYSxiKXtmb3IoYi09MTtiPDA7KWIrPTEyO2ZvcihiJT0xMixhLnNldFVUQ01vbnRoKGIpO2EuZ2V0VVRDTW9udGgoKSE9YjspYS5zZXRVVENEYXRlKGEuZ2V0VVRDRGF0ZSgpLTEpO3JldHVybiBhfSxkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuc2V0VVRDRGF0ZShiKX19O2lmKHAuTT1wLk1NPXAubW09cC5tLHAuZGQ9cC5kLGM9YihjLmdldEZ1bGxZZWFyKCksYy5nZXRNb250aCgpLGMuZ2V0RGF0ZSgpLDAsMCwwKSxqLmxlbmd0aD09ZS5wYXJ0cy5sZW5ndGgpe2Zvcih2YXIgaz0wLHE9ZS5wYXJ0cy5sZW5ndGg7azxxO2srKyl7aWYobD1wYXJzZUludChqW2tdLDEwKSxnPWUucGFydHNba10saXNOYU4obCkpc3dpdGNoKGcpe2Nhc2VcIk1NXCI6bT1hKGRbZl0ubW9udGhzKS5maWx0ZXIoZnVuY3Rpb24oKXt2YXIgYT10aGlzLnNsaWNlKDAsaltrXS5sZW5ndGgpLGI9altrXS5zbGljZSgwLGEubGVuZ3RoKTtyZXR1cm4gYT09Yn0pLGw9YS5pbkFycmF5KG1bMF0sZFtmXS5tb250aHMpKzE7YnJlYWs7Y2FzZVwiTVwiOm09YShkW2ZdLm1vbnRoc1Nob3J0KS5maWx0ZXIoZnVuY3Rpb24oKXt2YXIgYT10aGlzLnNsaWNlKDAsaltrXS5sZW5ndGgpLGI9altrXS5zbGljZSgwLGEubGVuZ3RoKTtyZXR1cm4gYT09Yn0pLGw9YS5pbkFycmF5KG1bMF0sZFtmXS5tb250aHNTaG9ydCkrMX1uW2ddPWx9Zm9yKHZhciByLGs9MDtrPG8ubGVuZ3RoO2srKylyPW9ba10sciBpbiBuJiYhaXNOYU4obltyXSkmJnBbcl0oYyxuW3JdKX1yZXR1cm4gY30sZm9ybWF0RGF0ZTpmdW5jdGlvbihiLGMsZSl7aWYobnVsbD09YilyZXR1cm5cIlwiO3ZhciBmPXtoOmIuZ2V0VVRDSG91cnMoKSxpOmIuZ2V0VVRDTWludXRlcygpLHM6Yi5nZXRVVENTZWNvbmRzKCksZDpiLmdldFVUQ0RhdGUoKSxtOmIuZ2V0VVRDTW9udGgoKSsxLE06ZFtlXS5tb250aHNTaG9ydFtiLmdldFVUQ01vbnRoKCldLE1NOmRbZV0ubW9udGhzW2IuZ2V0VVRDTW9udGgoKV0seXk6Yi5nZXRVVENGdWxsWWVhcigpLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpLHl5eXk6Yi5nZXRVVENGdWxsWWVhcigpfTtmLmhoPShmLmg8MTA/XCIwXCI6XCJcIikrZi5oLGYuaWk9KGYuaTwxMD9cIjBcIjpcIlwiKStmLmksZi5zcz0oZi5zPDEwP1wiMFwiOlwiXCIpK2YucyxmLmRkPShmLmQ8MTA/XCIwXCI6XCJcIikrZi5kLGYubW09KGYubTwxMD9cIjBcIjpcIlwiKStmLm07Zm9yKHZhciBiPVtdLGc9YS5leHRlbmQoW10sYy5zZXBhcmF0b3JzKSxoPTAsaT1jLnBhcnRzLmxlbmd0aDtoPGk7aCsrKWcubGVuZ3RoJiZiLnB1c2goZy5zaGlmdCgpKSxiLnB1c2goZltjLnBhcnRzW2hdXSk7cmV0dXJuIGIuam9pbihcIlwiKX0sY29udmVydFZpZXdNb2RlOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIDQ6Y2FzZVwiZGVjYWRlXCI6YT00O2JyZWFrO2Nhc2UgMzpjYXNlXCJ5ZWFyXCI6YT0zO2JyZWFrO2Nhc2UgMjpjYXNlXCJtb250aFwiOmE9MjticmVhaztjYXNlIDE6Y2FzZVwiZGF5XCI6YT0xO2JyZWFrO2Nhc2UgMDpjYXNlXCJob3VyXCI6YT0wfXJldHVybiBhfSxoZWFkVGVtcGxhdGU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4nPHRoZWFkPjx0cj48dGggY2xhc3M9XCJwcmV2XCI+JythKyc8L3RoPjx0aCBjb2xzcGFuPVwiNVwiIGNsYXNzPVwiZGF0ZS1zd2l0Y2hcIj48L3RoPjx0aCBjbGFzcz1cIm5leHRcIj4nK2IrXCI8L3RoPjwvdHI+PC90aGVhZD5cIn0sY29udFRlbXBsYXRlOic8dGJvZHk+PHRyPjx0ZCBjb2xzcGFuPVwiN1wiPjwvdGQ+PC90cj48L3Rib2R5PicsZm9vdFRlbXBsYXRlOic8dGZvb3Q+PHRyPjx0aCBjb2xzcGFuPVwiN1wiIGNsYXNzPVwidG9kYXlcIj48L3RoPjwvdHI+PC90Zm9vdD4nfTtlLnRlbXBsYXRlPWZ1bmN0aW9uKGEsYixjKXtyZXR1cm4nPGRpdiBjbGFzcz1cImRhdGVwaWNrZXJcIj48ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlci1taW51dGVzXCI+PHRhYmxlIGNsYXNzPVwiIHRhYmxlLWNvbmRlbnNlZFwiPicrZS5oZWFkVGVtcGxhdGUoYSxiKStlLmNvbnRUZW1wbGF0ZStlLmZvb3RUZW1wbGF0ZSsnPC90YWJsZT48L2Rpdj48ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlci1ob3Vyc1wiPjx0YWJsZSBjbGFzcz1cIiB0YWJsZS1jb25kZW5zZWRcIj4nK2UuaGVhZFRlbXBsYXRlKGEsYikrZS5jb250VGVtcGxhdGUrZS5mb290VGVtcGxhdGUrJzwvdGFibGU+PC9kaXY+PGRpdiBjbGFzcz1cImRhdGVwaWNrZXItZGF5c1wiPjx0YWJsZSBjbGFzcz1cIiB0YWJsZS1jb25kZW5zZWRcIj4nK2UuaGVhZFRlbXBsYXRlKGEsYikrXCI8dGJvZHk+PC90Ym9keT5cIitlLmZvb3RUZW1wbGF0ZSsnPC90YWJsZT48L2Rpdj48ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlci1tb250aHNcIj48dGFibGUgY2xhc3M9XCJ0YWJsZS1jb25kZW5zZWRcIj4nK2UuaGVhZFRlbXBsYXRlKGEsYikrZS5jb250VGVtcGxhdGUrZS5mb290VGVtcGxhdGUrJzwvdGFibGU+PC9kaXY+PGRpdiBjbGFzcz1cImRhdGVwaWNrZXIteWVhcnNcIj48dGFibGUgY2xhc3M9XCJ0YWJsZS1jb25kZW5zZWRcIj4nK2UuaGVhZFRlbXBsYXRlKGEsYikrZS5jb250VGVtcGxhdGUrZS5mb290VGVtcGxhdGUrJzwvdGFibGU+PC9kaXY+PGEgY2xhc3M9XCJidXR0b24gZGF0ZXBpY2tlci1jbG9zZSB0aW55IGFsZXJ0IHJpZ2h0XCIgc3R5bGU9XCJ3aWR0aDphdXRvO1wiPicrYytcIjwvYT48L2Rpdj5cIn0sYS5mbi5mZGF0ZXBpY2tlci5EUEdsb2JhbD1lfSh3aW5kb3cualF1ZXJ5KTsiLCIvKlxyXG4gKiBGb3VuZGF0aW9uIFJlc3BvbnNpdmUgTGlicmFyeVxyXG4gKiBodHRwOi8vZm91bmRhdGlvbi56dXJiLmNvbVxyXG4gKiBDb3B5cmlnaHQgMjAxNSwgWlVSQlxyXG4gKiBGcmVlIHRvIHVzZSB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXHJcbiAqIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcbiovXHJcblxyXG4oZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIGhlYWRlcl9oZWxwZXJzID0gZnVuY3Rpb24gKGNsYXNzX2FycmF5KSB7XHJcbiAgICB2YXIgaGVhZCA9ICQoJ2hlYWQnKTtcclxuICAgIGhlYWQucHJlcGVuZCgkLm1hcChjbGFzc19hcnJheSwgZnVuY3Rpb24gKGNsYXNzX25hbWUpIHtcclxuICAgICAgaWYgKGhlYWQuaGFzKCcuJyArIGNsYXNzX25hbWUpLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybiAnPG1ldGEgY2xhc3M9XCInICsgY2xhc3NfbmFtZSArICdcIiAvPic7XHJcbiAgICAgIH1cclxuICAgIH0pKTtcclxuICB9O1xyXG5cclxuICBoZWFkZXJfaGVscGVycyhbXHJcbiAgICAnZm91bmRhdGlvbi1tcS1zbWFsbCcsXHJcbiAgICAnZm91bmRhdGlvbi1tcS1zbWFsbC1vbmx5JyxcclxuICAgICdmb3VuZGF0aW9uLW1xLW1lZGl1bScsXHJcbiAgICAnZm91bmRhdGlvbi1tcS1tZWRpdW0tb25seScsXHJcbiAgICAnZm91bmRhdGlvbi1tcS1sYXJnZScsXHJcbiAgICAnZm91bmRhdGlvbi1tcS1sYXJnZS1vbmx5JyxcclxuICAgICdmb3VuZGF0aW9uLW1xLXhsYXJnZScsXHJcbiAgICAnZm91bmRhdGlvbi1tcS14bGFyZ2Utb25seScsXHJcbiAgICAnZm91bmRhdGlvbi1tcS14eGxhcmdlJyxcclxuICAgICdmb3VuZGF0aW9uLWRhdGEtYXR0cmlidXRlLW5hbWVzcGFjZSddKTtcclxuXHJcbiAgLy8gRW5hYmxlIEZhc3RDbGljayBpZiBwcmVzZW50XHJcblxyXG4gICQoZnVuY3Rpb24gKCkge1xyXG4gICAgaWYgKHR5cGVvZiBGYXN0Q2xpY2sgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIC8vIERvbid0IGF0dGFjaCB0byBib2R5IGlmIHVuZGVmaW5lZFxyXG4gICAgICBpZiAodHlwZW9mIGRvY3VtZW50LmJvZHkgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgRmFzdENsaWNrLmF0dGFjaChkb2N1bWVudC5ib2R5KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBwcml2YXRlIEZhc3QgU2VsZWN0b3Igd3JhcHBlcixcclxuICAvLyByZXR1cm5zIGpRdWVyeSBvYmplY3QuIE9ubHkgdXNlIHdoZXJlXHJcbiAgLy8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IGF2YWlsYWJsZS5cclxuICB2YXIgUyA9IGZ1bmN0aW9uIChzZWxlY3RvciwgY29udGV4dCkge1xyXG4gICAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgaWYgKGNvbnRleHQpIHtcclxuICAgICAgICB2YXIgY29udDtcclxuICAgICAgICBpZiAoY29udGV4dC5qcXVlcnkpIHtcclxuICAgICAgICAgIGNvbnQgPSBjb250ZXh0WzBdO1xyXG4gICAgICAgICAgaWYgKCFjb250KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb250ID0gY29udGV4dDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuICQoY29udC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiAkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gJChzZWxlY3RvciwgY29udGV4dCk7XHJcbiAgfTtcclxuXHJcbiAgLy8gTmFtZXNwYWNlIGZ1bmN0aW9ucy5cclxuXHJcbiAgdmFyIGF0dHJfbmFtZSA9IGZ1bmN0aW9uIChpbml0KSB7XHJcbiAgICB2YXIgYXJyID0gW107XHJcbiAgICBpZiAoIWluaXQpIHtcclxuICAgICAgYXJyLnB1c2goJ2RhdGEnKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm5hbWVzcGFjZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGFyci5wdXNoKHRoaXMubmFtZXNwYWNlKTtcclxuICAgIH1cclxuICAgIGFyci5wdXNoKHRoaXMubmFtZSk7XHJcblxyXG4gICAgcmV0dXJuIGFyci5qb2luKCctJyk7XHJcbiAgfTtcclxuXHJcbiAgdmFyIGFkZF9uYW1lc3BhY2UgPSBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoJy0nKSxcclxuICAgICAgICBpID0gcGFydHMubGVuZ3RoLFxyXG4gICAgICAgIGFyciA9IFtdO1xyXG5cclxuICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgaWYgKGkgIT09IDApIHtcclxuICAgICAgICBhcnIucHVzaChwYXJ0c1tpXSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHRoaXMubmFtZXNwYWNlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGFyci5wdXNoKHRoaXMubmFtZXNwYWNlLCBwYXJ0c1tpXSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGFyci5wdXNoKHBhcnRzW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gYXJyLnJldmVyc2UoKS5qb2luKCctJyk7XHJcbiAgfTtcclxuXHJcbiAgLy8gRXZlbnQgYmluZGluZyBhbmQgZGF0YS1vcHRpb25zIHVwZGF0aW5nLlxyXG5cclxuICB2YXIgYmluZGluZ3MgPSBmdW5jdGlvbiAobWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgYmluZCA9IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICB2YXIgJHRoaXMgPSBTKHRoaXMpLFxyXG4gICAgICAgICAgICAgIHNob3VsZF9iaW5kX2V2ZW50cyA9ICEkdGhpcy5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0Jyk7XHJcbiAgICAgICAgICAkdGhpcy5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JywgJC5leHRlbmQoe30sIHNlbGYuc2V0dGluZ3MsIChvcHRpb25zIHx8IG1ldGhvZCksIHNlbGYuZGF0YV9vcHRpb25zKCR0aGlzKSkpO1xyXG5cclxuICAgICAgICAgIGlmIChzaG91bGRfYmluZF9ldmVudHMpIHtcclxuICAgICAgICAgICAgc2VsZi5ldmVudHModGhpcyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICBpZiAoUyh0aGlzLnNjb3BlKS5pcygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsnXScpKSB7XHJcbiAgICAgIGJpbmQuY2FsbCh0aGlzLnNjb3BlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIFMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArJ10nLCB0aGlzLnNjb3BlKS5lYWNoKGJpbmQpO1xyXG4gICAgfVxyXG4gICAgLy8gIyBQYXRjaCB0byBmaXggIzUwNDMgdG8gbW92ZSB0aGlzICphZnRlciogdGhlIGlmL2Vsc2UgY2xhdXNlIGluIG9yZGVyIGZvciBCYWNrYm9uZSBhbmQgc2ltaWxhciBmcmFtZXdvcmtzIHRvIGhhdmUgaW1wcm92ZWQgY29udHJvbCBvdmVyIGV2ZW50IGJpbmRpbmcgYW5kIGRhdGEtb3B0aW9ucyB1cGRhdGluZy5cclxuICAgIGlmICh0eXBlb2YgbWV0aG9kID09PSAnc3RyaW5nJykge1xyXG4gICAgICByZXR1cm4gdGhpc1ttZXRob2RdLmNhbGwodGhpcywgb3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gIH07XHJcblxyXG4gIHZhciBzaW5nbGVfaW1hZ2VfbG9hZGVkID0gZnVuY3Rpb24gKGltYWdlLCBjYWxsYmFjaykge1xyXG4gICAgZnVuY3Rpb24gbG9hZGVkICgpIHtcclxuICAgICAgY2FsbGJhY2soaW1hZ2VbMF0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGJpbmRMb2FkICgpIHtcclxuICAgICAgdGhpcy5vbmUoJ2xvYWQnLCBsb2FkZWQpO1xyXG5cclxuICAgICAgaWYgKC9NU0lFIChcXGQrXFwuXFxkKyk7Ly50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XHJcbiAgICAgICAgdmFyIHNyYyA9IHRoaXMuYXR0ciggJ3NyYycgKSxcclxuICAgICAgICAgICAgcGFyYW0gPSBzcmMubWF0Y2goIC9cXD8vICkgPyAnJicgOiAnPyc7XHJcblxyXG4gICAgICAgIHBhcmFtICs9ICdyYW5kb209JyArIChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgdGhpcy5hdHRyKCdzcmMnLCBzcmMgKyBwYXJhbSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWltYWdlLmF0dHIoJ3NyYycpKSB7XHJcbiAgICAgIGxvYWRlZCgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGltYWdlWzBdLmNvbXBsZXRlIHx8IGltYWdlWzBdLnJlYWR5U3RhdGUgPT09IDQpIHtcclxuICAgICAgbG9hZGVkKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBiaW5kTG9hZC5jYWxsKGltYWdlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvKiEgbWF0Y2hNZWRpYSgpIHBvbHlmaWxsIC0gVGVzdCBhIENTUyBtZWRpYSB0eXBlL3F1ZXJ5IGluIEpTLiBBdXRob3JzICYgY29weXJpZ2h0IChjKSAyMDEyOiBTY290dCBKZWhsLCBQYXVsIElyaXNoLCBOaWNob2xhcyBaYWthcywgRGF2aWQgS25pZ2h0LiBEdWFsIE1JVC9CU0QgbGljZW5zZSAqL1xyXG5cclxuICB3aW5kb3cubWF0Y2hNZWRpYSB8fCAod2luZG93Lm1hdGNoTWVkaWEgPSBmdW5jdGlvbigpIHtcclxuICAgICAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gICAgICAvLyBGb3IgYnJvd3NlcnMgdGhhdCBzdXBwb3J0IG1hdGNoTWVkaXVtIGFwaSBzdWNoIGFzIElFIDkgYW5kIHdlYmtpdFxyXG4gICAgICB2YXIgc3R5bGVNZWRpYSA9ICh3aW5kb3cuc3R5bGVNZWRpYSB8fCB3aW5kb3cubWVkaWEpO1xyXG5cclxuICAgICAgLy8gRm9yIHRob3NlIHRoYXQgZG9uJ3Qgc3VwcG9ydCBtYXRjaE1lZGl1bVxyXG4gICAgICBpZiAoIXN0eWxlTWVkaWEpIHtcclxuICAgICAgICAgIHZhciBzdHlsZSAgICAgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyksXHJcbiAgICAgICAgICAgICAgc2NyaXB0ICAgICAgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF0sXHJcbiAgICAgICAgICAgICAgaW5mbyAgICAgICAgPSBudWxsO1xyXG5cclxuICAgICAgICAgIHN0eWxlLnR5cGUgID0gJ3RleHQvY3NzJztcclxuICAgICAgICAgIHN0eWxlLmlkICAgID0gJ21hdGNobWVkaWFqcy10ZXN0JztcclxuXHJcbiAgICAgICAgICBzY3JpcHQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc3R5bGUsIHNjcmlwdCk7XHJcblxyXG4gICAgICAgICAgLy8gJ3N0eWxlLmN1cnJlbnRTdHlsZScgaXMgdXNlZCBieSBJRSA8PSA4IGFuZCAnd2luZG93LmdldENvbXB1dGVkU3R5bGUnIGZvciBhbGwgb3RoZXIgYnJvd3NlcnNcclxuICAgICAgICAgIGluZm8gPSAoJ2dldENvbXB1dGVkU3R5bGUnIGluIHdpbmRvdykgJiYgd2luZG93LmdldENvbXB1dGVkU3R5bGUoc3R5bGUsIG51bGwpIHx8IHN0eWxlLmN1cnJlbnRTdHlsZTtcclxuXHJcbiAgICAgICAgICBzdHlsZU1lZGlhID0ge1xyXG4gICAgICAgICAgICAgIG1hdGNoTWVkaXVtOiBmdW5jdGlvbihtZWRpYSkge1xyXG4gICAgICAgICAgICAgICAgICB2YXIgdGV4dCA9ICdAbWVkaWEgJyArIG1lZGlhICsgJ3sgI21hdGNobWVkaWFqcy10ZXN0IHsgd2lkdGg6IDFweDsgfSB9JztcclxuXHJcbiAgICAgICAgICAgICAgICAgIC8vICdzdHlsZS5zdHlsZVNoZWV0JyBpcyB1c2VkIGJ5IElFIDw9IDggYW5kICdzdHlsZS50ZXh0Q29udGVudCcgZm9yIGFsbCBvdGhlciBicm93c2Vyc1xyXG4gICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuc3R5bGVTaGVldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgc3R5bGUuc3R5bGVTaGVldC5jc3NUZXh0ID0gdGV4dDtcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHN0eWxlLnRleHRDb250ZW50ID0gdGV4dDtcclxuICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgLy8gVGVzdCBpZiBtZWRpYSBxdWVyeSBpcyB0cnVlIG9yIGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiBpbmZvLndpZHRoID09PSAnMXB4JztcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZnVuY3Rpb24obWVkaWEpIHtcclxuICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgbWF0Y2hlczogc3R5bGVNZWRpYS5tYXRjaE1lZGl1bShtZWRpYSB8fCAnYWxsJyksXHJcbiAgICAgICAgICAgICAgbWVkaWE6IG1lZGlhIHx8ICdhbGwnXHJcbiAgICAgICAgICB9O1xyXG4gICAgICB9O1xyXG4gIH0oKSk7XHJcblxyXG4gIC8qXHJcbiAgICoganF1ZXJ5LnJlcXVlc3RBbmltYXRpb25GcmFtZVxyXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9nbmFyZjM3L2pxdWVyeS1yZXF1ZXN0QW5pbWF0aW9uRnJhbWVcclxuICAgKiBSZXF1aXJlcyBqUXVlcnkgMS44K1xyXG4gICAqXHJcbiAgICogQ29weXJpZ2h0IChjKSAyMDEyIENvcmV5IEZyYW5nXHJcbiAgICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxyXG4gICAqL1xyXG5cclxuICAoZnVuY3Rpb24oalF1ZXJ5KSB7XHJcblxyXG5cclxuICAvLyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcG9seWZpbGwgYWRhcHRlZCBmcm9tIEVyaWsgTcO2bGxlclxyXG4gIC8vIGZpeGVzIGZyb20gUGF1bCBJcmlzaCBhbmQgVGlubyBaaWpkZWxcclxuICAvLyBodHRwOi8vcGF1bGlyaXNoLmNvbS8yMDExL3JlcXVlc3RhbmltYXRpb25mcmFtZS1mb3Itc21hcnQtYW5pbWF0aW5nL1xyXG4gIC8vIGh0dHA6Ly9teS5vcGVyYS5jb20vZW1vbGxlci9ibG9nLzIwMTEvMTIvMjAvcmVxdWVzdGFuaW1hdGlvbmZyYW1lLWZvci1zbWFydC1lci1hbmltYXRpbmdcclxuXHJcbiAgdmFyIGFuaW1hdGluZyxcclxuICAgICAgbGFzdFRpbWUgPSAwLFxyXG4gICAgICB2ZW5kb3JzID0gWyd3ZWJraXQnLCAnbW96J10sXHJcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUsXHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lID0gd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lLFxyXG4gICAgICBqcXVlcnlGeEF2YWlsYWJsZSA9ICd1bmRlZmluZWQnICE9PSB0eXBlb2YgalF1ZXJ5LmZ4O1xyXG5cclxuICBmb3IgKDsgbGFzdFRpbWUgPCB2ZW5kb3JzLmxlbmd0aCAmJiAhcmVxdWVzdEFuaW1hdGlvbkZyYW1lOyBsYXN0VGltZSsrKSB7XHJcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSB3aW5kb3dbIHZlbmRvcnNbbGFzdFRpbWVdICsgJ1JlcXVlc3RBbmltYXRpb25GcmFtZScgXTtcclxuICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lID0gY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcclxuICAgICAgd2luZG93WyB2ZW5kb3JzW2xhc3RUaW1lXSArICdDYW5jZWxBbmltYXRpb25GcmFtZScgXSB8fFxyXG4gICAgICB3aW5kb3dbIHZlbmRvcnNbbGFzdFRpbWVdICsgJ0NhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZScgXTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHJhZigpIHtcclxuICAgIGlmIChhbmltYXRpbmcpIHtcclxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJhZik7XHJcblxyXG4gICAgICBpZiAoanF1ZXJ5RnhBdmFpbGFibGUpIHtcclxuICAgICAgICBqUXVlcnkuZngudGljaygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAocmVxdWVzdEFuaW1hdGlvbkZyYW1lKSB7XHJcbiAgICAvLyB1c2UgckFGXHJcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xyXG4gICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lID0gY2FuY2VsQW5pbWF0aW9uRnJhbWU7XHJcblxyXG4gICAgaWYgKGpxdWVyeUZ4QXZhaWxhYmxlKSB7XHJcbiAgICAgIGpRdWVyeS5meC50aW1lciA9IGZ1bmN0aW9uICh0aW1lcikge1xyXG4gICAgICAgIGlmICh0aW1lcigpICYmIGpRdWVyeS50aW1lcnMucHVzaCh0aW1lcikgJiYgIWFuaW1hdGluZykge1xyXG4gICAgICAgICAgYW5pbWF0aW5nID0gdHJ1ZTtcclxuICAgICAgICAgIHJhZigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIGpRdWVyeS5meC5zdG9wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGFuaW1hdGluZyA9IGZhbHNlO1xyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICAvLyBwb2x5ZmlsbFxyXG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgICB2YXIgY3VyclRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSxcclxuICAgICAgICB0aW1lVG9DYWxsID0gTWF0aC5tYXgoMCwgMTYgLSAoY3VyclRpbWUgLSBsYXN0VGltZSkpLFxyXG4gICAgICAgIGlkID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgY2FsbGJhY2soY3VyclRpbWUgKyB0aW1lVG9DYWxsKTtcclxuICAgICAgICB9LCB0aW1lVG9DYWxsKTtcclxuICAgICAgbGFzdFRpbWUgPSBjdXJyVGltZSArIHRpbWVUb0NhbGw7XHJcbiAgICAgIHJldHVybiBpZDtcclxuICAgIH07XHJcblxyXG4gICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24gKGlkKSB7XHJcbiAgICAgIGNsZWFyVGltZW91dChpZCk7XHJcbiAgICB9O1xyXG5cclxuICB9XHJcblxyXG4gIH0oICQgKSk7XHJcblxyXG4gIGZ1bmN0aW9uIHJlbW92ZVF1b3RlcyAoc3RyaW5nKSB7XHJcbiAgICBpZiAodHlwZW9mIHN0cmluZyA9PT0gJ3N0cmluZycgfHwgc3RyaW5nIGluc3RhbmNlb2YgU3RyaW5nKSB7XHJcbiAgICAgIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC9eWydcXFxcL1wiXSt8KDtcXHM/fSkrfFsnXFxcXC9cIl0rJC9nLCAnJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHN0cmluZztcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIE1lZGlhUXVlcnkoc2VsZWN0b3IpIHtcclxuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcclxuICAgIHRoaXMucXVlcnkgPSAnJztcclxuICB9XHJcblxyXG4gIE1lZGlhUXVlcnkucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucXVlcnkgfHwgKHRoaXMucXVlcnkgPSBTKHRoaXMuc2VsZWN0b3IpLmNzcygnZm9udC1mYW1pbHknKS5yZXBsYWNlKC9eW1xcL1xcXFwnXCJdK3woO1xccz99KSt8W1xcL1xcXFwnXCJdKyQvZywgJycpKTtcclxuICB9O1xyXG5cclxuICB3aW5kb3cuRm91bmRhdGlvbiA9IHtcclxuICAgIG5hbWUgOiAnRm91bmRhdGlvbicsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgbWVkaWFfcXVlcmllcyA6IHtcclxuICAgICAgJ3NtYWxsJyAgICAgICA6IG5ldyBNZWRpYVF1ZXJ5KCcuZm91bmRhdGlvbi1tcS1zbWFsbCcpLFxyXG4gICAgICAnc21hbGwtb25seScgIDogbmV3IE1lZGlhUXVlcnkoJy5mb3VuZGF0aW9uLW1xLXNtYWxsLW9ubHknKSxcclxuICAgICAgJ21lZGl1bScgICAgICA6IG5ldyBNZWRpYVF1ZXJ5KCcuZm91bmRhdGlvbi1tcS1tZWRpdW0nKSxcclxuICAgICAgJ21lZGl1bS1vbmx5JyA6IG5ldyBNZWRpYVF1ZXJ5KCcuZm91bmRhdGlvbi1tcS1tZWRpdW0tb25seScpLFxyXG4gICAgICAnbGFyZ2UnICAgICAgIDogbmV3IE1lZGlhUXVlcnkoJy5mb3VuZGF0aW9uLW1xLWxhcmdlJyksXHJcbiAgICAgICdsYXJnZS1vbmx5JyAgOiBuZXcgTWVkaWFRdWVyeSgnLmZvdW5kYXRpb24tbXEtbGFyZ2Utb25seScpLFxyXG4gICAgICAneGxhcmdlJyAgICAgIDogbmV3IE1lZGlhUXVlcnkoJy5mb3VuZGF0aW9uLW1xLXhsYXJnZScpLFxyXG4gICAgICAneGxhcmdlLW9ubHknIDogbmV3IE1lZGlhUXVlcnkoJy5mb3VuZGF0aW9uLW1xLXhsYXJnZS1vbmx5JyksXHJcbiAgICAgICd4eGxhcmdlJyAgICAgOiBuZXcgTWVkaWFRdWVyeSgnLmZvdW5kYXRpb24tbXEteHhsYXJnZScpXHJcbiAgICB9LFxyXG5cclxuICAgIHN0eWxlc2hlZXQgOiAkKCc8c3R5bGU+PC9zdHlsZT4nKS5hcHBlbmRUbygnaGVhZCcpWzBdLnNoZWV0LFxyXG5cclxuICAgIGdsb2JhbCA6IHtcclxuICAgICAgbmFtZXNwYWNlIDogdW5kZWZpbmVkXHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIGxpYnJhcmllcywgbWV0aG9kLCBvcHRpb25zLCByZXNwb25zZSkge1xyXG4gICAgICB2YXIgYXJncyA9IFtzY29wZSwgbWV0aG9kLCBvcHRpb25zLCByZXNwb25zZV0sXHJcbiAgICAgICAgICByZXNwb25zZXMgPSBbXTtcclxuXHJcbiAgICAgIC8vIGNoZWNrIFJUTFxyXG4gICAgICB0aGlzLnJ0bCA9IC9ydGwvaS50ZXN0KFMoJ2h0bWwnKS5hdHRyKCdkaXInKSk7XHJcblxyXG4gICAgICAvLyBzZXQgZm91bmRhdGlvbiBnbG9iYWwgc2NvcGVcclxuICAgICAgdGhpcy5zY29wZSA9IHNjb3BlIHx8IHRoaXMuc2NvcGU7XHJcblxyXG4gICAgICB0aGlzLnNldF9uYW1lc3BhY2UoKTtcclxuXHJcbiAgICAgIGlmIChsaWJyYXJpZXMgJiYgdHlwZW9mIGxpYnJhcmllcyA9PT0gJ3N0cmluZycgJiYgIS9yZWZsb3cvaS50ZXN0KGxpYnJhcmllcykpIHtcclxuICAgICAgICBpZiAodGhpcy5saWJzLmhhc093blByb3BlcnR5KGxpYnJhcmllcykpIHtcclxuICAgICAgICAgIHJlc3BvbnNlcy5wdXNoKHRoaXMuaW5pdF9saWIobGlicmFyaWVzLCBhcmdzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZvciAodmFyIGxpYiBpbiB0aGlzLmxpYnMpIHtcclxuICAgICAgICAgIHJlc3BvbnNlcy5wdXNoKHRoaXMuaW5pdF9saWIobGliLCBsaWJyYXJpZXMpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIFMod2luZG93KS5sb2FkKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBTKHdpbmRvdylcclxuICAgICAgICAgIC50cmlnZ2VyKCdyZXNpemUuZm5kdG4uY2xlYXJpbmcnKVxyXG4gICAgICAgICAgLnRyaWdnZXIoJ3Jlc2l6ZS5mbmR0bi5kcm9wZG93bicpXHJcbiAgICAgICAgICAudHJpZ2dlcigncmVzaXplLmZuZHRuLmVxdWFsaXplcicpXHJcbiAgICAgICAgICAudHJpZ2dlcigncmVzaXplLmZuZHRuLmludGVyY2hhbmdlJylcclxuICAgICAgICAgIC50cmlnZ2VyKCdyZXNpemUuZm5kdG4uam95cmlkZScpXHJcbiAgICAgICAgICAudHJpZ2dlcigncmVzaXplLmZuZHRuLm1hZ2VsbGFuJylcclxuICAgICAgICAgIC50cmlnZ2VyKCdyZXNpemUuZm5kdG4udG9wYmFyJylcclxuICAgICAgICAgIC50cmlnZ2VyKCdyZXNpemUuZm5kdG4uc2xpZGVyJyk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIHNjb3BlO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbml0X2xpYiA6IGZ1bmN0aW9uIChsaWIsIGFyZ3MpIHtcclxuICAgICAgaWYgKHRoaXMubGlicy5oYXNPd25Qcm9wZXJ0eShsaWIpKSB7XHJcbiAgICAgICAgdGhpcy5wYXRjaCh0aGlzLmxpYnNbbGliXSk7XHJcblxyXG4gICAgICAgIGlmIChhcmdzICYmIGFyZ3MuaGFzT3duUHJvcGVydHkobGliKSkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMubGlic1tsaWJdLnNldHRpbmdzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICQuZXh0ZW5kKHRydWUsIHRoaXMubGlic1tsaWJdLnNldHRpbmdzLCBhcmdzW2xpYl0pO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLmxpYnNbbGliXS5kZWZhdWx0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgICAkLmV4dGVuZCh0cnVlLCB0aGlzLmxpYnNbbGliXS5kZWZhdWx0cywgYXJnc1tsaWJdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIHRoaXMubGlic1tsaWJdLmluaXQuYXBwbHkodGhpcy5saWJzW2xpYl0sIFt0aGlzLnNjb3BlLCBhcmdzW2xpYl1dKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFyZ3MgPSBhcmdzIGluc3RhbmNlb2YgQXJyYXkgPyBhcmdzIDogbmV3IEFycmF5KGFyZ3MpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxpYnNbbGliXS5pbml0LmFwcGx5KHRoaXMubGlic1tsaWJdLCBhcmdzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHt9O1xyXG4gICAgfSxcclxuXHJcbiAgICBwYXRjaCA6IGZ1bmN0aW9uIChsaWIpIHtcclxuICAgICAgbGliLnNjb3BlID0gdGhpcy5zY29wZTtcclxuICAgICAgbGliLm5hbWVzcGFjZSA9IHRoaXMuZ2xvYmFsLm5hbWVzcGFjZTtcclxuICAgICAgbGliLnJ0bCA9IHRoaXMucnRsO1xyXG4gICAgICBsaWJbJ2RhdGFfb3B0aW9ucyddID0gdGhpcy51dGlscy5kYXRhX29wdGlvbnM7XHJcbiAgICAgIGxpYlsnYXR0cl9uYW1lJ10gPSBhdHRyX25hbWU7XHJcbiAgICAgIGxpYlsnYWRkX25hbWVzcGFjZSddID0gYWRkX25hbWVzcGFjZTtcclxuICAgICAgbGliWydiaW5kaW5ncyddID0gYmluZGluZ3M7XHJcbiAgICAgIGxpYlsnUyddID0gdGhpcy51dGlscy5TO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbmhlcml0IDogZnVuY3Rpb24gKHNjb3BlLCBtZXRob2RzKSB7XHJcbiAgICAgIHZhciBtZXRob2RzX2FyciA9IG1ldGhvZHMuc3BsaXQoJyAnKSxcclxuICAgICAgICAgIGkgPSBtZXRob2RzX2Fyci5sZW5ndGg7XHJcblxyXG4gICAgICB3aGlsZSAoaS0tKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudXRpbHMuaGFzT3duUHJvcGVydHkobWV0aG9kc19hcnJbaV0pKSB7XHJcbiAgICAgICAgICBzY29wZVttZXRob2RzX2FycltpXV0gPSB0aGlzLnV0aWxzW21ldGhvZHNfYXJyW2ldXTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2V0X25hbWVzcGFjZSA6IGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgIC8vIERlc2NyaXB0aW9uOlxyXG4gICAgICAvLyAgICBEb24ndCBib3RoZXIgcmVhZGluZyB0aGUgbmFtZXNwYWNlIG91dCBvZiB0aGUgbWV0YSB0YWdcclxuICAgICAgLy8gICAgaWYgdGhlIG5hbWVzcGFjZSBoYXMgYmVlbiBzZXQgZ2xvYmFsbHkgaW4gamF2YXNjcmlwdFxyXG4gICAgICAvL1xyXG4gICAgICAvLyBFeGFtcGxlOlxyXG4gICAgICAvLyAgICBGb3VuZGF0aW9uLmdsb2JhbC5uYW1lc3BhY2UgPSAnbXktbmFtZXNwYWNlJztcclxuICAgICAgLy8gb3IgbWFrZSBpdCBhbiBlbXB0eSBzdHJpbmc6XHJcbiAgICAgIC8vICAgIEZvdW5kYXRpb24uZ2xvYmFsLm5hbWVzcGFjZSA9ICcnO1xyXG4gICAgICAvL1xyXG4gICAgICAvL1xyXG5cclxuICAgICAgLy8gSWYgdGhlIG5hbWVzcGFjZSBoYXMgbm90IGJlZW4gc2V0IChpcyB1bmRlZmluZWQpLCB0cnkgdG8gcmVhZCBpdCBvdXQgb2YgdGhlIG1ldGEgZWxlbWVudC5cclxuICAgICAgLy8gT3RoZXJ3aXNlIHVzZSB0aGUgZ2xvYmFsbHkgZGVmaW5lZCBuYW1lc3BhY2UsIGV2ZW4gaWYgaXQncyBlbXB0eSAoJycpXHJcbiAgICAgIHZhciBuYW1lc3BhY2UgPSAoIHRoaXMuZ2xvYmFsLm5hbWVzcGFjZSA9PT0gdW5kZWZpbmVkICkgPyAkKCcuZm91bmRhdGlvbi1kYXRhLWF0dHJpYnV0ZS1uYW1lc3BhY2UnKS5jc3MoJ2ZvbnQtZmFtaWx5JykgOiB0aGlzLmdsb2JhbC5uYW1lc3BhY2U7XHJcblxyXG4gICAgICAvLyBGaW5hbGx5LCBpZiB0aGUgbmFtc2VwYWNlIGlzIGVpdGhlciB1bmRlZmluZWQgb3IgZmFsc2UsIHNldCBpdCB0byBhbiBlbXB0eSBzdHJpbmcuXHJcbiAgICAgIC8vIE90aGVyd2lzZSB1c2UgdGhlIG5hbWVzcGFjZSB2YWx1ZS5cclxuICAgICAgdGhpcy5nbG9iYWwubmFtZXNwYWNlID0gKCBuYW1lc3BhY2UgPT09IHVuZGVmaW5lZCB8fCAvZmFsc2UvaS50ZXN0KG5hbWVzcGFjZSkgKSA/ICcnIDogbmFtZXNwYWNlO1xyXG4gICAgfSxcclxuXHJcbiAgICBsaWJzIDoge30sXHJcblxyXG4gICAgLy8gbWV0aG9kcyB0aGF0IGNhbiBiZSBpbmhlcml0ZWQgaW4gbGlicmFyaWVzXHJcbiAgICB1dGlscyA6IHtcclxuXHJcbiAgICAgIC8vIERlc2NyaXB0aW9uOlxyXG4gICAgICAvLyAgICBGYXN0IFNlbGVjdG9yIHdyYXBwZXIgcmV0dXJucyBqUXVlcnkgb2JqZWN0LiBPbmx5IHVzZSB3aGVyZSBnZXRFbGVtZW50QnlJZFxyXG4gICAgICAvLyAgICBpcyBub3QgYXZhaWxhYmxlLlxyXG4gICAgICAvL1xyXG4gICAgICAvLyBBcmd1bWVudHM6XHJcbiAgICAgIC8vICAgIFNlbGVjdG9yIChTdHJpbmcpOiBDU1Mgc2VsZWN0b3IgZGVzY3JpYmluZyB0aGUgZWxlbWVudChzKSB0byBiZVxyXG4gICAgICAvLyAgICByZXR1cm5lZCBhcyBhIGpRdWVyeSBvYmplY3QuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgIFNjb3BlIChTdHJpbmcpOiBDU1Mgc2VsZWN0b3IgZGVzY3JpYmluZyB0aGUgYXJlYSB0byBiZSBzZWFyY2hlZC4gRGVmYXVsdFxyXG4gICAgICAvLyAgICBpcyBkb2N1bWVudC5cclxuICAgICAgLy9cclxuICAgICAgLy8gUmV0dXJuczpcclxuICAgICAgLy8gICAgRWxlbWVudCAoalF1ZXJ5IE9iamVjdCk6IGpRdWVyeSBvYmplY3QgY29udGFpbmluZyBlbGVtZW50cyBtYXRjaGluZyB0aGVcclxuICAgICAgLy8gICAgc2VsZWN0b3Igd2l0aGluIHRoZSBzY29wZS5cclxuICAgICAgUyA6IFMsXHJcblxyXG4gICAgICAvLyBEZXNjcmlwdGlvbjpcclxuICAgICAgLy8gICAgRXhlY3V0ZXMgYSBmdW5jdGlvbiBhIG1heCBvZiBvbmNlIGV2ZXJ5IG4gbWlsbGlzZWNvbmRzXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIEFyZ3VtZW50czpcclxuICAgICAgLy8gICAgRnVuYyAoRnVuY3Rpb24pOiBGdW5jdGlvbiB0byBiZSB0aHJvdHRsZWQuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgIERlbGF5IChJbnRlZ2VyKTogRnVuY3Rpb24gZXhlY3V0aW9uIHRocmVzaG9sZCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIFJldHVybnM6XHJcbiAgICAgIC8vICAgIExhenlfZnVuY3Rpb24gKEZ1bmN0aW9uKTogRnVuY3Rpb24gd2l0aCB0aHJvdHRsaW5nIGFwcGxpZWQuXHJcbiAgICAgIHRocm90dGxlIDogZnVuY3Rpb24gKGZ1bmMsIGRlbGF5KSB7XHJcbiAgICAgICAgdmFyIHRpbWVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHZhciBjb250ZXh0ID0gdGhpcywgYXJncyA9IGFyZ3VtZW50cztcclxuXHJcbiAgICAgICAgICBpZiAodGltZXIgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XHJcbiAgICAgICAgICAgICAgdGltZXIgPSBudWxsO1xyXG4gICAgICAgICAgICB9LCBkZWxheSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIC8vIERlc2NyaXB0aW9uOlxyXG4gICAgICAvLyAgICBFeGVjdXRlcyBhIGZ1bmN0aW9uIHdoZW4gaXQgc3RvcHMgYmVpbmcgaW52b2tlZCBmb3IgbiBzZWNvbmRzXHJcbiAgICAgIC8vICAgIE1vZGlmaWVkIHZlcnNpb24gb2YgXy5kZWJvdW5jZSgpIGh0dHA6Ly91bmRlcnNjb3JlanMub3JnXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIEFyZ3VtZW50czpcclxuICAgICAgLy8gICAgRnVuYyAoRnVuY3Rpb24pOiBGdW5jdGlvbiB0byBiZSBkZWJvdW5jZWQuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgIERlbGF5IChJbnRlZ2VyKTogRnVuY3Rpb24gZXhlY3V0aW9uIHRocmVzaG9sZCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgIEltbWVkaWF0ZSAoQm9vbCk6IFdoZXRoZXIgdGhlIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgYXQgdGhlIGJlZ2lubmluZ1xyXG4gICAgICAvLyAgICBvZiB0aGUgZGVsYXkgaW5zdGVhZCBvZiB0aGUgZW5kLiBEZWZhdWx0IGlzIGZhbHNlLlxyXG4gICAgICAvL1xyXG4gICAgICAvLyBSZXR1cm5zOlxyXG4gICAgICAvLyAgICBMYXp5X2Z1bmN0aW9uIChGdW5jdGlvbik6IEZ1bmN0aW9uIHdpdGggZGVib3VuY2luZyBhcHBsaWVkLlxyXG4gICAgICBkZWJvdW5jZSA6IGZ1bmN0aW9uIChmdW5jLCBkZWxheSwgaW1tZWRpYXRlKSB7XHJcbiAgICAgICAgdmFyIHRpbWVvdXQsIHJlc3VsdDtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzO1xyXG4gICAgICAgICAgdmFyIGxhdGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aW1lb3V0ID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHtcclxuICAgICAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgICAgdmFyIGNhbGxOb3cgPSBpbW1lZGlhdGUgJiYgIXRpbWVvdXQ7XHJcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XHJcbiAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgZGVsYXkpO1xyXG4gICAgICAgICAgaWYgKGNhbGxOb3cpIHtcclxuICAgICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIC8vIERlc2NyaXB0aW9uOlxyXG4gICAgICAvLyAgICBQYXJzZXMgZGF0YS1vcHRpb25zIGF0dHJpYnV0ZVxyXG4gICAgICAvL1xyXG4gICAgICAvLyBBcmd1bWVudHM6XHJcbiAgICAgIC8vICAgIEVsIChqUXVlcnkgT2JqZWN0KTogRWxlbWVudCB0byBiZSBwYXJzZWQuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIFJldHVybnM6XHJcbiAgICAgIC8vICAgIE9wdGlvbnMgKEphdmFzY3JpcHQgT2JqZWN0KTogQ29udGVudHMgb2YgdGhlIGVsZW1lbnQncyBkYXRhLW9wdGlvbnNcclxuICAgICAgLy8gICAgYXR0cmlidXRlLlxyXG4gICAgICBkYXRhX29wdGlvbnMgOiBmdW5jdGlvbiAoZWwsIGRhdGFfYXR0cl9uYW1lKSB7XHJcbiAgICAgICAgZGF0YV9hdHRyX25hbWUgPSBkYXRhX2F0dHJfbmFtZSB8fCAnb3B0aW9ucyc7XHJcbiAgICAgICAgdmFyIG9wdHMgPSB7fSwgaWksIHAsIG9wdHNfYXJyLFxyXG4gICAgICAgICAgICBkYXRhX29wdGlvbnMgPSBmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgICB2YXIgbmFtZXNwYWNlID0gRm91bmRhdGlvbi5nbG9iYWwubmFtZXNwYWNlO1xyXG5cclxuICAgICAgICAgICAgICBpZiAobmFtZXNwYWNlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBlbC5kYXRhKG5hbWVzcGFjZSArICctJyArIGRhdGFfYXR0cl9uYW1lKTtcclxuICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgIHJldHVybiBlbC5kYXRhKGRhdGFfYXR0cl9uYW1lKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdmFyIGNhY2hlZF9vcHRpb25zID0gZGF0YV9vcHRpb25zKGVsKTtcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBjYWNoZWRfb3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgIHJldHVybiBjYWNoZWRfb3B0aW9ucztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG9wdHNfYXJyID0gKGNhY2hlZF9vcHRpb25zIHx8ICc6Jykuc3BsaXQoJzsnKTtcclxuICAgICAgICBpaSA9IG9wdHNfYXJyLmxlbmd0aDtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gaXNOdW1iZXIgKG8pIHtcclxuICAgICAgICAgIHJldHVybiAhaXNOYU4gKG8gLSAwKSAmJiBvICE9PSBudWxsICYmIG8gIT09ICcnICYmIG8gIT09IGZhbHNlICYmIG8gIT09IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB0cmltIChzdHIpIHtcclxuICAgICAgICAgIGlmICh0eXBlb2Ygc3RyID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXR1cm4gJC50cmltKHN0cik7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgd2hpbGUgKGlpLS0pIHtcclxuICAgICAgICAgIHAgPSBvcHRzX2FycltpaV0uc3BsaXQoJzonKTtcclxuICAgICAgICAgIHAgPSBbcFswXSwgcC5zbGljZSgxKS5qb2luKCc6JyldO1xyXG5cclxuICAgICAgICAgIGlmICgvdHJ1ZS9pLnRlc3QocFsxXSkpIHtcclxuICAgICAgICAgICAgcFsxXSA9IHRydWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoL2ZhbHNlL2kudGVzdChwWzFdKSkge1xyXG4gICAgICAgICAgICBwWzFdID0gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoaXNOdW1iZXIocFsxXSkpIHtcclxuICAgICAgICAgICAgaWYgKHBbMV0uaW5kZXhPZignLicpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgIHBbMV0gPSBwYXJzZUludChwWzFdLCAxMCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcFsxXSA9IHBhcnNlRmxvYXQocFsxXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAocC5sZW5ndGggPT09IDIgJiYgcFswXS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG9wdHNbdHJpbShwWzBdKV0gPSB0cmltKHBbMV0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG9wdHM7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICAvLyBEZXNjcmlwdGlvbjpcclxuICAgICAgLy8gICAgQWRkcyBKUy1yZWNvZ25pemFibGUgbWVkaWEgcXVlcmllc1xyXG4gICAgICAvL1xyXG4gICAgICAvLyBBcmd1bWVudHM6XHJcbiAgICAgIC8vICAgIE1lZGlhIChTdHJpbmcpOiBLZXkgc3RyaW5nIGZvciB0aGUgbWVkaWEgcXVlcnkgdG8gYmUgc3RvcmVkIGFzIGluXHJcbiAgICAgIC8vICAgIEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1xyXG4gICAgICAvL1xyXG4gICAgICAvLyAgICBDbGFzcyAoU3RyaW5nKTogQ2xhc3MgbmFtZSBmb3IgdGhlIGdlbmVyYXRlZCA8bWV0YT4gdGFnXHJcbiAgICAgIHJlZ2lzdGVyX21lZGlhIDogZnVuY3Rpb24gKG1lZGlhLCBtZWRpYV9jbGFzcykge1xyXG4gICAgICAgIGlmIChGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbbWVkaWFdID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICQoJ2hlYWQnKS5hcHBlbmQoJzxtZXRhIGNsYXNzPVwiJyArIG1lZGlhX2NsYXNzICsgJ1wiLz4nKTtcclxuICAgICAgICAgIEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1ttZWRpYV0gPSByZW1vdmVRdW90ZXMoJCgnLicgKyBtZWRpYV9jbGFzcykuY3NzKCdmb250LWZhbWlseScpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICAvLyBEZXNjcmlwdGlvbjpcclxuICAgICAgLy8gICAgQWRkIGN1c3RvbSBDU1Mgd2l0aGluIGEgSlMtZGVmaW5lZCBtZWRpYSBxdWVyeVxyXG4gICAgICAvL1xyXG4gICAgICAvLyBBcmd1bWVudHM6XHJcbiAgICAgIC8vICAgIFJ1bGUgKFN0cmluZyk6IENTUyBydWxlIHRvIGJlIGFwcGVuZGVkIHRvIHRoZSBkb2N1bWVudC5cclxuICAgICAgLy9cclxuICAgICAgLy8gICAgTWVkaWEgKFN0cmluZyk6IE9wdGlvbmFsIG1lZGlhIHF1ZXJ5IHN0cmluZyBmb3IgdGhlIENTUyBydWxlIHRvIGJlXHJcbiAgICAgIC8vICAgIG5lc3RlZCB1bmRlci5cclxuICAgICAgYWRkX2N1c3RvbV9ydWxlIDogZnVuY3Rpb24gKHJ1bGUsIG1lZGlhKSB7XHJcbiAgICAgICAgaWYgKG1lZGlhID09PSB1bmRlZmluZWQgJiYgRm91bmRhdGlvbi5zdHlsZXNoZWV0KSB7XHJcbiAgICAgICAgICBGb3VuZGF0aW9uLnN0eWxlc2hlZXQuaW5zZXJ0UnVsZShydWxlLCBGb3VuZGF0aW9uLnN0eWxlc2hlZXQuY3NzUnVsZXMubGVuZ3RoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdmFyIHF1ZXJ5ID0gRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzW21lZGlhXTtcclxuXHJcbiAgICAgICAgICBpZiAocXVlcnkgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBGb3VuZGF0aW9uLnN0eWxlc2hlZXQuaW5zZXJ0UnVsZSgnQG1lZGlhICcgK1xyXG4gICAgICAgICAgICAgIEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1ttZWRpYV0gKyAneyAnICsgcnVsZSArICcgfScsIEZvdW5kYXRpb24uc3R5bGVzaGVldC5jc3NSdWxlcy5sZW5ndGgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuXHJcbiAgICAgIC8vIERlc2NyaXB0aW9uOlxyXG4gICAgICAvLyAgICBQZXJmb3JtcyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHdoZW4gYW4gaW1hZ2UgaXMgZnVsbHkgbG9hZGVkXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIEFyZ3VtZW50czpcclxuICAgICAgLy8gICAgSW1hZ2UgKGpRdWVyeSBPYmplY3QpOiBJbWFnZShzKSB0byBjaGVjayBpZiBsb2FkZWQuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgIENhbGxiYWNrIChGdW5jdGlvbik6IEZ1bmN0aW9uIHRvIGV4ZWN1dGUgd2hlbiBpbWFnZSBpcyBmdWxseSBsb2FkZWQuXHJcbiAgICAgIGltYWdlX2xvYWRlZCA6IGZ1bmN0aW9uIChpbWFnZXMsIGNhbGxiYWNrKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgICB1bmxvYWRlZCA9IGltYWdlcy5sZW5ndGg7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHBpY3R1cmVzX2hhc19oZWlnaHQoaW1hZ2VzKSB7XHJcbiAgICAgICAgICB2YXIgcGljdHVyZXNfbnVtYmVyID0gaW1hZ2VzLmxlbmd0aDtcclxuXHJcbiAgICAgICAgICBmb3IgKHZhciBpID0gcGljdHVyZXNfbnVtYmVyIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgaWYoaW1hZ2VzLmF0dHIoJ2hlaWdodCcpID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHVubG9hZGVkID09PSAwIHx8IHBpY3R1cmVzX2hhc19oZWlnaHQoaW1hZ2VzKSkge1xyXG4gICAgICAgICAgY2FsbGJhY2soaW1hZ2VzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGltYWdlcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNpbmdsZV9pbWFnZV9sb2FkZWQoc2VsZi5TKHRoaXMpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHVubG9hZGVkIC09IDE7XHJcbiAgICAgICAgICAgIGlmICh1bmxvYWRlZCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgIGNhbGxiYWNrKGltYWdlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgLy8gRGVzY3JpcHRpb246XHJcbiAgICAgIC8vICAgIFJldHVybnMgYSByYW5kb20sIGFscGhhbnVtZXJpYyBzdHJpbmdcclxuICAgICAgLy9cclxuICAgICAgLy8gQXJndW1lbnRzOlxyXG4gICAgICAvLyAgICBMZW5ndGggKEludGVnZXIpOiBMZW5ndGggb2Ygc3RyaW5nIHRvIGJlIGdlbmVyYXRlZC4gRGVmYXVsdHMgdG8gcmFuZG9tXHJcbiAgICAgIC8vICAgIGludGVnZXIuXHJcbiAgICAgIC8vXHJcbiAgICAgIC8vIFJldHVybnM6XHJcbiAgICAgIC8vICAgIFJhbmQgKFN0cmluZyk6IFBzZXVkby1yYW5kb20sIGFscGhhbnVtZXJpYyBzdHJpbmcuXHJcbiAgICAgIHJhbmRvbV9zdHIgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZpZHgpIHtcclxuICAgICAgICAgIHRoaXMuZmlkeCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucHJlZml4ID0gdGhpcy5wcmVmaXggfHwgWyh0aGlzLm5hbWUgfHwgJ0YnKSwgKCtuZXcgRGF0ZSkudG9TdHJpbmcoMzYpXS5qb2luKCctJyk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnByZWZpeCArICh0aGlzLmZpZHgrKykudG9TdHJpbmcoMzYpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgLy8gRGVzY3JpcHRpb246XHJcbiAgICAgIC8vICAgIEhlbHBlciBmb3Igd2luZG93Lm1hdGNoTWVkaWFcclxuICAgICAgLy9cclxuICAgICAgLy8gQXJndW1lbnRzOlxyXG4gICAgICAvLyAgICBtcSAoU3RyaW5nKTogTWVkaWEgcXVlcnlcclxuICAgICAgLy9cclxuICAgICAgLy8gUmV0dXJuczpcclxuICAgICAgLy8gICAgKEJvb2xlYW4pOiBXaGV0aGVyIHRoZSBtZWRpYSBxdWVyeSBwYXNzZXMgb3Igbm90XHJcbiAgICAgIG1hdGNoIDogZnVuY3Rpb24gKG1xKSB7XHJcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKG1xKS5tYXRjaGVzO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgLy8gRGVzY3JpcHRpb246XHJcbiAgICAgIC8vICAgIEhlbHBlcnMgZm9yIGNoZWNraW5nIEZvdW5kYXRpb24gZGVmYXVsdCBtZWRpYSBxdWVyaWVzIHdpdGggSlNcclxuICAgICAgLy9cclxuICAgICAgLy8gUmV0dXJuczpcclxuICAgICAgLy8gICAgKEJvb2xlYW4pOiBXaGV0aGVyIHRoZSBtZWRpYSBxdWVyeSBwYXNzZXMgb3Igbm90XHJcblxyXG4gICAgICBpc19zbWFsbF91cCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaChGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXMuc21hbGwpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgaXNfbWVkaXVtX3VwIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllcy5tZWRpdW0pO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgaXNfbGFyZ2VfdXAgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2goRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLmxhcmdlKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGlzX3hsYXJnZV91cCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaChGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXMueGxhcmdlKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGlzX3h4bGFyZ2VfdXAgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2goRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLnh4bGFyZ2UpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgaXNfc21hbGxfb25seSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuaXNfbWVkaXVtX3VwKCkgJiYgIXRoaXMuaXNfbGFyZ2VfdXAoKSAmJiAhdGhpcy5pc194bGFyZ2VfdXAoKSAmJiAhdGhpcy5pc194eGxhcmdlX3VwKCk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBpc19tZWRpdW1fb25seSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc19tZWRpdW1fdXAoKSAmJiAhdGhpcy5pc19sYXJnZV91cCgpICYmICF0aGlzLmlzX3hsYXJnZV91cCgpICYmICF0aGlzLmlzX3h4bGFyZ2VfdXAoKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGlzX2xhcmdlX29ubHkgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNfbWVkaXVtX3VwKCkgJiYgdGhpcy5pc19sYXJnZV91cCgpICYmICF0aGlzLmlzX3hsYXJnZV91cCgpICYmICF0aGlzLmlzX3h4bGFyZ2VfdXAoKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGlzX3hsYXJnZV9vbmx5IDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlzX21lZGl1bV91cCgpICYmIHRoaXMuaXNfbGFyZ2VfdXAoKSAmJiB0aGlzLmlzX3hsYXJnZV91cCgpICYmICF0aGlzLmlzX3h4bGFyZ2VfdXAoKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGlzX3h4bGFyZ2Vfb25seSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc19tZWRpdW1fdXAoKSAmJiB0aGlzLmlzX2xhcmdlX3VwKCkgJiYgdGhpcy5pc194bGFyZ2VfdXAoKSAmJiB0aGlzLmlzX3h4bGFyZ2VfdXAoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gICQuZm4uZm91bmRhdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgRm91bmRhdGlvbi5pbml0LmFwcGx5KEZvdW5kYXRpb24sIFt0aGlzXS5jb25jYXQoYXJncykpO1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLmFiaWRlID0ge1xyXG4gICAgbmFtZSA6ICdhYmlkZScsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGxpdmVfdmFsaWRhdGUgOiB0cnVlLCAvLyB2YWxpZGF0ZSB0aGUgZm9ybSBhcyB5b3UgZ29cclxuICAgICAgdmFsaWRhdGVfb25fYmx1ciA6IHRydWUsIC8vIHZhbGlkYXRlIHdoZW5ldmVyIHlvdSBmb2N1cy9ibHVyIG9uIGFuIGlucHV0IGZpZWxkXHJcbiAgICAgIC8vIHZhbGlkYXRlX29uOiAndGFiJywgLy8gdGFiICh3aGVuIHVzZXIgdGFicyBiZXR3ZWVuIGZpZWxkcyksIGNoYW5nZSAoaW5wdXQgY2hhbmdlcyksIG1hbnVhbCAoY2FsbCBjdXN0b20gZXZlbnRzKVxyXG5cclxuICAgICAgZm9jdXNfb25faW52YWxpZCA6IHRydWUsIC8vIGF1dG9tYXRpY2FsbHkgYnJpbmcgdGhlIGZvY3VzIHRvIGFuIGludmFsaWQgaW5wdXQgZmllbGRcclxuICAgICAgZXJyb3JfbGFiZWxzIDogdHJ1ZSwgLy8gbGFiZWxzIHdpdGggYSBmb3I9XCJpbnB1dElkXCIgd2lsbCByZWNlaXZlIGFuIGBlcnJvcmAgY2xhc3NcclxuICAgICAgZXJyb3JfY2xhc3MgOiAnZXJyb3InLCAvLyBsYWJlbHMgd2l0aCBhIGZvcj1cImlucHV0SWRcIiB3aWxsIHJlY2VpdmUgYW4gYGVycm9yYCBjbGFzc1xyXG4gICAgICAvLyB0aGUgYW1vdW50IG9mIHRpbWUgQWJpZGUgd2lsbCB0YWtlIGJlZm9yZSBpdCB2YWxpZGF0ZXMgdGhlIGZvcm0gKGluIG1zKS5cclxuICAgICAgLy8gc21hbGxlciB0aW1lIHdpbGwgcmVzdWx0IGluIGZhc3RlciB2YWxpZGF0aW9uXHJcbiAgICAgIHRpbWVvdXQgOiAxMDAwLFxyXG4gICAgICBwYXR0ZXJucyA6IHtcclxuICAgICAgICBhbHBoYSA6IC9eW2EtekEtWl0rJC8sXHJcbiAgICAgICAgYWxwaGFfbnVtZXJpYyA6IC9eW2EtekEtWjAtOV0rJC8sXHJcbiAgICAgICAgaW50ZWdlciA6IC9eWy0rXT9cXGQrJC8sXHJcbiAgICAgICAgbnVtYmVyIDogL15bLStdP1xcZCooPzpbXFwuXFwsXVxcZCspPyQvLFxyXG5cclxuICAgICAgICAvLyBhbWV4LCB2aXNhLCBkaW5lcnNcclxuICAgICAgICBjYXJkIDogL14oPzo0WzAtOV17MTJ9KD86WzAtOV17M30pP3w1WzEtNV1bMC05XXsxNH18Nig/OjAxMXw1WzAtOV1bMC05XSlbMC05XXsxMn18M1s0N11bMC05XXsxM318Myg/OjBbMC01XXxbNjhdWzAtOV0pWzAtOV17MTF9fCg/OjIxMzF8MTgwMHwzNVxcZHszfSlcXGR7MTF9KSQvLFxyXG4gICAgICAgIGN2diA6IC9eKFswLTldKXszLDR9JC8sXHJcblxyXG4gICAgICAgIC8vIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL3N0YXRlcy1vZi10aGUtdHlwZS1hdHRyaWJ1dGUuaHRtbCN2YWxpZC1lLW1haWwtYWRkcmVzc1xyXG4gICAgICAgIGVtYWlsIDogL15bYS16QS1aMC05LiEjJCUmJyorXFwvPT9eX2B7fH1+LV0rQFthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPyg/OlxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykrJC8sXHJcblxyXG4gICAgICAgIC8vIGh0dHA6Ly9ibG9ncy5sc2UuYWMudWsvbHRpLzIwMDgvMDQvMjMvYS1yZWd1bGFyLWV4cHJlc3Npb24tdG8tbWF0Y2gtYW55LXVybC9cclxuICAgICAgICB1cmw6IC9eKGh0dHBzP3xmdHB8ZmlsZXxzc2gpOlxcL1xcLyhbLTs6Jj1cXCtcXCQsXFx3XStAezF9KT8oWy1BLVphLXowLTlcXC5dKykrOj8oXFxkKyk/KChcXC9bLVxcK34lXFwvXFwuXFx3XSspP1xcPz8oWy1cXCs9JjslQFxcLlxcd10rKT8jPyhbXFx3XSspPyk/LyxcclxuICAgICAgICAvLyBhYmMuZGVcclxuICAgICAgICBkb21haW4gOiAvXihbYS16QS1aMC05XShbYS16QS1aMC05XFwtXXswLDYxfVthLXpBLVowLTldKT9cXC4pK1thLXpBLVpdezIsOH0kLyxcclxuXHJcbiAgICAgICAgZGF0ZXRpbWUgOiAvXihbMC0yXVswLTldezN9KVxcLShbMC0xXVswLTldKVxcLShbMC0zXVswLTldKVQoWzAtNV1bMC05XSlcXDooWzAtNV1bMC05XSlcXDooWzAtNV1bMC05XSkoWnwoW1xcLVxcK10oWzAtMV1bMC05XSlcXDowMCkpJC8sXHJcbiAgICAgICAgLy8gWVlZWS1NTS1ERFxyXG4gICAgICAgIGRhdGUgOiAvKD86MTl8MjApWzAtOV17Mn0tKD86KD86MFsxLTldfDFbMC0yXSktKD86MFsxLTldfDFbMC05XXwyWzAtOV0pfCg/Oig/ITAyKSg/OjBbMS05XXwxWzAtMl0pLSg/OjMwKSl8KD86KD86MFsxMzU3OF18MVswMl0pLTMxKSkkLyxcclxuICAgICAgICAvLyBISDpNTTpTU1xyXG4gICAgICAgIHRpbWUgOiAvXigwWzAtOV18MVswLTldfDJbMC0zXSkoOlswLTVdWzAtOV0pezJ9JC8sXHJcbiAgICAgICAgZGF0ZUlTTyA6IC9eXFxkezR9W1xcL1xcLV1cXGR7MSwyfVtcXC9cXC1dXFxkezEsMn0kLyxcclxuICAgICAgICAvLyBNTS9ERC9ZWVlZXHJcbiAgICAgICAgbW9udGhfZGF5X3llYXIgOiAvXigwWzEtOV18MVswMTJdKVstIFxcLy5dKDBbMS05XXxbMTJdWzAtOV18M1swMV0pWy0gXFwvLl1cXGR7NH0kLyxcclxuICAgICAgICAvLyBERC9NTS9ZWVlZXHJcbiAgICAgICAgZGF5X21vbnRoX3llYXIgOiAvXigwWzEtOV18WzEyXVswLTldfDNbMDFdKVstIFxcLy5dKDBbMS05XXwxWzAxMl0pWy0gXFwvLl1cXGR7NH0kLyxcclxuXHJcbiAgICAgICAgLy8gI0ZGRiBvciAjRkZGRkZGXHJcbiAgICAgICAgY29sb3IgOiAvXiM/KFthLWZBLUYwLTldezZ9fFthLWZBLUYwLTldezN9KSQvXHJcbiAgICAgIH0sXHJcbiAgICAgIHZhbGlkYXRvcnMgOiB7XHJcbiAgICAgICAgZXF1YWxUbyA6IGZ1bmN0aW9uIChlbCwgcmVxdWlyZWQsIHBhcmVudCkge1xyXG4gICAgICAgICAgdmFyIGZyb20gID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwuZ2V0QXR0cmlidXRlKHRoaXMuYWRkX25hbWVzcGFjZSgnZGF0YS1lcXVhbHRvJykpKS52YWx1ZSxcclxuICAgICAgICAgICAgICB0byAgICA9IGVsLnZhbHVlLFxyXG4gICAgICAgICAgICAgIHZhbGlkID0gKGZyb20gPT09IHRvKTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gdmFsaWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHRpbWVyIDogbnVsbCxcclxuXHJcbiAgICBpbml0IDogZnVuY3Rpb24gKHNjb3BlLCBtZXRob2QsIG9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5iaW5kaW5ncyhtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBldmVudHMgOiBmdW5jdGlvbiAoc2NvcGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgZm9ybSA9IHNlbGYuUyhzY29wZSkuYXR0cignbm92YWxpZGF0ZScsICdub3ZhbGlkYXRlJyksXHJcbiAgICAgICAgICBzZXR0aW5ncyA9IGZvcm0uZGF0YSh0aGlzLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHt9O1xyXG5cclxuICAgICAgdGhpcy5pbnZhbGlkX2F0dHIgPSB0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtaW52YWxpZCcpO1xyXG5cclxuICAgICAgZnVuY3Rpb24gdmFsaWRhdGUob3JpZ2luYWxTZWxmLCBlKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZXIpO1xyXG4gICAgICAgIHNlbGYudGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYudmFsaWRhdGUoW29yaWdpbmFsU2VsZl0sIGUpO1xyXG4gICAgICAgIH0uYmluZChvcmlnaW5hbFNlbGYpLCBzZXR0aW5ncy50aW1lb3V0KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZm9ybVxyXG4gICAgICAgIC5vZmYoJy5hYmlkZScpXHJcbiAgICAgICAgLm9uKCdzdWJtaXQuZm5kdG4uYWJpZGUnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIGlzX2FqYXggPSAvYWpheC9pLnRlc3Qoc2VsZi5TKHRoaXMpLmF0dHIoc2VsZi5hdHRyX25hbWUoKSkpO1xyXG4gICAgICAgICAgcmV0dXJuIHNlbGYudmFsaWRhdGUoc2VsZi5TKHRoaXMpLmZpbmQoJ2lucHV0LCB0ZXh0YXJlYSwgc2VsZWN0Jykubm90KFwiOmhpZGRlbiwgW2RhdGEtYWJpZGUtaWdub3JlXVwiKS5nZXQoKSwgZSwgaXNfYWpheCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ3ZhbGlkYXRlLmZuZHRuLmFiaWRlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGlmIChzZXR0aW5ncy52YWxpZGF0ZV9vbiA9PT0gJ21hbnVhbCcpIHtcclxuICAgICAgICAgICAgc2VsZi52YWxpZGF0ZShbZS50YXJnZXRdLCBlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbigncmVzZXQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgcmV0dXJuIHNlbGYucmVzZXQoJCh0aGlzKSwgZSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAuZmluZCgnaW5wdXQsIHRleHRhcmVhLCBzZWxlY3QnKS5ub3QoXCI6aGlkZGVuLCBbZGF0YS1hYmlkZS1pZ25vcmVdXCIpXHJcbiAgICAgICAgICAub2ZmKCcuYWJpZGUnKVxyXG4gICAgICAgICAgLm9uKCdibHVyLmZuZHRuLmFiaWRlIGNoYW5nZS5mbmR0bi5hYmlkZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgdmFyIGlkID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2lkJyksXHJcbiAgICAgICAgICAgICAgICAgIGVxVG8gPSBmb3JtLmZpbmQoJ1tkYXRhLWVxdWFsdG89XCInKyBpZCArJ1wiXScpO1xyXG4gICAgICAgICAgICAvLyBvbGQgc2V0dGluZ3MgZmFsbGJhY2tcclxuICAgICAgICAgICAgLy8gd2lsbCBiZSBkZXByZWNhdGVkIHdpdGggRjYgcmVsZWFzZVxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MudmFsaWRhdGVfb25fYmx1ciAmJiBzZXR0aW5ncy52YWxpZGF0ZV9vbl9ibHVyID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgdmFsaWRhdGUodGhpcywgZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gY2hlY2tzIGlmIHRoZXJlIGlzIGFuIGVxdWFsVG8gZXF1aXZhbGVudCByZWxhdGVkIGJ5IGlkXHJcbiAgICAgICAgICAgIGlmKHR5cGVvZiBlcVRvLmdldCgwKSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBlcVRvLnZhbCgpLmxlbmd0aCl7XHJcbiAgICAgICAgICAgICAgdmFsaWRhdGUoZXFUby5nZXQoMCksZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gbmV3IHNldHRpbmdzIGNvbWJpbmluZyB2YWxpZGF0ZSBvcHRpb25zIGludG8gb25lIHNldHRpbmdcclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLnZhbGlkYXRlX29uID09PSAnY2hhbmdlJykge1xyXG4gICAgICAgICAgICAgIHZhbGlkYXRlKHRoaXMsIGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICAgLm9uKCdrZXlkb3duLmZuZHRuLmFiaWRlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgdmFyIGlkID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2lkJyksXHJcbiAgICAgICAgICAgICAgICBlcVRvID0gZm9ybS5maW5kKCdbZGF0YS1lcXVhbHRvPVwiJysgaWQgKydcIl0nKTtcclxuICAgICAgICAgICAgLy8gb2xkIHNldHRpbmdzIGZhbGxiYWNrXHJcbiAgICAgICAgICAgIC8vIHdpbGwgYmUgZGVwcmVjYXRlZCB3aXRoIEY2IHJlbGVhc2VcclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmxpdmVfdmFsaWRhdGUgJiYgc2V0dGluZ3MubGl2ZV92YWxpZGF0ZSA9PT0gdHJ1ZSAmJiBlLndoaWNoICE9IDkpIHtcclxuICAgICAgICAgICAgICB2YWxpZGF0ZSh0aGlzLCBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBjaGVja3MgaWYgdGhlcmUgaXMgYW4gZXF1YWxUbyBlcXVpdmFsZW50IHJlbGF0ZWQgYnkgaWRcclxuICAgICAgICAgICAgaWYodHlwZW9mIGVxVG8uZ2V0KDApICE9PSBcInVuZGVmaW5lZFwiICYmIGVxVG8udmFsKCkubGVuZ3RoKXtcclxuICAgICAgICAgICAgICB2YWxpZGF0ZShlcVRvLmdldCgwKSxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBuZXcgc2V0dGluZ3MgY29tYmluaW5nIHZhbGlkYXRlIG9wdGlvbnMgaW50byBvbmUgc2V0dGluZ1xyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MudmFsaWRhdGVfb24gPT09ICd0YWInICYmIGUud2hpY2ggPT09IDkpIHtcclxuICAgICAgICAgICAgICB2YWxpZGF0ZSh0aGlzLCBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChzZXR0aW5ncy52YWxpZGF0ZV9vbiA9PT0gJ2NoYW5nZScpIHtcclxuICAgICAgICAgICAgICB2YWxpZGF0ZSh0aGlzLCBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgIC5vbignZm9jdXMnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZHxpUGhvbmV8QW5kcm9pZHxCbGFja0JlcnJ5fFdpbmRvd3MgUGhvbmV8d2ViT1MvaSkpIHtcclxuICAgICAgICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZSh7XHJcbiAgICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogJChlLnRhcmdldCkub2Zmc2V0KCkudG9wXHJcbiAgICAgICAgICAgICAgfSwgMTAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlc2V0IDogZnVuY3Rpb24gKGZvcm0sIGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICBmb3JtLnJlbW92ZUF0dHIoc2VsZi5pbnZhbGlkX2F0dHIpO1xyXG5cclxuICAgICAgJCgnWycgKyBzZWxmLmludmFsaWRfYXR0ciArICddJywgZm9ybSkucmVtb3ZlQXR0cihzZWxmLmludmFsaWRfYXR0cik7XHJcbiAgICAgICQoJy4nICsgc2VsZi5zZXR0aW5ncy5lcnJvcl9jbGFzcywgZm9ybSkubm90KCdzbWFsbCcpLnJlbW92ZUNsYXNzKHNlbGYuc2V0dGluZ3MuZXJyb3JfY2xhc3MpO1xyXG4gICAgICAkKCc6aW5wdXQnLCBmb3JtKS5ub3QoJzpidXR0b24sIDpzdWJtaXQsIDpyZXNldCwgOmhpZGRlbiwgW2RhdGEtYWJpZGUtaWdub3JlXScpLnZhbCgnJykucmVtb3ZlQXR0cihzZWxmLmludmFsaWRfYXR0cik7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlIDogZnVuY3Rpb24gKGVscywgZSwgaXNfYWpheCkge1xyXG4gICAgICB2YXIgdmFsaWRhdGlvbnMgPSB0aGlzLnBhcnNlX3BhdHRlcm5zKGVscyksXHJcbiAgICAgICAgICB2YWxpZGF0aW9uX2NvdW50ID0gdmFsaWRhdGlvbnMubGVuZ3RoLFxyXG4gICAgICAgICAgZm9ybSA9IHRoaXMuUyhlbHNbMF0pLmNsb3Nlc3QoJ2Zvcm0nKSxcclxuICAgICAgICAgIHN1Ym1pdF9ldmVudCA9IC9zdWJtaXQvLnRlc3QoZS50eXBlKTtcclxuXHJcbiAgICAgIC8vIEhhcyB0byBjb3VudCB1cCB0byBtYWtlIHN1cmUgdGhlIGZvY3VzIGdldHMgYXBwbGllZCB0byB0aGUgdG9wIGVycm9yXHJcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsaWRhdGlvbl9jb3VudDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKCF2YWxpZGF0aW9uc1tpXSAmJiAoc3VibWl0X2V2ZW50IHx8IGlzX2FqYXgpKSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5mb2N1c19vbl9pbnZhbGlkKSB7XHJcbiAgICAgICAgICAgIGVsc1tpXS5mb2N1cygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZm9ybS50cmlnZ2VyKCdpbnZhbGlkLmZuZHRuLmFiaWRlJyk7XHJcbiAgICAgICAgICB0aGlzLlMoZWxzW2ldKS5jbG9zZXN0KCdmb3JtJykuYXR0cih0aGlzLmludmFsaWRfYXR0ciwgJycpO1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHN1Ym1pdF9ldmVudCB8fCBpc19hamF4KSB7XHJcbiAgICAgICAgZm9ybS50cmlnZ2VyKCd2YWxpZC5mbmR0bi5hYmlkZScpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBmb3JtLnJlbW92ZUF0dHIodGhpcy5pbnZhbGlkX2F0dHIpO1xyXG5cclxuICAgICAgaWYgKGlzX2FqYXgpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBwYXJzZV9wYXR0ZXJucyA6IGZ1bmN0aW9uIChlbHMpIHtcclxuICAgICAgdmFyIGkgPSBlbHMubGVuZ3RoLFxyXG4gICAgICAgICAgZWxfcGF0dGVybnMgPSBbXTtcclxuXHJcbiAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICBlbF9wYXR0ZXJucy5wdXNoKHRoaXMucGF0dGVybihlbHNbaV0pKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tfdmFsaWRhdGlvbl9hbmRfYXBwbHlfc3R5bGVzKGVsX3BhdHRlcm5zKTtcclxuICAgIH0sXHJcblxyXG4gICAgcGF0dGVybiA6IGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICB2YXIgdHlwZSA9IGVsLmdldEF0dHJpYnV0ZSgndHlwZScpLFxyXG4gICAgICAgICAgcmVxdWlyZWQgPSB0eXBlb2YgZWwuZ2V0QXR0cmlidXRlKCdyZXF1aXJlZCcpID09PSAnc3RyaW5nJztcclxuXHJcbiAgICAgIHZhciBwYXR0ZXJuID0gZWwuZ2V0QXR0cmlidXRlKCdwYXR0ZXJuJykgfHwgJyc7XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5wYXR0ZXJucy5oYXNPd25Qcm9wZXJ0eShwYXR0ZXJuKSAmJiBwYXR0ZXJuLmxlbmd0aCA+IDApIHtcclxuICAgICAgICByZXR1cm4gW2VsLCB0aGlzLnNldHRpbmdzLnBhdHRlcm5zW3BhdHRlcm5dLCByZXF1aXJlZF07XHJcbiAgICAgIH0gZWxzZSBpZiAocGF0dGVybi5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIFtlbCwgbmV3IFJlZ0V4cChwYXR0ZXJuKSwgcmVxdWlyZWRdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5wYXR0ZXJucy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xyXG4gICAgICAgIHJldHVybiBbZWwsIHRoaXMuc2V0dGluZ3MucGF0dGVybnNbdHlwZV0sIHJlcXVpcmVkXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcGF0dGVybiA9IC8uKi87XHJcblxyXG4gICAgICByZXR1cm4gW2VsLCBwYXR0ZXJuLCByZXF1aXJlZF07XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIFRPRE86IEJyZWFrIHRoaXMgdXAgaW50byBzbWFsbGVyIG1ldGhvZHMsIGdldHRpbmcgaGFyZCB0byByZWFkLlxyXG4gICAgY2hlY2tfdmFsaWRhdGlvbl9hbmRfYXBwbHlfc3R5bGVzIDogZnVuY3Rpb24gKGVsX3BhdHRlcm5zKSB7XHJcbiAgICAgIHZhciBpID0gZWxfcGF0dGVybnMubGVuZ3RoLFxyXG4gICAgICAgICAgdmFsaWRhdGlvbnMgPSBbXTtcclxuICAgICAgaWYgKGkgPT0gMCkge1xyXG4gICAgICAgIHJldHVybiB2YWxpZGF0aW9ucztcclxuICAgICAgfVxyXG4gICAgICB2YXIgZm9ybSA9IHRoaXMuUyhlbF9wYXR0ZXJuc1swXVswXSkuY2xvc2VzdCgnW2RhdGEtJyArIHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJ10nKSxcclxuICAgICAgICAgIHNldHRpbmdzID0gZm9ybS5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwge307XHJcbiAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICB2YXIgZWwgPSBlbF9wYXR0ZXJuc1tpXVswXSxcclxuICAgICAgICAgICAgcmVxdWlyZWQgPSBlbF9wYXR0ZXJuc1tpXVsyXSxcclxuICAgICAgICAgICAgdmFsdWUgPSBlbC52YWx1ZS50cmltKCksXHJcbiAgICAgICAgICAgIGRpcmVjdF9wYXJlbnQgPSB0aGlzLlMoZWwpLnBhcmVudCgpLFxyXG4gICAgICAgICAgICB2YWxpZGF0b3IgPSBlbC5nZXRBdHRyaWJ1dGUodGhpcy5hZGRfbmFtZXNwYWNlKCdkYXRhLWFiaWRlLXZhbGlkYXRvcicpKSxcclxuICAgICAgICAgICAgaXNfcmFkaW8gPSBlbC50eXBlID09PSAncmFkaW8nLFxyXG4gICAgICAgICAgICBpc19jaGVja2JveCA9IGVsLnR5cGUgPT09ICdjaGVja2JveCcsXHJcbiAgICAgICAgICAgIGxhYmVsID0gdGhpcy5TKCdsYWJlbFtmb3I9XCInICsgZWwuZ2V0QXR0cmlidXRlKCdpZCcpICsgJ1wiXScpLFxyXG4gICAgICAgICAgICB2YWxpZF9sZW5ndGggPSAocmVxdWlyZWQpID8gKGVsLnZhbHVlLmxlbmd0aCA+IDApIDogdHJ1ZSxcclxuICAgICAgICAgICAgZWxfdmFsaWRhdGlvbnMgPSBbXTtcclxuXHJcbiAgICAgICAgdmFyIHBhcmVudCwgdmFsaWQ7XHJcblxyXG4gICAgICAgIC8vIHN1cHBvcnQgb2xkIHdheSB0byBkbyBlcXVhbFRvIHZhbGlkYXRpb25zXHJcbiAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZSh0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtZXF1YWx0bycpKSkgeyB2YWxpZGF0b3IgPSAnZXF1YWxUbycgfVxyXG5cclxuICAgICAgICBpZiAoIWRpcmVjdF9wYXJlbnQuaXMoJ2xhYmVsJykpIHtcclxuICAgICAgICAgIHBhcmVudCA9IGRpcmVjdF9wYXJlbnQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHBhcmVudCA9IGRpcmVjdF9wYXJlbnQucGFyZW50KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaXNfcmFkaW8gJiYgcmVxdWlyZWQpIHtcclxuICAgICAgICAgIGVsX3ZhbGlkYXRpb25zLnB1c2godGhpcy52YWxpZF9yYWRpbyhlbCwgcmVxdWlyZWQpKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGlzX2NoZWNrYm94ICYmIHJlcXVpcmVkKSB7XHJcbiAgICAgICAgICBlbF92YWxpZGF0aW9ucy5wdXNoKHRoaXMudmFsaWRfY2hlY2tib3goZWwsIHJlcXVpcmVkKSk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodmFsaWRhdG9yKSB7XHJcbiAgICAgICAgICAvLyBWYWxpZGF0ZSB1c2luZyBlYWNoIG9mIHRoZSBzcGVjaWZpZWQgKHNwYWNlLWRlbGltaXRlZCkgdmFsaWRhdG9ycy5cclxuICAgICAgICAgIHZhciB2YWxpZGF0b3JzID0gdmFsaWRhdG9yLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgICB2YXIgbGFzdF92YWxpZCA9IHRydWUsIGFsbF92YWxpZCA9IHRydWU7XHJcbiAgICAgICAgICBmb3IgKHZhciBpdiA9IDA7IGl2IDwgdmFsaWRhdG9ycy5sZW5ndGg7IGl2KyspIHtcclxuICAgICAgICAgICAgICB2YWxpZCA9IHRoaXMuc2V0dGluZ3MudmFsaWRhdG9yc1t2YWxpZGF0b3JzW2l2XV0uYXBwbHkodGhpcywgW2VsLCByZXF1aXJlZCwgcGFyZW50XSlcclxuICAgICAgICAgICAgICBlbF92YWxpZGF0aW9ucy5wdXNoKHZhbGlkKTtcclxuICAgICAgICAgICAgICBhbGxfdmFsaWQgPSB2YWxpZCAmJiBsYXN0X3ZhbGlkO1xyXG4gICAgICAgICAgICAgIGxhc3RfdmFsaWQgPSB2YWxpZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChhbGxfdmFsaWQpIHtcclxuICAgICAgICAgICAgICB0aGlzLlMoZWwpLnJlbW92ZUF0dHIodGhpcy5pbnZhbGlkX2F0dHIpO1xyXG4gICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDbGFzcygnZXJyb3InKTtcclxuICAgICAgICAgICAgICBpZiAobGFiZWwubGVuZ3RoID4gMCAmJiB0aGlzLnNldHRpbmdzLmVycm9yX2xhYmVscykge1xyXG4gICAgICAgICAgICAgICAgbGFiZWwucmVtb3ZlQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcykucmVtb3ZlQXR0cigncm9sZScpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAkKGVsKS50cmlnZ2VySGFuZGxlcigndmFsaWQnKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5TKGVsKS5hdHRyKHRoaXMuaW52YWxpZF9hdHRyLCAnJyk7XHJcbiAgICAgICAgICAgICAgcGFyZW50LmFkZENsYXNzKCdlcnJvcicpO1xyXG4gICAgICAgICAgICAgIGlmIChsYWJlbC5sZW5ndGggPiAwICYmIHRoaXMuc2V0dGluZ3MuZXJyb3JfbGFiZWxzKSB7XHJcbiAgICAgICAgICAgICAgICBsYWJlbC5hZGRDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKS5hdHRyKCdyb2xlJywgJ2FsZXJ0Jyk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICQoZWwpLnRyaWdnZXJIYW5kbGVyKCdpbnZhbGlkJyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICBpZiAoZWxfcGF0dGVybnNbaV1bMV0udGVzdCh2YWx1ZSkgJiYgdmFsaWRfbGVuZ3RoIHx8XHJcbiAgICAgICAgICAgICFyZXF1aXJlZCAmJiBlbC52YWx1ZS5sZW5ndGggPCAxIHx8ICQoZWwpLmF0dHIoJ2Rpc2FibGVkJykpIHtcclxuICAgICAgICAgICAgZWxfdmFsaWRhdGlvbnMucHVzaCh0cnVlKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGVsX3ZhbGlkYXRpb25zLnB1c2goZmFsc2UpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGVsX3ZhbGlkYXRpb25zID0gW2VsX3ZhbGlkYXRpb25zLmV2ZXJ5KGZ1bmN0aW9uICh2YWxpZCkge3JldHVybiB2YWxpZDt9KV07XHJcbiAgICAgICAgICBpZiAoZWxfdmFsaWRhdGlvbnNbMF0pIHtcclxuICAgICAgICAgICAgdGhpcy5TKGVsKS5yZW1vdmVBdHRyKHRoaXMuaW52YWxpZF9hdHRyKTtcclxuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdhcmlhLWludmFsaWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5Jyk7XHJcbiAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKTtcclxuICAgICAgICAgICAgaWYgKGxhYmVsLmxlbmd0aCA+IDAgJiYgdGhpcy5zZXR0aW5ncy5lcnJvcl9sYWJlbHMpIHtcclxuICAgICAgICAgICAgICBsYWJlbC5yZW1vdmVDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKS5yZW1vdmVBdHRyKCdyb2xlJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJChlbCkudHJpZ2dlckhhbmRsZXIoJ3ZhbGlkJyk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLlMoZWwpLmF0dHIodGhpcy5pbnZhbGlkX2F0dHIsICcnKTtcclxuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdhcmlhLWludmFsaWQnLCAndHJ1ZScpO1xyXG5cclxuICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdGhlIGVycm9yIGFzc29jaWF0ZWQgd2l0aCB0aGUgaW5wdXRcclxuICAgICAgICAgICAgdmFyIGVycm9yRWxlbSA9IHBhcmVudC5maW5kKCdzbWFsbC4nICsgdGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcywgJ3NwYW4uJyArIHRoaXMuc2V0dGluZ3MuZXJyb3JfY2xhc3MpO1xyXG4gICAgICAgICAgICB2YXIgZXJyb3JJRCA9IGVycm9yRWxlbS5sZW5ndGggPiAwID8gZXJyb3JFbGVtWzBdLmlkIDogJyc7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcklELmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtZGVzY3JpYmVkYnknLCBlcnJvcklEKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gZWwuc2V0QXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JywgJChlbCkuZmluZCgnLmVycm9yJylbMF0uaWQpO1xyXG4gICAgICAgICAgICBwYXJlbnQuYWRkQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcyk7XHJcbiAgICAgICAgICAgIGlmIChsYWJlbC5sZW5ndGggPiAwICYmIHRoaXMuc2V0dGluZ3MuZXJyb3JfbGFiZWxzKSB7XHJcbiAgICAgICAgICAgICAgbGFiZWwuYWRkQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcykuYXR0cigncm9sZScsICdhbGVydCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICQoZWwpLnRyaWdnZXJIYW5kbGVyKCdpbnZhbGlkJyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhbGlkYXRpb25zID0gdmFsaWRhdGlvbnMuY29uY2F0KGVsX3ZhbGlkYXRpb25zKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb25zO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZF9jaGVja2JveCA6IGZ1bmN0aW9uIChlbCwgcmVxdWlyZWQpIHtcclxuICAgICAgdmFyIGVsID0gdGhpcy5TKGVsKSxcclxuICAgICAgICAgIHZhbGlkID0gKGVsLmlzKCc6Y2hlY2tlZCcpIHx8ICFyZXF1aXJlZCB8fCBlbC5nZXQoMCkuZ2V0QXR0cmlidXRlKCdkaXNhYmxlZCcpKTtcclxuXHJcbiAgICAgIGlmICh2YWxpZCkge1xyXG4gICAgICAgIGVsLnJlbW92ZUF0dHIodGhpcy5pbnZhbGlkX2F0dHIpLnBhcmVudCgpLnJlbW92ZUNsYXNzKHRoaXMuc2V0dGluZ3MuZXJyb3JfY2xhc3MpO1xyXG4gICAgICAgICQoZWwpLnRyaWdnZXJIYW5kbGVyKCd2YWxpZCcpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVsLmF0dHIodGhpcy5pbnZhbGlkX2F0dHIsICcnKS5wYXJlbnQoKS5hZGRDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKTtcclxuICAgICAgICAkKGVsKS50cmlnZ2VySGFuZGxlcignaW52YWxpZCcpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWQ7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkX3JhZGlvIDogZnVuY3Rpb24gKGVsLCByZXF1aXJlZCkge1xyXG4gICAgICB2YXIgbmFtZSA9IGVsLmdldEF0dHJpYnV0ZSgnbmFtZScpLFxyXG4gICAgICAgICAgZ3JvdXAgPSB0aGlzLlMoZWwpLmNsb3Nlc3QoJ1tkYXRhLScgKyB0aGlzLmF0dHJfbmFtZSh0cnVlKSArICddJykuZmluZChcIltuYW1lPSdcIiArIG5hbWUgKyBcIiddXCIpLFxyXG4gICAgICAgICAgY291bnQgPSBncm91cC5sZW5ndGgsXHJcbiAgICAgICAgICB2YWxpZCA9IGZhbHNlLFxyXG4gICAgICAgICAgZGlzYWJsZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgIC8vIEhhcyB0byBjb3VudCB1cCB0byBtYWtlIHN1cmUgdGhlIGZvY3VzIGdldHMgYXBwbGllZCB0byB0aGUgdG9wIGVycm9yXHJcbiAgICAgIGZvciAodmFyIGk9MDsgaSA8IGNvdW50OyBpKyspIHtcclxuICAgICAgICBpZiggZ3JvdXBbaV0uZ2V0QXR0cmlidXRlKCdkaXNhYmxlZCcpICl7XHJcbiAgICAgICAgICBkaXNhYmxlZD10cnVlO1xyXG4gICAgICAgICAgdmFsaWQ9dHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKGdyb3VwW2ldLmNoZWNrZWQpe1xyXG4gICAgICAgICAgICB2YWxpZCA9IHRydWU7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiggZGlzYWJsZWQgKXtcclxuICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBIYXMgdG8gY291bnQgdXAgdG8gbWFrZSBzdXJlIHRoZSBmb2N1cyBnZXRzIGFwcGxpZWQgdG8gdGhlIHRvcCBlcnJvclxyXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcclxuICAgICAgICBpZiAodmFsaWQpIHtcclxuICAgICAgICAgIHRoaXMuUyhncm91cFtpXSkucmVtb3ZlQXR0cih0aGlzLmludmFsaWRfYXR0cikucGFyZW50KCkucmVtb3ZlQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcyk7XHJcbiAgICAgICAgICAkKGdyb3VwW2ldKS50cmlnZ2VySGFuZGxlcigndmFsaWQnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5TKGdyb3VwW2ldKS5hdHRyKHRoaXMuaW52YWxpZF9hdHRyLCAnJykucGFyZW50KCkuYWRkQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcyk7XHJcbiAgICAgICAgICAkKGdyb3VwW2ldKS50cmlnZ2VySGFuZGxlcignaW52YWxpZCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZF9lcXVhbCA6IGZ1bmN0aW9uIChlbCwgcmVxdWlyZWQsIHBhcmVudCkge1xyXG4gICAgICB2YXIgZnJvbSAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbC5nZXRBdHRyaWJ1dGUodGhpcy5hZGRfbmFtZXNwYWNlKCdkYXRhLWVxdWFsdG8nKSkpLnZhbHVlLFxyXG4gICAgICAgICAgdG8gICAgPSBlbC52YWx1ZSxcclxuICAgICAgICAgIHZhbGlkID0gKGZyb20gPT09IHRvKTtcclxuXHJcbiAgICAgIGlmICh2YWxpZCkge1xyXG4gICAgICAgIHRoaXMuUyhlbCkucmVtb3ZlQXR0cih0aGlzLmludmFsaWRfYXR0cik7XHJcbiAgICAgICAgcGFyZW50LnJlbW92ZUNsYXNzKHRoaXMuc2V0dGluZ3MuZXJyb3JfY2xhc3MpO1xyXG4gICAgICAgIGlmIChsYWJlbC5sZW5ndGggPiAwICYmIHNldHRpbmdzLmVycm9yX2xhYmVscykge1xyXG4gICAgICAgICAgbGFiZWwucmVtb3ZlQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuUyhlbCkuYXR0cih0aGlzLmludmFsaWRfYXR0ciwgJycpO1xyXG4gICAgICAgIHBhcmVudC5hZGRDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKTtcclxuICAgICAgICBpZiAobGFiZWwubGVuZ3RoID4gMCAmJiBzZXR0aW5ncy5lcnJvcl9sYWJlbHMpIHtcclxuICAgICAgICAgIGxhYmVsLmFkZENsYXNzKHRoaXMuc2V0dGluZ3MuZXJyb3JfY2xhc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZF9vbmVvZiA6IGZ1bmN0aW9uIChlbCwgcmVxdWlyZWQsIHBhcmVudCwgZG9Ob3RWYWxpZGF0ZU90aGVycykge1xyXG4gICAgICB2YXIgZWwgPSB0aGlzLlMoZWwpLFxyXG4gICAgICAgIG90aGVycyA9IHRoaXMuUygnWycgKyB0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtb25lb2YnKSArICddJyksXHJcbiAgICAgICAgdmFsaWQgPSBvdGhlcnMuZmlsdGVyKCc6Y2hlY2tlZCcpLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICBpZiAodmFsaWQpIHtcclxuICAgICAgICBlbC5yZW1vdmVBdHRyKHRoaXMuaW52YWxpZF9hdHRyKS5wYXJlbnQoKS5yZW1vdmVDbGFzcyh0aGlzLnNldHRpbmdzLmVycm9yX2NsYXNzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlbC5hdHRyKHRoaXMuaW52YWxpZF9hdHRyLCAnJykucGFyZW50KCkuYWRkQ2xhc3ModGhpcy5zZXR0aW5ncy5lcnJvcl9jbGFzcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghZG9Ob3RWYWxpZGF0ZU90aGVycykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgb3RoZXJzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgX3RoaXMudmFsaWRfb25lb2YuY2FsbChfdGhpcywgdGhpcywgbnVsbCwgbnVsbCwgdHJ1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB2YWxpZDtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24oc2NvcGUsIG9wdGlvbnMpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgZm9ybSA9IHNlbGYuUygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nKS5hdHRyKCdub3ZhbGlkYXRlJywgJ25vdmFsaWRhdGUnKTtcclxuICAgICAgICAgIHNlbGYuUyhmb3JtKS5lYWNoKGZ1bmN0aW9uIChpZHgsIGVsKSB7XHJcbiAgICAgICAgICAgIHNlbGYuZXZlbnRzKGVsKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH07XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG5cclxuOyhmdW5jdGlvbiAoJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBGb3VuZGF0aW9uLmxpYnMuYWNjb3JkaW9uID0ge1xyXG4gICAgbmFtZSA6ICdhY2NvcmRpb24nLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBjb250ZW50X2NsYXNzIDogJ2NvbnRlbnQnLFxyXG4gICAgICBhY3RpdmVfY2xhc3MgOiAnYWN0aXZlJyxcclxuICAgICAgbXVsdGlfZXhwYW5kIDogZmFsc2UsXHJcbiAgICAgIHRvZ2dsZWFibGUgOiB0cnVlLFxyXG4gICAgICBjYWxsYmFjayA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgIHZhciBTID0gdGhpcy5TO1xyXG4gICAgICBzZWxmLmNyZWF0ZSh0aGlzLlMoaW5zdGFuY2UpKTtcclxuXHJcbiAgICAgIFModGhpcy5zY29wZSlcclxuICAgICAgLm9mZignLmZuZHRuLmFjY29yZGlvbicpXHJcbiAgICAgIC5vbignY2xpY2suZm5kdG4uYWNjb3JkaW9uJywgJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddID4gZGQgPiBhLCBbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSA+IGxpID4gYScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgdmFyIGFjY29yZGlvbiA9IFModGhpcykuY2xvc2VzdCgnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10nKSxcclxuICAgICAgICAgICAgZ3JvdXBTZWxlY3RvciA9IHNlbGYuYXR0cl9uYW1lKCkgKyAnPScgKyBhY2NvcmRpb24uYXR0cihzZWxmLmF0dHJfbmFtZSgpKSxcclxuICAgICAgICAgICAgc2V0dGluZ3MgPSBhY2NvcmRpb24uZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3MsXHJcbiAgICAgICAgICAgIHRhcmdldCA9IFMoJyMnICsgdGhpcy5ocmVmLnNwbGl0KCcjJylbMV0pLFxyXG4gICAgICAgICAgICBhdW50cyA9ICQoJz4gZGQsID4gbGknLCBhY2NvcmRpb24pLFxyXG4gICAgICAgICAgICBzaWJsaW5ncyA9IGF1bnRzLmNoaWxkcmVuKCcuJyArIHNldHRpbmdzLmNvbnRlbnRfY2xhc3MpLFxyXG4gICAgICAgICAgICBhY3RpdmVfY29udGVudCA9IHNpYmxpbmdzLmZpbHRlcignLicgKyBzZXR0aW5ncy5hY3RpdmVfY2xhc3MpO1xyXG5cclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgIGlmIChhY2NvcmRpb24uYXR0cihzZWxmLmF0dHJfbmFtZSgpKSkge1xyXG4gICAgICAgICAgc2libGluZ3MgPSBzaWJsaW5ncy5hZGQoJ1snICsgZ3JvdXBTZWxlY3RvciArICddIGRkID4gJyArICcuJyArIHNldHRpbmdzLmNvbnRlbnRfY2xhc3MgKyAnLCBbJyArIGdyb3VwU2VsZWN0b3IgKyAnXSBsaSA+ICcgKyAnLicgKyBzZXR0aW5ncy5jb250ZW50X2NsYXNzKTtcclxuICAgICAgICAgIGF1bnRzID0gYXVudHMuYWRkKCdbJyArIGdyb3VwU2VsZWN0b3IgKyAnXSBkZCwgWycgKyBncm91cFNlbGVjdG9yICsgJ10gbGknKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzZXR0aW5ncy50b2dnbGVhYmxlICYmIHRhcmdldC5pcyhhY3RpdmVfY29udGVudCkpIHtcclxuICAgICAgICAgIHRhcmdldC5wYXJlbnQoJ2RkLCBsaScpLnRvZ2dsZUNsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgdGFyZ2V0LnRvZ2dsZUNsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcywgZmFsc2UpO1xyXG4gICAgICAgICAgUyh0aGlzKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgZnVuY3Rpb24oaSwgYXR0cil7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGF0dHIgPT09ICd0cnVlJyA/ICdmYWxzZScgOiAndHJ1ZSc7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIHNldHRpbmdzLmNhbGxiYWNrKHRhcmdldCk7XHJcbiAgICAgICAgICB0YXJnZXQudHJpZ2dlckhhbmRsZXIoJ3RvZ2dsZWQnLCBbYWNjb3JkaW9uXSk7XHJcbiAgICAgICAgICBhY2NvcmRpb24udHJpZ2dlckhhbmRsZXIoJ3RvZ2dsZWQnLCBbdGFyZ2V0XSk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXNldHRpbmdzLm11bHRpX2V4cGFuZCkge1xyXG4gICAgICAgICAgc2libGluZ3MucmVtb3ZlQ2xhc3Moc2V0dGluZ3MuYWN0aXZlX2NsYXNzKTtcclxuICAgICAgICAgIGF1bnRzLnJlbW92ZUNsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcyk7XHJcbiAgICAgICAgICBhdW50cy5jaGlsZHJlbignYScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCdmYWxzZScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGFyZ2V0LmFkZENsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcykucGFyZW50KCkuYWRkQ2xhc3Moc2V0dGluZ3MuYWN0aXZlX2NsYXNzKTtcclxuICAgICAgICBzZXR0aW5ncy5jYWxsYmFjayh0YXJnZXQpO1xyXG4gICAgICAgIHRhcmdldC50cmlnZ2VySGFuZGxlcigndG9nZ2xlZCcsIFthY2NvcmRpb25dKTtcclxuICAgICAgICBhY2NvcmRpb24udHJpZ2dlckhhbmRsZXIoJ3RvZ2dsZWQnLCBbdGFyZ2V0XSk7XHJcbiAgICAgICAgUyh0aGlzKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywndHJ1ZScpO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlOiBmdW5jdGlvbigkaW5zdGFuY2UpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgYWNjb3JkaW9uID0gJGluc3RhbmNlLFxyXG4gICAgICAgICAgYXVudHMgPSAkKCc+IC5hY2NvcmRpb24tbmF2aWdhdGlvbicsIGFjY29yZGlvbiksXHJcbiAgICAgICAgICBzZXR0aW5ncyA9IGFjY29yZGlvbi5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwgc2VsZi5zZXR0aW5ncztcclxuXHJcbiAgICAgIGF1bnRzLmNoaWxkcmVuKCdhJykuYXR0cignYXJpYS1leHBhbmRlZCcsJ2ZhbHNlJyk7XHJcbiAgICAgIGF1bnRzLmhhcygnLicgKyBzZXR0aW5ncy5jb250ZW50X2NsYXNzICsgJy4nICsgc2V0dGluZ3MuYWN0aXZlX2NsYXNzKS5hZGRDbGFzcyhzZXR0aW5ncy5hY3RpdmVfY2xhc3MpLmNoaWxkcmVuKCdhJykuYXR0cignYXJpYS1leHBhbmRlZCcsJ3RydWUnKTtcclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5tdWx0aV9leHBhbmQpIHtcclxuICAgICAgICAkaW5zdGFuY2UuYXR0cignYXJpYS1tdWx0aXNlbGVjdGFibGUnLCd0cnVlJyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblx0XHJcbiAgXHR0b2dnbGUgOiBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgXHRcdHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucyA6IHt9O1xyXG4gIFx0XHR2YXIgc2VsZWN0b3IgPSB0eXBlb2Ygb3B0aW9ucy5zZWxlY3RvciAhPT0gJ3VuZGVmaW5lZCcgPyBvcHRpb25zLnNlbGVjdG9yIDogJyc7XHJcbiAgXHRcdHZhciB0b2dnbGVfc3RhdGUgPSB0eXBlb2Ygb3B0aW9ucy50b2dnbGVfc3RhdGUgIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucy50b2dnbGVfc3RhdGUgOiAnJztcclxuICBcdFx0dmFyICRhY2NvcmRpb24gPSB0eXBlb2Ygb3B0aW9ucy4kYWNjb3JkaW9uICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMuJGFjY29yZGlvbiA6IHRoaXMuUyh0aGlzLnNjb3BlKS5jbG9zZXN0KCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScpO1xyXG4gIFxyXG4gIFx0XHR2YXIgJGl0ZW1zID0gJGFjY29yZGlvbi5maW5kKCc+IGRkJyArIHNlbGVjdG9yICsgJywgPiBsaScgKyBzZWxlY3Rvcik7XHJcbiAgXHRcdGlmICggJGl0ZW1zLmxlbmd0aCA8IDEgKSB7XHJcbiAgXHRcdFx0aWYgKCB3aW5kb3cuY29uc29sZSApIHtcclxuICBcdFx0XHRcdGNvbnNvbGUuZXJyb3IoJ1NlbGVjdGlvbiBub3QgZm91bmQuJywgc2VsZWN0b3IpO1xyXG4gIFx0XHRcdH1cclxuICBcdFx0XHRyZXR1cm4gZmFsc2U7XHJcbiAgXHRcdH1cclxuICBcclxuICBcdFx0dmFyIFMgPSB0aGlzLlM7XHJcbiAgXHRcdHZhciBhY3RpdmVfY2xhc3MgPSB0aGlzLnNldHRpbmdzLmFjdGl2ZV9jbGFzcztcclxuICBcdFx0JGl0ZW1zLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgXHRcdFx0dmFyICRpdGVtID0gUyh0aGlzKTtcclxuICBcdFx0XHR2YXIgaXNfYWN0aXZlID0gJGl0ZW0uaGFzQ2xhc3MoYWN0aXZlX2NsYXNzKTtcclxuICBcdFx0XHRpZiAoICggaXNfYWN0aXZlICYmIHRvZ2dsZV9zdGF0ZSA9PT0gJ2Nsb3NlJyApIHx8ICggIWlzX2FjdGl2ZSAmJiB0b2dnbGVfc3RhdGUgPT09ICdvcGVuJyApIHx8IHRvZ2dsZV9zdGF0ZSA9PT0gJycgKSB7XHJcbiAgXHRcdFx0XHQkaXRlbS5maW5kKCc+IGEnKS50cmlnZ2VyKCdjbGljay5mbmR0bi5hY2NvcmRpb24nKTtcclxuICBcdFx0XHR9XHJcbiAgXHRcdH0pO1xyXG4gIFx0fSxcclxuICBcclxuICBcdG9wZW4gOiBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgXHRcdHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucyA6IHt9O1xyXG4gIFx0XHRvcHRpb25zLnRvZ2dsZV9zdGF0ZSA9ICdvcGVuJztcclxuICBcdFx0dGhpcy50b2dnbGUob3B0aW9ucyk7XHJcbiAgXHR9LFxyXG4gIFxyXG4gIFx0Y2xvc2UgOiBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgXHRcdHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucyA6IHt9O1xyXG4gIFx0XHRvcHRpb25zLnRvZ2dsZV9zdGF0ZSA9ICdjbG9zZSc7XHJcbiAgXHRcdHRoaXMudG9nZ2xlKG9wdGlvbnMpO1xyXG4gIFx0fSxcdFxyXG5cclxuICAgIG9mZiA6IGZ1bmN0aW9uICgpIHt9LFxyXG5cclxuICAgIHJlZmxvdyA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgfTtcclxufShqUXVlcnksIHdpbmRvdywgd2luZG93LmRvY3VtZW50KSk7XHJcblxyXG47KGZ1bmN0aW9uICgkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicy5hbGVydCA9IHtcclxuICAgIG5hbWUgOiAnYWxlcnQnLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBjYWxsYmFjayA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgUyA9IHRoaXMuUztcclxuXHJcbiAgICAgICQodGhpcy5zY29wZSkub2ZmKCcuYWxlcnQnKS5vbignY2xpY2suZm5kdG4uYWxlcnQnLCAnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10gLmNsb3NlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICB2YXIgYWxlcnRCb3ggPSBTKHRoaXMpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJyksXHJcbiAgICAgICAgICAgIHNldHRpbmdzID0gYWxlcnRCb3guZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3M7XHJcblxyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBpZiAoTW9kZXJuaXpyLmNzc3RyYW5zaXRpb25zKSB7XHJcbiAgICAgICAgICBhbGVydEJveC5hZGRDbGFzcygnYWxlcnQtY2xvc2UnKTtcclxuICAgICAgICAgIGFsZXJ0Qm94Lm9uKCd0cmFuc2l0aW9uZW5kIHdlYmtpdFRyYW5zaXRpb25FbmQgb1RyYW5zaXRpb25FbmQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBTKHRoaXMpLnRyaWdnZXIoJ2Nsb3NlLmZuZHRuLmFsZXJ0JykucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIHNldHRpbmdzLmNhbGxiYWNrKCk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgYWxlcnRCb3guZmFkZU91dCgzMDAsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgUyh0aGlzKS50cmlnZ2VyKCdjbG9zZS5mbmR0bi5hbGVydCcpLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICBzZXR0aW5ncy5jYWxsYmFjaygpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge31cclxuICB9O1xyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLmNsZWFyaW5nID0ge1xyXG4gICAgbmFtZSA6ICdjbGVhcmluZycsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIHRlbXBsYXRlcyA6IHtcclxuICAgICAgICB2aWV3aW5nIDogJzxhIGhyZWY9XCIjXCIgY2xhc3M9XCJjbGVhcmluZy1jbG9zZVwiPiZ0aW1lczs8L2E+JyArXHJcbiAgICAgICAgICAnPGRpdiBjbGFzcz1cInZpc2libGUtaW1nXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+PGRpdiBjbGFzcz1cImNsZWFyaW5nLXRvdWNoLWxhYmVsXCI+PC9kaXY+PGltZyBzcmM9XCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhBUUFCQUFEL0FDd0FBQUFBQVFBQkFBQUNBRHMlM0RcIiBhbHQ9XCJcIiAvPicgK1xyXG4gICAgICAgICAgJzxwIGNsYXNzPVwiY2xlYXJpbmctY2FwdGlvblwiPjwvcD48YSBocmVmPVwiI1wiIGNsYXNzPVwiY2xlYXJpbmctbWFpbi1wcmV2XCI+PHNwYW4+PC9zcGFuPjwvYT4nICtcclxuICAgICAgICAgICc8YSBocmVmPVwiI1wiIGNsYXNzPVwiY2xlYXJpbmctbWFpbi1uZXh0XCI+PHNwYW4+PC9zcGFuPjwvYT48L2Rpdj4nICtcclxuICAgICAgICAgICc8aW1nIGNsYXNzPVwiY2xlYXJpbmctcHJlbG9hZC1uZXh0XCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgc3JjPVwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoQVFBQkFBRC9BQ3dBQUFBQUFRQUJBQUFDQURzJTNEXCIgYWx0PVwiXCIgLz4nICtcclxuICAgICAgICAgICc8aW1nIGNsYXNzPVwiY2xlYXJpbmctcHJlbG9hZC1wcmV2XCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgc3JjPVwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoQVFBQkFBRC9BQ3dBQUFBQUFRQUJBQUFDQURzJTNEXCIgYWx0PVwiXCIgLz4nXHJcbiAgICAgIH0sXHJcblxyXG4gICAgICAvLyBjb21tYSBkZWxpbWl0ZWQgbGlzdCBvZiBzZWxlY3RvcnMgdGhhdCwgb24gY2xpY2ssIHdpbGwgY2xvc2UgY2xlYXJpbmcsXHJcbiAgICAgIC8vIGFkZCAnZGl2LmNsZWFyaW5nLWJsYWNrb3V0LCBkaXYudmlzaWJsZS1pbWcnIHRvIGNsb3NlIG9uIGJhY2tncm91bmQgY2xpY2tcclxuICAgICAgY2xvc2Vfc2VsZWN0b3JzIDogJy5jbGVhcmluZy1jbG9zZSwgZGl2LmNsZWFyaW5nLWJsYWNrb3V0JyxcclxuXHJcbiAgICAgIC8vIERlZmF1bHQgdG8gdGhlIGVudGlyZSBsaSBlbGVtZW50LlxyXG4gICAgICBvcGVuX3NlbGVjdG9ycyA6ICcnLFxyXG5cclxuICAgICAgLy8gSW1hZ2Ugd2lsbCBiZSBza2lwcGVkIGluIGNhcm91c2VsLlxyXG4gICAgICBza2lwX3NlbGVjdG9yIDogJycsXHJcblxyXG4gICAgICB0b3VjaF9sYWJlbCA6ICcnLFxyXG5cclxuICAgICAgLy8gZXZlbnQgaW5pdGlhbGl6ZXIgYW5kIGxvY2tzXHJcbiAgICAgIGluaXQgOiBmYWxzZSxcclxuICAgICAgbG9ja2VkIDogZmFsc2VcclxuICAgIH0sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgRm91bmRhdGlvbi5pbmhlcml0KHRoaXMsICd0aHJvdHRsZSBpbWFnZV9sb2FkZWQnKTtcclxuXHJcbiAgICAgIHRoaXMuYmluZGluZ3MobWV0aG9kLCBvcHRpb25zKTtcclxuXHJcbiAgICAgIGlmIChzZWxmLlModGhpcy5zY29wZSkuaXMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJykpIHtcclxuICAgICAgICB0aGlzLmFzc2VtYmxlKHNlbGYuUygnbGknLCB0aGlzLnNjb3BlKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc2VsZi5TKCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMuc2NvcGUpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi5hc3NlbWJsZShzZWxmLlMoJ2xpJywgdGhpcykpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uIChzY29wZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBTID0gc2VsZi5TLFxyXG4gICAgICAgICAgJHNjcm9sbF9jb250YWluZXIgPSAkKCcuc2Nyb2xsLWNvbnRhaW5lcicpO1xyXG5cclxuICAgICAgaWYgKCRzY3JvbGxfY29udGFpbmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB0aGlzLnNjb3BlID0gJHNjcm9sbF9jb250YWluZXI7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIFModGhpcy5zY29wZSlcclxuICAgICAgICAub2ZmKCcuY2xlYXJpbmcnKVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4uY2xlYXJpbmcnLCAndWxbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSBsaSAnICsgdGhpcy5zZXR0aW5ncy5vcGVuX3NlbGVjdG9ycyxcclxuICAgICAgICAgIGZ1bmN0aW9uIChlLCBjdXJyZW50LCB0YXJnZXQpIHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSBjdXJyZW50IHx8IFModGhpcyksXHJcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQgfHwgY3VycmVudCxcclxuICAgICAgICAgICAgICAgIG5leHQgPSBjdXJyZW50Lm5leHQoJ2xpJyksXHJcbiAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IGN1cnJlbnQuY2xvc2VzdCgnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10nKS5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JyksXHJcbiAgICAgICAgICAgICAgICBpbWFnZSA9IFMoZS50YXJnZXQpO1xyXG5cclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICAgIHNlbGYuaW5pdCgpO1xyXG4gICAgICAgICAgICAgIHNldHRpbmdzID0gY3VycmVudC5jbG9zZXN0KCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLmRhdGEoc2VsZi5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaWYgY2xlYXJpbmcgaXMgb3BlbiBhbmQgdGhlIGN1cnJlbnQgaW1hZ2UgaXNcclxuICAgICAgICAgICAgLy8gY2xpY2tlZCwgZ28gdG8gdGhlIG5leHQgaW1hZ2UgaW4gc2VxdWVuY2VcclxuICAgICAgICAgICAgaWYgKHRhcmdldC5oYXNDbGFzcygndmlzaWJsZScpICYmXHJcbiAgICAgICAgICAgICAgY3VycmVudFswXSA9PT0gdGFyZ2V0WzBdICYmXHJcbiAgICAgICAgICAgICAgbmV4dC5sZW5ndGggPiAwICYmIHNlbGYuaXNfb3BlbihjdXJyZW50KSkge1xyXG4gICAgICAgICAgICAgIHRhcmdldCA9IG5leHQ7XHJcbiAgICAgICAgICAgICAgaW1hZ2UgPSBTKCdpbWcnLCB0YXJnZXQpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBzZXQgY3VycmVudCBhbmQgdGFyZ2V0IHRvIHRoZSBjbGlja2VkIGxpIGlmIG5vdCBvdGhlcndpc2UgZGVmaW5lZC5cclxuICAgICAgICAgICAgc2VsZi5vcGVuKGltYWdlLCBjdXJyZW50LCB0YXJnZXQpO1xyXG4gICAgICAgICAgICBzZWxmLnVwZGF0ZV9wYWRkbGVzKHRhcmdldCk7XHJcbiAgICAgICAgICB9KVxyXG5cclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLmNsZWFyaW5nJywgJy5jbGVhcmluZy1tYWluLW5leHQnLFxyXG4gICAgICAgICAgZnVuY3Rpb24gKGUpIHsgc2VsZi5uYXYoZSwgJ25leHQnKSB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4uY2xlYXJpbmcnLCAnLmNsZWFyaW5nLW1haW4tcHJldicsXHJcbiAgICAgICAgICBmdW5jdGlvbiAoZSkgeyBzZWxmLm5hdihlLCAncHJldicpIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5jbGVhcmluZycsIHRoaXMuc2V0dGluZ3MuY2xvc2Vfc2VsZWN0b3JzLFxyXG4gICAgICAgICAgZnVuY3Rpb24gKGUpIHsgRm91bmRhdGlvbi5saWJzLmNsZWFyaW5nLmNsb3NlKGUsIHRoaXMpIH0pO1xyXG5cclxuICAgICAgJChkb2N1bWVudCkub24oJ2tleWRvd24uZm5kdG4uY2xlYXJpbmcnLFxyXG4gICAgICAgICAgZnVuY3Rpb24gKGUpIHsgc2VsZi5rZXlkb3duKGUpIH0pO1xyXG5cclxuICAgICAgUyh3aW5kb3cpLm9mZignLmNsZWFyaW5nJykub24oJ3Jlc2l6ZS5mbmR0bi5jbGVhcmluZycsXHJcbiAgICAgICAgZnVuY3Rpb24gKCkgeyBzZWxmLnJlc2l6ZSgpIH0pO1xyXG5cclxuICAgICAgdGhpcy5zd2lwZV9ldmVudHMoc2NvcGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzd2lwZV9ldmVudHMgOiBmdW5jdGlvbiAoc2NvcGUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICBTID0gc2VsZi5TO1xyXG5cclxuICAgICAgUyh0aGlzLnNjb3BlKVxyXG4gICAgICAgIC5vbigndG91Y2hzdGFydC5mbmR0bi5jbGVhcmluZycsICcudmlzaWJsZS1pbWcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgaWYgKCFlLnRvdWNoZXMpIHsgZSA9IGUub3JpZ2luYWxFdmVudDsgfVxyXG4gICAgICAgICAgdmFyIGRhdGEgPSB7XHJcbiAgICAgICAgICAgICAgICBzdGFydF9wYWdlX3ggOiBlLnRvdWNoZXNbMF0ucGFnZVgsXHJcbiAgICAgICAgICAgICAgICBzdGFydF9wYWdlX3kgOiBlLnRvdWNoZXNbMF0ucGFnZVksXHJcbiAgICAgICAgICAgICAgICBzdGFydF90aW1lIDogKG5ldyBEYXRlKCkpLmdldFRpbWUoKSxcclxuICAgICAgICAgICAgICAgIGRlbHRhX3ggOiAwLFxyXG4gICAgICAgICAgICAgICAgaXNfc2Nyb2xsaW5nIDogdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICBTKHRoaXMpLmRhdGEoJ3N3aXBlLXRyYW5zaXRpb24nLCBkYXRhKTtcclxuICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ3RvdWNobW92ZS5mbmR0bi5jbGVhcmluZycsICcudmlzaWJsZS1pbWcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgaWYgKCFlLnRvdWNoZXMpIHtcclxuICAgICAgICAgICAgZSA9IGUub3JpZ2luYWxFdmVudDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIElnbm9yZSBwaW5jaC96b29tIGV2ZW50c1xyXG4gICAgICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggPiAxIHx8IGUuc2NhbGUgJiYgZS5zY2FsZSAhPT0gMSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdmFyIGRhdGEgPSBTKHRoaXMpLmRhdGEoJ3N3aXBlLXRyYW5zaXRpb24nKTtcclxuXHJcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgIGRhdGEgPSB7fTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBkYXRhLmRlbHRhX3ggPSBlLnRvdWNoZXNbMF0ucGFnZVggLSBkYXRhLnN0YXJ0X3BhZ2VfeDtcclxuXHJcbiAgICAgICAgICBpZiAoRm91bmRhdGlvbi5ydGwpIHtcclxuICAgICAgICAgICAgZGF0YS5kZWx0YV94ID0gLWRhdGEuZGVsdGFfeDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEuaXNfc2Nyb2xsaW5nID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICBkYXRhLmlzX3Njcm9sbGluZyA9ICEhKCBkYXRhLmlzX3Njcm9sbGluZyB8fCBNYXRoLmFicyhkYXRhLmRlbHRhX3gpIDwgTWF0aC5hYnMoZS50b3VjaGVzWzBdLnBhZ2VZIC0gZGF0YS5zdGFydF9wYWdlX3kpICk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKCFkYXRhLmlzX3Njcm9sbGluZyAmJiAhZGF0YS5hY3RpdmUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gKGRhdGEuZGVsdGFfeCA8IDApID8gJ25leHQnIDogJ3ByZXYnO1xyXG4gICAgICAgICAgICBkYXRhLmFjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgICAgIHNlbGYubmF2KGUsIGRpcmVjdGlvbik7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ3RvdWNoZW5kLmZuZHRuLmNsZWFyaW5nJywgJy52aXNpYmxlLWltZycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBTKHRoaXMpLmRhdGEoJ3N3aXBlLXRyYW5zaXRpb24nLCB7fSk7XHJcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBhc3NlbWJsZSA6IGZ1bmN0aW9uICgkbGkpIHtcclxuICAgICAgdmFyICRlbCA9ICRsaS5wYXJlbnQoKTtcclxuXHJcbiAgICAgIGlmICgkZWwucGFyZW50KCkuaGFzQ2xhc3MoJ2Nhcm91c2VsJykpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICRlbC5hZnRlcignPGRpdiBpZD1cImZvdW5kYXRpb25DbGVhcmluZ0hvbGRlclwiPjwvZGl2PicpO1xyXG5cclxuICAgICAgdmFyIGdyaWQgPSAkZWwuZGV0YWNoKCksXHJcbiAgICAgICAgICBncmlkX291dGVySFRNTCA9ICcnO1xyXG5cclxuICAgICAgaWYgKGdyaWRbMF0gPT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBncmlkX291dGVySFRNTCA9IGdyaWRbMF0ub3V0ZXJIVE1MO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgaG9sZGVyID0gdGhpcy5TKCcjZm91bmRhdGlvbkNsZWFyaW5nSG9sZGVyJyksXHJcbiAgICAgICAgICBzZXR0aW5ncyA9ICRlbC5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JyksXHJcbiAgICAgICAgICBkYXRhID0ge1xyXG4gICAgICAgICAgICBncmlkIDogJzxkaXYgY2xhc3M9XCJjYXJvdXNlbFwiPicgKyBncmlkX291dGVySFRNTCArICc8L2Rpdj4nLFxyXG4gICAgICAgICAgICB2aWV3aW5nIDogc2V0dGluZ3MudGVtcGxhdGVzLnZpZXdpbmdcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB3cmFwcGVyID0gJzxkaXYgY2xhc3M9XCJjbGVhcmluZy1hc3NlbWJsZWRcIj48ZGl2PicgKyBkYXRhLnZpZXdpbmcgK1xyXG4gICAgICAgICAgICBkYXRhLmdyaWQgKyAnPC9kaXY+PC9kaXY+JyxcclxuICAgICAgICAgIHRvdWNoX2xhYmVsID0gdGhpcy5zZXR0aW5ncy50b3VjaF9sYWJlbDtcclxuXHJcbiAgICAgIGlmIChNb2Rlcm5penIudG91Y2gpIHtcclxuICAgICAgICB3cmFwcGVyID0gJCh3cmFwcGVyKS5maW5kKCcuY2xlYXJpbmctdG91Y2gtbGFiZWwnKS5odG1sKHRvdWNoX2xhYmVsKS5lbmQoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaG9sZGVyLmFmdGVyKHdyYXBwZXIpLnJlbW92ZSgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBvcGVuIDogZnVuY3Rpb24gKCRpbWFnZSwgY3VycmVudCwgdGFyZ2V0KSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgIGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpLFxyXG4gICAgICAgICAgcm9vdCA9IHRhcmdldC5jbG9zZXN0KCcuY2xlYXJpbmctYXNzZW1ibGVkJyksXHJcbiAgICAgICAgICBjb250YWluZXIgPSBzZWxmLlMoJ2RpdicsIHJvb3QpLmZpcnN0KCksXHJcbiAgICAgICAgICB2aXNpYmxlX2ltYWdlID0gc2VsZi5TKCcudmlzaWJsZS1pbWcnLCBjb250YWluZXIpLFxyXG4gICAgICAgICAgaW1hZ2UgPSBzZWxmLlMoJ2ltZycsIHZpc2libGVfaW1hZ2UpLm5vdCgkaW1hZ2UpLFxyXG4gICAgICAgICAgbGFiZWwgPSBzZWxmLlMoJy5jbGVhcmluZy10b3VjaC1sYWJlbCcsIGNvbnRhaW5lciksXHJcbiAgICAgICAgICBlcnJvciA9IGZhbHNlLFxyXG4gICAgICAgICAgbG9hZGVkID0ge307XHJcblxyXG4gICAgICAvLyBFdmVudCB0byBkaXNhYmxlIHNjcm9sbGluZyBvbiB0b3VjaCBkZXZpY2VzIHdoZW4gQ2xlYXJpbmcgaXMgYWN0aXZhdGVkXHJcbiAgICAgICQoJ2JvZHknKS5vbigndG91Y2htb3ZlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaW1hZ2UuZXJyb3IoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGVycm9yID0gdHJ1ZTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBmdW5jdGlvbiBzdGFydExvYWQoKSB7XHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICB0aGlzLmltYWdlX2xvYWRlZChpbWFnZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoaW1hZ2Uub3V0ZXJXaWR0aCgpID09PSAxICYmICFlcnJvcikge1xyXG4gICAgICAgICAgICAgIHN0YXJ0TG9hZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNiLmNhbGwodGhpcywgaW1hZ2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSwgMTAwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZnVuY3Rpb24gY2IgKGltYWdlKSB7XHJcbiAgICAgICAgdmFyICRpbWFnZSA9ICQoaW1hZ2UpO1xyXG4gICAgICAgICRpbWFnZS5jc3MoJ3Zpc2liaWxpdHknLCAndmlzaWJsZScpO1xyXG4gICAgICAgICRpbWFnZS50cmlnZ2VyKCdpbWFnZVZpc2libGUnKTtcclxuICAgICAgICAvLyB0b2dnbGUgdGhlIGdhbGxlcnlcclxuICAgICAgICBib2R5LmNzcygnb3ZlcmZsb3cnLCAnaGlkZGVuJyk7XHJcbiAgICAgICAgcm9vdC5hZGRDbGFzcygnY2xlYXJpbmctYmxhY2tvdXQnKTtcclxuICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoJ2NsZWFyaW5nLWNvbnRhaW5lcicpO1xyXG4gICAgICAgIHZpc2libGVfaW1hZ2Uuc2hvdygpO1xyXG4gICAgICAgIHRoaXMuZml4X2hlaWdodCh0YXJnZXQpXHJcbiAgICAgICAgICAuY2FwdGlvbihzZWxmLlMoJy5jbGVhcmluZy1jYXB0aW9uJywgdmlzaWJsZV9pbWFnZSksIHNlbGYuUygnaW1nJywgdGFyZ2V0KSlcclxuICAgICAgICAgIC5jZW50ZXJfYW5kX2xhYmVsKGltYWdlLCBsYWJlbClcclxuICAgICAgICAgIC5zaGlmdChjdXJyZW50LCB0YXJnZXQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGFyZ2V0LmNsb3Nlc3QoJ2xpJykuc2libGluZ3MoKS5yZW1vdmVDbGFzcygndmlzaWJsZScpO1xyXG4gICAgICAgICAgICB0YXJnZXQuY2xvc2VzdCgnbGknKS5hZGRDbGFzcygndmlzaWJsZScpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgdmlzaWJsZV9pbWFnZS50cmlnZ2VyKCdvcGVuZWQuZm5kdG4uY2xlYXJpbmcnKVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIXRoaXMubG9ja2VkKCkpIHtcclxuICAgICAgICB2aXNpYmxlX2ltYWdlLnRyaWdnZXIoJ29wZW4uZm5kdG4uY2xlYXJpbmcnKTtcclxuICAgICAgICAvLyBzZXQgdGhlIGltYWdlIHRvIHRoZSBzZWxlY3RlZCB0aHVtYm5haWxcclxuICAgICAgICBsb2FkZWQgPSB0aGlzLmxvYWQoJGltYWdlKTtcclxuICAgICAgICBpZiAobG9hZGVkLmludGVyY2hhbmdlKSB7XHJcbiAgICAgICAgICBpbWFnZVxyXG4gICAgICAgICAgICAuYXR0cignZGF0YS1pbnRlcmNoYW5nZScsIGxvYWRlZC5pbnRlcmNoYW5nZSlcclxuICAgICAgICAgICAgLmZvdW5kYXRpb24oJ2ludGVyY2hhbmdlJywgJ3JlZmxvdycpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpbWFnZVxyXG4gICAgICAgICAgICAuYXR0cignc3JjJywgbG9hZGVkLnNyYylcclxuICAgICAgICAgICAgLmF0dHIoJ2RhdGEtaW50ZXJjaGFuZ2UnLCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGltYWdlLmNzcygndmlzaWJpbGl0eScsICdoaWRkZW4nKTtcclxuXHJcbiAgICAgICAgc3RhcnRMb2FkLmNhbGwodGhpcyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY2xvc2UgOiBmdW5jdGlvbiAoZSwgZWwpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgdmFyIHJvb3QgPSAoZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICAgICAgICBpZiAoL2JsYWNrb3V0Ly50ZXN0KHRhcmdldC5zZWxlY3RvcikpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiB0YXJnZXQuY2xvc2VzdCgnLmNsZWFyaW5nLWJsYWNrb3V0Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0oJChlbCkpKSxcclxuICAgICAgICAgIGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpLCBjb250YWluZXIsIHZpc2libGVfaW1hZ2U7XHJcblxyXG4gICAgICBpZiAoZWwgPT09IGUudGFyZ2V0ICYmIHJvb3QpIHtcclxuICAgICAgICBib2R5LmNzcygnb3ZlcmZsb3cnLCAnJyk7XHJcbiAgICAgICAgY29udGFpbmVyID0gJCgnZGl2Jywgcm9vdCkuZmlyc3QoKTtcclxuICAgICAgICB2aXNpYmxlX2ltYWdlID0gJCgnLnZpc2libGUtaW1nJywgY29udGFpbmVyKTtcclxuICAgICAgICB2aXNpYmxlX2ltYWdlLnRyaWdnZXIoJ2Nsb3NlLmZuZHRuLmNsZWFyaW5nJyk7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5wcmV2X2luZGV4ID0gMDtcclxuICAgICAgICAkKCd1bFsnICsgdGhpcy5hdHRyX25hbWUoKSArICddJywgcm9vdClcclxuICAgICAgICAgIC5hdHRyKCdzdHlsZScsICcnKS5jbG9zZXN0KCcuY2xlYXJpbmctYmxhY2tvdXQnKVxyXG4gICAgICAgICAgLnJlbW92ZUNsYXNzKCdjbGVhcmluZy1ibGFja291dCcpO1xyXG4gICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcygnY2xlYXJpbmctY29udGFpbmVyJyk7XHJcbiAgICAgICAgdmlzaWJsZV9pbWFnZS5oaWRlKCk7XHJcbiAgICAgICAgdmlzaWJsZV9pbWFnZS50cmlnZ2VyKCdjbG9zZWQuZm5kdG4uY2xlYXJpbmcnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRXZlbnQgdG8gcmUtZW5hYmxlIHNjcm9sbGluZyBvbiB0b3VjaCBkZXZpY2VzXHJcbiAgICAgICQoJ2JvZHknKS5vZmYoJ3RvdWNobW92ZScpO1xyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICBpc19vcGVuIDogZnVuY3Rpb24gKGN1cnJlbnQpIHtcclxuICAgICAgcmV0dXJuIGN1cnJlbnQucGFyZW50KCkucHJvcCgnc3R5bGUnKS5sZW5ndGggPiAwO1xyXG4gICAgfSxcclxuXHJcbiAgICBrZXlkb3duIDogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyIGNsZWFyaW5nID0gJCgnLmNsZWFyaW5nLWJsYWNrb3V0IHVsWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nKSxcclxuICAgICAgICAgIE5FWFRfS0VZID0gdGhpcy5ydGwgPyAzNyA6IDM5LFxyXG4gICAgICAgICAgUFJFVl9LRVkgPSB0aGlzLnJ0bCA/IDM5IDogMzcsXHJcbiAgICAgICAgICBFU0NfS0VZID0gMjc7XHJcblxyXG4gICAgICBpZiAoZS53aGljaCA9PT0gTkVYVF9LRVkpIHtcclxuICAgICAgICB0aGlzLmdvKGNsZWFyaW5nLCAnbmV4dCcpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChlLndoaWNoID09PSBQUkVWX0tFWSkge1xyXG4gICAgICAgIHRoaXMuZ28oY2xlYXJpbmcsICdwcmV2Jyk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGUud2hpY2ggPT09IEVTQ19LRVkpIHtcclxuICAgICAgICB0aGlzLlMoJ2EuY2xlYXJpbmctY2xvc2UnKS50cmlnZ2VyKCdjbGljay5mbmR0bi5jbGVhcmluZycpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIG5hdiA6IGZ1bmN0aW9uIChlLCBkaXJlY3Rpb24pIHtcclxuICAgICAgdmFyIGNsZWFyaW5nID0gJCgndWxbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScsICcuY2xlYXJpbmctYmxhY2tvdXQnKTtcclxuXHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdGhpcy5nbyhjbGVhcmluZywgZGlyZWN0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVzaXplIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgaW1hZ2UgPSAkKCdpbWcnLCAnLmNsZWFyaW5nLWJsYWNrb3V0IC52aXNpYmxlLWltZycpLFxyXG4gICAgICAgICAgbGFiZWwgPSAkKCcuY2xlYXJpbmctdG91Y2gtbGFiZWwnLCAnLmNsZWFyaW5nLWJsYWNrb3V0Jyk7XHJcblxyXG4gICAgICBpZiAoaW1hZ2UubGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5jZW50ZXJfYW5kX2xhYmVsKGltYWdlLCBsYWJlbCk7XHJcbiAgICAgICAgaW1hZ2UudHJpZ2dlcigncmVzaXplZC5mbmR0bi5jbGVhcmluZycpXHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgLy8gdmlzdWFsIGFkanVzdG1lbnRzXHJcbiAgICBmaXhfaGVpZ2h0IDogZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICB2YXIgbGlzID0gdGFyZ2V0LnBhcmVudCgpLmNoaWxkcmVuKCksXHJcbiAgICAgICAgICBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgIGxpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgbGkgPSBzZWxmLlModGhpcyksXHJcbiAgICAgICAgICAgIGltYWdlID0gbGkuZmluZCgnaW1nJyk7XHJcblxyXG4gICAgICAgIGlmIChsaS5oZWlnaHQoKSA+IGltYWdlLm91dGVySGVpZ2h0KCkpIHtcclxuICAgICAgICAgIGxpLmFkZENsYXNzKCdmaXgtaGVpZ2h0Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2xvc2VzdCgndWwnKVxyXG4gICAgICAud2lkdGgobGlzLmxlbmd0aCAqIDEwMCArICclJyk7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH0sXHJcblxyXG4gICAgdXBkYXRlX3BhZGRsZXMgOiBmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAgIHRhcmdldCA9IHRhcmdldC5jbG9zZXN0KCdsaScpO1xyXG4gICAgICB2YXIgdmlzaWJsZV9pbWFnZSA9IHRhcmdldFxyXG4gICAgICAgIC5jbG9zZXN0KCcuY2Fyb3VzZWwnKVxyXG4gICAgICAgIC5zaWJsaW5ncygnLnZpc2libGUtaW1nJyk7XHJcblxyXG4gICAgICBpZiAodGFyZ2V0Lm5leHQoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgdGhpcy5TKCcuY2xlYXJpbmctbWFpbi1uZXh0JywgdmlzaWJsZV9pbWFnZSkucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5TKCcuY2xlYXJpbmctbWFpbi1uZXh0JywgdmlzaWJsZV9pbWFnZSkuYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0YXJnZXQucHJldigpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB0aGlzLlMoJy5jbGVhcmluZy1tYWluLXByZXYnLCB2aXNpYmxlX2ltYWdlKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLlMoJy5jbGVhcmluZy1tYWluLXByZXYnLCB2aXNpYmxlX2ltYWdlKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBjZW50ZXJfYW5kX2xhYmVsIDogZnVuY3Rpb24gKHRhcmdldCwgbGFiZWwpIHtcclxuICAgICAgaWYgKCF0aGlzLnJ0bCAmJiBsYWJlbC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgbGFiZWwuY3NzKHtcclxuICAgICAgICAgIG1hcmdpbkxlZnQgOiAtKGxhYmVsLm91dGVyV2lkdGgoKSAvIDIpLFxyXG4gICAgICAgICAgbWFyZ2luVG9wIDogLSh0YXJnZXQub3V0ZXJIZWlnaHQoKSAvIDIpLWxhYmVsLm91dGVySGVpZ2h0KCktMTBcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsYWJlbC5jc3Moe1xyXG4gICAgICAgICAgbWFyZ2luUmlnaHQgOiAtKGxhYmVsLm91dGVyV2lkdGgoKSAvIDIpLFxyXG4gICAgICAgICAgbWFyZ2luVG9wIDogLSh0YXJnZXQub3V0ZXJIZWlnaHQoKSAvIDIpLWxhYmVsLm91dGVySGVpZ2h0KCktMTAsXHJcbiAgICAgICAgICBsZWZ0OiAnYXV0bycsXHJcbiAgICAgICAgICByaWdodDogJzUwJSdcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH0sXHJcblxyXG4gICAgLy8gaW1hZ2UgbG9hZGluZyBhbmQgcHJlbG9hZGluZ1xyXG5cclxuICAgIGxvYWQgOiBmdW5jdGlvbiAoJGltYWdlKSB7XHJcbiAgICAgIHZhciBocmVmLFxyXG4gICAgICAgICAgaW50ZXJjaGFuZ2UsXHJcbiAgICAgICAgICBjbG9zZXN0X2E7XHJcblxyXG4gICAgICBpZiAoJGltYWdlWzBdLm5vZGVOYW1lID09PSAnQScpIHtcclxuICAgICAgICBocmVmID0gJGltYWdlLmF0dHIoJ2hyZWYnKTtcclxuICAgICAgICBpbnRlcmNoYW5nZSA9ICRpbWFnZS5kYXRhKCdjbGVhcmluZy1pbnRlcmNoYW5nZScpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNsb3Nlc3RfYSA9ICRpbWFnZS5jbG9zZXN0KCdhJyk7XHJcbiAgICAgICAgaHJlZiA9IGNsb3Nlc3RfYS5hdHRyKCdocmVmJyk7XHJcbiAgICAgICAgaW50ZXJjaGFuZ2UgPSBjbG9zZXN0X2EuZGF0YSgnY2xlYXJpbmctaW50ZXJjaGFuZ2UnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5wcmVsb2FkKCRpbWFnZSk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgICdzcmMnOiBocmVmID8gaHJlZiA6ICRpbWFnZS5hdHRyKCdzcmMnKSxcclxuICAgICAgICAnaW50ZXJjaGFuZ2UnOiBocmVmID8gaW50ZXJjaGFuZ2UgOiAkaW1hZ2UuZGF0YSgnY2xlYXJpbmctaW50ZXJjaGFuZ2UnKVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHByZWxvYWQgOiBmdW5jdGlvbiAoJGltYWdlKSB7XHJcbiAgICAgIHRoaXNcclxuICAgICAgICAuaW1nKCRpbWFnZS5jbG9zZXN0KCdsaScpLm5leHQoKSwgJ25leHQnKVxyXG4gICAgICAgIC5pbWcoJGltYWdlLmNsb3Nlc3QoJ2xpJykucHJldigpLCAncHJldicpO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbWcgOiBmdW5jdGlvbiAoaW1nLCBzaWJsaW5nX3R5cGUpIHtcclxuICAgICAgaWYgKGltZy5sZW5ndGgpIHtcclxuICAgICAgICB2YXIgcHJlbG9hZF9pbWcgPSAkKCcuY2xlYXJpbmctcHJlbG9hZC0nICsgc2libGluZ190eXBlKSxcclxuICAgICAgICAgICAgbmV3X2EgPSB0aGlzLlMoJ2EnLCBpbWcpLFxyXG4gICAgICAgICAgICBzcmMsXHJcbiAgICAgICAgICAgIGludGVyY2hhbmdlLFxyXG4gICAgICAgICAgICBpbWFnZTtcclxuXHJcbiAgICAgICAgaWYgKG5ld19hLmxlbmd0aCkge1xyXG4gICAgICAgICAgc3JjID0gbmV3X2EuYXR0cignaHJlZicpO1xyXG4gICAgICAgICAgaW50ZXJjaGFuZ2UgPSBuZXdfYS5kYXRhKCdjbGVhcmluZy1pbnRlcmNoYW5nZScpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpbWFnZSA9IHRoaXMuUygnaW1nJywgaW1nKTtcclxuICAgICAgICAgIHNyYyA9IGltYWdlLmF0dHIoJ3NyYycpO1xyXG4gICAgICAgICAgaW50ZXJjaGFuZ2UgPSBpbWFnZS5kYXRhKCdjbGVhcmluZy1pbnRlcmNoYW5nZScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGludGVyY2hhbmdlKSB7XHJcbiAgICAgICAgICBwcmVsb2FkX2ltZy5hdHRyKCdkYXRhLWludGVyY2hhbmdlJywgaW50ZXJjaGFuZ2UpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBwcmVsb2FkX2ltZy5hdHRyKCdzcmMnLCBzcmMpO1xyXG4gICAgICAgICAgcHJlbG9hZF9pbWcuYXR0cignZGF0YS1pbnRlcmNoYW5nZScsICcnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9LFxyXG5cclxuICAgIC8vIGltYWdlIGNhcHRpb25cclxuXHJcbiAgICBjYXB0aW9uIDogZnVuY3Rpb24gKGNvbnRhaW5lciwgJGltYWdlKSB7XHJcbiAgICAgIHZhciBjYXB0aW9uID0gJGltYWdlLmF0dHIoJ2RhdGEtY2FwdGlvbicpO1xyXG5cclxuICAgICAgaWYgKGNhcHRpb24pIHtcclxuICAgICAgXHR2YXIgY29udGFpbmVyUGxhaW4gPSBjb250YWluZXIuZ2V0KDApO1xyXG4gICAgICBcdGNvbnRhaW5lclBsYWluLmlubmVySFRNTCA9IGNhcHRpb247XHJcbiAgICAgICAgY29udGFpbmVyLnNob3coKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb250YWluZXJcclxuICAgICAgICAgIC50ZXh0KCcnKVxyXG4gICAgICAgICAgLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH0sXHJcblxyXG4gICAgLy8gZGlyZWN0aW9uYWwgbWV0aG9kc1xyXG5cclxuICAgIGdvIDogZnVuY3Rpb24gKCR1bCwgZGlyZWN0aW9uKSB7XHJcbiAgICAgIHZhciBjdXJyZW50ID0gdGhpcy5TKCcudmlzaWJsZScsICR1bCksXHJcbiAgICAgICAgICB0YXJnZXQgPSBjdXJyZW50W2RpcmVjdGlvbl0oKTtcclxuXHJcbiAgICAgIC8vIENoZWNrIGZvciBza2lwIHNlbGVjdG9yLlxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5za2lwX3NlbGVjdG9yICYmIHRhcmdldC5maW5kKHRoaXMuc2V0dGluZ3Muc2tpcF9zZWxlY3RvcikubGVuZ3RoICE9IDApIHtcclxuICAgICAgICB0YXJnZXQgPSB0YXJnZXRbZGlyZWN0aW9uXSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGFyZ2V0Lmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuUygnaW1nJywgdGFyZ2V0KVxyXG4gICAgICAgICAgLnRyaWdnZXIoJ2NsaWNrLmZuZHRuLmNsZWFyaW5nJywgW2N1cnJlbnQsIHRhcmdldF0pXHJcbiAgICAgICAgICAudHJpZ2dlcignY2hhbmdlLmZuZHRuLmNsZWFyaW5nJyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2hpZnQgOiBmdW5jdGlvbiAoY3VycmVudCwgdGFyZ2V0LCBjYWxsYmFjaykge1xyXG4gICAgICB2YXIgY2xlYXJpbmcgPSB0YXJnZXQucGFyZW50KCksXHJcbiAgICAgICAgICBvbGRfaW5kZXggPSB0aGlzLnNldHRpbmdzLnByZXZfaW5kZXggfHwgdGFyZ2V0LmluZGV4KCksXHJcbiAgICAgICAgICBkaXJlY3Rpb24gPSB0aGlzLmRpcmVjdGlvbihjbGVhcmluZywgY3VycmVudCwgdGFyZ2V0KSxcclxuICAgICAgICAgIGRpciA9IHRoaXMucnRsID8gJ3JpZ2h0JyA6ICdsZWZ0JyxcclxuICAgICAgICAgIGxlZnQgPSBwYXJzZUludChjbGVhcmluZy5jc3MoJ2xlZnQnKSwgMTApLFxyXG4gICAgICAgICAgd2lkdGggPSB0YXJnZXQub3V0ZXJXaWR0aCgpLFxyXG4gICAgICAgICAgc2tpcF9zaGlmdDtcclxuXHJcbiAgICAgIHZhciBkaXJfb2JqID0ge307XHJcblxyXG4gICAgICAvLyB3ZSB1c2UgalF1ZXJ5IGFuaW1hdGUgaW5zdGVhZCBvZiBDU1MgdHJhbnNpdGlvbnMgYmVjYXVzZSB3ZVxyXG4gICAgICAvLyBuZWVkIGEgY2FsbGJhY2sgdG8gdW5sb2NrIHRoZSBuZXh0IGFuaW1hdGlvblxyXG4gICAgICAvLyBuZWVkcyBzdXBwb3J0IGZvciBSVEwgKipcclxuICAgICAgaWYgKHRhcmdldC5pbmRleCgpICE9PSBvbGRfaW5kZXggJiYgIS9za2lwLy50ZXN0KGRpcmVjdGlvbikpIHtcclxuICAgICAgICBpZiAoL2xlZnQvLnRlc3QoZGlyZWN0aW9uKSkge1xyXG4gICAgICAgICAgdGhpcy5sb2NrKCk7XHJcbiAgICAgICAgICBkaXJfb2JqW2Rpcl0gPSBsZWZ0ICsgd2lkdGg7XHJcbiAgICAgICAgICBjbGVhcmluZy5hbmltYXRlKGRpcl9vYmosIDMwMCwgdGhpcy51bmxvY2soKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICgvcmlnaHQvLnRlc3QoZGlyZWN0aW9uKSkge1xyXG4gICAgICAgICAgdGhpcy5sb2NrKCk7XHJcbiAgICAgICAgICBkaXJfb2JqW2Rpcl0gPSBsZWZ0IC0gd2lkdGg7XHJcbiAgICAgICAgICBjbGVhcmluZy5hbmltYXRlKGRpcl9vYmosIDMwMCwgdGhpcy51bmxvY2soKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKC9za2lwLy50ZXN0KGRpcmVjdGlvbikpIHtcclxuICAgICAgICAvLyB0aGUgdGFyZ2V0IGltYWdlIGlzIG5vdCBhZGphY2VudCB0byB0aGUgY3VycmVudCBpbWFnZSwgc29cclxuICAgICAgICAvLyBkbyB3ZSBzY3JvbGwgcmlnaHQgb3Igbm90XHJcbiAgICAgICAgc2tpcF9zaGlmdCA9IHRhcmdldC5pbmRleCgpIC0gdGhpcy5zZXR0aW5ncy51cF9jb3VudDtcclxuICAgICAgICB0aGlzLmxvY2soKTtcclxuXHJcbiAgICAgICAgaWYgKHNraXBfc2hpZnQgPiAwKSB7XHJcbiAgICAgICAgICBkaXJfb2JqW2Rpcl0gPSAtKHNraXBfc2hpZnQgKiB3aWR0aCk7XHJcbiAgICAgICAgICBjbGVhcmluZy5hbmltYXRlKGRpcl9vYmosIDMwMCwgdGhpcy51bmxvY2soKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGRpcl9vYmpbZGlyXSA9IDA7XHJcbiAgICAgICAgICBjbGVhcmluZy5hbmltYXRlKGRpcl9vYmosIDMwMCwgdGhpcy51bmxvY2soKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBjYWxsYmFjaygpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkaXJlY3Rpb24gOiBmdW5jdGlvbiAoJGVsLCBjdXJyZW50LCB0YXJnZXQpIHtcclxuICAgICAgdmFyIGxpcyA9IHRoaXMuUygnbGknLCAkZWwpLFxyXG4gICAgICAgICAgbGlfd2lkdGggPSBsaXMub3V0ZXJXaWR0aCgpICsgKGxpcy5vdXRlcldpZHRoKCkgLyA0KSxcclxuICAgICAgICAgIHVwX2NvdW50ID0gTWF0aC5mbG9vcih0aGlzLlMoJy5jbGVhcmluZy1jb250YWluZXInKS5vdXRlcldpZHRoKCkgLyBsaV93aWR0aCkgLSAxLFxyXG4gICAgICAgICAgdGFyZ2V0X2luZGV4ID0gbGlzLmluZGV4KHRhcmdldCksXHJcbiAgICAgICAgICByZXNwb25zZTtcclxuXHJcbiAgICAgIHRoaXMuc2V0dGluZ3MudXBfY291bnQgPSB1cF9jb3VudDtcclxuXHJcbiAgICAgIGlmICh0aGlzLmFkamFjZW50KHRoaXMuc2V0dGluZ3MucHJldl9pbmRleCwgdGFyZ2V0X2luZGV4KSkge1xyXG4gICAgICAgIGlmICgodGFyZ2V0X2luZGV4ID4gdXBfY291bnQpICYmIHRhcmdldF9pbmRleCA+IHRoaXMuc2V0dGluZ3MucHJldl9pbmRleCkge1xyXG4gICAgICAgICAgcmVzcG9uc2UgPSAncmlnaHQnO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoKHRhcmdldF9pbmRleCA+IHVwX2NvdW50IC0gMSkgJiYgdGFyZ2V0X2luZGV4IDw9IHRoaXMuc2V0dGluZ3MucHJldl9pbmRleCkge1xyXG4gICAgICAgICAgcmVzcG9uc2UgPSAnbGVmdCc7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJlc3BvbnNlID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlc3BvbnNlID0gJ3NraXAnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnNldHRpbmdzLnByZXZfaW5kZXggPSB0YXJnZXRfaW5kZXg7XHJcblxyXG4gICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkamFjZW50IDogZnVuY3Rpb24gKGN1cnJlbnRfaW5kZXgsIHRhcmdldF9pbmRleCkge1xyXG4gICAgICBmb3IgKHZhciBpID0gdGFyZ2V0X2luZGV4ICsgMTsgaSA+PSB0YXJnZXRfaW5kZXggLSAxOyBpLS0pIHtcclxuICAgICAgICBpZiAoaSA9PT0gY3VycmVudF9pbmRleCkge1xyXG4gICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gbG9jayBtYW5hZ2VtZW50XHJcblxyXG4gICAgbG9jayA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5zZXR0aW5ncy5sb2NrZWQgPSB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICB1bmxvY2sgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MubG9ja2VkID0gZmFsc2U7XHJcbiAgICB9LFxyXG5cclxuICAgIGxvY2tlZCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3MubG9ja2VkO1xyXG4gICAgfSxcclxuXHJcbiAgICBvZmYgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuUyh0aGlzLnNjb3BlKS5vZmYoJy5mbmR0bi5jbGVhcmluZycpO1xyXG4gICAgICB0aGlzLlMod2luZG93KS5vZmYoJy5mbmR0bi5jbGVhcmluZycpO1xyXG4gICAgfSxcclxuXHJcbiAgICByZWZsb3cgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLmRyb3Bkb3duID0ge1xyXG4gICAgbmFtZSA6ICdkcm9wZG93bicsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGFjdGl2ZV9jbGFzcyA6ICdvcGVuJyxcclxuICAgICAgZGlzYWJsZWRfY2xhc3MgOiAnZGlzYWJsZWQnLFxyXG4gICAgICBtZWdhX2NsYXNzIDogJ21lZ2EnLFxyXG4gICAgICBhbGlnbiA6ICdib3R0b20nLFxyXG4gICAgICBpc19ob3ZlciA6IGZhbHNlLFxyXG4gICAgICBob3Zlcl90aW1lb3V0IDogMTUwLFxyXG4gICAgICBvcGVuZWQgOiBmdW5jdGlvbiAoKSB7fSxcclxuICAgICAgY2xvc2VkIDogZnVuY3Rpb24gKCkge31cclxuICAgIH0sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIEZvdW5kYXRpb24uaW5oZXJpdCh0aGlzLCAndGhyb3R0bGUnKTtcclxuXHJcbiAgICAgICQuZXh0ZW5kKHRydWUsIHRoaXMuc2V0dGluZ3MsIG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICAgIHRoaXMuYmluZGluZ3MobWV0aG9kLCBvcHRpb25zKTtcclxuICAgIH0sXHJcblxyXG4gICAgZXZlbnRzIDogZnVuY3Rpb24gKHNjb3BlKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgIFMgPSBzZWxmLlM7XHJcblxyXG4gICAgICBTKHRoaXMuc2NvcGUpXHJcbiAgICAgICAgLm9mZignLmRyb3Bkb3duJylcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLmRyb3Bkb3duJywgJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncyA9IFModGhpcykuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3M7XHJcbiAgICAgICAgICBpZiAoIXNldHRpbmdzLmlzX2hvdmVyIHx8IE1vZGVybml6ci50b3VjaCkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGlmIChTKHRoaXMpLnBhcmVudCgnW2RhdGEtcmV2ZWFsLWlkXScpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VsZi50b2dnbGUoJCh0aGlzKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ21vdXNlZW50ZXIuZm5kdG4uZHJvcGRvd24nLCAnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10sIFsnICsgdGhpcy5hdHRyX25hbWUoKSArICctY29udGVudF0nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyICR0aGlzID0gUyh0aGlzKSxcclxuICAgICAgICAgICAgICBkcm9wZG93bixcclxuICAgICAgICAgICAgICB0YXJnZXQ7XHJcblxyXG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZW91dCk7XHJcblxyXG4gICAgICAgICAgaWYgKCR0aGlzLmRhdGEoc2VsZi5kYXRhX2F0dHIoKSkpIHtcclxuICAgICAgICAgICAgZHJvcGRvd24gPSBTKCcjJyArICR0aGlzLmRhdGEoc2VsZi5kYXRhX2F0dHIoKSkpO1xyXG4gICAgICAgICAgICB0YXJnZXQgPSAkdGhpcztcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGRyb3Bkb3duID0gJHRoaXM7XHJcbiAgICAgICAgICAgIHRhcmdldCA9IFMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICc9XCInICsgZHJvcGRvd24uYXR0cignaWQnKSArICdcIl0nKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICB2YXIgc2V0dGluZ3MgPSB0YXJnZXQuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3M7XHJcblxyXG4gICAgICAgICAgaWYgKFMoZS5jdXJyZW50VGFyZ2V0KS5kYXRhKHNlbGYuZGF0YV9hdHRyKCkpICYmIHNldHRpbmdzLmlzX2hvdmVyKSB7XHJcbiAgICAgICAgICAgIHNlbGYuY2xvc2VhbGwuY2FsbChzZWxmKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoc2V0dGluZ3MuaXNfaG92ZXIpIHtcclxuICAgICAgICAgICAgc2VsZi5vcGVuLmFwcGx5KHNlbGYsIFtkcm9wZG93biwgdGFyZ2V0XSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ21vdXNlbGVhdmUuZm5kdG4uZHJvcGRvd24nLCAnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10sIFsnICsgdGhpcy5hdHRyX25hbWUoKSArICctY29udGVudF0nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyICR0aGlzID0gUyh0aGlzKTtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncztcclxuXHJcbiAgICAgICAgICBpZiAoJHRoaXMuZGF0YShzZWxmLmRhdGFfYXR0cigpKSkge1xyXG4gICAgICAgICAgICAgIHNldHRpbmdzID0gJHRoaXMuZGF0YShzZWxmLmRhdGFfYXR0cih0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3M7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHZhciB0YXJnZXQgICA9IFMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICc9XCInICsgUyh0aGlzKS5hdHRyKCdpZCcpICsgJ1wiXScpLFxyXG4gICAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IHRhcmdldC5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwgc2VsZi5zZXR0aW5ncztcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzZWxmLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCR0aGlzLmRhdGEoc2VsZi5kYXRhX2F0dHIoKSkpIHtcclxuICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuaXNfaG92ZXIpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuY2xvc2UuY2FsbChzZWxmLCBTKCcjJyArICR0aGlzLmRhdGEoc2VsZi5kYXRhX2F0dHIoKSkpKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLmlzX2hvdmVyKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmNsb3NlLmNhbGwoc2VsZiwgJHRoaXMpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfS5iaW5kKHRoaXMpLCBzZXR0aW5ncy5ob3Zlcl90aW1lb3V0KTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4uZHJvcGRvd24nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIHBhcmVudCA9IFMoZS50YXJnZXQpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICctY29udGVudF0nKTtcclxuICAgICAgICAgIHZhciBsaW5rcyAgPSBwYXJlbnQuZmluZCgnYScpO1xyXG5cclxuICAgICAgICAgIGlmIChsaW5rcy5sZW5ndGggPiAwICYmIHBhcmVudC5hdHRyKCdhcmlhLWF1dG9jbG9zZScpICE9PSAnZmFsc2UnKSB7XHJcbiAgICAgICAgICAgICAgc2VsZi5jbG9zZS5jYWxsKHNlbGYsIFMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICctY29udGVudF0nKSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKGUudGFyZ2V0ICE9PSBkb2N1bWVudCAmJiAhJC5jb250YWlucyhkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGUudGFyZ2V0KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKFMoZS50YXJnZXQpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJykubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKCEoUyhlLnRhcmdldCkuZGF0YSgncmV2ZWFsSWQnKSkgJiZcclxuICAgICAgICAgICAgKHBhcmVudC5sZW5ndGggPiAwICYmIChTKGUudGFyZ2V0KS5pcygnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJy1jb250ZW50XScpIHx8XHJcbiAgICAgICAgICAgICAgJC5jb250YWlucyhwYXJlbnQuZmlyc3QoKVswXSwgZS50YXJnZXQpKSkpIHtcclxuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHNlbGYuY2xvc2UuY2FsbChzZWxmLCBTKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnLWNvbnRlbnRdJykpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdvcGVuZWQuZm5kdG4uZHJvcGRvd24nLCAnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJy1jb250ZW50XScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYuc2V0dGluZ3Mub3BlbmVkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2Nsb3NlZC5mbmR0bi5kcm9wZG93bicsICdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnLWNvbnRlbnRdJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgc2VsZi5zZXR0aW5ncy5jbG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgIFMod2luZG93KVxyXG4gICAgICAgIC5vZmYoJy5kcm9wZG93bicpXHJcbiAgICAgICAgLm9uKCdyZXNpemUuZm5kdG4uZHJvcGRvd24nLCBzZWxmLnRocm90dGxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYucmVzaXplLmNhbGwoc2VsZik7XHJcbiAgICAgICAgfSwgNTApKTtcclxuXHJcbiAgICAgIHRoaXMucmVzaXplKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGNsb3NlIDogZnVuY3Rpb24gKGRyb3Bkb3duKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgZHJvcGRvd24uZWFjaChmdW5jdGlvbiAoaWR4KSB7XHJcbiAgICAgICAgdmFyIG9yaWdpbmFsX3RhcmdldCA9ICQoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICc9JyArIGRyb3Bkb3duW2lkeF0uaWQgKyAnXScpIHx8ICQoJ2FyaWEtY29udHJvbHM9JyArIGRyb3Bkb3duW2lkeF0uaWQgKyAnXScpO1xyXG4gICAgICAgIG9yaWdpbmFsX3RhcmdldC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ2ZhbHNlJyk7XHJcbiAgICAgICAgaWYgKHNlbGYuUyh0aGlzKS5oYXNDbGFzcyhzZWxmLnNldHRpbmdzLmFjdGl2ZV9jbGFzcykpIHtcclxuICAgICAgICAgIHNlbGYuUyh0aGlzKVxyXG4gICAgICAgICAgICAuY3NzKEZvdW5kYXRpb24ucnRsID8gJ3JpZ2h0JyA6ICdsZWZ0JywgJy05OTk5OXB4JylcclxuICAgICAgICAgICAgLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3Moc2VsZi5zZXR0aW5ncy5hY3RpdmVfY2xhc3MpXHJcbiAgICAgICAgICAgIC5wcmV2KCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpXHJcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhzZWxmLnNldHRpbmdzLmFjdGl2ZV9jbGFzcylcclxuICAgICAgICAgICAgLnJlbW92ZURhdGEoJ3RhcmdldCcpO1xyXG5cclxuICAgICAgICAgIHNlbGYuUyh0aGlzKS50cmlnZ2VyKCdjbG9zZWQuZm5kdG4uZHJvcGRvd24nLCBbZHJvcGRvd25dKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICBkcm9wZG93bi5yZW1vdmVDbGFzcygnZi1vcGVuLScgKyB0aGlzLmF0dHJfbmFtZSh0cnVlKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGNsb3NlYWxsIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICQuZWFjaChzZWxmLlMoJy5mLW9wZW4tJyArIHRoaXMuYXR0cl9uYW1lKHRydWUpKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHNlbGYuY2xvc2UuY2FsbChzZWxmLCBzZWxmLlModGhpcykpO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgb3BlbiA6IGZ1bmN0aW9uIChkcm9wZG93biwgdGFyZ2V0KSB7XHJcbiAgICAgIHRoaXNcclxuICAgICAgICAuY3NzKGRyb3Bkb3duXHJcbiAgICAgICAgLmFkZENsYXNzKHRoaXMuc2V0dGluZ3MuYWN0aXZlX2NsYXNzKSwgdGFyZ2V0KTtcclxuICAgICAgZHJvcGRvd24ucHJldignWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nKS5hZGRDbGFzcyh0aGlzLnNldHRpbmdzLmFjdGl2ZV9jbGFzcyk7XHJcbiAgICAgIGRyb3Bkb3duLmRhdGEoJ3RhcmdldCcsIHRhcmdldC5nZXQoMCkpLnRyaWdnZXIoJ29wZW5lZC5mbmR0bi5kcm9wZG93bicsIFtkcm9wZG93biwgdGFyZ2V0XSk7XHJcbiAgICAgIGRyb3Bkb3duLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcbiAgICAgIHRhcmdldC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgZHJvcGRvd24uZm9jdXMoKTtcclxuICAgICAgZHJvcGRvd24uYWRkQ2xhc3MoJ2Ytb3Blbi0nICsgdGhpcy5hdHRyX25hbWUodHJ1ZSkpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkYXRhX2F0dHIgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICh0aGlzLm5hbWVzcGFjZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZXNwYWNlICsgJy0nICsgdGhpcy5uYW1lO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5uYW1lO1xyXG4gICAgfSxcclxuXHJcbiAgICB0b2dnbGUgOiBmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAgIGlmICh0YXJnZXQuaGFzQ2xhc3ModGhpcy5zZXR0aW5ncy5kaXNhYmxlZF9jbGFzcykpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdmFyIGRyb3Bkb3duID0gdGhpcy5TKCcjJyArIHRhcmdldC5kYXRhKHRoaXMuZGF0YV9hdHRyKCkpKTtcclxuICAgICAgaWYgKGRyb3Bkb3duLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIC8vIE5vIGRyb3Bkb3duIGZvdW5kLCBub3QgY29udGludWluZ1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5jbG9zZS5jYWxsKHRoaXMsIHRoaXMuUygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJy1jb250ZW50XScpLm5vdChkcm9wZG93bikpO1xyXG5cclxuICAgICAgaWYgKGRyb3Bkb3duLmhhc0NsYXNzKHRoaXMuc2V0dGluZ3MuYWN0aXZlX2NsYXNzKSkge1xyXG4gICAgICAgIHRoaXMuY2xvc2UuY2FsbCh0aGlzLCBkcm9wZG93bik7XHJcbiAgICAgICAgaWYgKGRyb3Bkb3duLmRhdGEoJ3RhcmdldCcpICE9PSB0YXJnZXQuZ2V0KDApKSB7XHJcbiAgICAgICAgICB0aGlzLm9wZW4uY2FsbCh0aGlzLCBkcm9wZG93biwgdGFyZ2V0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5vcGVuLmNhbGwodGhpcywgZHJvcGRvd24sIHRhcmdldCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgcmVzaXplIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgZHJvcGRvd24gPSB0aGlzLlMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICctY29udGVudF0ub3BlbicpO1xyXG4gICAgICB2YXIgdGFyZ2V0ID0gJChkcm9wZG93bi5kYXRhKFwidGFyZ2V0XCIpKTtcclxuXHJcbiAgICAgIGlmIChkcm9wZG93bi5sZW5ndGggJiYgdGFyZ2V0Lmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuY3NzKGRyb3Bkb3duLCB0YXJnZXQpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGNzcyA6IGZ1bmN0aW9uIChkcm9wZG93biwgdGFyZ2V0KSB7XHJcbiAgICAgIHZhciBsZWZ0X29mZnNldCA9IE1hdGgubWF4KCh0YXJnZXQud2lkdGgoKSAtIGRyb3Bkb3duLndpZHRoKCkpIC8gMiwgOCksXHJcbiAgICAgICAgICBzZXR0aW5ncyA9IHRhcmdldC5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwgdGhpcy5zZXR0aW5ncyxcclxuICAgICAgICAgIHBhcmVudE92ZXJmbG93ID0gZHJvcGRvd24ucGFyZW50KCkuY3NzKCdvdmVyZmxvdy15JykgfHwgZHJvcGRvd24ucGFyZW50KCkuY3NzKCdvdmVyZmxvdycpO1xyXG5cclxuICAgICAgdGhpcy5jbGVhcl9pZHgoKTtcclxuXHJcblxyXG5cclxuICAgICAgaWYgKHRoaXMuc21hbGwoKSkge1xyXG4gICAgICAgIHZhciBwID0gdGhpcy5kaXJzLmJvdHRvbS5jYWxsKGRyb3Bkb3duLCB0YXJnZXQsIHNldHRpbmdzKTtcclxuXHJcbiAgICAgICAgZHJvcGRvd24uYXR0cignc3R5bGUnLCAnJykucmVtb3ZlQ2xhc3MoJ2Ryb3AtbGVmdCBkcm9wLXJpZ2h0IGRyb3AtdG9wJykuY3NzKHtcclxuICAgICAgICAgIHBvc2l0aW9uIDogJ2Fic29sdXRlJyxcclxuICAgICAgICAgIHdpZHRoIDogJzk1JScsXHJcbiAgICAgICAgICAnbWF4LXdpZHRoJyA6ICdub25lJyxcclxuICAgICAgICAgIHRvcCA6IHAudG9wXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGRyb3Bkb3duLmNzcyhGb3VuZGF0aW9uLnJ0bCA/ICdyaWdodCcgOiAnbGVmdCcsIGxlZnRfb2Zmc2V0KTtcclxuICAgICAgfVxyXG4gICAgICAvLyBkZXRlY3QgaWYgZHJvcGRvd24gaXMgaW4gYW4gb3ZlcmZsb3cgY29udGFpbmVyXHJcbiAgICAgIGVsc2UgaWYgKHBhcmVudE92ZXJmbG93ICE9PSAndmlzaWJsZScpIHtcclxuICAgICAgICB2YXIgb2Zmc2V0ID0gdGFyZ2V0WzBdLm9mZnNldFRvcCArIHRhcmdldFswXS5vZmZzZXRIZWlnaHQ7XHJcblxyXG4gICAgICAgIGRyb3Bkb3duLmF0dHIoJ3N0eWxlJywgJycpLmNzcyh7XHJcbiAgICAgICAgICBwb3NpdGlvbiA6ICdhYnNvbHV0ZScsXHJcbiAgICAgICAgICB0b3AgOiBvZmZzZXRcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgZHJvcGRvd24uY3NzKEZvdW5kYXRpb24ucnRsID8gJ3JpZ2h0JyA6ICdsZWZ0JywgbGVmdF9vZmZzZXQpO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG5cclxuICAgICAgICB0aGlzLnN0eWxlKGRyb3Bkb3duLCB0YXJnZXQsIHNldHRpbmdzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGRyb3Bkb3duO1xyXG4gICAgfSxcclxuXHJcbiAgICBzdHlsZSA6IGZ1bmN0aW9uIChkcm9wZG93biwgdGFyZ2V0LCBzZXR0aW5ncykge1xyXG4gICAgICB2YXIgY3NzID0gJC5leHRlbmQoe3Bvc2l0aW9uIDogJ2Fic29sdXRlJ30sXHJcbiAgICAgICAgdGhpcy5kaXJzW3NldHRpbmdzLmFsaWduXS5jYWxsKGRyb3Bkb3duLCB0YXJnZXQsIHNldHRpbmdzKSk7XHJcblxyXG4gICAgICBkcm9wZG93bi5hdHRyKCdzdHlsZScsICcnKS5jc3MoY3NzKTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gcmV0dXJuIENTUyBwcm9wZXJ0eSBvYmplY3RcclxuICAgIC8vIGB0aGlzYCBpcyB0aGUgZHJvcGRvd25cclxuICAgIGRpcnMgOiB7XHJcbiAgICAgIC8vIENhbGN1bGF0ZSB0YXJnZXQgb2Zmc2V0XHJcbiAgICAgIF9iYXNlIDogZnVuY3Rpb24gKHQsIHMpIHtcclxuICAgICAgICB2YXIgb19wID0gdGhpcy5vZmZzZXRQYXJlbnQoKSxcclxuICAgICAgICAgICAgbyA9IG9fcC5vZmZzZXQoKSxcclxuICAgICAgICAgICAgcCA9IHQub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgIHAudG9wIC09IG8udG9wO1xyXG4gICAgICAgIHAubGVmdCAtPSBvLmxlZnQ7XHJcblxyXG4gICAgICAgIC8vc2V0IHNvbWUgZmxhZ3Mgb24gdGhlIHAgb2JqZWN0IHRvIHBhc3MgYWxvbmdcclxuICAgICAgICBwLm1pc3NSaWdodCA9IGZhbHNlO1xyXG4gICAgICAgIHAubWlzc1RvcCA9IGZhbHNlO1xyXG4gICAgICAgIHAubWlzc0xlZnQgPSBmYWxzZTtcclxuICAgICAgICBwLmxlZnRSaWdodEZsYWcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy9sZXRzIHNlZSBpZiB0aGUgcGFuZWwgd2lsbCBiZSBvZmYgdGhlIHNjcmVlblxyXG4gICAgICAgIC8vZ2V0IHRoZSBhY3R1YWwgd2lkdGggb2YgdGhlIHBhZ2UgYW5kIHN0b3JlIGl0XHJcbiAgICAgICAgdmFyIGFjdHVhbEJvZHlXaWR0aDtcclxuICAgICAgICB2YXIgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgncm93JylbMF0pIHtcclxuICAgICAgICAgIGFjdHVhbEJvZHlXaWR0aCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3JvdycpWzBdLmNsaWVudFdpZHRoO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBhY3R1YWxCb2R5V2lkdGggPSB3aW5kb3dXaWR0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBhY3R1YWxNYXJnaW5XaWR0aCA9ICh3aW5kb3dXaWR0aCAtIGFjdHVhbEJvZHlXaWR0aCkgLyAyO1xyXG4gICAgICAgIHZhciBhY3R1YWxCb3VuZGFyeSA9IGFjdHVhbEJvZHlXaWR0aDtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLmhhc0NsYXNzKCdtZWdhJykgJiYgIXMuaWdub3JlX3JlcG9zaXRpb25pbmcpIHtcclxuICAgICAgICAgIHZhciBvdXRlcldpZHRoID0gdGhpcy5vdXRlcldpZHRoKCk7XHJcbiAgICAgICAgICB2YXIgb19sZWZ0ID0gdC5vZmZzZXQoKS5sZWZ0O1xyXG5cdFx0ICBcclxuICAgICAgICAgIC8vbWlzcyB0b3BcclxuICAgICAgICAgIGlmICh0Lm9mZnNldCgpLnRvcCA8PSB0aGlzLm91dGVySGVpZ2h0KCkpIHtcclxuICAgICAgICAgICAgcC5taXNzVG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgYWN0dWFsQm91bmRhcnkgPSB3aW5kb3dXaWR0aCAtIGFjdHVhbE1hcmdpbldpZHRoO1xyXG4gICAgICAgICAgICBwLmxlZnRSaWdodEZsYWcgPSB0cnVlO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIC8vbWlzcyByaWdodFxyXG4gICAgICAgICAgaWYgKG9fbGVmdCArIG91dGVyV2lkdGggPiBvX2xlZnQgKyBhY3R1YWxNYXJnaW5XaWR0aCAmJiBvX2xlZnQgLSBhY3R1YWxNYXJnaW5XaWR0aCA+IG91dGVyV2lkdGgpIHtcclxuICAgICAgICAgICAgcC5taXNzUmlnaHQgPSB0cnVlO1xyXG4gICAgICAgICAgICBwLm1pc3NMZWZ0ID0gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy9taXNzIGxlZnRcclxuICAgICAgICAgIGlmIChvX2xlZnQgLSBvdXRlcldpZHRoIDw9IDApIHtcclxuICAgICAgICAgICAgcC5taXNzTGVmdCA9IHRydWU7XHJcbiAgICAgICAgICAgIHAubWlzc1JpZ2h0ID0gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcDtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIHRvcCA6IGZ1bmN0aW9uICh0LCBzKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSBGb3VuZGF0aW9uLmxpYnMuZHJvcGRvd24sXHJcbiAgICAgICAgICAgIHAgPSBzZWxmLmRpcnMuX2Jhc2UuY2FsbCh0aGlzLCB0LCBzKTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGRDbGFzcygnZHJvcC10b3AnKTtcclxuXHJcbiAgICAgICAgaWYgKHAubWlzc1RvcCA9PSB0cnVlKSB7XHJcbiAgICAgICAgICBwLnRvcCA9IHAudG9wICsgdC5vdXRlckhlaWdodCgpICsgdGhpcy5vdXRlckhlaWdodCgpO1xyXG4gICAgICAgICAgdGhpcy5yZW1vdmVDbGFzcygnZHJvcC10b3AnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwLm1pc3NSaWdodCA9PSB0cnVlKSB7XHJcbiAgICAgICAgICBwLmxlZnQgPSBwLmxlZnQgLSB0aGlzLm91dGVyV2lkdGgoKSArIHQub3V0ZXJXaWR0aCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHQub3V0ZXJXaWR0aCgpIDwgdGhpcy5vdXRlcldpZHRoKCkgfHwgc2VsZi5zbWFsbCgpIHx8IHRoaXMuaGFzQ2xhc3Mocy5tZWdhX21lbnUpKSB7XHJcbiAgICAgICAgICBzZWxmLmFkanVzdF9waXAodGhpcywgdCwgcywgcCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoRm91bmRhdGlvbi5ydGwpIHtcclxuICAgICAgICAgIHJldHVybiB7bGVmdCA6IHAubGVmdCAtIHRoaXMub3V0ZXJXaWR0aCgpICsgdC5vdXRlcldpZHRoKCksXHJcbiAgICAgICAgICAgIHRvcCA6IHAudG9wIC0gdGhpcy5vdXRlckhlaWdodCgpfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7bGVmdCA6IHAubGVmdCwgdG9wIDogcC50b3AgLSB0aGlzLm91dGVySGVpZ2h0KCl9O1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgYm90dG9tIDogZnVuY3Rpb24gKHQsIHMpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IEZvdW5kYXRpb24ubGlicy5kcm9wZG93bixcclxuICAgICAgICAgICAgcCA9IHNlbGYuZGlycy5fYmFzZS5jYWxsKHRoaXMsIHQsIHMpO1xyXG5cclxuICAgICAgICBpZiAocC5taXNzUmlnaHQgPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgcC5sZWZ0ID0gcC5sZWZ0IC0gdGhpcy5vdXRlcldpZHRoKCkgKyB0Lm91dGVyV2lkdGgoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0Lm91dGVyV2lkdGgoKSA8IHRoaXMub3V0ZXJXaWR0aCgpIHx8IHNlbGYuc21hbGwoKSB8fCB0aGlzLmhhc0NsYXNzKHMubWVnYV9tZW51KSkge1xyXG4gICAgICAgICAgc2VsZi5hZGp1c3RfcGlwKHRoaXMsIHQsIHMsIHApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNlbGYucnRsKSB7XHJcbiAgICAgICAgICByZXR1cm4ge2xlZnQgOiBwLmxlZnQgLSB0aGlzLm91dGVyV2lkdGgoKSArIHQub3V0ZXJXaWR0aCgpLCB0b3AgOiBwLnRvcCArIHQub3V0ZXJIZWlnaHQoKX07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge2xlZnQgOiBwLmxlZnQsIHRvcCA6IHAudG9wICsgdC5vdXRlckhlaWdodCgpfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIGxlZnQgOiBmdW5jdGlvbiAodCwgcykge1xyXG4gICAgICAgIHZhciBwID0gRm91bmRhdGlvbi5saWJzLmRyb3Bkb3duLmRpcnMuX2Jhc2UuY2FsbCh0aGlzLCB0LCBzKTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGRDbGFzcygnZHJvcC1sZWZ0Jyk7XHJcblxyXG4gICAgICAgIGlmIChwLm1pc3NMZWZ0ID09IHRydWUpIHtcclxuICAgICAgICAgIHAubGVmdCA9ICBwLmxlZnQgKyB0aGlzLm91dGVyV2lkdGgoKTtcclxuICAgICAgICAgIHAudG9wID0gcC50b3AgKyB0Lm91dGVySGVpZ2h0KCk7XHJcbiAgICAgICAgICB0aGlzLnJlbW92ZUNsYXNzKCdkcm9wLWxlZnQnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7bGVmdCA6IHAubGVmdCAtIHRoaXMub3V0ZXJXaWR0aCgpLCB0b3AgOiBwLnRvcH07XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICByaWdodCA6IGZ1bmN0aW9uICh0LCBzKSB7XHJcbiAgICAgICAgdmFyIHAgPSBGb3VuZGF0aW9uLmxpYnMuZHJvcGRvd24uZGlycy5fYmFzZS5jYWxsKHRoaXMsIHQsIHMpO1xyXG5cclxuICAgICAgICB0aGlzLmFkZENsYXNzKCdkcm9wLXJpZ2h0Jyk7XHJcblxyXG4gICAgICAgIGlmIChwLm1pc3NSaWdodCA9PSB0cnVlKSB7XHJcbiAgICAgICAgICBwLmxlZnQgPSBwLmxlZnQgLSB0aGlzLm91dGVyV2lkdGgoKTtcclxuICAgICAgICAgIHAudG9wID0gcC50b3AgKyB0Lm91dGVySGVpZ2h0KCk7XHJcbiAgICAgICAgICB0aGlzLnJlbW92ZUNsYXNzKCdkcm9wLXJpZ2h0Jyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHAudHJpZ2dlcmVkUmlnaHQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNlbGYgPSBGb3VuZGF0aW9uLmxpYnMuZHJvcGRvd247XHJcblxyXG4gICAgICAgIGlmICh0Lm91dGVyV2lkdGgoKSA8IHRoaXMub3V0ZXJXaWR0aCgpIHx8IHNlbGYuc21hbGwoKSB8fCB0aGlzLmhhc0NsYXNzKHMubWVnYV9tZW51KSkge1xyXG4gICAgICAgICAgc2VsZi5hZGp1c3RfcGlwKHRoaXMsIHQsIHMsIHApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHtsZWZ0IDogcC5sZWZ0ICsgdC5vdXRlcldpZHRoKCksIHRvcCA6IHAudG9wfTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBJbnNlcnQgcnVsZSB0byBzdHlsZSBwc3VlZG8gZWxlbWVudHNcclxuICAgIGFkanVzdF9waXAgOiBmdW5jdGlvbiAoZHJvcGRvd24sIHRhcmdldCwgc2V0dGluZ3MsIHBvc2l0aW9uKSB7XHJcbiAgICAgIHZhciBzaGVldCA9IEZvdW5kYXRpb24uc3R5bGVzaGVldCxcclxuICAgICAgICAgIHBpcF9vZmZzZXRfYmFzZSA9IDg7XHJcblxyXG4gICAgICBpZiAoZHJvcGRvd24uaGFzQ2xhc3Moc2V0dGluZ3MubWVnYV9jbGFzcykpIHtcclxuICAgICAgICBwaXBfb2Zmc2V0X2Jhc2UgPSBwb3NpdGlvbi5sZWZ0ICsgKHRhcmdldC5vdXRlcldpZHRoKCkgLyAyKSAtIDg7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zbWFsbCgpKSB7XHJcbiAgICAgICAgcGlwX29mZnNldF9iYXNlICs9IHBvc2l0aW9uLmxlZnQgLSA4O1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnJ1bGVfaWR4ID0gc2hlZXQuY3NzUnVsZXMubGVuZ3RoO1xyXG5cclxuICAgICAgLy9kZWZhdWx0XHJcbiAgICAgIHZhciBzZWxfYmVmb3JlID0gJy5mLWRyb3Bkb3duLm9wZW46YmVmb3JlJyxcclxuICAgICAgICAgIHNlbF9hZnRlciAgPSAnLmYtZHJvcGRvd24ub3BlbjphZnRlcicsXHJcbiAgICAgICAgICBjc3NfYmVmb3JlID0gJ2xlZnQ6ICcgKyBwaXBfb2Zmc2V0X2Jhc2UgKyAncHg7JyxcclxuICAgICAgICAgIGNzc19hZnRlciAgPSAnbGVmdDogJyArIChwaXBfb2Zmc2V0X2Jhc2UgLSAxKSArICdweDsnO1xyXG5cclxuICAgICAgaWYgKHBvc2l0aW9uLm1pc3NSaWdodCA9PSB0cnVlKSB7XHJcbiAgICAgICAgcGlwX29mZnNldF9iYXNlID0gZHJvcGRvd24ub3V0ZXJXaWR0aCgpIC0gMjM7XHJcbiAgICAgICAgc2VsX2JlZm9yZSA9ICcuZi1kcm9wZG93bi5vcGVuOmJlZm9yZScsXHJcbiAgICAgICAgc2VsX2FmdGVyICA9ICcuZi1kcm9wZG93bi5vcGVuOmFmdGVyJyxcclxuICAgICAgICBjc3NfYmVmb3JlID0gJ2xlZnQ6ICcgKyBwaXBfb2Zmc2V0X2Jhc2UgKyAncHg7JyxcclxuICAgICAgICBjc3NfYWZ0ZXIgID0gJ2xlZnQ6ICcgKyAocGlwX29mZnNldF9iYXNlIC0gMSkgKyAncHg7JztcclxuICAgICAgfVxyXG5cclxuICAgICAgLy9qdXN0IGEgY2FzZSB3aGVyZSByaWdodCBpcyBmaXJlZCwgYnV0IGl0cyBub3QgbWlzc2luZyByaWdodFxyXG4gICAgICBpZiAocG9zaXRpb24udHJpZ2dlcmVkUmlnaHQgPT0gdHJ1ZSkge1xyXG4gICAgICAgIHNlbF9iZWZvcmUgPSAnLmYtZHJvcGRvd24ub3BlbjpiZWZvcmUnLFxyXG4gICAgICAgIHNlbF9hZnRlciAgPSAnLmYtZHJvcGRvd24ub3BlbjphZnRlcicsXHJcbiAgICAgICAgY3NzX2JlZm9yZSA9ICdsZWZ0Oi0xMnB4OycsXHJcbiAgICAgICAgY3NzX2FmdGVyICA9ICdsZWZ0Oi0xNHB4Oyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzaGVldC5pbnNlcnRSdWxlKSB7XHJcbiAgICAgICAgc2hlZXQuaW5zZXJ0UnVsZShbc2VsX2JlZm9yZSwgJ3snLCBjc3NfYmVmb3JlLCAnfSddLmpvaW4oJyAnKSwgdGhpcy5ydWxlX2lkeCk7XHJcbiAgICAgICAgc2hlZXQuaW5zZXJ0UnVsZShbc2VsX2FmdGVyLCAneycsIGNzc19hZnRlciwgJ30nXS5qb2luKCcgJyksIHRoaXMucnVsZV9pZHggKyAxKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzaGVldC5hZGRSdWxlKHNlbF9iZWZvcmUsIGNzc19iZWZvcmUsIHRoaXMucnVsZV9pZHgpO1xyXG4gICAgICAgIHNoZWV0LmFkZFJ1bGUoc2VsX2FmdGVyLCBjc3NfYWZ0ZXIsIHRoaXMucnVsZV9pZHggKyAxKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvLyBSZW1vdmUgb2xkIGRyb3Bkb3duIHJ1bGUgaW5kZXhcclxuICAgIGNsZWFyX2lkeCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNoZWV0ID0gRm91bmRhdGlvbi5zdHlsZXNoZWV0O1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiB0aGlzLnJ1bGVfaWR4ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHNoZWV0LmRlbGV0ZVJ1bGUodGhpcy5ydWxlX2lkeCk7XHJcbiAgICAgICAgc2hlZXQuZGVsZXRlUnVsZSh0aGlzLnJ1bGVfaWR4KTtcclxuICAgICAgICBkZWxldGUgdGhpcy5ydWxlX2lkeDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzbWFsbCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuIG1hdGNoTWVkaWEoRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLnNtYWxsKS5tYXRjaGVzICYmXHJcbiAgICAgICAgIW1hdGNoTWVkaWEoRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLm1lZGl1bSkubWF0Y2hlcztcclxuICAgIH0sXHJcblxyXG4gICAgb2ZmIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB0aGlzLlModGhpcy5zY29wZSkub2ZmKCcuZm5kdG4uZHJvcGRvd24nKTtcclxuICAgICAgdGhpcy5TKCdodG1sLCBib2R5Jykub2ZmKCcuZm5kdG4uZHJvcGRvd24nKTtcclxuICAgICAgdGhpcy5TKHdpbmRvdykub2ZmKCcuZm5kdG4uZHJvcGRvd24nKTtcclxuICAgICAgdGhpcy5TKCdbZGF0YS1kcm9wZG93bi1jb250ZW50XScpLm9mZignLmZuZHRuLmRyb3Bkb3duJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlZmxvdyA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgfTtcclxufShqUXVlcnksIHdpbmRvdywgd2luZG93LmRvY3VtZW50KSk7XHJcblxyXG47KGZ1bmN0aW9uICgkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIgPSB7XHJcbiAgICBuYW1lIDogJ2VxdWFsaXplcicsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIHVzZV90YWxsZXN0IDogdHJ1ZSxcclxuICAgICAgYmVmb3JlX2hlaWdodF9jaGFuZ2UgOiAkLm5vb3AsXHJcbiAgICAgIGFmdGVyX2hlaWdodF9jaGFuZ2UgOiAkLm5vb3AsXHJcbiAgICAgIGVxdWFsaXplX29uX3N0YWNrIDogZmFsc2UsXHJcbiAgICAgIGFjdF9vbl9oaWRkZW5fZWw6IGZhbHNlXHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICBGb3VuZGF0aW9uLmluaGVyaXQodGhpcywgJ2ltYWdlX2xvYWRlZCcpO1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICAgIHRoaXMucmVmbG93KCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5TKHdpbmRvdykub2ZmKCcuZXF1YWxpemVyJykub24oJ3Jlc2l6ZS5mbmR0bi5lcXVhbGl6ZXInLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHRoaXMucmVmbG93KCk7XHJcbiAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGVxdWFsaXplIDogZnVuY3Rpb24gKGVxdWFsaXplcikge1xyXG4gICAgICB2YXIgaXNTdGFja2VkID0gZmFsc2UsXHJcbiAgICAgICAgICBncm91cCA9IGVxdWFsaXplci5kYXRhKCdlcXVhbGl6ZXInKSxcclxuICAgICAgICAgIHNldHRpbmdzID0gZXF1YWxpemVyLmRhdGEodGhpcy5hdHRyX25hbWUodHJ1ZSkrJy1pbml0JykgfHwgdGhpcy5zZXR0aW5ncyxcclxuICAgICAgICAgIHZhbHMsXHJcbiAgICAgICAgICBmaXJzdFRvcE9mZnNldDtcclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5hY3Rfb25faGlkZGVuX2VsKSB7XHJcbiAgICAgICAgdmFscyA9IGdyb3VwID8gZXF1YWxpemVyLmZpbmQoJ1snK3RoaXMuYXR0cl9uYW1lKCkrJy13YXRjaD1cIicrZ3JvdXArJ1wiXScpIDogZXF1YWxpemVyLmZpbmQoJ1snK3RoaXMuYXR0cl9uYW1lKCkrJy13YXRjaF0nKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICB2YWxzID0gZ3JvdXAgPyBlcXVhbGl6ZXIuZmluZCgnWycrdGhpcy5hdHRyX25hbWUoKSsnLXdhdGNoPVwiJytncm91cCsnXCJdOnZpc2libGUnKSA6IGVxdWFsaXplci5maW5kKCdbJyt0aGlzLmF0dHJfbmFtZSgpKyctd2F0Y2hdOnZpc2libGUnKTtcclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgaWYgKHZhbHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZXR0aW5ncy5iZWZvcmVfaGVpZ2h0X2NoYW5nZSgpO1xyXG4gICAgICBlcXVhbGl6ZXIudHJpZ2dlcignYmVmb3JlLWhlaWdodC1jaGFuZ2UuZm5kdGguZXF1YWxpemVyJyk7XHJcbiAgICAgIHZhbHMuaGVpZ2h0KCdpbmhlcml0Jyk7XHJcblxyXG4gICAgICBpZiAoc2V0dGluZ3MuZXF1YWxpemVfb25fc3RhY2sgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgZmlyc3RUb3BPZmZzZXQgPSB2YWxzLmZpcnN0KCkub2Zmc2V0KCkudG9wO1xyXG4gICAgICAgIHZhbHMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBpZiAoJCh0aGlzKS5vZmZzZXQoKS50b3AgIT09IGZpcnN0VG9wT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIGlzU3RhY2tlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoaXNTdGFja2VkKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgaGVpZ2h0cyA9IHZhbHMubWFwKGZ1bmN0aW9uICgpIHsgcmV0dXJuICQodGhpcykub3V0ZXJIZWlnaHQoZmFsc2UpIH0pLmdldCgpO1xyXG5cclxuICAgICAgaWYgKHNldHRpbmdzLnVzZV90YWxsZXN0KSB7XHJcbiAgICAgICAgdmFyIG1heCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIGhlaWdodHMpO1xyXG4gICAgICAgIHZhbHMuY3NzKCdoZWlnaHQnLCBtYXgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBtaW4gPSBNYXRoLm1pbi5hcHBseShudWxsLCBoZWlnaHRzKTtcclxuICAgICAgICB2YWxzLmNzcygnaGVpZ2h0JywgbWluKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2V0dGluZ3MuYWZ0ZXJfaGVpZ2h0X2NoYW5nZSgpO1xyXG4gICAgICBlcXVhbGl6ZXIudHJpZ2dlcignYWZ0ZXItaGVpZ2h0LWNoYW5nZS5mbmR0bi5lcXVhbGl6ZXInKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICB0aGlzLlMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJywgdGhpcy5zY29wZSkuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyICRlcV90YXJnZXQgPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICBtZWRpYV9xdWVyeSA9ICRlcV90YXJnZXQuZGF0YSgnZXF1YWxpemVyLW1xJyksXHJcbiAgICAgICAgICAgIGlnbm9yZV9tZWRpYV9xdWVyeSA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmIChtZWRpYV9xdWVyeSkge1xyXG4gICAgICAgICAgbWVkaWFfcXVlcnkgPSAnaXNfJyArIG1lZGlhX3F1ZXJ5LnJlcGxhY2UoLy0vZywgJ18nKTtcclxuICAgICAgICAgIGlmIChGb3VuZGF0aW9uLnV0aWxzLmhhc093blByb3BlcnR5KG1lZGlhX3F1ZXJ5KSkge1xyXG4gICAgICAgICAgICBpZ25vcmVfbWVkaWFfcXVlcnkgPSBmYWxzZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNlbGYuaW1hZ2VfbG9hZGVkKHNlbGYuUygnaW1nJywgdGhpcyksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGlmIChpZ25vcmVfbWVkaWFfcXVlcnkgfHwgRm91bmRhdGlvbi51dGlsc1ttZWRpYV9xdWVyeV0oKSkge1xyXG4gICAgICAgICAgICBzZWxmLmVxdWFsaXplKCRlcV90YXJnZXQpXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgdmFscyA9ICRlcV90YXJnZXQuZmluZCgnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJy13YXRjaF06dmlzaWJsZScpO1xyXG4gICAgICAgICAgICB2YWxzLmNzcygnaGVpZ2h0JywgJ2F1dG8nKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfTtcclxufSkoalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCk7XHJcblxyXG47KGZ1bmN0aW9uICgkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicy5pbnRlcmNoYW5nZSA9IHtcclxuICAgIG5hbWUgOiAnaW50ZXJjaGFuZ2UnLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIGNhY2hlIDoge30sXHJcblxyXG4gICAgaW1hZ2VzX2xvYWRlZCA6IGZhbHNlLFxyXG4gICAgbm9kZXNfbG9hZGVkIDogZmFsc2UsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGxvYWRfYXR0ciA6ICdpbnRlcmNoYW5nZScsXHJcblxyXG4gICAgICBuYW1lZF9xdWVyaWVzIDoge1xyXG4gICAgICAgICdkZWZhdWx0JyAgICAgOiAnb25seSBzY3JlZW4nLFxyXG4gICAgICAgICdzbWFsbCcgICAgICAgOiBGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ3NtYWxsJ10sXHJcbiAgICAgICAgJ3NtYWxsLW9ubHknICA6IEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1snc21hbGwtb25seSddLFxyXG4gICAgICAgICdtZWRpdW0nICAgICAgOiBGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ21lZGl1bSddLFxyXG4gICAgICAgICdtZWRpdW0tb25seScgOiBGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ21lZGl1bS1vbmx5J10sXHJcbiAgICAgICAgJ2xhcmdlJyAgICAgICA6IEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1snbGFyZ2UnXSxcclxuICAgICAgICAnbGFyZ2Utb25seScgIDogRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzWydsYXJnZS1vbmx5J10sXHJcbiAgICAgICAgJ3hsYXJnZScgICAgICA6IEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1sneGxhcmdlJ10sXHJcbiAgICAgICAgJ3hsYXJnZS1vbmx5JyA6IEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1sneGxhcmdlLW9ubHknXSxcclxuICAgICAgICAneHhsYXJnZScgICAgIDogRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzWyd4eGxhcmdlJ10sXHJcbiAgICAgICAgJ2xhbmRzY2FwZScgICA6ICdvbmx5IHNjcmVlbiBhbmQgKG9yaWVudGF0aW9uOiBsYW5kc2NhcGUpJyxcclxuICAgICAgICAncG9ydHJhaXQnICAgIDogJ29ubHkgc2NyZWVuIGFuZCAob3JpZW50YXRpb246IHBvcnRyYWl0KScsXHJcbiAgICAgICAgJ3JldGluYScgICAgICA6ICdvbmx5IHNjcmVlbiBhbmQgKC13ZWJraXQtbWluLWRldmljZS1waXhlbC1yYXRpbzogMiksJyArXHJcbiAgICAgICAgICAnb25seSBzY3JlZW4gYW5kIChtaW4tLW1vei1kZXZpY2UtcGl4ZWwtcmF0aW86IDIpLCcgK1xyXG4gICAgICAgICAgJ29ubHkgc2NyZWVuIGFuZCAoLW8tbWluLWRldmljZS1waXhlbC1yYXRpbzogMi8xKSwnICtcclxuICAgICAgICAgICdvbmx5IHNjcmVlbiBhbmQgKG1pbi1kZXZpY2UtcGl4ZWwtcmF0aW86IDIpLCcgK1xyXG4gICAgICAgICAgJ29ubHkgc2NyZWVuIGFuZCAobWluLXJlc29sdXRpb246IDE5MmRwaSksJyArXHJcbiAgICAgICAgICAnb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjogMmRwcHgpJ1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgZGlyZWN0aXZlcyA6IHtcclxuICAgICAgICByZXBsYWNlIDogZnVuY3Rpb24gKGVsLCBwYXRoLCB0cmlnZ2VyKSB7XHJcbiAgICAgICAgICAvLyBUaGUgdHJpZ2dlciBhcmd1bWVudCwgaWYgY2FsbGVkIHdpdGhpbiB0aGUgZGlyZWN0aXZlLCBmaXJlc1xyXG4gICAgICAgICAgLy8gYW4gZXZlbnQgbmFtZWQgYWZ0ZXIgdGhlIGRpcmVjdGl2ZSBvbiB0aGUgZWxlbWVudCwgcGFzc2luZ1xyXG4gICAgICAgICAgLy8gYW55IHBhcmFtZXRlcnMgYWxvbmcgdG8gdGhlIGV2ZW50IHRoYXQgeW91IHBhc3MgdG8gdHJpZ2dlci5cclxuICAgICAgICAgIC8vXHJcbiAgICAgICAgICAvLyBleC4gdHJpZ2dlcigpLCB0cmlnZ2VyKFthLCBiLCBjXSksIG9yIHRyaWdnZXIoYSwgYiwgYylcclxuICAgICAgICAgIC8vXHJcbiAgICAgICAgICAvLyBUaGlzIGFsbG93cyB5b3UgdG8gYmluZCBhIGNhbGxiYWNrIGxpa2Ugc286XHJcbiAgICAgICAgICAvLyAkKCcjaW50ZXJjaGFuZ2VDb250YWluZXInKS5vbigncmVwbGFjZScsIGZ1bmN0aW9uIChlLCBhLCBiLCBjKSB7XHJcbiAgICAgICAgICAvLyAgIGNvbnNvbGUubG9nKCQodGhpcykuaHRtbCgpLCBhLCBiLCBjKTtcclxuICAgICAgICAgIC8vIH0pO1xyXG5cclxuICAgICAgICAgIGlmIChlbCAhPT0gbnVsbCAmJiAvSU1HLy50ZXN0KGVsWzBdLm5vZGVOYW1lKSkge1xyXG4gICAgICAgICAgICB2YXIgb3JpZ19wYXRoID0gJC5lYWNoKGVsLCBmdW5jdGlvbigpe3RoaXMuc3JjID0gcGF0aDt9KTtcclxuICAgICAgICAgICAgLy8gdmFyIG9yaWdfcGF0aCA9IGVsWzBdLnNyYztcclxuXHJcbiAgICAgICAgICAgIGlmIChuZXcgUmVnRXhwKHBhdGgsICdpJykudGVzdChvcmlnX3BhdGgpKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbC5hdHRyKFwic3JjXCIsIHBhdGgpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRyaWdnZXIoZWxbMF0uc3JjKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHZhciBsYXN0X3BhdGggPSBlbC5kYXRhKHRoaXMuZGF0YV9hdHRyICsgJy1sYXN0LXBhdGgnKSxcclxuICAgICAgICAgICAgICBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgICAgICBpZiAobGFzdF9wYXRoID09IHBhdGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICgvXFwuKGdpZnxqcGd8anBlZ3x0aWZmfHBuZykoWz8jXS4qKT8vaS50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgICAgICQoZWwpLmNzcygnYmFja2dyb3VuZC1pbWFnZScsICd1cmwoJyArIHBhdGggKyAnKScpO1xyXG4gICAgICAgICAgICBlbC5kYXRhKCdpbnRlcmNoYW5nZS1sYXN0LXBhdGgnLCBwYXRoKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRyaWdnZXIocGF0aCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgcmV0dXJuICQuZ2V0KHBhdGgsIGZ1bmN0aW9uIChyZXNwb25zZSkge1xyXG4gICAgICAgICAgICBlbC5odG1sKHJlc3BvbnNlKTtcclxuICAgICAgICAgICAgZWwuZGF0YShzZWxmLmRhdGFfYXR0ciArICctbGFzdC1wYXRoJywgcGF0aCk7XHJcbiAgICAgICAgICAgIHRyaWdnZXIoKTtcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIEZvdW5kYXRpb24uaW5oZXJpdCh0aGlzLCAndGhyb3R0bGUgcmFuZG9tX3N0cicpO1xyXG5cclxuICAgICAgdGhpcy5kYXRhX2F0dHIgPSB0aGlzLnNldF9kYXRhX2F0dHIoKTtcclxuICAgICAgJC5leHRlbmQodHJ1ZSwgdGhpcy5zZXR0aW5ncywgbWV0aG9kLCBvcHRpb25zKTtcclxuICAgICAgdGhpcy5iaW5kaW5ncyhtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgICB0aGlzLnJlZmxvdygpO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRfbWVkaWFfaGFzaCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgbWVkaWFIYXNoID0gJyc7XHJcbiAgICAgICAgZm9yICh2YXIgcXVlcnlOYW1lIGluIHRoaXMuc2V0dGluZ3MubmFtZWRfcXVlcmllcyApIHtcclxuICAgICAgICAgICAgbWVkaWFIYXNoICs9IG1hdGNoTWVkaWEodGhpcy5zZXR0aW5ncy5uYW1lZF9xdWVyaWVzW3F1ZXJ5TmFtZV0pLm1hdGNoZXMudG9TdHJpbmcoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG1lZGlhSGFzaDtcclxuICAgIH0sXHJcblxyXG4gICAgZXZlbnRzIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsIHByZXZNZWRpYUhhc2g7XHJcblxyXG4gICAgICAkKHdpbmRvdylcclxuICAgICAgICAub2ZmKCcuaW50ZXJjaGFuZ2UnKVxyXG4gICAgICAgIC5vbigncmVzaXplLmZuZHRuLmludGVyY2hhbmdlJywgc2VsZi50aHJvdHRsZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBjdXJyTWVkaWFIYXNoID0gc2VsZi5nZXRfbWVkaWFfaGFzaCgpO1xyXG4gICAgICAgICAgICBpZiAoY3Vyck1lZGlhSGFzaCAhPT0gcHJldk1lZGlhSGFzaCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5yZXNpemUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwcmV2TWVkaWFIYXNoID0gY3Vyck1lZGlhSGFzaDtcclxuICAgICAgICB9LCA1MCkpO1xyXG5cclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlc2l6ZSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGNhY2hlID0gdGhpcy5jYWNoZTtcclxuXHJcbiAgICAgIGlmICghdGhpcy5pbWFnZXNfbG9hZGVkIHx8ICF0aGlzLm5vZGVzX2xvYWRlZCkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoJC5wcm94eSh0aGlzLnJlc2l6ZSwgdGhpcyksIDUwKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZvciAodmFyIHV1aWQgaW4gY2FjaGUpIHtcclxuICAgICAgICBpZiAoY2FjaGUuaGFzT3duUHJvcGVydHkodXVpZCkpIHtcclxuICAgICAgICAgIHZhciBwYXNzZWQgPSB0aGlzLnJlc3VsdHModXVpZCwgY2FjaGVbdXVpZF0pO1xyXG4gICAgICAgICAgaWYgKHBhc3NlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzLmRpcmVjdGl2ZXNbcGFzc2VkXHJcbiAgICAgICAgICAgICAgLnNjZW5hcmlvWzFdXS5jYWxsKHRoaXMsIHBhc3NlZC5lbCwgcGFzc2VkLnNjZW5hcmlvWzBdLCAoZnVuY3Rpb24gKHBhc3NlZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1swXSBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzWzBdO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgcGFzc2VkLmVsLnRyaWdnZXIocGFzc2VkLnNjZW5hcmlvWzFdLCBhcmdzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KHBhc3NlZCkpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICB9LFxyXG5cclxuICAgIHJlc3VsdHMgOiBmdW5jdGlvbiAodXVpZCwgc2NlbmFyaW9zKSB7XHJcbiAgICAgIHZhciBjb3VudCA9IHNjZW5hcmlvcy5sZW5ndGg7XHJcblxyXG4gICAgICBpZiAoY291bnQgPiAwKSB7XHJcbiAgICAgICAgdmFyIGVsID0gdGhpcy5TKCdbJyArIHRoaXMuYWRkX25hbWVzcGFjZSgnZGF0YS11dWlkJykgKyAnPVwiJyArIHV1aWQgKyAnXCJdJyk7XHJcblxyXG4gICAgICAgIHdoaWxlIChjb3VudC0tKSB7XHJcbiAgICAgICAgICB2YXIgbXEsIHJ1bGUgPSBzY2VuYXJpb3NbY291bnRdWzJdO1xyXG4gICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MubmFtZWRfcXVlcmllcy5oYXNPd25Qcm9wZXJ0eShydWxlKSkge1xyXG4gICAgICAgICAgICBtcSA9IG1hdGNoTWVkaWEodGhpcy5zZXR0aW5ncy5uYW1lZF9xdWVyaWVzW3J1bGVdKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG1xID0gbWF0Y2hNZWRpYShydWxlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChtcS5tYXRjaGVzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7ZWwgOiBlbCwgc2NlbmFyaW8gOiBzY2VuYXJpb3NbY291bnRdfTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0sXHJcblxyXG4gICAgbG9hZCA6IGZ1bmN0aW9uICh0eXBlLCBmb3JjZV91cGRhdGUpIHtcclxuICAgICAgaWYgKHR5cGVvZiB0aGlzWydjYWNoZWRfJyArIHR5cGVdID09PSAndW5kZWZpbmVkJyB8fCBmb3JjZV91cGRhdGUpIHtcclxuICAgICAgICB0aGlzWyd1cGRhdGVfJyArIHR5cGVdKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzWydjYWNoZWRfJyArIHR5cGVdO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVfaW1hZ2VzIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgaW1hZ2VzID0gdGhpcy5TKCdpbWdbJyArIHRoaXMuZGF0YV9hdHRyICsgJ10nKSxcclxuICAgICAgICAgIGNvdW50ID0gaW1hZ2VzLmxlbmd0aCxcclxuICAgICAgICAgIGkgPSBjb3VudCxcclxuICAgICAgICAgIGxvYWRlZF9jb3VudCA9IDAsXHJcbiAgICAgICAgICBkYXRhX2F0dHIgPSB0aGlzLmRhdGFfYXR0cjtcclxuXHJcbiAgICAgIHRoaXMuY2FjaGUgPSB7fTtcclxuICAgICAgdGhpcy5jYWNoZWRfaW1hZ2VzID0gW107XHJcbiAgICAgIHRoaXMuaW1hZ2VzX2xvYWRlZCA9IChjb3VudCA9PT0gMCk7XHJcblxyXG4gICAgICB3aGlsZSAoaS0tKSB7XHJcbiAgICAgICAgbG9hZGVkX2NvdW50Kys7XHJcbiAgICAgICAgaWYgKGltYWdlc1tpXSkge1xyXG4gICAgICAgICAgdmFyIHN0ciA9IGltYWdlc1tpXS5nZXRBdHRyaWJ1dGUoZGF0YV9hdHRyKSB8fCAnJztcclxuXHJcbiAgICAgICAgICBpZiAoc3RyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgdGhpcy5jYWNoZWRfaW1hZ2VzLnB1c2goaW1hZ2VzW2ldKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChsb2FkZWRfY291bnQgPT09IGNvdW50KSB7XHJcbiAgICAgICAgICB0aGlzLmltYWdlc19sb2FkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgdGhpcy5lbmhhbmNlKCdpbWFnZXMnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVfbm9kZXMgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBub2RlcyA9IHRoaXMuUygnWycgKyB0aGlzLmRhdGFfYXR0ciArICddJykubm90KCdpbWcnKSxcclxuICAgICAgICAgIGNvdW50ID0gbm9kZXMubGVuZ3RoLFxyXG4gICAgICAgICAgaSA9IGNvdW50LFxyXG4gICAgICAgICAgbG9hZGVkX2NvdW50ID0gMCxcclxuICAgICAgICAgIGRhdGFfYXR0ciA9IHRoaXMuZGF0YV9hdHRyO1xyXG5cclxuICAgICAgdGhpcy5jYWNoZWRfbm9kZXMgPSBbXTtcclxuICAgICAgdGhpcy5ub2Rlc19sb2FkZWQgPSAoY291bnQgPT09IDApO1xyXG5cclxuICAgICAgd2hpbGUgKGktLSkge1xyXG4gICAgICAgIGxvYWRlZF9jb3VudCsrO1xyXG4gICAgICAgIHZhciBzdHIgPSBub2Rlc1tpXS5nZXRBdHRyaWJ1dGUoZGF0YV9hdHRyKSB8fCAnJztcclxuXHJcbiAgICAgICAgaWYgKHN0ci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICB0aGlzLmNhY2hlZF9ub2Rlcy5wdXNoKG5vZGVzW2ldKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChsb2FkZWRfY291bnQgPT09IGNvdW50KSB7XHJcbiAgICAgICAgICB0aGlzLm5vZGVzX2xvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLmVuaGFuY2UoJ25vZGVzJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH0sXHJcblxyXG4gICAgZW5oYW5jZSA6IGZ1bmN0aW9uICh0eXBlKSB7XHJcbiAgICAgIHZhciBpID0gdGhpc1snY2FjaGVkXycgKyB0eXBlXS5sZW5ndGg7XHJcblxyXG4gICAgICB3aGlsZSAoaS0tKSB7XHJcbiAgICAgICAgdGhpcy5vYmplY3QoJCh0aGlzWydjYWNoZWRfJyArIHR5cGVdW2ldKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiAkKHdpbmRvdykudHJpZ2dlcigncmVzaXplLmZuZHRuLmludGVyY2hhbmdlJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGNvbnZlcnRfZGlyZWN0aXZlIDogZnVuY3Rpb24gKGRpcmVjdGl2ZSkge1xyXG5cclxuICAgICAgdmFyIHRyaW1tZWQgPSB0aGlzLnRyaW0oZGlyZWN0aXZlKTtcclxuXHJcbiAgICAgIGlmICh0cmltbWVkLmxlbmd0aCA+IDApIHtcclxuICAgICAgICByZXR1cm4gdHJpbW1lZDtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuICdyZXBsYWNlJztcclxuICAgIH0sXHJcblxyXG4gICAgcGFyc2Vfc2NlbmFyaW8gOiBmdW5jdGlvbiAoc2NlbmFyaW8pIHtcclxuICAgICAgLy8gVGhpcyBsb2dpYyBoYWQgdG8gYmUgbWFkZSBtb3JlIGNvbXBsZXggc2luY2Ugc29tZSB1c2VycyB3ZXJlIHVzaW5nIGNvbW1hcyBpbiB0aGUgdXJsIHBhdGhcclxuICAgICAgLy8gU28gd2UgY2Fubm90IHNpbXBseSBqdXN0IHNwbGl0IG9uIGEgY29tbWFcclxuXHJcbiAgICAgIHZhciBkaXJlY3RpdmVfbWF0Y2ggPSBzY2VuYXJpb1swXS5tYXRjaCgvKC4rKSxcXHMqKFxcdyspXFxzKiQvKSxcclxuICAgICAgLy8gZ2V0dGluZyB0aGUgbXEgaGFzIGdvdHRlbiBhIGJpdCBjb21wbGljYXRlZCBzaW5jZSB3ZSBzdGFydGVkIGFjY291bnRpbmcgZm9yIHNldmVyYWwgdXNlIGNhc2VzXHJcbiAgICAgIC8vIG9mIFVSTHMuIEZvciBub3cgd2UnbGwgY29udGludWUgdG8gbWF0Y2ggdGhlc2Ugc2NlbmFyaW9zLCBidXQgd2UgbWF5IGNvbnNpZGVyIGhhdmluZyB0aGVzZSBzY2VuYXJpb3NcclxuICAgICAgLy8gYXMgbmVzdGVkIG9iamVjdHMgb3IgYXJyYXlzIGluIEY2LlxyXG4gICAgICAvLyByZWdleDogbWF0Y2ggZXZlcnl0aGluZyBiZWZvcmUgY2xvc2UgcGFyZW50aGVzaXMgZm9yIG1xXHJcbiAgICAgIG1lZGlhX3F1ZXJ5ICAgICAgICAgPSBzY2VuYXJpb1sxXS5tYXRjaCgvKC4qKVxcKS8pO1xyXG5cclxuICAgICAgaWYgKGRpcmVjdGl2ZV9tYXRjaCkge1xyXG4gICAgICAgIHZhciBwYXRoICA9IGRpcmVjdGl2ZV9tYXRjaFsxXSxcclxuICAgICAgICBkaXJlY3RpdmUgPSBkaXJlY3RpdmVfbWF0Y2hbMl07XHJcblxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBjYWNoZWRfc3BsaXQgPSBzY2VuYXJpb1swXS5zcGxpdCgvLFxccyokLyksXHJcbiAgICAgICAgcGF0aCAgICAgICAgICAgICA9IGNhY2hlZF9zcGxpdFswXSxcclxuICAgICAgICBkaXJlY3RpdmUgICAgICAgID0gJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBbdGhpcy50cmltKHBhdGgpLCB0aGlzLmNvbnZlcnRfZGlyZWN0aXZlKGRpcmVjdGl2ZSksIHRoaXMudHJpbShtZWRpYV9xdWVyeVsxXSldO1xyXG4gICAgfSxcclxuXHJcbiAgICBvYmplY3QgOiBmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgdmFyIHJhd19hcnIgPSB0aGlzLnBhcnNlX2RhdGFfYXR0cihlbCksXHJcbiAgICAgICAgICBzY2VuYXJpb3MgPSBbXSxcclxuICAgICAgICAgIGkgPSByYXdfYXJyLmxlbmd0aDtcclxuXHJcbiAgICAgIGlmIChpID4gMCkge1xyXG4gICAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICAgIC8vIHNwbGl0IGFycmF5IGJldHdlZW4gY29tbWEgZGVsaW1pdGVkIGNvbnRlbnQgYW5kIG1xXHJcbiAgICAgICAgICAvLyByZWdleDogY29tbWEsIG9wdGlvbmFsIHNwYWNlLCBvcGVuIHBhcmVudGhlc2lzXHJcbiAgICAgICAgICB2YXIgc2NlbmFyaW8gPSByYXdfYXJyW2ldLnNwbGl0KC8sXFxzP1xcKC8pO1xyXG5cclxuICAgICAgICAgIGlmIChzY2VuYXJpby5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSB0aGlzLnBhcnNlX3NjZW5hcmlvKHNjZW5hcmlvKTtcclxuICAgICAgICAgICAgc2NlbmFyaW9zLnB1c2gocGFyYW1zKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzLnN0b3JlKGVsLCBzY2VuYXJpb3MpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzdG9yZSA6IGZ1bmN0aW9uIChlbCwgc2NlbmFyaW9zKSB7XHJcbiAgICAgIHZhciB1dWlkID0gdGhpcy5yYW5kb21fc3RyKCksXHJcbiAgICAgICAgICBjdXJyZW50X3V1aWQgPSBlbC5kYXRhKHRoaXMuYWRkX25hbWVzcGFjZSgndXVpZCcsIHRydWUpKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmNhY2hlW2N1cnJlbnRfdXVpZF0pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVtjdXJyZW50X3V1aWRdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbC5hdHRyKHRoaXMuYWRkX25hbWVzcGFjZSgnZGF0YS11dWlkJyksIHV1aWQpO1xyXG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVt1dWlkXSA9IHNjZW5hcmlvcztcclxuICAgIH0sXHJcblxyXG4gICAgdHJpbSA6IGZ1bmN0aW9uIChzdHIpIHtcclxuXHJcbiAgICAgIGlmICh0eXBlb2Ygc3RyID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHJldHVybiAkLnRyaW0oc3RyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHN0cjtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0X2RhdGFfYXR0ciA6IGZ1bmN0aW9uIChpbml0KSB7XHJcbiAgICAgIGlmIChpbml0KSB7XHJcbiAgICAgICAgaWYgKHRoaXMubmFtZXNwYWNlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLm5hbWVzcGFjZSArICctJyArIHRoaXMuc2V0dGluZ3MubG9hZF9hdHRyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3MubG9hZF9hdHRyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5uYW1lc3BhY2UubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHJldHVybiAnZGF0YS0nICsgdGhpcy5uYW1lc3BhY2UgKyAnLScgKyB0aGlzLnNldHRpbmdzLmxvYWRfYXR0cjtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuICdkYXRhLScgKyB0aGlzLnNldHRpbmdzLmxvYWRfYXR0cjtcclxuICAgIH0sXHJcblxyXG4gICAgcGFyc2VfZGF0YV9hdHRyIDogZnVuY3Rpb24gKGVsKSB7XHJcbiAgICAgIHZhciByYXcgPSBlbC5hdHRyKHRoaXMuYXR0cl9uYW1lKCkpLnNwbGl0KC9cXFsoLio/KVxcXS8pLFxyXG4gICAgICAgICAgaSA9IHJhdy5sZW5ndGgsXHJcbiAgICAgICAgICBvdXRwdXQgPSBbXTtcclxuXHJcbiAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICBpZiAocmF3W2ldLnJlcGxhY2UoL1tcXFdcXGRdKy8sICcnKS5sZW5ndGggPiA0KSB7XHJcbiAgICAgICAgICBvdXRwdXQucHVzaChyYXdbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB0aGlzLmxvYWQoJ2ltYWdlcycsIHRydWUpO1xyXG4gICAgICB0aGlzLmxvYWQoJ25vZGVzJywgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gIH07XHJcblxyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIE1vZGVybml6ciA9IE1vZGVybml6ciB8fCBmYWxzZTtcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLmpveXJpZGUgPSB7XHJcbiAgICBuYW1lIDogJ2pveXJpZGUnLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIGRlZmF1bHRzIDoge1xyXG4gICAgICBleHBvc2UgICAgICAgICAgICAgICAgICAgOiBmYWxzZSwgICAgIC8vIHR1cm4gb24gb3Igb2ZmIHRoZSBleHBvc2UgZmVhdHVyZVxyXG4gICAgICBtb2RhbCAgICAgICAgICAgICAgICAgICAgOiB0cnVlLCAgICAgIC8vIFdoZXRoZXIgdG8gY292ZXIgcGFnZSB3aXRoIG1vZGFsIGR1cmluZyB0aGUgdG91clxyXG4gICAgICBrZXlib2FyZCAgICAgICAgICAgICAgICAgOiB0cnVlLCAgICAgIC8vIGVuYWJsZSBsZWZ0LCByaWdodCBhbmQgZXNjIGtleXN0cm9rZXNcclxuICAgICAgdGlwX2xvY2F0aW9uICAgICAgICAgICAgIDogJ2JvdHRvbScsICAvLyAndG9wJywgJ2JvdHRvbScsICdsZWZ0JyBvciAncmlnaHQnIGluIHJlbGF0aW9uIHRvIHBhcmVudFxyXG4gICAgICBudWJfcG9zaXRpb24gICAgICAgICAgICAgOiAnYXV0bycsICAgIC8vIG92ZXJyaWRlIG9uIGEgcGVyIHRvb2x0aXAgYmFzZXNcclxuICAgICAgc2Nyb2xsX3NwZWVkICAgICAgICAgICAgIDogMTUwMCwgICAgICAvLyBQYWdlIHNjcm9sbGluZyBzcGVlZCBpbiBtaWxsaXNlY29uZHMsIDAgPSBubyBzY3JvbGwgYW5pbWF0aW9uXHJcbiAgICAgIHNjcm9sbF9hbmltYXRpb24gICAgICAgICA6ICdsaW5lYXInLCAgLy8gc3VwcG9ydHMgJ3N3aW5nJyBhbmQgJ2xpbmVhcicsIGV4dGVuZCB3aXRoIGpRdWVyeSBVSS5cclxuICAgICAgdGltZXIgICAgICAgICAgICAgICAgICAgIDogMCwgICAgICAgICAvLyAwID0gbm8gdGltZXIgLCBhbGwgb3RoZXIgbnVtYmVycyA9IHRpbWVyIGluIG1pbGxpc2Vjb25kc1xyXG4gICAgICBzdGFydF90aW1lcl9vbl9jbGljayAgICAgOiB0cnVlLCAgICAgIC8vIHRydWUgb3IgZmFsc2UgLSB0cnVlIHJlcXVpcmVzIGNsaWNraW5nIHRoZSBmaXJzdCBidXR0b24gc3RhcnQgdGhlIHRpbWVyXHJcbiAgICAgIHN0YXJ0X29mZnNldCAgICAgICAgICAgICA6IDAsICAgICAgICAgLy8gdGhlIGluZGV4IG9mIHRoZSB0b29sdGlwIHlvdSB3YW50IHRvIHN0YXJ0IG9uIChpbmRleCBvZiB0aGUgbGkpXHJcbiAgICAgIG5leHRfYnV0dG9uICAgICAgICAgICAgICA6IHRydWUsICAgICAgLy8gdHJ1ZSBvciBmYWxzZSB0byBjb250cm9sIHdoZXRoZXIgYSBuZXh0IGJ1dHRvbiBpcyB1c2VkXHJcbiAgICAgIHByZXZfYnV0dG9uICAgICAgICAgICAgICA6IHRydWUsICAgICAgLy8gdHJ1ZSBvciBmYWxzZSB0byBjb250cm9sIHdoZXRoZXIgYSBwcmV2IGJ1dHRvbiBpcyB1c2VkXHJcbiAgICAgIHRpcF9hbmltYXRpb24gICAgICAgICAgICA6ICdmYWRlJywgICAgLy8gJ3BvcCcgb3IgJ2ZhZGUnIGluIGVhY2ggdGlwXHJcbiAgICAgIHBhdXNlX2FmdGVyICAgICAgICAgICAgICA6IFtdLCAgICAgICAgLy8gYXJyYXkgb2YgaW5kZXhlcyB3aGVyZSB0byBwYXVzZSB0aGUgdG91ciBhZnRlclxyXG4gICAgICBleHBvc2VkICAgICAgICAgICAgICAgICAgOiBbXSwgICAgICAgIC8vIGFycmF5IG9mIGV4cG9zZSBlbGVtZW50c1xyXG4gICAgICB0aXBfYW5pbWF0aW9uX2ZhZGVfc3BlZWQgOiAzMDAsICAgICAgIC8vIHdoZW4gdGlwQW5pbWF0aW9uID0gJ2ZhZGUnIHRoaXMgaXMgc3BlZWQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgdHJhbnNpdGlvblxyXG4gICAgICBjb29raWVfbW9uc3RlciAgICAgICAgICAgOiBmYWxzZSwgICAgIC8vIHRydWUgb3IgZmFsc2UgdG8gY29udHJvbCB3aGV0aGVyIGNvb2tpZXMgYXJlIHVzZWRcclxuICAgICAgY29va2llX25hbWUgICAgICAgICAgICAgIDogJ2pveXJpZGUnLCAvLyBOYW1lIHRoZSBjb29raWUgeW91J2xsIHVzZVxyXG4gICAgICBjb29raWVfZG9tYWluICAgICAgICAgICAgOiBmYWxzZSwgICAgIC8vIFdpbGwgdGhpcyBjb29raWUgYmUgYXR0YWNoZWQgdG8gYSBkb21haW4sIGllLiAnLm5vdGFibGVhcHAuY29tJ1xyXG4gICAgICBjb29raWVfZXhwaXJlcyAgICAgICAgICAgOiAzNjUsICAgICAgIC8vIHNldCB3aGVuIHlvdSB3b3VsZCBsaWtlIHRoZSBjb29raWUgdG8gZXhwaXJlLlxyXG4gICAgICB0aXBfY29udGFpbmVyICAgICAgICAgICAgOiAnYm9keScsICAgIC8vIFdoZXJlIHdpbGwgdGhlIHRpcCBiZSBhdHRhY2hlZFxyXG4gICAgICBhYm9ydF9vbl9jbG9zZSAgICAgICAgICAgOiB0cnVlLCAgICAgIC8vIFdoZW4gdHJ1ZSwgdGhlIGNsb3NlIGV2ZW50IHdpbGwgbm90IGZpcmUgYW55IGNhbGxiYWNrXHJcbiAgICAgIHRpcF9sb2NhdGlvbl9wYXR0ZXJucyAgICA6IHtcclxuICAgICAgICB0b3AgOiBbJ2JvdHRvbSddLFxyXG4gICAgICAgIGJvdHRvbSA6IFtdLCAvLyBib3R0b20gc2hvdWxkIG5vdCBuZWVkIHRvIGJlIHJlcG9zaXRpb25lZFxyXG4gICAgICAgIGxlZnQgOiBbJ3JpZ2h0JywgJ3RvcCcsICdib3R0b20nXSxcclxuICAgICAgICByaWdodCA6IFsnbGVmdCcsICd0b3AnLCAnYm90dG9tJ11cclxuICAgICAgfSxcclxuICAgICAgcG9zdF9yaWRlX2NhbGxiYWNrICAgICA6IGZ1bmN0aW9uICgpIHt9LCAgICAvLyBBIG1ldGhvZCB0byBjYWxsIG9uY2UgdGhlIHRvdXIgY2xvc2VzIChjYW5jZWxlZCBvciBjb21wbGV0ZSlcclxuICAgICAgcG9zdF9zdGVwX2NhbGxiYWNrICAgICA6IGZ1bmN0aW9uICgpIHt9LCAgICAvLyBBIG1ldGhvZCB0byBjYWxsIGFmdGVyIGVhY2ggc3RlcFxyXG4gICAgICBwcmVfc3RlcF9jYWxsYmFjayAgICAgIDogZnVuY3Rpb24gKCkge30sICAgIC8vIEEgbWV0aG9kIHRvIGNhbGwgYmVmb3JlIGVhY2ggc3RlcFxyXG4gICAgICBwcmVfcmlkZV9jYWxsYmFjayAgICAgIDogZnVuY3Rpb24gKCkge30sICAgIC8vIEEgbWV0aG9kIHRvIGNhbGwgYmVmb3JlIHRoZSB0b3VyIHN0YXJ0cyAocGFzc2VkIGluZGV4LCB0aXAsIGFuZCBjbG9uZWQgZXhwb3NlZCBlbGVtZW50KVxyXG4gICAgICBwb3N0X2V4cG9zZV9jYWxsYmFjayAgIDogZnVuY3Rpb24gKCkge30sICAgIC8vIEEgbWV0aG9kIHRvIGNhbGwgYWZ0ZXIgYW4gZWxlbWVudCBoYXMgYmVlbiBleHBvc2VkXHJcbiAgICAgIHRlbXBsYXRlIDogeyAvLyBIVE1MIHNlZ21lbnRzIGZvciB0aXAgbGF5b3V0XHJcbiAgICAgICAgbGluayAgICAgICAgICA6ICc8YSBocmVmPVwiI2Nsb3NlXCIgY2xhc3M9XCJqb3lyaWRlLWNsb3NlLXRpcFwiPiZ0aW1lczs8L2E+JyxcclxuICAgICAgICB0aW1lciAgICAgICAgIDogJzxkaXYgY2xhc3M9XCJqb3lyaWRlLXRpbWVyLWluZGljYXRvci13cmFwXCI+PHNwYW4gY2xhc3M9XCJqb3lyaWRlLXRpbWVyLWluZGljYXRvclwiPjwvc3Bhbj48L2Rpdj4nLFxyXG4gICAgICAgIHRpcCAgICAgICAgICAgOiAnPGRpdiBjbGFzcz1cImpveXJpZGUtdGlwLWd1aWRlXCI+PHNwYW4gY2xhc3M9XCJqb3lyaWRlLW51YlwiPjwvc3Bhbj48L2Rpdj4nLFxyXG4gICAgICAgIHdyYXBwZXIgICAgICAgOiAnPGRpdiBjbGFzcz1cImpveXJpZGUtY29udGVudC13cmFwcGVyXCI+PC9kaXY+JyxcclxuICAgICAgICBidXR0b24gICAgICAgIDogJzxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzbWFsbCBidXR0b24gam95cmlkZS1uZXh0LXRpcFwiPjwvYT4nLFxyXG4gICAgICAgIHByZXZfYnV0dG9uICAgOiAnPGEgaHJlZj1cIiNcIiBjbGFzcz1cInNtYWxsIGJ1dHRvbiBqb3lyaWRlLXByZXYtdGlwXCI+PC9hPicsXHJcbiAgICAgICAgbW9kYWwgICAgICAgICA6ICc8ZGl2IGNsYXNzPVwiam95cmlkZS1tb2RhbC1iZ1wiPjwvZGl2PicsXHJcbiAgICAgICAgZXhwb3NlICAgICAgICA6ICc8ZGl2IGNsYXNzPVwiam95cmlkZS1leHBvc2Utd3JhcHBlclwiPjwvZGl2PicsXHJcbiAgICAgICAgZXhwb3NlX2NvdmVyICA6ICc8ZGl2IGNsYXNzPVwiam95cmlkZS1leHBvc2UtY292ZXJcIj48L2Rpdj4nXHJcbiAgICAgIH0sXHJcbiAgICAgIGV4cG9zZV9hZGRfY2xhc3MgOiAnJyAvLyBPbmUgb3IgbW9yZSBzcGFjZS1zZXBhcmF0ZWQgY2xhc3MgbmFtZXMgdG8gYmUgYWRkZWQgdG8gZXhwb3NlZCBlbGVtZW50XHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICBGb3VuZGF0aW9uLmluaGVyaXQodGhpcywgJ3Rocm90dGxlIHJhbmRvbV9zdHInKTtcclxuXHJcbiAgICAgIHRoaXMuc2V0dGluZ3MgPSB0aGlzLnNldHRpbmdzIHx8ICQuZXh0ZW5kKHt9LCB0aGlzLmRlZmF1bHRzLCAob3B0aW9ucyB8fCBtZXRob2QpKTtcclxuXHJcbiAgICAgIHRoaXMuYmluZGluZ3MobWV0aG9kLCBvcHRpb25zKVxyXG4gICAgfSxcclxuXHJcbiAgICBnb19uZXh0IDogZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy4kbGkubmV4dCgpLmxlbmd0aCA8IDEpIHtcclxuICAgICAgICB0aGlzLmVuZCgpO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2V0dGluZ3MudGltZXIgPiAwKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuc2V0dGluZ3MuYXV0b21hdGUpO1xyXG4gICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgICAgIHRoaXMuc3RhcnRUaW1lcigpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGdvX3ByZXYgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLiRsaS5wcmV2KCkubGVuZ3RoIDwgMSkge1xyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgdGhlcmUgYXJlIG5vIHByZXYgZWxlbWVudFxyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2V0dGluZ3MudGltZXIgPiAwKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuc2V0dGluZ3MuYXV0b21hdGUpO1xyXG4gICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICAgIHRoaXMuc2hvdyhudWxsLCB0cnVlKTtcclxuICAgICAgICB0aGlzLnN0YXJ0VGltZXIoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgICB0aGlzLnNob3cobnVsbCwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgZXZlbnRzIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAkKHRoaXMuc2NvcGUpXHJcbiAgICAgICAgLm9mZignLmpveXJpZGUnKVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4uam95cmlkZScsICcuam95cmlkZS1uZXh0LXRpcCwgLmpveXJpZGUtbW9kYWwtYmcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgdGhpcy5nb19uZXh0KClcclxuICAgICAgICB9LmJpbmQodGhpcykpXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5qb3lyaWRlJywgJy5qb3lyaWRlLXByZXYtdGlwJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIHRoaXMuZ29fcHJldigpO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSlcclxuXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5qb3lyaWRlJywgJy5qb3lyaWRlLWNsb3NlLXRpcCcsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICB0aGlzLmVuZCh0aGlzLnNldHRpbmdzLmFib3J0X29uX2Nsb3NlKTtcclxuICAgICAgICB9LmJpbmQodGhpcykpXHJcblxyXG4gICAgICAgIC5vbigna2V5dXAuZm5kdG4uam95cmlkZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBrZXlzdHJva2VzIGFyZSBkaXNhYmxlZFxyXG4gICAgICAgICAgLy8gb3IgaWYgdGhlIGpveXJpZGUgaXMgbm90IGJlaW5nIHNob3duXHJcbiAgICAgICAgICBpZiAoIXRoaXMuc2V0dGluZ3Mua2V5Ym9hcmQgfHwgIXRoaXMuc2V0dGluZ3MucmlkaW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzd2l0Y2ggKGUud2hpY2gpIHtcclxuICAgICAgICAgICAgY2FzZSAzOTogLy8gcmlnaHQgYXJyb3dcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5nb19uZXh0KCk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzc6IC8vIGxlZnQgYXJyb3dcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5nb19wcmV2KCk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMjc6IC8vIGVzY2FwZVxyXG4gICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICB0aGlzLmVuZCh0aGlzLnNldHRpbmdzLmFib3J0X29uX2Nsb3NlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG5cclxuICAgICAgJCh3aW5kb3cpXHJcbiAgICAgICAgLm9mZignLmpveXJpZGUnKVxyXG4gICAgICAgIC5vbigncmVzaXplLmZuZHRuLmpveXJpZGUnLCBzZWxmLnRocm90dGxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGlmICgkKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLmxlbmd0aCA+IDAgJiYgc2VsZi5zZXR0aW5ncy4kbmV4dF90aXAgJiYgc2VsZi5zZXR0aW5ncy5yaWRpbmcpIHtcclxuICAgICAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3MuZXhwb3NlZC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgdmFyICRlbHMgPSAkKHNlbGYuc2V0dGluZ3MuZXhwb3NlZCk7XHJcblxyXG4gICAgICAgICAgICAgICRlbHMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgc2VsZi51bl9leHBvc2UoJHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgc2VsZi5leHBvc2UoJHRoaXMpO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZi5pc19waG9uZSgpKSB7XHJcbiAgICAgICAgICAgICAgc2VsZi5wb3NfcGhvbmUoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBzZWxmLnBvc19kZWZhdWx0KGZhbHNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sIDEwMCkpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzdGFydCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgJHRoaXMgPSAkKCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMuc2NvcGUpLFxyXG4gICAgICAgICAgaW50ZWdlcl9zZXR0aW5ncyA9IFsndGltZXInLCAnc2Nyb2xsU3BlZWQnLCAnc3RhcnRPZmZzZXQnLCAndGlwQW5pbWF0aW9uRmFkZVNwZWVkJywgJ2Nvb2tpZUV4cGlyZXMnXSxcclxuICAgICAgICAgIGludF9zZXR0aW5nc19jb3VudCA9IGludGVnZXJfc2V0dGluZ3MubGVuZ3RoO1xyXG5cclxuICAgICAgaWYgKCEkdGhpcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIXRoaXMuc2V0dGluZ3MuaW5pdCkge1xyXG4gICAgICAgIHRoaXMuZXZlbnRzKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuc2V0dGluZ3MgPSAkdGhpcy5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0Jyk7XHJcblxyXG4gICAgICAvLyBub24gY29uZmlndXJlYWJsZSBzZXR0aW5nc1xyXG4gICAgICB0aGlzLnNldHRpbmdzLiRjb250ZW50X2VsID0gJHRoaXM7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuJGJvZHkgPSAkKHRoaXMuc2V0dGluZ3MudGlwX2NvbnRhaW5lcik7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuYm9keV9vZmZzZXQgPSAkKHRoaXMuc2V0dGluZ3MudGlwX2NvbnRhaW5lcikucG9zaXRpb24oKTtcclxuICAgICAgdGhpcy5zZXR0aW5ncy4kdGlwX2NvbnRlbnQgPSB0aGlzLnNldHRpbmdzLiRjb250ZW50X2VsLmZpbmQoJz4gbGknKTtcclxuICAgICAgdGhpcy5zZXR0aW5ncy5wYXVzZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5zZXR0aW5ncy5hdHRlbXB0cyA9IDA7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MucmlkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgIC8vIGNhbiB3ZSBjcmVhdGUgY29va2llcz9cclxuICAgICAgaWYgKHR5cGVvZiAkLmNvb2tpZSAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuY29va2llX21vbnN0ZXIgPSBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gZ2VuZXJhdGUgdGhlIHRpcHMgYW5kIGluc2VydCBpbnRvIGRvbS5cclxuICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmNvb2tpZV9tb25zdGVyIHx8IHRoaXMuc2V0dGluZ3MuY29va2llX21vbnN0ZXIgJiYgISQuY29va2llKHRoaXMuc2V0dGluZ3MuY29va2llX25hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kdGlwX2NvbnRlbnQuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcyk7XHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzID0gJC5leHRlbmQoe30sIHNlbGYuZGVmYXVsdHMsIHNlbGYuZGF0YV9vcHRpb25zKCR0aGlzKSk7XHJcblxyXG4gICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgc2V0dGluZ3MgcGFyc2VkIGZyb20gZGF0YV9vcHRpb25zIGFyZSBpbnRlZ2VycyB3aGVyZSBuZWNlc3NhcnlcclxuICAgICAgICAgIHZhciBpID0gaW50X3NldHRpbmdzX2NvdW50O1xyXG4gICAgICAgICAgd2hpbGUgKGktLSkge1xyXG4gICAgICAgICAgICBzZWxmLnNldHRpbmdzW2ludGVnZXJfc2V0dGluZ3NbaV1dID0gcGFyc2VJbnQoc2VsZi5zZXR0aW5nc1tpbnRlZ2VyX3NldHRpbmdzW2ldXSwgMTApO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc2VsZi5jcmVhdGUoeyRsaSA6ICR0aGlzLCBpbmRleCA6IGluZGV4fSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIHNob3cgZmlyc3QgdGlwXHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLnN0YXJ0X3RpbWVyX29uX2NsaWNrICYmIHRoaXMuc2V0dGluZ3MudGltZXIgPiAwKSB7XHJcbiAgICAgICAgICB0aGlzLnNob3coJ2luaXQnKTtcclxuICAgICAgICAgIHRoaXMuc3RhcnRUaW1lcigpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLnNob3coJ2luaXQnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHJlc3VtZSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5zZXRfbGkoKTtcclxuICAgICAgdGhpcy5zaG93KCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHRpcF90ZW1wbGF0ZSA6IGZ1bmN0aW9uIChvcHRzKSB7XHJcbiAgICAgIHZhciAkYmxhbmssIGNvbnRlbnQ7XHJcblxyXG4gICAgICBvcHRzLnRpcF9jbGFzcyA9IG9wdHMudGlwX2NsYXNzIHx8ICcnO1xyXG5cclxuICAgICAgJGJsYW5rID0gJCh0aGlzLnNldHRpbmdzLnRlbXBsYXRlLnRpcCkuYWRkQ2xhc3Mob3B0cy50aXBfY2xhc3MpO1xyXG4gICAgICBjb250ZW50ID0gJC50cmltKCQob3B0cy5saSkuaHRtbCgpKSArXHJcbiAgICAgICAgdGhpcy5wcmV2X2J1dHRvbl90ZXh0KG9wdHMucHJldl9idXR0b25fdGV4dCwgb3B0cy5pbmRleCkgK1xyXG4gICAgICAgIHRoaXMuYnV0dG9uX3RleHQob3B0cy5idXR0b25fdGV4dCkgK1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MudGVtcGxhdGUubGluayArXHJcbiAgICAgICAgdGhpcy50aW1lcl9pbnN0YW5jZShvcHRzLmluZGV4KTtcclxuXHJcbiAgICAgICRibGFuay5hcHBlbmQoJCh0aGlzLnNldHRpbmdzLnRlbXBsYXRlLndyYXBwZXIpKTtcclxuICAgICAgJGJsYW5rLmZpcnN0KCkuYXR0cih0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtaW5kZXgnKSwgb3B0cy5pbmRleCk7XHJcbiAgICAgICQoJy5qb3lyaWRlLWNvbnRlbnQtd3JhcHBlcicsICRibGFuaykuYXBwZW5kKGNvbnRlbnQpO1xyXG5cclxuICAgICAgcmV0dXJuICRibGFua1swXTtcclxuICAgIH0sXHJcblxyXG4gICAgdGltZXJfaW5zdGFuY2UgOiBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgdmFyIHR4dDtcclxuXHJcbiAgICAgIGlmICgoaW5kZXggPT09IDAgJiYgdGhpcy5zZXR0aW5ncy5zdGFydF90aW1lcl9vbl9jbGljayAmJiB0aGlzLnNldHRpbmdzLnRpbWVyID4gMCkgfHwgdGhpcy5zZXR0aW5ncy50aW1lciA9PT0gMCkge1xyXG4gICAgICAgIHR4dCA9ICcnO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHR4dCA9ICQodGhpcy5zZXR0aW5ncy50ZW1wbGF0ZS50aW1lcilbMF0ub3V0ZXJIVE1MO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB0eHQ7XHJcbiAgICB9LFxyXG5cclxuICAgIGJ1dHRvbl90ZXh0IDogZnVuY3Rpb24gKHR4dCkge1xyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MubmV4dF9idXR0b24pIHtcclxuICAgICAgICB0eHQgPSAkLnRyaW0odHh0KSB8fCAnTmV4dCc7XHJcbiAgICAgICAgdHh0ID0gJCh0aGlzLnNldHRpbmdzLnRlbXBsYXRlLmJ1dHRvbikuYXBwZW5kKHR4dClbMF0ub3V0ZXJIVE1MO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHR4dCA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB0eHQ7XHJcbiAgICB9LFxyXG5cclxuICAgIHByZXZfYnV0dG9uX3RleHQgOiBmdW5jdGlvbiAodHh0LCBpZHgpIHtcclxuICAgICAgaWYgKHRoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzLnByZXZfYnV0dG9uKSB7XHJcbiAgICAgICAgdHh0ID0gJC50cmltKHR4dCkgfHwgJ1ByZXZpb3VzJztcclxuXHJcbiAgICAgICAgLy8gQWRkIHRoZSBkaXNhYmxlZCBjbGFzcyB0byB0aGUgYnV0dG9uIGlmIGl0J3MgdGhlIGZpcnN0IGVsZW1lbnRcclxuICAgICAgICBpZiAoaWR4ID09IDApIHtcclxuICAgICAgICAgIHR4dCA9ICQodGhpcy5zZXR0aW5ncy50ZW1wbGF0ZS5wcmV2X2J1dHRvbikuYXBwZW5kKHR4dCkuYWRkQ2xhc3MoJ2Rpc2FibGVkJylbMF0ub3V0ZXJIVE1MO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0eHQgPSAkKHRoaXMuc2V0dGluZ3MudGVtcGxhdGUucHJldl9idXR0b24pLmFwcGVuZCh0eHQpWzBdLm91dGVySFRNTDtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdHh0ID0gJyc7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHR4dDtcclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlIDogZnVuY3Rpb24gKG9wdHMpIHtcclxuICAgICAgdGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgdGhpcy5zZXR0aW5ncywgdGhpcy5kYXRhX29wdGlvbnMob3B0cy4kbGkpKTtcclxuICAgICAgdmFyIGJ1dHRvblRleHQgPSBvcHRzLiRsaS5hdHRyKHRoaXMuYWRkX25hbWVzcGFjZSgnZGF0YS1idXR0b24nKSkgfHwgb3B0cy4kbGkuYXR0cih0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtdGV4dCcpKSxcclxuICAgICAgICAgIHByZXZCdXR0b25UZXh0ID0gb3B0cy4kbGkuYXR0cih0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtYnV0dG9uLXByZXYnKSkgfHwgb3B0cy4kbGkuYXR0cih0aGlzLmFkZF9uYW1lc3BhY2UoJ2RhdGEtcHJldi10ZXh0JykpLFxyXG4gICAgICAgIHRpcENsYXNzID0gb3B0cy4kbGkuYXR0cignY2xhc3MnKSxcclxuICAgICAgICAkdGlwX2NvbnRlbnQgPSAkKHRoaXMudGlwX3RlbXBsYXRlKHtcclxuICAgICAgICAgIHRpcF9jbGFzcyA6IHRpcENsYXNzLFxyXG4gICAgICAgICAgaW5kZXggOiBvcHRzLmluZGV4LFxyXG4gICAgICAgICAgYnV0dG9uX3RleHQgOiBidXR0b25UZXh0LFxyXG4gICAgICAgICAgcHJldl9idXR0b25fdGV4dCA6IHByZXZCdXR0b25UZXh0LFxyXG4gICAgICAgICAgbGkgOiBvcHRzLiRsaVxyXG4gICAgICAgIH0pKTtcclxuXHJcbiAgICAgICQodGhpcy5zZXR0aW5ncy50aXBfY29udGFpbmVyKS5hcHBlbmQoJHRpcF9jb250ZW50KTtcclxuICAgIH0sXHJcblxyXG4gICAgc2hvdyA6IGZ1bmN0aW9uIChpbml0LCBpc19wcmV2KSB7XHJcbiAgICAgIHZhciAkdGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgLy8gYXJlIHdlIHBhdXNlZD9cclxuICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuJGxpID09PSB1bmRlZmluZWQgfHwgKCQuaW5BcnJheSh0aGlzLnNldHRpbmdzLiRsaS5pbmRleCgpLCB0aGlzLnNldHRpbmdzLnBhdXNlX2FmdGVyKSA9PT0gLTEpKSB7XHJcblxyXG4gICAgICAgIC8vIGRvbid0IGdvIHRvIHRoZSBuZXh0IGxpIGlmIHRoZSB0b3VyIHdhcyBwYXVzZWRcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5wYXVzZWQpIHtcclxuICAgICAgICAgIHRoaXMuc2V0dGluZ3MucGF1c2VkID0gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2V0X2xpKGluaXQsIGlzX3ByZXYpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5hdHRlbXB0cyA9IDA7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLiRsaS5sZW5ndGggJiYgdGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGlmIChpbml0KSB7IC8vcnVuIHdoZW4gd2UgZmlyc3Qgc3RhcnRcclxuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy5wcmVfcmlkZV9jYWxsYmFjayh0aGlzLnNldHRpbmdzLiRsaS5pbmRleCgpLCB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcCk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLm1vZGFsKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zaG93X21vZGFsKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLnByZV9zdGVwX2NhbGxiYWNrKHRoaXMuc2V0dGluZ3MuJGxpLmluZGV4KCksIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwKTtcclxuXHJcbiAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb2RhbCAmJiB0aGlzLnNldHRpbmdzLmV4cG9zZSkge1xyXG4gICAgICAgICAgICB0aGlzLmV4cG9zZSgpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHRoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzID0gJC5leHRlbmQoe30sIHRoaXMuc2V0dGluZ3MsIHRoaXMuZGF0YV9vcHRpb25zKHRoaXMuc2V0dGluZ3MuJGxpKSk7XHJcblxyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy50aW1lciA9IHBhcnNlSW50KHRoaXMuc2V0dGluZ3MudGltZXIsIDEwKTtcclxuXHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy50aXBfbG9jYXRpb25fcGF0dGVybiA9IHRoaXMuc2V0dGluZ3MudGlwX2xvY2F0aW9uX3BhdHRlcm5zW3RoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzLnRpcF9sb2NhdGlvbl07XHJcblxyXG4gICAgICAgICAgLy8gc2Nyb2xsIGFuZCBoaWRlIGJnIGlmIG5vdCBtb2RhbCBhbmQgbm90IGV4cG9zZVxyXG4gICAgICAgICAgaWYgKCEvYm9keS9pLnRlc3QodGhpcy5zZXR0aW5ncy4kdGFyZ2V0LnNlbGVjdG9yKSAmJiAhdGhpcy5zZXR0aW5ncy5leHBvc2UpIHtcclxuICAgICAgICAgICAgdmFyIGpveXJpZGVtb2RhbGJnID0gJCgnLmpveXJpZGUtbW9kYWwtYmcnKTtcclxuICAgICAgICAgICAgaWYgKC9wb3AvaS50ZXN0KHRoaXMuc2V0dGluZ3MudGlwQW5pbWF0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgam95cmlkZW1vZGFsYmcuaGlkZSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgam95cmlkZW1vZGFsYmcuZmFkZU91dCh0aGlzLnNldHRpbmdzLnRpcEFuaW1hdGlvbkZhZGVTcGVlZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5zY3JvbGxfdG8oKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAodGhpcy5pc19waG9uZSgpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucG9zX3Bob25lKHRydWUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5wb3NfZGVmYXVsdCh0cnVlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAkdGltZXIgPSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5maW5kKCcuam95cmlkZS10aW1lci1pbmRpY2F0b3InKTtcclxuXHJcbiAgICAgICAgICBpZiAoL3BvcC9pLnRlc3QodGhpcy5zZXR0aW5ncy50aXBfYW5pbWF0aW9uKSkge1xyXG5cclxuICAgICAgICAgICAgJHRpbWVyLndpZHRoKDApO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MudGltZXIgPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLnNob3coKTtcclxuXHJcbiAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAkdGltZXIuYW5pbWF0ZSh7XHJcbiAgICAgICAgICAgICAgICAgIHdpZHRoIDogJHRpbWVyLnBhcmVudCgpLndpZHRoKClcclxuICAgICAgICAgICAgICAgIH0sIHRoaXMuc2V0dGluZ3MudGltZXIsICdsaW5lYXInKTtcclxuICAgICAgICAgICAgICB9LmJpbmQodGhpcyksIHRoaXMuc2V0dGluZ3MudGlwX2FuaW1hdGlvbl9mYWRlX3NwZWVkKTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuc2hvdygpO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIH0gZWxzZSBpZiAoL2ZhZGUvaS50ZXN0KHRoaXMuc2V0dGluZ3MudGlwX2FuaW1hdGlvbikpIHtcclxuXHJcbiAgICAgICAgICAgICR0aW1lci53aWR0aCgwKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLnRpbWVyID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcFxyXG4gICAgICAgICAgICAgICAgLmZhZGVJbih0aGlzLnNldHRpbmdzLnRpcF9hbmltYXRpb25fZmFkZV9zcGVlZClcclxuICAgICAgICAgICAgICAgIC5zaG93KCk7XHJcblxyXG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgJHRpbWVyLmFuaW1hdGUoe1xyXG4gICAgICAgICAgICAgICAgICB3aWR0aCA6ICR0aW1lci5wYXJlbnQoKS53aWR0aCgpXHJcbiAgICAgICAgICAgICAgICB9LCB0aGlzLnNldHRpbmdzLnRpbWVyLCAnbGluZWFyJyk7XHJcbiAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCB0aGlzLnNldHRpbmdzLnRpcF9hbmltYXRpb25fZmFkZV9zcGVlZCk7XHJcblxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmZhZGVJbih0aGlzLnNldHRpbmdzLnRpcF9hbmltYXRpb25fZmFkZV9zcGVlZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLiRjdXJyZW50X3RpcCA9IHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwO1xyXG5cclxuICAgICAgICAvLyBza2lwIG5vbi1leGlzdGFudCB0YXJnZXRzXHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLiRsaSAmJiB0aGlzLnNldHRpbmdzLiR0YXJnZXQubGVuZ3RoIDwgMSkge1xyXG5cclxuICAgICAgICAgIHRoaXMuc2hvdyhpbml0LCBpc19wcmV2KTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICB0aGlzLmVuZCgpO1xyXG5cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MucGF1c2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgIH1cclxuXHJcbiAgICB9LFxyXG5cclxuICAgIGlzX3Bob25lIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gbWF0Y2hNZWRpYShGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXMuc21hbGwpLm1hdGNoZXMgJiZcclxuICAgICAgICAhbWF0Y2hNZWRpYShGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXMubWVkaXVtKS5tYXRjaGVzO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRlIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb2RhbCAmJiB0aGlzLnNldHRpbmdzLmV4cG9zZSkge1xyXG4gICAgICAgIHRoaXMudW5fZXhwb3NlKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5tb2RhbCkge1xyXG4gICAgICAgICQoJy5qb3lyaWRlLW1vZGFsLWJnJykuaGlkZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBQcmV2ZW50IHNjcm9sbCBib3VuY2luZy4uLndhaXQgdG8gcmVtb3ZlIGZyb20gbGF5b3V0XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuJGN1cnJlbnRfdGlwLmNzcygndmlzaWJpbGl0eScsICdoaWRkZW4nKTtcclxuICAgICAgc2V0VGltZW91dCgkLnByb3h5KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgICB0aGlzLmNzcygndmlzaWJpbGl0eScsICd2aXNpYmxlJyk7XHJcbiAgICAgIH0sIHRoaXMuc2V0dGluZ3MuJGN1cnJlbnRfdGlwKSwgMCk7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MucG9zdF9zdGVwX2NhbGxiYWNrKHRoaXMuc2V0dGluZ3MuJGxpLmluZGV4KCksXHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kY3VycmVudF90aXApO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRfbGkgOiBmdW5jdGlvbiAoaW5pdCwgaXNfcHJldikge1xyXG4gICAgICBpZiAoaW5pdCkge1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuJGxpID0gdGhpcy5zZXR0aW5ncy4kdGlwX2NvbnRlbnQuZXEodGhpcy5zZXR0aW5ncy5zdGFydF9vZmZzZXQpO1xyXG4gICAgICAgIHRoaXMuc2V0X25leHRfdGlwKCk7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kY3VycmVudF90aXAgPSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoaXNfcHJldikge1xyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbGkgPSB0aGlzLnNldHRpbmdzLiRsaS5wcmV2KCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2V0dGluZ3MuJGxpID0gdGhpcy5zZXR0aW5ncy4kbGkubmV4dCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNldF9uZXh0X3RpcCgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnNldF90YXJnZXQoKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0X25leHRfdGlwIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcCA9ICQoJy5qb3lyaWRlLXRpcC1ndWlkZScpLmVxKHRoaXMuc2V0dGluZ3MuJGxpLmluZGV4KCkpO1xyXG4gICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5kYXRhKCdjbG9zZWQnLCAnJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldF90YXJnZXQgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBjbCA9IHRoaXMuc2V0dGluZ3MuJGxpLmF0dHIodGhpcy5hZGRfbmFtZXNwYWNlKCdkYXRhLWNsYXNzJykpLFxyXG4gICAgICAgICAgaWQgPSB0aGlzLnNldHRpbmdzLiRsaS5hdHRyKHRoaXMuYWRkX25hbWVzcGFjZSgnZGF0YS1pZCcpKSxcclxuICAgICAgICAgICRzZWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChpZCkge1xyXG4gICAgICAgICAgICAgIHJldHVybiAkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2wpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gJCgnLicgKyBjbCkuZmlyc3QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICByZXR1cm4gJCgnYm9keScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG5cclxuICAgICAgdGhpcy5zZXR0aW5ncy4kdGFyZ2V0ID0gJHNlbCgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzY3JvbGxfdG8gOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciB3aW5kb3dfaGFsZiwgdGlwT2Zmc2V0O1xyXG5cclxuICAgICAgd2luZG93X2hhbGYgPSAkKHdpbmRvdykuaGVpZ2h0KCkgLyAyO1xyXG4gICAgICB0aXBPZmZzZXQgPSBNYXRoLmNlaWwodGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLnRvcCAtIHdpbmRvd19oYWxmICsgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAub3V0ZXJIZWlnaHQoKSk7XHJcblxyXG4gICAgICBpZiAodGlwT2Zmc2V0ICE9IDApIHtcclxuICAgICAgICAkKCdodG1sLCBib2R5Jykuc3RvcCgpLmFuaW1hdGUoe1xyXG4gICAgICAgICAgc2Nyb2xsVG9wIDogdGlwT2Zmc2V0XHJcbiAgICAgICAgfSwgdGhpcy5zZXR0aW5ncy5zY3JvbGxfc3BlZWQsICdzd2luZycpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIHBhdXNlZCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuICgkLmluQXJyYXkoKHRoaXMuc2V0dGluZ3MuJGxpLmluZGV4KCkgKyAxKSwgdGhpcy5zZXR0aW5ncy5wYXVzZV9hZnRlcikgPT09IC0xKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVzdGFydCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5oaWRlKCk7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuJGxpID0gdW5kZWZpbmVkO1xyXG4gICAgICB0aGlzLnNob3coJ2luaXQnKTtcclxuICAgIH0sXHJcblxyXG4gICAgcG9zX2RlZmF1bHQgOiBmdW5jdGlvbiAoaW5pdCkge1xyXG4gICAgICB2YXIgJG51YiA9IHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmZpbmQoJy5qb3lyaWRlLW51YicpLFxyXG4gICAgICAgICAgbnViX3dpZHRoID0gTWF0aC5jZWlsKCRudWIub3V0ZXJXaWR0aCgpIC8gMiksXHJcbiAgICAgICAgICBudWJfaGVpZ2h0ID0gTWF0aC5jZWlsKCRudWIub3V0ZXJIZWlnaHQoKSAvIDIpLFxyXG4gICAgICAgICAgdG9nZ2xlID0gaW5pdCB8fCBmYWxzZTtcclxuXHJcbiAgICAgIC8vIHRpcCBtdXN0IG5vdCBiZSBcImRpc3BsYXk6IG5vbmVcIiB0byBjYWxjdWxhdGUgcG9zaXRpb25cclxuICAgICAgaWYgKHRvZ2dsZSkge1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmNzcygndmlzaWJpbGl0eScsICdoaWRkZW4nKTtcclxuICAgICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5zaG93KCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghL2JvZHkvaS50ZXN0KHRoaXMuc2V0dGluZ3MuJHRhcmdldC5zZWxlY3RvcikpIHtcclxuICAgICAgICB2YXIgdG9wQWRqdXN0bWVudCA9IHRoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzLnRpcEFkanVzdG1lbnRZID8gcGFyc2VJbnQodGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MudGlwQWRqdXN0bWVudFkpIDogMCxcclxuICAgICAgICAgICAgbGVmdEFkanVzdG1lbnQgPSB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy50aXBBZGp1c3RtZW50WCA/IHBhcnNlSW50KHRoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzLnRpcEFkanVzdG1lbnRYKSA6IDA7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmJvdHRvbSgpKSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5ydGwpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKHtcclxuICAgICAgICAgICAgICB0b3AgOiAodGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLnRvcCArIG51Yl9oZWlnaHQgKyB0aGlzLnNldHRpbmdzLiR0YXJnZXQub3V0ZXJIZWlnaHQoKSArIHRvcEFkanVzdG1lbnQpLFxyXG4gICAgICAgICAgICAgIGxlZnQgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkubGVmdCArIHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vdXRlcldpZHRoKCkgLSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlcldpZHRoKCkgKyBsZWZ0QWRqdXN0bWVudH0pO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKHtcclxuICAgICAgICAgICAgICB0b3AgOiAodGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLnRvcCArIG51Yl9oZWlnaHQgKyB0aGlzLnNldHRpbmdzLiR0YXJnZXQub3V0ZXJIZWlnaHQoKSArIHRvcEFkanVzdG1lbnQpLFxyXG4gICAgICAgICAgICAgIGxlZnQgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkubGVmdCArIGxlZnRBZGp1c3RtZW50fSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdGhpcy5udWJfcG9zaXRpb24oJG51YiwgdGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MubnViX3Bvc2l0aW9uLCAndG9wJyk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50b3AoKSkge1xyXG4gICAgICAgICAgaWYgKHRoaXMucnRsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmNzcyh7XHJcbiAgICAgICAgICAgICAgdG9wIDogKHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vZmZzZXQoKS50b3AgLSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlckhlaWdodCgpIC0gbnViX2hlaWdodCArIHRvcEFkanVzdG1lbnQpLFxyXG4gICAgICAgICAgICAgIGxlZnQgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkubGVmdCArIHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vdXRlcldpZHRoKCkgLSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlcldpZHRoKCl9KTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmNzcyh7XHJcbiAgICAgICAgICAgICAgdG9wIDogKHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vZmZzZXQoKS50b3AgLSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlckhlaWdodCgpIC0gbnViX2hlaWdodCArIHRvcEFkanVzdG1lbnQpLFxyXG4gICAgICAgICAgICAgIGxlZnQgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkubGVmdCArIGxlZnRBZGp1c3RtZW50fSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdGhpcy5udWJfcG9zaXRpb24oJG51YiwgdGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MubnViX3Bvc2l0aW9uLCAnYm90dG9tJyk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5yaWdodCgpKSB7XHJcblxyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKHtcclxuICAgICAgICAgICAgdG9wIDogdGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLnRvcCArIHRvcEFkanVzdG1lbnQsXHJcbiAgICAgICAgICAgIGxlZnQgOiAodGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm91dGVyV2lkdGgoKSArIHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vZmZzZXQoKS5sZWZ0ICsgbnViX3dpZHRoICsgbGVmdEFkanVzdG1lbnQpfSk7XHJcblxyXG4gICAgICAgICAgdGhpcy5udWJfcG9zaXRpb24oJG51YiwgdGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MubnViX3Bvc2l0aW9uLCAnbGVmdCcpO1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubGVmdCgpKSB7XHJcblxyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKHtcclxuICAgICAgICAgICAgdG9wIDogdGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLnRvcCArIHRvcEFkanVzdG1lbnQsXHJcbiAgICAgICAgICAgIGxlZnQgOiAodGhpcy5zZXR0aW5ncy4kdGFyZ2V0Lm9mZnNldCgpLmxlZnQgLSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlcldpZHRoKCkgLSBudWJfd2lkdGggKyBsZWZ0QWRqdXN0bWVudCl9KTtcclxuXHJcbiAgICAgICAgICB0aGlzLm51Yl9wb3NpdGlvbigkbnViLCB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy5udWJfcG9zaXRpb24sICdyaWdodCcpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy52aXNpYmxlKHRoaXMuY29ybmVycyh0aGlzLnNldHRpbmdzLiRuZXh0X3RpcCkpICYmIHRoaXMuc2V0dGluZ3MuYXR0ZW1wdHMgPCB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy50aXBfbG9jYXRpb25fcGF0dGVybi5sZW5ndGgpIHtcclxuXHJcbiAgICAgICAgICAkbnViLnJlbW92ZUNsYXNzKCdib3R0b20nKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3RvcCcpXHJcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcygncmlnaHQnKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2xlZnQnKTtcclxuXHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy50aXBfbG9jYXRpb24gPSB0aGlzLnNldHRpbmdzLnRpcF9zZXR0aW5ncy50aXBfbG9jYXRpb25fcGF0dGVyblt0aGlzLnNldHRpbmdzLmF0dGVtcHRzXTtcclxuXHJcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLmF0dGVtcHRzKys7XHJcblxyXG4gICAgICAgICAgdGhpcy5wb3NfZGVmYXVsdCgpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2V0dGluZ3MuJGxpLmxlbmd0aCkge1xyXG5cclxuICAgICAgICB0aGlzLnBvc19tb2RhbCgkbnViKTtcclxuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0b2dnbGUpIHtcclxuICAgICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5oaWRlKCk7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKCd2aXNpYmlsaXR5JywgJ3Zpc2libGUnKTtcclxuICAgICAgfVxyXG5cclxuICAgIH0sXHJcblxyXG4gICAgcG9zX3Bob25lIDogZnVuY3Rpb24gKGluaXQpIHtcclxuICAgICAgdmFyIHRpcF9oZWlnaHQgPSB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5vdXRlckhlaWdodCgpLFxyXG4gICAgICAgICAgdGlwX29mZnNldCA9IHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLm9mZnNldCgpLFxyXG4gICAgICAgICAgdGFyZ2V0X2hlaWdodCA9IHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vdXRlckhlaWdodCgpLFxyXG4gICAgICAgICAgJG51YiA9ICQoJy5qb3lyaWRlLW51YicsIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwKSxcclxuICAgICAgICAgIG51Yl9oZWlnaHQgPSBNYXRoLmNlaWwoJG51Yi5vdXRlckhlaWdodCgpIC8gMiksXHJcbiAgICAgICAgICB0b2dnbGUgPSBpbml0IHx8IGZhbHNlO1xyXG5cclxuICAgICAgJG51Yi5yZW1vdmVDbGFzcygnYm90dG9tJylcclxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ3RvcCcpXHJcbiAgICAgICAgLnJlbW92ZUNsYXNzKCdyaWdodCcpXHJcbiAgICAgICAgLnJlbW92ZUNsYXNzKCdsZWZ0Jyk7XHJcblxyXG4gICAgICBpZiAodG9nZ2xlKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuY3NzKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLnNob3coKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCEvYm9keS9pLnRlc3QodGhpcy5zZXR0aW5ncy4kdGFyZ2V0LnNlbGVjdG9yKSkge1xyXG5cclxuICAgICAgICBpZiAodGhpcy50b3AoKSkge1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAub2Zmc2V0KHt0b3AgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkudG9wIC0gdGlwX2hlaWdodCAtIG51Yl9oZWlnaHR9KTtcclxuICAgICAgICAgICAgJG51Yi5hZGRDbGFzcygnYm90dG9tJyk7XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAub2Zmc2V0KHt0b3AgOiB0aGlzLnNldHRpbmdzLiR0YXJnZXQub2Zmc2V0KCkudG9wICsgdGFyZ2V0X2hlaWdodCArIG51Yl9oZWlnaHR9KTtcclxuICAgICAgICAgICRudWIuYWRkQ2xhc3MoJ3RvcCcpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2V0dGluZ3MuJGxpLmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMucG9zX21vZGFsKCRudWIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodG9nZ2xlKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuaGlkZSgpO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLmNzcygndmlzaWJpbGl0eScsICd2aXNpYmxlJyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgcG9zX21vZGFsIDogZnVuY3Rpb24gKCRudWIpIHtcclxuICAgICAgdGhpcy5jZW50ZXIoKTtcclxuICAgICAgJG51Yi5oaWRlKCk7XHJcblxyXG4gICAgICB0aGlzLnNob3dfbW9kYWwoKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2hvd19tb2RhbCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5kYXRhKCdjbG9zZWQnKSkge1xyXG4gICAgICAgIHZhciBqb3lyaWRlbW9kYWxiZyA9ICAkKCcuam95cmlkZS1tb2RhbC1iZycpO1xyXG4gICAgICAgIGlmIChqb3lyaWRlbW9kYWxiZy5sZW5ndGggPCAxKSB7XHJcbiAgICAgICAgICB2YXIgam95cmlkZW1vZGFsYmcgPSAkKHRoaXMuc2V0dGluZ3MudGVtcGxhdGUubW9kYWwpO1xyXG4gICAgICAgICAgam95cmlkZW1vZGFsYmcuYXBwZW5kVG8oJ2JvZHknKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICgvcG9wL2kudGVzdCh0aGlzLnNldHRpbmdzLnRpcF9hbmltYXRpb24pKSB7XHJcbiAgICAgICAgICAgIGpveXJpZGVtb2RhbGJnLnNob3coKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBqb3lyaWRlbW9kYWxiZy5mYWRlSW4odGhpcy5zZXR0aW5ncy50aXBfYW5pbWF0aW9uX2ZhZGVfc3BlZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBleHBvc2UgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBleHBvc2UsXHJcbiAgICAgICAgICBleHBvc2VDb3ZlcixcclxuICAgICAgICAgIGVsLFxyXG4gICAgICAgICAgb3JpZ0NTUyxcclxuICAgICAgICAgIG9yaWdDbGFzc2VzLFxyXG4gICAgICAgICAgcmFuZElkID0gJ2V4cG9zZS0nICsgdGhpcy5yYW5kb21fc3RyKDYpO1xyXG5cclxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSBpbnN0YW5jZW9mICQpIHtcclxuICAgICAgICBlbCA9IGFyZ3VtZW50c1swXTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLiR0YXJnZXQgJiYgIS9ib2R5L2kudGVzdCh0aGlzLnNldHRpbmdzLiR0YXJnZXQuc2VsZWN0b3IpKSB7XHJcbiAgICAgICAgZWwgPSB0aGlzLnNldHRpbmdzLiR0YXJnZXQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoZWwubGVuZ3RoIDwgMSkge1xyXG4gICAgICAgIGlmICh3aW5kb3cuY29uc29sZSkge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcignZWxlbWVudCBub3QgdmFsaWQnLCBlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZXhwb3NlID0gJCh0aGlzLnNldHRpbmdzLnRlbXBsYXRlLmV4cG9zZSk7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuJGJvZHkuYXBwZW5kKGV4cG9zZSk7XHJcbiAgICAgIGV4cG9zZS5jc3Moe1xyXG4gICAgICAgIHRvcCA6IGVsLm9mZnNldCgpLnRvcCxcclxuICAgICAgICBsZWZ0IDogZWwub2Zmc2V0KCkubGVmdCxcclxuICAgICAgICB3aWR0aCA6IGVsLm91dGVyV2lkdGgodHJ1ZSksXHJcbiAgICAgICAgaGVpZ2h0IDogZWwub3V0ZXJIZWlnaHQodHJ1ZSlcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBleHBvc2VDb3ZlciA9ICQodGhpcy5zZXR0aW5ncy50ZW1wbGF0ZS5leHBvc2VfY292ZXIpO1xyXG5cclxuICAgICAgb3JpZ0NTUyA9IHtcclxuICAgICAgICB6SW5kZXggOiBlbC5jc3MoJ3otaW5kZXgnKSxcclxuICAgICAgICBwb3NpdGlvbiA6IGVsLmNzcygncG9zaXRpb24nKVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgb3JpZ0NsYXNzZXMgPSBlbC5hdHRyKCdjbGFzcycpID09IG51bGwgPyAnJyA6IGVsLmF0dHIoJ2NsYXNzJyk7XHJcblxyXG4gICAgICBlbC5jc3MoJ3otaW5kZXgnLCBwYXJzZUludChleHBvc2UuY3NzKCd6LWluZGV4JykpICsgMSk7XHJcblxyXG4gICAgICBpZiAob3JpZ0NTUy5wb3NpdGlvbiA9PSAnc3RhdGljJykge1xyXG4gICAgICAgIGVsLmNzcygncG9zaXRpb24nLCAncmVsYXRpdmUnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZWwuZGF0YSgnZXhwb3NlLWNzcycsIG9yaWdDU1MpO1xyXG4gICAgICBlbC5kYXRhKCdvcmlnLWNsYXNzJywgb3JpZ0NsYXNzZXMpO1xyXG4gICAgICBlbC5hdHRyKCdjbGFzcycsIG9yaWdDbGFzc2VzICsgJyAnICsgdGhpcy5zZXR0aW5ncy5leHBvc2VfYWRkX2NsYXNzKTtcclxuXHJcbiAgICAgIGV4cG9zZUNvdmVyLmNzcyh7XHJcbiAgICAgICAgdG9wIDogZWwub2Zmc2V0KCkudG9wLFxyXG4gICAgICAgIGxlZnQgOiBlbC5vZmZzZXQoKS5sZWZ0LFxyXG4gICAgICAgIHdpZHRoIDogZWwub3V0ZXJXaWR0aCh0cnVlKSxcclxuICAgICAgICBoZWlnaHQgOiBlbC5vdXRlckhlaWdodCh0cnVlKVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLm1vZGFsKSB7XHJcbiAgICAgICAgdGhpcy5zaG93X21vZGFsKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuJGJvZHkuYXBwZW5kKGV4cG9zZUNvdmVyKTtcclxuICAgICAgZXhwb3NlLmFkZENsYXNzKHJhbmRJZCk7XHJcbiAgICAgIGV4cG9zZUNvdmVyLmFkZENsYXNzKHJhbmRJZCk7XHJcbiAgICAgIGVsLmRhdGEoJ2V4cG9zZScsIHJhbmRJZCk7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MucG9zdF9leHBvc2VfY2FsbGJhY2sodGhpcy5zZXR0aW5ncy4kbGkuaW5kZXgoKSwgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAsIGVsKTtcclxuICAgICAgdGhpcy5hZGRfZXhwb3NlZChlbCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHVuX2V4cG9zZSA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGV4cG9zZUlkLFxyXG4gICAgICAgICAgZWwsXHJcbiAgICAgICAgICBleHBvc2UsXHJcbiAgICAgICAgICBvcmlnQ1NTLFxyXG4gICAgICAgICAgb3JpZ0NsYXNzZXMsXHJcbiAgICAgICAgICBjbGVhckFsbCA9IGZhbHNlO1xyXG5cclxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSBpbnN0YW5jZW9mICQpIHtcclxuICAgICAgICBlbCA9IGFyZ3VtZW50c1swXTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLiR0YXJnZXQgJiYgIS9ib2R5L2kudGVzdCh0aGlzLnNldHRpbmdzLiR0YXJnZXQuc2VsZWN0b3IpKSB7XHJcbiAgICAgICAgZWwgPSB0aGlzLnNldHRpbmdzLiR0YXJnZXQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoZWwubGVuZ3RoIDwgMSkge1xyXG4gICAgICAgIGlmICh3aW5kb3cuY29uc29sZSkge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcignZWxlbWVudCBub3QgdmFsaWQnLCBlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZXhwb3NlSWQgPSBlbC5kYXRhKCdleHBvc2UnKTtcclxuICAgICAgZXhwb3NlID0gJCgnLicgKyBleHBvc2VJZCk7XHJcblxyXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICBjbGVhckFsbCA9IGFyZ3VtZW50c1sxXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGNsZWFyQWxsID09PSB0cnVlKSB7XHJcbiAgICAgICAgJCgnLmpveXJpZGUtZXhwb3NlLXdyYXBwZXIsLmpveXJpZGUtZXhwb3NlLWNvdmVyJykucmVtb3ZlKCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZXhwb3NlLnJlbW92ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBvcmlnQ1NTID0gZWwuZGF0YSgnZXhwb3NlLWNzcycpO1xyXG5cclxuICAgICAgaWYgKG9yaWdDU1MuekluZGV4ID09ICdhdXRvJykge1xyXG4gICAgICAgIGVsLmNzcygnei1pbmRleCcsICcnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlbC5jc3MoJ3otaW5kZXgnLCBvcmlnQ1NTLnpJbmRleCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcmlnQ1NTLnBvc2l0aW9uICE9IGVsLmNzcygncG9zaXRpb24nKSkge1xyXG4gICAgICAgIGlmIChvcmlnQ1NTLnBvc2l0aW9uID09ICdzdGF0aWMnKSB7Ly8gdGhpcyBpcyBkZWZhdWx0LCBubyBuZWVkIHRvIHNldCBpdC5cclxuICAgICAgICAgIGVsLmNzcygncG9zaXRpb24nLCAnJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGVsLmNzcygncG9zaXRpb24nLCBvcmlnQ1NTLnBvc2l0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIG9yaWdDbGFzc2VzID0gZWwuZGF0YSgnb3JpZy1jbGFzcycpO1xyXG4gICAgICBlbC5hdHRyKCdjbGFzcycsIG9yaWdDbGFzc2VzKTtcclxuICAgICAgZWwucmVtb3ZlRGF0YSgnb3JpZy1jbGFzc2VzJyk7XHJcblxyXG4gICAgICBlbC5yZW1vdmVEYXRhKCdleHBvc2UnKTtcclxuICAgICAgZWwucmVtb3ZlRGF0YSgnZXhwb3NlLXotaW5kZXgnKTtcclxuICAgICAgdGhpcy5yZW1vdmVfZXhwb3NlZChlbCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZF9leHBvc2VkIDogZnVuY3Rpb24gKGVsKSB7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MuZXhwb3NlZCA9IHRoaXMuc2V0dGluZ3MuZXhwb3NlZCB8fCBbXTtcclxuICAgICAgaWYgKGVsIGluc3RhbmNlb2YgJCB8fCB0eXBlb2YgZWwgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5leHBvc2VkLnB1c2goZWxbMF0pO1xyXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbCA9PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MuZXhwb3NlZC5wdXNoKGVsKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVfZXhwb3NlZCA6IGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICB2YXIgc2VhcmNoLCBpO1xyXG4gICAgICBpZiAoZWwgaW5zdGFuY2VvZiAkKSB7XHJcbiAgICAgICAgc2VhcmNoID0gZWxbMF1cclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZWwgPT0gJ3N0cmluZycpIHtcclxuICAgICAgICBzZWFyY2ggPSBlbDtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5zZXR0aW5ncy5leHBvc2VkID0gdGhpcy5zZXR0aW5ncy5leHBvc2VkIHx8IFtdO1xyXG4gICAgICBpID0gdGhpcy5zZXR0aW5ncy5leHBvc2VkLmxlbmd0aDtcclxuXHJcbiAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5leHBvc2VkW2ldID09IHNlYXJjaCkge1xyXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy5leHBvc2VkLnNwbGljZShpLCAxKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY2VudGVyIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgJHcgPSAkKHdpbmRvdyk7XHJcblxyXG4gICAgICB0aGlzLnNldHRpbmdzLiRuZXh0X3RpcC5jc3Moe1xyXG4gICAgICAgIHRvcCA6ICgoKCR3LmhlaWdodCgpIC0gdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAub3V0ZXJIZWlnaHQoKSkgLyAyKSArICR3LnNjcm9sbFRvcCgpKSxcclxuICAgICAgICBsZWZ0IDogKCgoJHcud2lkdGgoKSAtIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLm91dGVyV2lkdGgoKSkgLyAyKSArICR3LnNjcm9sbExlZnQoKSlcclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgYm90dG9tIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gL2JvdHRvbS9pLnRlc3QodGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MudGlwX2xvY2F0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgdG9wIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gL3RvcC9pLnRlc3QodGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MudGlwX2xvY2F0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmlnaHQgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiAvcmlnaHQvaS50ZXN0KHRoaXMuc2V0dGluZ3MudGlwX3NldHRpbmdzLnRpcF9sb2NhdGlvbik7XHJcbiAgICB9LFxyXG5cclxuICAgIGxlZnQgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiAvbGVmdC9pLnRlc3QodGhpcy5zZXR0aW5ncy50aXBfc2V0dGluZ3MudGlwX2xvY2F0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgY29ybmVycyA6IGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICBpZiAoZWwubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgIHJldHVybiBbZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2VdOyAgIFxyXG4gICAgICB9XHJcbiAgICAgIFxyXG4gICAgICB2YXIgdyA9ICQod2luZG93KSxcclxuICAgICAgICAgIHdpbmRvd19oYWxmID0gdy5oZWlnaHQoKSAvIDIsXHJcbiAgICAgICAgICAvL3VzaW5nIHRoaXMgdG8gY2FsY3VsYXRlIHNpbmNlIHNjcm9sbCBtYXkgbm90IGhhdmUgZmluaXNoZWQgeWV0LlxyXG4gICAgICAgICAgdGlwT2Zmc2V0ID0gTWF0aC5jZWlsKHRoaXMuc2V0dGluZ3MuJHRhcmdldC5vZmZzZXQoKS50b3AgLSB3aW5kb3dfaGFsZiArIHRoaXMuc2V0dGluZ3MuJG5leHRfdGlwLm91dGVySGVpZ2h0KCkpLFxyXG4gICAgICAgICAgcmlnaHQgPSB3LndpZHRoKCkgKyB3LnNjcm9sbExlZnQoKSxcclxuICAgICAgICAgIG9mZnNldEJvdHRvbSA9ICB3LmhlaWdodCgpICsgdGlwT2Zmc2V0LFxyXG4gICAgICAgICAgYm90dG9tID0gdy5oZWlnaHQoKSArIHcuc2Nyb2xsVG9wKCksXHJcbiAgICAgICAgICB0b3AgPSB3LnNjcm9sbFRvcCgpO1xyXG5cclxuICAgICAgaWYgKHRpcE9mZnNldCA8IHRvcCkge1xyXG4gICAgICAgIGlmICh0aXBPZmZzZXQgPCAwKSB7XHJcbiAgICAgICAgICB0b3AgPSAwO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0b3AgPSB0aXBPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob2Zmc2V0Qm90dG9tID4gYm90dG9tKSB7XHJcbiAgICAgICAgYm90dG9tID0gb2Zmc2V0Qm90dG9tO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gW1xyXG4gICAgICAgIGVsLm9mZnNldCgpLnRvcCA8IHRvcCxcclxuICAgICAgICByaWdodCA8IGVsLm9mZnNldCgpLmxlZnQgKyBlbC5vdXRlcldpZHRoKCksXHJcbiAgICAgICAgYm90dG9tIDwgZWwub2Zmc2V0KCkudG9wICsgZWwub3V0ZXJIZWlnaHQoKSxcclxuICAgICAgICB3LnNjcm9sbExlZnQoKSA+IGVsLm9mZnNldCgpLmxlZnRcclxuICAgICAgXTtcclxuICAgIH0sXHJcblxyXG4gICAgdmlzaWJsZSA6IGZ1bmN0aW9uIChoaWRkZW5fY29ybmVycykge1xyXG4gICAgICB2YXIgaSA9IGhpZGRlbl9jb3JuZXJzLmxlbmd0aDtcclxuXHJcbiAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICBpZiAoaGlkZGVuX2Nvcm5lcnNbaV0pIHtcclxuICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBudWJfcG9zaXRpb24gOiBmdW5jdGlvbiAobnViLCBwb3MsIGRlZikge1xyXG4gICAgICBpZiAocG9zID09PSAnYXV0bycpIHtcclxuICAgICAgICBudWIuYWRkQ2xhc3MoZGVmKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBudWIuYWRkQ2xhc3MocG9zKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzdGFydFRpbWVyIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy4kbGkubGVuZ3RoKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5hdXRvbWF0ZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgICAgIHRoaXMuc3RhcnRUaW1lcigpO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSwgdGhpcy5zZXR0aW5ncy50aW1lcik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuc2V0dGluZ3MuYXV0b21hdGUpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGVuZCA6IGZ1bmN0aW9uIChhYm9ydCkge1xyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5jb29raWVfbW9uc3Rlcikge1xyXG4gICAgICAgICQuY29va2llKHRoaXMuc2V0dGluZ3MuY29va2llX25hbWUsICdyaWRkZW4nLCB7ZXhwaXJlcyA6IHRoaXMuc2V0dGluZ3MuY29va2llX2V4cGlyZXMsIGRvbWFpbiA6IHRoaXMuc2V0dGluZ3MuY29va2llX2RvbWFpbn0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy50aW1lciA+IDApIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5zZXR0aW5ncy5hdXRvbWF0ZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLm1vZGFsICYmIHRoaXMuc2V0dGluZ3MuZXhwb3NlKSB7XHJcbiAgICAgICAgdGhpcy51bl9leHBvc2UoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gVW5wbHVnIGtleXN0cm9rZXMgbGlzdGVuZXJcclxuICAgICAgJCh0aGlzLnNjb3BlKS5vZmYoJ2tleXVwLmpveXJpZGUnKVxyXG5cclxuICAgICAgdGhpcy5zZXR0aW5ncy4kbmV4dF90aXAuZGF0YSgnY2xvc2VkJywgdHJ1ZSk7XHJcbiAgICAgIHRoaXMuc2V0dGluZ3MucmlkaW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAkKCcuam95cmlkZS1tb2RhbC1iZycpLmhpZGUoKTtcclxuICAgICAgdGhpcy5zZXR0aW5ncy4kY3VycmVudF90aXAuaGlkZSgpO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBhYm9ydCA9PT0gJ3VuZGVmaW5lZCcgfHwgYWJvcnQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5wb3N0X3N0ZXBfY2FsbGJhY2sodGhpcy5zZXR0aW5ncy4kbGkuaW5kZXgoKSwgdGhpcy5zZXR0aW5ncy4kY3VycmVudF90aXApO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MucG9zdF9yaWRlX2NhbGxiYWNrKHRoaXMuc2V0dGluZ3MuJGxpLmluZGV4KCksIHRoaXMuc2V0dGluZ3MuJGN1cnJlbnRfdGlwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgJCgnLmpveXJpZGUtdGlwLWd1aWRlJykucmVtb3ZlKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIG9mZiA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgJCh0aGlzLnNjb3BlKS5vZmYoJy5qb3lyaWRlJyk7XHJcbiAgICAgICQod2luZG93KS5vZmYoJy5qb3lyaWRlJyk7XHJcbiAgICAgICQoJy5qb3lyaWRlLWNsb3NlLXRpcCwgLmpveXJpZGUtbmV4dC10aXAsIC5qb3lyaWRlLW1vZGFsLWJnJykub2ZmKCcuam95cmlkZScpO1xyXG4gICAgICAkKCcuam95cmlkZS10aXAtZ3VpZGUsIC5qb3lyaWRlLW1vZGFsLWJnJykucmVtb3ZlKCk7XHJcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNldHRpbmdzLmF1dG9tYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge31cclxuICB9O1xyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzWydtYWdlbGxhbi1leHBlZGl0aW9uJ10gPSB7XHJcbiAgICBuYW1lIDogJ21hZ2VsbGFuLWV4cGVkaXRpb24nLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBhY3RpdmVfY2xhc3MgOiAnYWN0aXZlJyxcclxuICAgICAgdGhyZXNob2xkIDogMCwgLy8gcGl4ZWxzIGZyb20gdGhlIHRvcCBvZiB0aGUgZXhwZWRpdGlvbiBmb3IgaXQgdG8gYmVjb21lIGZpeGVzXHJcbiAgICAgIGRlc3RpbmF0aW9uX3RocmVzaG9sZCA6IDIwLCAvLyBwaXhlbHMgZnJvbSB0aGUgdG9wIG9mIGRlc3RpbmF0aW9uIGZvciBpdCB0byBiZSBjb25zaWRlcmVkIGFjdGl2ZVxyXG4gICAgICB0aHJvdHRsZV9kZWxheSA6IDMwLCAvLyBjYWxjdWxhdGlvbiB0aHJvdHRsaW5nIHRvIGluY3JlYXNlIGZyYW1lcmF0ZVxyXG4gICAgICBmaXhlZF90b3AgOiAwLCAvLyB0b3AgZGlzdGFuY2UgaW4gcGl4ZWxzIGFzc2lnZW5kIHRvIHRoZSBmaXhlZCBlbGVtZW50IG9uIHNjcm9sbFxyXG4gICAgICBvZmZzZXRfYnlfaGVpZ2h0IDogdHJ1ZSwgIC8vIHdoZXRoZXIgdG8gb2Zmc2V0IHRoZSBkZXN0aW5hdGlvbiBieSB0aGUgZXhwZWRpdGlvbiBoZWlnaHQuIFVzdWFsbHkgeW91IHdhbnQgdGhpcyB0byBiZSB0cnVlLCB1bmxlc3MgeW91ciBleHBlZGl0aW9uIGlzIG9uIHRoZSBzaWRlLlxyXG4gICAgICBkdXJhdGlvbiA6IDcwMCwgLy8gYW5pbWF0aW9uIGR1cmF0aW9uIHRpbWVcclxuICAgICAgZWFzaW5nIDogJ3N3aW5nJyAvLyBhbmltYXRpb24gZWFzaW5nXHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICBGb3VuZGF0aW9uLmluaGVyaXQodGhpcywgJ3Rocm90dGxlJyk7XHJcbiAgICAgIHRoaXMuYmluZGluZ3MobWV0aG9kLCBvcHRpb25zKTtcclxuICAgIH0sXHJcblxyXG4gICAgZXZlbnRzIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBTID0gc2VsZi5TLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSBzZWxmLnNldHRpbmdzO1xyXG5cclxuICAgICAgLy8gaW5pdGlhbGl6ZSBleHBlZGl0aW9uIG9mZnNldFxyXG4gICAgICBzZWxmLnNldF9leHBlZGl0aW9uX3Bvc2l0aW9uKCk7XHJcblxyXG4gICAgICBTKHNlbGYuc2NvcGUpXHJcbiAgICAgICAgLm9mZignLm1hZ2VsbGFuJylcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm1hZ2VsbGFuJywgJ1snICsgc2VsZi5hZGRfbmFtZXNwYWNlKCdkYXRhLW1hZ2VsbGFuLWFycml2YWwnKSArICddIGFbaHJlZio9I10nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIHNhbWVIb3N0ID0gKCh0aGlzLmhvc3RuYW1lID09PSBsb2NhdGlvbi5ob3N0bmFtZSkgfHwgIXRoaXMuaG9zdG5hbWUpLFxyXG4gICAgICAgICAgICAgIHNhbWVQYXRoID0gc2VsZi5maWx0ZXJQYXRobmFtZShsb2NhdGlvbi5wYXRobmFtZSkgPT09IHNlbGYuZmlsdGVyUGF0aG5hbWUodGhpcy5wYXRobmFtZSksXHJcbiAgICAgICAgICAgICAgdGVzdEhhc2ggPSB0aGlzLmhhc2gucmVwbGFjZSgvKDp8XFwufFxcLykvZywgJ1xcXFwkMScpLFxyXG4gICAgICAgICAgICAgIGFuY2hvciA9IHRoaXM7XHJcblxyXG4gICAgICAgICAgaWYgKHNhbWVIb3N0ICYmIHNhbWVQYXRoICYmIHRlc3RIYXNoKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgdmFyIGV4cGVkaXRpb24gPSAkKHRoaXMpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJyksXHJcbiAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IGV4cGVkaXRpb24uZGF0YSgnbWFnZWxsYW4tZXhwZWRpdGlvbi1pbml0JyksXHJcbiAgICAgICAgICAgICAgICBoYXNoID0gdGhpcy5oYXNoLnNwbGl0KCcjJykuam9pbignJyksXHJcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSAkKCdhW25hbWU9XCInICsgaGFzaCArICdcIl0nKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0YXJnZXQubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgdGFyZ2V0ID0gJCgnIycgKyBoYXNoKTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEFjY291bnQgZm9yIGV4cGVkaXRpb24gaGVpZ2h0IGlmIGZpeGVkIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIHZhciBzY3JvbGxfdG9wID0gdGFyZ2V0Lm9mZnNldCgpLnRvcCAtIHNldHRpbmdzLmRlc3RpbmF0aW9uX3RocmVzaG9sZCArIDE7XHJcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5vZmZzZXRfYnlfaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgc2Nyb2xsX3RvcCA9IHNjcm9sbF90b3AgLSBleHBlZGl0aW9uLm91dGVySGVpZ2h0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJCgnaHRtbCwgYm9keScpLnN0b3AoKS5hbmltYXRlKHtcclxuICAgICAgICAgICAgICAnc2Nyb2xsVG9wJyA6IHNjcm9sbF90b3BcclxuICAgICAgICAgICAgfSwgc2V0dGluZ3MuZHVyYXRpb24sIHNldHRpbmdzLmVhc2luZywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgIGlmIChoaXN0b3J5LnB1c2hTdGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5wdXNoU3RhdGUobnVsbCwgbnVsbCwgYW5jaG9yLnBhdGhuYW1lICsgYW5jaG9yLnNlYXJjaCArICcjJyArIGhhc2gpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsb2NhdGlvbi5oYXNoID0gYW5jaG9yLnBhdGhuYW1lICsgYW5jaG9yLnNlYXJjaCArICcjJyArIGhhc2g7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignc2Nyb2xsLmZuZHRuLm1hZ2VsbGFuJywgc2VsZi50aHJvdHRsZSh0aGlzLmNoZWNrX2Zvcl9hcnJpdmFscy5iaW5kKHRoaXMpLCBzZXR0aW5ncy50aHJvdHRsZV9kZWxheSkpO1xyXG4gICAgfSxcclxuXHJcbiAgICBjaGVja19mb3JfYXJyaXZhbHMgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgc2VsZi51cGRhdGVfYXJyaXZhbHMoKTtcclxuICAgICAgc2VsZi51cGRhdGVfZXhwZWRpdGlvbl9wb3NpdGlvbnMoKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0X2V4cGVkaXRpb25fcG9zaXRpb24gOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgJCgnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJz1maXhlZF0nLCBzZWxmLnNjb3BlKS5lYWNoKGZ1bmN0aW9uIChpZHgsIGVsKSB7XHJcbiAgICAgICAgdmFyIGV4cGVkaXRpb24gPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IGV4cGVkaXRpb24uZGF0YSgnbWFnZWxsYW4tZXhwZWRpdGlvbi1pbml0JyksXHJcbiAgICAgICAgICAgIHN0eWxlcyA9IGV4cGVkaXRpb24uYXR0cignc3R5bGVzJyksIC8vIHNhdmUgc3R5bGVzXHJcbiAgICAgICAgICAgIHRvcF9vZmZzZXQsIGZpeGVkX3RvcDtcclxuXHJcbiAgICAgICAgZXhwZWRpdGlvbi5hdHRyKCdzdHlsZScsICcnKTtcclxuICAgICAgICB0b3Bfb2Zmc2V0ID0gZXhwZWRpdGlvbi5vZmZzZXQoKS50b3AgKyBzZXR0aW5ncy50aHJlc2hvbGQ7XHJcblxyXG4gICAgICAgIC8vc2V0IGZpeGVkLXRvcCBieSBhdHRyaWJ1dGVcclxuICAgICAgICBmaXhlZF90b3AgPSBwYXJzZUludChleHBlZGl0aW9uLmRhdGEoJ21hZ2VsbGFuLWZpeGVkLXRvcCcpKTtcclxuICAgICAgICBpZiAoIWlzTmFOKGZpeGVkX3RvcCkpIHtcclxuICAgICAgICAgIHNlbGYuc2V0dGluZ3MuZml4ZWRfdG9wID0gZml4ZWRfdG9wO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwZWRpdGlvbi5kYXRhKHNlbGYuZGF0YV9hdHRyKCdtYWdlbGxhbi10b3Atb2Zmc2V0JyksIHRvcF9vZmZzZXQpO1xyXG4gICAgICAgIGV4cGVkaXRpb24uYXR0cignc3R5bGUnLCBzdHlsZXMpO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgdXBkYXRlX2V4cGVkaXRpb25fcG9zaXRpb25zIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICB3aW5kb3dfdG9wX29mZnNldCA9ICQod2luZG93KS5zY3JvbGxUb3AoKTtcclxuXHJcbiAgICAgICQoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICc9Zml4ZWRdJywgc2VsZi5zY29wZSkuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGV4cGVkaXRpb24gPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IGV4cGVkaXRpb24uZGF0YSgnbWFnZWxsYW4tZXhwZWRpdGlvbi1pbml0JyksXHJcbiAgICAgICAgICAgIHN0eWxlcyA9IGV4cGVkaXRpb24uYXR0cignc3R5bGUnKSwgLy8gc2F2ZSBzdHlsZXNcclxuICAgICAgICAgICAgdG9wX29mZnNldCA9IGV4cGVkaXRpb24uZGF0YSgnbWFnZWxsYW4tdG9wLW9mZnNldCcpO1xyXG5cclxuICAgICAgICAvL3Njcm9sbCB0byB0aGUgdG9wIGRpc3RhbmNlXHJcbiAgICAgICAgaWYgKHdpbmRvd190b3Bfb2Zmc2V0ICsgc2VsZi5zZXR0aW5ncy5maXhlZF90b3AgPj0gdG9wX29mZnNldCkge1xyXG4gICAgICAgICAgLy8gUGxhY2Vob2xkZXIgYWxsb3dzIGhlaWdodCBjYWxjdWxhdGlvbnMgdG8gYmUgY29uc2lzdGVudCBldmVuIHdoZW5cclxuICAgICAgICAgIC8vIGFwcGVhcmluZyB0byBzd2l0Y2ggYmV0d2VlbiBmaXhlZC9ub24tZml4ZWQgcGxhY2VtZW50XHJcbiAgICAgICAgICB2YXIgcGxhY2Vob2xkZXIgPSBleHBlZGl0aW9uLnByZXYoJ1snICsgc2VsZi5hZGRfbmFtZXNwYWNlKCdkYXRhLW1hZ2VsbGFuLWV4cGVkaXRpb24tY2xvbmUnKSArICddJyk7XHJcbiAgICAgICAgICBpZiAocGxhY2Vob2xkZXIubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyID0gZXhwZWRpdGlvbi5jbG9uZSgpO1xyXG4gICAgICAgICAgICBwbGFjZWhvbGRlci5yZW1vdmVBdHRyKHNlbGYuYXR0cl9uYW1lKCkpO1xyXG4gICAgICAgICAgICBwbGFjZWhvbGRlci5hdHRyKHNlbGYuYWRkX25hbWVzcGFjZSgnZGF0YS1tYWdlbGxhbi1leHBlZGl0aW9uLWNsb25lJyksICcnKTtcclxuICAgICAgICAgICAgZXhwZWRpdGlvbi5iZWZvcmUocGxhY2Vob2xkZXIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZXhwZWRpdGlvbi5jc3Moe3Bvc2l0aW9uIDonZml4ZWQnLCB0b3AgOiBzZXR0aW5ncy5maXhlZF90b3B9KS5hZGRDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgZXhwZWRpdGlvbi5wcmV2KCdbJyArIHNlbGYuYWRkX25hbWVzcGFjZSgnZGF0YS1tYWdlbGxhbi1leHBlZGl0aW9uLWNsb25lJykgKyAnXScpLnJlbW92ZSgpO1xyXG4gICAgICAgICAgZXhwZWRpdGlvbi5hdHRyKCdzdHlsZScsIHN0eWxlcykuY3NzKCdwb3NpdGlvbicsICcnKS5jc3MoJ3RvcCcsICcnKS5yZW1vdmVDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVfYXJyaXZhbHMgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgIHdpbmRvd190b3Bfb2Zmc2V0ID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xyXG5cclxuICAgICAgJCgnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nLCBzZWxmLnNjb3BlKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgZXhwZWRpdGlvbiA9ICQodGhpcyksXHJcbiAgICAgICAgICAgIHNldHRpbmdzID0gZXhwZWRpdGlvbi5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JyksXHJcbiAgICAgICAgICAgIG9mZnNldHMgPSBzZWxmLm9mZnNldHMoZXhwZWRpdGlvbiwgd2luZG93X3RvcF9vZmZzZXQpLFxyXG4gICAgICAgICAgICBhcnJpdmFscyA9IGV4cGVkaXRpb24uZmluZCgnWycgKyBzZWxmLmFkZF9uYW1lc3BhY2UoJ2RhdGEtbWFnZWxsYW4tYXJyaXZhbCcpICsgJ10nKSxcclxuICAgICAgICAgICAgYWN0aXZlX2l0ZW0gPSBmYWxzZTtcclxuICAgICAgICBvZmZzZXRzLmVhY2goZnVuY3Rpb24gKGlkeCwgaXRlbSkge1xyXG4gICAgICAgICAgaWYgKGl0ZW0udmlld3BvcnRfb2Zmc2V0ID49IGl0ZW0udG9wX29mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgYXJyaXZhbHMgPSBleHBlZGl0aW9uLmZpbmQoJ1snICsgc2VsZi5hZGRfbmFtZXNwYWNlKCdkYXRhLW1hZ2VsbGFuLWFycml2YWwnKSArICddJyk7XHJcbiAgICAgICAgICAgIGFycml2YWxzLm5vdChpdGVtLmFycml2YWwpLnJlbW92ZUNsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcyk7XHJcbiAgICAgICAgICAgIGl0ZW0uYXJyaXZhbC5hZGRDbGFzcyhzZXR0aW5ncy5hY3RpdmVfY2xhc3MpO1xyXG4gICAgICAgICAgICBhY3RpdmVfaXRlbSA9IHRydWU7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoIWFjdGl2ZV9pdGVtKSB7XHJcbiAgICAgICAgICBhcnJpdmFscy5yZW1vdmVDbGFzcyhzZXR0aW5ncy5hY3RpdmVfY2xhc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIG9mZnNldHMgOiBmdW5jdGlvbiAoZXhwZWRpdGlvbiwgd2luZG93X29mZnNldCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBzZXR0aW5ncyA9IGV4cGVkaXRpb24uZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpLFxyXG4gICAgICAgICAgdmlld3BvcnRfb2Zmc2V0ID0gd2luZG93X29mZnNldDtcclxuXHJcbiAgICAgIHJldHVybiBleHBlZGl0aW9uLmZpbmQoJ1snICsgc2VsZi5hZGRfbmFtZXNwYWNlKCdkYXRhLW1hZ2VsbGFuLWFycml2YWwnKSArICddJykubWFwKGZ1bmN0aW9uIChpZHgsIGVsKSB7XHJcbiAgICAgICAgdmFyIG5hbWUgPSAkKHRoaXMpLmRhdGEoc2VsZi5kYXRhX2F0dHIoJ21hZ2VsbGFuLWFycml2YWwnKSksXHJcbiAgICAgICAgICAgIGRlc3QgPSAkKCdbJyArIHNlbGYuYWRkX25hbWVzcGFjZSgnZGF0YS1tYWdlbGxhbi1kZXN0aW5hdGlvbicpICsgJz0nICsgbmFtZSArICddJyk7XHJcbiAgICAgICAgaWYgKGRlc3QubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgdmFyIHRvcF9vZmZzZXQgPSBkZXN0Lm9mZnNldCgpLnRvcCAtIHNldHRpbmdzLmRlc3RpbmF0aW9uX3RocmVzaG9sZDtcclxuICAgICAgICAgIGlmIChzZXR0aW5ncy5vZmZzZXRfYnlfaGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIHRvcF9vZmZzZXQgPSB0b3Bfb2Zmc2V0IC0gZXhwZWRpdGlvbi5vdXRlckhlaWdodCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdG9wX29mZnNldCA9IE1hdGguZmxvb3IodG9wX29mZnNldCk7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkZXN0aW5hdGlvbiA6IGRlc3QsXHJcbiAgICAgICAgICAgIGFycml2YWwgOiAkKHRoaXMpLFxyXG4gICAgICAgICAgICB0b3Bfb2Zmc2V0IDogdG9wX29mZnNldCxcclxuICAgICAgICAgICAgdmlld3BvcnRfb2Zmc2V0IDogdmlld3BvcnRfb2Zmc2V0XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XHJcbiAgICAgICAgaWYgKGEudG9wX29mZnNldCA8IGIudG9wX29mZnNldCkge1xyXG4gICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYS50b3Bfb2Zmc2V0ID4gYi50b3Bfb2Zmc2V0KSB7XHJcbiAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBkYXRhX2F0dHIgOiBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgIGlmICh0aGlzLm5hbWVzcGFjZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZXNwYWNlICsgJy0nICsgc3RyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc3RyO1xyXG4gICAgfSxcclxuXHJcbiAgICBvZmYgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHRoaXMuUyh0aGlzLnNjb3BlKS5vZmYoJy5tYWdlbGxhbicpO1xyXG4gICAgICB0aGlzLlMod2luZG93KS5vZmYoJy5tYWdlbGxhbicpO1xyXG4gICAgfSxcclxuXHJcbiAgICBmaWx0ZXJQYXRobmFtZSA6IGZ1bmN0aW9uIChwYXRobmFtZSkge1xyXG4gICAgICBwYXRobmFtZSA9IHBhdGhuYW1lIHx8ICcnO1xyXG4gICAgICByZXR1cm4gcGF0aG5hbWVcclxuICAgICAgICAgIC5yZXBsYWNlKC9eXFwvLywnJylcclxuICAgICAgICAgIC5yZXBsYWNlKC8oPzppbmRleHxkZWZhdWx0KS5bYS16QS1aXXszLDR9JC8sJycpXHJcbiAgICAgICAgICAucmVwbGFjZSgvXFwvJC8sJycpO1xyXG4gICAgfSxcclxuXHJcbiAgICByZWZsb3cgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgLy8gcmVtb3ZlIHBsYWNlaG9sZGVyIGV4cGVkaXRpb25zIHVzZWQgZm9yIGhlaWdodCBjYWxjdWxhdGlvbiBwdXJwb3Nlc1xyXG4gICAgICAkKCdbJyArIHNlbGYuYWRkX25hbWVzcGFjZSgnZGF0YS1tYWdlbGxhbi1leHBlZGl0aW9uLWNsb25lJykgKyAnXScsIHNlbGYuc2NvcGUpLnJlbW92ZSgpO1xyXG4gICAgfVxyXG4gIH07XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG5cclxuOyhmdW5jdGlvbiAoJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBGb3VuZGF0aW9uLmxpYnMub2ZmY2FudmFzID0ge1xyXG4gICAgbmFtZSA6ICdvZmZjYW52YXMnLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBvcGVuX21ldGhvZCA6ICdtb3ZlJyxcclxuICAgICAgY2xvc2Vfb25fY2xpY2sgOiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICBpbml0IDogZnVuY3Rpb24gKHNjb3BlLCBtZXRob2QsIG9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5iaW5kaW5ncyhtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBldmVudHMgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgIFMgPSBzZWxmLlMsXHJcbiAgICAgICAgICBtb3ZlX2NsYXNzID0gJycsXHJcbiAgICAgICAgICByaWdodF9wb3N0Zml4ID0gJycsXHJcbiAgICAgICAgICBsZWZ0X3Bvc3RmaXggPSAnJyxcclxuICAgICAgICAgIHRvcF9wb3N0Zml4ID0gJycsXHJcbiAgICAgICAgICBib3R0b21fcG9zdGZpeCA9ICcnO1xyXG5cclxuICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mub3Blbl9tZXRob2QgPT09ICdtb3ZlJykge1xyXG4gICAgICAgIG1vdmVfY2xhc3MgPSAnbW92ZS0nO1xyXG4gICAgICAgIHJpZ2h0X3Bvc3RmaXggPSAncmlnaHQnO1xyXG4gICAgICAgIGxlZnRfcG9zdGZpeCA9ICdsZWZ0JztcclxuICAgICAgICB0b3BfcG9zdGZpeCA9ICd0b3AnO1xyXG4gICAgICAgIGJvdHRvbV9wb3N0Zml4ID0gJ2JvdHRvbSc7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5vcGVuX21ldGhvZCA9PT0gJ292ZXJsYXBfc2luZ2xlJykge1xyXG4gICAgICAgIG1vdmVfY2xhc3MgPSAnb2ZmY2FudmFzLW92ZXJsYXAtJztcclxuICAgICAgICByaWdodF9wb3N0Zml4ID0gJ3JpZ2h0JztcclxuICAgICAgICBsZWZ0X3Bvc3RmaXggPSAnbGVmdCc7XHJcbiAgICAgICAgdG9wX3Bvc3RmaXggPSAndG9wJztcclxuICAgICAgICBib3R0b21fcG9zdGZpeCA9ICdib3R0b20nO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2V0dGluZ3Mub3Blbl9tZXRob2QgPT09ICdvdmVybGFwJykge1xyXG4gICAgICAgIG1vdmVfY2xhc3MgPSAnb2ZmY2FudmFzLW92ZXJsYXAnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBTKHRoaXMuc2NvcGUpLm9mZignLm9mZmNhbnZhcycpXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmxlZnQtb2ZmLWNhbnZhcy10b2dnbGUnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5jbGlja190b2dnbGVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3Mub3Blbl9tZXRob2QgIT09ICdvdmVybGFwJykge1xyXG4gICAgICAgICAgICBTKCcubGVmdC1zdWJtZW51JykucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLmxlZnQtb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5sZWZ0LW9mZi1jYW52YXMtbWVudSBhJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHNlbGYuZ2V0X3NldHRpbmdzKGUpO1xyXG4gICAgICAgICAgdmFyIHBhcmVudCA9IFModGhpcykucGFyZW50KCk7XHJcblxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmNsb3NlX29uX2NsaWNrICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2hhcy1zdWJtZW51JykgJiYgIXBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaGlkZS5jYWxsKHNlbGYsIG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4LCBzZWxmLmdldF93cmFwcGVyKGUpKTtcclxuICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoUyh0aGlzKS5wYXJlbnQoKS5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIFModGhpcykuc2libGluZ3MoJy5sZWZ0LXN1Ym1lbnUnKS50b2dnbGVDbGFzcyhtb3ZlX2NsYXNzICsgcmlnaHRfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy5sZWZ0LW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAvL2VuZCBvZiBsZWZ0IGNhbnZhc1xyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5yaWdodC1vZmYtY2FudmFzLXRvZ2dsZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3RvZ2dsZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgbGVmdF9wb3N0Zml4KTtcclxuICAgICAgICAgIGlmIChzZWxmLnNldHRpbmdzLm9wZW5fbWV0aG9kICE9PSAnb3ZlcmxhcCcpIHtcclxuICAgICAgICAgICAgUygnLnJpZ2h0LXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgbGVmdF9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy5yaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLnJpZ2h0LW9mZi1jYW52YXMtbWVudSBhJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHNlbGYuZ2V0X3NldHRpbmdzKGUpO1xyXG4gICAgICAgICAgdmFyIHBhcmVudCA9IFModGhpcykucGFyZW50KCk7XHJcblxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmNsb3NlX29uX2NsaWNrICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2hhcy1zdWJtZW51JykgJiYgIXBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaGlkZS5jYWxsKHNlbGYsIG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgsIHNlbGYuZ2V0X3dyYXBwZXIoZSkpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKFModGhpcykucGFyZW50KCkuaGFzQ2xhc3MoJ2hhcy1zdWJtZW51JykpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBTKHRoaXMpLnNpYmxpbmdzKCcucmlnaHQtc3VibWVudScpLnRvZ2dsZUNsYXNzKG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChwYXJlbnQuaGFzQ2xhc3MoJ2JhY2snKSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHBhcmVudC5wYXJlbnQoKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgbGVmdF9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy5yaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLy9lbmQgb2YgcmlnaHQgY2FudmFzXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLnRvcC1vZmYtY2FudmFzLXRvZ2dsZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3RvZ2dsZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3Mub3Blbl9tZXRob2QgIT09ICdvdmVybGFwJykge1xyXG4gICAgICAgICAgICBTKCcudG9wLXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLnRvcC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLnRvcC1vZmYtY2FudmFzLW1lbnUgYScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICB2YXIgc2V0dGluZ3MgPSBzZWxmLmdldF9zZXR0aW5ncyhlKTtcclxuICAgICAgICAgIHZhciBwYXJlbnQgPSBTKHRoaXMpLnBhcmVudCgpO1xyXG5cclxuICAgICAgICAgIGlmIChzZXR0aW5ncy5jbG9zZV9vbl9jbGljayAmJiAhcGFyZW50Lmhhc0NsYXNzKCdoYXMtc3VibWVudScpICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2JhY2snKSkge1xyXG4gICAgICAgICAgICBzZWxmLmhpZGUuY2FsbChzZWxmLCBtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgsIHNlbGYuZ2V0X3dyYXBwZXIoZSkpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIGJvdHRvbV9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoUyh0aGlzKS5wYXJlbnQoKS5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIFModGhpcykuc2libGluZ3MoJy50b3Atc3VibWVudScpLnRvZ2dsZUNsYXNzKG1vdmVfY2xhc3MgKyBib3R0b21fcG9zdGZpeCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBib3R0b21fcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcudG9wLW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAvL2VuZCBvZiB0b3AgY2FudmFzXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmJvdHRvbS1vZmYtY2FudmFzLXRvZ2dsZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3RvZ2dsZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3Mub3Blbl9tZXRob2QgIT09ICdvdmVybGFwJykge1xyXG4gICAgICAgICAgICBTKCcuYm90dG9tLXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLmJvdHRvbS1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmJvdHRvbS1vZmYtY2FudmFzLW1lbnUgYScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICB2YXIgc2V0dGluZ3MgPSBzZWxmLmdldF9zZXR0aW5ncyhlKTtcclxuICAgICAgICAgIHZhciBwYXJlbnQgPSBTKHRoaXMpLnBhcmVudCgpO1xyXG5cclxuICAgICAgICAgIGlmIChzZXR0aW5ncy5jbG9zZV9vbl9jbGljayAmJiAhcGFyZW50Lmhhc0NsYXNzKCdoYXMtc3VibWVudScpICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2JhY2snKSkge1xyXG4gICAgICAgICAgICBzZWxmLmhpZGUuY2FsbChzZWxmLCBtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgsIHNlbGYuZ2V0X3dyYXBwZXIoZSkpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoUyh0aGlzKS5wYXJlbnQoKS5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIFModGhpcykuc2libGluZ3MoJy5ib3R0b20tc3VibWVudScpLnRvZ2dsZUNsYXNzKG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcuYm90dG9tLW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAvL2VuZCBvZiBib3R0b21cclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcuZXhpdC1vZmYtY2FudmFzJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuY2xpY2tfcmVtb3ZlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgUygnLnJpZ2h0LXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgbGVmdF9wb3N0Zml4KTtcclxuICAgICAgICAgIGlmIChyaWdodF9wb3N0Zml4KSB7XHJcbiAgICAgICAgICAgIHNlbGYuY2xpY2tfcmVtb3ZlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4KTtcclxuICAgICAgICAgICAgUygnLmxlZnQtc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcuZXhpdC1vZmYtY2FudmFzJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuY2xpY2tfcmVtb3ZlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgJCgnLmxlZnQtb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ2ZhbHNlJyk7XHJcbiAgICAgICAgICBpZiAocmlnaHRfcG9zdGZpeCkge1xyXG4gICAgICAgICAgICBzZWxmLmNsaWNrX3JlbW92ZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgcmlnaHRfcG9zdGZpeCk7XHJcbiAgICAgICAgICAgICQoJy5yaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5leGl0LW9mZi1jYW52YXMnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIFMoJy5ib3R0b20tc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCk7XHJcbiAgICAgICAgICBpZiAoYm90dG9tX3Bvc3RmaXgpIHtcclxuICAgICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIGJvdHRvbV9wb3N0Zml4KTtcclxuICAgICAgICAgICAgUygnLnRvcC1zdWJtZW51JykucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy5ib3R0b20tb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5leGl0LW9mZi1jYW52YXMnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgICQoJy50b3Atb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ2ZhbHNlJyk7XHJcbiAgICAgICAgICBpZiAoYm90dG9tX3Bvc3RmaXgpIHtcclxuICAgICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIGJvdHRvbV9wb3N0Zml4KTtcclxuICAgICAgICAgICAgJCgnLmJvdHRvbS1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgdG9nZ2xlIDogZnVuY3Rpb24gKGNsYXNzX25hbWUsICRvZmZfY2FudmFzKSB7XHJcbiAgICAgICRvZmZfY2FudmFzID0gJG9mZl9jYW52YXMgfHwgdGhpcy5nZXRfd3JhcHBlcigpO1xyXG4gICAgICBpZiAoJG9mZl9jYW52YXMuaXMoJy4nICsgY2xhc3NfbmFtZSkpIHtcclxuICAgICAgICB0aGlzLmhpZGUoY2xhc3NfbmFtZSwgJG9mZl9jYW52YXMpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc2hvdyhjbGFzc19uYW1lLCAkb2ZmX2NhbnZhcyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2hvdyA6IGZ1bmN0aW9uIChjbGFzc19uYW1lLCAkb2ZmX2NhbnZhcykge1xyXG4gICAgICAkb2ZmX2NhbnZhcyA9ICRvZmZfY2FudmFzIHx8IHRoaXMuZ2V0X3dyYXBwZXIoKTtcclxuICAgICAgJG9mZl9jYW52YXMudHJpZ2dlcignb3Blbi5mbmR0bi5vZmZjYW52YXMnKTtcclxuICAgICAgJG9mZl9jYW52YXMuYWRkQ2xhc3MoY2xhc3NfbmFtZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGUgOiBmdW5jdGlvbiAoY2xhc3NfbmFtZSwgJG9mZl9jYW52YXMpIHtcclxuICAgICAgJG9mZl9jYW52YXMgPSAkb2ZmX2NhbnZhcyB8fCB0aGlzLmdldF93cmFwcGVyKCk7XHJcbiAgICAgICRvZmZfY2FudmFzLnRyaWdnZXIoJ2Nsb3NlLmZuZHRuLm9mZmNhbnZhcycpO1xyXG4gICAgICAkb2ZmX2NhbnZhcy5yZW1vdmVDbGFzcyhjbGFzc19uYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgY2xpY2tfdG9nZ2xlX2NsYXNzIDogZnVuY3Rpb24gKGUsIGNsYXNzX25hbWUpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB2YXIgJG9mZl9jYW52YXMgPSB0aGlzLmdldF93cmFwcGVyKGUpO1xyXG4gICAgICB0aGlzLnRvZ2dsZShjbGFzc19uYW1lLCAkb2ZmX2NhbnZhcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGNsaWNrX3JlbW92ZV9jbGFzcyA6IGZ1bmN0aW9uIChlLCBjbGFzc19uYW1lKSB7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdmFyICRvZmZfY2FudmFzID0gdGhpcy5nZXRfd3JhcHBlcihlKTtcclxuICAgICAgdGhpcy5oaWRlKGNsYXNzX25hbWUsICRvZmZfY2FudmFzKTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0X3NldHRpbmdzIDogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyIG9mZmNhbnZhcyAgPSB0aGlzLlMoZS50YXJnZXQpLmNsb3Nlc3QoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJyk7XHJcbiAgICAgIHJldHVybiBvZmZjYW52YXMuZGF0YSh0aGlzLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHRoaXMuc2V0dGluZ3M7XHJcbiAgICB9LFxyXG5cclxuICAgIGdldF93cmFwcGVyIDogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyICRvZmZfY2FudmFzID0gdGhpcy5TKGUgPyBlLnRhcmdldCA6IHRoaXMuc2NvcGUpLmNsb3Nlc3QoJy5vZmYtY2FudmFzLXdyYXAnKTtcclxuXHJcbiAgICAgIGlmICgkb2ZmX2NhbnZhcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAkb2ZmX2NhbnZhcyA9IHRoaXMuUygnLm9mZi1jYW52YXMtd3JhcCcpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiAkb2ZmX2NhbnZhcztcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge31cclxuICB9O1xyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIG5vb3AgPSBmdW5jdGlvbiAoKSB7fTtcclxuXHJcbiAgdmFyIE9yYml0ID0gZnVuY3Rpb24gKGVsLCBzZXR0aW5ncykge1xyXG4gICAgLy8gRG9uJ3QgcmVpbml0aWFsaXplIHBsdWdpblxyXG4gICAgaWYgKGVsLmhhc0NsYXNzKHNldHRpbmdzLnNsaWRlc19jb250YWluZXJfY2xhc3MpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBjb250YWluZXIsXHJcbiAgICAgICAgc2xpZGVzX2NvbnRhaW5lciA9IGVsLFxyXG4gICAgICAgIG51bWJlcl9jb250YWluZXIsXHJcbiAgICAgICAgYnVsbGV0c19jb250YWluZXIsXHJcbiAgICAgICAgdGltZXJfY29udGFpbmVyLFxyXG4gICAgICAgIGlkeCA9IDAsXHJcbiAgICAgICAgYW5pbWF0ZSxcclxuICAgICAgICB0aW1lcixcclxuICAgICAgICBsb2NrZWQgPSBmYWxzZSxcclxuICAgICAgICBhZGp1c3RfaGVpZ2h0X2FmdGVyID0gZmFsc2U7XHJcblxyXG4gICAgc2VsZi5zbGlkZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiBzbGlkZXNfY29udGFpbmVyLmNoaWxkcmVuKHNldHRpbmdzLnNsaWRlX3NlbGVjdG9yKTtcclxuICAgIH07XHJcblxyXG4gICAgc2VsZi5zbGlkZXMoKS5maXJzdCgpLmFkZENsYXNzKHNldHRpbmdzLmFjdGl2ZV9zbGlkZV9jbGFzcyk7XHJcblxyXG4gICAgc2VsZi51cGRhdGVfc2xpZGVfbnVtYmVyID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgIGlmIChzZXR0aW5ncy5zbGlkZV9udW1iZXIpIHtcclxuICAgICAgICBudW1iZXJfY29udGFpbmVyLmZpbmQoJ3NwYW46Zmlyc3QnKS50ZXh0KHBhcnNlSW50KGluZGV4KSArIDEpO1xyXG4gICAgICAgIG51bWJlcl9jb250YWluZXIuZmluZCgnc3BhbjpsYXN0JykudGV4dChzZWxmLnNsaWRlcygpLmxlbmd0aCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHNldHRpbmdzLmJ1bGxldHMpIHtcclxuICAgICAgICBidWxsZXRzX2NvbnRhaW5lci5jaGlsZHJlbigpLnJlbW92ZUNsYXNzKHNldHRpbmdzLmJ1bGxldHNfYWN0aXZlX2NsYXNzKTtcclxuICAgICAgICAkKGJ1bGxldHNfY29udGFpbmVyLmNoaWxkcmVuKCkuZ2V0KGluZGV4KSkuYWRkQ2xhc3Moc2V0dGluZ3MuYnVsbGV0c19hY3RpdmVfY2xhc3MpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYudXBkYXRlX2FjdGl2ZV9saW5rID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgIHZhciBsaW5rID0gJCgnW2RhdGEtb3JiaXQtbGluaz1cIicgKyBzZWxmLnNsaWRlcygpLmVxKGluZGV4KS5hdHRyKCdkYXRhLW9yYml0LXNsaWRlJykgKyAnXCJdJyk7XHJcbiAgICAgIGxpbmsuc2libGluZ3MoKS5yZW1vdmVDbGFzcyhzZXR0aW5ncy5idWxsZXRzX2FjdGl2ZV9jbGFzcyk7XHJcbiAgICAgIGxpbmsuYWRkQ2xhc3Moc2V0dGluZ3MuYnVsbGV0c19hY3RpdmVfY2xhc3MpO1xyXG4gICAgfTtcclxuXHJcbiAgICBzZWxmLmJ1aWxkX21hcmt1cCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2xpZGVzX2NvbnRhaW5lci53cmFwKCc8ZGl2IGNsYXNzPVwiJyArIHNldHRpbmdzLmNvbnRhaW5lcl9jbGFzcyArICdcIj48L2Rpdj4nKTtcclxuICAgICAgY29udGFpbmVyID0gc2xpZGVzX2NvbnRhaW5lci5wYXJlbnQoKTtcclxuICAgICAgc2xpZGVzX2NvbnRhaW5lci5hZGRDbGFzcyhzZXR0aW5ncy5zbGlkZXNfY29udGFpbmVyX2NsYXNzKTtcclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5zdGFja19vbl9zbWFsbCkge1xyXG4gICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzZXR0aW5ncy5zdGFja19vbl9zbWFsbF9jbGFzcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5uYXZpZ2F0aW9uX2Fycm93cykge1xyXG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmQoJCgnPGEgaHJlZj1cIiNcIj48c3Bhbj48L3NwYW4+PC9hPicpLmFkZENsYXNzKHNldHRpbmdzLnByZXZfY2xhc3MpKTtcclxuICAgICAgICBjb250YWluZXIuYXBwZW5kKCQoJzxhIGhyZWY9XCIjXCI+PHNwYW4+PC9zcGFuPjwvYT4nKS5hZGRDbGFzcyhzZXR0aW5ncy5uZXh0X2NsYXNzKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy50aW1lcikge1xyXG4gICAgICAgIHRpbWVyX2NvbnRhaW5lciA9ICQoJzxkaXY+JykuYWRkQ2xhc3Moc2V0dGluZ3MudGltZXJfY29udGFpbmVyX2NsYXNzKTtcclxuICAgICAgICB0aW1lcl9jb250YWluZXIuYXBwZW5kKCc8c3Bhbj4nKTtcclxuICAgICAgICB0aW1lcl9jb250YWluZXIuYXBwZW5kKCQoJzxkaXY+JykuYWRkQ2xhc3Moc2V0dGluZ3MudGltZXJfcHJvZ3Jlc3NfY2xhc3MpKTtcclxuICAgICAgICB0aW1lcl9jb250YWluZXIuYWRkQ2xhc3Moc2V0dGluZ3MudGltZXJfcGF1c2VkX2NsYXNzKTtcclxuICAgICAgICBjb250YWluZXIuYXBwZW5kKHRpbWVyX2NvbnRhaW5lcik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5zbGlkZV9udW1iZXIpIHtcclxuICAgICAgICBudW1iZXJfY29udGFpbmVyID0gJCgnPGRpdj4nKS5hZGRDbGFzcyhzZXR0aW5ncy5zbGlkZV9udW1iZXJfY2xhc3MpO1xyXG4gICAgICAgIG51bWJlcl9jb250YWluZXIuYXBwZW5kKCc8c3Bhbj48L3NwYW4+ICcgKyBzZXR0aW5ncy5zbGlkZV9udW1iZXJfdGV4dCArICcgPHNwYW4+PC9zcGFuPicpO1xyXG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmQobnVtYmVyX2NvbnRhaW5lcik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5idWxsZXRzKSB7XHJcbiAgICAgICAgYnVsbGV0c19jb250YWluZXIgPSAkKCc8b2w+JykuYWRkQ2xhc3Moc2V0dGluZ3MuYnVsbGV0c19jb250YWluZXJfY2xhc3MpO1xyXG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmQoYnVsbGV0c19jb250YWluZXIpO1xyXG4gICAgICAgIGJ1bGxldHNfY29udGFpbmVyLndyYXAoJzxkaXYgY2xhc3M9XCJvcmJpdC1idWxsZXRzLWNvbnRhaW5lclwiPjwvZGl2PicpO1xyXG4gICAgICAgIHNlbGYuc2xpZGVzKCkuZWFjaChmdW5jdGlvbiAoaWR4LCBlbCkge1xyXG4gICAgICAgICAgdmFyIGJ1bGxldCA9ICQoJzxsaT4nKS5hdHRyKCdkYXRhLW9yYml0LXNsaWRlJywgaWR4KS5vbignY2xpY2snLCBzZWxmLmxpbmtfYnVsbGV0KTs7XHJcbiAgICAgICAgICBidWxsZXRzX2NvbnRhaW5lci5hcHBlbmQoYnVsbGV0KTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgc2VsZi5fZ290byA9IGZ1bmN0aW9uIChuZXh0X2lkeCwgc3RhcnRfdGltZXIpIHtcclxuICAgICAgLy8gaWYgKGxvY2tlZCkge3JldHVybiBmYWxzZTt9XHJcbiAgICAgIGlmIChuZXh0X2lkeCA9PT0gaWR4KSB7cmV0dXJuIGZhbHNlO31cclxuICAgICAgaWYgKHR5cGVvZiB0aW1lciA9PT0gJ29iamVjdCcpIHt0aW1lci5yZXN0YXJ0KCk7fVxyXG4gICAgICB2YXIgc2xpZGVzID0gc2VsZi5zbGlkZXMoKTtcclxuXHJcbiAgICAgIHZhciBkaXIgPSAnbmV4dCc7XHJcbiAgICAgIGxvY2tlZCA9IHRydWU7XHJcbiAgICAgIGlmIChuZXh0X2lkeCA8IGlkeCkge2RpciA9ICdwcmV2Jzt9XHJcbiAgICAgIGlmIChuZXh0X2lkeCA+PSBzbGlkZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncy5jaXJjdWxhcikge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBuZXh0X2lkeCA9IDA7XHJcbiAgICAgIH0gZWxzZSBpZiAobmV4dF9pZHggPCAwKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncy5jaXJjdWxhcikge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBuZXh0X2lkeCA9IHNsaWRlcy5sZW5ndGggLSAxO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY3VycmVudCA9ICQoc2xpZGVzLmdldChpZHgpKTtcclxuICAgICAgdmFyIG5leHQgPSAkKHNsaWRlcy5nZXQobmV4dF9pZHgpKTtcclxuXHJcbiAgICAgIGN1cnJlbnQuY3NzKCd6SW5kZXgnLCAyKTtcclxuICAgICAgY3VycmVudC5yZW1vdmVDbGFzcyhzZXR0aW5ncy5hY3RpdmVfc2xpZGVfY2xhc3MpO1xyXG4gICAgICBuZXh0LmNzcygnekluZGV4JywgNCkuYWRkQ2xhc3Moc2V0dGluZ3MuYWN0aXZlX3NsaWRlX2NsYXNzKTtcclxuXHJcbiAgICAgIHNsaWRlc19jb250YWluZXIudHJpZ2dlcignYmVmb3JlLXNsaWRlLWNoYW5nZS5mbmR0bi5vcmJpdCcpO1xyXG4gICAgICBzZXR0aW5ncy5iZWZvcmVfc2xpZGVfY2hhbmdlKCk7XHJcbiAgICAgIHNlbGYudXBkYXRlX2FjdGl2ZV9saW5rKG5leHRfaWR4KTtcclxuXHJcbiAgICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdW5sb2NrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgaWR4ID0gbmV4dF9pZHg7XHJcbiAgICAgICAgICBsb2NrZWQgPSBmYWxzZTtcclxuICAgICAgICAgIGlmIChzdGFydF90aW1lciA9PT0gdHJ1ZSkge3RpbWVyID0gc2VsZi5jcmVhdGVfdGltZXIoKTsgdGltZXIuc3RhcnQoKTt9XHJcbiAgICAgICAgICBzZWxmLnVwZGF0ZV9zbGlkZV9udW1iZXIoaWR4KTtcclxuICAgICAgICAgIHNsaWRlc19jb250YWluZXIudHJpZ2dlcignYWZ0ZXItc2xpZGUtY2hhbmdlLmZuZHRuLm9yYml0JywgW3tzbGlkZV9udW1iZXIgOiBpZHgsIHRvdGFsX3NsaWRlcyA6IHNsaWRlcy5sZW5ndGh9XSk7XHJcbiAgICAgICAgICBzZXR0aW5ncy5hZnRlcl9zbGlkZV9jaGFuZ2UoaWR4LCBzbGlkZXMubGVuZ3RoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmIChzbGlkZXNfY29udGFpbmVyLm91dGVySGVpZ2h0KCkgIT0gbmV4dC5vdXRlckhlaWdodCgpICYmIHNldHRpbmdzLnZhcmlhYmxlX2hlaWdodCkge1xyXG4gICAgICAgICAgc2xpZGVzX2NvbnRhaW5lci5hbmltYXRlKHsnaGVpZ2h0JzogbmV4dC5vdXRlckhlaWdodCgpfSwgMjUwLCAnbGluZWFyJywgdW5sb2NrKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdW5sb2NrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgaWYgKHNsaWRlcy5sZW5ndGggPT09IDEpIHtjYWxsYmFjaygpOyByZXR1cm4gZmFsc2U7fVxyXG5cclxuICAgICAgdmFyIHN0YXJ0X2FuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoZGlyID09PSAnbmV4dCcpIHthbmltYXRlLm5leHQoY3VycmVudCwgbmV4dCwgY2FsbGJhY2spO31cclxuICAgICAgICBpZiAoZGlyID09PSAncHJldicpIHthbmltYXRlLnByZXYoY3VycmVudCwgbmV4dCwgY2FsbGJhY2spO31cclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChuZXh0Lm91dGVySGVpZ2h0KCkgPiBzbGlkZXNfY29udGFpbmVyLm91dGVySGVpZ2h0KCkgJiYgc2V0dGluZ3MudmFyaWFibGVfaGVpZ2h0KSB7XHJcbiAgICAgICAgc2xpZGVzX2NvbnRhaW5lci5hbmltYXRlKHsnaGVpZ2h0JzogbmV4dC5vdXRlckhlaWdodCgpfSwgMjUwLCAnbGluZWFyJywgc3RhcnRfYW5pbWF0aW9uKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzdGFydF9hbmltYXRpb24oKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBzZWxmLm5leHQgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIHNlbGYuX2dvdG8oaWR4ICsgMSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYucHJldiA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgc2VsZi5fZ290byhpZHggLSAxKTtcclxuICAgIH07XHJcblxyXG4gICAgc2VsZi5saW5rX2N1c3RvbSA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdmFyIGxpbmsgPSAkKHRoaXMpLmF0dHIoJ2RhdGEtb3JiaXQtbGluaycpO1xyXG4gICAgICBpZiAoKHR5cGVvZiBsaW5rID09PSAnc3RyaW5nJykgJiYgKGxpbmsgPSAkLnRyaW0obGluaykpICE9ICcnKSB7XHJcbiAgICAgICAgdmFyIHNsaWRlID0gY29udGFpbmVyLmZpbmQoJ1tkYXRhLW9yYml0LXNsaWRlPScgKyBsaW5rICsgJ10nKTtcclxuICAgICAgICBpZiAoc2xpZGUuaW5kZXgoKSAhPSAtMSkge3NlbGYuX2dvdG8oc2xpZGUuaW5kZXgoKSk7fVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYubGlua19idWxsZXQgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICB2YXIgaW5kZXggPSAkKHRoaXMpLmF0dHIoJ2RhdGEtb3JiaXQtc2xpZGUnKTtcclxuICAgICAgaWYgKCh0eXBlb2YgaW5kZXggPT09ICdzdHJpbmcnKSAmJiAoaW5kZXggPSAkLnRyaW0oaW5kZXgpKSAhPSAnJykge1xyXG4gICAgICAgIGlmIChpc05hTihwYXJzZUludChpbmRleCkpKSB7XHJcbiAgICAgICAgICB2YXIgc2xpZGUgPSBjb250YWluZXIuZmluZCgnW2RhdGEtb3JiaXQtc2xpZGU9JyArIGluZGV4ICsgJ10nKTtcclxuICAgICAgICAgIGlmIChzbGlkZS5pbmRleCgpICE9IC0xKSB7c2VsZi5fZ290byhzbGlkZS5pbmRleCgpICsgMSk7fVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzZWxmLl9nb3RvKHBhcnNlSW50KGluZGV4KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHNlbGYudGltZXJfY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuX2dvdG8oaWR4ICsgMSwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZi5jb21wdXRlX2RpbWVuc2lvbnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBjdXJyZW50ID0gJChzZWxmLnNsaWRlcygpLmdldChpZHgpKTtcclxuICAgICAgdmFyIGggPSBjdXJyZW50Lm91dGVySGVpZ2h0KCk7XHJcbiAgICAgIGlmICghc2V0dGluZ3MudmFyaWFibGVfaGVpZ2h0KSB7XHJcbiAgICAgICAgc2VsZi5zbGlkZXMoKS5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICBpZiAoJCh0aGlzKS5vdXRlckhlaWdodCgpID4gaCkgeyBoID0gJCh0aGlzKS5vdXRlckhlaWdodCgpOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgc2xpZGVzX2NvbnRhaW5lci5oZWlnaHQoaCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYuY3JlYXRlX3RpbWVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgdCA9IG5ldyBUaW1lcihcclxuICAgICAgICBjb250YWluZXIuZmluZCgnLicgKyBzZXR0aW5ncy50aW1lcl9jb250YWluZXJfY2xhc3MpLFxyXG4gICAgICAgIHNldHRpbmdzLFxyXG4gICAgICAgIHNlbGYudGltZXJfY2FsbGJhY2tcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIHNlbGYuc3RvcF90aW1lciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKHR5cGVvZiB0aW1lciA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICB0aW1lci5zdG9wKCk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgc2VsZi50b2dnbGVfdGltZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciB0ID0gY29udGFpbmVyLmZpbmQoJy4nICsgc2V0dGluZ3MudGltZXJfY29udGFpbmVyX2NsYXNzKTtcclxuICAgICAgaWYgKHQuaGFzQ2xhc3Moc2V0dGluZ3MudGltZXJfcGF1c2VkX2NsYXNzKSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdGltZXIgPT09ICd1bmRlZmluZWQnKSB7dGltZXIgPSBzZWxmLmNyZWF0ZV90aW1lcigpO31cclxuICAgICAgICB0aW1lci5zdGFydCgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdGltZXIgPT09ICdvYmplY3QnKSB7dGltZXIuc3RvcCgpO31cclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBzZWxmLmluaXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuYnVpbGRfbWFya3VwKCk7XHJcbiAgICAgIGlmIChzZXR0aW5ncy50aW1lcikge1xyXG4gICAgICAgIHRpbWVyID0gc2VsZi5jcmVhdGVfdGltZXIoKTtcclxuICAgICAgICBGb3VuZGF0aW9uLnV0aWxzLmltYWdlX2xvYWRlZCh0aGlzLnNsaWRlcygpLmNoaWxkcmVuKCdpbWcnKSwgdGltZXIuc3RhcnQpO1xyXG4gICAgICB9XHJcbiAgICAgIGFuaW1hdGUgPSBuZXcgRmFkZUFuaW1hdGlvbihzZXR0aW5ncywgc2xpZGVzX2NvbnRhaW5lcik7XHJcbiAgICAgIGlmIChzZXR0aW5ncy5hbmltYXRpb24gPT09ICdzbGlkZScpIHtcclxuICAgICAgICBhbmltYXRlID0gbmV3IFNsaWRlQW5pbWF0aW9uKHNldHRpbmdzLCBzbGlkZXNfY29udGFpbmVyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29udGFpbmVyLm9uKCdjbGljaycsICcuJyArIHNldHRpbmdzLm5leHRfY2xhc3MsIHNlbGYubmV4dCk7XHJcbiAgICAgIGNvbnRhaW5lci5vbignY2xpY2snLCAnLicgKyBzZXR0aW5ncy5wcmV2X2NsYXNzLCBzZWxmLnByZXYpO1xyXG5cclxuICAgICAgaWYgKHNldHRpbmdzLm5leHRfb25fY2xpY2spIHtcclxuICAgICAgICBjb250YWluZXIub24oJ2NsaWNrJywgJy4nICsgc2V0dGluZ3Muc2xpZGVzX2NvbnRhaW5lcl9jbGFzcyArICcgW2RhdGEtb3JiaXQtc2xpZGVdJywgc2VsZi5saW5rX2J1bGxldCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnRhaW5lci5vbignY2xpY2snLCBzZWxmLnRvZ2dsZV90aW1lcik7XHJcbiAgICAgIGlmIChzZXR0aW5ncy5zd2lwZSkge1xyXG4gICAgICAgIGNvbnRhaW5lci5vbigndG91Y2hzdGFydC5mbmR0bi5vcmJpdCcsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBpZiAoIWUudG91Y2hlcykge2UgPSBlLm9yaWdpbmFsRXZlbnQ7fVxyXG4gICAgICAgICAgdmFyIGRhdGEgPSB7XHJcbiAgICAgICAgICAgIHN0YXJ0X3BhZ2VfeCA6IGUudG91Y2hlc1swXS5wYWdlWCxcclxuICAgICAgICAgICAgc3RhcnRfcGFnZV95IDogZS50b3VjaGVzWzBdLnBhZ2VZLFxyXG4gICAgICAgICAgICBzdGFydF90aW1lIDogKG5ldyBEYXRlKCkpLmdldFRpbWUoKSxcclxuICAgICAgICAgICAgZGVsdGFfeCA6IDAsXHJcbiAgICAgICAgICAgIGlzX3Njcm9sbGluZyA6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIGNvbnRhaW5lci5kYXRhKCdzd2lwZS10cmFuc2l0aW9uJywgZGF0YSk7XHJcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCd0b3VjaG1vdmUuZm5kdG4ub3JiaXQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgaWYgKCFlLnRvdWNoZXMpIHtcclxuICAgICAgICAgICAgZSA9IGUub3JpZ2luYWxFdmVudDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIElnbm9yZSBwaW5jaC96b29tIGV2ZW50c1xyXG4gICAgICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggPiAxIHx8IGUuc2NhbGUgJiYgZS5zY2FsZSAhPT0gMSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdmFyIGRhdGEgPSBjb250YWluZXIuZGF0YSgnc3dpcGUtdHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhID09PSAndW5kZWZpbmVkJykge2RhdGEgPSB7fTt9XHJcblxyXG4gICAgICAgICAgZGF0YS5kZWx0YV94ID0gZS50b3VjaGVzWzBdLnBhZ2VYIC0gZGF0YS5zdGFydF9wYWdlX3g7XHJcblxyXG4gICAgICAgICAgaWYgKCB0eXBlb2YgZGF0YS5pc19zY3JvbGxpbmcgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgIGRhdGEuaXNfc2Nyb2xsaW5nID0gISEoIGRhdGEuaXNfc2Nyb2xsaW5nIHx8IE1hdGguYWJzKGRhdGEuZGVsdGFfeCkgPCBNYXRoLmFicyhlLnRvdWNoZXNbMF0ucGFnZVkgLSBkYXRhLnN0YXJ0X3BhZ2VfeSkgKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoIWRhdGEuaXNfc2Nyb2xsaW5nICYmICFkYXRhLmFjdGl2ZSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZGF0YS5kZWx0YV94IDwgMCkgPyAoaWR4ICsgMSkgOiAoaWR4IC0gMSk7XHJcbiAgICAgICAgICAgIGRhdGEuYWN0aXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VsZi5fZ290byhkaXJlY3Rpb24pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCd0b3VjaGVuZC5mbmR0bi5vcmJpdCcsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBjb250YWluZXIuZGF0YSgnc3dpcGUtdHJhbnNpdGlvbicsIHt9KTtcclxuICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgICBjb250YWluZXIub24oJ21vdXNlZW50ZXIuZm5kdG4ub3JiaXQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGlmIChzZXR0aW5ncy50aW1lciAmJiBzZXR0aW5ncy5wYXVzZV9vbl9ob3Zlcikge1xyXG4gICAgICAgICAgc2VsZi5zdG9wX3RpbWVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAub24oJ21vdXNlbGVhdmUuZm5kdG4ub3JiaXQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGlmIChzZXR0aW5ncy50aW1lciAmJiBzZXR0aW5ncy5yZXN1bWVfb25fbW91c2VvdXQpIHtcclxuICAgICAgICAgIHRpbWVyLnN0YXJ0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICdbZGF0YS1vcmJpdC1saW5rXScsIHNlbGYubGlua19jdXN0b20pO1xyXG4gICAgICAkKHdpbmRvdykub24oJ2xvYWQgcmVzaXplJywgc2VsZi5jb21wdXRlX2RpbWVuc2lvbnMpO1xyXG4gICAgICBGb3VuZGF0aW9uLnV0aWxzLmltYWdlX2xvYWRlZCh0aGlzLnNsaWRlcygpLmNoaWxkcmVuKCdpbWcnKSwgc2VsZi5jb21wdXRlX2RpbWVuc2lvbnMpO1xyXG4gICAgICBGb3VuZGF0aW9uLnV0aWxzLmltYWdlX2xvYWRlZCh0aGlzLnNsaWRlcygpLmNoaWxkcmVuKCdpbWcnKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnRhaW5lci5wcmV2KCcuJyArIHNldHRpbmdzLnByZWxvYWRlcl9jbGFzcykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcclxuICAgICAgICBzZWxmLnVwZGF0ZV9zbGlkZV9udW1iZXIoMCk7XHJcbiAgICAgICAgc2VsZi51cGRhdGVfYWN0aXZlX2xpbmsoMCk7XHJcbiAgICAgICAgc2xpZGVzX2NvbnRhaW5lci50cmlnZ2VyKCdyZWFkeS5mbmR0bi5vcmJpdCcpO1xyXG4gICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgc2VsZi5pbml0KCk7XHJcbiAgfTtcclxuXHJcbiAgdmFyIFRpbWVyID0gZnVuY3Rpb24gKGVsLCBzZXR0aW5ncywgY2FsbGJhY2spIHtcclxuICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICBkdXJhdGlvbiA9IHNldHRpbmdzLnRpbWVyX3NwZWVkLFxyXG4gICAgICAgIHByb2dyZXNzID0gZWwuZmluZCgnLicgKyBzZXR0aW5ncy50aW1lcl9wcm9ncmVzc19jbGFzcyksXHJcbiAgICAgICAgc3RhcnQsXHJcbiAgICAgICAgdGltZW91dCxcclxuICAgICAgICBsZWZ0ID0gLTE7XHJcblxyXG4gICAgdGhpcy51cGRhdGVfcHJvZ3Jlc3MgPSBmdW5jdGlvbiAodykge1xyXG4gICAgICB2YXIgbmV3X3Byb2dyZXNzID0gcHJvZ3Jlc3MuY2xvbmUoKTtcclxuICAgICAgbmV3X3Byb2dyZXNzLmF0dHIoJ3N0eWxlJywgJycpO1xyXG4gICAgICBuZXdfcHJvZ3Jlc3MuY3NzKCd3aWR0aCcsIHcgKyAnJScpO1xyXG4gICAgICBwcm9ncmVzcy5yZXBsYWNlV2l0aChuZXdfcHJvZ3Jlc3MpO1xyXG4gICAgICBwcm9ncmVzcyA9IG5ld19wcm9ncmVzcztcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5yZXN0YXJ0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XHJcbiAgICAgIGVsLmFkZENsYXNzKHNldHRpbmdzLnRpbWVyX3BhdXNlZF9jbGFzcyk7XHJcbiAgICAgIGxlZnQgPSAtMTtcclxuICAgICAgc2VsZi51cGRhdGVfcHJvZ3Jlc3MoMCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICghZWwuaGFzQ2xhc3Moc2V0dGluZ3MudGltZXJfcGF1c2VkX2NsYXNzKSkge3JldHVybiB0cnVlO31cclxuICAgICAgbGVmdCA9IChsZWZ0ID09PSAtMSkgPyBkdXJhdGlvbiA6IGxlZnQ7XHJcbiAgICAgIGVsLnJlbW92ZUNsYXNzKHNldHRpbmdzLnRpbWVyX3BhdXNlZF9jbGFzcyk7XHJcbiAgICAgIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICAgIHByb2dyZXNzLmFuaW1hdGUoeyd3aWR0aCcgOiAnMTAwJSd9LCBsZWZ0LCAnbGluZWFyJyk7XHJcbiAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBzZWxmLnJlc3RhcnQoKTtcclxuICAgICAgICBjYWxsYmFjaygpO1xyXG4gICAgICB9LCBsZWZ0KTtcclxuICAgICAgZWwudHJpZ2dlcigndGltZXItc3RhcnRlZC5mbmR0bi5vcmJpdCcpXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuc3RvcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKGVsLmhhc0NsYXNzKHNldHRpbmdzLnRpbWVyX3BhdXNlZF9jbGFzcykpIHtyZXR1cm4gdHJ1ZTt9XHJcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgZWwuYWRkQ2xhc3Moc2V0dGluZ3MudGltZXJfcGF1c2VkX2NsYXNzKTtcclxuICAgICAgdmFyIGVuZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICBsZWZ0ID0gbGVmdCAtIChlbmQgLSBzdGFydCk7XHJcbiAgICAgIHZhciB3ID0gMTAwIC0gKChsZWZ0IC8gZHVyYXRpb24pICogMTAwKTtcclxuICAgICAgc2VsZi51cGRhdGVfcHJvZ3Jlc3Modyk7XHJcbiAgICAgIGVsLnRyaWdnZXIoJ3RpbWVyLXN0b3BwZWQuZm5kdG4ub3JiaXQnKTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIFNsaWRlQW5pbWF0aW9uID0gZnVuY3Rpb24gKHNldHRpbmdzLCBjb250YWluZXIpIHtcclxuICAgIHZhciBkdXJhdGlvbiA9IHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZDtcclxuICAgIHZhciBpc19ydGwgPSAoJCgnaHRtbFtkaXI9cnRsXScpLmxlbmd0aCA9PT0gMSk7XHJcbiAgICB2YXIgbWFyZ2luID0gaXNfcnRsID8gJ21hcmdpblJpZ2h0JyA6ICdtYXJnaW5MZWZ0JztcclxuICAgIHZhciBhbmltTWFyZ2luID0ge307XHJcbiAgICBhbmltTWFyZ2luW21hcmdpbl0gPSAnMCUnO1xyXG5cclxuICAgIHRoaXMubmV4dCA9IGZ1bmN0aW9uIChjdXJyZW50LCBuZXh0LCBjYWxsYmFjaykge1xyXG4gICAgICBjdXJyZW50LmFuaW1hdGUoe21hcmdpbkxlZnQgOiAnLTEwMCUnfSwgZHVyYXRpb24pO1xyXG4gICAgICBuZXh0LmFuaW1hdGUoYW5pbU1hcmdpbiwgZHVyYXRpb24sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBjdXJyZW50LmNzcyhtYXJnaW4sICcxMDAlJyk7XHJcbiAgICAgICAgY2FsbGJhY2soKTtcclxuICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMucHJldiA9IGZ1bmN0aW9uIChjdXJyZW50LCBwcmV2LCBjYWxsYmFjaykge1xyXG4gICAgICBjdXJyZW50LmFuaW1hdGUoe21hcmdpbkxlZnQgOiAnMTAwJSd9LCBkdXJhdGlvbik7XHJcbiAgICAgIHByZXYuY3NzKG1hcmdpbiwgJy0xMDAlJyk7XHJcbiAgICAgIHByZXYuYW5pbWF0ZShhbmltTWFyZ2luLCBkdXJhdGlvbiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGN1cnJlbnQuY3NzKG1hcmdpbiwgJzEwMCUnKTtcclxuICAgICAgICBjYWxsYmFjaygpO1xyXG4gICAgICB9KTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIEZhZGVBbmltYXRpb24gPSBmdW5jdGlvbiAoc2V0dGluZ3MsIGNvbnRhaW5lcikge1xyXG4gICAgdmFyIGR1cmF0aW9uID0gc2V0dGluZ3MuYW5pbWF0aW9uX3NwZWVkO1xyXG4gICAgdmFyIGlzX3J0bCA9ICgkKCdodG1sW2Rpcj1ydGxdJykubGVuZ3RoID09PSAxKTtcclxuICAgIHZhciBtYXJnaW4gPSBpc19ydGwgPyAnbWFyZ2luUmlnaHQnIDogJ21hcmdpbkxlZnQnO1xyXG5cclxuICAgIHRoaXMubmV4dCA9IGZ1bmN0aW9uIChjdXJyZW50LCBuZXh0LCBjYWxsYmFjaykge1xyXG4gICAgICBuZXh0LmNzcyh7J21hcmdpbicgOiAnMCUnLCAnb3BhY2l0eScgOiAnMC4wMSd9KTtcclxuICAgICAgbmV4dC5hbmltYXRlKHsnb3BhY2l0eScgOicxJ30sIGR1cmF0aW9uLCAnbGluZWFyJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGN1cnJlbnQuY3NzKCdtYXJnaW4nLCAnMTAwJScpO1xyXG4gICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLnByZXYgPSBmdW5jdGlvbiAoY3VycmVudCwgcHJldiwgY2FsbGJhY2spIHtcclxuICAgICAgcHJldi5jc3MoeydtYXJnaW4nIDogJzAlJywgJ29wYWNpdHknIDogJzAuMDEnfSk7XHJcbiAgICAgIHByZXYuYW5pbWF0ZSh7J29wYWNpdHknIDogJzEnfSwgZHVyYXRpb24sICdsaW5lYXInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY3VycmVudC5jc3MoJ21hcmdpbicsICcxMDAlJyk7XHJcbiAgICAgICAgY2FsbGJhY2soKTtcclxuICAgICAgfSk7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicyA9IEZvdW5kYXRpb24ubGlicyB8fCB7fTtcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLm9yYml0ID0ge1xyXG4gICAgbmFtZSA6ICdvcmJpdCcsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGFuaW1hdGlvbiA6ICdzbGlkZScsXHJcbiAgICAgIHRpbWVyX3NwZWVkIDogMTAwMDAsXHJcbiAgICAgIHBhdXNlX29uX2hvdmVyIDogdHJ1ZSxcclxuICAgICAgcmVzdW1lX29uX21vdXNlb3V0IDogZmFsc2UsXHJcbiAgICAgIG5leHRfb25fY2xpY2sgOiB0cnVlLFxyXG4gICAgICBhbmltYXRpb25fc3BlZWQgOiA1MDAsXHJcbiAgICAgIHN0YWNrX29uX3NtYWxsIDogZmFsc2UsXHJcbiAgICAgIG5hdmlnYXRpb25fYXJyb3dzIDogdHJ1ZSxcclxuICAgICAgc2xpZGVfbnVtYmVyIDogdHJ1ZSxcclxuICAgICAgc2xpZGVfbnVtYmVyX3RleHQgOiAnb2YnLFxyXG4gICAgICBjb250YWluZXJfY2xhc3MgOiAnb3JiaXQtY29udGFpbmVyJyxcclxuICAgICAgc3RhY2tfb25fc21hbGxfY2xhc3MgOiAnb3JiaXQtc3RhY2stb24tc21hbGwnLFxyXG4gICAgICBuZXh0X2NsYXNzIDogJ29yYml0LW5leHQnLFxyXG4gICAgICBwcmV2X2NsYXNzIDogJ29yYml0LXByZXYnLFxyXG4gICAgICB0aW1lcl9jb250YWluZXJfY2xhc3MgOiAnb3JiaXQtdGltZXInLFxyXG4gICAgICB0aW1lcl9wYXVzZWRfY2xhc3MgOiAncGF1c2VkJyxcclxuICAgICAgdGltZXJfcHJvZ3Jlc3NfY2xhc3MgOiAnb3JiaXQtcHJvZ3Jlc3MnLFxyXG4gICAgICBzbGlkZXNfY29udGFpbmVyX2NsYXNzIDogJ29yYml0LXNsaWRlcy1jb250YWluZXInLFxyXG4gICAgICBwcmVsb2FkZXJfY2xhc3MgOiAncHJlbG9hZGVyJyxcclxuICAgICAgc2xpZGVfc2VsZWN0b3IgOiAnKicsXHJcbiAgICAgIGJ1bGxldHNfY29udGFpbmVyX2NsYXNzIDogJ29yYml0LWJ1bGxldHMnLFxyXG4gICAgICBidWxsZXRzX2FjdGl2ZV9jbGFzcyA6ICdhY3RpdmUnLFxyXG4gICAgICBzbGlkZV9udW1iZXJfY2xhc3MgOiAnb3JiaXQtc2xpZGUtbnVtYmVyJyxcclxuICAgICAgY2FwdGlvbl9jbGFzcyA6ICdvcmJpdC1jYXB0aW9uJyxcclxuICAgICAgYWN0aXZlX3NsaWRlX2NsYXNzIDogJ2FjdGl2ZScsXHJcbiAgICAgIG9yYml0X3RyYW5zaXRpb25fY2xhc3MgOiAnb3JiaXQtdHJhbnNpdGlvbmluZycsXHJcbiAgICAgIGJ1bGxldHMgOiB0cnVlLFxyXG4gICAgICBjaXJjdWxhciA6IHRydWUsXHJcbiAgICAgIHRpbWVyIDogdHJ1ZSxcclxuICAgICAgdmFyaWFibGVfaGVpZ2h0IDogZmFsc2UsXHJcbiAgICAgIHN3aXBlIDogdHJ1ZSxcclxuICAgICAgYmVmb3JlX3NsaWRlX2NoYW5nZSA6IG5vb3AsXHJcbiAgICAgIGFmdGVyX3NsaWRlX2NoYW5nZSA6IG5vb3BcclxuICAgIH0sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgdGhpcy5iaW5kaW5ncyhtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBldmVudHMgOiBmdW5jdGlvbiAoaW5zdGFuY2UpIHtcclxuICAgICAgdmFyIG9yYml0X2luc3RhbmNlID0gbmV3IE9yYml0KHRoaXMuUyhpbnN0YW5jZSksIHRoaXMuUyhpbnN0YW5jZSkuZGF0YSgnb3JiaXQtaW5pdCcpKTtcclxuICAgICAgdGhpcy5TKGluc3RhbmNlKS5kYXRhKHRoaXMubmFtZSArICctaW5zdGFuY2UnLCBvcmJpdF9pbnN0YW5jZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlZmxvdyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKHNlbGYuUyhzZWxmLnNjb3BlKS5pcygnW2RhdGEtb3JiaXRdJykpIHtcclxuICAgICAgICB2YXIgJGVsID0gc2VsZi5TKHNlbGYuc2NvcGUpO1xyXG4gICAgICAgIHZhciBpbnN0YW5jZSA9ICRlbC5kYXRhKHNlbGYubmFtZSArICctaW5zdGFuY2UnKTtcclxuICAgICAgICBpbnN0YW5jZS5jb21wdXRlX2RpbWVuc2lvbnMoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzZWxmLlMoJ1tkYXRhLW9yYml0XScsIHNlbGYuc2NvcGUpLmVhY2goZnVuY3Rpb24gKGlkeCwgZWwpIHtcclxuICAgICAgICAgIHZhciAkZWwgPSBzZWxmLlMoZWwpO1xyXG4gICAgICAgICAgdmFyIG9wdHMgPSBzZWxmLmRhdGFfb3B0aW9ucygkZWwpO1xyXG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gJGVsLmRhdGEoc2VsZi5uYW1lICsgJy1pbnN0YW5jZScpO1xyXG4gICAgICAgICAgaW5zdGFuY2UuY29tcHV0ZV9kaW1lbnNpb25zKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxufShqUXVlcnksIHdpbmRvdywgd2luZG93LmRvY3VtZW50KSk7XHJcblxyXG47KGZ1bmN0aW9uICgkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIHZhciBvcGVuTW9kYWxzID0gW107XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicy5yZXZlYWwgPSB7XHJcbiAgICBuYW1lIDogJ3JldmVhbCcsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgbG9ja2VkIDogZmFsc2UsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGFuaW1hdGlvbiA6ICdmYWRlQW5kUG9wJyxcclxuICAgICAgYW5pbWF0aW9uX3NwZWVkIDogMjUwLFxyXG4gICAgICBjbG9zZV9vbl9iYWNrZ3JvdW5kX2NsaWNrIDogdHJ1ZSxcclxuICAgICAgY2xvc2Vfb25fZXNjIDogdHJ1ZSxcclxuICAgICAgZGlzbWlzc19tb2RhbF9jbGFzcyA6ICdjbG9zZS1yZXZlYWwtbW9kYWwnLFxyXG4gICAgICBtdWx0aXBsZV9vcGVuZWQgOiBmYWxzZSxcclxuICAgICAgYmdfY2xhc3MgOiAncmV2ZWFsLW1vZGFsLWJnJyxcclxuICAgICAgcm9vdF9lbGVtZW50IDogJ2JvZHknLFxyXG4gICAgICBvcGVuIDogZnVuY3Rpb24oKXt9LFxyXG4gICAgICBvcGVuZWQgOiBmdW5jdGlvbigpe30sXHJcbiAgICAgIGNsb3NlIDogZnVuY3Rpb24oKXt9LFxyXG4gICAgICBjbG9zZWQgOiBmdW5jdGlvbigpe30sXHJcbiAgICAgIG9uX2FqYXhfZXJyb3I6ICQubm9vcCxcclxuICAgICAgYmcgOiAkKCcucmV2ZWFsLW1vZGFsLWJnJyksXHJcbiAgICAgIGNzcyA6IHtcclxuICAgICAgICBvcGVuIDoge1xyXG4gICAgICAgICAgJ29wYWNpdHknIDogMCxcclxuICAgICAgICAgICd2aXNpYmlsaXR5JyA6ICd2aXNpYmxlJyxcclxuICAgICAgICAgICdkaXNwbGF5JyA6ICdibG9jaydcclxuICAgICAgICB9LFxyXG4gICAgICAgIGNsb3NlIDoge1xyXG4gICAgICAgICAgJ29wYWNpdHknIDogMSxcclxuICAgICAgICAgICd2aXNpYmlsaXR5JyA6ICdoaWRkZW4nLFxyXG4gICAgICAgICAgJ2Rpc3BsYXknIDogJ25vbmUnXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICAkLmV4dGVuZCh0cnVlLCB0aGlzLnNldHRpbmdzLCBtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uIChzY29wZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBTID0gc2VsZi5TO1xyXG5cclxuICAgICAgUyh0aGlzLnNjb3BlKVxyXG4gICAgICAgIC5vZmYoJy5yZXZlYWwnKVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ucmV2ZWFsJywgJ1snICsgdGhpcy5hZGRfbmFtZXNwYWNlKCdkYXRhLXJldmVhbC1pZCcpICsgJ106bm90KFtkaXNhYmxlZF0pJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICBpZiAoIXNlbGYubG9ja2VkKSB7XHJcbiAgICAgICAgICAgIHZhciBlbGVtZW50ID0gUyh0aGlzKSxcclxuICAgICAgICAgICAgICAgIGFqYXggPSBlbGVtZW50LmRhdGEoc2VsZi5kYXRhX2F0dHIoJ3JldmVhbC1hamF4JykpLFxyXG4gICAgICAgICAgICAgICAgcmVwbGFjZUNvbnRlbnRTZWwgPSBlbGVtZW50LmRhdGEoc2VsZi5kYXRhX2F0dHIoJ3JldmVhbC1yZXBsYWNlLWNvbnRlbnQnKSk7XHJcblxyXG4gICAgICAgICAgICBzZWxmLmxvY2tlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGFqYXggPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgc2VsZi5vcGVuLmNhbGwoc2VsZiwgZWxlbWVudCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdmFyIHVybCA9IGFqYXggPT09IHRydWUgPyBlbGVtZW50LmF0dHIoJ2hyZWYnKSA6IGFqYXg7XHJcbiAgICAgICAgICAgICAgc2VsZi5vcGVuLmNhbGwoc2VsZiwgZWxlbWVudCwge3VybCA6IHVybH0sIHsgcmVwbGFjZUNvbnRlbnRTZWwgOiByZXBsYWNlQ29udGVudFNlbCB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgUyhkb2N1bWVudClcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLnJldmVhbCcsIHRoaXMuY2xvc2VfdGFyZ2V0cygpLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgaWYgKCFzZWxmLmxvY2tlZCkge1xyXG4gICAgICAgICAgICB2YXIgc2V0dGluZ3MgPSBTKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXS5vcGVuJykuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpIHx8IHNlbGYuc2V0dGluZ3MsXHJcbiAgICAgICAgICAgICAgICBiZ19jbGlja2VkID0gUyhlLnRhcmdldClbMF0gPT09IFMoJy4nICsgc2V0dGluZ3MuYmdfY2xhc3MpWzBdO1xyXG5cclxuICAgICAgICAgICAgaWYgKGJnX2NsaWNrZWQpIHtcclxuICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuY2xvc2Vfb25fYmFja2dyb3VuZF9jbGljaykge1xyXG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc2VsZi5sb2NrZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzZWxmLmNsb3NlLmNhbGwoc2VsZiwgYmdfY2xpY2tlZCA/IFMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddLm9wZW46bm90KC50b2JhY2spJykgOiBTKHRoaXMpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJykpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKFMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJywgdGhpcy5zY29wZSkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIFModGhpcy5zY29wZSlcclxuICAgICAgICAgIC8vIC5vZmYoJy5yZXZlYWwnKVxyXG4gICAgICAgICAgLm9uKCdvcGVuLmZuZHRuLnJldmVhbCcsIHRoaXMuc2V0dGluZ3Mub3BlbilcclxuICAgICAgICAgIC5vbignb3BlbmVkLmZuZHRuLnJldmVhbCcsIHRoaXMuc2V0dGluZ3Mub3BlbmVkKVxyXG4gICAgICAgICAgLm9uKCdvcGVuZWQuZm5kdG4ucmV2ZWFsJywgdGhpcy5vcGVuX3ZpZGVvKVxyXG4gICAgICAgICAgLm9uKCdjbG9zZS5mbmR0bi5yZXZlYWwnLCB0aGlzLnNldHRpbmdzLmNsb3NlKVxyXG4gICAgICAgICAgLm9uKCdjbG9zZWQuZm5kdG4ucmV2ZWFsJywgdGhpcy5zZXR0aW5ncy5jbG9zZWQpXHJcbiAgICAgICAgICAub24oJ2Nsb3NlZC5mbmR0bi5yZXZlYWwnLCB0aGlzLmNsb3NlX3ZpZGVvKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBTKHRoaXMuc2NvcGUpXHJcbiAgICAgICAgICAvLyAub2ZmKCcucmV2ZWFsJylcclxuICAgICAgICAgIC5vbignb3Blbi5mbmR0bi5yZXZlYWwnLCAnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10nLCB0aGlzLnNldHRpbmdzLm9wZW4pXHJcbiAgICAgICAgICAub24oJ29wZW5lZC5mbmR0bi5yZXZlYWwnLCAnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10nLCB0aGlzLnNldHRpbmdzLm9wZW5lZClcclxuICAgICAgICAgIC5vbignb3BlbmVkLmZuZHRuLnJldmVhbCcsICdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMub3Blbl92aWRlbylcclxuICAgICAgICAgIC5vbignY2xvc2UuZm5kdG4ucmV2ZWFsJywgJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJywgdGhpcy5zZXR0aW5ncy5jbG9zZSlcclxuICAgICAgICAgIC5vbignY2xvc2VkLmZuZHRuLnJldmVhbCcsICdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMuc2V0dGluZ3MuY2xvc2VkKVxyXG4gICAgICAgICAgLm9uKCdjbG9zZWQuZm5kdG4ucmV2ZWFsJywgJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJywgdGhpcy5jbG9zZV92aWRlbyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvLyBQQVRDSCAjMzogdHVybmluZyBvbiBrZXkgdXAgY2FwdHVyZSBvbmx5IHdoZW4gYSByZXZlYWwgd2luZG93IGlzIG9wZW5cclxuICAgIGtleV91cF9vbiA6IGZ1bmN0aW9uIChzY29wZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAvLyBQQVRDSCAjMTogZml4aW5nIG11bHRpcGxlIGtleXVwIGV2ZW50IHRyaWdnZXIgZnJvbSBzaW5nbGUga2V5IHByZXNzXHJcbiAgICAgIHNlbGYuUygnYm9keScpLm9mZigna2V5dXAuZm5kdG4ucmV2ZWFsJykub24oJ2tleXVwLmZuZHRuLnJldmVhbCcsIGZ1bmN0aW9uICggZXZlbnQgKSB7XHJcbiAgICAgICAgdmFyIG9wZW5fbW9kYWwgPSBzZWxmLlMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddLm9wZW4nKSxcclxuICAgICAgICAgICAgc2V0dGluZ3MgPSBvcGVuX21vZGFsLmRhdGEoc2VsZi5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKSB8fCBzZWxmLnNldHRpbmdzIDtcclxuICAgICAgICAvLyBQQVRDSCAjMjogbWFraW5nIHN1cmUgdGhhdCB0aGUgY2xvc2UgZXZlbnQgY2FuIGJlIGNhbGxlZCBvbmx5IHdoaWxlIHVubG9ja2VkLFxyXG4gICAgICAgIC8vICAgICAgICAgICBzbyB0aGF0IG11bHRpcGxlIGtleXVwLmZuZHRuLnJldmVhbCBldmVudHMgZG9uJ3QgcHJldmVudCBjbGVhbiBjbG9zaW5nIG9mIHRoZSByZXZlYWwgd2luZG93LlxyXG4gICAgICAgIGlmICggc2V0dGluZ3MgJiYgZXZlbnQud2hpY2ggPT09IDI3ICAmJiBzZXR0aW5ncy5jbG9zZV9vbl9lc2MgJiYgIXNlbGYubG9ja2VkKSB7IC8vIDI3IGlzIHRoZSBrZXljb2RlIGZvciB0aGUgRXNjYXBlIGtleVxyXG4gICAgICAgICAgc2VsZi5jbG9zZS5jYWxsKHNlbGYsIG9wZW5fbW9kYWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgLy8gUEFUQ0ggIzM6IHR1cm5pbmcgb24ga2V5IHVwIGNhcHR1cmUgb25seSB3aGVuIGEgcmV2ZWFsIHdpbmRvdyBpcyBvcGVuXHJcbiAgICBrZXlfdXBfb2ZmIDogZnVuY3Rpb24gKHNjb3BlKSB7XHJcbiAgICAgIHRoaXMuUygnYm9keScpLm9mZigna2V5dXAuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBvcGVuIDogZnVuY3Rpb24gKHRhcmdldCwgYWpheF9zZXR0aW5ncykge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBtb2RhbDtcclxuXHJcbiAgICAgIGlmICh0YXJnZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHRhcmdldC5zZWxlY3RvciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgIC8vIEZpbmQgdGhlIG5hbWVkIG5vZGU7IG9ubHkgdXNlIHRoZSBmaXJzdCBvbmUgZm91bmQsIHNpbmNlIHRoZSByZXN0IG9mIHRoZSBjb2RlIGFzc3VtZXMgdGhlcmUncyBvbmx5IG9uZSBub2RlXHJcbiAgICAgICAgICBtb2RhbCA9IHNlbGYuUygnIycgKyB0YXJnZXQuZGF0YShzZWxmLmRhdGFfYXR0cigncmV2ZWFsLWlkJykpKS5maXJzdCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBtb2RhbCA9IHNlbGYuUyh0aGlzLnNjb3BlKTtcclxuXHJcbiAgICAgICAgICBhamF4X3NldHRpbmdzID0gdGFyZ2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtb2RhbCA9IHNlbGYuUyh0aGlzLnNjb3BlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNldHRpbmdzID0gbW9kYWwuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpO1xyXG4gICAgICBzZXR0aW5ncyA9IHNldHRpbmdzIHx8IHRoaXMuc2V0dGluZ3M7XHJcblxyXG5cclxuICAgICAgaWYgKG1vZGFsLmhhc0NsYXNzKCdvcGVuJykgJiYgdGFyZ2V0ICE9PSB1bmRlZmluZWQgJiYgdGFyZ2V0LmF0dHIoJ2RhdGEtcmV2ZWFsLWlkJykgPT0gbW9kYWwuYXR0cignaWQnKSkge1xyXG4gICAgICAgIHJldHVybiBzZWxmLmNsb3NlKG1vZGFsKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFtb2RhbC5oYXNDbGFzcygnb3BlbicpKSB7XHJcbiAgICAgICAgdmFyIG9wZW5fbW9kYWwgPSBzZWxmLlMoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddLm9wZW4nKTtcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBtb2RhbC5kYXRhKCdjc3MtdG9wJykgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICBtb2RhbC5kYXRhKCdjc3MtdG9wJywgcGFyc2VJbnQobW9kYWwuY3NzKCd0b3AnKSwgMTApKVxyXG4gICAgICAgICAgICAuZGF0YSgnb2Zmc2V0JywgdGhpcy5jYWNoZV9vZmZzZXQobW9kYWwpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1vZGFsLmF0dHIoJ3RhYmluZGV4JywnMCcpLmF0dHIoJ2FyaWEtaGlkZGVuJywnZmFsc2UnKTtcclxuXHJcbiAgICAgICAgdGhpcy5rZXlfdXBfb24obW9kYWwpOyAgICAvLyBQQVRDSCAjMzogdHVybmluZyBvbiBrZXkgdXAgY2FwdHVyZSBvbmx5IHdoZW4gYSByZXZlYWwgd2luZG93IGlzIG9wZW5cclxuXHJcbiAgICAgICAgLy8gUHJldmVudCBuYW1lc3BhY2UgZXZlbnQgZnJvbSB0cmlnZ2VyaW5nIHR3aWNlXHJcbiAgICAgICAgbW9kYWwub24oJ29wZW4uZm5kdG4ucmV2ZWFsJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgaWYgKGUubmFtZXNwYWNlICE9PSAnZm5kdG4ucmV2ZWFsJykgcmV0dXJuO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBtb2RhbC5vbignb3Blbi5mbmR0bi5yZXZlYWwnKS50cmlnZ2VyKCdvcGVuLmZuZHRuLnJldmVhbCcpO1xyXG5cclxuICAgICAgICBpZiAob3Blbl9tb2RhbC5sZW5ndGggPCAxKSB7XHJcbiAgICAgICAgICB0aGlzLnRvZ2dsZV9iZyhtb2RhbCwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGFqYXhfc2V0dGluZ3MgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICBhamF4X3NldHRpbmdzID0ge1xyXG4gICAgICAgICAgICB1cmwgOiBhamF4X3NldHRpbmdzXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG9wZW5Nb2RhbCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYob3Blbl9tb2RhbC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGlmKHNldHRpbmdzLm11bHRpcGxlX29wZW5lZCkge1xyXG4gICAgICAgICAgICAgIHNlbGYudG9fYmFjayhvcGVuX21vZGFsKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBzZWxmLmhpZGUob3Blbl9tb2RhbCwgc2V0dGluZ3MuY3NzLmNsb3NlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIC8vIGJsOiBhZGQgdGhlIG9wZW5fbW9kYWwgdGhhdCBpc24ndCBhbHJlYWR5IGluIHRoZSBiYWNrZ3JvdW5kIHRvIHRoZSBvcGVuTW9kYWxzIGFycmF5XHJcbiAgICAgICAgICBpZihzZXR0aW5ncy5tdWx0aXBsZV9vcGVuZWQpIHtcclxuICAgICAgICAgICAgb3Blbk1vZGFscy5wdXNoKG1vZGFsKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzZWxmLnNob3cobW9kYWwsIHNldHRpbmdzLmNzcy5vcGVuKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGFqYXhfc2V0dGluZ3MgPT09ICd1bmRlZmluZWQnIHx8ICFhamF4X3NldHRpbmdzLnVybCkge1xyXG4gICAgICAgICAgb3Blbk1vZGFsKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHZhciBvbGRfc3VjY2VzcyA9IHR5cGVvZiBhamF4X3NldHRpbmdzLnN1Y2Nlc3MgIT09ICd1bmRlZmluZWQnID8gYWpheF9zZXR0aW5ncy5zdWNjZXNzIDogbnVsbDtcclxuICAgICAgICAgICQuZXh0ZW5kKGFqYXhfc2V0dGluZ3MsIHtcclxuICAgICAgICAgICAgc3VjY2VzcyA6IGZ1bmN0aW9uIChkYXRhLCB0ZXh0U3RhdHVzLCBqcVhIUikge1xyXG4gICAgICAgICAgICAgIGlmICggJC5pc0Z1bmN0aW9uKG9sZF9zdWNjZXNzKSApIHtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvbGRfc3VjY2VzcyhkYXRhLCB0ZXh0U3RhdHVzLCBqcVhIUik7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICBkYXRhID0gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygb3B0aW9ucy5yZXBsYWNlQ29udGVudFNlbCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgICAgIG1vZGFsLmZpbmQob3B0aW9ucy5yZXBsYWNlQ29udGVudFNlbCkuaHRtbChkYXRhKTtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbW9kYWwuaHRtbChkYXRhKTtcclxuICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgIHNlbGYuUyhtb2RhbCkuZm91bmRhdGlvbignc2VjdGlvbicsICdyZWZsb3cnKTtcclxuICAgICAgICAgICAgICBzZWxmLlMobW9kYWwpLmNoaWxkcmVuKCkuZm91bmRhdGlvbigpO1xyXG5cclxuICAgICAgICAgICAgICBvcGVuTW9kYWwoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgLy8gY2hlY2sgZm9yIGlmIHVzZXIgaW5pdGFsaXplZCB3aXRoIGVycm9yIGNhbGxiYWNrXHJcbiAgICAgICAgICBpZiAoc2V0dGluZ3Mub25fYWpheF9lcnJvciAhPT0gJC5ub29wKSB7XHJcbiAgICAgICAgICAgICQuZXh0ZW5kKGFqYXhfc2V0dGluZ3MsIHtcclxuICAgICAgICAgICAgICBlcnJvciA6IHNldHRpbmdzLm9uX2FqYXhfZXJyb3JcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgJC5hamF4KGFqYXhfc2V0dGluZ3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBzZWxmLlMod2luZG93KS50cmlnZ2VyKCdyZXNpemUnKTtcclxuICAgIH0sXHJcblxyXG4gICAgY2xvc2UgOiBmdW5jdGlvbiAobW9kYWwpIHtcclxuICAgICAgdmFyIG1vZGFsID0gbW9kYWwgJiYgbW9kYWwubGVuZ3RoID8gbW9kYWwgOiB0aGlzLlModGhpcy5zY29wZSksXHJcbiAgICAgICAgICBvcGVuX21vZGFscyA9IHRoaXMuUygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10ub3BlbicpLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSBtb2RhbC5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwgdGhpcy5zZXR0aW5ncyxcclxuICAgICAgICAgIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKG9wZW5fbW9kYWxzLmxlbmd0aCA+IDApIHtcclxuXHJcbiAgICAgICAgbW9kYWwucmVtb3ZlQXR0cigndGFiaW5kZXgnLCcwJykuYXR0cignYXJpYS1oaWRkZW4nLCd0cnVlJyk7XHJcblxyXG4gICAgICAgIHRoaXMubG9ja2VkID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmtleV91cF9vZmYobW9kYWwpOyAgIC8vIFBBVENIICMzOiB0dXJuaW5nIG9uIGtleSB1cCBjYXB0dXJlIG9ubHkgd2hlbiBhIHJldmVhbCB3aW5kb3cgaXMgb3BlblxyXG5cclxuICAgICAgICBtb2RhbC50cmlnZ2VyKCdjbG9zZS5mbmR0bi5yZXZlYWwnKTtcclxuXHJcbiAgICAgICAgaWYgKChzZXR0aW5ncy5tdWx0aXBsZV9vcGVuZWQgJiYgb3Blbl9tb2RhbHMubGVuZ3RoID09PSAxKSB8fCAhc2V0dGluZ3MubXVsdGlwbGVfb3BlbmVkIHx8IG1vZGFsLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgIHNlbGYudG9nZ2xlX2JnKG1vZGFsLCBmYWxzZSk7XHJcbiAgICAgICAgICBzZWxmLnRvX2Zyb250KG1vZGFsKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzZXR0aW5ncy5tdWx0aXBsZV9vcGVuZWQpIHtcclxuICAgICAgICAgIHZhciBpc0N1cnJlbnQgPSBtb2RhbC5pcygnOm5vdCgudG9iYWNrKScpO1xyXG4gICAgICAgICAgc2VsZi5oaWRlKG1vZGFsLCBzZXR0aW5ncy5jc3MuY2xvc2UsIHNldHRpbmdzKTtcclxuICAgICAgICAgIGlmKGlzQ3VycmVudCkge1xyXG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIGxhc3QgbW9kYWwgc2luY2UgaXQgaXMgbm93IGNsb3NlZFxyXG4gICAgICAgICAgICBvcGVuTW9kYWxzLnBvcCgpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gaWYgdGhpcyBpc24ndCB0aGUgY3VycmVudCBtb2RhbCwgdGhlbiBmaW5kIGl0IGluIHRoZSBhcnJheSBhbmQgcmVtb3ZlIGl0XHJcbiAgICAgICAgICAgIG9wZW5Nb2RhbHMgPSAkLmdyZXAob3Blbk1vZGFscywgZnVuY3Rpb24oZWx0KSB7XHJcbiAgICAgICAgICAgICAgdmFyIGlzVGhpcyA9IGVsdFswXT09PW1vZGFsWzBdO1xyXG4gICAgICAgICAgICAgIGlmKGlzVGhpcykge1xyXG4gICAgICAgICAgICAgICAgLy8gc2luY2UgaXQncyBub3QgY3VycmVudGx5IGluIHRoZSBmcm9udCwgcHV0IGl0IGluIHRoZSBmcm9udCBub3cgdGhhdCBpdCBpcyBoaWRkZW5cclxuICAgICAgICAgICAgICAgIC8vIHNvIHRoYXQgaWYgaXQncyByZS1vcGVuZWQsIGl0IHdvbid0IGJlIC50b2JhY2tcclxuICAgICAgICAgICAgICAgIHNlbGYudG9fZnJvbnQobW9kYWwpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICByZXR1cm4gIWlzVGhpcztcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvLyBmaW5hbGx5LCBzaG93IHRoZSBuZXh0IG1vZGFsIGluIHRoZSBzdGFjaywgaWYgdGhlcmUgaXMgb25lXHJcbiAgICAgICAgICBpZihvcGVuTW9kYWxzLmxlbmd0aD4wKSB7XHJcbiAgICAgICAgICAgIHNlbGYudG9fZnJvbnQob3Blbk1vZGFsc1tvcGVuTW9kYWxzLmxlbmd0aCAtIDFdKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2VsZi5oaWRlKG9wZW5fbW9kYWxzLCBzZXR0aW5ncy5jc3MuY2xvc2UsIHNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY2xvc2VfdGFyZ2V0cyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGJhc2UgPSAnLicgKyB0aGlzLnNldHRpbmdzLmRpc21pc3NfbW9kYWxfY2xhc3M7XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5jbG9zZV9vbl9iYWNrZ3JvdW5kX2NsaWNrKSB7XHJcbiAgICAgICAgcmV0dXJuIGJhc2UgKyAnLCAuJyArIHRoaXMuc2V0dGluZ3MuYmdfY2xhc3M7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBiYXNlO1xyXG4gICAgfSxcclxuXHJcbiAgICB0b2dnbGVfYmcgOiBmdW5jdGlvbiAobW9kYWwsIHN0YXRlKSB7XHJcbiAgICAgIGlmICh0aGlzLlMoJy4nICsgdGhpcy5zZXR0aW5ncy5iZ19jbGFzcykubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5iZyA9ICQoJzxkaXYgLz4nLCB7J2NsYXNzJzogdGhpcy5zZXR0aW5ncy5iZ19jbGFzc30pXHJcbiAgICAgICAgICAuYXBwZW5kVG8oJ2JvZHknKS5oaWRlKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciB2aXNpYmxlID0gdGhpcy5zZXR0aW5ncy5iZy5maWx0ZXIoJzp2aXNpYmxlJykubGVuZ3RoID4gMDtcclxuICAgICAgaWYgKCBzdGF0ZSAhPSB2aXNpYmxlICkge1xyXG4gICAgICAgIGlmICggc3RhdGUgPT0gdW5kZWZpbmVkID8gdmlzaWJsZSA6ICFzdGF0ZSApIHtcclxuICAgICAgICAgIHRoaXMuaGlkZSh0aGlzLnNldHRpbmdzLmJnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5zaG93KHRoaXMuc2V0dGluZ3MuYmcpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzaG93IDogZnVuY3Rpb24gKGVsLCBjc3MpIHtcclxuICAgICAgLy8gaXMgbW9kYWxcclxuICAgICAgaWYgKGNzcykge1xyXG4gICAgICAgIHZhciBzZXR0aW5ncyA9IGVsLmRhdGEodGhpcy5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKSB8fCB0aGlzLnNldHRpbmdzLFxyXG4gICAgICAgICAgICByb290X2VsZW1lbnQgPSBzZXR0aW5ncy5yb290X2VsZW1lbnQsXHJcbiAgICAgICAgICAgIGNvbnRleHQgPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoZWwucGFyZW50KHJvb3RfZWxlbWVudCkubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICB2YXIgcGxhY2Vob2xkZXIgPSBlbC53cmFwKCc8ZGl2IHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIiAvPicpLnBhcmVudCgpO1xyXG5cclxuICAgICAgICAgIGVsLm9uKCdjbG9zZWQuZm5kdG4ucmV2ZWFsLndyYXBwZWQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGVsLmRldGFjaCgpLmFwcGVuZFRvKHBsYWNlaG9sZGVyKTtcclxuICAgICAgICAgICAgZWwudW53cmFwKCkudW5iaW5kKCdjbG9zZWQuZm5kdG4ucmV2ZWFsLndyYXBwZWQnKTtcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIGVsLmRldGFjaCgpLmFwcGVuZFRvKHJvb3RfZWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgYW5pbURhdGEgPSBnZXRBbmltYXRpb25EYXRhKHNldHRpbmdzLmFuaW1hdGlvbik7XHJcbiAgICAgICAgaWYgKCFhbmltRGF0YS5hbmltYXRlKSB7XHJcbiAgICAgICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYW5pbURhdGEucG9wKSB7XHJcbiAgICAgICAgICBjc3MudG9wID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpIC0gZWwuZGF0YSgnb2Zmc2V0JykgKyAncHgnO1xyXG4gICAgICAgICAgdmFyIGVuZF9jc3MgPSB7XHJcbiAgICAgICAgICAgIHRvcDogJCh3aW5kb3cpLnNjcm9sbFRvcCgpICsgZWwuZGF0YSgnY3NzLXRvcCcpICsgJ3B4JyxcclxuICAgICAgICAgICAgb3BhY2l0eTogMVxyXG4gICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbFxyXG4gICAgICAgICAgICAgIC5jc3MoY3NzKVxyXG4gICAgICAgICAgICAgIC5hbmltYXRlKGVuZF9jc3MsIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCwgJ2xpbmVhcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQubG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBlbC50cmlnZ2VyKCdvcGVuZWQuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ29wZW4nKTtcclxuICAgICAgICAgIH0sIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCAvIDIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY3NzLnRvcCA9ICQod2luZG93KS5zY3JvbGxUb3AoKSArIGVsLmRhdGEoJ2Nzcy10b3AnKSArICdweCc7XHJcblxyXG4gICAgICAgIGlmIChhbmltRGF0YS5mYWRlKSB7XHJcbiAgICAgICAgICB2YXIgZW5kX2NzcyA9IHtvcGFjaXR5OiAxfTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbFxyXG4gICAgICAgICAgICAgIC5jc3MoY3NzKVxyXG4gICAgICAgICAgICAgIC5hbmltYXRlKGVuZF9jc3MsIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCwgJ2xpbmVhcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQubG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBlbC50cmlnZ2VyKCdvcGVuZWQuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ29wZW4nKTtcclxuICAgICAgICAgIH0sIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCAvIDIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGVsLmNzcyhjc3MpLnNob3coKS5jc3Moe29wYWNpdHkgOiAxfSkuYWRkQ2xhc3MoJ29wZW4nKS50cmlnZ2VyKCdvcGVuZWQuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBzZXR0aW5ncyA9IHRoaXMuc2V0dGluZ3M7XHJcblxyXG4gICAgICAvLyBzaG91bGQgd2UgYW5pbWF0ZSB0aGUgYmFja2dyb3VuZD9cclxuICAgICAgaWYgKGdldEFuaW1hdGlvbkRhdGEoc2V0dGluZ3MuYW5pbWF0aW9uKS5mYWRlKSB7XHJcbiAgICAgICAgcmV0dXJuIGVsLmZhZGVJbihzZXR0aW5ncy5hbmltYXRpb25fc3BlZWQgLyAyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5sb2NrZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgIHJldHVybiBlbC5zaG93KCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHRvX2JhY2sgOiBmdW5jdGlvbihlbCkge1xyXG4gICAgICBlbC5hZGRDbGFzcygndG9iYWNrJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHRvX2Zyb250IDogZnVuY3Rpb24oZWwpIHtcclxuICAgICAgZWwucmVtb3ZlQ2xhc3MoJ3RvYmFjaycpO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRlIDogZnVuY3Rpb24gKGVsLCBjc3MpIHtcclxuICAgICAgLy8gaXMgbW9kYWxcclxuICAgICAgaWYgKGNzcykge1xyXG4gICAgICAgIHZhciBzZXR0aW5ncyA9IGVsLmRhdGEodGhpcy5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKSxcclxuICAgICAgICAgICAgY29udGV4dCA9IHRoaXM7XHJcbiAgICAgICAgc2V0dGluZ3MgPSBzZXR0aW5ncyB8fCB0aGlzLnNldHRpbmdzO1xyXG5cclxuICAgICAgICB2YXIgYW5pbURhdGEgPSBnZXRBbmltYXRpb25EYXRhKHNldHRpbmdzLmFuaW1hdGlvbik7XHJcbiAgICAgICAgaWYgKCFhbmltRGF0YS5hbmltYXRlKSB7XHJcbiAgICAgICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYW5pbURhdGEucG9wKSB7XHJcbiAgICAgICAgICB2YXIgZW5kX2NzcyA9IHtcclxuICAgICAgICAgICAgdG9wOiAtICQod2luZG93KS5zY3JvbGxUb3AoKSAtIGVsLmRhdGEoJ29mZnNldCcpICsgJ3B4JyxcclxuICAgICAgICAgICAgb3BhY2l0eTogMFxyXG4gICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbFxyXG4gICAgICAgICAgICAgIC5hbmltYXRlKGVuZF9jc3MsIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCwgJ2xpbmVhcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQubG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBlbC5jc3MoY3NzKS50cmlnZ2VyKCdjbG9zZWQuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ29wZW4nKTtcclxuICAgICAgICAgIH0sIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCAvIDIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGFuaW1EYXRhLmZhZGUpIHtcclxuICAgICAgICAgIHZhciBlbmRfY3NzID0ge29wYWNpdHkgOiAwfTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbFxyXG4gICAgICAgICAgICAgIC5hbmltYXRlKGVuZF9jc3MsIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCwgJ2xpbmVhcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQubG9ja2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBlbC5jc3MoY3NzKS50cmlnZ2VyKCdjbG9zZWQuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ29wZW4nKTtcclxuICAgICAgICAgIH0sIHNldHRpbmdzLmFuaW1hdGlvbl9zcGVlZCAvIDIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGVsLmhpZGUoKS5jc3MoY3NzKS5yZW1vdmVDbGFzcygnb3BlbicpLnRyaWdnZXIoJ2Nsb3NlZC5mbmR0bi5yZXZlYWwnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNldHRpbmdzID0gdGhpcy5zZXR0aW5ncztcclxuXHJcbiAgICAgIC8vIHNob3VsZCB3ZSBhbmltYXRlIHRoZSBiYWNrZ3JvdW5kP1xyXG4gICAgICBpZiAoZ2V0QW5pbWF0aW9uRGF0YShzZXR0aW5ncy5hbmltYXRpb24pLmZhZGUpIHtcclxuICAgICAgICByZXR1cm4gZWwuZmFkZU91dChzZXR0aW5ncy5hbmltYXRpb25fc3BlZWQgLyAyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGVsLmhpZGUoKTtcclxuICAgIH0sXHJcblxyXG4gICAgY2xvc2VfdmlkZW8gOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICB2YXIgdmlkZW8gPSAkKCcuZmxleC12aWRlbycsIGUudGFyZ2V0KSxcclxuICAgICAgICAgIGlmcmFtZSA9ICQoJ2lmcmFtZScsIHZpZGVvKTtcclxuXHJcbiAgICAgIGlmIChpZnJhbWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGlmcmFtZS5hdHRyKCdkYXRhLXNyYycsIGlmcmFtZVswXS5zcmMpO1xyXG4gICAgICAgIGlmcmFtZS5hdHRyKCdzcmMnLCBpZnJhbWUuYXR0cignc3JjJykpO1xyXG4gICAgICAgIHZpZGVvLmhpZGUoKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBvcGVuX3ZpZGVvIDogZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyIHZpZGVvID0gJCgnLmZsZXgtdmlkZW8nLCBlLnRhcmdldCksXHJcbiAgICAgICAgICBpZnJhbWUgPSB2aWRlby5maW5kKCdpZnJhbWUnKTtcclxuXHJcbiAgICAgIGlmIChpZnJhbWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHZhciBkYXRhX3NyYyA9IGlmcmFtZS5hdHRyKCdkYXRhLXNyYycpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZGF0YV9zcmMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICBpZnJhbWVbMF0uc3JjID0gaWZyYW1lLmF0dHIoJ2RhdGEtc3JjJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHZhciBzcmMgPSBpZnJhbWVbMF0uc3JjO1xyXG4gICAgICAgICAgaWZyYW1lWzBdLnNyYyA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIGlmcmFtZVswXS5zcmMgPSBzcmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZpZGVvLnNob3coKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBkYXRhX2F0dHIgOiBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgIGlmICh0aGlzLm5hbWVzcGFjZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZXNwYWNlICsgJy0nICsgc3RyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc3RyO1xyXG4gICAgfSxcclxuXHJcbiAgICBjYWNoZV9vZmZzZXQgOiBmdW5jdGlvbiAobW9kYWwpIHtcclxuICAgICAgdmFyIG9mZnNldCA9IG1vZGFsLnNob3coKS5oZWlnaHQoKSArIHBhcnNlSW50KG1vZGFsLmNzcygndG9wJyksIDEwKSArIG1vZGFsLnNjcm9sbFk7XHJcblxyXG4gICAgICBtb2RhbC5oaWRlKCk7XHJcblxyXG4gICAgICByZXR1cm4gb2Zmc2V0O1xyXG4gICAgfSxcclxuXHJcbiAgICBvZmYgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICQodGhpcy5zY29wZSkub2ZmKCcuZm5kdG4ucmV2ZWFsJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlZmxvdyA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgfTtcclxuXHJcbiAgLypcclxuICAgKiBnZXRBbmltYXRpb25EYXRhKCdwb3BBbmRGYWRlJykgLy8ge2FuaW1hdGU6IHRydWUsICBwb3A6IHRydWUsICBmYWRlOiB0cnVlfVxyXG4gICAqIGdldEFuaW1hdGlvbkRhdGEoJ2ZhZGUnKSAgICAgICAvLyB7YW5pbWF0ZTogdHJ1ZSwgIHBvcDogZmFsc2UsIGZhZGU6IHRydWV9XHJcbiAgICogZ2V0QW5pbWF0aW9uRGF0YSgncG9wJykgICAgICAgIC8vIHthbmltYXRlOiB0cnVlLCAgcG9wOiB0cnVlLCAgZmFkZTogZmFsc2V9XHJcbiAgICogZ2V0QW5pbWF0aW9uRGF0YSgnZm9vJykgICAgICAgIC8vIHthbmltYXRlOiBmYWxzZSwgcG9wOiBmYWxzZSwgZmFkZTogZmFsc2V9XHJcbiAgICogZ2V0QW5pbWF0aW9uRGF0YShudWxsKSAgICAgICAgIC8vIHthbmltYXRlOiBmYWxzZSwgcG9wOiBmYWxzZSwgZmFkZTogZmFsc2V9XHJcbiAgICovXHJcbiAgZnVuY3Rpb24gZ2V0QW5pbWF0aW9uRGF0YShzdHIpIHtcclxuICAgIHZhciBmYWRlID0gL2ZhZGUvaS50ZXN0KHN0cik7XHJcbiAgICB2YXIgcG9wID0gL3BvcC9pLnRlc3Qoc3RyKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGFuaW1hdGUgOiBmYWRlIHx8IHBvcCxcclxuICAgICAgcG9wIDogcG9wLFxyXG4gICAgICBmYWRlIDogZmFkZVxyXG4gICAgfTtcclxuICB9XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG5cclxuOyhmdW5jdGlvbiAoJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBGb3VuZGF0aW9uLmxpYnMuc2xpZGVyID0ge1xyXG4gICAgbmFtZSA6ICdzbGlkZXInLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBzdGFydCA6IDAsXHJcbiAgICAgIGVuZCA6IDEwMCxcclxuICAgICAgc3RlcCA6IDEsXHJcbiAgICAgIHByZWNpc2lvbiA6IDIsXHJcbiAgICAgIGluaXRpYWwgOiBudWxsLFxyXG4gICAgICBkaXNwbGF5X3NlbGVjdG9yIDogJycsXHJcbiAgICAgIHZlcnRpY2FsIDogZmFsc2UsXHJcbiAgICAgIHRyaWdnZXJfaW5wdXRfY2hhbmdlIDogZmFsc2UsXHJcbiAgICAgIG9uX2NoYW5nZSA6IGZ1bmN0aW9uICgpIHt9XHJcbiAgICB9LFxyXG5cclxuICAgIGNhY2hlIDoge30sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIEZvdW5kYXRpb24uaW5oZXJpdCh0aGlzLCAndGhyb3R0bGUnKTtcclxuICAgICAgdGhpcy5iaW5kaW5ncyhtZXRob2QsIG9wdGlvbnMpO1xyXG4gICAgICB0aGlzLnJlZmxvdygpO1xyXG4gICAgfSxcclxuXHJcbiAgICBldmVudHMgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgJCh0aGlzLnNjb3BlKVxyXG4gICAgICAgIC5vZmYoJy5zbGlkZXInKVxyXG4gICAgICAgIC5vbignbW91c2Vkb3duLmZuZHRuLnNsaWRlciB0b3VjaHN0YXJ0LmZuZHRuLnNsaWRlciBwb2ludGVyZG93bi5mbmR0bi5zbGlkZXInLFxyXG4gICAgICAgICdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXTpub3QoLmRpc2FibGVkLCBbZGlzYWJsZWRdKSAucmFuZ2Utc2xpZGVyLWhhbmRsZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBpZiAoIXNlbGYuY2FjaGUuYWN0aXZlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgc2VsZi5zZXRfYWN0aXZlX3NsaWRlcigkKGUudGFyZ2V0KSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ21vdXNlbW92ZS5mbmR0bi5zbGlkZXIgdG91Y2htb3ZlLmZuZHRuLnNsaWRlciBwb2ludGVybW92ZS5mbmR0bi5zbGlkZXInLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgaWYgKCEhc2VsZi5jYWNoZS5hY3RpdmUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBpZiAoJC5kYXRhKHNlbGYuY2FjaGUuYWN0aXZlWzBdLCAnc2V0dGluZ3MnKS52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgIHZhciBzY3JvbGxfb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICBpZiAoIWUucGFnZVkpIHtcclxuICAgICAgICAgICAgICAgIHNjcm9sbF9vZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgc2VsZi5jYWxjdWxhdGVfcG9zaXRpb24oc2VsZi5jYWNoZS5hY3RpdmUsIHNlbGYuZ2V0X2N1cnNvcl9wb3NpdGlvbihlLCAneScpICsgc2Nyb2xsX29mZnNldCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgc2VsZi5jYWxjdWxhdGVfcG9zaXRpb24oc2VsZi5jYWNoZS5hY3RpdmUsIHNlbGYuZ2V0X2N1cnNvcl9wb3NpdGlvbihlLCAneCcpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdtb3VzZXVwLmZuZHRuLnNsaWRlciB0b3VjaGVuZC5mbmR0bi5zbGlkZXIgcG9pbnRlcnVwLmZuZHRuLnNsaWRlcicsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBpZighc2VsZi5jYWNoZS5hY3RpdmUpIHtcclxuICAgICAgICAgICAgLy8gaWYgdGhlIHVzZXIgaGFzIGp1c3QgY2xpY2tlZCBpbnRvIHRoZSBzbGlkZXIgd2l0aG91dCBzdGFydGluZyB0byBkcmFnIHRoZSBoYW5kbGVcclxuICAgICAgICAgICAgdmFyIHNsaWRlciA9ICQoZS50YXJnZXQpLmF0dHIoJ3JvbGUnKSA9PT0gJ3NsaWRlcicgPyAkKGUudGFyZ2V0KSA6ICQoZS50YXJnZXQpLmNsb3Nlc3QoJy5yYW5nZS1zbGlkZXInKS5maW5kKFwiW3JvbGU9J3NsaWRlciddXCIpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNsaWRlci5sZW5ndGggJiYgKCFzbGlkZXIucGFyZW50KCkuaGFzQ2xhc3MoJ2Rpc2FibGVkJykgJiYgIXNsaWRlci5wYXJlbnQoKS5hdHRyKCdkaXNhYmxlZCcpKSkge1xyXG4gICAgICAgICAgICAgIHNlbGYuc2V0X2FjdGl2ZV9zbGlkZXIoc2xpZGVyKTtcclxuICAgICAgICAgICAgICBpZiAoJC5kYXRhKHNlbGYuY2FjaGUuYWN0aXZlWzBdLCAnc2V0dGluZ3MnKS52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbF9vZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlLnBhZ2VZKSB7XHJcbiAgICAgICAgICAgICAgICAgIHNjcm9sbF9vZmZzZXQgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHNlbGYuY2FsY3VsYXRlX3Bvc2l0aW9uKHNlbGYuY2FjaGUuYWN0aXZlLCBzZWxmLmdldF9jdXJzb3JfcG9zaXRpb24oZSwgJ3knKSArIHNjcm9sbF9vZmZzZXQpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmNhbGN1bGF0ZV9wb3NpdGlvbihzZWxmLmNhY2hlLmFjdGl2ZSwgc2VsZi5nZXRfY3Vyc29yX3Bvc2l0aW9uKGUsICd4JykpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc2VsZi5yZW1vdmVfYWN0aXZlX3NsaWRlcigpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjaGFuZ2UuZm5kdG4uc2xpZGVyJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuc2V0dGluZ3Mub25fY2hhbmdlKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICBzZWxmLlMod2luZG93KVxyXG4gICAgICAgIC5vbigncmVzaXplLmZuZHRuLnNsaWRlcicsIHNlbGYudGhyb3R0bGUoZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYucmVmbG93KCk7XHJcbiAgICAgICAgfSwgMzAwKSk7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgc2xpZGVyIHZhbHVlIGFzIHVzZXJzIGNoYW5nZSBpbnB1dCB2YWx1ZVxyXG4gICAgICB0aGlzLlMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJykuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHNsaWRlciA9ICQodGhpcyksXHJcbiAgICAgICAgICAgIGhhbmRsZSA9IHNsaWRlci5jaGlsZHJlbignLnJhbmdlLXNsaWRlci1oYW5kbGUnKVswXSxcclxuICAgICAgICAgICAgc2V0dGluZ3MgPSBzZWxmLmluaXRpYWxpemVfc2V0dGluZ3MoaGFuZGxlKTtcclxuXHJcbiAgICAgICAgaWYgKHNldHRpbmdzLmRpc3BsYXlfc2VsZWN0b3IgIT0gJycpIHtcclxuICAgICAgICAgICQoc2V0dGluZ3MuZGlzcGxheV9zZWxlY3RvcikuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICBpZiAoJCh0aGlzKS5hdHRyKCd2YWx1ZScpKSB7XHJcbiAgICAgICAgICAgICAgJCh0aGlzKS5vZmYoJ2NoYW5nZScpLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBzbGlkZXIuZm91bmRhdGlvbihcInNsaWRlclwiLCBcInNldF92YWx1ZVwiLCAkKHRoaXMpLnZhbCgpKTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0X2N1cnNvcl9wb3NpdGlvbiA6IGZ1bmN0aW9uIChlLCB4eSkge1xyXG4gICAgICB2YXIgcGFnZVhZID0gJ3BhZ2UnICsgeHkudG9VcHBlckNhc2UoKSxcclxuICAgICAgICAgIGNsaWVudFhZID0gJ2NsaWVudCcgKyB4eS50b1VwcGVyQ2FzZSgpLFxyXG4gICAgICAgICAgcG9zaXRpb247XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGVbcGFnZVhZXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBwb3NpdGlvbiA9IGVbcGFnZVhZXTtcclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZS5vcmlnaW5hbEV2ZW50W2NsaWVudFhZXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBwb3NpdGlvbiA9IGUub3JpZ2luYWxFdmVudFtjbGllbnRYWV07XHJcbiAgICAgIH0gZWxzZSBpZiAoZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXMgJiYgZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0gJiYgdHlwZW9mIGUub3JpZ2luYWxFdmVudC50b3VjaGVzWzBdW2NsaWVudFhZXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBwb3NpdGlvbiA9IGUub3JpZ2luYWxFdmVudC50b3VjaGVzWzBdW2NsaWVudFhZXTtcclxuICAgICAgfSBlbHNlIGlmIChlLmN1cnJlbnRQb2ludCAmJiB0eXBlb2YgZS5jdXJyZW50UG9pbnRbeHldICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHBvc2l0aW9uID0gZS5jdXJyZW50UG9pbnRbeHldO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gcG9zaXRpb247XHJcbiAgICB9LFxyXG5cclxuICAgIHNldF9hY3RpdmVfc2xpZGVyIDogZnVuY3Rpb24gKCRoYW5kbGUpIHtcclxuICAgICAgdGhpcy5jYWNoZS5hY3RpdmUgPSAkaGFuZGxlO1xyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVfYWN0aXZlX3NsaWRlciA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5jYWNoZS5hY3RpdmUgPSBudWxsO1xyXG4gICAgfSxcclxuXHJcbiAgICBjYWxjdWxhdGVfcG9zaXRpb24gOiBmdW5jdGlvbiAoJGhhbmRsZSwgY3Vyc29yX3gpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSAkLmRhdGEoJGhhbmRsZVswXSwgJ3NldHRpbmdzJyksXHJcbiAgICAgICAgICBoYW5kbGVfbCA9ICQuZGF0YSgkaGFuZGxlWzBdLCAnaGFuZGxlX2wnKSxcclxuICAgICAgICAgIGhhbmRsZV9vID0gJC5kYXRhKCRoYW5kbGVbMF0sICdoYW5kbGVfbycpLFxyXG4gICAgICAgICAgYmFyX2wgPSAkLmRhdGEoJGhhbmRsZVswXSwgJ2Jhcl9sJyksXHJcbiAgICAgICAgICBiYXJfbyA9ICQuZGF0YSgkaGFuZGxlWzBdLCAnYmFyX28nKTtcclxuXHJcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHBjdDtcclxuXHJcbiAgICAgICAgaWYgKEZvdW5kYXRpb24ucnRsICYmICFzZXR0aW5ncy52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgcGN0ID0gc2VsZi5saW1pdF90bygoKGJhcl9vICsgYmFyX2wgLSBjdXJzb3JfeCkgLyBiYXJfbCksIDAsIDEpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBwY3QgPSBzZWxmLmxpbWl0X3RvKCgoY3Vyc29yX3ggLSBiYXJfbykgLyBiYXJfbCksIDAsIDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcGN0ID0gc2V0dGluZ3MudmVydGljYWwgPyAxIC0gcGN0IDogcGN0O1xyXG5cclxuICAgICAgICB2YXIgbm9ybSA9IHNlbGYubm9ybWFsaXplZF92YWx1ZShwY3QsIHNldHRpbmdzLnN0YXJ0LCBzZXR0aW5ncy5lbmQsIHNldHRpbmdzLnN0ZXAsIHNldHRpbmdzLnByZWNpc2lvbik7XHJcblxyXG4gICAgICAgIHNlbGYuc2V0X3VpKCRoYW5kbGUsIG5vcm0pO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0X3VpIDogZnVuY3Rpb24gKCRoYW5kbGUsIHZhbHVlKSB7XHJcbiAgICAgIHZhciBzZXR0aW5ncyA9ICQuZGF0YSgkaGFuZGxlWzBdLCAnc2V0dGluZ3MnKSxcclxuICAgICAgICAgIGhhbmRsZV9sID0gJC5kYXRhKCRoYW5kbGVbMF0sICdoYW5kbGVfbCcpLFxyXG4gICAgICAgICAgYmFyX2wgPSAkLmRhdGEoJGhhbmRsZVswXSwgJ2Jhcl9sJyksXHJcbiAgICAgICAgICBub3JtX3BjdCA9IHRoaXMubm9ybWFsaXplZF9wZXJjZW50YWdlKHZhbHVlLCBzZXR0aW5ncy5zdGFydCwgc2V0dGluZ3MuZW5kKSxcclxuICAgICAgICAgIGhhbmRsZV9vZmZzZXQgPSBub3JtX3BjdCAqIChiYXJfbCAtIGhhbmRsZV9sKSAtIDEsXHJcbiAgICAgICAgICBwcm9ncmVzc19iYXJfbGVuZ3RoID0gbm9ybV9wY3QgKiAxMDAsXHJcbiAgICAgICAgICAkaGFuZGxlX3BhcmVudCA9ICRoYW5kbGUucGFyZW50KCksXHJcbiAgICAgICAgICAkaGlkZGVuX2lucHV0cyA9ICRoYW5kbGUucGFyZW50KCkuY2hpbGRyZW4oJ2lucHV0W3R5cGU9aGlkZGVuXScpO1xyXG5cclxuICAgICAgaWYgKEZvdW5kYXRpb24ucnRsICYmICFzZXR0aW5ncy52ZXJ0aWNhbCkge1xyXG4gICAgICAgIGhhbmRsZV9vZmZzZXQgPSAtaGFuZGxlX29mZnNldDtcclxuICAgICAgfVxyXG5cclxuICAgICAgaGFuZGxlX29mZnNldCA9IHNldHRpbmdzLnZlcnRpY2FsID8gLWhhbmRsZV9vZmZzZXQgKyBiYXJfbCAtIGhhbmRsZV9sICsgMSA6IGhhbmRsZV9vZmZzZXQ7XHJcbiAgICAgIHRoaXMuc2V0X3RyYW5zbGF0ZSgkaGFuZGxlLCBoYW5kbGVfb2Zmc2V0LCBzZXR0aW5ncy52ZXJ0aWNhbCk7XHJcblxyXG4gICAgICBpZiAoc2V0dGluZ3MudmVydGljYWwpIHtcclxuICAgICAgICAkaGFuZGxlLnNpYmxpbmdzKCcucmFuZ2Utc2xpZGVyLWFjdGl2ZS1zZWdtZW50JykuY3NzKCdoZWlnaHQnLCBwcm9ncmVzc19iYXJfbGVuZ3RoICsgJyUnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAkaGFuZGxlLnNpYmxpbmdzKCcucmFuZ2Utc2xpZGVyLWFjdGl2ZS1zZWdtZW50JykuY3NzKCd3aWR0aCcsIHByb2dyZXNzX2Jhcl9sZW5ndGggKyAnJScpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkaGFuZGxlX3BhcmVudC5hdHRyKHRoaXMuYXR0cl9uYW1lKCksIHZhbHVlKS50cmlnZ2VyKCdjaGFuZ2UuZm5kdG4uc2xpZGVyJyk7XHJcblxyXG4gICAgICAkaGlkZGVuX2lucHV0cy52YWwodmFsdWUpO1xyXG4gICAgICBpZiAoc2V0dGluZ3MudHJpZ2dlcl9pbnB1dF9jaGFuZ2UpIHtcclxuICAgICAgICAgICRoaWRkZW5faW5wdXRzLnRyaWdnZXIoJ2NoYW5nZS5mbmR0bi5zbGlkZXInKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCEkaGFuZGxlWzBdLmhhc0F0dHJpYnV0ZSgnYXJpYS12YWx1ZW1pbicpKSB7XHJcbiAgICAgICAgJGhhbmRsZS5hdHRyKHtcclxuICAgICAgICAgICdhcmlhLXZhbHVlbWluJyA6IHNldHRpbmdzLnN0YXJ0LFxyXG4gICAgICAgICAgJ2FyaWEtdmFsdWVtYXgnIDogc2V0dGluZ3MuZW5kXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgJGhhbmRsZS5hdHRyKCdhcmlhLXZhbHVlbm93JywgdmFsdWUpO1xyXG5cclxuICAgICAgaWYgKHNldHRpbmdzLmRpc3BsYXlfc2VsZWN0b3IgIT0gJycpIHtcclxuICAgICAgICAkKHNldHRpbmdzLmRpc3BsYXlfc2VsZWN0b3IpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSB7XHJcbiAgICAgICAgICAgICQodGhpcykudmFsKHZhbHVlKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICQodGhpcykudGV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICB9LFxyXG5cclxuICAgIG5vcm1hbGl6ZWRfcGVyY2VudGFnZSA6IGZ1bmN0aW9uICh2YWwsIHN0YXJ0LCBlbmQpIHtcclxuICAgICAgcmV0dXJuIE1hdGgubWluKDEsICh2YWwgLSBzdGFydCkgLyAoZW5kIC0gc3RhcnQpKTtcclxuICAgIH0sXHJcblxyXG4gICAgbm9ybWFsaXplZF92YWx1ZSA6IGZ1bmN0aW9uICh2YWwsIHN0YXJ0LCBlbmQsIHN0ZXAsIHByZWNpc2lvbikge1xyXG4gICAgICB2YXIgcmFuZ2UgPSBlbmQgLSBzdGFydCxcclxuICAgICAgICAgIHBvaW50ID0gdmFsICogcmFuZ2UsXHJcbiAgICAgICAgICBtb2QgPSAocG9pbnQgLSAocG9pbnQgJSBzdGVwKSkgLyBzdGVwLFxyXG4gICAgICAgICAgcmVtID0gcG9pbnQgJSBzdGVwLFxyXG4gICAgICAgICAgcm91bmQgPSAoIHJlbSA+PSBzdGVwICogMC41ID8gc3RlcCA6IDApO1xyXG4gICAgICByZXR1cm4gKChtb2QgKiBzdGVwICsgcm91bmQpICsgc3RhcnQpLnRvRml4ZWQocHJlY2lzaW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0X3RyYW5zbGF0ZSA6IGZ1bmN0aW9uIChlbGUsIG9mZnNldCwgdmVydGljYWwpIHtcclxuICAgICAgaWYgKHZlcnRpY2FsKSB7XHJcbiAgICAgICAgJChlbGUpXHJcbiAgICAgICAgICAuY3NzKCctd2Via2l0LXRyYW5zZm9ybScsICd0cmFuc2xhdGVZKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJy1tb3otdHJhbnNmb3JtJywgJ3RyYW5zbGF0ZVkoJyArIG9mZnNldCArICdweCknKVxyXG4gICAgICAgICAgLmNzcygnLW1zLXRyYW5zZm9ybScsICd0cmFuc2xhdGVZKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJy1vLXRyYW5zZm9ybScsICd0cmFuc2xhdGVZKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGVZKCcgKyBvZmZzZXQgKyAncHgpJyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgJChlbGUpXHJcbiAgICAgICAgICAuY3NzKCctd2Via2l0LXRyYW5zZm9ybScsICd0cmFuc2xhdGVYKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJy1tb3otdHJhbnNmb3JtJywgJ3RyYW5zbGF0ZVgoJyArIG9mZnNldCArICdweCknKVxyXG4gICAgICAgICAgLmNzcygnLW1zLXRyYW5zZm9ybScsICd0cmFuc2xhdGVYKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJy1vLXRyYW5zZm9ybScsICd0cmFuc2xhdGVYKCcgKyBvZmZzZXQgKyAncHgpJylcclxuICAgICAgICAgIC5jc3MoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGVYKCcgKyBvZmZzZXQgKyAncHgpJyk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgbGltaXRfdG8gOiBmdW5jdGlvbiAodmFsLCBtaW4sIG1heCkge1xyXG4gICAgICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsLCBtaW4pLCBtYXgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbml0aWFsaXplX3NldHRpbmdzIDogZnVuY3Rpb24gKGhhbmRsZSkge1xyXG4gICAgICB2YXIgc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgdGhpcy5zZXR0aW5ncywgdGhpcy5kYXRhX29wdGlvbnMoJChoYW5kbGUpLnBhcmVudCgpKSksXHJcbiAgICAgICAgICBkZWNpbWFsX3BsYWNlc19tYXRjaF9yZXN1bHQ7XHJcblxyXG4gICAgICBpZiAoc2V0dGluZ3MucHJlY2lzaW9uID09PSBudWxsKSB7XHJcbiAgICAgICAgZGVjaW1hbF9wbGFjZXNfbWF0Y2hfcmVzdWx0ID0gKCcnICsgc2V0dGluZ3Muc3RlcCkubWF0Y2goL1xcLihbXFxkXSopLyk7XHJcbiAgICAgICAgc2V0dGluZ3MucHJlY2lzaW9uID0gZGVjaW1hbF9wbGFjZXNfbWF0Y2hfcmVzdWx0ICYmIGRlY2ltYWxfcGxhY2VzX21hdGNoX3Jlc3VsdFsxXSA/IGRlY2ltYWxfcGxhY2VzX21hdGNoX3Jlc3VsdFsxXS5sZW5ndGggOiAwO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2V0dGluZ3MudmVydGljYWwpIHtcclxuICAgICAgICAkLmRhdGEoaGFuZGxlLCAnYmFyX28nLCAkKGhhbmRsZSkucGFyZW50KCkub2Zmc2V0KCkudG9wKTtcclxuICAgICAgICAkLmRhdGEoaGFuZGxlLCAnYmFyX2wnLCAkKGhhbmRsZSkucGFyZW50KCkub3V0ZXJIZWlnaHQoKSk7XHJcbiAgICAgICAgJC5kYXRhKGhhbmRsZSwgJ2hhbmRsZV9vJywgJChoYW5kbGUpLm9mZnNldCgpLnRvcCk7XHJcbiAgICAgICAgJC5kYXRhKGhhbmRsZSwgJ2hhbmRsZV9sJywgJChoYW5kbGUpLm91dGVySGVpZ2h0KCkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgICQuZGF0YShoYW5kbGUsICdiYXJfbycsICQoaGFuZGxlKS5wYXJlbnQoKS5vZmZzZXQoKS5sZWZ0KTtcclxuICAgICAgICAkLmRhdGEoaGFuZGxlLCAnYmFyX2wnLCAkKGhhbmRsZSkucGFyZW50KCkub3V0ZXJXaWR0aCgpKTtcclxuICAgICAgICAkLmRhdGEoaGFuZGxlLCAnaGFuZGxlX28nLCAkKGhhbmRsZSkub2Zmc2V0KCkubGVmdCk7XHJcbiAgICAgICAgJC5kYXRhKGhhbmRsZSwgJ2hhbmRsZV9sJywgJChoYW5kbGUpLm91dGVyV2lkdGgoKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICQuZGF0YShoYW5kbGUsICdiYXInLCAkKGhhbmRsZSkucGFyZW50KCkpO1xyXG4gICAgICByZXR1cm4gJC5kYXRhKGhhbmRsZSwgJ3NldHRpbmdzJywgc2V0dGluZ3MpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRfaW5pdGlhbF9wb3NpdGlvbiA6IGZ1bmN0aW9uICgkZWxlKSB7XHJcbiAgICAgIHZhciBzZXR0aW5ncyA9ICQuZGF0YSgkZWxlLmNoaWxkcmVuKCcucmFuZ2Utc2xpZGVyLWhhbmRsZScpWzBdLCAnc2V0dGluZ3MnKSxcclxuICAgICAgICAgIGluaXRpYWwgPSAoKHR5cGVvZiBzZXR0aW5ncy5pbml0aWFsID09ICdudW1iZXInICYmICFpc05hTihzZXR0aW5ncy5pbml0aWFsKSkgPyBzZXR0aW5ncy5pbml0aWFsIDogTWF0aC5mbG9vcigoc2V0dGluZ3MuZW5kIC0gc2V0dGluZ3Muc3RhcnQpICogMC41IC8gc2V0dGluZ3Muc3RlcCkgKiBzZXR0aW5ncy5zdGVwICsgc2V0dGluZ3Muc3RhcnQpLFxyXG4gICAgICAgICAgJGhhbmRsZSA9ICRlbGUuY2hpbGRyZW4oJy5yYW5nZS1zbGlkZXItaGFuZGxlJyk7XHJcbiAgICAgIHRoaXMuc2V0X3VpKCRoYW5kbGUsIGluaXRpYWwpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRfdmFsdWUgOiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAkKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMuc2NvcGUpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICQodGhpcykuYXR0cihzZWxmLmF0dHJfbmFtZSgpLCB2YWx1ZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAoISEkKHRoaXMuc2NvcGUpLmF0dHIoc2VsZi5hdHRyX25hbWUoKSkpIHtcclxuICAgICAgICAkKHRoaXMuc2NvcGUpLmF0dHIoc2VsZi5hdHRyX25hbWUoKSwgdmFsdWUpO1xyXG4gICAgICB9XHJcbiAgICAgIHNlbGYucmVmbG93KCk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlZmxvdyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICBzZWxmLlMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJykuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGhhbmRsZSA9ICQodGhpcykuY2hpbGRyZW4oJy5yYW5nZS1zbGlkZXItaGFuZGxlJylbMF0sXHJcbiAgICAgICAgICAgIHZhbCA9ICQodGhpcykuYXR0cihzZWxmLmF0dHJfbmFtZSgpKTtcclxuICAgICAgICBzZWxmLmluaXRpYWxpemVfc2V0dGluZ3MoaGFuZGxlKTtcclxuXHJcbiAgICAgICAgaWYgKHZhbCkge1xyXG4gICAgICAgICAgc2VsZi5zZXRfdWkoJChoYW5kbGUpLCBwYXJzZUZsb2F0KHZhbCkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzZWxmLnNldF9pbml0aWFsX3Bvc2l0aW9uKCQodGhpcykpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG5cclxuOyhmdW5jdGlvbiAoJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBGb3VuZGF0aW9uLmxpYnMudGFiID0ge1xyXG4gICAgbmFtZSA6ICd0YWInLFxyXG5cclxuICAgIHZlcnNpb24gOiAnNS41LjMnLFxyXG5cclxuICAgIHNldHRpbmdzIDoge1xyXG4gICAgICBhY3RpdmVfY2xhc3MgOiAnYWN0aXZlJyxcclxuICAgICAgY2FsbGJhY2sgOiBmdW5jdGlvbiAoKSB7fSxcclxuICAgICAgZGVlcF9saW5raW5nIDogZmFsc2UsXHJcbiAgICAgIHNjcm9sbF90b19jb250ZW50IDogdHJ1ZSxcclxuICAgICAgaXNfaG92ZXIgOiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICBkZWZhdWx0X3RhYl9oYXNoZXMgOiBbXSxcclxuXHJcbiAgICBpbml0IDogZnVuY3Rpb24gKHNjb3BlLCBtZXRob2QsIG9wdGlvbnMpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgUyA9IHRoaXMuUztcclxuXHJcbiAgXHQgIC8vIFN0b3JlIHRoZSBkZWZhdWx0IGFjdGl2ZSB0YWJzIHdoaWNoIHdpbGwgYmUgcmVmZXJlbmNlZCB3aGVuIHRoZVxyXG4gIFx0ICAvLyBsb2NhdGlvbiBoYXNoIGlzIGFic2VudCwgYXMgaW4gdGhlIGNhc2Ugb2YgbmF2aWdhdGluZyB0aGUgdGFicyBhbmRcclxuICBcdCAgLy8gcmV0dXJuaW5nIHRvIHRoZSBmaXJzdCB2aWV3aW5nIHZpYSB0aGUgYnJvd3NlciBCYWNrIGJ1dHRvbi5cclxuICBcdCAgUygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10gPiAuYWN0aXZlID4gYScsIHRoaXMuc2NvcGUpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gIFx0ICAgIHNlbGYuZGVmYXVsdF90YWJfaGFzaGVzLnB1c2godGhpcy5oYXNoKTtcclxuICBcdCAgfSk7XHJcblxyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICAgIHRoaXMuaGFuZGxlX2xvY2F0aW9uX2hhc2hfY2hhbmdlKCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgUyA9IHRoaXMuUztcclxuXHJcbiAgICAgIHZhciB1c3VhbF90YWJfYmVoYXZpb3IgPSAgZnVuY3Rpb24gKGUsIHRhcmdldCkge1xyXG4gICAgICAgIHZhciBzZXR0aW5ncyA9IFModGFyZ2V0KS5jbG9zZXN0KCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLmRhdGEoc2VsZi5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKTtcclxuICAgICAgICBpZiAoIXNldHRpbmdzLmlzX2hvdmVyIHx8IE1vZGVybml6ci50b3VjaCkge1xyXG4gICAgICAgICAgLy8gaWYgdXNlciBkaWQgbm90IHByZXNzZWQgdGFiIGtleSwgcHJldmVudCBkZWZhdWx0IGFjdGlvblxyXG4gICAgICAgICAgdmFyIGtleUNvZGUgPSBlLmtleUNvZGUgfHwgZS53aGljaDtcclxuICAgICAgICAgIGlmIChrZXlDb2RlICE9PSA5KSB7IFxyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBzZWxmLnRvZ2dsZV9hY3RpdmVfdGFiKFModGFyZ2V0KS5wYXJlbnQoKSk7XHJcbiAgICAgICAgICBcclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBTKHRoaXMuc2NvcGUpXHJcbiAgICAgICAgLm9mZignLnRhYicpXHJcbiAgICAgICAgLy8gS2V5IGV2ZW50OiBmb2N1cy90YWIga2V5XHJcbiAgICAgICAgLm9uKCdrZXlkb3duLmZuZHRuLnRhYicsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSA+ICogPiBhJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgdmFyIGtleUNvZGUgPSBlLmtleUNvZGUgfHwgZS53aGljaDtcclxuICAgICAgICAgIC8vIGlmIHVzZXIgcHJlc3NlZCB0YWIga2V5XHJcbiAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMTMgfHwga2V5Q29kZSA9PT0gMzIpIHsgLy8gZW50ZXIgb3Igc3BhY2VcclxuICAgICAgICAgICAgdmFyIGVsID0gdGhpcztcclxuICAgICAgICAgICAgdXN1YWxfdGFiX2JlaGF2aW9yKGUsIGVsKTtcclxuICAgICAgICAgIH0gXHJcbiAgICAgICAgfSlcclxuICAgICAgICAvLyBDbGljayBldmVudDogdGFiIHRpdGxlXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi50YWInLCAnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10gPiAqID4gYScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgIHZhciBlbCA9IHRoaXM7XHJcbiAgICAgICAgICB1c3VhbF90YWJfYmVoYXZpb3IoZSwgZWwpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLy8gSG92ZXIgZXZlbnQ6IHRhYiB0aXRsZVxyXG4gICAgICAgIC5vbignbW91c2VlbnRlci5mbmR0bi50YWInLCAnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10gPiAqID4gYScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICB2YXIgc2V0dGluZ3MgPSBTKHRoaXMpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJykuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpO1xyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmlzX2hvdmVyKSB7XHJcbiAgICAgICAgICAgIHNlbGYudG9nZ2xlX2FjdGl2ZV90YWIoUyh0aGlzKS5wYXJlbnQoKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBMb2NhdGlvbiBoYXNoIGNoYW5nZSBldmVudFxyXG4gICAgICBTKHdpbmRvdykub24oJ2hhc2hjaGFuZ2UuZm5kdG4udGFiJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgc2VsZi5oYW5kbGVfbG9jYXRpb25faGFzaF9jaGFuZ2UoKTtcclxuICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhhbmRsZV9sb2NhdGlvbl9oYXNoX2NoYW5nZSA6IGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgIFMgPSB0aGlzLlM7XHJcblxyXG4gICAgICBTKCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScsIHRoaXMuc2NvcGUpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzZXR0aW5ncyA9IFModGhpcykuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpO1xyXG4gICAgICAgIGlmIChzZXR0aW5ncy5kZWVwX2xpbmtpbmcpIHtcclxuICAgICAgICAgIC8vIE1hdGNoIHRoZSBsb2NhdGlvbiBoYXNoIHRvIGEgbGFiZWxcclxuICAgICAgICAgIHZhciBoYXNoO1xyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLnNjcm9sbF90b19jb250ZW50KSB7XHJcbiAgICAgICAgICAgIGhhc2ggPSBzZWxmLnNjb3BlLmxvY2F0aW9uLmhhc2g7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBwcmVmaXggdGhlIGhhc2ggdG8gcHJldmVudCBhbmNob3Igc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgIGhhc2ggPSBzZWxmLnNjb3BlLmxvY2F0aW9uLmhhc2gucmVwbGFjZSgnZm5kdG4tJywgJycpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKGhhc2ggIT0gJycpIHtcclxuICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgbG9jYXRpb24gaGFzaCByZWZlcmVuY2VzIGEgdGFiIGNvbnRlbnQgZGl2IG9yXHJcbiAgICAgICAgICAgIC8vIGFub3RoZXIgZWxlbWVudCBvbiB0aGUgcGFnZSAoaW5zaWRlIG9yIG91dHNpZGUgdGhlIHRhYiBjb250ZW50IGRpdilcclxuICAgICAgICAgICAgdmFyIGhhc2hfZWxlbWVudCA9IFMoaGFzaCk7XHJcbiAgICAgICAgICAgIGlmIChoYXNoX2VsZW1lbnQuaGFzQ2xhc3MoJ2NvbnRlbnQnKSAmJiBoYXNoX2VsZW1lbnQucGFyZW50KCkuaGFzQ2xhc3MoJ3RhYnMtY29udGVudCcpKSB7XHJcbiAgICAgICAgICAgICAgLy8gVGFiIGNvbnRlbnQgZGl2XHJcbiAgICAgICAgICAgICAgc2VsZi50b2dnbGVfYWN0aXZlX3RhYigkKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXSA+ICogPiBhW2hyZWY9JyArIGhhc2ggKyAnXScpLnBhcmVudCgpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvLyBOb3QgdGhlIHRhYiBjb250ZW50IGRpdi4gSWYgaW5zaWRlIHRoZSB0YWIgY29udGVudCwgZmluZCB0aGVcclxuICAgICAgICAgICAgICAvLyBjb250YWluaW5nIHRhYiBhbmQgdG9nZ2xlIGl0IGFzIGFjdGl2ZS5cclxuICAgICAgICAgICAgICB2YXIgaGFzaF90YWJfY29udGFpbmVyX2lkID0gaGFzaF9lbGVtZW50LmNsb3Nlc3QoJy5jb250ZW50JykuYXR0cignaWQnKTtcclxuICAgICAgICAgICAgICBpZiAoaGFzaF90YWJfY29udGFpbmVyX2lkICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgc2VsZi50b2dnbGVfYWN0aXZlX3RhYigkKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXSA+ICogPiBhW2hyZWY9IycgKyBoYXNoX3RhYl9jb250YWluZXJfaWQgKyAnXScpLnBhcmVudCgpLCBoYXNoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFJlZmVyZW5jZSB0aGUgZGVmYXVsdCB0YWIgaGFzaGVzIHdoaWNoIHdlcmUgaW5pdGlhbGl6ZWQgaW4gdGhlIGluaXQgZnVuY3Rpb25cclxuICAgICAgICAgICAgZm9yICh2YXIgaW5kID0gMDsgaW5kIDwgc2VsZi5kZWZhdWx0X3RhYl9oYXNoZXMubGVuZ3RoOyBpbmQrKykge1xyXG4gICAgICAgICAgICAgIHNlbGYudG9nZ2xlX2FjdGl2ZV90YWIoJCgnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10gPiAqID4gYVtocmVmPScgKyBzZWxmLmRlZmF1bHRfdGFiX2hhc2hlc1tpbmRdICsgJ10nKS5wYXJlbnQoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICB9KTtcclxuICAgICB9LFxyXG5cclxuICAgIHRvZ2dsZV9hY3RpdmVfdGFiIDogZnVuY3Rpb24gKHRhYiwgbG9jYXRpb25faGFzaCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBTID0gc2VsZi5TLFxyXG4gICAgICAgICAgdGFicyA9IHRhYi5jbG9zZXN0KCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScpLFxyXG4gICAgICAgICAgdGFiX2xpbmsgPSB0YWIuZmluZCgnYScpLFxyXG4gICAgICAgICAgYW5jaG9yID0gdGFiLmNoaWxkcmVuKCdhJykuZmlyc3QoKSxcclxuICAgICAgICAgIHRhcmdldF9oYXNoID0gJyMnICsgYW5jaG9yLmF0dHIoJ2hyZWYnKS5zcGxpdCgnIycpWzFdLFxyXG4gICAgICAgICAgdGFyZ2V0ID0gUyh0YXJnZXRfaGFzaCksXHJcbiAgICAgICAgICBzaWJsaW5ncyA9IHRhYi5zaWJsaW5ncygpLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSB0YWJzLmRhdGEodGhpcy5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKSxcclxuICAgICAgICAgIGludGVycHJldF9rZXl1cF9hY3Rpb24gPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAvLyBMaWdodCBtb2RpZmljYXRpb24gb2YgSGV5ZG9uIFBpY2tlcmluZydzIFByYWN0aWNhbCBBUklBIEV4YW1wbGVzOiBodHRwOi8vaGV5ZG9ud29ya3MuY29tL3ByYWN0aWNhbF9hcmlhX2V4YW1wbGVzL2pzL2ExMXkuanNcclxuXHJcbiAgICAgICAgICAgIC8vIGRlZmluZSBjdXJyZW50LCBwcmV2aW91cyBhbmQgbmV4dCAocG9zc2libGUpIHRhYnNcclxuXHJcbiAgICAgICAgICAgIHZhciAkb3JpZ2luYWwgPSAkKHRoaXMpO1xyXG4gICAgICAgICAgICB2YXIgJHByZXYgPSAkKHRoaXMpLnBhcmVudHMoJ2xpJykucHJldigpLmNoaWxkcmVuKCdbcm9sZT1cInRhYlwiXScpO1xyXG4gICAgICAgICAgICB2YXIgJG5leHQgPSAkKHRoaXMpLnBhcmVudHMoJ2xpJykubmV4dCgpLmNoaWxkcmVuKCdbcm9sZT1cInRhYlwiXScpO1xyXG4gICAgICAgICAgICB2YXIgJHRhcmdldDtcclxuXHJcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIGRpcmVjdGlvbiAocHJldiBvciBuZXh0KVxyXG5cclxuICAgICAgICAgICAgc3dpdGNoIChlLmtleUNvZGUpIHtcclxuICAgICAgICAgICAgICBjYXNlIDM3OlxyXG4gICAgICAgICAgICAgICAgJHRhcmdldCA9ICRwcmV2O1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgY2FzZSAzOTpcclxuICAgICAgICAgICAgICAgICR0YXJnZXQgPSAkbmV4dDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAkdGFyZ2V0ID0gZmFsc2VcclxuICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICgkdGFyZ2V0Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICRvcmlnaW5hbC5hdHRyKHtcclxuICAgICAgICAgICAgICAgICd0YWJpbmRleCcgOiAnLTEnLFxyXG4gICAgICAgICAgICAgICAgJ2FyaWEtc2VsZWN0ZWQnIDogbnVsbFxyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICR0YXJnZXQuYXR0cih7XHJcbiAgICAgICAgICAgICAgICAndGFiaW5kZXgnIDogJzAnLFxyXG4gICAgICAgICAgICAgICAgJ2FyaWEtc2VsZWN0ZWQnIDogdHJ1ZVxyXG4gICAgICAgICAgICAgIH0pLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEhpZGUgcGFuZWxzXHJcblxyXG4gICAgICAgICAgICAkKCdbcm9sZT1cInRhYnBhbmVsXCJdJylcclxuICAgICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2hvdyBwYW5lbCB3aGljaCBjb3JyZXNwb25kcyB0byB0YXJnZXRcclxuXHJcbiAgICAgICAgICAgICQoJyMnICsgJChkb2N1bWVudC5hY3RpdmVFbGVtZW50KS5hdHRyKCdocmVmJykuc3Vic3RyaW5nKDEpKVxyXG4gICAgICAgICAgICAgIC5hdHRyKCdhcmlhLWhpZGRlbicsIG51bGwpO1xyXG5cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBnb190b19oYXNoID0gZnVuY3Rpb24oaGFzaCkge1xyXG4gICAgICAgICAgICAvLyBUaGlzIGZ1bmN0aW9uIGFsbG93cyBjb3JyZWN0IGJlaGF2aW91ciBvZiB0aGUgYnJvd3NlcidzIGJhY2sgYnV0dG9uIHdoZW4gZGVlcCBsaW5raW5nIGlzIGVuYWJsZWQuIFdpdGhvdXQgaXRcclxuICAgICAgICAgICAgLy8gdGhlIHVzZXIgd291bGQgZ2V0IGNvbnRpbnVhbGx5IHJlZGlyZWN0ZWQgdG8gdGhlIGRlZmF1bHQgaGFzaC5cclxuICAgICAgICAgICAgdmFyIGRlZmF1bHRfaGFzaCA9IHNldHRpbmdzLnNjcm9sbF90b19jb250ZW50ID8gc2VsZi5kZWZhdWx0X3RhYl9oYXNoZXNbMF0gOiAnZm5kdG4tJyArIHNlbGYuZGVmYXVsdF90YWJfaGFzaGVzWzBdLnJlcGxhY2UoJyMnLCAnJyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoaGFzaCAhPT0gZGVmYXVsdF9oYXNoIHx8IHdpbmRvdy5sb2NhdGlvbi5oYXNoKSB7XHJcbiAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBoYXNoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG5cclxuICAgICAgLy8gYWxsb3cgdXNhZ2Ugb2YgZGF0YS10YWItY29udGVudCBhdHRyaWJ1dGUgaW5zdGVhZCBvZiBocmVmXHJcbiAgICAgIGlmIChhbmNob3IuZGF0YSgndGFiLWNvbnRlbnQnKSkge1xyXG4gICAgICAgIHRhcmdldF9oYXNoID0gJyMnICsgYW5jaG9yLmRhdGEoJ3RhYi1jb250ZW50Jykuc3BsaXQoJyMnKVsxXTtcclxuICAgICAgICB0YXJnZXQgPSBTKHRhcmdldF9oYXNoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHNldHRpbmdzLmRlZXBfbGlua2luZykge1xyXG5cclxuICAgICAgICBpZiAoc2V0dGluZ3Muc2Nyb2xsX3RvX2NvbnRlbnQpIHtcclxuXHJcbiAgICAgICAgICAvLyByZXRhaW4gY3VycmVudCBoYXNoIHRvIHNjcm9sbCB0byBjb250ZW50XHJcbiAgICAgICAgICBnb190b19oYXNoKGxvY2F0aW9uX2hhc2ggfHwgdGFyZ2V0X2hhc2gpO1xyXG5cclxuICAgICAgICAgIGlmIChsb2NhdGlvbl9oYXNoID09IHVuZGVmaW5lZCB8fCBsb2NhdGlvbl9oYXNoID09IHRhcmdldF9oYXNoKSB7XHJcbiAgICAgICAgICAgIHRhYi5wYXJlbnQoKVswXS5zY3JvbGxJbnRvVmlldygpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgUyh0YXJnZXRfaGFzaClbMF0uc2Nyb2xsSW50b1ZpZXcoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gcHJlZml4IHRoZSBoYXNoZXMgc28gdGhhdCB0aGUgYnJvd3NlciBkb2Vzbid0IHNjcm9sbCBkb3duXHJcbiAgICAgICAgICBpZiAobG9jYXRpb25faGFzaCAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgZ29fdG9faGFzaCgnZm5kdG4tJyArIGxvY2F0aW9uX2hhc2gucmVwbGFjZSgnIycsICcnKSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBnb190b19oYXNoKCdmbmR0bi0nICsgdGFyZ2V0X2hhc2gucmVwbGFjZSgnIycsICcnKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBXQVJOSU5HOiBUaGUgYWN0aXZhdGlvbiBhbmQgZGVhY3RpdmF0aW9uIG9mIHRoZSB0YWIgY29udGVudCBtdXN0XHJcbiAgICAgIC8vIG9jY3VyIGFmdGVyIHRoZSBkZWVwIGxpbmtpbmcgaW4gb3JkZXIgdG8gcHJvcGVybHkgcmVmcmVzaCB0aGUgYnJvd3NlclxyXG4gICAgICAvLyB3aW5kb3cgKG5vdGFibHkgaW4gQ2hyb21lKS5cclxuICAgICAgLy8gQ2xlYW4gdXAgbXVsdGlwbGUgYXR0ciBpbnN0YW5jZXMgdG8gZG9uZSBvbmNlXHJcbiAgICAgIHRhYi5hZGRDbGFzcyhzZXR0aW5ncy5hY3RpdmVfY2xhc3MpLnRyaWdnZXJIYW5kbGVyKCdvcGVuZWQnKTtcclxuICAgICAgdGFiX2xpbmsuYXR0cih7J2FyaWEtc2VsZWN0ZWQnIDogJ3RydWUnLCAgdGFiaW5kZXggOiAwfSk7XHJcbiAgICAgIHNpYmxpbmdzLnJlbW92ZUNsYXNzKHNldHRpbmdzLmFjdGl2ZV9jbGFzcylcclxuICAgICAgc2libGluZ3MuZmluZCgnYScpLmF0dHIoeydhcmlhLXNlbGVjdGVkJyA6ICdmYWxzZScvKiwgIHRhYmluZGV4IDogLTEqL30pO1xyXG4gICAgICB0YXJnZXQuc2libGluZ3MoKS5yZW1vdmVDbGFzcyhzZXR0aW5ncy5hY3RpdmVfY2xhc3MpLmF0dHIoeydhcmlhLWhpZGRlbicgOiAndHJ1ZScvKiwgIHRhYmluZGV4IDogLTEqL30pO1xyXG4gICAgICB0YXJnZXQuYWRkQ2xhc3Moc2V0dGluZ3MuYWN0aXZlX2NsYXNzKS5hdHRyKCdhcmlhLWhpZGRlbicsICdmYWxzZScpLnJlbW92ZUF0dHIoJ3RhYmluZGV4Jyk7XHJcbiAgICAgIHNldHRpbmdzLmNhbGxiYWNrKHRhYik7XHJcbiAgICAgIHRhcmdldC50cmlnZ2VySGFuZGxlcigndG9nZ2xlZCcsIFt0YXJnZXRdKTtcclxuICAgICAgdGFicy50cmlnZ2VySGFuZGxlcigndG9nZ2xlZCcsIFt0YWJdKTtcclxuXHJcbiAgICAgIHRhYl9saW5rLm9mZigna2V5ZG93bicpLm9uKCdrZXlkb3duJywgaW50ZXJwcmV0X2tleXVwX2FjdGlvbiApO1xyXG4gICAgfSxcclxuXHJcbiAgICBkYXRhX2F0dHIgOiBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgIGlmICh0aGlzLm5hbWVzcGFjZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZXNwYWNlICsgJy0nICsgc3RyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc3RyO1xyXG4gICAgfSxcclxuXHJcbiAgICBvZmYgOiBmdW5jdGlvbiAoKSB7fSxcclxuXHJcbiAgICByZWZsb3cgOiBmdW5jdGlvbiAoKSB7fVxyXG4gIH07XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG5cclxuOyhmdW5jdGlvbiAoJCwgd2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICBGb3VuZGF0aW9uLmxpYnMudG9vbHRpcCA9IHtcclxuICAgIG5hbWUgOiAndG9vbHRpcCcsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIGFkZGl0aW9uYWxfaW5oZXJpdGFibGVfY2xhc3NlcyA6IFtdLFxyXG4gICAgICB0b29sdGlwX2NsYXNzIDogJy50b29sdGlwJyxcclxuICAgICAgYXBwZW5kX3RvIDogJ2JvZHknLFxyXG4gICAgICB0b3VjaF9jbG9zZV90ZXh0IDogJ1RhcCBUbyBDbG9zZScsXHJcbiAgICAgIGRpc2FibGVfZm9yX3RvdWNoIDogZmFsc2UsXHJcbiAgICAgIGhvdmVyX2RlbGF5IDogMjAwLFxyXG4gICAgICBmYWRlX2luX2R1cmF0aW9uIDogMTUwLFxyXG4gICAgICBmYWRlX291dF9kdXJhdGlvbiA6IDE1MCxcclxuICAgICAgc2hvd19vbiA6ICdhbGwnLFxyXG4gICAgICB0aXBfdGVtcGxhdGUgOiBmdW5jdGlvbiAoc2VsZWN0b3IsIGNvbnRlbnQpIHtcclxuICAgICAgICByZXR1cm4gJzxzcGFuIGRhdGEtc2VsZWN0b3I9XCInICsgc2VsZWN0b3IgKyAnXCIgaWQ9XCInICsgc2VsZWN0b3IgKyAnXCIgY2xhc3M9XCInXHJcbiAgICAgICAgICArIEZvdW5kYXRpb24ubGlicy50b29sdGlwLnNldHRpbmdzLnRvb2x0aXBfY2xhc3Muc3Vic3RyaW5nKDEpXHJcbiAgICAgICAgICArICdcIiByb2xlPVwidG9vbHRpcFwiPicgKyBjb250ZW50ICsgJzxzcGFuIGNsYXNzPVwibnViXCI+PC9zcGFuPjwvc3Bhbj4nO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGNhY2hlIDoge30sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzY29wZSwgbWV0aG9kLCBvcHRpb25zKSB7XHJcbiAgICAgIEZvdW5kYXRpb24uaW5oZXJpdCh0aGlzLCAncmFuZG9tX3N0cicpO1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3VsZF9zaG93IDogZnVuY3Rpb24gKHRhcmdldCwgdGlwKSB7XHJcbiAgICAgIHZhciBzZXR0aW5ncyA9ICQuZXh0ZW5kKHt9LCB0aGlzLnNldHRpbmdzLCB0aGlzLmRhdGFfb3B0aW9ucyh0YXJnZXQpKTtcclxuXHJcbiAgICAgIGlmIChzZXR0aW5ncy5zaG93X29uID09PSAnYWxsJykge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc21hbGwoKSAmJiBzZXR0aW5ncy5zaG93X29uID09PSAnc21hbGwnKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5tZWRpdW0oKSAmJiBzZXR0aW5ncy5zaG93X29uID09PSAnbWVkaXVtJykge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMubGFyZ2UoKSAmJiBzZXR0aW5ncy5zaG93X29uID09PSAnbGFyZ2UnKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICBtZWRpdW0gOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiBtYXRjaE1lZGlhKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1snbWVkaXVtJ10pLm1hdGNoZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGxhcmdlIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gbWF0Y2hNZWRpYShGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ2xhcmdlJ10pLm1hdGNoZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBTID0gc2VsZi5TO1xyXG5cclxuICAgICAgc2VsZi5jcmVhdGUodGhpcy5TKGluc3RhbmNlKSk7XHJcblxyXG4gICAgICBmdW5jdGlvbiBfc3RhcnRTaG93KGVsdCwgJHRoaXMsIGltbWVkaWF0ZSkge1xyXG4gICAgICAgIGlmIChlbHQudGltZXIpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChpbW1lZGlhdGUpIHtcclxuICAgICAgICAgIGVsdC50aW1lciA9IG51bGw7XHJcbiAgICAgICAgICBzZWxmLnNob3dUaXAoJHRoaXMpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBlbHQudGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZWx0LnRpbWVyID0gbnVsbDtcclxuICAgICAgICAgICAgc2VsZi5zaG93VGlwKCR0aGlzKTtcclxuICAgICAgICAgIH0uYmluZChlbHQpLCBzZWxmLnNldHRpbmdzLmhvdmVyX2RlbGF5KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZ1bmN0aW9uIF9zdGFydEhpZGUoZWx0LCAkdGhpcykge1xyXG4gICAgICAgIGlmIChlbHQudGltZXIpIHtcclxuICAgICAgICAgIGNsZWFyVGltZW91dChlbHQudGltZXIpO1xyXG4gICAgICAgICAgZWx0LnRpbWVyID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNlbGYuaGlkZSgkdGhpcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICQodGhpcy5zY29wZSlcclxuICAgICAgICAub2ZmKCcudG9vbHRpcCcpXHJcbiAgICAgICAgLm9uKCdtb3VzZWVudGVyLmZuZHRuLnRvb2x0aXAgbW91c2VsZWF2ZS5mbmR0bi50b29sdGlwIHRvdWNoc3RhcnQuZm5kdG4udG9vbHRpcCBNU1BvaW50ZXJEb3duLmZuZHRuLnRvb2x0aXAnLFxyXG4gICAgICAgICAgJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciAkdGhpcyA9IFModGhpcyksXHJcbiAgICAgICAgICAgICAgc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgc2VsZi5zZXR0aW5ncywgc2VsZi5kYXRhX29wdGlvbnMoJHRoaXMpKSxcclxuICAgICAgICAgICAgICBpc190b3VjaCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgIGlmIChNb2Rlcm5penIudG91Y2ggJiYgL3RvdWNoc3RhcnR8TVNQb2ludGVyRG93bi9pLnRlc3QoZS50eXBlKSAmJiBTKGUudGFyZ2V0KS5pcygnYScpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoL21vdXNlL2kudGVzdChlLnR5cGUpICYmIHNlbGYuaWVfdG91Y2goZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgXHJcbiAgICAgICAgICBpZiAoJHRoaXMuaGFzQ2xhc3MoJ29wZW4nKSkge1xyXG4gICAgICAgICAgICBpZiAoTW9kZXJuaXpyLnRvdWNoICYmIC90b3VjaHN0YXJ0fE1TUG9pbnRlckRvd24vaS50ZXN0KGUudHlwZSkpIHtcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VsZi5oaWRlKCR0aGlzKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5kaXNhYmxlX2Zvcl90b3VjaCAmJiBNb2Rlcm5penIudG91Y2ggJiYgL3RvdWNoc3RhcnR8TVNQb2ludGVyRG93bi9pLnRlc3QoZS50eXBlKSkge1xyXG4gICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICghc2V0dGluZ3MuZGlzYWJsZV9mb3JfdG91Y2ggJiYgTW9kZXJuaXpyLnRvdWNoICYmIC90b3VjaHN0YXJ0fE1TUG9pbnRlckRvd24vaS50ZXN0KGUudHlwZSkpIHtcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgUyhzZXR0aW5ncy50b29sdGlwX2NsYXNzICsgJy5vcGVuJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAgIGlzX3RvdWNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAvLyBjbG9zZSBvdGhlciBvcGVuIHRvb2x0aXBzIG9uIHRvdWNoXHJcbiAgICAgICAgICAgICAgaWYgKCQoJy5vcGVuWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10nKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgIHZhciBwcmV2T3BlbiA9IFMoJCgnLm9wZW5bJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpWzBdKTtcclxuICAgICAgICAgICAgICAgc2VsZi5oaWRlKHByZXZPcGVuKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICgvZW50ZXJ8b3Zlci9pLnRlc3QoZS50eXBlKSkge1xyXG4gICAgICAgICAgICAgIF9zdGFydFNob3codGhpcywgJHRoaXMpO1xyXG5cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlLnR5cGUgPT09ICdtb3VzZW91dCcgfHwgZS50eXBlID09PSAnbW91c2VsZWF2ZScpIHtcclxuICAgICAgICAgICAgICBfc3RhcnRIaWRlKHRoaXMsICR0aGlzKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBfc3RhcnRTaG93KHRoaXMsICR0aGlzLCB0cnVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdtb3VzZWxlYXZlLmZuZHRuLnRvb2x0aXAgdG91Y2hzdGFydC5mbmR0bi50b29sdGlwIE1TUG9pbnRlckRvd24uZm5kdG4udG9vbHRpcCcsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXS5vcGVuJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGlmICgvbW91c2UvaS50ZXN0KGUudHlwZSkgJiYgc2VsZi5pZV90b3VjaChlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKCQodGhpcykuZGF0YSgndG9vbHRpcC1vcGVuLWV2ZW50LXR5cGUnKSA9PSAndG91Y2gnICYmIGUudHlwZSA9PSAnbW91c2VsZWF2ZScpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfSBlbHNlIGlmICgkKHRoaXMpLmRhdGEoJ3Rvb2x0aXAtb3Blbi1ldmVudC10eXBlJykgPT0gJ21vdXNlJyAmJiAvTVNQb2ludGVyRG93bnx0b3VjaHN0YXJ0L2kudGVzdChlLnR5cGUpKSB7XHJcbiAgICAgICAgICAgIHNlbGYuY29udmVydF90b190b3VjaCgkKHRoaXMpKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIF9zdGFydEhpZGUodGhpcywgJCh0aGlzKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ0RPTU5vZGVSZW1vdmVkIERPTUF0dHJNb2RpZmllZCcsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXTpub3QoYSknLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgX3N0YXJ0SGlkZSh0aGlzLCBTKHRoaXMpKTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgaWVfdG91Y2ggOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAvLyBIb3cgZG8gSSBkaXN0aW5ndWlzaCBiZXR3ZWVuIElFMTEgYW5kIFdpbmRvd3MgUGhvbmUgOD8/Pz8/XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0sXHJcblxyXG4gICAgc2hvd1RpcCA6IGZ1bmN0aW9uICgkdGFyZ2V0KSB7XHJcbiAgICAgIHZhciAkdGlwID0gdGhpcy5nZXRUaXAoJHRhcmdldCk7XHJcbiAgICAgIGlmICh0aGlzLnNob3VsZF9zaG93KCR0YXJnZXQsICR0aXApKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hvdygkdGFyZ2V0KTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9LFxyXG5cclxuICAgIGdldFRpcCA6IGZ1bmN0aW9uICgkdGFyZ2V0KSB7XHJcbiAgICAgIHZhciBzZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IoJHRhcmdldCksXHJcbiAgICAgICAgICBzZXR0aW5ncyA9ICQuZXh0ZW5kKHt9LCB0aGlzLnNldHRpbmdzLCB0aGlzLmRhdGFfb3B0aW9ucygkdGFyZ2V0KSksXHJcbiAgICAgICAgICB0aXAgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgdGlwID0gdGhpcy5TKCdzcGFuW2RhdGEtc2VsZWN0b3I9XCInICsgc2VsZWN0b3IgKyAnXCJdJyArIHNldHRpbmdzLnRvb2x0aXBfY2xhc3MpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gKHR5cGVvZiB0aXAgPT09ICdvYmplY3QnKSA/IHRpcCA6IGZhbHNlO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZWxlY3RvciA6IGZ1bmN0aW9uICgkdGFyZ2V0KSB7XHJcbiAgICAgIHZhciBkYXRhU2VsZWN0b3IgPSAkdGFyZ2V0LmF0dHIodGhpcy5hdHRyX25hbWUoKSkgfHwgJHRhcmdldC5hdHRyKCdkYXRhLXNlbGVjdG9yJyk7XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGRhdGFTZWxlY3RvciAhPSAnc3RyaW5nJykge1xyXG4gICAgICAgIGRhdGFTZWxlY3RvciA9IHRoaXMucmFuZG9tX3N0cig2KTtcclxuICAgICAgICAkdGFyZ2V0XHJcbiAgICAgICAgICAuYXR0cignZGF0YS1zZWxlY3RvcicsIGRhdGFTZWxlY3RvcilcclxuICAgICAgICAgIC5hdHRyKCdhcmlhLWRlc2NyaWJlZGJ5JywgZGF0YVNlbGVjdG9yKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGRhdGFTZWxlY3RvcjtcclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlIDogZnVuY3Rpb24gKCR0YXJnZXQpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgdGhpcy5zZXR0aW5ncywgdGhpcy5kYXRhX29wdGlvbnMoJHRhcmdldCkpLFxyXG4gICAgICAgICAgdGlwX3RlbXBsYXRlID0gdGhpcy5zZXR0aW5ncy50aXBfdGVtcGxhdGU7XHJcblxyXG4gICAgICBpZiAodHlwZW9mIHNldHRpbmdzLnRpcF90ZW1wbGF0ZSA9PT0gJ3N0cmluZycgJiYgd2luZG93Lmhhc093blByb3BlcnR5KHNldHRpbmdzLnRpcF90ZW1wbGF0ZSkpIHtcclxuICAgICAgICB0aXBfdGVtcGxhdGUgPSB3aW5kb3dbc2V0dGluZ3MudGlwX3RlbXBsYXRlXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyICR0aXAgPSAkKHRpcF90ZW1wbGF0ZSh0aGlzLnNlbGVjdG9yKCR0YXJnZXQpLCAkKCc8ZGl2PjwvZGl2PicpLmh0bWwoJHRhcmdldC5hdHRyKCd0aXRsZScpKS5odG1sKCkpKSxcclxuICAgICAgICAgIGNsYXNzZXMgPSB0aGlzLmluaGVyaXRhYmxlX2NsYXNzZXMoJHRhcmdldCk7XHJcblxyXG4gICAgICAkdGlwLmFkZENsYXNzKGNsYXNzZXMpLmFwcGVuZFRvKHNldHRpbmdzLmFwcGVuZF90byk7XHJcblxyXG4gICAgICBpZiAoTW9kZXJuaXpyLnRvdWNoKSB7XHJcbiAgICAgICAgJHRpcC5hcHBlbmQoJzxzcGFuIGNsYXNzPVwidGFwLXRvLWNsb3NlXCI+JyArIHNldHRpbmdzLnRvdWNoX2Nsb3NlX3RleHQgKyAnPC9zcGFuPicpO1xyXG4gICAgICAgICR0aXAub24oJ3RvdWNoc3RhcnQuZm5kdG4udG9vbHRpcCBNU1BvaW50ZXJEb3duLmZuZHRuLnRvb2x0aXAnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5oaWRlKCR0YXJnZXQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkdGFyZ2V0LnJlbW92ZUF0dHIoJ3RpdGxlJykuYXR0cigndGl0bGUnLCAnJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlcG9zaXRpb24gOiBmdW5jdGlvbiAodGFyZ2V0LCB0aXAsIGNsYXNzZXMpIHtcclxuICAgICAgdmFyIHdpZHRoLCBudWIsIG51YkhlaWdodCwgbnViV2lkdGgsIG9ialBvcztcclxuXHJcbiAgICAgIHRpcC5jc3MoJ3Zpc2liaWxpdHknLCAnaGlkZGVuJykuc2hvdygpO1xyXG5cclxuICAgICAgd2lkdGggPSB0YXJnZXQuZGF0YSgnd2lkdGgnKTtcclxuICAgICAgbnViID0gdGlwLmNoaWxkcmVuKCcubnViJyk7XHJcbiAgICAgIG51YkhlaWdodCA9IG51Yi5vdXRlckhlaWdodCgpO1xyXG4gICAgICBudWJXaWR0aCA9IG51Yi5vdXRlcldpZHRoKCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5zbWFsbCgpKSB7XHJcbiAgICAgICAgdGlwLmNzcyh7J3dpZHRoJyA6ICcxMDAlJ30pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRpcC5jc3Moeyd3aWR0aCcgOiAod2lkdGgpID8gd2lkdGggOiAnYXV0byd9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgb2JqUG9zID0gZnVuY3Rpb24gKG9iaiwgdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0LCB3aWR0aCkge1xyXG4gICAgICAgIHJldHVybiBvYmouY3NzKHtcclxuICAgICAgICAgICd0b3AnIDogKHRvcCkgPyB0b3AgOiAnYXV0bycsXHJcbiAgICAgICAgICAnYm90dG9tJyA6IChib3R0b20pID8gYm90dG9tIDogJ2F1dG8nLFxyXG4gICAgICAgICAgJ2xlZnQnIDogKGxlZnQpID8gbGVmdCA6ICdhdXRvJyxcclxuICAgICAgICAgICdyaWdodCcgOiAocmlnaHQpID8gcmlnaHQgOiAnYXV0bydcclxuICAgICAgICB9KS5lbmQoKTtcclxuICAgICAgfTtcclxuICAgICAgXHJcbiAgICAgIHZhciBvX3RvcCA9IHRhcmdldC5vZmZzZXQoKS50b3A7XHJcbiAgICAgIHZhciBvX2xlZnQgPSB0YXJnZXQub2Zmc2V0KCkubGVmdDtcclxuICAgICAgdmFyIG91dGVySGVpZ2h0ID0gdGFyZ2V0Lm91dGVySGVpZ2h0KCk7XHJcblxyXG4gICAgICBvYmpQb3ModGlwLCAob190b3AgKyBvdXRlckhlaWdodCArIDEwKSwgJ2F1dG8nLCAnYXV0bycsIG9fbGVmdCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5zbWFsbCgpKSB7XHJcbiAgICAgICAgb2JqUG9zKHRpcCwgKG9fdG9wICsgb3V0ZXJIZWlnaHQgKyAxMCksICdhdXRvJywgJ2F1dG8nLCAxMi41LCAkKHRoaXMuc2NvcGUpLndpZHRoKCkpO1xyXG4gICAgICAgIHRpcC5hZGRDbGFzcygndGlwLW92ZXJyaWRlJyk7XHJcbiAgICAgICAgb2JqUG9zKG51YiwgLW51YkhlaWdodCwgJ2F1dG8nLCAnYXV0bycsIG9fbGVmdCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKEZvdW5kYXRpb24ucnRsKSB7XHJcbiAgICAgICAgICBudWIuYWRkQ2xhc3MoJ3J0bCcpO1xyXG4gICAgICAgICAgb19sZWZ0ID0gb19sZWZ0ICsgdGFyZ2V0Lm91dGVyV2lkdGgoKSAtIHRpcC5vdXRlcldpZHRoKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBvYmpQb3ModGlwLCAob190b3AgKyBvdXRlckhlaWdodCArIDEwKSwgJ2F1dG8nLCAnYXV0bycsIG9fbGVmdCk7XHJcbiAgICAgICAgLy8gcmVzZXQgbnViIGZyb20gc21hbGwgc3R5bGVzLCBpZiB0aGV5J3ZlIGJlZW4gYXBwbGllZFxyXG4gICAgICAgIGlmIChudWIuYXR0cignc3R5bGUnKSkge1xyXG4gICAgICAgICAgbnViLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHRpcC5yZW1vdmVDbGFzcygndGlwLW92ZXJyaWRlJyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdmFyIHRpcF9vdXRlckhlaWdodCA9IHRpcC5vdXRlckhlaWdodCgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjbGFzc2VzICYmIGNsYXNzZXMuaW5kZXhPZigndGlwLXRvcCcpID4gLTEpIHtcclxuICAgICAgICAgIGlmIChGb3VuZGF0aW9uLnJ0bCkge1xyXG4gICAgICAgICAgICBudWIuYWRkQ2xhc3MoJ3J0bCcpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgb2JqUG9zKHRpcCwgKG9fdG9wIC0gdGlwX291dGVySGVpZ2h0KSwgJ2F1dG8nLCAnYXV0bycsIG9fbGVmdClcclxuICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCd0aXAtb3ZlcnJpZGUnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGNsYXNzZXMgJiYgY2xhc3Nlcy5pbmRleE9mKCd0aXAtbGVmdCcpID4gLTEpIHtcclxuICAgICAgICAgIG9ialBvcyh0aXAsIChvX3RvcCArIChvdXRlckhlaWdodCAvIDIpIC0gKHRpcF9vdXRlckhlaWdodCAvIDIpKSwgJ2F1dG8nLCAnYXV0bycsIChvX2xlZnQgLSB0aXAub3V0ZXJXaWR0aCgpIC0gbnViSGVpZ2h0KSlcclxuICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCd0aXAtb3ZlcnJpZGUnKTtcclxuICAgICAgICAgIG51Yi5yZW1vdmVDbGFzcygncnRsJyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChjbGFzc2VzICYmIGNsYXNzZXMuaW5kZXhPZigndGlwLXJpZ2h0JykgPiAtMSkge1xyXG4gICAgICAgICAgb2JqUG9zKHRpcCwgKG9fdG9wICsgKG91dGVySGVpZ2h0IC8gMikgLSAodGlwX291dGVySGVpZ2h0IC8gMikpLCAnYXV0bycsICdhdXRvJywgKG9fbGVmdCArIHRhcmdldC5vdXRlcldpZHRoKCkgKyBudWJIZWlnaHQpKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3RpcC1vdmVycmlkZScpO1xyXG4gICAgICAgICAgbnViLnJlbW92ZUNsYXNzKCdydGwnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRpcC5jc3MoJ3Zpc2liaWxpdHknLCAndmlzaWJsZScpLmhpZGUoKTtcclxuICAgIH0sXHJcblxyXG4gICAgc21hbGwgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiBtYXRjaE1lZGlhKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllcy5zbWFsbCkubWF0Y2hlcyAmJlxyXG4gICAgICAgICFtYXRjaE1lZGlhKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllcy5tZWRpdW0pLm1hdGNoZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGluaGVyaXRhYmxlX2NsYXNzZXMgOiBmdW5jdGlvbiAoJHRhcmdldCkge1xyXG4gICAgICB2YXIgc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgdGhpcy5zZXR0aW5ncywgdGhpcy5kYXRhX29wdGlvbnMoJHRhcmdldCkpLFxyXG4gICAgICAgICAgaW5oZXJpdGFibGVzID0gWyd0aXAtdG9wJywgJ3RpcC1sZWZ0JywgJ3RpcC1ib3R0b20nLCAndGlwLXJpZ2h0JywgJ3JhZGl1cycsICdyb3VuZCddLmNvbmNhdChzZXR0aW5ncy5hZGRpdGlvbmFsX2luaGVyaXRhYmxlX2NsYXNzZXMpLFxyXG4gICAgICAgICAgY2xhc3NlcyA9ICR0YXJnZXQuYXR0cignY2xhc3MnKSxcclxuICAgICAgICAgIGZpbHRlcmVkID0gY2xhc3NlcyA/ICQubWFwKGNsYXNzZXMuc3BsaXQoJyAnKSwgZnVuY3Rpb24gKGVsLCBpKSB7XHJcbiAgICAgICAgICAgIGlmICgkLmluQXJyYXkoZWwsIGluaGVyaXRhYmxlcykgIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGVsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KS5qb2luKCcgJykgOiAnJztcclxuXHJcbiAgICAgIHJldHVybiAkLnRyaW0oZmlsdGVyZWQpO1xyXG4gICAgfSxcclxuXHJcbiAgICBjb252ZXJ0X3RvX3RvdWNoIDogZnVuY3Rpb24gKCR0YXJnZXQpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgJHRpcCA9IHNlbGYuZ2V0VGlwKCR0YXJnZXQpLFxyXG4gICAgICAgICAgc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgc2VsZi5zZXR0aW5ncywgc2VsZi5kYXRhX29wdGlvbnMoJHRhcmdldCkpO1xyXG5cclxuICAgICAgaWYgKCR0aXAuZmluZCgnLnRhcC10by1jbG9zZScpLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICR0aXAuYXBwZW5kKCc8c3BhbiBjbGFzcz1cInRhcC10by1jbG9zZVwiPicgKyBzZXR0aW5ncy50b3VjaF9jbG9zZV90ZXh0ICsgJzwvc3Bhbj4nKTtcclxuICAgICAgICAkdGlwLm9uKCdjbGljay5mbmR0bi50b29sdGlwLnRhcGNsb3NlIHRvdWNoc3RhcnQuZm5kdG4udG9vbHRpcC50YXBjbG9zZSBNU1BvaW50ZXJEb3duLmZuZHRuLnRvb2x0aXAudGFwY2xvc2UnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5oaWRlKCR0YXJnZXQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkdGFyZ2V0LmRhdGEoJ3Rvb2x0aXAtb3Blbi1ldmVudC10eXBlJywgJ3RvdWNoJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3cgOiBmdW5jdGlvbiAoJHRhcmdldCkge1xyXG4gICAgICB2YXIgJHRpcCA9IHRoaXMuZ2V0VGlwKCR0YXJnZXQpO1xyXG4gICAgICBpZiAoJHRhcmdldC5kYXRhKCd0b29sdGlwLW9wZW4tZXZlbnQtdHlwZScpID09ICd0b3VjaCcpIHtcclxuICAgICAgICB0aGlzLmNvbnZlcnRfdG9fdG91Y2goJHRhcmdldCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMucmVwb3NpdGlvbigkdGFyZ2V0LCAkdGlwLCAkdGFyZ2V0LmF0dHIoJ2NsYXNzJykpO1xyXG4gICAgICAkdGFyZ2V0LmFkZENsYXNzKCdvcGVuJyk7XHJcbiAgICAgICR0aXAuZmFkZUluKHRoaXMuc2V0dGluZ3MuZmFkZV9pbl9kdXJhdGlvbik7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGUgOiBmdW5jdGlvbiAoJHRhcmdldCkge1xyXG4gICAgICB2YXIgJHRpcCA9IHRoaXMuZ2V0VGlwKCR0YXJnZXQpO1xyXG5cclxuICAgICAgJHRpcC5mYWRlT3V0KHRoaXMuc2V0dGluZ3MuZmFkZV9vdXRfZHVyYXRpb24sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAkdGlwLmZpbmQoJy50YXAtdG8tY2xvc2UnKS5yZW1vdmUoKTtcclxuICAgICAgICAkdGlwLm9mZignY2xpY2suZm5kdG4udG9vbHRpcC50YXBjbG9zZSBNU1BvaW50ZXJEb3duLmZuZHRuLnRhcGNsb3NlJyk7XHJcbiAgICAgICAgJHRhcmdldC5yZW1vdmVDbGFzcygnb3BlbicpO1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgb2ZmIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgIHRoaXMuUyh0aGlzLnNjb3BlKS5vZmYoJy5mbmR0bi50b29sdGlwJyk7XHJcbiAgICAgIHRoaXMuUyh0aGlzLnNldHRpbmdzLnRvb2x0aXBfY2xhc3MpLmVhY2goZnVuY3Rpb24gKGkpIHtcclxuICAgICAgICAkKCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLmVxKGkpLmF0dHIoJ3RpdGxlJywgJCh0aGlzKS50ZXh0KCkpO1xyXG4gICAgICB9KS5yZW1vdmUoKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVmbG93IDogZnVuY3Rpb24gKCkge31cclxuICB9O1xyXG59KGpRdWVyeSwgd2luZG93LCB3aW5kb3cuZG9jdW1lbnQpKTtcclxuXHJcbjsoZnVuY3Rpb24gKCQsIHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgRm91bmRhdGlvbi5saWJzLnRvcGJhciA9IHtcclxuICAgIG5hbWUgOiAndG9wYmFyJyxcclxuXHJcbiAgICB2ZXJzaW9uIDogJzUuNS4zJyxcclxuXHJcbiAgICBzZXR0aW5ncyA6IHtcclxuICAgICAgaW5kZXggOiAwLFxyXG4gICAgICBzdGFydF9vZmZzZXQgOiAwLFxyXG4gICAgICBzdGlja3lfY2xhc3MgOiAnc3RpY2t5JyxcclxuICAgICAgY3VzdG9tX2JhY2tfdGV4dCA6IHRydWUsXHJcbiAgICAgIGJhY2tfdGV4dCA6ICdCYWNrJyxcclxuICAgICAgbW9iaWxlX3Nob3dfcGFyZW50X2xpbmsgOiB0cnVlLFxyXG4gICAgICBpc19ob3ZlciA6IHRydWUsXHJcbiAgICAgIHNjcm9sbHRvcCA6IHRydWUsIC8vIGp1bXAgdG8gdG9wIHdoZW4gc3RpY2t5IG5hdiBtZW51IHRvZ2dsZSBpcyBjbGlja2VkXHJcbiAgICAgIHN0aWNreV9vbiA6ICdhbGwnLFxyXG4gICAgICBkcm9wZG93bl9hdXRvY2xvc2U6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uIChzZWN0aW9uLCBtZXRob2QsIG9wdGlvbnMpIHtcclxuICAgICAgRm91bmRhdGlvbi5pbmhlcml0KHRoaXMsICdhZGRfY3VzdG9tX3J1bGUgcmVnaXN0ZXJfbWVkaWEgdGhyb3R0bGUnKTtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgc2VsZi5yZWdpc3Rlcl9tZWRpYSgndG9wYmFyJywgJ2ZvdW5kYXRpb24tbXEtdG9wYmFyJyk7XHJcblxyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcblxyXG4gICAgICBzZWxmLlMoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJywgdGhpcy5zY29wZSkuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHRvcGJhciA9ICQodGhpcyksXHJcbiAgICAgICAgICAgIHNldHRpbmdzID0gdG9wYmFyLmRhdGEoc2VsZi5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKSxcclxuICAgICAgICAgICAgc2VjdGlvbiA9IHNlbGYuUygnc2VjdGlvbiwgLnRvcC1iYXItc2VjdGlvbicsIHRoaXMpO1xyXG4gICAgICAgIHRvcGJhci5kYXRhKCdpbmRleCcsIDApO1xyXG4gICAgICAgIHZhciB0b3BiYXJDb250YWluZXIgPSB0b3BiYXIucGFyZW50KCk7XHJcbiAgICAgICAgaWYgKHRvcGJhckNvbnRhaW5lci5oYXNDbGFzcygnZml4ZWQnKSB8fCBzZWxmLmlzX3N0aWNreSh0b3BiYXIsIHRvcGJhckNvbnRhaW5lciwgc2V0dGluZ3MpICkge1xyXG4gICAgICAgICAgc2VsZi5zZXR0aW5ncy5zdGlja3lfY2xhc3MgPSBzZXR0aW5ncy5zdGlja3lfY2xhc3M7XHJcbiAgICAgICAgICBzZWxmLnNldHRpbmdzLnN0aWNreV90b3BiYXIgPSB0b3BiYXI7XHJcbiAgICAgICAgICB0b3BiYXIuZGF0YSgnaGVpZ2h0JywgdG9wYmFyQ29udGFpbmVyLm91dGVySGVpZ2h0KCkpO1xyXG4gICAgICAgICAgdG9wYmFyLmRhdGEoJ3N0aWNreW9mZnNldCcsIHRvcGJhckNvbnRhaW5lci5vZmZzZXQoKS50b3ApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0b3BiYXIuZGF0YSgnaGVpZ2h0JywgdG9wYmFyLm91dGVySGVpZ2h0KCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncy5hc3NlbWJsZWQpIHtcclxuICAgICAgICAgIHNlbGYuYXNzZW1ibGUodG9wYmFyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzZXR0aW5ncy5pc19ob3Zlcikge1xyXG4gICAgICAgICAgc2VsZi5TKCcuaGFzLWRyb3Bkb3duJywgdG9wYmFyKS5hZGRDbGFzcygnbm90LWNsaWNrJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHNlbGYuUygnLmhhcy1kcm9wZG93bicsIHRvcGJhcikucmVtb3ZlQ2xhc3MoJ25vdC1jbGljaycpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGFkIGJvZHkgd2hlbiBzdGlja3kgKHNjcm9sbGVkKSBvciBmaXhlZC5cclxuICAgICAgICBzZWxmLmFkZF9jdXN0b21fcnVsZSgnLmYtdG9wYmFyLWZpeGVkIHsgcGFkZGluZy10b3A6ICcgKyB0b3BiYXIuZGF0YSgnaGVpZ2h0JykgKyAncHggfScpO1xyXG5cclxuICAgICAgICBpZiAodG9wYmFyQ29udGFpbmVyLmhhc0NsYXNzKCdmaXhlZCcpKSB7XHJcbiAgICAgICAgICBzZWxmLlMoJ2JvZHknKS5hZGRDbGFzcygnZi10b3BiYXItZml4ZWQnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIH0sXHJcblxyXG4gICAgaXNfc3RpY2t5IDogZnVuY3Rpb24gKHRvcGJhciwgdG9wYmFyQ29udGFpbmVyLCBzZXR0aW5ncykge1xyXG4gICAgICB2YXIgc3RpY2t5ICAgICA9IHRvcGJhckNvbnRhaW5lci5oYXNDbGFzcyhzZXR0aW5ncy5zdGlja3lfY2xhc3MpO1xyXG4gICAgICB2YXIgc21hbGxNYXRjaCA9IG1hdGNoTWVkaWEoRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLnNtYWxsKS5tYXRjaGVzO1xyXG4gICAgICB2YXIgbWVkTWF0Y2ggICA9IG1hdGNoTWVkaWEoRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzLm1lZGl1bSkubWF0Y2hlcztcclxuICAgICAgdmFyIGxyZ01hdGNoICAgPSBtYXRjaE1lZGlhKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllcy5sYXJnZSkubWF0Y2hlcztcclxuXHJcbiAgICAgIGlmIChzdGlja3kgJiYgc2V0dGluZ3Muc3RpY2t5X29uID09PSAnYWxsJykge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzdGlja3kgJiYgdGhpcy5zbWFsbCgpICYmIHNldHRpbmdzLnN0aWNreV9vbi5pbmRleE9mKCdzbWFsbCcpICE9PSAtMSkge1xyXG4gICAgICAgIGlmIChzbWFsbE1hdGNoICYmICFtZWRNYXRjaCAmJiAhbHJnTWF0Y2gpIHsgcmV0dXJuIHRydWU7IH1cclxuICAgICAgfVxyXG4gICAgICBpZiAoc3RpY2t5ICYmIHRoaXMubWVkaXVtKCkgJiYgc2V0dGluZ3Muc3RpY2t5X29uLmluZGV4T2YoJ21lZGl1bScpICE9PSAtMSkge1xyXG4gICAgICAgIGlmIChzbWFsbE1hdGNoICYmIG1lZE1hdGNoICYmICFscmdNYXRjaCkgeyByZXR1cm4gdHJ1ZTsgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChzdGlja3kgJiYgdGhpcy5sYXJnZSgpICYmIHNldHRpbmdzLnN0aWNreV9vbi5pbmRleE9mKCdsYXJnZScpICE9PSAtMSkge1xyXG4gICAgICAgIGlmIChzbWFsbE1hdGNoICYmIG1lZE1hdGNoICYmIGxyZ01hdGNoKSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9LFxyXG5cclxuICAgIHRvZ2dsZSA6IGZ1bmN0aW9uICh0b2dnbGVFbCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICB0b3BiYXI7XHJcblxyXG4gICAgICBpZiAodG9nZ2xlRWwpIHtcclxuICAgICAgICB0b3BiYXIgPSBzZWxmLlModG9nZ2xlRWwpLmNsb3Nlc3QoJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddJyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdG9wYmFyID0gc2VsZi5TKCdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXScpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgc2V0dGluZ3MgPSB0b3BiYXIuZGF0YSh0aGlzLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpO1xyXG5cclxuICAgICAgdmFyIHNlY3Rpb24gPSBzZWxmLlMoJ3NlY3Rpb24sIC50b3AtYmFyLXNlY3Rpb24nLCB0b3BiYXIpO1xyXG5cclxuICAgICAgaWYgKHNlbGYuYnJlYWtwb2ludCgpKSB7XHJcbiAgICAgICAgaWYgKCFzZWxmLnJ0bCkge1xyXG4gICAgICAgICAgc2VjdGlvbi5jc3Moe2xlZnQgOiAnMCUnfSk7XHJcbiAgICAgICAgICAkKCc+Lm5hbWUnLCBzZWN0aW9uKS5jc3Moe2xlZnQgOiAnMTAwJSd9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2VjdGlvbi5jc3Moe3JpZ2h0IDogJzAlJ30pO1xyXG4gICAgICAgICAgJCgnPi5uYW1lJywgc2VjdGlvbikuY3NzKHtyaWdodCA6ICcxMDAlJ30pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2VsZi5TKCdsaS5tb3ZlZCcsIHNlY3Rpb24pLnJlbW92ZUNsYXNzKCdtb3ZlZCcpO1xyXG4gICAgICAgIHRvcGJhci5kYXRhKCdpbmRleCcsIDApO1xyXG5cclxuICAgICAgICB0b3BiYXJcclxuICAgICAgICAgIC50b2dnbGVDbGFzcygnZXhwYW5kZWQnKVxyXG4gICAgICAgICAgLmNzcygnaGVpZ2h0JywgJycpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2V0dGluZ3Muc2Nyb2xsdG9wKSB7XHJcbiAgICAgICAgaWYgKCF0b3BiYXIuaGFzQ2xhc3MoJ2V4cGFuZGVkJykpIHtcclxuICAgICAgICAgIGlmICh0b3BiYXIuaGFzQ2xhc3MoJ2ZpeGVkJykpIHtcclxuICAgICAgICAgICAgdG9wYmFyLnBhcmVudCgpLmFkZENsYXNzKCdmaXhlZCcpO1xyXG4gICAgICAgICAgICB0b3BiYXIucmVtb3ZlQ2xhc3MoJ2ZpeGVkJyk7XHJcbiAgICAgICAgICAgIHNlbGYuUygnYm9keScpLmFkZENsYXNzKCdmLXRvcGJhci1maXhlZCcpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAodG9wYmFyLnBhcmVudCgpLmhhc0NsYXNzKCdmaXhlZCcpKSB7XHJcbiAgICAgICAgICBpZiAoc2V0dGluZ3Muc2Nyb2xsdG9wKSB7XHJcbiAgICAgICAgICAgIHRvcGJhci5wYXJlbnQoKS5yZW1vdmVDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICAgICAgdG9wYmFyLmFkZENsYXNzKCdmaXhlZCcpO1xyXG4gICAgICAgICAgICBzZWxmLlMoJ2JvZHknKS5yZW1vdmVDbGFzcygnZi10b3BiYXItZml4ZWQnKTtcclxuXHJcbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRvcGJhci5wYXJlbnQoKS5yZW1vdmVDbGFzcygnZXhwYW5kZWQnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHNlbGYuaXNfc3RpY2t5KHRvcGJhciwgdG9wYmFyLnBhcmVudCgpLCBzZXR0aW5ncykpIHtcclxuICAgICAgICAgIHRvcGJhci5wYXJlbnQoKS5hZGRDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0b3BiYXIucGFyZW50KCkuaGFzQ2xhc3MoJ2ZpeGVkJykpIHtcclxuICAgICAgICAgIGlmICghdG9wYmFyLmhhc0NsYXNzKCdleHBhbmRlZCcpKSB7XHJcbiAgICAgICAgICAgIHRvcGJhci5yZW1vdmVDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICAgICAgdG9wYmFyLnBhcmVudCgpLnJlbW92ZUNsYXNzKCdleHBhbmRlZCcpO1xyXG4gICAgICAgICAgICBzZWxmLnVwZGF0ZV9zdGlja3lfcG9zaXRpb25pbmcoKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRvcGJhci5hZGRDbGFzcygnZml4ZWQnKTtcclxuICAgICAgICAgICAgdG9wYmFyLnBhcmVudCgpLmFkZENsYXNzKCdleHBhbmRlZCcpO1xyXG4gICAgICAgICAgICBzZWxmLlMoJ2JvZHknKS5hZGRDbGFzcygnZi10b3BiYXItZml4ZWQnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgdGltZXIgOiBudWxsLFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uIChiYXIpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgUyA9IHRoaXMuUztcclxuXHJcbiAgICAgIFModGhpcy5zY29wZSlcclxuICAgICAgICAub2ZmKCcudG9wYmFyJylcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLnRvcGJhcicsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSAudG9nZ2xlLXRvcGJhcicsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBzZWxmLnRvZ2dsZSh0aGlzKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4udG9wYmFyIGNvbnRleHRtZW51LmZuZHRuLnRvcGJhcicsICcudG9wLWJhciAudG9wLWJhci1zZWN0aW9uIGxpIGFbaHJlZl49XCIjXCJdLFsnICsgdGhpcy5hdHRyX25hbWUoKSArICddIC50b3AtYmFyLXNlY3Rpb24gbGkgYVtocmVmXj1cIiNcIl0nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIGxpID0gJCh0aGlzKS5jbG9zZXN0KCdsaScpLFxyXG4gICAgICAgICAgICAgIHRvcGJhciA9IGxpLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJyksXHJcbiAgICAgICAgICAgICAgc2V0dGluZ3MgPSB0b3BiYXIuZGF0YShzZWxmLmF0dHJfbmFtZSh0cnVlKSArICctaW5pdCcpO1xyXG5cclxuICAgICAgICAgIGlmIChzZXR0aW5ncy5kcm9wZG93bl9hdXRvY2xvc2UgJiYgc2V0dGluZ3MuaXNfaG92ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGhvdmVyTGkgPSAkKHRoaXMpLmNsb3Nlc3QoJy5ob3ZlcicpO1xyXG4gICAgICAgICAgICBob3ZlckxpLnJlbW92ZUNsYXNzKCdob3ZlcicpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHNlbGYuYnJlYWtwb2ludCgpICYmICFsaS5oYXNDbGFzcygnYmFjaycpICYmICFsaS5oYXNDbGFzcygnaGFzLWRyb3Bkb3duJykpIHtcclxuICAgICAgICAgICAgc2VsZi50b2dnbGUoKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLnRvcGJhcicsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSBsaS5oYXMtZHJvcGRvd24nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIGxpID0gUyh0aGlzKSxcclxuICAgICAgICAgICAgICB0YXJnZXQgPSBTKGUudGFyZ2V0KSxcclxuICAgICAgICAgICAgICB0b3BiYXIgPSBsaS5jbG9zZXN0KCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLFxyXG4gICAgICAgICAgICAgIHNldHRpbmdzID0gdG9wYmFyLmRhdGEoc2VsZi5hdHRyX25hbWUodHJ1ZSkgKyAnLWluaXQnKTtcclxuXHJcbiAgICAgICAgICBpZiAodGFyZ2V0LmRhdGEoJ3JldmVhbElkJykpIHtcclxuICAgICAgICAgICAgc2VsZi50b2dnbGUoKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmIChzZWxmLmJyZWFrcG9pbnQoKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmlzX2hvdmVyICYmICFNb2Rlcm5penIudG91Y2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgICAgICAgaWYgKGxpLmhhc0NsYXNzKCdob3ZlcicpKSB7XHJcbiAgICAgICAgICAgIGxpXHJcbiAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdob3ZlcicpXHJcbiAgICAgICAgICAgICAgLmZpbmQoJ2xpJylcclxuICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2hvdmVyJyk7XHJcblxyXG4gICAgICAgICAgICBsaS5wYXJlbnRzKCdsaS5ob3ZlcicpXHJcbiAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdob3ZlcicpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGkuYWRkQ2xhc3MoJ2hvdmVyJyk7XHJcblxyXG4gICAgICAgICAgICAkKGxpKS5zaWJsaW5ncygpLnJlbW92ZUNsYXNzKCdob3ZlcicpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRhcmdldFswXS5ub2RlTmFtZSA9PT0gJ0EnICYmIHRhcmdldC5wYXJlbnQoKS5oYXNDbGFzcygnaGFzLWRyb3Bkb3duJykpIHtcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4udG9wYmFyJywgJ1snICsgdGhpcy5hdHRyX25hbWUoKSArICddIC5oYXMtZHJvcGRvd24+YScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBpZiAoc2VsZi5icmVha3BvaW50KCkpIHtcclxuXHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgIHZhciAkdGhpcyA9IFModGhpcyksXHJcbiAgICAgICAgICAgICAgICB0b3BiYXIgPSAkdGhpcy5jbG9zZXN0KCdbJyArIHNlbGYuYXR0cl9uYW1lKCkgKyAnXScpLFxyXG4gICAgICAgICAgICAgICAgc2VjdGlvbiA9IHRvcGJhci5maW5kKCdzZWN0aW9uLCAudG9wLWJhci1zZWN0aW9uJyksXHJcbiAgICAgICAgICAgICAgICBkcm9wZG93bkhlaWdodCA9ICR0aGlzLm5leHQoJy5kcm9wZG93bicpLm91dGVySGVpZ2h0KCksXHJcbiAgICAgICAgICAgICAgICAkc2VsZWN0ZWRMaSA9ICR0aGlzLmNsb3Nlc3QoJ2xpJyk7XHJcblxyXG4gICAgICAgICAgICB0b3BiYXIuZGF0YSgnaW5kZXgnLCB0b3BiYXIuZGF0YSgnaW5kZXgnKSArIDEpO1xyXG4gICAgICAgICAgICAkc2VsZWN0ZWRMaS5hZGRDbGFzcygnbW92ZWQnKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghc2VsZi5ydGwpIHtcclxuICAgICAgICAgICAgICBzZWN0aW9uLmNzcyh7bGVmdCA6IC0oMTAwICogdG9wYmFyLmRhdGEoJ2luZGV4JykpICsgJyUnfSk7XHJcbiAgICAgICAgICAgICAgc2VjdGlvbi5maW5kKCc+Lm5hbWUnKS5jc3Moe2xlZnQgOiAxMDAgKiB0b3BiYXIuZGF0YSgnaW5kZXgnKSArICclJ30pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHNlY3Rpb24uY3NzKHtyaWdodCA6IC0oMTAwICogdG9wYmFyLmRhdGEoJ2luZGV4JykpICsgJyUnfSk7XHJcbiAgICAgICAgICAgICAgc2VjdGlvbi5maW5kKCc+Lm5hbWUnKS5jc3Moe3JpZ2h0IDogMTAwICogdG9wYmFyLmRhdGEoJ2luZGV4JykgKyAnJSd9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdG9wYmFyLmNzcygnaGVpZ2h0JywgJHRoaXMuc2libGluZ3MoJ3VsJykub3V0ZXJIZWlnaHQodHJ1ZSkgKyB0b3BiYXIuZGF0YSgnaGVpZ2h0JykpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgUyh3aW5kb3cpLm9mZignLnRvcGJhcicpLm9uKCdyZXNpemUuZm5kdG4udG9wYmFyJywgc2VsZi50aHJvdHRsZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBzZWxmLnJlc2l6ZS5jYWxsKHNlbGYpO1xyXG4gICAgICB9LCA1MCkpLnRyaWdnZXIoJ3Jlc2l6ZS5mbmR0bi50b3BiYXInKS5sb2FkKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBvZmZzZXQgaXMgY2FsY3VsYXRlZCBhZnRlciBhbGwgb2YgdGhlIHBhZ2VzIHJlc291cmNlcyBoYXZlIGxvYWRlZFxyXG4gICAgICAgICAgUyh0aGlzKS50cmlnZ2VyKCdyZXNpemUuZm5kdG4udG9wYmFyJyk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgUygnYm9keScpLm9mZignLnRvcGJhcicpLm9uKCdjbGljay5mbmR0bi50b3BiYXInLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHZhciBwYXJlbnQgPSBTKGUudGFyZ2V0KS5jbG9zZXN0KCdsaScpLmNsb3Nlc3QoJ2xpLmhvdmVyJyk7XHJcblxyXG4gICAgICAgIGlmIChwYXJlbnQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgUygnWycgKyBzZWxmLmF0dHJfbmFtZSgpICsgJ10gbGkuaG92ZXInKS5yZW1vdmVDbGFzcygnaG92ZXInKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBHbyB1cCBhIGxldmVsIG9uIENsaWNrXHJcbiAgICAgIFModGhpcy5zY29wZSkub24oJ2NsaWNrLmZuZHRuLnRvcGJhcicsICdbJyArIHRoaXMuYXR0cl9uYW1lKCkgKyAnXSAuaGFzLWRyb3Bkb3duIC5iYWNrJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgIHZhciAkdGhpcyA9IFModGhpcyksXHJcbiAgICAgICAgICAgIHRvcGJhciA9ICR0aGlzLmNsb3Nlc3QoJ1snICsgc2VsZi5hdHRyX25hbWUoKSArICddJyksXHJcbiAgICAgICAgICAgIHNlY3Rpb24gPSB0b3BiYXIuZmluZCgnc2VjdGlvbiwgLnRvcC1iYXItc2VjdGlvbicpLFxyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IHRvcGJhci5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JyksXHJcbiAgICAgICAgICAgICRtb3ZlZExpID0gJHRoaXMuY2xvc2VzdCgnbGkubW92ZWQnKSxcclxuICAgICAgICAgICAgJHByZXZpb3VzTGV2ZWxVbCA9ICRtb3ZlZExpLnBhcmVudCgpO1xyXG5cclxuICAgICAgICB0b3BiYXIuZGF0YSgnaW5kZXgnLCB0b3BiYXIuZGF0YSgnaW5kZXgnKSAtIDEpO1xyXG5cclxuICAgICAgICBpZiAoIXNlbGYucnRsKSB7XHJcbiAgICAgICAgICBzZWN0aW9uLmNzcyh7bGVmdCA6IC0oMTAwICogdG9wYmFyLmRhdGEoJ2luZGV4JykpICsgJyUnfSk7XHJcbiAgICAgICAgICBzZWN0aW9uLmZpbmQoJz4ubmFtZScpLmNzcyh7bGVmdCA6IDEwMCAqIHRvcGJhci5kYXRhKCdpbmRleCcpICsgJyUnfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHNlY3Rpb24uY3NzKHtyaWdodCA6IC0oMTAwICogdG9wYmFyLmRhdGEoJ2luZGV4JykpICsgJyUnfSk7XHJcbiAgICAgICAgICBzZWN0aW9uLmZpbmQoJz4ubmFtZScpLmNzcyh7cmlnaHQgOiAxMDAgKiB0b3BiYXIuZGF0YSgnaW5kZXgnKSArICclJ30pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRvcGJhci5kYXRhKCdpbmRleCcpID09PSAwKSB7XHJcbiAgICAgICAgICB0b3BiYXIuY3NzKCdoZWlnaHQnLCAnJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRvcGJhci5jc3MoJ2hlaWdodCcsICRwcmV2aW91c0xldmVsVWwub3V0ZXJIZWlnaHQodHJ1ZSkgKyB0b3BiYXIuZGF0YSgnaGVpZ2h0JykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAkbW92ZWRMaS5yZW1vdmVDbGFzcygnbW92ZWQnKTtcclxuICAgICAgICB9LCAzMDApO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIFNob3cgZHJvcGRvd24gbWVudXMgd2hlbiB0aGVpciBpdGVtcyBhcmUgZm9jdXNlZFxyXG4gICAgICBTKHRoaXMuc2NvcGUpLmZpbmQoJy5kcm9wZG93biBhJylcclxuICAgICAgICAuZm9jdXMoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgJCh0aGlzKS5wYXJlbnRzKCcuaGFzLWRyb3Bkb3duJykuYWRkQ2xhc3MoJ2hvdmVyJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAuYmx1cihmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAkKHRoaXMpLnBhcmVudHMoJy5oYXMtZHJvcGRvd24nKS5yZW1vdmVDbGFzcygnaG92ZXInKTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVzaXplIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgIHNlbGYuUygnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdG9wYmFyID0gc2VsZi5TKHRoaXMpLFxyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IHRvcGJhci5kYXRhKHNlbGYuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0Jyk7XHJcblxyXG4gICAgICAgIHZhciBzdGlja3lDb250YWluZXIgPSB0b3BiYXIucGFyZW50KCcuJyArIHNlbGYuc2V0dGluZ3Muc3RpY2t5X2NsYXNzKTtcclxuICAgICAgICB2YXIgc3RpY2t5T2Zmc2V0O1xyXG5cclxuICAgICAgICBpZiAoIXNlbGYuYnJlYWtwb2ludCgpKSB7XHJcbiAgICAgICAgICB2YXIgZG9Ub2dnbGUgPSB0b3BiYXIuaGFzQ2xhc3MoJ2V4cGFuZGVkJyk7XHJcbiAgICAgICAgICB0b3BiYXJcclxuICAgICAgICAgICAgLmNzcygnaGVpZ2h0JywgJycpXHJcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnZXhwYW5kZWQnKVxyXG4gICAgICAgICAgICAuZmluZCgnbGknKVxyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2hvdmVyJyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZG9Ub2dnbGUpIHtcclxuICAgICAgICAgICAgICBzZWxmLnRvZ2dsZSh0b3BiYXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc2VsZi5pc19zdGlja3kodG9wYmFyLCBzdGlja3lDb250YWluZXIsIHNldHRpbmdzKSkge1xyXG4gICAgICAgICAgaWYgKHN0aWNreUNvbnRhaW5lci5oYXNDbGFzcygnZml4ZWQnKSkge1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGZpeGVkIHRvIGFsbG93IGZvciBjb3JyZWN0IGNhbGN1bGF0aW9uIG9mIHRoZSBvZmZzZXQuXHJcbiAgICAgICAgICAgIHN0aWNreUNvbnRhaW5lci5yZW1vdmVDbGFzcygnZml4ZWQnKTtcclxuXHJcbiAgICAgICAgICAgIHN0aWNreU9mZnNldCA9IHN0aWNreUNvbnRhaW5lci5vZmZzZXQoKS50b3A7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLlMoZG9jdW1lbnQuYm9keSkuaGFzQ2xhc3MoJ2YtdG9wYmFyLWZpeGVkJykpIHtcclxuICAgICAgICAgICAgICBzdGlja3lPZmZzZXQgLT0gdG9wYmFyLmRhdGEoJ2hlaWdodCcpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0b3BiYXIuZGF0YSgnc3RpY2t5b2Zmc2V0Jywgc3RpY2t5T2Zmc2V0KTtcclxuICAgICAgICAgICAgc3RpY2t5Q29udGFpbmVyLmFkZENsYXNzKCdmaXhlZCcpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3RpY2t5T2Zmc2V0ID0gc3RpY2t5Q29udGFpbmVyLm9mZnNldCgpLnRvcDtcclxuICAgICAgICAgICAgdG9wYmFyLmRhdGEoJ3N0aWNreW9mZnNldCcsIHN0aWNreU9mZnNldCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGJyZWFrcG9pbnQgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiAhbWF0Y2hNZWRpYShGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ3RvcGJhciddKS5tYXRjaGVzO1xyXG4gICAgfSxcclxuXHJcbiAgICBzbWFsbCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuIG1hdGNoTWVkaWEoRm91bmRhdGlvbi5tZWRpYV9xdWVyaWVzWydzbWFsbCddKS5tYXRjaGVzO1xyXG4gICAgfSxcclxuXHJcbiAgICBtZWRpdW0gOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiBtYXRjaE1lZGlhKEZvdW5kYXRpb24ubWVkaWFfcXVlcmllc1snbWVkaXVtJ10pLm1hdGNoZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGxhcmdlIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gbWF0Y2hNZWRpYShGb3VuZGF0aW9uLm1lZGlhX3F1ZXJpZXNbJ2xhcmdlJ10pLm1hdGNoZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIGFzc2VtYmxlIDogZnVuY3Rpb24gKHRvcGJhcikge1xyXG4gICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICBzZXR0aW5ncyA9IHRvcGJhci5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JyksXHJcbiAgICAgICAgICBzZWN0aW9uID0gc2VsZi5TKCdzZWN0aW9uLCAudG9wLWJhci1zZWN0aW9uJywgdG9wYmFyKTtcclxuXHJcbiAgICAgIC8vIFB1bGwgZWxlbWVudCBvdXQgb2YgdGhlIERPTSBmb3IgbWFuaXB1bGF0aW9uXHJcbiAgICAgIHNlY3Rpb24uZGV0YWNoKCk7XHJcblxyXG4gICAgICBzZWxmLlMoJy5oYXMtZHJvcGRvd24+YScsIHNlY3Rpb24pLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciAkbGluayA9IHNlbGYuUyh0aGlzKSxcclxuICAgICAgICAgICAgJGRyb3Bkb3duID0gJGxpbmsuc2libGluZ3MoJy5kcm9wZG93bicpLFxyXG4gICAgICAgICAgICB1cmwgPSAkbGluay5hdHRyKCdocmVmJyksXHJcbiAgICAgICAgICAgICR0aXRsZUxpO1xyXG5cclxuICAgICAgICBpZiAoISRkcm9wZG93bi5maW5kKCcudGl0bGUuYmFjaycpLmxlbmd0aCkge1xyXG5cclxuICAgICAgICAgIGlmIChzZXR0aW5ncy5tb2JpbGVfc2hvd19wYXJlbnRfbGluayA9PSB0cnVlICYmIHVybCkge1xyXG4gICAgICAgICAgICAkdGl0bGVMaSA9ICQoJzxsaSBjbGFzcz1cInRpdGxlIGJhY2sganMtZ2VuZXJhdGVkXCI+PGg1PjxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIj48L2E+PC9oNT48L2xpPjxsaSBjbGFzcz1cInBhcmVudC1saW5rIGhpZGUtZm9yLW1lZGl1bS11cFwiPjxhIGNsYXNzPVwicGFyZW50LWxpbmsganMtZ2VuZXJhdGVkXCIgaHJlZj1cIicgKyB1cmwgKyAnXCI+JyArICRsaW5rLmh0bWwoKSArJzwvYT48L2xpPicpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgJHRpdGxlTGkgPSAkKCc8bGkgY2xhc3M9XCJ0aXRsZSBiYWNrIGpzLWdlbmVyYXRlZFwiPjxoNT48YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCI+PC9hPjwvaDU+Jyk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy8gQ29weSBsaW5rIHRvIHN1Ym5hdlxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmN1c3RvbV9iYWNrX3RleHQgPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAkKCdoNT5hJywgJHRpdGxlTGkpLmh0bWwoc2V0dGluZ3MuYmFja190ZXh0KTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICQoJ2g1PmEnLCAkdGl0bGVMaSkuaHRtbCgnJmxhcXVvOyAnICsgJGxpbmsuaHRtbCgpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICRkcm9wZG93bi5wcmVwZW5kKCR0aXRsZUxpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gUHV0IGVsZW1lbnQgYmFjayBpbiB0aGUgRE9NXHJcbiAgICAgIHNlY3Rpb24uYXBwZW5kVG8odG9wYmFyKTtcclxuXHJcbiAgICAgIC8vIGNoZWNrIGZvciBzdGlja3lcclxuICAgICAgdGhpcy5zdGlja3koKTtcclxuXHJcbiAgICAgIHRoaXMuYXNzZW1ibGVkKHRvcGJhcik7XHJcbiAgICB9LFxyXG5cclxuICAgIGFzc2VtYmxlZCA6IGZ1bmN0aW9uICh0b3BiYXIpIHtcclxuICAgICAgdG9wYmFyLmRhdGEodGhpcy5hdHRyX25hbWUodHJ1ZSksICQuZXh0ZW5kKHt9LCB0b3BiYXIuZGF0YSh0aGlzLmF0dHJfbmFtZSh0cnVlKSksIHthc3NlbWJsZWQgOiB0cnVlfSkpO1xyXG4gICAgfSxcclxuXHJcbiAgICBoZWlnaHQgOiBmdW5jdGlvbiAodWwpIHtcclxuICAgICAgdmFyIHRvdGFsID0gMCxcclxuICAgICAgICAgIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgJCgnPiBsaScsIHVsKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0b3RhbCArPSBzZWxmLlModGhpcykub3V0ZXJIZWlnaHQodHJ1ZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIHRvdGFsO1xyXG4gICAgfSxcclxuXHJcbiAgICBzdGlja3kgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAgIHRoaXMuUyh3aW5kb3cpLm9uKCdzY3JvbGwnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgc2VsZi51cGRhdGVfc3RpY2t5X3Bvc2l0aW9uaW5nKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVfc3RpY2t5X3Bvc2l0aW9uaW5nIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIga2xhc3MgPSAnLicgKyB0aGlzLnNldHRpbmdzLnN0aWNreV9jbGFzcyxcclxuICAgICAgICAgICR3aW5kb3cgPSB0aGlzLlMod2luZG93KSxcclxuICAgICAgICAgIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgaWYgKHNlbGYuc2V0dGluZ3Muc3RpY2t5X3RvcGJhciAmJiBzZWxmLmlzX3N0aWNreSh0aGlzLnNldHRpbmdzLnN0aWNreV90b3BiYXIsdGhpcy5zZXR0aW5ncy5zdGlja3lfdG9wYmFyLnBhcmVudCgpLCB0aGlzLnNldHRpbmdzKSkge1xyXG4gICAgICAgIHZhciBkaXN0YW5jZSA9IHRoaXMuc2V0dGluZ3Muc3RpY2t5X3RvcGJhci5kYXRhKCdzdGlja3lvZmZzZXQnKSArIHRoaXMuc2V0dGluZ3Muc3RhcnRfb2Zmc2V0O1xyXG4gICAgICAgIGlmICghc2VsZi5TKGtsYXNzKS5oYXNDbGFzcygnZXhwYW5kZWQnKSkge1xyXG4gICAgICAgICAgaWYgKCR3aW5kb3cuc2Nyb2xsVG9wKCkgPiAoZGlzdGFuY2UpKSB7XHJcbiAgICAgICAgICAgIGlmICghc2VsZi5TKGtsYXNzKS5oYXNDbGFzcygnZml4ZWQnKSkge1xyXG4gICAgICAgICAgICAgIHNlbGYuUyhrbGFzcykuYWRkQ2xhc3MoJ2ZpeGVkJyk7XHJcbiAgICAgICAgICAgICAgc2VsZi5TKCdib2R5JykuYWRkQ2xhc3MoJ2YtdG9wYmFyLWZpeGVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSBpZiAoJHdpbmRvdy5zY3JvbGxUb3AoKSA8PSBkaXN0YW5jZSkge1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5TKGtsYXNzKS5oYXNDbGFzcygnZml4ZWQnKSkge1xyXG4gICAgICAgICAgICAgIHNlbGYuUyhrbGFzcykucmVtb3ZlQ2xhc3MoJ2ZpeGVkJyk7XHJcbiAgICAgICAgICAgICAgc2VsZi5TKCdib2R5JykucmVtb3ZlQ2xhc3MoJ2YtdG9wYmFyLWZpeGVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgb2ZmIDogZnVuY3Rpb24gKCkge1xyXG4gICAgICB0aGlzLlModGhpcy5zY29wZSkub2ZmKCcuZm5kdG4udG9wYmFyJyk7XHJcbiAgICAgIHRoaXMuUyh3aW5kb3cpLm9mZignLmZuZHRuLnRvcGJhcicpO1xyXG4gICAgfSxcclxuXHJcbiAgICByZWZsb3cgOiBmdW5jdGlvbiAoKSB7fVxyXG4gIH07XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG4iLCI7KGZ1bmN0aW9uICgkLCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQpIHtcclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIEZvdW5kYXRpb24ubGlicy5vZmZjYW52YXMgPSB7XHJcbiAgICBuYW1lIDogJ29mZmNhbnZhcycsXHJcblxyXG4gICAgdmVyc2lvbiA6ICc1LjUuMycsXHJcblxyXG4gICAgc2V0dGluZ3MgOiB7XHJcbiAgICAgIG9wZW5fbWV0aG9kIDogJ21vdmUnLFxyXG4gICAgICBjbG9zZV9vbl9jbGljayA6IGZhbHNlXHJcbiAgICB9LFxyXG5cclxuICAgIGluaXQgOiBmdW5jdGlvbiAoc2NvcGUsIG1ldGhvZCwgb3B0aW9ucykge1xyXG4gICAgICB0aGlzLmJpbmRpbmdzKG1ldGhvZCwgb3B0aW9ucyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGV2ZW50cyA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICAgICAgUyA9IHNlbGYuUyxcclxuICAgICAgICAgIG1vdmVfY2xhc3MgPSAnJyxcclxuICAgICAgICAgIHJpZ2h0X3Bvc3RmaXggPSAnJyxcclxuICAgICAgICAgIGxlZnRfcG9zdGZpeCA9ICcnLFxyXG4gICAgICAgICAgdG9wX3Bvc3RmaXggPSAnJyxcclxuICAgICAgICAgIGJvdHRvbV9wb3N0Zml4ID0gJyc7XHJcblxyXG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5vcGVuX21ldGhvZCA9PT0gJ21vdmUnKSB7XHJcbiAgICAgICAgbW92ZV9jbGFzcyA9ICdtb3ZlLSc7XHJcbiAgICAgICAgcmlnaHRfcG9zdGZpeCA9ICdyaWdodCc7XHJcbiAgICAgICAgbGVmdF9wb3N0Zml4ID0gJ2xlZnQnO1xyXG4gICAgICAgIHRvcF9wb3N0Zml4ID0gJ3RvcCc7XHJcbiAgICAgICAgYm90dG9tX3Bvc3RmaXggPSAnYm90dG9tJztcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLm9wZW5fbWV0aG9kID09PSAnb3ZlcmxhcF9zaW5nbGUnKSB7XHJcbiAgICAgICAgbW92ZV9jbGFzcyA9ICdvZmZjYW52YXMtb3ZlcmxhcC0nO1xyXG4gICAgICAgIHJpZ2h0X3Bvc3RmaXggPSAncmlnaHQnO1xyXG4gICAgICAgIGxlZnRfcG9zdGZpeCA9ICdsZWZ0JztcclxuICAgICAgICB0b3BfcG9zdGZpeCA9ICd0b3AnO1xyXG4gICAgICAgIGJvdHRvbV9wb3N0Zml4ID0gJ2JvdHRvbSc7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5vcGVuX21ldGhvZCA9PT0gJ292ZXJsYXAnKSB7XHJcbiAgICAgICAgbW92ZV9jbGFzcyA9ICdvZmZjYW52YXMtb3ZlcmxhcCc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIFModGhpcy5zY29wZSkub2ZmKCcub2ZmY2FudmFzJylcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcubGVmdC1vZmYtY2FudmFzLXRvZ2dsZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3RvZ2dsZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgcmlnaHRfcG9zdGZpeCk7XHJcbiAgICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5vcGVuX21ldGhvZCAhPT0gJ292ZXJsYXAnKSB7XHJcbiAgICAgICAgICAgIFMoJy5sZWZ0LXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgcmlnaHRfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcubGVmdC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmxlZnQtb2ZmLWNhbnZhcy1tZW51IGEnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIHNldHRpbmdzID0gc2VsZi5nZXRfc2V0dGluZ3MoZSk7XHJcbiAgICAgICAgICB2YXIgcGFyZW50ID0gUyh0aGlzKS5wYXJlbnQoKTtcclxuXHJcbiAgICAgICAgICBpZiAoc2V0dGluZ3MuY2xvc2Vfb25fY2xpY2sgJiYgIXBhcmVudC5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSAmJiAhcGFyZW50Lmhhc0NsYXNzKCdiYWNrJykpIHtcclxuICAgICAgICAgICAgc2VsZi5oaWRlLmNhbGwoc2VsZiwgbW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgsIHNlbGYuZ2V0X3dyYXBwZXIoZSkpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChTKHRoaXMpLnBhcmVudCgpLmhhc0NsYXNzKCdoYXMtc3VibWVudScpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgUyh0aGlzKS5zaWJsaW5ncygnLmxlZnQtc3VibWVudScpLnRvZ2dsZUNsYXNzKG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAocGFyZW50Lmhhc0NsYXNzKCdiYWNrJykpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLmxlZnQtb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC8vZW5kIG9mIGxlZnQgY2FudmFzXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuY2xpY2tfdG9nZ2xlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgaWYgKHNlbGYuc2V0dGluZ3Mub3Blbl9tZXRob2QgIT09ICdvdmVybGFwJykge1xyXG4gICAgICAgICAgICBTKCcucmlnaHQtc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcucmlnaHQtb2ZmLWNhbnZhcy1tZW51IGEnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgdmFyIHNldHRpbmdzID0gc2VsZi5nZXRfc2V0dGluZ3MoZSk7XHJcbiAgICAgICAgICB2YXIgcGFyZW50ID0gUyh0aGlzKS5wYXJlbnQoKTtcclxuXHJcbiAgICAgICAgICBpZiAoc2V0dGluZ3MuY2xvc2Vfb25fY2xpY2sgJiYgIXBhcmVudC5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSAmJiAhcGFyZW50Lmhhc0NsYXNzKCdiYWNrJykpIHtcclxuICAgICAgICAgICAgc2VsZi5oaWRlLmNhbGwoc2VsZiwgbW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCwgc2VsZi5nZXRfd3JhcHBlcihlKSk7XHJcbiAgICAgICAgICAgIHBhcmVudC5wYXJlbnQoKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgbGVmdF9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoUyh0aGlzKS5wYXJlbnQoKS5oYXNDbGFzcygnaGFzLXN1Ym1lbnUnKSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIFModGhpcykuc2libGluZ3MoJy5yaWdodC1zdWJtZW51JykudG9nZ2xlQ2xhc3MobW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgcGFyZW50LnBhcmVudCgpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAvL2VuZCBvZiByaWdodCBjYW52YXNcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcudG9wLW9mZi1jYW52YXMtdG9nZ2xlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuY2xpY2tfdG9nZ2xlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyBib3R0b21fcG9zdGZpeCk7XHJcbiAgICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5vcGVuX21ldGhvZCAhPT0gJ292ZXJsYXAnKSB7XHJcbiAgICAgICAgICAgIFMoJy50b3Atc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBib3R0b21fcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcudG9wLW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcudG9wLW9mZi1jYW52YXMtbWVudSBhJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHNlbGYuZ2V0X3NldHRpbmdzKGUpO1xyXG4gICAgICAgICAgdmFyIHBhcmVudCA9IFModGhpcykucGFyZW50KCk7XHJcblxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmNsb3NlX29uX2NsaWNrICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2hhcy1zdWJtZW51JykgJiYgIXBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaGlkZS5jYWxsKHNlbGYsIG1vdmVfY2xhc3MgKyBib3R0b21fcG9zdGZpeCwgc2VsZi5nZXRfd3JhcHBlcihlKSk7XHJcbiAgICAgICAgICAgIHBhcmVudC5wYXJlbnQoKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChTKHRoaXMpLnBhcmVudCgpLmhhc0NsYXNzKCdoYXMtc3VibWVudScpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgUyh0aGlzKS5zaWJsaW5ncygnLnRvcC1zdWJtZW51JykudG9nZ2xlQ2xhc3MobW92ZV9jbGFzcyArIGJvdHRvbV9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAocGFyZW50Lmhhc0NsYXNzKCdiYWNrJykpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIGJvdHRvbV9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy50b3Atb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC8vZW5kIG9mIHRvcCBjYW52YXNcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcuYm90dG9tLW9mZi1jYW52YXMtdG9nZ2xlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHNlbGYuY2xpY2tfdG9nZ2xlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCk7XHJcbiAgICAgICAgICBpZiAoc2VsZi5zZXR0aW5ncy5vcGVuX21ldGhvZCAhPT0gJ292ZXJsYXAnKSB7XHJcbiAgICAgICAgICAgIFMoJy5ib3R0b20tc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcuYm90dG9tLW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAub24oJ2NsaWNrLmZuZHRuLm9mZmNhbnZhcycsICcuYm90dG9tLW9mZi1jYW52YXMtbWVudSBhJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHNlbGYuZ2V0X3NldHRpbmdzKGUpO1xyXG4gICAgICAgICAgdmFyIHBhcmVudCA9IFModGhpcykucGFyZW50KCk7XHJcblxyXG4gICAgICAgICAgaWYgKHNldHRpbmdzLmNsb3NlX29uX2NsaWNrICYmICFwYXJlbnQuaGFzQ2xhc3MoJ2hhcy1zdWJtZW51JykgJiYgIXBhcmVudC5oYXNDbGFzcygnYmFjaycpKSB7XHJcbiAgICAgICAgICAgIHNlbGYuaGlkZS5jYWxsKHNlbGYsIG1vdmVfY2xhc3MgKyB0b3BfcG9zdGZpeCwgc2VsZi5nZXRfd3JhcHBlcihlKSk7XHJcbiAgICAgICAgICAgIHBhcmVudC5wYXJlbnQoKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChTKHRoaXMpLnBhcmVudCgpLmhhc0NsYXNzKCdoYXMtc3VibWVudScpKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgUyh0aGlzKS5zaWJsaW5ncygnLmJvdHRvbS1zdWJtZW51JykudG9nZ2xlQ2xhc3MobW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAocGFyZW50Lmhhc0NsYXNzKCdiYWNrJykpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBwYXJlbnQucGFyZW50KCkucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgICQoJy5ib3R0b20tb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC8vZW5kIG9mIGJvdHRvbVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5leGl0LW9mZi1jYW52YXMnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCk7XHJcbiAgICAgICAgICBTKCcucmlnaHQtc3VibWVudScpLnJlbW92ZUNsYXNzKG1vdmVfY2xhc3MgKyBsZWZ0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgaWYgKHJpZ2h0X3Bvc3RmaXgpIHtcclxuICAgICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIHJpZ2h0X3Bvc3RmaXgpO1xyXG4gICAgICAgICAgICBTKCcubGVmdC1zdWJtZW51JykucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcucmlnaHQtb2ZmLWNhbnZhcy10b2dnbGUnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5vbignY2xpY2suZm5kdG4ub2ZmY2FudmFzJywgJy5leGl0LW9mZi1jYW52YXMnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgc2VsZi5jbGlja19yZW1vdmVfY2xhc3MoZSwgbW92ZV9jbGFzcyArIGxlZnRfcG9zdGZpeCk7XHJcbiAgICAgICAgICAkKCcubGVmdC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgIGlmIChyaWdodF9wb3N0Zml4KSB7XHJcbiAgICAgICAgICAgIHNlbGYuY2xpY2tfcmVtb3ZlX2NsYXNzKGUsIG1vdmVfY2xhc3MgKyByaWdodF9wb3N0Zml4KTtcclxuICAgICAgICAgICAgJCgnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmV4aXQtb2ZmLWNhbnZhcycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3JlbW92ZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgUygnLmJvdHRvbS1zdWJtZW51JykucmVtb3ZlQ2xhc3MobW92ZV9jbGFzcyArIHRvcF9wb3N0Zml4KTtcclxuICAgICAgICAgIGlmIChib3R0b21fcG9zdGZpeCkge1xyXG4gICAgICAgICAgICBzZWxmLmNsaWNrX3JlbW92ZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgICBTKCcudG9wLXN1Ym1lbnUnKS5yZW1vdmVDbGFzcyhtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgJCgnLmJvdHRvbS1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLm9uKCdjbGljay5mbmR0bi5vZmZjYW52YXMnLCAnLmV4aXQtb2ZmLWNhbnZhcycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBzZWxmLmNsaWNrX3JlbW92ZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgdG9wX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgJCgnLnRvcC1vZmYtY2FudmFzLXRvZ2dsZScpLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgIGlmIChib3R0b21fcG9zdGZpeCkge1xyXG4gICAgICAgICAgICBzZWxmLmNsaWNrX3JlbW92ZV9jbGFzcyhlLCBtb3ZlX2NsYXNzICsgYm90dG9tX3Bvc3RmaXgpO1xyXG4gICAgICAgICAgICAkKCcuYm90dG9tLW9mZi1jYW52YXMtdG9nZ2xlJykuYXR0cignYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB0b2dnbGUgOiBmdW5jdGlvbiAoY2xhc3NfbmFtZSwgJG9mZl9jYW52YXMpIHtcclxuICAgICAgJG9mZl9jYW52YXMgPSAkb2ZmX2NhbnZhcyB8fCB0aGlzLmdldF93cmFwcGVyKCk7XHJcbiAgICAgIGlmICgkb2ZmX2NhbnZhcy5pcygnLicgKyBjbGFzc19uYW1lKSkge1xyXG4gICAgICAgIHRoaXMuaGlkZShjbGFzc19uYW1lLCAkb2ZmX2NhbnZhcyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zaG93KGNsYXNzX25hbWUsICRvZmZfY2FudmFzKTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzaG93IDogZnVuY3Rpb24gKGNsYXNzX25hbWUsICRvZmZfY2FudmFzKSB7XHJcbiAgICAgICRvZmZfY2FudmFzID0gJG9mZl9jYW52YXMgfHwgdGhpcy5nZXRfd3JhcHBlcigpO1xyXG4gICAgICAkb2ZmX2NhbnZhcy50cmlnZ2VyKCdvcGVuLmZuZHRuLm9mZmNhbnZhcycpO1xyXG4gICAgICAkb2ZmX2NhbnZhcy5hZGRDbGFzcyhjbGFzc19uYW1lKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZSA6IGZ1bmN0aW9uIChjbGFzc19uYW1lLCAkb2ZmX2NhbnZhcykge1xyXG4gICAgICAkb2ZmX2NhbnZhcyA9ICRvZmZfY2FudmFzIHx8IHRoaXMuZ2V0X3dyYXBwZXIoKTtcclxuICAgICAgJG9mZl9jYW52YXMudHJpZ2dlcignY2xvc2UuZm5kdG4ub2ZmY2FudmFzJyk7XHJcbiAgICAgICRvZmZfY2FudmFzLnJlbW92ZUNsYXNzKGNsYXNzX25hbWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBjbGlja190b2dnbGVfY2xhc3MgOiBmdW5jdGlvbiAoZSwgY2xhc3NfbmFtZSkge1xyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIHZhciAkb2ZmX2NhbnZhcyA9IHRoaXMuZ2V0X3dyYXBwZXIoZSk7XHJcbiAgICAgIHRoaXMudG9nZ2xlKGNsYXNzX25hbWUsICRvZmZfY2FudmFzKTtcclxuICAgIH0sXHJcblxyXG4gICAgY2xpY2tfcmVtb3ZlX2NsYXNzIDogZnVuY3Rpb24gKGUsIGNsYXNzX25hbWUpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB2YXIgJG9mZl9jYW52YXMgPSB0aGlzLmdldF93cmFwcGVyKGUpO1xyXG4gICAgICB0aGlzLmhpZGUoY2xhc3NfbmFtZSwgJG9mZl9jYW52YXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRfc2V0dGluZ3MgOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICB2YXIgb2ZmY2FudmFzICA9IHRoaXMuUyhlLnRhcmdldCkuY2xvc2VzdCgnWycgKyB0aGlzLmF0dHJfbmFtZSgpICsgJ10nKTtcclxuICAgICAgcmV0dXJuIG9mZmNhbnZhcy5kYXRhKHRoaXMuYXR0cl9uYW1lKHRydWUpICsgJy1pbml0JykgfHwgdGhpcy5zZXR0aW5ncztcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0X3dyYXBwZXIgOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICB2YXIgJG9mZl9jYW52YXMgPSB0aGlzLlMoZSA/IGUudGFyZ2V0IDogdGhpcy5zY29wZSkuY2xvc2VzdCgnLm9mZi1jYW52YXMtd3JhcCcpO1xyXG5cclxuICAgICAgaWYgKCRvZmZfY2FudmFzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICRvZmZfY2FudmFzID0gdGhpcy5TKCcub2ZmLWNhbnZhcy13cmFwJyk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuICRvZmZfY2FudmFzO1xyXG4gICAgfSxcclxuXHJcbiAgICByZWZsb3cgOiBmdW5jdGlvbiAoKSB7fVxyXG4gIH07XHJcbn0oalF1ZXJ5LCB3aW5kb3csIHdpbmRvdy5kb2N1bWVudCkpO1xyXG4iLCIvKiEgalF1ZXJ5IFVJIC0gdjEuMTEuNCAtIDIwMTUtMDMtMTFcclxuKiBodHRwOi8vanF1ZXJ5dWkuY29tXHJcbiogSW5jbHVkZXM6IGNvcmUuanMsIHdpZGdldC5qcywgbW91c2UuanMsIHBvc2l0aW9uLmpzLCBhY2NvcmRpb24uanMsIGF1dG9jb21wbGV0ZS5qcywgYnV0dG9uLmpzLCBkYXRlcGlja2VyLmpzLCBkaWFsb2cuanMsIGRyYWdnYWJsZS5qcywgZHJvcHBhYmxlLmpzLCBlZmZlY3QuanMsIGVmZmVjdC1ibGluZC5qcywgZWZmZWN0LWJvdW5jZS5qcywgZWZmZWN0LWNsaXAuanMsIGVmZmVjdC1kcm9wLmpzLCBlZmZlY3QtZXhwbG9kZS5qcywgZWZmZWN0LWZhZGUuanMsIGVmZmVjdC1mb2xkLmpzLCBlZmZlY3QtaGlnaGxpZ2h0LmpzLCBlZmZlY3QtcHVmZi5qcywgZWZmZWN0LXB1bHNhdGUuanMsIGVmZmVjdC1zY2FsZS5qcywgZWZmZWN0LXNoYWtlLmpzLCBlZmZlY3Qtc2l6ZS5qcywgZWZmZWN0LXNsaWRlLmpzLCBlZmZlY3QtdHJhbnNmZXIuanMsIG1lbnUuanMsIHByb2dyZXNzYmFyLmpzLCByZXNpemFibGUuanMsIHNlbGVjdGFibGUuanMsIHNlbGVjdG1lbnUuanMsIHNsaWRlci5qcywgc29ydGFibGUuanMsIHNwaW5uZXIuanMsIHRhYnMuanMsIHRvb2x0aXAuanNcclxuKiBDb3B5cmlnaHQgMjAxNSBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzOyBMaWNlbnNlZCBNSVQgKi9cclxuXHJcbihmdW5jdGlvbihlKXtcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcImpxdWVyeVwiXSxlKTplKGpRdWVyeSl9KShmdW5jdGlvbihlKXtmdW5jdGlvbiB0KHQscyl7dmFyIG4sYSxvLHI9dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVyblwiYXJlYVwiPT09cj8obj10LnBhcmVudE5vZGUsYT1uLm5hbWUsdC5ocmVmJiZhJiZcIm1hcFwiPT09bi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPyhvPWUoXCJpbWdbdXNlbWFwPScjXCIrYStcIiddXCIpWzBdLCEhbyYmaShvKSk6ITEpOigvXihpbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9ufG9iamVjdCkkLy50ZXN0KHIpPyF0LmRpc2FibGVkOlwiYVwiPT09cj90LmhyZWZ8fHM6cykmJmkodCl9ZnVuY3Rpb24gaSh0KXtyZXR1cm4gZS5leHByLmZpbHRlcnMudmlzaWJsZSh0KSYmIWUodCkucGFyZW50cygpLmFkZEJhY2soKS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm5cImhpZGRlblwiPT09ZS5jc3ModGhpcyxcInZpc2liaWxpdHlcIil9KS5sZW5ndGh9ZnVuY3Rpb24gcyhlKXtmb3IodmFyIHQsaTtlLmxlbmd0aCYmZVswXSE9PWRvY3VtZW50Oyl7aWYodD1lLmNzcyhcInBvc2l0aW9uXCIpLChcImFic29sdXRlXCI9PT10fHxcInJlbGF0aXZlXCI9PT10fHxcImZpeGVkXCI9PT10KSYmKGk9cGFyc2VJbnQoZS5jc3MoXCJ6SW5kZXhcIiksMTApLCFpc05hTihpKSYmMCE9PWkpKXJldHVybiBpO2U9ZS5wYXJlbnQoKX1yZXR1cm4gMH1mdW5jdGlvbiBuKCl7dGhpcy5fY3VySW5zdD1udWxsLHRoaXMuX2tleUV2ZW50PSExLHRoaXMuX2Rpc2FibGVkSW5wdXRzPVtdLHRoaXMuX2RhdGVwaWNrZXJTaG93aW5nPSExLHRoaXMuX2luRGlhbG9nPSExLHRoaXMuX21haW5EaXZJZD1cInVpLWRhdGVwaWNrZXItZGl2XCIsdGhpcy5faW5saW5lQ2xhc3M9XCJ1aS1kYXRlcGlja2VyLWlubGluZVwiLHRoaXMuX2FwcGVuZENsYXNzPVwidWktZGF0ZXBpY2tlci1hcHBlbmRcIix0aGlzLl90cmlnZ2VyQ2xhc3M9XCJ1aS1kYXRlcGlja2VyLXRyaWdnZXJcIix0aGlzLl9kaWFsb2dDbGFzcz1cInVpLWRhdGVwaWNrZXItZGlhbG9nXCIsdGhpcy5fZGlzYWJsZUNsYXNzPVwidWktZGF0ZXBpY2tlci1kaXNhYmxlZFwiLHRoaXMuX3Vuc2VsZWN0YWJsZUNsYXNzPVwidWktZGF0ZXBpY2tlci11bnNlbGVjdGFibGVcIix0aGlzLl9jdXJyZW50Q2xhc3M9XCJ1aS1kYXRlcGlja2VyLWN1cnJlbnQtZGF5XCIsdGhpcy5fZGF5T3ZlckNsYXNzPVwidWktZGF0ZXBpY2tlci1kYXlzLWNlbGwtb3ZlclwiLHRoaXMucmVnaW9uYWw9W10sdGhpcy5yZWdpb25hbFtcIlwiXT17Y2xvc2VUZXh0OlwiRG9uZVwiLHByZXZUZXh0OlwiUHJldlwiLG5leHRUZXh0OlwiTmV4dFwiLGN1cnJlbnRUZXh0OlwiVG9kYXlcIixtb250aE5hbWVzOltcIkphbnVhcnlcIixcIkZlYnJ1YXJ5XCIsXCJNYXJjaFwiLFwiQXByaWxcIixcIk1heVwiLFwiSnVuZVwiLFwiSnVseVwiLFwiQXVndXN0XCIsXCJTZXB0ZW1iZXJcIixcIk9jdG9iZXJcIixcIk5vdmVtYmVyXCIsXCJEZWNlbWJlclwiXSxtb250aE5hbWVzU2hvcnQ6W1wiSmFuXCIsXCJGZWJcIixcIk1hclwiLFwiQXByXCIsXCJNYXlcIixcIkp1blwiLFwiSnVsXCIsXCJBdWdcIixcIlNlcFwiLFwiT2N0XCIsXCJOb3ZcIixcIkRlY1wiXSxkYXlOYW1lczpbXCJTdW5kYXlcIixcIk1vbmRheVwiLFwiVHVlc2RheVwiLFwiV2VkbmVzZGF5XCIsXCJUaHVyc2RheVwiLFwiRnJpZGF5XCIsXCJTYXR1cmRheVwiXSxkYXlOYW1lc1Nob3J0OltcIlN1blwiLFwiTW9uXCIsXCJUdWVcIixcIldlZFwiLFwiVGh1XCIsXCJGcmlcIixcIlNhdFwiXSxkYXlOYW1lc01pbjpbXCJTdVwiLFwiTW9cIixcIlR1XCIsXCJXZVwiLFwiVGhcIixcIkZyXCIsXCJTYVwiXSx3ZWVrSGVhZGVyOlwiV2tcIixkYXRlRm9ybWF0OlwibW0vZGQveXlcIixmaXJzdERheTowLGlzUlRMOiExLHNob3dNb250aEFmdGVyWWVhcjohMSx5ZWFyU3VmZml4OlwiXCJ9LHRoaXMuX2RlZmF1bHRzPXtzaG93T246XCJmb2N1c1wiLHNob3dBbmltOlwiZmFkZUluXCIsc2hvd09wdGlvbnM6e30sZGVmYXVsdERhdGU6bnVsbCxhcHBlbmRUZXh0OlwiXCIsYnV0dG9uVGV4dDpcIi4uLlwiLGJ1dHRvbkltYWdlOlwiXCIsYnV0dG9uSW1hZ2VPbmx5OiExLGhpZGVJZk5vUHJldk5leHQ6ITEsbmF2aWdhdGlvbkFzRGF0ZUZvcm1hdDohMSxnb3RvQ3VycmVudDohMSxjaGFuZ2VNb250aDohMSxjaGFuZ2VZZWFyOiExLHllYXJSYW5nZTpcImMtMTA6YysxMFwiLHNob3dPdGhlck1vbnRoczohMSxzZWxlY3RPdGhlck1vbnRoczohMSxzaG93V2VlazohMSxjYWxjdWxhdGVXZWVrOnRoaXMuaXNvODYwMVdlZWssc2hvcnRZZWFyQ3V0b2ZmOlwiKzEwXCIsbWluRGF0ZTpudWxsLG1heERhdGU6bnVsbCxkdXJhdGlvbjpcImZhc3RcIixiZWZvcmVTaG93RGF5Om51bGwsYmVmb3JlU2hvdzpudWxsLG9uU2VsZWN0Om51bGwsb25DaGFuZ2VNb250aFllYXI6bnVsbCxvbkNsb3NlOm51bGwsbnVtYmVyT2ZNb250aHM6MSxzaG93Q3VycmVudEF0UG9zOjAsc3RlcE1vbnRoczoxLHN0ZXBCaWdNb250aHM6MTIsYWx0RmllbGQ6XCJcIixhbHRGb3JtYXQ6XCJcIixjb25zdHJhaW5JbnB1dDohMCxzaG93QnV0dG9uUGFuZWw6ITEsYXV0b1NpemU6ITEsZGlzYWJsZWQ6ITF9LGUuZXh0ZW5kKHRoaXMuX2RlZmF1bHRzLHRoaXMucmVnaW9uYWxbXCJcIl0pLHRoaXMucmVnaW9uYWwuZW49ZS5leHRlbmQoITAse30sdGhpcy5yZWdpb25hbFtcIlwiXSksdGhpcy5yZWdpb25hbFtcImVuLVVTXCJdPWUuZXh0ZW5kKCEwLHt9LHRoaXMucmVnaW9uYWwuZW4pLHRoaXMuZHBEaXY9YShlKFwiPGRpdiBpZD0nXCIrdGhpcy5fbWFpbkRpdklkK1wiJyBjbGFzcz0ndWktZGF0ZXBpY2tlciB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktaGVscGVyLWNsZWFyZml4IHVpLWNvcm5lci1hbGwnPjwvZGl2PlwiKSl9ZnVuY3Rpb24gYSh0KXt2YXIgaT1cImJ1dHRvbiwgLnVpLWRhdGVwaWNrZXItcHJldiwgLnVpLWRhdGVwaWNrZXItbmV4dCwgLnVpLWRhdGVwaWNrZXItY2FsZW5kYXIgdGQgYVwiO3JldHVybiB0LmRlbGVnYXRlKGksXCJtb3VzZW91dFwiLGZ1bmN0aW9uKCl7ZSh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWhvdmVyXCIpLC0xIT09dGhpcy5jbGFzc05hbWUuaW5kZXhPZihcInVpLWRhdGVwaWNrZXItcHJldlwiKSYmZSh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLWRhdGVwaWNrZXItcHJldi1ob3ZlclwiKSwtMSE9PXRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLW5leHRcIikmJmUodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW5leHQtaG92ZXJcIil9KS5kZWxlZ2F0ZShpLFwibW91c2VvdmVyXCIsbyl9ZnVuY3Rpb24gbygpe2UuZGF0ZXBpY2tlci5faXNEaXNhYmxlZERhdGVwaWNrZXIodi5pbmxpbmU/di5kcERpdi5wYXJlbnQoKVswXTp2LmlucHV0WzBdKXx8KGUodGhpcykucGFyZW50cyhcIi51aS1kYXRlcGlja2VyLWNhbGVuZGFyXCIpLmZpbmQoXCJhXCIpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtaG92ZXJcIiksZSh0aGlzKS5hZGRDbGFzcyhcInVpLXN0YXRlLWhvdmVyXCIpLC0xIT09dGhpcy5jbGFzc05hbWUuaW5kZXhPZihcInVpLWRhdGVwaWNrZXItcHJldlwiKSYmZSh0aGlzKS5hZGRDbGFzcyhcInVpLWRhdGVwaWNrZXItcHJldi1ob3ZlclwiKSwtMSE9PXRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLW5leHRcIikmJmUodGhpcykuYWRkQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW5leHQtaG92ZXJcIikpfWZ1bmN0aW9uIHIodCxpKXtlLmV4dGVuZCh0LGkpO2Zvcih2YXIgcyBpbiBpKW51bGw9PWlbc10mJih0W3NdPWlbc10pO3JldHVybiB0fWZ1bmN0aW9uIGgoZSl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5lbGVtZW50LnZhbCgpO2UuYXBwbHkodGhpcyxhcmd1bWVudHMpLHRoaXMuX3JlZnJlc2goKSx0IT09dGhpcy5lbGVtZW50LnZhbCgpJiZ0aGlzLl90cmlnZ2VyKFwiY2hhbmdlXCIpfX1lLnVpPWUudWl8fHt9LGUuZXh0ZW5kKGUudWkse3ZlcnNpb246XCIxLjExLjRcIixrZXlDb2RlOntCQUNLU1BBQ0U6OCxDT01NQToxODgsREVMRVRFOjQ2LERPV046NDAsRU5EOjM1LEVOVEVSOjEzLEVTQ0FQRToyNyxIT01FOjM2LExFRlQ6MzcsUEFHRV9ET1dOOjM0LFBBR0VfVVA6MzMsUEVSSU9EOjE5MCxSSUdIVDozOSxTUEFDRTozMixUQUI6OSxVUDozOH19KSxlLmZuLmV4dGVuZCh7c2Nyb2xsUGFyZW50OmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMuY3NzKFwicG9zaXRpb25cIikscz1cImFic29sdXRlXCI9PT1pLG49dD8vKGF1dG98c2Nyb2xsfGhpZGRlbikvOi8oYXV0b3xzY3JvbGwpLyxhPXRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpe3ZhciB0PWUodGhpcyk7cmV0dXJuIHMmJlwic3RhdGljXCI9PT10LmNzcyhcInBvc2l0aW9uXCIpPyExOm4udGVzdCh0LmNzcyhcIm92ZXJmbG93XCIpK3QuY3NzKFwib3ZlcmZsb3cteVwiKSt0LmNzcyhcIm92ZXJmbG93LXhcIikpfSkuZXEoMCk7cmV0dXJuXCJmaXhlZFwiIT09aSYmYS5sZW5ndGg/YTplKHRoaXNbMF0ub3duZXJEb2N1bWVudHx8ZG9jdW1lbnQpfSx1bmlxdWVJZDpmdW5jdGlvbigpe3ZhciBlPTA7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe3RoaXMuaWR8fCh0aGlzLmlkPVwidWktaWQtXCIrICsrZSl9KX19KCkscmVtb3ZlVW5pcXVlSWQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7L151aS1pZC1cXGQrJC8udGVzdCh0aGlzLmlkKSYmZSh0aGlzKS5yZW1vdmVBdHRyKFwiaWRcIil9KX19KSxlLmV4dGVuZChlLmV4cHJbXCI6XCJdLHtkYXRhOmUuZXhwci5jcmVhdGVQc2V1ZG8/ZS5leHByLmNyZWF0ZVBzZXVkbyhmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oaSl7cmV0dXJuISFlLmRhdGEoaSx0KX19KTpmdW5jdGlvbih0LGkscyl7cmV0dXJuISFlLmRhdGEodCxzWzNdKX0sZm9jdXNhYmxlOmZ1bmN0aW9uKGkpe3JldHVybiB0KGksIWlzTmFOKGUuYXR0cihpLFwidGFiaW5kZXhcIikpKX0sdGFiYmFibGU6ZnVuY3Rpb24oaSl7dmFyIHM9ZS5hdHRyKGksXCJ0YWJpbmRleFwiKSxuPWlzTmFOKHMpO3JldHVybihufHxzPj0wKSYmdChpLCFuKX19KSxlKFwiPGE+XCIpLm91dGVyV2lkdGgoMSkuanF1ZXJ5fHxlLmVhY2goW1wiV2lkdGhcIixcIkhlaWdodFwiXSxmdW5jdGlvbih0LGkpe2Z1bmN0aW9uIHModCxpLHMsYSl7cmV0dXJuIGUuZWFjaChuLGZ1bmN0aW9uKCl7aS09cGFyc2VGbG9hdChlLmNzcyh0LFwicGFkZGluZ1wiK3RoaXMpKXx8MCxzJiYoaS09cGFyc2VGbG9hdChlLmNzcyh0LFwiYm9yZGVyXCIrdGhpcytcIldpZHRoXCIpKXx8MCksYSYmKGktPXBhcnNlRmxvYXQoZS5jc3ModCxcIm1hcmdpblwiK3RoaXMpKXx8MCl9KSxpfXZhciBuPVwiV2lkdGhcIj09PWk/W1wiTGVmdFwiLFwiUmlnaHRcIl06W1wiVG9wXCIsXCJCb3R0b21cIl0sYT1pLnRvTG93ZXJDYXNlKCksbz17aW5uZXJXaWR0aDplLmZuLmlubmVyV2lkdGgsaW5uZXJIZWlnaHQ6ZS5mbi5pbm5lckhlaWdodCxvdXRlcldpZHRoOmUuZm4ub3V0ZXJXaWR0aCxvdXRlckhlaWdodDplLmZuLm91dGVySGVpZ2h0fTtlLmZuW1wiaW5uZXJcIitpXT1mdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dD9vW1wiaW5uZXJcIitpXS5jYWxsKHRoaXMpOnRoaXMuZWFjaChmdW5jdGlvbigpe2UodGhpcykuY3NzKGEscyh0aGlzLHQpK1wicHhcIil9KX0sZS5mbltcIm91dGVyXCIraV09ZnVuY3Rpb24odCxuKXtyZXR1cm5cIm51bWJlclwiIT10eXBlb2YgdD9vW1wib3V0ZXJcIitpXS5jYWxsKHRoaXMsdCk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZSh0aGlzKS5jc3MoYSxzKHRoaXMsdCwhMCxuKStcInB4XCIpfSl9fSksZS5mbi5hZGRCYWNrfHwoZS5mbi5hZGRCYWNrPWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmFkZChudWxsPT1lP3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKGUpKX0pLGUoXCI8YT5cIikuZGF0YShcImEtYlwiLFwiYVwiKS5yZW1vdmVEYXRhKFwiYS1iXCIpLmRhdGEoXCJhLWJcIikmJihlLmZuLnJlbW92ZURhdGE9ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGkpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoP3QuY2FsbCh0aGlzLGUuY2FtZWxDYXNlKGkpKTp0LmNhbGwodGhpcyl9fShlLmZuLnJlbW92ZURhdGEpKSxlLnVpLmllPSEhL21zaWUgW1xcdy5dKy8uZXhlYyhuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpLGUuZm4uZXh0ZW5kKHtmb2N1czpmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oaSxzKXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgaT90aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgdD10aGlzO3NldFRpbWVvdXQoZnVuY3Rpb24oKXtlKHQpLmZvY3VzKCkscyYmcy5jYWxsKHQpfSxpKX0pOnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0oZS5mbi5mb2N1cyksZGlzYWJsZVNlbGVjdGlvbjpmdW5jdGlvbigpe3ZhciBlPVwib25zZWxlY3RzdGFydFwiaW4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKT9cInNlbGVjdHN0YXJ0XCI6XCJtb3VzZWRvd25cIjtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iaW5kKGUrXCIudWktZGlzYWJsZVNlbGVjdGlvblwiLGZ1bmN0aW9uKGUpe2UucHJldmVudERlZmF1bHQoKX0pfX0oKSxlbmFibGVTZWxlY3Rpb246ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51bmJpbmQoXCIudWktZGlzYWJsZVNlbGVjdGlvblwiKX0sekluZGV4OmZ1bmN0aW9uKHQpe2lmKHZvaWQgMCE9PXQpcmV0dXJuIHRoaXMuY3NzKFwiekluZGV4XCIsdCk7aWYodGhpcy5sZW5ndGgpZm9yKHZhciBpLHMsbj1lKHRoaXNbMF0pO24ubGVuZ3RoJiZuWzBdIT09ZG9jdW1lbnQ7KXtpZihpPW4uY3NzKFwicG9zaXRpb25cIiksKFwiYWJzb2x1dGVcIj09PWl8fFwicmVsYXRpdmVcIj09PWl8fFwiZml4ZWRcIj09PWkpJiYocz1wYXJzZUludChuLmNzcyhcInpJbmRleFwiKSwxMCksIWlzTmFOKHMpJiYwIT09cykpcmV0dXJuIHM7bj1uLnBhcmVudCgpfXJldHVybiAwfX0pLGUudWkucGx1Z2luPXthZGQ6ZnVuY3Rpb24odCxpLHMpe3ZhciBuLGE9ZS51aVt0XS5wcm90b3R5cGU7Zm9yKG4gaW4gcylhLnBsdWdpbnNbbl09YS5wbHVnaW5zW25dfHxbXSxhLnBsdWdpbnNbbl0ucHVzaChbaSxzW25dXSl9LGNhbGw6ZnVuY3Rpb24oZSx0LGkscyl7dmFyIG4sYT1lLnBsdWdpbnNbdF07aWYoYSYmKHN8fGUuZWxlbWVudFswXS5wYXJlbnROb2RlJiYxMSE9PWUuZWxlbWVudFswXS5wYXJlbnROb2RlLm5vZGVUeXBlKSlmb3Iobj0wO2EubGVuZ3RoPm47bisrKWUub3B0aW9uc1thW25dWzBdXSYmYVtuXVsxXS5hcHBseShlLmVsZW1lbnQsaSl9fTt2YXIgbD0wLHU9QXJyYXkucHJvdG90eXBlLnNsaWNlO2UuY2xlYW5EYXRhPWZ1bmN0aW9uKHQpe3JldHVybiBmdW5jdGlvbihpKXt2YXIgcyxuLGE7Zm9yKGE9MDtudWxsIT0obj1pW2FdKTthKyspdHJ5e3M9ZS5fZGF0YShuLFwiZXZlbnRzXCIpLHMmJnMucmVtb3ZlJiZlKG4pLnRyaWdnZXJIYW5kbGVyKFwicmVtb3ZlXCIpfWNhdGNoKG8pe310KGkpfX0oZS5jbGVhbkRhdGEpLGUud2lkZ2V0PWZ1bmN0aW9uKHQsaSxzKXt2YXIgbixhLG8scixoPXt9LGw9dC5zcGxpdChcIi5cIilbMF07cmV0dXJuIHQ9dC5zcGxpdChcIi5cIilbMV0sbj1sK1wiLVwiK3Qsc3x8KHM9aSxpPWUuV2lkZ2V0KSxlLmV4cHJbXCI6XCJdW24udG9Mb3dlckNhc2UoKV09ZnVuY3Rpb24odCl7cmV0dXJuISFlLmRhdGEodCxuKX0sZVtsXT1lW2xdfHx7fSxhPWVbbF1bdF0sbz1lW2xdW3RdPWZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMuX2NyZWF0ZVdpZGdldD8oYXJndW1lbnRzLmxlbmd0aCYmdGhpcy5fY3JlYXRlV2lkZ2V0KGUsdCksdm9pZCAwKTpuZXcgbyhlLHQpfSxlLmV4dGVuZChvLGEse3ZlcnNpb246cy52ZXJzaW9uLF9wcm90bzplLmV4dGVuZCh7fSxzKSxfY2hpbGRDb25zdHJ1Y3RvcnM6W119KSxyPW5ldyBpLHIub3B0aW9ucz1lLndpZGdldC5leHRlbmQoe30sci5vcHRpb25zKSxlLmVhY2gocyxmdW5jdGlvbih0LHMpe3JldHVybiBlLmlzRnVuY3Rpb24ocyk/KGhbdF09ZnVuY3Rpb24oKXt2YXIgZT1mdW5jdGlvbigpe3JldHVybiBpLnByb3RvdHlwZVt0XS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9LG49ZnVuY3Rpb24oZSl7cmV0dXJuIGkucHJvdG90eXBlW3RdLmFwcGx5KHRoaXMsZSl9O3JldHVybiBmdW5jdGlvbigpe3ZhciB0LGk9dGhpcy5fc3VwZXIsYT10aGlzLl9zdXBlckFwcGx5O3JldHVybiB0aGlzLl9zdXBlcj1lLHRoaXMuX3N1cGVyQXBwbHk9bix0PXMuYXBwbHkodGhpcyxhcmd1bWVudHMpLHRoaXMuX3N1cGVyPWksdGhpcy5fc3VwZXJBcHBseT1hLHR9fSgpLHZvaWQgMCk6KGhbdF09cyx2b2lkIDApfSksby5wcm90b3R5cGU9ZS53aWRnZXQuZXh0ZW5kKHIse3dpZGdldEV2ZW50UHJlZml4OmE/ci53aWRnZXRFdmVudFByZWZpeHx8dDp0fSxoLHtjb25zdHJ1Y3RvcjpvLG5hbWVzcGFjZTpsLHdpZGdldE5hbWU6dCx3aWRnZXRGdWxsTmFtZTpufSksYT8oZS5lYWNoKGEuX2NoaWxkQ29uc3RydWN0b3JzLGZ1bmN0aW9uKHQsaSl7dmFyIHM9aS5wcm90b3R5cGU7ZS53aWRnZXQocy5uYW1lc3BhY2UrXCIuXCIrcy53aWRnZXROYW1lLG8saS5fcHJvdG8pfSksZGVsZXRlIGEuX2NoaWxkQ29uc3RydWN0b3JzKTppLl9jaGlsZENvbnN0cnVjdG9ycy5wdXNoKG8pLGUud2lkZ2V0LmJyaWRnZSh0LG8pLG99LGUud2lkZ2V0LmV4dGVuZD1mdW5jdGlvbih0KXtmb3IodmFyIGkscyxuPXUuY2FsbChhcmd1bWVudHMsMSksYT0wLG89bi5sZW5ndGg7bz5hO2ErKylmb3IoaSBpbiBuW2FdKXM9blthXVtpXSxuW2FdLmhhc093blByb3BlcnR5KGkpJiZ2b2lkIDAhPT1zJiYodFtpXT1lLmlzUGxhaW5PYmplY3Qocyk/ZS5pc1BsYWluT2JqZWN0KHRbaV0pP2Uud2lkZ2V0LmV4dGVuZCh7fSx0W2ldLHMpOmUud2lkZ2V0LmV4dGVuZCh7fSxzKTpzKTtyZXR1cm4gdH0sZS53aWRnZXQuYnJpZGdlPWZ1bmN0aW9uKHQsaSl7dmFyIHM9aS5wcm90b3R5cGUud2lkZ2V0RnVsbE5hbWV8fHQ7ZS5mblt0XT1mdW5jdGlvbihuKXt2YXIgYT1cInN0cmluZ1wiPT10eXBlb2YgbixvPXUuY2FsbChhcmd1bWVudHMsMSkscj10aGlzO3JldHVybiBhP3RoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBpLGE9ZS5kYXRhKHRoaXMscyk7cmV0dXJuXCJpbnN0YW5jZVwiPT09bj8ocj1hLCExKTphP2UuaXNGdW5jdGlvbihhW25dKSYmXCJfXCIhPT1uLmNoYXJBdCgwKT8oaT1hW25dLmFwcGx5KGEsbyksaSE9PWEmJnZvaWQgMCE9PWk/KHI9aSYmaS5qcXVlcnk/ci5wdXNoU3RhY2soaS5nZXQoKSk6aSwhMSk6dm9pZCAwKTplLmVycm9yKFwibm8gc3VjaCBtZXRob2QgJ1wiK24rXCInIGZvciBcIit0K1wiIHdpZGdldCBpbnN0YW5jZVwiKTplLmVycm9yKFwiY2Fubm90IGNhbGwgbWV0aG9kcyBvbiBcIit0K1wiIHByaW9yIHRvIGluaXRpYWxpemF0aW9uOyBcIitcImF0dGVtcHRlZCB0byBjYWxsIG1ldGhvZCAnXCIrbitcIidcIil9KTooby5sZW5ndGgmJihuPWUud2lkZ2V0LmV4dGVuZC5hcHBseShudWxsLFtuXS5jb25jYXQobykpKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lLmRhdGEodGhpcyxzKTt0Pyh0Lm9wdGlvbihufHx7fSksdC5faW5pdCYmdC5faW5pdCgpKTplLmRhdGEodGhpcyxzLG5ldyBpKG4sdGhpcykpfSkpLHJ9fSxlLldpZGdldD1mdW5jdGlvbigpe30sZS5XaWRnZXQuX2NoaWxkQ29uc3RydWN0b3JzPVtdLGUuV2lkZ2V0LnByb3RvdHlwZT17d2lkZ2V0TmFtZTpcIndpZGdldFwiLHdpZGdldEV2ZW50UHJlZml4OlwiXCIsZGVmYXVsdEVsZW1lbnQ6XCI8ZGl2PlwiLG9wdGlvbnM6e2Rpc2FibGVkOiExLGNyZWF0ZTpudWxsfSxfY3JlYXRlV2lkZ2V0OmZ1bmN0aW9uKHQsaSl7aT1lKGl8fHRoaXMuZGVmYXVsdEVsZW1lbnR8fHRoaXMpWzBdLHRoaXMuZWxlbWVudD1lKGkpLHRoaXMudXVpZD1sKyssdGhpcy5ldmVudE5hbWVzcGFjZT1cIi5cIit0aGlzLndpZGdldE5hbWUrdGhpcy51dWlkLHRoaXMuYmluZGluZ3M9ZSgpLHRoaXMuaG92ZXJhYmxlPWUoKSx0aGlzLmZvY3VzYWJsZT1lKCksaSE9PXRoaXMmJihlLmRhdGEoaSx0aGlzLndpZGdldEZ1bGxOYW1lLHRoaXMpLHRoaXMuX29uKCEwLHRoaXMuZWxlbWVudCx7cmVtb3ZlOmZ1bmN0aW9uKGUpe2UudGFyZ2V0PT09aSYmdGhpcy5kZXN0cm95KCl9fSksdGhpcy5kb2N1bWVudD1lKGkuc3R5bGU/aS5vd25lckRvY3VtZW50OmkuZG9jdW1lbnR8fGkpLHRoaXMud2luZG93PWUodGhpcy5kb2N1bWVudFswXS5kZWZhdWx0Vmlld3x8dGhpcy5kb2N1bWVudFswXS5wYXJlbnRXaW5kb3cpKSx0aGlzLm9wdGlvbnM9ZS53aWRnZXQuZXh0ZW5kKHt9LHRoaXMub3B0aW9ucyx0aGlzLl9nZXRDcmVhdGVPcHRpb25zKCksdCksdGhpcy5fY3JlYXRlKCksdGhpcy5fdHJpZ2dlcihcImNyZWF0ZVwiLG51bGwsdGhpcy5fZ2V0Q3JlYXRlRXZlbnREYXRhKCkpLHRoaXMuX2luaXQoKX0sX2dldENyZWF0ZU9wdGlvbnM6ZS5ub29wLF9nZXRDcmVhdGVFdmVudERhdGE6ZS5ub29wLF9jcmVhdGU6ZS5ub29wLF9pbml0OmUubm9vcCxkZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5fZGVzdHJveSgpLHRoaXMuZWxlbWVudC51bmJpbmQodGhpcy5ldmVudE5hbWVzcGFjZSkucmVtb3ZlRGF0YSh0aGlzLndpZGdldEZ1bGxOYW1lKS5yZW1vdmVEYXRhKGUuY2FtZWxDYXNlKHRoaXMud2lkZ2V0RnVsbE5hbWUpKSx0aGlzLndpZGdldCgpLnVuYmluZCh0aGlzLmV2ZW50TmFtZXNwYWNlKS5yZW1vdmVBdHRyKFwiYXJpYS1kaXNhYmxlZFwiKS5yZW1vdmVDbGFzcyh0aGlzLndpZGdldEZ1bGxOYW1lK1wiLWRpc2FibGVkIFwiK1widWktc3RhdGUtZGlzYWJsZWRcIiksdGhpcy5iaW5kaW5ncy51bmJpbmQodGhpcy5ldmVudE5hbWVzcGFjZSksdGhpcy5ob3ZlcmFibGUucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKSx0aGlzLmZvY3VzYWJsZS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWZvY3VzXCIpfSxfZGVzdHJveTplLm5vb3Asd2lkZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWxlbWVudH0sb3B0aW9uOmZ1bmN0aW9uKHQsaSl7dmFyIHMsbixhLG89dDtpZigwPT09YXJndW1lbnRzLmxlbmd0aClyZXR1cm4gZS53aWRnZXQuZXh0ZW5kKHt9LHRoaXMub3B0aW9ucyk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHQpaWYobz17fSxzPXQuc3BsaXQoXCIuXCIpLHQ9cy5zaGlmdCgpLHMubGVuZ3RoKXtmb3Iobj1vW3RdPWUud2lkZ2V0LmV4dGVuZCh7fSx0aGlzLm9wdGlvbnNbdF0pLGE9MDtzLmxlbmd0aC0xPmE7YSsrKW5bc1thXV09bltzW2FdXXx8e30sbj1uW3NbYV1dO2lmKHQ9cy5wb3AoKSwxPT09YXJndW1lbnRzLmxlbmd0aClyZXR1cm4gdm9pZCAwPT09blt0XT9udWxsOm5bdF07blt0XT1pfWVsc2V7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIHZvaWQgMD09PXRoaXMub3B0aW9uc1t0XT9udWxsOnRoaXMub3B0aW9uc1t0XTtvW3RdPWl9cmV0dXJuIHRoaXMuX3NldE9wdGlvbnMobyksdGhpc30sX3NldE9wdGlvbnM6ZnVuY3Rpb24oZSl7dmFyIHQ7Zm9yKHQgaW4gZSl0aGlzLl9zZXRPcHRpb24odCxlW3RdKTtyZXR1cm4gdGhpc30sX3NldE9wdGlvbjpmdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLm9wdGlvbnNbZV09dCxcImRpc2FibGVkXCI9PT1lJiYodGhpcy53aWRnZXQoKS50b2dnbGVDbGFzcyh0aGlzLndpZGdldEZ1bGxOYW1lK1wiLWRpc2FibGVkXCIsISF0KSx0JiYodGhpcy5ob3ZlcmFibGUucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKSx0aGlzLmZvY3VzYWJsZS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWZvY3VzXCIpKSksdGhpc30sZW5hYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoe2Rpc2FibGVkOiExfSl9LGRpc2FibGU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fc2V0T3B0aW9ucyh7ZGlzYWJsZWQ6ITB9KX0sX29uOmZ1bmN0aW9uKHQsaSxzKXt2YXIgbixhPXRoaXM7XCJib29sZWFuXCIhPXR5cGVvZiB0JiYocz1pLGk9dCx0PSExKSxzPyhpPW49ZShpKSx0aGlzLmJpbmRpbmdzPXRoaXMuYmluZGluZ3MuYWRkKGkpKToocz1pLGk9dGhpcy5lbGVtZW50LG49dGhpcy53aWRnZXQoKSksZS5lYWNoKHMsZnVuY3Rpb24ocyxvKXtmdW5jdGlvbiByKCl7cmV0dXJuIHR8fGEub3B0aW9ucy5kaXNhYmxlZCE9PSEwJiYhZSh0aGlzKS5oYXNDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIpPyhcInN0cmluZ1wiPT10eXBlb2Ygbz9hW29dOm8pLmFwcGx5KGEsYXJndW1lbnRzKTp2b2lkIDB9XCJzdHJpbmdcIiE9dHlwZW9mIG8mJihyLmd1aWQ9by5ndWlkPW8uZ3VpZHx8ci5ndWlkfHxlLmd1aWQrKyk7dmFyIGg9cy5tYXRjaCgvXihbXFx3Oi1dKilcXHMqKC4qKSQvKSxsPWhbMV0rYS5ldmVudE5hbWVzcGFjZSx1PWhbMl07dT9uLmRlbGVnYXRlKHUsbCxyKTppLmJpbmQobCxyKX0pfSxfb2ZmOmZ1bmN0aW9uKHQsaSl7aT0oaXx8XCJcIikuc3BsaXQoXCIgXCIpLmpvaW4odGhpcy5ldmVudE5hbWVzcGFjZStcIiBcIikrdGhpcy5ldmVudE5hbWVzcGFjZSx0LnVuYmluZChpKS51bmRlbGVnYXRlKGkpLHRoaXMuYmluZGluZ3M9ZSh0aGlzLmJpbmRpbmdzLm5vdCh0KS5nZXQoKSksdGhpcy5mb2N1c2FibGU9ZSh0aGlzLmZvY3VzYWJsZS5ub3QodCkuZ2V0KCkpLHRoaXMuaG92ZXJhYmxlPWUodGhpcy5ob3ZlcmFibGUubm90KHQpLmdldCgpKX0sX2RlbGF5OmZ1bmN0aW9uKGUsdCl7ZnVuY3Rpb24gaSgpe3JldHVybihcInN0cmluZ1wiPT10eXBlb2YgZT9zW2VdOmUpLmFwcGx5KHMsYXJndW1lbnRzKX12YXIgcz10aGlzO3JldHVybiBzZXRUaW1lb3V0KGksdHx8MCl9LF9ob3ZlcmFibGU6ZnVuY3Rpb24odCl7dGhpcy5ob3ZlcmFibGU9dGhpcy5ob3ZlcmFibGUuYWRkKHQpLHRoaXMuX29uKHQse21vdXNlZW50ZXI6ZnVuY3Rpb24odCl7ZSh0LmN1cnJlbnRUYXJnZXQpLmFkZENsYXNzKFwidWktc3RhdGUtaG92ZXJcIil9LG1vdXNlbGVhdmU6ZnVuY3Rpb24odCl7ZSh0LmN1cnJlbnRUYXJnZXQpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtaG92ZXJcIil9fSl9LF9mb2N1c2FibGU6ZnVuY3Rpb24odCl7dGhpcy5mb2N1c2FibGU9dGhpcy5mb2N1c2FibGUuYWRkKHQpLHRoaXMuX29uKHQse2ZvY3VzaW46ZnVuY3Rpb24odCl7ZSh0LmN1cnJlbnRUYXJnZXQpLmFkZENsYXNzKFwidWktc3RhdGUtZm9jdXNcIil9LGZvY3Vzb3V0OmZ1bmN0aW9uKHQpe2UodC5jdXJyZW50VGFyZ2V0KS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWZvY3VzXCIpfX0pfSxfdHJpZ2dlcjpmdW5jdGlvbih0LGkscyl7dmFyIG4sYSxvPXRoaXMub3B0aW9uc1t0XTtpZihzPXN8fHt9LGk9ZS5FdmVudChpKSxpLnR5cGU9KHQ9PT10aGlzLndpZGdldEV2ZW50UHJlZml4P3Q6dGhpcy53aWRnZXRFdmVudFByZWZpeCt0KS50b0xvd2VyQ2FzZSgpLGkudGFyZ2V0PXRoaXMuZWxlbWVudFswXSxhPWkub3JpZ2luYWxFdmVudClmb3IobiBpbiBhKW4gaW4gaXx8KGlbbl09YVtuXSk7cmV0dXJuIHRoaXMuZWxlbWVudC50cmlnZ2VyKGkscyksIShlLmlzRnVuY3Rpb24obykmJm8uYXBwbHkodGhpcy5lbGVtZW50WzBdLFtpXS5jb25jYXQocykpPT09ITF8fGkuaXNEZWZhdWx0UHJldmVudGVkKCkpfX0sZS5lYWNoKHtzaG93OlwiZmFkZUluXCIsaGlkZTpcImZhZGVPdXRcIn0sZnVuY3Rpb24odCxpKXtlLldpZGdldC5wcm90b3R5cGVbXCJfXCIrdF09ZnVuY3Rpb24ocyxuLGEpe1wic3RyaW5nXCI9PXR5cGVvZiBuJiYobj17ZWZmZWN0Om59KTt2YXIgbyxyPW4/bj09PSEwfHxcIm51bWJlclwiPT10eXBlb2Ygbj9pOm4uZWZmZWN0fHxpOnQ7bj1ufHx7fSxcIm51bWJlclwiPT10eXBlb2YgbiYmKG49e2R1cmF0aW9uOm59KSxvPSFlLmlzRW1wdHlPYmplY3Qobiksbi5jb21wbGV0ZT1hLG4uZGVsYXkmJnMuZGVsYXkobi5kZWxheSksbyYmZS5lZmZlY3RzJiZlLmVmZmVjdHMuZWZmZWN0W3JdP3NbdF0obik6ciE9PXQmJnNbcl0/c1tyXShuLmR1cmF0aW9uLG4uZWFzaW5nLGEpOnMucXVldWUoZnVuY3Rpb24oaSl7ZSh0aGlzKVt0XSgpLGEmJmEuY2FsbChzWzBdKSxpKCl9KX19KSxlLndpZGdldDt2YXIgZD0hMTtlKGRvY3VtZW50KS5tb3VzZXVwKGZ1bmN0aW9uKCl7ZD0hMX0pLGUud2lkZ2V0KFwidWkubW91c2VcIix7dmVyc2lvbjpcIjEuMTEuNFwiLG9wdGlvbnM6e2NhbmNlbDpcImlucHV0LHRleHRhcmVhLGJ1dHRvbixzZWxlY3Qsb3B0aW9uXCIsZGlzdGFuY2U6MSxkZWxheTowfSxfbW91c2VJbml0OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLmVsZW1lbnQuYmluZChcIm1vdXNlZG93bi5cIit0aGlzLndpZGdldE5hbWUsZnVuY3Rpb24oZSl7cmV0dXJuIHQuX21vdXNlRG93bihlKX0pLmJpbmQoXCJjbGljay5cIit0aGlzLndpZGdldE5hbWUsZnVuY3Rpb24oaSl7cmV0dXJuITA9PT1lLmRhdGEoaS50YXJnZXQsdC53aWRnZXROYW1lK1wiLnByZXZlbnRDbGlja0V2ZW50XCIpPyhlLnJlbW92ZURhdGEoaS50YXJnZXQsdC53aWRnZXROYW1lK1wiLnByZXZlbnRDbGlja0V2ZW50XCIpLGkuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksITEpOnZvaWQgMH0pLHRoaXMuc3RhcnRlZD0hMX0sX21vdXNlRGVzdHJveTpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC51bmJpbmQoXCIuXCIrdGhpcy53aWRnZXROYW1lKSx0aGlzLl9tb3VzZU1vdmVEZWxlZ2F0ZSYmdGhpcy5kb2N1bWVudC51bmJpbmQoXCJtb3VzZW1vdmUuXCIrdGhpcy53aWRnZXROYW1lLHRoaXMuX21vdXNlTW92ZURlbGVnYXRlKS51bmJpbmQoXCJtb3VzZXVwLlwiK3RoaXMud2lkZ2V0TmFtZSx0aGlzLl9tb3VzZVVwRGVsZWdhdGUpfSxfbW91c2VEb3duOmZ1bmN0aW9uKHQpe2lmKCFkKXt0aGlzLl9tb3VzZU1vdmVkPSExLHRoaXMuX21vdXNlU3RhcnRlZCYmdGhpcy5fbW91c2VVcCh0KSx0aGlzLl9tb3VzZURvd25FdmVudD10O3ZhciBpPXRoaXMscz0xPT09dC53aGljaCxuPVwic3RyaW5nXCI9PXR5cGVvZiB0aGlzLm9wdGlvbnMuY2FuY2VsJiZ0LnRhcmdldC5ub2RlTmFtZT9lKHQudGFyZ2V0KS5jbG9zZXN0KHRoaXMub3B0aW9ucy5jYW5jZWwpLmxlbmd0aDohMTtyZXR1cm4gcyYmIW4mJnRoaXMuX21vdXNlQ2FwdHVyZSh0KT8odGhpcy5tb3VzZURlbGF5TWV0PSF0aGlzLm9wdGlvbnMuZGVsYXksdGhpcy5tb3VzZURlbGF5TWV0fHwodGhpcy5fbW91c2VEZWxheVRpbWVyPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtpLm1vdXNlRGVsYXlNZXQ9ITB9LHRoaXMub3B0aW9ucy5kZWxheSkpLHRoaXMuX21vdXNlRGlzdGFuY2VNZXQodCkmJnRoaXMuX21vdXNlRGVsYXlNZXQodCkmJih0aGlzLl9tb3VzZVN0YXJ0ZWQ9dGhpcy5fbW91c2VTdGFydCh0KSE9PSExLCF0aGlzLl9tb3VzZVN0YXJ0ZWQpPyh0LnByZXZlbnREZWZhdWx0KCksITApOighMD09PWUuZGF0YSh0LnRhcmdldCx0aGlzLndpZGdldE5hbWUrXCIucHJldmVudENsaWNrRXZlbnRcIikmJmUucmVtb3ZlRGF0YSh0LnRhcmdldCx0aGlzLndpZGdldE5hbWUrXCIucHJldmVudENsaWNrRXZlbnRcIiksdGhpcy5fbW91c2VNb3ZlRGVsZWdhdGU9ZnVuY3Rpb24oZSl7cmV0dXJuIGkuX21vdXNlTW92ZShlKX0sdGhpcy5fbW91c2VVcERlbGVnYXRlPWZ1bmN0aW9uKGUpe3JldHVybiBpLl9tb3VzZVVwKGUpfSx0aGlzLmRvY3VtZW50LmJpbmQoXCJtb3VzZW1vdmUuXCIrdGhpcy53aWRnZXROYW1lLHRoaXMuX21vdXNlTW92ZURlbGVnYXRlKS5iaW5kKFwibW91c2V1cC5cIit0aGlzLndpZGdldE5hbWUsdGhpcy5fbW91c2VVcERlbGVnYXRlKSx0LnByZXZlbnREZWZhdWx0KCksZD0hMCwhMCkpOiEwfX0sX21vdXNlTW92ZTpmdW5jdGlvbih0KXtpZih0aGlzLl9tb3VzZU1vdmVkKXtpZihlLnVpLmllJiYoIWRvY3VtZW50LmRvY3VtZW50TW9kZXx8OT5kb2N1bWVudC5kb2N1bWVudE1vZGUpJiYhdC5idXR0b24pcmV0dXJuIHRoaXMuX21vdXNlVXAodCk7aWYoIXQud2hpY2gpcmV0dXJuIHRoaXMuX21vdXNlVXAodCl9cmV0dXJuKHQud2hpY2h8fHQuYnV0dG9uKSYmKHRoaXMuX21vdXNlTW92ZWQ9ITApLHRoaXMuX21vdXNlU3RhcnRlZD8odGhpcy5fbW91c2VEcmFnKHQpLHQucHJldmVudERlZmF1bHQoKSk6KHRoaXMuX21vdXNlRGlzdGFuY2VNZXQodCkmJnRoaXMuX21vdXNlRGVsYXlNZXQodCkmJih0aGlzLl9tb3VzZVN0YXJ0ZWQ9dGhpcy5fbW91c2VTdGFydCh0aGlzLl9tb3VzZURvd25FdmVudCx0KSE9PSExLHRoaXMuX21vdXNlU3RhcnRlZD90aGlzLl9tb3VzZURyYWcodCk6dGhpcy5fbW91c2VVcCh0KSksIXRoaXMuX21vdXNlU3RhcnRlZCl9LF9tb3VzZVVwOmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmRvY3VtZW50LnVuYmluZChcIm1vdXNlbW92ZS5cIit0aGlzLndpZGdldE5hbWUsdGhpcy5fbW91c2VNb3ZlRGVsZWdhdGUpLnVuYmluZChcIm1vdXNldXAuXCIrdGhpcy53aWRnZXROYW1lLHRoaXMuX21vdXNlVXBEZWxlZ2F0ZSksdGhpcy5fbW91c2VTdGFydGVkJiYodGhpcy5fbW91c2VTdGFydGVkPSExLHQudGFyZ2V0PT09dGhpcy5fbW91c2VEb3duRXZlbnQudGFyZ2V0JiZlLmRhdGEodC50YXJnZXQsdGhpcy53aWRnZXROYW1lK1wiLnByZXZlbnRDbGlja0V2ZW50XCIsITApLHRoaXMuX21vdXNlU3RvcCh0KSksZD0hMSwhMX0sX21vdXNlRGlzdGFuY2VNZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIE1hdGgubWF4KE1hdGguYWJzKHRoaXMuX21vdXNlRG93bkV2ZW50LnBhZ2VYLWUucGFnZVgpLE1hdGguYWJzKHRoaXMuX21vdXNlRG93bkV2ZW50LnBhZ2VZLWUucGFnZVkpKT49dGhpcy5vcHRpb25zLmRpc3RhbmNlfSxfbW91c2VEZWxheU1ldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1vdXNlRGVsYXlNZXR9LF9tb3VzZVN0YXJ0OmZ1bmN0aW9uKCl7fSxfbW91c2VEcmFnOmZ1bmN0aW9uKCl7fSxfbW91c2VTdG9wOmZ1bmN0aW9uKCl7fSxfbW91c2VDYXB0dXJlOmZ1bmN0aW9uKCl7cmV0dXJuITB9fSksZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUsdCxpKXtyZXR1cm5bcGFyc2VGbG9hdChlWzBdKSoocC50ZXN0KGVbMF0pP3QvMTAwOjEpLHBhcnNlRmxvYXQoZVsxXSkqKHAudGVzdChlWzFdKT9pLzEwMDoxKV19ZnVuY3Rpb24gaSh0LGkpe3JldHVybiBwYXJzZUludChlLmNzcyh0LGkpLDEwKXx8MH1mdW5jdGlvbiBzKHQpe3ZhciBpPXRbMF07cmV0dXJuIDk9PT1pLm5vZGVUeXBlP3t3aWR0aDp0LndpZHRoKCksaGVpZ2h0OnQuaGVpZ2h0KCksb2Zmc2V0Ont0b3A6MCxsZWZ0OjB9fTplLmlzV2luZG93KGkpP3t3aWR0aDp0LndpZHRoKCksaGVpZ2h0OnQuaGVpZ2h0KCksb2Zmc2V0Ont0b3A6dC5zY3JvbGxUb3AoKSxsZWZ0OnQuc2Nyb2xsTGVmdCgpfX06aS5wcmV2ZW50RGVmYXVsdD97d2lkdGg6MCxoZWlnaHQ6MCxvZmZzZXQ6e3RvcDppLnBhZ2VZLGxlZnQ6aS5wYWdlWH19Ont3aWR0aDp0Lm91dGVyV2lkdGgoKSxoZWlnaHQ6dC5vdXRlckhlaWdodCgpLG9mZnNldDp0Lm9mZnNldCgpfX1lLnVpPWUudWl8fHt9O3ZhciBuLGEsbz1NYXRoLm1heCxyPU1hdGguYWJzLGg9TWF0aC5yb3VuZCxsPS9sZWZ0fGNlbnRlcnxyaWdodC8sdT0vdG9wfGNlbnRlcnxib3R0b20vLGQ9L1tcXCtcXC1dXFxkKyhcXC5bXFxkXSspPyU/LyxjPS9eXFx3Ky8scD0vJSQvLGY9ZS5mbi5wb3NpdGlvbjtlLnBvc2l0aW9uPXtzY3JvbGxiYXJXaWR0aDpmdW5jdGlvbigpe2lmKHZvaWQgMCE9PW4pcmV0dXJuIG47dmFyIHQsaSxzPWUoXCI8ZGl2IHN0eWxlPSdkaXNwbGF5OmJsb2NrO3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjUwcHg7aGVpZ2h0OjUwcHg7b3ZlcmZsb3c6aGlkZGVuOyc+PGRpdiBzdHlsZT0naGVpZ2h0OjEwMHB4O3dpZHRoOmF1dG87Jz48L2Rpdj48L2Rpdj5cIiksYT1zLmNoaWxkcmVuKClbMF07cmV0dXJuIGUoXCJib2R5XCIpLmFwcGVuZChzKSx0PWEub2Zmc2V0V2lkdGgscy5jc3MoXCJvdmVyZmxvd1wiLFwic2Nyb2xsXCIpLGk9YS5vZmZzZXRXaWR0aCx0PT09aSYmKGk9c1swXS5jbGllbnRXaWR0aCkscy5yZW1vdmUoKSxuPXQtaX0sZ2V0U2Nyb2xsSW5mbzpmdW5jdGlvbih0KXt2YXIgaT10LmlzV2luZG93fHx0LmlzRG9jdW1lbnQ/XCJcIjp0LmVsZW1lbnQuY3NzKFwib3ZlcmZsb3cteFwiKSxzPXQuaXNXaW5kb3d8fHQuaXNEb2N1bWVudD9cIlwiOnQuZWxlbWVudC5jc3MoXCJvdmVyZmxvdy15XCIpLG49XCJzY3JvbGxcIj09PWl8fFwiYXV0b1wiPT09aSYmdC53aWR0aDx0LmVsZW1lbnRbMF0uc2Nyb2xsV2lkdGgsYT1cInNjcm9sbFwiPT09c3x8XCJhdXRvXCI9PT1zJiZ0LmhlaWdodDx0LmVsZW1lbnRbMF0uc2Nyb2xsSGVpZ2h0O3JldHVybnt3aWR0aDphP2UucG9zaXRpb24uc2Nyb2xsYmFyV2lkdGgoKTowLGhlaWdodDpuP2UucG9zaXRpb24uc2Nyb2xsYmFyV2lkdGgoKTowfX0sZ2V0V2l0aGluSW5mbzpmdW5jdGlvbih0KXt2YXIgaT1lKHR8fHdpbmRvdykscz1lLmlzV2luZG93KGlbMF0pLG49ISFpWzBdJiY5PT09aVswXS5ub2RlVHlwZTtyZXR1cm57ZWxlbWVudDppLGlzV2luZG93OnMsaXNEb2N1bWVudDpuLG9mZnNldDppLm9mZnNldCgpfHx7bGVmdDowLHRvcDowfSxzY3JvbGxMZWZ0Omkuc2Nyb2xsTGVmdCgpLHNjcm9sbFRvcDppLnNjcm9sbFRvcCgpLHdpZHRoOnN8fG4/aS53aWR0aCgpOmkub3V0ZXJXaWR0aCgpLGhlaWdodDpzfHxuP2kuaGVpZ2h0KCk6aS5vdXRlckhlaWdodCgpfX19LGUuZm4ucG9zaXRpb249ZnVuY3Rpb24obil7aWYoIW58fCFuLm9mKXJldHVybiBmLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtuPWUuZXh0ZW5kKHt9LG4pO3ZhciBwLG0sZyx2LHksYixfPWUobi5vZikseD1lLnBvc2l0aW9uLmdldFdpdGhpbkluZm8obi53aXRoaW4pLHc9ZS5wb3NpdGlvbi5nZXRTY3JvbGxJbmZvKHgpLGs9KG4uY29sbGlzaW9ufHxcImZsaXBcIikuc3BsaXQoXCIgXCIpLFQ9e307cmV0dXJuIGI9cyhfKSxfWzBdLnByZXZlbnREZWZhdWx0JiYobi5hdD1cImxlZnQgdG9wXCIpLG09Yi53aWR0aCxnPWIuaGVpZ2h0LHY9Yi5vZmZzZXQseT1lLmV4dGVuZCh7fSx2KSxlLmVhY2goW1wibXlcIixcImF0XCJdLGZ1bmN0aW9uKCl7dmFyIGUsdCxpPShuW3RoaXNdfHxcIlwiKS5zcGxpdChcIiBcIik7MT09PWkubGVuZ3RoJiYoaT1sLnRlc3QoaVswXSk/aS5jb25jYXQoW1wiY2VudGVyXCJdKTp1LnRlc3QoaVswXSk/W1wiY2VudGVyXCJdLmNvbmNhdChpKTpbXCJjZW50ZXJcIixcImNlbnRlclwiXSksaVswXT1sLnRlc3QoaVswXSk/aVswXTpcImNlbnRlclwiLGlbMV09dS50ZXN0KGlbMV0pP2lbMV06XCJjZW50ZXJcIixlPWQuZXhlYyhpWzBdKSx0PWQuZXhlYyhpWzFdKSxUW3RoaXNdPVtlP2VbMF06MCx0P3RbMF06MF0sblt0aGlzXT1bYy5leGVjKGlbMF0pWzBdLGMuZXhlYyhpWzFdKVswXV19KSwxPT09ay5sZW5ndGgmJihrWzFdPWtbMF0pLFwicmlnaHRcIj09PW4uYXRbMF0/eS5sZWZ0Kz1tOlwiY2VudGVyXCI9PT1uLmF0WzBdJiYoeS5sZWZ0Kz1tLzIpLFwiYm90dG9tXCI9PT1uLmF0WzFdP3kudG9wKz1nOlwiY2VudGVyXCI9PT1uLmF0WzFdJiYoeS50b3ArPWcvMikscD10KFQuYXQsbSxnKSx5LmxlZnQrPXBbMF0seS50b3ArPXBbMV0sdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIHMsbCx1PWUodGhpcyksZD11Lm91dGVyV2lkdGgoKSxjPXUub3V0ZXJIZWlnaHQoKSxmPWkodGhpcyxcIm1hcmdpbkxlZnRcIiksYj1pKHRoaXMsXCJtYXJnaW5Ub3BcIiksRD1kK2YraSh0aGlzLFwibWFyZ2luUmlnaHRcIikrdy53aWR0aCxTPWMrYitpKHRoaXMsXCJtYXJnaW5Cb3R0b21cIikrdy5oZWlnaHQsTT1lLmV4dGVuZCh7fSx5KSxDPXQoVC5teSx1Lm91dGVyV2lkdGgoKSx1Lm91dGVySGVpZ2h0KCkpO1wicmlnaHRcIj09PW4ubXlbMF0/TS5sZWZ0LT1kOlwiY2VudGVyXCI9PT1uLm15WzBdJiYoTS5sZWZ0LT1kLzIpLFwiYm90dG9tXCI9PT1uLm15WzFdP00udG9wLT1jOlwiY2VudGVyXCI9PT1uLm15WzFdJiYoTS50b3AtPWMvMiksTS5sZWZ0Kz1DWzBdLE0udG9wKz1DWzFdLGF8fChNLmxlZnQ9aChNLmxlZnQpLE0udG9wPWgoTS50b3ApKSxzPXttYXJnaW5MZWZ0OmYsbWFyZ2luVG9wOmJ9LGUuZWFjaChbXCJsZWZ0XCIsXCJ0b3BcIl0sZnVuY3Rpb24odCxpKXtlLnVpLnBvc2l0aW9uW2tbdF1dJiZlLnVpLnBvc2l0aW9uW2tbdF1dW2ldKE0se3RhcmdldFdpZHRoOm0sdGFyZ2V0SGVpZ2h0OmcsZWxlbVdpZHRoOmQsZWxlbUhlaWdodDpjLGNvbGxpc2lvblBvc2l0aW9uOnMsY29sbGlzaW9uV2lkdGg6RCxjb2xsaXNpb25IZWlnaHQ6UyxvZmZzZXQ6W3BbMF0rQ1swXSxwWzFdK0NbMV1dLG15Om4ubXksYXQ6bi5hdCx3aXRoaW46eCxlbGVtOnV9KX0pLG4udXNpbmcmJihsPWZ1bmN0aW9uKGUpe3ZhciB0PXYubGVmdC1NLmxlZnQsaT10K20tZCxzPXYudG9wLU0udG9wLGE9cytnLWMsaD17dGFyZ2V0OntlbGVtZW50Ol8sbGVmdDp2LmxlZnQsdG9wOnYudG9wLHdpZHRoOm0saGVpZ2h0Omd9LGVsZW1lbnQ6e2VsZW1lbnQ6dSxsZWZ0Ok0ubGVmdCx0b3A6TS50b3Asd2lkdGg6ZCxoZWlnaHQ6Y30saG9yaXpvbnRhbDowPmk/XCJsZWZ0XCI6dD4wP1wicmlnaHRcIjpcImNlbnRlclwiLHZlcnRpY2FsOjA+YT9cInRvcFwiOnM+MD9cImJvdHRvbVwiOlwibWlkZGxlXCJ9O2Q+bSYmbT5yKHQraSkmJihoLmhvcml6b250YWw9XCJjZW50ZXJcIiksYz5nJiZnPnIocythKSYmKGgudmVydGljYWw9XCJtaWRkbGVcIiksaC5pbXBvcnRhbnQ9byhyKHQpLHIoaSkpPm8ocihzKSxyKGEpKT9cImhvcml6b250YWxcIjpcInZlcnRpY2FsXCIsbi51c2luZy5jYWxsKHRoaXMsZSxoKX0pLHUub2Zmc2V0KGUuZXh0ZW5kKE0se3VzaW5nOmx9KSl9KX0sZS51aS5wb3NpdGlvbj17Zml0OntsZWZ0OmZ1bmN0aW9uKGUsdCl7dmFyIGkscz10LndpdGhpbixuPXMuaXNXaW5kb3c/cy5zY3JvbGxMZWZ0OnMub2Zmc2V0LmxlZnQsYT1zLndpZHRoLHI9ZS5sZWZ0LXQuY29sbGlzaW9uUG9zaXRpb24ubWFyZ2luTGVmdCxoPW4tcixsPXIrdC5jb2xsaXNpb25XaWR0aC1hLW47dC5jb2xsaXNpb25XaWR0aD5hP2g+MCYmMD49bD8oaT1lLmxlZnQraCt0LmNvbGxpc2lvbldpZHRoLWEtbixlLmxlZnQrPWgtaSk6ZS5sZWZ0PWw+MCYmMD49aD9uOmg+bD9uK2EtdC5jb2xsaXNpb25XaWR0aDpuOmg+MD9lLmxlZnQrPWg6bD4wP2UubGVmdC09bDplLmxlZnQ9byhlLmxlZnQtcixlLmxlZnQpfSx0b3A6ZnVuY3Rpb24oZSx0KXt2YXIgaSxzPXQud2l0aGluLG49cy5pc1dpbmRvdz9zLnNjcm9sbFRvcDpzLm9mZnNldC50b3AsYT10LndpdGhpbi5oZWlnaHQscj1lLnRvcC10LmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpblRvcCxoPW4tcixsPXIrdC5jb2xsaXNpb25IZWlnaHQtYS1uO3QuY29sbGlzaW9uSGVpZ2h0PmE/aD4wJiYwPj1sPyhpPWUudG9wK2grdC5jb2xsaXNpb25IZWlnaHQtYS1uLGUudG9wKz1oLWkpOmUudG9wPWw+MCYmMD49aD9uOmg+bD9uK2EtdC5jb2xsaXNpb25IZWlnaHQ6bjpoPjA/ZS50b3ArPWg6bD4wP2UudG9wLT1sOmUudG9wPW8oZS50b3AtcixlLnRvcCl9fSxmbGlwOntsZWZ0OmZ1bmN0aW9uKGUsdCl7dmFyIGkscyxuPXQud2l0aGluLGE9bi5vZmZzZXQubGVmdCtuLnNjcm9sbExlZnQsbz1uLndpZHRoLGg9bi5pc1dpbmRvdz9uLnNjcm9sbExlZnQ6bi5vZmZzZXQubGVmdCxsPWUubGVmdC10LmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpbkxlZnQsdT1sLWgsZD1sK3QuY29sbGlzaW9uV2lkdGgtby1oLGM9XCJsZWZ0XCI9PT10Lm15WzBdPy10LmVsZW1XaWR0aDpcInJpZ2h0XCI9PT10Lm15WzBdP3QuZWxlbVdpZHRoOjAscD1cImxlZnRcIj09PXQuYXRbMF0/dC50YXJnZXRXaWR0aDpcInJpZ2h0XCI9PT10LmF0WzBdPy10LnRhcmdldFdpZHRoOjAsZj0tMip0Lm9mZnNldFswXTswPnU/KGk9ZS5sZWZ0K2MrcCtmK3QuY29sbGlzaW9uV2lkdGgtby1hLCgwPml8fHIodSk+aSkmJihlLmxlZnQrPWMrcCtmKSk6ZD4wJiYocz1lLmxlZnQtdC5jb2xsaXNpb25Qb3NpdGlvbi5tYXJnaW5MZWZ0K2MrcCtmLWgsKHM+MHx8ZD5yKHMpKSYmKGUubGVmdCs9YytwK2YpKX0sdG9wOmZ1bmN0aW9uKGUsdCl7dmFyIGkscyxuPXQud2l0aGluLGE9bi5vZmZzZXQudG9wK24uc2Nyb2xsVG9wLG89bi5oZWlnaHQsaD1uLmlzV2luZG93P24uc2Nyb2xsVG9wOm4ub2Zmc2V0LnRvcCxsPWUudG9wLXQuY29sbGlzaW9uUG9zaXRpb24ubWFyZ2luVG9wLHU9bC1oLGQ9bCt0LmNvbGxpc2lvbkhlaWdodC1vLWgsYz1cInRvcFwiPT09dC5teVsxXSxwPWM/LXQuZWxlbUhlaWdodDpcImJvdHRvbVwiPT09dC5teVsxXT90LmVsZW1IZWlnaHQ6MCxmPVwidG9wXCI9PT10LmF0WzFdP3QudGFyZ2V0SGVpZ2h0OlwiYm90dG9tXCI9PT10LmF0WzFdPy10LnRhcmdldEhlaWdodDowLG09LTIqdC5vZmZzZXRbMV07MD51PyhzPWUudG9wK3ArZittK3QuY29sbGlzaW9uSGVpZ2h0LW8tYSwoMD5zfHxyKHUpPnMpJiYoZS50b3ArPXArZittKSk6ZD4wJiYoaT1lLnRvcC10LmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpblRvcCtwK2YrbS1oLChpPjB8fGQ+cihpKSkmJihlLnRvcCs9cCtmK20pKX19LGZsaXBmaXQ6e2xlZnQ6ZnVuY3Rpb24oKXtlLnVpLnBvc2l0aW9uLmZsaXAubGVmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyksZS51aS5wb3NpdGlvbi5maXQubGVmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9LHRvcDpmdW5jdGlvbigpe2UudWkucG9zaXRpb24uZmxpcC50b3AuYXBwbHkodGhpcyxhcmd1bWVudHMpLGUudWkucG9zaXRpb24uZml0LnRvcC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX0sZnVuY3Rpb24oKXt2YXIgdCxpLHMsbixvLHI9ZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJib2R5XCIpWzBdLGg9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTt0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocj9cImRpdlwiOlwiYm9keVwiKSxzPXt2aXNpYmlsaXR5OlwiaGlkZGVuXCIsd2lkdGg6MCxoZWlnaHQ6MCxib3JkZXI6MCxtYXJnaW46MCxiYWNrZ3JvdW5kOlwibm9uZVwifSxyJiZlLmV4dGVuZChzLHtwb3NpdGlvbjpcImFic29sdXRlXCIsbGVmdDpcIi0xMDAwcHhcIix0b3A6XCItMTAwMHB4XCJ9KTtmb3IobyBpbiBzKXQuc3R5bGVbb109c1tvXTt0LmFwcGVuZENoaWxkKGgpLGk9cnx8ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LGkuaW5zZXJ0QmVmb3JlKHQsaS5maXJzdENoaWxkKSxoLnN0eWxlLmNzc1RleHQ9XCJwb3NpdGlvbjogYWJzb2x1dGU7IGxlZnQ6IDEwLjc0MzIyMjJweDtcIixuPWUoaCkub2Zmc2V0KCkubGVmdCxhPW4+MTAmJjExPm4sdC5pbm5lckhUTUw9XCJcIixpLnJlbW92ZUNoaWxkKHQpfSgpfSgpLGUudWkucG9zaXRpb24sZS53aWRnZXQoXCJ1aS5hY2NvcmRpb25cIix7dmVyc2lvbjpcIjEuMTEuNFwiLG9wdGlvbnM6e2FjdGl2ZTowLGFuaW1hdGU6e30sY29sbGFwc2libGU6ITEsZXZlbnQ6XCJjbGlja1wiLGhlYWRlcjpcIj4gbGkgPiA6Zmlyc3QtY2hpbGQsPiA6bm90KGxpKTpldmVuXCIsaGVpZ2h0U3R5bGU6XCJhdXRvXCIsaWNvbnM6e2FjdGl2ZUhlYWRlcjpcInVpLWljb24tdHJpYW5nbGUtMS1zXCIsaGVhZGVyOlwidWktaWNvbi10cmlhbmdsZS0xLWVcIn0sYWN0aXZhdGU6bnVsbCxiZWZvcmVBY3RpdmF0ZTpudWxsfSxoaWRlUHJvcHM6e2JvcmRlclRvcFdpZHRoOlwiaGlkZVwiLGJvcmRlckJvdHRvbVdpZHRoOlwiaGlkZVwiLHBhZGRpbmdUb3A6XCJoaWRlXCIscGFkZGluZ0JvdHRvbTpcImhpZGVcIixoZWlnaHQ6XCJoaWRlXCJ9LHNob3dQcm9wczp7Ym9yZGVyVG9wV2lkdGg6XCJzaG93XCIsYm9yZGVyQm90dG9tV2lkdGg6XCJzaG93XCIscGFkZGluZ1RvcDpcInNob3dcIixwYWRkaW5nQm90dG9tOlwic2hvd1wiLGhlaWdodDpcInNob3dcIn0sX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9uczt0aGlzLnByZXZTaG93PXRoaXMucHJldkhpZGU9ZSgpLHRoaXMuZWxlbWVudC5hZGRDbGFzcyhcInVpLWFjY29yZGlvbiB1aS13aWRnZXQgdWktaGVscGVyLXJlc2V0XCIpLmF0dHIoXCJyb2xlXCIsXCJ0YWJsaXN0XCIpLHQuY29sbGFwc2libGV8fHQuYWN0aXZlIT09ITEmJm51bGwhPXQuYWN0aXZlfHwodC5hY3RpdmU9MCksdGhpcy5fcHJvY2Vzc1BhbmVscygpLDA+dC5hY3RpdmUmJih0LmFjdGl2ZSs9dGhpcy5oZWFkZXJzLmxlbmd0aCksdGhpcy5fcmVmcmVzaCgpfSxfZ2V0Q3JlYXRlRXZlbnREYXRhOmZ1bmN0aW9uKCl7cmV0dXJue2hlYWRlcjp0aGlzLmFjdGl2ZSxwYW5lbDp0aGlzLmFjdGl2ZS5sZW5ndGg/dGhpcy5hY3RpdmUubmV4dCgpOmUoKX19LF9jcmVhdGVJY29uczpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9ucy5pY29uczt0JiYoZShcIjxzcGFuPlwiKS5hZGRDbGFzcyhcInVpLWFjY29yZGlvbi1oZWFkZXItaWNvbiB1aS1pY29uIFwiK3QuaGVhZGVyKS5wcmVwZW5kVG8odGhpcy5oZWFkZXJzKSx0aGlzLmFjdGl2ZS5jaGlsZHJlbihcIi51aS1hY2NvcmRpb24taGVhZGVyLWljb25cIikucmVtb3ZlQ2xhc3ModC5oZWFkZXIpLmFkZENsYXNzKHQuYWN0aXZlSGVhZGVyKSx0aGlzLmhlYWRlcnMuYWRkQ2xhc3MoXCJ1aS1hY2NvcmRpb24taWNvbnNcIikpfSxfZGVzdHJveUljb25zOmZ1bmN0aW9uKCl7dGhpcy5oZWFkZXJzLnJlbW92ZUNsYXNzKFwidWktYWNjb3JkaW9uLWljb25zXCIpLmNoaWxkcmVuKFwiLnVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiKS5yZW1vdmUoKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt2YXIgZTt0aGlzLmVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS1hY2NvcmRpb24gdWktd2lkZ2V0IHVpLWhlbHBlci1yZXNldFwiKS5yZW1vdmVBdHRyKFwicm9sZVwiKSx0aGlzLmhlYWRlcnMucmVtb3ZlQ2xhc3MoXCJ1aS1hY2NvcmRpb24taGVhZGVyIHVpLWFjY29yZGlvbi1oZWFkZXItYWN0aXZlIHVpLXN0YXRlLWRlZmF1bHQgdWktY29ybmVyLWFsbCB1aS1zdGF0ZS1hY3RpdmUgdWktc3RhdGUtZGlzYWJsZWQgdWktY29ybmVyLXRvcFwiKS5yZW1vdmVBdHRyKFwicm9sZVwiKS5yZW1vdmVBdHRyKFwiYXJpYS1leHBhbmRlZFwiKS5yZW1vdmVBdHRyKFwiYXJpYS1zZWxlY3RlZFwiKS5yZW1vdmVBdHRyKFwiYXJpYS1jb250cm9sc1wiKS5yZW1vdmVBdHRyKFwidGFiSW5kZXhcIikucmVtb3ZlVW5pcXVlSWQoKSx0aGlzLl9kZXN0cm95SWNvbnMoKSxlPXRoaXMuaGVhZGVycy5uZXh0KCkucmVtb3ZlQ2xhc3MoXCJ1aS1oZWxwZXItcmVzZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktY29ybmVyLWJvdHRvbSB1aS1hY2NvcmRpb24tY29udGVudCB1aS1hY2NvcmRpb24tY29udGVudC1hY3RpdmUgdWktc3RhdGUtZGlzYWJsZWRcIikuY3NzKFwiZGlzcGxheVwiLFwiXCIpLnJlbW92ZUF0dHIoXCJyb2xlXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWhpZGRlblwiKS5yZW1vdmVBdHRyKFwiYXJpYS1sYWJlbGxlZGJ5XCIpLnJlbW92ZVVuaXF1ZUlkKCksXCJjb250ZW50XCIhPT10aGlzLm9wdGlvbnMuaGVpZ2h0U3R5bGUmJmUuY3NzKFwiaGVpZ2h0XCIsXCJcIil9LF9zZXRPcHRpb246ZnVuY3Rpb24oZSx0KXtyZXR1cm5cImFjdGl2ZVwiPT09ZT8odGhpcy5fYWN0aXZhdGUodCksdm9pZCAwKTooXCJldmVudFwiPT09ZSYmKHRoaXMub3B0aW9ucy5ldmVudCYmdGhpcy5fb2ZmKHRoaXMuaGVhZGVycyx0aGlzLm9wdGlvbnMuZXZlbnQpLHRoaXMuX3NldHVwRXZlbnRzKHQpKSx0aGlzLl9zdXBlcihlLHQpLFwiY29sbGFwc2libGVcIiE9PWV8fHR8fHRoaXMub3B0aW9ucy5hY3RpdmUhPT0hMXx8dGhpcy5fYWN0aXZhdGUoMCksXCJpY29uc1wiPT09ZSYmKHRoaXMuX2Rlc3Ryb3lJY29ucygpLHQmJnRoaXMuX2NyZWF0ZUljb25zKCkpLFwiZGlzYWJsZWRcIj09PWUmJih0aGlzLmVsZW1lbnQudG9nZ2xlQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiLCEhdCkuYXR0cihcImFyaWEtZGlzYWJsZWRcIix0KSx0aGlzLmhlYWRlcnMuYWRkKHRoaXMuaGVhZGVycy5uZXh0KCkpLnRvZ2dsZUNsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIXQpKSx2b2lkIDApfSxfa2V5ZG93bjpmdW5jdGlvbih0KXtpZighdC5hbHRLZXkmJiF0LmN0cmxLZXkpe3ZhciBpPWUudWkua2V5Q29kZSxzPXRoaXMuaGVhZGVycy5sZW5ndGgsbj10aGlzLmhlYWRlcnMuaW5kZXgodC50YXJnZXQpLGE9ITE7c3dpdGNoKHQua2V5Q29kZSl7Y2FzZSBpLlJJR0hUOmNhc2UgaS5ET1dOOmE9dGhpcy5oZWFkZXJzWyhuKzEpJXNdO2JyZWFrO2Nhc2UgaS5MRUZUOmNhc2UgaS5VUDphPXRoaXMuaGVhZGVyc1sobi0xK3MpJXNdO2JyZWFrO2Nhc2UgaS5TUEFDRTpjYXNlIGkuRU5URVI6dGhpcy5fZXZlbnRIYW5kbGVyKHQpO2JyZWFrO2Nhc2UgaS5IT01FOmE9dGhpcy5oZWFkZXJzWzBdO2JyZWFrO2Nhc2UgaS5FTkQ6YT10aGlzLmhlYWRlcnNbcy0xXX1hJiYoZSh0LnRhcmdldCkuYXR0cihcInRhYkluZGV4XCIsLTEpLGUoYSkuYXR0cihcInRhYkluZGV4XCIsMCksYS5mb2N1cygpLHQucHJldmVudERlZmF1bHQoKSl9fSxfcGFuZWxLZXlEb3duOmZ1bmN0aW9uKHQpe3Qua2V5Q29kZT09PWUudWkua2V5Q29kZS5VUCYmdC5jdHJsS2V5JiZlKHQuY3VycmVudFRhcmdldCkucHJldigpLmZvY3VzKCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnM7dGhpcy5fcHJvY2Vzc1BhbmVscygpLHQuYWN0aXZlPT09ITEmJnQuY29sbGFwc2libGU9PT0hMHx8IXRoaXMuaGVhZGVycy5sZW5ndGg/KHQuYWN0aXZlPSExLHRoaXMuYWN0aXZlPWUoKSk6dC5hY3RpdmU9PT0hMT90aGlzLl9hY3RpdmF0ZSgwKTp0aGlzLmFjdGl2ZS5sZW5ndGgmJiFlLmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSx0aGlzLmFjdGl2ZVswXSk/dGhpcy5oZWFkZXJzLmxlbmd0aD09PXRoaXMuaGVhZGVycy5maW5kKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpLmxlbmd0aD8odC5hY3RpdmU9ITEsdGhpcy5hY3RpdmU9ZSgpKTp0aGlzLl9hY3RpdmF0ZShNYXRoLm1heCgwLHQuYWN0aXZlLTEpKTp0LmFjdGl2ZT10aGlzLmhlYWRlcnMuaW5kZXgodGhpcy5hY3RpdmUpLHRoaXMuX2Rlc3Ryb3lJY29ucygpLHRoaXMuX3JlZnJlc2goKX0sX3Byb2Nlc3NQYW5lbHM6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmhlYWRlcnMsdD10aGlzLnBhbmVsczt0aGlzLmhlYWRlcnM9dGhpcy5lbGVtZW50LmZpbmQodGhpcy5vcHRpb25zLmhlYWRlcikuYWRkQ2xhc3MoXCJ1aS1hY2NvcmRpb24taGVhZGVyIHVpLXN0YXRlLWRlZmF1bHQgdWktY29ybmVyLWFsbFwiKSx0aGlzLnBhbmVscz10aGlzLmhlYWRlcnMubmV4dCgpLmFkZENsYXNzKFwidWktYWNjb3JkaW9uLWNvbnRlbnQgdWktaGVscGVyLXJlc2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWNvcm5lci1ib3R0b21cIikuZmlsdGVyKFwiOm5vdCgudWktYWNjb3JkaW9uLWNvbnRlbnQtYWN0aXZlKVwiKS5oaWRlKCksdCYmKHRoaXMuX29mZihlLm5vdCh0aGlzLmhlYWRlcnMpKSx0aGlzLl9vZmYodC5ub3QodGhpcy5wYW5lbHMpKSl9LF9yZWZyZXNoOmZ1bmN0aW9uKCl7dmFyIHQsaT10aGlzLm9wdGlvbnMscz1pLmhlaWdodFN0eWxlLG49dGhpcy5lbGVtZW50LnBhcmVudCgpO3RoaXMuYWN0aXZlPXRoaXMuX2ZpbmRBY3RpdmUoaS5hY3RpdmUpLmFkZENsYXNzKFwidWktYWNjb3JkaW9uLWhlYWRlci1hY3RpdmUgdWktc3RhdGUtYWN0aXZlIHVpLWNvcm5lci10b3BcIikucmVtb3ZlQ2xhc3MoXCJ1aS1jb3JuZXItYWxsXCIpLHRoaXMuYWN0aXZlLm5leHQoKS5hZGRDbGFzcyhcInVpLWFjY29yZGlvbi1jb250ZW50LWFjdGl2ZVwiKS5zaG93KCksdGhpcy5oZWFkZXJzLmF0dHIoXCJyb2xlXCIsXCJ0YWJcIikuZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcyksaT10LnVuaXF1ZUlkKCkuYXR0cihcImlkXCIpLHM9dC5uZXh0KCksbj1zLnVuaXF1ZUlkKCkuYXR0cihcImlkXCIpO3QuYXR0cihcImFyaWEtY29udHJvbHNcIixuKSxzLmF0dHIoXCJhcmlhLWxhYmVsbGVkYnlcIixpKX0pLm5leHQoKS5hdHRyKFwicm9sZVwiLFwidGFicGFuZWxcIiksdGhpcy5oZWFkZXJzLm5vdCh0aGlzLmFjdGl2ZSkuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJmYWxzZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIix0YWJJbmRleDotMX0pLm5leHQoKS5hdHRyKHtcImFyaWEtaGlkZGVuXCI6XCJ0cnVlXCJ9KS5oaWRlKCksdGhpcy5hY3RpdmUubGVuZ3RoP3RoaXMuYWN0aXZlLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwidHJ1ZVwiLHRhYkluZGV4OjB9KS5uZXh0KCkuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwiZmFsc2VcIn0pOnRoaXMuaGVhZGVycy5lcSgwKS5hdHRyKFwidGFiSW5kZXhcIiwwKSx0aGlzLl9jcmVhdGVJY29ucygpLHRoaXMuX3NldHVwRXZlbnRzKGkuZXZlbnQpLFwiZmlsbFwiPT09cz8odD1uLmhlaWdodCgpLHRoaXMuZWxlbWVudC5zaWJsaW5ncyhcIjp2aXNpYmxlXCIpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT1lKHRoaXMpLHM9aS5jc3MoXCJwb3NpdGlvblwiKTtcImFic29sdXRlXCIhPT1zJiZcImZpeGVkXCIhPT1zJiYodC09aS5vdXRlckhlaWdodCghMCkpfSksdGhpcy5oZWFkZXJzLmVhY2goZnVuY3Rpb24oKXt0LT1lKHRoaXMpLm91dGVySGVpZ2h0KCEwKX0pLHRoaXMuaGVhZGVycy5uZXh0KCkuZWFjaChmdW5jdGlvbigpe2UodGhpcykuaGVpZ2h0KE1hdGgubWF4KDAsdC1lKHRoaXMpLmlubmVySGVpZ2h0KCkrZSh0aGlzKS5oZWlnaHQoKSkpfSkuY3NzKFwib3ZlcmZsb3dcIixcImF1dG9cIikpOlwiYXV0b1wiPT09cyYmKHQ9MCx0aGlzLmhlYWRlcnMubmV4dCgpLmVhY2goZnVuY3Rpb24oKXt0PU1hdGgubWF4KHQsZSh0aGlzKS5jc3MoXCJoZWlnaHRcIixcIlwiKS5oZWlnaHQoKSl9KS5oZWlnaHQodCkpfSxfYWN0aXZhdGU6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5fZmluZEFjdGl2ZSh0KVswXTtpIT09dGhpcy5hY3RpdmVbMF0mJihpPWl8fHRoaXMuYWN0aXZlWzBdLHRoaXMuX2V2ZW50SGFuZGxlcih7dGFyZ2V0OmksY3VycmVudFRhcmdldDppLHByZXZlbnREZWZhdWx0OmUubm9vcH0pKX0sX2ZpbmRBY3RpdmU6ZnVuY3Rpb24odCl7cmV0dXJuXCJudW1iZXJcIj09dHlwZW9mIHQ/dGhpcy5oZWFkZXJzLmVxKHQpOmUoKX0sX3NldHVwRXZlbnRzOmZ1bmN0aW9uKHQpe3ZhciBpPXtrZXlkb3duOlwiX2tleWRvd25cIn07dCYmZS5lYWNoKHQuc3BsaXQoXCIgXCIpLGZ1bmN0aW9uKGUsdCl7aVt0XT1cIl9ldmVudEhhbmRsZXJcIn0pLHRoaXMuX29mZih0aGlzLmhlYWRlcnMuYWRkKHRoaXMuaGVhZGVycy5uZXh0KCkpKSx0aGlzLl9vbih0aGlzLmhlYWRlcnMsaSksdGhpcy5fb24odGhpcy5oZWFkZXJzLm5leHQoKSx7a2V5ZG93bjpcIl9wYW5lbEtleURvd25cIn0pLHRoaXMuX2hvdmVyYWJsZSh0aGlzLmhlYWRlcnMpLHRoaXMuX2ZvY3VzYWJsZSh0aGlzLmhlYWRlcnMpfSxfZXZlbnRIYW5kbGVyOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMub3B0aW9ucyxzPXRoaXMuYWN0aXZlLG49ZSh0LmN1cnJlbnRUYXJnZXQpLGE9blswXT09PXNbMF0sbz1hJiZpLmNvbGxhcHNpYmxlLHI9bz9lKCk6bi5uZXh0KCksaD1zLm5leHQoKSxsPXtvbGRIZWFkZXI6cyxvbGRQYW5lbDpoLG5ld0hlYWRlcjpvP2UoKTpuLG5ld1BhbmVsOnJ9O3QucHJldmVudERlZmF1bHQoKSxhJiYhaS5jb2xsYXBzaWJsZXx8dGhpcy5fdHJpZ2dlcihcImJlZm9yZUFjdGl2YXRlXCIsdCxsKT09PSExfHwoaS5hY3RpdmU9bz8hMTp0aGlzLmhlYWRlcnMuaW5kZXgobiksdGhpcy5hY3RpdmU9YT9lKCk6bix0aGlzLl90b2dnbGUobCkscy5yZW1vdmVDbGFzcyhcInVpLWFjY29yZGlvbi1oZWFkZXItYWN0aXZlIHVpLXN0YXRlLWFjdGl2ZVwiKSxpLmljb25zJiZzLmNoaWxkcmVuKFwiLnVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiKS5yZW1vdmVDbGFzcyhpLmljb25zLmFjdGl2ZUhlYWRlcikuYWRkQ2xhc3MoaS5pY29ucy5oZWFkZXIpLGF8fChuLnJlbW92ZUNsYXNzKFwidWktY29ybmVyLWFsbFwiKS5hZGRDbGFzcyhcInVpLWFjY29yZGlvbi1oZWFkZXItYWN0aXZlIHVpLXN0YXRlLWFjdGl2ZSB1aS1jb3JuZXItdG9wXCIpLGkuaWNvbnMmJm4uY2hpbGRyZW4oXCIudWktYWNjb3JkaW9uLWhlYWRlci1pY29uXCIpLnJlbW92ZUNsYXNzKGkuaWNvbnMuaGVhZGVyKS5hZGRDbGFzcyhpLmljb25zLmFjdGl2ZUhlYWRlciksbi5uZXh0KCkuYWRkQ2xhc3MoXCJ1aS1hY2NvcmRpb24tY29udGVudC1hY3RpdmVcIikpKX0sX3RvZ2dsZTpmdW5jdGlvbih0KXt2YXIgaT10Lm5ld1BhbmVsLHM9dGhpcy5wcmV2U2hvdy5sZW5ndGg/dGhpcy5wcmV2U2hvdzp0Lm9sZFBhbmVsO3RoaXMucHJldlNob3cuYWRkKHRoaXMucHJldkhpZGUpLnN0b3AoITAsITApLHRoaXMucHJldlNob3c9aSx0aGlzLnByZXZIaWRlPXMsdGhpcy5vcHRpb25zLmFuaW1hdGU/dGhpcy5fYW5pbWF0ZShpLHMsdCk6KHMuaGlkZSgpLGkuc2hvdygpLHRoaXMuX3RvZ2dsZUNvbXBsZXRlKHQpKSxzLmF0dHIoe1wiYXJpYS1oaWRkZW5cIjpcInRydWVcIn0pLHMucHJldigpLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwiZmFsc2VcIixcImFyaWEtZXhwYW5kZWRcIjpcImZhbHNlXCJ9KSxpLmxlbmd0aCYmcy5sZW5ndGg/cy5wcmV2KCkuYXR0cih7dGFiSW5kZXg6LTEsXCJhcmlhLWV4cGFuZGVkXCI6XCJmYWxzZVwifSk6aS5sZW5ndGgmJnRoaXMuaGVhZGVycy5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4gMD09PXBhcnNlSW50KGUodGhpcykuYXR0cihcInRhYkluZGV4XCIpLDEwKX0pLmF0dHIoXCJ0YWJJbmRleFwiLC0xKSxpLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwiZmFsc2VcIikucHJldigpLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwidHJ1ZVwiLHRhYkluZGV4OjB9KX0sX2FuaW1hdGU6ZnVuY3Rpb24oZSx0LGkpe3ZhciBzLG4sYSxvPXRoaXMscj0wLGg9ZS5jc3MoXCJib3gtc2l6aW5nXCIpLGw9ZS5sZW5ndGgmJighdC5sZW5ndGh8fGUuaW5kZXgoKTx0LmluZGV4KCkpLHU9dGhpcy5vcHRpb25zLmFuaW1hdGV8fHt9LGQ9bCYmdS5kb3dufHx1LGM9ZnVuY3Rpb24oKXtvLl90b2dnbGVDb21wbGV0ZShpKX07cmV0dXJuXCJudW1iZXJcIj09dHlwZW9mIGQmJihhPWQpLFwic3RyaW5nXCI9PXR5cGVvZiBkJiYobj1kKSxuPW58fGQuZWFzaW5nfHx1LmVhc2luZyxhPWF8fGQuZHVyYXRpb258fHUuZHVyYXRpb24sdC5sZW5ndGg/ZS5sZW5ndGg/KHM9ZS5zaG93KCkub3V0ZXJIZWlnaHQoKSx0LmFuaW1hdGUodGhpcy5oaWRlUHJvcHMse2R1cmF0aW9uOmEsZWFzaW5nOm4sc3RlcDpmdW5jdGlvbihlLHQpe3Qubm93PU1hdGgucm91bmQoZSl9fSksZS5oaWRlKCkuYW5pbWF0ZSh0aGlzLnNob3dQcm9wcyx7ZHVyYXRpb246YSxlYXNpbmc6bixjb21wbGV0ZTpjLHN0ZXA6ZnVuY3Rpb24oZSxpKXtpLm5vdz1NYXRoLnJvdW5kKGUpLFwiaGVpZ2h0XCIhPT1pLnByb3A/XCJjb250ZW50LWJveFwiPT09aCYmKHIrPWkubm93KTpcImNvbnRlbnRcIiE9PW8ub3B0aW9ucy5oZWlnaHRTdHlsZSYmKGkubm93PU1hdGgucm91bmQocy10Lm91dGVySGVpZ2h0KCktcikscj0wKX19KSx2b2lkIDApOnQuYW5pbWF0ZSh0aGlzLmhpZGVQcm9wcyxhLG4sYyk6ZS5hbmltYXRlKHRoaXMuc2hvd1Byb3BzLGEsbixjKX0sX3RvZ2dsZUNvbXBsZXRlOmZ1bmN0aW9uKGUpe3ZhciB0PWUub2xkUGFuZWw7dC5yZW1vdmVDbGFzcyhcInVpLWFjY29yZGlvbi1jb250ZW50LWFjdGl2ZVwiKS5wcmV2KCkucmVtb3ZlQ2xhc3MoXCJ1aS1jb3JuZXItdG9wXCIpLmFkZENsYXNzKFwidWktY29ybmVyLWFsbFwiKSx0Lmxlbmd0aCYmKHQucGFyZW50KClbMF0uY2xhc3NOYW1lPXQucGFyZW50KClbMF0uY2xhc3NOYW1lKSx0aGlzLl90cmlnZ2VyKFwiYWN0aXZhdGVcIixudWxsLGUpfX0pLGUud2lkZ2V0KFwidWkubWVudVwiLHt2ZXJzaW9uOlwiMS4xMS40XCIsZGVmYXVsdEVsZW1lbnQ6XCI8dWw+XCIsZGVsYXk6MzAwLG9wdGlvbnM6e2ljb25zOntzdWJtZW51OlwidWktaWNvbi1jYXJhdC0xLWVcIn0saXRlbXM6XCI+ICpcIixtZW51czpcInVsXCIscG9zaXRpb246e215OlwibGVmdC0xIHRvcFwiLGF0OlwicmlnaHQgdG9wXCJ9LHJvbGU6XCJtZW51XCIsYmx1cjpudWxsLGZvY3VzOm51bGwsc2VsZWN0Om51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLmFjdGl2ZU1lbnU9dGhpcy5lbGVtZW50LHRoaXMubW91c2VIYW5kbGVkPSExLHRoaXMuZWxlbWVudC51bmlxdWVJZCgpLmFkZENsYXNzKFwidWktbWVudSB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnRcIikudG9nZ2xlQ2xhc3MoXCJ1aS1tZW51LWljb25zXCIsISF0aGlzLmVsZW1lbnQuZmluZChcIi51aS1pY29uXCIpLmxlbmd0aCkuYXR0cih7cm9sZTp0aGlzLm9wdGlvbnMucm9sZSx0YWJJbmRleDowfSksdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKS5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLFwidHJ1ZVwiKSx0aGlzLl9vbih7XCJtb3VzZWRvd24gLnVpLW1lbnUtaXRlbVwiOmZ1bmN0aW9uKGUpe2UucHJldmVudERlZmF1bHQoKX0sXCJjbGljayAudWktbWVudS1pdGVtXCI6ZnVuY3Rpb24odCl7dmFyIGk9ZSh0LnRhcmdldCk7IXRoaXMubW91c2VIYW5kbGVkJiZpLm5vdChcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKS5sZW5ndGgmJih0aGlzLnNlbGVjdCh0KSx0LmlzUHJvcGFnYXRpb25TdG9wcGVkKCl8fCh0aGlzLm1vdXNlSGFuZGxlZD0hMCksaS5oYXMoXCIudWktbWVudVwiKS5sZW5ndGg/dGhpcy5leHBhbmQodCk6IXRoaXMuZWxlbWVudC5pcyhcIjpmb2N1c1wiKSYmZSh0aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQpLmNsb3Nlc3QoXCIudWktbWVudVwiKS5sZW5ndGgmJih0aGlzLmVsZW1lbnQudHJpZ2dlcihcImZvY3VzXCIsWyEwXSksdGhpcy5hY3RpdmUmJjE9PT10aGlzLmFjdGl2ZS5wYXJlbnRzKFwiLnVpLW1lbnVcIikubGVuZ3RoJiZjbGVhclRpbWVvdXQodGhpcy50aW1lcikpKX0sXCJtb3VzZWVudGVyIC51aS1tZW51LWl0ZW1cIjpmdW5jdGlvbih0KXtpZighdGhpcy5wcmV2aW91c0ZpbHRlcil7dmFyIGk9ZSh0LmN1cnJlbnRUYXJnZXQpO1xyXG5pLnNpYmxpbmdzKFwiLnVpLXN0YXRlLWFjdGl2ZVwiKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKSx0aGlzLmZvY3VzKHQsaSl9fSxtb3VzZWxlYXZlOlwiY29sbGFwc2VBbGxcIixcIm1vdXNlbGVhdmUgLnVpLW1lbnVcIjpcImNvbGxhcHNlQWxsXCIsZm9jdXM6ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLmFjdGl2ZXx8dGhpcy5lbGVtZW50LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKS5lcSgwKTt0fHx0aGlzLmZvY3VzKGUsaSl9LGJsdXI6ZnVuY3Rpb24odCl7dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXtlLmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSx0aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQpfHx0aGlzLmNvbGxhcHNlQWxsKHQpfSl9LGtleWRvd246XCJfa2V5ZG93blwifSksdGhpcy5yZWZyZXNoKCksdGhpcy5fb24odGhpcy5kb2N1bWVudCx7Y2xpY2s6ZnVuY3Rpb24oZSl7dGhpcy5fY2xvc2VPbkRvY3VtZW50Q2xpY2soZSkmJnRoaXMuY29sbGFwc2VBbGwoZSksdGhpcy5tb3VzZUhhbmRsZWQ9ITF9fSl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUF0dHIoXCJhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcIikuZmluZChcIi51aS1tZW51XCIpLmFkZEJhY2soKS5yZW1vdmVDbGFzcyhcInVpLW1lbnUgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLW1lbnUtaWNvbnMgdWktZnJvbnRcIikucmVtb3ZlQXR0cihcInJvbGVcIikucmVtb3ZlQXR0cihcInRhYkluZGV4XCIpLnJlbW92ZUF0dHIoXCJhcmlhLWxhYmVsbGVkYnlcIikucmVtb3ZlQXR0cihcImFyaWEtZXhwYW5kZWRcIikucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWRpc2FibGVkXCIpLnJlbW92ZVVuaXF1ZUlkKCkuc2hvdygpLHRoaXMuZWxlbWVudC5maW5kKFwiLnVpLW1lbnUtaXRlbVwiKS5yZW1vdmVDbGFzcyhcInVpLW1lbnUtaXRlbVwiKS5yZW1vdmVBdHRyKFwicm9sZVwiKS5yZW1vdmVBdHRyKFwiYXJpYS1kaXNhYmxlZFwiKS5yZW1vdmVVbmlxdWVJZCgpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtaG92ZXJcIikucmVtb3ZlQXR0cihcInRhYkluZGV4XCIpLnJlbW92ZUF0dHIoXCJyb2xlXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWhhc3BvcHVwXCIpLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcyk7dC5kYXRhKFwidWktbWVudS1zdWJtZW51LWNhcmF0XCIpJiZ0LnJlbW92ZSgpfSksdGhpcy5lbGVtZW50LmZpbmQoXCIudWktbWVudS1kaXZpZGVyXCIpLnJlbW92ZUNsYXNzKFwidWktbWVudS1kaXZpZGVyIHVpLXdpZGdldC1jb250ZW50XCIpfSxfa2V5ZG93bjpmdW5jdGlvbih0KXt2YXIgaSxzLG4sYSxvPSEwO3N3aXRjaCh0LmtleUNvZGUpe2Nhc2UgZS51aS5rZXlDb2RlLlBBR0VfVVA6dGhpcy5wcmV2aW91c1BhZ2UodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuUEFHRV9ET1dOOnRoaXMubmV4dFBhZ2UodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuSE9NRTp0aGlzLl9tb3ZlKFwiZmlyc3RcIixcImZpcnN0XCIsdCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuRU5EOnRoaXMuX21vdmUoXCJsYXN0XCIsXCJsYXN0XCIsdCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuVVA6dGhpcy5wcmV2aW91cyh0KTticmVhaztjYXNlIGUudWkua2V5Q29kZS5ET1dOOnRoaXMubmV4dCh0KTticmVhaztjYXNlIGUudWkua2V5Q29kZS5MRUZUOnRoaXMuY29sbGFwc2UodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuUklHSFQ6dGhpcy5hY3RpdmUmJiF0aGlzLmFjdGl2ZS5pcyhcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKSYmdGhpcy5leHBhbmQodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuRU5URVI6Y2FzZSBlLnVpLmtleUNvZGUuU1BBQ0U6dGhpcy5fYWN0aXZhdGUodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuRVNDQVBFOnRoaXMuY29sbGFwc2UodCk7YnJlYWs7ZGVmYXVsdDpvPSExLHM9dGhpcy5wcmV2aW91c0ZpbHRlcnx8XCJcIixuPVN0cmluZy5mcm9tQ2hhckNvZGUodC5rZXlDb2RlKSxhPSExLGNsZWFyVGltZW91dCh0aGlzLmZpbHRlclRpbWVyKSxuPT09cz9hPSEwOm49cytuLGk9dGhpcy5fZmlsdGVyTWVudUl0ZW1zKG4pLGk9YSYmLTEhPT1pLmluZGV4KHRoaXMuYWN0aXZlLm5leHQoKSk/dGhpcy5hY3RpdmUubmV4dEFsbChcIi51aS1tZW51LWl0ZW1cIik6aSxpLmxlbmd0aHx8KG49U3RyaW5nLmZyb21DaGFyQ29kZSh0LmtleUNvZGUpLGk9dGhpcy5fZmlsdGVyTWVudUl0ZW1zKG4pKSxpLmxlbmd0aD8odGhpcy5mb2N1cyh0LGkpLHRoaXMucHJldmlvdXNGaWx0ZXI9bix0aGlzLmZpbHRlclRpbWVyPXRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXMucHJldmlvdXNGaWx0ZXJ9LDFlMykpOmRlbGV0ZSB0aGlzLnByZXZpb3VzRmlsdGVyfW8mJnQucHJldmVudERlZmF1bHQoKX0sX2FjdGl2YXRlOmZ1bmN0aW9uKGUpe3RoaXMuYWN0aXZlLmlzKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpfHwodGhpcy5hY3RpdmUuaXMoXCJbYXJpYS1oYXNwb3B1cD0ndHJ1ZSddXCIpP3RoaXMuZXhwYW5kKGUpOnRoaXMuc2VsZWN0KGUpKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciB0LGkscz10aGlzLG49dGhpcy5vcHRpb25zLmljb25zLnN1Ym1lbnUsYT10aGlzLmVsZW1lbnQuZmluZCh0aGlzLm9wdGlvbnMubWVudXMpO3RoaXMuZWxlbWVudC50b2dnbGVDbGFzcyhcInVpLW1lbnUtaWNvbnNcIiwhIXRoaXMuZWxlbWVudC5maW5kKFwiLnVpLWljb25cIikubGVuZ3RoKSxhLmZpbHRlcihcIjpub3QoLnVpLW1lbnUpXCIpLmFkZENsYXNzKFwidWktbWVudSB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktZnJvbnRcIikuaGlkZSgpLmF0dHIoe3JvbGU6dGhpcy5vcHRpb25zLnJvbGUsXCJhcmlhLWhpZGRlblwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIn0pLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpLGk9dC5wYXJlbnQoKSxzPWUoXCI8c3Bhbj5cIikuYWRkQ2xhc3MoXCJ1aS1tZW51LWljb24gdWktaWNvbiBcIituKS5kYXRhKFwidWktbWVudS1zdWJtZW51LWNhcmF0XCIsITApO2kuYXR0cihcImFyaWEtaGFzcG9wdXBcIixcInRydWVcIikucHJlcGVuZChzKSx0LmF0dHIoXCJhcmlhLWxhYmVsbGVkYnlcIixpLmF0dHIoXCJpZFwiKSl9KSx0PWEuYWRkKHRoaXMuZWxlbWVudCksaT10LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKSxpLm5vdChcIi51aS1tZW51LWl0ZW1cIikuZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcyk7cy5faXNEaXZpZGVyKHQpJiZ0LmFkZENsYXNzKFwidWktd2lkZ2V0LWNvbnRlbnQgdWktbWVudS1kaXZpZGVyXCIpfSksaS5ub3QoXCIudWktbWVudS1pdGVtLCAudWktbWVudS1kaXZpZGVyXCIpLmFkZENsYXNzKFwidWktbWVudS1pdGVtXCIpLnVuaXF1ZUlkKCkuYXR0cih7dGFiSW5kZXg6LTEscm9sZTp0aGlzLl9pdGVtUm9sZSgpfSksaS5maWx0ZXIoXCIudWktc3RhdGUtZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcInRydWVcIiksdGhpcy5hY3RpdmUmJiFlLmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSx0aGlzLmFjdGl2ZVswXSkmJnRoaXMuYmx1cigpfSxfaXRlbVJvbGU6ZnVuY3Rpb24oKXtyZXR1cm57bWVudTpcIm1lbnVpdGVtXCIsbGlzdGJveDpcIm9wdGlvblwifVt0aGlzLm9wdGlvbnMucm9sZV19LF9zZXRPcHRpb246ZnVuY3Rpb24oZSx0KXtcImljb25zXCI9PT1lJiZ0aGlzLmVsZW1lbnQuZmluZChcIi51aS1tZW51LWljb25cIikucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmljb25zLnN1Ym1lbnUpLmFkZENsYXNzKHQuc3VibWVudSksXCJkaXNhYmxlZFwiPT09ZSYmdGhpcy5lbGVtZW50LnRvZ2dsZUNsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIXQpLmF0dHIoXCJhcmlhLWRpc2FibGVkXCIsdCksdGhpcy5fc3VwZXIoZSx0KX0sZm9jdXM6ZnVuY3Rpb24oZSx0KXt2YXIgaSxzO3RoaXMuYmx1cihlLGUmJlwiZm9jdXNcIj09PWUudHlwZSksdGhpcy5fc2Nyb2xsSW50b1ZpZXcodCksdGhpcy5hY3RpdmU9dC5maXJzdCgpLHM9dGhpcy5hY3RpdmUuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1mb2N1c1wiKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKSx0aGlzLm9wdGlvbnMucm9sZSYmdGhpcy5lbGVtZW50LmF0dHIoXCJhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcIixzLmF0dHIoXCJpZFwiKSksdGhpcy5hY3RpdmUucGFyZW50KCkuY2xvc2VzdChcIi51aS1tZW51LWl0ZW1cIikuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIiksZSYmXCJrZXlkb3duXCI9PT1lLnR5cGU/dGhpcy5fY2xvc2UoKTp0aGlzLnRpbWVyPXRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dGhpcy5fY2xvc2UoKX0sdGhpcy5kZWxheSksaT10LmNoaWxkcmVuKFwiLnVpLW1lbnVcIiksaS5sZW5ndGgmJmUmJi9ebW91c2UvLnRlc3QoZS50eXBlKSYmdGhpcy5fc3RhcnRPcGVuaW5nKGkpLHRoaXMuYWN0aXZlTWVudT10LnBhcmVudCgpLHRoaXMuX3RyaWdnZXIoXCJmb2N1c1wiLGUse2l0ZW06dH0pfSxfc2Nyb2xsSW50b1ZpZXc6ZnVuY3Rpb24odCl7dmFyIGkscyxuLGEsbyxyO3RoaXMuX2hhc1Njcm9sbCgpJiYoaT1wYXJzZUZsb2F0KGUuY3NzKHRoaXMuYWN0aXZlTWVudVswXSxcImJvcmRlclRvcFdpZHRoXCIpKXx8MCxzPXBhcnNlRmxvYXQoZS5jc3ModGhpcy5hY3RpdmVNZW51WzBdLFwicGFkZGluZ1RvcFwiKSl8fDAsbj10Lm9mZnNldCgpLnRvcC10aGlzLmFjdGl2ZU1lbnUub2Zmc2V0KCkudG9wLWktcyxhPXRoaXMuYWN0aXZlTWVudS5zY3JvbGxUb3AoKSxvPXRoaXMuYWN0aXZlTWVudS5oZWlnaHQoKSxyPXQub3V0ZXJIZWlnaHQoKSwwPm4/dGhpcy5hY3RpdmVNZW51LnNjcm9sbFRvcChhK24pOm4rcj5vJiZ0aGlzLmFjdGl2ZU1lbnUuc2Nyb2xsVG9wKGErbi1vK3IpKX0sYmx1cjpmdW5jdGlvbihlLHQpe3R8fGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLmFjdGl2ZSYmKHRoaXMuYWN0aXZlLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZm9jdXNcIiksdGhpcy5hY3RpdmU9bnVsbCx0aGlzLl90cmlnZ2VyKFwiYmx1clwiLGUse2l0ZW06dGhpcy5hY3RpdmV9KSl9LF9zdGFydE9wZW5pbmc6ZnVuY3Rpb24oZSl7Y2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLFwidHJ1ZVwiPT09ZS5hdHRyKFwiYXJpYS1oaWRkZW5cIikmJih0aGlzLnRpbWVyPXRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dGhpcy5fY2xvc2UoKSx0aGlzLl9vcGVuKGUpfSx0aGlzLmRlbGF5KSl9LF9vcGVuOmZ1bmN0aW9uKHQpe3ZhciBpPWUuZXh0ZW5kKHtvZjp0aGlzLmFjdGl2ZX0sdGhpcy5vcHRpb25zLnBvc2l0aW9uKTtjbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy5lbGVtZW50LmZpbmQoXCIudWktbWVudVwiKS5ub3QodC5wYXJlbnRzKFwiLnVpLW1lbnVcIikpLmhpZGUoKS5hdHRyKFwiYXJpYS1oaWRkZW5cIixcInRydWVcIiksdC5zaG93KCkucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuXCIpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsXCJ0cnVlXCIpLnBvc2l0aW9uKGkpfSxjb2xsYXBzZUFsbDpmdW5jdGlvbih0LGkpe2NsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPXRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dmFyIHM9aT90aGlzLmVsZW1lbnQ6ZSh0JiZ0LnRhcmdldCkuY2xvc2VzdCh0aGlzLmVsZW1lbnQuZmluZChcIi51aS1tZW51XCIpKTtzLmxlbmd0aHx8KHM9dGhpcy5lbGVtZW50KSx0aGlzLl9jbG9zZShzKSx0aGlzLmJsdXIodCksdGhpcy5hY3RpdmVNZW51PXN9LHRoaXMuZGVsYXkpfSxfY2xvc2U6ZnVuY3Rpb24oZSl7ZXx8KGU9dGhpcy5hY3RpdmU/dGhpcy5hY3RpdmUucGFyZW50KCk6dGhpcy5lbGVtZW50KSxlLmZpbmQoXCIudWktbWVudVwiKS5oaWRlKCkuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJ0cnVlXCIpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsXCJmYWxzZVwiKS5lbmQoKS5maW5kKFwiLnVpLXN0YXRlLWFjdGl2ZVwiKS5ub3QoXCIudWktc3RhdGUtZm9jdXNcIikucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIil9LF9jbG9zZU9uRG9jdW1lbnRDbGljazpmdW5jdGlvbih0KXtyZXR1cm4hZSh0LnRhcmdldCkuY2xvc2VzdChcIi51aS1tZW51XCIpLmxlbmd0aH0sX2lzRGl2aWRlcjpmdW5jdGlvbihlKXtyZXR1cm4hL1teXFwtXFx1MjAxNFxcdTIwMTNcXHNdLy50ZXN0KGUudGV4dCgpKX0sY29sbGFwc2U6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5hY3RpdmUmJnRoaXMuYWN0aXZlLnBhcmVudCgpLmNsb3Nlc3QoXCIudWktbWVudS1pdGVtXCIsdGhpcy5lbGVtZW50KTt0JiZ0Lmxlbmd0aCYmKHRoaXMuX2Nsb3NlKCksdGhpcy5mb2N1cyhlLHQpKX0sZXhwYW5kOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuYWN0aXZlJiZ0aGlzLmFjdGl2ZS5jaGlsZHJlbihcIi51aS1tZW51IFwiKS5maW5kKHRoaXMub3B0aW9ucy5pdGVtcykuZmlyc3QoKTt0JiZ0Lmxlbmd0aCYmKHRoaXMuX29wZW4odC5wYXJlbnQoKSksdGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLmZvY3VzKGUsdCl9KSl9LG5leHQ6ZnVuY3Rpb24oZSl7dGhpcy5fbW92ZShcIm5leHRcIixcImZpcnN0XCIsZSl9LHByZXZpb3VzOmZ1bmN0aW9uKGUpe3RoaXMuX21vdmUoXCJwcmV2XCIsXCJsYXN0XCIsZSl9LGlzRmlyc3RJdGVtOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYWN0aXZlJiYhdGhpcy5hY3RpdmUucHJldkFsbChcIi51aS1tZW51LWl0ZW1cIikubGVuZ3RofSxpc0xhc3RJdGVtOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYWN0aXZlJiYhdGhpcy5hY3RpdmUubmV4dEFsbChcIi51aS1tZW51LWl0ZW1cIikubGVuZ3RofSxfbW92ZTpmdW5jdGlvbihlLHQsaSl7dmFyIHM7dGhpcy5hY3RpdmUmJihzPVwiZmlyc3RcIj09PWV8fFwibGFzdFwiPT09ZT90aGlzLmFjdGl2ZVtcImZpcnN0XCI9PT1lP1wicHJldkFsbFwiOlwibmV4dEFsbFwiXShcIi51aS1tZW51LWl0ZW1cIikuZXEoLTEpOnRoaXMuYWN0aXZlW2UrXCJBbGxcIl0oXCIudWktbWVudS1pdGVtXCIpLmVxKDApKSxzJiZzLmxlbmd0aCYmdGhpcy5hY3RpdmV8fChzPXRoaXMuYWN0aXZlTWVudS5maW5kKHRoaXMub3B0aW9ucy5pdGVtcylbdF0oKSksdGhpcy5mb2N1cyhpLHMpfSxuZXh0UGFnZTpmdW5jdGlvbih0KXt2YXIgaSxzLG47cmV0dXJuIHRoaXMuYWN0aXZlPyh0aGlzLmlzTGFzdEl0ZW0oKXx8KHRoaXMuX2hhc1Njcm9sbCgpPyhzPXRoaXMuYWN0aXZlLm9mZnNldCgpLnRvcCxuPXRoaXMuZWxlbWVudC5oZWlnaHQoKSx0aGlzLmFjdGl2ZS5uZXh0QWxsKFwiLnVpLW1lbnUtaXRlbVwiKS5lYWNoKGZ1bmN0aW9uKCl7cmV0dXJuIGk9ZSh0aGlzKSwwPmkub2Zmc2V0KCkudG9wLXMtbn0pLHRoaXMuZm9jdXModCxpKSk6dGhpcy5mb2N1cyh0LHRoaXMuYWN0aXZlTWVudS5maW5kKHRoaXMub3B0aW9ucy5pdGVtcylbdGhpcy5hY3RpdmU/XCJsYXN0XCI6XCJmaXJzdFwiXSgpKSksdm9pZCAwKToodGhpcy5uZXh0KHQpLHZvaWQgMCl9LHByZXZpb3VzUGFnZTpmdW5jdGlvbih0KXt2YXIgaSxzLG47cmV0dXJuIHRoaXMuYWN0aXZlPyh0aGlzLmlzRmlyc3RJdGVtKCl8fCh0aGlzLl9oYXNTY3JvbGwoKT8ocz10aGlzLmFjdGl2ZS5vZmZzZXQoKS50b3Asbj10aGlzLmVsZW1lbnQuaGVpZ2h0KCksdGhpcy5hY3RpdmUucHJldkFsbChcIi51aS1tZW51LWl0ZW1cIikuZWFjaChmdW5jdGlvbigpe3JldHVybiBpPWUodGhpcyksaS5vZmZzZXQoKS50b3AtcytuPjB9KSx0aGlzLmZvY3VzKHQsaSkpOnRoaXMuZm9jdXModCx0aGlzLmFjdGl2ZU1lbnUuZmluZCh0aGlzLm9wdGlvbnMuaXRlbXMpLmZpcnN0KCkpKSx2b2lkIDApOih0aGlzLm5leHQodCksdm9pZCAwKX0sX2hhc1Njcm9sbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmVsZW1lbnQub3V0ZXJIZWlnaHQoKTx0aGlzLmVsZW1lbnQucHJvcChcInNjcm9sbEhlaWdodFwiKX0sc2VsZWN0OmZ1bmN0aW9uKHQpe3RoaXMuYWN0aXZlPXRoaXMuYWN0aXZlfHxlKHQudGFyZ2V0KS5jbG9zZXN0KFwiLnVpLW1lbnUtaXRlbVwiKTt2YXIgaT17aXRlbTp0aGlzLmFjdGl2ZX07dGhpcy5hY3RpdmUuaGFzKFwiLnVpLW1lbnVcIikubGVuZ3RofHx0aGlzLmNvbGxhcHNlQWxsKHQsITApLHRoaXMuX3RyaWdnZXIoXCJzZWxlY3RcIix0LGkpfSxfZmlsdGVyTWVudUl0ZW1zOmZ1bmN0aW9uKHQpe3ZhciBpPXQucmVwbGFjZSgvW1xcLVxcW1xcXXt9KCkqKz8uLFxcXFxcXF4kfCNcXHNdL2csXCJcXFxcJCZcIikscz1SZWdFeHAoXCJeXCIraSxcImlcIik7cmV0dXJuIHRoaXMuYWN0aXZlTWVudS5maW5kKHRoaXMub3B0aW9ucy5pdGVtcykuZmlsdGVyKFwiLnVpLW1lbnUtaXRlbVwiKS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4gcy50ZXN0KGUudHJpbShlKHRoaXMpLnRleHQoKSkpfSl9fSksZS53aWRnZXQoXCJ1aS5hdXRvY29tcGxldGVcIix7dmVyc2lvbjpcIjEuMTEuNFwiLGRlZmF1bHRFbGVtZW50OlwiPGlucHV0PlwiLG9wdGlvbnM6e2FwcGVuZFRvOm51bGwsYXV0b0ZvY3VzOiExLGRlbGF5OjMwMCxtaW5MZW5ndGg6MSxwb3NpdGlvbjp7bXk6XCJsZWZ0IHRvcFwiLGF0OlwibGVmdCBib3R0b21cIixjb2xsaXNpb246XCJub25lXCJ9LHNvdXJjZTpudWxsLGNoYW5nZTpudWxsLGNsb3NlOm51bGwsZm9jdXM6bnVsbCxvcGVuOm51bGwscmVzcG9uc2U6bnVsbCxzZWFyY2g6bnVsbCxzZWxlY3Q6bnVsbH0scmVxdWVzdEluZGV4OjAscGVuZGluZzowLF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgdCxpLHMsbj10aGlzLmVsZW1lbnRbMF0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxhPVwidGV4dGFyZWFcIj09PW4sbz1cImlucHV0XCI9PT1uO3RoaXMuaXNNdWx0aUxpbmU9YT8hMDpvPyExOnRoaXMuZWxlbWVudC5wcm9wKFwiaXNDb250ZW50RWRpdGFibGVcIiksdGhpcy52YWx1ZU1ldGhvZD10aGlzLmVsZW1lbnRbYXx8bz9cInZhbFwiOlwidGV4dFwiXSx0aGlzLmlzTmV3TWVudT0hMCx0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1hdXRvY29tcGxldGUtaW5wdXRcIikuYXR0cihcImF1dG9jb21wbGV0ZVwiLFwib2ZmXCIpLHRoaXMuX29uKHRoaXMuZWxlbWVudCx7a2V5ZG93bjpmdW5jdGlvbihuKXtpZih0aGlzLmVsZW1lbnQucHJvcChcInJlYWRPbmx5XCIpKXJldHVybiB0PSEwLHM9ITAsaT0hMCx2b2lkIDA7dD0hMSxzPSExLGk9ITE7dmFyIGE9ZS51aS5rZXlDb2RlO3N3aXRjaChuLmtleUNvZGUpe2Nhc2UgYS5QQUdFX1VQOnQ9ITAsdGhpcy5fbW92ZShcInByZXZpb3VzUGFnZVwiLG4pO2JyZWFrO2Nhc2UgYS5QQUdFX0RPV046dD0hMCx0aGlzLl9tb3ZlKFwibmV4dFBhZ2VcIixuKTticmVhaztjYXNlIGEuVVA6dD0hMCx0aGlzLl9rZXlFdmVudChcInByZXZpb3VzXCIsbik7YnJlYWs7Y2FzZSBhLkRPV046dD0hMCx0aGlzLl9rZXlFdmVudChcIm5leHRcIixuKTticmVhaztjYXNlIGEuRU5URVI6dGhpcy5tZW51LmFjdGl2ZSYmKHQ9ITAsbi5wcmV2ZW50RGVmYXVsdCgpLHRoaXMubWVudS5zZWxlY3QobikpO2JyZWFrO2Nhc2UgYS5UQUI6dGhpcy5tZW51LmFjdGl2ZSYmdGhpcy5tZW51LnNlbGVjdChuKTticmVhaztjYXNlIGEuRVNDQVBFOnRoaXMubWVudS5lbGVtZW50LmlzKFwiOnZpc2libGVcIikmJih0aGlzLmlzTXVsdGlMaW5lfHx0aGlzLl92YWx1ZSh0aGlzLnRlcm0pLHRoaXMuY2xvc2Uobiksbi5wcmV2ZW50RGVmYXVsdCgpKTticmVhaztkZWZhdWx0Omk9ITAsdGhpcy5fc2VhcmNoVGltZW91dChuKX19LGtleXByZXNzOmZ1bmN0aW9uKHMpe2lmKHQpcmV0dXJuIHQ9ITEsKCF0aGlzLmlzTXVsdGlMaW5lfHx0aGlzLm1lbnUuZWxlbWVudC5pcyhcIjp2aXNpYmxlXCIpKSYmcy5wcmV2ZW50RGVmYXVsdCgpLHZvaWQgMDtpZighaSl7dmFyIG49ZS51aS5rZXlDb2RlO3N3aXRjaChzLmtleUNvZGUpe2Nhc2Ugbi5QQUdFX1VQOnRoaXMuX21vdmUoXCJwcmV2aW91c1BhZ2VcIixzKTticmVhaztjYXNlIG4uUEFHRV9ET1dOOnRoaXMuX21vdmUoXCJuZXh0UGFnZVwiLHMpO2JyZWFrO2Nhc2Ugbi5VUDp0aGlzLl9rZXlFdmVudChcInByZXZpb3VzXCIscyk7YnJlYWs7Y2FzZSBuLkRPV046dGhpcy5fa2V5RXZlbnQoXCJuZXh0XCIscyl9fX0saW5wdXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIHM/KHM9ITEsZS5wcmV2ZW50RGVmYXVsdCgpLHZvaWQgMCk6KHRoaXMuX3NlYXJjaFRpbWVvdXQoZSksdm9pZCAwKX0sZm9jdXM6ZnVuY3Rpb24oKXt0aGlzLnNlbGVjdGVkSXRlbT1udWxsLHRoaXMucHJldmlvdXM9dGhpcy5fdmFsdWUoKX0sYmx1cjpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5jYW5jZWxCbHVyPyhkZWxldGUgdGhpcy5jYW5jZWxCbHVyLHZvaWQgMCk6KGNsZWFyVGltZW91dCh0aGlzLnNlYXJjaGluZyksdGhpcy5jbG9zZShlKSx0aGlzLl9jaGFuZ2UoZSksdm9pZCAwKX19KSx0aGlzLl9pbml0U291cmNlKCksdGhpcy5tZW51PWUoXCI8dWw+XCIpLmFkZENsYXNzKFwidWktYXV0b2NvbXBsZXRlIHVpLWZyb250XCIpLmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLm1lbnUoe3JvbGU6bnVsbH0pLmhpZGUoKS5tZW51KFwiaW5zdGFuY2VcIiksdGhpcy5fb24odGhpcy5tZW51LmVsZW1lbnQse21vdXNlZG93bjpmdW5jdGlvbih0KXt0LnByZXZlbnREZWZhdWx0KCksdGhpcy5jYW5jZWxCbHVyPSEwLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXMuY2FuY2VsQmx1cn0pO3ZhciBpPXRoaXMubWVudS5lbGVtZW50WzBdO2UodC50YXJnZXQpLmNsb3Nlc3QoXCIudWktbWVudS1pdGVtXCIpLmxlbmd0aHx8dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt2YXIgdD10aGlzO3RoaXMuZG9jdW1lbnQub25lKFwibW91c2Vkb3duXCIsZnVuY3Rpb24ocyl7cy50YXJnZXQ9PT10LmVsZW1lbnRbMF18fHMudGFyZ2V0PT09aXx8ZS5jb250YWlucyhpLHMudGFyZ2V0KXx8dC5jbG9zZSgpfSl9KX0sbWVudWZvY3VzOmZ1bmN0aW9uKHQsaSl7dmFyIHMsbjtyZXR1cm4gdGhpcy5pc05ld01lbnUmJih0aGlzLmlzTmV3TWVudT0hMSx0Lm9yaWdpbmFsRXZlbnQmJi9ebW91c2UvLnRlc3QodC5vcmlnaW5hbEV2ZW50LnR5cGUpKT8odGhpcy5tZW51LmJsdXIoKSx0aGlzLmRvY3VtZW50Lm9uZShcIm1vdXNlbW92ZVwiLGZ1bmN0aW9uKCl7ZSh0LnRhcmdldCkudHJpZ2dlcih0Lm9yaWdpbmFsRXZlbnQpfSksdm9pZCAwKToobj1pLml0ZW0uZGF0YShcInVpLWF1dG9jb21wbGV0ZS1pdGVtXCIpLCExIT09dGhpcy5fdHJpZ2dlcihcImZvY3VzXCIsdCx7aXRlbTpufSkmJnQub3JpZ2luYWxFdmVudCYmL15rZXkvLnRlc3QodC5vcmlnaW5hbEV2ZW50LnR5cGUpJiZ0aGlzLl92YWx1ZShuLnZhbHVlKSxzPWkuaXRlbS5hdHRyKFwiYXJpYS1sYWJlbFwiKXx8bi52YWx1ZSxzJiZlLnRyaW0ocykubGVuZ3RoJiYodGhpcy5saXZlUmVnaW9uLmNoaWxkcmVuKCkuaGlkZSgpLGUoXCI8ZGl2PlwiKS50ZXh0KHMpLmFwcGVuZFRvKHRoaXMubGl2ZVJlZ2lvbikpLHZvaWQgMCl9LG1lbnVzZWxlY3Q6ZnVuY3Rpb24oZSx0KXt2YXIgaT10Lml0ZW0uZGF0YShcInVpLWF1dG9jb21wbGV0ZS1pdGVtXCIpLHM9dGhpcy5wcmV2aW91czt0aGlzLmVsZW1lbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQmJih0aGlzLmVsZW1lbnQuZm9jdXMoKSx0aGlzLnByZXZpb3VzPXMsdGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLnByZXZpb3VzPXMsdGhpcy5zZWxlY3RlZEl0ZW09aX0pKSwhMSE9PXRoaXMuX3RyaWdnZXIoXCJzZWxlY3RcIixlLHtpdGVtOml9KSYmdGhpcy5fdmFsdWUoaS52YWx1ZSksdGhpcy50ZXJtPXRoaXMuX3ZhbHVlKCksdGhpcy5jbG9zZShlKSx0aGlzLnNlbGVjdGVkSXRlbT1pfX0pLHRoaXMubGl2ZVJlZ2lvbj1lKFwiPHNwYW4+XCIse3JvbGU6XCJzdGF0dXNcIixcImFyaWEtbGl2ZVwiOlwiYXNzZXJ0aXZlXCIsXCJhcmlhLXJlbGV2YW50XCI6XCJhZGRpdGlvbnNcIn0pLmFkZENsYXNzKFwidWktaGVscGVyLWhpZGRlbi1hY2Nlc3NpYmxlXCIpLmFwcGVuZFRvKHRoaXMuZG9jdW1lbnRbMF0uYm9keSksdGhpcy5fb24odGhpcy53aW5kb3cse2JlZm9yZXVubG9hZDpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5yZW1vdmVBdHRyKFwiYXV0b2NvbXBsZXRlXCIpfX0pfSxfZGVzdHJveTpmdW5jdGlvbigpe2NsZWFyVGltZW91dCh0aGlzLnNlYXJjaGluZyksdGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktYXV0b2NvbXBsZXRlLWlucHV0XCIpLnJlbW92ZUF0dHIoXCJhdXRvY29tcGxldGVcIiksdGhpcy5tZW51LmVsZW1lbnQucmVtb3ZlKCksdGhpcy5saXZlUmVnaW9uLnJlbW92ZSgpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsdCl7dGhpcy5fc3VwZXIoZSx0KSxcInNvdXJjZVwiPT09ZSYmdGhpcy5faW5pdFNvdXJjZSgpLFwiYXBwZW5kVG9cIj09PWUmJnRoaXMubWVudS5lbGVtZW50LmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLFwiZGlzYWJsZWRcIj09PWUmJnQmJnRoaXMueGhyJiZ0aGlzLnhoci5hYm9ydCgpfSxfYXBwZW5kVG86ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnMuYXBwZW5kVG87cmV0dXJuIHQmJih0PXQuanF1ZXJ5fHx0Lm5vZGVUeXBlP2UodCk6dGhpcy5kb2N1bWVudC5maW5kKHQpLmVxKDApKSx0JiZ0WzBdfHwodD10aGlzLmVsZW1lbnQuY2xvc2VzdChcIi51aS1mcm9udFwiKSksdC5sZW5ndGh8fCh0PXRoaXMuZG9jdW1lbnRbMF0uYm9keSksdH0sX2luaXRTb3VyY2U6ZnVuY3Rpb24oKXt2YXIgdCxpLHM9dGhpcztlLmlzQXJyYXkodGhpcy5vcHRpb25zLnNvdXJjZSk/KHQ9dGhpcy5vcHRpb25zLnNvdXJjZSx0aGlzLnNvdXJjZT1mdW5jdGlvbihpLHMpe3MoZS51aS5hdXRvY29tcGxldGUuZmlsdGVyKHQsaS50ZXJtKSl9KTpcInN0cmluZ1wiPT10eXBlb2YgdGhpcy5vcHRpb25zLnNvdXJjZT8oaT10aGlzLm9wdGlvbnMuc291cmNlLHRoaXMuc291cmNlPWZ1bmN0aW9uKHQsbil7cy54aHImJnMueGhyLmFib3J0KCkscy54aHI9ZS5hamF4KHt1cmw6aSxkYXRhOnQsZGF0YVR5cGU6XCJqc29uXCIsc3VjY2VzczpmdW5jdGlvbihlKXtuKGUpfSxlcnJvcjpmdW5jdGlvbigpe24oW10pfX0pfSk6dGhpcy5zb3VyY2U9dGhpcy5vcHRpb25zLnNvdXJjZX0sX3NlYXJjaFRpbWVvdXQ6ZnVuY3Rpb24oZSl7Y2xlYXJUaW1lb3V0KHRoaXMuc2VhcmNoaW5nKSx0aGlzLnNlYXJjaGluZz10aGlzLl9kZWxheShmdW5jdGlvbigpe3ZhciB0PXRoaXMudGVybT09PXRoaXMuX3ZhbHVlKCksaT10aGlzLm1lbnUuZWxlbWVudC5pcyhcIjp2aXNpYmxlXCIpLHM9ZS5hbHRLZXl8fGUuY3RybEtleXx8ZS5tZXRhS2V5fHxlLnNoaWZ0S2V5OyghdHx8dCYmIWkmJiFzKSYmKHRoaXMuc2VsZWN0ZWRJdGVtPW51bGwsdGhpcy5zZWFyY2gobnVsbCxlKSl9LHRoaXMub3B0aW9ucy5kZWxheSl9LHNlYXJjaDpmdW5jdGlvbihlLHQpe3JldHVybiBlPW51bGwhPWU/ZTp0aGlzLl92YWx1ZSgpLHRoaXMudGVybT10aGlzLl92YWx1ZSgpLGUubGVuZ3RoPHRoaXMub3B0aW9ucy5taW5MZW5ndGg/dGhpcy5jbG9zZSh0KTp0aGlzLl90cmlnZ2VyKFwic2VhcmNoXCIsdCkhPT0hMT90aGlzLl9zZWFyY2goZSk6dm9pZCAwfSxfc2VhcmNoOmZ1bmN0aW9uKGUpe3RoaXMucGVuZGluZysrLHRoaXMuZWxlbWVudC5hZGRDbGFzcyhcInVpLWF1dG9jb21wbGV0ZS1sb2FkaW5nXCIpLHRoaXMuY2FuY2VsU2VhcmNoPSExLHRoaXMuc291cmNlKHt0ZXJtOmV9LHRoaXMuX3Jlc3BvbnNlKCkpfSxfcmVzcG9uc2U6ZnVuY3Rpb24oKXt2YXIgdD0rK3RoaXMucmVxdWVzdEluZGV4O3JldHVybiBlLnByb3h5KGZ1bmN0aW9uKGUpe3Q9PT10aGlzLnJlcXVlc3RJbmRleCYmdGhpcy5fX3Jlc3BvbnNlKGUpLHRoaXMucGVuZGluZy0tLHRoaXMucGVuZGluZ3x8dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktYXV0b2NvbXBsZXRlLWxvYWRpbmdcIil9LHRoaXMpfSxfX3Jlc3BvbnNlOmZ1bmN0aW9uKGUpe2UmJihlPXRoaXMuX25vcm1hbGl6ZShlKSksdGhpcy5fdHJpZ2dlcihcInJlc3BvbnNlXCIsbnVsbCx7Y29udGVudDplfSksIXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmZSYmZS5sZW5ndGgmJiF0aGlzLmNhbmNlbFNlYXJjaD8odGhpcy5fc3VnZ2VzdChlKSx0aGlzLl90cmlnZ2VyKFwib3BlblwiKSk6dGhpcy5fY2xvc2UoKX0sY2xvc2U6ZnVuY3Rpb24oZSl7dGhpcy5jYW5jZWxTZWFyY2g9ITAsdGhpcy5fY2xvc2UoZSl9LF9jbG9zZTpmdW5jdGlvbihlKXt0aGlzLm1lbnUuZWxlbWVudC5pcyhcIjp2aXNpYmxlXCIpJiYodGhpcy5tZW51LmVsZW1lbnQuaGlkZSgpLHRoaXMubWVudS5ibHVyKCksdGhpcy5pc05ld01lbnU9ITAsdGhpcy5fdHJpZ2dlcihcImNsb3NlXCIsZSkpfSxfY2hhbmdlOmZ1bmN0aW9uKGUpe3RoaXMucHJldmlvdXMhPT10aGlzLl92YWx1ZSgpJiZ0aGlzLl90cmlnZ2VyKFwiY2hhbmdlXCIsZSx7aXRlbTp0aGlzLnNlbGVjdGVkSXRlbX0pfSxfbm9ybWFsaXplOmZ1bmN0aW9uKHQpe3JldHVybiB0Lmxlbmd0aCYmdFswXS5sYWJlbCYmdFswXS52YWx1ZT90OmUubWFwKHQsZnVuY3Rpb24odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHQ/e2xhYmVsOnQsdmFsdWU6dH06ZS5leHRlbmQoe30sdCx7bGFiZWw6dC5sYWJlbHx8dC52YWx1ZSx2YWx1ZTp0LnZhbHVlfHx0LmxhYmVsfSl9KX0sX3N1Z2dlc3Q6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5tZW51LmVsZW1lbnQuZW1wdHkoKTt0aGlzLl9yZW5kZXJNZW51KGksdCksdGhpcy5pc05ld01lbnU9ITAsdGhpcy5tZW51LnJlZnJlc2goKSxpLnNob3coKSx0aGlzLl9yZXNpemVNZW51KCksaS5wb3NpdGlvbihlLmV4dGVuZCh7b2Y6dGhpcy5lbGVtZW50fSx0aGlzLm9wdGlvbnMucG9zaXRpb24pKSx0aGlzLm9wdGlvbnMuYXV0b0ZvY3VzJiZ0aGlzLm1lbnUubmV4dCgpfSxfcmVzaXplTWVudTpmdW5jdGlvbigpe3ZhciBlPXRoaXMubWVudS5lbGVtZW50O2Uub3V0ZXJXaWR0aChNYXRoLm1heChlLndpZHRoKFwiXCIpLm91dGVyV2lkdGgoKSsxLHRoaXMuZWxlbWVudC5vdXRlcldpZHRoKCkpKX0sX3JlbmRlck1lbnU6ZnVuY3Rpb24odCxpKXt2YXIgcz10aGlzO2UuZWFjaChpLGZ1bmN0aW9uKGUsaSl7cy5fcmVuZGVySXRlbURhdGEodCxpKX0pfSxfcmVuZGVySXRlbURhdGE6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5fcmVuZGVySXRlbShlLHQpLmRhdGEoXCJ1aS1hdXRvY29tcGxldGUtaXRlbVwiLHQpfSxfcmVuZGVySXRlbTpmdW5jdGlvbih0LGkpe3JldHVybiBlKFwiPGxpPlwiKS50ZXh0KGkubGFiZWwpLmFwcGVuZFRvKHQpfSxfbW92ZTpmdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLm1lbnUuZWxlbWVudC5pcyhcIjp2aXNpYmxlXCIpP3RoaXMubWVudS5pc0ZpcnN0SXRlbSgpJiYvXnByZXZpb3VzLy50ZXN0KGUpfHx0aGlzLm1lbnUuaXNMYXN0SXRlbSgpJiYvXm5leHQvLnRlc3QoZSk/KHRoaXMuaXNNdWx0aUxpbmV8fHRoaXMuX3ZhbHVlKHRoaXMudGVybSksdGhpcy5tZW51LmJsdXIoKSx2b2lkIDApOih0aGlzLm1lbnVbZV0odCksdm9pZCAwKToodGhpcy5zZWFyY2gobnVsbCx0KSx2b2lkIDApfSx3aWRnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tZW51LmVsZW1lbnR9LF92YWx1ZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnZhbHVlTWV0aG9kLmFwcGx5KHRoaXMuZWxlbWVudCxhcmd1bWVudHMpfSxfa2V5RXZlbnQ6ZnVuY3Rpb24oZSx0KXsoIXRoaXMuaXNNdWx0aUxpbmV8fHRoaXMubWVudS5lbGVtZW50LmlzKFwiOnZpc2libGVcIikpJiYodGhpcy5fbW92ZShlLHQpLHQucHJldmVudERlZmF1bHQoKSl9fSksZS5leHRlbmQoZS51aS5hdXRvY29tcGxldGUse2VzY2FwZVJlZ2V4OmZ1bmN0aW9uKGUpe3JldHVybiBlLnJlcGxhY2UoL1tcXC1cXFtcXF17fSgpKis/LixcXFxcXFxeJHwjXFxzXS9nLFwiXFxcXCQmXCIpfSxmaWx0ZXI6ZnVuY3Rpb24odCxpKXt2YXIgcz1SZWdFeHAoZS51aS5hdXRvY29tcGxldGUuZXNjYXBlUmVnZXgoaSksXCJpXCIpO3JldHVybiBlLmdyZXAodCxmdW5jdGlvbihlKXtyZXR1cm4gcy50ZXN0KGUubGFiZWx8fGUudmFsdWV8fGUpfSl9fSksZS53aWRnZXQoXCJ1aS5hdXRvY29tcGxldGVcIixlLnVpLmF1dG9jb21wbGV0ZSx7b3B0aW9uczp7bWVzc2FnZXM6e25vUmVzdWx0czpcIk5vIHNlYXJjaCByZXN1bHRzLlwiLHJlc3VsdHM6ZnVuY3Rpb24oZSl7cmV0dXJuIGUrKGU+MT9cIiByZXN1bHRzIGFyZVwiOlwiIHJlc3VsdCBpc1wiKStcIiBhdmFpbGFibGUsIHVzZSB1cCBhbmQgZG93biBhcnJvdyBrZXlzIHRvIG5hdmlnYXRlLlwifX19LF9fcmVzcG9uc2U6ZnVuY3Rpb24odCl7dmFyIGk7dGhpcy5fc3VwZXJBcHBseShhcmd1bWVudHMpLHRoaXMub3B0aW9ucy5kaXNhYmxlZHx8dGhpcy5jYW5jZWxTZWFyY2h8fChpPXQmJnQubGVuZ3RoP3RoaXMub3B0aW9ucy5tZXNzYWdlcy5yZXN1bHRzKHQubGVuZ3RoKTp0aGlzLm9wdGlvbnMubWVzc2FnZXMubm9SZXN1bHRzLHRoaXMubGl2ZVJlZ2lvbi5jaGlsZHJlbigpLmhpZGUoKSxlKFwiPGRpdj5cIikudGV4dChpKS5hcHBlbmRUbyh0aGlzLmxpdmVSZWdpb24pKX19KSxlLnVpLmF1dG9jb21wbGV0ZTt2YXIgYyxwPVwidWktYnV0dG9uIHVpLXdpZGdldCB1aS1zdGF0ZS1kZWZhdWx0IHVpLWNvcm5lci1hbGxcIixmPVwidWktYnV0dG9uLWljb25zLW9ubHkgdWktYnV0dG9uLWljb24tb25seSB1aS1idXR0b24tdGV4dC1pY29ucyB1aS1idXR0b24tdGV4dC1pY29uLXByaW1hcnkgdWktYnV0dG9uLXRleHQtaWNvbi1zZWNvbmRhcnkgdWktYnV0dG9uLXRleHQtb25seVwiLG09ZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpO3NldFRpbWVvdXQoZnVuY3Rpb24oKXt0LmZpbmQoXCI6dWktYnV0dG9uXCIpLmJ1dHRvbihcInJlZnJlc2hcIil9LDEpfSxnPWZ1bmN0aW9uKHQpe3ZhciBpPXQubmFtZSxzPXQuZm9ybSxuPWUoW10pO3JldHVybiBpJiYoaT1pLnJlcGxhY2UoLycvZyxcIlxcXFwnXCIpLG49cz9lKHMpLmZpbmQoXCJbbmFtZT0nXCIraStcIiddW3R5cGU9cmFkaW9dXCIpOmUoXCJbbmFtZT0nXCIraStcIiddW3R5cGU9cmFkaW9dXCIsdC5vd25lckRvY3VtZW50KS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4hdGhpcy5mb3JtfSkpLG59O2Uud2lkZ2V0KFwidWkuYnV0dG9uXCIse3ZlcnNpb246XCIxLjExLjRcIixkZWZhdWx0RWxlbWVudDpcIjxidXR0b24+XCIsb3B0aW9uczp7ZGlzYWJsZWQ6bnVsbCx0ZXh0OiEwLGxhYmVsOm51bGwsaWNvbnM6e3ByaW1hcnk6bnVsbCxzZWNvbmRhcnk6bnVsbH19LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQuY2xvc2VzdChcImZvcm1cIikudW5iaW5kKFwicmVzZXRcIit0aGlzLmV2ZW50TmFtZXNwYWNlKS5iaW5kKFwicmVzZXRcIit0aGlzLmV2ZW50TmFtZXNwYWNlLG0pLFwiYm9vbGVhblwiIT10eXBlb2YgdGhpcy5vcHRpb25zLmRpc2FibGVkP3RoaXMub3B0aW9ucy5kaXNhYmxlZD0hIXRoaXMuZWxlbWVudC5wcm9wKFwiZGlzYWJsZWRcIik6dGhpcy5lbGVtZW50LnByb3AoXCJkaXNhYmxlZFwiLHRoaXMub3B0aW9ucy5kaXNhYmxlZCksdGhpcy5fZGV0ZXJtaW5lQnV0dG9uVHlwZSgpLHRoaXMuaGFzVGl0bGU9ISF0aGlzLmJ1dHRvbkVsZW1lbnQuYXR0cihcInRpdGxlXCIpO3ZhciB0PXRoaXMsaT10aGlzLm9wdGlvbnMscz1cImNoZWNrYm94XCI9PT10aGlzLnR5cGV8fFwicmFkaW9cIj09PXRoaXMudHlwZSxuPXM/XCJcIjpcInVpLXN0YXRlLWFjdGl2ZVwiO251bGw9PT1pLmxhYmVsJiYoaS5sYWJlbD1cImlucHV0XCI9PT10aGlzLnR5cGU/dGhpcy5idXR0b25FbGVtZW50LnZhbCgpOnRoaXMuYnV0dG9uRWxlbWVudC5odG1sKCkpLHRoaXMuX2hvdmVyYWJsZSh0aGlzLmJ1dHRvbkVsZW1lbnQpLHRoaXMuYnV0dG9uRWxlbWVudC5hZGRDbGFzcyhwKS5hdHRyKFwicm9sZVwiLFwiYnV0dG9uXCIpLmJpbmQoXCJtb3VzZWVudGVyXCIrdGhpcy5ldmVudE5hbWVzcGFjZSxmdW5jdGlvbigpe2kuZGlzYWJsZWR8fHRoaXM9PT1jJiZlKHRoaXMpLmFkZENsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpfSkuYmluZChcIm1vdXNlbGVhdmVcIit0aGlzLmV2ZW50TmFtZXNwYWNlLGZ1bmN0aW9uKCl7aS5kaXNhYmxlZHx8ZSh0aGlzKS5yZW1vdmVDbGFzcyhuKX0pLmJpbmQoXCJjbGlja1wiK3RoaXMuZXZlbnROYW1lc3BhY2UsZnVuY3Rpb24oZSl7aS5kaXNhYmxlZCYmKGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpKX0pLHRoaXMuX29uKHtmb2N1czpmdW5jdGlvbigpe3RoaXMuYnV0dG9uRWxlbWVudC5hZGRDbGFzcyhcInVpLXN0YXRlLWZvY3VzXCIpfSxibHVyOmZ1bmN0aW9uKCl7dGhpcy5idXR0b25FbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZm9jdXNcIil9fSkscyYmdGhpcy5lbGVtZW50LmJpbmQoXCJjaGFuZ2VcIit0aGlzLmV2ZW50TmFtZXNwYWNlLGZ1bmN0aW9uKCl7dC5yZWZyZXNoKCl9KSxcImNoZWNrYm94XCI9PT10aGlzLnR5cGU/dGhpcy5idXR0b25FbGVtZW50LmJpbmQoXCJjbGlja1wiK3RoaXMuZXZlbnROYW1lc3BhY2UsZnVuY3Rpb24oKXtyZXR1cm4gaS5kaXNhYmxlZD8hMTp2b2lkIDB9KTpcInJhZGlvXCI9PT10aGlzLnR5cGU/dGhpcy5idXR0b25FbGVtZW50LmJpbmQoXCJjbGlja1wiK3RoaXMuZXZlbnROYW1lc3BhY2UsZnVuY3Rpb24oKXtpZihpLmRpc2FibGVkKXJldHVybiExO2UodGhpcykuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIiksdC5idXR0b25FbGVtZW50LmF0dHIoXCJhcmlhLXByZXNzZWRcIixcInRydWVcIik7dmFyIHM9dC5lbGVtZW50WzBdO2cocykubm90KHMpLm1hcChmdW5jdGlvbigpe3JldHVybiBlKHRoaXMpLmJ1dHRvbihcIndpZGdldFwiKVswXX0pLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpLmF0dHIoXCJhcmlhLXByZXNzZWRcIixcImZhbHNlXCIpfSk6KHRoaXMuYnV0dG9uRWxlbWVudC5iaW5kKFwibW91c2Vkb3duXCIrdGhpcy5ldmVudE5hbWVzcGFjZSxmdW5jdGlvbigpe3JldHVybiBpLmRpc2FibGVkPyExOihlKHRoaXMpLmFkZENsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpLGM9dGhpcyx0LmRvY3VtZW50Lm9uZShcIm1vdXNldXBcIixmdW5jdGlvbigpe2M9bnVsbH0pLHZvaWQgMCl9KS5iaW5kKFwibW91c2V1cFwiK3RoaXMuZXZlbnROYW1lc3BhY2UsZnVuY3Rpb24oKXtyZXR1cm4gaS5kaXNhYmxlZD8hMTooZSh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKSx2b2lkIDApfSkuYmluZChcImtleWRvd25cIit0aGlzLmV2ZW50TmFtZXNwYWNlLGZ1bmN0aW9uKHQpe3JldHVybiBpLmRpc2FibGVkPyExOigodC5rZXlDb2RlPT09ZS51aS5rZXlDb2RlLlNQQUNFfHx0LmtleUNvZGU9PT1lLnVpLmtleUNvZGUuRU5URVIpJiZlKHRoaXMpLmFkZENsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpLHZvaWQgMCl9KS5iaW5kKFwia2V5dXBcIit0aGlzLmV2ZW50TmFtZXNwYWNlK1wiIGJsdXJcIit0aGlzLmV2ZW50TmFtZXNwYWNlLGZ1bmN0aW9uKCl7ZSh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKX0pLHRoaXMuYnV0dG9uRWxlbWVudC5pcyhcImFcIikmJnRoaXMuYnV0dG9uRWxlbWVudC5rZXl1cChmdW5jdGlvbih0KXt0LmtleUNvZGU9PT1lLnVpLmtleUNvZGUuU1BBQ0UmJmUodGhpcykuY2xpY2soKX0pKSx0aGlzLl9zZXRPcHRpb24oXCJkaXNhYmxlZFwiLGkuZGlzYWJsZWQpLHRoaXMuX3Jlc2V0QnV0dG9uKCl9LF9kZXRlcm1pbmVCdXR0b25UeXBlOmZ1bmN0aW9uKCl7dmFyIGUsdCxpO3RoaXMudHlwZT10aGlzLmVsZW1lbnQuaXMoXCJbdHlwZT1jaGVja2JveF1cIik/XCJjaGVja2JveFwiOnRoaXMuZWxlbWVudC5pcyhcIlt0eXBlPXJhZGlvXVwiKT9cInJhZGlvXCI6dGhpcy5lbGVtZW50LmlzKFwiaW5wdXRcIik/XCJpbnB1dFwiOlwiYnV0dG9uXCIsXCJjaGVja2JveFwiPT09dGhpcy50eXBlfHxcInJhZGlvXCI9PT10aGlzLnR5cGU/KGU9dGhpcy5lbGVtZW50LnBhcmVudHMoKS5sYXN0KCksdD1cImxhYmVsW2Zvcj0nXCIrdGhpcy5lbGVtZW50LmF0dHIoXCJpZFwiKStcIiddXCIsdGhpcy5idXR0b25FbGVtZW50PWUuZmluZCh0KSx0aGlzLmJ1dHRvbkVsZW1lbnQubGVuZ3RofHwoZT1lLmxlbmd0aD9lLnNpYmxpbmdzKCk6dGhpcy5lbGVtZW50LnNpYmxpbmdzKCksdGhpcy5idXR0b25FbGVtZW50PWUuZmlsdGVyKHQpLHRoaXMuYnV0dG9uRWxlbWVudC5sZW5ndGh8fCh0aGlzLmJ1dHRvbkVsZW1lbnQ9ZS5maW5kKHQpKSksdGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktaGVscGVyLWhpZGRlbi1hY2Nlc3NpYmxlXCIpLGk9dGhpcy5lbGVtZW50LmlzKFwiOmNoZWNrZWRcIiksaSYmdGhpcy5idXR0b25FbGVtZW50LmFkZENsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpLHRoaXMuYnV0dG9uRWxlbWVudC5wcm9wKFwiYXJpYS1wcmVzc2VkXCIsaSkpOnRoaXMuYnV0dG9uRWxlbWVudD10aGlzLmVsZW1lbnR9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ1dHRvbkVsZW1lbnR9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktaGVscGVyLWhpZGRlbi1hY2Nlc3NpYmxlXCIpLHRoaXMuYnV0dG9uRWxlbWVudC5yZW1vdmVDbGFzcyhwK1wiIHVpLXN0YXRlLWFjdGl2ZSBcIitmKS5yZW1vdmVBdHRyKFwicm9sZVwiKS5yZW1vdmVBdHRyKFwiYXJpYS1wcmVzc2VkXCIpLmh0bWwodGhpcy5idXR0b25FbGVtZW50LmZpbmQoXCIudWktYnV0dG9uLXRleHRcIikuaHRtbCgpKSx0aGlzLmhhc1RpdGxlfHx0aGlzLmJ1dHRvbkVsZW1lbnQucmVtb3ZlQXR0cihcInRpdGxlXCIpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMuX3N1cGVyKGUsdCksXCJkaXNhYmxlZFwiPT09ZT8odGhpcy53aWRnZXQoKS50b2dnbGVDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIsISF0KSx0aGlzLmVsZW1lbnQucHJvcChcImRpc2FibGVkXCIsISF0KSx0JiYoXCJjaGVja2JveFwiPT09dGhpcy50eXBlfHxcInJhZGlvXCI9PT10aGlzLnR5cGU/dGhpcy5idXR0b25FbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZm9jdXNcIik6dGhpcy5idXR0b25FbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZm9jdXMgdWktc3RhdGUtYWN0aXZlXCIpKSx2b2lkIDApOih0aGlzLl9yZXNldEJ1dHRvbigpLHZvaWQgMCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmVsZW1lbnQuaXMoXCJpbnB1dCwgYnV0dG9uXCIpP3RoaXMuZWxlbWVudC5pcyhcIjpkaXNhYmxlZFwiKTp0aGlzLmVsZW1lbnQuaGFzQ2xhc3MoXCJ1aS1idXR0b24tZGlzYWJsZWRcIik7dCE9PXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmdGhpcy5fc2V0T3B0aW9uKFwiZGlzYWJsZWRcIix0KSxcInJhZGlvXCI9PT10aGlzLnR5cGU/Zyh0aGlzLmVsZW1lbnRbMF0pLmVhY2goZnVuY3Rpb24oKXtlKHRoaXMpLmlzKFwiOmNoZWNrZWRcIik/ZSh0aGlzKS5idXR0b24oXCJ3aWRnZXRcIikuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIikuYXR0cihcImFyaWEtcHJlc3NlZFwiLFwidHJ1ZVwiKTplKHRoaXMpLmJ1dHRvbihcIndpZGdldFwiKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKS5hdHRyKFwiYXJpYS1wcmVzc2VkXCIsXCJmYWxzZVwiKX0pOlwiY2hlY2tib3hcIj09PXRoaXMudHlwZSYmKHRoaXMuZWxlbWVudC5pcyhcIjpjaGVja2VkXCIpP3RoaXMuYnV0dG9uRWxlbWVudC5hZGRDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKS5hdHRyKFwiYXJpYS1wcmVzc2VkXCIsXCJ0cnVlXCIpOnRoaXMuYnV0dG9uRWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKS5hdHRyKFwiYXJpYS1wcmVzc2VkXCIsXCJmYWxzZVwiKSl9LF9yZXNldEJ1dHRvbjpmdW5jdGlvbigpe2lmKFwiaW5wdXRcIj09PXRoaXMudHlwZSlyZXR1cm4gdGhpcy5vcHRpb25zLmxhYmVsJiZ0aGlzLmVsZW1lbnQudmFsKHRoaXMub3B0aW9ucy5sYWJlbCksdm9pZCAwO3ZhciB0PXRoaXMuYnV0dG9uRWxlbWVudC5yZW1vdmVDbGFzcyhmKSxpPWUoXCI8c3Bhbj48L3NwYW4+XCIsdGhpcy5kb2N1bWVudFswXSkuYWRkQ2xhc3MoXCJ1aS1idXR0b24tdGV4dFwiKS5odG1sKHRoaXMub3B0aW9ucy5sYWJlbCkuYXBwZW5kVG8odC5lbXB0eSgpKS50ZXh0KCkscz10aGlzLm9wdGlvbnMuaWNvbnMsbj1zLnByaW1hcnkmJnMuc2Vjb25kYXJ5LGE9W107cy5wcmltYXJ5fHxzLnNlY29uZGFyeT8odGhpcy5vcHRpb25zLnRleHQmJmEucHVzaChcInVpLWJ1dHRvbi10ZXh0LWljb25cIisobj9cInNcIjpzLnByaW1hcnk/XCItcHJpbWFyeVwiOlwiLXNlY29uZGFyeVwiKSkscy5wcmltYXJ5JiZ0LnByZXBlbmQoXCI8c3BhbiBjbGFzcz0ndWktYnV0dG9uLWljb24tcHJpbWFyeSB1aS1pY29uIFwiK3MucHJpbWFyeStcIic+PC9zcGFuPlwiKSxzLnNlY29uZGFyeSYmdC5hcHBlbmQoXCI8c3BhbiBjbGFzcz0ndWktYnV0dG9uLWljb24tc2Vjb25kYXJ5IHVpLWljb24gXCIrcy5zZWNvbmRhcnkrXCInPjwvc3Bhbj5cIiksdGhpcy5vcHRpb25zLnRleHR8fChhLnB1c2gobj9cInVpLWJ1dHRvbi1pY29ucy1vbmx5XCI6XCJ1aS1idXR0b24taWNvbi1vbmx5XCIpLHRoaXMuaGFzVGl0bGV8fHQuYXR0cihcInRpdGxlXCIsZS50cmltKGkpKSkpOmEucHVzaChcInVpLWJ1dHRvbi10ZXh0LW9ubHlcIiksdC5hZGRDbGFzcyhhLmpvaW4oXCIgXCIpKX19KSxlLndpZGdldChcInVpLmJ1dHRvbnNldFwiLHt2ZXJzaW9uOlwiMS4xMS40XCIsb3B0aW9uczp7aXRlbXM6XCJidXR0b24sIGlucHV0W3R5cGU9YnV0dG9uXSwgaW5wdXRbdHlwZT1zdWJtaXRdLCBpbnB1dFt0eXBlPXJlc2V0XSwgaW5wdXRbdHlwZT1jaGVja2JveF0sIGlucHV0W3R5cGU9cmFkaW9dLCBhLCA6ZGF0YSh1aS1idXR0b24pXCJ9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1idXR0b25zZXRcIil9LF9pbml0OmZ1bmN0aW9uKCl7dGhpcy5yZWZyZXNoKCl9LF9zZXRPcHRpb246ZnVuY3Rpb24oZSx0KXtcImRpc2FibGVkXCI9PT1lJiZ0aGlzLmJ1dHRvbnMuYnV0dG9uKFwib3B0aW9uXCIsZSx0KSx0aGlzLl9zdXBlcihlLHQpfSxyZWZyZXNoOmZ1bmN0aW9uKCl7dmFyIHQ9XCJydGxcIj09PXRoaXMuZWxlbWVudC5jc3MoXCJkaXJlY3Rpb25cIiksaT10aGlzLmVsZW1lbnQuZmluZCh0aGlzLm9wdGlvbnMuaXRlbXMpLHM9aS5maWx0ZXIoXCI6dWktYnV0dG9uXCIpO2kubm90KFwiOnVpLWJ1dHRvblwiKS5idXR0b24oKSxzLmJ1dHRvbihcInJlZnJlc2hcIiksdGhpcy5idXR0b25zPWkubWFwKGZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcykuYnV0dG9uKFwid2lkZ2V0XCIpWzBdfSkucmVtb3ZlQ2xhc3MoXCJ1aS1jb3JuZXItYWxsIHVpLWNvcm5lci1sZWZ0IHVpLWNvcm5lci1yaWdodFwiKS5maWx0ZXIoXCI6Zmlyc3RcIikuYWRkQ2xhc3ModD9cInVpLWNvcm5lci1yaWdodFwiOlwidWktY29ybmVyLWxlZnRcIikuZW5kKCkuZmlsdGVyKFwiOmxhc3RcIikuYWRkQ2xhc3ModD9cInVpLWNvcm5lci1sZWZ0XCI6XCJ1aS1jb3JuZXItcmlnaHRcIikuZW5kKCkuZW5kKCl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktYnV0dG9uc2V0XCIpLHRoaXMuYnV0dG9ucy5tYXAoZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzKS5idXR0b24oXCJ3aWRnZXRcIilbMF19KS5yZW1vdmVDbGFzcyhcInVpLWNvcm5lci1sZWZ0IHVpLWNvcm5lci1yaWdodFwiKS5lbmQoKS5idXR0b24oXCJkZXN0cm95XCIpfX0pLGUudWkuYnV0dG9uLGUuZXh0ZW5kKGUudWkse2RhdGVwaWNrZXI6e3ZlcnNpb246XCIxLjExLjRcIn19KTt2YXIgdjtlLmV4dGVuZChuLnByb3RvdHlwZSx7bWFya2VyQ2xhc3NOYW1lOlwiaGFzRGF0ZXBpY2tlclwiLG1heFJvd3M6NCxfd2lkZ2V0RGF0ZXBpY2tlcjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmRwRGl2fSxzZXREZWZhdWx0czpmdW5jdGlvbihlKXtyZXR1cm4gcih0aGlzLl9kZWZhdWx0cyxlfHx7fSksdGhpc30sX2F0dGFjaERhdGVwaWNrZXI6ZnVuY3Rpb24odCxpKXt2YXIgcyxuLGE7cz10Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksbj1cImRpdlwiPT09c3x8XCJzcGFuXCI9PT1zLHQuaWR8fCh0aGlzLnV1aWQrPTEsdC5pZD1cImRwXCIrdGhpcy51dWlkKSxhPXRoaXMuX25ld0luc3QoZSh0KSxuKSxhLnNldHRpbmdzPWUuZXh0ZW5kKHt9LGl8fHt9KSxcImlucHV0XCI9PT1zP3RoaXMuX2Nvbm5lY3REYXRlcGlja2VyKHQsYSk6biYmdGhpcy5faW5saW5lRGF0ZXBpY2tlcih0LGEpfSxfbmV3SW5zdDpmdW5jdGlvbih0LGkpe3ZhciBzPXRbMF0uaWQucmVwbGFjZSgvKFteQS1aYS16MC05X1xcLV0pL2csXCJcXFxcXFxcXCQxXCIpO3JldHVybntpZDpzLGlucHV0OnQsc2VsZWN0ZWREYXk6MCxzZWxlY3RlZE1vbnRoOjAsc2VsZWN0ZWRZZWFyOjAsZHJhd01vbnRoOjAsZHJhd1llYXI6MCxpbmxpbmU6aSxkcERpdjppP2EoZShcIjxkaXYgY2xhc3M9J1wiK3RoaXMuX2lubGluZUNsYXNzK1wiIHVpLWRhdGVwaWNrZXIgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWhlbHBlci1jbGVhcmZpeCB1aS1jb3JuZXItYWxsJz48L2Rpdj5cIikpOnRoaXMuZHBEaXZ9fSxfY29ubmVjdERhdGVwaWNrZXI6ZnVuY3Rpb24odCxpKXt2YXIgcz1lKHQpO2kuYXBwZW5kPWUoW10pLGkudHJpZ2dlcj1lKFtdKSxzLmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKXx8KHRoaXMuX2F0dGFjaG1lbnRzKHMsaSkscy5hZGRDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkua2V5ZG93bih0aGlzLl9kb0tleURvd24pLmtleXByZXNzKHRoaXMuX2RvS2V5UHJlc3MpLmtleXVwKHRoaXMuX2RvS2V5VXApLHRoaXMuX2F1dG9TaXplKGkpLGUuZGF0YSh0LFwiZGF0ZXBpY2tlclwiLGkpLGkuc2V0dGluZ3MuZGlzYWJsZWQmJnRoaXMuX2Rpc2FibGVEYXRlcGlja2VyKHQpKX0sX2F0dGFjaG1lbnRzOmZ1bmN0aW9uKHQsaSl7dmFyIHMsbixhLG89dGhpcy5fZ2V0KGksXCJhcHBlbmRUZXh0XCIpLHI9dGhpcy5fZ2V0KGksXCJpc1JUTFwiKTtpLmFwcGVuZCYmaS5hcHBlbmQucmVtb3ZlKCksbyYmKGkuYXBwZW5kPWUoXCI8c3BhbiBjbGFzcz0nXCIrdGhpcy5fYXBwZW5kQ2xhc3MrXCInPlwiK28rXCI8L3NwYW4+XCIpLHRbcj9cImJlZm9yZVwiOlwiYWZ0ZXJcIl0oaS5hcHBlbmQpKSx0LnVuYmluZChcImZvY3VzXCIsdGhpcy5fc2hvd0RhdGVwaWNrZXIpLGkudHJpZ2dlciYmaS50cmlnZ2VyLnJlbW92ZSgpLHM9dGhpcy5fZ2V0KGksXCJzaG93T25cIiksKFwiZm9jdXNcIj09PXN8fFwiYm90aFwiPT09cykmJnQuZm9jdXModGhpcy5fc2hvd0RhdGVwaWNrZXIpLChcImJ1dHRvblwiPT09c3x8XCJib3RoXCI9PT1zKSYmKG49dGhpcy5fZ2V0KGksXCJidXR0b25UZXh0XCIpLGE9dGhpcy5fZ2V0KGksXCJidXR0b25JbWFnZVwiKSxpLnRyaWdnZXI9ZSh0aGlzLl9nZXQoaSxcImJ1dHRvbkltYWdlT25seVwiKT9lKFwiPGltZy8+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuYXR0cih7c3JjOmEsYWx0Om4sdGl0bGU6bn0pOmUoXCI8YnV0dG9uIHR5cGU9J2J1dHRvbic+PC9idXR0b24+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuaHRtbChhP2UoXCI8aW1nLz5cIikuYXR0cih7c3JjOmEsYWx0Om4sdGl0bGU6bn0pOm4pKSx0W3I/XCJiZWZvcmVcIjpcImFmdGVyXCJdKGkudHJpZ2dlciksaS50cmlnZ2VyLmNsaWNrKGZ1bmN0aW9uKCl7cmV0dXJuIGUuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcmJmUuZGF0ZXBpY2tlci5fbGFzdElucHV0PT09dFswXT9lLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk6ZS5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyYmZS5kYXRlcGlja2VyLl9sYXN0SW5wdXQhPT10WzBdPyhlLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCksZS5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcih0WzBdKSk6ZS5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcih0WzBdKSwhMX0pKX0sX2F1dG9TaXplOmZ1bmN0aW9uKGUpe2lmKHRoaXMuX2dldChlLFwiYXV0b1NpemVcIikmJiFlLmlubGluZSl7dmFyIHQsaSxzLG4sYT1uZXcgRGF0ZSgyMDA5LDExLDIwKSxvPXRoaXMuX2dldChlLFwiZGF0ZUZvcm1hdFwiKTtvLm1hdGNoKC9bRE1dLykmJih0PWZ1bmN0aW9uKGUpe2ZvcihpPTAscz0wLG49MDtlLmxlbmd0aD5uO24rKyllW25dLmxlbmd0aD5pJiYoaT1lW25dLmxlbmd0aCxzPW4pO3JldHVybiBzfSxhLnNldE1vbnRoKHQodGhpcy5fZ2V0KGUsby5tYXRjaCgvTU0vKT9cIm1vbnRoTmFtZXNcIjpcIm1vbnRoTmFtZXNTaG9ydFwiKSkpLGEuc2V0RGF0ZSh0KHRoaXMuX2dldChlLG8ubWF0Y2goL0RELyk/XCJkYXlOYW1lc1wiOlwiZGF5TmFtZXNTaG9ydFwiKSkrMjAtYS5nZXREYXkoKSkpLGUuaW5wdXQuYXR0cihcInNpemVcIix0aGlzLl9mb3JtYXREYXRlKGUsYSkubGVuZ3RoKX19LF9pbmxpbmVEYXRlcGlja2VyOmZ1bmN0aW9uKHQsaSl7dmFyIHM9ZSh0KTtzLmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKXx8KHMuYWRkQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmFwcGVuZChpLmRwRGl2KSxlLmRhdGEodCxcImRhdGVwaWNrZXJcIixpKSx0aGlzLl9zZXREYXRlKGksdGhpcy5fZ2V0RGVmYXVsdERhdGUoaSksITApLHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaSksdGhpcy5fdXBkYXRlQWx0ZXJuYXRlKGkpLGkuc2V0dGluZ3MuZGlzYWJsZWQmJnRoaXMuX2Rpc2FibGVEYXRlcGlja2VyKHQpLGkuZHBEaXYuY3NzKFwiZGlzcGxheVwiLFwiYmxvY2tcIikpfSxfZGlhbG9nRGF0ZXBpY2tlcjpmdW5jdGlvbih0LGkscyxuLGEpe3ZhciBvLGgsbCx1LGQsYz10aGlzLl9kaWFsb2dJbnN0O3JldHVybiBjfHwodGhpcy51dWlkKz0xLG89XCJkcFwiK3RoaXMudXVpZCx0aGlzLl9kaWFsb2dJbnB1dD1lKFwiPGlucHV0IHR5cGU9J3RleHQnIGlkPSdcIitvK1wiJyBzdHlsZT0ncG9zaXRpb246IGFic29sdXRlOyB0b3A6IC0xMDBweDsgd2lkdGg6IDBweDsnLz5cIiksdGhpcy5fZGlhbG9nSW5wdXQua2V5ZG93bih0aGlzLl9kb0tleURvd24pLGUoXCJib2R5XCIpLmFwcGVuZCh0aGlzLl9kaWFsb2dJbnB1dCksYz10aGlzLl9kaWFsb2dJbnN0PXRoaXMuX25ld0luc3QodGhpcy5fZGlhbG9nSW5wdXQsITEpLGMuc2V0dGluZ3M9e30sZS5kYXRhKHRoaXMuX2RpYWxvZ0lucHV0WzBdLFwiZGF0ZXBpY2tlclwiLGMpKSxyKGMuc2V0dGluZ3Msbnx8e30pLGk9aSYmaS5jb25zdHJ1Y3Rvcj09PURhdGU/dGhpcy5fZm9ybWF0RGF0ZShjLGkpOmksdGhpcy5fZGlhbG9nSW5wdXQudmFsKGkpLHRoaXMuX3Bvcz1hP2EubGVuZ3RoP2E6W2EucGFnZVgsYS5wYWdlWV06bnVsbCx0aGlzLl9wb3N8fChoPWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCxsPWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQsdT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdHx8ZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0LGQ9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcHx8ZG9jdW1lbnQuYm9keS5zY3JvbGxUb3AsdGhpcy5fcG9zPVtoLzItMTAwK3UsbC8yLTE1MCtkXSksdGhpcy5fZGlhbG9nSW5wdXQuY3NzKFwibGVmdFwiLHRoaXMuX3Bvc1swXSsyMCtcInB4XCIpLmNzcyhcInRvcFwiLHRoaXMuX3Bvc1sxXStcInB4XCIpLGMuc2V0dGluZ3Mub25TZWxlY3Q9cyx0aGlzLl9pbkRpYWxvZz0hMCx0aGlzLmRwRGl2LmFkZENsYXNzKHRoaXMuX2RpYWxvZ0NsYXNzKSx0aGlzLl9zaG93RGF0ZXBpY2tlcih0aGlzLl9kaWFsb2dJbnB1dFswXSksZS5ibG9ja1VJJiZlLmJsb2NrVUkodGhpcy5kcERpdiksZS5kYXRhKHRoaXMuX2RpYWxvZ0lucHV0WzBdLFwiZGF0ZXBpY2tlclwiLGMpLHRoaXN9LF9kZXN0cm95RGF0ZXBpY2tlcjpmdW5jdGlvbih0KXt2YXIgaSxzPWUodCksbj1lLmRhdGEodCxcImRhdGVwaWNrZXJcIik7cy5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkmJihpPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxlLnJlbW92ZURhdGEodCxcImRhdGVwaWNrZXJcIiksXCJpbnB1dFwiPT09aT8obi5hcHBlbmQucmVtb3ZlKCksbi50cmlnZ2VyLnJlbW92ZSgpLHMucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLnVuYmluZChcImZvY3VzXCIsdGhpcy5fc2hvd0RhdGVwaWNrZXIpLnVuYmluZChcImtleWRvd25cIix0aGlzLl9kb0tleURvd24pLnVuYmluZChcImtleXByZXNzXCIsdGhpcy5fZG9LZXlQcmVzcykudW5iaW5kKFwia2V5dXBcIix0aGlzLl9kb0tleVVwKSk6KFwiZGl2XCI9PT1pfHxcInNwYW5cIj09PWkpJiZzLnJlbW92ZUNsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5lbXB0eSgpLHY9PT1uJiYodj1udWxsKSl9LF9lbmFibGVEYXRlcGlja2VyOmZ1bmN0aW9uKHQpe3ZhciBpLHMsbj1lKHQpLGE9ZS5kYXRhKHQsXCJkYXRlcGlja2VyXCIpO24uaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpJiYoaT10Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksXCJpbnB1dFwiPT09aT8odC5kaXNhYmxlZD0hMSxhLnRyaWdnZXIuZmlsdGVyKFwiYnV0dG9uXCIpLmVhY2goZnVuY3Rpb24oKXt0aGlzLmRpc2FibGVkPSExfSkuZW5kKCkuZmlsdGVyKFwiaW1nXCIpLmNzcyh7b3BhY2l0eTpcIjEuMFwiLGN1cnNvcjpcIlwifSkpOihcImRpdlwiPT09aXx8XCJzcGFuXCI9PT1pKSYmKHM9bi5jaGlsZHJlbihcIi5cIit0aGlzLl9pbmxpbmVDbGFzcykscy5jaGlsZHJlbigpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIikscy5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXItbW9udGgsIHNlbGVjdC51aS1kYXRlcGlja2VyLXllYXJcIikucHJvcChcImRpc2FibGVkXCIsITEpKSx0aGlzLl9kaXNhYmxlZElucHV0cz1lLm1hcCh0aGlzLl9kaXNhYmxlZElucHV0cyxmdW5jdGlvbihlKXtyZXR1cm4gZT09PXQ/bnVsbDplfSkpfSxfZGlzYWJsZURhdGVwaWNrZXI6ZnVuY3Rpb24odCl7dmFyIGkscyxuPWUodCksYT1lLmRhdGEodCxcImRhdGVwaWNrZXJcIik7bi5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkmJihpPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcImlucHV0XCI9PT1pPyh0LmRpc2FibGVkPSEwLGEudHJpZ2dlci5maWx0ZXIoXCJidXR0b25cIikuZWFjaChmdW5jdGlvbigpe3RoaXMuZGlzYWJsZWQ9ITB9KS5lbmQoKS5maWx0ZXIoXCJpbWdcIikuY3NzKHtvcGFjaXR5OlwiMC41XCIsY3Vyc29yOlwiZGVmYXVsdFwifSkpOihcImRpdlwiPT09aXx8XCJzcGFuXCI9PT1pKSYmKHM9bi5jaGlsZHJlbihcIi5cIit0aGlzLl9pbmxpbmVDbGFzcykscy5jaGlsZHJlbigpLmFkZENsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIikscy5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXItbW9udGgsIHNlbGVjdC51aS1kYXRlcGlja2VyLXllYXJcIikucHJvcChcImRpc2FibGVkXCIsITApKSx0aGlzLl9kaXNhYmxlZElucHV0cz1lLm1hcCh0aGlzLl9kaXNhYmxlZElucHV0cyxmdW5jdGlvbihlKXtyZXR1cm4gZT09PXQ/bnVsbDplfSksdGhpcy5fZGlzYWJsZWRJbnB1dHNbdGhpcy5fZGlzYWJsZWRJbnB1dHMubGVuZ3RoXT10KX0sX2lzRGlzYWJsZWREYXRlcGlja2VyOmZ1bmN0aW9uKGUpe2lmKCFlKXJldHVybiExO2Zvcih2YXIgdD0wO3RoaXMuX2Rpc2FibGVkSW5wdXRzLmxlbmd0aD50O3QrKylpZih0aGlzLl9kaXNhYmxlZElucHV0c1t0XT09PWUpcmV0dXJuITA7cmV0dXJuITF9LF9nZXRJbnN0OmZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gZS5kYXRhKHQsXCJkYXRlcGlja2VyXCIpfWNhdGNoKGkpe3Rocm93XCJNaXNzaW5nIGluc3RhbmNlIGRhdGEgZm9yIHRoaXMgZGF0ZXBpY2tlclwifX0sX29wdGlvbkRhdGVwaWNrZXI6ZnVuY3Rpb24odCxpLHMpe3ZhciBuLGEsbyxoLGw9dGhpcy5fZ2V0SW5zdCh0KTtyZXR1cm4gMj09PWFyZ3VtZW50cy5sZW5ndGgmJlwic3RyaW5nXCI9PXR5cGVvZiBpP1wiZGVmYXVsdHNcIj09PWk/ZS5leHRlbmQoe30sZS5kYXRlcGlja2VyLl9kZWZhdWx0cyk6bD9cImFsbFwiPT09aT9lLmV4dGVuZCh7fSxsLnNldHRpbmdzKTp0aGlzLl9nZXQobCxpKTpudWxsOihuPWl8fHt9LFwic3RyaW5nXCI9PXR5cGVvZiBpJiYobj17fSxuW2ldPXMpLGwmJih0aGlzLl9jdXJJbnN0PT09bCYmdGhpcy5faGlkZURhdGVwaWNrZXIoKSxhPXRoaXMuX2dldERhdGVEYXRlcGlja2VyKHQsITApLG89dGhpcy5fZ2V0TWluTWF4RGF0ZShsLFwibWluXCIpLGg9dGhpcy5fZ2V0TWluTWF4RGF0ZShsLFwibWF4XCIpLHIobC5zZXR0aW5ncyxuKSxudWxsIT09byYmdm9pZCAwIT09bi5kYXRlRm9ybWF0JiZ2b2lkIDA9PT1uLm1pbkRhdGUmJihsLnNldHRpbmdzLm1pbkRhdGU9dGhpcy5fZm9ybWF0RGF0ZShsLG8pKSxudWxsIT09aCYmdm9pZCAwIT09bi5kYXRlRm9ybWF0JiZ2b2lkIDA9PT1uLm1heERhdGUmJihsLnNldHRpbmdzLm1heERhdGU9dGhpcy5fZm9ybWF0RGF0ZShsLGgpKSxcImRpc2FibGVkXCJpbiBuJiYobi5kaXNhYmxlZD90aGlzLl9kaXNhYmxlRGF0ZXBpY2tlcih0KTp0aGlzLl9lbmFibGVEYXRlcGlja2VyKHQpKSx0aGlzLl9hdHRhY2htZW50cyhlKHQpLGwpLHRoaXMuX2F1dG9TaXplKGwpLHRoaXMuX3NldERhdGUobCxhKSx0aGlzLl91cGRhdGVBbHRlcm5hdGUobCksdGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihsKSksdm9pZCAwKX0sX2NoYW5nZURhdGVwaWNrZXI6ZnVuY3Rpb24oZSx0LGkpe3RoaXMuX29wdGlvbkRhdGVwaWNrZXIoZSx0LGkpfSxfcmVmcmVzaERhdGVwaWNrZXI6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5fZ2V0SW5zdChlKTt0JiZ0aGlzLl91cGRhdGVEYXRlcGlja2VyKHQpfSxfc2V0RGF0ZURhdGVwaWNrZXI6ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLl9nZXRJbnN0KGUpO2kmJih0aGlzLl9zZXREYXRlKGksdCksdGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpKSx0aGlzLl91cGRhdGVBbHRlcm5hdGUoaSkpfSxfZ2V0RGF0ZURhdGVwaWNrZXI6ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLl9nZXRJbnN0KGUpO3JldHVybiBpJiYhaS5pbmxpbmUmJnRoaXMuX3NldERhdGVGcm9tRmllbGQoaSx0KSxpP3RoaXMuX2dldERhdGUoaSk6bnVsbH0sX2RvS2V5RG93bjpmdW5jdGlvbih0KXt2YXIgaSxzLG4sYT1lLmRhdGVwaWNrZXIuX2dldEluc3QodC50YXJnZXQpLG89ITAscj1hLmRwRGl2LmlzKFwiLnVpLWRhdGVwaWNrZXItcnRsXCIpO2lmKGEuX2tleUV2ZW50PSEwLGUuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcpc3dpdGNoKHQua2V5Q29kZSl7Y2FzZSA5OmUuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKSxvPSExO2JyZWFrO2Nhc2UgMTM6cmV0dXJuIG49ZShcInRkLlwiK2UuZGF0ZXBpY2tlci5fZGF5T3ZlckNsYXNzK1wiOm5vdCguXCIrZS5kYXRlcGlja2VyLl9jdXJyZW50Q2xhc3MrXCIpXCIsYS5kcERpdiksblswXSYmZS5kYXRlcGlja2VyLl9zZWxlY3REYXkodC50YXJnZXQsYS5zZWxlY3RlZE1vbnRoLGEuc2VsZWN0ZWRZZWFyLG5bMF0pLGk9ZS5kYXRlcGlja2VyLl9nZXQoYSxcIm9uU2VsZWN0XCIpLGk/KHM9ZS5kYXRlcGlja2VyLl9mb3JtYXREYXRlKGEpLGkuYXBwbHkoYS5pbnB1dD9hLmlucHV0WzBdOm51bGwsW3MsYV0pKTplLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCksITE7Y2FzZSAyNzplLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7YnJlYWs7Y2FzZSAzMzplLmRhdGVwaWNrZXIuX2FkanVzdERhdGUodC50YXJnZXQsdC5jdHJsS2V5Py1lLmRhdGVwaWNrZXIuX2dldChhLFwic3RlcEJpZ01vbnRoc1wiKTotZS5kYXRlcGlja2VyLl9nZXQoYSxcInN0ZXBNb250aHNcIiksXCJNXCIpO2JyZWFrO2Nhc2UgMzQ6ZS5kYXRlcGlja2VyLl9hZGp1c3REYXRlKHQudGFyZ2V0LHQuY3RybEtleT8rZS5kYXRlcGlja2VyLl9nZXQoYSxcInN0ZXBCaWdNb250aHNcIik6K2UuZGF0ZXBpY2tlci5fZ2V0KGEsXCJzdGVwTW9udGhzXCIpLFwiTVwiKTticmVhaztjYXNlIDM1Oih0LmN0cmxLZXl8fHQubWV0YUtleSkmJmUuZGF0ZXBpY2tlci5fY2xlYXJEYXRlKHQudGFyZ2V0KSxvPXQuY3RybEtleXx8dC5tZXRhS2V5O2JyZWFrO2Nhc2UgMzY6KHQuY3RybEtleXx8dC5tZXRhS2V5KSYmZS5kYXRlcGlja2VyLl9nb3RvVG9kYXkodC50YXJnZXQpLG89dC5jdHJsS2V5fHx0Lm1ldGFLZXk7YnJlYWs7Y2FzZSAzNzoodC5jdHJsS2V5fHx0Lm1ldGFLZXkpJiZlLmRhdGVwaWNrZXIuX2FkanVzdERhdGUodC50YXJnZXQscj8xOi0xLFwiRFwiKSxvPXQuY3RybEtleXx8dC5tZXRhS2V5LHQub3JpZ2luYWxFdmVudC5hbHRLZXkmJmUuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZSh0LnRhcmdldCx0LmN0cmxLZXk/LWUuZGF0ZXBpY2tlci5fZ2V0KGEsXCJzdGVwQmlnTW9udGhzXCIpOi1lLmRhdGVwaWNrZXIuX2dldChhLFwic3RlcE1vbnRoc1wiKSxcIk1cIik7YnJlYWs7Y2FzZSAzODoodC5jdHJsS2V5fHx0Lm1ldGFLZXkpJiZlLmRhdGVwaWNrZXIuX2FkanVzdERhdGUodC50YXJnZXQsLTcsXCJEXCIpLG89dC5jdHJsS2V5fHx0Lm1ldGFLZXk7YnJlYWs7Y2FzZSAzOToodC5jdHJsS2V5fHx0Lm1ldGFLZXkpJiZlLmRhdGVwaWNrZXIuX2FkanVzdERhdGUodC50YXJnZXQscj8tMToxLFwiRFwiKSxvPXQuY3RybEtleXx8dC5tZXRhS2V5LHQub3JpZ2luYWxFdmVudC5hbHRLZXkmJmUuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZSh0LnRhcmdldCx0LmN0cmxLZXk/K2UuZGF0ZXBpY2tlci5fZ2V0KGEsXCJzdGVwQmlnTW9udGhzXCIpOitlLmRhdGVwaWNrZXIuX2dldChhLFwic3RlcE1vbnRoc1wiKSxcIk1cIik7YnJlYWs7Y2FzZSA0MDoodC5jdHJsS2V5fHx0Lm1ldGFLZXkpJiZlLmRhdGVwaWNrZXIuX2FkanVzdERhdGUodC50YXJnZXQsNyxcIkRcIiksbz10LmN0cmxLZXl8fHQubWV0YUtleTticmVhaztkZWZhdWx0Om89ITF9ZWxzZSAzNj09PXQua2V5Q29kZSYmdC5jdHJsS2V5P2UuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIodGhpcyk6bz0hMTtvJiYodC5wcmV2ZW50RGVmYXVsdCgpLHQuc3RvcFByb3BhZ2F0aW9uKCkpfSxfZG9LZXlQcmVzczpmdW5jdGlvbih0KXt2YXIgaSxzLG49ZS5kYXRlcGlja2VyLl9nZXRJbnN0KHQudGFyZ2V0KTtcclxucmV0dXJuIGUuZGF0ZXBpY2tlci5fZ2V0KG4sXCJjb25zdHJhaW5JbnB1dFwiKT8oaT1lLmRhdGVwaWNrZXIuX3Bvc3NpYmxlQ2hhcnMoZS5kYXRlcGlja2VyLl9nZXQobixcImRhdGVGb3JtYXRcIikpLHM9U3RyaW5nLmZyb21DaGFyQ29kZShudWxsPT10LmNoYXJDb2RlP3Qua2V5Q29kZTp0LmNoYXJDb2RlKSx0LmN0cmxLZXl8fHQubWV0YUtleXx8XCIgXCI+c3x8IWl8fGkuaW5kZXhPZihzKT4tMSk6dm9pZCAwfSxfZG9LZXlVcDpmdW5jdGlvbih0KXt2YXIgaSxzPWUuZGF0ZXBpY2tlci5fZ2V0SW5zdCh0LnRhcmdldCk7aWYocy5pbnB1dC52YWwoKSE9PXMubGFzdFZhbCl0cnl7aT1lLmRhdGVwaWNrZXIucGFyc2VEYXRlKGUuZGF0ZXBpY2tlci5fZ2V0KHMsXCJkYXRlRm9ybWF0XCIpLHMuaW5wdXQ/cy5pbnB1dC52YWwoKTpudWxsLGUuZGF0ZXBpY2tlci5fZ2V0Rm9ybWF0Q29uZmlnKHMpKSxpJiYoZS5kYXRlcGlja2VyLl9zZXREYXRlRnJvbUZpZWxkKHMpLGUuZGF0ZXBpY2tlci5fdXBkYXRlQWx0ZXJuYXRlKHMpLGUuZGF0ZXBpY2tlci5fdXBkYXRlRGF0ZXBpY2tlcihzKSl9Y2F0Y2gobil7fXJldHVybiEwfSxfc2hvd0RhdGVwaWNrZXI6ZnVuY3Rpb24odCl7aWYodD10LnRhcmdldHx8dCxcImlucHV0XCIhPT10Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkmJih0PWUoXCJpbnB1dFwiLHQucGFyZW50Tm9kZSlbMF0pLCFlLmRhdGVwaWNrZXIuX2lzRGlzYWJsZWREYXRlcGlja2VyKHQpJiZlLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCE9PXQpe3ZhciBpLG4sYSxvLGgsbCx1O2k9ZS5kYXRlcGlja2VyLl9nZXRJbnN0KHQpLGUuZGF0ZXBpY2tlci5fY3VySW5zdCYmZS5kYXRlcGlja2VyLl9jdXJJbnN0IT09aSYmKGUuZGF0ZXBpY2tlci5fY3VySW5zdC5kcERpdi5zdG9wKCEwLCEwKSxpJiZlLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nJiZlLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKGUuZGF0ZXBpY2tlci5fY3VySW5zdC5pbnB1dFswXSkpLG49ZS5kYXRlcGlja2VyLl9nZXQoaSxcImJlZm9yZVNob3dcIiksYT1uP24uYXBwbHkodCxbdCxpXSk6e30sYSE9PSExJiYocihpLnNldHRpbmdzLGEpLGkubGFzdFZhbD1udWxsLGUuZGF0ZXBpY2tlci5fbGFzdElucHV0PXQsZS5kYXRlcGlja2VyLl9zZXREYXRlRnJvbUZpZWxkKGkpLGUuZGF0ZXBpY2tlci5faW5EaWFsb2cmJih0LnZhbHVlPVwiXCIpLGUuZGF0ZXBpY2tlci5fcG9zfHwoZS5kYXRlcGlja2VyLl9wb3M9ZS5kYXRlcGlja2VyLl9maW5kUG9zKHQpLGUuZGF0ZXBpY2tlci5fcG9zWzFdKz10Lm9mZnNldEhlaWdodCksbz0hMSxlKHQpLnBhcmVudHMoKS5lYWNoKGZ1bmN0aW9uKCl7cmV0dXJuIG98PVwiZml4ZWRcIj09PWUodGhpcykuY3NzKFwicG9zaXRpb25cIiksIW99KSxoPXtsZWZ0OmUuZGF0ZXBpY2tlci5fcG9zWzBdLHRvcDplLmRhdGVwaWNrZXIuX3Bvc1sxXX0sZS5kYXRlcGlja2VyLl9wb3M9bnVsbCxpLmRwRGl2LmVtcHR5KCksaS5kcERpdi5jc3Moe3Bvc2l0aW9uOlwiYWJzb2x1dGVcIixkaXNwbGF5OlwiYmxvY2tcIix0b3A6XCItMTAwMHB4XCJ9KSxlLmRhdGVwaWNrZXIuX3VwZGF0ZURhdGVwaWNrZXIoaSksaD1lLmRhdGVwaWNrZXIuX2NoZWNrT2Zmc2V0KGksaCxvKSxpLmRwRGl2LmNzcyh7cG9zaXRpb246ZS5kYXRlcGlja2VyLl9pbkRpYWxvZyYmZS5ibG9ja1VJP1wic3RhdGljXCI6bz9cImZpeGVkXCI6XCJhYnNvbHV0ZVwiLGRpc3BsYXk6XCJub25lXCIsbGVmdDpoLmxlZnQrXCJweFwiLHRvcDpoLnRvcCtcInB4XCJ9KSxpLmlubGluZXx8KGw9ZS5kYXRlcGlja2VyLl9nZXQoaSxcInNob3dBbmltXCIpLHU9ZS5kYXRlcGlja2VyLl9nZXQoaSxcImR1cmF0aW9uXCIpLGkuZHBEaXYuY3NzKFwiei1pbmRleFwiLHMoZSh0KSkrMSksZS5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZz0hMCxlLmVmZmVjdHMmJmUuZWZmZWN0cy5lZmZlY3RbbF0/aS5kcERpdi5zaG93KGwsZS5kYXRlcGlja2VyLl9nZXQoaSxcInNob3dPcHRpb25zXCIpLHUpOmkuZHBEaXZbbHx8XCJzaG93XCJdKGw/dTpudWxsKSxlLmRhdGVwaWNrZXIuX3Nob3VsZEZvY3VzSW5wdXQoaSkmJmkuaW5wdXQuZm9jdXMoKSxlLmRhdGVwaWNrZXIuX2N1ckluc3Q9aSkpfX0sX3VwZGF0ZURhdGVwaWNrZXI6ZnVuY3Rpb24odCl7dGhpcy5tYXhSb3dzPTQsdj10LHQuZHBEaXYuZW1wdHkoKS5hcHBlbmQodGhpcy5fZ2VuZXJhdGVIVE1MKHQpKSx0aGlzLl9hdHRhY2hIYW5kbGVycyh0KTt2YXIgaSxzPXRoaXMuX2dldE51bWJlck9mTW9udGhzKHQpLG49c1sxXSxhPTE3LHI9dC5kcERpdi5maW5kKFwiLlwiK3RoaXMuX2RheU92ZXJDbGFzcytcIiBhXCIpO3IubGVuZ3RoPjAmJm8uYXBwbHkoci5nZXQoMCkpLHQuZHBEaXYucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW11bHRpLTIgdWktZGF0ZXBpY2tlci1tdWx0aS0zIHVpLWRhdGVwaWNrZXItbXVsdGktNFwiKS53aWR0aChcIlwiKSxuPjEmJnQuZHBEaXYuYWRkQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW11bHRpLVwiK24pLmNzcyhcIndpZHRoXCIsYSpuK1wiZW1cIiksdC5kcERpdlsoMSE9PXNbMF18fDEhPT1zWzFdP1wiYWRkXCI6XCJyZW1vdmVcIikrXCJDbGFzc1wiXShcInVpLWRhdGVwaWNrZXItbXVsdGlcIiksdC5kcERpdlsodGhpcy5fZ2V0KHQsXCJpc1JUTFwiKT9cImFkZFwiOlwicmVtb3ZlXCIpK1wiQ2xhc3NcIl0oXCJ1aS1kYXRlcGlja2VyLXJ0bFwiKSx0PT09ZS5kYXRlcGlja2VyLl9jdXJJbnN0JiZlLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nJiZlLmRhdGVwaWNrZXIuX3Nob3VsZEZvY3VzSW5wdXQodCkmJnQuaW5wdXQuZm9jdXMoKSx0LnllYXJzaHRtbCYmKGk9dC55ZWFyc2h0bWwsc2V0VGltZW91dChmdW5jdGlvbigpe2k9PT10LnllYXJzaHRtbCYmdC55ZWFyc2h0bWwmJnQuZHBEaXYuZmluZChcInNlbGVjdC51aS1kYXRlcGlja2VyLXllYXI6Zmlyc3RcIikucmVwbGFjZVdpdGgodC55ZWFyc2h0bWwpLGk9dC55ZWFyc2h0bWw9bnVsbH0sMCkpfSxfc2hvdWxkRm9jdXNJbnB1dDpmdW5jdGlvbihlKXtyZXR1cm4gZS5pbnB1dCYmZS5pbnB1dC5pcyhcIjp2aXNpYmxlXCIpJiYhZS5pbnB1dC5pcyhcIjpkaXNhYmxlZFwiKSYmIWUuaW5wdXQuaXMoXCI6Zm9jdXNcIil9LF9jaGVja09mZnNldDpmdW5jdGlvbih0LGkscyl7dmFyIG49dC5kcERpdi5vdXRlcldpZHRoKCksYT10LmRwRGl2Lm91dGVySGVpZ2h0KCksbz10LmlucHV0P3QuaW5wdXQub3V0ZXJXaWR0aCgpOjAscj10LmlucHV0P3QuaW5wdXQub3V0ZXJIZWlnaHQoKTowLGg9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKyhzPzA6ZShkb2N1bWVudCkuc2Nyb2xsTGVmdCgpKSxsPWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQrKHM/MDplKGRvY3VtZW50KS5zY3JvbGxUb3AoKSk7cmV0dXJuIGkubGVmdC09dGhpcy5fZ2V0KHQsXCJpc1JUTFwiKT9uLW86MCxpLmxlZnQtPXMmJmkubGVmdD09PXQuaW5wdXQub2Zmc2V0KCkubGVmdD9lKGRvY3VtZW50KS5zY3JvbGxMZWZ0KCk6MCxpLnRvcC09cyYmaS50b3A9PT10LmlucHV0Lm9mZnNldCgpLnRvcCtyP2UoZG9jdW1lbnQpLnNjcm9sbFRvcCgpOjAsaS5sZWZ0LT1NYXRoLm1pbihpLmxlZnQsaS5sZWZ0K24+aCYmaD5uP01hdGguYWJzKGkubGVmdCtuLWgpOjApLGkudG9wLT1NYXRoLm1pbihpLnRvcCxpLnRvcCthPmwmJmw+YT9NYXRoLmFicyhhK3IpOjApLGl9LF9maW5kUG9zOmZ1bmN0aW9uKHQpe2Zvcih2YXIgaSxzPXRoaXMuX2dldEluc3QodCksbj10aGlzLl9nZXQocyxcImlzUlRMXCIpO3QmJihcImhpZGRlblwiPT09dC50eXBlfHwxIT09dC5ub2RlVHlwZXx8ZS5leHByLmZpbHRlcnMuaGlkZGVuKHQpKTspdD10W24/XCJwcmV2aW91c1NpYmxpbmdcIjpcIm5leHRTaWJsaW5nXCJdO3JldHVybiBpPWUodCkub2Zmc2V0KCksW2kubGVmdCxpLnRvcF19LF9oaWRlRGF0ZXBpY2tlcjpmdW5jdGlvbih0KXt2YXIgaSxzLG4sYSxvPXRoaXMuX2N1ckluc3Q7IW98fHQmJm8hPT1lLmRhdGEodCxcImRhdGVwaWNrZXJcIil8fHRoaXMuX2RhdGVwaWNrZXJTaG93aW5nJiYoaT10aGlzLl9nZXQobyxcInNob3dBbmltXCIpLHM9dGhpcy5fZ2V0KG8sXCJkdXJhdGlvblwiKSxuPWZ1bmN0aW9uKCl7ZS5kYXRlcGlja2VyLl90aWR5RGlhbG9nKG8pfSxlLmVmZmVjdHMmJihlLmVmZmVjdHMuZWZmZWN0W2ldfHxlLmVmZmVjdHNbaV0pP28uZHBEaXYuaGlkZShpLGUuZGF0ZXBpY2tlci5fZ2V0KG8sXCJzaG93T3B0aW9uc1wiKSxzLG4pOm8uZHBEaXZbXCJzbGlkZURvd25cIj09PWk/XCJzbGlkZVVwXCI6XCJmYWRlSW5cIj09PWk/XCJmYWRlT3V0XCI6XCJoaWRlXCJdKGk/czpudWxsLG4pLGl8fG4oKSx0aGlzLl9kYXRlcGlja2VyU2hvd2luZz0hMSxhPXRoaXMuX2dldChvLFwib25DbG9zZVwiKSxhJiZhLmFwcGx5KG8uaW5wdXQ/by5pbnB1dFswXTpudWxsLFtvLmlucHV0P28uaW5wdXQudmFsKCk6XCJcIixvXSksdGhpcy5fbGFzdElucHV0PW51bGwsdGhpcy5faW5EaWFsb2cmJih0aGlzLl9kaWFsb2dJbnB1dC5jc3Moe3Bvc2l0aW9uOlwiYWJzb2x1dGVcIixsZWZ0OlwiMFwiLHRvcDpcIi0xMDBweFwifSksZS5ibG9ja1VJJiYoZS51bmJsb2NrVUkoKSxlKFwiYm9keVwiKS5hcHBlbmQodGhpcy5kcERpdikpKSx0aGlzLl9pbkRpYWxvZz0hMSl9LF90aWR5RGlhbG9nOmZ1bmN0aW9uKGUpe2UuZHBEaXYucmVtb3ZlQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpLnVuYmluZChcIi51aS1kYXRlcGlja2VyLWNhbGVuZGFyXCIpfSxfY2hlY2tFeHRlcm5hbENsaWNrOmZ1bmN0aW9uKHQpe2lmKGUuZGF0ZXBpY2tlci5fY3VySW5zdCl7dmFyIGk9ZSh0LnRhcmdldCkscz1lLmRhdGVwaWNrZXIuX2dldEluc3QoaVswXSk7KGlbMF0uaWQhPT1lLmRhdGVwaWNrZXIuX21haW5EaXZJZCYmMD09PWkucGFyZW50cyhcIiNcIitlLmRhdGVwaWNrZXIuX21haW5EaXZJZCkubGVuZ3RoJiYhaS5oYXNDbGFzcyhlLmRhdGVwaWNrZXIubWFya2VyQ2xhc3NOYW1lKSYmIWkuY2xvc2VzdChcIi5cIitlLmRhdGVwaWNrZXIuX3RyaWdnZXJDbGFzcykubGVuZ3RoJiZlLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nJiYoIWUuZGF0ZXBpY2tlci5faW5EaWFsb2d8fCFlLmJsb2NrVUkpfHxpLmhhc0NsYXNzKGUuZGF0ZXBpY2tlci5tYXJrZXJDbGFzc05hbWUpJiZlLmRhdGVwaWNrZXIuX2N1ckluc3QhPT1zKSYmZS5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpfX0sX2FkanVzdERhdGU6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPWUodCksYT10aGlzLl9nZXRJbnN0KG5bMF0pO3RoaXMuX2lzRGlzYWJsZWREYXRlcGlja2VyKG5bMF0pfHwodGhpcy5fYWRqdXN0SW5zdERhdGUoYSxpKyhcIk1cIj09PXM/dGhpcy5fZ2V0KGEsXCJzaG93Q3VycmVudEF0UG9zXCIpOjApLHMpLHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoYSkpfSxfZ290b1RvZGF5OmZ1bmN0aW9uKHQpe3ZhciBpLHM9ZSh0KSxuPXRoaXMuX2dldEluc3Qoc1swXSk7dGhpcy5fZ2V0KG4sXCJnb3RvQ3VycmVudFwiKSYmbi5jdXJyZW50RGF5PyhuLnNlbGVjdGVkRGF5PW4uY3VycmVudERheSxuLmRyYXdNb250aD1uLnNlbGVjdGVkTW9udGg9bi5jdXJyZW50TW9udGgsbi5kcmF3WWVhcj1uLnNlbGVjdGVkWWVhcj1uLmN1cnJlbnRZZWFyKTooaT1uZXcgRGF0ZSxuLnNlbGVjdGVkRGF5PWkuZ2V0RGF0ZSgpLG4uZHJhd01vbnRoPW4uc2VsZWN0ZWRNb250aD1pLmdldE1vbnRoKCksbi5kcmF3WWVhcj1uLnNlbGVjdGVkWWVhcj1pLmdldEZ1bGxZZWFyKCkpLHRoaXMuX25vdGlmeUNoYW5nZShuKSx0aGlzLl9hZGp1c3REYXRlKHMpfSxfc2VsZWN0TW9udGhZZWFyOmZ1bmN0aW9uKHQsaSxzKXt2YXIgbj1lKHQpLGE9dGhpcy5fZ2V0SW5zdChuWzBdKTthW1wic2VsZWN0ZWRcIisoXCJNXCI9PT1zP1wiTW9udGhcIjpcIlllYXJcIildPWFbXCJkcmF3XCIrKFwiTVwiPT09cz9cIk1vbnRoXCI6XCJZZWFyXCIpXT1wYXJzZUludChpLm9wdGlvbnNbaS5zZWxlY3RlZEluZGV4XS52YWx1ZSwxMCksdGhpcy5fbm90aWZ5Q2hhbmdlKGEpLHRoaXMuX2FkanVzdERhdGUobil9LF9zZWxlY3REYXk6ZnVuY3Rpb24odCxpLHMsbil7dmFyIGEsbz1lKHQpO2UobikuaGFzQ2xhc3ModGhpcy5fdW5zZWxlY3RhYmxlQ2xhc3MpfHx0aGlzLl9pc0Rpc2FibGVkRGF0ZXBpY2tlcihvWzBdKXx8KGE9dGhpcy5fZ2V0SW5zdChvWzBdKSxhLnNlbGVjdGVkRGF5PWEuY3VycmVudERheT1lKFwiYVwiLG4pLmh0bWwoKSxhLnNlbGVjdGVkTW9udGg9YS5jdXJyZW50TW9udGg9aSxhLnNlbGVjdGVkWWVhcj1hLmN1cnJlbnRZZWFyPXMsdGhpcy5fc2VsZWN0RGF0ZSh0LHRoaXMuX2Zvcm1hdERhdGUoYSxhLmN1cnJlbnREYXksYS5jdXJyZW50TW9udGgsYS5jdXJyZW50WWVhcikpKX0sX2NsZWFyRGF0ZTpmdW5jdGlvbih0KXt2YXIgaT1lKHQpO3RoaXMuX3NlbGVjdERhdGUoaSxcIlwiKX0sX3NlbGVjdERhdGU6ZnVuY3Rpb24odCxpKXt2YXIgcyxuPWUodCksYT10aGlzLl9nZXRJbnN0KG5bMF0pO2k9bnVsbCE9aT9pOnRoaXMuX2Zvcm1hdERhdGUoYSksYS5pbnB1dCYmYS5pbnB1dC52YWwoaSksdGhpcy5fdXBkYXRlQWx0ZXJuYXRlKGEpLHM9dGhpcy5fZ2V0KGEsXCJvblNlbGVjdFwiKSxzP3MuYXBwbHkoYS5pbnB1dD9hLmlucHV0WzBdOm51bGwsW2ksYV0pOmEuaW5wdXQmJmEuaW5wdXQudHJpZ2dlcihcImNoYW5nZVwiKSxhLmlubGluZT90aGlzLl91cGRhdGVEYXRlcGlja2VyKGEpOih0aGlzLl9oaWRlRGF0ZXBpY2tlcigpLHRoaXMuX2xhc3RJbnB1dD1hLmlucHV0WzBdLFwib2JqZWN0XCIhPXR5cGVvZiBhLmlucHV0WzBdJiZhLmlucHV0LmZvY3VzKCksdGhpcy5fbGFzdElucHV0PW51bGwpfSxfdXBkYXRlQWx0ZXJuYXRlOmZ1bmN0aW9uKHQpe3ZhciBpLHMsbixhPXRoaXMuX2dldCh0LFwiYWx0RmllbGRcIik7YSYmKGk9dGhpcy5fZ2V0KHQsXCJhbHRGb3JtYXRcIil8fHRoaXMuX2dldCh0LFwiZGF0ZUZvcm1hdFwiKSxzPXRoaXMuX2dldERhdGUodCksbj10aGlzLmZvcm1hdERhdGUoaSxzLHRoaXMuX2dldEZvcm1hdENvbmZpZyh0KSksZShhKS5lYWNoKGZ1bmN0aW9uKCl7ZSh0aGlzKS52YWwobil9KSl9LG5vV2Vla2VuZHM6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5nZXREYXkoKTtyZXR1cm5bdD4wJiY2PnQsXCJcIl19LGlzbzg2MDFXZWVrOmZ1bmN0aW9uKGUpe3ZhciB0LGk9bmV3IERhdGUoZS5nZXRUaW1lKCkpO3JldHVybiBpLnNldERhdGUoaS5nZXREYXRlKCkrNC0oaS5nZXREYXkoKXx8NykpLHQ9aS5nZXRUaW1lKCksaS5zZXRNb250aCgwKSxpLnNldERhdGUoMSksTWF0aC5mbG9vcihNYXRoLnJvdW5kKCh0LWkpLzg2NGU1KS83KSsxfSxwYXJzZURhdGU6ZnVuY3Rpb24odCxpLHMpe2lmKG51bGw9PXR8fG51bGw9PWkpdGhyb3dcIkludmFsaWQgYXJndW1lbnRzXCI7aWYoaT1cIm9iamVjdFwiPT10eXBlb2YgaT9cIlwiK2k6aStcIlwiLFwiXCI9PT1pKXJldHVybiBudWxsO3ZhciBuLGEsbyxyLGg9MCxsPShzP3Muc2hvcnRZZWFyQ3V0b2ZmOm51bGwpfHx0aGlzLl9kZWZhdWx0cy5zaG9ydFllYXJDdXRvZmYsdT1cInN0cmluZ1wiIT10eXBlb2YgbD9sOihuZXcgRGF0ZSkuZ2V0RnVsbFllYXIoKSUxMDArcGFyc2VJbnQobCwxMCksZD0ocz9zLmRheU5hbWVzU2hvcnQ6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzU2hvcnQsYz0ocz9zLmRheU5hbWVzOm51bGwpfHx0aGlzLl9kZWZhdWx0cy5kYXlOYW1lcyxwPShzP3MubW9udGhOYW1lc1Nob3J0Om51bGwpfHx0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzU2hvcnQsZj0ocz9zLm1vbnRoTmFtZXM6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXMsbT0tMSxnPS0xLHY9LTEseT0tMSxiPSExLF89ZnVuY3Rpb24oZSl7dmFyIGk9dC5sZW5ndGg+bisxJiZ0LmNoYXJBdChuKzEpPT09ZTtyZXR1cm4gaSYmbisrLGl9LHg9ZnVuY3Rpb24oZSl7dmFyIHQ9XyhlKSxzPVwiQFwiPT09ZT8xNDpcIiFcIj09PWU/MjA6XCJ5XCI9PT1lJiZ0PzQ6XCJvXCI9PT1lPzM6MixuPVwieVwiPT09ZT9zOjEsYT1SZWdFeHAoXCJeXFxcXGR7XCIrbitcIixcIitzK1wifVwiKSxvPWkuc3Vic3RyaW5nKGgpLm1hdGNoKGEpO2lmKCFvKXRocm93XCJNaXNzaW5nIG51bWJlciBhdCBwb3NpdGlvbiBcIitoO3JldHVybiBoKz1vWzBdLmxlbmd0aCxwYXJzZUludChvWzBdLDEwKX0sdz1mdW5jdGlvbih0LHMsbil7dmFyIGE9LTEsbz1lLm1hcChfKHQpP246cyxmdW5jdGlvbihlLHQpe3JldHVybltbdCxlXV19KS5zb3J0KGZ1bmN0aW9uKGUsdCl7cmV0dXJuLShlWzFdLmxlbmd0aC10WzFdLmxlbmd0aCl9KTtpZihlLmVhY2gobyxmdW5jdGlvbihlLHQpe3ZhciBzPXRbMV07cmV0dXJuIGkuc3Vic3RyKGgscy5sZW5ndGgpLnRvTG93ZXJDYXNlKCk9PT1zLnRvTG93ZXJDYXNlKCk/KGE9dFswXSxoKz1zLmxlbmd0aCwhMSk6dm9pZCAwfSksLTEhPT1hKXJldHVybiBhKzE7dGhyb3dcIlVua25vd24gbmFtZSBhdCBwb3NpdGlvbiBcIitofSxrPWZ1bmN0aW9uKCl7aWYoaS5jaGFyQXQoaCkhPT10LmNoYXJBdChuKSl0aHJvd1wiVW5leHBlY3RlZCBsaXRlcmFsIGF0IHBvc2l0aW9uIFwiK2g7aCsrfTtmb3Iobj0wO3QubGVuZ3RoPm47bisrKWlmKGIpXCInXCIhPT10LmNoYXJBdChuKXx8XyhcIidcIik/aygpOmI9ITE7ZWxzZSBzd2l0Y2godC5jaGFyQXQobikpe2Nhc2VcImRcIjp2PXgoXCJkXCIpO2JyZWFrO2Nhc2VcIkRcIjp3KFwiRFwiLGQsYyk7YnJlYWs7Y2FzZVwib1wiOnk9eChcIm9cIik7YnJlYWs7Y2FzZVwibVwiOmc9eChcIm1cIik7YnJlYWs7Y2FzZVwiTVwiOmc9dyhcIk1cIixwLGYpO2JyZWFrO2Nhc2VcInlcIjptPXgoXCJ5XCIpO2JyZWFrO2Nhc2VcIkBcIjpyPW5ldyBEYXRlKHgoXCJAXCIpKSxtPXIuZ2V0RnVsbFllYXIoKSxnPXIuZ2V0TW9udGgoKSsxLHY9ci5nZXREYXRlKCk7YnJlYWs7Y2FzZVwiIVwiOnI9bmV3IERhdGUoKHgoXCIhXCIpLXRoaXMuX3RpY2tzVG8xOTcwKS8xZTQpLG09ci5nZXRGdWxsWWVhcigpLGc9ci5nZXRNb250aCgpKzEsdj1yLmdldERhdGUoKTticmVhaztjYXNlXCInXCI6XyhcIidcIik/aygpOmI9ITA7YnJlYWs7ZGVmYXVsdDprKCl9aWYoaS5sZW5ndGg+aCYmKG89aS5zdWJzdHIoaCksIS9eXFxzKy8udGVzdChvKSkpdGhyb3dcIkV4dHJhL3VucGFyc2VkIGNoYXJhY3RlcnMgZm91bmQgaW4gZGF0ZTogXCIrbztpZigtMT09PW0/bT0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCk6MTAwPm0mJihtKz0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCktKG5ldyBEYXRlKS5nZXRGdWxsWWVhcigpJTEwMCsodT49bT8wOi0xMDApKSx5Pi0xKWZvcihnPTEsdj15Ozspe2lmKGE9dGhpcy5fZ2V0RGF5c0luTW9udGgobSxnLTEpLGE+PXYpYnJlYWs7ZysrLHYtPWF9aWYocj10aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShtLGctMSx2KSksci5nZXRGdWxsWWVhcigpIT09bXx8ci5nZXRNb250aCgpKzEhPT1nfHxyLmdldERhdGUoKSE9PXYpdGhyb3dcIkludmFsaWQgZGF0ZVwiO3JldHVybiByfSxBVE9NOlwieXktbW0tZGRcIixDT09LSUU6XCJELCBkZCBNIHl5XCIsSVNPXzg2MDE6XCJ5eS1tbS1kZFwiLFJGQ184MjI6XCJELCBkIE0geVwiLFJGQ184NTA6XCJERCwgZGQtTS15XCIsUkZDXzEwMzY6XCJELCBkIE0geVwiLFJGQ18xMTIzOlwiRCwgZCBNIHl5XCIsUkZDXzI4MjI6XCJELCBkIE0geXlcIixSU1M6XCJELCBkIE0geVwiLFRJQ0tTOlwiIVwiLFRJTUVTVEFNUDpcIkBcIixXM0M6XCJ5eS1tbS1kZFwiLF90aWNrc1RvMTk3MDoxZTcqNjAqNjAqMjQqKDcxODY4NStNYXRoLmZsb29yKDQ5Mi41KS1NYXRoLmZsb29yKDE5LjcpK01hdGguZmxvb3IoNC45MjUpKSxmb3JtYXREYXRlOmZ1bmN0aW9uKGUsdCxpKXtpZighdClyZXR1cm5cIlwiO3ZhciBzLG49KGk/aS5kYXlOYW1lc1Nob3J0Om51bGwpfHx0aGlzLl9kZWZhdWx0cy5kYXlOYW1lc1Nob3J0LGE9KGk/aS5kYXlOYW1lczpudWxsKXx8dGhpcy5fZGVmYXVsdHMuZGF5TmFtZXMsbz0oaT9pLm1vbnRoTmFtZXNTaG9ydDpudWxsKXx8dGhpcy5fZGVmYXVsdHMubW9udGhOYW1lc1Nob3J0LHI9KGk/aS5tb250aE5hbWVzOm51bGwpfHx0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzLGg9ZnVuY3Rpb24odCl7dmFyIGk9ZS5sZW5ndGg+cysxJiZlLmNoYXJBdChzKzEpPT09dDtyZXR1cm4gaSYmcysrLGl9LGw9ZnVuY3Rpb24oZSx0LGkpe3ZhciBzPVwiXCIrdDtpZihoKGUpKWZvcig7aT5zLmxlbmd0aDspcz1cIjBcIitzO3JldHVybiBzfSx1PWZ1bmN0aW9uKGUsdCxpLHMpe3JldHVybiBoKGUpP3NbdF06aVt0XX0sZD1cIlwiLGM9ITE7aWYodClmb3Iocz0wO2UubGVuZ3RoPnM7cysrKWlmKGMpXCInXCIhPT1lLmNoYXJBdChzKXx8aChcIidcIik/ZCs9ZS5jaGFyQXQocyk6Yz0hMTtlbHNlIHN3aXRjaChlLmNoYXJBdChzKSl7Y2FzZVwiZFwiOmQrPWwoXCJkXCIsdC5nZXREYXRlKCksMik7YnJlYWs7Y2FzZVwiRFwiOmQrPXUoXCJEXCIsdC5nZXREYXkoKSxuLGEpO2JyZWFrO2Nhc2VcIm9cIjpkKz1sKFwib1wiLE1hdGgucm91bmQoKG5ldyBEYXRlKHQuZ2V0RnVsbFllYXIoKSx0LmdldE1vbnRoKCksdC5nZXREYXRlKCkpLmdldFRpbWUoKS1uZXcgRGF0ZSh0LmdldEZ1bGxZZWFyKCksMCwwKS5nZXRUaW1lKCkpLzg2NGU1KSwzKTticmVhaztjYXNlXCJtXCI6ZCs9bChcIm1cIix0LmdldE1vbnRoKCkrMSwyKTticmVhaztjYXNlXCJNXCI6ZCs9dShcIk1cIix0LmdldE1vbnRoKCksbyxyKTticmVhaztjYXNlXCJ5XCI6ZCs9aChcInlcIik/dC5nZXRGdWxsWWVhcigpOigxMD50LmdldFllYXIoKSUxMDA/XCIwXCI6XCJcIikrdC5nZXRZZWFyKCklMTAwO2JyZWFrO2Nhc2VcIkBcIjpkKz10LmdldFRpbWUoKTticmVhaztjYXNlXCIhXCI6ZCs9MWU0KnQuZ2V0VGltZSgpK3RoaXMuX3RpY2tzVG8xOTcwO2JyZWFrO2Nhc2VcIidcIjpoKFwiJ1wiKT9kKz1cIidcIjpjPSEwO2JyZWFrO2RlZmF1bHQ6ZCs9ZS5jaGFyQXQocyl9cmV0dXJuIGR9LF9wb3NzaWJsZUNoYXJzOmZ1bmN0aW9uKGUpe3ZhciB0LGk9XCJcIixzPSExLG49ZnVuY3Rpb24oaSl7dmFyIHM9ZS5sZW5ndGg+dCsxJiZlLmNoYXJBdCh0KzEpPT09aTtyZXR1cm4gcyYmdCsrLHN9O2Zvcih0PTA7ZS5sZW5ndGg+dDt0KyspaWYocylcIidcIiE9PWUuY2hhckF0KHQpfHxuKFwiJ1wiKT9pKz1lLmNoYXJBdCh0KTpzPSExO2Vsc2Ugc3dpdGNoKGUuY2hhckF0KHQpKXtjYXNlXCJkXCI6Y2FzZVwibVwiOmNhc2VcInlcIjpjYXNlXCJAXCI6aSs9XCIwMTIzNDU2Nzg5XCI7YnJlYWs7Y2FzZVwiRFwiOmNhc2VcIk1cIjpyZXR1cm4gbnVsbDtjYXNlXCInXCI6bihcIidcIik/aSs9XCInXCI6cz0hMDticmVhaztkZWZhdWx0OmkrPWUuY2hhckF0KHQpfXJldHVybiBpfSxfZ2V0OmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHZvaWQgMCE9PWUuc2V0dGluZ3NbdF0/ZS5zZXR0aW5nc1t0XTp0aGlzLl9kZWZhdWx0c1t0XX0sX3NldERhdGVGcm9tRmllbGQ6ZnVuY3Rpb24oZSx0KXtpZihlLmlucHV0LnZhbCgpIT09ZS5sYXN0VmFsKXt2YXIgaT10aGlzLl9nZXQoZSxcImRhdGVGb3JtYXRcIikscz1lLmxhc3RWYWw9ZS5pbnB1dD9lLmlucHV0LnZhbCgpOm51bGwsbj10aGlzLl9nZXREZWZhdWx0RGF0ZShlKSxhPW4sbz10aGlzLl9nZXRGb3JtYXRDb25maWcoZSk7dHJ5e2E9dGhpcy5wYXJzZURhdGUoaSxzLG8pfHxufWNhdGNoKHIpe3M9dD9cIlwiOnN9ZS5zZWxlY3RlZERheT1hLmdldERhdGUoKSxlLmRyYXdNb250aD1lLnNlbGVjdGVkTW9udGg9YS5nZXRNb250aCgpLGUuZHJhd1llYXI9ZS5zZWxlY3RlZFllYXI9YS5nZXRGdWxsWWVhcigpLGUuY3VycmVudERheT1zP2EuZ2V0RGF0ZSgpOjAsZS5jdXJyZW50TW9udGg9cz9hLmdldE1vbnRoKCk6MCxlLmN1cnJlbnRZZWFyPXM/YS5nZXRGdWxsWWVhcigpOjAsdGhpcy5fYWRqdXN0SW5zdERhdGUoZSl9fSxfZ2V0RGVmYXVsdERhdGU6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuX3Jlc3RyaWN0TWluTWF4KGUsdGhpcy5fZGV0ZXJtaW5lRGF0ZShlLHRoaXMuX2dldChlLFwiZGVmYXVsdERhdGVcIiksbmV3IERhdGUpKX0sX2RldGVybWluZURhdGU6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPWZ1bmN0aW9uKGUpe3ZhciB0PW5ldyBEYXRlO3JldHVybiB0LnNldERhdGUodC5nZXREYXRlKCkrZSksdH0sYT1mdW5jdGlvbihpKXt0cnl7cmV0dXJuIGUuZGF0ZXBpY2tlci5wYXJzZURhdGUoZS5kYXRlcGlja2VyLl9nZXQodCxcImRhdGVGb3JtYXRcIiksaSxlLmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyh0KSl9Y2F0Y2gocyl7fWZvcih2YXIgbj0oaS50b0xvd2VyQ2FzZSgpLm1hdGNoKC9eYy8pP2UuZGF0ZXBpY2tlci5fZ2V0RGF0ZSh0KTpudWxsKXx8bmV3IERhdGUsYT1uLmdldEZ1bGxZZWFyKCksbz1uLmdldE1vbnRoKCkscj1uLmdldERhdGUoKSxoPS8oWytcXC1dP1swLTldKylcXHMqKGR8RHx3fFd8bXxNfHl8WSk/L2csbD1oLmV4ZWMoaSk7bDspe3N3aXRjaChsWzJdfHxcImRcIil7Y2FzZVwiZFwiOmNhc2VcIkRcIjpyKz1wYXJzZUludChsWzFdLDEwKTticmVhaztjYXNlXCJ3XCI6Y2FzZVwiV1wiOnIrPTcqcGFyc2VJbnQobFsxXSwxMCk7YnJlYWs7Y2FzZVwibVwiOmNhc2VcIk1cIjpvKz1wYXJzZUludChsWzFdLDEwKSxyPU1hdGgubWluKHIsZS5kYXRlcGlja2VyLl9nZXREYXlzSW5Nb250aChhLG8pKTticmVhaztjYXNlXCJ5XCI6Y2FzZVwiWVwiOmErPXBhcnNlSW50KGxbMV0sMTApLHI9TWF0aC5taW4ocixlLmRhdGVwaWNrZXIuX2dldERheXNJbk1vbnRoKGEsbykpfWw9aC5leGVjKGkpfXJldHVybiBuZXcgRGF0ZShhLG8scil9LG89bnVsbD09aXx8XCJcIj09PWk/czpcInN0cmluZ1wiPT10eXBlb2YgaT9hKGkpOlwibnVtYmVyXCI9PXR5cGVvZiBpP2lzTmFOKGkpP3M6bihpKTpuZXcgRGF0ZShpLmdldFRpbWUoKSk7cmV0dXJuIG89byYmXCJJbnZhbGlkIERhdGVcIj09XCJcIitvP3M6byxvJiYoby5zZXRIb3VycygwKSxvLnNldE1pbnV0ZXMoMCksby5zZXRTZWNvbmRzKDApLG8uc2V0TWlsbGlzZWNvbmRzKDApKSx0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChvKX0sX2RheWxpZ2h0U2F2aW5nQWRqdXN0OmZ1bmN0aW9uKGUpe3JldHVybiBlPyhlLnNldEhvdXJzKGUuZ2V0SG91cnMoKT4xMj9lLmdldEhvdXJzKCkrMjowKSxlKTpudWxsfSxfc2V0RGF0ZTpmdW5jdGlvbihlLHQsaSl7dmFyIHM9IXQsbj1lLnNlbGVjdGVkTW9udGgsYT1lLnNlbGVjdGVkWWVhcixvPXRoaXMuX3Jlc3RyaWN0TWluTWF4KGUsdGhpcy5fZGV0ZXJtaW5lRGF0ZShlLHQsbmV3IERhdGUpKTtlLnNlbGVjdGVkRGF5PWUuY3VycmVudERheT1vLmdldERhdGUoKSxlLmRyYXdNb250aD1lLnNlbGVjdGVkTW9udGg9ZS5jdXJyZW50TW9udGg9by5nZXRNb250aCgpLGUuZHJhd1llYXI9ZS5zZWxlY3RlZFllYXI9ZS5jdXJyZW50WWVhcj1vLmdldEZ1bGxZZWFyKCksbj09PWUuc2VsZWN0ZWRNb250aCYmYT09PWUuc2VsZWN0ZWRZZWFyfHxpfHx0aGlzLl9ub3RpZnlDaGFuZ2UoZSksdGhpcy5fYWRqdXN0SW5zdERhdGUoZSksZS5pbnB1dCYmZS5pbnB1dC52YWwocz9cIlwiOnRoaXMuX2Zvcm1hdERhdGUoZSkpfSxfZ2V0RGF0ZTpmdW5jdGlvbihlKXt2YXIgdD0hZS5jdXJyZW50WWVhcnx8ZS5pbnB1dCYmXCJcIj09PWUuaW5wdXQudmFsKCk/bnVsbDp0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShlLmN1cnJlbnRZZWFyLGUuY3VycmVudE1vbnRoLGUuY3VycmVudERheSkpO3JldHVybiB0fSxfYXR0YWNoSGFuZGxlcnM6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5fZ2V0KHQsXCJzdGVwTW9udGhzXCIpLHM9XCIjXCIrdC5pZC5yZXBsYWNlKC9cXFxcXFxcXC9nLFwiXFxcXFwiKTt0LmRwRGl2LmZpbmQoXCJbZGF0YS1oYW5kbGVyXVwiKS5tYXAoZnVuY3Rpb24oKXt2YXIgdD17cHJldjpmdW5jdGlvbigpe2UuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShzLC1pLFwiTVwiKX0sbmV4dDpmdW5jdGlvbigpe2UuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShzLCtpLFwiTVwiKX0saGlkZTpmdW5jdGlvbigpe2UuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKX0sdG9kYXk6ZnVuY3Rpb24oKXtlLmRhdGVwaWNrZXIuX2dvdG9Ub2RheShzKX0sc2VsZWN0RGF5OmZ1bmN0aW9uKCl7cmV0dXJuIGUuZGF0ZXBpY2tlci5fc2VsZWN0RGF5KHMsK3RoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS1tb250aFwiKSwrdGhpcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLXllYXJcIiksdGhpcyksITF9LHNlbGVjdE1vbnRoOmZ1bmN0aW9uKCl7cmV0dXJuIGUuZGF0ZXBpY2tlci5fc2VsZWN0TW9udGhZZWFyKHMsdGhpcyxcIk1cIiksITF9LHNlbGVjdFllYXI6ZnVuY3Rpb24oKXtyZXR1cm4gZS5kYXRlcGlja2VyLl9zZWxlY3RNb250aFllYXIocyx0aGlzLFwiWVwiKSwhMX19O2UodGhpcykuYmluZCh0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEtZXZlbnRcIiksdFt0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEtaGFuZGxlclwiKV0pfSl9LF9nZW5lcmF0ZUhUTUw6ZnVuY3Rpb24oZSl7dmFyIHQsaSxzLG4sYSxvLHIsaCxsLHUsZCxjLHAsZixtLGcsdix5LGIsXyx4LHcsayxULEQsUyxNLEMsTixBLFAsSSxILHosRixFLE8saixXLEw9bmV3IERhdGUsUj10aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShMLmdldEZ1bGxZZWFyKCksTC5nZXRNb250aCgpLEwuZ2V0RGF0ZSgpKSksWT10aGlzLl9nZXQoZSxcImlzUlRMXCIpLEI9dGhpcy5fZ2V0KGUsXCJzaG93QnV0dG9uUGFuZWxcIiksSj10aGlzLl9nZXQoZSxcImhpZGVJZk5vUHJldk5leHRcIikscT10aGlzLl9nZXQoZSxcIm5hdmlnYXRpb25Bc0RhdGVGb3JtYXRcIiksSz10aGlzLl9nZXROdW1iZXJPZk1vbnRocyhlKSxWPXRoaXMuX2dldChlLFwic2hvd0N1cnJlbnRBdFBvc1wiKSxVPXRoaXMuX2dldChlLFwic3RlcE1vbnRoc1wiKSxRPTEhPT1LWzBdfHwxIT09S1sxXSxHPXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KGUuY3VycmVudERheT9uZXcgRGF0ZShlLmN1cnJlbnRZZWFyLGUuY3VycmVudE1vbnRoLGUuY3VycmVudERheSk6bmV3IERhdGUoOTk5OSw5LDkpKSxYPXRoaXMuX2dldE1pbk1heERhdGUoZSxcIm1pblwiKSwkPXRoaXMuX2dldE1pbk1heERhdGUoZSxcIm1heFwiKSxaPWUuZHJhd01vbnRoLVYsZXQ9ZS5kcmF3WWVhcjtpZigwPlomJihaKz0xMixldC0tKSwkKWZvcih0PXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKCQuZ2V0RnVsbFllYXIoKSwkLmdldE1vbnRoKCktS1swXSpLWzFdKzEsJC5nZXREYXRlKCkpKSx0PVgmJlg+dD9YOnQ7dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZXQsWiwxKSk+dDspWi0tLDA+WiYmKFo9MTEsZXQtLSk7Zm9yKGUuZHJhd01vbnRoPVosZS5kcmF3WWVhcj1ldCxpPXRoaXMuX2dldChlLFwicHJldlRleHRcIiksaT1xP3RoaXMuZm9ybWF0RGF0ZShpLHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGV0LFotVSwxKSksdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGUpKTppLHM9dGhpcy5fY2FuQWRqdXN0TW9udGgoZSwtMSxldCxaKT9cIjxhIGNsYXNzPSd1aS1kYXRlcGlja2VyLXByZXYgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSdwcmV2JyBkYXRhLWV2ZW50PSdjbGljaycgdGl0bGU9J1wiK2krXCInPjxzcGFuIGNsYXNzPSd1aS1pY29uIHVpLWljb24tY2lyY2xlLXRyaWFuZ2xlLVwiKyhZP1wiZVwiOlwid1wiKStcIic+XCIraStcIjwvc3Bhbj48L2E+XCI6Sj9cIlwiOlwiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItcHJldiB1aS1jb3JuZXItYWxsIHVpLXN0YXRlLWRpc2FibGVkJyB0aXRsZT0nXCIraStcIic+PHNwYW4gY2xhc3M9J3VpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtXCIrKFk/XCJlXCI6XCJ3XCIpK1wiJz5cIitpK1wiPC9zcGFuPjwvYT5cIixuPXRoaXMuX2dldChlLFwibmV4dFRleHRcIiksbj1xP3RoaXMuZm9ybWF0RGF0ZShuLHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGV0LForVSwxKSksdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGUpKTpuLGE9dGhpcy5fY2FuQWRqdXN0TW9udGgoZSwxLGV0LFopP1wiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItbmV4dCB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J25leHQnIGRhdGEtZXZlbnQ9J2NsaWNrJyB0aXRsZT0nXCIrbitcIic+PHNwYW4gY2xhc3M9J3VpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtXCIrKFk/XCJ3XCI6XCJlXCIpK1wiJz5cIituK1wiPC9zcGFuPjwvYT5cIjpKP1wiXCI6XCI8YSBjbGFzcz0ndWktZGF0ZXBpY2tlci1uZXh0IHVpLWNvcm5lci1hbGwgdWktc3RhdGUtZGlzYWJsZWQnIHRpdGxlPSdcIituK1wiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIisoWT9cIndcIjpcImVcIikrXCInPlwiK24rXCI8L3NwYW4+PC9hPlwiLG89dGhpcy5fZ2V0KGUsXCJjdXJyZW50VGV4dFwiKSxyPXRoaXMuX2dldChlLFwiZ290b0N1cnJlbnRcIikmJmUuY3VycmVudERheT9HOlIsbz1xP3RoaXMuZm9ybWF0RGF0ZShvLHIsdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGUpKTpvLGg9ZS5pbmxpbmU/XCJcIjpcIjxidXR0b24gdHlwZT0nYnV0dG9uJyBjbGFzcz0ndWktZGF0ZXBpY2tlci1jbG9zZSB1aS1zdGF0ZS1kZWZhdWx0IHVpLXByaW9yaXR5LXByaW1hcnkgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSdoaWRlJyBkYXRhLWV2ZW50PSdjbGljayc+XCIrdGhpcy5fZ2V0KGUsXCJjbG9zZVRleHRcIikrXCI8L2J1dHRvbj5cIixsPUI/XCI8ZGl2IGNsYXNzPSd1aS1kYXRlcGlja2VyLWJ1dHRvbnBhbmUgdWktd2lkZ2V0LWNvbnRlbnQnPlwiKyhZP2g6XCJcIikrKHRoaXMuX2lzSW5SYW5nZShlLHIpP1wiPGJ1dHRvbiB0eXBlPSdidXR0b24nIGNsYXNzPSd1aS1kYXRlcGlja2VyLWN1cnJlbnQgdWktc3RhdGUtZGVmYXVsdCB1aS1wcmlvcml0eS1zZWNvbmRhcnkgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSd0b2RheScgZGF0YS1ldmVudD0nY2xpY2snPlwiK28rXCI8L2J1dHRvbj5cIjpcIlwiKSsoWT9cIlwiOmgpK1wiPC9kaXY+XCI6XCJcIix1PXBhcnNlSW50KHRoaXMuX2dldChlLFwiZmlyc3REYXlcIiksMTApLHU9aXNOYU4odSk/MDp1LGQ9dGhpcy5fZ2V0KGUsXCJzaG93V2Vla1wiKSxjPXRoaXMuX2dldChlLFwiZGF5TmFtZXNcIikscD10aGlzLl9nZXQoZSxcImRheU5hbWVzTWluXCIpLGY9dGhpcy5fZ2V0KGUsXCJtb250aE5hbWVzXCIpLG09dGhpcy5fZ2V0KGUsXCJtb250aE5hbWVzU2hvcnRcIiksZz10aGlzLl9nZXQoZSxcImJlZm9yZVNob3dEYXlcIiksdj10aGlzLl9nZXQoZSxcInNob3dPdGhlck1vbnRoc1wiKSx5PXRoaXMuX2dldChlLFwic2VsZWN0T3RoZXJNb250aHNcIiksYj10aGlzLl9nZXREZWZhdWx0RGF0ZShlKSxfPVwiXCIsdz0wO0tbMF0+dzt3Kyspe2ZvcihrPVwiXCIsdGhpcy5tYXhSb3dzPTQsVD0wO0tbMV0+VDtUKyspe2lmKEQ9dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZXQsWixlLnNlbGVjdGVkRGF5KSksUz1cIiB1aS1jb3JuZXItYWxsXCIsTT1cIlwiLFEpe2lmKE0rPVwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1ncm91cFwiLEtbMV0+MSlzd2l0Y2goVCl7Y2FzZSAwOk0rPVwiIHVpLWRhdGVwaWNrZXItZ3JvdXAtZmlyc3RcIixTPVwiIHVpLWNvcm5lci1cIisoWT9cInJpZ2h0XCI6XCJsZWZ0XCIpO2JyZWFrO2Nhc2UgS1sxXS0xOk0rPVwiIHVpLWRhdGVwaWNrZXItZ3JvdXAtbGFzdFwiLFM9XCIgdWktY29ybmVyLVwiKyhZP1wibGVmdFwiOlwicmlnaHRcIik7YnJlYWs7ZGVmYXVsdDpNKz1cIiB1aS1kYXRlcGlja2VyLWdyb3VwLW1pZGRsZVwiLFM9XCJcIn1NKz1cIic+XCJ9Zm9yKE0rPVwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1oZWFkZXIgdWktd2lkZ2V0LWhlYWRlciB1aS1oZWxwZXItY2xlYXJmaXhcIitTK1wiJz5cIisoL2FsbHxsZWZ0Ly50ZXN0KFMpJiYwPT09dz9ZP2E6czpcIlwiKSsoL2FsbHxyaWdodC8udGVzdChTKSYmMD09PXc/WT9zOmE6XCJcIikrdGhpcy5fZ2VuZXJhdGVNb250aFllYXJIZWFkZXIoZSxaLGV0LFgsJCx3PjB8fFQ+MCxmLG0pK1wiPC9kaXY+PHRhYmxlIGNsYXNzPSd1aS1kYXRlcGlja2VyLWNhbGVuZGFyJz48dGhlYWQ+XCIrXCI8dHI+XCIsQz1kP1wiPHRoIGNsYXNzPSd1aS1kYXRlcGlja2VyLXdlZWstY29sJz5cIit0aGlzLl9nZXQoZSxcIndlZWtIZWFkZXJcIikrXCI8L3RoPlwiOlwiXCIseD0wOzc+eDt4KyspTj0oeCt1KSU3LEMrPVwiPHRoIHNjb3BlPSdjb2wnXCIrKCh4K3UrNiklNz49NT9cIiBjbGFzcz0ndWktZGF0ZXBpY2tlci13ZWVrLWVuZCdcIjpcIlwiKStcIj5cIitcIjxzcGFuIHRpdGxlPSdcIitjW05dK1wiJz5cIitwW05dK1wiPC9zcGFuPjwvdGg+XCI7Zm9yKE0rPUMrXCI8L3RyPjwvdGhlYWQ+PHRib2R5PlwiLEE9dGhpcy5fZ2V0RGF5c0luTW9udGgoZXQsWiksZXQ9PT1lLnNlbGVjdGVkWWVhciYmWj09PWUuc2VsZWN0ZWRNb250aCYmKGUuc2VsZWN0ZWREYXk9TWF0aC5taW4oZS5zZWxlY3RlZERheSxBKSksUD0odGhpcy5fZ2V0Rmlyc3REYXlPZk1vbnRoKGV0LFopLXUrNyklNyxJPU1hdGguY2VpbCgoUCtBKS83KSxIPVE/dGhpcy5tYXhSb3dzPkk/dGhpcy5tYXhSb3dzOkk6SSx0aGlzLm1heFJvd3M9SCx6PXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGV0LFosMS1QKSksRj0wO0g+RjtGKyspe2ZvcihNKz1cIjx0cj5cIixFPWQ/XCI8dGQgY2xhc3M9J3VpLWRhdGVwaWNrZXItd2Vlay1jb2wnPlwiK3RoaXMuX2dldChlLFwiY2FsY3VsYXRlV2Vla1wiKSh6KStcIjwvdGQ+XCI6XCJcIix4PTA7Nz54O3grKylPPWc/Zy5hcHBseShlLmlucHV0P2UuaW5wdXRbMF06bnVsbCxbel0pOlshMCxcIlwiXSxqPXouZ2V0TW9udGgoKSE9PVosVz1qJiYheXx8IU9bMF18fFgmJlg+enx8JCYmej4kLEUrPVwiPHRkIGNsYXNzPSdcIisoKHgrdSs2KSU3Pj01P1wiIHVpLWRhdGVwaWNrZXItd2Vlay1lbmRcIjpcIlwiKSsoaj9cIiB1aS1kYXRlcGlja2VyLW90aGVyLW1vbnRoXCI6XCJcIikrKHouZ2V0VGltZSgpPT09RC5nZXRUaW1lKCkmJlo9PT1lLnNlbGVjdGVkTW9udGgmJmUuX2tleUV2ZW50fHxiLmdldFRpbWUoKT09PXouZ2V0VGltZSgpJiZiLmdldFRpbWUoKT09PUQuZ2V0VGltZSgpP1wiIFwiK3RoaXMuX2RheU92ZXJDbGFzczpcIlwiKSsoVz9cIiBcIit0aGlzLl91bnNlbGVjdGFibGVDbGFzcytcIiB1aS1zdGF0ZS1kaXNhYmxlZFwiOlwiXCIpKyhqJiYhdj9cIlwiOlwiIFwiK09bMV0rKHouZ2V0VGltZSgpPT09Ry5nZXRUaW1lKCk/XCIgXCIrdGhpcy5fY3VycmVudENsYXNzOlwiXCIpKyh6LmdldFRpbWUoKT09PVIuZ2V0VGltZSgpP1wiIHVpLWRhdGVwaWNrZXItdG9kYXlcIjpcIlwiKSkrXCInXCIrKGomJiF2fHwhT1syXT9cIlwiOlwiIHRpdGxlPSdcIitPWzJdLnJlcGxhY2UoLycvZyxcIiYjMzk7XCIpK1wiJ1wiKSsoVz9cIlwiOlwiIGRhdGEtaGFuZGxlcj0nc2VsZWN0RGF5JyBkYXRhLWV2ZW50PSdjbGljaycgZGF0YS1tb250aD0nXCIrei5nZXRNb250aCgpK1wiJyBkYXRhLXllYXI9J1wiK3ouZ2V0RnVsbFllYXIoKStcIidcIikrXCI+XCIrKGomJiF2P1wiJiN4YTA7XCI6Vz9cIjxzcGFuIGNsYXNzPSd1aS1zdGF0ZS1kZWZhdWx0Jz5cIit6LmdldERhdGUoKStcIjwvc3Bhbj5cIjpcIjxhIGNsYXNzPSd1aS1zdGF0ZS1kZWZhdWx0XCIrKHouZ2V0VGltZSgpPT09Ui5nZXRUaW1lKCk/XCIgdWktc3RhdGUtaGlnaGxpZ2h0XCI6XCJcIikrKHouZ2V0VGltZSgpPT09Ry5nZXRUaW1lKCk/XCIgdWktc3RhdGUtYWN0aXZlXCI6XCJcIikrKGo/XCIgdWktcHJpb3JpdHktc2Vjb25kYXJ5XCI6XCJcIikrXCInIGhyZWY9JyMnPlwiK3ouZ2V0RGF0ZSgpK1wiPC9hPlwiKStcIjwvdGQ+XCIsei5zZXREYXRlKHouZ2V0RGF0ZSgpKzEpLHo9dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3Qoeik7TSs9RStcIjwvdHI+XCJ9WisrLFo+MTEmJihaPTAsZXQrKyksTSs9XCI8L3Rib2R5PjwvdGFibGU+XCIrKFE/XCI8L2Rpdj5cIisoS1swXT4wJiZUPT09S1sxXS0xP1wiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1yb3ctYnJlYWsnPjwvZGl2PlwiOlwiXCIpOlwiXCIpLGsrPU19Xys9a31yZXR1cm4gXys9bCxlLl9rZXlFdmVudD0hMSxffSxfZ2VuZXJhdGVNb250aFllYXJIZWFkZXI6ZnVuY3Rpb24oZSx0LGkscyxuLGEsbyxyKXt2YXIgaCxsLHUsZCxjLHAsZixtLGc9dGhpcy5fZ2V0KGUsXCJjaGFuZ2VNb250aFwiKSx2PXRoaXMuX2dldChlLFwiY2hhbmdlWWVhclwiKSx5PXRoaXMuX2dldChlLFwic2hvd01vbnRoQWZ0ZXJZZWFyXCIpLGI9XCI8ZGl2IGNsYXNzPSd1aS1kYXRlcGlja2VyLXRpdGxlJz5cIixfPVwiXCI7aWYoYXx8IWcpXys9XCI8c3BhbiBjbGFzcz0ndWktZGF0ZXBpY2tlci1tb250aCc+XCIrb1t0XStcIjwvc3Bhbj5cIjtlbHNle2ZvcihoPXMmJnMuZ2V0RnVsbFllYXIoKT09PWksbD1uJiZuLmdldEZ1bGxZZWFyKCk9PT1pLF8rPVwiPHNlbGVjdCBjbGFzcz0ndWktZGF0ZXBpY2tlci1tb250aCcgZGF0YS1oYW5kbGVyPSdzZWxlY3RNb250aCcgZGF0YS1ldmVudD0nY2hhbmdlJz5cIix1PTA7MTI+dTt1KyspKCFofHx1Pj1zLmdldE1vbnRoKCkpJiYoIWx8fG4uZ2V0TW9udGgoKT49dSkmJihfKz1cIjxvcHRpb24gdmFsdWU9J1wiK3UrXCInXCIrKHU9PT10P1wiIHNlbGVjdGVkPSdzZWxlY3RlZCdcIjpcIlwiKStcIj5cIityW3VdK1wiPC9vcHRpb24+XCIpO18rPVwiPC9zZWxlY3Q+XCJ9aWYoeXx8KGIrPV8rKCFhJiZnJiZ2P1wiXCI6XCImI3hhMDtcIikpLCFlLnllYXJzaHRtbClpZihlLnllYXJzaHRtbD1cIlwiLGF8fCF2KWIrPVwiPHNwYW4gY2xhc3M9J3VpLWRhdGVwaWNrZXIteWVhcic+XCIraStcIjwvc3Bhbj5cIjtlbHNle2ZvcihkPXRoaXMuX2dldChlLFwieWVhclJhbmdlXCIpLnNwbGl0KFwiOlwiKSxjPShuZXcgRGF0ZSkuZ2V0RnVsbFllYXIoKSxwPWZ1bmN0aW9uKGUpe3ZhciB0PWUubWF0Y2goL2NbK1xcLV0uKi8pP2krcGFyc2VJbnQoZS5zdWJzdHJpbmcoMSksMTApOmUubWF0Y2goL1srXFwtXS4qLyk/YytwYXJzZUludChlLDEwKTpwYXJzZUludChlLDEwKTtyZXR1cm4gaXNOYU4odCk/Yzp0fSxmPXAoZFswXSksbT1NYXRoLm1heChmLHAoZFsxXXx8XCJcIikpLGY9cz9NYXRoLm1heChmLHMuZ2V0RnVsbFllYXIoKSk6ZixtPW4/TWF0aC5taW4obSxuLmdldEZ1bGxZZWFyKCkpOm0sZS55ZWFyc2h0bWwrPVwiPHNlbGVjdCBjbGFzcz0ndWktZGF0ZXBpY2tlci15ZWFyJyBkYXRhLWhhbmRsZXI9J3NlbGVjdFllYXInIGRhdGEtZXZlbnQ9J2NoYW5nZSc+XCI7bT49ZjtmKyspZS55ZWFyc2h0bWwrPVwiPG9wdGlvbiB2YWx1ZT0nXCIrZitcIidcIisoZj09PWk/XCIgc2VsZWN0ZWQ9J3NlbGVjdGVkJ1wiOlwiXCIpK1wiPlwiK2YrXCI8L29wdGlvbj5cIjtlLnllYXJzaHRtbCs9XCI8L3NlbGVjdD5cIixiKz1lLnllYXJzaHRtbCxlLnllYXJzaHRtbD1udWxsfXJldHVybiBiKz10aGlzLl9nZXQoZSxcInllYXJTdWZmaXhcIikseSYmKGIrPSghYSYmZyYmdj9cIlwiOlwiJiN4YTA7XCIpK18pLGIrPVwiPC9kaXY+XCJ9LF9hZGp1c3RJbnN0RGF0ZTpmdW5jdGlvbihlLHQsaSl7dmFyIHM9ZS5kcmF3WWVhcisoXCJZXCI9PT1pP3Q6MCksbj1lLmRyYXdNb250aCsoXCJNXCI9PT1pP3Q6MCksYT1NYXRoLm1pbihlLnNlbGVjdGVkRGF5LHRoaXMuX2dldERheXNJbk1vbnRoKHMsbikpKyhcIkRcIj09PWk/dDowKSxvPXRoaXMuX3Jlc3RyaWN0TWluTWF4KGUsdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUocyxuLGEpKSk7ZS5zZWxlY3RlZERheT1vLmdldERhdGUoKSxlLmRyYXdNb250aD1lLnNlbGVjdGVkTW9udGg9by5nZXRNb250aCgpLGUuZHJhd1llYXI9ZS5zZWxlY3RlZFllYXI9by5nZXRGdWxsWWVhcigpLChcIk1cIj09PWl8fFwiWVwiPT09aSkmJnRoaXMuX25vdGlmeUNoYW5nZShlKX0sX3Jlc3RyaWN0TWluTWF4OmZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy5fZ2V0TWluTWF4RGF0ZShlLFwibWluXCIpLHM9dGhpcy5fZ2V0TWluTWF4RGF0ZShlLFwibWF4XCIpLG49aSYmaT50P2k6dDtyZXR1cm4gcyYmbj5zP3M6bn0sX25vdGlmeUNoYW5nZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nZXQoZSxcIm9uQ2hhbmdlTW9udGhZZWFyXCIpO3QmJnQuYXBwbHkoZS5pbnB1dD9lLmlucHV0WzBdOm51bGwsW2Uuc2VsZWN0ZWRZZWFyLGUuc2VsZWN0ZWRNb250aCsxLGVdKX0sX2dldE51bWJlck9mTW9udGhzOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuX2dldChlLFwibnVtYmVyT2ZNb250aHNcIik7cmV0dXJuIG51bGw9PXQ/WzEsMV06XCJudW1iZXJcIj09dHlwZW9mIHQ/WzEsdF06dH0sX2dldE1pbk1heERhdGU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5fZGV0ZXJtaW5lRGF0ZShlLHRoaXMuX2dldChlLHQrXCJEYXRlXCIpLG51bGwpfSxfZ2V0RGF5c0luTW9udGg6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gMzItdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZSx0LDMyKSkuZ2V0RGF0ZSgpfSxfZ2V0Rmlyc3REYXlPZk1vbnRoOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIG5ldyBEYXRlKGUsdCwxKS5nZXREYXkoKX0sX2NhbkFkanVzdE1vbnRoOmZ1bmN0aW9uKGUsdCxpLHMpe3ZhciBuPXRoaXMuX2dldE51bWJlck9mTW9udGhzKGUpLGE9dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoaSxzKygwPnQ/dDpuWzBdKm5bMV0pLDEpKTtyZXR1cm4gMD50JiZhLnNldERhdGUodGhpcy5fZ2V0RGF5c0luTW9udGgoYS5nZXRGdWxsWWVhcigpLGEuZ2V0TW9udGgoKSkpLHRoaXMuX2lzSW5SYW5nZShlLGEpfSxfaXNJblJhbmdlOmZ1bmN0aW9uKGUsdCl7dmFyIGkscyxuPXRoaXMuX2dldE1pbk1heERhdGUoZSxcIm1pblwiKSxhPXRoaXMuX2dldE1pbk1heERhdGUoZSxcIm1heFwiKSxvPW51bGwscj1udWxsLGg9dGhpcy5fZ2V0KGUsXCJ5ZWFyUmFuZ2VcIik7cmV0dXJuIGgmJihpPWguc3BsaXQoXCI6XCIpLHM9KG5ldyBEYXRlKS5nZXRGdWxsWWVhcigpLG89cGFyc2VJbnQoaVswXSwxMCkscj1wYXJzZUludChpWzFdLDEwKSxpWzBdLm1hdGNoKC9bK1xcLV0uKi8pJiYobys9cyksaVsxXS5tYXRjaCgvWytcXC1dLiovKSYmKHIrPXMpKSwoIW58fHQuZ2V0VGltZSgpPj1uLmdldFRpbWUoKSkmJighYXx8dC5nZXRUaW1lKCk8PWEuZ2V0VGltZSgpKSYmKCFvfHx0LmdldEZ1bGxZZWFyKCk+PW8pJiYoIXJ8fHI+PXQuZ2V0RnVsbFllYXIoKSl9LF9nZXRGb3JtYXRDb25maWc6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5fZ2V0KGUsXCJzaG9ydFllYXJDdXRvZmZcIik7cmV0dXJuIHQ9XCJzdHJpbmdcIiE9dHlwZW9mIHQ/dDoobmV3IERhdGUpLmdldEZ1bGxZZWFyKCklMTAwK3BhcnNlSW50KHQsMTApLHtzaG9ydFllYXJDdXRvZmY6dCxkYXlOYW1lc1Nob3J0OnRoaXMuX2dldChlLFwiZGF5TmFtZXNTaG9ydFwiKSxkYXlOYW1lczp0aGlzLl9nZXQoZSxcImRheU5hbWVzXCIpLG1vbnRoTmFtZXNTaG9ydDp0aGlzLl9nZXQoZSxcIm1vbnRoTmFtZXNTaG9ydFwiKSxtb250aE5hbWVzOnRoaXMuX2dldChlLFwibW9udGhOYW1lc1wiKX19LF9mb3JtYXREYXRlOmZ1bmN0aW9uKGUsdCxpLHMpe3R8fChlLmN1cnJlbnREYXk9ZS5zZWxlY3RlZERheSxlLmN1cnJlbnRNb250aD1lLnNlbGVjdGVkTW9udGgsZS5jdXJyZW50WWVhcj1lLnNlbGVjdGVkWWVhcik7dmFyIG49dD9cIm9iamVjdFwiPT10eXBlb2YgdD90OnRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHMsaSx0KSk6dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZS5jdXJyZW50WWVhcixlLmN1cnJlbnRNb250aCxlLmN1cnJlbnREYXkpKTtyZXR1cm4gdGhpcy5mb3JtYXREYXRlKHRoaXMuX2dldChlLFwiZGF0ZUZvcm1hdFwiKSxuLHRoaXMuX2dldEZvcm1hdENvbmZpZyhlKSl9fSksZS5mbi5kYXRlcGlja2VyPWZ1bmN0aW9uKHQpe2lmKCF0aGlzLmxlbmd0aClyZXR1cm4gdGhpcztlLmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWR8fChlKGRvY3VtZW50KS5tb3VzZWRvd24oZS5kYXRlcGlja2VyLl9jaGVja0V4dGVybmFsQ2xpY2spLGUuZGF0ZXBpY2tlci5pbml0aWFsaXplZD0hMCksMD09PWUoXCIjXCIrZS5kYXRlcGlja2VyLl9tYWluRGl2SWQpLmxlbmd0aCYmZShcImJvZHlcIikuYXBwZW5kKGUuZGF0ZXBpY2tlci5kcERpdik7dmFyIGk9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO3JldHVyblwic3RyaW5nXCIhPXR5cGVvZiB0fHxcImlzRGlzYWJsZWRcIiE9PXQmJlwiZ2V0RGF0ZVwiIT09dCYmXCJ3aWRnZXRcIiE9PXQ/XCJvcHRpb25cIj09PXQmJjI9PT1hcmd1bWVudHMubGVuZ3RoJiZcInN0cmluZ1wiPT10eXBlb2YgYXJndW1lbnRzWzFdP2UuZGF0ZXBpY2tlcltcIl9cIit0K1wiRGF0ZXBpY2tlclwiXS5hcHBseShlLmRhdGVwaWNrZXIsW3RoaXNbMF1dLmNvbmNhdChpKSk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7XCJzdHJpbmdcIj09dHlwZW9mIHQ/ZS5kYXRlcGlja2VyW1wiX1wiK3QrXCJEYXRlcGlja2VyXCJdLmFwcGx5KGUuZGF0ZXBpY2tlcixbdGhpc10uY29uY2F0KGkpKTplLmRhdGVwaWNrZXIuX2F0dGFjaERhdGVwaWNrZXIodGhpcyx0KX0pOmUuZGF0ZXBpY2tlcltcIl9cIit0K1wiRGF0ZXBpY2tlclwiXS5hcHBseShlLmRhdGVwaWNrZXIsW3RoaXNbMF1dLmNvbmNhdChpKSl9LGUuZGF0ZXBpY2tlcj1uZXcgbixlLmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWQ9ITEsZS5kYXRlcGlja2VyLnV1aWQ9KG5ldyBEYXRlKS5nZXRUaW1lKCksZS5kYXRlcGlja2VyLnZlcnNpb249XCIxLjExLjRcIixlLmRhdGVwaWNrZXIsZS53aWRnZXQoXCJ1aS5kcmFnZ2FibGVcIixlLnVpLm1vdXNlLHt2ZXJzaW9uOlwiMS4xMS40XCIsd2lkZ2V0RXZlbnRQcmVmaXg6XCJkcmFnXCIsb3B0aW9uczp7YWRkQ2xhc3NlczohMCxhcHBlbmRUbzpcInBhcmVudFwiLGF4aXM6ITEsY29ubmVjdFRvU29ydGFibGU6ITEsY29udGFpbm1lbnQ6ITEsY3Vyc29yOlwiYXV0b1wiLGN1cnNvckF0OiExLGdyaWQ6ITEsaGFuZGxlOiExLGhlbHBlcjpcIm9yaWdpbmFsXCIsaWZyYW1lRml4OiExLG9wYWNpdHk6ITEscmVmcmVzaFBvc2l0aW9uczohMSxyZXZlcnQ6ITEscmV2ZXJ0RHVyYXRpb246NTAwLHNjb3BlOlwiZGVmYXVsdFwiLHNjcm9sbDohMCxzY3JvbGxTZW5zaXRpdml0eToyMCxzY3JvbGxTcGVlZDoyMCxzbmFwOiExLHNuYXBNb2RlOlwiYm90aFwiLHNuYXBUb2xlcmFuY2U6MjAsc3RhY2s6ITEsekluZGV4OiExLGRyYWc6bnVsbCxzdGFydDpudWxsLHN0b3A6bnVsbH0sX2NyZWF0ZTpmdW5jdGlvbigpe1wib3JpZ2luYWxcIj09PXRoaXMub3B0aW9ucy5oZWxwZXImJnRoaXMuX3NldFBvc2l0aW9uUmVsYXRpdmUoKSx0aGlzLm9wdGlvbnMuYWRkQ2xhc3NlcyYmdGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktZHJhZ2dhYmxlXCIpLHRoaXMub3B0aW9ucy5kaXNhYmxlZCYmdGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktZHJhZ2dhYmxlLWRpc2FibGVkXCIpLHRoaXMuX3NldEhhbmRsZUNsYXNzTmFtZSgpLHRoaXMuX21vdXNlSW5pdCgpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsdCl7dGhpcy5fc3VwZXIoZSx0KSxcImhhbmRsZVwiPT09ZSYmKHRoaXMuX3JlbW92ZUhhbmRsZUNsYXNzTmFtZSgpLHRoaXMuX3NldEhhbmRsZUNsYXNzTmFtZSgpKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXtyZXR1cm4odGhpcy5oZWxwZXJ8fHRoaXMuZWxlbWVudCkuaXMoXCIudWktZHJhZ2dhYmxlLWRyYWdnaW5nXCIpPyh0aGlzLmRlc3Ryb3lPbkNsZWFyPSEwLHZvaWQgMCk6KHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLWRyYWdnYWJsZSB1aS1kcmFnZ2FibGUtZHJhZ2dpbmcgdWktZHJhZ2dhYmxlLWRpc2FibGVkXCIpLHRoaXMuX3JlbW92ZUhhbmRsZUNsYXNzTmFtZSgpLHRoaXMuX21vdXNlRGVzdHJveSgpLHZvaWQgMCl9LF9tb3VzZUNhcHR1cmU6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5vcHRpb25zO3JldHVybiB0aGlzLl9ibHVyQWN0aXZlRWxlbWVudCh0KSx0aGlzLmhlbHBlcnx8aS5kaXNhYmxlZHx8ZSh0LnRhcmdldCkuY2xvc2VzdChcIi51aS1yZXNpemFibGUtaGFuZGxlXCIpLmxlbmd0aD4wPyExOih0aGlzLmhhbmRsZT10aGlzLl9nZXRIYW5kbGUodCksdGhpcy5oYW5kbGU/KHRoaXMuX2Jsb2NrRnJhbWVzKGkuaWZyYW1lRml4PT09ITA/XCJpZnJhbWVcIjppLmlmcmFtZUZpeCksITApOiExKX0sX2Jsb2NrRnJhbWVzOmZ1bmN0aW9uKHQpe3RoaXMuaWZyYW1lQmxvY2tzPXRoaXMuZG9jdW1lbnQuZmluZCh0KS5tYXAoZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpO3JldHVybiBlKFwiPGRpdj5cIikuY3NzKFwicG9zaXRpb25cIixcImFic29sdXRlXCIpLmFwcGVuZFRvKHQucGFyZW50KCkpLm91dGVyV2lkdGgodC5vdXRlcldpZHRoKCkpLm91dGVySGVpZ2h0KHQub3V0ZXJIZWlnaHQoKSkub2Zmc2V0KHQub2Zmc2V0KCkpWzBdfSl9LF91bmJsb2NrRnJhbWVzOmZ1bmN0aW9uKCl7dGhpcy5pZnJhbWVCbG9ja3MmJih0aGlzLmlmcmFtZUJsb2Nrcy5yZW1vdmUoKSxkZWxldGUgdGhpcy5pZnJhbWVCbG9ja3MpfSxfYmx1ckFjdGl2ZUVsZW1lbnQ6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5kb2N1bWVudFswXTtpZih0aGlzLmhhbmRsZUVsZW1lbnQuaXModC50YXJnZXQpKXRyeXtpLmFjdGl2ZUVsZW1lbnQmJlwiYm9keVwiIT09aS5hY3RpdmVFbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkmJmUoaS5hY3RpdmVFbGVtZW50KS5ibHVyKCl9Y2F0Y2gocyl7fX0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5vcHRpb25zO3JldHVybiB0aGlzLmhlbHBlcj10aGlzLl9jcmVhdGVIZWxwZXIodCksdGhpcy5oZWxwZXIuYWRkQ2xhc3MoXCJ1aS1kcmFnZ2FibGUtZHJhZ2dpbmdcIiksdGhpcy5fY2FjaGVIZWxwZXJQcm9wb3J0aW9ucygpLGUudWkuZGRtYW5hZ2VyJiYoZS51aS5kZG1hbmFnZXIuY3VycmVudD10aGlzKSx0aGlzLl9jYWNoZU1hcmdpbnMoKSx0aGlzLmNzc1Bvc2l0aW9uPXRoaXMuaGVscGVyLmNzcyhcInBvc2l0aW9uXCIpLHRoaXMuc2Nyb2xsUGFyZW50PXRoaXMuaGVscGVyLnNjcm9sbFBhcmVudCghMCksdGhpcy5vZmZzZXRQYXJlbnQ9dGhpcy5oZWxwZXIub2Zmc2V0UGFyZW50KCksdGhpcy5oYXNGaXhlZEFuY2VzdG9yPXRoaXMuaGVscGVyLnBhcmVudHMoKS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm5cImZpeGVkXCI9PT1lKHRoaXMpLmNzcyhcInBvc2l0aW9uXCIpfSkubGVuZ3RoPjAsdGhpcy5wb3NpdGlvbkFicz10aGlzLmVsZW1lbnQub2Zmc2V0KCksdGhpcy5fcmVmcmVzaE9mZnNldHModCksdGhpcy5vcmlnaW5hbFBvc2l0aW9uPXRoaXMucG9zaXRpb249dGhpcy5fZ2VuZXJhdGVQb3NpdGlvbih0LCExKSx0aGlzLm9yaWdpbmFsUGFnZVg9dC5wYWdlWCx0aGlzLm9yaWdpbmFsUGFnZVk9dC5wYWdlWSxpLmN1cnNvckF0JiZ0aGlzLl9hZGp1c3RPZmZzZXRGcm9tSGVscGVyKGkuY3Vyc29yQXQpLHRoaXMuX3NldENvbnRhaW5tZW50KCksdGhpcy5fdHJpZ2dlcihcInN0YXJ0XCIsdCk9PT0hMT8odGhpcy5fY2xlYXIoKSwhMSk6KHRoaXMuX2NhY2hlSGVscGVyUHJvcG9ydGlvbnMoKSxlLnVpLmRkbWFuYWdlciYmIWkuZHJvcEJlaGF2aW91ciYmZS51aS5kZG1hbmFnZXIucHJlcGFyZU9mZnNldHModGhpcyx0KSx0aGlzLl9ub3JtYWxpemVSaWdodEJvdHRvbSgpLHRoaXMuX21vdXNlRHJhZyh0LCEwKSxlLnVpLmRkbWFuYWdlciYmZS51aS5kZG1hbmFnZXIuZHJhZ1N0YXJ0KHRoaXMsdCksITApfSxfcmVmcmVzaE9mZnNldHM6ZnVuY3Rpb24oZSl7dGhpcy5vZmZzZXQ9e3RvcDp0aGlzLnBvc2l0aW9uQWJzLnRvcC10aGlzLm1hcmdpbnMudG9wLGxlZnQ6dGhpcy5wb3NpdGlvbkFicy5sZWZ0LXRoaXMubWFyZ2lucy5sZWZ0LHNjcm9sbDohMSxwYXJlbnQ6dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkscmVsYXRpdmU6dGhpcy5fZ2V0UmVsYXRpdmVPZmZzZXQoKX0sdGhpcy5vZmZzZXQuY2xpY2s9e2xlZnQ6ZS5wYWdlWC10aGlzLm9mZnNldC5sZWZ0LHRvcDplLnBhZ2VZLXRoaXMub2Zmc2V0LnRvcH19LF9tb3VzZURyYWc6ZnVuY3Rpb24odCxpKXtpZih0aGlzLmhhc0ZpeGVkQW5jZXN0b3ImJih0aGlzLm9mZnNldC5wYXJlbnQ9dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkpLHRoaXMucG9zaXRpb249dGhpcy5fZ2VuZXJhdGVQb3NpdGlvbih0LCEwKSx0aGlzLnBvc2l0aW9uQWJzPXRoaXMuX2NvbnZlcnRQb3NpdGlvblRvKFwiYWJzb2x1dGVcIiksIWkpe3ZhciBzPXRoaXMuX3VpSGFzaCgpO2lmKHRoaXMuX3RyaWdnZXIoXCJkcmFnXCIsdCxzKT09PSExKXJldHVybiB0aGlzLl9tb3VzZVVwKHt9KSwhMTt0aGlzLnBvc2l0aW9uPXMucG9zaXRpb259cmV0dXJuIHRoaXMuaGVscGVyWzBdLnN0eWxlLmxlZnQ9dGhpcy5wb3NpdGlvbi5sZWZ0K1wicHhcIix0aGlzLmhlbHBlclswXS5zdHlsZS50b3A9dGhpcy5wb3NpdGlvbi50b3ArXCJweFwiLGUudWkuZGRtYW5hZ2VyJiZlLnVpLmRkbWFuYWdlci5kcmFnKHRoaXMsdCksITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcyxzPSExO3JldHVybiBlLnVpLmRkbWFuYWdlciYmIXRoaXMub3B0aW9ucy5kcm9wQmVoYXZpb3VyJiYocz1lLnVpLmRkbWFuYWdlci5kcm9wKHRoaXMsdCkpLHRoaXMuZHJvcHBlZCYmKHM9dGhpcy5kcm9wcGVkLHRoaXMuZHJvcHBlZD0hMSksXCJpbnZhbGlkXCI9PT10aGlzLm9wdGlvbnMucmV2ZXJ0JiYhc3x8XCJ2YWxpZFwiPT09dGhpcy5vcHRpb25zLnJldmVydCYmc3x8dGhpcy5vcHRpb25zLnJldmVydD09PSEwfHxlLmlzRnVuY3Rpb24odGhpcy5vcHRpb25zLnJldmVydCkmJnRoaXMub3B0aW9ucy5yZXZlcnQuY2FsbCh0aGlzLmVsZW1lbnQscyk/ZSh0aGlzLmhlbHBlcikuYW5pbWF0ZSh0aGlzLm9yaWdpbmFsUG9zaXRpb24scGFyc2VJbnQodGhpcy5vcHRpb25zLnJldmVydER1cmF0aW9uLDEwKSxmdW5jdGlvbigpe2kuX3RyaWdnZXIoXCJzdG9wXCIsdCkhPT0hMSYmaS5fY2xlYXIoKX0pOnRoaXMuX3RyaWdnZXIoXCJzdG9wXCIsdCkhPT0hMSYmdGhpcy5fY2xlYXIoKSwhMX0sX21vdXNlVXA6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX3VuYmxvY2tGcmFtZXMoKSxlLnVpLmRkbWFuYWdlciYmZS51aS5kZG1hbmFnZXIuZHJhZ1N0b3AodGhpcyx0KSx0aGlzLmhhbmRsZUVsZW1lbnQuaXModC50YXJnZXQpJiZ0aGlzLmVsZW1lbnQuZm9jdXMoKSxlLnVpLm1vdXNlLnByb3RvdHlwZS5fbW91c2VVcC5jYWxsKHRoaXMsdCl9LGNhbmNlbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmhlbHBlci5pcyhcIi51aS1kcmFnZ2FibGUtZHJhZ2dpbmdcIik/dGhpcy5fbW91c2VVcCh7fSk6dGhpcy5fY2xlYXIoKSx0aGlzfSxfZ2V0SGFuZGxlOmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLm9wdGlvbnMuaGFuZGxlPyEhZSh0LnRhcmdldCkuY2xvc2VzdCh0aGlzLmVsZW1lbnQuZmluZCh0aGlzLm9wdGlvbnMuaGFuZGxlKSkubGVuZ3RoOiEwfSxfc2V0SGFuZGxlQ2xhc3NOYW1lOmZ1bmN0aW9uKCl7dGhpcy5oYW5kbGVFbGVtZW50PXRoaXMub3B0aW9ucy5oYW5kbGU/dGhpcy5lbGVtZW50LmZpbmQodGhpcy5vcHRpb25zLmhhbmRsZSk6dGhpcy5lbGVtZW50LHRoaXMuaGFuZGxlRWxlbWVudC5hZGRDbGFzcyhcInVpLWRyYWdnYWJsZS1oYW5kbGVcIil9LF9yZW1vdmVIYW5kbGVDbGFzc05hbWU6ZnVuY3Rpb24oKXt0aGlzLmhhbmRsZUVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS1kcmFnZ2FibGUtaGFuZGxlXCIpfSxfY3JlYXRlSGVscGVyOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMub3B0aW9ucyxzPWUuaXNGdW5jdGlvbihpLmhlbHBlciksbj1zP2UoaS5oZWxwZXIuYXBwbHkodGhpcy5lbGVtZW50WzBdLFt0XSkpOlwiY2xvbmVcIj09PWkuaGVscGVyP3RoaXMuZWxlbWVudC5jbG9uZSgpLnJlbW92ZUF0dHIoXCJpZFwiKTp0aGlzLmVsZW1lbnQ7cmV0dXJuIG4ucGFyZW50cyhcImJvZHlcIikubGVuZ3RofHxuLmFwcGVuZFRvKFwicGFyZW50XCI9PT1pLmFwcGVuZFRvP3RoaXMuZWxlbWVudFswXS5wYXJlbnROb2RlOmkuYXBwZW5kVG8pLHMmJm5bMF09PT10aGlzLmVsZW1lbnRbMF0mJnRoaXMuX3NldFBvc2l0aW9uUmVsYXRpdmUoKSxuWzBdPT09dGhpcy5lbGVtZW50WzBdfHwvKGZpeGVkfGFic29sdXRlKS8udGVzdChuLmNzcyhcInBvc2l0aW9uXCIpKXx8bi5jc3MoXCJwb3NpdGlvblwiLFwiYWJzb2x1dGVcIiksbn0sX3NldFBvc2l0aW9uUmVsYXRpdmU6ZnVuY3Rpb24oKXsvXig/OnJ8YXxmKS8udGVzdCh0aGlzLmVsZW1lbnQuY3NzKFwicG9zaXRpb25cIikpfHwodGhpcy5lbGVtZW50WzBdLnN0eWxlLnBvc2l0aW9uPVwicmVsYXRpdmVcIil9LF9hZGp1c3RPZmZzZXRGcm9tSGVscGVyOmZ1bmN0aW9uKHQpe1wic3RyaW5nXCI9PXR5cGVvZiB0JiYodD10LnNwbGl0KFwiIFwiKSksZS5pc0FycmF5KHQpJiYodD17bGVmdDordFswXSx0b3A6K3RbMV18fDB9KSxcImxlZnRcImluIHQmJih0aGlzLm9mZnNldC5jbGljay5sZWZ0PXQubGVmdCt0aGlzLm1hcmdpbnMubGVmdCksXCJyaWdodFwiaW4gdCYmKHRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ9dGhpcy5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aC10LnJpZ2h0K3RoaXMubWFyZ2lucy5sZWZ0KSxcInRvcFwiaW4gdCYmKHRoaXMub2Zmc2V0LmNsaWNrLnRvcD10LnRvcCt0aGlzLm1hcmdpbnMudG9wKSxcImJvdHRvbVwiaW4gdCYmKHRoaXMub2Zmc2V0LmNsaWNrLnRvcD10aGlzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodC10LmJvdHRvbSt0aGlzLm1hcmdpbnMudG9wKX0sX2lzUm9vdE5vZGU6ZnVuY3Rpb24oZSl7cmV0dXJuLyhodG1sfGJvZHkpL2kudGVzdChlLnRhZ05hbWUpfHxlPT09dGhpcy5kb2N1bWVudFswXX0sX2dldFBhcmVudE9mZnNldDpmdW5jdGlvbigpe3ZhciB0PXRoaXMub2Zmc2V0UGFyZW50Lm9mZnNldCgpLGk9dGhpcy5kb2N1bWVudFswXTtyZXR1cm5cImFic29sdXRlXCI9PT10aGlzLmNzc1Bvc2l0aW9uJiZ0aGlzLnNjcm9sbFBhcmVudFswXSE9PWkmJmUuY29udGFpbnModGhpcy5zY3JvbGxQYXJlbnRbMF0sdGhpcy5vZmZzZXRQYXJlbnRbMF0pJiYodC5sZWZ0Kz10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxMZWZ0KCksdC50b3ArPXRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbFRvcCgpKSx0aGlzLl9pc1Jvb3ROb2RlKHRoaXMub2Zmc2V0UGFyZW50WzBdKSYmKHQ9e3RvcDowLGxlZnQ6MH0pLHt0b3A6dC50b3ArKHBhcnNlSW50KHRoaXMub2Zmc2V0UGFyZW50LmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLDEwKXx8MCksbGVmdDp0LmxlZnQrKHBhcnNlSW50KHRoaXMub2Zmc2V0UGFyZW50LmNzcyhcImJvcmRlckxlZnRXaWR0aFwiKSwxMCl8fDApfX0sX2dldFJlbGF0aXZlT2Zmc2V0OmZ1bmN0aW9uKCl7aWYoXCJyZWxhdGl2ZVwiIT09dGhpcy5jc3NQb3NpdGlvbilyZXR1cm57dG9wOjAsbGVmdDowfTt2YXIgZT10aGlzLmVsZW1lbnQucG9zaXRpb24oKSx0PXRoaXMuX2lzUm9vdE5vZGUodGhpcy5zY3JvbGxQYXJlbnRbMF0pO3JldHVybnt0b3A6ZS50b3AtKHBhcnNlSW50KHRoaXMuaGVscGVyLmNzcyhcInRvcFwiKSwxMCl8fDApKyh0PzA6dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsVG9wKCkpLGxlZnQ6ZS5sZWZ0LShwYXJzZUludCh0aGlzLmhlbHBlci5jc3MoXCJsZWZ0XCIpLDEwKXx8MCkrKHQ/MDp0aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxMZWZ0KCkpfX0sX2NhY2hlTWFyZ2luczpmdW5jdGlvbigpe3RoaXMubWFyZ2lucz17bGVmdDpwYXJzZUludCh0aGlzLmVsZW1lbnQuY3NzKFwibWFyZ2luTGVmdFwiKSwxMCl8fDAsdG9wOnBhcnNlSW50KHRoaXMuZWxlbWVudC5jc3MoXCJtYXJnaW5Ub3BcIiksMTApfHwwLHJpZ2h0OnBhcnNlSW50KHRoaXMuZWxlbWVudC5jc3MoXCJtYXJnaW5SaWdodFwiKSwxMCl8fDAsYm90dG9tOnBhcnNlSW50KHRoaXMuZWxlbWVudC5jc3MoXCJtYXJnaW5Cb3R0b21cIiksMTApfHwwfX0sX2NhY2hlSGVscGVyUHJvcG9ydGlvbnM6ZnVuY3Rpb24oKXt0aGlzLmhlbHBlclByb3BvcnRpb25zPXt3aWR0aDp0aGlzLmhlbHBlci5vdXRlcldpZHRoKCksaGVpZ2h0OnRoaXMuaGVscGVyLm91dGVySGVpZ2h0KCl9fSxfc2V0Q29udGFpbm1lbnQ6ZnVuY3Rpb24oKXt2YXIgdCxpLHMsbj10aGlzLm9wdGlvbnMsYT10aGlzLmRvY3VtZW50WzBdO3JldHVybiB0aGlzLnJlbGF0aXZlQ29udGFpbmVyPW51bGwsbi5jb250YWlubWVudD9cIndpbmRvd1wiPT09bi5jb250YWlubWVudD8odGhpcy5jb250YWlubWVudD1bZSh3aW5kb3cpLnNjcm9sbExlZnQoKS10aGlzLm9mZnNldC5yZWxhdGl2ZS5sZWZ0LXRoaXMub2Zmc2V0LnBhcmVudC5sZWZ0LGUod2luZG93KS5zY3JvbGxUb3AoKS10aGlzLm9mZnNldC5yZWxhdGl2ZS50b3AtdGhpcy5vZmZzZXQucGFyZW50LnRvcCxlKHdpbmRvdykuc2Nyb2xsTGVmdCgpK2Uod2luZG93KS53aWR0aCgpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtdGhpcy5tYXJnaW5zLmxlZnQsZSh3aW5kb3cpLnNjcm9sbFRvcCgpKyhlKHdpbmRvdykuaGVpZ2h0KCl8fGEuYm9keS5wYXJlbnROb2RlLnNjcm9sbEhlaWdodCktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQtdGhpcy5tYXJnaW5zLnRvcF0sdm9pZCAwKTpcImRvY3VtZW50XCI9PT1uLmNvbnRhaW5tZW50Pyh0aGlzLmNvbnRhaW5tZW50PVswLDAsZShhKS53aWR0aCgpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtdGhpcy5tYXJnaW5zLmxlZnQsKGUoYSkuaGVpZ2h0KCl8fGEuYm9keS5wYXJlbnROb2RlLnNjcm9sbEhlaWdodCktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQtdGhpcy5tYXJnaW5zLnRvcF0sdm9pZCAwKTpuLmNvbnRhaW5tZW50LmNvbnN0cnVjdG9yPT09QXJyYXk/KHRoaXMuY29udGFpbm1lbnQ9bi5jb250YWlubWVudCx2b2lkIDApOihcInBhcmVudFwiPT09bi5jb250YWlubWVudCYmKG4uY29udGFpbm1lbnQ9dGhpcy5oZWxwZXJbMF0ucGFyZW50Tm9kZSksaT1lKG4uY29udGFpbm1lbnQpLHM9aVswXSxzJiYodD0vKHNjcm9sbHxhdXRvKS8udGVzdChpLmNzcyhcIm92ZXJmbG93XCIpKSx0aGlzLmNvbnRhaW5tZW50PVsocGFyc2VJbnQoaS5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKSsocGFyc2VJbnQoaS5jc3MoXCJwYWRkaW5nTGVmdFwiKSwxMCl8fDApLChwYXJzZUludChpLmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLDEwKXx8MCkrKHBhcnNlSW50KGkuY3NzKFwicGFkZGluZ1RvcFwiKSwxMCl8fDApLCh0P01hdGgubWF4KHMuc2Nyb2xsV2lkdGgscy5vZmZzZXRXaWR0aCk6cy5vZmZzZXRXaWR0aCktKHBhcnNlSW50KGkuY3NzKFwiYm9yZGVyUmlnaHRXaWR0aFwiKSwxMCl8fDApLShwYXJzZUludChpLmNzcyhcInBhZGRpbmdSaWdodFwiKSwxMCl8fDApLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtdGhpcy5tYXJnaW5zLmxlZnQtdGhpcy5tYXJnaW5zLnJpZ2h0LCh0P01hdGgubWF4KHMuc2Nyb2xsSGVpZ2h0LHMub2Zmc2V0SGVpZ2h0KTpzLm9mZnNldEhlaWdodCktKHBhcnNlSW50KGkuY3NzKFwiYm9yZGVyQm90dG9tV2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoaS5jc3MoXCJwYWRkaW5nQm90dG9tXCIpLDEwKXx8MCktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQtdGhpcy5tYXJnaW5zLnRvcC10aGlzLm1hcmdpbnMuYm90dG9tXSx0aGlzLnJlbGF0aXZlQ29udGFpbmVyPWkpLHZvaWQgMCk6KHRoaXMuY29udGFpbm1lbnQ9bnVsbCx2b2lkIDApXHJcbn0sX2NvbnZlcnRQb3NpdGlvblRvOmZ1bmN0aW9uKGUsdCl7dHx8KHQ9dGhpcy5wb3NpdGlvbik7dmFyIGk9XCJhYnNvbHV0ZVwiPT09ZT8xOi0xLHM9dGhpcy5faXNSb290Tm9kZSh0aGlzLnNjcm9sbFBhcmVudFswXSk7cmV0dXJue3RvcDp0LnRvcCt0aGlzLm9mZnNldC5yZWxhdGl2ZS50b3AqaSt0aGlzLm9mZnNldC5wYXJlbnQudG9wKmktKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMub2Zmc2V0LnNjcm9sbC50b3A6cz8wOnRoaXMub2Zmc2V0LnNjcm9sbC50b3ApKmksbGVmdDp0LmxlZnQrdGhpcy5vZmZzZXQucmVsYXRpdmUubGVmdCppK3RoaXMub2Zmc2V0LnBhcmVudC5sZWZ0KmktKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMub2Zmc2V0LnNjcm9sbC5sZWZ0OnM/MDp0aGlzLm9mZnNldC5zY3JvbGwubGVmdCkqaX19LF9nZW5lcmF0ZVBvc2l0aW9uOmZ1bmN0aW9uKGUsdCl7dmFyIGkscyxuLGEsbz10aGlzLm9wdGlvbnMscj10aGlzLl9pc1Jvb3ROb2RlKHRoaXMuc2Nyb2xsUGFyZW50WzBdKSxoPWUucGFnZVgsbD1lLnBhZ2VZO3JldHVybiByJiZ0aGlzLm9mZnNldC5zY3JvbGx8fCh0aGlzLm9mZnNldC5zY3JvbGw9e3RvcDp0aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSxsZWZ0OnRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbExlZnQoKX0pLHQmJih0aGlzLmNvbnRhaW5tZW50JiYodGhpcy5yZWxhdGl2ZUNvbnRhaW5lcj8ocz10aGlzLnJlbGF0aXZlQ29udGFpbmVyLm9mZnNldCgpLGk9W3RoaXMuY29udGFpbm1lbnRbMF0rcy5sZWZ0LHRoaXMuY29udGFpbm1lbnRbMV0rcy50b3AsdGhpcy5jb250YWlubWVudFsyXStzLmxlZnQsdGhpcy5jb250YWlubWVudFszXStzLnRvcF0pOmk9dGhpcy5jb250YWlubWVudCxlLnBhZ2VYLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ8aVswXSYmKGg9aVswXSt0aGlzLm9mZnNldC5jbGljay5sZWZ0KSxlLnBhZ2VZLXRoaXMub2Zmc2V0LmNsaWNrLnRvcDxpWzFdJiYobD1pWzFdK3RoaXMub2Zmc2V0LmNsaWNrLnRvcCksZS5wYWdlWC10aGlzLm9mZnNldC5jbGljay5sZWZ0PmlbMl0mJihoPWlbMl0rdGhpcy5vZmZzZXQuY2xpY2subGVmdCksZS5wYWdlWS10aGlzLm9mZnNldC5jbGljay50b3A+aVszXSYmKGw9aVszXSt0aGlzLm9mZnNldC5jbGljay50b3ApKSxvLmdyaWQmJihuPW8uZ3JpZFsxXT90aGlzLm9yaWdpbmFsUGFnZVkrTWF0aC5yb3VuZCgobC10aGlzLm9yaWdpbmFsUGFnZVkpL28uZ3JpZFsxXSkqby5ncmlkWzFdOnRoaXMub3JpZ2luYWxQYWdlWSxsPWk/bi10aGlzLm9mZnNldC5jbGljay50b3A+PWlbMV18fG4tdGhpcy5vZmZzZXQuY2xpY2sudG9wPmlbM10/bjpuLXRoaXMub2Zmc2V0LmNsaWNrLnRvcD49aVsxXT9uLW8uZ3JpZFsxXTpuK28uZ3JpZFsxXTpuLGE9by5ncmlkWzBdP3RoaXMub3JpZ2luYWxQYWdlWCtNYXRoLnJvdW5kKChoLXRoaXMub3JpZ2luYWxQYWdlWCkvby5ncmlkWzBdKSpvLmdyaWRbMF06dGhpcy5vcmlnaW5hbFBhZ2VYLGg9aT9hLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ+PWlbMF18fGEtdGhpcy5vZmZzZXQuY2xpY2subGVmdD5pWzJdP2E6YS10aGlzLm9mZnNldC5jbGljay5sZWZ0Pj1pWzBdP2Etby5ncmlkWzBdOmErby5ncmlkWzBdOmEpLFwieVwiPT09by5heGlzJiYoaD10aGlzLm9yaWdpbmFsUGFnZVgpLFwieFwiPT09by5heGlzJiYobD10aGlzLm9yaWdpbmFsUGFnZVkpKSx7dG9wOmwtdGhpcy5vZmZzZXQuY2xpY2sudG9wLXRoaXMub2Zmc2V0LnJlbGF0aXZlLnRvcC10aGlzLm9mZnNldC5wYXJlbnQudG9wKyhcImZpeGVkXCI9PT10aGlzLmNzc1Bvc2l0aW9uPy10aGlzLm9mZnNldC5zY3JvbGwudG9wOnI/MDp0aGlzLm9mZnNldC5zY3JvbGwudG9wKSxsZWZ0OmgtdGhpcy5vZmZzZXQuY2xpY2subGVmdC10aGlzLm9mZnNldC5yZWxhdGl2ZS5sZWZ0LXRoaXMub2Zmc2V0LnBhcmVudC5sZWZ0KyhcImZpeGVkXCI9PT10aGlzLmNzc1Bvc2l0aW9uPy10aGlzLm9mZnNldC5zY3JvbGwubGVmdDpyPzA6dGhpcy5vZmZzZXQuc2Nyb2xsLmxlZnQpfX0sX2NsZWFyOmZ1bmN0aW9uKCl7dGhpcy5oZWxwZXIucmVtb3ZlQ2xhc3MoXCJ1aS1kcmFnZ2FibGUtZHJhZ2dpbmdcIiksdGhpcy5oZWxwZXJbMF09PT10aGlzLmVsZW1lbnRbMF18fHRoaXMuY2FuY2VsSGVscGVyUmVtb3ZhbHx8dGhpcy5oZWxwZXIucmVtb3ZlKCksdGhpcy5oZWxwZXI9bnVsbCx0aGlzLmNhbmNlbEhlbHBlclJlbW92YWw9ITEsdGhpcy5kZXN0cm95T25DbGVhciYmdGhpcy5kZXN0cm95KCl9LF9ub3JtYWxpemVSaWdodEJvdHRvbTpmdW5jdGlvbigpe1wieVwiIT09dGhpcy5vcHRpb25zLmF4aXMmJlwiYXV0b1wiIT09dGhpcy5oZWxwZXIuY3NzKFwicmlnaHRcIikmJih0aGlzLmhlbHBlci53aWR0aCh0aGlzLmhlbHBlci53aWR0aCgpKSx0aGlzLmhlbHBlci5jc3MoXCJyaWdodFwiLFwiYXV0b1wiKSksXCJ4XCIhPT10aGlzLm9wdGlvbnMuYXhpcyYmXCJhdXRvXCIhPT10aGlzLmhlbHBlci5jc3MoXCJib3R0b21cIikmJih0aGlzLmhlbHBlci5oZWlnaHQodGhpcy5oZWxwZXIuaGVpZ2h0KCkpLHRoaXMuaGVscGVyLmNzcyhcImJvdHRvbVwiLFwiYXV0b1wiKSl9LF90cmlnZ2VyOmZ1bmN0aW9uKHQsaSxzKXtyZXR1cm4gcz1zfHx0aGlzLl91aUhhc2goKSxlLnVpLnBsdWdpbi5jYWxsKHRoaXMsdCxbaSxzLHRoaXNdLCEwKSwvXihkcmFnfHN0YXJ0fHN0b3ApLy50ZXN0KHQpJiYodGhpcy5wb3NpdGlvbkFicz10aGlzLl9jb252ZXJ0UG9zaXRpb25UbyhcImFic29sdXRlXCIpLHMub2Zmc2V0PXRoaXMucG9zaXRpb25BYnMpLGUuV2lkZ2V0LnByb3RvdHlwZS5fdHJpZ2dlci5jYWxsKHRoaXMsdCxpLHMpfSxwbHVnaW5zOnt9LF91aUhhc2g6ZnVuY3Rpb24oKXtyZXR1cm57aGVscGVyOnRoaXMuaGVscGVyLHBvc2l0aW9uOnRoaXMucG9zaXRpb24sb3JpZ2luYWxQb3NpdGlvbjp0aGlzLm9yaWdpbmFsUG9zaXRpb24sb2Zmc2V0OnRoaXMucG9zaXRpb25BYnN9fX0pLGUudWkucGx1Z2luLmFkZChcImRyYWdnYWJsZVwiLFwiY29ubmVjdFRvU29ydGFibGVcIix7c3RhcnQ6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPWUuZXh0ZW5kKHt9LGkse2l0ZW06cy5lbGVtZW50fSk7cy5zb3J0YWJsZXM9W10sZShzLm9wdGlvbnMuY29ubmVjdFRvU29ydGFibGUpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT1lKHRoaXMpLnNvcnRhYmxlKFwiaW5zdGFuY2VcIik7aSYmIWkub3B0aW9ucy5kaXNhYmxlZCYmKHMuc29ydGFibGVzLnB1c2goaSksaS5yZWZyZXNoUG9zaXRpb25zKCksaS5fdHJpZ2dlcihcImFjdGl2YXRlXCIsdCxuKSl9KX0sc3RvcDpmdW5jdGlvbih0LGkscyl7dmFyIG49ZS5leHRlbmQoe30saSx7aXRlbTpzLmVsZW1lbnR9KTtzLmNhbmNlbEhlbHBlclJlbW92YWw9ITEsZS5lYWNoKHMuc29ydGFibGVzLGZ1bmN0aW9uKCl7dmFyIGU9dGhpcztlLmlzT3Zlcj8oZS5pc092ZXI9MCxzLmNhbmNlbEhlbHBlclJlbW92YWw9ITAsZS5jYW5jZWxIZWxwZXJSZW1vdmFsPSExLGUuX3N0b3JlZENTUz17cG9zaXRpb246ZS5wbGFjZWhvbGRlci5jc3MoXCJwb3NpdGlvblwiKSx0b3A6ZS5wbGFjZWhvbGRlci5jc3MoXCJ0b3BcIiksbGVmdDplLnBsYWNlaG9sZGVyLmNzcyhcImxlZnRcIil9LGUuX21vdXNlU3RvcCh0KSxlLm9wdGlvbnMuaGVscGVyPWUub3B0aW9ucy5faGVscGVyKTooZS5jYW5jZWxIZWxwZXJSZW1vdmFsPSEwLGUuX3RyaWdnZXIoXCJkZWFjdGl2YXRlXCIsdCxuKSl9KX0sZHJhZzpmdW5jdGlvbih0LGkscyl7ZS5lYWNoKHMuc29ydGFibGVzLGZ1bmN0aW9uKCl7dmFyIG49ITEsYT10aGlzO2EucG9zaXRpb25BYnM9cy5wb3NpdGlvbkFicyxhLmhlbHBlclByb3BvcnRpb25zPXMuaGVscGVyUHJvcG9ydGlvbnMsYS5vZmZzZXQuY2xpY2s9cy5vZmZzZXQuY2xpY2ssYS5faW50ZXJzZWN0c1dpdGgoYS5jb250YWluZXJDYWNoZSkmJihuPSEwLGUuZWFjaChzLnNvcnRhYmxlcyxmdW5jdGlvbigpe3JldHVybiB0aGlzLnBvc2l0aW9uQWJzPXMucG9zaXRpb25BYnMsdGhpcy5oZWxwZXJQcm9wb3J0aW9ucz1zLmhlbHBlclByb3BvcnRpb25zLHRoaXMub2Zmc2V0LmNsaWNrPXMub2Zmc2V0LmNsaWNrLHRoaXMhPT1hJiZ0aGlzLl9pbnRlcnNlY3RzV2l0aCh0aGlzLmNvbnRhaW5lckNhY2hlKSYmZS5jb250YWlucyhhLmVsZW1lbnRbMF0sdGhpcy5lbGVtZW50WzBdKSYmKG49ITEpLG59KSksbj8oYS5pc092ZXJ8fChhLmlzT3Zlcj0xLHMuX3BhcmVudD1pLmhlbHBlci5wYXJlbnQoKSxhLmN1cnJlbnRJdGVtPWkuaGVscGVyLmFwcGVuZFRvKGEuZWxlbWVudCkuZGF0YShcInVpLXNvcnRhYmxlLWl0ZW1cIiwhMCksYS5vcHRpb25zLl9oZWxwZXI9YS5vcHRpb25zLmhlbHBlcixhLm9wdGlvbnMuaGVscGVyPWZ1bmN0aW9uKCl7cmV0dXJuIGkuaGVscGVyWzBdfSx0LnRhcmdldD1hLmN1cnJlbnRJdGVtWzBdLGEuX21vdXNlQ2FwdHVyZSh0LCEwKSxhLl9tb3VzZVN0YXJ0KHQsITAsITApLGEub2Zmc2V0LmNsaWNrLnRvcD1zLm9mZnNldC5jbGljay50b3AsYS5vZmZzZXQuY2xpY2subGVmdD1zLm9mZnNldC5jbGljay5sZWZ0LGEub2Zmc2V0LnBhcmVudC5sZWZ0LT1zLm9mZnNldC5wYXJlbnQubGVmdC1hLm9mZnNldC5wYXJlbnQubGVmdCxhLm9mZnNldC5wYXJlbnQudG9wLT1zLm9mZnNldC5wYXJlbnQudG9wLWEub2Zmc2V0LnBhcmVudC50b3Ascy5fdHJpZ2dlcihcInRvU29ydGFibGVcIix0KSxzLmRyb3BwZWQ9YS5lbGVtZW50LGUuZWFjaChzLnNvcnRhYmxlcyxmdW5jdGlvbigpe3RoaXMucmVmcmVzaFBvc2l0aW9ucygpfSkscy5jdXJyZW50SXRlbT1zLmVsZW1lbnQsYS5mcm9tT3V0c2lkZT1zKSxhLmN1cnJlbnRJdGVtJiYoYS5fbW91c2VEcmFnKHQpLGkucG9zaXRpb249YS5wb3NpdGlvbikpOmEuaXNPdmVyJiYoYS5pc092ZXI9MCxhLmNhbmNlbEhlbHBlclJlbW92YWw9ITAsYS5vcHRpb25zLl9yZXZlcnQ9YS5vcHRpb25zLnJldmVydCxhLm9wdGlvbnMucmV2ZXJ0PSExLGEuX3RyaWdnZXIoXCJvdXRcIix0LGEuX3VpSGFzaChhKSksYS5fbW91c2VTdG9wKHQsITApLGEub3B0aW9ucy5yZXZlcnQ9YS5vcHRpb25zLl9yZXZlcnQsYS5vcHRpb25zLmhlbHBlcj1hLm9wdGlvbnMuX2hlbHBlcixhLnBsYWNlaG9sZGVyJiZhLnBsYWNlaG9sZGVyLnJlbW92ZSgpLGkuaGVscGVyLmFwcGVuZFRvKHMuX3BhcmVudCkscy5fcmVmcmVzaE9mZnNldHModCksaS5wb3NpdGlvbj1zLl9nZW5lcmF0ZVBvc2l0aW9uKHQsITApLHMuX3RyaWdnZXIoXCJmcm9tU29ydGFibGVcIix0KSxzLmRyb3BwZWQ9ITEsZS5lYWNoKHMuc29ydGFibGVzLGZ1bmN0aW9uKCl7dGhpcy5yZWZyZXNoUG9zaXRpb25zKCl9KSl9KX19KSxlLnVpLnBsdWdpbi5hZGQoXCJkcmFnZ2FibGVcIixcImN1cnNvclwiLHtzdGFydDpmdW5jdGlvbih0LGkscyl7dmFyIG49ZShcImJvZHlcIiksYT1zLm9wdGlvbnM7bi5jc3MoXCJjdXJzb3JcIikmJihhLl9jdXJzb3I9bi5jc3MoXCJjdXJzb3JcIikpLG4uY3NzKFwiY3Vyc29yXCIsYS5jdXJzb3IpfSxzdG9wOmZ1bmN0aW9uKHQsaSxzKXt2YXIgbj1zLm9wdGlvbnM7bi5fY3Vyc29yJiZlKFwiYm9keVwiKS5jc3MoXCJjdXJzb3JcIixuLl9jdXJzb3IpfX0pLGUudWkucGx1Z2luLmFkZChcImRyYWdnYWJsZVwiLFwib3BhY2l0eVwiLHtzdGFydDpmdW5jdGlvbih0LGkscyl7dmFyIG49ZShpLmhlbHBlciksYT1zLm9wdGlvbnM7bi5jc3MoXCJvcGFjaXR5XCIpJiYoYS5fb3BhY2l0eT1uLmNzcyhcIm9wYWNpdHlcIikpLG4uY3NzKFwib3BhY2l0eVwiLGEub3BhY2l0eSl9LHN0b3A6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPXMub3B0aW9ucztuLl9vcGFjaXR5JiZlKGkuaGVscGVyKS5jc3MoXCJvcGFjaXR5XCIsbi5fb3BhY2l0eSl9fSksZS51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJzY3JvbGxcIix7c3RhcnQ6ZnVuY3Rpb24oZSx0LGkpe2kuc2Nyb2xsUGFyZW50Tm90SGlkZGVufHwoaS5zY3JvbGxQYXJlbnROb3RIaWRkZW49aS5oZWxwZXIuc2Nyb2xsUGFyZW50KCExKSksaS5zY3JvbGxQYXJlbnROb3RIaWRkZW5bMF0hPT1pLmRvY3VtZW50WzBdJiZcIkhUTUxcIiE9PWkuc2Nyb2xsUGFyZW50Tm90SGlkZGVuWzBdLnRhZ05hbWUmJihpLm92ZXJmbG93T2Zmc2V0PWkuc2Nyb2xsUGFyZW50Tm90SGlkZGVuLm9mZnNldCgpKX0sZHJhZzpmdW5jdGlvbih0LGkscyl7dmFyIG49cy5vcHRpb25zLGE9ITEsbz1zLnNjcm9sbFBhcmVudE5vdEhpZGRlblswXSxyPXMuZG9jdW1lbnRbMF07byE9PXImJlwiSFRNTFwiIT09by50YWdOYW1lPyhuLmF4aXMmJlwieFwiPT09bi5heGlzfHwocy5vdmVyZmxvd09mZnNldC50b3Arby5vZmZzZXRIZWlnaHQtdC5wYWdlWTxuLnNjcm9sbFNlbnNpdGl2aXR5P28uc2Nyb2xsVG9wPWE9by5zY3JvbGxUb3Arbi5zY3JvbGxTcGVlZDp0LnBhZ2VZLXMub3ZlcmZsb3dPZmZzZXQudG9wPG4uc2Nyb2xsU2Vuc2l0aXZpdHkmJihvLnNjcm9sbFRvcD1hPW8uc2Nyb2xsVG9wLW4uc2Nyb2xsU3BlZWQpKSxuLmF4aXMmJlwieVwiPT09bi5heGlzfHwocy5vdmVyZmxvd09mZnNldC5sZWZ0K28ub2Zmc2V0V2lkdGgtdC5wYWdlWDxuLnNjcm9sbFNlbnNpdGl2aXR5P28uc2Nyb2xsTGVmdD1hPW8uc2Nyb2xsTGVmdCtuLnNjcm9sbFNwZWVkOnQucGFnZVgtcy5vdmVyZmxvd09mZnNldC5sZWZ0PG4uc2Nyb2xsU2Vuc2l0aXZpdHkmJihvLnNjcm9sbExlZnQ9YT1vLnNjcm9sbExlZnQtbi5zY3JvbGxTcGVlZCkpKToobi5heGlzJiZcInhcIj09PW4uYXhpc3x8KHQucGFnZVktZShyKS5zY3JvbGxUb3AoKTxuLnNjcm9sbFNlbnNpdGl2aXR5P2E9ZShyKS5zY3JvbGxUb3AoZShyKS5zY3JvbGxUb3AoKS1uLnNjcm9sbFNwZWVkKTplKHdpbmRvdykuaGVpZ2h0KCktKHQucGFnZVktZShyKS5zY3JvbGxUb3AoKSk8bi5zY3JvbGxTZW5zaXRpdml0eSYmKGE9ZShyKS5zY3JvbGxUb3AoZShyKS5zY3JvbGxUb3AoKStuLnNjcm9sbFNwZWVkKSkpLG4uYXhpcyYmXCJ5XCI9PT1uLmF4aXN8fCh0LnBhZ2VYLWUocikuc2Nyb2xsTGVmdCgpPG4uc2Nyb2xsU2Vuc2l0aXZpdHk/YT1lKHIpLnNjcm9sbExlZnQoZShyKS5zY3JvbGxMZWZ0KCktbi5zY3JvbGxTcGVlZCk6ZSh3aW5kb3cpLndpZHRoKCktKHQucGFnZVgtZShyKS5zY3JvbGxMZWZ0KCkpPG4uc2Nyb2xsU2Vuc2l0aXZpdHkmJihhPWUocikuc2Nyb2xsTGVmdChlKHIpLnNjcm9sbExlZnQoKStuLnNjcm9sbFNwZWVkKSkpKSxhIT09ITEmJmUudWkuZGRtYW5hZ2VyJiYhbi5kcm9wQmVoYXZpb3VyJiZlLnVpLmRkbWFuYWdlci5wcmVwYXJlT2Zmc2V0cyhzLHQpfX0pLGUudWkucGx1Z2luLmFkZChcImRyYWdnYWJsZVwiLFwic25hcFwiLHtzdGFydDpmdW5jdGlvbih0LGkscyl7dmFyIG49cy5vcHRpb25zO3Muc25hcEVsZW1lbnRzPVtdLGUobi5zbmFwLmNvbnN0cnVjdG9yIT09U3RyaW5nP24uc25hcC5pdGVtc3x8XCI6ZGF0YSh1aS1kcmFnZ2FibGUpXCI6bi5zbmFwKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKSxpPXQub2Zmc2V0KCk7dGhpcyE9PXMuZWxlbWVudFswXSYmcy5zbmFwRWxlbWVudHMucHVzaCh7aXRlbTp0aGlzLHdpZHRoOnQub3V0ZXJXaWR0aCgpLGhlaWdodDp0Lm91dGVySGVpZ2h0KCksdG9wOmkudG9wLGxlZnQ6aS5sZWZ0fSl9KX0sZHJhZzpmdW5jdGlvbih0LGkscyl7dmFyIG4sYSxvLHIsaCxsLHUsZCxjLHAsZj1zLm9wdGlvbnMsbT1mLnNuYXBUb2xlcmFuY2UsZz1pLm9mZnNldC5sZWZ0LHY9ZytzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLHk9aS5vZmZzZXQudG9wLGI9eStzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodDtmb3IoYz1zLnNuYXBFbGVtZW50cy5sZW5ndGgtMTtjPj0wO2MtLSloPXMuc25hcEVsZW1lbnRzW2NdLmxlZnQtcy5tYXJnaW5zLmxlZnQsbD1oK3Muc25hcEVsZW1lbnRzW2NdLndpZHRoLHU9cy5zbmFwRWxlbWVudHNbY10udG9wLXMubWFyZ2lucy50b3AsZD11K3Muc25hcEVsZW1lbnRzW2NdLmhlaWdodCxoLW0+dnx8Zz5sK218fHUtbT5ifHx5PmQrbXx8IWUuY29udGFpbnMocy5zbmFwRWxlbWVudHNbY10uaXRlbS5vd25lckRvY3VtZW50LHMuc25hcEVsZW1lbnRzW2NdLml0ZW0pPyhzLnNuYXBFbGVtZW50c1tjXS5zbmFwcGluZyYmcy5vcHRpb25zLnNuYXAucmVsZWFzZSYmcy5vcHRpb25zLnNuYXAucmVsZWFzZS5jYWxsKHMuZWxlbWVudCx0LGUuZXh0ZW5kKHMuX3VpSGFzaCgpLHtzbmFwSXRlbTpzLnNuYXBFbGVtZW50c1tjXS5pdGVtfSkpLHMuc25hcEVsZW1lbnRzW2NdLnNuYXBwaW5nPSExKTooXCJpbm5lclwiIT09Zi5zbmFwTW9kZSYmKG49bT49TWF0aC5hYnModS1iKSxhPW0+PU1hdGguYWJzKGQteSksbz1tPj1NYXRoLmFicyhoLXYpLHI9bT49TWF0aC5hYnMobC1nKSxuJiYoaS5wb3NpdGlvbi50b3A9cy5fY29udmVydFBvc2l0aW9uVG8oXCJyZWxhdGl2ZVwiLHt0b3A6dS1zLmhlbHBlclByb3BvcnRpb25zLmhlaWdodCxsZWZ0OjB9KS50b3ApLGEmJihpLnBvc2l0aW9uLnRvcD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDpkLGxlZnQ6MH0pLnRvcCksbyYmKGkucG9zaXRpb24ubGVmdD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDowLGxlZnQ6aC1zLmhlbHBlclByb3BvcnRpb25zLndpZHRofSkubGVmdCksciYmKGkucG9zaXRpb24ubGVmdD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDowLGxlZnQ6bH0pLmxlZnQpKSxwPW58fGF8fG98fHIsXCJvdXRlclwiIT09Zi5zbmFwTW9kZSYmKG49bT49TWF0aC5hYnModS15KSxhPW0+PU1hdGguYWJzKGQtYiksbz1tPj1NYXRoLmFicyhoLWcpLHI9bT49TWF0aC5hYnMobC12KSxuJiYoaS5wb3NpdGlvbi50b3A9cy5fY29udmVydFBvc2l0aW9uVG8oXCJyZWxhdGl2ZVwiLHt0b3A6dSxsZWZ0OjB9KS50b3ApLGEmJihpLnBvc2l0aW9uLnRvcD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDpkLXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LGxlZnQ6MH0pLnRvcCksbyYmKGkucG9zaXRpb24ubGVmdD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDowLGxlZnQ6aH0pLmxlZnQpLHImJihpLnBvc2l0aW9uLmxlZnQ9cy5fY29udmVydFBvc2l0aW9uVG8oXCJyZWxhdGl2ZVwiLHt0b3A6MCxsZWZ0Omwtcy5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aH0pLmxlZnQpKSwhcy5zbmFwRWxlbWVudHNbY10uc25hcHBpbmcmJihufHxhfHxvfHxyfHxwKSYmcy5vcHRpb25zLnNuYXAuc25hcCYmcy5vcHRpb25zLnNuYXAuc25hcC5jYWxsKHMuZWxlbWVudCx0LGUuZXh0ZW5kKHMuX3VpSGFzaCgpLHtzbmFwSXRlbTpzLnNuYXBFbGVtZW50c1tjXS5pdGVtfSkpLHMuc25hcEVsZW1lbnRzW2NdLnNuYXBwaW5nPW58fGF8fG98fHJ8fHApfX0pLGUudWkucGx1Z2luLmFkZChcImRyYWdnYWJsZVwiLFwic3RhY2tcIix7c3RhcnQ6ZnVuY3Rpb24odCxpLHMpe3ZhciBuLGE9cy5vcHRpb25zLG89ZS5tYWtlQXJyYXkoZShhLnN0YWNrKSkuc29ydChmdW5jdGlvbih0LGkpe3JldHVybihwYXJzZUludChlKHQpLmNzcyhcInpJbmRleFwiKSwxMCl8fDApLShwYXJzZUludChlKGkpLmNzcyhcInpJbmRleFwiKSwxMCl8fDApfSk7by5sZW5ndGgmJihuPXBhcnNlSW50KGUob1swXSkuY3NzKFwiekluZGV4XCIpLDEwKXx8MCxlKG8pLmVhY2goZnVuY3Rpb24odCl7ZSh0aGlzKS5jc3MoXCJ6SW5kZXhcIixuK3QpfSksdGhpcy5jc3MoXCJ6SW5kZXhcIixuK28ubGVuZ3RoKSl9fSksZS51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJ6SW5kZXhcIix7c3RhcnQ6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPWUoaS5oZWxwZXIpLGE9cy5vcHRpb25zO24uY3NzKFwiekluZGV4XCIpJiYoYS5fekluZGV4PW4uY3NzKFwiekluZGV4XCIpKSxuLmNzcyhcInpJbmRleFwiLGEuekluZGV4KX0sc3RvcDpmdW5jdGlvbih0LGkscyl7dmFyIG49cy5vcHRpb25zO24uX3pJbmRleCYmZShpLmhlbHBlcikuY3NzKFwiekluZGV4XCIsbi5fekluZGV4KX19KSxlLnVpLmRyYWdnYWJsZSxlLndpZGdldChcInVpLnJlc2l6YWJsZVwiLGUudWkubW91c2Use3ZlcnNpb246XCIxLjExLjRcIix3aWRnZXRFdmVudFByZWZpeDpcInJlc2l6ZVwiLG9wdGlvbnM6e2Fsc29SZXNpemU6ITEsYW5pbWF0ZTohMSxhbmltYXRlRHVyYXRpb246XCJzbG93XCIsYW5pbWF0ZUVhc2luZzpcInN3aW5nXCIsYXNwZWN0UmF0aW86ITEsYXV0b0hpZGU6ITEsY29udGFpbm1lbnQ6ITEsZ2hvc3Q6ITEsZ3JpZDohMSxoYW5kbGVzOlwiZSxzLHNlXCIsaGVscGVyOiExLG1heEhlaWdodDpudWxsLG1heFdpZHRoOm51bGwsbWluSGVpZ2h0OjEwLG1pbldpZHRoOjEwLHpJbmRleDo5MCxyZXNpemU6bnVsbCxzdGFydDpudWxsLHN0b3A6bnVsbH0sX251bTpmdW5jdGlvbihlKXtyZXR1cm4gcGFyc2VJbnQoZSwxMCl8fDB9LF9pc051bWJlcjpmdW5jdGlvbihlKXtyZXR1cm4haXNOYU4ocGFyc2VJbnQoZSwxMCkpfSxfaGFzU2Nyb2xsOmZ1bmN0aW9uKHQsaSl7aWYoXCJoaWRkZW5cIj09PWUodCkuY3NzKFwib3ZlcmZsb3dcIikpcmV0dXJuITE7dmFyIHM9aSYmXCJsZWZ0XCI9PT1pP1wic2Nyb2xsTGVmdFwiOlwic2Nyb2xsVG9wXCIsbj0hMTtyZXR1cm4gdFtzXT4wPyEwOih0W3NdPTEsbj10W3NdPjAsdFtzXT0wLG4pfSxfY3JlYXRlOmZ1bmN0aW9uKCl7dmFyIHQsaSxzLG4sYSxvPXRoaXMscj10aGlzLm9wdGlvbnM7aWYodGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktcmVzaXphYmxlXCIpLGUuZXh0ZW5kKHRoaXMse19hc3BlY3RSYXRpbzohIXIuYXNwZWN0UmF0aW8sYXNwZWN0UmF0aW86ci5hc3BlY3RSYXRpbyxvcmlnaW5hbEVsZW1lbnQ6dGhpcy5lbGVtZW50LF9wcm9wb3J0aW9uYWxseVJlc2l6ZUVsZW1lbnRzOltdLF9oZWxwZXI6ci5oZWxwZXJ8fHIuZ2hvc3R8fHIuYW5pbWF0ZT9yLmhlbHBlcnx8XCJ1aS1yZXNpemFibGUtaGVscGVyXCI6bnVsbH0pLHRoaXMuZWxlbWVudFswXS5ub2RlTmFtZS5tYXRjaCgvXihjYW52YXN8dGV4dGFyZWF8aW5wdXR8c2VsZWN0fGJ1dHRvbnxpbWcpJC9pKSYmKHRoaXMuZWxlbWVudC53cmFwKGUoXCI8ZGl2IGNsYXNzPSd1aS13cmFwcGVyJyBzdHlsZT0nb3ZlcmZsb3c6IGhpZGRlbjsnPjwvZGl2PlwiKS5jc3Moe3Bvc2l0aW9uOnRoaXMuZWxlbWVudC5jc3MoXCJwb3NpdGlvblwiKSx3aWR0aDp0aGlzLmVsZW1lbnQub3V0ZXJXaWR0aCgpLGhlaWdodDp0aGlzLmVsZW1lbnQub3V0ZXJIZWlnaHQoKSx0b3A6dGhpcy5lbGVtZW50LmNzcyhcInRvcFwiKSxsZWZ0OnRoaXMuZWxlbWVudC5jc3MoXCJsZWZ0XCIpfSkpLHRoaXMuZWxlbWVudD10aGlzLmVsZW1lbnQucGFyZW50KCkuZGF0YShcInVpLXJlc2l6YWJsZVwiLHRoaXMuZWxlbWVudC5yZXNpemFibGUoXCJpbnN0YW5jZVwiKSksdGhpcy5lbGVtZW50SXNXcmFwcGVyPSEwLHRoaXMuZWxlbWVudC5jc3Moe21hcmdpbkxlZnQ6dGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwibWFyZ2luTGVmdFwiKSxtYXJnaW5Ub3A6dGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwibWFyZ2luVG9wXCIpLG1hcmdpblJpZ2h0OnRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcIm1hcmdpblJpZ2h0XCIpLG1hcmdpbkJvdHRvbTp0aGlzLm9yaWdpbmFsRWxlbWVudC5jc3MoXCJtYXJnaW5Cb3R0b21cIil9KSx0aGlzLm9yaWdpbmFsRWxlbWVudC5jc3Moe21hcmdpbkxlZnQ6MCxtYXJnaW5Ub3A6MCxtYXJnaW5SaWdodDowLG1hcmdpbkJvdHRvbTowfSksdGhpcy5vcmlnaW5hbFJlc2l6ZVN0eWxlPXRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcInJlc2l6ZVwiKSx0aGlzLm9yaWdpbmFsRWxlbWVudC5jc3MoXCJyZXNpemVcIixcIm5vbmVcIiksdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cy5wdXNoKHRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyh7cG9zaXRpb246XCJzdGF0aWNcIix6b29tOjEsZGlzcGxheTpcImJsb2NrXCJ9KSksdGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKHttYXJnaW46dGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwibWFyZ2luXCIpfSksdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemUoKSksdGhpcy5oYW5kbGVzPXIuaGFuZGxlc3x8KGUoXCIudWktcmVzaXphYmxlLWhhbmRsZVwiLHRoaXMuZWxlbWVudCkubGVuZ3RoP3tuOlwiLnVpLXJlc2l6YWJsZS1uXCIsZTpcIi51aS1yZXNpemFibGUtZVwiLHM6XCIudWktcmVzaXphYmxlLXNcIix3OlwiLnVpLXJlc2l6YWJsZS13XCIsc2U6XCIudWktcmVzaXphYmxlLXNlXCIsc3c6XCIudWktcmVzaXphYmxlLXN3XCIsbmU6XCIudWktcmVzaXphYmxlLW5lXCIsbnc6XCIudWktcmVzaXphYmxlLW53XCJ9OlwiZSxzLHNlXCIpLHRoaXMuX2hhbmRsZXM9ZSgpLHRoaXMuaGFuZGxlcy5jb25zdHJ1Y3Rvcj09PVN0cmluZylmb3IoXCJhbGxcIj09PXRoaXMuaGFuZGxlcyYmKHRoaXMuaGFuZGxlcz1cIm4sZSxzLHcsc2Usc3csbmUsbndcIiksdD10aGlzLmhhbmRsZXMuc3BsaXQoXCIsXCIpLHRoaXMuaGFuZGxlcz17fSxpPTA7dC5sZW5ndGg+aTtpKyspcz1lLnRyaW0odFtpXSksYT1cInVpLXJlc2l6YWJsZS1cIitzLG49ZShcIjxkaXYgY2xhc3M9J3VpLXJlc2l6YWJsZS1oYW5kbGUgXCIrYStcIic+PC9kaXY+XCIpLG4uY3NzKHt6SW5kZXg6ci56SW5kZXh9KSxcInNlXCI9PT1zJiZuLmFkZENsYXNzKFwidWktaWNvbiB1aS1pY29uLWdyaXBzbWFsbC1kaWFnb25hbC1zZVwiKSx0aGlzLmhhbmRsZXNbc109XCIudWktcmVzaXphYmxlLVwiK3MsdGhpcy5lbGVtZW50LmFwcGVuZChuKTt0aGlzLl9yZW5kZXJBeGlzPWZ1bmN0aW9uKHQpe3ZhciBpLHMsbixhO3Q9dHx8dGhpcy5lbGVtZW50O2ZvcihpIGluIHRoaXMuaGFuZGxlcyl0aGlzLmhhbmRsZXNbaV0uY29uc3RydWN0b3I9PT1TdHJpbmc/dGhpcy5oYW5kbGVzW2ldPXRoaXMuZWxlbWVudC5jaGlsZHJlbih0aGlzLmhhbmRsZXNbaV0pLmZpcnN0KCkuc2hvdygpOih0aGlzLmhhbmRsZXNbaV0uanF1ZXJ5fHx0aGlzLmhhbmRsZXNbaV0ubm9kZVR5cGUpJiYodGhpcy5oYW5kbGVzW2ldPWUodGhpcy5oYW5kbGVzW2ldKSx0aGlzLl9vbih0aGlzLmhhbmRsZXNbaV0se21vdXNlZG93bjpvLl9tb3VzZURvd259KSksdGhpcy5lbGVtZW50SXNXcmFwcGVyJiZ0aGlzLm9yaWdpbmFsRWxlbWVudFswXS5ub2RlTmFtZS5tYXRjaCgvXih0ZXh0YXJlYXxpbnB1dHxzZWxlY3R8YnV0dG9uKSQvaSkmJihzPWUodGhpcy5oYW5kbGVzW2ldLHRoaXMuZWxlbWVudCksYT0vc3d8bmV8bnd8c2V8bnxzLy50ZXN0KGkpP3Mub3V0ZXJIZWlnaHQoKTpzLm91dGVyV2lkdGgoKSxuPVtcInBhZGRpbmdcIiwvbmV8bnd8bi8udGVzdChpKT9cIlRvcFwiOi9zZXxzd3xzLy50ZXN0KGkpP1wiQm90dG9tXCI6L15lJC8udGVzdChpKT9cIlJpZ2h0XCI6XCJMZWZ0XCJdLmpvaW4oXCJcIiksdC5jc3MobixhKSx0aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZSgpKSx0aGlzLl9oYW5kbGVzPXRoaXMuX2hhbmRsZXMuYWRkKHRoaXMuaGFuZGxlc1tpXSl9LHRoaXMuX3JlbmRlckF4aXModGhpcy5lbGVtZW50KSx0aGlzLl9oYW5kbGVzPXRoaXMuX2hhbmRsZXMuYWRkKHRoaXMuZWxlbWVudC5maW5kKFwiLnVpLXJlc2l6YWJsZS1oYW5kbGVcIikpLHRoaXMuX2hhbmRsZXMuZGlzYWJsZVNlbGVjdGlvbigpLHRoaXMuX2hhbmRsZXMubW91c2VvdmVyKGZ1bmN0aW9uKCl7by5yZXNpemluZ3x8KHRoaXMuY2xhc3NOYW1lJiYobj10aGlzLmNsYXNzTmFtZS5tYXRjaCgvdWktcmVzaXphYmxlLShzZXxzd3xuZXxud3xufGV8c3x3KS9pKSksby5heGlzPW4mJm5bMV0/blsxXTpcInNlXCIpfSksci5hdXRvSGlkZSYmKHRoaXMuX2hhbmRsZXMuaGlkZSgpLGUodGhpcy5lbGVtZW50KS5hZGRDbGFzcyhcInVpLXJlc2l6YWJsZS1hdXRvaGlkZVwiKS5tb3VzZWVudGVyKGZ1bmN0aW9uKCl7ci5kaXNhYmxlZHx8KGUodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1yZXNpemFibGUtYXV0b2hpZGVcIiksby5faGFuZGxlcy5zaG93KCkpfSkubW91c2VsZWF2ZShmdW5jdGlvbigpe3IuZGlzYWJsZWR8fG8ucmVzaXppbmd8fChlKHRoaXMpLmFkZENsYXNzKFwidWktcmVzaXphYmxlLWF1dG9oaWRlXCIpLG8uX2hhbmRsZXMuaGlkZSgpKX0pKSx0aGlzLl9tb3VzZUluaXQoKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt0aGlzLl9tb3VzZURlc3Ryb3koKTt2YXIgdCxpPWZ1bmN0aW9uKHQpe2UodCkucmVtb3ZlQ2xhc3MoXCJ1aS1yZXNpemFibGUgdWktcmVzaXphYmxlLWRpc2FibGVkIHVpLXJlc2l6YWJsZS1yZXNpemluZ1wiKS5yZW1vdmVEYXRhKFwicmVzaXphYmxlXCIpLnJlbW92ZURhdGEoXCJ1aS1yZXNpemFibGVcIikudW5iaW5kKFwiLnJlc2l6YWJsZVwiKS5maW5kKFwiLnVpLXJlc2l6YWJsZS1oYW5kbGVcIikucmVtb3ZlKCl9O3JldHVybiB0aGlzLmVsZW1lbnRJc1dyYXBwZXImJihpKHRoaXMuZWxlbWVudCksdD10aGlzLmVsZW1lbnQsdGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKHtwb3NpdGlvbjp0LmNzcyhcInBvc2l0aW9uXCIpLHdpZHRoOnQub3V0ZXJXaWR0aCgpLGhlaWdodDp0Lm91dGVySGVpZ2h0KCksdG9wOnQuY3NzKFwidG9wXCIpLGxlZnQ6dC5jc3MoXCJsZWZ0XCIpfSkuaW5zZXJ0QWZ0ZXIodCksdC5yZW1vdmUoKSksdGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwicmVzaXplXCIsdGhpcy5vcmlnaW5hbFJlc2l6ZVN0eWxlKSxpKHRoaXMub3JpZ2luYWxFbGVtZW50KSx0aGlzfSxfbW91c2VDYXB0dXJlOmZ1bmN0aW9uKHQpe3ZhciBpLHMsbj0hMTtmb3IoaSBpbiB0aGlzLmhhbmRsZXMpcz1lKHRoaXMuaGFuZGxlc1tpXSlbMF0sKHM9PT10LnRhcmdldHx8ZS5jb250YWlucyhzLHQudGFyZ2V0KSkmJihuPSEwKTtyZXR1cm4hdGhpcy5vcHRpb25zLmRpc2FibGVkJiZufSxfbW91c2VTdGFydDpmdW5jdGlvbih0KXt2YXIgaSxzLG4sYT10aGlzLm9wdGlvbnMsbz10aGlzLmVsZW1lbnQ7cmV0dXJuIHRoaXMucmVzaXppbmc9ITAsdGhpcy5fcmVuZGVyUHJveHkoKSxpPXRoaXMuX251bSh0aGlzLmhlbHBlci5jc3MoXCJsZWZ0XCIpKSxzPXRoaXMuX251bSh0aGlzLmhlbHBlci5jc3MoXCJ0b3BcIikpLGEuY29udGFpbm1lbnQmJihpKz1lKGEuY29udGFpbm1lbnQpLnNjcm9sbExlZnQoKXx8MCxzKz1lKGEuY29udGFpbm1lbnQpLnNjcm9sbFRvcCgpfHwwKSx0aGlzLm9mZnNldD10aGlzLmhlbHBlci5vZmZzZXQoKSx0aGlzLnBvc2l0aW9uPXtsZWZ0OmksdG9wOnN9LHRoaXMuc2l6ZT10aGlzLl9oZWxwZXI/e3dpZHRoOnRoaXMuaGVscGVyLndpZHRoKCksaGVpZ2h0OnRoaXMuaGVscGVyLmhlaWdodCgpfTp7d2lkdGg6by53aWR0aCgpLGhlaWdodDpvLmhlaWdodCgpfSx0aGlzLm9yaWdpbmFsU2l6ZT10aGlzLl9oZWxwZXI/e3dpZHRoOm8ub3V0ZXJXaWR0aCgpLGhlaWdodDpvLm91dGVySGVpZ2h0KCl9Ont3aWR0aDpvLndpZHRoKCksaGVpZ2h0Om8uaGVpZ2h0KCl9LHRoaXMuc2l6ZURpZmY9e3dpZHRoOm8ub3V0ZXJXaWR0aCgpLW8ud2lkdGgoKSxoZWlnaHQ6by5vdXRlckhlaWdodCgpLW8uaGVpZ2h0KCl9LHRoaXMub3JpZ2luYWxQb3NpdGlvbj17bGVmdDppLHRvcDpzfSx0aGlzLm9yaWdpbmFsTW91c2VQb3NpdGlvbj17bGVmdDp0LnBhZ2VYLHRvcDp0LnBhZ2VZfSx0aGlzLmFzcGVjdFJhdGlvPVwibnVtYmVyXCI9PXR5cGVvZiBhLmFzcGVjdFJhdGlvP2EuYXNwZWN0UmF0aW86dGhpcy5vcmlnaW5hbFNpemUud2lkdGgvdGhpcy5vcmlnaW5hbFNpemUuaGVpZ2h0fHwxLG49ZShcIi51aS1yZXNpemFibGUtXCIrdGhpcy5heGlzKS5jc3MoXCJjdXJzb3JcIiksZShcImJvZHlcIikuY3NzKFwiY3Vyc29yXCIsXCJhdXRvXCI9PT1uP3RoaXMuYXhpcytcIi1yZXNpemVcIjpuKSxvLmFkZENsYXNzKFwidWktcmVzaXphYmxlLXJlc2l6aW5nXCIpLHRoaXMuX3Byb3BhZ2F0ZShcInN0YXJ0XCIsdCksITB9LF9tb3VzZURyYWc6ZnVuY3Rpb24odCl7dmFyIGkscyxuPXRoaXMub3JpZ2luYWxNb3VzZVBvc2l0aW9uLGE9dGhpcy5heGlzLG89dC5wYWdlWC1uLmxlZnR8fDAscj10LnBhZ2VZLW4udG9wfHwwLGg9dGhpcy5fY2hhbmdlW2FdO3JldHVybiB0aGlzLl91cGRhdGVQcmV2UHJvcGVydGllcygpLGg/KGk9aC5hcHBseSh0aGlzLFt0LG8scl0pLHRoaXMuX3VwZGF0ZVZpcnR1YWxCb3VuZGFyaWVzKHQuc2hpZnRLZXkpLCh0aGlzLl9hc3BlY3RSYXRpb3x8dC5zaGlmdEtleSkmJihpPXRoaXMuX3VwZGF0ZVJhdGlvKGksdCkpLGk9dGhpcy5fcmVzcGVjdFNpemUoaSx0KSx0aGlzLl91cGRhdGVDYWNoZShpKSx0aGlzLl9wcm9wYWdhdGUoXCJyZXNpemVcIix0KSxzPXRoaXMuX2FwcGx5Q2hhbmdlcygpLCF0aGlzLl9oZWxwZXImJnRoaXMuX3Byb3BvcnRpb25hbGx5UmVzaXplRWxlbWVudHMubGVuZ3RoJiZ0aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZSgpLGUuaXNFbXB0eU9iamVjdChzKXx8KHRoaXMuX3VwZGF0ZVByZXZQcm9wZXJ0aWVzKCksdGhpcy5fdHJpZ2dlcihcInJlc2l6ZVwiLHQsdGhpcy51aSgpKSx0aGlzLl9hcHBseUNoYW5nZXMoKSksITEpOiExfSxfbW91c2VTdG9wOmZ1bmN0aW9uKHQpe3RoaXMucmVzaXppbmc9ITE7dmFyIGkscyxuLGEsbyxyLGgsbD10aGlzLm9wdGlvbnMsdT10aGlzO3JldHVybiB0aGlzLl9oZWxwZXImJihpPXRoaXMuX3Byb3BvcnRpb25hbGx5UmVzaXplRWxlbWVudHMscz1pLmxlbmd0aCYmL3RleHRhcmVhL2kudGVzdChpWzBdLm5vZGVOYW1lKSxuPXMmJnRoaXMuX2hhc1Njcm9sbChpWzBdLFwibGVmdFwiKT8wOnUuc2l6ZURpZmYuaGVpZ2h0LGE9cz8wOnUuc2l6ZURpZmYud2lkdGgsbz17d2lkdGg6dS5oZWxwZXIud2lkdGgoKS1hLGhlaWdodDp1LmhlbHBlci5oZWlnaHQoKS1ufSxyPXBhcnNlSW50KHUuZWxlbWVudC5jc3MoXCJsZWZ0XCIpLDEwKSsodS5wb3NpdGlvbi5sZWZ0LXUub3JpZ2luYWxQb3NpdGlvbi5sZWZ0KXx8bnVsbCxoPXBhcnNlSW50KHUuZWxlbWVudC5jc3MoXCJ0b3BcIiksMTApKyh1LnBvc2l0aW9uLnRvcC11Lm9yaWdpbmFsUG9zaXRpb24udG9wKXx8bnVsbCxsLmFuaW1hdGV8fHRoaXMuZWxlbWVudC5jc3MoZS5leHRlbmQobyx7dG9wOmgsbGVmdDpyfSkpLHUuaGVscGVyLmhlaWdodCh1LnNpemUuaGVpZ2h0KSx1LmhlbHBlci53aWR0aCh1LnNpemUud2lkdGgpLHRoaXMuX2hlbHBlciYmIWwuYW5pbWF0ZSYmdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemUoKSksZShcImJvZHlcIikuY3NzKFwiY3Vyc29yXCIsXCJhdXRvXCIpLHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXJlc2l6YWJsZS1yZXNpemluZ1wiKSx0aGlzLl9wcm9wYWdhdGUoXCJzdG9wXCIsdCksdGhpcy5faGVscGVyJiZ0aGlzLmhlbHBlci5yZW1vdmUoKSwhMX0sX3VwZGF0ZVByZXZQcm9wZXJ0aWVzOmZ1bmN0aW9uKCl7dGhpcy5wcmV2UG9zaXRpb249e3RvcDp0aGlzLnBvc2l0aW9uLnRvcCxsZWZ0OnRoaXMucG9zaXRpb24ubGVmdH0sdGhpcy5wcmV2U2l6ZT17d2lkdGg6dGhpcy5zaXplLndpZHRoLGhlaWdodDp0aGlzLnNpemUuaGVpZ2h0fX0sX2FwcGx5Q2hhbmdlczpmdW5jdGlvbigpe3ZhciBlPXt9O3JldHVybiB0aGlzLnBvc2l0aW9uLnRvcCE9PXRoaXMucHJldlBvc2l0aW9uLnRvcCYmKGUudG9wPXRoaXMucG9zaXRpb24udG9wK1wicHhcIiksdGhpcy5wb3NpdGlvbi5sZWZ0IT09dGhpcy5wcmV2UG9zaXRpb24ubGVmdCYmKGUubGVmdD10aGlzLnBvc2l0aW9uLmxlZnQrXCJweFwiKSx0aGlzLnNpemUud2lkdGghPT10aGlzLnByZXZTaXplLndpZHRoJiYoZS53aWR0aD10aGlzLnNpemUud2lkdGgrXCJweFwiKSx0aGlzLnNpemUuaGVpZ2h0IT09dGhpcy5wcmV2U2l6ZS5oZWlnaHQmJihlLmhlaWdodD10aGlzLnNpemUuaGVpZ2h0K1wicHhcIiksdGhpcy5oZWxwZXIuY3NzKGUpLGV9LF91cGRhdGVWaXJ0dWFsQm91bmRhcmllczpmdW5jdGlvbihlKXt2YXIgdCxpLHMsbixhLG89dGhpcy5vcHRpb25zO2E9e21pbldpZHRoOnRoaXMuX2lzTnVtYmVyKG8ubWluV2lkdGgpP28ubWluV2lkdGg6MCxtYXhXaWR0aDp0aGlzLl9pc051bWJlcihvLm1heFdpZHRoKT9vLm1heFdpZHRoOjEvMCxtaW5IZWlnaHQ6dGhpcy5faXNOdW1iZXIoby5taW5IZWlnaHQpP28ubWluSGVpZ2h0OjAsbWF4SGVpZ2h0OnRoaXMuX2lzTnVtYmVyKG8ubWF4SGVpZ2h0KT9vLm1heEhlaWdodDoxLzB9LCh0aGlzLl9hc3BlY3RSYXRpb3x8ZSkmJih0PWEubWluSGVpZ2h0KnRoaXMuYXNwZWN0UmF0aW8scz1hLm1pbldpZHRoL3RoaXMuYXNwZWN0UmF0aW8saT1hLm1heEhlaWdodCp0aGlzLmFzcGVjdFJhdGlvLG49YS5tYXhXaWR0aC90aGlzLmFzcGVjdFJhdGlvLHQ+YS5taW5XaWR0aCYmKGEubWluV2lkdGg9dCkscz5hLm1pbkhlaWdodCYmKGEubWluSGVpZ2h0PXMpLGEubWF4V2lkdGg+aSYmKGEubWF4V2lkdGg9aSksYS5tYXhIZWlnaHQ+biYmKGEubWF4SGVpZ2h0PW4pKSx0aGlzLl92Qm91bmRhcmllcz1hfSxfdXBkYXRlQ2FjaGU6ZnVuY3Rpb24oZSl7dGhpcy5vZmZzZXQ9dGhpcy5oZWxwZXIub2Zmc2V0KCksdGhpcy5faXNOdW1iZXIoZS5sZWZ0KSYmKHRoaXMucG9zaXRpb24ubGVmdD1lLmxlZnQpLHRoaXMuX2lzTnVtYmVyKGUudG9wKSYmKHRoaXMucG9zaXRpb24udG9wPWUudG9wKSx0aGlzLl9pc051bWJlcihlLmhlaWdodCkmJih0aGlzLnNpemUuaGVpZ2h0PWUuaGVpZ2h0KSx0aGlzLl9pc051bWJlcihlLndpZHRoKSYmKHRoaXMuc2l6ZS53aWR0aD1lLndpZHRoKX0sX3VwZGF0ZVJhdGlvOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucG9zaXRpb24saT10aGlzLnNpemUscz10aGlzLmF4aXM7cmV0dXJuIHRoaXMuX2lzTnVtYmVyKGUuaGVpZ2h0KT9lLndpZHRoPWUuaGVpZ2h0KnRoaXMuYXNwZWN0UmF0aW86dGhpcy5faXNOdW1iZXIoZS53aWR0aCkmJihlLmhlaWdodD1lLndpZHRoL3RoaXMuYXNwZWN0UmF0aW8pLFwic3dcIj09PXMmJihlLmxlZnQ9dC5sZWZ0KyhpLndpZHRoLWUud2lkdGgpLGUudG9wPW51bGwpLFwibndcIj09PXMmJihlLnRvcD10LnRvcCsoaS5oZWlnaHQtZS5oZWlnaHQpLGUubGVmdD10LmxlZnQrKGkud2lkdGgtZS53aWR0aCkpLGV9LF9yZXNwZWN0U2l6ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLl92Qm91bmRhcmllcyxpPXRoaXMuYXhpcyxzPXRoaXMuX2lzTnVtYmVyKGUud2lkdGgpJiZ0Lm1heFdpZHRoJiZ0Lm1heFdpZHRoPGUud2lkdGgsbj10aGlzLl9pc051bWJlcihlLmhlaWdodCkmJnQubWF4SGVpZ2h0JiZ0Lm1heEhlaWdodDxlLmhlaWdodCxhPXRoaXMuX2lzTnVtYmVyKGUud2lkdGgpJiZ0Lm1pbldpZHRoJiZ0Lm1pbldpZHRoPmUud2lkdGgsbz10aGlzLl9pc051bWJlcihlLmhlaWdodCkmJnQubWluSGVpZ2h0JiZ0Lm1pbkhlaWdodD5lLmhlaWdodCxyPXRoaXMub3JpZ2luYWxQb3NpdGlvbi5sZWZ0K3RoaXMub3JpZ2luYWxTaXplLndpZHRoLGg9dGhpcy5wb3NpdGlvbi50b3ArdGhpcy5zaXplLmhlaWdodCxsPS9zd3xud3x3Ly50ZXN0KGkpLHU9L253fG5lfG4vLnRlc3QoaSk7cmV0dXJuIGEmJihlLndpZHRoPXQubWluV2lkdGgpLG8mJihlLmhlaWdodD10Lm1pbkhlaWdodCkscyYmKGUud2lkdGg9dC5tYXhXaWR0aCksbiYmKGUuaGVpZ2h0PXQubWF4SGVpZ2h0KSxhJiZsJiYoZS5sZWZ0PXItdC5taW5XaWR0aCkscyYmbCYmKGUubGVmdD1yLXQubWF4V2lkdGgpLG8mJnUmJihlLnRvcD1oLXQubWluSGVpZ2h0KSxuJiZ1JiYoZS50b3A9aC10Lm1heEhlaWdodCksZS53aWR0aHx8ZS5oZWlnaHR8fGUubGVmdHx8IWUudG9wP2Uud2lkdGh8fGUuaGVpZ2h0fHxlLnRvcHx8IWUubGVmdHx8KGUubGVmdD1udWxsKTplLnRvcD1udWxsLGV9LF9nZXRQYWRkaW5nUGx1c0JvcmRlckRpbWVuc2lvbnM6ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTAsaT1bXSxzPVtlLmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLGUuY3NzKFwiYm9yZGVyUmlnaHRXaWR0aFwiKSxlLmNzcyhcImJvcmRlckJvdHRvbVdpZHRoXCIpLGUuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpXSxuPVtlLmNzcyhcInBhZGRpbmdUb3BcIiksZS5jc3MoXCJwYWRkaW5nUmlnaHRcIiksZS5jc3MoXCJwYWRkaW5nQm90dG9tXCIpLGUuY3NzKFwicGFkZGluZ0xlZnRcIildOzQ+dDt0KyspaVt0XT1wYXJzZUludChzW3RdLDEwKXx8MCxpW3RdKz1wYXJzZUludChuW3RdLDEwKXx8MDtyZXR1cm57aGVpZ2h0OmlbMF0raVsyXSx3aWR0aDppWzFdK2lbM119fSxfcHJvcG9ydGlvbmFsbHlSZXNpemU6ZnVuY3Rpb24oKXtpZih0aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZUVsZW1lbnRzLmxlbmd0aClmb3IodmFyIGUsdD0wLGk9dGhpcy5oZWxwZXJ8fHRoaXMuZWxlbWVudDt0aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZUVsZW1lbnRzLmxlbmd0aD50O3QrKyllPXRoaXMuX3Byb3BvcnRpb25hbGx5UmVzaXplRWxlbWVudHNbdF0sdGhpcy5vdXRlckRpbWVuc2lvbnN8fCh0aGlzLm91dGVyRGltZW5zaW9ucz10aGlzLl9nZXRQYWRkaW5nUGx1c0JvcmRlckRpbWVuc2lvbnMoZSkpLGUuY3NzKHtoZWlnaHQ6aS5oZWlnaHQoKS10aGlzLm91dGVyRGltZW5zaW9ucy5oZWlnaHR8fDAsd2lkdGg6aS53aWR0aCgpLXRoaXMub3V0ZXJEaW1lbnNpb25zLndpZHRofHwwfSl9LF9yZW5kZXJQcm94eTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZWxlbWVudCxpPXRoaXMub3B0aW9uczt0aGlzLmVsZW1lbnRPZmZzZXQ9dC5vZmZzZXQoKSx0aGlzLl9oZWxwZXI/KHRoaXMuaGVscGVyPXRoaXMuaGVscGVyfHxlKFwiPGRpdiBzdHlsZT0nb3ZlcmZsb3c6aGlkZGVuOyc+PC9kaXY+XCIpLHRoaXMuaGVscGVyLmFkZENsYXNzKHRoaXMuX2hlbHBlcikuY3NzKHt3aWR0aDp0aGlzLmVsZW1lbnQub3V0ZXJXaWR0aCgpLTEsaGVpZ2h0OnRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpLTEscG9zaXRpb246XCJhYnNvbHV0ZVwiLGxlZnQ6dGhpcy5lbGVtZW50T2Zmc2V0LmxlZnQrXCJweFwiLHRvcDp0aGlzLmVsZW1lbnRPZmZzZXQudG9wK1wicHhcIix6SW5kZXg6KytpLnpJbmRleH0pLHRoaXMuaGVscGVyLmFwcGVuZFRvKFwiYm9keVwiKS5kaXNhYmxlU2VsZWN0aW9uKCkpOnRoaXMuaGVscGVyPXRoaXMuZWxlbWVudH0sX2NoYW5nZTp7ZTpmdW5jdGlvbihlLHQpe3JldHVybnt3aWR0aDp0aGlzLm9yaWdpbmFsU2l6ZS53aWR0aCt0fX0sdzpmdW5jdGlvbihlLHQpe3ZhciBpPXRoaXMub3JpZ2luYWxTaXplLHM9dGhpcy5vcmlnaW5hbFBvc2l0aW9uO3JldHVybntsZWZ0OnMubGVmdCt0LHdpZHRoOmkud2lkdGgtdH19LG46ZnVuY3Rpb24oZSx0LGkpe3ZhciBzPXRoaXMub3JpZ2luYWxTaXplLG49dGhpcy5vcmlnaW5hbFBvc2l0aW9uO3JldHVybnt0b3A6bi50b3AraSxoZWlnaHQ6cy5oZWlnaHQtaX19LHM6ZnVuY3Rpb24oZSx0LGkpe3JldHVybntoZWlnaHQ6dGhpcy5vcmlnaW5hbFNpemUuaGVpZ2h0K2l9fSxzZTpmdW5jdGlvbih0LGkscyl7cmV0dXJuIGUuZXh0ZW5kKHRoaXMuX2NoYW5nZS5zLmFwcGx5KHRoaXMsYXJndW1lbnRzKSx0aGlzLl9jaGFuZ2UuZS5hcHBseSh0aGlzLFt0LGksc10pKX0sc3c6ZnVuY3Rpb24odCxpLHMpe3JldHVybiBlLmV4dGVuZCh0aGlzLl9jaGFuZ2Uucy5hcHBseSh0aGlzLGFyZ3VtZW50cyksdGhpcy5fY2hhbmdlLncuYXBwbHkodGhpcyxbdCxpLHNdKSl9LG5lOmZ1bmN0aW9uKHQsaSxzKXtyZXR1cm4gZS5leHRlbmQodGhpcy5fY2hhbmdlLm4uYXBwbHkodGhpcyxhcmd1bWVudHMpLHRoaXMuX2NoYW5nZS5lLmFwcGx5KHRoaXMsW3QsaSxzXSkpfSxudzpmdW5jdGlvbih0LGkscyl7cmV0dXJuIGUuZXh0ZW5kKHRoaXMuX2NoYW5nZS5uLmFwcGx5KHRoaXMsYXJndW1lbnRzKSx0aGlzLl9jaGFuZ2Uudy5hcHBseSh0aGlzLFt0LGksc10pKX19LF9wcm9wYWdhdGU6ZnVuY3Rpb24odCxpKXtlLnVpLnBsdWdpbi5jYWxsKHRoaXMsdCxbaSx0aGlzLnVpKCldKSxcInJlc2l6ZVwiIT09dCYmdGhpcy5fdHJpZ2dlcih0LGksdGhpcy51aSgpKX0scGx1Z2luczp7fSx1aTpmdW5jdGlvbigpe3JldHVybntvcmlnaW5hbEVsZW1lbnQ6dGhpcy5vcmlnaW5hbEVsZW1lbnQsZWxlbWVudDp0aGlzLmVsZW1lbnQsaGVscGVyOnRoaXMuaGVscGVyLHBvc2l0aW9uOnRoaXMucG9zaXRpb24sc2l6ZTp0aGlzLnNpemUsb3JpZ2luYWxTaXplOnRoaXMub3JpZ2luYWxTaXplLG9yaWdpbmFsUG9zaXRpb246dGhpcy5vcmlnaW5hbFBvc2l0aW9ufX19KSxlLnVpLnBsdWdpbi5hZGQoXCJyZXNpemFibGVcIixcImFuaW1hdGVcIix7c3RvcDpmdW5jdGlvbih0KXt2YXIgaT1lKHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLHM9aS5vcHRpb25zLG49aS5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cyxhPW4ubGVuZ3RoJiYvdGV4dGFyZWEvaS50ZXN0KG5bMF0ubm9kZU5hbWUpLG89YSYmaS5faGFzU2Nyb2xsKG5bMF0sXCJsZWZ0XCIpPzA6aS5zaXplRGlmZi5oZWlnaHQscj1hPzA6aS5zaXplRGlmZi53aWR0aCxoPXt3aWR0aDppLnNpemUud2lkdGgtcixoZWlnaHQ6aS5zaXplLmhlaWdodC1vfSxsPXBhcnNlSW50KGkuZWxlbWVudC5jc3MoXCJsZWZ0XCIpLDEwKSsoaS5wb3NpdGlvbi5sZWZ0LWkub3JpZ2luYWxQb3NpdGlvbi5sZWZ0KXx8bnVsbCx1PXBhcnNlSW50KGkuZWxlbWVudC5jc3MoXCJ0b3BcIiksMTApKyhpLnBvc2l0aW9uLnRvcC1pLm9yaWdpbmFsUG9zaXRpb24udG9wKXx8bnVsbDtpLmVsZW1lbnQuYW5pbWF0ZShlLmV4dGVuZChoLHUmJmw/e3RvcDp1LGxlZnQ6bH06e30pLHtkdXJhdGlvbjpzLmFuaW1hdGVEdXJhdGlvbixlYXNpbmc6cy5hbmltYXRlRWFzaW5nLHN0ZXA6ZnVuY3Rpb24oKXt2YXIgcz17d2lkdGg6cGFyc2VJbnQoaS5lbGVtZW50LmNzcyhcIndpZHRoXCIpLDEwKSxoZWlnaHQ6cGFyc2VJbnQoaS5lbGVtZW50LmNzcyhcImhlaWdodFwiKSwxMCksdG9wOnBhcnNlSW50KGkuZWxlbWVudC5jc3MoXCJ0b3BcIiksMTApLGxlZnQ6cGFyc2VJbnQoaS5lbGVtZW50LmNzcyhcImxlZnRcIiksMTApfTtuJiZuLmxlbmd0aCYmZShuWzBdKS5jc3Moe3dpZHRoOnMud2lkdGgsaGVpZ2h0OnMuaGVpZ2h0fSksaS5fdXBkYXRlQ2FjaGUocyksaS5fcHJvcGFnYXRlKFwicmVzaXplXCIsdCl9fSl9fSksZS51aS5wbHVnaW4uYWRkKFwicmVzaXphYmxlXCIsXCJjb250YWlubWVudFwiLHtzdGFydDpmdW5jdGlvbigpe3ZhciB0LGkscyxuLGEsbyxyLGg9ZSh0aGlzKS5yZXNpemFibGUoXCJpbnN0YW5jZVwiKSxsPWgub3B0aW9ucyx1PWguZWxlbWVudCxkPWwuY29udGFpbm1lbnQsYz1kIGluc3RhbmNlb2YgZT9kLmdldCgwKTovcGFyZW50Ly50ZXN0KGQpP3UucGFyZW50KCkuZ2V0KDApOmQ7YyYmKGguY29udGFpbmVyRWxlbWVudD1lKGMpLC9kb2N1bWVudC8udGVzdChkKXx8ZD09PWRvY3VtZW50PyhoLmNvbnRhaW5lck9mZnNldD17bGVmdDowLHRvcDowfSxoLmNvbnRhaW5lclBvc2l0aW9uPXtsZWZ0OjAsdG9wOjB9LGgucGFyZW50RGF0YT17ZWxlbWVudDplKGRvY3VtZW50KSxsZWZ0OjAsdG9wOjAsd2lkdGg6ZShkb2N1bWVudCkud2lkdGgoKSxoZWlnaHQ6ZShkb2N1bWVudCkuaGVpZ2h0KCl8fGRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zY3JvbGxIZWlnaHR9KToodD1lKGMpLGk9W10sZShbXCJUb3BcIixcIlJpZ2h0XCIsXCJMZWZ0XCIsXCJCb3R0b21cIl0pLmVhY2goZnVuY3Rpb24oZSxzKXtpW2VdPWguX251bSh0LmNzcyhcInBhZGRpbmdcIitzKSl9KSxoLmNvbnRhaW5lck9mZnNldD10Lm9mZnNldCgpLGguY29udGFpbmVyUG9zaXRpb249dC5wb3NpdGlvbigpLGguY29udGFpbmVyU2l6ZT17aGVpZ2h0OnQuaW5uZXJIZWlnaHQoKS1pWzNdLHdpZHRoOnQuaW5uZXJXaWR0aCgpLWlbMV19LHM9aC5jb250YWluZXJPZmZzZXQsbj1oLmNvbnRhaW5lclNpemUuaGVpZ2h0LGE9aC5jb250YWluZXJTaXplLndpZHRoLG89aC5faGFzU2Nyb2xsKGMsXCJsZWZ0XCIpP2Muc2Nyb2xsV2lkdGg6YSxyPWguX2hhc1Njcm9sbChjKT9jLnNjcm9sbEhlaWdodDpuLGgucGFyZW50RGF0YT17ZWxlbWVudDpjLGxlZnQ6cy5sZWZ0LHRvcDpzLnRvcCx3aWR0aDpvLGhlaWdodDpyfSkpfSxyZXNpemU6ZnVuY3Rpb24odCl7dmFyIGkscyxuLGEsbz1lKHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLHI9by5vcHRpb25zLGg9by5jb250YWluZXJPZmZzZXQsbD1vLnBvc2l0aW9uLHU9by5fYXNwZWN0UmF0aW98fHQuc2hpZnRLZXksZD17dG9wOjAsbGVmdDowfSxjPW8uY29udGFpbmVyRWxlbWVudCxwPSEwO2NbMF0hPT1kb2N1bWVudCYmL3N0YXRpYy8udGVzdChjLmNzcyhcInBvc2l0aW9uXCIpKSYmKGQ9aCksbC5sZWZ0PChvLl9oZWxwZXI/aC5sZWZ0OjApJiYoby5zaXplLndpZHRoPW8uc2l6ZS53aWR0aCsoby5faGVscGVyP28ucG9zaXRpb24ubGVmdC1oLmxlZnQ6by5wb3NpdGlvbi5sZWZ0LWQubGVmdCksdSYmKG8uc2l6ZS5oZWlnaHQ9by5zaXplLndpZHRoL28uYXNwZWN0UmF0aW8scD0hMSksby5wb3NpdGlvbi5sZWZ0PXIuaGVscGVyP2gubGVmdDowKSxsLnRvcDwoby5faGVscGVyP2gudG9wOjApJiYoby5zaXplLmhlaWdodD1vLnNpemUuaGVpZ2h0KyhvLl9oZWxwZXI/by5wb3NpdGlvbi50b3AtaC50b3A6by5wb3NpdGlvbi50b3ApLHUmJihvLnNpemUud2lkdGg9by5zaXplLmhlaWdodCpvLmFzcGVjdFJhdGlvLHA9ITEpLG8ucG9zaXRpb24udG9wPW8uX2hlbHBlcj9oLnRvcDowKSxuPW8uY29udGFpbmVyRWxlbWVudC5nZXQoMCk9PT1vLmVsZW1lbnQucGFyZW50KCkuZ2V0KDApLGE9L3JlbGF0aXZlfGFic29sdXRlLy50ZXN0KG8uY29udGFpbmVyRWxlbWVudC5jc3MoXCJwb3NpdGlvblwiKSksbiYmYT8oby5vZmZzZXQubGVmdD1vLnBhcmVudERhdGEubGVmdCtvLnBvc2l0aW9uLmxlZnQsby5vZmZzZXQudG9wPW8ucGFyZW50RGF0YS50b3Arby5wb3NpdGlvbi50b3ApOihvLm9mZnNldC5sZWZ0PW8uZWxlbWVudC5vZmZzZXQoKS5sZWZ0LG8ub2Zmc2V0LnRvcD1vLmVsZW1lbnQub2Zmc2V0KCkudG9wKSxpPU1hdGguYWJzKG8uc2l6ZURpZmYud2lkdGgrKG8uX2hlbHBlcj9vLm9mZnNldC5sZWZ0LWQubGVmdDpvLm9mZnNldC5sZWZ0LWgubGVmdCkpLHM9TWF0aC5hYnMoby5zaXplRGlmZi5oZWlnaHQrKG8uX2hlbHBlcj9vLm9mZnNldC50b3AtZC50b3A6by5vZmZzZXQudG9wLWgudG9wKSksaStvLnNpemUud2lkdGg+PW8ucGFyZW50RGF0YS53aWR0aCYmKG8uc2l6ZS53aWR0aD1vLnBhcmVudERhdGEud2lkdGgtaSx1JiYoby5zaXplLmhlaWdodD1vLnNpemUud2lkdGgvby5hc3BlY3RSYXRpbyxwPSExKSkscytvLnNpemUuaGVpZ2h0Pj1vLnBhcmVudERhdGEuaGVpZ2h0JiYoby5zaXplLmhlaWdodD1vLnBhcmVudERhdGEuaGVpZ2h0LXMsdSYmKG8uc2l6ZS53aWR0aD1vLnNpemUuaGVpZ2h0Km8uYXNwZWN0UmF0aW8scD0hMSkpLHB8fChvLnBvc2l0aW9uLmxlZnQ9by5wcmV2UG9zaXRpb24ubGVmdCxvLnBvc2l0aW9uLnRvcD1vLnByZXZQb3NpdGlvbi50b3Asby5zaXplLndpZHRoPW8ucHJldlNpemUud2lkdGgsby5zaXplLmhlaWdodD1vLnByZXZTaXplLmhlaWdodCl9LHN0b3A6ZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLGk9dC5vcHRpb25zLHM9dC5jb250YWluZXJPZmZzZXQsbj10LmNvbnRhaW5lclBvc2l0aW9uLGE9dC5jb250YWluZXJFbGVtZW50LG89ZSh0LmhlbHBlcikscj1vLm9mZnNldCgpLGg9by5vdXRlcldpZHRoKCktdC5zaXplRGlmZi53aWR0aCxsPW8ub3V0ZXJIZWlnaHQoKS10LnNpemVEaWZmLmhlaWdodDt0Ll9oZWxwZXImJiFpLmFuaW1hdGUmJi9yZWxhdGl2ZS8udGVzdChhLmNzcyhcInBvc2l0aW9uXCIpKSYmZSh0aGlzKS5jc3Moe2xlZnQ6ci5sZWZ0LW4ubGVmdC1zLmxlZnQsd2lkdGg6aCxoZWlnaHQ6bH0pLHQuX2hlbHBlciYmIWkuYW5pbWF0ZSYmL3N0YXRpYy8udGVzdChhLmNzcyhcInBvc2l0aW9uXCIpKSYmZSh0aGlzKS5jc3Moe2xlZnQ6ci5sZWZ0LW4ubGVmdC1zLmxlZnQsd2lkdGg6aCxoZWlnaHQ6bH0pfX0pLGUudWkucGx1Z2luLmFkZChcInJlc2l6YWJsZVwiLFwiYWxzb1Jlc2l6ZVwiLHtzdGFydDpmdW5jdGlvbigpe3ZhciB0PWUodGhpcykucmVzaXphYmxlKFwiaW5zdGFuY2VcIiksaT10Lm9wdGlvbnM7ZShpLmFsc29SZXNpemUpLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpO3QuZGF0YShcInVpLXJlc2l6YWJsZS1hbHNvcmVzaXplXCIse3dpZHRoOnBhcnNlSW50KHQud2lkdGgoKSwxMCksaGVpZ2h0OnBhcnNlSW50KHQuaGVpZ2h0KCksMTApLGxlZnQ6cGFyc2VJbnQodC5jc3MoXCJsZWZ0XCIpLDEwKSx0b3A6cGFyc2VJbnQodC5jc3MoXCJ0b3BcIiksMTApfSl9KX0scmVzaXplOmZ1bmN0aW9uKHQsaSl7dmFyIHM9ZSh0aGlzKS5yZXNpemFibGUoXCJpbnN0YW5jZVwiKSxuPXMub3B0aW9ucyxhPXMub3JpZ2luYWxTaXplLG89cy5vcmlnaW5hbFBvc2l0aW9uLHI9e2hlaWdodDpzLnNpemUuaGVpZ2h0LWEuaGVpZ2h0fHwwLHdpZHRoOnMuc2l6ZS53aWR0aC1hLndpZHRofHwwLHRvcDpzLnBvc2l0aW9uLnRvcC1vLnRvcHx8MCxsZWZ0OnMucG9zaXRpb24ubGVmdC1vLmxlZnR8fDB9O2Uobi5hbHNvUmVzaXplKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKSxzPWUodGhpcykuZGF0YShcInVpLXJlc2l6YWJsZS1hbHNvcmVzaXplXCIpLG49e30sYT10LnBhcmVudHMoaS5vcmlnaW5hbEVsZW1lbnRbMF0pLmxlbmd0aD9bXCJ3aWR0aFwiLFwiaGVpZ2h0XCJdOltcIndpZHRoXCIsXCJoZWlnaHRcIixcInRvcFwiLFwibGVmdFwiXTtlLmVhY2goYSxmdW5jdGlvbihlLHQpe3ZhciBpPShzW3RdfHwwKSsoclt0XXx8MCk7aSYmaT49MCYmKG5bdF09aXx8bnVsbCl9KSx0LmNzcyhuKX0pfSxzdG9wOmZ1bmN0aW9uKCl7ZSh0aGlzKS5yZW1vdmVEYXRhKFwicmVzaXphYmxlLWFsc29yZXNpemVcIil9fSksZS51aS5wbHVnaW4uYWRkKFwicmVzaXphYmxlXCIsXCJnaG9zdFwiLHtzdGFydDpmdW5jdGlvbigpe3ZhciB0PWUodGhpcykucmVzaXphYmxlKFwiaW5zdGFuY2VcIiksaT10Lm9wdGlvbnMscz10LnNpemU7dC5naG9zdD10Lm9yaWdpbmFsRWxlbWVudC5jbG9uZSgpLHQuZ2hvc3QuY3NzKHtvcGFjaXR5Oi4yNSxkaXNwbGF5OlwiYmxvY2tcIixwb3NpdGlvbjpcInJlbGF0aXZlXCIsaGVpZ2h0OnMuaGVpZ2h0LHdpZHRoOnMud2lkdGgsbWFyZ2luOjAsbGVmdDowLHRvcDowfSkuYWRkQ2xhc3MoXCJ1aS1yZXNpemFibGUtZ2hvc3RcIikuYWRkQ2xhc3MoXCJzdHJpbmdcIj09dHlwZW9mIGkuZ2hvc3Q/aS5naG9zdDpcIlwiKSx0Lmdob3N0LmFwcGVuZFRvKHQuaGVscGVyKX0scmVzaXplOmZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKS5yZXNpemFibGUoXCJpbnN0YW5jZVwiKTt0Lmdob3N0JiZ0Lmdob3N0LmNzcyh7cG9zaXRpb246XCJyZWxhdGl2ZVwiLGhlaWdodDp0LnNpemUuaGVpZ2h0LHdpZHRoOnQuc2l6ZS53aWR0aH0pfSxzdG9wOmZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKS5yZXNpemFibGUoXCJpbnN0YW5jZVwiKTt0Lmdob3N0JiZ0LmhlbHBlciYmdC5oZWxwZXIuZ2V0KDApLnJlbW92ZUNoaWxkKHQuZ2hvc3QuZ2V0KDApKX19KSxlLnVpLnBsdWdpbi5hZGQoXCJyZXNpemFibGVcIixcImdyaWRcIix7cmVzaXplOmZ1bmN0aW9uKCl7dmFyIHQsaT1lKHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLHM9aS5vcHRpb25zLG49aS5zaXplLGE9aS5vcmlnaW5hbFNpemUsbz1pLm9yaWdpbmFsUG9zaXRpb24scj1pLmF4aXMsaD1cIm51bWJlclwiPT10eXBlb2Ygcy5ncmlkP1tzLmdyaWQscy5ncmlkXTpzLmdyaWQsbD1oWzBdfHwxLHU9aFsxXXx8MSxkPU1hdGgucm91bmQoKG4ud2lkdGgtYS53aWR0aCkvbCkqbCxjPU1hdGgucm91bmQoKG4uaGVpZ2h0LWEuaGVpZ2h0KS91KSp1LHA9YS53aWR0aCtkLGY9YS5oZWlnaHQrYyxtPXMubWF4V2lkdGgmJnA+cy5tYXhXaWR0aCxnPXMubWF4SGVpZ2h0JiZmPnMubWF4SGVpZ2h0LHY9cy5taW5XaWR0aCYmcy5taW5XaWR0aD5wLHk9cy5taW5IZWlnaHQmJnMubWluSGVpZ2h0PmY7cy5ncmlkPWgsdiYmKHArPWwpLHkmJihmKz11KSxtJiYocC09bCksZyYmKGYtPXUpLC9eKHNlfHN8ZSkkLy50ZXN0KHIpPyhpLnNpemUud2lkdGg9cCxpLnNpemUuaGVpZ2h0PWYpOi9eKG5lKSQvLnRlc3Qocik/KGkuc2l6ZS53aWR0aD1wLGkuc2l6ZS5oZWlnaHQ9ZixpLnBvc2l0aW9uLnRvcD1vLnRvcC1jKTovXihzdykkLy50ZXN0KHIpPyhpLnNpemUud2lkdGg9cCxpLnNpemUuaGVpZ2h0PWYsaS5wb3NpdGlvbi5sZWZ0PW8ubGVmdC1kKTooKDA+PWYtdXx8MD49cC1sKSYmKHQ9aS5fZ2V0UGFkZGluZ1BsdXNCb3JkZXJEaW1lbnNpb25zKHRoaXMpKSxmLXU+MD8oaS5zaXplLmhlaWdodD1mLGkucG9zaXRpb24udG9wPW8udG9wLWMpOihmPXUtdC5oZWlnaHQsaS5zaXplLmhlaWdodD1mLGkucG9zaXRpb24udG9wPW8udG9wK2EuaGVpZ2h0LWYpLHAtbD4wPyhpLnNpemUud2lkdGg9cCxpLnBvc2l0aW9uLmxlZnQ9by5sZWZ0LWQpOihwPWwtdC53aWR0aCxpLnNpemUud2lkdGg9cCxpLnBvc2l0aW9uLmxlZnQ9by5sZWZ0K2Eud2lkdGgtcCkpfX0pLGUudWkucmVzaXphYmxlLGUud2lkZ2V0KFwidWkuZGlhbG9nXCIse3ZlcnNpb246XCIxLjExLjRcIixvcHRpb25zOnthcHBlbmRUbzpcImJvZHlcIixhdXRvT3BlbjohMCxidXR0b25zOltdLGNsb3NlT25Fc2NhcGU6ITAsY2xvc2VUZXh0OlwiQ2xvc2VcIixkaWFsb2dDbGFzczpcIlwiLGRyYWdnYWJsZTohMCxoaWRlOm51bGwsaGVpZ2h0OlwiYXV0b1wiLG1heEhlaWdodDpudWxsLG1heFdpZHRoOm51bGwsbWluSGVpZ2h0OjE1MCxtaW5XaWR0aDoxNTAsbW9kYWw6ITEscG9zaXRpb246e215OlwiY2VudGVyXCIsYXQ6XCJjZW50ZXJcIixvZjp3aW5kb3csY29sbGlzaW9uOlwiZml0XCIsdXNpbmc6ZnVuY3Rpb24odCl7dmFyIGk9ZSh0aGlzKS5jc3ModCkub2Zmc2V0KCkudG9wOzA+aSYmZSh0aGlzKS5jc3MoXCJ0b3BcIix0LnRvcC1pKX19LHJlc2l6YWJsZTohMCxzaG93Om51bGwsdGl0bGU6bnVsbCx3aWR0aDozMDAsYmVmb3JlQ2xvc2U6bnVsbCxjbG9zZTpudWxsLGRyYWc6bnVsbCxkcmFnU3RhcnQ6bnVsbCxkcmFnU3RvcDpudWxsLGZvY3VzOm51bGwsb3BlbjpudWxsLHJlc2l6ZTpudWxsLHJlc2l6ZVN0YXJ0Om51bGwscmVzaXplU3RvcDpudWxsfSxzaXplUmVsYXRlZE9wdGlvbnM6e2J1dHRvbnM6ITAsaGVpZ2h0OiEwLG1heEhlaWdodDohMCxtYXhXaWR0aDohMCxtaW5IZWlnaHQ6ITAsbWluV2lkdGg6ITAsd2lkdGg6ITB9LHJlc2l6YWJsZVJlbGF0ZWRPcHRpb25zOnttYXhIZWlnaHQ6ITAsbWF4V2lkdGg6ITAsbWluSGVpZ2h0OiEwLG1pbldpZHRoOiEwfSxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5vcmlnaW5hbENzcz17ZGlzcGxheTp0aGlzLmVsZW1lbnRbMF0uc3R5bGUuZGlzcGxheSx3aWR0aDp0aGlzLmVsZW1lbnRbMF0uc3R5bGUud2lkdGgsbWluSGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5taW5IZWlnaHQsbWF4SGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5tYXhIZWlnaHQsaGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5oZWlnaHR9LHRoaXMub3JpZ2luYWxQb3NpdGlvbj17cGFyZW50OnRoaXMuZWxlbWVudC5wYXJlbnQoKSxpbmRleDp0aGlzLmVsZW1lbnQucGFyZW50KCkuY2hpbGRyZW4oKS5pbmRleCh0aGlzLmVsZW1lbnQpfSx0aGlzLm9yaWdpbmFsVGl0bGU9dGhpcy5lbGVtZW50LmF0dHIoXCJ0aXRsZVwiKSx0aGlzLm9wdGlvbnMudGl0bGU9dGhpcy5vcHRpb25zLnRpdGxlfHx0aGlzLm9yaWdpbmFsVGl0bGUsdGhpcy5fY3JlYXRlV3JhcHBlcigpLHRoaXMuZWxlbWVudC5zaG93KCkucmVtb3ZlQXR0cihcInRpdGxlXCIpLmFkZENsYXNzKFwidWktZGlhbG9nLWNvbnRlbnQgdWktd2lkZ2V0LWNvbnRlbnRcIikuYXBwZW5kVG8odGhpcy51aURpYWxvZyksdGhpcy5fY3JlYXRlVGl0bGViYXIoKSx0aGlzLl9jcmVhdGVCdXR0b25QYW5lKCksdGhpcy5vcHRpb25zLmRyYWdnYWJsZSYmZS5mbi5kcmFnZ2FibGUmJnRoaXMuX21ha2VEcmFnZ2FibGUoKSx0aGlzLm9wdGlvbnMucmVzaXphYmxlJiZlLmZuLnJlc2l6YWJsZSYmdGhpcy5fbWFrZVJlc2l6YWJsZSgpLHRoaXMuX2lzT3Blbj0hMSx0aGlzLl90cmFja0ZvY3VzKCl9LF9pbml0OmZ1bmN0aW9uKCl7dGhpcy5vcHRpb25zLmF1dG9PcGVuJiZ0aGlzLm9wZW4oKX0sX2FwcGVuZFRvOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5vcHRpb25zLmFwcGVuZFRvO3JldHVybiB0JiYodC5qcXVlcnl8fHQubm9kZVR5cGUpP2UodCk6dGhpcy5kb2N1bWVudC5maW5kKHR8fFwiYm9keVwiKS5lcSgwKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt2YXIgZSx0PXRoaXMub3JpZ2luYWxQb3NpdGlvbjt0aGlzLl91bnRyYWNrSW5zdGFuY2UoKSx0aGlzLl9kZXN0cm95T3ZlcmxheSgpLHRoaXMuZWxlbWVudC5yZW1vdmVVbmlxdWVJZCgpLnJlbW92ZUNsYXNzKFwidWktZGlhbG9nLWNvbnRlbnQgdWktd2lkZ2V0LWNvbnRlbnRcIikuY3NzKHRoaXMub3JpZ2luYWxDc3MpLmRldGFjaCgpLHRoaXMudWlEaWFsb2cuc3RvcCghMCwhMCkucmVtb3ZlKCksdGhpcy5vcmlnaW5hbFRpdGxlJiZ0aGlzLmVsZW1lbnQuYXR0cihcInRpdGxlXCIsdGhpcy5vcmlnaW5hbFRpdGxlKSxlPXQucGFyZW50LmNoaWxkcmVuKCkuZXEodC5pbmRleCksZS5sZW5ndGgmJmVbMF0hPT10aGlzLmVsZW1lbnRbMF0/ZS5iZWZvcmUodGhpcy5lbGVtZW50KTp0LnBhcmVudC5hcHBlbmQodGhpcy5lbGVtZW50KX0sd2lkZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudWlEaWFsb2d9LGRpc2FibGU6ZS5ub29wLGVuYWJsZTplLm5vb3AsY2xvc2U6ZnVuY3Rpb24odCl7dmFyIGkscz10aGlzO2lmKHRoaXMuX2lzT3BlbiYmdGhpcy5fdHJpZ2dlcihcImJlZm9yZUNsb3NlXCIsdCkhPT0hMSl7aWYodGhpcy5faXNPcGVuPSExLHRoaXMuX2ZvY3VzZWRFbGVtZW50PW51bGwsdGhpcy5fZGVzdHJveU92ZXJsYXkoKSx0aGlzLl91bnRyYWNrSW5zdGFuY2UoKSwhdGhpcy5vcGVuZXIuZmlsdGVyKFwiOmZvY3VzYWJsZVwiKS5mb2N1cygpLmxlbmd0aCl0cnl7aT10aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQsaSYmXCJib2R5XCIhPT1pLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkmJmUoaSkuYmx1cigpfWNhdGNoKG4pe310aGlzLl9oaWRlKHRoaXMudWlEaWFsb2csdGhpcy5vcHRpb25zLmhpZGUsZnVuY3Rpb24oKXtzLl90cmlnZ2VyKFwiY2xvc2VcIix0KX0pfX0saXNPcGVuOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2lzT3Blbn0sbW92ZVRvVG9wOmZ1bmN0aW9uKCl7dGhpcy5fbW92ZVRvVG9wKCl9LF9tb3ZlVG9Ub3A6ZnVuY3Rpb24odCxpKXt2YXIgcz0hMSxuPXRoaXMudWlEaWFsb2cuc2libGluZ3MoXCIudWktZnJvbnQ6dmlzaWJsZVwiKS5tYXAoZnVuY3Rpb24oKXtyZXR1cm4rZSh0aGlzKS5jc3MoXCJ6LWluZGV4XCIpfSkuZ2V0KCksYT1NYXRoLm1heC5hcHBseShudWxsLG4pO3JldHVybiBhPj0rdGhpcy51aURpYWxvZy5jc3MoXCJ6LWluZGV4XCIpJiYodGhpcy51aURpYWxvZy5jc3MoXCJ6LWluZGV4XCIsYSsxKSxzPSEwKSxzJiYhaSYmdGhpcy5fdHJpZ2dlcihcImZvY3VzXCIsdCksc30sb3BlbjpmdW5jdGlvbigpe3ZhciB0PXRoaXM7cmV0dXJuIHRoaXMuX2lzT3Blbj8odGhpcy5fbW92ZVRvVG9wKCkmJnRoaXMuX2ZvY3VzVGFiYmFibGUoKSx2b2lkIDApOih0aGlzLl9pc09wZW49ITAsdGhpcy5vcGVuZXI9ZSh0aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQpLHRoaXMuX3NpemUoKSx0aGlzLl9wb3NpdGlvbigpLHRoaXMuX2NyZWF0ZU92ZXJsYXkoKSx0aGlzLl9tb3ZlVG9Ub3AobnVsbCwhMCksdGhpcy5vdmVybGF5JiZ0aGlzLm92ZXJsYXkuY3NzKFwiei1pbmRleFwiLHRoaXMudWlEaWFsb2cuY3NzKFwiei1pbmRleFwiKS0xKSx0aGlzLl9zaG93KHRoaXMudWlEaWFsb2csdGhpcy5vcHRpb25zLnNob3csZnVuY3Rpb24oKXt0Ll9mb2N1c1RhYmJhYmxlKCksdC5fdHJpZ2dlcihcImZvY3VzXCIpfSksdGhpcy5fbWFrZUZvY3VzVGFyZ2V0KCksdGhpcy5fdHJpZ2dlcihcIm9wZW5cIiksdm9pZCAwKX0sX2ZvY3VzVGFiYmFibGU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLl9mb2N1c2VkRWxlbWVudDtlfHwoZT10aGlzLmVsZW1lbnQuZmluZChcIlthdXRvZm9jdXNdXCIpKSxlLmxlbmd0aHx8KGU9dGhpcy5lbGVtZW50LmZpbmQoXCI6dGFiYmFibGVcIikpLGUubGVuZ3RofHwoZT10aGlzLnVpRGlhbG9nQnV0dG9uUGFuZS5maW5kKFwiOnRhYmJhYmxlXCIpKSxlLmxlbmd0aHx8KGU9dGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2UuZmlsdGVyKFwiOnRhYmJhYmxlXCIpKSxlLmxlbmd0aHx8KGU9dGhpcy51aURpYWxvZyksZS5lcSgwKS5mb2N1cygpfSxfa2VlcEZvY3VzOmZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGkoKXt2YXIgdD10aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQsaT10aGlzLnVpRGlhbG9nWzBdPT09dHx8ZS5jb250YWlucyh0aGlzLnVpRGlhbG9nWzBdLHQpO2l8fHRoaXMuX2ZvY3VzVGFiYmFibGUoKX10LnByZXZlbnREZWZhdWx0KCksaS5jYWxsKHRoaXMpLHRoaXMuX2RlbGF5KGkpfSxfY3JlYXRlV3JhcHBlcjpmdW5jdGlvbigpe3RoaXMudWlEaWFsb2c9ZShcIjxkaXY+XCIpLmFkZENsYXNzKFwidWktZGlhbG9nIHVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1jb3JuZXItYWxsIHVpLWZyb250IFwiK3RoaXMub3B0aW9ucy5kaWFsb2dDbGFzcykuaGlkZSgpLmF0dHIoe3RhYkluZGV4Oi0xLHJvbGU6XCJkaWFsb2dcIn0pLmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLHRoaXMuX29uKHRoaXMudWlEaWFsb2cse2tleWRvd246ZnVuY3Rpb24odCl7aWYodGhpcy5vcHRpb25zLmNsb3NlT25Fc2NhcGUmJiF0LmlzRGVmYXVsdFByZXZlbnRlZCgpJiZ0LmtleUNvZGUmJnQua2V5Q29kZT09PWUudWkua2V5Q29kZS5FU0NBUEUpcmV0dXJuIHQucHJldmVudERlZmF1bHQoKSx0aGlzLmNsb3NlKHQpLHZvaWQgMDtcclxuaWYodC5rZXlDb2RlPT09ZS51aS5rZXlDb2RlLlRBQiYmIXQuaXNEZWZhdWx0UHJldmVudGVkKCkpe3ZhciBpPXRoaXMudWlEaWFsb2cuZmluZChcIjp0YWJiYWJsZVwiKSxzPWkuZmlsdGVyKFwiOmZpcnN0XCIpLG49aS5maWx0ZXIoXCI6bGFzdFwiKTt0LnRhcmdldCE9PW5bMF0mJnQudGFyZ2V0IT09dGhpcy51aURpYWxvZ1swXXx8dC5zaGlmdEtleT90LnRhcmdldCE9PXNbMF0mJnQudGFyZ2V0IT09dGhpcy51aURpYWxvZ1swXXx8IXQuc2hpZnRLZXl8fCh0aGlzLl9kZWxheShmdW5jdGlvbigpe24uZm9jdXMoKX0pLHQucHJldmVudERlZmF1bHQoKSk6KHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7cy5mb2N1cygpfSksdC5wcmV2ZW50RGVmYXVsdCgpKX19LG1vdXNlZG93bjpmdW5jdGlvbihlKXt0aGlzLl9tb3ZlVG9Ub3AoZSkmJnRoaXMuX2ZvY3VzVGFiYmFibGUoKX19KSx0aGlzLmVsZW1lbnQuZmluZChcIlthcmlhLWRlc2NyaWJlZGJ5XVwiKS5sZW5ndGh8fHRoaXMudWlEaWFsb2cuYXR0cih7XCJhcmlhLWRlc2NyaWJlZGJ5XCI6dGhpcy5lbGVtZW50LnVuaXF1ZUlkKCkuYXR0cihcImlkXCIpfSl9LF9jcmVhdGVUaXRsZWJhcjpmdW5jdGlvbigpe3ZhciB0O3RoaXMudWlEaWFsb2dUaXRsZWJhcj1lKFwiPGRpdj5cIikuYWRkQ2xhc3MoXCJ1aS1kaWFsb2ctdGl0bGViYXIgdWktd2lkZ2V0LWhlYWRlciB1aS1jb3JuZXItYWxsIHVpLWhlbHBlci1jbGVhcmZpeFwiKS5wcmVwZW5kVG8odGhpcy51aURpYWxvZyksdGhpcy5fb24odGhpcy51aURpYWxvZ1RpdGxlYmFyLHttb3VzZWRvd246ZnVuY3Rpb24odCl7ZSh0LnRhcmdldCkuY2xvc2VzdChcIi51aS1kaWFsb2ctdGl0bGViYXItY2xvc2VcIil8fHRoaXMudWlEaWFsb2cuZm9jdXMoKX19KSx0aGlzLnVpRGlhbG9nVGl0bGViYXJDbG9zZT1lKFwiPGJ1dHRvbiB0eXBlPSdidXR0b24nPjwvYnV0dG9uPlwiKS5idXR0b24oe2xhYmVsOnRoaXMub3B0aW9ucy5jbG9zZVRleHQsaWNvbnM6e3ByaW1hcnk6XCJ1aS1pY29uLWNsb3NldGhpY2tcIn0sdGV4dDohMX0pLmFkZENsYXNzKFwidWktZGlhbG9nLXRpdGxlYmFyLWNsb3NlXCIpLmFwcGVuZFRvKHRoaXMudWlEaWFsb2dUaXRsZWJhciksdGhpcy5fb24odGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2Use2NsaWNrOmZ1bmN0aW9uKGUpe2UucHJldmVudERlZmF1bHQoKSx0aGlzLmNsb3NlKGUpfX0pLHQ9ZShcIjxzcGFuPlwiKS51bmlxdWVJZCgpLmFkZENsYXNzKFwidWktZGlhbG9nLXRpdGxlXCIpLnByZXBlbmRUbyh0aGlzLnVpRGlhbG9nVGl0bGViYXIpLHRoaXMuX3RpdGxlKHQpLHRoaXMudWlEaWFsb2cuYXR0cih7XCJhcmlhLWxhYmVsbGVkYnlcIjp0LmF0dHIoXCJpZFwiKX0pfSxfdGl0bGU6ZnVuY3Rpb24oZSl7dGhpcy5vcHRpb25zLnRpdGxlfHxlLmh0bWwoXCImIzE2MDtcIiksZS50ZXh0KHRoaXMub3B0aW9ucy50aXRsZSl9LF9jcmVhdGVCdXR0b25QYW5lOmZ1bmN0aW9uKCl7dGhpcy51aURpYWxvZ0J1dHRvblBhbmU9ZShcIjxkaXY+XCIpLmFkZENsYXNzKFwidWktZGlhbG9nLWJ1dHRvbnBhbmUgdWktd2lkZ2V0LWNvbnRlbnQgdWktaGVscGVyLWNsZWFyZml4XCIpLHRoaXMudWlCdXR0b25TZXQ9ZShcIjxkaXY+XCIpLmFkZENsYXNzKFwidWktZGlhbG9nLWJ1dHRvbnNldFwiKS5hcHBlbmRUbyh0aGlzLnVpRGlhbG9nQnV0dG9uUGFuZSksdGhpcy5fY3JlYXRlQnV0dG9ucygpfSxfY3JlYXRlQnV0dG9uczpmdW5jdGlvbigpe3ZhciB0PXRoaXMsaT10aGlzLm9wdGlvbnMuYnV0dG9ucztyZXR1cm4gdGhpcy51aURpYWxvZ0J1dHRvblBhbmUucmVtb3ZlKCksdGhpcy51aUJ1dHRvblNldC5lbXB0eSgpLGUuaXNFbXB0eU9iamVjdChpKXx8ZS5pc0FycmF5KGkpJiYhaS5sZW5ndGg/KHRoaXMudWlEaWFsb2cucmVtb3ZlQ2xhc3MoXCJ1aS1kaWFsb2ctYnV0dG9uc1wiKSx2b2lkIDApOihlLmVhY2goaSxmdW5jdGlvbihpLHMpe3ZhciBuLGE7cz1lLmlzRnVuY3Rpb24ocyk/e2NsaWNrOnMsdGV4dDppfTpzLHM9ZS5leHRlbmQoe3R5cGU6XCJidXR0b25cIn0scyksbj1zLmNsaWNrLHMuY2xpY2s9ZnVuY3Rpb24oKXtuLmFwcGx5KHQuZWxlbWVudFswXSxhcmd1bWVudHMpfSxhPXtpY29uczpzLmljb25zLHRleHQ6cy5zaG93VGV4dH0sZGVsZXRlIHMuaWNvbnMsZGVsZXRlIHMuc2hvd1RleHQsZShcIjxidXR0b24+PC9idXR0b24+XCIscykuYnV0dG9uKGEpLmFwcGVuZFRvKHQudWlCdXR0b25TZXQpfSksdGhpcy51aURpYWxvZy5hZGRDbGFzcyhcInVpLWRpYWxvZy1idXR0b25zXCIpLHRoaXMudWlEaWFsb2dCdXR0b25QYW5lLmFwcGVuZFRvKHRoaXMudWlEaWFsb2cpLHZvaWQgMCl9LF9tYWtlRHJhZ2dhYmxlOmZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChlKXtyZXR1cm57cG9zaXRpb246ZS5wb3NpdGlvbixvZmZzZXQ6ZS5vZmZzZXR9fXZhciBpPXRoaXMscz10aGlzLm9wdGlvbnM7dGhpcy51aURpYWxvZy5kcmFnZ2FibGUoe2NhbmNlbDpcIi51aS1kaWFsb2ctY29udGVudCwgLnVpLWRpYWxvZy10aXRsZWJhci1jbG9zZVwiLGhhbmRsZTpcIi51aS1kaWFsb2ctdGl0bGViYXJcIixjb250YWlubWVudDpcImRvY3VtZW50XCIsc3RhcnQ6ZnVuY3Rpb24ocyxuKXtlKHRoaXMpLmFkZENsYXNzKFwidWktZGlhbG9nLWRyYWdnaW5nXCIpLGkuX2Jsb2NrRnJhbWVzKCksaS5fdHJpZ2dlcihcImRyYWdTdGFydFwiLHMsdChuKSl9LGRyYWc6ZnVuY3Rpb24oZSxzKXtpLl90cmlnZ2VyKFwiZHJhZ1wiLGUsdChzKSl9LHN0b3A6ZnVuY3Rpb24obixhKXt2YXIgbz1hLm9mZnNldC5sZWZ0LWkuZG9jdW1lbnQuc2Nyb2xsTGVmdCgpLHI9YS5vZmZzZXQudG9wLWkuZG9jdW1lbnQuc2Nyb2xsVG9wKCk7cy5wb3NpdGlvbj17bXk6XCJsZWZ0IHRvcFwiLGF0OlwibGVmdFwiKyhvPj0wP1wiK1wiOlwiXCIpK28rXCIgXCIrXCJ0b3BcIisocj49MD9cIitcIjpcIlwiKStyLG9mOmkud2luZG93fSxlKHRoaXMpLnJlbW92ZUNsYXNzKFwidWktZGlhbG9nLWRyYWdnaW5nXCIpLGkuX3VuYmxvY2tGcmFtZXMoKSxpLl90cmlnZ2VyKFwiZHJhZ1N0b3BcIixuLHQoYSkpfX0pfSxfbWFrZVJlc2l6YWJsZTpmdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSl7cmV0dXJue29yaWdpbmFsUG9zaXRpb246ZS5vcmlnaW5hbFBvc2l0aW9uLG9yaWdpbmFsU2l6ZTplLm9yaWdpbmFsU2l6ZSxwb3NpdGlvbjplLnBvc2l0aW9uLHNpemU6ZS5zaXplfX12YXIgaT10aGlzLHM9dGhpcy5vcHRpb25zLG49cy5yZXNpemFibGUsYT10aGlzLnVpRGlhbG9nLmNzcyhcInBvc2l0aW9uXCIpLG89XCJzdHJpbmdcIj09dHlwZW9mIG4/bjpcIm4sZSxzLHcsc2Usc3csbmUsbndcIjt0aGlzLnVpRGlhbG9nLnJlc2l6YWJsZSh7Y2FuY2VsOlwiLnVpLWRpYWxvZy1jb250ZW50XCIsY29udGFpbm1lbnQ6XCJkb2N1bWVudFwiLGFsc29SZXNpemU6dGhpcy5lbGVtZW50LG1heFdpZHRoOnMubWF4V2lkdGgsbWF4SGVpZ2h0OnMubWF4SGVpZ2h0LG1pbldpZHRoOnMubWluV2lkdGgsbWluSGVpZ2h0OnRoaXMuX21pbkhlaWdodCgpLGhhbmRsZXM6byxzdGFydDpmdW5jdGlvbihzLG4pe2UodGhpcykuYWRkQ2xhc3MoXCJ1aS1kaWFsb2ctcmVzaXppbmdcIiksaS5fYmxvY2tGcmFtZXMoKSxpLl90cmlnZ2VyKFwicmVzaXplU3RhcnRcIixzLHQobikpfSxyZXNpemU6ZnVuY3Rpb24oZSxzKXtpLl90cmlnZ2VyKFwicmVzaXplXCIsZSx0KHMpKX0sc3RvcDpmdW5jdGlvbihuLGEpe3ZhciBvPWkudWlEaWFsb2cub2Zmc2V0KCkscj1vLmxlZnQtaS5kb2N1bWVudC5zY3JvbGxMZWZ0KCksaD1vLnRvcC1pLmRvY3VtZW50LnNjcm9sbFRvcCgpO3MuaGVpZ2h0PWkudWlEaWFsb2cuaGVpZ2h0KCkscy53aWR0aD1pLnVpRGlhbG9nLndpZHRoKCkscy5wb3NpdGlvbj17bXk6XCJsZWZ0IHRvcFwiLGF0OlwibGVmdFwiKyhyPj0wP1wiK1wiOlwiXCIpK3IrXCIgXCIrXCJ0b3BcIisoaD49MD9cIitcIjpcIlwiKStoLG9mOmkud2luZG93fSxlKHRoaXMpLnJlbW92ZUNsYXNzKFwidWktZGlhbG9nLXJlc2l6aW5nXCIpLGkuX3VuYmxvY2tGcmFtZXMoKSxpLl90cmlnZ2VyKFwicmVzaXplU3RvcFwiLG4sdChhKSl9fSkuY3NzKFwicG9zaXRpb25cIixhKX0sX3RyYWNrRm9jdXM6ZnVuY3Rpb24oKXt0aGlzLl9vbih0aGlzLndpZGdldCgpLHtmb2N1c2luOmZ1bmN0aW9uKHQpe3RoaXMuX21ha2VGb2N1c1RhcmdldCgpLHRoaXMuX2ZvY3VzZWRFbGVtZW50PWUodC50YXJnZXQpfX0pfSxfbWFrZUZvY3VzVGFyZ2V0OmZ1bmN0aW9uKCl7dGhpcy5fdW50cmFja0luc3RhbmNlKCksdGhpcy5fdHJhY2tpbmdJbnN0YW5jZXMoKS51bnNoaWZ0KHRoaXMpfSxfdW50cmFja0luc3RhbmNlOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5fdHJhY2tpbmdJbnN0YW5jZXMoKSxpPWUuaW5BcnJheSh0aGlzLHQpOy0xIT09aSYmdC5zcGxpY2UoaSwxKX0sX3RyYWNraW5nSW5zdGFuY2VzOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLWluc3RhbmNlc1wiKTtyZXR1cm4gZXx8KGU9W10sdGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLWluc3RhbmNlc1wiLGUpKSxlfSxfbWluSGVpZ2h0OmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcHRpb25zO3JldHVyblwiYXV0b1wiPT09ZS5oZWlnaHQ/ZS5taW5IZWlnaHQ6TWF0aC5taW4oZS5taW5IZWlnaHQsZS5oZWlnaHQpfSxfcG9zaXRpb246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnVpRGlhbG9nLmlzKFwiOnZpc2libGVcIik7ZXx8dGhpcy51aURpYWxvZy5zaG93KCksdGhpcy51aURpYWxvZy5wb3NpdGlvbih0aGlzLm9wdGlvbnMucG9zaXRpb24pLGV8fHRoaXMudWlEaWFsb2cuaGlkZSgpfSxfc2V0T3B0aW9uczpmdW5jdGlvbih0KXt2YXIgaT10aGlzLHM9ITEsbj17fTtlLmVhY2godCxmdW5jdGlvbihlLHQpe2kuX3NldE9wdGlvbihlLHQpLGUgaW4gaS5zaXplUmVsYXRlZE9wdGlvbnMmJihzPSEwKSxlIGluIGkucmVzaXphYmxlUmVsYXRlZE9wdGlvbnMmJihuW2VdPXQpfSkscyYmKHRoaXMuX3NpemUoKSx0aGlzLl9wb3NpdGlvbigpKSx0aGlzLnVpRGlhbG9nLmlzKFwiOmRhdGEodWktcmVzaXphYmxlKVwiKSYmdGhpcy51aURpYWxvZy5yZXNpemFibGUoXCJvcHRpb25cIixuKX0sX3NldE9wdGlvbjpmdW5jdGlvbihlLHQpe3ZhciBpLHMsbj10aGlzLnVpRGlhbG9nO1wiZGlhbG9nQ2xhc3NcIj09PWUmJm4ucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmRpYWxvZ0NsYXNzKS5hZGRDbGFzcyh0KSxcImRpc2FibGVkXCIhPT1lJiYodGhpcy5fc3VwZXIoZSx0KSxcImFwcGVuZFRvXCI9PT1lJiZ0aGlzLnVpRGlhbG9nLmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLFwiYnV0dG9uc1wiPT09ZSYmdGhpcy5fY3JlYXRlQnV0dG9ucygpLFwiY2xvc2VUZXh0XCI9PT1lJiZ0aGlzLnVpRGlhbG9nVGl0bGViYXJDbG9zZS5idXR0b24oe2xhYmVsOlwiXCIrdH0pLFwiZHJhZ2dhYmxlXCI9PT1lJiYoaT1uLmlzKFwiOmRhdGEodWktZHJhZ2dhYmxlKVwiKSxpJiYhdCYmbi5kcmFnZ2FibGUoXCJkZXN0cm95XCIpLCFpJiZ0JiZ0aGlzLl9tYWtlRHJhZ2dhYmxlKCkpLFwicG9zaXRpb25cIj09PWUmJnRoaXMuX3Bvc2l0aW9uKCksXCJyZXNpemFibGVcIj09PWUmJihzPW4uaXMoXCI6ZGF0YSh1aS1yZXNpemFibGUpXCIpLHMmJiF0JiZuLnJlc2l6YWJsZShcImRlc3Ryb3lcIikscyYmXCJzdHJpbmdcIj09dHlwZW9mIHQmJm4ucmVzaXphYmxlKFwib3B0aW9uXCIsXCJoYW5kbGVzXCIsdCksc3x8dD09PSExfHx0aGlzLl9tYWtlUmVzaXphYmxlKCkpLFwidGl0bGVcIj09PWUmJnRoaXMuX3RpdGxlKHRoaXMudWlEaWFsb2dUaXRsZWJhci5maW5kKFwiLnVpLWRpYWxvZy10aXRsZVwiKSkpfSxfc2l6ZTpmdW5jdGlvbigpe3ZhciBlLHQsaSxzPXRoaXMub3B0aW9uczt0aGlzLmVsZW1lbnQuc2hvdygpLmNzcyh7d2lkdGg6XCJhdXRvXCIsbWluSGVpZ2h0OjAsbWF4SGVpZ2h0Olwibm9uZVwiLGhlaWdodDowfSkscy5taW5XaWR0aD5zLndpZHRoJiYocy53aWR0aD1zLm1pbldpZHRoKSxlPXRoaXMudWlEaWFsb2cuY3NzKHtoZWlnaHQ6XCJhdXRvXCIsd2lkdGg6cy53aWR0aH0pLm91dGVySGVpZ2h0KCksdD1NYXRoLm1heCgwLHMubWluSGVpZ2h0LWUpLGk9XCJudW1iZXJcIj09dHlwZW9mIHMubWF4SGVpZ2h0P01hdGgubWF4KDAscy5tYXhIZWlnaHQtZSk6XCJub25lXCIsXCJhdXRvXCI9PT1zLmhlaWdodD90aGlzLmVsZW1lbnQuY3NzKHttaW5IZWlnaHQ6dCxtYXhIZWlnaHQ6aSxoZWlnaHQ6XCJhdXRvXCJ9KTp0aGlzLmVsZW1lbnQuaGVpZ2h0KE1hdGgubWF4KDAscy5oZWlnaHQtZSkpLHRoaXMudWlEaWFsb2cuaXMoXCI6ZGF0YSh1aS1yZXNpemFibGUpXCIpJiZ0aGlzLnVpRGlhbG9nLnJlc2l6YWJsZShcIm9wdGlvblwiLFwibWluSGVpZ2h0XCIsdGhpcy5fbWluSGVpZ2h0KCkpfSxfYmxvY2tGcmFtZXM6ZnVuY3Rpb24oKXt0aGlzLmlmcmFtZUJsb2Nrcz10aGlzLmRvY3VtZW50LmZpbmQoXCJpZnJhbWVcIikubWFwKGZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKTtyZXR1cm4gZShcIjxkaXY+XCIpLmNzcyh7cG9zaXRpb246XCJhYnNvbHV0ZVwiLHdpZHRoOnQub3V0ZXJXaWR0aCgpLGhlaWdodDp0Lm91dGVySGVpZ2h0KCl9KS5hcHBlbmRUbyh0LnBhcmVudCgpKS5vZmZzZXQodC5vZmZzZXQoKSlbMF19KX0sX3VuYmxvY2tGcmFtZXM6ZnVuY3Rpb24oKXt0aGlzLmlmcmFtZUJsb2NrcyYmKHRoaXMuaWZyYW1lQmxvY2tzLnJlbW92ZSgpLGRlbGV0ZSB0aGlzLmlmcmFtZUJsb2Nrcyl9LF9hbGxvd0ludGVyYWN0aW9uOmZ1bmN0aW9uKHQpe3JldHVybiBlKHQudGFyZ2V0KS5jbG9zZXN0KFwiLnVpLWRpYWxvZ1wiKS5sZW5ndGg/ITA6ISFlKHQudGFyZ2V0KS5jbG9zZXN0KFwiLnVpLWRhdGVwaWNrZXJcIikubGVuZ3RofSxfY3JlYXRlT3ZlcmxheTpmdW5jdGlvbigpe2lmKHRoaXMub3B0aW9ucy5tb2RhbCl7dmFyIHQ9ITA7dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0PSExfSksdGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLW92ZXJsYXlzXCIpfHx0aGlzLl9vbih0aGlzLmRvY3VtZW50LHtmb2N1c2luOmZ1bmN0aW9uKGUpe3R8fHRoaXMuX2FsbG93SW50ZXJhY3Rpb24oZSl8fChlLnByZXZlbnREZWZhdWx0KCksdGhpcy5fdHJhY2tpbmdJbnN0YW5jZXMoKVswXS5fZm9jdXNUYWJiYWJsZSgpKX19KSx0aGlzLm92ZXJsYXk9ZShcIjxkaXY+XCIpLmFkZENsYXNzKFwidWktd2lkZ2V0LW92ZXJsYXkgdWktZnJvbnRcIikuYXBwZW5kVG8odGhpcy5fYXBwZW5kVG8oKSksdGhpcy5fb24odGhpcy5vdmVybGF5LHttb3VzZWRvd246XCJfa2VlcEZvY3VzXCJ9KSx0aGlzLmRvY3VtZW50LmRhdGEoXCJ1aS1kaWFsb2ctb3ZlcmxheXNcIiwodGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLW92ZXJsYXlzXCIpfHwwKSsxKX19LF9kZXN0cm95T3ZlcmxheTpmdW5jdGlvbigpe2lmKHRoaXMub3B0aW9ucy5tb2RhbCYmdGhpcy5vdmVybGF5KXt2YXIgZT10aGlzLmRvY3VtZW50LmRhdGEoXCJ1aS1kaWFsb2ctb3ZlcmxheXNcIiktMTtlP3RoaXMuZG9jdW1lbnQuZGF0YShcInVpLWRpYWxvZy1vdmVybGF5c1wiLGUpOnRoaXMuZG9jdW1lbnQudW5iaW5kKFwiZm9jdXNpblwiKS5yZW1vdmVEYXRhKFwidWktZGlhbG9nLW92ZXJsYXlzXCIpLHRoaXMub3ZlcmxheS5yZW1vdmUoKSx0aGlzLm92ZXJsYXk9bnVsbH19fSksZS53aWRnZXQoXCJ1aS5kcm9wcGFibGVcIix7dmVyc2lvbjpcIjEuMTEuNFwiLHdpZGdldEV2ZW50UHJlZml4OlwiZHJvcFwiLG9wdGlvbnM6e2FjY2VwdDpcIipcIixhY3RpdmVDbGFzczohMSxhZGRDbGFzc2VzOiEwLGdyZWVkeTohMSxob3ZlckNsYXNzOiExLHNjb3BlOlwiZGVmYXVsdFwiLHRvbGVyYW5jZTpcImludGVyc2VjdFwiLGFjdGl2YXRlOm51bGwsZGVhY3RpdmF0ZTpudWxsLGRyb3A6bnVsbCxvdXQ6bnVsbCxvdmVyOm51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgdCxpPXRoaXMub3B0aW9ucyxzPWkuYWNjZXB0O3RoaXMuaXNvdmVyPSExLHRoaXMuaXNvdXQ9ITAsdGhpcy5hY2NlcHQ9ZS5pc0Z1bmN0aW9uKHMpP3M6ZnVuY3Rpb24oZSl7cmV0dXJuIGUuaXMocyl9LHRoaXMucHJvcG9ydGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8odD1hcmd1bWVudHNbMF0sdm9pZCAwKTp0P3Q6dD17d2lkdGg6dGhpcy5lbGVtZW50WzBdLm9mZnNldFdpZHRoLGhlaWdodDp0aGlzLmVsZW1lbnRbMF0ub2Zmc2V0SGVpZ2h0fX0sdGhpcy5fYWRkVG9NYW5hZ2VyKGkuc2NvcGUpLGkuYWRkQ2xhc3NlcyYmdGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktZHJvcHBhYmxlXCIpfSxfYWRkVG9NYW5hZ2VyOmZ1bmN0aW9uKHQpe2UudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbdF09ZS51aS5kZG1hbmFnZXIuZHJvcHBhYmxlc1t0XXx8W10sZS51aS5kZG1hbmFnZXIuZHJvcHBhYmxlc1t0XS5wdXNoKHRoaXMpfSxfc3BsaWNlOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wO2UubGVuZ3RoPnQ7dCsrKWVbdF09PT10aGlzJiZlLnNwbGljZSh0LDEpfSxfZGVzdHJveTpmdW5jdGlvbigpe3ZhciB0PWUudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbdGhpcy5vcHRpb25zLnNjb3BlXTt0aGlzLl9zcGxpY2UodCksdGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktZHJvcHBhYmxlIHVpLWRyb3BwYWJsZS1kaXNhYmxlZFwiKX0sX3NldE9wdGlvbjpmdW5jdGlvbih0LGkpe2lmKFwiYWNjZXB0XCI9PT10KXRoaXMuYWNjZXB0PWUuaXNGdW5jdGlvbihpKT9pOmZ1bmN0aW9uKGUpe3JldHVybiBlLmlzKGkpfTtlbHNlIGlmKFwic2NvcGVcIj09PXQpe3ZhciBzPWUudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbdGhpcy5vcHRpb25zLnNjb3BlXTt0aGlzLl9zcGxpY2UocyksdGhpcy5fYWRkVG9NYW5hZ2VyKGkpfXRoaXMuX3N1cGVyKHQsaSl9LF9hY3RpdmF0ZTpmdW5jdGlvbih0KXt2YXIgaT1lLnVpLmRkbWFuYWdlci5jdXJyZW50O3RoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyYmdGhpcy5lbGVtZW50LmFkZENsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyksaSYmdGhpcy5fdHJpZ2dlcihcImFjdGl2YXRlXCIsdCx0aGlzLnVpKGkpKX0sX2RlYWN0aXZhdGU6ZnVuY3Rpb24odCl7dmFyIGk9ZS51aS5kZG1hbmFnZXIuY3VycmVudDt0aGlzLm9wdGlvbnMuYWN0aXZlQ2xhc3MmJnRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuYWN0aXZlQ2xhc3MpLGkmJnRoaXMuX3RyaWdnZXIoXCJkZWFjdGl2YXRlXCIsdCx0aGlzLnVpKGkpKX0sX292ZXI6ZnVuY3Rpb24odCl7dmFyIGk9ZS51aS5kZG1hbmFnZXIuY3VycmVudDtpJiYoaS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KVswXSE9PXRoaXMuZWxlbWVudFswXSYmdGhpcy5hY2NlcHQuY2FsbCh0aGlzLmVsZW1lbnRbMF0saS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KSYmKHRoaXMub3B0aW9ucy5ob3ZlckNsYXNzJiZ0aGlzLmVsZW1lbnQuYWRkQ2xhc3ModGhpcy5vcHRpb25zLmhvdmVyQ2xhc3MpLHRoaXMuX3RyaWdnZXIoXCJvdmVyXCIsdCx0aGlzLnVpKGkpKSl9LF9vdXQ6ZnVuY3Rpb24odCl7dmFyIGk9ZS51aS5kZG1hbmFnZXIuY3VycmVudDtpJiYoaS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KVswXSE9PXRoaXMuZWxlbWVudFswXSYmdGhpcy5hY2NlcHQuY2FsbCh0aGlzLmVsZW1lbnRbMF0saS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KSYmKHRoaXMub3B0aW9ucy5ob3ZlckNsYXNzJiZ0aGlzLmVsZW1lbnQucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmhvdmVyQ2xhc3MpLHRoaXMuX3RyaWdnZXIoXCJvdXRcIix0LHRoaXMudWkoaSkpKX0sX2Ryb3A6ZnVuY3Rpb24odCxpKXt2YXIgcz1pfHxlLnVpLmRkbWFuYWdlci5jdXJyZW50LG49ITE7cmV0dXJuIHMmJihzLmN1cnJlbnRJdGVtfHxzLmVsZW1lbnQpWzBdIT09dGhpcy5lbGVtZW50WzBdPyh0aGlzLmVsZW1lbnQuZmluZChcIjpkYXRhKHVpLWRyb3BwYWJsZSlcIikubm90KFwiLnVpLWRyYWdnYWJsZS1kcmFnZ2luZ1wiKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIGk9ZSh0aGlzKS5kcm9wcGFibGUoXCJpbnN0YW5jZVwiKTtyZXR1cm4gaS5vcHRpb25zLmdyZWVkeSYmIWkub3B0aW9ucy5kaXNhYmxlZCYmaS5vcHRpb25zLnNjb3BlPT09cy5vcHRpb25zLnNjb3BlJiZpLmFjY2VwdC5jYWxsKGkuZWxlbWVudFswXSxzLmN1cnJlbnRJdGVtfHxzLmVsZW1lbnQpJiZlLnVpLmludGVyc2VjdChzLGUuZXh0ZW5kKGkse29mZnNldDppLmVsZW1lbnQub2Zmc2V0KCl9KSxpLm9wdGlvbnMudG9sZXJhbmNlLHQpPyhuPSEwLCExKTp2b2lkIDB9KSxuPyExOnRoaXMuYWNjZXB0LmNhbGwodGhpcy5lbGVtZW50WzBdLHMuY3VycmVudEl0ZW18fHMuZWxlbWVudCk/KHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyYmdGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyksdGhpcy5vcHRpb25zLmhvdmVyQ2xhc3MmJnRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuaG92ZXJDbGFzcyksdGhpcy5fdHJpZ2dlcihcImRyb3BcIix0LHRoaXMudWkocykpLHRoaXMuZWxlbWVudCk6ITEpOiExfSx1aTpmdW5jdGlvbihlKXtyZXR1cm57ZHJhZ2dhYmxlOmUuY3VycmVudEl0ZW18fGUuZWxlbWVudCxoZWxwZXI6ZS5oZWxwZXIscG9zaXRpb246ZS5wb3NpdGlvbixvZmZzZXQ6ZS5wb3NpdGlvbkFic319fSksZS51aS5pbnRlcnNlY3Q9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUsdCxpKXtyZXR1cm4gZT49dCYmdCtpPmV9cmV0dXJuIGZ1bmN0aW9uKHQsaSxzLG4pe2lmKCFpLm9mZnNldClyZXR1cm4hMTt2YXIgYT0odC5wb3NpdGlvbkFic3x8dC5wb3NpdGlvbi5hYnNvbHV0ZSkubGVmdCt0Lm1hcmdpbnMubGVmdCxvPSh0LnBvc2l0aW9uQWJzfHx0LnBvc2l0aW9uLmFic29sdXRlKS50b3ArdC5tYXJnaW5zLnRvcCxyPWErdC5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aCxoPW8rdC5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQsbD1pLm9mZnNldC5sZWZ0LHU9aS5vZmZzZXQudG9wLGQ9bCtpLnByb3BvcnRpb25zKCkud2lkdGgsYz11K2kucHJvcG9ydGlvbnMoKS5oZWlnaHQ7c3dpdGNoKHMpe2Nhc2VcImZpdFwiOnJldHVybiBhPj1sJiZkPj1yJiZvPj11JiZjPj1oO2Nhc2VcImludGVyc2VjdFwiOnJldHVybiBhK3QuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgvMj5sJiZkPnItdC5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aC8yJiZvK3QuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LzI+dSYmYz5oLXQuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LzI7Y2FzZVwicG9pbnRlclwiOnJldHVybiBlKG4ucGFnZVksdSxpLnByb3BvcnRpb25zKCkuaGVpZ2h0KSYmZShuLnBhZ2VYLGwsaS5wcm9wb3J0aW9ucygpLndpZHRoKTtjYXNlXCJ0b3VjaFwiOnJldHVybihvPj11JiZjPj1vfHxoPj11JiZjPj1ofHx1Pm8mJmg+YykmJihhPj1sJiZkPj1hfHxyPj1sJiZkPj1yfHxsPmEmJnI+ZCk7ZGVmYXVsdDpyZXR1cm4hMX19fSgpLGUudWkuZGRtYW5hZ2VyPXtjdXJyZW50Om51bGwsZHJvcHBhYmxlczp7XCJkZWZhdWx0XCI6W119LHByZXBhcmVPZmZzZXRzOmZ1bmN0aW9uKHQsaSl7dmFyIHMsbixhPWUudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbdC5vcHRpb25zLnNjb3BlXXx8W10sbz1pP2kudHlwZTpudWxsLHI9KHQuY3VycmVudEl0ZW18fHQuZWxlbWVudCkuZmluZChcIjpkYXRhKHVpLWRyb3BwYWJsZSlcIikuYWRkQmFjaygpO2U6Zm9yKHM9MDthLmxlbmd0aD5zO3MrKylpZighKGFbc10ub3B0aW9ucy5kaXNhYmxlZHx8dCYmIWFbc10uYWNjZXB0LmNhbGwoYVtzXS5lbGVtZW50WzBdLHQuY3VycmVudEl0ZW18fHQuZWxlbWVudCkpKXtmb3Iobj0wO3IubGVuZ3RoPm47bisrKWlmKHJbbl09PT1hW3NdLmVsZW1lbnRbMF0pe2Fbc10ucHJvcG9ydGlvbnMoKS5oZWlnaHQ9MDtjb250aW51ZSBlfWFbc10udmlzaWJsZT1cIm5vbmVcIiE9PWFbc10uZWxlbWVudC5jc3MoXCJkaXNwbGF5XCIpLGFbc10udmlzaWJsZSYmKFwibW91c2Vkb3duXCI9PT1vJiZhW3NdLl9hY3RpdmF0ZS5jYWxsKGFbc10saSksYVtzXS5vZmZzZXQ9YVtzXS5lbGVtZW50Lm9mZnNldCgpLGFbc10ucHJvcG9ydGlvbnMoe3dpZHRoOmFbc10uZWxlbWVudFswXS5vZmZzZXRXaWR0aCxoZWlnaHQ6YVtzXS5lbGVtZW50WzBdLm9mZnNldEhlaWdodH0pKX19LGRyb3A6ZnVuY3Rpb24odCxpKXt2YXIgcz0hMTtyZXR1cm4gZS5lYWNoKChlLnVpLmRkbWFuYWdlci5kcm9wcGFibGVzW3Qub3B0aW9ucy5zY29wZV18fFtdKS5zbGljZSgpLGZ1bmN0aW9uKCl7dGhpcy5vcHRpb25zJiYoIXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmdGhpcy52aXNpYmxlJiZlLnVpLmludGVyc2VjdCh0LHRoaXMsdGhpcy5vcHRpb25zLnRvbGVyYW5jZSxpKSYmKHM9dGhpcy5fZHJvcC5jYWxsKHRoaXMsaSl8fHMpLCF0aGlzLm9wdGlvbnMuZGlzYWJsZWQmJnRoaXMudmlzaWJsZSYmdGhpcy5hY2NlcHQuY2FsbCh0aGlzLmVsZW1lbnRbMF0sdC5jdXJyZW50SXRlbXx8dC5lbGVtZW50KSYmKHRoaXMuaXNvdXQ9ITAsdGhpcy5pc292ZXI9ITEsdGhpcy5fZGVhY3RpdmF0ZS5jYWxsKHRoaXMsaSkpKX0pLHN9LGRyYWdTdGFydDpmdW5jdGlvbih0LGkpe3QuZWxlbWVudC5wYXJlbnRzVW50aWwoXCJib2R5XCIpLmJpbmQoXCJzY3JvbGwuZHJvcHBhYmxlXCIsZnVuY3Rpb24oKXt0Lm9wdGlvbnMucmVmcmVzaFBvc2l0aW9uc3x8ZS51aS5kZG1hbmFnZXIucHJlcGFyZU9mZnNldHModCxpKX0pfSxkcmFnOmZ1bmN0aW9uKHQsaSl7dC5vcHRpb25zLnJlZnJlc2hQb3NpdGlvbnMmJmUudWkuZGRtYW5hZ2VyLnByZXBhcmVPZmZzZXRzKHQsaSksZS5lYWNoKGUudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbdC5vcHRpb25zLnNjb3BlXXx8W10sZnVuY3Rpb24oKXtpZighdGhpcy5vcHRpb25zLmRpc2FibGVkJiYhdGhpcy5ncmVlZHlDaGlsZCYmdGhpcy52aXNpYmxlKXt2YXIgcyxuLGEsbz1lLnVpLmludGVyc2VjdCh0LHRoaXMsdGhpcy5vcHRpb25zLnRvbGVyYW5jZSxpKSxyPSFvJiZ0aGlzLmlzb3Zlcj9cImlzb3V0XCI6byYmIXRoaXMuaXNvdmVyP1wiaXNvdmVyXCI6bnVsbDtyJiYodGhpcy5vcHRpb25zLmdyZWVkeSYmKG49dGhpcy5vcHRpb25zLnNjb3BlLGE9dGhpcy5lbGVtZW50LnBhcmVudHMoXCI6ZGF0YSh1aS1kcm9wcGFibGUpXCIpLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiBlKHRoaXMpLmRyb3BwYWJsZShcImluc3RhbmNlXCIpLm9wdGlvbnMuc2NvcGU9PT1ufSksYS5sZW5ndGgmJihzPWUoYVswXSkuZHJvcHBhYmxlKFwiaW5zdGFuY2VcIikscy5ncmVlZHlDaGlsZD1cImlzb3ZlclwiPT09cikpLHMmJlwiaXNvdmVyXCI9PT1yJiYocy5pc292ZXI9ITEscy5pc291dD0hMCxzLl9vdXQuY2FsbChzLGkpKSx0aGlzW3JdPSEwLHRoaXNbXCJpc291dFwiPT09cj9cImlzb3ZlclwiOlwiaXNvdXRcIl09ITEsdGhpc1tcImlzb3ZlclwiPT09cj9cIl9vdmVyXCI6XCJfb3V0XCJdLmNhbGwodGhpcyxpKSxzJiZcImlzb3V0XCI9PT1yJiYocy5pc291dD0hMSxzLmlzb3Zlcj0hMCxzLl9vdmVyLmNhbGwocyxpKSkpfX0pfSxkcmFnU3RvcDpmdW5jdGlvbih0LGkpe3QuZWxlbWVudC5wYXJlbnRzVW50aWwoXCJib2R5XCIpLnVuYmluZChcInNjcm9sbC5kcm9wcGFibGVcIiksdC5vcHRpb25zLnJlZnJlc2hQb3NpdGlvbnN8fGUudWkuZGRtYW5hZ2VyLnByZXBhcmVPZmZzZXRzKHQsaSl9fSxlLnVpLmRyb3BwYWJsZTt2YXIgeT1cInVpLWVmZmVjdHMtXCIsYj1lO2UuZWZmZWN0cz17ZWZmZWN0Ont9fSxmdW5jdGlvbihlLHQpe2Z1bmN0aW9uIGkoZSx0LGkpe3ZhciBzPWRbdC50eXBlXXx8e307cmV0dXJuIG51bGw9PWU/aXx8IXQuZGVmP251bGw6dC5kZWY6KGU9cy5mbG9vcj9+fmU6cGFyc2VGbG9hdChlKSxpc05hTihlKT90LmRlZjpzLm1vZD8oZStzLm1vZCklcy5tb2Q6MD5lPzA6ZT5zLm1heD9zLm1heDplKX1mdW5jdGlvbiBzKGkpe3ZhciBzPWwoKSxuPXMuX3JnYmE9W107cmV0dXJuIGk9aS50b0xvd2VyQ2FzZSgpLGYoaCxmdW5jdGlvbihlLGEpe3ZhciBvLHI9YS5yZS5leGVjKGkpLGg9ciYmYS5wYXJzZShyKSxsPWEuc3BhY2V8fFwicmdiYVwiO3JldHVybiBoPyhvPXNbbF0oaCksc1t1W2xdLmNhY2hlXT1vW3VbbF0uY2FjaGVdLG49cy5fcmdiYT1vLl9yZ2JhLCExKTp0fSksbi5sZW5ndGg/KFwiMCwwLDAsMFwiPT09bi5qb2luKCkmJmUuZXh0ZW5kKG4sYS50cmFuc3BhcmVudCkscyk6YVtpXX1mdW5jdGlvbiBuKGUsdCxpKXtyZXR1cm4gaT0oaSsxKSUxLDE+NippP2UrNioodC1lKSppOjE+MippP3Q6Mj4zKmk/ZSs2Kih0LWUpKigyLzMtaSk6ZX12YXIgYSxvPVwiYmFja2dyb3VuZENvbG9yIGJvcmRlckJvdHRvbUNvbG9yIGJvcmRlckxlZnRDb2xvciBib3JkZXJSaWdodENvbG9yIGJvcmRlclRvcENvbG9yIGNvbG9yIGNvbHVtblJ1bGVDb2xvciBvdXRsaW5lQ29sb3IgdGV4dERlY29yYXRpb25Db2xvciB0ZXh0RW1waGFzaXNDb2xvclwiLHI9L14oW1xcLStdKT1cXHMqKFxcZCtcXC4/XFxkKikvLGg9W3tyZTovcmdiYT9cXChcXHMqKFxcZHsxLDN9KVxccyosXFxzKihcXGR7MSwzfSlcXHMqLFxccyooXFxkezEsM30pXFxzKig/OixcXHMqKFxcZD8oPzpcXC5cXGQrKT8pXFxzKik/XFwpLyxwYXJzZTpmdW5jdGlvbihlKXtyZXR1cm5bZVsxXSxlWzJdLGVbM10sZVs0XV19fSx7cmU6L3JnYmE/XFwoXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyosXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyosXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyooPzosXFxzKihcXGQ/KD86XFwuXFxkKyk/KVxccyopP1xcKS8scGFyc2U6ZnVuY3Rpb24oZSl7cmV0dXJuWzIuNTUqZVsxXSwyLjU1KmVbMl0sMi41NSplWzNdLGVbNF1dfX0se3JlOi8jKFthLWYwLTldezJ9KShbYS1mMC05XXsyfSkoW2EtZjAtOV17Mn0pLyxwYXJzZTpmdW5jdGlvbihlKXtyZXR1cm5bcGFyc2VJbnQoZVsxXSwxNikscGFyc2VJbnQoZVsyXSwxNikscGFyc2VJbnQoZVszXSwxNildfX0se3JlOi8jKFthLWYwLTldKShbYS1mMC05XSkoW2EtZjAtOV0pLyxwYXJzZTpmdW5jdGlvbihlKXtyZXR1cm5bcGFyc2VJbnQoZVsxXStlWzFdLDE2KSxwYXJzZUludChlWzJdK2VbMl0sMTYpLHBhcnNlSW50KGVbM10rZVszXSwxNildfX0se3JlOi9oc2xhP1xcKFxccyooXFxkKyg/OlxcLlxcZCspPylcXHMqLFxccyooXFxkKyg/OlxcLlxcZCspPylcXCVcXHMqLFxccyooXFxkKyg/OlxcLlxcZCspPylcXCVcXHMqKD86LFxccyooXFxkPyg/OlxcLlxcZCspPylcXHMqKT9cXCkvLHNwYWNlOlwiaHNsYVwiLHBhcnNlOmZ1bmN0aW9uKGUpe3JldHVybltlWzFdLGVbMl0vMTAwLGVbM10vMTAwLGVbNF1dfX1dLGw9ZS5Db2xvcj1mdW5jdGlvbih0LGkscyxuKXtyZXR1cm4gbmV3IGUuQ29sb3IuZm4ucGFyc2UodCxpLHMsbil9LHU9e3JnYmE6e3Byb3BzOntyZWQ6e2lkeDowLHR5cGU6XCJieXRlXCJ9LGdyZWVuOntpZHg6MSx0eXBlOlwiYnl0ZVwifSxibHVlOntpZHg6Mix0eXBlOlwiYnl0ZVwifX19LGhzbGE6e3Byb3BzOntodWU6e2lkeDowLHR5cGU6XCJkZWdyZWVzXCJ9LHNhdHVyYXRpb246e2lkeDoxLHR5cGU6XCJwZXJjZW50XCJ9LGxpZ2h0bmVzczp7aWR4OjIsdHlwZTpcInBlcmNlbnRcIn19fX0sZD17XCJieXRlXCI6e2Zsb29yOiEwLG1heDoyNTV9LHBlcmNlbnQ6e21heDoxfSxkZWdyZWVzOnttb2Q6MzYwLGZsb29yOiEwfX0sYz1sLnN1cHBvcnQ9e30scD1lKFwiPHA+XCIpWzBdLGY9ZS5lYWNoO3Auc3R5bGUuY3NzVGV4dD1cImJhY2tncm91bmQtY29sb3I6cmdiYSgxLDEsMSwuNSlcIixjLnJnYmE9cC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IuaW5kZXhPZihcInJnYmFcIik+LTEsZih1LGZ1bmN0aW9uKGUsdCl7dC5jYWNoZT1cIl9cIitlLHQucHJvcHMuYWxwaGE9e2lkeDozLHR5cGU6XCJwZXJjZW50XCIsZGVmOjF9fSksbC5mbj1lLmV4dGVuZChsLnByb3RvdHlwZSx7cGFyc2U6ZnVuY3Rpb24obixvLHIsaCl7aWYobj09PXQpcmV0dXJuIHRoaXMuX3JnYmE9W251bGwsbnVsbCxudWxsLG51bGxdLHRoaXM7KG4uanF1ZXJ5fHxuLm5vZGVUeXBlKSYmKG49ZShuKS5jc3Mobyksbz10KTt2YXIgZD10aGlzLGM9ZS50eXBlKG4pLHA9dGhpcy5fcmdiYT1bXTtyZXR1cm4gbyE9PXQmJihuPVtuLG8scixoXSxjPVwiYXJyYXlcIiksXCJzdHJpbmdcIj09PWM/dGhpcy5wYXJzZShzKG4pfHxhLl9kZWZhdWx0KTpcImFycmF5XCI9PT1jPyhmKHUucmdiYS5wcm9wcyxmdW5jdGlvbihlLHQpe3BbdC5pZHhdPWkoblt0LmlkeF0sdCl9KSx0aGlzKTpcIm9iamVjdFwiPT09Yz8obiBpbnN0YW5jZW9mIGw/Zih1LGZ1bmN0aW9uKGUsdCl7blt0LmNhY2hlXSYmKGRbdC5jYWNoZV09blt0LmNhY2hlXS5zbGljZSgpKX0pOmYodSxmdW5jdGlvbih0LHMpe3ZhciBhPXMuY2FjaGU7ZihzLnByb3BzLGZ1bmN0aW9uKGUsdCl7aWYoIWRbYV0mJnMudG8pe2lmKFwiYWxwaGFcIj09PWV8fG51bGw9PW5bZV0pcmV0dXJuO2RbYV09cy50byhkLl9yZ2JhKX1kW2FdW3QuaWR4XT1pKG5bZV0sdCwhMCl9KSxkW2FdJiYwPmUuaW5BcnJheShudWxsLGRbYV0uc2xpY2UoMCwzKSkmJihkW2FdWzNdPTEscy5mcm9tJiYoZC5fcmdiYT1zLmZyb20oZFthXSkpKX0pLHRoaXMpOnR9LGlzOmZ1bmN0aW9uKGUpe3ZhciBpPWwoZSkscz0hMCxuPXRoaXM7cmV0dXJuIGYodSxmdW5jdGlvbihlLGEpe3ZhciBvLHI9aVthLmNhY2hlXTtyZXR1cm4gciYmKG89blthLmNhY2hlXXx8YS50byYmYS50byhuLl9yZ2JhKXx8W10sZihhLnByb3BzLGZ1bmN0aW9uKGUsaSl7cmV0dXJuIG51bGwhPXJbaS5pZHhdP3M9cltpLmlkeF09PT1vW2kuaWR4XTp0fSkpLHN9KSxzfSxfc3BhY2U6ZnVuY3Rpb24oKXt2YXIgZT1bXSx0PXRoaXM7cmV0dXJuIGYodSxmdW5jdGlvbihpLHMpe3Rbcy5jYWNoZV0mJmUucHVzaChpKX0pLGUucG9wKCl9LHRyYW5zaXRpb246ZnVuY3Rpb24oZSx0KXt2YXIgcz1sKGUpLG49cy5fc3BhY2UoKSxhPXVbbl0sbz0wPT09dGhpcy5hbHBoYSgpP2woXCJ0cmFuc3BhcmVudFwiKTp0aGlzLHI9b1thLmNhY2hlXXx8YS50byhvLl9yZ2JhKSxoPXIuc2xpY2UoKTtyZXR1cm4gcz1zW2EuY2FjaGVdLGYoYS5wcm9wcyxmdW5jdGlvbihlLG4pe3ZhciBhPW4uaWR4LG89clthXSxsPXNbYV0sdT1kW24udHlwZV18fHt9O251bGwhPT1sJiYobnVsbD09PW8/aFthXT1sOih1Lm1vZCYmKGwtbz51Lm1vZC8yP28rPXUubW9kOm8tbD51Lm1vZC8yJiYoby09dS5tb2QpKSxoW2FdPWkoKGwtbykqdCtvLG4pKSl9KSx0aGlzW25dKGgpfSxibGVuZDpmdW5jdGlvbih0KXtpZigxPT09dGhpcy5fcmdiYVszXSlyZXR1cm4gdGhpczt2YXIgaT10aGlzLl9yZ2JhLnNsaWNlKCkscz1pLnBvcCgpLG49bCh0KS5fcmdiYTtyZXR1cm4gbChlLm1hcChpLGZ1bmN0aW9uKGUsdCl7cmV0dXJuKDEtcykqblt0XStzKmV9KSl9LHRvUmdiYVN0cmluZzpmdW5jdGlvbigpe3ZhciB0PVwicmdiYShcIixpPWUubWFwKHRoaXMuX3JnYmEsZnVuY3Rpb24oZSx0KXtyZXR1cm4gbnVsbD09ZT90PjI/MTowOmV9KTtyZXR1cm4gMT09PWlbM10mJihpLnBvcCgpLHQ9XCJyZ2IoXCIpLHQraS5qb2luKCkrXCIpXCJ9LHRvSHNsYVN0cmluZzpmdW5jdGlvbigpe3ZhciB0PVwiaHNsYShcIixpPWUubWFwKHRoaXMuaHNsYSgpLGZ1bmN0aW9uKGUsdCl7cmV0dXJuIG51bGw9PWUmJihlPXQ+Mj8xOjApLHQmJjM+dCYmKGU9TWF0aC5yb3VuZCgxMDAqZSkrXCIlXCIpLGV9KTtyZXR1cm4gMT09PWlbM10mJihpLnBvcCgpLHQ9XCJoc2woXCIpLHQraS5qb2luKCkrXCIpXCJ9LHRvSGV4U3RyaW5nOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMuX3JnYmEuc2xpY2UoKSxzPWkucG9wKCk7cmV0dXJuIHQmJmkucHVzaCh+figyNTUqcykpLFwiI1wiK2UubWFwKGksZnVuY3Rpb24oZSl7cmV0dXJuIGU9KGV8fDApLnRvU3RyaW5nKDE2KSwxPT09ZS5sZW5ndGg/XCIwXCIrZTplfSkuam9pbihcIlwiKX0sdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gMD09PXRoaXMuX3JnYmFbM10/XCJ0cmFuc3BhcmVudFwiOnRoaXMudG9SZ2JhU3RyaW5nKCl9fSksbC5mbi5wYXJzZS5wcm90b3R5cGU9bC5mbix1LmhzbGEudG89ZnVuY3Rpb24oZSl7aWYobnVsbD09ZVswXXx8bnVsbD09ZVsxXXx8bnVsbD09ZVsyXSlyZXR1cm5bbnVsbCxudWxsLG51bGwsZVszXV07dmFyIHQsaSxzPWVbMF0vMjU1LG49ZVsxXS8yNTUsYT1lWzJdLzI1NSxvPWVbM10scj1NYXRoLm1heChzLG4sYSksaD1NYXRoLm1pbihzLG4sYSksbD1yLWgsdT1yK2gsZD0uNSp1O3JldHVybiB0PWg9PT1yPzA6cz09PXI/NjAqKG4tYSkvbCszNjA6bj09PXI/NjAqKGEtcykvbCsxMjA6NjAqKHMtbikvbCsyNDAsaT0wPT09bD8wOi41Pj1kP2wvdTpsLygyLXUpLFtNYXRoLnJvdW5kKHQpJTM2MCxpLGQsbnVsbD09bz8xOm9dfSx1LmhzbGEuZnJvbT1mdW5jdGlvbihlKXtpZihudWxsPT1lWzBdfHxudWxsPT1lWzFdfHxudWxsPT1lWzJdKXJldHVybltudWxsLG51bGwsbnVsbCxlWzNdXTt2YXIgdD1lWzBdLzM2MCxpPWVbMV0scz1lWzJdLGE9ZVszXSxvPS41Pj1zP3MqKDEraSk6cytpLXMqaSxyPTIqcy1vO3JldHVybltNYXRoLnJvdW5kKDI1NSpuKHIsbyx0KzEvMykpLE1hdGgucm91bmQoMjU1Km4ocixvLHQpKSxNYXRoLnJvdW5kKDI1NSpuKHIsbyx0LTEvMykpLGFdfSxmKHUsZnVuY3Rpb24ocyxuKXt2YXIgYT1uLnByb3BzLG89bi5jYWNoZSxoPW4udG8sdT1uLmZyb207bC5mbltzXT1mdW5jdGlvbihzKXtpZihoJiYhdGhpc1tvXSYmKHRoaXNbb109aCh0aGlzLl9yZ2JhKSkscz09PXQpcmV0dXJuIHRoaXNbb10uc2xpY2UoKTt2YXIgbixyPWUudHlwZShzKSxkPVwiYXJyYXlcIj09PXJ8fFwib2JqZWN0XCI9PT1yP3M6YXJndW1lbnRzLGM9dGhpc1tvXS5zbGljZSgpO3JldHVybiBmKGEsZnVuY3Rpb24oZSx0KXt2YXIgcz1kW1wib2JqZWN0XCI9PT1yP2U6dC5pZHhdO251bGw9PXMmJihzPWNbdC5pZHhdKSxjW3QuaWR4XT1pKHMsdCl9KSx1PyhuPWwodShjKSksbltvXT1jLG4pOmwoYyl9LGYoYSxmdW5jdGlvbih0LGkpe2wuZm5bdF18fChsLmZuW3RdPWZ1bmN0aW9uKG4pe3ZhciBhLG89ZS50eXBlKG4pLGg9XCJhbHBoYVwiPT09dD90aGlzLl9oc2xhP1wiaHNsYVwiOlwicmdiYVwiOnMsbD10aGlzW2hdKCksdT1sW2kuaWR4XTtyZXR1cm5cInVuZGVmaW5lZFwiPT09bz91OihcImZ1bmN0aW9uXCI9PT1vJiYobj1uLmNhbGwodGhpcyx1KSxvPWUudHlwZShuKSksbnVsbD09biYmaS5lbXB0eT90aGlzOihcInN0cmluZ1wiPT09byYmKGE9ci5leGVjKG4pLGEmJihuPXUrcGFyc2VGbG9hdChhWzJdKSooXCIrXCI9PT1hWzFdPzE6LTEpKSksbFtpLmlkeF09bix0aGlzW2hdKGwpKSl9KX0pfSksbC5ob29rPWZ1bmN0aW9uKHQpe3ZhciBpPXQuc3BsaXQoXCIgXCIpO2YoaSxmdW5jdGlvbih0LGkpe2UuY3NzSG9va3NbaV09e3NldDpmdW5jdGlvbih0LG4pe3ZhciBhLG8scj1cIlwiO2lmKFwidHJhbnNwYXJlbnRcIiE9PW4mJihcInN0cmluZ1wiIT09ZS50eXBlKG4pfHwoYT1zKG4pKSkpe2lmKG49bChhfHxuKSwhYy5yZ2JhJiYxIT09bi5fcmdiYVszXSl7Zm9yKG89XCJiYWNrZ3JvdW5kQ29sb3JcIj09PWk/dC5wYXJlbnROb2RlOnQ7KFwiXCI9PT1yfHxcInRyYW5zcGFyZW50XCI9PT1yKSYmbyYmby5zdHlsZTspdHJ5e3I9ZS5jc3MobyxcImJhY2tncm91bmRDb2xvclwiKSxvPW8ucGFyZW50Tm9kZX1jYXRjaChoKXt9bj1uLmJsZW5kKHImJlwidHJhbnNwYXJlbnRcIiE9PXI/cjpcIl9kZWZhdWx0XCIpfW49bi50b1JnYmFTdHJpbmcoKX10cnl7dC5zdHlsZVtpXT1ufWNhdGNoKGgpe319fSxlLmZ4LnN0ZXBbaV09ZnVuY3Rpb24odCl7dC5jb2xvckluaXR8fCh0LnN0YXJ0PWwodC5lbGVtLGkpLHQuZW5kPWwodC5lbmQpLHQuY29sb3JJbml0PSEwKSxlLmNzc0hvb2tzW2ldLnNldCh0LmVsZW0sdC5zdGFydC50cmFuc2l0aW9uKHQuZW5kLHQucG9zKSl9fSl9LGwuaG9vayhvKSxlLmNzc0hvb2tzLmJvcmRlckNvbG9yPXtleHBhbmQ6ZnVuY3Rpb24oZSl7dmFyIHQ9e307cmV0dXJuIGYoW1wiVG9wXCIsXCJSaWdodFwiLFwiQm90dG9tXCIsXCJMZWZ0XCJdLGZ1bmN0aW9uKGkscyl7dFtcImJvcmRlclwiK3MrXCJDb2xvclwiXT1lfSksdH19LGE9ZS5Db2xvci5uYW1lcz17YXF1YTpcIiMwMGZmZmZcIixibGFjazpcIiMwMDAwMDBcIixibHVlOlwiIzAwMDBmZlwiLGZ1Y2hzaWE6XCIjZmYwMGZmXCIsZ3JheTpcIiM4MDgwODBcIixncmVlbjpcIiMwMDgwMDBcIixsaW1lOlwiIzAwZmYwMFwiLG1hcm9vbjpcIiM4MDAwMDBcIixuYXZ5OlwiIzAwMDA4MFwiLG9saXZlOlwiIzgwODAwMFwiLHB1cnBsZTpcIiM4MDAwODBcIixyZWQ6XCIjZmYwMDAwXCIsc2lsdmVyOlwiI2MwYzBjMFwiLHRlYWw6XCIjMDA4MDgwXCIsd2hpdGU6XCIjZmZmZmZmXCIseWVsbG93OlwiI2ZmZmYwMFwiLHRyYW5zcGFyZW50OltudWxsLG51bGwsbnVsbCwwXSxfZGVmYXVsdDpcIiNmZmZmZmZcIn19KGIpLGZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0KXt2YXIgaSxzLG49dC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3P3Qub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKHQsbnVsbCk6dC5jdXJyZW50U3R5bGUsYT17fTtpZihuJiZuLmxlbmd0aCYmblswXSYmbltuWzBdXSlmb3Iocz1uLmxlbmd0aDtzLS07KWk9bltzXSxcInN0cmluZ1wiPT10eXBlb2YgbltpXSYmKGFbZS5jYW1lbENhc2UoaSldPW5baV0pO2Vsc2UgZm9yKGkgaW4gbilcInN0cmluZ1wiPT10eXBlb2YgbltpXSYmKGFbaV09bltpXSk7cmV0dXJuIGF9ZnVuY3Rpb24gaSh0LGkpe3ZhciBzLGEsbz17fTtmb3IocyBpbiBpKWE9aVtzXSx0W3NdIT09YSYmKG5bc118fChlLmZ4LnN0ZXBbc118fCFpc05hTihwYXJzZUZsb2F0KGEpKSkmJihvW3NdPWEpKTtyZXR1cm4gb312YXIgcz1bXCJhZGRcIixcInJlbW92ZVwiLFwidG9nZ2xlXCJdLG49e2JvcmRlcjoxLGJvcmRlckJvdHRvbToxLGJvcmRlckNvbG9yOjEsYm9yZGVyTGVmdDoxLGJvcmRlclJpZ2h0OjEsYm9yZGVyVG9wOjEsYm9yZGVyV2lkdGg6MSxtYXJnaW46MSxwYWRkaW5nOjF9O2UuZWFjaChbXCJib3JkZXJMZWZ0U3R5bGVcIixcImJvcmRlclJpZ2h0U3R5bGVcIixcImJvcmRlckJvdHRvbVN0eWxlXCIsXCJib3JkZXJUb3BTdHlsZVwiXSxmdW5jdGlvbih0LGkpe2UuZnguc3RlcFtpXT1mdW5jdGlvbihlKXsoXCJub25lXCIhPT1lLmVuZCYmIWUuc2V0QXR0cnx8MT09PWUucG9zJiYhZS5zZXRBdHRyKSYmKGIuc3R5bGUoZS5lbGVtLGksZS5lbmQpLGUuc2V0QXR0cj0hMCl9fSksZS5mbi5hZGRCYWNrfHwoZS5mbi5hZGRCYWNrPWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmFkZChudWxsPT1lP3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKGUpKX0pLGUuZWZmZWN0cy5hbmltYXRlQ2xhc3M9ZnVuY3Rpb24obixhLG8scil7dmFyIGg9ZS5zcGVlZChhLG8scik7cmV0dXJuIHRoaXMucXVldWUoZnVuY3Rpb24oKXt2YXIgYSxvPWUodGhpcykscj1vLmF0dHIoXCJjbGFzc1wiKXx8XCJcIixsPWguY2hpbGRyZW4/by5maW5kKFwiKlwiKS5hZGRCYWNrKCk6bztsPWwubWFwKGZ1bmN0aW9uKCl7dmFyIGk9ZSh0aGlzKTtyZXR1cm57ZWw6aSxzdGFydDp0KHRoaXMpfX0pLGE9ZnVuY3Rpb24oKXtlLmVhY2gocyxmdW5jdGlvbihlLHQpe25bdF0mJm9bdCtcIkNsYXNzXCJdKG5bdF0pfSl9LGEoKSxsPWwubWFwKGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZW5kPXQodGhpcy5lbFswXSksdGhpcy5kaWZmPWkodGhpcy5zdGFydCx0aGlzLmVuZCksdGhpc30pLG8uYXR0cihcImNsYXNzXCIsciksbD1sLm1hcChmdW5jdGlvbigpe3ZhciB0PXRoaXMsaT1lLkRlZmVycmVkKCkscz1lLmV4dGVuZCh7fSxoLHtxdWV1ZTohMSxjb21wbGV0ZTpmdW5jdGlvbigpe2kucmVzb2x2ZSh0KX19KTtyZXR1cm4gdGhpcy5lbC5hbmltYXRlKHRoaXMuZGlmZixzKSxpLnByb21pc2UoKX0pLGUud2hlbi5hcHBseShlLGwuZ2V0KCkpLmRvbmUoZnVuY3Rpb24oKXthKCksZS5lYWNoKGFyZ3VtZW50cyxmdW5jdGlvbigpe3ZhciB0PXRoaXMuZWw7ZS5lYWNoKHRoaXMuZGlmZixmdW5jdGlvbihlKXt0LmNzcyhlLFwiXCIpfSl9KSxoLmNvbXBsZXRlLmNhbGwob1swXSl9KX0pfSxlLmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGkscyxuLGEpe3JldHVybiBzP2UuZWZmZWN0cy5hbmltYXRlQ2xhc3MuY2FsbCh0aGlzLHthZGQ6aX0scyxuLGEpOnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0oZS5mbi5hZGRDbGFzcykscmVtb3ZlQ2xhc3M6ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGkscyxuLGEpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPjE/ZS5lZmZlY3RzLmFuaW1hdGVDbGFzcy5jYWxsKHRoaXMse3JlbW92ZTppfSxzLG4sYSk6dC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fShlLmZuLnJlbW92ZUNsYXNzKSx0b2dnbGVDbGFzczpmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oaSxzLG4sYSxvKXtyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIHN8fHZvaWQgMD09PXM/bj9lLmVmZmVjdHMuYW5pbWF0ZUNsYXNzLmNhbGwodGhpcyxzP3thZGQ6aX06e3JlbW92ZTppfSxuLGEsbyk6dC5hcHBseSh0aGlzLGFyZ3VtZW50cyk6ZS5lZmZlY3RzLmFuaW1hdGVDbGFzcy5jYWxsKHRoaXMse3RvZ2dsZTppfSxzLG4sYSl9fShlLmZuLnRvZ2dsZUNsYXNzKSxzd2l0Y2hDbGFzczpmdW5jdGlvbih0LGkscyxuLGEpe3JldHVybiBlLmVmZmVjdHMuYW5pbWF0ZUNsYXNzLmNhbGwodGhpcyx7YWRkOmkscmVtb3ZlOnR9LHMsbixhKX19KX0oKSxmdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxpLHMsbil7cmV0dXJuIGUuaXNQbGFpbk9iamVjdCh0KSYmKGk9dCx0PXQuZWZmZWN0KSx0PXtlZmZlY3Q6dH0sbnVsbD09aSYmKGk9e30pLGUuaXNGdW5jdGlvbihpKSYmKG49aSxzPW51bGwsaT17fSksKFwibnVtYmVyXCI9PXR5cGVvZiBpfHxlLmZ4LnNwZWVkc1tpXSkmJihuPXMscz1pLGk9e30pLGUuaXNGdW5jdGlvbihzKSYmKG49cyxzPW51bGwpLGkmJmUuZXh0ZW5kKHQsaSkscz1zfHxpLmR1cmF0aW9uLHQuZHVyYXRpb249ZS5meC5vZmY/MDpcIm51bWJlclwiPT10eXBlb2Ygcz9zOnMgaW4gZS5meC5zcGVlZHM/ZS5meC5zcGVlZHNbc106ZS5meC5zcGVlZHMuX2RlZmF1bHQsdC5jb21wbGV0ZT1ufHxpLmNvbXBsZXRlLHR9ZnVuY3Rpb24gaSh0KXtyZXR1cm4hdHx8XCJudW1iZXJcIj09dHlwZW9mIHR8fGUuZnguc3BlZWRzW3RdPyEwOlwic3RyaW5nXCIhPXR5cGVvZiB0fHxlLmVmZmVjdHMuZWZmZWN0W3RdP2UuaXNGdW5jdGlvbih0KT8hMDpcIm9iamVjdFwiIT10eXBlb2YgdHx8dC5lZmZlY3Q/ITE6ITA6ITB9ZS5leHRlbmQoZS5lZmZlY3RzLHt2ZXJzaW9uOlwiMS4xMS40XCIsc2F2ZTpmdW5jdGlvbihlLHQpe2Zvcih2YXIgaT0wO3QubGVuZ3RoPmk7aSsrKW51bGwhPT10W2ldJiZlLmRhdGEoeSt0W2ldLGVbMF0uc3R5bGVbdFtpXV0pfSxyZXN0b3JlOmZ1bmN0aW9uKGUsdCl7dmFyIGkscztmb3Iocz0wO3QubGVuZ3RoPnM7cysrKW51bGwhPT10W3NdJiYoaT1lLmRhdGEoeSt0W3NdKSx2b2lkIDA9PT1pJiYoaT1cIlwiKSxlLmNzcyh0W3NdLGkpKX0sc2V0TW9kZTpmdW5jdGlvbihlLHQpe3JldHVyblwidG9nZ2xlXCI9PT10JiYodD1lLmlzKFwiOmhpZGRlblwiKT9cInNob3dcIjpcImhpZGVcIiksdH0sZ2V0QmFzZWxpbmU6ZnVuY3Rpb24oZSx0KXt2YXIgaSxzO3N3aXRjaChlWzBdKXtjYXNlXCJ0b3BcIjppPTA7YnJlYWs7Y2FzZVwibWlkZGxlXCI6aT0uNTticmVhaztjYXNlXCJib3R0b21cIjppPTE7YnJlYWs7ZGVmYXVsdDppPWVbMF0vdC5oZWlnaHR9c3dpdGNoKGVbMV0pe2Nhc2VcImxlZnRcIjpzPTA7YnJlYWs7Y2FzZVwiY2VudGVyXCI6cz0uNTticmVhaztjYXNlXCJyaWdodFwiOnM9MTticmVhaztkZWZhdWx0OnM9ZVsxXS90LndpZHRofXJldHVybnt4OnMseTppfX0sY3JlYXRlV3JhcHBlcjpmdW5jdGlvbih0KXtpZih0LnBhcmVudCgpLmlzKFwiLnVpLWVmZmVjdHMtd3JhcHBlclwiKSlyZXR1cm4gdC5wYXJlbnQoKTt2YXIgaT17d2lkdGg6dC5vdXRlcldpZHRoKCEwKSxoZWlnaHQ6dC5vdXRlckhlaWdodCghMCksXCJmbG9hdFwiOnQuY3NzKFwiZmxvYXRcIil9LHM9ZShcIjxkaXY+PC9kaXY+XCIpLmFkZENsYXNzKFwidWktZWZmZWN0cy13cmFwcGVyXCIpLmNzcyh7Zm9udFNpemU6XCIxMDAlXCIsYmFja2dyb3VuZDpcInRyYW5zcGFyZW50XCIsYm9yZGVyOlwibm9uZVwiLG1hcmdpbjowLHBhZGRpbmc6MH0pLG49e3dpZHRoOnQud2lkdGgoKSxoZWlnaHQ6dC5oZWlnaHQoKX0sYT1kb2N1bWVudC5hY3RpdmVFbGVtZW50O3RyeXthLmlkfWNhdGNoKG8pe2E9ZG9jdW1lbnQuYm9keX1yZXR1cm4gdC53cmFwKHMpLCh0WzBdPT09YXx8ZS5jb250YWlucyh0WzBdLGEpKSYmZShhKS5mb2N1cygpLHM9dC5wYXJlbnQoKSxcInN0YXRpY1wiPT09dC5jc3MoXCJwb3NpdGlvblwiKT8ocy5jc3Moe3Bvc2l0aW9uOlwicmVsYXRpdmVcIn0pLHQuY3NzKHtwb3NpdGlvbjpcInJlbGF0aXZlXCJ9KSk6KGUuZXh0ZW5kKGkse3Bvc2l0aW9uOnQuY3NzKFwicG9zaXRpb25cIiksekluZGV4OnQuY3NzKFwiei1pbmRleFwiKX0pLGUuZWFjaChbXCJ0b3BcIixcImxlZnRcIixcImJvdHRvbVwiLFwicmlnaHRcIl0sZnVuY3Rpb24oZSxzKXtpW3NdPXQuY3NzKHMpLGlzTmFOKHBhcnNlSW50KGlbc10sMTApKSYmKGlbc109XCJhdXRvXCIpfSksdC5jc3Moe3Bvc2l0aW9uOlwicmVsYXRpdmVcIix0b3A6MCxsZWZ0OjAscmlnaHQ6XCJhdXRvXCIsYm90dG9tOlwiYXV0b1wifSkpLHQuY3NzKG4pLHMuY3NzKGkpLnNob3coKX0scmVtb3ZlV3JhcHBlcjpmdW5jdGlvbih0KXt2YXIgaT1kb2N1bWVudC5hY3RpdmVFbGVtZW50O3JldHVybiB0LnBhcmVudCgpLmlzKFwiLnVpLWVmZmVjdHMtd3JhcHBlclwiKSYmKHQucGFyZW50KCkucmVwbGFjZVdpdGgodCksKHRbMF09PT1pfHxlLmNvbnRhaW5zKHRbMF0saSkpJiZlKGkpLmZvY3VzKCkpLHR9LHNldFRyYW5zaXRpb246ZnVuY3Rpb24odCxpLHMsbil7cmV0dXJuIG49bnx8e30sZS5lYWNoKGksZnVuY3Rpb24oZSxpKXt2YXIgYT10LmNzc1VuaXQoaSk7YVswXT4wJiYobltpXT1hWzBdKnMrYVsxXSl9KSxufX0pLGUuZm4uZXh0ZW5kKHtlZmZlY3Q6ZnVuY3Rpb24oKXtmdW5jdGlvbiBpKHQpe2Z1bmN0aW9uIGkoKXtlLmlzRnVuY3Rpb24oYSkmJmEuY2FsbChuWzBdKSxlLmlzRnVuY3Rpb24odCkmJnQoKX12YXIgbj1lKHRoaXMpLGE9cy5jb21wbGV0ZSxyPXMubW9kZTsobi5pcyhcIjpoaWRkZW5cIik/XCJoaWRlXCI9PT1yOlwic2hvd1wiPT09cik/KG5bcl0oKSxpKCkpOm8uY2FsbChuWzBdLHMsaSl9dmFyIHM9dC5hcHBseSh0aGlzLGFyZ3VtZW50cyksbj1zLm1vZGUsYT1zLnF1ZXVlLG89ZS5lZmZlY3RzLmVmZmVjdFtzLmVmZmVjdF07cmV0dXJuIGUuZngub2ZmfHwhbz9uP3RoaXNbbl0ocy5kdXJhdGlvbixzLmNvbXBsZXRlKTp0aGlzLmVhY2goZnVuY3Rpb24oKXtzLmNvbXBsZXRlJiZzLmNvbXBsZXRlLmNhbGwodGhpcyl9KTphPT09ITE/dGhpcy5lYWNoKGkpOnRoaXMucXVldWUoYXx8XCJmeFwiLGkpfSxzaG93OmZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbihzKXtpZihpKHMpKXJldHVybiBlLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt2YXIgbj10LmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gbi5tb2RlPVwic2hvd1wiLHRoaXMuZWZmZWN0LmNhbGwodGhpcyxuKX19KGUuZm4uc2hvdyksaGlkZTpmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24ocyl7aWYoaShzKSlyZXR1cm4gZS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7dmFyIG49dC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7cmV0dXJuIG4ubW9kZT1cImhpZGVcIix0aGlzLmVmZmVjdC5jYWxsKHRoaXMsbil9fShlLmZuLmhpZGUpLHRvZ2dsZTpmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24ocyl7aWYoaShzKXx8XCJib29sZWFuXCI9PXR5cGVvZiBzKXJldHVybiBlLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt2YXIgbj10LmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gbi5tb2RlPVwidG9nZ2xlXCIsdGhpcy5lZmZlY3QuY2FsbCh0aGlzLG4pfX0oZS5mbi50b2dnbGUpLGNzc1VuaXQ6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5jc3ModCkscz1bXTtyZXR1cm4gZS5lYWNoKFtcImVtXCIsXCJweFwiLFwiJVwiLFwicHRcIl0sZnVuY3Rpb24oZSx0KXtpLmluZGV4T2YodCk+MCYmKHM9W3BhcnNlRmxvYXQoaSksdF0pfSksc319KX0oKSxmdW5jdGlvbigpe3ZhciB0PXt9O2UuZWFjaChbXCJRdWFkXCIsXCJDdWJpY1wiLFwiUXVhcnRcIixcIlF1aW50XCIsXCJFeHBvXCJdLGZ1bmN0aW9uKGUsaSl7dFtpXT1mdW5jdGlvbih0KXtyZXR1cm4gTWF0aC5wb3codCxlKzIpfX0pLGUuZXh0ZW5kKHQse1NpbmU6ZnVuY3Rpb24oZSl7cmV0dXJuIDEtTWF0aC5jb3MoZSpNYXRoLlBJLzIpfSxDaXJjOmZ1bmN0aW9uKGUpe3JldHVybiAxLU1hdGguc3FydCgxLWUqZSl9LEVsYXN0aWM6ZnVuY3Rpb24oZSl7cmV0dXJuIDA9PT1lfHwxPT09ZT9lOi1NYXRoLnBvdygyLDgqKGUtMSkpKk1hdGguc2luKCg4MCooZS0xKS03LjUpKk1hdGguUEkvMTUpfSxCYWNrOmZ1bmN0aW9uKGUpe3JldHVybiBlKmUqKDMqZS0yKX0sQm91bmNlOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxpPTQ7KCh0PU1hdGgucG93KDIsLS1pKSktMSkvMTE+ZTspO3JldHVybiAxL01hdGgucG93KDQsMy1pKS03LjU2MjUqTWF0aC5wb3coKDMqdC0yKS8yMi1lLDIpfX0pLGUuZWFjaCh0LGZ1bmN0aW9uKHQsaSl7ZS5lYXNpbmdbXCJlYXNlSW5cIit0XT1pLGUuZWFzaW5nW1wiZWFzZU91dFwiK3RdPWZ1bmN0aW9uKGUpe3JldHVybiAxLWkoMS1lKX0sZS5lYXNpbmdbXCJlYXNlSW5PdXRcIit0XT1mdW5jdGlvbihlKXtyZXR1cm4uNT5lP2koMiplKS8yOjEtaSgtMiplKzIpLzJ9fSl9KCksZS5lZmZlY3RzLGUuZWZmZWN0cy5lZmZlY3QuYmxpbmQ9ZnVuY3Rpb24odCxpKXt2YXIgcyxuLGEsbz1lKHRoaXMpLHI9L3VwfGRvd258dmVydGljYWwvLGg9L3VwfGxlZnR8dmVydGljYWx8aG9yaXpvbnRhbC8sbD1bXCJwb3NpdGlvblwiLFwidG9wXCIsXCJib3R0b21cIixcImxlZnRcIixcInJpZ2h0XCIsXCJoZWlnaHRcIixcIndpZHRoXCJdLHU9ZS5lZmZlY3RzLnNldE1vZGUobyx0Lm1vZGV8fFwiaGlkZVwiKSxkPXQuZGlyZWN0aW9ufHxcInVwXCIsYz1yLnRlc3QoZCkscD1jP1wiaGVpZ2h0XCI6XCJ3aWR0aFwiLGY9Yz9cInRvcFwiOlwibGVmdFwiLG09aC50ZXN0KGQpLGc9e30sdj1cInNob3dcIj09PXU7by5wYXJlbnQoKS5pcyhcIi51aS1lZmZlY3RzLXdyYXBwZXJcIik/ZS5lZmZlY3RzLnNhdmUoby5wYXJlbnQoKSxsKTplLmVmZmVjdHMuc2F2ZShvLGwpLG8uc2hvdygpLHM9ZS5lZmZlY3RzLmNyZWF0ZVdyYXBwZXIobykuY3NzKHtvdmVyZmxvdzpcImhpZGRlblwifSksbj1zW3BdKCksYT1wYXJzZUZsb2F0KHMuY3NzKGYpKXx8MCxnW3BdPXY/bjowLG18fChvLmNzcyhjP1wiYm90dG9tXCI6XCJyaWdodFwiLDApLmNzcyhjP1widG9wXCI6XCJsZWZ0XCIsXCJhdXRvXCIpLmNzcyh7cG9zaXRpb246XCJhYnNvbHV0ZVwifSksZ1tmXT12P2E6bithKSx2JiYocy5jc3MocCwwKSxtfHxzLmNzcyhmLGErbikpLHMuYW5pbWF0ZShnLHtkdXJhdGlvbjp0LmR1cmF0aW9uLGVhc2luZzp0LmVhc2luZyxxdWV1ZTohMSxjb21wbGV0ZTpmdW5jdGlvbigpe1wiaGlkZVwiPT09dSYmby5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUobyxsKSxlLmVmZmVjdHMucmVtb3ZlV3JhcHBlcihvKSxpKCl9fSl9LGUuZWZmZWN0cy5lZmZlY3QuYm91bmNlPWZ1bmN0aW9uKHQsaSl7dmFyIHMsbixhLG89ZSh0aGlzKSxyPVtcInBvc2l0aW9uXCIsXCJ0b3BcIixcImJvdHRvbVwiLFwibGVmdFwiLFwicmlnaHRcIixcImhlaWdodFwiLFwid2lkdGhcIl0saD1lLmVmZmVjdHMuc2V0TW9kZShvLHQubW9kZXx8XCJlZmZlY3RcIiksbD1cImhpZGVcIj09PWgsdT1cInNob3dcIj09PWgsZD10LmRpcmVjdGlvbnx8XCJ1cFwiLGM9dC5kaXN0YW5jZSxwPXQudGltZXN8fDUsZj0yKnArKHV8fGw/MTowKSxtPXQuZHVyYXRpb24vZixnPXQuZWFzaW5nLHY9XCJ1cFwiPT09ZHx8XCJkb3duXCI9PT1kP1widG9wXCI6XCJsZWZ0XCIseT1cInVwXCI9PT1kfHxcImxlZnRcIj09PWQsYj1vLnF1ZXVlKCksXz1iLmxlbmd0aDtmb3IoKHV8fGwpJiZyLnB1c2goXCJvcGFjaXR5XCIpLGUuZWZmZWN0cy5zYXZlKG8sciksby5zaG93KCksZS5lZmZlY3RzLmNyZWF0ZVdyYXBwZXIobyksY3x8KGM9b1tcInRvcFwiPT09dj9cIm91dGVySGVpZ2h0XCI6XCJvdXRlcldpZHRoXCJdKCkvMyksdSYmKGE9e29wYWNpdHk6MX0sYVt2XT0wLG8uY3NzKFwib3BhY2l0eVwiLDApLmNzcyh2LHk/MiotYzoyKmMpLmFuaW1hdGUoYSxtLGcpKSxsJiYoYy89TWF0aC5wb3coMixwLTEpKSxhPXt9LGFbdl09MCxzPTA7cD5zO3MrKyluPXt9LG5bdl09KHk/XCItPVwiOlwiKz1cIikrYyxvLmFuaW1hdGUobixtLGcpLmFuaW1hdGUoYSxtLGcpLGM9bD8yKmM6Yy8yO2wmJihuPXtvcGFjaXR5OjB9LG5bdl09KHk/XCItPVwiOlwiKz1cIikrYyxvLmFuaW1hdGUobixtLGcpKSxvLnF1ZXVlKGZ1bmN0aW9uKCl7bCYmby5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUobyxyKSxlLmVmZmVjdHMucmVtb3ZlV3JhcHBlcihvKSxpKCl9KSxfPjEmJmIuc3BsaWNlLmFwcGx5KGIsWzEsMF0uY29uY2F0KGIuc3BsaWNlKF8sZisxKSkpLG8uZGVxdWV1ZSgpfSxlLmVmZmVjdHMuZWZmZWN0LmNsaXA9ZnVuY3Rpb24odCxpKXt2YXIgcyxuLGEsbz1lKHRoaXMpLHI9W1wicG9zaXRpb25cIixcInRvcFwiLFwiYm90dG9tXCIsXCJsZWZ0XCIsXCJyaWdodFwiLFwiaGVpZ2h0XCIsXCJ3aWR0aFwiXSxoPWUuZWZmZWN0cy5zZXRNb2RlKG8sdC5tb2RlfHxcImhpZGVcIiksbD1cInNob3dcIj09PWgsdT10LmRpcmVjdGlvbnx8XCJ2ZXJ0aWNhbFwiLGQ9XCJ2ZXJ0aWNhbFwiPT09dSxjPWQ/XCJoZWlnaHRcIjpcIndpZHRoXCIscD1kP1widG9wXCI6XCJsZWZ0XCIsZj17fTtlLmVmZmVjdHMuc2F2ZShvLHIpLG8uc2hvdygpLHM9ZS5lZmZlY3RzLmNyZWF0ZVdyYXBwZXIobykuY3NzKHtvdmVyZmxvdzpcImhpZGRlblwifSksbj1cIklNR1wiPT09b1swXS50YWdOYW1lP3M6byxhPW5bY10oKSxsJiYobi5jc3MoYywwKSxuLmNzcyhwLGEvMikpLGZbY109bD9hOjAsZltwXT1sPzA6YS8yLG4uYW5pbWF0ZShmLHtxdWV1ZTohMSxkdXJhdGlvbjp0LmR1cmF0aW9uLGVhc2luZzp0LmVhc2luZyxjb21wbGV0ZTpmdW5jdGlvbigpe2x8fG8uaGlkZSgpLGUuZWZmZWN0cy5yZXN0b3JlKG8sciksZS5lZmZlY3RzLnJlbW92ZVdyYXBwZXIobyksaSgpfX0pfSxlLmVmZmVjdHMuZWZmZWN0LmRyb3A9ZnVuY3Rpb24odCxpKXt2YXIgcyxuPWUodGhpcyksYT1bXCJwb3NpdGlvblwiLFwidG9wXCIsXCJib3R0b21cIixcImxlZnRcIixcInJpZ2h0XCIsXCJvcGFjaXR5XCIsXCJoZWlnaHRcIixcIndpZHRoXCJdLG89ZS5lZmZlY3RzLnNldE1vZGUobix0Lm1vZGV8fFwiaGlkZVwiKSxyPVwic2hvd1wiPT09byxoPXQuZGlyZWN0aW9ufHxcImxlZnRcIixsPVwidXBcIj09PWh8fFwiZG93blwiPT09aD9cInRvcFwiOlwibGVmdFwiLHU9XCJ1cFwiPT09aHx8XCJsZWZ0XCI9PT1oP1wicG9zXCI6XCJuZWdcIixkPXtvcGFjaXR5OnI/MTowfTtlLmVmZmVjdHMuc2F2ZShuLGEpLG4uc2hvdygpLGUuZWZmZWN0cy5jcmVhdGVXcmFwcGVyKG4pLHM9dC5kaXN0YW5jZXx8bltcInRvcFwiPT09bD9cIm91dGVySGVpZ2h0XCI6XCJvdXRlcldpZHRoXCJdKCEwKS8yLHImJm4uY3NzKFwib3BhY2l0eVwiLDApLmNzcyhsLFwicG9zXCI9PT11Py1zOnMpLGRbbF09KHI/XCJwb3NcIj09PXU/XCIrPVwiOlwiLT1cIjpcInBvc1wiPT09dT9cIi09XCI6XCIrPVwiKStzLG4uYW5pbWF0ZShkLHtxdWV1ZTohMSxkdXJhdGlvbjp0LmR1cmF0aW9uLGVhc2luZzp0LmVhc2luZyxjb21wbGV0ZTpmdW5jdGlvbigpe1wiaGlkZVwiPT09byYmbi5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUobixhKSxlLmVmZmVjdHMucmVtb3ZlV3JhcHBlcihuKSxpKCl9fSl9LGUuZWZmZWN0cy5lZmZlY3QuZXhwbG9kZT1mdW5jdGlvbih0LGkpe2Z1bmN0aW9uIHMoKXtiLnB1c2godGhpcyksYi5sZW5ndGg9PT1kKmMmJm4oKX1mdW5jdGlvbiBuKCl7cC5jc3Moe3Zpc2liaWxpdHk6XCJ2aXNpYmxlXCJ9KSxlKGIpLnJlbW92ZSgpLG18fHAuaGlkZSgpLGkoKX12YXIgYSxvLHIsaCxsLHUsZD10LnBpZWNlcz9NYXRoLnJvdW5kKE1hdGguc3FydCh0LnBpZWNlcykpOjMsYz1kLHA9ZSh0aGlzKSxmPWUuZWZmZWN0cy5zZXRNb2RlKHAsdC5tb2RlfHxcImhpZGVcIiksbT1cInNob3dcIj09PWYsZz1wLnNob3coKS5jc3MoXCJ2aXNpYmlsaXR5XCIsXCJoaWRkZW5cIikub2Zmc2V0KCksdj1NYXRoLmNlaWwocC5vdXRlcldpZHRoKCkvYykseT1NYXRoLmNlaWwocC5vdXRlckhlaWdodCgpL2QpLGI9W107Zm9yKGE9MDtkPmE7YSsrKWZvcihoPWcudG9wK2EqeSx1PWEtKGQtMSkvMixvPTA7Yz5vO28rKylyPWcubGVmdCtvKnYsbD1vLShjLTEpLzIscC5jbG9uZSgpLmFwcGVuZFRvKFwiYm9keVwiKS53cmFwKFwiPGRpdj48L2Rpdj5cIikuY3NzKHtwb3NpdGlvbjpcImFic29sdXRlXCIsdmlzaWJpbGl0eTpcInZpc2libGVcIixsZWZ0Oi1vKnYsdG9wOi1hKnl9KS5wYXJlbnQoKS5hZGRDbGFzcyhcInVpLWVmZmVjdHMtZXhwbG9kZVwiKS5jc3Moe3Bvc2l0aW9uOlwiYWJzb2x1dGVcIixvdmVyZmxvdzpcImhpZGRlblwiLHdpZHRoOnYsaGVpZ2h0OnksbGVmdDpyKyhtP2wqdjowKSx0b3A6aCsobT91Knk6MCksb3BhY2l0eTptPzA6MX0pLmFuaW1hdGUoe2xlZnQ6cisobT8wOmwqdiksdG9wOmgrKG0/MDp1KnkpLG9wYWNpdHk6bT8xOjB9LHQuZHVyYXRpb258fDUwMCx0LmVhc2luZyxzKX0sZS5lZmZlY3RzLmVmZmVjdC5mYWRlPWZ1bmN0aW9uKHQsaSl7dmFyIHM9ZSh0aGlzKSxuPWUuZWZmZWN0cy5zZXRNb2RlKHMsdC5tb2RlfHxcInRvZ2dsZVwiKTtzLmFuaW1hdGUoe29wYWNpdHk6bn0se3F1ZXVlOiExLGR1cmF0aW9uOnQuZHVyYXRpb24sZWFzaW5nOnQuZWFzaW5nLGNvbXBsZXRlOml9KX0sZS5lZmZlY3RzLmVmZmVjdC5mb2xkPWZ1bmN0aW9uKHQsaSl7dmFyIHMsbixhPWUodGhpcyksbz1bXCJwb3NpdGlvblwiLFwidG9wXCIsXCJib3R0b21cIixcImxlZnRcIixcInJpZ2h0XCIsXCJoZWlnaHRcIixcIndpZHRoXCJdLHI9ZS5lZmZlY3RzLnNldE1vZGUoYSx0Lm1vZGV8fFwiaGlkZVwiKSxoPVwic2hvd1wiPT09cixsPVwiaGlkZVwiPT09cix1PXQuc2l6ZXx8MTUsZD0vKFswLTldKyklLy5leGVjKHUpLGM9ISF0Lmhvcml6Rmlyc3QscD1oIT09YyxmPXA/W1wid2lkdGhcIixcImhlaWdodFwiXTpbXCJoZWlnaHRcIixcIndpZHRoXCJdLG09dC5kdXJhdGlvbi8yLGc9e30sdj17fTtlLmVmZmVjdHMuc2F2ZShhLG8pLGEuc2hvdygpLHM9ZS5lZmZlY3RzLmNyZWF0ZVdyYXBwZXIoYSkuY3NzKHtvdmVyZmxvdzpcImhpZGRlblwifSksbj1wP1tzLndpZHRoKCkscy5oZWlnaHQoKV06W3MuaGVpZ2h0KCkscy53aWR0aCgpXSxkJiYodT1wYXJzZUludChkWzFdLDEwKS8xMDAqbltsPzA6MV0pLGgmJnMuY3NzKGM/e2hlaWdodDowLHdpZHRoOnV9OntoZWlnaHQ6dSx3aWR0aDowfSksZ1tmWzBdXT1oP25bMF06dSx2W2ZbMV1dPWg/blsxXTowLHMuYW5pbWF0ZShnLG0sdC5lYXNpbmcpLmFuaW1hdGUodixtLHQuZWFzaW5nLGZ1bmN0aW9uKCl7bCYmYS5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUoYSxvKSxlLmVmZmVjdHMucmVtb3ZlV3JhcHBlcihhKSxpKCl9KX0sZS5lZmZlY3RzLmVmZmVjdC5oaWdobGlnaHQ9ZnVuY3Rpb24odCxpKXt2YXIgcz1lKHRoaXMpLG49W1wiYmFja2dyb3VuZEltYWdlXCIsXCJiYWNrZ3JvdW5kQ29sb3JcIixcIm9wYWNpdHlcIl0sYT1lLmVmZmVjdHMuc2V0TW9kZShzLHQubW9kZXx8XCJzaG93XCIpLG89e2JhY2tncm91bmRDb2xvcjpzLmNzcyhcImJhY2tncm91bmRDb2xvclwiKX07XCJoaWRlXCI9PT1hJiYoby5vcGFjaXR5PTApLGUuZWZmZWN0cy5zYXZlKHMsbikscy5zaG93KCkuY3NzKHtiYWNrZ3JvdW5kSW1hZ2U6XCJub25lXCIsYmFja2dyb3VuZENvbG9yOnQuY29sb3J8fFwiI2ZmZmY5OVwifSkuYW5pbWF0ZShvLHtxdWV1ZTohMSxkdXJhdGlvbjp0LmR1cmF0aW9uLGVhc2luZzp0LmVhc2luZyxjb21wbGV0ZTpmdW5jdGlvbigpe1wiaGlkZVwiPT09YSYmcy5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUocyxuKSxpKCl9fSl9LGUuZWZmZWN0cy5lZmZlY3Quc2l6ZT1mdW5jdGlvbih0LGkpe3ZhciBzLG4sYSxvPWUodGhpcykscj1bXCJwb3NpdGlvblwiLFwidG9wXCIsXCJib3R0b21cIixcImxlZnRcIixcInJpZ2h0XCIsXCJ3aWR0aFwiLFwiaGVpZ2h0XCIsXCJvdmVyZmxvd1wiLFwib3BhY2l0eVwiXSxoPVtcInBvc2l0aW9uXCIsXCJ0b3BcIixcImJvdHRvbVwiLFwibGVmdFwiLFwicmlnaHRcIixcIm92ZXJmbG93XCIsXCJvcGFjaXR5XCJdLGw9W1wid2lkdGhcIixcImhlaWdodFwiLFwib3ZlcmZsb3dcIl0sdT1bXCJmb250U2l6ZVwiXSxkPVtcImJvcmRlclRvcFdpZHRoXCIsXCJib3JkZXJCb3R0b21XaWR0aFwiLFwicGFkZGluZ1RvcFwiLFwicGFkZGluZ0JvdHRvbVwiXSxjPVtcImJvcmRlckxlZnRXaWR0aFwiLFwiYm9yZGVyUmlnaHRXaWR0aFwiLFwicGFkZGluZ0xlZnRcIixcInBhZGRpbmdSaWdodFwiXSxwPWUuZWZmZWN0cy5zZXRNb2RlKG8sdC5tb2RlfHxcImVmZmVjdFwiKSxmPXQucmVzdG9yZXx8XCJlZmZlY3RcIiE9PXAsbT10LnNjYWxlfHxcImJvdGhcIixnPXQub3JpZ2lufHxbXCJtaWRkbGVcIixcImNlbnRlclwiXSx2PW8uY3NzKFwicG9zaXRpb25cIikseT1mP3I6aCxiPXtoZWlnaHQ6MCx3aWR0aDowLG91dGVySGVpZ2h0OjAsb3V0ZXJXaWR0aDowfTtcInNob3dcIj09PXAmJm8uc2hvdygpLHM9e2hlaWdodDpvLmhlaWdodCgpLHdpZHRoOm8ud2lkdGgoKSxvdXRlckhlaWdodDpvLm91dGVySGVpZ2h0KCksb3V0ZXJXaWR0aDpvLm91dGVyV2lkdGgoKX0sXCJ0b2dnbGVcIj09PXQubW9kZSYmXCJzaG93XCI9PT1wPyhvLmZyb209dC50b3x8YixvLnRvPXQuZnJvbXx8cyk6KG8uZnJvbT10LmZyb218fChcInNob3dcIj09PXA/YjpzKSxvLnRvPXQudG98fChcImhpZGVcIj09PXA/YjpzKSksYT17ZnJvbTp7eTpvLmZyb20uaGVpZ2h0L3MuaGVpZ2h0LHg6by5mcm9tLndpZHRoL3Mud2lkdGh9LHRvOnt5Om8udG8uaGVpZ2h0L3MuaGVpZ2h0LHg6by50by53aWR0aC9zLndpZHRofX0sKFwiYm94XCI9PT1tfHxcImJvdGhcIj09PW0pJiYoYS5mcm9tLnkhPT1hLnRvLnkmJih5PXkuY29uY2F0KGQpLG8uZnJvbT1lLmVmZmVjdHMuc2V0VHJhbnNpdGlvbihvLGQsYS5mcm9tLnksby5mcm9tKSxvLnRvPWUuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKG8sZCxhLnRvLnksby50bykpLGEuZnJvbS54IT09YS50by54JiYoeT15LmNvbmNhdChjKSxvLmZyb209ZS5lZmZlY3RzLnNldFRyYW5zaXRpb24obyxjLGEuZnJvbS54LG8uZnJvbSksby50bz1lLmVmZmVjdHMuc2V0VHJhbnNpdGlvbihvLGMsYS50by54LG8udG8pKSksKFwiY29udGVudFwiPT09bXx8XCJib3RoXCI9PT1tKSYmYS5mcm9tLnkhPT1hLnRvLnkmJih5PXkuY29uY2F0KHUpLmNvbmNhdChsKSxvLmZyb209ZS5lZmZlY3RzLnNldFRyYW5zaXRpb24obyx1LGEuZnJvbS55LG8uZnJvbSksby50bz1lLmVmZmVjdHMuc2V0VHJhbnNpdGlvbihvLHUsYS50by55LG8udG8pKSxlLmVmZmVjdHMuc2F2ZShvLHkpLG8uc2hvdygpLGUuZWZmZWN0cy5jcmVhdGVXcmFwcGVyKG8pLG8uY3NzKFwib3ZlcmZsb3dcIixcImhpZGRlblwiKS5jc3Moby5mcm9tKSxnJiYobj1lLmVmZmVjdHMuZ2V0QmFzZWxpbmUoZyxzKSxvLmZyb20udG9wPShzLm91dGVySGVpZ2h0LW8ub3V0ZXJIZWlnaHQoKSkqbi55LG8uZnJvbS5sZWZ0PShzLm91dGVyV2lkdGgtby5vdXRlcldpZHRoKCkpKm4ueCxvLnRvLnRvcD0ocy5vdXRlckhlaWdodC1vLnRvLm91dGVySGVpZ2h0KSpuLnksby50by5sZWZ0PShzLm91dGVyV2lkdGgtby50by5vdXRlcldpZHRoKSpuLngpLG8uY3NzKG8uZnJvbSksKFwiY29udGVudFwiPT09bXx8XCJib3RoXCI9PT1tKSYmKGQ9ZC5jb25jYXQoW1wibWFyZ2luVG9wXCIsXCJtYXJnaW5Cb3R0b21cIl0pLmNvbmNhdCh1KSxjPWMuY29uY2F0KFtcIm1hcmdpbkxlZnRcIixcIm1hcmdpblJpZ2h0XCJdKSxsPXIuY29uY2F0KGQpLmNvbmNhdChjKSxvLmZpbmQoXCIqW3dpZHRoXVwiKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIGk9ZSh0aGlzKSxzPXtoZWlnaHQ6aS5oZWlnaHQoKSx3aWR0aDppLndpZHRoKCksb3V0ZXJIZWlnaHQ6aS5vdXRlckhlaWdodCgpLG91dGVyV2lkdGg6aS5vdXRlcldpZHRoKCl9O1xyXG5mJiZlLmVmZmVjdHMuc2F2ZShpLGwpLGkuZnJvbT17aGVpZ2h0OnMuaGVpZ2h0KmEuZnJvbS55LHdpZHRoOnMud2lkdGgqYS5mcm9tLngsb3V0ZXJIZWlnaHQ6cy5vdXRlckhlaWdodCphLmZyb20ueSxvdXRlcldpZHRoOnMub3V0ZXJXaWR0aCphLmZyb20ueH0saS50bz17aGVpZ2h0OnMuaGVpZ2h0KmEudG8ueSx3aWR0aDpzLndpZHRoKmEudG8ueCxvdXRlckhlaWdodDpzLmhlaWdodCphLnRvLnksb3V0ZXJXaWR0aDpzLndpZHRoKmEudG8ueH0sYS5mcm9tLnkhPT1hLnRvLnkmJihpLmZyb209ZS5lZmZlY3RzLnNldFRyYW5zaXRpb24oaSxkLGEuZnJvbS55LGkuZnJvbSksaS50bz1lLmVmZmVjdHMuc2V0VHJhbnNpdGlvbihpLGQsYS50by55LGkudG8pKSxhLmZyb20ueCE9PWEudG8ueCYmKGkuZnJvbT1lLmVmZmVjdHMuc2V0VHJhbnNpdGlvbihpLGMsYS5mcm9tLngsaS5mcm9tKSxpLnRvPWUuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKGksYyxhLnRvLngsaS50bykpLGkuY3NzKGkuZnJvbSksaS5hbmltYXRlKGkudG8sdC5kdXJhdGlvbix0LmVhc2luZyxmdW5jdGlvbigpe2YmJmUuZWZmZWN0cy5yZXN0b3JlKGksbCl9KX0pKSxvLmFuaW1hdGUoby50byx7cXVldWU6ITEsZHVyYXRpb246dC5kdXJhdGlvbixlYXNpbmc6dC5lYXNpbmcsY29tcGxldGU6ZnVuY3Rpb24oKXswPT09by50by5vcGFjaXR5JiZvLmNzcyhcIm9wYWNpdHlcIixvLmZyb20ub3BhY2l0eSksXCJoaWRlXCI9PT1wJiZvLmhpZGUoKSxlLmVmZmVjdHMucmVzdG9yZShvLHkpLGZ8fChcInN0YXRpY1wiPT09dj9vLmNzcyh7cG9zaXRpb246XCJyZWxhdGl2ZVwiLHRvcDpvLnRvLnRvcCxsZWZ0Om8udG8ubGVmdH0pOmUuZWFjaChbXCJ0b3BcIixcImxlZnRcIl0sZnVuY3Rpb24oZSx0KXtvLmNzcyh0LGZ1bmN0aW9uKHQsaSl7dmFyIHM9cGFyc2VJbnQoaSwxMCksbj1lP28udG8ubGVmdDpvLnRvLnRvcDtyZXR1cm5cImF1dG9cIj09PWk/bitcInB4XCI6cytuK1wicHhcIn0pfSkpLGUuZWZmZWN0cy5yZW1vdmVXcmFwcGVyKG8pLGkoKX19KX0sZS5lZmZlY3RzLmVmZmVjdC5zY2FsZT1mdW5jdGlvbih0LGkpe3ZhciBzPWUodGhpcyksbj1lLmV4dGVuZCghMCx7fSx0KSxhPWUuZWZmZWN0cy5zZXRNb2RlKHMsdC5tb2RlfHxcImVmZmVjdFwiKSxvPXBhcnNlSW50KHQucGVyY2VudCwxMCl8fCgwPT09cGFyc2VJbnQodC5wZXJjZW50LDEwKT8wOlwiaGlkZVwiPT09YT8wOjEwMCkscj10LmRpcmVjdGlvbnx8XCJib3RoXCIsaD10Lm9yaWdpbixsPXtoZWlnaHQ6cy5oZWlnaHQoKSx3aWR0aDpzLndpZHRoKCksb3V0ZXJIZWlnaHQ6cy5vdXRlckhlaWdodCgpLG91dGVyV2lkdGg6cy5vdXRlcldpZHRoKCl9LHU9e3k6XCJob3Jpem9udGFsXCIhPT1yP28vMTAwOjEseDpcInZlcnRpY2FsXCIhPT1yP28vMTAwOjF9O24uZWZmZWN0PVwic2l6ZVwiLG4ucXVldWU9ITEsbi5jb21wbGV0ZT1pLFwiZWZmZWN0XCIhPT1hJiYobi5vcmlnaW49aHx8W1wibWlkZGxlXCIsXCJjZW50ZXJcIl0sbi5yZXN0b3JlPSEwKSxuLmZyb209dC5mcm9tfHwoXCJzaG93XCI9PT1hP3toZWlnaHQ6MCx3aWR0aDowLG91dGVySGVpZ2h0OjAsb3V0ZXJXaWR0aDowfTpsKSxuLnRvPXtoZWlnaHQ6bC5oZWlnaHQqdS55LHdpZHRoOmwud2lkdGgqdS54LG91dGVySGVpZ2h0Omwub3V0ZXJIZWlnaHQqdS55LG91dGVyV2lkdGg6bC5vdXRlcldpZHRoKnUueH0sbi5mYWRlJiYoXCJzaG93XCI9PT1hJiYobi5mcm9tLm9wYWNpdHk9MCxuLnRvLm9wYWNpdHk9MSksXCJoaWRlXCI9PT1hJiYobi5mcm9tLm9wYWNpdHk9MSxuLnRvLm9wYWNpdHk9MCkpLHMuZWZmZWN0KG4pfSxlLmVmZmVjdHMuZWZmZWN0LnB1ZmY9ZnVuY3Rpb24odCxpKXt2YXIgcz1lKHRoaXMpLG49ZS5lZmZlY3RzLnNldE1vZGUocyx0Lm1vZGV8fFwiaGlkZVwiKSxhPVwiaGlkZVwiPT09bixvPXBhcnNlSW50KHQucGVyY2VudCwxMCl8fDE1MCxyPW8vMTAwLGg9e2hlaWdodDpzLmhlaWdodCgpLHdpZHRoOnMud2lkdGgoKSxvdXRlckhlaWdodDpzLm91dGVySGVpZ2h0KCksb3V0ZXJXaWR0aDpzLm91dGVyV2lkdGgoKX07ZS5leHRlbmQodCx7ZWZmZWN0Olwic2NhbGVcIixxdWV1ZTohMSxmYWRlOiEwLG1vZGU6bixjb21wbGV0ZTppLHBlcmNlbnQ6YT9vOjEwMCxmcm9tOmE/aDp7aGVpZ2h0OmguaGVpZ2h0KnIsd2lkdGg6aC53aWR0aCpyLG91dGVySGVpZ2h0Omgub3V0ZXJIZWlnaHQqcixvdXRlcldpZHRoOmgub3V0ZXJXaWR0aCpyfX0pLHMuZWZmZWN0KHQpfSxlLmVmZmVjdHMuZWZmZWN0LnB1bHNhdGU9ZnVuY3Rpb24odCxpKXt2YXIgcyxuPWUodGhpcyksYT1lLmVmZmVjdHMuc2V0TW9kZShuLHQubW9kZXx8XCJzaG93XCIpLG89XCJzaG93XCI9PT1hLHI9XCJoaWRlXCI9PT1hLGg9b3x8XCJoaWRlXCI9PT1hLGw9MioodC50aW1lc3x8NSkrKGg/MTowKSx1PXQuZHVyYXRpb24vbCxkPTAsYz1uLnF1ZXVlKCkscD1jLmxlbmd0aDtmb3IoKG98fCFuLmlzKFwiOnZpc2libGVcIikpJiYobi5jc3MoXCJvcGFjaXR5XCIsMCkuc2hvdygpLGQ9MSkscz0xO2w+cztzKyspbi5hbmltYXRlKHtvcGFjaXR5OmR9LHUsdC5lYXNpbmcpLGQ9MS1kO24uYW5pbWF0ZSh7b3BhY2l0eTpkfSx1LHQuZWFzaW5nKSxuLnF1ZXVlKGZ1bmN0aW9uKCl7ciYmbi5oaWRlKCksaSgpfSkscD4xJiZjLnNwbGljZS5hcHBseShjLFsxLDBdLmNvbmNhdChjLnNwbGljZShwLGwrMSkpKSxuLmRlcXVldWUoKX0sZS5lZmZlY3RzLmVmZmVjdC5zaGFrZT1mdW5jdGlvbih0LGkpe3ZhciBzLG49ZSh0aGlzKSxhPVtcInBvc2l0aW9uXCIsXCJ0b3BcIixcImJvdHRvbVwiLFwibGVmdFwiLFwicmlnaHRcIixcImhlaWdodFwiLFwid2lkdGhcIl0sbz1lLmVmZmVjdHMuc2V0TW9kZShuLHQubW9kZXx8XCJlZmZlY3RcIikscj10LmRpcmVjdGlvbnx8XCJsZWZ0XCIsaD10LmRpc3RhbmNlfHwyMCxsPXQudGltZXN8fDMsdT0yKmwrMSxkPU1hdGgucm91bmQodC5kdXJhdGlvbi91KSxjPVwidXBcIj09PXJ8fFwiZG93blwiPT09cj9cInRvcFwiOlwibGVmdFwiLHA9XCJ1cFwiPT09cnx8XCJsZWZ0XCI9PT1yLGY9e30sbT17fSxnPXt9LHY9bi5xdWV1ZSgpLHk9di5sZW5ndGg7Zm9yKGUuZWZmZWN0cy5zYXZlKG4sYSksbi5zaG93KCksZS5lZmZlY3RzLmNyZWF0ZVdyYXBwZXIobiksZltjXT0ocD9cIi09XCI6XCIrPVwiKStoLG1bY109KHA/XCIrPVwiOlwiLT1cIikrMipoLGdbY109KHA/XCItPVwiOlwiKz1cIikrMipoLG4uYW5pbWF0ZShmLGQsdC5lYXNpbmcpLHM9MTtsPnM7cysrKW4uYW5pbWF0ZShtLGQsdC5lYXNpbmcpLmFuaW1hdGUoZyxkLHQuZWFzaW5nKTtuLmFuaW1hdGUobSxkLHQuZWFzaW5nKS5hbmltYXRlKGYsZC8yLHQuZWFzaW5nKS5xdWV1ZShmdW5jdGlvbigpe1wiaGlkZVwiPT09byYmbi5oaWRlKCksZS5lZmZlY3RzLnJlc3RvcmUobixhKSxlLmVmZmVjdHMucmVtb3ZlV3JhcHBlcihuKSxpKCl9KSx5PjEmJnYuc3BsaWNlLmFwcGx5KHYsWzEsMF0uY29uY2F0KHYuc3BsaWNlKHksdSsxKSkpLG4uZGVxdWV1ZSgpfSxlLmVmZmVjdHMuZWZmZWN0LnNsaWRlPWZ1bmN0aW9uKHQsaSl7dmFyIHMsbj1lKHRoaXMpLGE9W1wicG9zaXRpb25cIixcInRvcFwiLFwiYm90dG9tXCIsXCJsZWZ0XCIsXCJyaWdodFwiLFwid2lkdGhcIixcImhlaWdodFwiXSxvPWUuZWZmZWN0cy5zZXRNb2RlKG4sdC5tb2RlfHxcInNob3dcIikscj1cInNob3dcIj09PW8saD10LmRpcmVjdGlvbnx8XCJsZWZ0XCIsbD1cInVwXCI9PT1ofHxcImRvd25cIj09PWg/XCJ0b3BcIjpcImxlZnRcIix1PVwidXBcIj09PWh8fFwibGVmdFwiPT09aCxkPXt9O2UuZWZmZWN0cy5zYXZlKG4sYSksbi5zaG93KCkscz10LmRpc3RhbmNlfHxuW1widG9wXCI9PT1sP1wib3V0ZXJIZWlnaHRcIjpcIm91dGVyV2lkdGhcIl0oITApLGUuZWZmZWN0cy5jcmVhdGVXcmFwcGVyKG4pLmNzcyh7b3ZlcmZsb3c6XCJoaWRkZW5cIn0pLHImJm4uY3NzKGwsdT9pc05hTihzKT9cIi1cIitzOi1zOnMpLGRbbF09KHI/dT9cIis9XCI6XCItPVwiOnU/XCItPVwiOlwiKz1cIikrcyxuLmFuaW1hdGUoZCx7cXVldWU6ITEsZHVyYXRpb246dC5kdXJhdGlvbixlYXNpbmc6dC5lYXNpbmcsY29tcGxldGU6ZnVuY3Rpb24oKXtcImhpZGVcIj09PW8mJm4uaGlkZSgpLGUuZWZmZWN0cy5yZXN0b3JlKG4sYSksZS5lZmZlY3RzLnJlbW92ZVdyYXBwZXIobiksaSgpfX0pfSxlLmVmZmVjdHMuZWZmZWN0LnRyYW5zZmVyPWZ1bmN0aW9uKHQsaSl7dmFyIHM9ZSh0aGlzKSxuPWUodC50byksYT1cImZpeGVkXCI9PT1uLmNzcyhcInBvc2l0aW9uXCIpLG89ZShcImJvZHlcIikscj1hP28uc2Nyb2xsVG9wKCk6MCxoPWE/by5zY3JvbGxMZWZ0KCk6MCxsPW4ub2Zmc2V0KCksdT17dG9wOmwudG9wLXIsbGVmdDpsLmxlZnQtaCxoZWlnaHQ6bi5pbm5lckhlaWdodCgpLHdpZHRoOm4uaW5uZXJXaWR0aCgpfSxkPXMub2Zmc2V0KCksYz1lKFwiPGRpdiBjbGFzcz0ndWktZWZmZWN0cy10cmFuc2Zlcic+PC9kaXY+XCIpLmFwcGVuZFRvKGRvY3VtZW50LmJvZHkpLmFkZENsYXNzKHQuY2xhc3NOYW1lKS5jc3Moe3RvcDpkLnRvcC1yLGxlZnQ6ZC5sZWZ0LWgsaGVpZ2h0OnMuaW5uZXJIZWlnaHQoKSx3aWR0aDpzLmlubmVyV2lkdGgoKSxwb3NpdGlvbjphP1wiZml4ZWRcIjpcImFic29sdXRlXCJ9KS5hbmltYXRlKHUsdC5kdXJhdGlvbix0LmVhc2luZyxmdW5jdGlvbigpe2MucmVtb3ZlKCksaSgpfSl9LGUud2lkZ2V0KFwidWkucHJvZ3Jlc3NiYXJcIix7dmVyc2lvbjpcIjEuMTEuNFwiLG9wdGlvbnM6e21heDoxMDAsdmFsdWU6MCxjaGFuZ2U6bnVsbCxjb21wbGV0ZTpudWxsfSxtaW46MCxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5vbGRWYWx1ZT10aGlzLm9wdGlvbnMudmFsdWU9dGhpcy5fY29uc3RyYWluZWRWYWx1ZSgpLHRoaXMuZWxlbWVudC5hZGRDbGFzcyhcInVpLXByb2dyZXNzYmFyIHVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1jb3JuZXItYWxsXCIpLmF0dHIoe3JvbGU6XCJwcm9ncmVzc2JhclwiLFwiYXJpYS12YWx1ZW1pblwiOnRoaXMubWlufSksdGhpcy52YWx1ZURpdj1lKFwiPGRpdiBjbGFzcz0ndWktcHJvZ3Jlc3NiYXItdmFsdWUgdWktd2lkZ2V0LWhlYWRlciB1aS1jb3JuZXItbGVmdCc+PC9kaXY+XCIpLmFwcGVuZFRvKHRoaXMuZWxlbWVudCksdGhpcy5fcmVmcmVzaFZhbHVlKCl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktcHJvZ3Jlc3NiYXIgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWNvcm5lci1hbGxcIikucmVtb3ZlQXR0cihcInJvbGVcIikucmVtb3ZlQXR0cihcImFyaWEtdmFsdWVtaW5cIikucmVtb3ZlQXR0cihcImFyaWEtdmFsdWVtYXhcIikucmVtb3ZlQXR0cihcImFyaWEtdmFsdWVub3dcIiksdGhpcy52YWx1ZURpdi5yZW1vdmUoKX0sdmFsdWU6ZnVuY3Rpb24oZSl7cmV0dXJuIHZvaWQgMD09PWU/dGhpcy5vcHRpb25zLnZhbHVlOih0aGlzLm9wdGlvbnMudmFsdWU9dGhpcy5fY29uc3RyYWluZWRWYWx1ZShlKSx0aGlzLl9yZWZyZXNoVmFsdWUoKSx2b2lkIDApfSxfY29uc3RyYWluZWRWYWx1ZTpmdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9dGhpcy5vcHRpb25zLnZhbHVlKSx0aGlzLmluZGV0ZXJtaW5hdGU9ZT09PSExLFwibnVtYmVyXCIhPXR5cGVvZiBlJiYoZT0wKSx0aGlzLmluZGV0ZXJtaW5hdGU/ITE6TWF0aC5taW4odGhpcy5vcHRpb25zLm1heCxNYXRoLm1heCh0aGlzLm1pbixlKSl9LF9zZXRPcHRpb25zOmZ1bmN0aW9uKGUpe3ZhciB0PWUudmFsdWU7ZGVsZXRlIGUudmFsdWUsdGhpcy5fc3VwZXIoZSksdGhpcy5vcHRpb25zLnZhbHVlPXRoaXMuX2NvbnN0cmFpbmVkVmFsdWUodCksdGhpcy5fcmVmcmVzaFZhbHVlKCl9LF9zZXRPcHRpb246ZnVuY3Rpb24oZSx0KXtcIm1heFwiPT09ZSYmKHQ9TWF0aC5tYXgodGhpcy5taW4sdCkpLFwiZGlzYWJsZWRcIj09PWUmJnRoaXMuZWxlbWVudC50b2dnbGVDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIsISF0KS5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLHQpLHRoaXMuX3N1cGVyKGUsdCl9LF9wZXJjZW50YWdlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaW5kZXRlcm1pbmF0ZT8xMDA6MTAwKih0aGlzLm9wdGlvbnMudmFsdWUtdGhpcy5taW4pLyh0aGlzLm9wdGlvbnMubWF4LXRoaXMubWluKX0sX3JlZnJlc2hWYWx1ZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9ucy52YWx1ZSxpPXRoaXMuX3BlcmNlbnRhZ2UoKTt0aGlzLnZhbHVlRGl2LnRvZ2dsZSh0aGlzLmluZGV0ZXJtaW5hdGV8fHQ+dGhpcy5taW4pLnRvZ2dsZUNsYXNzKFwidWktY29ybmVyLXJpZ2h0XCIsdD09PXRoaXMub3B0aW9ucy5tYXgpLndpZHRoKGkudG9GaXhlZCgwKStcIiVcIiksdGhpcy5lbGVtZW50LnRvZ2dsZUNsYXNzKFwidWktcHJvZ3Jlc3NiYXItaW5kZXRlcm1pbmF0ZVwiLHRoaXMuaW5kZXRlcm1pbmF0ZSksdGhpcy5pbmRldGVybWluYXRlPyh0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cihcImFyaWEtdmFsdWVub3dcIiksdGhpcy5vdmVybGF5RGl2fHwodGhpcy5vdmVybGF5RGl2PWUoXCI8ZGl2IGNsYXNzPSd1aS1wcm9ncmVzc2Jhci1vdmVybGF5Jz48L2Rpdj5cIikuYXBwZW5kVG8odGhpcy52YWx1ZURpdikpKToodGhpcy5lbGVtZW50LmF0dHIoe1wiYXJpYS12YWx1ZW1heFwiOnRoaXMub3B0aW9ucy5tYXgsXCJhcmlhLXZhbHVlbm93XCI6dH0pLHRoaXMub3ZlcmxheURpdiYmKHRoaXMub3ZlcmxheURpdi5yZW1vdmUoKSx0aGlzLm92ZXJsYXlEaXY9bnVsbCkpLHRoaXMub2xkVmFsdWUhPT10JiYodGhpcy5vbGRWYWx1ZT10LHRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIikpLHQ9PT10aGlzLm9wdGlvbnMubWF4JiZ0aGlzLl90cmlnZ2VyKFwiY29tcGxldGVcIil9fSksZS53aWRnZXQoXCJ1aS5zZWxlY3RhYmxlXCIsZS51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTEuNFwiLG9wdGlvbnM6e2FwcGVuZFRvOlwiYm9keVwiLGF1dG9SZWZyZXNoOiEwLGRpc3RhbmNlOjAsZmlsdGVyOlwiKlwiLHRvbGVyYW5jZTpcInRvdWNoXCIsc2VsZWN0ZWQ6bnVsbCxzZWxlY3Rpbmc6bnVsbCxzdGFydDpudWxsLHN0b3A6bnVsbCx1bnNlbGVjdGVkOm51bGwsdW5zZWxlY3Rpbmc6bnVsbH0sX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciB0LGk9dGhpczt0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1zZWxlY3RhYmxlXCIpLHRoaXMuZHJhZ2dlZD0hMSx0aGlzLnJlZnJlc2g9ZnVuY3Rpb24oKXt0PWUoaS5vcHRpb25zLmZpbHRlcixpLmVsZW1lbnRbMF0pLHQuYWRkQ2xhc3MoXCJ1aS1zZWxlY3RlZVwiKSx0LmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpLGk9dC5vZmZzZXQoKTtlLmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiLHtlbGVtZW50OnRoaXMsJGVsZW1lbnQ6dCxsZWZ0OmkubGVmdCx0b3A6aS50b3AscmlnaHQ6aS5sZWZ0K3Qub3V0ZXJXaWR0aCgpLGJvdHRvbTppLnRvcCt0Lm91dGVySGVpZ2h0KCksc3RhcnRzZWxlY3RlZDohMSxzZWxlY3RlZDp0Lmhhc0NsYXNzKFwidWktc2VsZWN0ZWRcIiksc2VsZWN0aW5nOnQuaGFzQ2xhc3MoXCJ1aS1zZWxlY3RpbmdcIiksdW5zZWxlY3Rpbmc6dC5oYXNDbGFzcyhcInVpLXVuc2VsZWN0aW5nXCIpfSl9KX0sdGhpcy5yZWZyZXNoKCksdGhpcy5zZWxlY3RlZXM9dC5hZGRDbGFzcyhcInVpLXNlbGVjdGVlXCIpLHRoaXMuX21vdXNlSW5pdCgpLHRoaXMuaGVscGVyPWUoXCI8ZGl2IGNsYXNzPSd1aS1zZWxlY3RhYmxlLWhlbHBlcic+PC9kaXY+XCIpfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuc2VsZWN0ZWVzLnJlbW92ZUNsYXNzKFwidWktc2VsZWN0ZWVcIikucmVtb3ZlRGF0YShcInNlbGVjdGFibGUtaXRlbVwiKSx0aGlzLmVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS1zZWxlY3RhYmxlIHVpLXNlbGVjdGFibGUtZGlzYWJsZWRcIiksdGhpcy5fbW91c2VEZXN0cm95KCl9LF9tb3VzZVN0YXJ0OmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMscz10aGlzLm9wdGlvbnM7dGhpcy5vcG9zPVt0LnBhZ2VYLHQucGFnZVldLHRoaXMub3B0aW9ucy5kaXNhYmxlZHx8KHRoaXMuc2VsZWN0ZWVzPWUocy5maWx0ZXIsdGhpcy5lbGVtZW50WzBdKSx0aGlzLl90cmlnZ2VyKFwic3RhcnRcIix0KSxlKHMuYXBwZW5kVG8pLmFwcGVuZCh0aGlzLmhlbHBlciksdGhpcy5oZWxwZXIuY3NzKHtsZWZ0OnQucGFnZVgsdG9wOnQucGFnZVksd2lkdGg6MCxoZWlnaHQ6MH0pLHMuYXV0b1JlZnJlc2gmJnRoaXMucmVmcmVzaCgpLHRoaXMuc2VsZWN0ZWVzLmZpbHRlcihcIi51aS1zZWxlY3RlZFwiKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHM9ZS5kYXRhKHRoaXMsXCJzZWxlY3RhYmxlLWl0ZW1cIik7cy5zdGFydHNlbGVjdGVkPSEwLHQubWV0YUtleXx8dC5jdHJsS2V5fHwocy4kZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXNlbGVjdGVkXCIpLHMuc2VsZWN0ZWQ9ITEscy4kZWxlbWVudC5hZGRDbGFzcyhcInVpLXVuc2VsZWN0aW5nXCIpLHMudW5zZWxlY3Rpbmc9ITAsaS5fdHJpZ2dlcihcInVuc2VsZWN0aW5nXCIsdCx7dW5zZWxlY3Rpbmc6cy5lbGVtZW50fSkpfSksZSh0LnRhcmdldCkucGFyZW50cygpLmFkZEJhY2soKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHMsbj1lLmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiKTtyZXR1cm4gbj8ocz0hdC5tZXRhS2V5JiYhdC5jdHJsS2V5fHwhbi4kZWxlbWVudC5oYXNDbGFzcyhcInVpLXNlbGVjdGVkXCIpLG4uJGVsZW1lbnQucmVtb3ZlQ2xhc3Mocz9cInVpLXVuc2VsZWN0aW5nXCI6XCJ1aS1zZWxlY3RlZFwiKS5hZGRDbGFzcyhzP1widWktc2VsZWN0aW5nXCI6XCJ1aS11bnNlbGVjdGluZ1wiKSxuLnVuc2VsZWN0aW5nPSFzLG4uc2VsZWN0aW5nPXMsbi5zZWxlY3RlZD1zLHM/aS5fdHJpZ2dlcihcInNlbGVjdGluZ1wiLHQse3NlbGVjdGluZzpuLmVsZW1lbnR9KTppLl90cmlnZ2VyKFwidW5zZWxlY3RpbmdcIix0LHt1bnNlbGVjdGluZzpuLmVsZW1lbnR9KSwhMSk6dm9pZCAwfSkpfSxfbW91c2VEcmFnOmZ1bmN0aW9uKHQpe2lmKHRoaXMuZHJhZ2dlZD0hMCwhdGhpcy5vcHRpb25zLmRpc2FibGVkKXt2YXIgaSxzPXRoaXMsbj10aGlzLm9wdGlvbnMsYT10aGlzLm9wb3NbMF0sbz10aGlzLm9wb3NbMV0scj10LnBhZ2VYLGg9dC5wYWdlWTtyZXR1cm4gYT5yJiYoaT1yLHI9YSxhPWkpLG8+aCYmKGk9aCxoPW8sbz1pKSx0aGlzLmhlbHBlci5jc3Moe2xlZnQ6YSx0b3A6byx3aWR0aDpyLWEsaGVpZ2h0Omgtb30pLHRoaXMuc2VsZWN0ZWVzLmVhY2goZnVuY3Rpb24oKXt2YXIgaT1lLmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiKSxsPSExO2kmJmkuZWxlbWVudCE9PXMuZWxlbWVudFswXSYmKFwidG91Y2hcIj09PW4udG9sZXJhbmNlP2w9IShpLmxlZnQ+cnx8YT5pLnJpZ2h0fHxpLnRvcD5ofHxvPmkuYm90dG9tKTpcImZpdFwiPT09bi50b2xlcmFuY2UmJihsPWkubGVmdD5hJiZyPmkucmlnaHQmJmkudG9wPm8mJmg+aS5ib3R0b20pLGw/KGkuc2VsZWN0ZWQmJihpLiRlbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc2VsZWN0ZWRcIiksaS5zZWxlY3RlZD0hMSksaS51bnNlbGVjdGluZyYmKGkuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS11bnNlbGVjdGluZ1wiKSxpLnVuc2VsZWN0aW5nPSExKSxpLnNlbGVjdGluZ3x8KGkuJGVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1zZWxlY3RpbmdcIiksaS5zZWxlY3Rpbmc9ITAscy5fdHJpZ2dlcihcInNlbGVjdGluZ1wiLHQse3NlbGVjdGluZzppLmVsZW1lbnR9KSkpOihpLnNlbGVjdGluZyYmKCh0Lm1ldGFLZXl8fHQuY3RybEtleSkmJmkuc3RhcnRzZWxlY3RlZD8oaS4kZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXNlbGVjdGluZ1wiKSxpLnNlbGVjdGluZz0hMSxpLiRlbGVtZW50LmFkZENsYXNzKFwidWktc2VsZWN0ZWRcIiksaS5zZWxlY3RlZD0hMCk6KGkuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS1zZWxlY3RpbmdcIiksaS5zZWxlY3Rpbmc9ITEsaS5zdGFydHNlbGVjdGVkJiYoaS4kZWxlbWVudC5hZGRDbGFzcyhcInVpLXVuc2VsZWN0aW5nXCIpLGkudW5zZWxlY3Rpbmc9ITApLHMuX3RyaWdnZXIoXCJ1bnNlbGVjdGluZ1wiLHQse3Vuc2VsZWN0aW5nOmkuZWxlbWVudH0pKSksaS5zZWxlY3RlZCYmKHQubWV0YUtleXx8dC5jdHJsS2V5fHxpLnN0YXJ0c2VsZWN0ZWR8fChpLiRlbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc2VsZWN0ZWRcIiksaS5zZWxlY3RlZD0hMSxpLiRlbGVtZW50LmFkZENsYXNzKFwidWktdW5zZWxlY3RpbmdcIiksaS51bnNlbGVjdGluZz0hMCxzLl90cmlnZ2VyKFwidW5zZWxlY3RpbmdcIix0LHt1bnNlbGVjdGluZzppLmVsZW1lbnR9KSkpKSl9KSwhMX19LF9tb3VzZVN0b3A6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcztyZXR1cm4gdGhpcy5kcmFnZ2VkPSExLGUoXCIudWktdW5zZWxlY3RpbmdcIix0aGlzLmVsZW1lbnRbMF0pLmVhY2goZnVuY3Rpb24oKXt2YXIgcz1lLmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiKTtzLiRlbGVtZW50LnJlbW92ZUNsYXNzKFwidWktdW5zZWxlY3RpbmdcIikscy51bnNlbGVjdGluZz0hMSxzLnN0YXJ0c2VsZWN0ZWQ9ITEsaS5fdHJpZ2dlcihcInVuc2VsZWN0ZWRcIix0LHt1bnNlbGVjdGVkOnMuZWxlbWVudH0pfSksZShcIi51aS1zZWxlY3RpbmdcIix0aGlzLmVsZW1lbnRbMF0pLmVhY2goZnVuY3Rpb24oKXt2YXIgcz1lLmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiKTtzLiRlbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc2VsZWN0aW5nXCIpLmFkZENsYXNzKFwidWktc2VsZWN0ZWRcIikscy5zZWxlY3Rpbmc9ITEscy5zZWxlY3RlZD0hMCxzLnN0YXJ0c2VsZWN0ZWQ9ITAsaS5fdHJpZ2dlcihcInNlbGVjdGVkXCIsdCx7c2VsZWN0ZWQ6cy5lbGVtZW50fSl9KSx0aGlzLl90cmlnZ2VyKFwic3RvcFwiLHQpLHRoaXMuaGVscGVyLnJlbW92ZSgpLCExfX0pLGUud2lkZ2V0KFwidWkuc2VsZWN0bWVudVwiLHt2ZXJzaW9uOlwiMS4xMS40XCIsZGVmYXVsdEVsZW1lbnQ6XCI8c2VsZWN0PlwiLG9wdGlvbnM6e2FwcGVuZFRvOm51bGwsZGlzYWJsZWQ6bnVsbCxpY29uczp7YnV0dG9uOlwidWktaWNvbi10cmlhbmdsZS0xLXNcIn0scG9zaXRpb246e215OlwibGVmdCB0b3BcIixhdDpcImxlZnQgYm90dG9tXCIsY29sbGlzaW9uOlwibm9uZVwifSx3aWR0aDpudWxsLGNoYW5nZTpudWxsLGNsb3NlOm51bGwsZm9jdXM6bnVsbCxvcGVuOm51bGwsc2VsZWN0Om51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmVsZW1lbnQudW5pcXVlSWQoKS5hdHRyKFwiaWRcIik7dGhpcy5pZHM9e2VsZW1lbnQ6ZSxidXR0b246ZStcIi1idXR0b25cIixtZW51OmUrXCItbWVudVwifSx0aGlzLl9kcmF3QnV0dG9uKCksdGhpcy5fZHJhd01lbnUoKSx0aGlzLm9wdGlvbnMuZGlzYWJsZWQmJnRoaXMuZGlzYWJsZSgpfSxfZHJhd0J1dHRvbjpmdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5sYWJlbD1lKFwibGFiZWxbZm9yPSdcIit0aGlzLmlkcy5lbGVtZW50K1wiJ11cIikuYXR0cihcImZvclwiLHRoaXMuaWRzLmJ1dHRvbiksdGhpcy5fb24odGhpcy5sYWJlbCx7Y2xpY2s6ZnVuY3Rpb24oZSl7dGhpcy5idXR0b24uZm9jdXMoKSxlLnByZXZlbnREZWZhdWx0KCl9fSksdGhpcy5lbGVtZW50LmhpZGUoKSx0aGlzLmJ1dHRvbj1lKFwiPHNwYW4+XCIse1wiY2xhc3NcIjpcInVpLXNlbGVjdG1lbnUtYnV0dG9uIHVpLXdpZGdldCB1aS1zdGF0ZS1kZWZhdWx0IHVpLWNvcm5lci1hbGxcIix0YWJpbmRleDp0aGlzLm9wdGlvbnMuZGlzYWJsZWQ/LTE6MCxpZDp0aGlzLmlkcy5idXR0b24scm9sZTpcImNvbWJvYm94XCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJmYWxzZVwiLFwiYXJpYS1hdXRvY29tcGxldGVcIjpcImxpc3RcIixcImFyaWEtb3duc1wiOnRoaXMuaWRzLm1lbnUsXCJhcmlhLWhhc3BvcHVwXCI6XCJ0cnVlXCJ9KS5pbnNlcnRBZnRlcih0aGlzLmVsZW1lbnQpLGUoXCI8c3Bhbj5cIix7XCJjbGFzc1wiOlwidWktaWNvbiBcIit0aGlzLm9wdGlvbnMuaWNvbnMuYnV0dG9ufSkucHJlcGVuZFRvKHRoaXMuYnV0dG9uKSx0aGlzLmJ1dHRvblRleHQ9ZShcIjxzcGFuPlwiLHtcImNsYXNzXCI6XCJ1aS1zZWxlY3RtZW51LXRleHRcIn0pLmFwcGVuZFRvKHRoaXMuYnV0dG9uKSx0aGlzLl9zZXRUZXh0KHRoaXMuYnV0dG9uVGV4dCx0aGlzLmVsZW1lbnQuZmluZChcIm9wdGlvbjpzZWxlY3RlZFwiKS50ZXh0KCkpLHRoaXMuX3Jlc2l6ZUJ1dHRvbigpLHRoaXMuX29uKHRoaXMuYnV0dG9uLHRoaXMuX2J1dHRvbkV2ZW50cyksdGhpcy5idXR0b24ub25lKFwiZm9jdXNpblwiLGZ1bmN0aW9uKCl7dC5tZW51SXRlbXN8fHQuX3JlZnJlc2hNZW51KCl9KSx0aGlzLl9ob3ZlcmFibGUodGhpcy5idXR0b24pLHRoaXMuX2ZvY3VzYWJsZSh0aGlzLmJ1dHRvbil9LF9kcmF3TWVudTpmdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5tZW51PWUoXCI8dWw+XCIse1wiYXJpYS1oaWRkZW5cIjpcInRydWVcIixcImFyaWEtbGFiZWxsZWRieVwiOnRoaXMuaWRzLmJ1dHRvbixpZDp0aGlzLmlkcy5tZW51fSksdGhpcy5tZW51V3JhcD1lKFwiPGRpdj5cIix7XCJjbGFzc1wiOlwidWktc2VsZWN0bWVudS1tZW51IHVpLWZyb250XCJ9KS5hcHBlbmQodGhpcy5tZW51KS5hcHBlbmRUbyh0aGlzLl9hcHBlbmRUbygpKSx0aGlzLm1lbnVJbnN0YW5jZT10aGlzLm1lbnUubWVudSh7cm9sZTpcImxpc3Rib3hcIixzZWxlY3Q6ZnVuY3Rpb24oZSxpKXtlLnByZXZlbnREZWZhdWx0KCksdC5fc2V0U2VsZWN0aW9uKCksdC5fc2VsZWN0KGkuaXRlbS5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIpLGUpfSxmb2N1czpmdW5jdGlvbihlLGkpe3ZhciBzPWkuaXRlbS5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIpO251bGwhPXQuZm9jdXNJbmRleCYmcy5pbmRleCE9PXQuZm9jdXNJbmRleCYmKHQuX3RyaWdnZXIoXCJmb2N1c1wiLGUse2l0ZW06c30pLHQuaXNPcGVufHx0Ll9zZWxlY3QocyxlKSksdC5mb2N1c0luZGV4PXMuaW5kZXgsdC5idXR0b24uYXR0cihcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiLHQubWVudUl0ZW1zLmVxKHMuaW5kZXgpLmF0dHIoXCJpZFwiKSl9fSkubWVudShcImluc3RhbmNlXCIpLHRoaXMubWVudS5hZGRDbGFzcyhcInVpLWNvcm5lci1ib3R0b21cIikucmVtb3ZlQ2xhc3MoXCJ1aS1jb3JuZXItYWxsXCIpLHRoaXMubWVudUluc3RhbmNlLl9vZmYodGhpcy5tZW51LFwibW91c2VsZWF2ZVwiKSx0aGlzLm1lbnVJbnN0YW5jZS5fY2xvc2VPbkRvY3VtZW50Q2xpY2s9ZnVuY3Rpb24oKXtyZXR1cm4hMX0sdGhpcy5tZW51SW5zdGFuY2UuX2lzRGl2aWRlcj1mdW5jdGlvbigpe3JldHVybiExfX0scmVmcmVzaDpmdW5jdGlvbigpe3RoaXMuX3JlZnJlc2hNZW51KCksdGhpcy5fc2V0VGV4dCh0aGlzLmJ1dHRvblRleHQsdGhpcy5fZ2V0U2VsZWN0ZWRJdGVtKCkudGV4dCgpKSx0aGlzLm9wdGlvbnMud2lkdGh8fHRoaXMuX3Jlc2l6ZUJ1dHRvbigpfSxfcmVmcmVzaE1lbnU6ZnVuY3Rpb24oKXt0aGlzLm1lbnUuZW1wdHkoKTt2YXIgZSx0PXRoaXMuZWxlbWVudC5maW5kKFwib3B0aW9uXCIpO3QubGVuZ3RoJiYodGhpcy5fcGFyc2VPcHRpb25zKHQpLHRoaXMuX3JlbmRlck1lbnUodGhpcy5tZW51LHRoaXMuaXRlbXMpLHRoaXMubWVudUluc3RhbmNlLnJlZnJlc2goKSx0aGlzLm1lbnVJdGVtcz10aGlzLm1lbnUuZmluZChcImxpXCIpLm5vdChcIi51aS1zZWxlY3RtZW51LW9wdGdyb3VwXCIpLGU9dGhpcy5fZ2V0U2VsZWN0ZWRJdGVtKCksdGhpcy5tZW51SW5zdGFuY2UuZm9jdXMobnVsbCxlKSx0aGlzLl9zZXRBcmlhKGUuZGF0YShcInVpLXNlbGVjdG1lbnUtaXRlbVwiKSksdGhpcy5fc2V0T3B0aW9uKFwiZGlzYWJsZWRcIix0aGlzLmVsZW1lbnQucHJvcChcImRpc2FibGVkXCIpKSl9LG9wZW46ZnVuY3Rpb24oZSl7dGhpcy5vcHRpb25zLmRpc2FibGVkfHwodGhpcy5tZW51SXRlbXM/KHRoaXMubWVudS5maW5kKFwiLnVpLXN0YXRlLWZvY3VzXCIpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtZm9jdXNcIiksdGhpcy5tZW51SW5zdGFuY2UuZm9jdXMobnVsbCx0aGlzLl9nZXRTZWxlY3RlZEl0ZW0oKSkpOnRoaXMuX3JlZnJlc2hNZW51KCksdGhpcy5pc09wZW49ITAsdGhpcy5fdG9nZ2xlQXR0cigpLHRoaXMuX3Jlc2l6ZU1lbnUoKSx0aGlzLl9wb3NpdGlvbigpLHRoaXMuX29uKHRoaXMuZG9jdW1lbnQsdGhpcy5fZG9jdW1lbnRDbGljayksdGhpcy5fdHJpZ2dlcihcIm9wZW5cIixlKSl9LF9wb3NpdGlvbjpmdW5jdGlvbigpe3RoaXMubWVudVdyYXAucG9zaXRpb24oZS5leHRlbmQoe29mOnRoaXMuYnV0dG9ufSx0aGlzLm9wdGlvbnMucG9zaXRpb24pKX0sY2xvc2U6ZnVuY3Rpb24oZSl7dGhpcy5pc09wZW4mJih0aGlzLmlzT3Blbj0hMSx0aGlzLl90b2dnbGVBdHRyKCksdGhpcy5yYW5nZT1udWxsLHRoaXMuX29mZih0aGlzLmRvY3VtZW50KSx0aGlzLl90cmlnZ2VyKFwiY2xvc2VcIixlKSl9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ1dHRvbn0sbWVudVdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1lbnV9LF9yZW5kZXJNZW51OmZ1bmN0aW9uKHQsaSl7dmFyIHM9dGhpcyxuPVwiXCI7ZS5lYWNoKGksZnVuY3Rpb24oaSxhKXthLm9wdGdyb3VwIT09biYmKGUoXCI8bGk+XCIse1wiY2xhc3NcIjpcInVpLXNlbGVjdG1lbnUtb3B0Z3JvdXAgdWktbWVudS1kaXZpZGVyXCIrKGEuZWxlbWVudC5wYXJlbnQoXCJvcHRncm91cFwiKS5wcm9wKFwiZGlzYWJsZWRcIik/XCIgdWktc3RhdGUtZGlzYWJsZWRcIjpcIlwiKSx0ZXh0OmEub3B0Z3JvdXB9KS5hcHBlbmRUbyh0KSxuPWEub3B0Z3JvdXApLHMuX3JlbmRlckl0ZW1EYXRhKHQsYSl9KX0sX3JlbmRlckl0ZW1EYXRhOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMuX3JlbmRlckl0ZW0oZSx0KS5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIsdCl9LF9yZW5kZXJJdGVtOmZ1bmN0aW9uKHQsaSl7dmFyIHM9ZShcIjxsaT5cIik7cmV0dXJuIGkuZGlzYWJsZWQmJnMuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKSx0aGlzLl9zZXRUZXh0KHMsaS5sYWJlbCkscy5hcHBlbmRUbyh0KX0sX3NldFRleHQ6ZnVuY3Rpb24oZSx0KXt0P2UudGV4dCh0KTplLmh0bWwoXCImIzE2MDtcIil9LF9tb3ZlOmZ1bmN0aW9uKGUsdCl7dmFyIGkscyxuPVwiLnVpLW1lbnUtaXRlbVwiO3RoaXMuaXNPcGVuP2k9dGhpcy5tZW51SXRlbXMuZXEodGhpcy5mb2N1c0luZGV4KTooaT10aGlzLm1lbnVJdGVtcy5lcSh0aGlzLmVsZW1lbnRbMF0uc2VsZWN0ZWRJbmRleCksbis9XCI6bm90KC51aS1zdGF0ZS1kaXNhYmxlZClcIikscz1cImZpcnN0XCI9PT1lfHxcImxhc3RcIj09PWU/aVtcImZpcnN0XCI9PT1lP1wicHJldkFsbFwiOlwibmV4dEFsbFwiXShuKS5lcSgtMSk6aVtlK1wiQWxsXCJdKG4pLmVxKDApLHMubGVuZ3RoJiZ0aGlzLm1lbnVJbnN0YW5jZS5mb2N1cyh0LHMpfSxfZ2V0U2VsZWN0ZWRJdGVtOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWVudUl0ZW1zLmVxKHRoaXMuZWxlbWVudFswXS5zZWxlY3RlZEluZGV4KX0sX3RvZ2dsZTpmdW5jdGlvbihlKXt0aGlzW3RoaXMuaXNPcGVuP1wiY2xvc2VcIjpcIm9wZW5cIl0oZSl9LF9zZXRTZWxlY3Rpb246ZnVuY3Rpb24oKXt2YXIgZTt0aGlzLnJhbmdlJiYod2luZG93LmdldFNlbGVjdGlvbj8oZT13aW5kb3cuZ2V0U2VsZWN0aW9uKCksZS5yZW1vdmVBbGxSYW5nZXMoKSxlLmFkZFJhbmdlKHRoaXMucmFuZ2UpKTp0aGlzLnJhbmdlLnNlbGVjdCgpLHRoaXMuYnV0dG9uLmZvY3VzKCkpfSxfZG9jdW1lbnRDbGljazp7bW91c2Vkb3duOmZ1bmN0aW9uKHQpe3RoaXMuaXNPcGVuJiYoZSh0LnRhcmdldCkuY2xvc2VzdChcIi51aS1zZWxlY3RtZW51LW1lbnUsICNcIit0aGlzLmlkcy5idXR0b24pLmxlbmd0aHx8dGhpcy5jbG9zZSh0KSl9fSxfYnV0dG9uRXZlbnRzOnttb3VzZWRvd246ZnVuY3Rpb24oKXt2YXIgZTt3aW5kb3cuZ2V0U2VsZWN0aW9uPyhlPXdpbmRvdy5nZXRTZWxlY3Rpb24oKSxlLnJhbmdlQ291bnQmJih0aGlzLnJhbmdlPWUuZ2V0UmFuZ2VBdCgwKSkpOnRoaXMucmFuZ2U9ZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCl9LGNsaWNrOmZ1bmN0aW9uKGUpe3RoaXMuX3NldFNlbGVjdGlvbigpLHRoaXMuX3RvZ2dsZShlKX0sa2V5ZG93bjpmdW5jdGlvbih0KXt2YXIgaT0hMDtzd2l0Y2godC5rZXlDb2RlKXtjYXNlIGUudWkua2V5Q29kZS5UQUI6Y2FzZSBlLnVpLmtleUNvZGUuRVNDQVBFOnRoaXMuY2xvc2UodCksaT0hMTticmVhaztjYXNlIGUudWkua2V5Q29kZS5FTlRFUjp0aGlzLmlzT3BlbiYmdGhpcy5fc2VsZWN0Rm9jdXNlZEl0ZW0odCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuVVA6dC5hbHRLZXk/dGhpcy5fdG9nZ2xlKHQpOnRoaXMuX21vdmUoXCJwcmV2XCIsdCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuRE9XTjp0LmFsdEtleT90aGlzLl90b2dnbGUodCk6dGhpcy5fbW92ZShcIm5leHRcIix0KTticmVhaztjYXNlIGUudWkua2V5Q29kZS5TUEFDRTp0aGlzLmlzT3Blbj90aGlzLl9zZWxlY3RGb2N1c2VkSXRlbSh0KTp0aGlzLl90b2dnbGUodCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuTEVGVDp0aGlzLl9tb3ZlKFwicHJldlwiLHQpO2JyZWFrO2Nhc2UgZS51aS5rZXlDb2RlLlJJR0hUOnRoaXMuX21vdmUoXCJuZXh0XCIsdCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuSE9NRTpjYXNlIGUudWkua2V5Q29kZS5QQUdFX1VQOnRoaXMuX21vdmUoXCJmaXJzdFwiLHQpO2JyZWFrO2Nhc2UgZS51aS5rZXlDb2RlLkVORDpjYXNlIGUudWkua2V5Q29kZS5QQUdFX0RPV046dGhpcy5fbW92ZShcImxhc3RcIix0KTticmVhaztkZWZhdWx0OnRoaXMubWVudS50cmlnZ2VyKHQpLGk9ITF9aSYmdC5wcmV2ZW50RGVmYXVsdCgpfX0sX3NlbGVjdEZvY3VzZWRJdGVtOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMubWVudUl0ZW1zLmVxKHRoaXMuZm9jdXNJbmRleCk7dC5oYXNDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIpfHx0aGlzLl9zZWxlY3QodC5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIpLGUpfSxfc2VsZWN0OmZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy5lbGVtZW50WzBdLnNlbGVjdGVkSW5kZXg7dGhpcy5lbGVtZW50WzBdLnNlbGVjdGVkSW5kZXg9ZS5pbmRleCx0aGlzLl9zZXRUZXh0KHRoaXMuYnV0dG9uVGV4dCxlLmxhYmVsKSx0aGlzLl9zZXRBcmlhKGUpLHRoaXMuX3RyaWdnZXIoXCJzZWxlY3RcIix0LHtpdGVtOmV9KSxlLmluZGV4IT09aSYmdGhpcy5fdHJpZ2dlcihcImNoYW5nZVwiLHQse2l0ZW06ZX0pLHRoaXMuY2xvc2UodCl9LF9zZXRBcmlhOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMubWVudUl0ZW1zLmVxKGUuaW5kZXgpLmF0dHIoXCJpZFwiKTt0aGlzLmJ1dHRvbi5hdHRyKHtcImFyaWEtbGFiZWxsZWRieVwiOnQsXCJhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcIjp0fSksdGhpcy5tZW51LmF0dHIoXCJhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcIix0KX0sX3NldE9wdGlvbjpmdW5jdGlvbihlLHQpe1wiaWNvbnNcIj09PWUmJnRoaXMuYnV0dG9uLmZpbmQoXCJzcGFuLnVpLWljb25cIikucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmljb25zLmJ1dHRvbikuYWRkQ2xhc3ModC5idXR0b24pLHRoaXMuX3N1cGVyKGUsdCksXCJhcHBlbmRUb1wiPT09ZSYmdGhpcy5tZW51V3JhcC5hcHBlbmRUbyh0aGlzLl9hcHBlbmRUbygpKSxcImRpc2FibGVkXCI9PT1lJiYodGhpcy5tZW51SW5zdGFuY2Uub3B0aW9uKFwiZGlzYWJsZWRcIix0KSx0aGlzLmJ1dHRvbi50b2dnbGVDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIsdCkuYXR0cihcImFyaWEtZGlzYWJsZWRcIix0KSx0aGlzLmVsZW1lbnQucHJvcChcImRpc2FibGVkXCIsdCksdD8odGhpcy5idXR0b24uYXR0cihcInRhYmluZGV4XCIsLTEpLHRoaXMuY2xvc2UoKSk6dGhpcy5idXR0b24uYXR0cihcInRhYmluZGV4XCIsMCkpLFwid2lkdGhcIj09PWUmJnRoaXMuX3Jlc2l6ZUJ1dHRvbigpfSxfYXBwZW5kVG86ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnMuYXBwZW5kVG87cmV0dXJuIHQmJih0PXQuanF1ZXJ5fHx0Lm5vZGVUeXBlP2UodCk6dGhpcy5kb2N1bWVudC5maW5kKHQpLmVxKDApKSx0JiZ0WzBdfHwodD10aGlzLmVsZW1lbnQuY2xvc2VzdChcIi51aS1mcm9udFwiKSksdC5sZW5ndGh8fCh0PXRoaXMuZG9jdW1lbnRbMF0uYm9keSksdH0sX3RvZ2dsZUF0dHI6ZnVuY3Rpb24oKXt0aGlzLmJ1dHRvbi50b2dnbGVDbGFzcyhcInVpLWNvcm5lci10b3BcIix0aGlzLmlzT3BlbikudG9nZ2xlQ2xhc3MoXCJ1aS1jb3JuZXItYWxsXCIsIXRoaXMuaXNPcGVuKS5hdHRyKFwiYXJpYS1leHBhbmRlZFwiLHRoaXMuaXNPcGVuKSx0aGlzLm1lbnVXcmFwLnRvZ2dsZUNsYXNzKFwidWktc2VsZWN0bWVudS1vcGVuXCIsdGhpcy5pc09wZW4pLHRoaXMubWVudS5hdHRyKFwiYXJpYS1oaWRkZW5cIiwhdGhpcy5pc09wZW4pfSxfcmVzaXplQnV0dG9uOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcHRpb25zLndpZHRoO2V8fChlPXRoaXMuZWxlbWVudC5zaG93KCkub3V0ZXJXaWR0aCgpLHRoaXMuZWxlbWVudC5oaWRlKCkpLHRoaXMuYnV0dG9uLm91dGVyV2lkdGgoZSl9LF9yZXNpemVNZW51OmZ1bmN0aW9uKCl7dGhpcy5tZW51Lm91dGVyV2lkdGgoTWF0aC5tYXgodGhpcy5idXR0b24ub3V0ZXJXaWR0aCgpLHRoaXMubWVudS53aWR0aChcIlwiKS5vdXRlcldpZHRoKCkrMSkpfSxfZ2V0Q3JlYXRlT3B0aW9uczpmdW5jdGlvbigpe3JldHVybntkaXNhYmxlZDp0aGlzLmVsZW1lbnQucHJvcChcImRpc2FibGVkXCIpfX0sX3BhcnNlT3B0aW9uczpmdW5jdGlvbih0KXt2YXIgaT1bXTt0LmVhY2goZnVuY3Rpb24odCxzKXt2YXIgbj1lKHMpLGE9bi5wYXJlbnQoXCJvcHRncm91cFwiKTtpLnB1c2goe2VsZW1lbnQ6bixpbmRleDp0LHZhbHVlOm4udmFsKCksbGFiZWw6bi50ZXh0KCksb3B0Z3JvdXA6YS5hdHRyKFwibGFiZWxcIil8fFwiXCIsZGlzYWJsZWQ6YS5wcm9wKFwiZGlzYWJsZWRcIil8fG4ucHJvcChcImRpc2FibGVkXCIpfSl9KSx0aGlzLml0ZW1zPWl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5tZW51V3JhcC5yZW1vdmUoKSx0aGlzLmJ1dHRvbi5yZW1vdmUoKSx0aGlzLmVsZW1lbnQuc2hvdygpLHRoaXMuZWxlbWVudC5yZW1vdmVVbmlxdWVJZCgpLHRoaXMubGFiZWwuYXR0cihcImZvclwiLHRoaXMuaWRzLmVsZW1lbnQpfX0pLGUud2lkZ2V0KFwidWkuc2xpZGVyXCIsZS51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTEuNFwiLHdpZGdldEV2ZW50UHJlZml4Olwic2xpZGVcIixvcHRpb25zOnthbmltYXRlOiExLGRpc3RhbmNlOjAsbWF4OjEwMCxtaW46MCxvcmllbnRhdGlvbjpcImhvcml6b250YWxcIixyYW5nZTohMSxzdGVwOjEsdmFsdWU6MCx2YWx1ZXM6bnVsbCxjaGFuZ2U6bnVsbCxzbGlkZTpudWxsLHN0YXJ0Om51bGwsc3RvcDpudWxsfSxudW1QYWdlczo1LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLl9rZXlTbGlkaW5nPSExLHRoaXMuX21vdXNlU2xpZGluZz0hMSx0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX2hhbmRsZUluZGV4PW51bGwsdGhpcy5fZGV0ZWN0T3JpZW50YXRpb24oKSx0aGlzLl9tb3VzZUluaXQoKSx0aGlzLl9jYWxjdWxhdGVOZXdNYXgoKSx0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoXCJ1aS1zbGlkZXIgdWktc2xpZGVyLVwiK3RoaXMub3JpZW50YXRpb24rXCIgdWktd2lkZ2V0XCIrXCIgdWktd2lkZ2V0LWNvbnRlbnRcIitcIiB1aS1jb3JuZXItYWxsXCIpLHRoaXMuX3JlZnJlc2goKSx0aGlzLl9zZXRPcHRpb24oXCJkaXNhYmxlZFwiLHRoaXMub3B0aW9ucy5kaXNhYmxlZCksdGhpcy5fYW5pbWF0ZU9mZj0hMX0sX3JlZnJlc2g6ZnVuY3Rpb24oKXt0aGlzLl9jcmVhdGVSYW5nZSgpLHRoaXMuX2NyZWF0ZUhhbmRsZXMoKSx0aGlzLl9zZXR1cEV2ZW50cygpLHRoaXMuX3JlZnJlc2hWYWx1ZSgpfSxfY3JlYXRlSGFuZGxlczpmdW5jdGlvbigpe3ZhciB0LGkscz10aGlzLm9wdGlvbnMsbj10aGlzLmVsZW1lbnQuZmluZChcIi51aS1zbGlkZXItaGFuZGxlXCIpLmFkZENsYXNzKFwidWktc3RhdGUtZGVmYXVsdCB1aS1jb3JuZXItYWxsXCIpLGE9XCI8c3BhbiBjbGFzcz0ndWktc2xpZGVyLWhhbmRsZSB1aS1zdGF0ZS1kZWZhdWx0IHVpLWNvcm5lci1hbGwnIHRhYmluZGV4PScwJz48L3NwYW4+XCIsbz1bXTtmb3IoaT1zLnZhbHVlcyYmcy52YWx1ZXMubGVuZ3RofHwxLG4ubGVuZ3RoPmkmJihuLnNsaWNlKGkpLnJlbW92ZSgpLG49bi5zbGljZSgwLGkpKSx0PW4ubGVuZ3RoO2k+dDt0Kyspby5wdXNoKGEpO3RoaXMuaGFuZGxlcz1uLmFkZChlKG8uam9pbihcIlwiKSkuYXBwZW5kVG8odGhpcy5lbGVtZW50KSksdGhpcy5oYW5kbGU9dGhpcy5oYW5kbGVzLmVxKDApLHRoaXMuaGFuZGxlcy5lYWNoKGZ1bmN0aW9uKHQpe2UodGhpcykuZGF0YShcInVpLXNsaWRlci1oYW5kbGUtaW5kZXhcIix0KX0pfSxfY3JlYXRlUmFuZ2U6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnMsaT1cIlwiO3QucmFuZ2U/KHQucmFuZ2U9PT0hMCYmKHQudmFsdWVzP3QudmFsdWVzLmxlbmd0aCYmMiE9PXQudmFsdWVzLmxlbmd0aD90LnZhbHVlcz1bdC52YWx1ZXNbMF0sdC52YWx1ZXNbMF1dOmUuaXNBcnJheSh0LnZhbHVlcykmJih0LnZhbHVlcz10LnZhbHVlcy5zbGljZSgwKSk6dC52YWx1ZXM9W3RoaXMuX3ZhbHVlTWluKCksdGhpcy5fdmFsdWVNaW4oKV0pLHRoaXMucmFuZ2UmJnRoaXMucmFuZ2UubGVuZ3RoP3RoaXMucmFuZ2UucmVtb3ZlQ2xhc3MoXCJ1aS1zbGlkZXItcmFuZ2UtbWluIHVpLXNsaWRlci1yYW5nZS1tYXhcIikuY3NzKHtsZWZ0OlwiXCIsYm90dG9tOlwiXCJ9KToodGhpcy5yYW5nZT1lKFwiPGRpdj48L2Rpdj5cIikuYXBwZW5kVG8odGhpcy5lbGVtZW50KSxpPVwidWktc2xpZGVyLXJhbmdlIHVpLXdpZGdldC1oZWFkZXIgdWktY29ybmVyLWFsbFwiKSx0aGlzLnJhbmdlLmFkZENsYXNzKGkrKFwibWluXCI9PT10LnJhbmdlfHxcIm1heFwiPT09dC5yYW5nZT9cIiB1aS1zbGlkZXItcmFuZ2UtXCIrdC5yYW5nZTpcIlwiKSkpOih0aGlzLnJhbmdlJiZ0aGlzLnJhbmdlLnJlbW92ZSgpLHRoaXMucmFuZ2U9bnVsbCl9LF9zZXR1cEV2ZW50czpmdW5jdGlvbigpe3RoaXMuX29mZih0aGlzLmhhbmRsZXMpLHRoaXMuX29uKHRoaXMuaGFuZGxlcyx0aGlzLl9oYW5kbGVFdmVudHMpLHRoaXMuX2hvdmVyYWJsZSh0aGlzLmhhbmRsZXMpLHRoaXMuX2ZvY3VzYWJsZSh0aGlzLmhhbmRsZXMpfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuaGFuZGxlcy5yZW1vdmUoKSx0aGlzLnJhbmdlJiZ0aGlzLnJhbmdlLnJlbW92ZSgpLHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXNsaWRlciB1aS1zbGlkZXItaG9yaXpvbnRhbCB1aS1zbGlkZXItdmVydGljYWwgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWNvcm5lci1hbGxcIiksdGhpcy5fbW91c2VEZXN0cm95KCl9LF9tb3VzZUNhcHR1cmU6ZnVuY3Rpb24odCl7dmFyIGkscyxuLGEsbyxyLGgsbCx1PXRoaXMsZD10aGlzLm9wdGlvbnM7cmV0dXJuIGQuZGlzYWJsZWQ/ITE6KHRoaXMuZWxlbWVudFNpemU9e3dpZHRoOnRoaXMuZWxlbWVudC5vdXRlcldpZHRoKCksaGVpZ2h0OnRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpfSx0aGlzLmVsZW1lbnRPZmZzZXQ9dGhpcy5lbGVtZW50Lm9mZnNldCgpLGk9e3g6dC5wYWdlWCx5OnQucGFnZVl9LHM9dGhpcy5fbm9ybVZhbHVlRnJvbU1vdXNlKGkpLG49dGhpcy5fdmFsdWVNYXgoKS10aGlzLl92YWx1ZU1pbigpKzEsdGhpcy5oYW5kbGVzLmVhY2goZnVuY3Rpb24odCl7dmFyIGk9TWF0aC5hYnMocy11LnZhbHVlcyh0KSk7KG4+aXx8bj09PWkmJih0PT09dS5fbGFzdENoYW5nZWRWYWx1ZXx8dS52YWx1ZXModCk9PT1kLm1pbikpJiYobj1pLGE9ZSh0aGlzKSxvPXQpfSkscj10aGlzLl9zdGFydCh0LG8pLHI9PT0hMT8hMToodGhpcy5fbW91c2VTbGlkaW5nPSEwLHRoaXMuX2hhbmRsZUluZGV4PW8sYS5hZGRDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKS5mb2N1cygpLGg9YS5vZmZzZXQoKSxsPSFlKHQudGFyZ2V0KS5wYXJlbnRzKCkuYWRkQmFjaygpLmlzKFwiLnVpLXNsaWRlci1oYW5kbGVcIiksdGhpcy5fY2xpY2tPZmZzZXQ9bD97bGVmdDowLHRvcDowfTp7bGVmdDp0LnBhZ2VYLWgubGVmdC1hLndpZHRoKCkvMix0b3A6dC5wYWdlWS1oLnRvcC1hLmhlaWdodCgpLzItKHBhcnNlSW50KGEuY3NzKFwiYm9yZGVyVG9wV2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoYS5jc3MoXCJib3JkZXJCb3R0b21XaWR0aFwiKSwxMCl8fDApKyhwYXJzZUludChhLmNzcyhcIm1hcmdpblRvcFwiKSwxMCl8fDApfSx0aGlzLmhhbmRsZXMuaGFzQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKXx8dGhpcy5fc2xpZGUodCxvLHMpLHRoaXMuX2FuaW1hdGVPZmY9ITAsITApKX0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sX21vdXNlRHJhZzpmdW5jdGlvbihlKXt2YXIgdD17eDplLnBhZ2VYLHk6ZS5wYWdlWX0saT10aGlzLl9ub3JtVmFsdWVGcm9tTW91c2UodCk7cmV0dXJuIHRoaXMuX3NsaWRlKGUsdGhpcy5faGFuZGxlSW5kZXgsaSksITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuaGFuZGxlcy5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKSx0aGlzLl9tb3VzZVNsaWRpbmc9ITEsdGhpcy5fc3RvcChlLHRoaXMuX2hhbmRsZUluZGV4KSx0aGlzLl9jaGFuZ2UoZSx0aGlzLl9oYW5kbGVJbmRleCksdGhpcy5faGFuZGxlSW5kZXg9bnVsbCx0aGlzLl9jbGlja09mZnNldD1udWxsLHRoaXMuX2FuaW1hdGVPZmY9ITEsITF9LF9kZXRlY3RPcmllbnRhdGlvbjpmdW5jdGlvbigpe3RoaXMub3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiPT09dGhpcy5vcHRpb25zLm9yaWVudGF0aW9uP1widmVydGljYWxcIjpcImhvcml6b250YWxcIn0sX25vcm1WYWx1ZUZyb21Nb3VzZTpmdW5jdGlvbihlKXt2YXIgdCxpLHMsbixhO3JldHVyblwiaG9yaXpvbnRhbFwiPT09dGhpcy5vcmllbnRhdGlvbj8odD10aGlzLmVsZW1lbnRTaXplLndpZHRoLGk9ZS54LXRoaXMuZWxlbWVudE9mZnNldC5sZWZ0LSh0aGlzLl9jbGlja09mZnNldD90aGlzLl9jbGlja09mZnNldC5sZWZ0OjApKToodD10aGlzLmVsZW1lbnRTaXplLmhlaWdodCxpPWUueS10aGlzLmVsZW1lbnRPZmZzZXQudG9wLSh0aGlzLl9jbGlja09mZnNldD90aGlzLl9jbGlja09mZnNldC50b3A6MCkpLHM9aS90LHM+MSYmKHM9MSksMD5zJiYocz0wKSxcInZlcnRpY2FsXCI9PT10aGlzLm9yaWVudGF0aW9uJiYocz0xLXMpLG49dGhpcy5fdmFsdWVNYXgoKS10aGlzLl92YWx1ZU1pbigpLGE9dGhpcy5fdmFsdWVNaW4oKStzKm4sdGhpcy5fdHJpbUFsaWduVmFsdWUoYSl9LF9zdGFydDpmdW5jdGlvbihlLHQpe3ZhciBpPXtoYW5kbGU6dGhpcy5oYW5kbGVzW3RdLHZhbHVlOnRoaXMudmFsdWUoKX07cmV0dXJuIHRoaXMub3B0aW9ucy52YWx1ZXMmJnRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoJiYoaS52YWx1ZT10aGlzLnZhbHVlcyh0KSxpLnZhbHVlcz10aGlzLnZhbHVlcygpKSx0aGlzLl90cmlnZ2VyKFwic3RhcnRcIixlLGkpfSxfc2xpZGU6ZnVuY3Rpb24oZSx0LGkpe3ZhciBzLG4sYTt0aGlzLm9wdGlvbnMudmFsdWVzJiZ0aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aD8ocz10aGlzLnZhbHVlcyh0PzA6MSksMj09PXRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoJiZ0aGlzLm9wdGlvbnMucmFuZ2U9PT0hMCYmKDA9PT10JiZpPnN8fDE9PT10JiZzPmkpJiYoaT1zKSxpIT09dGhpcy52YWx1ZXModCkmJihuPXRoaXMudmFsdWVzKCksblt0XT1pLGE9dGhpcy5fdHJpZ2dlcihcInNsaWRlXCIsZSx7aGFuZGxlOnRoaXMuaGFuZGxlc1t0XSx2YWx1ZTppLHZhbHVlczpufSkscz10aGlzLnZhbHVlcyh0PzA6MSksYSE9PSExJiZ0aGlzLnZhbHVlcyh0LGkpKSk6aSE9PXRoaXMudmFsdWUoKSYmKGE9dGhpcy5fdHJpZ2dlcihcInNsaWRlXCIsZSx7aGFuZGxlOnRoaXMuaGFuZGxlc1t0XSx2YWx1ZTppfSksYSE9PSExJiZ0aGlzLnZhbHVlKGkpKX0sX3N0b3A6ZnVuY3Rpb24oZSx0KXt2YXIgaT17aGFuZGxlOnRoaXMuaGFuZGxlc1t0XSx2YWx1ZTp0aGlzLnZhbHVlKCl9O3RoaXMub3B0aW9ucy52YWx1ZXMmJnRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoJiYoaS52YWx1ZT10aGlzLnZhbHVlcyh0KSxpLnZhbHVlcz10aGlzLnZhbHVlcygpKSx0aGlzLl90cmlnZ2VyKFwic3RvcFwiLGUsaSl9LF9jaGFuZ2U6ZnVuY3Rpb24oZSx0KXtpZighdGhpcy5fa2V5U2xpZGluZyYmIXRoaXMuX21vdXNlU2xpZGluZyl7dmFyIGk9e2hhbmRsZTp0aGlzLmhhbmRsZXNbdF0sdmFsdWU6dGhpcy52YWx1ZSgpfTt0aGlzLm9wdGlvbnMudmFsdWVzJiZ0aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aCYmKGkudmFsdWU9dGhpcy52YWx1ZXModCksaS52YWx1ZXM9dGhpcy52YWx1ZXMoKSksdGhpcy5fbGFzdENoYW5nZWRWYWx1ZT10LHRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIixlLGkpfX0sdmFsdWU6ZnVuY3Rpb24oZSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl90cmltQWxpZ25WYWx1ZShlKSx0aGlzLl9yZWZyZXNoVmFsdWUoKSx0aGlzLl9jaGFuZ2UobnVsbCwwKSx2b2lkIDApOnRoaXMuX3ZhbHVlKCl9LHZhbHVlczpmdW5jdGlvbih0LGkpe3ZhciBzLG4sYTtpZihhcmd1bWVudHMubGVuZ3RoPjEpcmV0dXJuIHRoaXMub3B0aW9ucy52YWx1ZXNbdF09dGhpcy5fdHJpbUFsaWduVmFsdWUoaSksdGhpcy5fcmVmcmVzaFZhbHVlKCksdGhpcy5fY2hhbmdlKG51bGwsdCksdm9pZCAwO2lmKCFhcmd1bWVudHMubGVuZ3RoKXJldHVybiB0aGlzLl92YWx1ZXMoKTtpZighZS5pc0FycmF5KGFyZ3VtZW50c1swXSkpcmV0dXJuIHRoaXMub3B0aW9ucy52YWx1ZXMmJnRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoP3RoaXMuX3ZhbHVlcyh0KTp0aGlzLnZhbHVlKCk7Zm9yKHM9dGhpcy5vcHRpb25zLnZhbHVlcyxuPWFyZ3VtZW50c1swXSxhPTA7cy5sZW5ndGg+YTthKz0xKXNbYV09dGhpcy5fdHJpbUFsaWduVmFsdWUoblthXSksdGhpcy5fY2hhbmdlKG51bGwsYSk7dGhpcy5fcmVmcmVzaFZhbHVlKCl9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxpKXt2YXIgcyxuPTA7c3dpdGNoKFwicmFuZ2VcIj09PXQmJnRoaXMub3B0aW9ucy5yYW5nZT09PSEwJiYoXCJtaW5cIj09PWk/KHRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl92YWx1ZXMoMCksdGhpcy5vcHRpb25zLnZhbHVlcz1udWxsKTpcIm1heFwiPT09aSYmKHRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl92YWx1ZXModGhpcy5vcHRpb25zLnZhbHVlcy5sZW5ndGgtMSksdGhpcy5vcHRpb25zLnZhbHVlcz1udWxsKSksZS5pc0FycmF5KHRoaXMub3B0aW9ucy52YWx1ZXMpJiYobj10aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aCksXCJkaXNhYmxlZFwiPT09dCYmdGhpcy5lbGVtZW50LnRvZ2dsZUNsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIWkpLHRoaXMuX3N1cGVyKHQsaSksdCl7Y2FzZVwib3JpZW50YXRpb25cIjp0aGlzLl9kZXRlY3RPcmllbnRhdGlvbigpLHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXNsaWRlci1ob3Jpem9udGFsIHVpLXNsaWRlci12ZXJ0aWNhbFwiKS5hZGRDbGFzcyhcInVpLXNsaWRlci1cIit0aGlzLm9yaWVudGF0aW9uKSx0aGlzLl9yZWZyZXNoVmFsdWUoKSx0aGlzLmhhbmRsZXMuY3NzKFwiaG9yaXpvbnRhbFwiPT09aT9cImJvdHRvbVwiOlwibGVmdFwiLFwiXCIpO2JyZWFrO2Nhc2VcInZhbHVlXCI6dGhpcy5fYW5pbWF0ZU9mZj0hMCx0aGlzLl9yZWZyZXNoVmFsdWUoKSx0aGlzLl9jaGFuZ2UobnVsbCwwKSx0aGlzLl9hbmltYXRlT2ZmPSExO2JyZWFrO2Nhc2VcInZhbHVlc1wiOmZvcih0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX3JlZnJlc2hWYWx1ZSgpLHM9MDtuPnM7cys9MSl0aGlzLl9jaGFuZ2UobnVsbCxzKTt0aGlzLl9hbmltYXRlT2ZmPSExO2JyZWFrO2Nhc2VcInN0ZXBcIjpjYXNlXCJtaW5cIjpjYXNlXCJtYXhcIjp0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX2NhbGN1bGF0ZU5ld01heCgpLHRoaXMuX3JlZnJlc2hWYWx1ZSgpLHRoaXMuX2FuaW1hdGVPZmY9ITE7YnJlYWs7Y2FzZVwicmFuZ2VcIjp0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX3JlZnJlc2goKSx0aGlzLl9hbmltYXRlT2ZmPSExfX0sX3ZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcHRpb25zLnZhbHVlO3JldHVybiBlPXRoaXMuX3RyaW1BbGlnblZhbHVlKGUpfSxfdmFsdWVzOmZ1bmN0aW9uKGUpe3ZhciB0LGkscztpZihhcmd1bWVudHMubGVuZ3RoKXJldHVybiB0PXRoaXMub3B0aW9ucy52YWx1ZXNbZV0sdD10aGlzLl90cmltQWxpZ25WYWx1ZSh0KTtpZih0aGlzLm9wdGlvbnMudmFsdWVzJiZ0aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aCl7Zm9yKGk9dGhpcy5vcHRpb25zLnZhbHVlcy5zbGljZSgpLHM9MDtpLmxlbmd0aD5zO3MrPTEpaVtzXT10aGlzLl90cmltQWxpZ25WYWx1ZShpW3NdKTtyZXR1cm4gaX1yZXR1cm5bXX0sX3RyaW1BbGlnblZhbHVlOmZ1bmN0aW9uKGUpe2lmKHRoaXMuX3ZhbHVlTWluKCk+PWUpcmV0dXJuIHRoaXMuX3ZhbHVlTWluKCk7aWYoZT49dGhpcy5fdmFsdWVNYXgoKSlyZXR1cm4gdGhpcy5fdmFsdWVNYXgoKTt2YXIgdD10aGlzLm9wdGlvbnMuc3RlcD4wP3RoaXMub3B0aW9ucy5zdGVwOjEsaT0oZS10aGlzLl92YWx1ZU1pbigpKSV0LHM9ZS1pO3JldHVybiAyKk1hdGguYWJzKGkpPj10JiYocys9aT4wP3Q6LXQpLHBhcnNlRmxvYXQocy50b0ZpeGVkKDUpKX0sX2NhbGN1bGF0ZU5ld01heDpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9ucy5tYXgsdD10aGlzLl92YWx1ZU1pbigpLGk9dGhpcy5vcHRpb25zLnN0ZXAscz1NYXRoLmZsb29yKCsoZS10KS50b0ZpeGVkKHRoaXMuX3ByZWNpc2lvbigpKS9pKSppO2U9cyt0LHRoaXMubWF4PXBhcnNlRmxvYXQoZS50b0ZpeGVkKHRoaXMuX3ByZWNpc2lvbigpKSl9LF9wcmVjaXNpb246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLl9wcmVjaXNpb25PZih0aGlzLm9wdGlvbnMuc3RlcCk7cmV0dXJuIG51bGwhPT10aGlzLm9wdGlvbnMubWluJiYoZT1NYXRoLm1heChlLHRoaXMuX3ByZWNpc2lvbk9mKHRoaXMub3B0aW9ucy5taW4pKSksZX0sX3ByZWNpc2lvbk9mOmZ1bmN0aW9uKGUpe3ZhciB0PVwiXCIrZSxpPXQuaW5kZXhPZihcIi5cIik7cmV0dXJuLTE9PT1pPzA6dC5sZW5ndGgtaS0xfSxfdmFsdWVNaW46ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcHRpb25zLm1pbn0sX3ZhbHVlTWF4OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWF4fSxfcmVmcmVzaFZhbHVlOmZ1bmN0aW9uKCl7dmFyIHQsaSxzLG4sYSxvPXRoaXMub3B0aW9ucy5yYW5nZSxyPXRoaXMub3B0aW9ucyxoPXRoaXMsbD10aGlzLl9hbmltYXRlT2ZmPyExOnIuYW5pbWF0ZSx1PXt9O3RoaXMub3B0aW9ucy52YWx1ZXMmJnRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoP3RoaXMuaGFuZGxlcy5lYWNoKGZ1bmN0aW9uKHMpe2k9MTAwKigoaC52YWx1ZXMocyktaC5fdmFsdWVNaW4oKSkvKGguX3ZhbHVlTWF4KCktaC5fdmFsdWVNaW4oKSkpLHVbXCJob3Jpem9udGFsXCI9PT1oLm9yaWVudGF0aW9uP1wibGVmdFwiOlwiYm90dG9tXCJdPWkrXCIlXCIsZSh0aGlzKS5zdG9wKDEsMSlbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh1LHIuYW5pbWF0ZSksaC5vcHRpb25zLnJhbmdlPT09ITAmJihcImhvcml6b250YWxcIj09PWgub3JpZW50YXRpb24/KDA9PT1zJiZoLnJhbmdlLnN0b3AoMSwxKVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHtsZWZ0OmkrXCIlXCJ9LHIuYW5pbWF0ZSksMT09PXMmJmgucmFuZ2VbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7d2lkdGg6aS10K1wiJVwifSx7cXVldWU6ITEsZHVyYXRpb246ci5hbmltYXRlfSkpOigwPT09cyYmaC5yYW5nZS5zdG9wKDEsMSlbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7Ym90dG9tOmkrXCIlXCJ9LHIuYW5pbWF0ZSksMT09PXMmJmgucmFuZ2VbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7aGVpZ2h0OmktdCtcIiVcIn0se3F1ZXVlOiExLGR1cmF0aW9uOnIuYW5pbWF0ZX0pKSksdD1pfSk6KHM9dGhpcy52YWx1ZSgpLG49dGhpcy5fdmFsdWVNaW4oKSxhPXRoaXMuX3ZhbHVlTWF4KCksaT1hIT09bj8xMDAqKChzLW4pLyhhLW4pKTowLHVbXCJob3Jpem9udGFsXCI9PT10aGlzLm9yaWVudGF0aW9uP1wibGVmdFwiOlwiYm90dG9tXCJdPWkrXCIlXCIsdGhpcy5oYW5kbGUuc3RvcCgxLDEpW2w/XCJhbmltYXRlXCI6XCJjc3NcIl0odSxyLmFuaW1hdGUpLFwibWluXCI9PT1vJiZcImhvcml6b250YWxcIj09PXRoaXMub3JpZW50YXRpb24mJnRoaXMucmFuZ2Uuc3RvcCgxLDEpW2w/XCJhbmltYXRlXCI6XCJjc3NcIl0oe3dpZHRoOmkrXCIlXCJ9LHIuYW5pbWF0ZSksXCJtYXhcIj09PW8mJlwiaG9yaXpvbnRhbFwiPT09dGhpcy5vcmllbnRhdGlvbiYmdGhpcy5yYW5nZVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHt3aWR0aDoxMDAtaStcIiVcIn0se3F1ZXVlOiExLGR1cmF0aW9uOnIuYW5pbWF0ZX0pLFwibWluXCI9PT1vJiZcInZlcnRpY2FsXCI9PT10aGlzLm9yaWVudGF0aW9uJiZ0aGlzLnJhbmdlLnN0b3AoMSwxKVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHtoZWlnaHQ6aStcIiVcIn0sci5hbmltYXRlKSxcIm1heFwiPT09byYmXCJ2ZXJ0aWNhbFwiPT09dGhpcy5vcmllbnRhdGlvbiYmdGhpcy5yYW5nZVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHtoZWlnaHQ6MTAwLWkrXCIlXCJ9LHtxdWV1ZTohMSxkdXJhdGlvbjpyLmFuaW1hdGV9KSl9LF9oYW5kbGVFdmVudHM6e2tleWRvd246ZnVuY3Rpb24odCl7dmFyIGkscyxuLGEsbz1lKHQudGFyZ2V0KS5kYXRhKFwidWktc2xpZGVyLWhhbmRsZS1pbmRleFwiKTtzd2l0Y2godC5rZXlDb2RlKXtjYXNlIGUudWkua2V5Q29kZS5IT01FOmNhc2UgZS51aS5rZXlDb2RlLkVORDpjYXNlIGUudWkua2V5Q29kZS5QQUdFX1VQOmNhc2UgZS51aS5rZXlDb2RlLlBBR0VfRE9XTjpjYXNlIGUudWkua2V5Q29kZS5VUDpjYXNlIGUudWkua2V5Q29kZS5SSUdIVDpjYXNlIGUudWkua2V5Q29kZS5ET1dOOmNhc2UgZS51aS5rZXlDb2RlLkxFRlQ6aWYodC5wcmV2ZW50RGVmYXVsdCgpLCF0aGlzLl9rZXlTbGlkaW5nJiYodGhpcy5fa2V5U2xpZGluZz0hMCxlKHQudGFyZ2V0KS5hZGRDbGFzcyhcInVpLXN0YXRlLWFjdGl2ZVwiKSxpPXRoaXMuX3N0YXJ0KHQsbyksaT09PSExKSlyZXR1cm59c3dpdGNoKGE9dGhpcy5vcHRpb25zLnN0ZXAscz1uPXRoaXMub3B0aW9ucy52YWx1ZXMmJnRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoP3RoaXMudmFsdWVzKG8pOnRoaXMudmFsdWUoKSx0LmtleUNvZGUpe2Nhc2UgZS51aS5rZXlDb2RlLkhPTUU6bj10aGlzLl92YWx1ZU1pbigpO2JyZWFrO2Nhc2UgZS51aS5rZXlDb2RlLkVORDpuPXRoaXMuX3ZhbHVlTWF4KCk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuUEFHRV9VUDpuPXRoaXMuX3RyaW1BbGlnblZhbHVlKHMrKHRoaXMuX3ZhbHVlTWF4KCktdGhpcy5fdmFsdWVNaW4oKSkvdGhpcy5udW1QYWdlcyk7YnJlYWs7Y2FzZSBlLnVpLmtleUNvZGUuUEFHRV9ET1dOOm49dGhpcy5fdHJpbUFsaWduVmFsdWUocy0odGhpcy5fdmFsdWVNYXgoKS10aGlzLl92YWx1ZU1pbigpKS90aGlzLm51bVBhZ2VzKTticmVhaztjYXNlIGUudWkua2V5Q29kZS5VUDpjYXNlIGUudWkua2V5Q29kZS5SSUdIVDppZihzPT09dGhpcy5fdmFsdWVNYXgoKSlyZXR1cm47bj10aGlzLl90cmltQWxpZ25WYWx1ZShzK2EpO2JyZWFrO2Nhc2UgZS51aS5rZXlDb2RlLkRPV046Y2FzZSBlLnVpLmtleUNvZGUuTEVGVDppZihzPT09dGhpcy5fdmFsdWVNaW4oKSlyZXR1cm47bj10aGlzLl90cmltQWxpZ25WYWx1ZShzLWEpfXRoaXMuX3NsaWRlKHQsbyxuKX0sa2V5dXA6ZnVuY3Rpb24odCl7dmFyIGk9ZSh0LnRhcmdldCkuZGF0YShcInVpLXNsaWRlci1oYW5kbGUtaW5kZXhcIik7dGhpcy5fa2V5U2xpZGluZyYmKHRoaXMuX2tleVNsaWRpbmc9ITEsdGhpcy5fc3RvcCh0LGkpLHRoaXMuX2NoYW5nZSh0LGkpLGUodC50YXJnZXQpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtYWN0aXZlXCIpKX19fSksZS53aWRnZXQoXCJ1aS5zb3J0YWJsZVwiLGUudWkubW91c2Use3ZlcnNpb246XCIxLjExLjRcIix3aWRnZXRFdmVudFByZWZpeDpcInNvcnRcIixyZWFkeTohMSxvcHRpb25zOnthcHBlbmRUbzpcInBhcmVudFwiLGF4aXM6ITEsY29ubmVjdFdpdGg6ITEsY29udGFpbm1lbnQ6ITEsY3Vyc29yOlwiYXV0b1wiLGN1cnNvckF0OiExLGRyb3BPbkVtcHR5OiEwLGZvcmNlUGxhY2Vob2xkZXJTaXplOiExLGZvcmNlSGVscGVyU2l6ZTohMSxncmlkOiExLGhhbmRsZTohMSxoZWxwZXI6XCJvcmlnaW5hbFwiLGl0ZW1zOlwiPiAqXCIsb3BhY2l0eTohMSxwbGFjZWhvbGRlcjohMSxyZXZlcnQ6ITEsc2Nyb2xsOiEwLHNjcm9sbFNlbnNpdGl2aXR5OjIwLHNjcm9sbFNwZWVkOjIwLHNjb3BlOlwiZGVmYXVsdFwiLHRvbGVyYW5jZTpcImludGVyc2VjdFwiLHpJbmRleDoxZTMsYWN0aXZhdGU6bnVsbCxiZWZvcmVTdG9wOm51bGwsY2hhbmdlOm51bGwsZGVhY3RpdmF0ZTpudWxsLG91dDpudWxsLG92ZXI6bnVsbCxyZWNlaXZlOm51bGwscmVtb3ZlOm51bGwsc29ydDpudWxsLHN0YXJ0Om51bGwsc3RvcDpudWxsLHVwZGF0ZTpudWxsfSxfaXNPdmVyQXhpczpmdW5jdGlvbihlLHQsaSl7cmV0dXJuIGU+PXQmJnQraT5lfSxfaXNGbG9hdGluZzpmdW5jdGlvbihlKXtyZXR1cm4vbGVmdHxyaWdodC8udGVzdChlLmNzcyhcImZsb2F0XCIpKXx8L2lubGluZXx0YWJsZS1jZWxsLy50ZXN0KGUuY3NzKFwiZGlzcGxheVwiKSl9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLmNvbnRhaW5lckNhY2hlPXt9LHRoaXMuZWxlbWVudC5hZGRDbGFzcyhcInVpLXNvcnRhYmxlXCIpLHRoaXMucmVmcmVzaCgpLHRoaXMub2Zmc2V0PXRoaXMuZWxlbWVudC5vZmZzZXQoKSx0aGlzLl9tb3VzZUluaXQoKSx0aGlzLl9zZXRIYW5kbGVDbGFzc05hbWUoKSx0aGlzLnJlYWR5PSEwfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsdCl7dGhpcy5fc3VwZXIoZSx0KSxcImhhbmRsZVwiPT09ZSYmdGhpcy5fc2V0SGFuZGxlQ2xhc3NOYW1lKCl9LF9zZXRIYW5kbGVDbGFzc05hbWU6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQuZmluZChcIi51aS1zb3J0YWJsZS1oYW5kbGVcIikucmVtb3ZlQ2xhc3MoXCJ1aS1zb3J0YWJsZS1oYW5kbGVcIiksZS5lYWNoKHRoaXMuaXRlbXMsZnVuY3Rpb24oKXsodGhpcy5pbnN0YW5jZS5vcHRpb25zLmhhbmRsZT90aGlzLml0ZW0uZmluZCh0aGlzLmluc3RhbmNlLm9wdGlvbnMuaGFuZGxlKTp0aGlzLml0ZW0pLmFkZENsYXNzKFwidWktc29ydGFibGUtaGFuZGxlXCIpfSl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKFwidWktc29ydGFibGUgdWktc29ydGFibGUtZGlzYWJsZWRcIikuZmluZChcIi51aS1zb3J0YWJsZS1oYW5kbGVcIikucmVtb3ZlQ2xhc3MoXCJ1aS1zb3J0YWJsZS1oYW5kbGVcIiksdGhpcy5fbW91c2VEZXN0cm95KCk7Zm9yKHZhciBlPXRoaXMuaXRlbXMubGVuZ3RoLTE7ZT49MDtlLS0pdGhpcy5pdGVtc1tlXS5pdGVtLnJlbW92ZURhdGEodGhpcy53aWRnZXROYW1lK1wiLWl0ZW1cIik7cmV0dXJuIHRoaXN9LF9tb3VzZUNhcHR1cmU6ZnVuY3Rpb24odCxpKXt2YXIgcz1udWxsLG49ITEsYT10aGlzO3JldHVybiB0aGlzLnJldmVydGluZz8hMTp0aGlzLm9wdGlvbnMuZGlzYWJsZWR8fFwic3RhdGljXCI9PT10aGlzLm9wdGlvbnMudHlwZT8hMToodGhpcy5fcmVmcmVzaEl0ZW1zKHQpLGUodC50YXJnZXQpLnBhcmVudHMoKS5lYWNoKGZ1bmN0aW9uKCl7cmV0dXJuIGUuZGF0YSh0aGlzLGEud2lkZ2V0TmFtZStcIi1pdGVtXCIpPT09YT8ocz1lKHRoaXMpLCExKTp2b2lkIDB9KSxlLmRhdGEodC50YXJnZXQsYS53aWRnZXROYW1lK1wiLWl0ZW1cIik9PT1hJiYocz1lKHQudGFyZ2V0KSkscz8hdGhpcy5vcHRpb25zLmhhbmRsZXx8aXx8KGUodGhpcy5vcHRpb25zLmhhbmRsZSxzKS5maW5kKFwiKlwiKS5hZGRCYWNrKCkuZWFjaChmdW5jdGlvbigpe3RoaXM9PT10LnRhcmdldCYmKG49ITApfSksbik/KHRoaXMuY3VycmVudEl0ZW09cyx0aGlzLl9yZW1vdmVDdXJyZW50c0Zyb21JdGVtcygpLCEwKTohMTohMSl9LF9tb3VzZVN0YXJ0OmZ1bmN0aW9uKHQsaSxzKXt2YXIgbixhLG89dGhpcy5vcHRpb25zO2lmKHRoaXMuY3VycmVudENvbnRhaW5lcj10aGlzLHRoaXMucmVmcmVzaFBvc2l0aW9ucygpLHRoaXMuaGVscGVyPXRoaXMuX2NyZWF0ZUhlbHBlcih0KSx0aGlzLl9jYWNoZUhlbHBlclByb3BvcnRpb25zKCksdGhpcy5fY2FjaGVNYXJnaW5zKCksdGhpcy5zY3JvbGxQYXJlbnQ9dGhpcy5oZWxwZXIuc2Nyb2xsUGFyZW50KCksdGhpcy5vZmZzZXQ9dGhpcy5jdXJyZW50SXRlbS5vZmZzZXQoKSx0aGlzLm9mZnNldD17dG9wOnRoaXMub2Zmc2V0LnRvcC10aGlzLm1hcmdpbnMudG9wLGxlZnQ6dGhpcy5vZmZzZXQubGVmdC10aGlzLm1hcmdpbnMubGVmdH0sZS5leHRlbmQodGhpcy5vZmZzZXQse2NsaWNrOntsZWZ0OnQucGFnZVgtdGhpcy5vZmZzZXQubGVmdCx0b3A6dC5wYWdlWS10aGlzLm9mZnNldC50b3B9LHBhcmVudDp0aGlzLl9nZXRQYXJlbnRPZmZzZXQoKSxyZWxhdGl2ZTp0aGlzLl9nZXRSZWxhdGl2ZU9mZnNldCgpfSksdGhpcy5oZWxwZXIuY3NzKFwicG9zaXRpb25cIixcImFic29sdXRlXCIpLHRoaXMuY3NzUG9zaXRpb249dGhpcy5oZWxwZXIuY3NzKFwicG9zaXRpb25cIiksdGhpcy5vcmlnaW5hbFBvc2l0aW9uPXRoaXMuX2dlbmVyYXRlUG9zaXRpb24odCksdGhpcy5vcmlnaW5hbFBhZ2VYPXQucGFnZVgsdGhpcy5vcmlnaW5hbFBhZ2VZPXQucGFnZVksby5jdXJzb3JBdCYmdGhpcy5fYWRqdXN0T2Zmc2V0RnJvbUhlbHBlcihvLmN1cnNvckF0KSx0aGlzLmRvbVBvc2l0aW9uPXtwcmV2OnRoaXMuY3VycmVudEl0ZW0ucHJldigpWzBdLHBhcmVudDp0aGlzLmN1cnJlbnRJdGVtLnBhcmVudCgpWzBdfSx0aGlzLmhlbHBlclswXSE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJnRoaXMuY3VycmVudEl0ZW0uaGlkZSgpLHRoaXMuX2NyZWF0ZVBsYWNlaG9sZGVyKCksby5jb250YWlubWVudCYmdGhpcy5fc2V0Q29udGFpbm1lbnQoKSxvLmN1cnNvciYmXCJhdXRvXCIhPT1vLmN1cnNvciYmKGE9dGhpcy5kb2N1bWVudC5maW5kKFwiYm9keVwiKSx0aGlzLnN0b3JlZEN1cnNvcj1hLmNzcyhcImN1cnNvclwiKSxhLmNzcyhcImN1cnNvclwiLG8uY3Vyc29yKSx0aGlzLnN0b3JlZFN0eWxlc2hlZXQ9ZShcIjxzdHlsZT4qeyBjdXJzb3I6IFwiK28uY3Vyc29yK1wiICFpbXBvcnRhbnQ7IH08L3N0eWxlPlwiKS5hcHBlbmRUbyhhKSksby5vcGFjaXR5JiYodGhpcy5oZWxwZXIuY3NzKFwib3BhY2l0eVwiKSYmKHRoaXMuX3N0b3JlZE9wYWNpdHk9dGhpcy5oZWxwZXIuY3NzKFwib3BhY2l0eVwiKSksdGhpcy5oZWxwZXIuY3NzKFwib3BhY2l0eVwiLG8ub3BhY2l0eSkpLG8uekluZGV4JiYodGhpcy5oZWxwZXIuY3NzKFwiekluZGV4XCIpJiYodGhpcy5fc3RvcmVkWkluZGV4PXRoaXMuaGVscGVyLmNzcyhcInpJbmRleFwiKSksdGhpcy5oZWxwZXIuY3NzKFwiekluZGV4XCIsby56SW5kZXgpKSx0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMuZG9jdW1lbnRbMF0mJlwiSFRNTFwiIT09dGhpcy5zY3JvbGxQYXJlbnRbMF0udGFnTmFtZSYmKHRoaXMub3ZlcmZsb3dPZmZzZXQ9dGhpcy5zY3JvbGxQYXJlbnQub2Zmc2V0KCkpLHRoaXMuX3RyaWdnZXIoXCJzdGFydFwiLHQsdGhpcy5fdWlIYXNoKCkpLHRoaXMuX3ByZXNlcnZlSGVscGVyUHJvcG9ydGlvbnN8fHRoaXMuX2NhY2hlSGVscGVyUHJvcG9ydGlvbnMoKSwhcylmb3Iobj10aGlzLmNvbnRhaW5lcnMubGVuZ3RoLTE7bj49MDtuLS0pdGhpcy5jb250YWluZXJzW25dLl90cmlnZ2VyKFwiYWN0aXZhdGVcIix0LHRoaXMuX3VpSGFzaCh0aGlzKSk7XHJcbnJldHVybiBlLnVpLmRkbWFuYWdlciYmKGUudWkuZGRtYW5hZ2VyLmN1cnJlbnQ9dGhpcyksZS51aS5kZG1hbmFnZXImJiFvLmRyb3BCZWhhdmlvdXImJmUudWkuZGRtYW5hZ2VyLnByZXBhcmVPZmZzZXRzKHRoaXMsdCksdGhpcy5kcmFnZ2luZz0hMCx0aGlzLmhlbHBlci5hZGRDbGFzcyhcInVpLXNvcnRhYmxlLWhlbHBlclwiKSx0aGlzLl9tb3VzZURyYWcodCksITB9LF9tb3VzZURyYWc6ZnVuY3Rpb24odCl7dmFyIGkscyxuLGEsbz10aGlzLm9wdGlvbnMscj0hMTtmb3IodGhpcy5wb3NpdGlvbj10aGlzLl9nZW5lcmF0ZVBvc2l0aW9uKHQpLHRoaXMucG9zaXRpb25BYnM9dGhpcy5fY29udmVydFBvc2l0aW9uVG8oXCJhYnNvbHV0ZVwiKSx0aGlzLmxhc3RQb3NpdGlvbkFic3x8KHRoaXMubGFzdFBvc2l0aW9uQWJzPXRoaXMucG9zaXRpb25BYnMpLHRoaXMub3B0aW9ucy5zY3JvbGwmJih0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMuZG9jdW1lbnRbMF0mJlwiSFRNTFwiIT09dGhpcy5zY3JvbGxQYXJlbnRbMF0udGFnTmFtZT8odGhpcy5vdmVyZmxvd09mZnNldC50b3ArdGhpcy5zY3JvbGxQYXJlbnRbMF0ub2Zmc2V0SGVpZ2h0LXQucGFnZVk8by5zY3JvbGxTZW5zaXRpdml0eT90aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3A9cj10aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3Arby5zY3JvbGxTcGVlZDp0LnBhZ2VZLXRoaXMub3ZlcmZsb3dPZmZzZXQudG9wPG8uc2Nyb2xsU2Vuc2l0aXZpdHkmJih0aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3A9cj10aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3Atby5zY3JvbGxTcGVlZCksdGhpcy5vdmVyZmxvd09mZnNldC5sZWZ0K3RoaXMuc2Nyb2xsUGFyZW50WzBdLm9mZnNldFdpZHRoLXQucGFnZVg8by5zY3JvbGxTZW5zaXRpdml0eT90aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxMZWZ0PXI9dGhpcy5zY3JvbGxQYXJlbnRbMF0uc2Nyb2xsTGVmdCtvLnNjcm9sbFNwZWVkOnQucGFnZVgtdGhpcy5vdmVyZmxvd09mZnNldC5sZWZ0PG8uc2Nyb2xsU2Vuc2l0aXZpdHkmJih0aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxMZWZ0PXI9dGhpcy5zY3JvbGxQYXJlbnRbMF0uc2Nyb2xsTGVmdC1vLnNjcm9sbFNwZWVkKSk6KHQucGFnZVktdGhpcy5kb2N1bWVudC5zY3JvbGxUb3AoKTxvLnNjcm9sbFNlbnNpdGl2aXR5P3I9dGhpcy5kb2N1bWVudC5zY3JvbGxUb3AodGhpcy5kb2N1bWVudC5zY3JvbGxUb3AoKS1vLnNjcm9sbFNwZWVkKTp0aGlzLndpbmRvdy5oZWlnaHQoKS0odC5wYWdlWS10aGlzLmRvY3VtZW50LnNjcm9sbFRvcCgpKTxvLnNjcm9sbFNlbnNpdGl2aXR5JiYocj10aGlzLmRvY3VtZW50LnNjcm9sbFRvcCh0aGlzLmRvY3VtZW50LnNjcm9sbFRvcCgpK28uc2Nyb2xsU3BlZWQpKSx0LnBhZ2VYLXRoaXMuZG9jdW1lbnQuc2Nyb2xsTGVmdCgpPG8uc2Nyb2xsU2Vuc2l0aXZpdHk/cj10aGlzLmRvY3VtZW50LnNjcm9sbExlZnQodGhpcy5kb2N1bWVudC5zY3JvbGxMZWZ0KCktby5zY3JvbGxTcGVlZCk6dGhpcy53aW5kb3cud2lkdGgoKS0odC5wYWdlWC10aGlzLmRvY3VtZW50LnNjcm9sbExlZnQoKSk8by5zY3JvbGxTZW5zaXRpdml0eSYmKHI9dGhpcy5kb2N1bWVudC5zY3JvbGxMZWZ0KHRoaXMuZG9jdW1lbnQuc2Nyb2xsTGVmdCgpK28uc2Nyb2xsU3BlZWQpKSksciE9PSExJiZlLnVpLmRkbWFuYWdlciYmIW8uZHJvcEJlaGF2aW91ciYmZS51aS5kZG1hbmFnZXIucHJlcGFyZU9mZnNldHModGhpcyx0KSksdGhpcy5wb3NpdGlvbkFicz10aGlzLl9jb252ZXJ0UG9zaXRpb25UbyhcImFic29sdXRlXCIpLHRoaXMub3B0aW9ucy5heGlzJiZcInlcIj09PXRoaXMub3B0aW9ucy5heGlzfHwodGhpcy5oZWxwZXJbMF0uc3R5bGUubGVmdD10aGlzLnBvc2l0aW9uLmxlZnQrXCJweFwiKSx0aGlzLm9wdGlvbnMuYXhpcyYmXCJ4XCI9PT10aGlzLm9wdGlvbnMuYXhpc3x8KHRoaXMuaGVscGVyWzBdLnN0eWxlLnRvcD10aGlzLnBvc2l0aW9uLnRvcCtcInB4XCIpLGk9dGhpcy5pdGVtcy5sZW5ndGgtMTtpPj0wO2ktLSlpZihzPXRoaXMuaXRlbXNbaV0sbj1zLml0ZW1bMF0sYT10aGlzLl9pbnRlcnNlY3RzV2l0aFBvaW50ZXIocyksYSYmcy5pbnN0YW5jZT09PXRoaXMuY3VycmVudENvbnRhaW5lciYmbiE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJnRoaXMucGxhY2Vob2xkZXJbMT09PWE/XCJuZXh0XCI6XCJwcmV2XCJdKClbMF0hPT1uJiYhZS5jb250YWlucyh0aGlzLnBsYWNlaG9sZGVyWzBdLG4pJiYoXCJzZW1pLWR5bmFtaWNcIj09PXRoaXMub3B0aW9ucy50eXBlPyFlLmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSxuKTohMCkpe2lmKHRoaXMuZGlyZWN0aW9uPTE9PT1hP1wiZG93blwiOlwidXBcIixcInBvaW50ZXJcIiE9PXRoaXMub3B0aW9ucy50b2xlcmFuY2UmJiF0aGlzLl9pbnRlcnNlY3RzV2l0aFNpZGVzKHMpKWJyZWFrO3RoaXMuX3JlYXJyYW5nZSh0LHMpLHRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIix0LHRoaXMuX3VpSGFzaCgpKTticmVha31yZXR1cm4gdGhpcy5fY29udGFjdENvbnRhaW5lcnModCksZS51aS5kZG1hbmFnZXImJmUudWkuZGRtYW5hZ2VyLmRyYWcodGhpcyx0KSx0aGlzLl90cmlnZ2VyKFwic29ydFwiLHQsdGhpcy5fdWlIYXNoKCkpLHRoaXMubGFzdFBvc2l0aW9uQWJzPXRoaXMucG9zaXRpb25BYnMsITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24odCxpKXtpZih0KXtpZihlLnVpLmRkbWFuYWdlciYmIXRoaXMub3B0aW9ucy5kcm9wQmVoYXZpb3VyJiZlLnVpLmRkbWFuYWdlci5kcm9wKHRoaXMsdCksdGhpcy5vcHRpb25zLnJldmVydCl7dmFyIHM9dGhpcyxuPXRoaXMucGxhY2Vob2xkZXIub2Zmc2V0KCksYT10aGlzLm9wdGlvbnMuYXhpcyxvPXt9O2EmJlwieFwiIT09YXx8KG8ubGVmdD1uLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQtdGhpcy5tYXJnaW5zLmxlZnQrKHRoaXMub2Zmc2V0UGFyZW50WzBdPT09dGhpcy5kb2N1bWVudFswXS5ib2R5PzA6dGhpcy5vZmZzZXRQYXJlbnRbMF0uc2Nyb2xsTGVmdCkpLGEmJlwieVwiIT09YXx8KG8udG9wPW4udG9wLXRoaXMub2Zmc2V0LnBhcmVudC50b3AtdGhpcy5tYXJnaW5zLnRvcCsodGhpcy5vZmZzZXRQYXJlbnRbMF09PT10aGlzLmRvY3VtZW50WzBdLmJvZHk/MDp0aGlzLm9mZnNldFBhcmVudFswXS5zY3JvbGxUb3ApKSx0aGlzLnJldmVydGluZz0hMCxlKHRoaXMuaGVscGVyKS5hbmltYXRlKG8scGFyc2VJbnQodGhpcy5vcHRpb25zLnJldmVydCwxMCl8fDUwMCxmdW5jdGlvbigpe3MuX2NsZWFyKHQpfSl9ZWxzZSB0aGlzLl9jbGVhcih0LGkpO3JldHVybiExfX0sY2FuY2VsOmZ1bmN0aW9uKCl7aWYodGhpcy5kcmFnZ2luZyl7dGhpcy5fbW91c2VVcCh7dGFyZ2V0Om51bGx9KSxcIm9yaWdpbmFsXCI9PT10aGlzLm9wdGlvbnMuaGVscGVyP3RoaXMuY3VycmVudEl0ZW0uY3NzKHRoaXMuX3N0b3JlZENTUykucmVtb3ZlQ2xhc3MoXCJ1aS1zb3J0YWJsZS1oZWxwZXJcIik6dGhpcy5jdXJyZW50SXRlbS5zaG93KCk7Zm9yKHZhciB0PXRoaXMuY29udGFpbmVycy5sZW5ndGgtMTt0Pj0wO3QtLSl0aGlzLmNvbnRhaW5lcnNbdF0uX3RyaWdnZXIoXCJkZWFjdGl2YXRlXCIsbnVsbCx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY29udGFpbmVyc1t0XS5jb250YWluZXJDYWNoZS5vdmVyJiYodGhpcy5jb250YWluZXJzW3RdLl90cmlnZ2VyKFwib3V0XCIsbnVsbCx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY29udGFpbmVyc1t0XS5jb250YWluZXJDYWNoZS5vdmVyPTApfXJldHVybiB0aGlzLnBsYWNlaG9sZGVyJiYodGhpcy5wbGFjZWhvbGRlclswXS5wYXJlbnROb2RlJiZ0aGlzLnBsYWNlaG9sZGVyWzBdLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5wbGFjZWhvbGRlclswXSksXCJvcmlnaW5hbFwiIT09dGhpcy5vcHRpb25zLmhlbHBlciYmdGhpcy5oZWxwZXImJnRoaXMuaGVscGVyWzBdLnBhcmVudE5vZGUmJnRoaXMuaGVscGVyLnJlbW92ZSgpLGUuZXh0ZW5kKHRoaXMse2hlbHBlcjpudWxsLGRyYWdnaW5nOiExLHJldmVydGluZzohMSxfbm9GaW5hbFNvcnQ6bnVsbH0pLHRoaXMuZG9tUG9zaXRpb24ucHJldj9lKHRoaXMuZG9tUG9zaXRpb24ucHJldikuYWZ0ZXIodGhpcy5jdXJyZW50SXRlbSk6ZSh0aGlzLmRvbVBvc2l0aW9uLnBhcmVudCkucHJlcGVuZCh0aGlzLmN1cnJlbnRJdGVtKSksdGhpc30sc2VyaWFsaXplOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMuX2dldEl0ZW1zQXNqUXVlcnkodCYmdC5jb25uZWN0ZWQpLHM9W107cmV0dXJuIHQ9dHx8e30sZShpKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIGk9KGUodC5pdGVtfHx0aGlzKS5hdHRyKHQuYXR0cmlidXRlfHxcImlkXCIpfHxcIlwiKS5tYXRjaCh0LmV4cHJlc3Npb258fC8oLispW1xcLT1fXSguKykvKTtpJiZzLnB1c2goKHQua2V5fHxpWzFdK1wiW11cIikrXCI9XCIrKHQua2V5JiZ0LmV4cHJlc3Npb24/aVsxXTppWzJdKSl9KSwhcy5sZW5ndGgmJnQua2V5JiZzLnB1c2godC5rZXkrXCI9XCIpLHMuam9pbihcIiZcIil9LHRvQXJyYXk6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5fZ2V0SXRlbXNBc2pRdWVyeSh0JiZ0LmNvbm5lY3RlZCkscz1bXTtyZXR1cm4gdD10fHx7fSxpLmVhY2goZnVuY3Rpb24oKXtzLnB1c2goZSh0Lml0ZW18fHRoaXMpLmF0dHIodC5hdHRyaWJ1dGV8fFwiaWRcIil8fFwiXCIpfSksc30sX2ludGVyc2VjdHNXaXRoOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucG9zaXRpb25BYnMubGVmdCxpPXQrdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aCxzPXRoaXMucG9zaXRpb25BYnMudG9wLG49cyt0aGlzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodCxhPWUubGVmdCxvPWErZS53aWR0aCxyPWUudG9wLGg9citlLmhlaWdodCxsPXRoaXMub2Zmc2V0LmNsaWNrLnRvcCx1PXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQsZD1cInhcIj09PXRoaXMub3B0aW9ucy5heGlzfHxzK2w+ciYmaD5zK2wsYz1cInlcIj09PXRoaXMub3B0aW9ucy5heGlzfHx0K3U+YSYmbz50K3UscD1kJiZjO3JldHVyblwicG9pbnRlclwiPT09dGhpcy5vcHRpb25zLnRvbGVyYW5jZXx8dGhpcy5vcHRpb25zLmZvcmNlUG9pbnRlckZvckNvbnRhaW5lcnN8fFwicG9pbnRlclwiIT09dGhpcy5vcHRpb25zLnRvbGVyYW5jZSYmdGhpcy5oZWxwZXJQcm9wb3J0aW9uc1t0aGlzLmZsb2F0aW5nP1wid2lkdGhcIjpcImhlaWdodFwiXT5lW3RoaXMuZmxvYXRpbmc/XCJ3aWR0aFwiOlwiaGVpZ2h0XCJdP3A6dCt0aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLzI+YSYmbz5pLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgvMiYmcyt0aGlzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodC8yPnImJmg+bi10aGlzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodC8yfSxfaW50ZXJzZWN0c1dpdGhQb2ludGVyOmZ1bmN0aW9uKGUpe3ZhciB0PVwieFwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy50b3ArdGhpcy5vZmZzZXQuY2xpY2sudG9wLGUudG9wLGUuaGVpZ2h0KSxpPVwieVwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy5sZWZ0K3RoaXMub2Zmc2V0LmNsaWNrLmxlZnQsZS5sZWZ0LGUud2lkdGgpLHM9dCYmaSxuPXRoaXMuX2dldERyYWdWZXJ0aWNhbERpcmVjdGlvbigpLGE9dGhpcy5fZ2V0RHJhZ0hvcml6b250YWxEaXJlY3Rpb24oKTtyZXR1cm4gcz90aGlzLmZsb2F0aW5nP2EmJlwicmlnaHRcIj09PWF8fFwiZG93blwiPT09bj8yOjE6biYmKFwiZG93blwiPT09bj8yOjEpOiExfSxfaW50ZXJzZWN0c1dpdGhTaWRlczpmdW5jdGlvbihlKXt2YXIgdD10aGlzLl9pc092ZXJBeGlzKHRoaXMucG9zaXRpb25BYnMudG9wK3RoaXMub2Zmc2V0LmNsaWNrLnRvcCxlLnRvcCtlLmhlaWdodC8yLGUuaGVpZ2h0KSxpPXRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy5sZWZ0K3RoaXMub2Zmc2V0LmNsaWNrLmxlZnQsZS5sZWZ0K2Uud2lkdGgvMixlLndpZHRoKSxzPXRoaXMuX2dldERyYWdWZXJ0aWNhbERpcmVjdGlvbigpLG49dGhpcy5fZ2V0RHJhZ0hvcml6b250YWxEaXJlY3Rpb24oKTtyZXR1cm4gdGhpcy5mbG9hdGluZyYmbj9cInJpZ2h0XCI9PT1uJiZpfHxcImxlZnRcIj09PW4mJiFpOnMmJihcImRvd25cIj09PXMmJnR8fFwidXBcIj09PXMmJiF0KX0sX2dldERyYWdWZXJ0aWNhbERpcmVjdGlvbjpmdW5jdGlvbigpe3ZhciBlPXRoaXMucG9zaXRpb25BYnMudG9wLXRoaXMubGFzdFBvc2l0aW9uQWJzLnRvcDtyZXR1cm4gMCE9PWUmJihlPjA/XCJkb3duXCI6XCJ1cFwiKX0sX2dldERyYWdIb3Jpem9udGFsRGlyZWN0aW9uOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wb3NpdGlvbkFicy5sZWZ0LXRoaXMubGFzdFBvc2l0aW9uQWJzLmxlZnQ7cmV0dXJuIDAhPT1lJiYoZT4wP1wicmlnaHRcIjpcImxlZnRcIil9LHJlZnJlc2g6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuX3JlZnJlc2hJdGVtcyhlKSx0aGlzLl9zZXRIYW5kbGVDbGFzc05hbWUoKSx0aGlzLnJlZnJlc2hQb3NpdGlvbnMoKSx0aGlzfSxfY29ubmVjdFdpdGg6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9wdGlvbnM7cmV0dXJuIGUuY29ubmVjdFdpdGguY29uc3RydWN0b3I9PT1TdHJpbmc/W2UuY29ubmVjdFdpdGhdOmUuY29ubmVjdFdpdGh9LF9nZXRJdGVtc0FzalF1ZXJ5OmZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGkoKXtyLnB1c2godGhpcyl9dmFyIHMsbixhLG8scj1bXSxoPVtdLGw9dGhpcy5fY29ubmVjdFdpdGgoKTtpZihsJiZ0KWZvcihzPWwubGVuZ3RoLTE7cz49MDtzLS0pZm9yKGE9ZShsW3NdLHRoaXMuZG9jdW1lbnRbMF0pLG49YS5sZW5ndGgtMTtuPj0wO24tLSlvPWUuZGF0YShhW25dLHRoaXMud2lkZ2V0RnVsbE5hbWUpLG8mJm8hPT10aGlzJiYhby5vcHRpb25zLmRpc2FibGVkJiZoLnB1c2goW2UuaXNGdW5jdGlvbihvLm9wdGlvbnMuaXRlbXMpP28ub3B0aW9ucy5pdGVtcy5jYWxsKG8uZWxlbWVudCk6ZShvLm9wdGlvbnMuaXRlbXMsby5lbGVtZW50KS5ub3QoXCIudWktc29ydGFibGUtaGVscGVyXCIpLm5vdChcIi51aS1zb3J0YWJsZS1wbGFjZWhvbGRlclwiKSxvXSk7Zm9yKGgucHVzaChbZS5pc0Z1bmN0aW9uKHRoaXMub3B0aW9ucy5pdGVtcyk/dGhpcy5vcHRpb25zLml0ZW1zLmNhbGwodGhpcy5lbGVtZW50LG51bGwse29wdGlvbnM6dGhpcy5vcHRpb25zLGl0ZW06dGhpcy5jdXJyZW50SXRlbX0pOmUodGhpcy5vcHRpb25zLml0ZW1zLHRoaXMuZWxlbWVudCkubm90KFwiLnVpLXNvcnRhYmxlLWhlbHBlclwiKS5ub3QoXCIudWktc29ydGFibGUtcGxhY2Vob2xkZXJcIiksdGhpc10pLHM9aC5sZW5ndGgtMTtzPj0wO3MtLSloW3NdWzBdLmVhY2goaSk7cmV0dXJuIGUocil9LF9yZW1vdmVDdXJyZW50c0Zyb21JdGVtczpmdW5jdGlvbigpe3ZhciB0PXRoaXMuY3VycmVudEl0ZW0uZmluZChcIjpkYXRhKFwiK3RoaXMud2lkZ2V0TmFtZStcIi1pdGVtKVwiKTt0aGlzLml0ZW1zPWUuZ3JlcCh0aGlzLml0ZW1zLGZ1bmN0aW9uKGUpe2Zvcih2YXIgaT0wO3QubGVuZ3RoPmk7aSsrKWlmKHRbaV09PT1lLml0ZW1bMF0pcmV0dXJuITE7cmV0dXJuITB9KX0sX3JlZnJlc2hJdGVtczpmdW5jdGlvbih0KXt0aGlzLml0ZW1zPVtdLHRoaXMuY29udGFpbmVycz1bdGhpc107dmFyIGkscyxuLGEsbyxyLGgsbCx1PXRoaXMuaXRlbXMsZD1bW2UuaXNGdW5jdGlvbih0aGlzLm9wdGlvbnMuaXRlbXMpP3RoaXMub3B0aW9ucy5pdGVtcy5jYWxsKHRoaXMuZWxlbWVudFswXSx0LHtpdGVtOnRoaXMuY3VycmVudEl0ZW19KTplKHRoaXMub3B0aW9ucy5pdGVtcyx0aGlzLmVsZW1lbnQpLHRoaXNdXSxjPXRoaXMuX2Nvbm5lY3RXaXRoKCk7aWYoYyYmdGhpcy5yZWFkeSlmb3IoaT1jLmxlbmd0aC0xO2k+PTA7aS0tKWZvcihuPWUoY1tpXSx0aGlzLmRvY3VtZW50WzBdKSxzPW4ubGVuZ3RoLTE7cz49MDtzLS0pYT1lLmRhdGEobltzXSx0aGlzLndpZGdldEZ1bGxOYW1lKSxhJiZhIT09dGhpcyYmIWEub3B0aW9ucy5kaXNhYmxlZCYmKGQucHVzaChbZS5pc0Z1bmN0aW9uKGEub3B0aW9ucy5pdGVtcyk/YS5vcHRpb25zLml0ZW1zLmNhbGwoYS5lbGVtZW50WzBdLHQse2l0ZW06dGhpcy5jdXJyZW50SXRlbX0pOmUoYS5vcHRpb25zLml0ZW1zLGEuZWxlbWVudCksYV0pLHRoaXMuY29udGFpbmVycy5wdXNoKGEpKTtmb3IoaT1kLmxlbmd0aC0xO2k+PTA7aS0tKWZvcihvPWRbaV1bMV0scj1kW2ldWzBdLHM9MCxsPXIubGVuZ3RoO2w+cztzKyspaD1lKHJbc10pLGguZGF0YSh0aGlzLndpZGdldE5hbWUrXCItaXRlbVwiLG8pLHUucHVzaCh7aXRlbTpoLGluc3RhbmNlOm8sd2lkdGg6MCxoZWlnaHQ6MCxsZWZ0OjAsdG9wOjB9KX0scmVmcmVzaFBvc2l0aW9uczpmdW5jdGlvbih0KXt0aGlzLmZsb2F0aW5nPXRoaXMuaXRlbXMubGVuZ3RoP1wieFwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHRoaXMuX2lzRmxvYXRpbmcodGhpcy5pdGVtc1swXS5pdGVtKTohMSx0aGlzLm9mZnNldFBhcmVudCYmdGhpcy5oZWxwZXImJih0aGlzLm9mZnNldC5wYXJlbnQ9dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkpO3ZhciBpLHMsbixhO2ZvcihpPXRoaXMuaXRlbXMubGVuZ3RoLTE7aT49MDtpLS0pcz10aGlzLml0ZW1zW2ldLHMuaW5zdGFuY2UhPT10aGlzLmN1cnJlbnRDb250YWluZXImJnRoaXMuY3VycmVudENvbnRhaW5lciYmcy5pdGVtWzBdIT09dGhpcy5jdXJyZW50SXRlbVswXXx8KG49dGhpcy5vcHRpb25zLnRvbGVyYW5jZUVsZW1lbnQ/ZSh0aGlzLm9wdGlvbnMudG9sZXJhbmNlRWxlbWVudCxzLml0ZW0pOnMuaXRlbSx0fHwocy53aWR0aD1uLm91dGVyV2lkdGgoKSxzLmhlaWdodD1uLm91dGVySGVpZ2h0KCkpLGE9bi5vZmZzZXQoKSxzLmxlZnQ9YS5sZWZ0LHMudG9wPWEudG9wKTtpZih0aGlzLm9wdGlvbnMuY3VzdG9tJiZ0aGlzLm9wdGlvbnMuY3VzdG9tLnJlZnJlc2hDb250YWluZXJzKXRoaXMub3B0aW9ucy5jdXN0b20ucmVmcmVzaENvbnRhaW5lcnMuY2FsbCh0aGlzKTtlbHNlIGZvcihpPXRoaXMuY29udGFpbmVycy5sZW5ndGgtMTtpPj0wO2ktLSlhPXRoaXMuY29udGFpbmVyc1tpXS5lbGVtZW50Lm9mZnNldCgpLHRoaXMuY29udGFpbmVyc1tpXS5jb250YWluZXJDYWNoZS5sZWZ0PWEubGVmdCx0aGlzLmNvbnRhaW5lcnNbaV0uY29udGFpbmVyQ2FjaGUudG9wPWEudG9wLHRoaXMuY29udGFpbmVyc1tpXS5jb250YWluZXJDYWNoZS53aWR0aD10aGlzLmNvbnRhaW5lcnNbaV0uZWxlbWVudC5vdXRlcldpZHRoKCksdGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlLmhlaWdodD10aGlzLmNvbnRhaW5lcnNbaV0uZWxlbWVudC5vdXRlckhlaWdodCgpO3JldHVybiB0aGlzfSxfY3JlYXRlUGxhY2Vob2xkZXI6ZnVuY3Rpb24odCl7dD10fHx0aGlzO3ZhciBpLHM9dC5vcHRpb25zO3MucGxhY2Vob2xkZXImJnMucGxhY2Vob2xkZXIuY29uc3RydWN0b3IhPT1TdHJpbmd8fChpPXMucGxhY2Vob2xkZXIscy5wbGFjZWhvbGRlcj17ZWxlbWVudDpmdW5jdGlvbigpe3ZhciBzPXQuY3VycmVudEl0ZW1bMF0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxuPWUoXCI8XCIrcytcIj5cIix0LmRvY3VtZW50WzBdKS5hZGRDbGFzcyhpfHx0LmN1cnJlbnRJdGVtWzBdLmNsYXNzTmFtZStcIiB1aS1zb3J0YWJsZS1wbGFjZWhvbGRlclwiKS5yZW1vdmVDbGFzcyhcInVpLXNvcnRhYmxlLWhlbHBlclwiKTtyZXR1cm5cInRib2R5XCI9PT1zP3QuX2NyZWF0ZVRyUGxhY2Vob2xkZXIodC5jdXJyZW50SXRlbS5maW5kKFwidHJcIikuZXEoMCksZShcIjx0cj5cIix0LmRvY3VtZW50WzBdKS5hcHBlbmRUbyhuKSk6XCJ0clwiPT09cz90Ll9jcmVhdGVUclBsYWNlaG9sZGVyKHQuY3VycmVudEl0ZW0sbik6XCJpbWdcIj09PXMmJm4uYXR0cihcInNyY1wiLHQuY3VycmVudEl0ZW0uYXR0cihcInNyY1wiKSksaXx8bi5jc3MoXCJ2aXNpYmlsaXR5XCIsXCJoaWRkZW5cIiksbn0sdXBkYXRlOmZ1bmN0aW9uKGUsbil7KCFpfHxzLmZvcmNlUGxhY2Vob2xkZXJTaXplKSYmKG4uaGVpZ2h0KCl8fG4uaGVpZ2h0KHQuY3VycmVudEl0ZW0uaW5uZXJIZWlnaHQoKS1wYXJzZUludCh0LmN1cnJlbnRJdGVtLmNzcyhcInBhZGRpbmdUb3BcIil8fDAsMTApLXBhcnNlSW50KHQuY3VycmVudEl0ZW0uY3NzKFwicGFkZGluZ0JvdHRvbVwiKXx8MCwxMCkpLG4ud2lkdGgoKXx8bi53aWR0aCh0LmN1cnJlbnRJdGVtLmlubmVyV2lkdGgoKS1wYXJzZUludCh0LmN1cnJlbnRJdGVtLmNzcyhcInBhZGRpbmdMZWZ0XCIpfHwwLDEwKS1wYXJzZUludCh0LmN1cnJlbnRJdGVtLmNzcyhcInBhZGRpbmdSaWdodFwiKXx8MCwxMCkpKX19KSx0LnBsYWNlaG9sZGVyPWUocy5wbGFjZWhvbGRlci5lbGVtZW50LmNhbGwodC5lbGVtZW50LHQuY3VycmVudEl0ZW0pKSx0LmN1cnJlbnRJdGVtLmFmdGVyKHQucGxhY2Vob2xkZXIpLHMucGxhY2Vob2xkZXIudXBkYXRlKHQsdC5wbGFjZWhvbGRlcil9LF9jcmVhdGVUclBsYWNlaG9sZGVyOmZ1bmN0aW9uKHQsaSl7dmFyIHM9dGhpczt0LmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpe2UoXCI8dGQ+JiMxNjA7PC90ZD5cIixzLmRvY3VtZW50WzBdKS5hdHRyKFwiY29sc3BhblwiLGUodGhpcykuYXR0cihcImNvbHNwYW5cIil8fDEpLmFwcGVuZFRvKGkpfSl9LF9jb250YWN0Q29udGFpbmVyczpmdW5jdGlvbih0KXt2YXIgaSxzLG4sYSxvLHIsaCxsLHUsZCxjPW51bGwscD1udWxsO2ZvcihpPXRoaXMuY29udGFpbmVycy5sZW5ndGgtMTtpPj0wO2ktLSlpZighZS5jb250YWlucyh0aGlzLmN1cnJlbnRJdGVtWzBdLHRoaXMuY29udGFpbmVyc1tpXS5lbGVtZW50WzBdKSlpZih0aGlzLl9pbnRlcnNlY3RzV2l0aCh0aGlzLmNvbnRhaW5lcnNbaV0uY29udGFpbmVyQ2FjaGUpKXtpZihjJiZlLmNvbnRhaW5zKHRoaXMuY29udGFpbmVyc1tpXS5lbGVtZW50WzBdLGMuZWxlbWVudFswXSkpY29udGludWU7Yz10aGlzLmNvbnRhaW5lcnNbaV0scD1pfWVsc2UgdGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlLm92ZXImJih0aGlzLmNvbnRhaW5lcnNbaV0uX3RyaWdnZXIoXCJvdXRcIix0LHRoaXMuX3VpSGFzaCh0aGlzKSksdGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlLm92ZXI9MCk7aWYoYylpZigxPT09dGhpcy5jb250YWluZXJzLmxlbmd0aCl0aGlzLmNvbnRhaW5lcnNbcF0uY29udGFpbmVyQ2FjaGUub3Zlcnx8KHRoaXMuY29udGFpbmVyc1twXS5fdHJpZ2dlcihcIm92ZXJcIix0LHRoaXMuX3VpSGFzaCh0aGlzKSksdGhpcy5jb250YWluZXJzW3BdLmNvbnRhaW5lckNhY2hlLm92ZXI9MSk7ZWxzZXtmb3Iobj0xZTQsYT1udWxsLHU9Yy5mbG9hdGluZ3x8dGhpcy5faXNGbG9hdGluZyh0aGlzLmN1cnJlbnRJdGVtKSxvPXU/XCJsZWZ0XCI6XCJ0b3BcIixyPXU/XCJ3aWR0aFwiOlwiaGVpZ2h0XCIsZD11P1wiY2xpZW50WFwiOlwiY2xpZW50WVwiLHM9dGhpcy5pdGVtcy5sZW5ndGgtMTtzPj0wO3MtLSllLmNvbnRhaW5zKHRoaXMuY29udGFpbmVyc1twXS5lbGVtZW50WzBdLHRoaXMuaXRlbXNbc10uaXRlbVswXSkmJnRoaXMuaXRlbXNbc10uaXRlbVswXSE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJihoPXRoaXMuaXRlbXNbc10uaXRlbS5vZmZzZXQoKVtvXSxsPSExLHRbZF0taD50aGlzLml0ZW1zW3NdW3JdLzImJihsPSEwKSxuPk1hdGguYWJzKHRbZF0taCkmJihuPU1hdGguYWJzKHRbZF0taCksYT10aGlzLml0ZW1zW3NdLHRoaXMuZGlyZWN0aW9uPWw/XCJ1cFwiOlwiZG93blwiKSk7aWYoIWEmJiF0aGlzLm9wdGlvbnMuZHJvcE9uRW1wdHkpcmV0dXJuO2lmKHRoaXMuY3VycmVudENvbnRhaW5lcj09PXRoaXMuY29udGFpbmVyc1twXSlyZXR1cm4gdGhpcy5jdXJyZW50Q29udGFpbmVyLmNvbnRhaW5lckNhY2hlLm92ZXJ8fCh0aGlzLmNvbnRhaW5lcnNbcF0uX3RyaWdnZXIoXCJvdmVyXCIsdCx0aGlzLl91aUhhc2goKSksdGhpcy5jdXJyZW50Q29udGFpbmVyLmNvbnRhaW5lckNhY2hlLm92ZXI9MSksdm9pZCAwO2E/dGhpcy5fcmVhcnJhbmdlKHQsYSxudWxsLCEwKTp0aGlzLl9yZWFycmFuZ2UodCxudWxsLHRoaXMuY29udGFpbmVyc1twXS5lbGVtZW50LCEwKSx0aGlzLl90cmlnZ2VyKFwiY2hhbmdlXCIsdCx0aGlzLl91aUhhc2goKSksdGhpcy5jb250YWluZXJzW3BdLl90cmlnZ2VyKFwiY2hhbmdlXCIsdCx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY3VycmVudENvbnRhaW5lcj10aGlzLmNvbnRhaW5lcnNbcF0sdGhpcy5vcHRpb25zLnBsYWNlaG9sZGVyLnVwZGF0ZSh0aGlzLmN1cnJlbnRDb250YWluZXIsdGhpcy5wbGFjZWhvbGRlciksdGhpcy5jb250YWluZXJzW3BdLl90cmlnZ2VyKFwib3ZlclwiLHQsdGhpcy5fdWlIYXNoKHRoaXMpKSx0aGlzLmNvbnRhaW5lcnNbcF0uY29udGFpbmVyQ2FjaGUub3Zlcj0xfX0sX2NyZWF0ZUhlbHBlcjpmdW5jdGlvbih0KXt2YXIgaT10aGlzLm9wdGlvbnMscz1lLmlzRnVuY3Rpb24oaS5oZWxwZXIpP2UoaS5oZWxwZXIuYXBwbHkodGhpcy5lbGVtZW50WzBdLFt0LHRoaXMuY3VycmVudEl0ZW1dKSk6XCJjbG9uZVwiPT09aS5oZWxwZXI/dGhpcy5jdXJyZW50SXRlbS5jbG9uZSgpOnRoaXMuY3VycmVudEl0ZW07cmV0dXJuIHMucGFyZW50cyhcImJvZHlcIikubGVuZ3RofHxlKFwicGFyZW50XCIhPT1pLmFwcGVuZFRvP2kuYXBwZW5kVG86dGhpcy5jdXJyZW50SXRlbVswXS5wYXJlbnROb2RlKVswXS5hcHBlbmRDaGlsZChzWzBdKSxzWzBdPT09dGhpcy5jdXJyZW50SXRlbVswXSYmKHRoaXMuX3N0b3JlZENTUz17d2lkdGg6dGhpcy5jdXJyZW50SXRlbVswXS5zdHlsZS53aWR0aCxoZWlnaHQ6dGhpcy5jdXJyZW50SXRlbVswXS5zdHlsZS5oZWlnaHQscG9zaXRpb246dGhpcy5jdXJyZW50SXRlbS5jc3MoXCJwb3NpdGlvblwiKSx0b3A6dGhpcy5jdXJyZW50SXRlbS5jc3MoXCJ0b3BcIiksbGVmdDp0aGlzLmN1cnJlbnRJdGVtLmNzcyhcImxlZnRcIil9KSwoIXNbMF0uc3R5bGUud2lkdGh8fGkuZm9yY2VIZWxwZXJTaXplKSYmcy53aWR0aCh0aGlzLmN1cnJlbnRJdGVtLndpZHRoKCkpLCghc1swXS5zdHlsZS5oZWlnaHR8fGkuZm9yY2VIZWxwZXJTaXplKSYmcy5oZWlnaHQodGhpcy5jdXJyZW50SXRlbS5oZWlnaHQoKSksc30sX2FkanVzdE9mZnNldEZyb21IZWxwZXI6ZnVuY3Rpb24odCl7XCJzdHJpbmdcIj09dHlwZW9mIHQmJih0PXQuc3BsaXQoXCIgXCIpKSxlLmlzQXJyYXkodCkmJih0PXtsZWZ0Oit0WzBdLHRvcDordFsxXXx8MH0pLFwibGVmdFwiaW4gdCYmKHRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ9dC5sZWZ0K3RoaXMubWFyZ2lucy5sZWZ0KSxcInJpZ2h0XCJpbiB0JiYodGhpcy5vZmZzZXQuY2xpY2subGVmdD10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLXQucmlnaHQrdGhpcy5tYXJnaW5zLmxlZnQpLFwidG9wXCJpbiB0JiYodGhpcy5vZmZzZXQuY2xpY2sudG9wPXQudG9wK3RoaXMubWFyZ2lucy50b3ApLFwiYm90dG9tXCJpbiB0JiYodGhpcy5vZmZzZXQuY2xpY2sudG9wPXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXQuYm90dG9tK3RoaXMubWFyZ2lucy50b3ApfSxfZ2V0UGFyZW50T2Zmc2V0OmZ1bmN0aW9uKCl7dGhpcy5vZmZzZXRQYXJlbnQ9dGhpcy5oZWxwZXIub2Zmc2V0UGFyZW50KCk7dmFyIHQ9dGhpcy5vZmZzZXRQYXJlbnQub2Zmc2V0KCk7cmV0dXJuXCJhYnNvbHV0ZVwiPT09dGhpcy5jc3NQb3NpdGlvbiYmdGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdJiZlLmNvbnRhaW5zKHRoaXMuc2Nyb2xsUGFyZW50WzBdLHRoaXMub2Zmc2V0UGFyZW50WzBdKSYmKHQubGVmdCs9dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpLHQudG9wKz10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSksKHRoaXMub2Zmc2V0UGFyZW50WzBdPT09dGhpcy5kb2N1bWVudFswXS5ib2R5fHx0aGlzLm9mZnNldFBhcmVudFswXS50YWdOYW1lJiZcImh0bWxcIj09PXRoaXMub2Zmc2V0UGFyZW50WzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSYmZS51aS5pZSkmJih0PXt0b3A6MCxsZWZ0OjB9KSx7dG9wOnQudG9wKyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJUb3BXaWR0aFwiKSwxMCl8fDApLGxlZnQ6dC5sZWZ0KyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKX19LF9nZXRSZWxhdGl2ZU9mZnNldDpmdW5jdGlvbigpe2lmKFwicmVsYXRpdmVcIj09PXRoaXMuY3NzUG9zaXRpb24pe3ZhciBlPXRoaXMuY3VycmVudEl0ZW0ucG9zaXRpb24oKTtyZXR1cm57dG9wOmUudG9wLShwYXJzZUludCh0aGlzLmhlbHBlci5jc3MoXCJ0b3BcIiksMTApfHwwKSt0aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSxsZWZ0OmUubGVmdC0ocGFyc2VJbnQodGhpcy5oZWxwZXIuY3NzKFwibGVmdFwiKSwxMCl8fDApK3RoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbExlZnQoKX19cmV0dXJue3RvcDowLGxlZnQ6MH19LF9jYWNoZU1hcmdpbnM6ZnVuY3Rpb24oKXt0aGlzLm1hcmdpbnM9e2xlZnQ6cGFyc2VJbnQodGhpcy5jdXJyZW50SXRlbS5jc3MoXCJtYXJnaW5MZWZ0XCIpLDEwKXx8MCx0b3A6cGFyc2VJbnQodGhpcy5jdXJyZW50SXRlbS5jc3MoXCJtYXJnaW5Ub3BcIiksMTApfHwwfX0sX2NhY2hlSGVscGVyUHJvcG9ydGlvbnM6ZnVuY3Rpb24oKXt0aGlzLmhlbHBlclByb3BvcnRpb25zPXt3aWR0aDp0aGlzLmhlbHBlci5vdXRlcldpZHRoKCksaGVpZ2h0OnRoaXMuaGVscGVyLm91dGVySGVpZ2h0KCl9fSxfc2V0Q29udGFpbm1lbnQ6ZnVuY3Rpb24oKXt2YXIgdCxpLHMsbj10aGlzLm9wdGlvbnM7XCJwYXJlbnRcIj09PW4uY29udGFpbm1lbnQmJihuLmNvbnRhaW5tZW50PXRoaXMuaGVscGVyWzBdLnBhcmVudE5vZGUpLChcImRvY3VtZW50XCI9PT1uLmNvbnRhaW5tZW50fHxcIndpbmRvd1wiPT09bi5jb250YWlubWVudCkmJih0aGlzLmNvbnRhaW5tZW50PVswLXRoaXMub2Zmc2V0LnJlbGF0aXZlLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQsMC10aGlzLm9mZnNldC5yZWxhdGl2ZS50b3AtdGhpcy5vZmZzZXQucGFyZW50LnRvcCxcImRvY3VtZW50XCI9PT1uLmNvbnRhaW5tZW50P3RoaXMuZG9jdW1lbnQud2lkdGgoKTp0aGlzLndpbmRvdy53aWR0aCgpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtdGhpcy5tYXJnaW5zLmxlZnQsKFwiZG9jdW1lbnRcIj09PW4uY29udGFpbm1lbnQ/dGhpcy5kb2N1bWVudC53aWR0aCgpOnRoaXMud2luZG93LmhlaWdodCgpfHx0aGlzLmRvY3VtZW50WzBdLmJvZHkucGFyZW50Tm9kZS5zY3JvbGxIZWlnaHQpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXRoaXMubWFyZ2lucy50b3BdKSwvXihkb2N1bWVudHx3aW5kb3d8cGFyZW50KSQvLnRlc3Qobi5jb250YWlubWVudCl8fCh0PWUobi5jb250YWlubWVudClbMF0saT1lKG4uY29udGFpbm1lbnQpLm9mZnNldCgpLHM9XCJoaWRkZW5cIiE9PWUodCkuY3NzKFwib3ZlcmZsb3dcIiksdGhpcy5jb250YWlubWVudD1baS5sZWZ0KyhwYXJzZUludChlKHQpLmNzcyhcImJvcmRlckxlZnRXaWR0aFwiKSwxMCl8fDApKyhwYXJzZUludChlKHQpLmNzcyhcInBhZGRpbmdMZWZ0XCIpLDEwKXx8MCktdGhpcy5tYXJnaW5zLmxlZnQsaS50b3ArKHBhcnNlSW50KGUodCkuY3NzKFwiYm9yZGVyVG9wV2lkdGhcIiksMTApfHwwKSsocGFyc2VJbnQoZSh0KS5jc3MoXCJwYWRkaW5nVG9wXCIpLDEwKXx8MCktdGhpcy5tYXJnaW5zLnRvcCxpLmxlZnQrKHM/TWF0aC5tYXgodC5zY3JvbGxXaWR0aCx0Lm9mZnNldFdpZHRoKTp0Lm9mZnNldFdpZHRoKS0ocGFyc2VJbnQoZSh0KS5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoZSh0KS5jc3MoXCJwYWRkaW5nUmlnaHRcIiksMTApfHwwKS10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLXRoaXMubWFyZ2lucy5sZWZ0LGkudG9wKyhzP01hdGgubWF4KHQuc2Nyb2xsSGVpZ2h0LHQub2Zmc2V0SGVpZ2h0KTp0Lm9mZnNldEhlaWdodCktKHBhcnNlSW50KGUodCkuY3NzKFwiYm9yZGVyVG9wV2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoZSh0KS5jc3MoXCJwYWRkaW5nQm90dG9tXCIpLDEwKXx8MCktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQtdGhpcy5tYXJnaW5zLnRvcF0pfSxfY29udmVydFBvc2l0aW9uVG86ZnVuY3Rpb24odCxpKXtpfHwoaT10aGlzLnBvc2l0aW9uKTt2YXIgcz1cImFic29sdXRlXCI9PT10PzE6LTEsbj1cImFic29sdXRlXCIhPT10aGlzLmNzc1Bvc2l0aW9ufHx0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMuZG9jdW1lbnRbMF0mJmUuY29udGFpbnModGhpcy5zY3JvbGxQYXJlbnRbMF0sdGhpcy5vZmZzZXRQYXJlbnRbMF0pP3RoaXMuc2Nyb2xsUGFyZW50OnRoaXMub2Zmc2V0UGFyZW50LGE9LyhodG1sfGJvZHkpL2kudGVzdChuWzBdLnRhZ05hbWUpO3JldHVybnt0b3A6aS50b3ArdGhpcy5vZmZzZXQucmVsYXRpdmUudG9wKnMrdGhpcy5vZmZzZXQucGFyZW50LnRvcCpzLShcImZpeGVkXCI9PT10aGlzLmNzc1Bvc2l0aW9uPy10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKTphPzA6bi5zY3JvbGxUb3AoKSkqcyxsZWZ0OmkubGVmdCt0aGlzLm9mZnNldC5yZWxhdGl2ZS5sZWZ0KnMrdGhpcy5vZmZzZXQucGFyZW50LmxlZnQqcy0oXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpOmE/MDpuLnNjcm9sbExlZnQoKSkqc319LF9nZW5lcmF0ZVBvc2l0aW9uOmZ1bmN0aW9uKHQpe3ZhciBpLHMsbj10aGlzLm9wdGlvbnMsYT10LnBhZ2VYLG89dC5wYWdlWSxyPVwiYWJzb2x1dGVcIiE9PXRoaXMuY3NzUG9zaXRpb258fHRoaXMuc2Nyb2xsUGFyZW50WzBdIT09dGhpcy5kb2N1bWVudFswXSYmZS5jb250YWlucyh0aGlzLnNjcm9sbFBhcmVudFswXSx0aGlzLm9mZnNldFBhcmVudFswXSk/dGhpcy5zY3JvbGxQYXJlbnQ6dGhpcy5vZmZzZXRQYXJlbnQsaD0vKGh0bWx8Ym9keSkvaS50ZXN0KHJbMF0udGFnTmFtZSk7cmV0dXJuXCJyZWxhdGl2ZVwiIT09dGhpcy5jc3NQb3NpdGlvbnx8dGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdJiZ0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMub2Zmc2V0UGFyZW50WzBdfHwodGhpcy5vZmZzZXQucmVsYXRpdmU9dGhpcy5fZ2V0UmVsYXRpdmVPZmZzZXQoKSksdGhpcy5vcmlnaW5hbFBvc2l0aW9uJiYodGhpcy5jb250YWlubWVudCYmKHQucGFnZVgtdGhpcy5vZmZzZXQuY2xpY2subGVmdDx0aGlzLmNvbnRhaW5tZW50WzBdJiYoYT10aGlzLmNvbnRhaW5tZW50WzBdK3RoaXMub2Zmc2V0LmNsaWNrLmxlZnQpLHQucGFnZVktdGhpcy5vZmZzZXQuY2xpY2sudG9wPHRoaXMuY29udGFpbm1lbnRbMV0mJihvPXRoaXMuY29udGFpbm1lbnRbMV0rdGhpcy5vZmZzZXQuY2xpY2sudG9wKSx0LnBhZ2VYLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ+dGhpcy5jb250YWlubWVudFsyXSYmKGE9dGhpcy5jb250YWlubWVudFsyXSt0aGlzLm9mZnNldC5jbGljay5sZWZ0KSx0LnBhZ2VZLXRoaXMub2Zmc2V0LmNsaWNrLnRvcD50aGlzLmNvbnRhaW5tZW50WzNdJiYobz10aGlzLmNvbnRhaW5tZW50WzNdK3RoaXMub2Zmc2V0LmNsaWNrLnRvcCkpLG4uZ3JpZCYmKGk9dGhpcy5vcmlnaW5hbFBhZ2VZK01hdGgucm91bmQoKG8tdGhpcy5vcmlnaW5hbFBhZ2VZKS9uLmdyaWRbMV0pKm4uZ3JpZFsxXSxvPXRoaXMuY29udGFpbm1lbnQ/aS10aGlzLm9mZnNldC5jbGljay50b3A+PXRoaXMuY29udGFpbm1lbnRbMV0mJmktdGhpcy5vZmZzZXQuY2xpY2sudG9wPD10aGlzLmNvbnRhaW5tZW50WzNdP2k6aS10aGlzLm9mZnNldC5jbGljay50b3A+PXRoaXMuY29udGFpbm1lbnRbMV0/aS1uLmdyaWRbMV06aStuLmdyaWRbMV06aSxzPXRoaXMub3JpZ2luYWxQYWdlWCtNYXRoLnJvdW5kKChhLXRoaXMub3JpZ2luYWxQYWdlWCkvbi5ncmlkWzBdKSpuLmdyaWRbMF0sYT10aGlzLmNvbnRhaW5tZW50P3MtdGhpcy5vZmZzZXQuY2xpY2subGVmdD49dGhpcy5jb250YWlubWVudFswXSYmcy10aGlzLm9mZnNldC5jbGljay5sZWZ0PD10aGlzLmNvbnRhaW5tZW50WzJdP3M6cy10aGlzLm9mZnNldC5jbGljay5sZWZ0Pj10aGlzLmNvbnRhaW5tZW50WzBdP3Mtbi5ncmlkWzBdOnMrbi5ncmlkWzBdOnMpKSx7dG9wOm8tdGhpcy5vZmZzZXQuY2xpY2sudG9wLXRoaXMub2Zmc2V0LnJlbGF0aXZlLnRvcC10aGlzLm9mZnNldC5wYXJlbnQudG9wKyhcImZpeGVkXCI9PT10aGlzLmNzc1Bvc2l0aW9uPy10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKTpoPzA6ci5zY3JvbGxUb3AoKSksbGVmdDphLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQtdGhpcy5vZmZzZXQucmVsYXRpdmUubGVmdC10aGlzLm9mZnNldC5wYXJlbnQubGVmdCsoXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpOmg/MDpyLnNjcm9sbExlZnQoKSl9fSxfcmVhcnJhbmdlOmZ1bmN0aW9uKGUsdCxpLHMpe2k/aVswXS5hcHBlbmRDaGlsZCh0aGlzLnBsYWNlaG9sZGVyWzBdKTp0Lml0ZW1bMF0ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5wbGFjZWhvbGRlclswXSxcImRvd25cIj09PXRoaXMuZGlyZWN0aW9uP3QuaXRlbVswXTp0Lml0ZW1bMF0ubmV4dFNpYmxpbmcpLHRoaXMuY291bnRlcj10aGlzLmNvdW50ZXI/Kyt0aGlzLmNvdW50ZXI6MTt2YXIgbj10aGlzLmNvdW50ZXI7dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXtuPT09dGhpcy5jb3VudGVyJiZ0aGlzLnJlZnJlc2hQb3NpdGlvbnMoIXMpfSl9LF9jbGVhcjpmdW5jdGlvbihlLHQpe2Z1bmN0aW9uIGkoZSx0LGkpe3JldHVybiBmdW5jdGlvbihzKXtpLl90cmlnZ2VyKGUscyx0Ll91aUhhc2godCkpfX10aGlzLnJldmVydGluZz0hMTt2YXIgcyxuPVtdO2lmKCF0aGlzLl9ub0ZpbmFsU29ydCYmdGhpcy5jdXJyZW50SXRlbS5wYXJlbnQoKS5sZW5ndGgmJnRoaXMucGxhY2Vob2xkZXIuYmVmb3JlKHRoaXMuY3VycmVudEl0ZW0pLHRoaXMuX25vRmluYWxTb3J0PW51bGwsdGhpcy5oZWxwZXJbMF09PT10aGlzLmN1cnJlbnRJdGVtWzBdKXtmb3IocyBpbiB0aGlzLl9zdG9yZWRDU1MpKFwiYXV0b1wiPT09dGhpcy5fc3RvcmVkQ1NTW3NdfHxcInN0YXRpY1wiPT09dGhpcy5fc3RvcmVkQ1NTW3NdKSYmKHRoaXMuX3N0b3JlZENTU1tzXT1cIlwiKTt0aGlzLmN1cnJlbnRJdGVtLmNzcyh0aGlzLl9zdG9yZWRDU1MpLnJlbW92ZUNsYXNzKFwidWktc29ydGFibGUtaGVscGVyXCIpfWVsc2UgdGhpcy5jdXJyZW50SXRlbS5zaG93KCk7Zm9yKHRoaXMuZnJvbU91dHNpZGUmJiF0JiZuLnB1c2goZnVuY3Rpb24oZSl7dGhpcy5fdHJpZ2dlcihcInJlY2VpdmVcIixlLHRoaXMuX3VpSGFzaCh0aGlzLmZyb21PdXRzaWRlKSl9KSwhdGhpcy5mcm9tT3V0c2lkZSYmdGhpcy5kb21Qb3NpdGlvbi5wcmV2PT09dGhpcy5jdXJyZW50SXRlbS5wcmV2KCkubm90KFwiLnVpLXNvcnRhYmxlLWhlbHBlclwiKVswXSYmdGhpcy5kb21Qb3NpdGlvbi5wYXJlbnQ9PT10aGlzLmN1cnJlbnRJdGVtLnBhcmVudCgpWzBdfHx0fHxuLnB1c2goZnVuY3Rpb24oZSl7dGhpcy5fdHJpZ2dlcihcInVwZGF0ZVwiLGUsdGhpcy5fdWlIYXNoKCkpfSksdGhpcyE9PXRoaXMuY3VycmVudENvbnRhaW5lciYmKHR8fChuLnB1c2goZnVuY3Rpb24oZSl7dGhpcy5fdHJpZ2dlcihcInJlbW92ZVwiLGUsdGhpcy5fdWlIYXNoKCkpfSksbi5wdXNoKGZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbih0KXtlLl90cmlnZ2VyKFwicmVjZWl2ZVwiLHQsdGhpcy5fdWlIYXNoKHRoaXMpKX19LmNhbGwodGhpcyx0aGlzLmN1cnJlbnRDb250YWluZXIpKSxuLnB1c2goZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe2UuX3RyaWdnZXIoXCJ1cGRhdGVcIix0LHRoaXMuX3VpSGFzaCh0aGlzKSl9fS5jYWxsKHRoaXMsdGhpcy5jdXJyZW50Q29udGFpbmVyKSkpKSxzPXRoaXMuY29udGFpbmVycy5sZW5ndGgtMTtzPj0wO3MtLSl0fHxuLnB1c2goaShcImRlYWN0aXZhdGVcIix0aGlzLHRoaXMuY29udGFpbmVyc1tzXSkpLHRoaXMuY29udGFpbmVyc1tzXS5jb250YWluZXJDYWNoZS5vdmVyJiYobi5wdXNoKGkoXCJvdXRcIix0aGlzLHRoaXMuY29udGFpbmVyc1tzXSkpLHRoaXMuY29udGFpbmVyc1tzXS5jb250YWluZXJDYWNoZS5vdmVyPTApO2lmKHRoaXMuc3RvcmVkQ3Vyc29yJiYodGhpcy5kb2N1bWVudC5maW5kKFwiYm9keVwiKS5jc3MoXCJjdXJzb3JcIix0aGlzLnN0b3JlZEN1cnNvciksdGhpcy5zdG9yZWRTdHlsZXNoZWV0LnJlbW92ZSgpKSx0aGlzLl9zdG9yZWRPcGFjaXR5JiZ0aGlzLmhlbHBlci5jc3MoXCJvcGFjaXR5XCIsdGhpcy5fc3RvcmVkT3BhY2l0eSksdGhpcy5fc3RvcmVkWkluZGV4JiZ0aGlzLmhlbHBlci5jc3MoXCJ6SW5kZXhcIixcImF1dG9cIj09PXRoaXMuX3N0b3JlZFpJbmRleD9cIlwiOnRoaXMuX3N0b3JlZFpJbmRleCksdGhpcy5kcmFnZ2luZz0hMSx0fHx0aGlzLl90cmlnZ2VyKFwiYmVmb3JlU3RvcFwiLGUsdGhpcy5fdWlIYXNoKCkpLHRoaXMucGxhY2Vob2xkZXJbMF0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnBsYWNlaG9sZGVyWzBdKSx0aGlzLmNhbmNlbEhlbHBlclJlbW92YWx8fCh0aGlzLmhlbHBlclswXSE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJnRoaXMuaGVscGVyLnJlbW92ZSgpLHRoaXMuaGVscGVyPW51bGwpLCF0KXtmb3Iocz0wO24ubGVuZ3RoPnM7cysrKW5bc10uY2FsbCh0aGlzLGUpO3RoaXMuX3RyaWdnZXIoXCJzdG9wXCIsZSx0aGlzLl91aUhhc2goKSl9cmV0dXJuIHRoaXMuZnJvbU91dHNpZGU9ITEsIXRoaXMuY2FuY2VsSGVscGVyUmVtb3ZhbH0sX3RyaWdnZXI6ZnVuY3Rpb24oKXtlLldpZGdldC5wcm90b3R5cGUuX3RyaWdnZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpPT09ITEmJnRoaXMuY2FuY2VsKCl9LF91aUhhc2g6ZnVuY3Rpb24odCl7dmFyIGk9dHx8dGhpcztyZXR1cm57aGVscGVyOmkuaGVscGVyLHBsYWNlaG9sZGVyOmkucGxhY2Vob2xkZXJ8fGUoW10pLHBvc2l0aW9uOmkucG9zaXRpb24sb3JpZ2luYWxQb3NpdGlvbjppLm9yaWdpbmFsUG9zaXRpb24sb2Zmc2V0OmkucG9zaXRpb25BYnMsaXRlbTppLmN1cnJlbnRJdGVtLHNlbmRlcjp0P3QuZWxlbWVudDpudWxsfX19KSxlLndpZGdldChcInVpLnNwaW5uZXJcIix7dmVyc2lvbjpcIjEuMTEuNFwiLGRlZmF1bHRFbGVtZW50OlwiPGlucHV0PlwiLHdpZGdldEV2ZW50UHJlZml4Olwic3BpblwiLG9wdGlvbnM6e2N1bHR1cmU6bnVsbCxpY29uczp7ZG93bjpcInVpLWljb24tdHJpYW5nbGUtMS1zXCIsdXA6XCJ1aS1pY29uLXRyaWFuZ2xlLTEtblwifSxpbmNyZW1lbnRhbDohMCxtYXg6bnVsbCxtaW46bnVsbCxudW1iZXJGb3JtYXQ6bnVsbCxwYWdlOjEwLHN0ZXA6MSxjaGFuZ2U6bnVsbCxzcGluOm51bGwsc3RhcnQ6bnVsbCxzdG9wOm51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLl9zZXRPcHRpb24oXCJtYXhcIix0aGlzLm9wdGlvbnMubWF4KSx0aGlzLl9zZXRPcHRpb24oXCJtaW5cIix0aGlzLm9wdGlvbnMubWluKSx0aGlzLl9zZXRPcHRpb24oXCJzdGVwXCIsdGhpcy5vcHRpb25zLnN0ZXApLFwiXCIhPT10aGlzLnZhbHVlKCkmJnRoaXMuX3ZhbHVlKHRoaXMuZWxlbWVudC52YWwoKSwhMCksdGhpcy5fZHJhdygpLHRoaXMuX29uKHRoaXMuX2V2ZW50cyksdGhpcy5fcmVmcmVzaCgpLHRoaXMuX29uKHRoaXMud2luZG93LHtiZWZvcmV1bmxvYWQ6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cihcImF1dG9jb21wbGV0ZVwiKX19KX0sX2dldENyZWF0ZU9wdGlvbnM6ZnVuY3Rpb24oKXt2YXIgdD17fSxpPXRoaXMuZWxlbWVudDtyZXR1cm4gZS5lYWNoKFtcIm1pblwiLFwibWF4XCIsXCJzdGVwXCJdLGZ1bmN0aW9uKGUscyl7dmFyIG49aS5hdHRyKHMpO3ZvaWQgMCE9PW4mJm4ubGVuZ3RoJiYodFtzXT1uKX0pLHR9LF9ldmVudHM6e2tleWRvd246ZnVuY3Rpb24oZSl7dGhpcy5fc3RhcnQoZSkmJnRoaXMuX2tleWRvd24oZSkmJmUucHJldmVudERlZmF1bHQoKX0sa2V5dXA6XCJfc3RvcFwiLGZvY3VzOmZ1bmN0aW9uKCl7dGhpcy5wcmV2aW91cz10aGlzLmVsZW1lbnQudmFsKCl9LGJsdXI6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuY2FuY2VsQmx1cj8oZGVsZXRlIHRoaXMuY2FuY2VsQmx1cix2b2lkIDApOih0aGlzLl9zdG9wKCksdGhpcy5fcmVmcmVzaCgpLHRoaXMucHJldmlvdXMhPT10aGlzLmVsZW1lbnQudmFsKCkmJnRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIixlKSx2b2lkIDApfSxtb3VzZXdoZWVsOmZ1bmN0aW9uKGUsdCl7aWYodCl7aWYoIXRoaXMuc3Bpbm5pbmcmJiF0aGlzLl9zdGFydChlKSlyZXR1cm4hMTt0aGlzLl9zcGluKCh0PjA/MTotMSkqdGhpcy5vcHRpb25zLnN0ZXAsZSksY2xlYXJUaW1lb3V0KHRoaXMubW91c2V3aGVlbFRpbWVyKSx0aGlzLm1vdXNld2hlZWxUaW1lcj10aGlzLl9kZWxheShmdW5jdGlvbigpe3RoaXMuc3Bpbm5pbmcmJnRoaXMuX3N0b3AoZSl9LDEwMCksZS5wcmV2ZW50RGVmYXVsdCgpfX0sXCJtb3VzZWRvd24gLnVpLXNwaW5uZXItYnV0dG9uXCI6ZnVuY3Rpb24odCl7ZnVuY3Rpb24gaSgpe3ZhciBlPXRoaXMuZWxlbWVudFswXT09PXRoaXMuZG9jdW1lbnRbMF0uYWN0aXZlRWxlbWVudDtlfHwodGhpcy5lbGVtZW50LmZvY3VzKCksdGhpcy5wcmV2aW91cz1zLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dGhpcy5wcmV2aW91cz1zfSkpfXZhciBzO3M9dGhpcy5lbGVtZW50WzBdPT09dGhpcy5kb2N1bWVudFswXS5hY3RpdmVFbGVtZW50P3RoaXMucHJldmlvdXM6dGhpcy5lbGVtZW50LnZhbCgpLHQucHJldmVudERlZmF1bHQoKSxpLmNhbGwodGhpcyksdGhpcy5jYW5jZWxCbHVyPSEwLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXMuY2FuY2VsQmx1cixpLmNhbGwodGhpcyl9KSx0aGlzLl9zdGFydCh0KSE9PSExJiZ0aGlzLl9yZXBlYXQobnVsbCxlKHQuY3VycmVudFRhcmdldCkuaGFzQ2xhc3MoXCJ1aS1zcGlubmVyLXVwXCIpPzE6LTEsdCl9LFwibW91c2V1cCAudWktc3Bpbm5lci1idXR0b25cIjpcIl9zdG9wXCIsXCJtb3VzZWVudGVyIC51aS1zcGlubmVyLWJ1dHRvblwiOmZ1bmN0aW9uKHQpe3JldHVybiBlKHQuY3VycmVudFRhcmdldCkuaGFzQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIik/dGhpcy5fc3RhcnQodCk9PT0hMT8hMToodGhpcy5fcmVwZWF0KG51bGwsZSh0LmN1cnJlbnRUYXJnZXQpLmhhc0NsYXNzKFwidWktc3Bpbm5lci11cFwiKT8xOi0xLHQpLHZvaWQgMCk6dm9pZCAwfSxcIm1vdXNlbGVhdmUgLnVpLXNwaW5uZXItYnV0dG9uXCI6XCJfc3RvcFwifSxfZHJhdzpmdW5jdGlvbigpe3ZhciBlPXRoaXMudWlTcGlubmVyPXRoaXMuZWxlbWVudC5hZGRDbGFzcyhcInVpLXNwaW5uZXItaW5wdXRcIikuYXR0cihcImF1dG9jb21wbGV0ZVwiLFwib2ZmXCIpLndyYXAodGhpcy5fdWlTcGlubmVySHRtbCgpKS5wYXJlbnQoKS5hcHBlbmQodGhpcy5fYnV0dG9uSHRtbCgpKTt0aGlzLmVsZW1lbnQuYXR0cihcInJvbGVcIixcInNwaW5idXR0b25cIiksdGhpcy5idXR0b25zPWUuZmluZChcIi51aS1zcGlubmVyLWJ1dHRvblwiKS5hdHRyKFwidGFiSW5kZXhcIiwtMSkuYnV0dG9uKCkucmVtb3ZlQ2xhc3MoXCJ1aS1jb3JuZXItYWxsXCIpLHRoaXMuYnV0dG9ucy5oZWlnaHQoKT5NYXRoLmNlaWwoLjUqZS5oZWlnaHQoKSkmJmUuaGVpZ2h0KCk+MCYmZS5oZWlnaHQoZS5oZWlnaHQoKSksdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLmRpc2FibGUoKX0sX2tleWRvd246ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5vcHRpb25zLHM9ZS51aS5rZXlDb2RlO3N3aXRjaCh0LmtleUNvZGUpe2Nhc2Ugcy5VUDpyZXR1cm4gdGhpcy5fcmVwZWF0KG51bGwsMSx0KSwhMDtjYXNlIHMuRE9XTjpyZXR1cm4gdGhpcy5fcmVwZWF0KG51bGwsLTEsdCksITA7Y2FzZSBzLlBBR0VfVVA6cmV0dXJuIHRoaXMuX3JlcGVhdChudWxsLGkucGFnZSx0KSwhMDtjYXNlIHMuUEFHRV9ET1dOOnJldHVybiB0aGlzLl9yZXBlYXQobnVsbCwtaS5wYWdlLHQpLCEwfXJldHVybiExfSxfdWlTcGlubmVySHRtbDpmdW5jdGlvbigpe3JldHVyblwiPHNwYW4gY2xhc3M9J3VpLXNwaW5uZXIgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWNvcm5lci1hbGwnPjwvc3Bhbj5cIn0sX2J1dHRvbkh0bWw6ZnVuY3Rpb24oKXtyZXR1cm5cIjxhIGNsYXNzPSd1aS1zcGlubmVyLWJ1dHRvbiB1aS1zcGlubmVyLXVwIHVpLWNvcm5lci10cic+PHNwYW4gY2xhc3M9J3VpLWljb24gXCIrdGhpcy5vcHRpb25zLmljb25zLnVwK1wiJz4mIzk2NTA7PC9zcGFuPlwiK1wiPC9hPlwiK1wiPGEgY2xhc3M9J3VpLXNwaW5uZXItYnV0dG9uIHVpLXNwaW5uZXItZG93biB1aS1jb3JuZXItYnInPlwiK1wiPHNwYW4gY2xhc3M9J3VpLWljb24gXCIrdGhpcy5vcHRpb25zLmljb25zLmRvd24rXCInPiYjOTY2MDs8L3NwYW4+XCIrXCI8L2E+XCJ9LF9zdGFydDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5zcGlubmluZ3x8dGhpcy5fdHJpZ2dlcihcInN0YXJ0XCIsZSkhPT0hMT8odGhpcy5jb3VudGVyfHwodGhpcy5jb3VudGVyPTEpLHRoaXMuc3Bpbm5pbmc9ITAsITApOiExfSxfcmVwZWF0OmZ1bmN0aW9uKGUsdCxpKXtlPWV8fDUwMCxjbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj10aGlzLl9kZWxheShmdW5jdGlvbigpe3RoaXMuX3JlcGVhdCg0MCx0LGkpfSxlKSx0aGlzLl9zcGluKHQqdGhpcy5vcHRpb25zLnN0ZXAsaSl9LF9zcGluOmZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy52YWx1ZSgpfHwwO3RoaXMuY291bnRlcnx8KHRoaXMuY291bnRlcj0xKSxpPXRoaXMuX2FkanVzdFZhbHVlKGkrZSp0aGlzLl9pbmNyZW1lbnQodGhpcy5jb3VudGVyKSksdGhpcy5zcGlubmluZyYmdGhpcy5fdHJpZ2dlcihcInNwaW5cIix0LHt2YWx1ZTppfSk9PT0hMXx8KHRoaXMuX3ZhbHVlKGkpLHRoaXMuY291bnRlcisrKX0sX2luY3JlbWVudDpmdW5jdGlvbih0KXt2YXIgaT10aGlzLm9wdGlvbnMuaW5jcmVtZW50YWw7cmV0dXJuIGk/ZS5pc0Z1bmN0aW9uKGkpP2kodCk6TWF0aC5mbG9vcih0KnQqdC81ZTQtdCp0LzUwMCsxNyp0LzIwMCsxKToxfSxfcHJlY2lzaW9uOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5fcHJlY2lzaW9uT2YodGhpcy5vcHRpb25zLnN0ZXApO3JldHVybiBudWxsIT09dGhpcy5vcHRpb25zLm1pbiYmKGU9TWF0aC5tYXgoZSx0aGlzLl9wcmVjaXNpb25PZih0aGlzLm9wdGlvbnMubWluKSkpLGV9LF9wcmVjaXNpb25PZjpmdW5jdGlvbihlKXt2YXIgdD1cIlwiK2UsaT10LmluZGV4T2YoXCIuXCIpO3JldHVybi0xPT09aT8wOnQubGVuZ3RoLWktMX0sX2FkanVzdFZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0LGkscz10aGlzLm9wdGlvbnM7cmV0dXJuIHQ9bnVsbCE9PXMubWluP3MubWluOjAsaT1lLXQsaT1NYXRoLnJvdW5kKGkvcy5zdGVwKSpzLnN0ZXAsZT10K2ksZT1wYXJzZUZsb2F0KGUudG9GaXhlZCh0aGlzLl9wcmVjaXNpb24oKSkpLG51bGwhPT1zLm1heCYmZT5zLm1heD9zLm1heDpudWxsIT09cy5taW4mJnMubWluPmU/cy5taW46ZX0sX3N0b3A6ZnVuY3Rpb24oZSl7dGhpcy5zcGlubmluZyYmKGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSxjbGVhclRpbWVvdXQodGhpcy5tb3VzZXdoZWVsVGltZXIpLHRoaXMuY291bnRlcj0wLHRoaXMuc3Bpbm5pbmc9ITEsdGhpcy5fdHJpZ2dlcihcInN0b3BcIixlKSl9LF9zZXRPcHRpb246ZnVuY3Rpb24oZSx0KXtpZihcImN1bHR1cmVcIj09PWV8fFwibnVtYmVyRm9ybWF0XCI9PT1lKXt2YXIgaT10aGlzLl9wYXJzZSh0aGlzLmVsZW1lbnQudmFsKCkpO3JldHVybiB0aGlzLm9wdGlvbnNbZV09dCx0aGlzLmVsZW1lbnQudmFsKHRoaXMuX2Zvcm1hdChpKSksdm9pZCAwfShcIm1heFwiPT09ZXx8XCJtaW5cIj09PWV8fFwic3RlcFwiPT09ZSkmJlwic3RyaW5nXCI9PXR5cGVvZiB0JiYodD10aGlzLl9wYXJzZSh0KSksXCJpY29uc1wiPT09ZSYmKHRoaXMuYnV0dG9ucy5maXJzdCgpLmZpbmQoXCIudWktaWNvblwiKS5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuaWNvbnMudXApLmFkZENsYXNzKHQudXApLHRoaXMuYnV0dG9ucy5sYXN0KCkuZmluZChcIi51aS1pY29uXCIpLnJlbW92ZUNsYXNzKHRoaXMub3B0aW9ucy5pY29ucy5kb3duKS5hZGRDbGFzcyh0LmRvd24pKSx0aGlzLl9zdXBlcihlLHQpLFwiZGlzYWJsZWRcIj09PWUmJih0aGlzLndpZGdldCgpLnRvZ2dsZUNsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIXQpLHRoaXMuZWxlbWVudC5wcm9wKFwiZGlzYWJsZWRcIiwhIXQpLHRoaXMuYnV0dG9ucy5idXR0b24odD9cImRpc2FibGVcIjpcImVuYWJsZVwiKSl9LF9zZXRPcHRpb25zOmgoZnVuY3Rpb24oZSl7dGhpcy5fc3VwZXIoZSl9KSxfcGFyc2U6ZnVuY3Rpb24oZSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGUmJlwiXCIhPT1lJiYoZT13aW5kb3cuR2xvYmFsaXplJiZ0aGlzLm9wdGlvbnMubnVtYmVyRm9ybWF0P0dsb2JhbGl6ZS5wYXJzZUZsb2F0KGUsMTAsdGhpcy5vcHRpb25zLmN1bHR1cmUpOitlKSxcIlwiPT09ZXx8aXNOYU4oZSk/bnVsbDplfSxfZm9ybWF0OmZ1bmN0aW9uKGUpe3JldHVyblwiXCI9PT1lP1wiXCI6d2luZG93Lkdsb2JhbGl6ZSYmdGhpcy5vcHRpb25zLm51bWJlckZvcm1hdD9HbG9iYWxpemUuZm9ybWF0KGUsdGhpcy5vcHRpb25zLm51bWJlckZvcm1hdCx0aGlzLm9wdGlvbnMuY3VsdHVyZSk6ZX0sX3JlZnJlc2g6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQuYXR0cih7XCJhcmlhLXZhbHVlbWluXCI6dGhpcy5vcHRpb25zLm1pbixcImFyaWEtdmFsdWVtYXhcIjp0aGlzLm9wdGlvbnMubWF4LFwiYXJpYS12YWx1ZW5vd1wiOnRoaXMuX3BhcnNlKHRoaXMuZWxlbWVudC52YWwoKSl9KX0saXNWYWxpZDpmdW5jdGlvbigpe3ZhciBlPXRoaXMudmFsdWUoKTtyZXR1cm4gbnVsbD09PWU/ITE6ZT09PXRoaXMuX2FkanVzdFZhbHVlKGUpfSxfdmFsdWU6ZnVuY3Rpb24oZSx0KXt2YXIgaTtcIlwiIT09ZSYmKGk9dGhpcy5fcGFyc2UoZSksbnVsbCE9PWkmJih0fHwoaT10aGlzLl9hZGp1c3RWYWx1ZShpKSksZT10aGlzLl9mb3JtYXQoaSkpKSx0aGlzLmVsZW1lbnQudmFsKGUpLHRoaXMuX3JlZnJlc2goKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQucmVtb3ZlQ2xhc3MoXCJ1aS1zcGlubmVyLWlucHV0XCIpLnByb3AoXCJkaXNhYmxlZFwiLCExKS5yZW1vdmVBdHRyKFwiYXV0b2NvbXBsZXRlXCIpLnJlbW92ZUF0dHIoXCJyb2xlXCIpLnJlbW92ZUF0dHIoXCJhcmlhLXZhbHVlbWluXCIpLnJlbW92ZUF0dHIoXCJhcmlhLXZhbHVlbWF4XCIpLnJlbW92ZUF0dHIoXCJhcmlhLXZhbHVlbm93XCIpLHRoaXMudWlTcGlubmVyLnJlcGxhY2VXaXRoKHRoaXMuZWxlbWVudCl9LHN0ZXBVcDpoKGZ1bmN0aW9uKGUpe3RoaXMuX3N0ZXBVcChlKX0pLF9zdGVwVXA6ZnVuY3Rpb24oZSl7dGhpcy5fc3RhcnQoKSYmKHRoaXMuX3NwaW4oKGV8fDEpKnRoaXMub3B0aW9ucy5zdGVwKSx0aGlzLl9zdG9wKCkpfSxzdGVwRG93bjpoKGZ1bmN0aW9uKGUpe3RoaXMuX3N0ZXBEb3duKGUpfSksX3N0ZXBEb3duOmZ1bmN0aW9uKGUpe3RoaXMuX3N0YXJ0KCkmJih0aGlzLl9zcGluKChlfHwxKSotdGhpcy5vcHRpb25zLnN0ZXApLHRoaXMuX3N0b3AoKSl9LHBhZ2VVcDpoKGZ1bmN0aW9uKGUpe3RoaXMuX3N0ZXBVcCgoZXx8MSkqdGhpcy5vcHRpb25zLnBhZ2UpfSkscGFnZURvd246aChmdW5jdGlvbihlKXt0aGlzLl9zdGVwRG93bigoZXx8MSkqdGhpcy5vcHRpb25zLnBhZ2UpfSksdmFsdWU6ZnVuY3Rpb24oZSl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KGgodGhpcy5fdmFsdWUpLmNhbGwodGhpcyxlKSx2b2lkIDApOnRoaXMuX3BhcnNlKHRoaXMuZWxlbWVudC52YWwoKSl9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnVpU3Bpbm5lcn19KSxlLndpZGdldChcInVpLnRhYnNcIix7dmVyc2lvbjpcIjEuMTEuNFwiLGRlbGF5OjMwMCxvcHRpb25zOnthY3RpdmU6bnVsbCxjb2xsYXBzaWJsZTohMSxldmVudDpcImNsaWNrXCIsaGVpZ2h0U3R5bGU6XCJjb250ZW50XCIsaGlkZTpudWxsLHNob3c6bnVsbCxhY3RpdmF0ZTpudWxsLGJlZm9yZUFjdGl2YXRlOm51bGwsYmVmb3JlTG9hZDpudWxsLGxvYWQ6bnVsbH0sX2lzTG9jYWw6ZnVuY3Rpb24oKXt2YXIgZT0vIy4qJC87cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBpLHM7dD10LmNsb25lTm9kZSghMSksaT10LmhyZWYucmVwbGFjZShlLFwiXCIpLHM9bG9jYXRpb24uaHJlZi5yZXBsYWNlKGUsXCJcIik7dHJ5e2k9ZGVjb2RlVVJJQ29tcG9uZW50KGkpfWNhdGNoKG4pe310cnl7cz1kZWNvZGVVUklDb21wb25lbnQocyl9Y2F0Y2gobil7fXJldHVybiB0Lmhhc2gubGVuZ3RoPjEmJmk9PT1zfX0oKSxfY3JlYXRlOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxpPXRoaXMub3B0aW9uczt0aGlzLnJ1bm5pbmc9ITEsdGhpcy5lbGVtZW50LmFkZENsYXNzKFwidWktdGFicyB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktY29ybmVyLWFsbFwiKS50b2dnbGVDbGFzcyhcInVpLXRhYnMtY29sbGFwc2libGVcIixpLmNvbGxhcHNpYmxlKSx0aGlzLl9wcm9jZXNzVGFicygpLGkuYWN0aXZlPXRoaXMuX2luaXRpYWxBY3RpdmUoKSxlLmlzQXJyYXkoaS5kaXNhYmxlZCkmJihpLmRpc2FibGVkPWUudW5pcXVlKGkuZGlzYWJsZWQuY29uY2F0KGUubWFwKHRoaXMudGFicy5maWx0ZXIoXCIudWktc3RhdGUtZGlzYWJsZWRcIiksZnVuY3Rpb24oZSl7cmV0dXJuIHQudGFicy5pbmRleChlKX0pKSkuc29ydCgpKSx0aGlzLmFjdGl2ZT10aGlzLm9wdGlvbnMuYWN0aXZlIT09ITEmJnRoaXMuYW5jaG9ycy5sZW5ndGg/dGhpcy5fZmluZEFjdGl2ZShpLmFjdGl2ZSk6ZSgpLHRoaXMuX3JlZnJlc2goKSx0aGlzLmFjdGl2ZS5sZW5ndGgmJnRoaXMubG9hZChpLmFjdGl2ZSl9LF9pbml0aWFsQWN0aXZlOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5vcHRpb25zLmFjdGl2ZSxpPXRoaXMub3B0aW9ucy5jb2xsYXBzaWJsZSxzPWxvY2F0aW9uLmhhc2guc3Vic3RyaW5nKDEpO3JldHVybiBudWxsPT09dCYmKHMmJnRoaXMudGFicy5lYWNoKGZ1bmN0aW9uKGksbil7cmV0dXJuIGUobikuYXR0cihcImFyaWEtY29udHJvbHNcIik9PT1zPyh0PWksITEpOnZvaWQgMH0pLG51bGw9PT10JiYodD10aGlzLnRhYnMuaW5kZXgodGhpcy50YWJzLmZpbHRlcihcIi51aS10YWJzLWFjdGl2ZVwiKSkpLChudWxsPT09dHx8LTE9PT10KSYmKHQ9dGhpcy50YWJzLmxlbmd0aD8wOiExKSksdCE9PSExJiYodD10aGlzLnRhYnMuaW5kZXgodGhpcy50YWJzLmVxKHQpKSwtMT09PXQmJih0PWk/ITE6MCkpLCFpJiZ0PT09ITEmJnRoaXMuYW5jaG9ycy5sZW5ndGgmJih0PTApLHR9LF9nZXRDcmVhdGVFdmVudERhdGE6ZnVuY3Rpb24oKXtyZXR1cm57dGFiOnRoaXMuYWN0aXZlLHBhbmVsOnRoaXMuYWN0aXZlLmxlbmd0aD90aGlzLl9nZXRQYW5lbEZvclRhYih0aGlzLmFjdGl2ZSk6ZSgpfX0sX3RhYktleWRvd246ZnVuY3Rpb24odCl7dmFyIGk9ZSh0aGlzLmRvY3VtZW50WzBdLmFjdGl2ZUVsZW1lbnQpLmNsb3Nlc3QoXCJsaVwiKSxzPXRoaXMudGFicy5pbmRleChpKSxuPSEwO2lmKCF0aGlzLl9oYW5kbGVQYWdlTmF2KHQpKXtzd2l0Y2godC5rZXlDb2RlKXtjYXNlIGUudWkua2V5Q29kZS5SSUdIVDpjYXNlIGUudWkua2V5Q29kZS5ET1dOOnMrKzticmVhaztjYXNlIGUudWkua2V5Q29kZS5VUDpjYXNlIGUudWkua2V5Q29kZS5MRUZUOm49ITEscy0tO2JyZWFrO2Nhc2UgZS51aS5rZXlDb2RlLkVORDpzPXRoaXMuYW5jaG9ycy5sZW5ndGgtMTticmVhaztjYXNlIGUudWkua2V5Q29kZS5IT01FOnM9MDticmVhaztjYXNlIGUudWkua2V5Q29kZS5TUEFDRTpyZXR1cm4gdC5wcmV2ZW50RGVmYXVsdCgpLGNsZWFyVGltZW91dCh0aGlzLmFjdGl2YXRpbmcpLHRoaXMuX2FjdGl2YXRlKHMpLHZvaWQgMDtjYXNlIGUudWkua2V5Q29kZS5FTlRFUjpyZXR1cm4gdC5wcmV2ZW50RGVmYXVsdCgpLGNsZWFyVGltZW91dCh0aGlzLmFjdGl2YXRpbmcpLHRoaXMuX2FjdGl2YXRlKHM9PT10aGlzLm9wdGlvbnMuYWN0aXZlPyExOnMpLHZvaWQgMDtkZWZhdWx0OnJldHVybn10LnByZXZlbnREZWZhdWx0KCksY2xlYXJUaW1lb3V0KHRoaXMuYWN0aXZhdGluZykscz10aGlzLl9mb2N1c05leHRUYWIocyxuKSx0LmN0cmxLZXl8fHQubWV0YUtleXx8KGkuYXR0cihcImFyaWEtc2VsZWN0ZWRcIixcImZhbHNlXCIpLHRoaXMudGFicy5lcShzKS5hdHRyKFwiYXJpYS1zZWxlY3RlZFwiLFwidHJ1ZVwiKSx0aGlzLmFjdGl2YXRpbmc9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLm9wdGlvbihcImFjdGl2ZVwiLHMpfSx0aGlzLmRlbGF5KSl9fSxfcGFuZWxLZXlkb3duOmZ1bmN0aW9uKHQpe3RoaXMuX2hhbmRsZVBhZ2VOYXYodCl8fHQuY3RybEtleSYmdC5rZXlDb2RlPT09ZS51aS5rZXlDb2RlLlVQJiYodC5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuYWN0aXZlLmZvY3VzKCkpfSxfaGFuZGxlUGFnZU5hdjpmdW5jdGlvbih0KXtyZXR1cm4gdC5hbHRLZXkmJnQua2V5Q29kZT09PWUudWkua2V5Q29kZS5QQUdFX1VQPyh0aGlzLl9hY3RpdmF0ZSh0aGlzLl9mb2N1c05leHRUYWIodGhpcy5vcHRpb25zLmFjdGl2ZS0xLCExKSksITApOnQuYWx0S2V5JiZ0LmtleUNvZGU9PT1lLnVpLmtleUNvZGUuUEFHRV9ET1dOPyh0aGlzLl9hY3RpdmF0ZSh0aGlzLl9mb2N1c05leHRUYWIodGhpcy5vcHRpb25zLmFjdGl2ZSsxLCEwKSksITApOnZvaWQgMH0sX2ZpbmROZXh0VGFiOmZ1bmN0aW9uKHQsaSl7ZnVuY3Rpb24gcygpe3JldHVybiB0Pm4mJih0PTApLDA+dCYmKHQ9biksdH1mb3IodmFyIG49dGhpcy50YWJzLmxlbmd0aC0xOy0xIT09ZS5pbkFycmF5KHMoKSx0aGlzLm9wdGlvbnMuZGlzYWJsZWQpOyl0PWk/dCsxOnQtMTtyZXR1cm4gdH0sX2ZvY3VzTmV4dFRhYjpmdW5jdGlvbihlLHQpe3JldHVybiBlPXRoaXMuX2ZpbmROZXh0VGFiKGUsdCksdGhpcy50YWJzLmVxKGUpLmZvY3VzKCksZX0sX3NldE9wdGlvbjpmdW5jdGlvbihlLHQpe3JldHVyblwiYWN0aXZlXCI9PT1lPyh0aGlzLl9hY3RpdmF0ZSh0KSx2b2lkIDApOlwiZGlzYWJsZWRcIj09PWU/KHRoaXMuX3NldHVwRGlzYWJsZWQodCksdm9pZCAwKToodGhpcy5fc3VwZXIoZSx0KSxcImNvbGxhcHNpYmxlXCI9PT1lJiYodGhpcy5lbGVtZW50LnRvZ2dsZUNsYXNzKFwidWktdGFicy1jb2xsYXBzaWJsZVwiLHQpLHR8fHRoaXMub3B0aW9ucy5hY3RpdmUhPT0hMXx8dGhpcy5fYWN0aXZhdGUoMCkpLFwiZXZlbnRcIj09PWUmJnRoaXMuX3NldHVwRXZlbnRzKHQpLFwiaGVpZ2h0U3R5bGVcIj09PWUmJnRoaXMuX3NldHVwSGVpZ2h0U3R5bGUodCksdm9pZCAwKX0sX3Nhbml0aXplU2VsZWN0b3I6ZnVuY3Rpb24oZSl7cmV0dXJuIGU/ZS5yZXBsYWNlKC9bIVwiJCUmJygpKissLlxcLzo7PD0+P0BcXFtcXF1cXF5ge3x9fl0vZyxcIlxcXFwkJlwiKTpcIlwifSxyZWZyZXNoOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5vcHRpb25zLGk9dGhpcy50YWJsaXN0LmNoaWxkcmVuKFwiOmhhcyhhW2hyZWZdKVwiKTt0LmRpc2FibGVkPWUubWFwKGkuZmlsdGVyKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpLGZ1bmN0aW9uKGUpe3JldHVybiBpLmluZGV4KGUpfSksdGhpcy5fcHJvY2Vzc1RhYnMoKSx0LmFjdGl2ZSE9PSExJiZ0aGlzLmFuY2hvcnMubGVuZ3RoP3RoaXMuYWN0aXZlLmxlbmd0aCYmIWUuY29udGFpbnModGhpcy50YWJsaXN0WzBdLHRoaXMuYWN0aXZlWzBdKT90aGlzLnRhYnMubGVuZ3RoPT09dC5kaXNhYmxlZC5sZW5ndGg/KHQuYWN0aXZlPSExLHRoaXMuYWN0aXZlPWUoKSk6dGhpcy5fYWN0aXZhdGUodGhpcy5fZmluZE5leHRUYWIoTWF0aC5tYXgoMCx0LmFjdGl2ZS0xKSwhMSkpOnQuYWN0aXZlPXRoaXMudGFicy5pbmRleCh0aGlzLmFjdGl2ZSk6KHQuYWN0aXZlPSExLHRoaXMuYWN0aXZlPWUoKSksdGhpcy5fcmVmcmVzaCgpfSxfcmVmcmVzaDpmdW5jdGlvbigpe3RoaXMuX3NldHVwRGlzYWJsZWQodGhpcy5vcHRpb25zLmRpc2FibGVkKSx0aGlzLl9zZXR1cEV2ZW50cyh0aGlzLm9wdGlvbnMuZXZlbnQpLHRoaXMuX3NldHVwSGVpZ2h0U3R5bGUodGhpcy5vcHRpb25zLmhlaWdodFN0eWxlKSx0aGlzLnRhYnMubm90KHRoaXMuYWN0aXZlKS5hdHRyKHtcImFyaWEtc2VsZWN0ZWRcIjpcImZhbHNlXCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJmYWxzZVwiLHRhYkluZGV4Oi0xfSksdGhpcy5wYW5lbHMubm90KHRoaXMuX2dldFBhbmVsRm9yVGFiKHRoaXMuYWN0aXZlKSkuaGlkZSgpLmF0dHIoe1wiYXJpYS1oaWRkZW5cIjpcInRydWVcIn0pLHRoaXMuYWN0aXZlLmxlbmd0aD8odGhpcy5hY3RpdmUuYWRkQ2xhc3MoXCJ1aS10YWJzLWFjdGl2ZSB1aS1zdGF0ZS1hY3RpdmVcIikuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJ0cnVlXCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJ0cnVlXCIsdGFiSW5kZXg6MH0pLHRoaXMuX2dldFBhbmVsRm9yVGFiKHRoaXMuYWN0aXZlKS5zaG93KCkuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwiZmFsc2VcIn0pKTp0aGlzLnRhYnMuZXEoMCkuYXR0cihcInRhYkluZGV4XCIsMCl9LF9wcm9jZXNzVGFiczpmdW5jdGlvbigpe3ZhciB0PXRoaXMsaT10aGlzLnRhYnMscz10aGlzLmFuY2hvcnMsbj10aGlzLnBhbmVscztcclxudGhpcy50YWJsaXN0PXRoaXMuX2dldExpc3QoKS5hZGRDbGFzcyhcInVpLXRhYnMtbmF2IHVpLWhlbHBlci1yZXNldCB1aS1oZWxwZXItY2xlYXJmaXggdWktd2lkZ2V0LWhlYWRlciB1aS1jb3JuZXItYWxsXCIpLmF0dHIoXCJyb2xlXCIsXCJ0YWJsaXN0XCIpLmRlbGVnYXRlKFwiPiBsaVwiLFwibW91c2Vkb3duXCIrdGhpcy5ldmVudE5hbWVzcGFjZSxmdW5jdGlvbih0KXtlKHRoaXMpLmlzKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpJiZ0LnByZXZlbnREZWZhdWx0KCl9KS5kZWxlZ2F0ZShcIi51aS10YWJzLWFuY2hvclwiLFwiZm9jdXNcIit0aGlzLmV2ZW50TmFtZXNwYWNlLGZ1bmN0aW9uKCl7ZSh0aGlzKS5jbG9zZXN0KFwibGlcIikuaXMoXCIudWktc3RhdGUtZGlzYWJsZWRcIikmJnRoaXMuYmx1cigpfSksdGhpcy50YWJzPXRoaXMudGFibGlzdC5maW5kKFwiPiBsaTpoYXMoYVtocmVmXSlcIikuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1kZWZhdWx0IHVpLWNvcm5lci10b3BcIikuYXR0cih7cm9sZTpcInRhYlwiLHRhYkluZGV4Oi0xfSksdGhpcy5hbmNob3JzPXRoaXMudGFicy5tYXAoZnVuY3Rpb24oKXtyZXR1cm4gZShcImFcIix0aGlzKVswXX0pLmFkZENsYXNzKFwidWktdGFicy1hbmNob3JcIikuYXR0cih7cm9sZTpcInByZXNlbnRhdGlvblwiLHRhYkluZGV4Oi0xfSksdGhpcy5wYW5lbHM9ZSgpLHRoaXMuYW5jaG9ycy5lYWNoKGZ1bmN0aW9uKGkscyl7dmFyIG4sYSxvLHI9ZShzKS51bmlxdWVJZCgpLmF0dHIoXCJpZFwiKSxoPWUocykuY2xvc2VzdChcImxpXCIpLGw9aC5hdHRyKFwiYXJpYS1jb250cm9sc1wiKTt0Ll9pc0xvY2FsKHMpPyhuPXMuaGFzaCxvPW4uc3Vic3RyaW5nKDEpLGE9dC5lbGVtZW50LmZpbmQodC5fc2FuaXRpemVTZWxlY3RvcihuKSkpOihvPWguYXR0cihcImFyaWEtY29udHJvbHNcIil8fGUoe30pLnVuaXF1ZUlkKClbMF0uaWQsbj1cIiNcIitvLGE9dC5lbGVtZW50LmZpbmQobiksYS5sZW5ndGh8fChhPXQuX2NyZWF0ZVBhbmVsKG8pLGEuaW5zZXJ0QWZ0ZXIodC5wYW5lbHNbaS0xXXx8dC50YWJsaXN0KSksYS5hdHRyKFwiYXJpYS1saXZlXCIsXCJwb2xpdGVcIikpLGEubGVuZ3RoJiYodC5wYW5lbHM9dC5wYW5lbHMuYWRkKGEpKSxsJiZoLmRhdGEoXCJ1aS10YWJzLWFyaWEtY29udHJvbHNcIixsKSxoLmF0dHIoe1wiYXJpYS1jb250cm9sc1wiOm8sXCJhcmlhLWxhYmVsbGVkYnlcIjpyfSksYS5hdHRyKFwiYXJpYS1sYWJlbGxlZGJ5XCIscil9KSx0aGlzLnBhbmVscy5hZGRDbGFzcyhcInVpLXRhYnMtcGFuZWwgdWktd2lkZ2V0LWNvbnRlbnQgdWktY29ybmVyLWJvdHRvbVwiKS5hdHRyKFwicm9sZVwiLFwidGFicGFuZWxcIiksaSYmKHRoaXMuX29mZihpLm5vdCh0aGlzLnRhYnMpKSx0aGlzLl9vZmYocy5ub3QodGhpcy5hbmNob3JzKSksdGhpcy5fb2ZmKG4ubm90KHRoaXMucGFuZWxzKSkpfSxfZ2V0TGlzdDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnRhYmxpc3R8fHRoaXMuZWxlbWVudC5maW5kKFwib2wsdWxcIikuZXEoMCl9LF9jcmVhdGVQYW5lbDpmdW5jdGlvbih0KXtyZXR1cm4gZShcIjxkaXY+XCIpLmF0dHIoXCJpZFwiLHQpLmFkZENsYXNzKFwidWktdGFicy1wYW5lbCB1aS13aWRnZXQtY29udGVudCB1aS1jb3JuZXItYm90dG9tXCIpLmRhdGEoXCJ1aS10YWJzLWRlc3Ryb3lcIiwhMCl9LF9zZXR1cERpc2FibGVkOmZ1bmN0aW9uKHQpe2UuaXNBcnJheSh0KSYmKHQubGVuZ3RoP3QubGVuZ3RoPT09dGhpcy5hbmNob3JzLmxlbmd0aCYmKHQ9ITApOnQ9ITEpO2Zvcih2YXIgaSxzPTA7aT10aGlzLnRhYnNbc107cysrKXQ9PT0hMHx8LTEhPT1lLmluQXJyYXkocyx0KT9lKGkpLmFkZENsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcInRydWVcIik6ZShpKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWRpc2FibGVkXCIpO3RoaXMub3B0aW9ucy5kaXNhYmxlZD10fSxfc2V0dXBFdmVudHM6ZnVuY3Rpb24odCl7dmFyIGk9e307dCYmZS5lYWNoKHQuc3BsaXQoXCIgXCIpLGZ1bmN0aW9uKGUsdCl7aVt0XT1cIl9ldmVudEhhbmRsZXJcIn0pLHRoaXMuX29mZih0aGlzLmFuY2hvcnMuYWRkKHRoaXMudGFicykuYWRkKHRoaXMucGFuZWxzKSksdGhpcy5fb24oITAsdGhpcy5hbmNob3JzLHtjbGljazpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCl9fSksdGhpcy5fb24odGhpcy5hbmNob3JzLGkpLHRoaXMuX29uKHRoaXMudGFicyx7a2V5ZG93bjpcIl90YWJLZXlkb3duXCJ9KSx0aGlzLl9vbih0aGlzLnBhbmVscyx7a2V5ZG93bjpcIl9wYW5lbEtleWRvd25cIn0pLHRoaXMuX2ZvY3VzYWJsZSh0aGlzLnRhYnMpLHRoaXMuX2hvdmVyYWJsZSh0aGlzLnRhYnMpfSxfc2V0dXBIZWlnaHRTdHlsZTpmdW5jdGlvbih0KXt2YXIgaSxzPXRoaXMuZWxlbWVudC5wYXJlbnQoKTtcImZpbGxcIj09PXQ/KGk9cy5oZWlnaHQoKSxpLT10aGlzLmVsZW1lbnQub3V0ZXJIZWlnaHQoKS10aGlzLmVsZW1lbnQuaGVpZ2h0KCksdGhpcy5lbGVtZW50LnNpYmxpbmdzKFwiOnZpc2libGVcIikuZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcykscz10LmNzcyhcInBvc2l0aW9uXCIpO1wiYWJzb2x1dGVcIiE9PXMmJlwiZml4ZWRcIiE9PXMmJihpLT10Lm91dGVySGVpZ2h0KCEwKSl9KSx0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5ub3QodGhpcy5wYW5lbHMpLmVhY2goZnVuY3Rpb24oKXtpLT1lKHRoaXMpLm91dGVySGVpZ2h0KCEwKX0pLHRoaXMucGFuZWxzLmVhY2goZnVuY3Rpb24oKXtlKHRoaXMpLmhlaWdodChNYXRoLm1heCgwLGktZSh0aGlzKS5pbm5lckhlaWdodCgpK2UodGhpcykuaGVpZ2h0KCkpKX0pLmNzcyhcIm92ZXJmbG93XCIsXCJhdXRvXCIpKTpcImF1dG9cIj09PXQmJihpPTAsdGhpcy5wYW5lbHMuZWFjaChmdW5jdGlvbigpe2k9TWF0aC5tYXgoaSxlKHRoaXMpLmhlaWdodChcIlwiKS5oZWlnaHQoKSl9KS5oZWlnaHQoaSkpfSxfZXZlbnRIYW5kbGVyOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMub3B0aW9ucyxzPXRoaXMuYWN0aXZlLG49ZSh0LmN1cnJlbnRUYXJnZXQpLGE9bi5jbG9zZXN0KFwibGlcIiksbz1hWzBdPT09c1swXSxyPW8mJmkuY29sbGFwc2libGUsaD1yP2UoKTp0aGlzLl9nZXRQYW5lbEZvclRhYihhKSxsPXMubGVuZ3RoP3RoaXMuX2dldFBhbmVsRm9yVGFiKHMpOmUoKSx1PXtvbGRUYWI6cyxvbGRQYW5lbDpsLG5ld1RhYjpyP2UoKTphLG5ld1BhbmVsOmh9O3QucHJldmVudERlZmF1bHQoKSxhLmhhc0NsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIil8fGEuaGFzQ2xhc3MoXCJ1aS10YWJzLWxvYWRpbmdcIil8fHRoaXMucnVubmluZ3x8byYmIWkuY29sbGFwc2libGV8fHRoaXMuX3RyaWdnZXIoXCJiZWZvcmVBY3RpdmF0ZVwiLHQsdSk9PT0hMXx8KGkuYWN0aXZlPXI/ITE6dGhpcy50YWJzLmluZGV4KGEpLHRoaXMuYWN0aXZlPW8/ZSgpOmEsdGhpcy54aHImJnRoaXMueGhyLmFib3J0KCksbC5sZW5ndGh8fGgubGVuZ3RofHxlLmVycm9yKFwialF1ZXJ5IFVJIFRhYnM6IE1pc21hdGNoaW5nIGZyYWdtZW50IGlkZW50aWZpZXIuXCIpLGgubGVuZ3RoJiZ0aGlzLmxvYWQodGhpcy50YWJzLmluZGV4KGEpLHQpLHRoaXMuX3RvZ2dsZSh0LHUpKX0sX3RvZ2dsZTpmdW5jdGlvbih0LGkpe2Z1bmN0aW9uIHMoKXthLnJ1bm5pbmc9ITEsYS5fdHJpZ2dlcihcImFjdGl2YXRlXCIsdCxpKX1mdW5jdGlvbiBuKCl7aS5uZXdUYWIuY2xvc2VzdChcImxpXCIpLmFkZENsYXNzKFwidWktdGFicy1hY3RpdmUgdWktc3RhdGUtYWN0aXZlXCIpLG8ubGVuZ3RoJiZhLm9wdGlvbnMuc2hvdz9hLl9zaG93KG8sYS5vcHRpb25zLnNob3cscyk6KG8uc2hvdygpLHMoKSl9dmFyIGE9dGhpcyxvPWkubmV3UGFuZWwscj1pLm9sZFBhbmVsO3RoaXMucnVubmluZz0hMCxyLmxlbmd0aCYmdGhpcy5vcHRpb25zLmhpZGU/dGhpcy5faGlkZShyLHRoaXMub3B0aW9ucy5oaWRlLGZ1bmN0aW9uKCl7aS5vbGRUYWIuY2xvc2VzdChcImxpXCIpLnJlbW92ZUNsYXNzKFwidWktdGFicy1hY3RpdmUgdWktc3RhdGUtYWN0aXZlXCIpLG4oKX0pOihpLm9sZFRhYi5jbG9zZXN0KFwibGlcIikucmVtb3ZlQ2xhc3MoXCJ1aS10YWJzLWFjdGl2ZSB1aS1zdGF0ZS1hY3RpdmVcIiksci5oaWRlKCksbigpKSxyLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwidHJ1ZVwiKSxpLm9sZFRhYi5hdHRyKHtcImFyaWEtc2VsZWN0ZWRcIjpcImZhbHNlXCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJmYWxzZVwifSksby5sZW5ndGgmJnIubGVuZ3RoP2kub2xkVGFiLmF0dHIoXCJ0YWJJbmRleFwiLC0xKTpvLmxlbmd0aCYmdGhpcy50YWJzLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiAwPT09ZSh0aGlzKS5hdHRyKFwidGFiSW5kZXhcIil9KS5hdHRyKFwidGFiSW5kZXhcIiwtMSksby5hdHRyKFwiYXJpYS1oaWRkZW5cIixcImZhbHNlXCIpLGkubmV3VGFiLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwidHJ1ZVwiLHRhYkluZGV4OjB9KX0sX2FjdGl2YXRlOmZ1bmN0aW9uKHQpe3ZhciBpLHM9dGhpcy5fZmluZEFjdGl2ZSh0KTtzWzBdIT09dGhpcy5hY3RpdmVbMF0mJihzLmxlbmd0aHx8KHM9dGhpcy5hY3RpdmUpLGk9cy5maW5kKFwiLnVpLXRhYnMtYW5jaG9yXCIpWzBdLHRoaXMuX2V2ZW50SGFuZGxlcih7dGFyZ2V0OmksY3VycmVudFRhcmdldDppLHByZXZlbnREZWZhdWx0OmUubm9vcH0pKX0sX2ZpbmRBY3RpdmU6ZnVuY3Rpb24odCl7cmV0dXJuIHQ9PT0hMT9lKCk6dGhpcy50YWJzLmVxKHQpfSxfZ2V0SW5kZXg6ZnVuY3Rpb24oZSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGUmJihlPXRoaXMuYW5jaG9ycy5pbmRleCh0aGlzLmFuY2hvcnMuZmlsdGVyKFwiW2hyZWYkPSdcIitlK1wiJ11cIikpKSxlfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMueGhyJiZ0aGlzLnhoci5hYm9ydCgpLHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcyhcInVpLXRhYnMgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWNvcm5lci1hbGwgdWktdGFicy1jb2xsYXBzaWJsZVwiKSx0aGlzLnRhYmxpc3QucmVtb3ZlQ2xhc3MoXCJ1aS10YWJzLW5hdiB1aS1oZWxwZXItcmVzZXQgdWktaGVscGVyLWNsZWFyZml4IHVpLXdpZGdldC1oZWFkZXIgdWktY29ybmVyLWFsbFwiKS5yZW1vdmVBdHRyKFwicm9sZVwiKSx0aGlzLmFuY2hvcnMucmVtb3ZlQ2xhc3MoXCJ1aS10YWJzLWFuY2hvclwiKS5yZW1vdmVBdHRyKFwicm9sZVwiKS5yZW1vdmVBdHRyKFwidGFiSW5kZXhcIikucmVtb3ZlVW5pcXVlSWQoKSx0aGlzLnRhYmxpc3QudW5iaW5kKHRoaXMuZXZlbnROYW1lc3BhY2UpLHRoaXMudGFicy5hZGQodGhpcy5wYW5lbHMpLmVhY2goZnVuY3Rpb24oKXtlLmRhdGEodGhpcyxcInVpLXRhYnMtZGVzdHJveVwiKT9lKHRoaXMpLnJlbW92ZSgpOmUodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1kZWZhdWx0IHVpLXN0YXRlLWFjdGl2ZSB1aS1zdGF0ZS1kaXNhYmxlZCB1aS1jb3JuZXItdG9wIHVpLWNvcm5lci1ib3R0b20gdWktd2lkZ2V0LWNvbnRlbnQgdWktdGFicy1hY3RpdmUgdWktdGFicy1wYW5lbFwiKS5yZW1vdmVBdHRyKFwidGFiSW5kZXhcIikucmVtb3ZlQXR0cihcImFyaWEtbGl2ZVwiKS5yZW1vdmVBdHRyKFwiYXJpYS1idXN5XCIpLnJlbW92ZUF0dHIoXCJhcmlhLXNlbGVjdGVkXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWxhYmVsbGVkYnlcIikucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuXCIpLnJlbW92ZUF0dHIoXCJhcmlhLWV4cGFuZGVkXCIpLnJlbW92ZUF0dHIoXCJyb2xlXCIpfSksdGhpcy50YWJzLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpLGk9dC5kYXRhKFwidWktdGFicy1hcmlhLWNvbnRyb2xzXCIpO2k/dC5hdHRyKFwiYXJpYS1jb250cm9sc1wiLGkpLnJlbW92ZURhdGEoXCJ1aS10YWJzLWFyaWEtY29udHJvbHNcIik6dC5yZW1vdmVBdHRyKFwiYXJpYS1jb250cm9sc1wiKX0pLHRoaXMucGFuZWxzLnNob3coKSxcImNvbnRlbnRcIiE9PXRoaXMub3B0aW9ucy5oZWlnaHRTdHlsZSYmdGhpcy5wYW5lbHMuY3NzKFwiaGVpZ2h0XCIsXCJcIil9LGVuYWJsZTpmdW5jdGlvbih0KXt2YXIgaT10aGlzLm9wdGlvbnMuZGlzYWJsZWQ7aSE9PSExJiYodm9pZCAwPT09dD9pPSExOih0PXRoaXMuX2dldEluZGV4KHQpLGk9ZS5pc0FycmF5KGkpP2UubWFwKGksZnVuY3Rpb24oZSl7cmV0dXJuIGUhPT10P2U6bnVsbH0pOmUubWFwKHRoaXMudGFicyxmdW5jdGlvbihlLGkpe3JldHVybiBpIT09dD9pOm51bGx9KSksdGhpcy5fc2V0dXBEaXNhYmxlZChpKSl9LGRpc2FibGU6ZnVuY3Rpb24odCl7dmFyIGk9dGhpcy5vcHRpb25zLmRpc2FibGVkO2lmKGkhPT0hMCl7aWYodm9pZCAwPT09dClpPSEwO2Vsc2V7aWYodD10aGlzLl9nZXRJbmRleCh0KSwtMSE9PWUuaW5BcnJheSh0LGkpKXJldHVybjtpPWUuaXNBcnJheShpKT9lLm1lcmdlKFt0XSxpKS5zb3J0KCk6W3RdfXRoaXMuX3NldHVwRGlzYWJsZWQoaSl9fSxsb2FkOmZ1bmN0aW9uKHQsaSl7dD10aGlzLl9nZXRJbmRleCh0KTt2YXIgcz10aGlzLG49dGhpcy50YWJzLmVxKHQpLGE9bi5maW5kKFwiLnVpLXRhYnMtYW5jaG9yXCIpLG89dGhpcy5fZ2V0UGFuZWxGb3JUYWIobikscj17dGFiOm4scGFuZWw6b30saD1mdW5jdGlvbihlLHQpe1wiYWJvcnRcIj09PXQmJnMucGFuZWxzLnN0b3AoITEsITApLG4ucmVtb3ZlQ2xhc3MoXCJ1aS10YWJzLWxvYWRpbmdcIiksby5yZW1vdmVBdHRyKFwiYXJpYS1idXN5XCIpLGU9PT1zLnhociYmZGVsZXRlIHMueGhyfTt0aGlzLl9pc0xvY2FsKGFbMF0pfHwodGhpcy54aHI9ZS5hamF4KHRoaXMuX2FqYXhTZXR0aW5ncyhhLGkscikpLHRoaXMueGhyJiZcImNhbmNlbGVkXCIhPT10aGlzLnhoci5zdGF0dXNUZXh0JiYobi5hZGRDbGFzcyhcInVpLXRhYnMtbG9hZGluZ1wiKSxvLmF0dHIoXCJhcmlhLWJ1c3lcIixcInRydWVcIiksdGhpcy54aHIuZG9uZShmdW5jdGlvbihlLHQsbil7c2V0VGltZW91dChmdW5jdGlvbigpe28uaHRtbChlKSxzLl90cmlnZ2VyKFwibG9hZFwiLGksciksaChuLHQpfSwxKX0pLmZhaWwoZnVuY3Rpb24oZSx0KXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aChlLHQpfSwxKX0pKSl9LF9hamF4U2V0dGluZ3M6ZnVuY3Rpb24odCxpLHMpe3ZhciBuPXRoaXM7cmV0dXJue3VybDp0LmF0dHIoXCJocmVmXCIpLGJlZm9yZVNlbmQ6ZnVuY3Rpb24odCxhKXtyZXR1cm4gbi5fdHJpZ2dlcihcImJlZm9yZUxvYWRcIixpLGUuZXh0ZW5kKHtqcVhIUjp0LGFqYXhTZXR0aW5nczphfSxzKSl9fX0sX2dldFBhbmVsRm9yVGFiOmZ1bmN0aW9uKHQpe3ZhciBpPWUodCkuYXR0cihcImFyaWEtY29udHJvbHNcIik7cmV0dXJuIHRoaXMuZWxlbWVudC5maW5kKHRoaXMuX3Nhbml0aXplU2VsZWN0b3IoXCIjXCIraSkpfX0pLGUud2lkZ2V0KFwidWkudG9vbHRpcFwiLHt2ZXJzaW9uOlwiMS4xMS40XCIsb3B0aW9uczp7Y29udGVudDpmdW5jdGlvbigpe3ZhciB0PWUodGhpcykuYXR0cihcInRpdGxlXCIpfHxcIlwiO3JldHVybiBlKFwiPGE+XCIpLnRleHQodCkuaHRtbCgpfSxoaWRlOiEwLGl0ZW1zOlwiW3RpdGxlXTpub3QoW2Rpc2FibGVkXSlcIixwb3NpdGlvbjp7bXk6XCJsZWZ0IHRvcCsxNVwiLGF0OlwibGVmdCBib3R0b21cIixjb2xsaXNpb246XCJmbGlwZml0IGZsaXBcIn0sc2hvdzohMCx0b29sdGlwQ2xhc3M6bnVsbCx0cmFjazohMSxjbG9zZTpudWxsLG9wZW46bnVsbH0sX2FkZERlc2NyaWJlZEJ5OmZ1bmN0aW9uKHQsaSl7dmFyIHM9KHQuYXR0cihcImFyaWEtZGVzY3JpYmVkYnlcIil8fFwiXCIpLnNwbGl0KC9cXHMrLyk7cy5wdXNoKGkpLHQuZGF0YShcInVpLXRvb2x0aXAtaWRcIixpKS5hdHRyKFwiYXJpYS1kZXNjcmliZWRieVwiLGUudHJpbShzLmpvaW4oXCIgXCIpKSl9LF9yZW1vdmVEZXNjcmliZWRCeTpmdW5jdGlvbih0KXt2YXIgaT10LmRhdGEoXCJ1aS10b29sdGlwLWlkXCIpLHM9KHQuYXR0cihcImFyaWEtZGVzY3JpYmVkYnlcIil8fFwiXCIpLnNwbGl0KC9cXHMrLyksbj1lLmluQXJyYXkoaSxzKTstMSE9PW4mJnMuc3BsaWNlKG4sMSksdC5yZW1vdmVEYXRhKFwidWktdG9vbHRpcC1pZFwiKSxzPWUudHJpbShzLmpvaW4oXCIgXCIpKSxzP3QuYXR0cihcImFyaWEtZGVzY3JpYmVkYnlcIixzKTp0LnJlbW92ZUF0dHIoXCJhcmlhLWRlc2NyaWJlZGJ5XCIpfSxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5fb24oe21vdXNlb3ZlcjpcIm9wZW5cIixmb2N1c2luOlwib3BlblwifSksdGhpcy50b29sdGlwcz17fSx0aGlzLnBhcmVudHM9e30sdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLl9kaXNhYmxlKCksdGhpcy5saXZlUmVnaW9uPWUoXCI8ZGl2PlwiKS5hdHRyKHtyb2xlOlwibG9nXCIsXCJhcmlhLWxpdmVcIjpcImFzc2VydGl2ZVwiLFwiYXJpYS1yZWxldmFudFwiOlwiYWRkaXRpb25zXCJ9KS5hZGRDbGFzcyhcInVpLWhlbHBlci1oaWRkZW4tYWNjZXNzaWJsZVwiKS5hcHBlbmRUbyh0aGlzLmRvY3VtZW50WzBdLmJvZHkpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsaSl7dmFyIHM9dGhpcztyZXR1cm5cImRpc2FibGVkXCI9PT10Pyh0aGlzW2k/XCJfZGlzYWJsZVwiOlwiX2VuYWJsZVwiXSgpLHRoaXMub3B0aW9uc1t0XT1pLHZvaWQgMCk6KHRoaXMuX3N1cGVyKHQsaSksXCJjb250ZW50XCI9PT10JiZlLmVhY2godGhpcy50b29sdGlwcyxmdW5jdGlvbihlLHQpe3MuX3VwZGF0ZUNvbnRlbnQodC5lbGVtZW50KX0pLHZvaWQgMCl9LF9kaXNhYmxlOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztlLmVhY2godGhpcy50b29sdGlwcyxmdW5jdGlvbihpLHMpe3ZhciBuPWUuRXZlbnQoXCJibHVyXCIpO24udGFyZ2V0PW4uY3VycmVudFRhcmdldD1zLmVsZW1lbnRbMF0sdC5jbG9zZShuLCEwKX0pLHRoaXMuZWxlbWVudC5maW5kKHRoaXMub3B0aW9ucy5pdGVtcykuYWRkQmFjaygpLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1lKHRoaXMpO3QuaXMoXCJbdGl0bGVdXCIpJiZ0LmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIsdC5hdHRyKFwidGl0bGVcIikpLnJlbW92ZUF0dHIoXCJ0aXRsZVwiKX0pfSxfZW5hYmxlOmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKS5hZGRCYWNrKCkuZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcyk7dC5kYXRhKFwidWktdG9vbHRpcC10aXRsZVwiKSYmdC5hdHRyKFwidGl0bGVcIix0LmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKX0pfSxvcGVuOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXMscz1lKHQ/dC50YXJnZXQ6dGhpcy5lbGVtZW50KS5jbG9zZXN0KHRoaXMub3B0aW9ucy5pdGVtcyk7cy5sZW5ndGgmJiFzLmRhdGEoXCJ1aS10b29sdGlwLWlkXCIpJiYocy5hdHRyKFwidGl0bGVcIikmJnMuZGF0YShcInVpLXRvb2x0aXAtdGl0bGVcIixzLmF0dHIoXCJ0aXRsZVwiKSkscy5kYXRhKFwidWktdG9vbHRpcC1vcGVuXCIsITApLHQmJlwibW91c2VvdmVyXCI9PT10LnR5cGUmJnMucGFyZW50cygpLmVhY2goZnVuY3Rpb24oKXt2YXIgdCxzPWUodGhpcyk7cy5kYXRhKFwidWktdG9vbHRpcC1vcGVuXCIpJiYodD1lLkV2ZW50KFwiYmx1clwiKSx0LnRhcmdldD10LmN1cnJlbnRUYXJnZXQ9dGhpcyxpLmNsb3NlKHQsITApKSxzLmF0dHIoXCJ0aXRsZVwiKSYmKHMudW5pcXVlSWQoKSxpLnBhcmVudHNbdGhpcy5pZF09e2VsZW1lbnQ6dGhpcyx0aXRsZTpzLmF0dHIoXCJ0aXRsZVwiKX0scy5hdHRyKFwidGl0bGVcIixcIlwiKSl9KSx0aGlzLl9yZWdpc3RlckNsb3NlSGFuZGxlcnModCxzKSx0aGlzLl91cGRhdGVDb250ZW50KHMsdCkpfSxfdXBkYXRlQ29udGVudDpmdW5jdGlvbihlLHQpe3ZhciBpLHM9dGhpcy5vcHRpb25zLmNvbnRlbnQsbj10aGlzLGE9dD90LnR5cGU6bnVsbDtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2Ygcz90aGlzLl9vcGVuKHQsZSxzKTooaT1zLmNhbGwoZVswXSxmdW5jdGlvbihpKXtuLl9kZWxheShmdW5jdGlvbigpe2UuZGF0YShcInVpLXRvb2x0aXAtb3BlblwiKSYmKHQmJih0LnR5cGU9YSksdGhpcy5fb3Blbih0LGUsaSkpfSl9KSxpJiZ0aGlzLl9vcGVuKHQsZSxpKSx2b2lkIDApfSxfb3BlbjpmdW5jdGlvbih0LGkscyl7ZnVuY3Rpb24gbihlKXtsLm9mPWUsby5pcyhcIjpoaWRkZW5cIil8fG8ucG9zaXRpb24obCl9dmFyIGEsbyxyLGgsbD1lLmV4dGVuZCh7fSx0aGlzLm9wdGlvbnMucG9zaXRpb24pO2lmKHMpe2lmKGE9dGhpcy5fZmluZChpKSlyZXR1cm4gYS50b29sdGlwLmZpbmQoXCIudWktdG9vbHRpcC1jb250ZW50XCIpLmh0bWwocyksdm9pZCAwO2kuaXMoXCJbdGl0bGVdXCIpJiYodCYmXCJtb3VzZW92ZXJcIj09PXQudHlwZT9pLmF0dHIoXCJ0aXRsZVwiLFwiXCIpOmkucmVtb3ZlQXR0cihcInRpdGxlXCIpKSxhPXRoaXMuX3Rvb2x0aXAoaSksbz1hLnRvb2x0aXAsdGhpcy5fYWRkRGVzY3JpYmVkQnkoaSxvLmF0dHIoXCJpZFwiKSksby5maW5kKFwiLnVpLXRvb2x0aXAtY29udGVudFwiKS5odG1sKHMpLHRoaXMubGl2ZVJlZ2lvbi5jaGlsZHJlbigpLmhpZGUoKSxzLmNsb25lPyhoPXMuY2xvbmUoKSxoLnJlbW92ZUF0dHIoXCJpZFwiKS5maW5kKFwiW2lkXVwiKS5yZW1vdmVBdHRyKFwiaWRcIikpOmg9cyxlKFwiPGRpdj5cIikuaHRtbChoKS5hcHBlbmRUbyh0aGlzLmxpdmVSZWdpb24pLHRoaXMub3B0aW9ucy50cmFjayYmdCYmL15tb3VzZS8udGVzdCh0LnR5cGUpPyh0aGlzLl9vbih0aGlzLmRvY3VtZW50LHttb3VzZW1vdmU6bn0pLG4odCkpOm8ucG9zaXRpb24oZS5leHRlbmQoe29mOml9LHRoaXMub3B0aW9ucy5wb3NpdGlvbikpLG8uaGlkZSgpLHRoaXMuX3Nob3cobyx0aGlzLm9wdGlvbnMuc2hvdyksdGhpcy5vcHRpb25zLnNob3cmJnRoaXMub3B0aW9ucy5zaG93LmRlbGF5JiYocj10aGlzLmRlbGF5ZWRTaG93PXNldEludGVydmFsKGZ1bmN0aW9uKCl7by5pcyhcIjp2aXNpYmxlXCIpJiYobihsLm9mKSxjbGVhckludGVydmFsKHIpKX0sZS5meC5pbnRlcnZhbCkpLHRoaXMuX3RyaWdnZXIoXCJvcGVuXCIsdCx7dG9vbHRpcDpvfSl9fSxfcmVnaXN0ZXJDbG9zZUhhbmRsZXJzOmZ1bmN0aW9uKHQsaSl7dmFyIHM9e2tleXVwOmZ1bmN0aW9uKHQpe2lmKHQua2V5Q29kZT09PWUudWkua2V5Q29kZS5FU0NBUEUpe3ZhciBzPWUuRXZlbnQodCk7cy5jdXJyZW50VGFyZ2V0PWlbMF0sdGhpcy5jbG9zZShzLCEwKX19fTtpWzBdIT09dGhpcy5lbGVtZW50WzBdJiYocy5yZW1vdmU9ZnVuY3Rpb24oKXt0aGlzLl9yZW1vdmVUb29sdGlwKHRoaXMuX2ZpbmQoaSkudG9vbHRpcCl9KSx0JiZcIm1vdXNlb3ZlclwiIT09dC50eXBlfHwocy5tb3VzZWxlYXZlPVwiY2xvc2VcIiksdCYmXCJmb2N1c2luXCIhPT10LnR5cGV8fChzLmZvY3Vzb3V0PVwiY2xvc2VcIiksdGhpcy5fb24oITAsaSxzKX0sY2xvc2U6ZnVuY3Rpb24odCl7dmFyIGkscz10aGlzLG49ZSh0P3QuY3VycmVudFRhcmdldDp0aGlzLmVsZW1lbnQpLGE9dGhpcy5fZmluZChuKTtyZXR1cm4gYT8oaT1hLnRvb2x0aXAsYS5jbG9zaW5nfHwoY2xlYXJJbnRlcnZhbCh0aGlzLmRlbGF5ZWRTaG93KSxuLmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpJiYhbi5hdHRyKFwidGl0bGVcIikmJm4uYXR0cihcInRpdGxlXCIsbi5kYXRhKFwidWktdG9vbHRpcC10aXRsZVwiKSksdGhpcy5fcmVtb3ZlRGVzY3JpYmVkQnkobiksYS5oaWRpbmc9ITAsaS5zdG9wKCEwKSx0aGlzLl9oaWRlKGksdGhpcy5vcHRpb25zLmhpZGUsZnVuY3Rpb24oKXtzLl9yZW1vdmVUb29sdGlwKGUodGhpcykpfSksbi5yZW1vdmVEYXRhKFwidWktdG9vbHRpcC1vcGVuXCIpLHRoaXMuX29mZihuLFwibW91c2VsZWF2ZSBmb2N1c291dCBrZXl1cFwiKSxuWzBdIT09dGhpcy5lbGVtZW50WzBdJiZ0aGlzLl9vZmYobixcInJlbW92ZVwiKSx0aGlzLl9vZmYodGhpcy5kb2N1bWVudCxcIm1vdXNlbW92ZVwiKSx0JiZcIm1vdXNlbGVhdmVcIj09PXQudHlwZSYmZS5lYWNoKHRoaXMucGFyZW50cyxmdW5jdGlvbih0LGkpe2UoaS5lbGVtZW50KS5hdHRyKFwidGl0bGVcIixpLnRpdGxlKSxkZWxldGUgcy5wYXJlbnRzW3RdfSksYS5jbG9zaW5nPSEwLHRoaXMuX3RyaWdnZXIoXCJjbG9zZVwiLHQse3Rvb2x0aXA6aX0pLGEuaGlkaW5nfHwoYS5jbG9zaW5nPSExKSksdm9pZCAwKToobi5yZW1vdmVEYXRhKFwidWktdG9vbHRpcC1vcGVuXCIpLHZvaWQgMCl9LF90b29sdGlwOmZ1bmN0aW9uKHQpe3ZhciBpPWUoXCI8ZGl2PlwiKS5hdHRyKFwicm9sZVwiLFwidG9vbHRpcFwiKS5hZGRDbGFzcyhcInVpLXRvb2x0aXAgdWktd2lkZ2V0IHVpLWNvcm5lci1hbGwgdWktd2lkZ2V0LWNvbnRlbnQgXCIrKHRoaXMub3B0aW9ucy50b29sdGlwQ2xhc3N8fFwiXCIpKSxzPWkudW5pcXVlSWQoKS5hdHRyKFwiaWRcIik7cmV0dXJuIGUoXCI8ZGl2PlwiKS5hZGRDbGFzcyhcInVpLXRvb2x0aXAtY29udGVudFwiKS5hcHBlbmRUbyhpKSxpLmFwcGVuZFRvKHRoaXMuZG9jdW1lbnRbMF0uYm9keSksdGhpcy50b29sdGlwc1tzXT17ZWxlbWVudDp0LHRvb2x0aXA6aX19LF9maW5kOmZ1bmN0aW9uKGUpe3ZhciB0PWUuZGF0YShcInVpLXRvb2x0aXAtaWRcIik7cmV0dXJuIHQ/dGhpcy50b29sdGlwc1t0XTpudWxsfSxfcmVtb3ZlVG9vbHRpcDpmdW5jdGlvbihlKXtlLnJlbW92ZSgpLGRlbGV0ZSB0aGlzLnRvb2x0aXBzW2UuYXR0cihcImlkXCIpXX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2UuZWFjaCh0aGlzLnRvb2x0aXBzLGZ1bmN0aW9uKGkscyl7dmFyIG49ZS5FdmVudChcImJsdXJcIiksYT1zLmVsZW1lbnQ7bi50YXJnZXQ9bi5jdXJyZW50VGFyZ2V0PWFbMF0sdC5jbG9zZShuLCEwKSxlKFwiI1wiK2kpLnJlbW92ZSgpLGEuZGF0YShcInVpLXRvb2x0aXAtdGl0bGVcIikmJihhLmF0dHIoXCJ0aXRsZVwiKXx8YS5hdHRyKFwidGl0bGVcIixhLmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKSxhLnJlbW92ZURhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKX0pLHRoaXMubGl2ZVJlZ2lvbi5yZW1vdmUoKX19KX0pOyIsIi8qIVxyXG4gKiBqUXVlcnkgQ29va2llIFBsdWdpbiB2MS40LjFcclxuICogaHR0cHM6Ly9naXRodWIuY29tL2NhcmhhcnRsL2pxdWVyeS1jb29raWVcclxuICpcclxuICogQ29weXJpZ2h0IDIwMTMgS2xhdXMgSGFydGxcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXHJcbiAqL1xyXG4oZnVuY3Rpb24gKGZhY3RvcnkpIHtcclxuXHRpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XHJcblx0XHQvLyBBTURcclxuXHRcdGRlZmluZShbJ2pxdWVyeSddLCBmYWN0b3J5KTtcclxuXHR9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xyXG5cdFx0Ly8gQ29tbW9uSlNcclxuXHRcdGZhY3RvcnkocmVxdWlyZSgnanF1ZXJ5JykpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyBCcm93c2VyIGdsb2JhbHNcclxuXHRcdGZhY3RvcnkoalF1ZXJ5KTtcclxuXHR9XHJcbn0oZnVuY3Rpb24gKCQpIHtcclxuXHJcblx0dmFyIHBsdXNlcyA9IC9cXCsvZztcclxuXHJcblx0ZnVuY3Rpb24gZW5jb2RlKHMpIHtcclxuXHRcdHJldHVybiBjb25maWcucmF3ID8gcyA6IGVuY29kZVVSSUNvbXBvbmVudChzKTtcclxuXHR9XHJcblxyXG5cdGZ1bmN0aW9uIGRlY29kZShzKSB7XHJcblx0XHRyZXR1cm4gY29uZmlnLnJhdyA/IHMgOiBkZWNvZGVVUklDb21wb25lbnQocyk7XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBzdHJpbmdpZnlDb29raWVWYWx1ZSh2YWx1ZSkge1xyXG5cdFx0cmV0dXJuIGVuY29kZShjb25maWcuanNvbiA/IEpTT04uc3RyaW5naWZ5KHZhbHVlKSA6IFN0cmluZyh2YWx1ZSkpO1xyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gcGFyc2VDb29raWVWYWx1ZShzKSB7XHJcblx0XHRpZiAocy5pbmRleE9mKCdcIicpID09PSAwKSB7XHJcblx0XHRcdC8vIFRoaXMgaXMgYSBxdW90ZWQgY29va2llIGFzIGFjY29yZGluZyB0byBSRkMyMDY4LCB1bmVzY2FwZS4uLlxyXG5cdFx0XHRzID0gcy5zbGljZSgxLCAtMSkucmVwbGFjZSgvXFxcXFwiL2csICdcIicpLnJlcGxhY2UoL1xcXFxcXFxcL2csICdcXFxcJyk7XHJcblx0XHR9XHJcblxyXG5cdFx0dHJ5IHtcclxuXHRcdFx0Ly8gUmVwbGFjZSBzZXJ2ZXItc2lkZSB3cml0dGVuIHBsdXNlcyB3aXRoIHNwYWNlcy5cclxuXHRcdFx0Ly8gSWYgd2UgY2FuJ3QgZGVjb2RlIHRoZSBjb29raWUsIGlnbm9yZSBpdCwgaXQncyB1bnVzYWJsZS5cclxuXHRcdFx0Ly8gSWYgd2UgY2FuJ3QgcGFyc2UgdGhlIGNvb2tpZSwgaWdub3JlIGl0LCBpdCdzIHVudXNhYmxlLlxyXG5cdFx0XHRzID0gZGVjb2RlVVJJQ29tcG9uZW50KHMucmVwbGFjZShwbHVzZXMsICcgJykpO1xyXG5cdFx0XHRyZXR1cm4gY29uZmlnLmpzb24gPyBKU09OLnBhcnNlKHMpIDogcztcclxuXHRcdH0gY2F0Y2goZSkge31cclxuXHR9XHJcblxyXG5cdGZ1bmN0aW9uIHJlYWQocywgY29udmVydGVyKSB7XHJcblx0XHR2YXIgdmFsdWUgPSBjb25maWcucmF3ID8gcyA6IHBhcnNlQ29va2llVmFsdWUocyk7XHJcblx0XHRyZXR1cm4gJC5pc0Z1bmN0aW9uKGNvbnZlcnRlcikgPyBjb252ZXJ0ZXIodmFsdWUpIDogdmFsdWU7XHJcblx0fVxyXG5cclxuXHR2YXIgY29uZmlnID0gJC5jb29raWUgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSwgb3B0aW9ucykge1xyXG5cclxuXHRcdC8vIFdyaXRlXHJcblxyXG5cdFx0aWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgISQuaXNGdW5jdGlvbih2YWx1ZSkpIHtcclxuXHRcdFx0b3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBjb25maWcuZGVmYXVsdHMsIG9wdGlvbnMpO1xyXG5cclxuXHRcdFx0aWYgKHR5cGVvZiBvcHRpb25zLmV4cGlyZXMgPT09ICdudW1iZXInKSB7XHJcblx0XHRcdFx0dmFyIGRheXMgPSBvcHRpb25zLmV4cGlyZXMsIHQgPSBvcHRpb25zLmV4cGlyZXMgPSBuZXcgRGF0ZSgpO1xyXG5cdFx0XHRcdHQuc2V0VGltZSgrdCArIGRheXMgKiA4NjRlKzUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gKGRvY3VtZW50LmNvb2tpZSA9IFtcclxuXHRcdFx0XHRlbmNvZGUoa2V5KSwgJz0nLCBzdHJpbmdpZnlDb29raWVWYWx1ZSh2YWx1ZSksXHJcblx0XHRcdFx0b3B0aW9ucy5leHBpcmVzID8gJzsgZXhwaXJlcz0nICsgb3B0aW9ucy5leHBpcmVzLnRvVVRDU3RyaW5nKCkgOiAnJywgLy8gdXNlIGV4cGlyZXMgYXR0cmlidXRlLCBtYXgtYWdlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgSUVcclxuXHRcdFx0XHRvcHRpb25zLnBhdGggICAgPyAnOyBwYXRoPScgKyBvcHRpb25zLnBhdGggOiAnJyxcclxuXHRcdFx0XHRvcHRpb25zLmRvbWFpbiAgPyAnOyBkb21haW49JyArIG9wdGlvbnMuZG9tYWluIDogJycsXHJcblx0XHRcdFx0b3B0aW9ucy5zZWN1cmUgID8gJzsgc2VjdXJlJyA6ICcnXHJcblx0XHRcdF0uam9pbignJykpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlYWRcclxuXHJcblx0XHR2YXIgcmVzdWx0ID0ga2V5ID8gdW5kZWZpbmVkIDoge307XHJcblxyXG5cdFx0Ly8gVG8gcHJldmVudCB0aGUgZm9yIGxvb3AgaW4gdGhlIGZpcnN0IHBsYWNlIGFzc2lnbiBhbiBlbXB0eSBhcnJheVxyXG5cdFx0Ly8gaW4gY2FzZSB0aGVyZSBhcmUgbm8gY29va2llcyBhdCBhbGwuIEFsc28gcHJldmVudHMgb2RkIHJlc3VsdCB3aGVuXHJcblx0XHQvLyBjYWxsaW5nICQuY29va2llKCkuXHJcblx0XHR2YXIgY29va2llcyA9IGRvY3VtZW50LmNvb2tpZSA/IGRvY3VtZW50LmNvb2tpZS5zcGxpdCgnOyAnKSA6IFtdO1xyXG5cclxuXHRcdGZvciAodmFyIGkgPSAwLCBsID0gY29va2llcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuXHRcdFx0dmFyIHBhcnRzID0gY29va2llc1tpXS5zcGxpdCgnPScpO1xyXG5cdFx0XHR2YXIgbmFtZSA9IGRlY29kZShwYXJ0cy5zaGlmdCgpKTtcclxuXHRcdFx0dmFyIGNvb2tpZSA9IHBhcnRzLmpvaW4oJz0nKTtcclxuXHJcblx0XHRcdGlmIChrZXkgJiYga2V5ID09PSBuYW1lKSB7XHJcblx0XHRcdFx0Ly8gSWYgc2Vjb25kIGFyZ3VtZW50ICh2YWx1ZSkgaXMgYSBmdW5jdGlvbiBpdCdzIGEgY29udmVydGVyLi4uXHJcblx0XHRcdFx0cmVzdWx0ID0gcmVhZChjb29raWUsIHZhbHVlKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gUHJldmVudCBzdG9yaW5nIGEgY29va2llIHRoYXQgd2UgY291bGRuJ3QgZGVjb2RlLlxyXG5cdFx0XHRpZiAoIWtleSAmJiAoY29va2llID0gcmVhZChjb29raWUpKSAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0cmVzdWx0W25hbWVdID0gY29va2llO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9O1xyXG5cclxuXHRjb25maWcuZGVmYXVsdHMgPSB7fTtcclxuXHJcblx0JC5yZW1vdmVDb29raWUgPSBmdW5jdGlvbiAoa2V5LCBvcHRpb25zKSB7XHJcblx0XHRpZiAoJC5jb29raWUoa2V5KSA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNdXN0IG5vdCBhbHRlciBvcHRpb25zLCB0aHVzIGV4dGVuZGluZyBhIGZyZXNoIG9iamVjdC4uLlxyXG5cdFx0JC5jb29raWUoa2V5LCAnJywgJC5leHRlbmQoe30sIG9wdGlvbnMsIHsgZXhwaXJlczogLTEgfSkpO1xyXG5cdFx0cmV0dXJuICEkLmNvb2tpZShrZXkpO1xyXG5cdH07XHJcblxyXG59KSk7XHJcbiIsIihmdW5jdGlvbihkKXt2YXIgcD17fSxlLGEsaD1kb2N1bWVudCxpPXdpbmRvdyxmPWguZG9jdW1lbnRFbGVtZW50LGo9ZC5leHBhbmRvO2QuZXZlbnQuc3BlY2lhbC5pbnZpZXc9e2FkZDpmdW5jdGlvbihhKXtwW2EuZ3VpZCtcIi1cIit0aGlzW2pdXT17ZGF0YTphLCRlbGVtZW50OmQodGhpcyl9fSxyZW1vdmU6ZnVuY3Rpb24oYSl7dHJ5e2RlbGV0ZSBwW2EuZ3VpZCtcIi1cIit0aGlzW2pdXX1jYXRjaChkKXt9fX07ZChpKS5iaW5kKFwic2Nyb2xsIHJlc2l6ZVwiLGZ1bmN0aW9uKCl7ZT1hPW51bGx9KTshZi5hZGRFdmVudExpc3RlbmVyJiZmLmF0dGFjaEV2ZW50JiZmLmF0dGFjaEV2ZW50KFwib25mb2N1c2luXCIsZnVuY3Rpb24oKXthPW51bGx9KTtzZXRJbnRlcnZhbChmdW5jdGlvbigpe3ZhciBrPWQoKSxqLG49MDtkLmVhY2gocCxmdW5jdGlvbihhLGIpe3ZhciBjPWIuZGF0YS5zZWxlY3RvcixkPWIuJGVsZW1lbnQ7az1rLmFkZChjP2QuZmluZChjKTpkKX0pO2lmKGo9ay5sZW5ndGgpe3ZhciBiO1xyXG5pZighKGI9ZSkpe3ZhciBnPXtoZWlnaHQ6aS5pbm5lckhlaWdodCx3aWR0aDppLmlubmVyV2lkdGh9O2lmKCFnLmhlaWdodCYmKChiPWguY29tcGF0TW9kZSl8fCFkLnN1cHBvcnQuYm94TW9kZWwpKWI9XCJDU1MxQ29tcGF0XCI9PT1iP2Y6aC5ib2R5LGc9e2hlaWdodDpiLmNsaWVudEhlaWdodCx3aWR0aDpiLmNsaWVudFdpZHRofTtiPWd9ZT1iO2ZvcihhPWF8fHt0b3A6aS5wYWdlWU9mZnNldHx8Zi5zY3JvbGxUb3B8fGguYm9keS5zY3JvbGxUb3AsbGVmdDppLnBhZ2VYT2Zmc2V0fHxmLnNjcm9sbExlZnR8fGguYm9keS5zY3JvbGxMZWZ0fTtuPGo7bisrKWlmKGQuY29udGFpbnMoZixrW25dKSl7Yj1kKGtbbl0pO3ZhciBsPWIuaGVpZ2h0KCksbT1iLndpZHRoKCksYz1iLm9mZnNldCgpLGc9Yi5kYXRhKFwiaW52aWV3XCIpO2lmKCFhfHwhZSlicmVhaztjLnRvcCtsPmEudG9wJiZjLnRvcDxhLnRvcCtlLmhlaWdodCYmYy5sZWZ0K20+YS5sZWZ0JiZjLmxlZnQ8YS5sZWZ0K2Uud2lkdGg/XHJcbihtPWEubGVmdD5jLmxlZnQ/XCJyaWdodFwiOmEubGVmdCtlLndpZHRoPGMubGVmdCttP1wibGVmdFwiOlwiYm90aFwiLGw9YS50b3A+Yy50b3A/XCJib3R0b21cIjphLnRvcCtlLmhlaWdodDxjLnRvcCtsP1widG9wXCI6XCJib3RoXCIsYz1tK1wiLVwiK2wsKCFnfHxnIT09YykmJmIuZGF0YShcImludmlld1wiLGMpLnRyaWdnZXIoXCJpbnZpZXdcIixbITAsbSxsXSkpOmcmJmIuZGF0YShcImludmlld1wiLCExKS50cmlnZ2VyKFwiaW52aWV3XCIsWyExXSl9fX0sMjUwKX0pKGpRdWVyeSk7IiwiLyoqXHJcbiAqIEBsaWNlbnNlIGpxdWVyeS5wYW56b29tLmpzIHYyLjAuNVxyXG4gKiBVcGRhdGVkOiBUaHUgQXByIDAzIDIwMTRcclxuICogQWRkIHBhbiBhbmQgem9vbSBmdW5jdGlvbmFsaXR5IHRvIGFueSBlbGVtZW50XHJcbiAqIENvcHlyaWdodCAoYykgMjAxNCB0aW1teSB3aWxsaXNvblxyXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcclxuICogaHR0cHM6Ly9naXRodWIuY29tL3RpbW15d2lsL2pxdWVyeS5wYW56b29tL2Jsb2IvbWFzdGVyL01JVC1MaWNlbnNlLnR4dFxyXG4gKi9cclxuXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuXHQvLyBBTURcclxuXHRpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XHJcblx0XHRkZWZpbmUoWyAnanF1ZXJ5JyBdLCBmdW5jdGlvbihqUXVlcnkpIHtcclxuXHRcdFx0cmV0dXJuIGZhY3RvcnkoZ2xvYmFsLCBqUXVlcnkpO1xyXG5cdFx0fSk7XHJcblx0Ly8gQ29tbW9uSlMvQnJvd3NlcmlmeVxyXG5cdH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XHJcblx0XHRmYWN0b3J5KGdsb2JhbCwgcmVxdWlyZSgnanF1ZXJ5JykpO1xyXG5cdC8vIEdsb2JhbFxyXG5cdH0gZWxzZSB7XHJcblx0XHRmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLmpRdWVyeSk7XHJcblx0fVxyXG59KHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24od2luZG93LCAkKSB7XHJcblx0J3VzZSBzdHJpY3QnO1xyXG5cclxuXHQvLyBDb21tb24gcHJvcGVydGllcyB0byBsaWZ0IGZvciB0b3VjaCBvciBwb2ludGVyIGV2ZW50c1xyXG5cdHZhciBsaXN0ID0gJ292ZXIgb3V0IGRvd24gdXAgbW92ZSBlbnRlciBsZWF2ZSBjYW5jZWwnLnNwbGl0KCcgJyk7XHJcblx0dmFyIGhvb2sgPSAkLmV4dGVuZCh7fSwgJC5ldmVudC5tb3VzZUhvb2tzKTtcclxuXHR2YXIgZXZlbnRzID0ge307XHJcblxyXG5cdC8vIFN1cHBvcnQgcG9pbnRlciBldmVudHMgaW4gSUUxMSsgaWYgYXZhaWxhYmxlXHJcblx0aWYgKCB3aW5kb3cuUG9pbnRlckV2ZW50ICkge1xyXG5cdFx0JC5lYWNoKGxpc3QsIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdFx0XHQvLyBBZGQgZXZlbnQgbmFtZSB0byBldmVudHMgcHJvcGVydHkgYW5kIGFkZCBmaXhIb29rXHJcblx0XHRcdCQuZXZlbnQuZml4SG9va3NbXHJcblx0XHRcdFx0KGV2ZW50c1tuYW1lXSA9ICdwb2ludGVyJyArIG5hbWUpXHJcblx0XHRcdF0gPSBob29rO1xyXG5cdFx0fSk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHZhciBtb3VzZVByb3BzID0gaG9vay5wcm9wcztcclxuXHRcdC8vIEFkZCB0b3VjaCBwcm9wZXJ0aWVzIGZvciB0aGUgdG91Y2ggaG9va1xyXG5cdFx0aG9vay5wcm9wcyA9IG1vdXNlUHJvcHMuY29uY2F0KFsndG91Y2hlcycsICdjaGFuZ2VkVG91Y2hlcycsICd0YXJnZXRUb3VjaGVzJywgJ2FsdEtleScsICdjdHJsS2V5JywgJ21ldGFLZXknLCAnc2hpZnRLZXknXSk7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBTdXBwb3J0OiBBbmRyb2lkXHJcblx0XHQgKiBBbmRyb2lkIHNldHMgcGFnZVgvWSB0byAwIGZvciBhbnkgdG91Y2ggZXZlbnRcclxuXHRcdCAqIEF0dGFjaCBmaXJzdCB0b3VjaCdzIHBhZ2VYL3BhZ2VZIGFuZCBjbGllbnRYL2NsaWVudFkgaWYgbm90IHNldCBjb3JyZWN0bHlcclxuXHRcdCAqL1xyXG5cdFx0aG9vay5maWx0ZXIgPSBmdW5jdGlvbiggZXZlbnQsIG9yaWdpbmFsRXZlbnQgKSB7XHJcblx0XHRcdHZhciB0b3VjaDtcclxuXHRcdFx0dmFyIGkgPSBtb3VzZVByb3BzLmxlbmd0aDtcclxuXHRcdFx0aWYgKCAhb3JpZ2luYWxFdmVudC5wYWdlWCAmJiBvcmlnaW5hbEV2ZW50LnRvdWNoZXMgJiYgKHRvdWNoID0gb3JpZ2luYWxFdmVudC50b3VjaGVzWzBdKSApIHtcclxuXHRcdFx0XHQvLyBDb3B5IG92ZXIgYWxsIG1vdXNlIHByb3BlcnRpZXNcclxuXHRcdFx0XHR3aGlsZShpLS0pIHtcclxuXHRcdFx0XHRcdGV2ZW50W21vdXNlUHJvcHNbaV1dID0gdG91Y2hbbW91c2VQcm9wc1tpXV07XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBldmVudDtcclxuXHRcdH07XHJcblxyXG5cdFx0JC5lYWNoKGxpc3QsIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdFx0XHQvLyBObyBlcXVpdmFsZW50IHRvdWNoIGV2ZW50cyBmb3Igb3ZlciBhbmQgb3V0XHJcblx0XHRcdGlmIChpIDwgMikge1xyXG5cdFx0XHRcdGV2ZW50c1sgbmFtZSBdID0gJ21vdXNlJyArIG5hbWU7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dmFyIHRvdWNoID0gJ3RvdWNoJyArXHJcblx0XHRcdFx0XHQobmFtZSA9PT0gJ2Rvd24nID8gJ3N0YXJ0JyA6IG5hbWUgPT09ICd1cCcgPyAnZW5kJyA6IG5hbWUpO1xyXG5cdFx0XHRcdC8vIEFkZCBmaXhIb29rXHJcblx0XHRcdFx0JC5ldmVudC5maXhIb29rc1sgdG91Y2ggXSA9IGhvb2s7XHJcblx0XHRcdFx0Ly8gQWRkIGV2ZW50IG5hbWVzIHRvIGV2ZW50cyBwcm9wZXJ0eVxyXG5cdFx0XHRcdGV2ZW50c1sgbmFtZSBdID0gdG91Y2ggKyAnIG1vdXNlJyArIG5hbWU7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0JC5wb2ludGVydG91Y2ggPSBldmVudHM7XHJcblxyXG5cdHZhciBkYXRha2V5ID0gJ19fcHpfXyc7XHJcblx0dmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xyXG5cdHZhciBwb2ludGVyRXZlbnRzID0gISF3aW5kb3cuUG9pbnRlckV2ZW50O1xyXG5cclxuXHQvLyBSZWdleFxyXG5cdHZhciBydXBwZXIgPSAvKFtBLVpdKS9nO1xyXG5cdHZhciByc3ZnID0gL15odHRwOltcXHdcXC5cXC9dK3N2ZyQvO1xyXG5cdHZhciByaW5saW5lID0gL15pbmxpbmUvO1xyXG5cclxuXHR2YXIgZmxvYXRpbmcgPSAnKFxcXFwtP1tcXFxcZFxcXFwuZV0rKSc7XHJcblx0dmFyIGNvbW1hU3BhY2UgPSAnXFxcXCw/XFxcXHMqJztcclxuXHR2YXIgcm1hdHJpeCA9IG5ldyBSZWdFeHAoXHJcblx0XHQnXm1hdHJpeFxcXFwoJyArXHJcblx0XHRmbG9hdGluZyArIGNvbW1hU3BhY2UgK1xyXG5cdFx0ZmxvYXRpbmcgKyBjb21tYVNwYWNlICtcclxuXHRcdGZsb2F0aW5nICsgY29tbWFTcGFjZSArXHJcblx0XHRmbG9hdGluZyArIGNvbW1hU3BhY2UgK1xyXG5cdFx0ZmxvYXRpbmcgKyBjb21tYVNwYWNlICtcclxuXHRcdGZsb2F0aW5nICsgJ1xcXFwpJCdcclxuXHQpO1xyXG5cclxuXHQvKipcclxuXHQgKiBVdGlsaXR5IGZvciBkZXRlcm1pbmcgdHJhbnNmb3JtIG1hdHJpeCBlcXVhbGl0eVxyXG5cdCAqIENoZWNrcyBiYWNrd2FyZHMgdG8gdGVzdCB0cmFuc2xhdGlvbiBmaXJzdFxyXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGZpcnN0XHJcblx0ICogQHBhcmFtIHtBcnJheX0gc2Vjb25kXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gbWF0cml4RXF1YWxzKGZpcnN0LCBzZWNvbmQpIHtcclxuXHRcdHZhciBpID0gZmlyc3QubGVuZ3RoO1xyXG5cdFx0d2hpbGUoLS1pKSB7XHJcblx0XHRcdGlmICgrZmlyc3RbaV0gIT09ICtzZWNvbmRbaV0pIHtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiB0cnVlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ3JlYXRlcyB0aGUgb3B0aW9ucyBvYmplY3QgZm9yIHJlc2V0IGZ1bmN0aW9uc1xyXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IG9wdHMgU2VlIHJlc2V0IG1ldGhvZHNcclxuXHQgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXdseS1jcmVhdGVkIG9wdGlvbnMgb2JqZWN0XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gY3JlYXRlUmVzZXRPcHRpb25zKG9wdHMpIHtcclxuXHRcdHZhciBvcHRpb25zID0geyByYW5nZTogdHJ1ZSwgYW5pbWF0ZTogdHJ1ZSB9O1xyXG5cdFx0aWYgKHR5cGVvZiBvcHRzID09PSAnYm9vbGVhbicpIHtcclxuXHRcdFx0b3B0aW9ucy5hbmltYXRlID0gb3B0cztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdCQuZXh0ZW5kKG9wdGlvbnMsIG9wdHMpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG9wdGlvbnM7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXByZXNlbnQgYSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXggd2l0aCBhIDN4MyBtYXRyaXggZm9yIGNhbGN1bGF0aW9uc1xyXG5cdCAqIE1hdHJpeCBmdW5jdGlvbnMgYWRhcHRlZCBmcm9tIExvdWlzIFJlbWkncyBqUXVlcnkudHJhbnNmb3JtIChodHRwczovL2dpdGh1Yi5jb20vbG91aXNyZW1pL2pxdWVyeS50cmFuc2Zvcm0uanMpXHJcblx0ICogQHBhcmFtIHtBcnJheXxOdW1iZXJ9IGEgQW4gYXJyYXkgb2Ygc2l4IHZhbHVlcyByZXByZXNlbnRpbmcgYSAyZCB0cmFuc2Zvcm1hdGlvbiBtYXRyaXhcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBNYXRyaXgoYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSkge1xyXG5cdFx0aWYgKCQudHlwZShhKSA9PT0gJ2FycmF5Jykge1xyXG5cdFx0XHR0aGlzLmVsZW1lbnRzID0gW1xyXG5cdFx0XHRcdCthWzBdLCArYVsyXSwgK2FbNF0sXHJcblx0XHRcdFx0K2FbMV0sICthWzNdLCArYVs1XSxcclxuXHRcdFx0XHQgICAgMCwgICAgIDAsICAgICAxXHJcblx0XHRcdF07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmVsZW1lbnRzID0gW1xyXG5cdFx0XHRcdGEsIGIsIGMsXHJcblx0XHRcdFx0ZCwgZSwgZixcclxuXHRcdFx0XHRnIHx8IDAsIGggfHwgMCwgaSB8fCAxXHJcblx0XHRcdF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRNYXRyaXgucHJvdG90eXBlID0ge1xyXG5cdFx0LyoqXHJcblx0XHQgKiBNdWx0aXBseSBhIDN4MyBtYXRyaXggYnkgYSBzaW1pbGFyIG1hdHJpeCBvciBhIHZlY3RvclxyXG5cdFx0ICogQHBhcmFtIHtNYXRyaXh8VmVjdG9yfSBtYXRyaXhcclxuXHRcdCAqIEByZXR1cm4ge01hdHJpeHxWZWN0b3J9IFJldHVybnMgYSB2ZWN0b3IgaWYgbXVsdGlwbHlpbmcgYnkgYSB2ZWN0b3JcclxuXHRcdCAqL1xyXG5cdFx0eDogZnVuY3Rpb24obWF0cml4KSB7XHJcblx0XHRcdHZhciBpc1ZlY3RvciA9IG1hdHJpeCBpbnN0YW5jZW9mIFZlY3RvcjtcclxuXHJcblx0XHRcdHZhciBhID0gdGhpcy5lbGVtZW50cyxcclxuXHRcdFx0XHRiID0gbWF0cml4LmVsZW1lbnRzO1xyXG5cclxuXHRcdFx0aWYgKGlzVmVjdG9yICYmIGIubGVuZ3RoID09PSAzKSB7XHJcblx0XHRcdFx0Ly8gYiBpcyBhY3R1YWxseSBhIHZlY3RvclxyXG5cdFx0XHRcdHJldHVybiBuZXcgVmVjdG9yKFxyXG5cdFx0XHRcdFx0YVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSArIGFbMl0gKiBiWzJdLFxyXG5cdFx0XHRcdFx0YVszXSAqIGJbMF0gKyBhWzRdICogYlsxXSArIGFbNV0gKiBiWzJdLFxyXG5cdFx0XHRcdFx0YVs2XSAqIGJbMF0gKyBhWzddICogYlsxXSArIGFbOF0gKiBiWzJdXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSBlbHNlIGlmIChiLmxlbmd0aCA9PT0gYS5sZW5ndGgpIHtcclxuXHRcdFx0XHQvLyBiIGlzIGEgM3gzIG1hdHJpeFxyXG5cdFx0XHRcdHJldHVybiBuZXcgTWF0cml4KFxyXG5cdFx0XHRcdFx0YVswXSAqIGJbMF0gKyBhWzFdICogYlszXSArIGFbMl0gKiBiWzZdLFxyXG5cdFx0XHRcdFx0YVswXSAqIGJbMV0gKyBhWzFdICogYls0XSArIGFbMl0gKiBiWzddLFxyXG5cdFx0XHRcdFx0YVswXSAqIGJbMl0gKyBhWzFdICogYls1XSArIGFbMl0gKiBiWzhdLFxyXG5cclxuXHRcdFx0XHRcdGFbM10gKiBiWzBdICsgYVs0XSAqIGJbM10gKyBhWzVdICogYls2XSxcclxuXHRcdFx0XHRcdGFbM10gKiBiWzFdICsgYVs0XSAqIGJbNF0gKyBhWzVdICogYls3XSxcclxuXHRcdFx0XHRcdGFbM10gKiBiWzJdICsgYVs0XSAqIGJbNV0gKyBhWzVdICogYls4XSxcclxuXHJcblx0XHRcdFx0XHRhWzZdICogYlswXSArIGFbN10gKiBiWzNdICsgYVs4XSAqIGJbNl0sXHJcblx0XHRcdFx0XHRhWzZdICogYlsxXSArIGFbN10gKiBiWzRdICsgYVs4XSAqIGJbN10sXHJcblx0XHRcdFx0XHRhWzZdICogYlsyXSArIGFbN10gKiBiWzVdICsgYVs4XSAqIGJbOF1cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBmYWxzZTsgLy8gZmFpbFxyXG5cdFx0fSxcclxuXHRcdC8qKlxyXG5cdFx0ICogR2VuZXJhdGVzIGFuIGludmVyc2Ugb2YgdGhlIGN1cnJlbnQgbWF0cml4XHJcblx0XHQgKiBAcmV0dXJucyB7TWF0cml4fVxyXG5cdFx0ICovXHJcblx0XHRpbnZlcnNlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGQgPSAxIC8gdGhpcy5kZXRlcm1pbmFudCgpLFxyXG5cdFx0XHRcdGEgPSB0aGlzLmVsZW1lbnRzO1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeChcclxuXHRcdFx0XHRkICogKCBhWzhdICogYVs0XSAtIGFbN10gKiBhWzVdKSxcclxuXHRcdFx0XHRkICogKC0oYVs4XSAqIGFbMV0gLSBhWzddICogYVsyXSkpLFxyXG5cdFx0XHRcdGQgKiAoIGFbNV0gKiBhWzFdIC0gYVs0XSAqIGFbMl0pLFxyXG5cclxuXHRcdFx0XHRkICogKC0oYVs4XSAqIGFbM10gLSBhWzZdICogYVs1XSkpLFxyXG5cdFx0XHRcdGQgKiAoIGFbOF0gKiBhWzBdIC0gYVs2XSAqIGFbMl0pLFxyXG5cdFx0XHRcdGQgKiAoLShhWzVdICogYVswXSAtIGFbM10gKiBhWzJdKSksXHJcblxyXG5cdFx0XHRcdGQgKiAoIGFbN10gKiBhWzNdIC0gYVs2XSAqIGFbNF0pLFxyXG5cdFx0XHRcdGQgKiAoLShhWzddICogYVswXSAtIGFbNl0gKiBhWzFdKSksXHJcblx0XHRcdFx0ZCAqICggYVs0XSAqIGFbMF0gLSBhWzNdICogYVsxXSlcclxuXHRcdFx0KTtcclxuXHRcdH0sXHJcblx0XHQvKipcclxuXHRcdCAqIENhbGN1bGF0ZXMgdGhlIGRldGVybWluYW50IG9mIHRoZSBjdXJyZW50IG1hdHJpeFxyXG5cdFx0ICogQHJldHVybnMge051bWJlcn1cclxuXHRcdCAqL1xyXG5cdFx0ZGV0ZXJtaW5hbnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgYSA9IHRoaXMuZWxlbWVudHM7XHJcblx0XHRcdHJldHVybiBhWzBdICogKGFbOF0gKiBhWzRdIC0gYVs3XSAqIGFbNV0pIC0gYVszXSAqIChhWzhdICogYVsxXSAtIGFbN10gKiBhWzJdKSArIGFbNl0gKiAoYVs1XSAqIGFbMV0gLSBhWzRdICogYVsyXSk7XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogQ3JlYXRlIGEgdmVjdG9yIGNvbnRhaW5pbmcgdGhyZWUgdmFsdWVzXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gVmVjdG9yKHgsIHksIHopIHtcclxuXHRcdHRoaXMuZWxlbWVudHMgPSBbIHgsIHksIHogXTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCB0aGUgZWxlbWVudCBhdCB6ZXJvLWluZGV4ZWQgaW5kZXggaVxyXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBpXHJcblx0ICovXHJcblx0VmVjdG9yLnByb3RvdHlwZS5lID0gTWF0cml4LnByb3RvdHlwZS5lID0gZnVuY3Rpb24oaSkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZWxlbWVudHNbIGkgXTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBDcmVhdGUgYSBQYW56b29tIG9iamVjdCBmb3IgYSBnaXZlbiBlbGVtZW50XHJcblx0ICogQGNvbnN0cnVjdG9yXHJcblx0ICogQHBhcmFtIHtFbGVtZW50fSBlbGVtIC0gRWxlbWVudCB0byB1c2UgcGFuIGFuZCB6b29tXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIEFuIG9iamVjdCBsaXRlcmFsIGNvbnRhaW5pbmcgb3B0aW9ucyB0byBvdmVycmlkZSBkZWZhdWx0IG9wdGlvbnNcclxuXHQgKiAgKFNlZSBQYW56b29tLmRlZmF1bHRzIGZvciBvbmVzIG5vdCBsaXN0ZWQgYmVsb3cpXHJcblx0ICogQHBhcmFtIHtqUXVlcnl9IFtvcHRpb25zLiR6b29tSW5dIC0gem9vbSBpbiBidXR0b25zL2xpbmtzIGNvbGxlY3Rpb24gKHlvdSBjYW4gYWxzbyBiaW5kIHRoZXNlIHlvdXJzZWxmXHJcblx0ICogIGUuZy4gJGJ1dHRvbi5vbignY2xpY2snLCBmdW5jdGlvbihlKSB7IGUucHJldmVudERlZmF1bHQoKTsgJGVsZW0ucGFuem9vb20oJ3pvb21JbicpOyB9KTspXHJcblx0ICogQHBhcmFtIHtqUXVlcnl9IFtvcHRpb25zLiR6b29tT3V0XSAtIHpvb20gb3V0IGJ1dHRvbnMvbGlua3MgY29sbGVjdGlvbiBvbiB3aGljaCB0byBiaW5kIHpvb21PdXRcclxuXHQgKiBAcGFyYW0ge2pRdWVyeX0gW29wdGlvbnMuJHpvb21SYW5nZV0gLSB6b29tIGluL291dCB3aXRoIHRoaXMgcmFuZ2UgY29udHJvbFxyXG5cdCAqIEBwYXJhbSB7alF1ZXJ5fSBbb3B0aW9ucy4kcmVzZXRdIC0gUmVzZXQgYnV0dG9ucy9saW5rcyBjb2xsZWN0aW9uIG9uIHdoaWNoIHRvIGJpbmQgdGhlIHJlc2V0IG1ldGhvZFxyXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLm9uW1N0YXJ0fENoYW5nZXxab29tfFBhbnxFbmR8UmVzZXRdIC0gT3B0aW9uYWwgY2FsbGJhY2tzIGZvciBwYW56b29tIGV2ZW50c1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIFBhbnpvb20oZWxlbSwgb3B0aW9ucykge1xyXG5cclxuXHRcdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCBgbmV3YCBrZXl3b3JkXHJcblx0XHRpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFuem9vbSkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBQYW56b29tKGVsZW0sIG9wdGlvbnMpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNhbml0eSBjaGVja3NcclxuXHRcdGlmIChlbGVtLm5vZGVUeXBlICE9PSAxKSB7XHJcblx0XHRcdCQuZXJyb3IoJ1Bhbnpvb20gY2FsbGVkIG9uIG5vbi1FbGVtZW50IG5vZGUnKTtcclxuXHRcdH1cclxuXHRcdGlmICghJC5jb250YWlucyhkb2N1bWVudCwgZWxlbSkpIHtcclxuXHRcdFx0JC5lcnJvcignUGFuem9vbSBlbGVtZW50IG11c3QgYmUgYXR0YWNoZWQgdG8gdGhlIGRvY3VtZW50Jyk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRG9uJ3QgcmVtYWtlXHJcblx0XHR2YXIgZCA9ICQuZGF0YShlbGVtLCBkYXRha2V5KTtcclxuXHRcdGlmIChkKSB7XHJcblx0XHRcdHJldHVybiBkO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEV4dGVuZCBkZWZhdWx0IHdpdGggZ2l2ZW4gb2JqZWN0IGxpdGVyYWxcclxuXHRcdC8vIEVhY2ggaW5zdGFuY2UgZ2V0cyBpdHMgb3duIG9wdGlvbnNcclxuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgUGFuem9vbS5kZWZhdWx0cywgb3B0aW9ucyk7XHJcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xyXG5cdFx0dmFyICRlbGVtID0gdGhpcy4kZWxlbSA9ICQoZWxlbSk7XHJcblx0XHR0aGlzLiRzZXQgPSBvcHRpb25zLiRzZXQgJiYgb3B0aW9ucy4kc2V0Lmxlbmd0aCA/IG9wdGlvbnMuJHNldCA6ICRlbGVtO1xyXG5cdFx0dGhpcy4kZG9jID0gJChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQpO1xyXG5cdFx0dGhpcy4kcGFyZW50ID0gJGVsZW0ucGFyZW50KCk7XHJcblxyXG5cdFx0Ly8gVGhpcyBpcyBTVkcgaWYgdGhlIG5hbWVzcGFjZSBpcyBTVkdcclxuXHRcdC8vIEhvd2V2ZXIsIHdoaWxlIDxzdmc+IGVsZW1lbnRzIGFyZSBTVkcsIHdlIHdhbnQgdG8gdHJlYXQgdGhvc2UgbGlrZSBvdGhlciBlbGVtZW50c1xyXG5cdFx0dGhpcy5pc1NWRyA9IHJzdmcudGVzdChlbGVtLm5hbWVzcGFjZVVSSSkgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnc3ZnJztcclxuXHJcblx0XHR0aGlzLnBhbm5pbmcgPSBmYWxzZTtcclxuXHJcblx0XHQvLyBTYXZlIHRoZSBvcmlnaW5hbCB0cmFuc2Zvcm0gdmFsdWVcclxuXHRcdC8vIFNhdmUgdGhlIHByZWZpeGVkIHRyYW5zZm9ybSBzdHlsZSBrZXlcclxuXHRcdC8vIFNldCB0aGUgc3RhcnRpbmcgdHJhbnNmb3JtXHJcblx0XHR0aGlzLl9idWlsZFRyYW5zZm9ybSgpO1xyXG5cclxuXHRcdC8vIEJ1aWxkIHRoZSBhcHByb3ByaWF0ZWx5LXByZWZpeGVkIHRyYW5zZm9ybSBzdHlsZSBwcm9wZXJ0eSBuYW1lXHJcblx0XHQvLyBEZS1jYW1lbGNhc2VcclxuXHRcdHRoaXMuX3RyYW5zZm9ybSA9ICF0aGlzLmlzU1ZHICYmICQuY3NzUHJvcHMudHJhbnNmb3JtLnJlcGxhY2UocnVwcGVyLCAnLSQxJykudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0XHQvLyBCdWlsZCB0aGUgdHJhbnNpdGlvbiB2YWx1ZVxyXG5cdFx0dGhpcy5fYnVpbGRUcmFuc2l0aW9uKCk7XHJcblxyXG5cdFx0Ly8gQnVpbGQgY29udGFpbm1lbnQgZGltZW5zaW9uc1xyXG5cdFx0dGhpcy5yZXNldERpbWVuc2lvbnMoKTtcclxuXHJcblx0XHQvLyBBZGQgem9vbSBhbmQgcmVzZXQgYnV0dG9ucyB0byBgdGhpc2BcclxuXHRcdHZhciAkZW1wdHkgPSAkKCk7XHJcblx0XHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0XHQkLmVhY2goWyAnJHpvb21JbicsICckem9vbU91dCcsICckem9vbVJhbmdlJywgJyRyZXNldCcgXSwgZnVuY3Rpb24oaSwgbmFtZSkge1xyXG5cdFx0XHRzZWxmWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF0gfHwgJGVtcHR5O1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5lbmFibGUoKTtcclxuXHJcblx0XHQvLyBTYXZlIHRoZSBpbnN0YW5jZVxyXG5cdFx0JC5kYXRhKGVsZW0sIGRhdGFrZXksIHRoaXMpO1xyXG5cdH1cclxuXHJcblx0Ly8gQXR0YWNoIHJlZ2V4IGZvciBwb3NzaWJsZSB1c2UgKGltbXV0YWJsZSlcclxuXHRQYW56b29tLnJtYXRyaXggPSBybWF0cml4O1xyXG5cclxuXHQvLyBDb250YWluZXIgZm9yIGV2ZW50IG5hbWVzXHJcblx0UGFuem9vbS5ldmVudHMgPSAkLnBvaW50ZXJ0b3VjaDtcclxuXHJcblx0UGFuem9vbS5kZWZhdWx0cyA9IHtcclxuXHRcdC8vIFNob3VsZCBhbHdheXMgYmUgbm9uLWVtcHR5XHJcblx0XHQvLyBVc2VkIHRvIGJpbmQgalF1ZXJ5IGV2ZW50cyB3aXRob3V0IGNvbGxpc2lvbnNcclxuXHRcdC8vIEEgZ3VpZCBpcyBub3QgYWRkZWQgaGVyZSBhcyBkaWZmZXJlbnQgaW5zdGFudGlhdGlvbnMvdmVyc2lvbnMgb2YgcGFuem9vbVxyXG5cdFx0Ly8gb24gdGhlIHNhbWUgZWxlbWVudCBpcyBub3Qgc3VwcG9ydGVkLCBzbyBkb24ndCBkbyBpdC5cclxuXHRcdGV2ZW50TmFtZXNwYWNlOiAnLnBhbnpvb20nLFxyXG5cclxuXHRcdC8vIFdoZXRoZXIgb3Igbm90IHRvIHRyYW5zaXRpb24gdGhlIHNjYWxlXHJcblx0XHR0cmFuc2l0aW9uOiB0cnVlLFxyXG5cclxuXHRcdC8vIERlZmF1bHQgY3Vyc29yIHN0eWxlIGZvciB0aGUgZWxlbWVudFxyXG5cdFx0Y3Vyc29yOiAnbW92ZScsXHJcblxyXG5cdFx0Ly8gVGhlcmUgbWF5IGJlIHNvbWUgdXNlIGNhc2VzIGZvciB6b29taW5nIHdpdGhvdXQgcGFubmluZyBvciB2aWNlIHZlcnNhXHJcblx0XHRkaXNhYmxlUGFuOiBmYWxzZSxcclxuXHRcdGRpc2FibGVab29tOiBmYWxzZSxcclxuXHJcblx0XHQvLyBUaGUgaW5jcmVtZW50IGF0IHdoaWNoIHRvIHpvb21cclxuXHRcdC8vIGFkZHMvc3VidHJhY3RzIHRvIHRoZSBzY2FsZSBlYWNoIHRpbWUgem9vbUluL091dCBpcyBjYWxsZWRcclxuXHRcdGluY3JlbWVudDogMC4zLFxyXG5cclxuXHRcdG1pblNjYWxlOiAwLjQsXHJcblx0XHRtYXhTY2FsZTogNSxcclxuXHJcblx0XHQvLyBUaGUgZGVmYXVsdCBzdGVwIGZvciB0aGUgcmFuZ2UgaW5wdXRcclxuXHRcdC8vIFByZWNlbmRlbmNlOiBkZWZhdWx0IDwgSFRNTCBhdHRyaWJ1dGUgPCBvcHRpb24gc2V0dGluZ1xyXG5cdFx0cmFuZ2VTdGVwOiAwLjA1LFxyXG5cclxuXHRcdC8vIEFuaW1hdGlvbiBkdXJhdGlvbiAobXMpXHJcblx0XHRkdXJhdGlvbjogMjAwLFxyXG5cdFx0Ly8gQ1NTIGVhc2luZyB1c2VkIGZvciBzY2FsZSB0cmFuc2l0aW9uXHJcblx0XHRlYXNpbmc6ICdlYXNlLWluLW91dCcsXHJcblxyXG5cdFx0Ly8gSW5kaWNhdGUgdGhhdCB0aGUgZWxlbWVudCBzaG91bGQgYmUgY29udGFpbmVkIHdpdGhpbiBpdCdzIHBhcmVudCB3aGVuIHBhbm5pbmdcclxuXHRcdC8vIE5vdGU6IHRoaXMgZG9lcyBub3QgYWZmZWN0IHpvb21pbmcgb3V0c2lkZSBvZiB0aGUgcGFyZW50XHJcblx0XHQvLyBTZXQgdGhpcyB2YWx1ZSB0byAnaW52ZXJ0JyB0byBvbmx5IGFsbG93IHBhbm5pbmcgb3V0c2lkZSBvZiB0aGUgcGFyZW50IGVsZW1lbnQgKGJhc2ljYWxseSB0aGUgb3Bwb3NpdGUgb2YgdGhlIG5vcm1hbCB1c2Ugb2YgY29udGFpbilcclxuXHRcdC8vICdpbnZlcnQnIGlzIHVzZWZ1bCBmb3IgYSBsYXJnZSBwYW56b29tIGVsZW1lbnQgd2hlcmUgeW91IGRvbid0IHdhbnQgdG8gc2hvdyBhbnl0aGluZyBiZWhpbmQgaXRcclxuXHRcdGNvbnRhaW46IGZhbHNlXHJcblx0fTtcclxuXHJcblx0UGFuem9vbS5wcm90b3R5cGUgPSB7XHJcblx0XHRjb25zdHJ1Y3RvcjogUGFuem9vbSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEByZXR1cm5zIHtQYW56b29tfSBSZXR1cm5zIHRoZSBpbnN0YW5jZVxyXG5cdFx0ICovXHJcblx0XHRpbnN0YW5jZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEVuYWJsZSBvciByZS1lbmFibGUgdGhlIHBhbnpvb20gaW5zdGFuY2VcclxuXHRcdCAqL1xyXG5cdFx0ZW5hYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0Ly8gVW5iaW5kIGZpcnN0XHJcblx0XHRcdHRoaXMuX2luaXRTdHlsZSgpO1xyXG5cdFx0XHR0aGlzLl9iaW5kKCk7XHJcblx0XHRcdHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBEaXNhYmxlIHBhbnpvb21cclxuXHRcdCAqL1xyXG5cdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdHRoaXMuZGlzYWJsZWQgPSB0cnVlO1xyXG5cdFx0XHR0aGlzLl9yZXNldFN0eWxlKCk7XHJcblx0XHRcdHRoaXMuX3VuYmluZCgpO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEByZXR1cm5zIHtCb29sZWFufSBSZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgcGFuem9vbSBpbnN0YW5jZSBpcyBkaXNhYmxlZFxyXG5cdFx0ICovXHJcblx0XHRpc0Rpc2FibGVkOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMuZGlzYWJsZWQ7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogRGVzdHJveSB0aGUgcGFuem9vbSBpbnN0YW5jZVxyXG5cdFx0ICovXHJcblx0XHRkZXN0cm95OiBmdW5jdGlvbigpIHtcclxuXHRcdFx0dGhpcy5kaXNhYmxlKCk7XHJcblx0XHRcdCQucmVtb3ZlRGF0YSh0aGlzLmVsZW0sIGRhdGFrZXkpO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEJ1aWxkcyB0aGUgcmVzdHJpY2luZyBkaW1lbnNpb25zIGZyb20gdGhlIGNvbnRhaW5tZW50IGVsZW1lbnRcclxuXHRcdCAqIEFsc28gdXNlZCB3aXRoIGZvY2FsIHBvaW50c1xyXG5cdFx0ICogQ2FsbCB0aGlzIG1ldGhvZCB3aGVuZXZlciB0aGUgZGltZW5zaW9ucyBvZiB0aGUgZWxlbWVudCBvciBwYXJlbnQgYXJlIGNoYW5nZWRcclxuXHRcdCAqL1xyXG5cdFx0cmVzZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0Ly8gUmVzZXQgY29udGFpbmVyIHByb3BlcnRpZXNcclxuXHRcdFx0dmFyICRwYXJlbnQgPSB0aGlzLiRwYXJlbnQ7XHJcblx0XHRcdHRoaXMuY29udGFpbmVyID0ge1xyXG5cdFx0XHRcdHdpZHRoOiAkcGFyZW50LmlubmVyV2lkdGgoKSxcclxuXHRcdFx0XHRoZWlnaHQ6ICRwYXJlbnQuaW5uZXJIZWlnaHQoKVxyXG5cdFx0XHR9O1xyXG5cdFx0XHR2YXIgcG8gPSAkcGFyZW50Lm9mZnNldCgpO1xyXG5cdFx0XHR2YXIgZWxlbSA9IHRoaXMuZWxlbTtcclxuXHRcdFx0dmFyICRlbGVtID0gdGhpcy4kZWxlbTtcclxuXHRcdFx0dmFyIGRpbXM7XHJcblx0XHRcdGlmICh0aGlzLmlzU1ZHKSB7XHJcblx0XHRcdFx0ZGltcyA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblx0XHRcdFx0ZGltcyA9IHtcclxuXHRcdFx0XHRcdGxlZnQ6IGRpbXMubGVmdCAtIHBvLmxlZnQsXHJcblx0XHRcdFx0XHR0b3A6IGRpbXMudG9wIC0gcG8udG9wLFxyXG5cdFx0XHRcdFx0d2lkdGg6IGRpbXMud2lkdGgsXHJcblx0XHRcdFx0XHRoZWlnaHQ6IGRpbXMuaGVpZ2h0LFxyXG5cdFx0XHRcdFx0bWFyZ2luOiB7IGxlZnQ6IDAsIHRvcDogMCB9XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRkaW1zID0ge1xyXG5cdFx0XHRcdFx0bGVmdDogJC5jc3MoZWxlbSwgJ2xlZnQnLCB0cnVlKSB8fCAwLFxyXG5cdFx0XHRcdFx0dG9wOiAkLmNzcyhlbGVtLCAndG9wJywgdHJ1ZSkgfHwgMCxcclxuXHRcdFx0XHRcdHdpZHRoOiAkZWxlbS5pbm5lcldpZHRoKCksXHJcblx0XHRcdFx0XHRoZWlnaHQ6ICRlbGVtLmlubmVySGVpZ2h0KCksXHJcblx0XHRcdFx0XHRtYXJnaW46IHtcclxuXHRcdFx0XHRcdFx0dG9wOiAkLmNzcyhlbGVtLCAnbWFyZ2luVG9wJywgdHJ1ZSkgfHwgMCxcclxuXHRcdFx0XHRcdFx0bGVmdDogJC5jc3MoZWxlbSwgJ21hcmdpbkxlZnQnLCB0cnVlKSB8fCAwXHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cdFx0XHRkaW1zLndpZHRoQm9yZGVyID0gKCQuY3NzKGVsZW0sICdib3JkZXJMZWZ0V2lkdGgnLCB0cnVlKSArICQuY3NzKGVsZW0sICdib3JkZXJSaWdodFdpZHRoJywgdHJ1ZSkpIHx8IDA7XHJcblx0XHRcdGRpbXMuaGVpZ2h0Qm9yZGVyID0gKCQuY3NzKGVsZW0sICdib3JkZXJUb3BXaWR0aCcsIHRydWUpICsgJC5jc3MoZWxlbSwgJ2JvcmRlckJvdHRvbVdpZHRoJywgdHJ1ZSkpIHx8IDA7XHJcblx0XHRcdHRoaXMuZGltZW5zaW9ucyA9IGRpbXM7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmV0dXJuIHRoZSBlbGVtZW50IHRvIGl0J3Mgb3JpZ2luYWwgdHJhbnNmb3JtIG1hdHJpeFxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9uc10gSWYgYSBib29sZWFuIGlzIHBhc3NlZCwgYW5pbWF0ZSB0aGUgcmVzZXQgKGRlZmF1bHQ6IHRydWUpLiBJZiBhbiBvcHRpb25zIG9iamVjdCBpcyBwYXNzZWQsIHNpbXBseSBwYXNzIHRoYXQgYWxvbmcgdG8gc2V0TWF0cml4LlxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zaWxlbnRdIFNpbGVuY2UgdGhlIHJlc2V0IGV2ZW50XHJcblx0XHQgKi9cclxuXHRcdHJlc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0XHRcdG9wdGlvbnMgPSBjcmVhdGVSZXNldE9wdGlvbnMob3B0aW9ucyk7XHJcblx0XHRcdC8vIFJlc2V0IHRoZSB0cmFuc2Zvcm0gdG8gaXRzIG9yaWdpbmFsIHZhbHVlXHJcblx0XHRcdHZhciBtYXRyaXggPSB0aGlzLnNldE1hdHJpeCh0aGlzLl9vcmlnVHJhbnNmb3JtLCBvcHRpb25zKTtcclxuXHRcdFx0aWYgKCFvcHRpb25zLnNpbGVudCkge1xyXG5cdFx0XHRcdHRoaXMuX3RyaWdnZXIoJ3Jlc2V0JywgbWF0cml4KTtcclxuXHRcdFx0fVxyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIE9ubHkgcmVzZXRzIHpvb20gbGV2ZWxcclxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IFtvcHRpb25zXSBXaGV0aGVyIHRvIGFuaW1hdGUgdGhlIHJlc2V0IChkZWZhdWx0OiB0cnVlKSBvciBhbiBvYmplY3Qgb2Ygb3B0aW9ucyB0byBwYXNzIHRvIHpvb20oKVxyXG5cdFx0ICovXHJcblx0XHRyZXNldFpvb206IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHRcdFx0b3B0aW9ucyA9IGNyZWF0ZVJlc2V0T3B0aW9ucyhvcHRpb25zKTtcclxuXHRcdFx0dmFyIG9yaWdNYXRyaXggPSB0aGlzLmdldE1hdHJpeCh0aGlzLl9vcmlnVHJhbnNmb3JtKTtcclxuXHRcdFx0b3B0aW9ucy5kVmFsdWUgPSBvcmlnTWF0cml4WyAzIF07XHJcblx0XHRcdHRoaXMuem9vbShvcmlnTWF0cml4WzBdLCBvcHRpb25zKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBPbmx5IHJlc2V0IHBhbm5pbmdcclxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IFtvcHRpb25zXSBXaGV0aGVyIHRvIGFuaW1hdGUgdGhlIHJlc2V0IChkZWZhdWx0OiB0cnVlKSBvciBhbiBvYmplY3Qgb2Ygb3B0aW9ucyB0byBwYXNzIHRvIHBhbigpXHJcblx0XHQgKi9cclxuXHRcdHJlc2V0UGFuOiBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0XHRcdHZhciBvcmlnTWF0cml4ID0gdGhpcy5nZXRNYXRyaXgodGhpcy5fb3JpZ1RyYW5zZm9ybSk7XHJcblx0XHRcdHRoaXMucGFuKG9yaWdNYXRyaXhbNF0sIG9yaWdNYXRyaXhbNV0sIGNyZWF0ZVJlc2V0T3B0aW9ucyhvcHRpb25zKSk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogU2V0cyBhIHRyYW5zZm9ybSBvbiB0aGUgJHNldFxyXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zZm9ybVxyXG5cdFx0ICovXHJcblx0XHRzZXRUcmFuc2Zvcm06IGZ1bmN0aW9uKHRyYW5zZm9ybSkge1xyXG5cdFx0XHR2YXIgbWV0aG9kID0gdGhpcy5pc1NWRyA/ICdhdHRyJyA6ICdzdHlsZSc7XHJcblx0XHRcdHZhciAkc2V0ID0gdGhpcy4kc2V0O1xyXG5cdFx0XHR2YXIgaSA9ICRzZXQubGVuZ3RoO1xyXG5cdFx0XHR3aGlsZShpLS0pIHtcclxuXHRcdFx0XHQkW21ldGhvZF0oJHNldFtpXSwgJ3RyYW5zZm9ybScsIHRyYW5zZm9ybSk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZXRyaWV2aW5nIHRoZSB0cmFuc2Zvcm0gaXMgZGlmZmVyZW50IGZvciBTVkdcclxuXHRcdCAqICAodW5sZXNzIGEgc3R5bGUgdHJhbnNmb3JtIGlzIGFscmVhZHkgcHJlc2VudClcclxuXHRcdCAqIFVzZXMgdGhlICRzZXQgY29sbGVjdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdHJhbnNmb3JtXHJcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gW3RyYW5zZm9ybV0gUGFzcyBpbiBhbiB0cmFuc2Zvcm0gdmFsdWUgKGxpa2UgJ3NjYWxlKDEuMSknKVxyXG5cdFx0ICogIHRvIGhhdmUgaXQgZm9ybWF0dGVkIGludG8gbWF0cml4IGZvcm1hdCBmb3IgdXNlIGJ5IFBhbnpvb21cclxuXHRcdCAqIEByZXR1cm5zIHtTdHJpbmd9IFJldHVybnMgdGhlIGN1cnJlbnQgdHJhbnNmb3JtIHZhbHVlIG9mIHRoZSBlbGVtZW50XHJcblx0XHQgKi9cclxuXHRcdGdldFRyYW5zZm9ybTogZnVuY3Rpb24odHJhbnNmb3JtKSB7XHJcblx0XHRcdHZhciAkc2V0ID0gdGhpcy4kc2V0O1xyXG5cdFx0XHR2YXIgdHJhbnNmb3JtRWxlbSA9ICRzZXRbMF07XHJcblx0XHRcdGlmICh0cmFuc2Zvcm0pIHtcclxuXHRcdFx0XHR0aGlzLnNldFRyYW5zZm9ybSh0cmFuc2Zvcm0pO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdC8vIFJldHJpZXZlIHRoZSB0cmFuc2Zvcm1cclxuXHRcdFx0XHR0cmFuc2Zvcm0gPSAkW3RoaXMuaXNTVkcgPyAnYXR0cicgOiAnc3R5bGUnXSh0cmFuc2Zvcm1FbGVtLCAndHJhbnNmb3JtJyk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIENvbnZlcnQgYW55IHRyYW5zZm9ybXMgc2V0IGJ5IHRoZSB1c2VyIHRvIG1hdHJpeCBmb3JtYXRcclxuXHRcdFx0Ly8gYnkgc2V0dGluZyB0byBjb21wdXRlZFxyXG5cdFx0XHRpZiAodHJhbnNmb3JtICE9PSAnbm9uZScgJiYgIXJtYXRyaXgudGVzdCh0cmFuc2Zvcm0pKSB7XHJcblx0XHRcdFx0Ly8gR2V0IGNvbXB1dGVkIGFuZCBzZXQgZm9yIG5leHQgdGltZVxyXG5cdFx0XHRcdHRoaXMuc2V0VHJhbnNmb3JtKHRyYW5zZm9ybSA9ICQuY3NzKHRyYW5zZm9ybUVsZW0sICd0cmFuc2Zvcm0nKSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiB0cmFuc2Zvcm0gfHwgJ25vbmUnO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJldHJpZXZlIHRoZSBjdXJyZW50IHRyYW5zZm9ybSBtYXRyaXggZm9yICRlbGVtIChvciB0dXJuIGEgdHJhbnNmb3JtIGludG8gaXQncyBhcnJheSB2YWx1ZXMpXHJcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gW3RyYW5zZm9ybV0gbWF0cml4LWZvcm1hdHRlZCB0cmFuc2Zvcm0gdmFsdWVcclxuXHRcdCAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY3VycmVudCB0cmFuc2Zvcm0gbWF0cml4IHNwbGl0IHVwIGludG8gaXQncyBwYXJ0cywgb3IgYSBkZWZhdWx0IG1hdHJpeFxyXG5cdFx0ICovXHJcblx0XHRnZXRNYXRyaXg6IGZ1bmN0aW9uKHRyYW5zZm9ybSkge1xyXG5cdFx0XHR2YXIgbWF0cml4ID0gcm1hdHJpeC5leGVjKHRyYW5zZm9ybSB8fCB0aGlzLmdldFRyYW5zZm9ybSgpKTtcclxuXHRcdFx0aWYgKG1hdHJpeCkge1xyXG5cdFx0XHRcdG1hdHJpeC5zaGlmdCgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBtYXRyaXggfHwgWyAxLCAwLCAwLCAxLCAwLCAwIF07XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogR2l2ZW4gYSBtYXRyaXggb2JqZWN0LCBxdWlja2x5IHNldCB0aGUgY3VycmVudCBtYXRyaXggb2YgdGhlIGVsZW1lbnRcclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBtYXRyaXhcclxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW2FuaW1hdGVdIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgdHJhbnNmb3JtIGNoYW5nZVxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufFN0cmluZ30gW29wdGlvbnMuYW5pbWF0ZV0gV2hldGhlciB0byBhbmltYXRlIHRoZSB0cmFuc2Zvcm0gY2hhbmdlLCBvciAnc2tpcCcgaW5kaWNhdGluZyB0aGF0IGl0IGlzIHVubmVjZXNzYXJ5IHRvIHNldFxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5jb250YWluXSBPdmVycmlkZSB0aGUgZ2xvYmFsIGNvbnRhaW4gb3B0aW9uXHJcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnJhbmdlXSBJZiB0cnVlLCAkem9vbVJhbmdlJ3MgdmFsdWUgd2lsbCBiZSB1cGRhdGVkLlxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zaWxlbnRdIElmIHRydWUsIHRoZSBjaGFuZ2UgZXZlbnQgd2lsbCBub3QgYmUgdHJpZ2dlcmVkXHJcblx0XHQgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ld2x5LXNldCBtYXRyaXhcclxuXHRcdCAqL1xyXG5cdFx0c2V0TWF0cml4OiBmdW5jdGlvbihtYXRyaXgsIG9wdGlvbnMpIHtcclxuXHRcdFx0aWYgKHRoaXMuZGlzYWJsZWQpIHsgcmV0dXJuOyB9XHJcblx0XHRcdGlmICghb3B0aW9ucykgeyBvcHRpb25zID0ge307IH1cclxuXHRcdFx0Ly8gQ29udmVydCB0byBhcnJheVxyXG5cdFx0XHRpZiAodHlwZW9mIG1hdHJpeCA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0XHRtYXRyaXggPSB0aGlzLmdldE1hdHJpeChtYXRyaXgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZhciBkaW1zLCBjb250YWluZXIsIG1hcmdpblcsIG1hcmdpbkgsIGRpZmZXLCBkaWZmSCwgbGVmdCwgdG9wLCB3aWR0aCwgaGVpZ2h0O1xyXG5cdFx0XHR2YXIgc2NhbGUgPSArbWF0cml4WzBdO1xyXG5cdFx0XHR2YXIgJHBhcmVudCA9IHRoaXMuJHBhcmVudDtcclxuXHRcdFx0dmFyIGNvbnRhaW4gPSB0eXBlb2Ygb3B0aW9ucy5jb250YWluICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMuY29udGFpbiA6IHRoaXMub3B0aW9ucy5jb250YWluO1xyXG5cclxuXHRcdFx0Ly8gQXBwbHkgY29udGFpbm1lbnRcclxuXHRcdFx0aWYgKGNvbnRhaW4pIHtcclxuXHRcdFx0XHRkaW1zID0gdGhpcy5fY2hlY2tEaW1zKCk7XHJcblx0XHRcdFx0Y29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XHJcblx0XHRcdFx0d2lkdGggPSBkaW1zLndpZHRoICsgZGltcy53aWR0aEJvcmRlcjtcclxuXHRcdFx0XHRoZWlnaHQgPSBkaW1zLmhlaWdodCArIGRpbXMuaGVpZ2h0Qm9yZGVyO1xyXG5cdFx0XHRcdC8vIFVzZSBhYnNvbHV0ZSB2YWx1ZSBvZiBzY2FsZSBoZXJlIGFzIG5lZ2F0aXZlIHNjYWxlIGRvZXNuJ3QgbWVhbiBldmVuIHNtYWxsZXJcclxuXHRcdFx0XHRtYXJnaW5XID0gKCh3aWR0aCAqIE1hdGguYWJzKHNjYWxlKSkgLSBjb250YWluZXIud2lkdGgpIC8gMjtcclxuXHRcdFx0XHRtYXJnaW5IID0gKChoZWlnaHQgKiBNYXRoLmFicyhzY2FsZSkpIC0gY29udGFpbmVyLmhlaWdodCkgLyAyO1xyXG5cdFx0XHRcdGxlZnQgPSBkaW1zLmxlZnQgKyBkaW1zLm1hcmdpbi5sZWZ0O1xyXG5cdFx0XHRcdHRvcCA9IGRpbXMudG9wICsgZGltcy5tYXJnaW4udG9wO1xyXG5cdFx0XHRcdGlmIChjb250YWluID09PSAnaW52ZXJ0Jykge1xyXG5cdFx0XHRcdFx0ZGlmZlcgPSB3aWR0aCA+IGNvbnRhaW5lci53aWR0aCA/IHdpZHRoIC0gY29udGFpbmVyLndpZHRoIDogMDtcclxuXHRcdFx0XHRcdGRpZmZIID0gaGVpZ2h0ID4gY29udGFpbmVyLmhlaWdodCA/IGhlaWdodCAtIGNvbnRhaW5lci5oZWlnaHQgOiAwO1xyXG5cdFx0XHRcdFx0bWFyZ2luVyArPSAoY29udGFpbmVyLndpZHRoIC0gd2lkdGgpIC8gMjtcclxuXHRcdFx0XHRcdG1hcmdpbkggKz0gKGNvbnRhaW5lci5oZWlnaHQgLSBoZWlnaHQpIC8gMjtcclxuXHRcdFx0XHRcdG1hdHJpeFs0XSA9IE1hdGgubWF4KE1hdGgubWluKG1hdHJpeFs0XSwgbWFyZ2luVyAtIGxlZnQpLCAtbWFyZ2luVyAtIGxlZnQgLSBkaWZmVyk7XHJcblx0XHRcdFx0XHRtYXRyaXhbNV0gPSBNYXRoLm1heChNYXRoLm1pbihtYXRyaXhbNV0sIG1hcmdpbkggLSB0b3ApLCAtbWFyZ2luSCAtIHRvcCAtIGRpZmZIICsgZGltcy5oZWlnaHRCb3JkZXIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHQvLyBtYXJnaW5XICs9IGRpbXMud2lkdGhCb3JkZXIgLyAyO1xyXG5cdFx0XHRcdFx0bWFyZ2luSCArPSBkaW1zLmhlaWdodEJvcmRlciAvIDI7XHJcblx0XHRcdFx0XHRkaWZmVyA9IGNvbnRhaW5lci53aWR0aCA+IHdpZHRoID8gY29udGFpbmVyLndpZHRoIC0gd2lkdGggOiAwO1xyXG5cdFx0XHRcdFx0ZGlmZkggPSBjb250YWluZXIuaGVpZ2h0ID4gaGVpZ2h0ID8gY29udGFpbmVyLmhlaWdodCAtIGhlaWdodCA6IDA7XHJcblx0XHRcdFx0XHQvLyBJZiB0aGUgZWxlbWVudCBpcyBub3QgbmF0dXJhbGx5IGNlbnRlcmVkLCBhc3N1bWUgZnVsbCBtYXJnaW4gcmlnaHRcclxuXHRcdFx0XHRcdGlmICgkcGFyZW50LmNzcygndGV4dEFsaWduJykgIT09ICdjZW50ZXInIHx8ICFyaW5saW5lLnRlc3QoJC5jc3ModGhpcy5lbGVtLCAnZGlzcGxheScpKSkge1xyXG5cdFx0XHRcdFx0XHRtYXJnaW5XID0gbWFyZ2luSCA9IDA7XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRkaWZmVyA9IDA7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRtYXRyaXhbNF0gPSBNYXRoLm1pbihcclxuXHRcdFx0XHRcdFx0TWF0aC5tYXgobWF0cml4WzRdLCBtYXJnaW5XIC0gbGVmdCksXHJcblx0XHRcdFx0XHRcdC1tYXJnaW5XIC0gbGVmdCArIGRpZmZXXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0bWF0cml4WzVdID0gTWF0aC5taW4oXHJcblx0XHRcdFx0XHRcdE1hdGgubWF4KG1hdHJpeFs1XSwgbWFyZ2luSCAtIHRvcCksXHJcblx0XHRcdFx0XHRcdC1tYXJnaW5IIC0gdG9wICsgZGlmZkhcclxuXHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChvcHRpb25zLmFuaW1hdGUgIT09ICdza2lwJykge1xyXG5cdFx0XHRcdC8vIFNldCB0cmFuc2l0aW9uXHJcblx0XHRcdFx0dGhpcy50cmFuc2l0aW9uKCFvcHRpb25zLmFuaW1hdGUpO1xyXG5cdFx0XHR9XHJcblx0XHRcdC8vIFVwZGF0ZSByYW5nZVxyXG5cdFx0XHRpZiAob3B0aW9ucy5yYW5nZSkge1xyXG5cdFx0XHRcdHRoaXMuJHpvb21SYW5nZS52YWwoc2NhbGUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZXQgdGhlIG1hdHJpeCBvbiB0aGlzLiRzZXRcclxuXHRcdFx0dGhpcy5zZXRUcmFuc2Zvcm0oJ21hdHJpeCgnICsgbWF0cml4LmpvaW4oJywnKSArICcpJyk7XHJcblxyXG5cdFx0XHRpZiAoIW9wdGlvbnMuc2lsZW50KSB7XHJcblx0XHRcdFx0dGhpcy5fdHJpZ2dlcignY2hhbmdlJywgbWF0cml4KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG1hdHJpeDtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBAcmV0dXJucyB7Qm9vbGVhbn0gUmV0dXJucyB3aGV0aGVyIHRoZSBwYW56b29tIGVsZW1lbnQgaXMgY3VycmVudGx5IGJlaW5nIGRyYWdnZWRcclxuXHRcdCAqL1xyXG5cdFx0aXNQYW5uaW5nOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMucGFubmluZztcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBBcHBseSB0aGUgY3VycmVudCB0cmFuc2l0aW9uIHRvIHRoZSBlbGVtZW50LCBpZiBhbGxvd2VkXHJcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvZmZdIEluZGljYXRlcyB0aGF0IHRoZSB0cmFuc2l0aW9uIHNob3VsZCBiZSB0dXJuZWQgb2ZmXHJcblx0XHQgKi9cclxuXHRcdHRyYW5zaXRpb246IGZ1bmN0aW9uKG9mZikge1xyXG5cdFx0XHRpZiAoIXRoaXMuX3RyYW5zaXRpb24pIHsgcmV0dXJuOyB9XHJcblx0XHRcdHZhciB0cmFuc2l0aW9uID0gb2ZmIHx8ICF0aGlzLm9wdGlvbnMudHJhbnNpdGlvbiA/ICdub25lJyA6IHRoaXMuX3RyYW5zaXRpb247XHJcblx0XHRcdHZhciAkc2V0ID0gdGhpcy4kc2V0O1xyXG5cdFx0XHR2YXIgaSA9ICRzZXQubGVuZ3RoO1xyXG5cdFx0XHR3aGlsZShpLS0pIHtcclxuXHRcdFx0XHQvLyBBdm9pZCByZWZsb3dzIHdoZW4gem9vbWluZ1xyXG5cdFx0XHRcdGlmICgkLnN0eWxlKCRzZXRbaV0sICd0cmFuc2l0aW9uJykgIT09IHRyYW5zaXRpb24pIHtcclxuXHRcdFx0XHRcdCQuc3R5bGUoJHNldFtpXSwgJ3RyYW5zaXRpb24nLCB0cmFuc2l0aW9uKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBQYW4gdGhlIGVsZW1lbnQgdG8gdGhlIHNwZWNpZmllZCB0cmFuc2xhdGlvbiBYIGFuZCBZXHJcblx0XHQgKiBOb3RlOiB0aGlzIGlzIG5vdCB0aGUgc2FtZSBhcyBzZXR0aW5nIGpRdWVyeSNvZmZzZXQoKSBvciBqUXVlcnkjcG9zaXRpb24oKVxyXG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcclxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSB5XHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIFRoZXNlIG9wdGlvbnMgYXJlIHBhc3NlZCBhbG9uZyB0byBzZXRNYXRyaXhcclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IFtvcHRpb25zLm1hdHJpeF0gVGhlIG1hdHJpeCBiZWluZyBtYW5pcHVsYXRlZCAoaWYgYWxyZWFkeSBrbm93biBzbyBpdCBkb2Vzbid0IGhhdmUgdG8gYmUgcmV0cmlldmVkIGFnYWluKVxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zaWxlbnRdIFNpbGVuY2UgdGhlIHBhbiBldmVudC4gTm90ZSB0aGF0IHRoaXMgd2lsbCBhbHNvIHNpbGVuY2UgdGhlIHNldE1hdHJpeCBjaGFuZ2UgZXZlbnQuXHJcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnJlbGF0aXZlXSBNYWtlIHRoZSB4IGFuZCB5IHZhbHVlcyByZWxhdGl2ZSB0byB0aGUgZXhpc3RpbmcgbWF0cml4XHJcblx0XHQgKi9cclxuXHRcdHBhbjogZnVuY3Rpb24oeCwgeSwgb3B0aW9ucykge1xyXG5cdFx0XHRpZiAodGhpcy5vcHRpb25zLmRpc2FibGVQYW4pIHsgcmV0dXJuOyB9XHJcblx0XHRcdGlmICghb3B0aW9ucykgeyBvcHRpb25zID0ge307IH1cclxuXHRcdFx0dmFyIG1hdHJpeCA9IG9wdGlvbnMubWF0cml4O1xyXG5cdFx0XHRpZiAoIW1hdHJpeCkge1xyXG5cdFx0XHRcdG1hdHJpeCA9IHRoaXMuZ2V0TWF0cml4KCk7XHJcblx0XHRcdH1cclxuXHRcdFx0Ly8gQ2FzdCBleGlzdGluZyBtYXRyaXggdmFsdWVzIHRvIG51bWJlcnNcclxuXHRcdFx0aWYgKG9wdGlvbnMucmVsYXRpdmUpIHtcclxuXHRcdFx0XHR4ICs9ICttYXRyaXhbNF07XHJcblx0XHRcdFx0eSArPSArbWF0cml4WzVdO1xyXG5cdFx0XHR9XHJcblx0XHRcdG1hdHJpeFs0XSA9IHg7XHJcblx0XHRcdG1hdHJpeFs1XSA9IHk7XHJcblx0XHRcdHRoaXMuc2V0TWF0cml4KG1hdHJpeCwgb3B0aW9ucyk7XHJcblx0XHRcdGlmICghb3B0aW9ucy5zaWxlbnQpIHtcclxuXHRcdFx0XHR0aGlzLl90cmlnZ2VyKCdwYW4nLCBtYXRyaXhbNF0sIG1hdHJpeFs1XSk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBab29tIGluL291dCB0aGUgZWxlbWVudCB1c2luZyB0aGUgc2NhbGUgcHJvcGVydGllcyBvZiBhIHRyYW5zZm9ybSBtYXRyaXhcclxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfEJvb2xlYW59IFtzY2FsZV0gVGhlIHNjYWxlIHRvIHdoaWNoIHRvIHpvb20gb3IgYSBib29sZWFuIGluZGljYXRpbmcgdG8gdHJhbnNpdGlvbiBhIHpvb20gb3V0XHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gW29wdHNdIEFsbCBnbG9iYWwgb3B0aW9ucyBjYW4gYmUgb3ZlcndyaXR0ZW4gYnkgdGhpcyBvcHRpb25zIG9iamVjdC4gRm9yIGV4YW1wbGUsIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGluY3JlbWVudC5cclxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdHMubm9TZXRSYW5nZV0gU3BlY2lmeSB0aGF0IHRoZSBtZXRob2Qgc2hvdWxkIG5vdCBzZXQgdGhlICR6b29tUmFuZ2UgdmFsdWUgKGFzIGlzIHRoZSBjYXNlIHdoZW4gJHpvb21SYW5nZSBpcyBjYWxsaW5nIHpvb20gb24gY2hhbmdlKVxyXG5cdFx0ICogQHBhcmFtIHtqUXVlcnkuRXZlbnR8T2JqZWN0fSBbb3B0cy5mb2NhbF0gQSBmb2NhbCBwb2ludCBvbiB0aGUgcGFuem9vbSBlbGVtZW50IG9uIHdoaWNoIHRvIHpvb20uXHJcblx0XHQgKiAgSWYgYW4gb2JqZWN0LCBzZXQgdGhlIGNsaWVudFggYW5kIGNsaWVudFkgcHJvcGVydGllcyB0byB0aGUgcG9zaXRpb24gcmVsYXRpdmUgdG8gdGhlIHBhcmVudFxyXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0cy5hbmltYXRlXSBXaGV0aGVyIHRvIGFuaW1hdGUgdGhlIHpvb20gKGRlZmF1bHRzIHRvIHRydWUgaWYgc2NhbGUgaXMgbm90IGEgbnVtYmVyLCBmYWxzZSBvdGhlcndpc2UpXHJcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRzLnNpbGVudF0gU2lsZW5jZSB0aGUgem9vbSBldmVudFxyXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gW29wdHMubWF0cml4XSBPcHRpb25hbGx5IHBhc3MgdGhlIGN1cnJlbnQgbWF0cml4IHNvIGl0IGRvZXNuJ3QgbmVlZCB0byBiZSByZXRyaWV2ZWRcclxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0cy5kVmFsdWVdIFRoaW5rIG9mIGEgdHJhbnNmb3JtIG1hdHJpeCBhcyBmb3VyIHZhbHVlcyBhLCBiLCBjLCBkXHJcblx0XHQgKiAgd2hlcmUgYS9kIGFyZSB0aGUgaG9yaXpvbnRhbC92ZXJ0aWNhbCBzY2FsZSB2YWx1ZXMgYW5kIGIvYyBhcmUgdGhlIHNrZXcgdmFsdWVzXHJcblx0XHQgKiAgKDUgYW5kIDYgb2YgbWF0cml4IGFycmF5IGFyZSB0aGUgdHgvdHkgdHJhbnNmb3JtIHZhbHVlcykuXHJcblx0XHQgKiAgTm9ybWFsbHksIHRoZSBzY2FsZSBpcyBzZXQgdG8gYm90aCB0aGUgYSBhbmQgZCB2YWx1ZXMgb2YgdGhlIG1hdHJpeC5cclxuXHRcdCAqICBUaGlzIG9wdGlvbiBhbGxvd3MgeW91IHRvIHNwZWNpZnkgYSBkaWZmZXJlbnQgZCB2YWx1ZSBmb3IgdGhlIHpvb20uXHJcblx0XHQgKiAgRm9yIGluc3RhbmNlLCB0byBmbGlwIHZlcnRpY2FsbHksIHlvdSBjb3VsZCBzZXQgLTEgYXMgdGhlIGRWYWx1ZS5cclxuXHRcdCAqL1xyXG5cdFx0em9vbTogZnVuY3Rpb24oc2NhbGUsIG9wdHMpIHtcclxuXHRcdFx0Ly8gU2h1ZmZsZSBhcmd1bWVudHNcclxuXHRcdFx0aWYgKHR5cGVvZiBzY2FsZSA9PT0gJ29iamVjdCcpIHtcclxuXHRcdFx0XHRvcHRzID0gc2NhbGU7XHJcblx0XHRcdFx0c2NhbGUgPSBudWxsO1xyXG5cdFx0XHR9IGVsc2UgaWYgKCFvcHRzKSB7XHJcblx0XHRcdFx0b3B0cyA9IHt9O1xyXG5cdFx0XHR9XHJcblx0XHRcdHZhciBvcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMub3B0aW9ucywgb3B0cyk7XHJcblx0XHRcdC8vIENoZWNrIGlmIGRpc2FibGVkXHJcblx0XHRcdGlmIChvcHRpb25zLmRpc2FibGVab29tKSB7IHJldHVybjsgfVxyXG5cdFx0XHR2YXIgYW5pbWF0ZSA9IGZhbHNlO1xyXG5cdFx0XHR2YXIgbWF0cml4ID0gb3B0aW9ucy5tYXRyaXggfHwgdGhpcy5nZXRNYXRyaXgoKTtcclxuXHJcblx0XHRcdC8vIENhbGN1bGF0ZSB6b29tIGJhc2VkIG9uIGluY3JlbWVudFxyXG5cdFx0XHRpZiAodHlwZW9mIHNjYWxlICE9PSAnbnVtYmVyJykge1xyXG5cdFx0XHRcdHNjYWxlID0gK21hdHJpeFswXSArIChvcHRpb25zLmluY3JlbWVudCAqIChzY2FsZSA/IC0xIDogMSkpO1xyXG5cdFx0XHRcdGFuaW1hdGUgPSB0cnVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBDb25zdHJhaW4gc2NhbGVcclxuXHRcdFx0aWYgKHNjYWxlID4gb3B0aW9ucy5tYXhTY2FsZSkge1xyXG5cdFx0XHRcdHNjYWxlID0gb3B0aW9ucy5tYXhTY2FsZTtcclxuXHRcdFx0fSBlbHNlIGlmIChzY2FsZSA8IG9wdGlvbnMubWluU2NhbGUpIHtcclxuXHRcdFx0XHRzY2FsZSA9IG9wdGlvbnMubWluU2NhbGU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIENhbGN1bGF0ZSBmb2NhbCBwb2ludCBiYXNlZCBvbiBzY2FsZVxyXG5cdFx0XHR2YXIgZm9jYWwgPSBvcHRpb25zLmZvY2FsO1xyXG5cdFx0XHRpZiAoZm9jYWwgJiYgIW9wdGlvbnMuZGlzYWJsZVBhbikge1xyXG5cdFx0XHRcdC8vIEFkYXB0ZWQgZnJvbSBjb2RlIGJ5IEZsb3JpYW4gR8O8bnRoZXJcclxuXHRcdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vZmxvcmlhbmd1ZW50aGVyL3p1aTUzXHJcblx0XHRcdFx0dmFyIGRpbXMgPSB0aGlzLl9jaGVja0RpbXMoKTtcclxuXHRcdFx0XHR2YXIgY2xpZW50WCA9IGZvY2FsLmNsaWVudFg7XHJcblx0XHRcdFx0dmFyIGNsaWVudFkgPSBmb2NhbC5jbGllbnRZO1xyXG5cdFx0XHRcdC8vIEFkanVzdCB0aGUgZm9jYWwgcG9pbnQgZm9yIGRlZmF1bHQgdHJhbnNmb3JtLW9yaWdpbiA9PiA1MCUgNTAlXHJcblx0XHRcdFx0aWYgKCF0aGlzLmlzU1ZHKSB7XHJcblx0XHRcdFx0XHRjbGllbnRYIC09IChkaW1zLndpZHRoICsgZGltcy53aWR0aEJvcmRlcikgLyAyO1xyXG5cdFx0XHRcdFx0Y2xpZW50WSAtPSAoZGltcy5oZWlnaHQgKyBkaW1zLmhlaWdodEJvcmRlcikgLyAyO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR2YXIgY2xpZW50ViA9IG5ldyBWZWN0b3IoY2xpZW50WCwgY2xpZW50WSwgMSk7XHJcblx0XHRcdFx0dmFyIHN1cmZhY2VNID0gbmV3IE1hdHJpeChtYXRyaXgpO1xyXG5cdFx0XHRcdC8vIFN1cHBseSBhbiBvZmZzZXQgbWFudWFsbHkgaWYgbmVjZXNzYXJ5XHJcblx0XHRcdFx0dmFyIG8gPSB0aGlzLnBhcmVudE9mZnNldCB8fCB0aGlzLiRwYXJlbnQub2Zmc2V0KCk7XHJcblx0XHRcdFx0dmFyIG9mZnNldE0gPSBuZXcgTWF0cml4KDEsIDAsIG8ubGVmdCAtIHRoaXMuJGRvYy5zY3JvbGxMZWZ0KCksIDAsIDEsIG8udG9wIC0gdGhpcy4kZG9jLnNjcm9sbFRvcCgpKTtcclxuXHRcdFx0XHR2YXIgc3VyZmFjZVYgPSBzdXJmYWNlTS5pbnZlcnNlKCkueChvZmZzZXRNLmludmVyc2UoKS54KGNsaWVudFYpKTtcclxuXHRcdFx0XHR2YXIgc2NhbGVCeSA9IHNjYWxlIC8gbWF0cml4WzBdO1xyXG5cdFx0XHRcdHN1cmZhY2VNID0gc3VyZmFjZU0ueChuZXcgTWF0cml4KFsgc2NhbGVCeSwgMCwgMCwgc2NhbGVCeSwgMCwgMCBdKSk7XHJcblx0XHRcdFx0Y2xpZW50ViA9IG9mZnNldE0ueChzdXJmYWNlTS54KHN1cmZhY2VWKSk7XHJcblx0XHRcdFx0bWF0cml4WzRdID0gK21hdHJpeFs0XSArIChjbGllbnRYIC0gY2xpZW50Vi5lKDApKTtcclxuXHRcdFx0XHRtYXRyaXhbNV0gPSArbWF0cml4WzVdICsgKGNsaWVudFkgLSBjbGllbnRWLmUoMSkpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZXQgdGhlIHNjYWxlXHJcblx0XHRcdG1hdHJpeFswXSA9IHNjYWxlO1xyXG5cdFx0XHRtYXRyaXhbM10gPSB0eXBlb2Ygb3B0aW9ucy5kVmFsdWUgPT09ICdudW1iZXInID8gb3B0aW9ucy5kVmFsdWUgOiBzY2FsZTtcclxuXHJcblx0XHRcdC8vIENhbGxpbmcgem9vbSBtYXkgc3RpbGwgcGFuIHRoZSBlbGVtZW50XHJcblx0XHRcdHRoaXMuc2V0TWF0cml4KG1hdHJpeCwge1xyXG5cdFx0XHRcdGFuaW1hdGU6IHR5cGVvZiBvcHRpb25zLmFuaW1hdGUgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuYW5pbWF0ZSA6IGFuaW1hdGUsXHJcblx0XHRcdFx0Ly8gU2V0IHRoZSB6b29tUmFuZ2UgdmFsdWVcclxuXHRcdFx0XHRyYW5nZTogIW9wdGlvbnMubm9TZXRSYW5nZVxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdC8vIFRyaWdnZXIgem9vbSBldmVudFxyXG5cdFx0XHRpZiAoIW9wdGlvbnMuc2lsZW50KSB7XHJcblx0XHRcdFx0dGhpcy5fdHJpZ2dlcignem9vbScsIG1hdHJpeFswXSwgb3B0aW9ucyk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBHZXQvc2V0IG9wdGlvbiBvbiBhbiBleGlzdGluZyBpbnN0YW5jZVxyXG5cdFx0ICogQHJldHVybnMge0FycmF5fHVuZGVmaW5lZH0gSWYgZ2V0dGluZywgcmV0dXJucyBhbiBhcnJheSBvZiBhbGwgdmFsdWVzXHJcblx0XHQgKiAgIG9uIGVhY2ggaW5zdGFuY2UgZm9yIGEgZ2l2ZW4ga2V5LiBJZiBzZXR0aW5nLCBjb250aW51ZSBjaGFpbmluZyBieSByZXR1cm5pbmcgdW5kZWZpbmVkLlxyXG5cdFx0ICovXHJcblx0XHRvcHRpb246IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcclxuXHRcdFx0dmFyIG9wdGlvbnM7XHJcblx0XHRcdGlmICgha2V5KSB7XHJcblx0XHRcdFx0Ly8gQXZvaWRzIHJldHVybmluZyBkaXJlY3QgcmVmZXJlbmNlXHJcblx0XHRcdFx0cmV0dXJuICQuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAodHlwZW9mIGtleSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMub3B0aW9uc1sga2V5IF0gIT09IHVuZGVmaW5lZCA/XHJcblx0XHRcdFx0XHRcdHRoaXMub3B0aW9uc1sga2V5IF0gOlxyXG5cdFx0XHRcdFx0XHRudWxsO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRvcHRpb25zID0ge307XHJcblx0XHRcdFx0b3B0aW9uc1sga2V5IF0gPSB2YWx1ZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRvcHRpb25zID0ga2V5O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLl9zZXRPcHRpb25zKG9wdGlvbnMpO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEludGVybmFsbHkgc2V0cyBvcHRpb25zXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEFuIG9iamVjdCBsaXRlcmFsIG9mIG9wdGlvbnMgdG8gc2V0XHJcblx0XHQgKi9cclxuXHRcdF9zZXRPcHRpb25zOiBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0XHRcdCQuZWFjaChvcHRpb25zLCAkLnByb3h5KGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcclxuXHRcdFx0XHRzd2l0Y2goa2V5KSB7XHJcblx0XHRcdFx0XHRjYXNlICdkaXNhYmxlUGFuJzpcclxuXHRcdFx0XHRcdFx0dGhpcy5fcmVzZXRTdHlsZSgpO1xyXG5cdFx0XHRcdFx0XHQvKiBmYWxscyB0aHJvdWdoICovXHJcblx0XHRcdFx0XHRjYXNlICckem9vbUluJzpcclxuXHRcdFx0XHRcdGNhc2UgJyR6b29tT3V0JzpcclxuXHRcdFx0XHRcdGNhc2UgJyR6b29tUmFuZ2UnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnJHJlc2V0JzpcclxuXHRcdFx0XHRcdGNhc2UgJ2Rpc2FibGVab29tJzpcclxuXHRcdFx0XHRcdGNhc2UgJ29uU3RhcnQnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25DaGFuZ2UnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25ab29tJzpcclxuXHRcdFx0XHRcdGNhc2UgJ29uUGFuJzpcclxuXHRcdFx0XHRcdGNhc2UgJ29uRW5kJzpcclxuXHRcdFx0XHRcdGNhc2UgJ29uUmVzZXQnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnZXZlbnROYW1lc3BhY2UnOlxyXG5cdFx0XHRcdFx0XHR0aGlzLl91bmJpbmQoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhpcy5vcHRpb25zWyBrZXkgXSA9IHZhbHVlO1xyXG5cdFx0XHRcdHN3aXRjaChrZXkpIHtcclxuXHRcdFx0XHRcdGNhc2UgJ2Rpc2FibGVQYW4nOlxyXG5cdFx0XHRcdFx0XHR0aGlzLl9pbml0U3R5bGUoKTtcclxuXHRcdFx0XHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xyXG5cdFx0XHRcdFx0Y2FzZSAnJHpvb21Jbic6XHJcblx0XHRcdFx0XHRjYXNlICckem9vbU91dCc6XHJcblx0XHRcdFx0XHRjYXNlICckem9vbVJhbmdlJzpcclxuXHRcdFx0XHRcdGNhc2UgJyRyZXNldCc6XHJcblx0XHRcdFx0XHRcdC8vIFNldCB0aGVzZSBvbiB0aGUgaW5zdGFuY2VcclxuXHRcdFx0XHRcdFx0dGhpc1sga2V5IF0gPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xyXG5cdFx0XHRcdFx0Y2FzZSAnZGlzYWJsZVpvb20nOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25TdGFydCc6XHJcblx0XHRcdFx0XHRjYXNlICdvbkNoYW5nZSc6XHJcblx0XHRcdFx0XHRjYXNlICdvblpvb20nOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25QYW4nOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25FbmQnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnb25SZXNldCc6XHJcblx0XHRcdFx0XHRjYXNlICdldmVudE5hbWVzcGFjZSc6XHJcblx0XHRcdFx0XHRcdHRoaXMuX2JpbmQoKTtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRjYXNlICdjdXJzb3InOlxyXG5cdFx0XHRcdFx0XHQkLnN0eWxlKHRoaXMuZWxlbSwgJ2N1cnNvcicsIHZhbHVlKTtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRjYXNlICdtaW5TY2FsZSc6XHJcblx0XHRcdFx0XHRcdHRoaXMuJHpvb21SYW5nZS5hdHRyKCdtaW4nLCB2YWx1ZSk7XHJcblx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0Y2FzZSAnbWF4U2NhbGUnOlxyXG5cdFx0XHRcdFx0XHR0aGlzLiR6b29tUmFuZ2UuYXR0cignbWF4JywgdmFsdWUpO1xyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdGNhc2UgJ3JhbmdlU3RlcCc6XHJcblx0XHRcdFx0XHRcdHRoaXMuJHpvb21SYW5nZS5hdHRyKCdzdGVwJywgdmFsdWUpO1xyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdGNhc2UgJ3N0YXJ0VHJhbnNmb3JtJzpcclxuXHRcdFx0XHRcdFx0dGhpcy5fYnVpbGRUcmFuc2Zvcm0oKTtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XHJcblx0XHRcdFx0XHRjYXNlICdlYXNpbmcnOlxyXG5cdFx0XHRcdFx0XHR0aGlzLl9idWlsZFRyYW5zaXRpb24oKTtcclxuXHRcdFx0XHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xyXG5cdFx0XHRcdFx0Y2FzZSAndHJhbnNpdGlvbic6XHJcblx0XHRcdFx0XHRcdHRoaXMudHJhbnNpdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdGNhc2UgJyRzZXQnOlxyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUgaW5zdGFuY2VvZiAkICYmIHZhbHVlLmxlbmd0aCkge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMuJHNldCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc2V0IHN0eWxlc1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2luaXRTdHlsZSgpO1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2J1aWxkVHJhbnNmb3JtKCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sIHRoaXMpKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJbml0aWFsaXplIGJhc2Ugc3R5bGVzIGZvciB0aGUgZWxlbWVudCBhbmQgaXRzIHBhcmVudFxyXG5cdFx0ICovXHJcblx0XHRfaW5pdFN0eWxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIHN0eWxlcyA9IHtcclxuXHRcdFx0XHQvLyBQcm9tb3RlIHRoZSBlbGVtZW50IHRvIGl0J3Mgb3duIGNvbXBvc2l0b3IgbGF5ZXJcclxuXHRcdFx0XHQnYmFja2ZhY2UtdmlzaWJpbGl0eSc6ICdoaWRkZW4nLFxyXG5cdFx0XHRcdC8vIFNldCB0byBkZWZhdWx0cyBmb3IgdGhlIG5hbWVzcGFjZVxyXG5cdFx0XHRcdCd0cmFuc2Zvcm0tb3JpZ2luJzogdGhpcy5pc1NWRyA/ICcwIDAnIDogJzUwJSA1MCUnXHJcblx0XHRcdH07XHJcblx0XHRcdC8vIFNldCBlbGVtIHN0eWxlc1xyXG5cdFx0XHRpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlUGFuKSB7XHJcblx0XHRcdFx0c3R5bGVzLmN1cnNvciA9IHRoaXMub3B0aW9ucy5jdXJzb3I7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy4kc2V0LmNzcyhzdHlsZXMpO1xyXG5cclxuXHRcdFx0Ly8gU2V0IHBhcmVudCB0byByZWxhdGl2ZSBpZiBzZXQgdG8gc3RhdGljXHJcblx0XHRcdHZhciAkcGFyZW50ID0gdGhpcy4kcGFyZW50O1xyXG5cdFx0XHQvLyBObyBuZWVkIHRvIGFkZCBzdHlsZXMgdG8gdGhlIGJvZHlcclxuXHRcdFx0aWYgKCRwYXJlbnQubGVuZ3RoICYmICEkLm5vZGVOYW1lKCRwYXJlbnRbMF0sICdib2R5JykpIHtcclxuXHRcdFx0XHRzdHlsZXMgPSB7XHJcblx0XHRcdFx0XHRvdmVyZmxvdzogJ2hpZGRlbidcclxuXHRcdFx0XHR9O1xyXG5cdFx0XHRcdGlmICgkcGFyZW50LmNzcygncG9zaXRpb24nKSA9PT0gJ3N0YXRpYycpIHtcclxuXHRcdFx0XHRcdHN0eWxlcy5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdCRwYXJlbnQuY3NzKHN0eWxlcyk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBVbmRvIGFueSBzdHlsZXMgYXR0YWNoZWQgaW4gdGhpcyBwbHVnaW5cclxuXHRcdCAqL1xyXG5cdFx0X3Jlc2V0U3R5bGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR0aGlzLiRlbGVtLmNzcyh7XHJcblx0XHRcdFx0J2N1cnNvcic6ICcnLFxyXG5cdFx0XHRcdCd0cmFuc2l0aW9uJzogJydcclxuXHRcdFx0fSk7XHJcblx0XHRcdHRoaXMuJHBhcmVudC5jc3Moe1xyXG5cdFx0XHRcdCdvdmVyZmxvdyc6ICcnLFxyXG5cdFx0XHRcdCdwb3NpdGlvbic6ICcnXHJcblx0XHRcdH0pO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEJpbmRzIGFsbCBuZWNlc3NhcnkgZXZlbnRzXHJcblx0XHQgKi9cclxuXHRcdF9iaW5kOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cdFx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcclxuXHRcdFx0dmFyIG5zID0gb3B0aW9ucy5ldmVudE5hbWVzcGFjZTtcclxuXHRcdFx0dmFyIHN0cl9zdGFydCA9IHBvaW50ZXJFdmVudHMgPyAncG9pbnRlcmRvd24nICsgbnMgOiAoJ3RvdWNoc3RhcnQnICsgbnMgKyAnIG1vdXNlZG93bicgKyBucyk7XHJcblx0XHRcdHZhciBzdHJfY2xpY2sgPSBwb2ludGVyRXZlbnRzID8gJ3BvaW50ZXJ1cCcgKyBucyA6ICgndG91Y2hlbmQnICsgbnMgKyAnIGNsaWNrJyArIG5zKTtcclxuXHRcdFx0dmFyIGV2ZW50cyA9IHt9O1xyXG5cdFx0XHR2YXIgJHJlc2V0ID0gdGhpcy4kcmVzZXQ7XHJcblx0XHRcdHZhciAkem9vbVJhbmdlID0gdGhpcy4kem9vbVJhbmdlO1xyXG5cclxuXHRcdFx0Ly8gQmluZCBwYW56b29tIGV2ZW50cyBmcm9tIG9wdGlvbnNcclxuXHRcdFx0JC5lYWNoKFsgJ1N0YXJ0JywgJ0NoYW5nZScsICdab29tJywgJ1BhbicsICdFbmQnLCAnUmVzZXQnIF0sIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBtID0gb3B0aW9uc1sgJ29uJyArIHRoaXMgXTtcclxuXHRcdFx0XHRpZiAoJC5pc0Z1bmN0aW9uKG0pKSB7XHJcblx0XHRcdFx0XHRldmVudHNbICdwYW56b29tJyArIHRoaXMudG9Mb3dlckNhc2UoKSArIG5zIF0gPSBtO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBCaW5kICRlbGVtIGRyYWcgYW5kIGNsaWNrL3RvdWNoZG93biBldmVudHNcclxuXHRcdFx0Ly8gQmluZCB0b3VjaHN0YXJ0IGlmIGVpdGhlciBwYW5uaW5nIG9yIHpvb21pbmcgaXMgZW5hYmxlZFxyXG5cdFx0XHRpZiAoIW9wdGlvbnMuZGlzYWJsZVBhbiB8fCAhb3B0aW9ucy5kaXNhYmxlWm9vbSkge1xyXG5cdFx0XHRcdGV2ZW50c1sgc3RyX3N0YXJ0IF0gPSBmdW5jdGlvbihlKSB7XHJcblx0XHRcdFx0XHR2YXIgdG91Y2hlcztcclxuXHRcdFx0XHRcdGlmIChlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyA/XHJcblx0XHRcdFx0XHRcdC8vIFRvdWNoXHJcblx0XHRcdFx0XHRcdCh0b3VjaGVzID0gZS50b3VjaGVzKSAmJlxyXG5cdFx0XHRcdFx0XHRcdCgodG91Y2hlcy5sZW5ndGggPT09IDEgJiYgIW9wdGlvbnMuZGlzYWJsZVBhbikgfHwgdG91Y2hlcy5sZW5ndGggPT09IDIpIDpcclxuXHRcdFx0XHRcdFx0Ly8gTW91c2UvUG9pbnRlcjogSWdub3JlIHJpZ2h0IGNsaWNrXHJcblx0XHRcdFx0XHRcdCFvcHRpb25zLmRpc2FibGVQYW4gJiYgZS53aGljaCA9PT0gMSkge1xyXG5cclxuXHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRzZWxmLl9zdGFydE1vdmUoZSwgdG91Y2hlcyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLiRlbGVtLm9uKGV2ZW50cyk7XHJcblxyXG5cdFx0XHQvLyBCaW5kIHJlc2V0XHJcblx0XHRcdGlmICgkcmVzZXQubGVuZ3RoKSB7XHJcblx0XHRcdFx0JHJlc2V0Lm9uKHN0cl9jbGljaywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0c2VsZi5yZXNldCgpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZXQgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciB0aGUgcmFuZ2UgaW5wdXRcclxuXHRcdFx0aWYgKCR6b29tUmFuZ2UubGVuZ3RoKSB7XHJcblx0XHRcdFx0JHpvb21SYW5nZS5hdHRyKHtcclxuXHRcdFx0XHRcdC8vIE9ubHkgc2V0IHRoZSByYW5nZSBzdGVwIGlmIGV4cGxpY2l0IG9yXHJcblx0XHRcdFx0XHQvLyBzZXQgdGhlIGRlZmF1bHQgaWYgdGhlcmUgaXMgbm8gYXR0cmlidXRlIHByZXNlbnRcclxuXHRcdFx0XHRcdHN0ZXA6IG9wdGlvbnMucmFuZ2VTdGVwID09PSBQYW56b29tLmRlZmF1bHRzLnJhbmdlU3RlcCAmJlxyXG5cdFx0XHRcdFx0XHQkem9vbVJhbmdlLmF0dHIoJ3N0ZXAnKSB8fFxyXG5cdFx0XHRcdFx0XHRvcHRpb25zLnJhbmdlU3RlcCxcclxuXHRcdFx0XHRcdG1pbjogb3B0aW9ucy5taW5TY2FsZSxcclxuXHRcdFx0XHRcdG1heDogb3B0aW9ucy5tYXhTY2FsZVxyXG5cdFx0XHRcdH0pLnByb3Aoe1xyXG5cdFx0XHRcdFx0dmFsdWU6IHRoaXMuZ2V0TWF0cml4KClbMF1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTm8gYmluZGluZ3MgaWYgem9vbWluZyBpcyBkaXNhYmxlZFxyXG5cdFx0XHRpZiAob3B0aW9ucy5kaXNhYmxlWm9vbSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyICR6b29tSW4gPSB0aGlzLiR6b29tSW47XHJcblx0XHRcdHZhciAkem9vbU91dCA9IHRoaXMuJHpvb21PdXQ7XHJcblxyXG5cdFx0XHQvLyBCaW5kIHpvb20gaW4vb3V0XHJcblx0XHRcdC8vIERvbid0IGJpbmQgb25lIHdpdGhvdXQgdGhlIG90aGVyXHJcblx0XHRcdGlmICgkem9vbUluLmxlbmd0aCAmJiAkem9vbU91dC5sZW5ndGgpIHtcclxuXHRcdFx0XHQvLyBwcmV2ZW50RGVmYXVsdCBjYW5jZWxzIGZ1dHVyZSBtb3VzZSBldmVudHMgb24gdG91Y2ggZXZlbnRzXHJcblx0XHRcdFx0JHpvb21Jbi5vbihzdHJfY2xpY2ssIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHRcdHNlbGYuem9vbSgpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdCR6b29tT3V0Lm9uKHN0cl9jbGljaywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0c2VsZi56b29tKHRydWUpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoJHpvb21SYW5nZS5sZW5ndGgpIHtcclxuXHRcdFx0XHRldmVudHMgPSB7fTtcclxuXHRcdFx0XHQvLyBDYW5ub3QgcHJldmVudCBkZWZhdWx0IGFjdGlvbiBoZXJlLCBqdXN0IHVzZSBwb2ludGVyZG93bi9tb3VzZWRvd25cclxuXHRcdFx0XHRldmVudHNbIChwb2ludGVyRXZlbnRzID8gJ3BvaW50ZXJkb3duJyA6ICdtb3VzZWRvd24nKSArIG5zIF0gPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRcdHNlbGYudHJhbnNpdGlvbih0cnVlKTtcclxuXHRcdFx0XHR9O1xyXG5cdFx0XHRcdGV2ZW50c1sgJ2NoYW5nZScgKyBucyBdID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRzZWxmLnpvb20oK3RoaXMudmFsdWUsIHsgbm9TZXRSYW5nZTogdHJ1ZSB9KTtcclxuXHRcdFx0XHR9O1xyXG5cdFx0XHRcdCR6b29tUmFuZ2Uub24oZXZlbnRzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFVuYmluZCBhbGwgZXZlbnRzXHJcblx0XHQgKi9cclxuXHRcdF91bmJpbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR0aGlzLiRlbGVtXHJcblx0XHRcdFx0LmFkZCh0aGlzLiR6b29tSW4pXHJcblx0XHRcdFx0LmFkZCh0aGlzLiR6b29tT3V0KVxyXG5cdFx0XHRcdC5hZGQodGhpcy4kcmVzZXQpXHJcblx0XHRcdFx0Lm9mZih0aGlzLm9wdGlvbnMuZXZlbnROYW1lc3BhY2UpO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEJ1aWxkcyB0aGUgb3JpZ2luYWwgdHJhbnNmb3JtIHZhbHVlXHJcblx0XHQgKi9cclxuXHRcdF9idWlsZFRyYW5zZm9ybTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdC8vIFNhdmUgdGhlIG9yaWdpbmFsIHRyYW5zZm9ybVxyXG5cdFx0XHQvLyBSZXRyaWV2aW5nIHRoaXMgYWxzbyBhZGRzIHRoZSBjb3JyZWN0IHByZWZpeGVkIHN0eWxlIG5hbWVcclxuXHRcdFx0Ly8gdG8galF1ZXJ5J3MgaW50ZXJuYWwgJC5jc3NQcm9wc1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5fb3JpZ1RyYW5zZm9ybSA9IHRoaXMuZ2V0VHJhbnNmb3JtKHRoaXMub3B0aW9ucy5zdGFydFRyYW5zZm9ybSk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogU2V0IHRyYW5zaXRpb24gcHJvcGVydHkgZm9yIGxhdGVyIHVzZSB3aGVuIHpvb21pbmdcclxuXHRcdCAqIElmIFNWRywgY3JlYXRlIG5lY2Vzc2FyeSBhbmltYXRpb25zIGVsZW1lbnRzIGZvciB0cmFuc2xhdGlvbnMgYW5kIHNjYWxpbmdcclxuXHRcdCAqL1xyXG5cdFx0X2J1aWxkVHJhbnNpdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICh0aGlzLl90cmFuc2Zvcm0pIHtcclxuXHRcdFx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcclxuXHRcdFx0XHR0aGlzLl90cmFuc2l0aW9uID0gdGhpcy5fdHJhbnNmb3JtICsgJyAnICsgb3B0aW9ucy5kdXJhdGlvbiArICdtcyAnICsgb3B0aW9ucy5lYXNpbmc7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDaGVja3MgZGltZW5zaW9ucyB0byBtYWtlIHN1cmUgdGhleSBkb24ndCBuZWVkIHRvIGJlIHJlLWNhbGN1bGF0ZWRcclxuXHRcdCAqL1xyXG5cdFx0X2NoZWNrRGltczogZnVuY3Rpb24oKSB7XHJcblx0XHRcdHZhciBkaW1zID0gdGhpcy5kaW1lbnNpb25zO1xyXG5cdFx0XHQvLyBSZWJ1aWxkIGlmIHdpZHRoIG9yIGhlaWdodCBpcyBzdGlsbCAwXHJcblx0XHRcdGlmICghZGltcy53aWR0aCB8fCAhZGltcy5oZWlnaHQpIHtcclxuXHRcdFx0XHR0aGlzLnJlc2V0RGltZW5zaW9ucygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiB0aGlzLmRpbWVuc2lvbnM7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28gdG91Y2ggcG9pbnRzXHJcblx0XHQgKiBSZW1lbWJlciBweXRoYWdvcmVhbj9cclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IHRvdWNoZXNcclxuXHRcdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgdGhlIGRpc3RhbmNlXHJcblx0XHQgKi9cclxuXHRcdF9nZXREaXN0YW5jZTogZnVuY3Rpb24odG91Y2hlcykge1xyXG5cdFx0XHR2YXIgdG91Y2gxID0gdG91Y2hlc1swXTtcclxuXHRcdFx0dmFyIHRvdWNoMiA9IHRvdWNoZXNbMV07XHJcblx0XHRcdHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3coTWF0aC5hYnModG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCksIDIpICsgTWF0aC5wb3coTWF0aC5hYnModG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WSksIDIpKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDb25zdHJ1Y3RzIGFuIGFwcHJveGltYXRlZCBwb2ludCBpbiB0aGUgbWlkZGxlIG9mIHR3byB0b3VjaCBwb2ludHNcclxuXHRcdCAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgcGFnZVggYW5kIHBhZ2VZXHJcblx0XHQgKi9cclxuXHRcdF9nZXRNaWRkbGU6IGZ1bmN0aW9uKHRvdWNoZXMpIHtcclxuXHRcdFx0dmFyIHRvdWNoMSA9IHRvdWNoZXNbMF07XHJcblx0XHRcdHZhciB0b3VjaDIgPSB0b3VjaGVzWzFdO1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdGNsaWVudFg6ICgodG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCkgLyAyKSArIHRvdWNoMS5jbGllbnRYLFxyXG5cdFx0XHRcdGNsaWVudFk6ICgodG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WSkgLyAyKSArIHRvdWNoMS5jbGllbnRZXHJcblx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogVHJpZ2dlciBhIHBhbnpvb20gZXZlbnQgb24gb3VyIGVsZW1lbnRcclxuXHRcdCAqIFRoZSBldmVudCBpcyBwYXNzZWQgdGhlIFBhbnpvb20gaW5zdGFuY2VcclxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfGpRdWVyeS5FdmVudH0gZXZlbnRcclxuXHRcdCAqIEBwYXJhbSB7TWl4ZWR9IGFyZzFbLCBhcmcyLCBhcmczLCAuLi5dIEFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhlIHRyaWdnZXJcclxuXHRcdCAqL1xyXG5cdFx0X3RyaWdnZXI6IGZ1bmN0aW9uIChldmVudCkge1xyXG5cdFx0XHRpZiAodHlwZW9mIGV2ZW50ID09PSAnc3RyaW5nJykge1xyXG5cdFx0XHRcdGV2ZW50ID0gJ3Bhbnpvb20nICsgZXZlbnQ7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy4kZWxlbS50cmlnZ2VySGFuZGxlcihldmVudCwgW3RoaXNdLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBTdGFydHMgdGhlIHBhblxyXG5cdFx0ICogVGhpcyBpcyBib3VuZCB0byBtb3VzZS90b3VjaG1vdmUgb24gdGhlIGVsZW1lbnRcclxuXHRcdCAqIEBwYXJhbSB7alF1ZXJ5LkV2ZW50fSBldmVudCBBbiBldmVudCB3aXRoIHBhZ2VYLCBwYWdlWSwgYW5kIHBvc3NpYmx5IHRoZSB0b3VjaGVzIGxpc3RcclxuXHRcdCAqIEBwYXJhbSB7VG91Y2hMaXN0fSBbdG91Y2hlc10gVGhlIHRvdWNoZXMgbGlzdCBpZiBwcmVzZW50XHJcblx0XHQgKi9cclxuXHRcdF9zdGFydE1vdmU6IGZ1bmN0aW9uKGV2ZW50LCB0b3VjaGVzKSB7XHJcblx0XHRcdHZhciBtb3ZlLCBtb3ZlRXZlbnQsIGVuZEV2ZW50LFxyXG5cdFx0XHRcdHN0YXJ0RGlzdGFuY2UsIHN0YXJ0U2NhbGUsIHN0YXJ0TWlkZGxlLFxyXG5cdFx0XHRcdHN0YXJ0UGFnZVgsIHN0YXJ0UGFnZVk7XHJcblx0XHRcdHZhciBzZWxmID0gdGhpcztcclxuXHRcdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XHJcblx0XHRcdHZhciBucyA9IG9wdGlvbnMuZXZlbnROYW1lc3BhY2U7XHJcblx0XHRcdHZhciBtYXRyaXggPSB0aGlzLmdldE1hdHJpeCgpO1xyXG5cdFx0XHR2YXIgb3JpZ2luYWwgPSBtYXRyaXguc2xpY2UoMCk7XHJcblx0XHRcdHZhciBvcmlnUGFnZVggPSArb3JpZ2luYWxbNF07XHJcblx0XHRcdHZhciBvcmlnUGFnZVkgPSArb3JpZ2luYWxbNV07XHJcblx0XHRcdHZhciBwYW5PcHRpb25zID0geyBtYXRyaXg6IG1hdHJpeCwgYW5pbWF0ZTogJ3NraXAnIH07XHJcblxyXG5cdFx0XHQvLyBVc2UgcHJvcGVyIGV2ZW50c1xyXG5cdFx0XHRpZiAocG9pbnRlckV2ZW50cykge1xyXG5cdFx0XHRcdG1vdmVFdmVudCA9ICdwb2ludGVybW92ZSc7XHJcblx0XHRcdFx0ZW5kRXZlbnQgPSAncG9pbnRlcnVwJztcclxuXHRcdFx0fSBlbHNlIGlmIChldmVudC50eXBlID09PSAndG91Y2hzdGFydCcpIHtcclxuXHRcdFx0XHRtb3ZlRXZlbnQgPSAndG91Y2htb3ZlJztcclxuXHRcdFx0XHRlbmRFdmVudCA9ICd0b3VjaGVuZCc7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0bW92ZUV2ZW50ID0gJ21vdXNlbW92ZSc7XHJcblx0XHRcdFx0ZW5kRXZlbnQgPSAnbW91c2V1cCc7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEFkZCBuYW1lc3BhY2VcclxuXHRcdFx0bW92ZUV2ZW50ICs9IG5zO1xyXG5cdFx0XHRlbmRFdmVudCArPSBucztcclxuXHJcblx0XHRcdC8vIFJlbW92ZSBhbnkgdHJhbnNpdGlvbnMgaGFwcGVuaW5nXHJcblx0XHRcdHRoaXMudHJhbnNpdGlvbih0cnVlKTtcclxuXHJcblx0XHRcdC8vIEluZGljYXRlIHRoYXQgd2UgYXJlIGN1cnJlbnRseSBwYW5uaW5nXHJcblx0XHRcdHRoaXMucGFubmluZyA9IHRydWU7XHJcblxyXG5cdFx0XHQvLyBUcmlnZ2VyIHN0YXJ0IGV2ZW50XHJcblx0XHRcdHRoaXMuX3RyaWdnZXIoJ3N0YXJ0JywgZXZlbnQsIHRvdWNoZXMpO1xyXG5cclxuXHRcdFx0aWYgKHRvdWNoZXMgJiYgdG91Y2hlcy5sZW5ndGggPT09IDIpIHtcclxuXHRcdFx0XHRzdGFydERpc3RhbmNlID0gdGhpcy5fZ2V0RGlzdGFuY2UodG91Y2hlcyk7XHJcblx0XHRcdFx0c3RhcnRTY2FsZSA9ICttYXRyaXhbMF07XHJcblx0XHRcdFx0c3RhcnRNaWRkbGUgPSB0aGlzLl9nZXRNaWRkbGUodG91Y2hlcyk7XHJcblx0XHRcdFx0bW92ZSA9IGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRcdFx0XHQvLyBDYWxjdWxhdGUgbW92ZSBvbiBtaWRkbGUgcG9pbnRcclxuXHRcdFx0XHRcdHZhciBtaWRkbGUgPSBzZWxmLl9nZXRNaWRkbGUodG91Y2hlcyA9IGUudG91Y2hlcyk7XHJcblx0XHRcdFx0XHR2YXIgZGlmZiA9IHNlbGYuX2dldERpc3RhbmNlKHRvdWNoZXMpIC0gc3RhcnREaXN0YW5jZTtcclxuXHJcblx0XHRcdFx0XHQvLyBTZXQgem9vbVxyXG5cdFx0XHRcdFx0c2VsZi56b29tKGRpZmYgKiAob3B0aW9ucy5pbmNyZW1lbnQgLyAxMDApICsgc3RhcnRTY2FsZSwge1xyXG5cdFx0XHRcdFx0XHRmb2NhbDogbWlkZGxlLFxyXG5cdFx0XHRcdFx0XHRtYXRyaXg6IG1hdHJpeCxcclxuXHRcdFx0XHRcdFx0YW5pbWF0ZTogZmFsc2VcclxuXHRcdFx0XHRcdH0pO1xyXG5cclxuXHRcdFx0XHRcdC8vIFNldCBwYW5cclxuXHRcdFx0XHRcdHNlbGYucGFuKFxyXG5cdFx0XHRcdFx0XHQrbWF0cml4WzRdICsgbWlkZGxlLmNsaWVudFggLSBzdGFydE1pZGRsZS5jbGllbnRYLFxyXG5cdFx0XHRcdFx0XHQrbWF0cml4WzVdICsgbWlkZGxlLmNsaWVudFkgLSBzdGFydE1pZGRsZS5jbGllbnRZLFxyXG5cdFx0XHRcdFx0XHRwYW5PcHRpb25zXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0c3RhcnRNaWRkbGUgPSBtaWRkbGU7XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRzdGFydFBhZ2VYID0gZXZlbnQucGFnZVg7XHJcblx0XHRcdFx0c3RhcnRQYWdlWSA9IGV2ZW50LnBhZ2VZO1xyXG5cclxuXHRcdFx0XHQvKipcclxuXHRcdFx0XHQgKiBNb3VzZW1vdmUvdG91Y2htb3ZlIGZ1bmN0aW9uIHRvIHBhbiB0aGUgZWxlbWVudFxyXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBlIEV2ZW50IG9iamVjdFxyXG5cdFx0XHRcdCAqL1xyXG5cdFx0XHRcdG1vdmUgPSBmdW5jdGlvbihlKSB7XHJcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0XHRzZWxmLnBhbihcclxuXHRcdFx0XHRcdFx0b3JpZ1BhZ2VYICsgZS5wYWdlWCAtIHN0YXJ0UGFnZVgsXHJcblx0XHRcdFx0XHRcdG9yaWdQYWdlWSArIGUucGFnZVkgLSBzdGFydFBhZ2VZLFxyXG5cdFx0XHRcdFx0XHRwYW5PcHRpb25zXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH07XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEJpbmQgdGhlIGhhbmRsZXJzXHJcblx0XHRcdCQoZG9jdW1lbnQpXHJcblx0XHRcdFx0Lm9mZihucylcclxuXHRcdFx0XHQub24obW92ZUV2ZW50LCBtb3ZlKVxyXG5cdFx0XHRcdC5vbihlbmRFdmVudCwgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0Ly8gVW5iaW5kIGFsbCBkb2N1bWVudCBldmVudHNcclxuXHRcdFx0XHRcdCQodGhpcykub2ZmKG5zKTtcclxuXHRcdFx0XHRcdHNlbGYucGFubmluZyA9IGZhbHNlO1xyXG5cdFx0XHRcdFx0Ly8gVHJpZ2dlciBvdXIgZW5kIGV2ZW50XHJcblx0XHRcdFx0XHQvLyBTaW1wbHkgc2V0IHRoZSB0eXBlIHRvIFwicGFuem9vbWVuZFwiIHRvIHBhc3MgdGhyb3VnaCBhbGwgZW5kIHByb3BlcnRpZXNcclxuXHRcdFx0XHRcdC8vIGpRdWVyeSdzIGBub3RgIGlzIHVzZWQgaGVyZSB0byBjb21wYXJlIEFycmF5IGVxdWFsaXR5XHJcblx0XHRcdFx0XHRlLnR5cGUgPSAncGFuem9vbWVuZCc7XHJcblx0XHRcdFx0XHRzZWxmLl90cmlnZ2VyKGUsIG1hdHJpeCwgIW1hdHJpeEVxdWFscyhtYXRyaXgsIG9yaWdpbmFsKSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0Ly8gQWRkIFBhbnpvb20gYXMgYSBzdGF0aWMgcHJvcGVydHlcclxuXHQkLlBhbnpvb20gPSBQYW56b29tO1xyXG5cclxuXHQvKipcclxuXHQgKiBFeHRlbmQgalF1ZXJ5XHJcblx0ICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBvcHRpb25zIC0gVGhlIG5hbWUgb2YgYSBtZXRob2QgdG8gY2FsbCBvbiB0aGUgcHJvdG90eXBlXHJcblx0ICogIG9yIGFuIG9iamVjdCBsaXRlcmFsIG9mIG9wdGlvbnNcclxuXHQgKiBAcmV0dXJucyB7alF1ZXJ5fE1peGVkfSBqUXVlcnkgaW5zdGFuY2UgZm9yIHJlZ3VsYXIgY2hhaW5pbmcgb3IgdGhlIHJldHVybiB2YWx1ZShzKSBvZiBhIHBhbnpvb20gbWV0aG9kIGNhbGxcclxuXHQgKi9cclxuXHQkLmZuLnBhbnpvb20gPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0XHR2YXIgaW5zdGFuY2UsIGFyZ3MsIG0sIHJldDtcclxuXHJcblx0XHQvLyBDYWxsIG1ldGhvZHMgd2lkZ2V0LXN0eWxlXHJcblx0XHRpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XHJcblx0XHRcdHJldCA9IFtdO1xyXG5cdFx0XHRhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xyXG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aW5zdGFuY2UgPSAkLmRhdGEodGhpcywgZGF0YWtleSk7XHJcblxyXG5cdFx0XHRcdGlmICghaW5zdGFuY2UpIHtcclxuXHRcdFx0XHRcdHJldC5wdXNoKHVuZGVmaW5lZCk7XHJcblxyXG5cdFx0XHRcdC8vIElnbm9yZSBtZXRob2RzIGJlZ2lubmluZyB3aXRoIGBfYFxyXG5cdFx0XHRcdH0gZWxzZSBpZiAob3B0aW9ucy5jaGFyQXQoMCkgIT09ICdfJyAmJlxyXG5cdFx0XHRcdFx0dHlwZW9mIChtID0gaW5zdGFuY2VbIG9wdGlvbnMgXSkgPT09ICdmdW5jdGlvbicgJiZcclxuXHRcdFx0XHRcdC8vIElmIG5vdGhpbmcgaXMgcmV0dXJuZWQsIGRvIG5vdCBhZGQgdG8gcmV0dXJuIHZhbHVlc1xyXG5cdFx0XHRcdFx0KG0gPSBtLmFwcGx5KGluc3RhbmNlLCBhcmdzKSkgIT09IHVuZGVmaW5lZCkge1xyXG5cclxuXHRcdFx0XHRcdHJldC5wdXNoKG0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBSZXR1cm4gYW4gYXJyYXkgb2YgdmFsdWVzIGZvciB0aGUgalF1ZXJ5IGluc3RhbmNlc1xyXG5cdFx0XHQvLyBPciB0aGUgdmFsdWUgaXRzZWxmIGlmIHRoZXJlIGlzIG9ubHkgb25lXHJcblx0XHRcdC8vIE9yIGtlZXAgY2hhaW5pbmdcclxuXHRcdFx0cmV0dXJuIHJldC5sZW5ndGggP1xyXG5cdFx0XHRcdChyZXQubGVuZ3RoID09PSAxID8gcmV0WzBdIDogcmV0KSA6XHJcblx0XHRcdFx0dGhpcztcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkgeyBuZXcgUGFuem9vbSh0aGlzLCBvcHRpb25zKTsgfSk7XHJcblx0fTtcclxuXHJcblx0cmV0dXJuIFBhbnpvb207XHJcbn0pKTtcclxuIiwiOyB2YXIgX19icm93c2VyaWZ5X3NoaW1fcmVxdWlyZV9fPXJlcXVpcmU7KGZ1bmN0aW9uIGJyb3dzZXJpZnlTaGltKG1vZHVsZSwgZXhwb3J0cywgcmVxdWlyZSwgZGVmaW5lLCBicm93c2VyaWZ5X3NoaW1fX2RlZmluZV9fbW9kdWxlX19leHBvcnRfXykge1xuLyohXHJcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjIuMi40XHJcbiAqIGh0dHA6Ly9qcXVlcnkuY29tL1xyXG4gKlxyXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcclxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cclxuICpcclxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXHJcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcclxuICpcclxuICogRGF0ZTogMjAxNi0wNS0yMFQxNzoyM1pcclxuICovXHJcblxyXG4oZnVuY3Rpb24oIGdsb2JhbCwgZmFjdG9yeSApIHtcclxuXHJcblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2BcclxuXHRcdC8vIGlzIHByZXNlbnQsIGV4ZWN1dGUgdGhlIGZhY3RvcnkgYW5kIGdldCBqUXVlcnkuXHJcblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSBgd2luZG93YCB3aXRoIGEgYGRvY3VtZW50YFxyXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXHJcblx0XHQvLyBUaGlzIGFjY2VudHVhdGVzIHRoZSBuZWVkIGZvciB0aGUgY3JlYXRpb24gb2YgYSByZWFsIGB3aW5kb3dgLlxyXG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xyXG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cclxuXHRcdG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsLmRvY3VtZW50ID9cclxuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxyXG5cdFx0XHRmdW5jdGlvbiggdyApIHtcclxuXHRcdFx0XHRpZiAoICF3LmRvY3VtZW50ICkge1xyXG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gZmFjdG9yeSggdyApO1xyXG5cdFx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmYWN0b3J5KCBnbG9iYWwgKTtcclxuXHR9XHJcblxyXG4vLyBQYXNzIHRoaXMgaWYgd2luZG93IGlzIG5vdCBkZWZpbmVkIHlldFxyXG59KHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcclxuXHJcbi8vIFN1cHBvcnQ6IEZpcmVmb3ggMTgrXHJcbi8vIENhbid0IGJlIGluIHN0cmljdCBtb2RlLCBzZXZlcmFsIGxpYnMgaW5jbHVkaW5nIEFTUC5ORVQgdHJhY2VcclxuLy8gdGhlIHN0YWNrIHZpYSBhcmd1bWVudHMuY2FsbGVyLmNhbGxlZSBhbmQgRmlyZWZveCBkaWVzIGlmXHJcbi8vIHlvdSB0cnkgdG8gdHJhY2UgdGhyb3VnaCBcInVzZSBzdHJpY3RcIiBjYWxsIGNoYWlucy4gKCMxMzMzNSlcclxuLy9cInVzZSBzdHJpY3RcIjtcclxudmFyIGFyciA9IFtdO1xyXG5cclxudmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xyXG5cclxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xyXG5cclxudmFyIGNvbmNhdCA9IGFyci5jb25jYXQ7XHJcblxyXG52YXIgcHVzaCA9IGFyci5wdXNoO1xyXG5cclxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcclxuXHJcbnZhciBjbGFzczJ0eXBlID0ge307XHJcblxyXG52YXIgdG9TdHJpbmcgPSBjbGFzczJ0eXBlLnRvU3RyaW5nO1xyXG5cclxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XHJcblxyXG52YXIgc3VwcG9ydCA9IHt9O1xyXG5cclxuXHJcblxyXG52YXJcclxuXHR2ZXJzaW9uID0gXCIyLjIuNFwiLFxyXG5cclxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxyXG5cdGpRdWVyeSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcclxuXHJcblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcclxuXHRcdC8vIE5lZWQgaW5pdCBpZiBqUXVlcnkgaXMgY2FsbGVkIChqdXN0IGFsbG93IGVycm9yIHRvIGJlIHRocm93biBpZiBub3QgaW5jbHVkZWQpXHJcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4xXHJcblx0Ly8gTWFrZSBzdXJlIHdlIHRyaW0gQk9NIGFuZCBOQlNQXHJcblx0cnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csXHJcblxyXG5cdC8vIE1hdGNoZXMgZGFzaGVkIHN0cmluZyBmb3IgY2FtZWxpemluZ1xyXG5cdHJtc1ByZWZpeCA9IC9eLW1zLS8sXHJcblx0cmRhc2hBbHBoYSA9IC8tKFtcXGRhLXpdKS9naSxcclxuXHJcblx0Ly8gVXNlZCBieSBqUXVlcnkuY2FtZWxDYXNlIGFzIGNhbGxiYWNrIHRvIHJlcGxhY2UoKVxyXG5cdGZjYW1lbENhc2UgPSBmdW5jdGlvbiggYWxsLCBsZXR0ZXIgKSB7XHJcblx0XHRyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XHJcblx0fTtcclxuXHJcbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XHJcblxyXG5cdC8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWRcclxuXHRqcXVlcnk6IHZlcnNpb24sXHJcblxyXG5cdGNvbnN0cnVjdG9yOiBqUXVlcnksXHJcblxyXG5cdC8vIFN0YXJ0IHdpdGggYW4gZW1wdHkgc2VsZWN0b3JcclxuXHRzZWxlY3RvcjogXCJcIixcclxuXHJcblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXHJcblx0bGVuZ3RoOiAwLFxyXG5cclxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxyXG5cdC8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5XHJcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xyXG5cdFx0cmV0dXJuIG51bSAhPSBudWxsID9cclxuXHJcblx0XHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcclxuXHRcdFx0KCBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdICkgOlxyXG5cclxuXHRcdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxyXG5cdFx0XHRzbGljZS5jYWxsKCB0aGlzICk7XHJcblx0fSxcclxuXHJcblx0Ly8gVGFrZSBhbiBhcnJheSBvZiBlbGVtZW50cyBhbmQgcHVzaCBpdCBvbnRvIHRoZSBzdGFja1xyXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxyXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xyXG5cclxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XHJcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XHJcblxyXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcclxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcclxuXHRcdHJldC5jb250ZXh0ID0gdGhpcy5jb250ZXh0O1xyXG5cclxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XHJcblx0XHRyZXR1cm4gcmV0O1xyXG5cdH0sXHJcblxyXG5cdC8vIEV4ZWN1dGUgYSBjYWxsYmFjayBmb3IgZXZlcnkgZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBzZXQuXHJcblx0ZWFjaDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjayApO1xyXG5cdH0sXHJcblxyXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkubWFwKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcclxuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcclxuXHRcdH0gKSApO1xyXG5cdH0sXHJcblxyXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggc2xpY2UuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApICk7XHJcblx0fSxcclxuXHJcblx0Zmlyc3Q6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZXEoIDAgKTtcclxuXHR9LFxyXG5cclxuXHRsYXN0OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xyXG5cdH0sXHJcblxyXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcclxuXHRcdHZhciBsZW4gPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0aiA9ICtpICsgKCBpIDwgMCA/IGxlbiA6IDAgKTtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbIGogXSBdIDogW10gKTtcclxuXHR9LFxyXG5cclxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHJldk9iamVjdCB8fCB0aGlzLmNvbnN0cnVjdG9yKCk7XHJcblx0fSxcclxuXHJcblx0Ly8gRm9yIGludGVybmFsIHVzZSBvbmx5LlxyXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxyXG5cdHB1c2g6IHB1c2gsXHJcblx0c29ydDogYXJyLnNvcnQsXHJcblx0c3BsaWNlOiBhcnIuc3BsaWNlXHJcbn07XHJcblxyXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcclxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgMCBdIHx8IHt9LFxyXG5cdFx0aSA9IDEsXHJcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxyXG5cdFx0ZGVlcCA9IGZhbHNlO1xyXG5cclxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXHJcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcclxuXHRcdGRlZXAgPSB0YXJnZXQ7XHJcblxyXG5cdFx0Ly8gU2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxyXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307XHJcblx0XHRpKys7XHJcblx0fVxyXG5cclxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcclxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKCB0YXJnZXQgKSApIHtcclxuXHRcdHRhcmdldCA9IHt9O1xyXG5cdH1cclxuXHJcblx0Ly8gRXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkXHJcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XHJcblx0XHR0YXJnZXQgPSB0aGlzO1xyXG5cdFx0aS0tO1xyXG5cdH1cclxuXHJcblx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XHJcblxyXG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xyXG5cdFx0aWYgKCAoIG9wdGlvbnMgPSBhcmd1bWVudHNbIGkgXSApICE9IG51bGwgKSB7XHJcblxyXG5cdFx0XHQvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XHJcblx0XHRcdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcclxuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcclxuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1sgbmFtZSBdO1xyXG5cclxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXHJcblx0XHRcdFx0aWYgKCB0YXJnZXQgPT09IGNvcHkgKSB7XHJcblx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFJlY3Vyc2UgaWYgd2UncmUgbWVyZ2luZyBwbGFpbiBvYmplY3RzIG9yIGFycmF5c1xyXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvcHkgKSB8fFxyXG5cdFx0XHRcdFx0KCBjb3B5SXNBcnJheSA9IGpRdWVyeS5pc0FycmF5KCBjb3B5ICkgKSApICkge1xyXG5cclxuXHRcdFx0XHRcdGlmICggY29weUlzQXJyYXkgKSB7XHJcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc0FycmF5KCBzcmMgKSA/IHNyYyA6IFtdO1xyXG5cclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBzcmMgKSA/IHNyYyA6IHt9O1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxyXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBqUXVlcnkuZXh0ZW5kKCBkZWVwLCBjbG9uZSwgY29weSApO1xyXG5cclxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXHJcblx0XHRcdFx0fSBlbHNlIGlmICggY29weSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBjb3B5O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3RcclxuXHRyZXR1cm4gdGFyZ2V0O1xyXG59O1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBVbmlxdWUgZm9yIGVhY2ggY29weSBvZiBqUXVlcnkgb24gdGhlIHBhZ2VcclxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxyXG5cclxuXHQvLyBBc3N1bWUgalF1ZXJ5IGlzIHJlYWR5IHdpdGhvdXQgdGhlIHJlYWR5IG1vZHVsZVxyXG5cdGlzUmVhZHk6IHRydWUsXHJcblxyXG5cdGVycm9yOiBmdW5jdGlvbiggbXNnICkge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcclxuXHR9LFxyXG5cclxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxyXG5cclxuXHRpc0Z1bmN0aW9uOiBmdW5jdGlvbiggb2JqICkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJmdW5jdGlvblwiO1xyXG5cdH0sXHJcblxyXG5cdGlzQXJyYXk6IEFycmF5LmlzQXJyYXksXHJcblxyXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xyXG5cdFx0cmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PT0gb2JqLndpbmRvdztcclxuXHR9LFxyXG5cclxuXHRpc051bWVyaWM6IGZ1bmN0aW9uKCBvYmogKSB7XHJcblxyXG5cdFx0Ly8gcGFyc2VGbG9hdCBOYU5zIG51bWVyaWMtY2FzdCBmYWxzZSBwb3NpdGl2ZXMgKG51bGx8dHJ1ZXxmYWxzZXxcIlwiKVxyXG5cdFx0Ly8gLi4uYnV0IG1pc2ludGVycHJldHMgbGVhZGluZy1udW1iZXIgc3RyaW5ncywgcGFydGljdWxhcmx5IGhleCBsaXRlcmFscyAoXCIweC4uLlwiKVxyXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXHJcblx0XHQvLyBhZGRpbmcgMSBjb3JyZWN0cyBsb3NzIG9mIHByZWNpc2lvbiBmcm9tIHBhcnNlRmxvYXQgKCMxNTEwMClcclxuXHRcdHZhciByZWFsU3RyaW5nT2JqID0gb2JqICYmIG9iai50b1N0cmluZygpO1xyXG5cdFx0cmV0dXJuICFqUXVlcnkuaXNBcnJheSggb2JqICkgJiYgKCByZWFsU3RyaW5nT2JqIC0gcGFyc2VGbG9hdCggcmVhbFN0cmluZ09iaiApICsgMSApID49IDA7XHJcblx0fSxcclxuXHJcblx0aXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdHZhciBrZXk7XHJcblxyXG5cdFx0Ly8gTm90IHBsYWluIG9iamVjdHM6XHJcblx0XHQvLyAtIEFueSBvYmplY3Qgb3IgdmFsdWUgd2hvc2UgaW50ZXJuYWwgW1tDbGFzc11dIHByb3BlcnR5IGlzIG5vdCBcIltvYmplY3QgT2JqZWN0XVwiXHJcblx0XHQvLyAtIERPTSBub2Rlc1xyXG5cdFx0Ly8gLSB3aW5kb3dcclxuXHRcdGlmICggalF1ZXJ5LnR5cGUoIG9iaiApICE9PSBcIm9iamVjdFwiIHx8IG9iai5ub2RlVHlwZSB8fCBqUXVlcnkuaXNXaW5kb3coIG9iaiApICkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTm90IG93biBjb25zdHJ1Y3RvciBwcm9wZXJ0eSBtdXN0IGJlIE9iamVjdFxyXG5cdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcclxuXHRcdFx0XHQhaGFzT3duLmNhbGwoIG9iaiwgXCJjb25zdHJ1Y3RvclwiICkgJiZcclxuXHRcdFx0XHQhaGFzT3duLmNhbGwoIG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwge30sIFwiaXNQcm90b3R5cGVPZlwiICkgKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBPd24gcHJvcGVydGllcyBhcmUgZW51bWVyYXRlZCBmaXJzdGx5LCBzbyB0byBzcGVlZCB1cCxcclxuXHRcdC8vIGlmIGxhc3Qgb25lIGlzIG93biwgdGhlbiBhbGwgcHJvcGVydGllcyBhcmUgb3duXHJcblx0XHRmb3IgKCBrZXkgaW4gb2JqICkge31cclxuXHJcblx0XHRyZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgfHwgaGFzT3duLmNhbGwoIG9iaiwga2V5ICk7XHJcblx0fSxcclxuXHJcblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdHZhciBuYW1lO1xyXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB0cnVlO1xyXG5cdH0sXHJcblxyXG5cdHR5cGU6IGZ1bmN0aW9uKCBvYmogKSB7XHJcblx0XHRpZiAoIG9iaiA9PSBudWxsICkge1xyXG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMCwgaU9TPDYgKGZ1bmN0aW9uaXNoIFJlZ0V4cClcclxuXHRcdHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/XHJcblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwoIG9iaiApIF0gfHwgXCJvYmplY3RcIiA6XHJcblx0XHRcdHR5cGVvZiBvYmo7XHJcblx0fSxcclxuXHJcblx0Ly8gRXZhbHVhdGVzIGEgc2NyaXB0IGluIGEgZ2xvYmFsIGNvbnRleHRcclxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSApIHtcclxuXHRcdHZhciBzY3JpcHQsXHJcblx0XHRcdGluZGlyZWN0ID0gZXZhbDtcclxuXHJcblx0XHRjb2RlID0galF1ZXJ5LnRyaW0oIGNvZGUgKTtcclxuXHJcblx0XHRpZiAoIGNvZGUgKSB7XHJcblxyXG5cdFx0XHQvLyBJZiB0aGUgY29kZSBpbmNsdWRlcyBhIHZhbGlkLCBwcm9sb2d1ZSBwb3NpdGlvblxyXG5cdFx0XHQvLyBzdHJpY3QgbW9kZSBwcmFnbWEsIGV4ZWN1dGUgY29kZSBieSBpbmplY3RpbmcgYVxyXG5cdFx0XHQvLyBzY3JpcHQgdGFnIGludG8gdGhlIGRvY3VtZW50LlxyXG5cdFx0XHRpZiAoIGNvZGUuaW5kZXhPZiggXCJ1c2Ugc3RyaWN0XCIgKSA9PT0gMSApIHtcclxuXHRcdFx0XHRzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNjcmlwdFwiICk7XHJcblx0XHRcdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xyXG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHQvLyBPdGhlcndpc2UsIGF2b2lkIHRoZSBET00gbm9kZSBjcmVhdGlvbiwgaW5zZXJ0aW9uXHJcblx0XHRcdFx0Ly8gYW5kIHJlbW92YWwgYnkgdXNpbmcgYW4gaW5kaXJlY3QgZ2xvYmFsIGV2YWxcclxuXHJcblx0XHRcdFx0aW5kaXJlY3QoIGNvZGUgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIENvbnZlcnQgZGFzaGVkIHRvIGNhbWVsQ2FzZTsgdXNlZCBieSB0aGUgY3NzIGFuZCBkYXRhIG1vZHVsZXNcclxuXHQvLyBTdXBwb3J0OiBJRTktMTErXHJcblx0Ly8gTWljcm9zb2Z0IGZvcmdvdCB0byBodW1wIHRoZWlyIHZlbmRvciBwcmVmaXggKCM5NTcyKVxyXG5cdGNhbWVsQ2FzZTogZnVuY3Rpb24oIHN0cmluZyApIHtcclxuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xyXG5cdH0sXHJcblxyXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdH0sXHJcblxyXG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrICkge1xyXG5cdFx0dmFyIGxlbmd0aCwgaSA9IDA7XHJcblxyXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggb2JqICkgKSB7XHJcblx0XHRcdGxlbmd0aCA9IG9iai5sZW5ndGg7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcclxuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBvYmo7XHJcblx0fSxcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjFcclxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcclxuXHRcdHJldHVybiB0ZXh0ID09IG51bGwgP1xyXG5cdFx0XHRcIlwiIDpcclxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XHJcblx0fSxcclxuXHJcblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxyXG5cdG1ha2VBcnJheTogZnVuY3Rpb24oIGFyciwgcmVzdWx0cyApIHtcclxuXHRcdHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xyXG5cclxuXHRcdGlmICggYXJyICE9IG51bGwgKSB7XHJcblx0XHRcdGlmICggaXNBcnJheUxpa2UoIE9iamVjdCggYXJyICkgKSApIHtcclxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHJldCxcclxuXHRcdFx0XHRcdHR5cGVvZiBhcnIgPT09IFwic3RyaW5nXCIgP1xyXG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJldDtcclxuXHR9LFxyXG5cclxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xyXG5cdFx0cmV0dXJuIGFyciA9PSBudWxsID8gLTEgOiBpbmRleE9mLmNhbGwoIGFyciwgZWxlbSwgaSApO1xyXG5cdH0sXHJcblxyXG5cdG1lcmdlOiBmdW5jdGlvbiggZmlyc3QsIHNlY29uZCApIHtcclxuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcclxuXHRcdFx0aiA9IDAsXHJcblx0XHRcdGkgPSBmaXJzdC5sZW5ndGg7XHJcblxyXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XHJcblx0XHRcdGZpcnN0WyBpKysgXSA9IHNlY29uZFsgaiBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZpcnN0Lmxlbmd0aCA9IGk7XHJcblxyXG5cdFx0cmV0dXJuIGZpcnN0O1xyXG5cdH0sXHJcblxyXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcclxuXHRcdHZhciBjYWxsYmFja0ludmVyc2UsXHJcblx0XHRcdG1hdGNoZXMgPSBbXSxcclxuXHRcdFx0aSA9IDAsXHJcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aCxcclxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xyXG5cclxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCBvbmx5IHNhdmluZyB0aGUgaXRlbXNcclxuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXHJcblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0Y2FsbGJhY2tJbnZlcnNlID0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7XHJcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcclxuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtYXRjaGVzO1xyXG5cdH0sXHJcblxyXG5cdC8vIGFyZyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxyXG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xyXG5cdFx0dmFyIGxlbmd0aCwgdmFsdWUsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRyZXQgPSBbXTtcclxuXHJcblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xyXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggZWxlbXMgKSApIHtcclxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoO1xyXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcclxuXHJcblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xyXG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XHJcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XHJcblxyXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcclxuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcclxuXHRcdHJldHVybiBjb25jYXQuYXBwbHkoIFtdLCByZXQgKTtcclxuXHR9LFxyXG5cclxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcclxuXHRndWlkOiAxLFxyXG5cclxuXHQvLyBCaW5kIGEgZnVuY3Rpb24gdG8gYSBjb250ZXh0LCBvcHRpb25hbGx5IHBhcnRpYWxseSBhcHBseWluZyBhbnlcclxuXHQvLyBhcmd1bWVudHMuXHJcblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcclxuXHRcdHZhciB0bXAsIGFyZ3MsIHByb3h5O1xyXG5cclxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHRtcCA9IGZuWyBjb250ZXh0IF07XHJcblx0XHRcdGNvbnRleHQgPSBmbjtcclxuXHRcdFx0Zm4gPSB0bXA7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcclxuXHRcdC8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybiB1bmRlZmluZWQuXHJcblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggZm4gKSApIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTaW11bGF0ZWQgYmluZFxyXG5cdFx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMiApO1xyXG5cdFx0cHJveHkgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxyXG5cdFx0cHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7XHJcblxyXG5cdFx0cmV0dXJuIHByb3h5O1xyXG5cdH0sXHJcblxyXG5cdG5vdzogRGF0ZS5ub3csXHJcblxyXG5cdC8vIGpRdWVyeS5zdXBwb3J0IGlzIG5vdCB1c2VkIGluIENvcmUgYnV0IG90aGVyIHByb2plY3RzIGF0dGFjaCB0aGVpclxyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXHJcblx0c3VwcG9ydDogc3VwcG9ydFxyXG59ICk7XHJcblxyXG4vLyBKU0hpbnQgd291bGQgZXJyb3Igb24gdGhpcyBjb2RlIGR1ZSB0byB0aGUgU3ltYm9sIG5vdCBiZWluZyBkZWZpbmVkIGluIEVTNS5cclxuLy8gRGVmaW5pbmcgdGhpcyBnbG9iYWwgaW4gLmpzaGludHJjIHdvdWxkIGNyZWF0ZSBhIGRhbmdlciBvZiB1c2luZyB0aGUgZ2xvYmFsXHJcbi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBqdXN0IGRpc2FibGUgSlNIaW50IGZvciB0aGVzZVxyXG4vLyB0aHJlZSBsaW5lcy5cclxuLyoganNoaW50IGlnbm9yZTogc3RhcnQgKi9cclxuaWYgKCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgKSB7XHJcblx0alF1ZXJ5LmZuWyBTeW1ib2wuaXRlcmF0b3IgXSA9IGFyclsgU3ltYm9sLml0ZXJhdG9yIF07XHJcbn1cclxuLyoganNoaW50IGlnbm9yZTogZW5kICovXHJcblxyXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcclxualF1ZXJ5LmVhY2goIFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdCggXCIgXCIgKSxcclxuZnVuY3Rpb24oIGksIG5hbWUgKSB7XHJcblx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XHJcbn0gKTtcclxuXHJcbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IGlPUyA4LjIgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxyXG5cdC8vIGBpbmAgY2hlY2sgdXNlZCB0byBwcmV2ZW50IEpJVCBlcnJvciAoZ2gtMjE0NSlcclxuXHQvLyBoYXNPd24gaXNuJ3QgdXNlZCBoZXJlIGR1ZSB0byBmYWxzZSBuZWdhdGl2ZXNcclxuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXHJcblx0dmFyIGxlbmd0aCA9ICEhb2JqICYmIFwibGVuZ3RoXCIgaW4gb2JqICYmIG9iai5sZW5ndGgsXHJcblx0XHR0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xyXG5cclxuXHRpZiAoIHR5cGUgPT09IFwiZnVuY3Rpb25cIiB8fCBqUXVlcnkuaXNXaW5kb3coIG9iaiApICkge1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcclxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XHJcbn1cclxudmFyIFNpenpsZSA9XHJcbi8qIVxyXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2Mi4yLjFcclxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cclxuICpcclxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXHJcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcclxuICpcclxuICogRGF0ZTogMjAxNS0xMC0xN1xyXG4gKi9cclxuKGZ1bmN0aW9uKCB3aW5kb3cgKSB7XHJcblxyXG52YXIgaSxcclxuXHRzdXBwb3J0LFxyXG5cdEV4cHIsXHJcblx0Z2V0VGV4dCxcclxuXHRpc1hNTCxcclxuXHR0b2tlbml6ZSxcclxuXHRjb21waWxlLFxyXG5cdHNlbGVjdCxcclxuXHRvdXRlcm1vc3RDb250ZXh0LFxyXG5cdHNvcnRJbnB1dCxcclxuXHRoYXNEdXBsaWNhdGUsXHJcblxyXG5cdC8vIExvY2FsIGRvY3VtZW50IHZhcnNcclxuXHRzZXREb2N1bWVudCxcclxuXHRkb2N1bWVudCxcclxuXHRkb2NFbGVtLFxyXG5cdGRvY3VtZW50SXNIVE1MLFxyXG5cdHJidWdneVFTQSxcclxuXHRyYnVnZ3lNYXRjaGVzLFxyXG5cdG1hdGNoZXMsXHJcblx0Y29udGFpbnMsXHJcblxyXG5cdC8vIEluc3RhbmNlLXNwZWNpZmljIGRhdGFcclxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxyXG5cdHByZWZlcnJlZERvYyA9IHdpbmRvdy5kb2N1bWVudCxcclxuXHRkaXJydW5zID0gMCxcclxuXHRkb25lID0gMCxcclxuXHRjbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHR0b2tlbkNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHRzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHtcclxuXHRcdGlmICggYSA9PT0gYiApIHtcclxuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdlbmVyYWwtcHVycG9zZSBjb25zdGFudHNcclxuXHRNQVhfTkVHQVRJVkUgPSAxIDw8IDMxLFxyXG5cclxuXHQvLyBJbnN0YW5jZSBtZXRob2RzXHJcblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcclxuXHRhcnIgPSBbXSxcclxuXHRwb3AgPSBhcnIucG9wLFxyXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXHJcblx0cHVzaCA9IGFyci5wdXNoLFxyXG5cdHNsaWNlID0gYXJyLnNsaWNlLFxyXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxyXG5cdC8vIGh0dHA6Ly9qc3BlcmYuY29tL3Rob3ItaW5kZXhvZi12cy1mb3IvNVxyXG5cdGluZGV4T2YgPSBmdW5jdGlvbiggbGlzdCwgZWxlbSApIHtcclxuXHRcdHZhciBpID0gMCxcclxuXHRcdFx0bGVuID0gbGlzdC5sZW5ndGg7XHJcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFx0aWYgKCBsaXN0W2ldID09PSBlbGVtICkge1xyXG5cdFx0XHRcdHJldHVybiBpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gLTE7XHJcblx0fSxcclxuXHJcblx0Ym9vbGVhbnMgPSBcImNoZWNrZWR8c2VsZWN0ZWR8YXN5bmN8YXV0b2ZvY3VzfGF1dG9wbGF5fGNvbnRyb2xzfGRlZmVyfGRpc2FibGVkfGhpZGRlbnxpc21hcHxsb29wfG11bHRpcGxlfG9wZW58cmVhZG9ubHl8cmVxdWlyZWR8c2NvcGVkXCIsXHJcblxyXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcclxuXHJcblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2VcclxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxyXG5cclxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyMS9zeW5kYXRhLmh0bWwjdmFsdWUtZGVmLWlkZW50aWZpZXJcclxuXHRpZGVudGlmaWVyID0gXCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXFxceDAwLVxcXFx4YTBdKStcIixcclxuXHJcblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXHJcblx0YXR0cmlidXRlcyA9IFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIiooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XCIgKyB3aGl0ZXNwYWNlICtcclxuXHRcdC8vIE9wZXJhdG9yIChjYXB0dXJlIDIpXHJcblx0XHRcIiooWypeJHwhfl0/PSlcIiArIHdoaXRlc3BhY2UgK1xyXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcclxuXHRcdFwiKig/OicoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcInwoXCIgKyBpZGVudGlmaWVyICsgXCIpKXwpXCIgKyB3aGl0ZXNwYWNlICtcclxuXHRcdFwiKlxcXFxdXCIsXHJcblxyXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XFxcXCgoXCIgK1xyXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcclxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxyXG5cdFx0XCIoJygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwiKXxcIiArXHJcblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcclxuXHRcdFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiICsgYXR0cmlidXRlcyArIFwiKSopfFwiICtcclxuXHRcdC8vIDMuIGFueXRoaW5nIGVsc2UgKGNhcHR1cmUgMilcclxuXHRcdFwiLipcIiArXHJcblx0XHRcIilcXFxcKXwpXCIsXHJcblxyXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcclxuXHRyd2hpdGVzcGFjZSA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcIitcIiwgXCJnXCIgKSxcclxuXHRydHJpbSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiK3woKD86XnxbXlxcXFxcXFxcXSkoPzpcXFxcXFxcXC4pKilcIiArIHdoaXRlc3BhY2UgKyBcIiskXCIsIFwiZ1wiICksXHJcblxyXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxyXG5cdHJjb21iaW5hdG9ycyA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKihbPit+XXxcIiArIHdoaXRlc3BhY2UgKyBcIilcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxyXG5cclxuXHRyYXR0cmlidXRlUXVvdGVzID0gbmV3IFJlZ0V4cCggXCI9XCIgKyB3aGl0ZXNwYWNlICsgXCIqKFteXFxcXF0nXFxcIl0qPylcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLCBcImdcIiApLFxyXG5cclxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxyXG5cdHJpZGVudGlmaWVyID0gbmV3IFJlZ0V4cCggXCJeXCIgKyBpZGVudGlmaWVyICsgXCIkXCIgKSxcclxuXHJcblx0bWF0Y2hFeHByID0ge1xyXG5cdFx0XCJJRFwiOiBuZXcgUmVnRXhwKCBcIl4jKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXHJcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXHJcblx0XHRcIlRBR1wiOiBuZXcgUmVnRXhwKCBcIl4oXCIgKyBpZGVudGlmaWVyICsgXCJ8WypdKVwiICksXHJcblx0XHRcIkFUVFJcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBhdHRyaWJ1dGVzICksXHJcblx0XHRcIlBTRVVET1wiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHBzZXVkb3MgKSxcclxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICsgd2hpdGVzcGFjZSArXHJcblx0XHRcdFwiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86KFsrLV18KVwiICsgd2hpdGVzcGFjZSArXHJcblx0XHRcdFwiKihcXFxcZCspfCkpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KVwiLCBcImlcIiApLFxyXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXHJcblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcclxuXHRcdC8vIFdlIHVzZSB0aGlzIGZvciBQT1MgbWF0Y2hpbmcgaW4gYHNlbGVjdGBcclxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArXHJcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooKD86LVxcXFxkKT9cXFxcZCopXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KSg/PVteLV18JClcIiwgXCJpXCIgKVxyXG5cdH0sXHJcblxyXG5cdHJpbnB1dHMgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFxyXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXHJcblxyXG5cdHJuYXRpdmUgPSAvXltee10rXFx7XFxzKlxcW25hdGl2ZSBcXHcvLFxyXG5cclxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcclxuXHRycXVpY2tFeHByID0gL14oPzojKFtcXHctXSspfChcXHcrKXxcXC4oW1xcdy1dKykpJC8sXHJcblxyXG5cdHJzaWJsaW5nID0gL1srfl0vLFxyXG5cdHJlc2NhcGUgPSAvJ3xcXFxcL2csXHJcblxyXG5cdC8vIENTUyBlc2NhcGVzIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcclxuXHRydW5lc2NhcGUgPSBuZXcgUmVnRXhwKCBcIlxcXFxcXFxcKFtcXFxcZGEtZl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3woXCIgKyB3aGl0ZXNwYWNlICsgXCIpfC4pXCIsIFwiaWdcIiApLFxyXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBfLCBlc2NhcGVkLCBlc2NhcGVkV2hpdGVzcGFjZSApIHtcclxuXHRcdHZhciBoaWdoID0gXCIweFwiICsgZXNjYXBlZCAtIDB4MTAwMDA7XHJcblx0XHQvLyBOYU4gbWVhbnMgbm9uLWNvZGVwb2ludFxyXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveDwyNFxyXG5cdFx0Ly8gV29ya2Fyb3VuZCBlcnJvbmVvdXMgbnVtZXJpYyBpbnRlcnByZXRhdGlvbiBvZiArXCIweFwiXHJcblx0XHRyZXR1cm4gaGlnaCAhPT0gaGlnaCB8fCBlc2NhcGVkV2hpdGVzcGFjZSA/XHJcblx0XHRcdGVzY2FwZWQgOlxyXG5cdFx0XHRoaWdoIDwgMCA/XHJcblx0XHRcdFx0Ly8gQk1QIGNvZGVwb2ludFxyXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxyXG5cdFx0XHRcdC8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKVxyXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggPj4gMTAgfCAweEQ4MDAsIGhpZ2ggJiAweDNGRiB8IDB4REMwMCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcclxuXHQvLyBTZWUgc2V0RG9jdW1lbnQoKVxyXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxyXG5cdC8vIGVycm9yIGluIElFXHJcblx0dW5sb2FkSGFuZGxlciA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0c2V0RG9jdW1lbnQoKTtcclxuXHR9O1xyXG5cclxuLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0IClcclxudHJ5IHtcclxuXHRwdXNoLmFwcGx5KFxyXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxyXG5cdFx0cHJlZmVycmVkRG9jLmNoaWxkTm9kZXNcclxuXHQpO1xyXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXHJcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxyXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XHJcbn0gY2F0Y2ggKCBlICkge1xyXG5cdHB1c2ggPSB7IGFwcGx5OiBhcnIubGVuZ3RoID9cclxuXHJcblx0XHQvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZVxyXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xyXG5cdFx0XHRwdXNoX25hdGl2ZS5hcHBseSggdGFyZ2V0LCBzbGljZS5jYWxsKGVscykgKTtcclxuXHRcdH0gOlxyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFPDlcclxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcclxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcclxuXHRcdFx0dmFyIGogPSB0YXJnZXQubGVuZ3RoLFxyXG5cdFx0XHRcdGkgPSAwO1xyXG5cdFx0XHQvLyBDYW4ndCB0cnVzdCBOb2RlTGlzdC5sZW5ndGhcclxuXHRcdFx0d2hpbGUgKCAodGFyZ2V0W2orK10gPSBlbHNbaSsrXSkgKSB7fVxyXG5cdFx0XHR0YXJnZXQubGVuZ3RoID0gaiAtIDE7XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcclxuXHR2YXIgbSwgaSwgZWxlbSwgbmlkLCBuaWRzZWxlY3QsIG1hdGNoLCBncm91cHMsIG5ld1NlbGVjdG9yLFxyXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxyXG5cclxuXHRcdC8vIG5vZGVUeXBlIGRlZmF1bHRzIHRvIDksIHNpbmNlIGNvbnRleHQgZGVmYXVsdHMgdG8gZG9jdW1lbnRcclxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xyXG5cclxuXHRyZXN1bHRzID0gcmVzdWx0cyB8fCBbXTtcclxuXHJcblx0Ly8gUmV0dXJuIGVhcmx5IGZyb20gY2FsbHMgd2l0aCBpbnZhbGlkIHNlbGVjdG9yIG9yIGNvbnRleHRcclxuXHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiB8fCAhc2VsZWN0b3IgfHxcclxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHR9XHJcblxyXG5cdC8vIFRyeSB0byBzaG9ydGN1dCBmaW5kIG9wZXJhdGlvbnMgKGFzIG9wcG9zZWQgdG8gZmlsdGVycykgaW4gSFRNTCBkb2N1bWVudHNcclxuXHRpZiAoICFzZWVkICkge1xyXG5cclxuXHRcdGlmICggKCBjb250ZXh0ID8gY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgOiBwcmVmZXJyZWREb2MgKSAhPT0gZG9jdW1lbnQgKSB7XHJcblx0XHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XHJcblx0XHR9XHJcblx0XHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcclxuXHJcblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xyXG5cclxuXHRcdFx0Ly8gSWYgdGhlIHNlbGVjdG9yIGlzIHN1ZmZpY2llbnRseSBzaW1wbGUsIHRyeSB1c2luZyBhIFwiZ2V0KkJ5KlwiIERPTSBtZXRob2RcclxuXHRcdFx0Ly8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KVxyXG5cdFx0XHRpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xyXG5cclxuXHRcdFx0XHQvLyBJRCBzZWxlY3RvclxyXG5cdFx0XHRcdGlmICggKG0gPSBtYXRjaFsxXSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gRG9jdW1lbnQgY29udGV4dFxyXG5cdFx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XHJcblx0XHRcdFx0XHRcdFx0Ly8gVE9ETzogaWRlbnRpZnkgdmVyc2lvbnNcclxuXHRcdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBFbGVtZW50IGNvbnRleHRcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSwgT3BlcmEsIFdlYmtpdFxyXG5cdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xyXG5cdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXHJcblx0XHRcdFx0XHRcdGlmICggbmV3Q29udGV4dCAmJiAoZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgJiZcclxuXHRcdFx0XHRcdFx0XHRjb250YWlucyggY29udGV4dCwgZWxlbSApICYmXHJcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gVHlwZSBzZWxlY3RvclxyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWzJdICkge1xyXG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblxyXG5cdFx0XHRcdC8vIENsYXNzIHNlbGVjdG9yXHJcblx0XHRcdFx0fSBlbHNlIGlmICggKG0gPSBtYXRjaFszXSkgJiYgc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmXHJcblx0XHRcdFx0XHRjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSB7XHJcblxyXG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBtICkgKTtcclxuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxyXG5cdFx0XHRpZiAoIHN1cHBvcnQucXNhICYmXHJcblx0XHRcdFx0IWNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXSAmJlxyXG5cdFx0XHRcdCghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7XHJcblxyXG5cdFx0XHRcdGlmICggbm9kZVR5cGUgIT09IDEgKSB7XHJcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcclxuXHRcdFx0XHRcdG5ld1NlbGVjdG9yID0gc2VsZWN0b3I7XHJcblxyXG5cdFx0XHRcdC8vIHFTQSBsb29rcyBvdXRzaWRlIEVsZW1lbnQgY29udGV4dCwgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudFxyXG5cdFx0XHRcdC8vIFRoYW5rcyB0byBBbmRyZXcgRHVwb250IGZvciB0aGlzIHdvcmthcm91bmQgdGVjaG5pcXVlXHJcblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD04XHJcblx0XHRcdFx0Ly8gRXhjbHVkZSBvYmplY3QgZWxlbWVudHNcclxuXHRcdFx0XHR9IGVsc2UgaWYgKCBjb250ZXh0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwib2JqZWN0XCIgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gQ2FwdHVyZSB0aGUgY29udGV4dCBJRCwgc2V0dGluZyBpdCBmaXJzdCBpZiBuZWNlc3NhcnlcclxuXHRcdFx0XHRcdGlmICggKG5pZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKCBcImlkXCIgKSkgKSB7XHJcblx0XHRcdFx0XHRcdG5pZCA9IG5pZC5yZXBsYWNlKCByZXNjYXBlLCBcIlxcXFwkJlwiICk7XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCAobmlkID0gZXhwYW5kbykgKTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBQcmVmaXggZXZlcnkgc2VsZWN0b3IgaW4gdGhlIGxpc3RcclxuXHRcdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xyXG5cdFx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XHJcblx0XHRcdFx0XHRuaWRzZWxlY3QgPSByaWRlbnRpZmllci50ZXN0KCBuaWQgKSA/IFwiI1wiICsgbmlkIDogXCJbaWQ9J1wiICsgbmlkICsgXCInXVwiO1xyXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0XHRcdGdyb3Vwc1tpXSA9IG5pZHNlbGVjdCArIFwiIFwiICsgdG9TZWxlY3RvciggZ3JvdXBzW2ldICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCBcIixcIiApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEV4cGFuZCBjb250ZXh0IGZvciBzaWJsaW5nIHNlbGVjdG9yc1xyXG5cdFx0XHRcdFx0bmV3Q29udGV4dCA9IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8XHJcblx0XHRcdFx0XHRcdGNvbnRleHQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIG5ld1NlbGVjdG9yICkge1xyXG5cdFx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cyxcclxuXHRcdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHR9IGNhdGNoICggcXNhRXJyb3IgKSB7XHJcblx0XHRcdFx0XHR9IGZpbmFsbHkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIG5pZCA9PT0gZXhwYW5kbyApIHtcclxuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIEFsbCBvdGhlcnNcclxuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBrZXktdmFsdWUgY2FjaGVzIG9mIGxpbWl0ZWQgc2l6ZVxyXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb24oc3RyaW5nLCBvYmplY3QpfSBSZXR1cm5zIHRoZSBPYmplY3QgZGF0YSBhZnRlciBzdG9yaW5nIGl0IG9uIGl0c2VsZiB3aXRoXHJcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxyXG4gKlx0ZGVsZXRpbmcgdGhlIG9sZGVzdCBlbnRyeVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XHJcblx0dmFyIGtleXMgPSBbXTtcclxuXHJcblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XHJcblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxyXG5cdFx0aWYgKCBrZXlzLnB1c2goIGtleSArIFwiIFwiICkgPiBFeHByLmNhY2hlTGVuZ3RoICkge1xyXG5cdFx0XHQvLyBPbmx5IGtlZXAgdGhlIG1vc3QgcmVjZW50IGVudHJpZXNcclxuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAoY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSk7XHJcblx0fVxyXG5cdHJldHVybiBjYWNoZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrXHJcbiAqL1xyXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xyXG5cdGZuWyBleHBhbmRvIF0gPSB0cnVlO1xyXG5cdHJldHVybiBmbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFBhc3NlZCB0aGUgY3JlYXRlZCBkaXYgYW5kIGV4cGVjdHMgYSBib29sZWFuIHJlc3VsdFxyXG4gKi9cclxuZnVuY3Rpb24gYXNzZXJ0KCBmbiApIHtcclxuXHR2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuXHJcblx0dHJ5IHtcclxuXHRcdHJldHVybiAhIWZuKCBkaXYgKTtcclxuXHR9IGNhdGNoIChlKSB7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fSBmaW5hbGx5IHtcclxuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxyXG5cdFx0aWYgKCBkaXYucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0ZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGRpdiApO1xyXG5cdFx0fVxyXG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcclxuXHRcdGRpdiA9IG51bGw7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXIgVGhlIG1ldGhvZCB0aGF0IHdpbGwgYmUgYXBwbGllZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcclxuXHR2YXIgYXJyID0gYXR0cnMuc3BsaXQoXCJ8XCIpLFxyXG5cdFx0aSA9IGFyci5sZW5ndGg7XHJcblxyXG5cdHdoaWxlICggaS0tICkge1xyXG5cdFx0RXhwci5hdHRySGFuZGxlWyBhcnJbaV0gXSA9IGhhbmRsZXI7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGRvY3VtZW50IG9yZGVyIG9mIHR3byBzaWJsaW5nc1xyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcclxuICogQHBhcmFtIHtFbGVtZW50fSBiXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgbGVzcyB0aGFuIDAgaWYgYSBwcmVjZWRlcyBiLCBncmVhdGVyIHRoYW4gMCBpZiBhIGZvbGxvd3MgYlxyXG4gKi9cclxuZnVuY3Rpb24gc2libGluZ0NoZWNrKCBhLCBiICkge1xyXG5cdHZhciBjdXIgPSBiICYmIGEsXHJcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHQoIH5iLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApIC1cclxuXHRcdFx0KCB+YS5zb3VyY2VJbmRleCB8fCBNQVhfTkVHQVRJVkUgKTtcclxuXHJcblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXHJcblx0aWYgKCBkaWZmICkge1xyXG5cdFx0cmV0dXJuIGRpZmY7XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayBpZiBiIGZvbGxvd3MgYVxyXG5cdGlmICggY3VyICkge1xyXG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLm5leHRTaWJsaW5nKSApIHtcclxuXHRcdFx0aWYgKCBjdXIgPT09IGIgKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gYSA/IDEgOiAtMTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xyXG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XHJcblx0fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgYnV0dG9uc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQnV0dG9uUHNldWRvKCB0eXBlICkge1xyXG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0cmV0dXJuIChuYW1lID09PSBcImlucHV0XCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIikgJiYgZWxlbS50eXBlID09PSB0eXBlO1xyXG5cdH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcclxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcclxuXHRcdGFyZ3VtZW50ID0gK2FyZ3VtZW50O1xyXG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcclxuXHRcdFx0dmFyIGosXHJcblx0XHRcdFx0bWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSxcclxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcclxuXHJcblx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlc1xyXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRpZiAoIHNlZWRbIChqID0gbWF0Y2hJbmRleGVzW2ldKSBdICkge1xyXG5cdFx0XHRcdFx0c2VlZFtqXSA9ICEobWF0Y2hlc1tqXSA9IHNlZWRbal0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XHJcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XHJcbiAqIEByZXR1cm5zIHtFbGVtZW50fE9iamVjdHxCb29sZWFufSBUaGUgaW5wdXQgbm9kZSBpZiBhY2NlcHRhYmxlLCBvdGhlcndpc2UgYSBmYWxzeSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XHJcblx0cmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29udGV4dDtcclxufVxyXG5cclxuLy8gRXhwb3NlIHN1cHBvcnQgdmFycyBmb3IgY29udmVuaWVuY2Vcclxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XHJcblxyXG4vKipcclxuICogRGV0ZWN0cyBYTUwgbm9kZXNcclxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gZWxlbSBBbiBlbGVtZW50IG9yIGEgZG9jdW1lbnRcclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWZmIGVsZW0gaXMgYSBub24tSFRNTCBYTUwgbm9kZVxyXG4gKi9cclxuaXNYTUwgPSBTaXp6bGUuaXNYTUwgPSBmdW5jdGlvbiggZWxlbSApIHtcclxuXHQvLyBkb2N1bWVudEVsZW1lbnQgaXMgdmVyaWZpZWQgZm9yIGNhc2VzIHdoZXJlIGl0IGRvZXNuJ3QgeWV0IGV4aXN0XHJcblx0Ly8gKHN1Y2ggYXMgbG9hZGluZyBpZnJhbWVzIGluIElFIC0gIzQ4MzMpXHJcblx0dmFyIGRvY3VtZW50RWxlbWVudCA9IGVsZW0gJiYgKGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtKS5kb2N1bWVudEVsZW1lbnQ7XHJcblx0cmV0dXJuIGRvY3VtZW50RWxlbWVudCA/IGRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gXCJIVE1MXCIgOiBmYWxzZTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcclxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gW2RvY10gQW4gZWxlbWVudCBvciBkb2N1bWVudCBvYmplY3QgdG8gdXNlIHRvIHNldCB0aGUgZG9jdW1lbnRcclxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxyXG4gKi9cclxuc2V0RG9jdW1lbnQgPSBTaXp6bGUuc2V0RG9jdW1lbnQgPSBmdW5jdGlvbiggbm9kZSApIHtcclxuXHR2YXIgaGFzQ29tcGFyZSwgcGFyZW50LFxyXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xyXG5cclxuXHQvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZFxyXG5cdGlmICggZG9jID09PSBkb2N1bWVudCB8fCBkb2Mubm9kZVR5cGUgIT09IDkgfHwgIWRvYy5kb2N1bWVudEVsZW1lbnQgKSB7XHJcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XHJcblx0fVxyXG5cclxuXHQvLyBVcGRhdGUgZ2xvYmFsIHZhcmlhYmxlc1xyXG5cdGRvY3VtZW50ID0gZG9jO1xyXG5cdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvY3VtZW50ICk7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFIDktMTEsIEVkZ2VcclxuXHQvLyBBY2Nlc3NpbmcgaWZyYW1lIGRvY3VtZW50cyBhZnRlciB1bmxvYWQgdGhyb3dzIFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvcnMgKGpRdWVyeSAjMTM5MzYpXHJcblx0aWYgKCAocGFyZW50ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcpICYmIHBhcmVudC50b3AgIT09IHBhcmVudCApIHtcclxuXHRcdC8vIFN1cHBvcnQ6IElFIDExXHJcblx0XHRpZiAoIHBhcmVudC5hZGRFdmVudExpc3RlbmVyICkge1xyXG5cdFx0XHRwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgdW5sb2FkSGFuZGxlciwgZmFsc2UgKTtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTAgb25seVxyXG5cdFx0fSBlbHNlIGlmICggcGFyZW50LmF0dGFjaEV2ZW50ICkge1xyXG5cdFx0XHRwYXJlbnQuYXR0YWNoRXZlbnQoIFwib251bmxvYWRcIiwgdW5sb2FkSGFuZGxlciApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyogQXR0cmlidXRlc1xyXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8OFxyXG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xyXG5cdC8vIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxyXG5cdHN1cHBvcnQuYXR0cmlidXRlcyA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xyXG5cdFx0ZGl2LmNsYXNzTmFtZSA9IFwiaVwiO1xyXG5cdFx0cmV0dXJuICFkaXYuZ2V0QXR0cmlidXRlKFwiY2xhc3NOYW1lXCIpO1xyXG5cdH0pO1xyXG5cclxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXHJcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikgcmV0dXJucyBvbmx5IGVsZW1lbnRzXHJcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xyXG5cdFx0ZGl2LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVDb21tZW50KFwiXCIpICk7XHJcblx0XHRyZXR1cm4gIWRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikubGVuZ3RoO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTw5XHJcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICk7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFPDEwXHJcblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lXHJcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbWF0aWNhbGx5LXNldCBuYW1lcyxcclxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3RcclxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlkID0gZXhwYW5kbztcclxuXHRcdHJldHVybiAhZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBJRCBmaW5kIGFuZCBmaWx0ZXJcclxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcclxuXHRcdEV4cHIuZmluZFtcIklEXCJdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xyXG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xyXG5cdFx0XHRcdHZhciBtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcclxuXHRcdFx0XHRyZXR1cm4gbSA/IFsgbSBdIDogW107XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gZnVuY3Rpb24oIGlkICkge1xyXG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShcImlkXCIpID09PSBhdHRySWQ7XHJcblx0XHRcdH07XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyBTdXBwb3J0OiBJRTYvN1xyXG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxyXG5cdFx0ZGVsZXRlIEV4cHIuZmluZFtcIklEXCJdO1xyXG5cclxuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSAgZnVuY3Rpb24oIGlkICkge1xyXG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxyXG5cdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKFwiaWRcIik7XHJcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xyXG5cdFx0XHR9O1xyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdC8vIFRhZ1xyXG5cdEV4cHIuZmluZFtcIlRBR1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xyXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcclxuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcclxuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XHJcblxyXG5cdFx0XHQvLyBEb2N1bWVudEZyYWdtZW50IG5vZGVzIGRvbid0IGhhdmUgZ0VCVE5cclxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnICk7XHJcblx0XHRcdH1cclxuXHRcdH0gOlxyXG5cclxuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XHJcblx0XHRcdHZhciBlbGVtLFxyXG5cdFx0XHRcdHRtcCA9IFtdLFxyXG5cdFx0XHRcdGkgPSAwLFxyXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cclxuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XHJcblxyXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXHJcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcclxuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcclxuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldHVybiB0bXA7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHR9O1xyXG5cclxuXHQvLyBDbGFzc1xyXG5cdEV4cHIuZmluZFtcIkNMQVNTXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGZ1bmN0aW9uKCBjbGFzc05hbWUsIGNvbnRleHQgKSB7XHJcblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XHJcblx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIGNsYXNzTmFtZSApO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3JcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcclxuXHJcblx0Ly8gbWF0Y2hlc1NlbGVjdG9yKDphY3RpdmUpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChJRTkvT3BlcmEgMTEuNSlcclxuXHRyYnVnZ3lNYXRjaGVzID0gW107XHJcblxyXG5cdC8vIHFTYSg6Zm9jdXMpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChDaHJvbWUgMjEpXHJcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXHJcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxyXG5cdC8vIFNvLCB3ZSBhbGxvdyA6Zm9jdXMgdG8gcGFzcyB0aHJvdWdoIFFTQSBhbGwgdGhlIHRpbWUgdG8gYXZvaWQgdGhlIElFIGVycm9yXHJcblx0Ly8gU2VlIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XHJcblx0cmJ1Z2d5UVNBID0gW107XHJcblxyXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkpICkge1xyXG5cdFx0Ly8gQnVpbGQgUVNBIHJlZ2V4XHJcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gU2VsZWN0IGlzIHNldCB0byBlbXB0eSBzdHJpbmcgb24gcHVycG9zZVxyXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcclxuXHRcdFx0Ly8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsXHJcblx0XHRcdC8vIHNpbmNlIGl0cyBwcmVzZW5jZSBzaG91bGQgYmUgZW5vdWdoXHJcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XHJcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlubmVySFRNTCA9IFwiPGEgaWQ9J1wiICsgZXhwYW5kbyArIFwiJz48L2E+XCIgK1xyXG5cdFx0XHRcdFwiPHNlbGVjdCBpZD0nXCIgKyBleHBhbmRvICsgXCItXFxyXFxcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+XCIgK1xyXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTZcclxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxyXG5cdFx0XHQvLyBUaGUgdGVzdCBhdHRyaWJ1dGUgbXVzdCBiZSB1bmtub3duIGluIE9wZXJhIGJ1dCBcInNhZmVcIiBmb3IgV2luUlRcclxuXHRcdFx0Ly8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2hoNDY1Mzg4LmFzcHgjYXR0cmlidXRlX3NlY3Rpb25cclxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIlttc2FsbG93Y2FwdHVyZV49JyddXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbKl4kXT1cIiArIHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcclxuXHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGFuZCBcInZhbHVlXCIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseVxyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xyXG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86dmFsdWV8XCIgKyBib29sZWFucyArIFwiKVwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZTwyOSwgQW5kcm9pZDw0LjQsIFNhZmFyaTw3LjArLCBpT1M8Ny4wKywgUGhhbnRvbUpTPDEuOS44K1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJbaWR+PVwiICsgZXhwYW5kbyArIFwiLV1cIiApLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIn49XCIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xyXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxyXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjpjaGVja2VkXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIjpjaGVja2VkXCIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCssIGlPUyA4K1xyXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXHJcblx0XHRcdC8vIEluLXBhZ2UgYHNlbGVjdG9yI2lkIHNpYmluZy1jb21iaW5hdG9yIHNlbGVjdG9yYCBmYWlsc1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJhI1wiICsgZXhwYW5kbyArIFwiKypcIiApLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIi4jLitbK35dXCIpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXHJcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxyXG5cdFx0XHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XHJcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwiaGlkZGVuXCIgKTtcclxuXHRcdFx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcclxuXHRcdFx0Ly8gRW5mb3JjZSBjYXNlLXNlbnNpdGl2aXR5IG9mIG5hbWUgYXR0cmlidXRlXHJcblx0XHRcdGlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZT1kXVwiKS5sZW5ndGggKSB7XHJcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxyXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjplbmFibGVkXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXHJcblx0XHRcdGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiKiw6eFwiKTtcclxuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCIsLio6XCIpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcclxuXHRcdGRvY0VsZW0ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XHJcblx0XHRkb2NFbGVtLm1vek1hdGNoZXNTZWxlY3RvciB8fFxyXG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XHJcblx0XHRkb2NFbGVtLm1zTWF0Y2hlc1NlbGVjdG9yKSApKSApIHtcclxuXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXHJcblx0XHRcdC8vIG9uIGEgZGlzY29ubmVjdGVkIG5vZGUgKElFIDkpXHJcblx0XHRcdHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggPSBtYXRjaGVzLmNhbGwoIGRpdiwgXCJkaXZcIiApO1xyXG5cclxuXHRcdFx0Ly8gVGhpcyBzaG91bGQgZmFpbCB3aXRoIGFuIGV4Y2VwdGlvblxyXG5cdFx0XHQvLyBHZWNrbyBkb2VzIG5vdCBlcnJvciwgcmV0dXJucyBmYWxzZSBpbnN0ZWFkXHJcblx0XHRcdG1hdGNoZXMuY2FsbCggZGl2LCBcIltzIT0nJ106eFwiICk7XHJcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oXCJ8XCIpICk7XHJcblx0cmJ1Z2d5TWF0Y2hlcyA9IHJidWdneU1hdGNoZXMubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneU1hdGNoZXMuam9pbihcInxcIikgKTtcclxuXHJcblx0LyogQ29udGFpbnNcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xyXG5cclxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcclxuXHQvLyBQdXJwb3NlZnVsbHkgc2VsZi1leGNsdXNpdmVcclxuXHQvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZlxyXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XHJcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcclxuXHRcdFx0dmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSxcclxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcclxuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXHJcblx0XHRcdFx0YWRvd24uY29udGFpbnMgP1xyXG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcclxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxyXG5cdFx0XHQpKTtcclxuXHRcdH0gOlxyXG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XHJcblx0XHRcdGlmICggYiApIHtcclxuXHRcdFx0XHR3aGlsZSAoIChiID0gYi5wYXJlbnROb2RlKSApIHtcclxuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH07XHJcblxyXG5cdC8qIFNvcnRpbmdcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmdcclxuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cclxuXHRmdW5jdGlvbiggYSwgYiApIHtcclxuXHJcblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxyXG5cdFx0aWYgKCBhID09PSBiICkge1xyXG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXHJcblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XHJcblx0XHRpZiAoIGNvbXBhcmUgKSB7XHJcblx0XHRcdHJldHVybiBjb21wYXJlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcclxuXHRcdGNvbXBhcmUgPSAoIGEub3duZXJEb2N1bWVudCB8fCBhICkgPT09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XHJcblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGIgKSA6XHJcblxyXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcclxuXHRcdFx0MTtcclxuXHJcblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcclxuXHRcdGlmICggY29tcGFyZSAmIDEgfHxcclxuXHRcdFx0KCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkge1xyXG5cclxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XHJcblx0XHRcdGlmICggYSA9PT0gZG9jdW1lbnQgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCBiID09PSBkb2N1bWVudCB8fCBiLm93bmVyRG9jdW1lbnQgPT09IHByZWZlcnJlZERvYyAmJiBjb250YWlucyhwcmVmZXJyZWREb2MsIGIpICkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxyXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cclxuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XHJcblx0XHRcdFx0MDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XHJcblx0fSA6XHJcblx0ZnVuY3Rpb24oIGEsIGIgKSB7XHJcblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXHJcblx0XHRpZiAoIGEgPT09IGIgKSB7XHJcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjdXIsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRhdXAgPSBhLnBhcmVudE5vZGUsXHJcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcclxuXHRcdFx0YXAgPSBbIGEgXSxcclxuXHRcdFx0YnAgPSBbIGIgXTtcclxuXHJcblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxyXG5cdFx0aWYgKCAhYXVwIHx8ICFidXAgKSB7XHJcblx0XHRcdHJldHVybiBhID09PSBkb2N1bWVudCA/IC0xIDpcclxuXHRcdFx0XHRiID09PSBkb2N1bWVudCA/IDEgOlxyXG5cdFx0XHRcdGF1cCA/IC0xIDpcclxuXHRcdFx0XHRidXAgPyAxIDpcclxuXHRcdFx0XHRzb3J0SW5wdXQgP1xyXG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcclxuXHRcdFx0XHQwO1xyXG5cclxuXHRcdC8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrXHJcblx0XHR9IGVsc2UgaWYgKCBhdXAgPT09IGJ1cCApIHtcclxuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXHJcblx0XHRjdXIgPSBhO1xyXG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLnBhcmVudE5vZGUpICkge1xyXG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcclxuXHRcdH1cclxuXHRcdGN1ciA9IGI7XHJcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XHJcblx0XHRcdGJwLnVuc2hpZnQoIGN1ciApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFdhbGsgZG93biB0aGUgdHJlZSBsb29raW5nIGZvciBhIGRpc2NyZXBhbmN5XHJcblx0XHR3aGlsZSAoIGFwW2ldID09PSBicFtpXSApIHtcclxuXHRcdFx0aSsrO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBpID9cclxuXHRcdFx0Ly8gRG8gYSBzaWJsaW5nIGNoZWNrIGlmIHRoZSBub2RlcyBoYXZlIGEgY29tbW9uIGFuY2VzdG9yXHJcblx0XHRcdHNpYmxpbmdDaGVjayggYXBbaV0sIGJwW2ldICkgOlxyXG5cclxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XHJcblx0XHRcdGFwW2ldID09PSBwcmVmZXJyZWREb2MgPyAtMSA6XHJcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcclxuXHRcdFx0MDtcclxuXHR9O1xyXG5cclxuXHRyZXR1cm4gZG9jdW1lbnQ7XHJcbn07XHJcblxyXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcclxuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xyXG59O1xyXG5cclxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xyXG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxyXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcclxuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XHJcblx0fVxyXG5cclxuXHQvLyBNYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGUgc2VsZWN0b3JzIGFyZSBxdW90ZWRcclxuXHRleHByID0gZXhwci5yZXBsYWNlKCByYXR0cmlidXRlUXVvdGVzLCBcIj0nJDEnXVwiICk7XHJcblxyXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcclxuXHRcdCFjb21waWxlckNhY2hlWyBleHByICsgXCIgXCIgXSAmJlxyXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxyXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xyXG5cclxuXHRcdHRyeSB7XHJcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcclxuXHJcblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcclxuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxyXG5cdFx0XHRcdFx0Ly8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnRcclxuXHRcdFx0XHRcdC8vIGZyYWdtZW50IGluIElFIDlcclxuXHRcdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0fVxyXG5cdFx0fSBjYXRjaCAoZSkge31cclxuXHR9XHJcblxyXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XHJcbn07XHJcblxyXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcclxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcclxuXHRpZiAoICggY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgKSAhPT0gZG9jdW1lbnQgKSB7XHJcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xyXG5cdH1cclxuXHRyZXR1cm4gY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKTtcclxufTtcclxuXHJcblNpenpsZS5hdHRyID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XHJcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXHJcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xyXG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcclxuXHR9XHJcblxyXG5cdHZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sXHJcblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcclxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cclxuXHRcdFx0Zm4oIGVsZW0sIG5hbWUsICFkb2N1bWVudElzSFRNTCApIDpcclxuXHRcdFx0dW5kZWZpbmVkO1xyXG5cclxuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0dmFsIDpcclxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xyXG5cdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApIDpcclxuXHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/XHJcblx0XHRcdFx0dmFsLnZhbHVlIDpcclxuXHRcdFx0XHRudWxsO1xyXG59O1xyXG5cclxuU2l6emxlLmVycm9yID0gZnVuY3Rpb24oIG1zZyApIHtcclxuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXHJcbiAqIEBwYXJhbSB7QXJyYXlMaWtlfSByZXN1bHRzXHJcbiAqL1xyXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xyXG5cdHZhciBlbGVtLFxyXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxyXG5cdFx0aiA9IDAsXHJcblx0XHRpID0gMDtcclxuXHJcblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxyXG5cdGhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LmRldGVjdER1cGxpY2F0ZXM7XHJcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XHJcblx0cmVzdWx0cy5zb3J0KCBzb3J0T3JkZXIgKTtcclxuXHJcblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XHJcblx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcclxuXHRcdFx0aWYgKCBlbGVtID09PSByZXN1bHRzWyBpIF0gKSB7XHJcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHR3aGlsZSAoIGotLSApIHtcclxuXHRcdFx0cmVzdWx0cy5zcGxpY2UoIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gQ2xlYXIgaW5wdXQgYWZ0ZXIgc29ydGluZyB0byByZWxlYXNlIG9iamVjdHNcclxuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcclxuXHRzb3J0SW5wdXQgPSBudWxsO1xyXG5cclxuXHRyZXR1cm4gcmVzdWx0cztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xyXG4gKiBAcGFyYW0ge0FycmF5fEVsZW1lbnR9IGVsZW1cclxuICovXHJcbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdHZhciBub2RlLFxyXG5cdFx0cmV0ID0gXCJcIixcclxuXHRcdGkgPSAwLFxyXG5cdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xyXG5cclxuXHRpZiAoICFub2RlVHlwZSApIHtcclxuXHRcdC8vIElmIG5vIG5vZGVUeXBlLCB0aGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5XHJcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcclxuXHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcclxuXHRcdFx0cmV0ICs9IGdldFRleHQoIG5vZGUgKTtcclxuXHRcdH1cclxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XHJcblx0XHQvLyBVc2UgdGV4dENvbnRlbnQgZm9yIGVsZW1lbnRzXHJcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxyXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBUcmF2ZXJzZSBpdHMgY2hpbGRyZW5cclxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XHJcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xyXG5cdFx0cmV0dXJuIGVsZW0ubm9kZVZhbHVlO1xyXG5cdH1cclxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcclxuXHJcblx0cmV0dXJuIHJldDtcclxufTtcclxuXHJcbkV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzID0ge1xyXG5cclxuXHQvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXJcclxuXHRjYWNoZUxlbmd0aDogNTAsXHJcblxyXG5cdGNyZWF0ZVBzZXVkbzogbWFya0Z1bmN0aW9uLFxyXG5cclxuXHRtYXRjaDogbWF0Y2hFeHByLFxyXG5cclxuXHRhdHRySGFuZGxlOiB7fSxcclxuXHJcblx0ZmluZDoge30sXHJcblxyXG5cdHJlbGF0aXZlOiB7XHJcblx0XHRcIj5cIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiLCBmaXJzdDogdHJ1ZSB9LFxyXG5cdFx0XCIgXCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiB9LFxyXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxyXG5cdFx0XCJ+XCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiIH1cclxuXHR9LFxyXG5cclxuXHRwcmVGaWx0ZXI6IHtcclxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XHJcblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHJcblx0XHRcdC8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkXHJcblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHJcblx0XHRcdGlmICggbWF0Y2hbMl0gPT09IFwifj1cIiApIHtcclxuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xyXG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cclxuXHRcdFx0XHQxIHR5cGUgKG9ubHl8bnRofC4uLilcclxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXHJcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcclxuXHRcdFx0XHQ0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xcZCpufClcclxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XHJcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxyXG5cdFx0XHRcdDcgc2lnbiBvZiB5LWNvbXBvbmVudFxyXG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxyXG5cdFx0XHQqL1xyXG5cdFx0XHRtYXRjaFsxXSA9IG1hdGNoWzFdLnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdFx0XHRpZiAoIG1hdGNoWzFdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XHJcblx0XHRcdFx0Ly8gbnRoLSogcmVxdWlyZXMgYXJndW1lbnRcclxuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcclxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxyXG5cdFx0XHRcdC8vIHJlbWVtYmVyIHRoYXQgZmFsc2UvdHJ1ZSBjYXN0IHJlc3BlY3RpdmVseSB0byAwLzFcclxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xyXG5cdFx0XHRcdG1hdGNoWzVdID0gKyggKCBtYXRjaFs3XSArIG1hdGNoWzhdICkgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKTtcclxuXHJcblx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xyXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFszXSApIHtcclxuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBtYXRjaDtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xyXG5cdFx0XHR2YXIgZXhjZXNzLFxyXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWzZdICYmIG1hdGNoWzJdO1xyXG5cclxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbXCJDSElMRFwiXS50ZXN0KCBtYXRjaFswXSApICkge1xyXG5cdFx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pc1xyXG5cdFx0XHRpZiAoIG1hdGNoWzNdICkge1xyXG5cdFx0XHRcdG1hdGNoWzJdID0gbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIjtcclxuXHJcblx0XHRcdC8vIFN0cmlwIGV4Y2VzcyBjaGFyYWN0ZXJzIGZyb20gdW5xdW90ZWQgYXJndW1lbnRzXHJcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxyXG5cdFx0XHRcdC8vIEdldCBleGNlc3MgZnJvbSB0b2tlbml6ZSAocmVjdXJzaXZlbHkpXHJcblx0XHRcdFx0KGV4Y2VzcyA9IHRva2VuaXplKCB1bnF1b3RlZCwgdHJ1ZSApKSAmJlxyXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xyXG5cdFx0XHRcdChleGNlc3MgPSB1bnF1b3RlZC5pbmRleE9mKCBcIilcIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGgpICkge1xyXG5cclxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxyXG5cdFx0XHRcdG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xyXG5cdFx0XHRcdG1hdGNoWzJdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcclxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZmlsdGVyOiB7XHJcblxyXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XHJcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRyZXR1cm4gbm9kZU5hbWVTZWxlY3RvciA9PT0gXCIqXCIgP1xyXG5cdFx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSA6XHJcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5vZGVOYW1lO1xyXG5cdFx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcclxuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xyXG5cclxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcclxuXHRcdFx0XHQocGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkpICYmXHJcblx0XHRcdFx0Y2xhc3NDYWNoZSggY2xhc3NOYW1lLCBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoIHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSB8fCBcIlwiICk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbmFtZSwgb3BlcmF0b3IsIGNoZWNrICkge1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7XHJcblxyXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiIT1cIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJlc3VsdCArPSBcIlwiO1xyXG5cclxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIhPVwiID8gcmVzdWx0ICE9PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxyXG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxyXG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiJD1cIiA/IGNoZWNrICYmIHJlc3VsdC5zbGljZSggLWNoZWNrLmxlbmd0aCApID09PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdC5yZXBsYWNlKCByd2hpdGVzcGFjZSwgXCIgXCIgKSArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcclxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcclxuXHRcdFx0XHRcdGZhbHNlO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSxcclxuXHJcblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBhcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XHJcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXHJcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxyXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xyXG5cclxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xyXG5cclxuXHRcdFx0XHQvLyBTaG9ydGN1dCBmb3IgOm50aC0qKG4pXHJcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XHJcblx0XHRcdFx0fSA6XHJcblxyXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdFx0XHR2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LFxyXG5cdFx0XHRcdFx0XHRkaXIgPSBzaW1wbGUgIT09IGZvcndhcmQgPyBcIm5leHRTaWJsaW5nXCIgOiBcInByZXZpb3VzU2libGluZ1wiLFxyXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXHJcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxyXG5cdFx0XHRcdFx0XHR1c2VDYWNoZSA9ICF4bWwgJiYgIW9mVHlwZSxcclxuXHRcdFx0XHRcdFx0ZGlmZiA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHRcdGlmICggcGFyZW50ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxyXG5cdFx0XHRcdFx0XHRpZiAoIHNpbXBsZSApIHtcclxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcclxuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xyXG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9IG5vZGVbIGRpciBdKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBvZlR5cGUgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcclxuXHRcdFx0XHRcdFx0XHRcdHN0YXJ0ID0gZGlyID0gdHlwZSA9PT0gXCJvbmx5XCIgJiYgIXN0YXJ0ICYmIFwibmV4dFNpYmxpbmdcIjtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxyXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleFxyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XHJcblx0XHRcdFx0XHRcdFx0bm9kZSA9IHBhcmVudDtcclxuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcclxuXHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0KG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xyXG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcclxuXHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4ICYmIGNhY2hlWyAyIF07XHJcblx0XHRcdFx0XHRcdFx0bm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07XHJcblxyXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcclxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIFdoZW4gZm91bmQsIGNhY2hlIGluZGV4ZXMgb24gYHBhcmVudGAgYW5kIGJyZWFrXHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxyXG5cdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XHJcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcclxuXHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdChvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xyXG5cdFx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleDtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIHhtbCA6bnRoLWNoaWxkKC4uLilcclxuXHRcdFx0XHRcdFx0XHQvLyBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBkaWZmID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XHJcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApICYmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0KytkaWZmICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBDYWNoZSB0aGUgaW5kZXggb2YgZWFjaCBlbmNvdW50ZXJlZCBlbGVtZW50XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdChvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxyXG5cdFx0XHRcdFx0XHRkaWZmIC09IGxhc3Q7XHJcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xyXG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcclxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3Nlc1xyXG5cdFx0XHQvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVyc1xyXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXHJcblx0XHRcdHZhciBhcmdzLFxyXG5cdFx0XHRcdGZuID0gRXhwci5wc2V1ZG9zWyBwc2V1ZG8gXSB8fCBFeHByLnNldEZpbHRlcnNbIHBzZXVkby50b0xvd2VyQ2FzZSgpIF0gfHxcclxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XHJcblxyXG5cdFx0XHQvLyBUaGUgdXNlciBtYXkgdXNlIGNyZWF0ZVBzZXVkbyB0byBpbmRpY2F0ZSB0aGF0XHJcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXHJcblx0XHRcdC8vIGp1c3QgYXMgU2l6emxlIGRvZXNcclxuXHRcdFx0aWYgKCBmblsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXHJcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcclxuXHRcdFx0XHRhcmdzID0gWyBwc2V1ZG8sIHBzZXVkbywgXCJcIiwgYXJndW1lbnQgXTtcclxuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cclxuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcclxuXHRcdFx0XHRcdFx0dmFyIGlkeCxcclxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXHJcblx0XHRcdFx0XHRcdFx0aSA9IG1hdGNoZWQubGVuZ3RoO1xyXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7XHJcblx0XHRcdFx0XHRcdFx0c2VlZFsgaWR4IF0gPSAhKCBtYXRjaGVzWyBpZHggXSA9IG1hdGNoZWRbaV0gKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSkgOlxyXG5cdFx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiBmbiggZWxlbSwgMCwgYXJncyApO1xyXG5cdFx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGZuO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHBzZXVkb3M6IHtcclxuXHRcdC8vIFBvdGVudGlhbGx5IGNvbXBsZXggcHNldWRvc1xyXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcclxuXHRcdFx0Ly8gdG8gYXZvaWQgdHJlYXRpbmcgbGVhZGluZyBhbmQgdHJhaWxpbmdcclxuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXHJcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxyXG5cdFx0XHRcdHJlc3VsdHMgPSBbXSxcclxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID9cclxuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcclxuXHRcdFx0XHRcdHZhciBlbGVtLFxyXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXHJcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcclxuXHJcblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XHJcblx0XHRcdFx0XHRcdFx0c2VlZFtpXSA9ICEobWF0Y2hlc1tpXSA9IGVsZW0pO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSkgOlxyXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdFx0XHRpbnB1dFswXSA9IGVsZW07XHJcblx0XHRcdFx0XHRtYXRjaGVyKCBpbnB1dCwgbnVsbCwgeG1sLCByZXN1bHRzICk7XHJcblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxyXG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBudWxsO1xyXG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xyXG5cdFx0XHRcdH07XHJcblx0XHR9KSxcclxuXHJcblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0cmV0dXJuIFNpenpsZSggc2VsZWN0b3IsIGVsZW0gKS5sZW5ndGggPiAwO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XHJcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XHJcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSksXHJcblxyXG5cdFx0Ly8gXCJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yXHJcblx0XHQvLyBpcyBiYXNlZCBzb2xlbHkgb24gdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZVxyXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcclxuXHRcdC8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgXCItXCIuXHJcblx0XHQvLyBUaGUgbWF0Y2hpbmcgb2YgQyBhZ2FpbnN0IHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWUgaXMgcGVyZm9ybWVkIGNhc2UtaW5zZW5zaXRpdmVseS5cclxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcclxuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG9cclxuXHRcdFwibGFuZ1wiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBsYW5nICkge1xyXG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXHJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QobGFuZyB8fCBcIlwiKSApIHtcclxuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgbGFuZzogXCIgKyBsYW5nICk7XHJcblx0XHRcdH1cclxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xyXG5cdFx0XHRcdGRvIHtcclxuXHRcdFx0XHRcdGlmICggKGVsZW1MYW5nID0gZG9jdW1lbnRJc0hUTUwgP1xyXG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxyXG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZShcInhtbDpsYW5nXCIpIHx8IGVsZW0uZ2V0QXR0cmlidXRlKFwibGFuZ1wiKSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH07XHJcblx0XHR9KSxcclxuXHJcblx0XHQvLyBNaXNjZWxsYW5lb3VzXHJcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XHJcblx0XHRcdHJldHVybiBoYXNoICYmIGhhc2guc2xpY2UoIDEgKSA9PT0gZWxlbS5pZDtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJyb290XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKCFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpKSAmJiAhIShlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4KTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXHJcblx0XHRcImVuYWJsZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJkaXNhYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0Ly8gSW4gQ1NTMywgOmNoZWNrZWQgc2hvdWxkIHJldHVybiBib3RoIGNoZWNrZWQgYW5kIHNlbGVjdGVkIGVsZW1lbnRzXHJcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXHJcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0cmV0dXJuIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmICEhZWxlbS5jaGVja2VkKSB8fCAobm9kZU5hbWUgPT09IFwib3B0aW9uXCIgJiYgISFlbGVtLnNlbGVjdGVkKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJzZWxlY3RlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxyXG5cdFx0XHQvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5XHJcblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gQ29udGVudHNcclxuXHRcdFwiZW1wdHlcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jZW1wdHktcHNldWRvXHJcblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcclxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcclxuXHRcdFx0Ly8gbm9kZVR5cGUgPCA2IHdvcmtzIGJlY2F1c2UgYXR0cmlidXRlcyAoMikgZG8gbm90IGFwcGVhciBhcyBjaGlsZHJlblxyXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcclxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJwYXJlbnRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xyXG5cdFx0XCJoZWFkZXJcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJpbnB1dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xyXG5cdFx0fSxcclxuXHJcblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSBcImJ1dHRvblwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCI7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwidGV4dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIGF0dHI7XHJcblx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiAmJlxyXG5cdFx0XHRcdGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCIgJiZcclxuXHJcblx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OFxyXG5cdFx0XHRcdC8vIE5ldyBIVE1MNSBhdHRyaWJ1dGUgdmFsdWVzIChlLmcuLCBcInNlYXJjaFwiKSBhcHBlYXIgd2l0aCBlbGVtLnR5cGUgPT09IFwidGV4dFwiXHJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cclxuXHRcdFwiZmlyc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIFsgMCBdO1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJsYXN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XHJcblx0XHR9KSxcclxuXHJcblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcclxuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJldmVuXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHR2YXIgaSA9IDA7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHR2YXIgaSA9IDE7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwibHRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xyXG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XHJcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwiZ3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xyXG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XHJcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcclxuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XHJcblx0XHR9KVxyXG5cdH1cclxufTtcclxuXHJcbkV4cHIucHNldWRvc1tcIm50aFwiXSA9IEV4cHIucHNldWRvc1tcImVxXCJdO1xyXG5cclxuLy8gQWRkIGJ1dHRvbi9pbnB1dCB0eXBlIHBzZXVkb3NcclxuZm9yICggaSBpbiB7IHJhZGlvOiB0cnVlLCBjaGVja2JveDogdHJ1ZSwgZmlsZTogdHJ1ZSwgcGFzc3dvcmQ6IHRydWUsIGltYWdlOiB0cnVlIH0gKSB7XHJcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xyXG59XHJcbmZvciAoIGkgaW4geyBzdWJtaXQ6IHRydWUsIHJlc2V0OiB0cnVlIH0gKSB7XHJcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcclxufVxyXG5cclxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXHJcbmZ1bmN0aW9uIHNldEZpbHRlcnMoKSB7fVxyXG5zZXRGaWx0ZXJzLnByb3RvdHlwZSA9IEV4cHIuZmlsdGVycyA9IEV4cHIucHNldWRvcztcclxuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcclxuXHJcbnRva2VuaXplID0gU2l6emxlLnRva2VuaXplID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBwYXJzZU9ubHkgKSB7XHJcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXHJcblx0XHRzb0ZhciwgZ3JvdXBzLCBwcmVGaWx0ZXJzLFxyXG5cdFx0Y2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xyXG5cclxuXHRpZiAoIGNhY2hlZCApIHtcclxuXHRcdHJldHVybiBwYXJzZU9ubHkgPyAwIDogY2FjaGVkLnNsaWNlKCAwICk7XHJcblx0fVxyXG5cclxuXHRzb0ZhciA9IHNlbGVjdG9yO1xyXG5cdGdyb3VwcyA9IFtdO1xyXG5cdHByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjtcclxuXHJcblx0d2hpbGUgKCBzb0ZhciApIHtcclxuXHJcblx0XHQvLyBDb21tYSBhbmQgZmlyc3QgcnVuXHJcblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcclxuXHRcdFx0aWYgKCBtYXRjaCApIHtcclxuXHRcdFx0XHQvLyBEb24ndCBjb25zdW1lIHRyYWlsaW5nIGNvbW1hcyBhcyB2YWxpZFxyXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGdyb3Vwcy5wdXNoKCAodG9rZW5zID0gW10pICk7XHJcblx0XHR9XHJcblxyXG5cdFx0bWF0Y2hlZCA9IGZhbHNlO1xyXG5cclxuXHRcdC8vIENvbWJpbmF0b3JzXHJcblx0XHRpZiAoIChtYXRjaCA9IHJjb21iaW5hdG9ycy5leGVjKCBzb0ZhciApKSApIHtcclxuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XHJcblx0XHRcdHRva2Vucy5wdXNoKHtcclxuXHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcclxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2VcclxuXHRcdFx0XHR0eXBlOiBtYXRjaFswXS5yZXBsYWNlKCBydHJpbSwgXCIgXCIgKVxyXG5cdFx0XHR9KTtcclxuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGaWx0ZXJzXHJcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xyXG5cdFx0XHRpZiAoIChtYXRjaCA9IG1hdGNoRXhwclsgdHlwZSBdLmV4ZWMoIHNvRmFyICkpICYmICghcHJlRmlsdGVyc1sgdHlwZSBdIHx8XHJcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XHJcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XHJcblx0XHRcdFx0dG9rZW5zLnB1c2goe1xyXG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXHJcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxyXG5cdFx0XHRcdFx0bWF0Y2hlczogbWF0Y2hcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCAhbWF0Y2hlZCApIHtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3NcclxuXHQvLyBpZiB3ZSdyZSBqdXN0IHBhcnNpbmdcclxuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcclxuXHRyZXR1cm4gcGFyc2VPbmx5ID9cclxuXHRcdHNvRmFyLmxlbmd0aCA6XHJcblx0XHRzb0ZhciA/XHJcblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XHJcblx0XHRcdC8vIENhY2hlIHRoZSB0b2tlbnNcclxuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XHJcblx0dmFyIGkgPSAwLFxyXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcclxuXHRcdHNlbGVjdG9yID0gXCJcIjtcclxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdHNlbGVjdG9yICs9IHRva2Vuc1tpXS52YWx1ZTtcclxuXHR9XHJcblx0cmV0dXJuIHNlbGVjdG9yO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xyXG5cdHZhciBkaXIgPSBjb21iaW5hdG9yLmRpcixcclxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGRpciA9PT0gXCJwYXJlbnROb2RlXCIsXHJcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcclxuXHJcblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xyXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XHJcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xyXG5cdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xyXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSA6XHJcblxyXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXHJcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xyXG5cdFx0XHR2YXIgb2xkQ2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLFxyXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xyXG5cclxuXHRcdFx0Ly8gV2UgY2FuJ3Qgc2V0IGFyYml0cmFyeSBkYXRhIG9uIFhNTCBub2Rlcywgc28gdGhleSBkb24ndCBiZW5lZml0IGZyb20gY29tYmluYXRvciBjYWNoaW5nXHJcblx0XHRcdGlmICggeG1sICkge1xyXG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xyXG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XHJcblx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcclxuXHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXHJcblx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdIHx8IChvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IHVuaXF1ZUNhY2hlWyBkaXIgXSkgJiZcclxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBBc3NpZ24gdG8gbmV3Q2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFJldXNlIG5ld2NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcclxuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgZGlyIF0gPSBuZXdDYWNoZTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXHJcblx0XHRcdFx0XHRcdFx0aWYgKCAobmV3Q2FjaGVbIDIgXSA9IG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xyXG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cclxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xyXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRpZiAoICFtYXRjaGVyc1tpXSggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSA6XHJcblx0XHRtYXRjaGVyc1swXTtcclxufVxyXG5cclxuZnVuY3Rpb24gbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IsIGNvbnRleHRzLCByZXN1bHRzICkge1xyXG5cdHZhciBpID0gMCxcclxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcclxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XHJcblx0fVxyXG5cdHJldHVybiByZXN1bHRzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb25kZW5zZSggdW5tYXRjaGVkLCBtYXAsIGZpbHRlciwgY29udGV4dCwgeG1sICkge1xyXG5cdHZhciBlbGVtLFxyXG5cdFx0bmV3VW5tYXRjaGVkID0gW10sXHJcblx0XHRpID0gMCxcclxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXHJcblx0XHRtYXBwZWQgPSBtYXAgIT0gbnVsbDtcclxuXHJcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XHJcblx0XHRpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHtcclxuXHRcdFx0aWYgKCAhZmlsdGVyIHx8IGZpbHRlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XHJcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcclxuXHRcdFx0XHRcdG1hcC5wdXNoKCBpICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gbmV3VW5tYXRjaGVkO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRNYXRjaGVyKCBwcmVGaWx0ZXIsIHNlbGVjdG9yLCBtYXRjaGVyLCBwb3N0RmlsdGVyLCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKSB7XHJcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XHJcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xyXG5cdH1cclxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcclxuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcclxuXHR9XHJcblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xyXG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sXHJcblx0XHRcdHByZU1hcCA9IFtdLFxyXG5cdFx0XHRwb3N0TWFwID0gW10sXHJcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXHJcblxyXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxyXG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksXHJcblxyXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cclxuXHRcdFx0bWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/XHJcblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxyXG5cdFx0XHRcdGVsZW1zLFxyXG5cclxuXHRcdFx0bWF0Y2hlck91dCA9IG1hdGNoZXIgP1xyXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXHJcblx0XHRcdFx0cG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xyXG5cclxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxyXG5cdFx0XHRcdFx0W10gOlxyXG5cclxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxyXG5cdFx0XHRcdFx0cmVzdWx0cyA6XHJcblx0XHRcdFx0bWF0Y2hlckluO1xyXG5cclxuXHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXHJcblx0XHRpZiAoIG1hdGNoZXIgKSB7XHJcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxyXG5cdFx0aWYgKCBwb3N0RmlsdGVyICkge1xyXG5cdFx0XHR0ZW1wID0gY29uZGVuc2UoIG1hdGNoZXJPdXQsIHBvc3RNYXAgKTtcclxuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xyXG5cclxuXHRcdFx0Ly8gVW4tbWF0Y2ggZmFpbGluZyBlbGVtZW50cyBieSBtb3ZpbmcgdGhlbSBiYWNrIHRvIG1hdGNoZXJJblxyXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XHJcblx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdGlmICggKGVsZW0gPSB0ZW1wW2ldKSApIHtcclxuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XHJcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xyXG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBmaW5hbCBtYXRjaGVyT3V0IGJ5IGNvbmRlbnNpbmcgdGhpcyBpbnRlcm1lZGlhdGUgaW50byBwb3N0RmluZGVyIGNvbnRleHRzXHJcblx0XHRcdFx0XHR0ZW1wID0gW107XHJcblx0XHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgbWF0Y2hlckluIHNpbmNlIGVsZW0gaXMgbm90IHlldCBhIGZpbmFsIG1hdGNoXHJcblx0XHRcdFx0XHRcdFx0dGVtcC5wdXNoKCAobWF0Y2hlckluW2ldID0gZWxlbSkgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgKG1hdGNoZXJPdXQgPSBbXSksIHRlbXAsIHhtbCApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWRcclxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XHJcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0XHRpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgJiZcclxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZiggc2VlZCwgZWxlbSApIDogcHJlTWFwW2ldKSA+IC0xICkge1xyXG5cclxuXHRcdFx0XHRcdFx0c2VlZFt0ZW1wXSA9ICEocmVzdWx0c1t0ZW1wXSA9IGVsZW0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bWF0Y2hlck91dCA9IGNvbmRlbnNlKFxyXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xyXG5cdFx0XHRcdFx0bWF0Y2hlck91dC5zcGxpY2UoIHByZWV4aXN0aW5nLCBtYXRjaGVyT3V0Lmxlbmd0aCApIDpcclxuXHRcdFx0XHRcdG1hdGNoZXJPdXRcclxuXHRcdFx0KTtcclxuXHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xyXG5cdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIHJlc3VsdHMsIG1hdGNoZXJPdXQsIHhtbCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkge1xyXG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXHJcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxyXG5cdFx0bGVhZGluZ1JlbGF0aXZlID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWzBdLnR5cGUgXSxcclxuXHRcdGltcGxpY2l0UmVsYXRpdmUgPSBsZWFkaW5nUmVsYXRpdmUgfHwgRXhwci5yZWxhdGl2ZVtcIiBcIl0sXHJcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXHJcblxyXG5cdFx0Ly8gVGhlIGZvdW5kYXRpb25hbCBtYXRjaGVyIGVuc3VyZXMgdGhhdCBlbGVtZW50cyBhcmUgcmVhY2hhYmxlIGZyb20gdG9wLWxldmVsIGNvbnRleHQocylcclxuXHRcdG1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xyXG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxyXG5cdFx0bWF0Y2hBbnlDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBpbmRleE9mKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xyXG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxyXG5cdFx0bWF0Y2hlcnMgPSBbIGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdHZhciByZXQgPSAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxyXG5cdFx0XHRcdChjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/XHJcblx0XHRcdFx0XHRtYXRjaENvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApIDpcclxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcclxuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnQgKGlzc3VlICMyOTkpXHJcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9IF07XHJcblxyXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0aWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkge1xyXG5cdFx0XHRtYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvcihlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlcikgXTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zW2ldLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zW2ldLm1hdGNoZXMgKTtcclxuXHJcblx0XHRcdC8vIFJldHVybiBzcGVjaWFsIHVwb24gc2VlaW5nIGEgcG9zaXRpb25hbCBtYXRjaGVyXHJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xyXG5cdFx0XHRcdGogPSArK2k7XHJcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XHJcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1tqXS50eXBlIF0gKSB7XHJcblx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcclxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxyXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3RvcihcclxuXHRcdFx0XHRcdFx0Ly8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmBcclxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSlcclxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxyXG5cdFx0XHRcdFx0bWF0Y2hlcixcclxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxyXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKHRva2VucyA9IHRva2Vucy5zbGljZSggaiApKSApLFxyXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XHJcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcclxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxyXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcclxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxyXG5cdFx0XHRcdGkgPSBcIjBcIixcclxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxyXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcclxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcclxuXHRcdFx0XHQvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0XHJcblx0XHRcdFx0ZWxlbXMgPSBzZWVkIHx8IGJ5RWxlbWVudCAmJiBFeHByLmZpbmRbXCJUQUdcIl0oIFwiKlwiLCBvdXRlcm1vc3QgKSxcclxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxyXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEpLFxyXG5cdFx0XHRcdGxlbiA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0ID09PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcclxuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OSwgU2FmYXJpXHJcblx0XHRcdC8vIFRvbGVyYXRlIE5vZGVMaXN0IHByb3BlcnRpZXMgKElFOiBcImxlbmd0aFwiOyBTYWZhcmk6IDxudW1iZXI+KSBtYXRjaGluZyBlbGVtZW50cyBieSBpZFxyXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XHJcblx0XHRcdFx0aWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHtcclxuXHRcdFx0XHRcdGogPSAwO1xyXG5cdFx0XHRcdFx0aWYgKCAhY29udGV4dCAmJiBlbGVtLm93bmVyRG9jdW1lbnQgIT09IGRvY3VtZW50ICkge1xyXG5cdFx0XHRcdFx0XHRzZXREb2N1bWVudCggZWxlbSApO1xyXG5cdFx0XHRcdFx0XHR4bWwgPSAhZG9jdW1lbnRJc0hUTUw7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzW2orK10pICkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQgfHwgZG9jdW1lbnQsIHhtbCkgKSB7XHJcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcclxuXHRcdFx0XHRpZiAoIGJ5U2V0ICkge1xyXG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xyXG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0pICkge1xyXG5cdFx0XHRcdFx0XHRtYXRjaGVkQ291bnQtLTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBMZW5ndGhlbiB0aGUgYXJyYXkgZm9yIGV2ZXJ5IGVsZW1lbnQsIG1hdGNoZWQgb3Igbm90XHJcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBgaWAgaXMgbm93IHRoZSBjb3VudCBvZiBlbGVtZW50cyB2aXNpdGVkIGFib3ZlLCBhbmQgYWRkaW5nIGl0IHRvIGBtYXRjaGVkQ291bnRgXHJcblx0XHRcdC8vIG1ha2VzIHRoZSBsYXR0ZXIgbm9ubmVnYXRpdmUuXHJcblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xyXG5cclxuXHRcdFx0Ly8gQXBwbHkgc2V0IGZpbHRlcnMgdG8gdW5tYXRjaGVkIGVsZW1lbnRzXHJcblx0XHRcdC8vIE5PVEU6IFRoaXMgY2FuIGJlIHNraXBwZWQgaWYgdGhlcmUgYXJlIG5vIHVubWF0Y2hlZCBlbGVtZW50cyAoaS5lLiwgYG1hdGNoZWRDb3VudGBcclxuXHRcdFx0Ly8gZXF1YWxzIGBpYCksIHVubGVzcyB3ZSBkaWRuJ3QgdmlzaXQgX2FueV8gZWxlbWVudHMgaW4gdGhlIGFib3ZlIGxvb3AgYmVjYXVzZSB3ZSBoYXZlXHJcblx0XHRcdC8vIG5vIGVsZW1lbnQgbWF0Y2hlcnMgYW5kIG5vIHNlZWQuXHJcblx0XHRcdC8vIEluY3JlbWVudGluZyBhbiBpbml0aWFsbHktc3RyaW5nIFwiMFwiIGBpYCBhbGxvd3MgYGlgIHRvIHJlbWFpbiBhIHN0cmluZyBvbmx5IGluIHRoYXRcclxuXHRcdFx0Ly8gY2FzZSwgd2hpY2ggd2lsbCByZXN1bHQgaW4gYSBcIjAwXCIgYG1hdGNoZWRDb3VudGAgdGhhdCBkaWZmZXJzIGZyb20gYGlgIGJ1dCBpcyBhbHNvXHJcblx0XHRcdC8vIG51bWVyaWNhbGx5IHplcm8uXHJcblx0XHRcdGlmICggYnlTZXQgJiYgaSAhPT0gbWF0Y2hlZENvdW50ICkge1xyXG5cdFx0XHRcdGogPSAwO1xyXG5cdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBzZXRNYXRjaGVyc1tqKytdKSApIHtcclxuXHRcdFx0XHRcdG1hdGNoZXIoIHVubWF0Y2hlZCwgc2V0TWF0Y2hlZCwgY29udGV4dCwgeG1sICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXHJcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XHJcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkW2ldID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xyXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXHJcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2V0TWF0Y2hlZCApO1xyXG5cclxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcclxuXHRcdFx0XHRpZiAoIG91dGVybW9zdCAmJiAhc2VlZCAmJiBzZXRNYXRjaGVkLmxlbmd0aCA+IDAgJiZcclxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xyXG5cclxuXHRcdFx0XHRcdFNpenpsZS51bmlxdWVTb3J0KCByZXN1bHRzICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcclxuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XHJcblx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XHJcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XHJcblx0XHR9O1xyXG5cclxuXHRyZXR1cm4gYnlTZXQgP1xyXG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XHJcblx0XHRzdXBlck1hdGNoZXI7XHJcbn1cclxuXHJcbmNvbXBpbGUgPSBTaXp6bGUuY29tcGlsZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgbWF0Y2ggLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XHJcblx0dmFyIGksXHJcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxyXG5cdFx0ZWxlbWVudE1hdGNoZXJzID0gW10sXHJcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XHJcblxyXG5cdGlmICggIWNhY2hlZCApIHtcclxuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxyXG5cdFx0aWYgKCAhbWF0Y2ggKSB7XHJcblx0XHRcdG1hdGNoID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XHJcblx0XHR9XHJcblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFtpXSApO1xyXG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdHNldE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENhY2hlIHRoZSBjb21waWxlZCBmdW5jdGlvblxyXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZSggc2VsZWN0b3IsIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApICk7XHJcblxyXG5cdFx0Ly8gU2F2ZSBzZWxlY3RvciBhbmQgdG9rZW5pemF0aW9uXHJcblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3RvcjtcclxuXHR9XHJcblx0cmV0dXJuIGNhY2hlZDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXHJcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcclxuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHNlbGVjdG9yIEEgc2VsZWN0b3Igb3IgYSBwcmUtY29tcGlsZWRcclxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcclxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XHJcbiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHRzXVxyXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxyXG4gKi9cclxuc2VsZWN0ID0gU2l6emxlLnNlbGVjdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcclxuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcclxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXHJcblx0XHRtYXRjaCA9ICFzZWVkICYmIHRva2VuaXplKCAoc2VsZWN0b3IgPSBjb21waWxlZC5zZWxlY3RvciB8fCBzZWxlY3RvcikgKTtcclxuXHJcblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XHJcblxyXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNlbGVjdG9yIGluIHRoZSBsaXN0IGFuZCBubyBzZWVkXHJcblx0Ly8gKHRoZSBsYXR0ZXIgb2Ygd2hpY2ggZ3VhcmFudGVlcyB1cyBjb250ZXh0KVxyXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xyXG5cclxuXHRcdC8vIFJlZHVjZSBjb250ZXh0IGlmIHRoZSBsZWFkaW5nIGNvbXBvdW5kIHNlbGVjdG9yIGlzIGFuIElEXHJcblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XHJcblx0XHRpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICh0b2tlbiA9IHRva2Vuc1swXSkudHlwZSA9PT0gXCJJRFwiICYmXHJcblx0XHRcdFx0c3VwcG9ydC5nZXRCeUlkICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgZG9jdW1lbnRJc0hUTUwgJiZcclxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xyXG5cclxuXHRcdFx0Y29udGV4dCA9ICggRXhwci5maW5kW1wiSURcIl0oIHRva2VuLm1hdGNoZXNbMF0ucmVwbGFjZShydW5lc2NhcGUsIGZ1bmVzY2FwZSksIGNvbnRleHQgKSB8fCBbXSApWzBdO1xyXG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xyXG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xyXG5cclxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxyXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21waWxlZCApIHtcclxuXHRcdFx0XHRjb250ZXh0ID0gY29udGV4dC5wYXJlbnROb2RlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZWxlY3RvciA9IHNlbGVjdG9yLnNsaWNlKCB0b2tlbnMuc2hpZnQoKS52YWx1ZS5sZW5ndGggKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGZXRjaCBhIHNlZWQgc2V0IGZvciByaWdodC10by1sZWZ0IG1hdGNoaW5nXHJcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcclxuXHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHR0b2tlbiA9IHRva2Vuc1tpXTtcclxuXHJcblx0XHRcdC8vIEFib3J0IGlmIHdlIGhpdCBhIGNvbWJpbmF0b3JcclxuXHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyAodHlwZSA9IHRva2VuLnR5cGUpIF0gKSB7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCAoZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdKSApIHtcclxuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcclxuXHRcdFx0XHRpZiAoIChzZWVkID0gZmluZChcclxuXHRcdFx0XHRcdHRva2VuLm1hdGNoZXNbMF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcclxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcclxuXHRcdFx0XHQpKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcclxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcclxuXHRcdFx0XHRcdHNlbGVjdG9yID0gc2VlZC5sZW5ndGggJiYgdG9TZWxlY3RvciggdG9rZW5zICk7XHJcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcclxuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIENvbXBpbGUgYW5kIGV4ZWN1dGUgYSBmaWx0ZXJpbmcgZnVuY3Rpb24gaWYgb25lIGlzIG5vdCBwcm92aWRlZFxyXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcclxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXHJcblx0XHRzZWVkLFxyXG5cdFx0Y29udGV4dCxcclxuXHRcdCFkb2N1bWVudElzSFRNTCxcclxuXHRcdHJlc3VsdHMsXHJcblx0XHQhY29udGV4dCB8fCByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XHJcblx0KTtcclxuXHRyZXR1cm4gcmVzdWx0cztcclxufTtcclxuXHJcbi8vIE9uZS10aW1lIGFzc2lnbm1lbnRzXHJcblxyXG4vLyBTb3J0IHN0YWJpbGl0eVxyXG5zdXBwb3J0LnNvcnRTdGFibGUgPSBleHBhbmRvLnNwbGl0KFwiXCIpLnNvcnQoIHNvcnRPcmRlciApLmpvaW4oXCJcIikgPT09IGV4cGFuZG87XHJcblxyXG4vLyBTdXBwb3J0OiBDaHJvbWUgMTQtMzUrXHJcbi8vIEFsd2F5cyBhc3N1bWUgZHVwbGljYXRlcyBpZiB0aGV5IGFyZW4ndCBwYXNzZWQgdG8gdGhlIGNvbXBhcmlzb24gZnVuY3Rpb25cclxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XHJcblxyXG4vLyBJbml0aWFsaXplIGFnYWluc3QgdGhlIGRlZmF1bHQgZG9jdW1lbnRcclxuc2V0RG9jdW1lbnQoKTtcclxuXHJcbi8vIFN1cHBvcnQ6IFdlYmtpdDw1MzcuMzIgLSBTYWZhcmkgNi4wLjMvQ2hyb21lIDI1IChmaXhlZCBpbiBDaHJvbWUgMjcpXHJcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxyXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydChmdW5jdGlvbiggZGl2MSApIHtcclxuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcclxuXHRyZXR1cm4gZGl2MS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSApICYgMTtcclxufSk7XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw4XHJcbi8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5IFwiaW50ZXJwb2xhdGlvblwiXHJcbi8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjQyOSUyOFZTLjg1JTI5LmFzcHhcclxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XHJcblx0ZGl2LmlubmVySFRNTCA9IFwiPGEgaHJlZj0nIyc+PC9hPlwiO1xyXG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIiA7XHJcbn0pICkge1xyXG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcclxuXHRcdGlmICggIWlzWE1MICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0eXBlXCIgPyAxIDogMiApO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw5XHJcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcclxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRkaXYuaW5uZXJIVE1MID0gXCI8aW5wdXQvPlwiO1xyXG5cdGRpdi5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XHJcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IFwiXCI7XHJcbn0pICkge1xyXG5cdGFkZEhhbmRsZSggXCJ2YWx1ZVwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XHJcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw5XHJcbi8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXNcclxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XHJcblx0cmV0dXJuIGRpdi5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSA9PSBudWxsO1xyXG59KSApIHtcclxuXHRhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XHJcblx0XHR2YXIgdmFsO1xyXG5cdFx0aWYgKCAhaXNYTUwgKSB7XHJcblx0XHRcdHJldHVybiBlbGVtWyBuYW1lIF0gPT09IHRydWUgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOlxyXG5cdFx0XHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID9cclxuXHRcdFx0XHRcdHZhbC52YWx1ZSA6XHJcblx0XHRcdFx0bnVsbDtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxucmV0dXJuIFNpenpsZTtcclxuXHJcbn0pKCB3aW5kb3cgKTtcclxuXHJcblxyXG5cclxualF1ZXJ5LmZpbmQgPSBTaXp6bGU7XHJcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcclxualF1ZXJ5LmV4cHJbIFwiOlwiIF0gPSBqUXVlcnkuZXhwci5wc2V1ZG9zO1xyXG5qUXVlcnkudW5pcXVlU29ydCA9IGpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcclxualF1ZXJ5LnRleHQgPSBTaXp6bGUuZ2V0VGV4dDtcclxualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xyXG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XHJcblxyXG5cclxuXHJcbnZhciBkaXIgPSBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcclxuXHR2YXIgbWF0Y2hlZCA9IFtdLFxyXG5cdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuXHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgJiYgZWxlbS5ub2RlVHlwZSAhPT0gOSApIHtcclxuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdFx0aWYgKCB0cnVuY2F0ZSAmJiBqUXVlcnkoIGVsZW0gKS5pcyggdW50aWwgKSApIHtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0XHRtYXRjaGVkLnB1c2goIGVsZW0gKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIG1hdGNoZWQ7XHJcbn07XHJcblxyXG5cclxudmFyIHNpYmxpbmdzID0gZnVuY3Rpb24oIG4sIGVsZW0gKSB7XHJcblx0dmFyIG1hdGNoZWQgPSBbXTtcclxuXHJcblx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcclxuXHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xyXG5cdFx0XHRtYXRjaGVkLnB1c2goIG4gKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBtYXRjaGVkO1xyXG59O1xyXG5cclxuXHJcbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xyXG5cclxudmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbXFx3LV0rKVxccypcXC8/Pig/OjxcXC9cXDE+fCkkLyApO1xyXG5cclxuXHJcblxyXG52YXIgcmlzU2ltcGxlID0gL14uW146I1xcW1xcLixdKiQvO1xyXG5cclxuLy8gSW1wbGVtZW50IHRoZSBpZGVudGljYWwgZnVuY3Rpb25hbGl0eSBmb3IgZmlsdGVyIGFuZCBub3RcclxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XHJcblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcclxuXHRcdFx0LyoganNoaW50IC1XMDE4ICovXHJcblx0XHRcdHJldHVybiAhIXF1YWxpZmllci5jYWxsKCBlbGVtLCBpLCBlbGVtICkgIT09IG5vdDtcclxuXHRcdH0gKTtcclxuXHJcblx0fVxyXG5cclxuXHRpZiAoIHF1YWxpZmllci5ub2RlVHlwZSApIHtcclxuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xyXG5cdFx0fSApO1xyXG5cclxuXHR9XHJcblxyXG5cdGlmICggdHlwZW9mIHF1YWxpZmllciA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdGlmICggcmlzU2ltcGxlLnRlc3QoIHF1YWxpZmllciApICkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cywgbm90ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cXVhbGlmaWVyID0galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cyApO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xyXG5cdH0gKTtcclxufVxyXG5cclxualF1ZXJ5LmZpbHRlciA9IGZ1bmN0aW9uKCBleHByLCBlbGVtcywgbm90ICkge1xyXG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcclxuXHJcblx0aWYgKCBub3QgKSB7XHJcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW1zLmxlbmd0aCA9PT0gMSAmJiBlbGVtLm5vZGVUeXBlID09PSAxID9cclxuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXSA6XHJcblx0XHRqUXVlcnkuZmluZC5tYXRjaGVzKCBleHByLCBqUXVlcnkuZ3JlcCggZWxlbXMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTtcclxuXHRcdH0gKSApO1xyXG59O1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGZpbmQ6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHZhciBpLFxyXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0cmV0ID0gW10sXHJcblx0XHRcdHNlbGYgPSB0aGlzO1xyXG5cclxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFx0alF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE5lZWRlZCBiZWNhdXNlICQoIHNlbGVjdG9yLCBjb250ZXh0ICkgYmVjb21lcyAkKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKVxyXG5cdFx0cmV0ID0gdGhpcy5wdXNoU3RhY2soIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlKCByZXQgKSA6IHJldCApO1xyXG5cdFx0cmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciA/IHRoaXMuc2VsZWN0b3IgKyBcIiBcIiArIHNlbGVjdG9yIDogc2VsZWN0b3I7XHJcblx0XHRyZXR1cm4gcmV0O1xyXG5cdH0sXHJcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlICkgKTtcclxuXHR9LFxyXG5cdG5vdDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlICkgKTtcclxuXHR9LFxyXG5cdGlzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHRyZXR1cm4gISF3aW5ub3coXHJcblx0XHRcdHRoaXMsXHJcblxyXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XHJcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cclxuXHRcdFx0dHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICYmIHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/XHJcblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcclxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcclxuXHRcdFx0ZmFsc2VcclxuXHRcdCkubGVuZ3RoO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbi8vIEluaXRpYWxpemUgYSBqUXVlcnkgb2JqZWN0XHJcblxyXG5cclxuLy8gQSBjZW50cmFsIHJlZmVyZW5jZSB0byB0aGUgcm9vdCBqUXVlcnkoZG9jdW1lbnQpXHJcbnZhciByb290alF1ZXJ5LFxyXG5cclxuXHQvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5nc1xyXG5cdC8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoICgjOTUyMSlcclxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcclxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKikpJC8sXHJcblxyXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcm9vdCApIHtcclxuXHRcdHZhciBtYXRjaCwgZWxlbTtcclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcclxuXHRcdGlmICggIXNlbGVjdG9yICkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNZXRob2QgaW5pdCgpIGFjY2VwdHMgYW4gYWx0ZXJuYXRlIHJvb3RqUXVlcnlcclxuXHRcdC8vIHNvIG1pZ3JhdGUgY2FuIHN1cHBvcnQgalF1ZXJ5LnN1YiAoZ2gtMjEwMSlcclxuXHRcdHJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7XHJcblxyXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xyXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGlmICggc2VsZWN0b3JbIDAgXSA9PT0gXCI8XCIgJiZcclxuXHRcdFx0XHRzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJlxyXG5cdFx0XHRcdHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xyXG5cclxuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xyXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xyXG5cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxyXG5cdFx0XHRpZiAoIG1hdGNoICYmICggbWF0Y2hbIDEgXSB8fCAhY29udGV4dCApICkge1xyXG5cclxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcclxuXHRcdFx0XHRpZiAoIG1hdGNoWyAxIF0gKSB7XHJcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbIDAgXSA6IGNvbnRleHQ7XHJcblxyXG5cdFx0XHRcdFx0Ly8gT3B0aW9uIHRvIHJ1biBzY3JpcHRzIGlzIHRydWUgZm9yIGJhY2stY29tcGF0XHJcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxyXG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxyXG5cdFx0XHRcdFx0XHRtYXRjaFsgMSBdLFxyXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxyXG5cdFx0XHRcdFx0XHR0cnVlXHJcblx0XHRcdFx0XHQpICk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxyXG5cdFx0XHRcdFx0aWYgKCByc2luZ2xlVGFnLnRlc3QoIG1hdGNoWyAxIF0gKSAmJiBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29udGV4dCApICkge1xyXG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBQcm9wZXJ0aWVzIG9mIGNvbnRleHQgYXJlIGNhbGxlZCBhcyBtZXRob2RzIGlmIHBvc3NpYmxlXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdGhpc1sgbWF0Y2ggXSApICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgb3RoZXJ3aXNlIHNldCBhcyBhdHRyaWJ1dGVzXHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHJcblx0XHRcdFx0Ly8gSEFORExFOiAkKCNpZClcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsgMiBdICk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogQmxhY2tiZXJyeSA0LjZcclxuXHRcdFx0XHRcdC8vIGdFQklEIHJldHVybnMgbm9kZXMgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAoIzY5NjMpXHJcblx0XHRcdFx0XHRpZiAoIGVsZW0gJiYgZWxlbS5wYXJlbnROb2RlICkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gSW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3RcclxuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xyXG5cdFx0XHRcdFx0XHR0aGlzWyAwIF0gPSBlbGVtO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHRoaXMuY29udGV4dCA9IGRvY3VtZW50O1xyXG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsICQoLi4uKSlcclxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XHJcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290ICkuZmluZCggc2VsZWN0b3IgKTtcclxuXHJcblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxyXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcclxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xyXG5cdFx0XHR0aGlzLmNvbnRleHQgPSB0aGlzWyAwIF0gPSBzZWxlY3RvcjtcclxuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXHJcblx0XHQvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHlcclxuXHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBzZWxlY3RvciApICkge1xyXG5cdFx0XHRyZXR1cm4gcm9vdC5yZWFkeSAhPT0gdW5kZWZpbmVkID9cclxuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcclxuXHJcblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxyXG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHNlbGVjdG9yLnNlbGVjdG9yICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHRoaXMuc2VsZWN0b3IgPSBzZWxlY3Rvci5zZWxlY3RvcjtcclxuXHRcdFx0dGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcclxuXHR9O1xyXG5cclxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxyXG5pbml0LnByb3RvdHlwZSA9IGpRdWVyeS5mbjtcclxuXHJcbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2Vcclxucm9vdGpRdWVyeSA9IGpRdWVyeSggZG9jdW1lbnQgKTtcclxuXHJcblxyXG52YXIgcnBhcmVudHNwcmV2ID0gL14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sXHJcblxyXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XHJcblx0Z3VhcmFudGVlZFVuaXF1ZSA9IHtcclxuXHRcdGNoaWxkcmVuOiB0cnVlLFxyXG5cdFx0Y29udGVudHM6IHRydWUsXHJcblx0XHRuZXh0OiB0cnVlLFxyXG5cdFx0cHJldjogdHJ1ZVxyXG5cdH07XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xyXG5cdFx0dmFyIHRhcmdldHMgPSBqUXVlcnkoIHRhcmdldCwgdGhpcyApLFxyXG5cdFx0XHRsID0gdGFyZ2V0cy5sZW5ndGg7XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGkgPSAwO1xyXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHRoaXMsIHRhcmdldHNbIGkgXSApICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcclxuXHRcdHZhciBjdXIsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXHJcblx0XHRcdG1hdGNoZWQgPSBbXSxcclxuXHRcdFx0cG9zID0gcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSB8fCB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiID9cclxuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9ycywgY29udGV4dCB8fCB0aGlzLmNvbnRleHQgKSA6XHJcblx0XHRcdFx0MDtcclxuXHJcblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdGZvciAoIGN1ciA9IHRoaXNbIGkgXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XHJcblxyXG5cdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xyXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCBwb3MgP1xyXG5cdFx0XHRcdFx0cG9zLmluZGV4KCBjdXIgKSA+IC0xIDpcclxuXHJcblx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcclxuXHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcclxuXHJcblx0XHRcdFx0XHRtYXRjaGVkLnB1c2goIGN1ciApO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkLmxlbmd0aCA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApIDogbWF0Y2hlZCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCB3aXRoaW4gdGhlIHNldFxyXG5cdGluZGV4OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHJcblx0XHQvLyBObyBhcmd1bWVudCwgcmV0dXJuIGluZGV4IGluIHBhcmVudFxyXG5cdFx0aWYgKCAhZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXHJcblx0XHRpZiAoIHR5cGVvZiBlbGVtID09PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdGhpc1sgMCBdICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTG9jYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZGVzaXJlZCBlbGVtZW50XHJcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxyXG5cclxuXHRcdFx0Ly8gSWYgaXQgcmVjZWl2ZXMgYSBqUXVlcnkgb2JqZWN0LCB0aGUgZmlyc3QgZWxlbWVudCBpcyB1c2VkXHJcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxyXG5cdFx0KTtcclxuXHR9LFxyXG5cclxuXHRhZGQ6IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayhcclxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLmdldCgpLCBqUXVlcnkoIHNlbGVjdG9yLCBjb250ZXh0ICkgKVxyXG5cdFx0XHQpXHJcblx0XHQpO1xyXG5cdH0sXHJcblxyXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHJldHVybiB0aGlzLmFkZCggc2VsZWN0b3IgPT0gbnVsbCA/XHJcblx0XHRcdHRoaXMucHJldk9iamVjdCA6IHRoaXMucHJldk9iamVjdC5maWx0ZXIoIHNlbGVjdG9yIClcclxuXHRcdCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5mdW5jdGlvbiBzaWJsaW5nKCBjdXIsIGRpciApIHtcclxuXHR3aGlsZSAoICggY3VyID0gY3VyWyBkaXIgXSApICYmIGN1ci5ub2RlVHlwZSAhPT0gMSApIHt9XHJcblx0cmV0dXJuIGN1cjtcclxufVxyXG5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRwYXJlbnQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcclxuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XHJcblx0fSxcclxuXHRwYXJlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XHJcblx0fSxcclxuXHRwYXJlbnRzVW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiLCB1bnRpbCApO1xyXG5cdH0sXHJcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XHJcblx0fSxcclxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XHJcblx0fSxcclxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xyXG5cdH0sXHJcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XHJcblx0fSxcclxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcclxuXHR9LFxyXG5cdHByZXZVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xyXG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcclxuXHR9LFxyXG5cdHNpYmxpbmdzOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XHJcblx0fSxcclxuXHRjaGlsZHJlbjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xyXG5cdH0sXHJcblx0Y29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0cmV0dXJuIGVsZW0uY29udGVudERvY3VtZW50IHx8IGpRdWVyeS5tZXJnZSggW10sIGVsZW0uY2hpbGROb2RlcyApO1xyXG5cdH1cclxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHVudGlsLCBzZWxlY3RvciApIHtcclxuXHRcdHZhciBtYXRjaGVkID0galF1ZXJ5Lm1hcCggdGhpcywgZm4sIHVudGlsICk7XHJcblxyXG5cdFx0aWYgKCBuYW1lLnNsaWNlKCAtNSApICE9PSBcIlVudGlsXCIgKSB7XHJcblx0XHRcdHNlbGVjdG9yID0gdW50aWw7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0Ly8gUmVtb3ZlIGR1cGxpY2F0ZXNcclxuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xyXG5cdFx0XHRcdGpRdWVyeS51bmlxdWVTb3J0KCBtYXRjaGVkICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFJldmVyc2Ugb3JkZXIgZm9yIHBhcmVudHMqIGFuZCBwcmV2LWRlcml2YXRpdmVzXHJcblx0XHRcdGlmICggcnBhcmVudHNwcmV2LnRlc3QoIG5hbWUgKSApIHtcclxuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZCApO1xyXG5cdH07XHJcbn0gKTtcclxudmFyIHJub3R3aGl0ZSA9ICggL1xcUysvZyApO1xyXG5cclxuXHJcblxyXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lc1xyXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xyXG5cdHZhciBvYmplY3QgPSB7fTtcclxuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xyXG5cdFx0b2JqZWN0WyBmbGFnIF0gPSB0cnVlO1xyXG5cdH0gKTtcclxuXHRyZXR1cm4gb2JqZWN0O1xyXG59XHJcblxyXG4vKlxyXG4gKiBDcmVhdGUgYSBjYWxsYmFjayBsaXN0IHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcclxuICpcclxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcclxuICpcdFx0XHR0aGUgY2FsbGJhY2sgbGlzdCBiZWhhdmVzIG9yIGEgbW9yZSB0cmFkaXRpb25hbCBvcHRpb24gb2JqZWN0XHJcbiAqXHJcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXHJcbiAqIFwiZmlyZWRcIiBtdWx0aXBsZSB0aW1lcy5cclxuICpcclxuICogUG9zc2libGUgb3B0aW9uczpcclxuICpcclxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxyXG4gKlxyXG4gKlx0bWVtb3J5Olx0XHRcdHdpbGwga2VlcCB0cmFjayBvZiBwcmV2aW91cyB2YWx1ZXMgYW5kIHdpbGwgY2FsbCBhbnkgY2FsbGJhY2sgYWRkZWRcclxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxyXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcclxuICpcclxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcclxuICpcclxuICpcdHN0b3BPbkZhbHNlOlx0aW50ZXJydXB0IGNhbGxpbmdzIHdoZW4gYSBjYWxsYmFjayByZXR1cm5zIGZhbHNlXHJcbiAqXHJcbiAqL1xyXG5qUXVlcnkuQ2FsbGJhY2tzID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XHJcblxyXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcclxuXHQvLyAod2UgY2hlY2sgaW4gY2FjaGUgZmlyc3QpXHJcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cclxuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XHJcblx0XHRqUXVlcnkuZXh0ZW5kKCB7fSwgb3B0aW9ucyApO1xyXG5cclxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xyXG5cdFx0ZmlyaW5nLFxyXG5cclxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXHJcblx0XHRtZW1vcnksXHJcblxyXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcclxuXHRcdGZpcmVkLFxyXG5cclxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcclxuXHRcdGxvY2tlZCxcclxuXHJcblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxyXG5cdFx0bGlzdCA9IFtdLFxyXG5cclxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXHJcblx0XHRxdWV1ZSA9IFtdLFxyXG5cclxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxyXG5cdFx0ZmlyaW5nSW5kZXggPSAtMSxcclxuXHJcblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xyXG5cdFx0ZmlyZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXHJcblx0XHRcdGxvY2tlZCA9IG9wdGlvbnMub25jZTtcclxuXHJcblx0XHRcdC8vIEV4ZWN1dGUgY2FsbGJhY2tzIGZvciBhbGwgcGVuZGluZyBleGVjdXRpb25zLFxyXG5cdFx0XHQvLyByZXNwZWN0aW5nIGZpcmluZ0luZGV4IG92ZXJyaWRlcyBhbmQgcnVudGltZSBjaGFuZ2VzXHJcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcclxuXHRcdFx0Zm9yICggOyBxdWV1ZS5sZW5ndGg7IGZpcmluZ0luZGV4ID0gLTEgKSB7XHJcblx0XHRcdFx0bWVtb3J5ID0gcXVldWUuc2hpZnQoKTtcclxuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBSdW4gY2FsbGJhY2sgYW5kIGNoZWNrIGZvciBlYXJseSB0ZXJtaW5hdGlvblxyXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcclxuXHRcdFx0XHRcdFx0b3B0aW9ucy5zdG9wT25GYWxzZSApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcclxuXHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXggPSBsaXN0Lmxlbmd0aDtcclxuXHRcdFx0XHRcdFx0bWVtb3J5ID0gZmFsc2U7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBGb3JnZXQgdGhlIGRhdGEgaWYgd2UncmUgZG9uZSB3aXRoIGl0XHJcblx0XHRcdGlmICggIW9wdGlvbnMubWVtb3J5ICkge1xyXG5cdFx0XHRcdG1lbW9yeSA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcclxuXHJcblx0XHRcdC8vIENsZWFuIHVwIGlmIHdlJ3JlIGRvbmUgZmlyaW5nIGZvciBnb29kXHJcblx0XHRcdGlmICggbG9ja2VkICkge1xyXG5cclxuXHRcdFx0XHQvLyBLZWVwIGFuIGVtcHR5IGxpc3QgaWYgd2UgaGF2ZSBkYXRhIGZvciBmdXR1cmUgYWRkIGNhbGxzXHJcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XHJcblx0XHRcdFx0XHRsaXN0ID0gW107XHJcblxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0bGlzdCA9IFwiXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIEFjdHVhbCBDYWxsYmFja3Mgb2JqZWN0XHJcblx0XHRzZWxmID0ge1xyXG5cclxuXHRcdFx0Ly8gQWRkIGEgY2FsbGJhY2sgb3IgYSBjb2xsZWN0aW9uIG9mIGNhbGxiYWNrcyB0byB0aGUgbGlzdFxyXG5cdFx0XHRhZGQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggbGlzdCApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBJZiB3ZSBoYXZlIG1lbW9yeSBmcm9tIGEgcGFzdCBydW4sIHdlIHNob3VsZCBmaXJlIGFmdGVyIGFkZGluZ1xyXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcclxuXHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXggPSBsaXN0Lmxlbmd0aCAtIDE7XHJcblx0XHRcdFx0XHRcdHF1ZXVlLnB1c2goIG1lbW9yeSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCggZnVuY3Rpb24gYWRkKCBhcmdzICkge1xyXG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhcmcgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGxpc3QucHVzaCggYXJnICk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgalF1ZXJ5LnR5cGUoIGFyZyApICE9PSBcInN0cmluZ1wiICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIEluc3BlY3QgcmVjdXJzaXZlbHlcclxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0XHR9ICkoIGFyZ3VtZW50cyApO1xyXG5cclxuXHRcdFx0XHRcdGlmICggbWVtb3J5ICYmICFmaXJpbmcgKSB7XHJcblx0XHRcdFx0XHRcdGZpcmUoKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgYSBjYWxsYmFjayBmcm9tIHRoZSBsaXN0XHJcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3VtZW50cywgZnVuY3Rpb24oIF8sIGFyZyApIHtcclxuXHRcdFx0XHRcdHZhciBpbmRleDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xyXG5cdFx0XHRcdFx0XHRsaXN0LnNwbGljZSggaW5kZXgsIDEgKTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xyXG5cdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0luZGV4ICkge1xyXG5cdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxyXG5cdFx0XHQvLyBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgcmV0dXJuIHdoZXRoZXIgb3Igbm90IGxpc3QgaGFzIGNhbGxiYWNrcyBhdHRhY2hlZC5cclxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZuID9cclxuXHRcdFx0XHRcdGpRdWVyeS5pbkFycmF5KCBmbiwgbGlzdCApID4gLTEgOlxyXG5cdFx0XHRcdFx0bGlzdC5sZW5ndGggPiAwO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxyXG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xyXG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIERpc2FibGUgLmZpcmUgYW5kIC5hZGRcclxuXHRcdFx0Ly8gQWJvcnQgYW55IGN1cnJlbnQvcGVuZGluZyBleGVjdXRpb25zXHJcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xyXG5cdFx0XHRkaXNhYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRsb2NrZWQgPSBxdWV1ZSA9IFtdO1xyXG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuICFsaXN0O1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gRGlzYWJsZSAuZmlyZVxyXG5cdFx0XHQvLyBBbHNvIGRpc2FibGUgLmFkZCB1bmxlc3Mgd2UgaGF2ZSBtZW1vcnkgKHNpbmNlIGl0IHdvdWxkIGhhdmUgbm8gZWZmZWN0KVxyXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXHJcblx0XHRcdGxvY2s6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XHJcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICkge1xyXG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRsb2NrZWQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHJldHVybiAhIWxvY2tlZDtcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcclxuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xyXG5cdFx0XHRcdGlmICggIWxvY2tlZCApIHtcclxuXHRcdFx0XHRcdGFyZ3MgPSBhcmdzIHx8IFtdO1xyXG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcclxuXHRcdFx0XHRcdHF1ZXVlLnB1c2goIGFyZ3MgKTtcclxuXHRcdFx0XHRcdGlmICggIWZpcmluZyApIHtcclxuXHRcdFx0XHRcdFx0ZmlyZSgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXHJcblx0XHRcdGZpcmU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXHJcblx0XHRcdGZpcmVkOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHJcblx0cmV0dXJuIHNlbGY7XHJcbn07XHJcblxyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XHJcblx0XHR2YXIgdHVwbGVzID0gW1xyXG5cclxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgbGlzdGVuZXIgbGlzdCwgZmluYWwgc3RhdGVcclxuXHRcdFx0XHRbIFwicmVzb2x2ZVwiLCBcImRvbmVcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksIFwicmVzb2x2ZWRcIiBdLFxyXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCBcInJlamVjdGVkXCIgXSxcclxuXHRcdFx0XHRbIFwibm90aWZ5XCIsIFwicHJvZ3Jlc3NcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApIF1cclxuXHRcdFx0XSxcclxuXHRcdFx0c3RhdGUgPSBcInBlbmRpbmdcIixcclxuXHRcdFx0cHJvbWlzZSA9IHtcclxuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGU7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0ZGVmZXJyZWQuZG9uZSggYXJndW1lbnRzICkuZmFpbCggYXJndW1lbnRzICk7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCAvKiBmbkRvbmUsIGZuRmFpbCwgZm5Qcm9ncmVzcyAqLyApIHtcclxuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XHJcblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XHJcblx0XHRcdFx0XHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcclxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBqUXVlcnkuaXNGdW5jdGlvbiggZm5zWyBpIF0gKSAmJiBmbnNbIGkgXTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWRbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSBmb3IgZm9yd2FyZGluZyBhY3Rpb25zIHRvIG5ld0RlZmVyXHJcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdFx0XHR2YXIgcmV0dXJuZWQgPSBmbiAmJiBmbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHJldHVybmVkICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXR1cm5lZC5wcm9taXNlICkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnByb21pc2UoKVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZG9uZSggbmV3RGVmZXIucmVzb2x2ZSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXJbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMgPT09IHByb21pc2UgPyBuZXdEZWZlci5wcm9taXNlKCkgOiB0aGlzLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0XHRcdGZucyA9IG51bGw7XHJcblx0XHRcdFx0XHR9ICkucHJvbWlzZSgpO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIEdldCBhIHByb21pc2UgZm9yIHRoaXMgZGVmZXJyZWRcclxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XHJcblx0XHRcdFx0cHJvbWlzZTogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdFx0XHRcdHJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblx0XHRcdGRlZmVycmVkID0ge307XHJcblxyXG5cdFx0Ly8gS2VlcCBwaXBlIGZvciBiYWNrLWNvbXBhdFxyXG5cdFx0cHJvbWlzZS5waXBlID0gcHJvbWlzZS50aGVuO1xyXG5cclxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcclxuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcclxuXHRcdFx0dmFyIGxpc3QgPSB0dXBsZVsgMiBdLFxyXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDMgXTtcclxuXHJcblx0XHRcdC8vIHByb21pc2VbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSA9IGxpc3QuYWRkXHJcblx0XHRcdHByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkO1xyXG5cclxuXHRcdFx0Ly8gSGFuZGxlIHN0YXRlXHJcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XHJcblx0XHRcdFx0bGlzdC5hZGQoIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHRcdC8vIHN0YXRlID0gWyByZXNvbHZlZCB8IHJlamVjdGVkIF1cclxuXHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XHJcblxyXG5cdFx0XHRcdC8vIFsgcmVqZWN0X2xpc3QgfCByZXNvbHZlX2xpc3QgXS5kaXNhYmxlOyBwcm9ncmVzc19saXN0LmxvY2tcclxuXHRcdFx0XHR9LCB0dXBsZXNbIGkgXiAxIF1bIDIgXS5kaXNhYmxlLCB0dXBsZXNbIDIgXVsgMiBdLmxvY2sgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gZGVmZXJyZWRbIHJlc29sdmUgfCByZWplY3QgfCBub3RpZnkgXVxyXG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBkZWZlcnJlZCA/IHByb21pc2UgOiB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fTtcclxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcclxuXHRcdH0gKTtcclxuXHJcblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2VcclxuXHRcdHByb21pc2UucHJvbWlzZSggZGVmZXJyZWQgKTtcclxuXHJcblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XHJcblx0XHRpZiAoIGZ1bmMgKSB7XHJcblx0XHRcdGZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsIGRvbmUhXHJcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XHJcblx0fSxcclxuXHJcblx0Ly8gRGVmZXJyZWQgaGVscGVyXHJcblx0d2hlbjogZnVuY3Rpb24oIHN1Ym9yZGluYXRlIC8qICwgLi4uLCBzdWJvcmRpbmF0ZU4gKi8gKSB7XHJcblx0XHR2YXIgaSA9IDAsXHJcblx0XHRcdHJlc29sdmVWYWx1ZXMgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcclxuXHRcdFx0bGVuZ3RoID0gcmVzb2x2ZVZhbHVlcy5sZW5ndGgsXHJcblxyXG5cdFx0XHQvLyB0aGUgY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXHJcblx0XHRcdHJlbWFpbmluZyA9IGxlbmd0aCAhPT0gMSB8fFxyXG5cdFx0XHRcdCggc3Vib3JkaW5hdGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHN1Ym9yZGluYXRlLnByb21pc2UgKSApID8gbGVuZ3RoIDogMCxcclxuXHJcblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWQuXHJcblx0XHRcdC8vIElmIHJlc29sdmVWYWx1ZXMgY29uc2lzdCBvZiBvbmx5IGEgc2luZ2xlIERlZmVycmVkLCBqdXN0IHVzZSB0aGF0LlxyXG5cdFx0XHRkZWZlcnJlZCA9IHJlbWFpbmluZyA9PT0gMSA/IHN1Ym9yZGluYXRlIDogalF1ZXJ5LkRlZmVycmVkKCksXHJcblxyXG5cdFx0XHQvLyBVcGRhdGUgZnVuY3Rpb24gZm9yIGJvdGggcmVzb2x2ZSBhbmQgcHJvZ3Jlc3MgdmFsdWVzXHJcblx0XHRcdHVwZGF0ZUZ1bmMgPSBmdW5jdGlvbiggaSwgY29udGV4dHMsIHZhbHVlcyApIHtcclxuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0XHRcdFx0Y29udGV4dHNbIGkgXSA9IHRoaXM7XHJcblx0XHRcdFx0XHR2YWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcclxuXHRcdFx0XHRcdGlmICggdmFsdWVzID09PSBwcm9ncmVzc1ZhbHVlcyApIHtcclxuXHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICggISggLS1yZW1haW5pbmcgKSApIHtcclxuXHRcdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNvbnRleHRzLCB2YWx1ZXMgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9O1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMsIHByb2dyZXNzQ29udGV4dHMsIHJlc29sdmVDb250ZXh0cztcclxuXHJcblx0XHQvLyBBZGQgbGlzdGVuZXJzIHRvIERlZmVycmVkIHN1Ym9yZGluYXRlczsgdHJlYXQgb3RoZXJzIGFzIHJlc29sdmVkXHJcblx0XHRpZiAoIGxlbmd0aCA+IDEgKSB7XHJcblx0XHRcdHByb2dyZXNzVmFsdWVzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcclxuXHRcdFx0cHJvZ3Jlc3NDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XHJcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHRcdGlmICggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0ucHJvbWlzZSApICkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZVZhbHVlc1sgaSBdLnByb21pc2UoKVxyXG5cdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIHVwZGF0ZUZ1bmMoIGksIHByb2dyZXNzQ29udGV4dHMsIHByb2dyZXNzVmFsdWVzICkgKVxyXG5cdFx0XHRcdFx0XHQuZG9uZSggdXBkYXRlRnVuYyggaSwgcmVzb2x2ZUNvbnRleHRzLCByZXNvbHZlVmFsdWVzICkgKVxyXG5cdFx0XHRcdFx0XHQuZmFpbCggZGVmZXJyZWQucmVqZWN0ICk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC0tcmVtYWluaW5nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIElmIHdlJ3JlIG5vdCB3YWl0aW5nIG9uIGFueXRoaW5nLCByZXNvbHZlIHRoZSBtYXN0ZXJcclxuXHRcdGlmICggIXJlbWFpbmluZyApIHtcclxuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxuLy8gVGhlIGRlZmVycmVkIHVzZWQgb24gRE9NIHJlYWR5XHJcbnZhciByZWFkeUxpc3Q7XHJcblxyXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XHJcblxyXG5cdC8vIEFkZCB0aGUgY2FsbGJhY2tcclxuXHRqUXVlcnkucmVhZHkucHJvbWlzZSgpLmRvbmUoIGZuICk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxyXG5cdGlzUmVhZHk6IGZhbHNlLFxyXG5cclxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXHJcblx0Ly8gdGhlIHJlYWR5IGV2ZW50IGZpcmVzLiBTZWUgIzY3ODFcclxuXHRyZWFkeVdhaXQ6IDEsXHJcblxyXG5cdC8vIEhvbGQgKG9yIHJlbGVhc2UpIHRoZSByZWFkeSBldmVudFxyXG5cdGhvbGRSZWFkeTogZnVuY3Rpb24oIGhvbGQgKSB7XHJcblx0XHRpZiAoIGhvbGQgKSB7XHJcblx0XHRcdGpRdWVyeS5yZWFkeVdhaXQrKztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIEhhbmRsZSB3aGVuIHRoZSBET00gaXMgcmVhZHlcclxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XHJcblxyXG5cdFx0Ly8gQWJvcnQgaWYgdGhlcmUgYXJlIHBlbmRpbmcgaG9sZHMgb3Igd2UncmUgYWxyZWFkeSByZWFkeVxyXG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcclxuXHRcdGpRdWVyeS5pc1JlYWR5ID0gdHJ1ZTtcclxuXHJcblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxyXG5cdFx0aWYgKCB3YWl0ICE9PSB0cnVlICYmIC0talF1ZXJ5LnJlYWR5V2FpdCA+IDAgKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXHJcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XHJcblxyXG5cdFx0Ly8gVHJpZ2dlciBhbnkgYm91bmQgcmVhZHkgZXZlbnRzXHJcblx0XHRpZiAoIGpRdWVyeS5mbi50cmlnZ2VySGFuZGxlciApIHtcclxuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLnRyaWdnZXJIYW5kbGVyKCBcInJlYWR5XCIgKTtcclxuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLm9mZiggXCJyZWFkeVwiICk7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG4vKipcclxuICogVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcclxuICovXHJcbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcclxuXHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkICk7XHJcblx0d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcclxuXHRqUXVlcnkucmVhZHkoKTtcclxufVxyXG5cclxualF1ZXJ5LnJlYWR5LnByb21pc2UgPSBmdW5jdGlvbiggb2JqICkge1xyXG5cdGlmICggIXJlYWR5TGlzdCApIHtcclxuXHJcblx0XHRyZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcclxuXHJcblx0XHQvLyBDYXRjaCBjYXNlcyB3aGVyZSAkKGRvY3VtZW50KS5yZWFkeSgpIGlzIGNhbGxlZFxyXG5cdFx0Ly8gYWZ0ZXIgdGhlIGJyb3dzZXIgZXZlbnQgaGFzIGFscmVhZHkgb2NjdXJyZWQuXHJcblx0XHQvLyBTdXBwb3J0OiBJRTktMTAgb25seVxyXG5cdFx0Ly8gT2xkZXIgSUUgc29tZXRpbWVzIHNpZ25hbHMgXCJpbnRlcmFjdGl2ZVwiIHRvbyBzb29uXHJcblx0XHRpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fFxyXG5cdFx0XHQoIGRvY3VtZW50LnJlYWR5U3RhdGUgIT09IFwibG9hZGluZ1wiICYmICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwgKSApIHtcclxuXHJcblx0XHRcdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxyXG5cdFx0XHR3aW5kb3cuc2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcclxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xyXG5cclxuXHRcdFx0Ly8gQSBmYWxsYmFjayB0byB3aW5kb3cub25sb2FkLCB0aGF0IHdpbGwgYWx3YXlzIHdvcmtcclxuXHRcdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIHJlYWR5TGlzdC5wcm9taXNlKCBvYmogKTtcclxufTtcclxuXHJcbi8vIEtpY2sgb2ZmIHRoZSBET00gcmVhZHkgY2hlY2sgZXZlbiBpZiB0aGUgdXNlciBkb2VzIG5vdFxyXG5qUXVlcnkucmVhZHkucHJvbWlzZSgpO1xyXG5cclxuXHJcblxyXG5cclxuLy8gTXVsdGlmdW5jdGlvbmFsIG1ldGhvZCB0byBnZXQgYW5kIHNldCB2YWx1ZXMgb2YgYSBjb2xsZWN0aW9uXHJcbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxyXG52YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xyXG5cdHZhciBpID0gMCxcclxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcclxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcclxuXHJcblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xyXG5cdGlmICggalF1ZXJ5LnR5cGUoIGtleSApID09PSBcIm9iamVjdFwiICkge1xyXG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcclxuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xyXG5cdFx0XHRhY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5WyBpIF0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTtcclxuXHRcdH1cclxuXHJcblx0Ly8gU2V0cyBvbmUgdmFsdWVcclxuXHR9IGVsc2UgaWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcclxuXHJcblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcclxuXHRcdFx0cmF3ID0gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGJ1bGsgKSB7XHJcblxyXG5cdFx0XHQvLyBCdWxrIG9wZXJhdGlvbnMgcnVuIGFnYWluc3QgdGhlIGVudGlyZSBzZXRcclxuXHRcdFx0aWYgKCByYXcgKSB7XHJcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XHJcblx0XHRcdFx0Zm4gPSBudWxsO1xyXG5cclxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGJ1bGsgPSBmbjtcclxuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBrZXksIHZhbHVlICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGJ1bGsuY2FsbCggalF1ZXJ5KCBlbGVtICksIHZhbHVlICk7XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggZm4gKSB7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0XHRcdGZuKFxyXG5cdFx0XHRcdFx0ZWxlbXNbIGkgXSwga2V5LCByYXcgP1xyXG5cdFx0XHRcdFx0dmFsdWUgOlxyXG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gY2hhaW5hYmxlID9cclxuXHRcdGVsZW1zIDpcclxuXHJcblx0XHQvLyBHZXRzXHJcblx0XHRidWxrID9cclxuXHRcdFx0Zm4uY2FsbCggZWxlbXMgKSA6XHJcblx0XHRcdGxlbiA/IGZuKCBlbGVtc1sgMCBdLCBrZXkgKSA6IGVtcHR5R2V0O1xyXG59O1xyXG52YXIgYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcclxuXHJcblx0Ly8gQWNjZXB0cyBvbmx5OlxyXG5cdC8vICAtIE5vZGVcclxuXHQvLyAgICAtIE5vZGUuRUxFTUVOVF9OT0RFXHJcblx0Ly8gICAgLSBOb2RlLkRPQ1VNRU5UX05PREVcclxuXHQvLyAgLSBPYmplY3RcclxuXHQvLyAgICAtIEFueVxyXG5cdC8qIGpzaGludCAtVzAxOCAqL1xyXG5cdHJldHVybiBvd25lci5ub2RlVHlwZSA9PT0gMSB8fCBvd25lci5ub2RlVHlwZSA9PT0gOSB8fCAhKCArb3duZXIubm9kZVR5cGUgKTtcclxufTtcclxuXHJcblxyXG5cclxuXHJcbmZ1bmN0aW9uIERhdGEoKSB7XHJcblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xyXG59XHJcblxyXG5EYXRhLnVpZCA9IDE7XHJcblxyXG5EYXRhLnByb3RvdHlwZSA9IHtcclxuXHJcblx0cmVnaXN0ZXI6IGZ1bmN0aW9uKCBvd25lciwgaW5pdGlhbCApIHtcclxuXHRcdHZhciB2YWx1ZSA9IGluaXRpYWwgfHwge307XHJcblxyXG5cdFx0Ly8gSWYgaXQgaXMgYSBub2RlIHVubGlrZWx5IHRvIGJlIHN0cmluZ2lmeS1lZCBvciBsb29wZWQgb3ZlclxyXG5cdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcclxuXHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XHJcblx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHZhbHVlO1xyXG5cclxuXHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSwgbm9uLXdyaXRhYmxlIHByb3BlcnR5XHJcblx0XHQvLyBjb25maWd1cmFiaWxpdHkgbXVzdCBiZSB0cnVlIHRvIGFsbG93IHRoZSBwcm9wZXJ0eSB0byBiZVxyXG5cdFx0Ly8gZGVsZXRlZCB3aXRoIHRoZSBkZWxldGUgb3BlcmF0b3JcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggb3duZXIsIHRoaXMuZXhwYW5kbywge1xyXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZSxcclxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZSxcclxuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcclxuXHR9LFxyXG5cdGNhY2hlOiBmdW5jdGlvbiggb3duZXIgKSB7XHJcblxyXG5cdFx0Ly8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsXHJcblx0XHQvLyBidXQgd2Ugc2hvdWxkIG5vdCwgc2VlICM4MzM1LlxyXG5cdFx0Ly8gQWx3YXlzIHJldHVybiBhbiBlbXB0eSBvYmplY3QuXHJcblx0XHRpZiAoICFhY2NlcHREYXRhKCBvd25lciApICkge1xyXG5cdFx0XHRyZXR1cm4ge307XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlXHJcblx0XHR2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XHJcblxyXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXHJcblx0XHRpZiAoICF2YWx1ZSApIHtcclxuXHRcdFx0dmFsdWUgPSB7fTtcclxuXHJcblx0XHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxyXG5cdFx0XHQvLyBidXQgd2Ugc2hvdWxkIG5vdCwgc2VlICM4MzM1LlxyXG5cdFx0XHQvLyBBbHdheXMgcmV0dXJuIGFuIGVtcHR5IG9iamVjdC5cclxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBvd25lciApICkge1xyXG5cclxuXHRcdFx0XHQvLyBJZiBpdCBpcyBhIG5vZGUgdW5saWtlbHkgdG8gYmUgc3RyaW5naWZ5LWVkIG9yIGxvb3BlZCBvdmVyXHJcblx0XHRcdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcclxuXHRcdFx0XHRpZiAoIG93bmVyLm5vZGVUeXBlICkge1xyXG5cdFx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdmFsdWU7XHJcblxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxyXG5cdFx0XHRcdC8vIGNvbmZpZ3VyYWJsZSBtdXN0IGJlIHRydWUgdG8gYWxsb3cgdGhlIHByb3BlcnR5IHRvIGJlXHJcblx0XHRcdFx0Ly8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZFxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIG93bmVyLCB0aGlzLmV4cGFuZG8sIHtcclxuXHRcdFx0XHRcdFx0dmFsdWU6IHZhbHVlLFxyXG5cdFx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcclxuXHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdmFsdWU7XHJcblx0fSxcclxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XHJcblx0XHR2YXIgcHJvcCxcclxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlKCBvd25lciApO1xyXG5cclxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwga2V5LCB2YWx1ZSBdIGFyZ3NcclxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGNhY2hlWyBkYXRhIF0gPSB2YWx1ZTtcclxuXHJcblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb25lLWJ5LW9uZSB0byB0aGUgY2FjaGUgb2JqZWN0XHJcblx0XHRcdGZvciAoIHByb3AgaW4gZGF0YSApIHtcclxuXHRcdFx0XHRjYWNoZVsgcHJvcCBdID0gZGF0YVsgcHJvcCBdO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gY2FjaGU7XHJcblx0fSxcclxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xyXG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cclxuXHRcdFx0dGhpcy5jYWNoZSggb3duZXIgKSA6XHJcblx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSAmJiBvd25lclsgdGhpcy5leHBhbmRvIF1bIGtleSBdO1xyXG5cdH0sXHJcblx0YWNjZXNzOiBmdW5jdGlvbiggb3duZXIsIGtleSwgdmFsdWUgKSB7XHJcblx0XHR2YXIgc3RvcmVkO1xyXG5cclxuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcclxuXHRcdC8vXHJcblx0XHQvLyAgIDEuIE5vIGtleSB3YXMgc3BlY2lmaWVkXHJcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcclxuXHRcdC8vXHJcblx0XHQvLyBUYWtlIHRoZSBcInJlYWRcIiBwYXRoIGFuZCBhbGxvdyB0aGUgZ2V0IG1ldGhvZCB0byBkZXRlcm1pbmVcclxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcclxuXHRcdC8vXHJcblx0XHQvLyAgIDEuIFRoZSBlbnRpcmUgY2FjaGUgb2JqZWN0XHJcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XHJcblx0XHQvL1xyXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fFxyXG5cdFx0XHRcdCggKCBrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSApIHtcclxuXHJcblx0XHRcdHN0b3JlZCA9IHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gc3RvcmVkICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0XHRcdHN0b3JlZCA6IHRoaXMuZ2V0KCBvd25lciwgalF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZVxyXG5cdFx0Ly8gYXJlIHNwZWNpZmllZCwgc2V0IG9yIGV4dGVuZCAoZXhpc3Rpbmcgb2JqZWN0cykgd2l0aCBlaXRoZXI6XHJcblx0XHQvL1xyXG5cdFx0Ly8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllc1xyXG5cdFx0Ly8gICAyLiBBIGtleSBhbmQgdmFsdWVcclxuXHRcdC8vXHJcblx0XHR0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTtcclxuXHJcblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcclxuXHRcdC8vIHJldHVybiB0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXVxyXG5cdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IGtleTtcclxuXHR9LFxyXG5cdHJlbW92ZTogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XHJcblx0XHR2YXIgaSwgbmFtZSwgY2FtZWwsXHJcblx0XHRcdGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xyXG5cclxuXHRcdGlmICggY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHRoaXMucmVnaXN0ZXIoIG93bmVyICk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzXHJcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIGtleSApICkge1xyXG5cclxuXHRcdFx0XHQvLyBJZiBcIm5hbWVcIiBpcyBhbiBhcnJheSBvZiBrZXlzLi4uXHJcblx0XHRcdFx0Ly8gV2hlbiBkYXRhIGlzIGluaXRpYWxseSBjcmVhdGVkLCB2aWEgKFwia2V5XCIsIFwidmFsXCIpIHNpZ25hdHVyZSxcclxuXHRcdFx0XHQvLyBrZXlzIHdpbGwgYmUgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cclxuXHRcdFx0XHQvLyBTaW5jZSB0aGVyZSBpcyBubyB3YXkgdG8gdGVsbCBfaG93XyBhIGtleSB3YXMgYWRkZWQsIHJlbW92ZVxyXG5cdFx0XHRcdC8vIGJvdGggcGxhaW4ga2V5IGFuZCBjYW1lbENhc2Uga2V5LiAjMTI3ODZcclxuXHRcdFx0XHQvLyBUaGlzIHdpbGwgb25seSBwZW5hbGl6ZSB0aGUgYXJyYXkgYXJndW1lbnQgcGF0aC5cclxuXHRcdFx0XHRuYW1lID0ga2V5LmNvbmNhdCgga2V5Lm1hcCggalF1ZXJ5LmNhbWVsQ2FzZSApICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y2FtZWwgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcclxuXHJcblx0XHRcdFx0Ly8gVHJ5IHRoZSBzdHJpbmcgYXMgYSBrZXkgYmVmb3JlIGFueSBtYW5pcHVsYXRpb25cclxuXHRcdFx0XHRpZiAoIGtleSBpbiBjYWNoZSApIHtcclxuXHRcdFx0XHRcdG5hbWUgPSBbIGtleSwgY2FtZWwgXTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cclxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlXHJcblx0XHRcdFx0XHRuYW1lID0gY2FtZWw7XHJcblx0XHRcdFx0XHRuYW1lID0gbmFtZSBpbiBjYWNoZSA/XHJcblx0XHRcdFx0XHRcdFsgbmFtZSBdIDogKCBuYW1lLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aSA9IG5hbWUubGVuZ3RoO1xyXG5cclxuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBuYW1lWyBpIF0gXTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiB0aGVyZSdzIG5vIG1vcmUgZGF0YVxyXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fCBqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKSApIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PSAzNS00NStcclxuXHRcdFx0Ly8gV2Via2l0ICYgQmxpbmsgcGVyZm9ybWFuY2Ugc3VmZmVycyB3aGVuIGRlbGV0aW5nIHByb3BlcnRpZXNcclxuXHRcdFx0Ly8gZnJvbSBET00gbm9kZXMsIHNvIHNldCB0byB1bmRlZmluZWQgaW5zdGVhZFxyXG5cdFx0XHQvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzc4NjA3XHJcblx0XHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XHJcblx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGRlbGV0ZSBvd25lclsgdGhpcy5leHBhbmRvIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcclxuXHRcdHZhciBjYWNoZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcclxuXHRcdHJldHVybiBjYWNoZSAhPT0gdW5kZWZpbmVkICYmICFqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKTtcclxuXHR9XHJcbn07XHJcbnZhciBkYXRhUHJpdiA9IG5ldyBEYXRhKCk7XHJcblxyXG52YXIgZGF0YVVzZXIgPSBuZXcgRGF0YSgpO1xyXG5cclxuXHJcblxyXG4vL1x0SW1wbGVtZW50YXRpb24gU3VtbWFyeVxyXG4vL1xyXG4vL1x0MS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaFxyXG4vL1x0Mi4gSW1wcm92ZSB0aGUgbW9kdWxlJ3MgbWFpbnRhaW5hYmlsaXR5IGJ5IHJlZHVjaW5nIHRoZSBzdG9yYWdlXHJcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cclxuLy9cdDMuIFVzZSB0aGUgc2FtZSBzaW5nbGUgbWVjaGFuaXNtIHRvIHN1cHBvcnQgXCJwcml2YXRlXCIgYW5kIFwidXNlclwiIGRhdGEuXHJcbi8vXHQ0LiBfTmV2ZXJfIGV4cG9zZSBcInByaXZhdGVcIiBkYXRhIHRvIHVzZXIgY29kZSAoVE9ETzogRHJvcCBfZGF0YSwgX3JlbW92ZURhdGEpXHJcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcclxuLy9cdDYuIFByb3ZpZGUgYSBjbGVhciBwYXRoIGZvciBpbXBsZW1lbnRhdGlvbiB1cGdyYWRlIHRvIFdlYWtNYXAgaW4gMjAxNFxyXG5cclxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcclxuXHRybXVsdGlEYXNoID0gL1tBLVpdL2c7XHJcblxyXG5mdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkge1xyXG5cdHZhciBuYW1lO1xyXG5cclxuXHQvLyBJZiBub3RoaW5nIHdhcyBmb3VuZCBpbnRlcm5hbGx5LCB0cnkgdG8gZmV0Y2ggYW55XHJcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXHJcblx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdG5hbWUgPSBcImRhdGEtXCIgKyBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcclxuXHJcblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdGRhdGEgPSBkYXRhID09PSBcInRydWVcIiA/IHRydWUgOlxyXG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJmYWxzZVwiID8gZmFsc2UgOlxyXG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJudWxsXCIgPyBudWxsIDpcclxuXHJcblx0XHRcdFx0XHQvLyBPbmx5IGNvbnZlcnQgdG8gYSBudW1iZXIgaWYgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIHN0cmluZ1xyXG5cdFx0XHRcdFx0K2RhdGEgKyBcIlwiID09PSBkYXRhID8gK2RhdGEgOlxyXG5cdFx0XHRcdFx0cmJyYWNlLnRlc3QoIGRhdGEgKSA/IGpRdWVyeS5wYXJzZUpTT04oIGRhdGEgKSA6XHJcblx0XHRcdFx0XHRkYXRhO1xyXG5cdFx0XHR9IGNhdGNoICggZSApIHt9XHJcblxyXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcclxuXHRcdFx0ZGF0YVVzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBkYXRhO1xyXG59XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0aGFzRGF0YTogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gZGF0YVVzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKTtcclxuXHR9LFxyXG5cclxuXHRkYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcclxuXHRcdHJldHVybiBkYXRhVXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcclxuXHR9LFxyXG5cclxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdGRhdGFVc2VyLnJlbW92ZSggZWxlbSwgbmFtZSApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFRPRE86IE5vdyB0aGF0IGFsbCBjYWxscyB0byBfZGF0YSBhbmQgX3JlbW92ZURhdGEgaGF2ZSBiZWVuIHJlcGxhY2VkXHJcblx0Ly8gd2l0aCBkaXJlY3QgY2FsbHMgdG8gZGF0YVByaXYgbWV0aG9kcywgdGhlc2UgY2FuIGJlIGRlcHJlY2F0ZWQuXHJcblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xyXG5cdFx0cmV0dXJuIGRhdGFQcml2LmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xyXG5cdH0sXHJcblxyXG5cdF9yZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgbmFtZSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGRhdGE6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xyXG5cdFx0dmFyIGksIG5hbWUsIGRhdGEsXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXHJcblx0XHRcdGF0dHJzID0gZWxlbSAmJiBlbGVtLmF0dHJpYnV0ZXM7XHJcblxyXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXHJcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xyXG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTtcclxuXHJcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhUHJpdi5nZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIgKSApIHtcclxuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTErXHJcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxyXG5cdFx0XHRcdFx0XHRpZiAoIGF0dHJzWyBpIF0gKSB7XHJcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZS5zbGljZSggNSApICk7XHJcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBkYXRhO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNldHMgbXVsdGlwbGUgdmFsdWVzXHJcblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwib2JqZWN0XCIgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5ICk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdHZhciBkYXRhLCBjYW1lbEtleTtcclxuXHJcblx0XHRcdC8vIFRoZSBjYWxsaW5nIGpRdWVyeSBvYmplY3QgKGVsZW1lbnQgbWF0Y2hlcykgaXMgbm90IGVtcHR5XHJcblx0XHRcdC8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlXHJcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XHJcblx0XHRcdC8vIHdpbGwgcmVzdWx0IGluIGB1bmRlZmluZWRgIGZvciBlbGVtID0gdGhpc1sgMCBdIHdoaWNoIHdpbGxcclxuXHRcdFx0Ly8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS5cclxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XHJcblxyXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcclxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgYXMtaXNcclxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKSB8fFxyXG5cclxuXHRcdFx0XHRcdC8vIFRyeSB0byBmaW5kIGRhc2hlZCBrZXkgaWYgaXQgZXhpc3RzIChnaC0yNzc5KVxyXG5cdFx0XHRcdFx0Ly8gVGhpcyBpcyBmb3IgMi4yLnggb25seVxyXG5cdFx0XHRcdFx0ZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCkgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGNhbWVsS2V5ID0galF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICk7XHJcblxyXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcclxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgY2FtZWxpemVkXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFVc2VyLmdldCggZWxlbSwgY2FtZWxLZXkgKTtcclxuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBcImRpc2NvdmVyXCIgdGhlIGRhdGEgaW5cclxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFBdHRyKCBlbGVtLCBjYW1lbEtleSwgdW5kZWZpbmVkICk7XHJcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFdlIHRyaWVkIHJlYWxseSBoYXJkLCBidXQgdGhlIGRhdGEgZG9lc24ndCBleGlzdC5cclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxyXG5cdFx0XHRjYW1lbEtleSA9IGpRdWVyeS5jYW1lbENhc2UoIGtleSApO1xyXG5cdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHQvLyBGaXJzdCwgYXR0ZW1wdCB0byBzdG9yZSBhIGNvcHkgb3IgcmVmZXJlbmNlIG9mIGFueVxyXG5cdFx0XHRcdC8vIGRhdGEgdGhhdCBtaWdodCd2ZSBiZWVuIHN0b3JlIHdpdGggYSBjYW1lbENhc2VkIGtleS5cclxuXHRcdFx0XHR2YXIgZGF0YSA9IGRhdGFVc2VyLmdldCggdGhpcywgY2FtZWxLZXkgKTtcclxuXHJcblx0XHRcdFx0Ly8gRm9yIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGUgaW50ZXJvcCwgd2UgaGF2ZSB0b1xyXG5cdFx0XHRcdC8vIHN0b3JlIHByb3BlcnR5IG5hbWVzIHdpdGggZGFzaGVzIGluIGEgY2FtZWxDYXNlIGZvcm0uXHJcblx0XHRcdFx0Ly8gVGhpcyBtaWdodCBub3QgYXBwbHkgdG8gYWxsIHByb3BlcnRpZXMuLi4qXHJcblx0XHRcdFx0ZGF0YVVzZXIuc2V0KCB0aGlzLCBjYW1lbEtleSwgdmFsdWUgKTtcclxuXHJcblx0XHRcdFx0Ly8gKi4uLiBJbiB0aGUgY2FzZSBvZiBwcm9wZXJ0aWVzIHRoYXQgbWlnaHQgX2FjdHVhbGx5X1xyXG5cdFx0XHRcdC8vIGhhdmUgZGFzaGVzLCB3ZSBuZWVkIHRvIGFsc28gc3RvcmUgYSBjb3B5IG9mIHRoYXRcclxuXHRcdFx0XHQvLyB1bmNoYW5nZWQgcHJvcGVydHkuXHJcblx0XHRcdFx0aWYgKCBrZXkuaW5kZXhPZiggXCItXCIgKSA+IC0xICYmIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxLCBudWxsLCB0cnVlICk7XHJcblx0fSxcclxuXHJcblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGtleSApIHtcclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbmpRdWVyeS5leHRlbmQoIHtcclxuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XHJcblx0XHR2YXIgcXVldWU7XHJcblxyXG5cdFx0aWYgKCBlbGVtICkge1xyXG5cdFx0XHR0eXBlID0gKCB0eXBlIHx8IFwiZnhcIiApICsgXCJxdWV1ZVwiO1xyXG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xyXG5cclxuXHRcdFx0Ly8gU3BlZWQgdXAgZGVxdWV1ZSBieSBnZXR0aW5nIG91dCBxdWlja2x5IGlmIHRoaXMgaXMganVzdCBhIGxvb2t1cFxyXG5cdFx0XHRpZiAoIGRhdGEgKSB7XHJcblx0XHRcdFx0aWYgKCAhcXVldWUgfHwgalF1ZXJ5LmlzQXJyYXkoIGRhdGEgKSApIHtcclxuXHRcdFx0XHRcdHF1ZXVlID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KCBkYXRhICkgKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XHJcblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XHJcblxyXG5cdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksXHJcblx0XHRcdHN0YXJ0TGVuZ3RoID0gcXVldWUubGVuZ3RoLFxyXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXHJcblx0XHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksXHJcblx0XHRcdG5leHQgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcclxuXHRcdGlmICggZm4gPT09IFwiaW5wcm9ncmVzc1wiICkge1xyXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCk7XHJcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBmbiApIHtcclxuXHJcblx0XHRcdC8vIEFkZCBhIHByb2dyZXNzIHNlbnRpbmVsIHRvIHByZXZlbnQgdGhlIGZ4IHF1ZXVlIGZyb20gYmVpbmdcclxuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxyXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiApIHtcclxuXHRcdFx0XHRxdWV1ZS51bnNoaWZ0KCBcImlucHJvZ3Jlc3NcIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBDbGVhciB1cCB0aGUgbGFzdCBxdWV1ZSBzdG9wIGZ1bmN0aW9uXHJcblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xyXG5cdFx0XHRmbi5jYWxsKCBlbGVtLCBuZXh0LCBob29rcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggIXN0YXJ0TGVuZ3RoICYmIGhvb2tzICkge1xyXG5cdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcclxuXHRfcXVldWVIb29rczogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XHJcblx0XHR2YXIga2V5ID0gdHlwZSArIFwicXVldWVIb29rc1wiO1xyXG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcclxuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLmFkZCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBbIHR5cGUgKyBcInF1ZXVlXCIsIGtleSBdICk7XHJcblx0XHRcdH0gKVxyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcclxuXHRcdHZhciBzZXR0ZXIgPSAyO1xyXG5cclxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGRhdGEgPSB0eXBlO1xyXG5cdFx0XHR0eXBlID0gXCJmeFwiO1xyXG5cdFx0XHRzZXR0ZXItLTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XHJcblx0XHRcdHJldHVybiBqUXVlcnkucXVldWUoIHRoaXNbIDAgXSwgdHlwZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBkYXRhID09PSB1bmRlZmluZWQgP1xyXG5cdFx0XHR0aGlzIDpcclxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTtcclxuXHJcblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcclxuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIHRoaXMsIHR5cGUgKTtcclxuXHJcblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XHJcblx0XHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdH0sXHJcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cdGNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGVcclxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcclxuXHRwcm9taXNlOiBmdW5jdGlvbiggdHlwZSwgb2JqICkge1xyXG5cdFx0dmFyIHRtcCxcclxuXHRcdFx0Y291bnQgPSAxLFxyXG5cdFx0XHRkZWZlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxyXG5cdFx0XHRlbGVtZW50cyA9IHRoaXMsXHJcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0cmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggISggLS1jb3VudCApICkge1xyXG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH07XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdFx0b2JqID0gdHlwZTtcclxuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcclxuXHJcblx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0dG1wID0gZGF0YVByaXYuZ2V0KCBlbGVtZW50c1sgaSBdLCB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgKTtcclxuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xyXG5cdFx0XHRcdGNvdW50Kys7XHJcblx0XHRcdFx0dG1wLmVtcHR5LmFkZCggcmVzb2x2ZSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXNvbHZlKCk7XHJcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XHJcblx0fVxyXG59ICk7XHJcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcclxuXHJcbnZhciByY3NzTnVtID0gbmV3IFJlZ0V4cCggXCJeKD86KFsrLV0pPXwpKFwiICsgcG51bSArIFwiKShbYS16JV0qKSRcIiwgXCJpXCIgKTtcclxuXHJcblxyXG52YXIgY3NzRXhwYW5kID0gWyBcIlRvcFwiLCBcIlJpZ2h0XCIsIFwiQm90dG9tXCIsIFwiTGVmdFwiIF07XHJcblxyXG52YXIgaXNIaWRkZW4gPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7XHJcblxyXG5cdFx0Ly8gaXNIaWRkZW4gbWlnaHQgYmUgY2FsbGVkIGZyb20galF1ZXJ5I2ZpbHRlciBmdW5jdGlvbjtcclxuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxyXG5cdFx0ZWxlbSA9IGVsIHx8IGVsZW07XHJcblx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCIgfHxcclxuXHRcdFx0IWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XHJcblx0fTtcclxuXHJcblxyXG5cclxuZnVuY3Rpb24gYWRqdXN0Q1NTKCBlbGVtLCBwcm9wLCB2YWx1ZVBhcnRzLCB0d2VlbiApIHtcclxuXHR2YXIgYWRqdXN0ZWQsXHJcblx0XHRzY2FsZSA9IDEsXHJcblx0XHRtYXhJdGVyYXRpb25zID0gMjAsXHJcblx0XHRjdXJyZW50VmFsdWUgPSB0d2VlbiA/XHJcblx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHdlZW4uY3VyKCk7IH0gOlxyXG5cdFx0XHRmdW5jdGlvbigpIHsgcmV0dXJuIGpRdWVyeS5jc3MoIGVsZW0sIHByb3AsIFwiXCIgKTsgfSxcclxuXHRcdGluaXRpYWwgPSBjdXJyZW50VmFsdWUoKSxcclxuXHRcdHVuaXQgPSB2YWx1ZVBhcnRzICYmIHZhbHVlUGFydHNbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKSxcclxuXHJcblx0XHQvLyBTdGFydGluZyB2YWx1ZSBjb21wdXRhdGlvbiBpcyByZXF1aXJlZCBmb3IgcG90ZW50aWFsIHVuaXQgbWlzbWF0Y2hlc1xyXG5cdFx0aW5pdGlhbEluVW5pdCA9ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdIHx8IHVuaXQgIT09IFwicHhcIiAmJiAraW5pdGlhbCApICYmXHJcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XHJcblxyXG5cdGlmICggaW5pdGlhbEluVW5pdCAmJiBpbml0aWFsSW5Vbml0WyAzIF0gIT09IHVuaXQgKSB7XHJcblxyXG5cdFx0Ly8gVHJ1c3QgdW5pdHMgcmVwb3J0ZWQgYnkgalF1ZXJ5LmNzc1xyXG5cdFx0dW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdO1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSB3ZSB1cGRhdGUgdGhlIHR3ZWVuIHByb3BlcnRpZXMgbGF0ZXIgb25cclxuXHRcdHZhbHVlUGFydHMgPSB2YWx1ZVBhcnRzIHx8IFtdO1xyXG5cclxuXHRcdC8vIEl0ZXJhdGl2ZWx5IGFwcHJveGltYXRlIGZyb20gYSBub256ZXJvIHN0YXJ0aW5nIHBvaW50XHJcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWwgfHwgMTtcclxuXHJcblx0XHRkbyB7XHJcblxyXG5cdFx0XHQvLyBJZiBwcmV2aW91cyBpdGVyYXRpb24gemVyb2VkIG91dCwgZG91YmxlIHVudGlsIHdlIGdldCAqc29tZXRoaW5nKi5cclxuXHRcdFx0Ly8gVXNlIHN0cmluZyBmb3IgZG91Ymxpbmcgc28gd2UgZG9uJ3QgYWNjaWRlbnRhbGx5IHNlZSBzY2FsZSBhcyB1bmNoYW5nZWQgYmVsb3dcclxuXHRcdFx0c2NhbGUgPSBzY2FsZSB8fCBcIi41XCI7XHJcblxyXG5cdFx0XHQvLyBBZGp1c3QgYW5kIGFwcGx5XHJcblx0XHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0IC8gc2NhbGU7XHJcblx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTtcclxuXHJcblx0XHQvLyBVcGRhdGUgc2NhbGUsIHRvbGVyYXRpbmcgemVybyBvciBOYU4gZnJvbSB0d2Vlbi5jdXIoKVxyXG5cdFx0Ly8gQnJlYWsgdGhlIGxvb3AgaWYgc2NhbGUgaXMgdW5jaGFuZ2VkIG9yIHBlcmZlY3QsIG9yIGlmIHdlJ3ZlIGp1c3QgaGFkIGVub3VnaC5cclxuXHRcdH0gd2hpbGUgKFxyXG5cdFx0XHRzY2FsZSAhPT0gKCBzY2FsZSA9IGN1cnJlbnRWYWx1ZSgpIC8gaW5pdGlhbCApICYmIHNjYWxlICE9PSAxICYmIC0tbWF4SXRlcmF0aW9uc1xyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdGlmICggdmFsdWVQYXJ0cyApIHtcclxuXHRcdGluaXRpYWxJblVuaXQgPSAraW5pdGlhbEluVW5pdCB8fCAraW5pdGlhbCB8fCAwO1xyXG5cclxuXHRcdC8vIEFwcGx5IHJlbGF0aXZlIG9mZnNldCAoKz0vLT0pIGlmIHNwZWNpZmllZFxyXG5cdFx0YWRqdXN0ZWQgPSB2YWx1ZVBhcnRzWyAxIF0gP1xyXG5cdFx0XHRpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOlxyXG5cdFx0XHQrdmFsdWVQYXJ0c1sgMiBdO1xyXG5cdFx0aWYgKCB0d2VlbiApIHtcclxuXHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XHJcblx0XHRcdHR3ZWVuLnN0YXJ0ID0gaW5pdGlhbEluVW5pdDtcclxuXHRcdFx0dHdlZW4uZW5kID0gYWRqdXN0ZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBhZGp1c3RlZDtcclxufVxyXG52YXIgcmNoZWNrYWJsZVR5cGUgPSAoIC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pICk7XHJcblxyXG52YXIgcnRhZ05hbWUgPSAoIC88KFtcXHc6LV0rKS8gKTtcclxuXHJcbnZhciByc2NyaXB0VHlwZSA9ICggL14kfFxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSApO1xyXG5cclxuXHJcblxyXG4vLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxyXG52YXIgd3JhcE1hcCA9IHtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5XHJcblx0b3B0aW9uOiBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF0sXHJcblxyXG5cdC8vIFhIVE1MIHBhcnNlcnMgZG8gbm90IG1hZ2ljYWxseSBpbnNlcnQgZWxlbWVudHMgaW4gdGhlXHJcblx0Ly8gc2FtZSB3YXkgdGhhdCB0YWcgc291cCBwYXJzZXJzIGRvLiBTbyB3ZSBjYW5ub3Qgc2hvcnRlblxyXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cclxuXHR0aGVhZDogWyAxLCBcIjx0YWJsZT5cIiwgXCI8L3RhYmxlPlwiIF0sXHJcblx0Y29sOiBbIDIsIFwiPHRhYmxlPjxjb2xncm91cD5cIiwgXCI8L2NvbGdyb3VwPjwvdGFibGU+XCIgXSxcclxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXHJcblx0dGQ6IFsgMywgXCI8dGFibGU+PHRib2R5Pjx0cj5cIiwgXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIiBdLFxyXG5cclxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cclxufTtcclxuXHJcbi8vIFN1cHBvcnQ6IElFOVxyXG53cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247XHJcblxyXG53cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkO1xyXG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5LTExK1xyXG5cdC8vIFVzZSB0eXBlb2YgdG8gYXZvaWQgemVyby1hcmd1bWVudCBtZXRob2QgaW52b2NhdGlvbiBvbiBob3N0IG9iamVjdHMgKCMxNTE1MSlcclxuXHR2YXIgcmV0ID0gdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgP1xyXG5cdFx0XHRjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKSA6XHJcblx0XHRcdHR5cGVvZiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgP1xyXG5cdFx0XHRcdGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnIHx8IFwiKlwiICkgOlxyXG5cdFx0XHRbXTtcclxuXHJcblx0cmV0dXJuIHRhZyA9PT0gdW5kZWZpbmVkIHx8IHRhZyAmJiBqUXVlcnkubm9kZU5hbWUoIGNvbnRleHQsIHRhZyApID9cclxuXHRcdGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApIDpcclxuXHRcdHJldDtcclxufVxyXG5cclxuXHJcbi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZFxyXG5mdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7XHJcblx0dmFyIGkgPSAwLFxyXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0ZGF0YVByaXYuc2V0KFxyXG5cdFx0XHRlbGVtc1sgaSBdLFxyXG5cdFx0XHRcImdsb2JhbEV2YWxcIixcclxuXHRcdFx0IXJlZkVsZW1lbnRzIHx8IGRhdGFQcml2LmdldCggcmVmRWxlbWVudHNbIGkgXSwgXCJnbG9iYWxFdmFsXCIgKVxyXG5cdFx0KTtcclxuXHR9XHJcbn1cclxuXHJcblxyXG52YXIgcmh0bWwgPSAvPHwmIz9cXHcrOy87XHJcblxyXG5mdW5jdGlvbiBidWlsZEZyYWdtZW50KCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uLCBpZ25vcmVkICkge1xyXG5cdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgY29udGFpbnMsIGosXHJcblx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxyXG5cdFx0bm9kZXMgPSBbXSxcclxuXHRcdGkgPSAwLFxyXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1zWyBpIF07XHJcblxyXG5cdFx0aWYgKCBlbGVtIHx8IGVsZW0gPT09IDAgKSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcclxuXHRcdFx0aWYgKCBqUXVlcnkudHlwZSggZWxlbSApID09PSBcIm9iamVjdFwiICkge1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBub24taHRtbCBpbnRvIGEgdGV4dCBub2RlXHJcblx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XHJcblx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XHJcblxyXG5cdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0bXAgPSB0bXAgfHwgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGNvbnRleHQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XHJcblxyXG5cdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cclxuXHRcdFx0XHR0YWcgPSAoIHJ0YWdOYW1lLmV4ZWMoIGVsZW0gKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcclxuXHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgalF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIGVsZW0gKSArIHdyYXBbIDIgXTtcclxuXHJcblx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XHJcblx0XHRcdFx0aiA9IHdyYXBbIDAgXTtcclxuXHRcdFx0XHR3aGlsZSAoIGotLSApIHtcclxuXHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgdG1wLmNoaWxkTm9kZXMgKTtcclxuXHJcblx0XHRcdFx0Ly8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXJcclxuXHRcdFx0XHR0bXAgPSBmcmFnbWVudC5maXJzdENoaWxkO1xyXG5cclxuXHRcdFx0XHQvLyBFbnN1cmUgdGhlIGNyZWF0ZWQgbm9kZXMgYXJlIG9ycGhhbmVkICgjMTIzOTIpXHJcblx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxyXG5cdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcclxuXHJcblx0aSA9IDA7XHJcblx0d2hpbGUgKCAoIGVsZW0gPSBub2Rlc1sgaSsrIF0gKSApIHtcclxuXHJcblx0XHQvLyBTa2lwIGVsZW1lbnRzIGFscmVhZHkgaW4gdGhlIGNvbnRleHQgY29sbGVjdGlvbiAodHJhYy00MDg3KVxyXG5cdFx0aWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApID4gLTEgKSB7XHJcblx0XHRcdGlmICggaWdub3JlZCApIHtcclxuXHRcdFx0XHRpZ25vcmVkLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjb250aW51ZTtcclxuXHRcdH1cclxuXHJcblx0XHRjb250YWlucyA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XHJcblxyXG5cdFx0Ly8gQXBwZW5kIHRvIGZyYWdtZW50XHJcblx0XHR0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksIFwic2NyaXB0XCIgKTtcclxuXHJcblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XHJcblx0XHRpZiAoIGNvbnRhaW5zICkge1xyXG5cdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDYXB0dXJlIGV4ZWN1dGFibGVzXHJcblx0XHRpZiAoIHNjcmlwdHMgKSB7XHJcblx0XHRcdGogPSAwO1xyXG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRtcFsgaisrIF0gKSApIHtcclxuXHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIGVsZW0udHlwZSB8fCBcIlwiICkgKSB7XHJcblx0XHRcdFx0XHRzY3JpcHRzLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBmcmFnbWVudDtcclxufVxyXG5cclxuXHJcbiggZnVuY3Rpb24oKSB7XHJcblx0dmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxyXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxyXG5cdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAtNC4zLCBTYWZhcmk8PTUuMVxyXG5cdC8vIENoZWNrIHN0YXRlIGxvc3QgaWYgdGhlIG5hbWUgaXMgc2V0ICgjMTEyMTcpXHJcblx0Ly8gU3VwcG9ydDogV2luZG93cyBXZWIgQXBwcyAoV1dBKVxyXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxyXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xyXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJjaGVja2VkXCIsIFwiY2hlY2tlZFwiICk7XHJcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcclxuXHJcblx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBTYWZhcmk8PTUuMSwgQW5kcm9pZDw0LjJcclxuXHQvLyBPbGRlciBXZWJLaXQgZG9lc24ndCBjbG9uZSBjaGVja2VkIHN0YXRlIGNvcnJlY3RseSBpbiBmcmFnbWVudHNcclxuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFPD0xMStcclxuXHQvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZFxyXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcclxuXHRzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkID0gISFkaXYuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZTtcclxufSApKCk7XHJcblxyXG5cclxudmFyXHJcblx0cmtleUV2ZW50ID0gL15rZXkvLFxyXG5cdHJtb3VzZUV2ZW50ID0gL14oPzptb3VzZXxwb2ludGVyfGNvbnRleHRtZW51fGRyYWd8ZHJvcCl8Y2xpY2svLFxyXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpLztcclxuXHJcbmZ1bmN0aW9uIHJldHVyblRydWUoKSB7XHJcblx0cmV0dXJuIHRydWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xyXG5cdHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuLy8gU3VwcG9ydDogSUU5XHJcbi8vIFNlZSAjMTMzOTMgZm9yIG1vcmUgaW5mb1xyXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcclxuXHR0cnkge1xyXG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XHJcblx0fSBjYXRjaCAoIGVyciApIHsgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBvbiggZWxlbSwgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgb25lICkge1xyXG5cdHZhciBvcmlnRm4sIHR5cGU7XHJcblxyXG5cdC8vIFR5cGVzIGNhbiBiZSBhIG1hcCBvZiB0eXBlcy9oYW5kbGVyc1xyXG5cdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xyXG5cclxuXHRcdC8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApXHJcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBkYXRhIClcclxuXHRcdFx0ZGF0YSA9IGRhdGEgfHwgc2VsZWN0b3I7XHJcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcclxuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBlbGVtO1xyXG5cdH1cclxuXHJcblx0aWYgKCBkYXRhID09IG51bGwgJiYgZm4gPT0gbnVsbCApIHtcclxuXHJcblx0XHQvLyAoIHR5cGVzLCBmbiApXHJcblx0XHRmbiA9IHNlbGVjdG9yO1xyXG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xyXG5cdH0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7XHJcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMsIHNlbGVjdG9yLCBmbiApXHJcblx0XHRcdGZuID0gZGF0YTtcclxuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXHJcblx0XHRcdGZuID0gZGF0YTtcclxuXHRcdFx0ZGF0YSA9IHNlbGVjdG9yO1xyXG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XHJcblx0XHRmbiA9IHJldHVybkZhbHNlO1xyXG5cdH0gZWxzZSBpZiAoICFmbiApIHtcclxuXHRcdHJldHVybiBlbGVtO1xyXG5cdH1cclxuXHJcblx0aWYgKCBvbmUgPT09IDEgKSB7XHJcblx0XHRvcmlnRm4gPSBmbjtcclxuXHRcdGZuID0gZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdFx0Ly8gQ2FuIHVzZSBhbiBlbXB0eSBzZXQsIHNpbmNlIGV2ZW50IGNvbnRhaW5zIHRoZSBpbmZvXHJcblx0XHRcdGpRdWVyeSgpLm9mZiggZXZlbnQgKTtcclxuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXHJcblx0XHRmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTtcclxuXHR9XHJcblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlcywgZm4sIGRhdGEsIHNlbGVjdG9yICk7XHJcblx0fSApO1xyXG59XHJcblxyXG4vKlxyXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXHJcbiAqIFByb3BzIHRvIERlYW4gRWR3YXJkcycgYWRkRXZlbnQgbGlicmFyeSBmb3IgbWFueSBvZiB0aGUgaWRlYXMuXHJcbiAqL1xyXG5qUXVlcnkuZXZlbnQgPSB7XHJcblxyXG5cdGdsb2JhbDoge30sXHJcblxyXG5cdGFkZDogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBkYXRhLCBzZWxlY3RvciApIHtcclxuXHJcblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXHJcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxyXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXHJcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XHJcblxyXG5cdFx0Ly8gRG9uJ3QgYXR0YWNoIGV2ZW50cyB0byBub0RhdGEgb3IgdGV4dC9jb21tZW50IG5vZGVzIChidXQgYWxsb3cgcGxhaW4gb2JqZWN0cylcclxuXHRcdGlmICggIWVsZW1EYXRhICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGFuIG9iamVjdCBvZiBjdXN0b20gZGF0YSBpbiBsaWV1IG9mIHRoZSBoYW5kbGVyXHJcblx0XHRpZiAoIGhhbmRsZXIuaGFuZGxlciApIHtcclxuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xyXG5cdFx0XHRoYW5kbGVyID0gaGFuZGxlT2JqSW4uaGFuZGxlcjtcclxuXHRcdFx0c2VsZWN0b3IgPSBoYW5kbGVPYmpJbi5zZWxlY3RvcjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgaGFuZGxlciBoYXMgYSB1bmlxdWUgSUQsIHVzZWQgdG8gZmluZC9yZW1vdmUgaXQgbGF0ZXJcclxuXHRcdGlmICggIWhhbmRsZXIuZ3VpZCApIHtcclxuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XHJcblx0XHRpZiAoICEoIGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyApICkge1xyXG5cdFx0XHRldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgPSB7fTtcclxuXHRcdH1cclxuXHRcdGlmICggISggZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgKSApIHtcclxuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcclxuXHJcblx0XHRcdFx0Ly8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmRcclxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXHJcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IFwidW5kZWZpbmVkXCIgJiYgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCAhPT0gZS50eXBlID9cclxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxyXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XHJcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCB0LS0gKSB7XHJcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzWyB0IF0gKSB8fCBbXTtcclxuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XHJcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XHJcblxyXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcclxuXHRcdFx0aWYgKCAhdHlwZSApIHtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlXHJcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xyXG5cclxuXHRcdFx0Ly8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlXHJcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcclxuXHJcblx0XHRcdC8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGVcclxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XHJcblxyXG5cdFx0XHQvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVyc1xyXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7XHJcblx0XHRcdFx0dHlwZTogdHlwZSxcclxuXHRcdFx0XHRvcmlnVHlwZTogb3JpZ1R5cGUsXHJcblx0XHRcdFx0ZGF0YTogZGF0YSxcclxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxyXG5cdFx0XHRcdGd1aWQ6IGhhbmRsZXIuZ3VpZCxcclxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXHJcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcclxuXHRcdFx0XHRuYW1lc3BhY2U6IG5hbWVzcGFjZXMuam9pbiggXCIuXCIgKVxyXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xyXG5cclxuXHRcdFx0Ly8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZSBpZiB3ZSdyZSB0aGUgZmlyc3RcclxuXHRcdFx0aWYgKCAhKCBoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdICkgKSB7XHJcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xyXG5cdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwO1xyXG5cclxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2VcclxuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnNldHVwIHx8XHJcblx0XHRcdFx0XHRzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xyXG5cclxuXHRcdFx0XHRcdGlmICggZWxlbS5hZGRFdmVudExpc3RlbmVyICkge1xyXG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIHNwZWNpYWwuYWRkICkge1xyXG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xyXG5cclxuXHRcdFx0XHRpZiAoICFoYW5kbGVPYmouaGFuZGxlci5ndWlkICkge1xyXG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEFkZCB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdCwgZGVsZWdhdGVzIGluIGZyb250XHJcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XHJcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIGV2ZW50cyBoYXZlIGV2ZXIgYmVlbiB1c2VkLCBmb3IgZXZlbnQgb3B0aW1pemF0aW9uXHJcblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XHJcblx0XHR9XHJcblxyXG5cdH0sXHJcblxyXG5cdC8vIERldGFjaCBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzIGZyb20gYW4gZWxlbWVudFxyXG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XHJcblxyXG5cdFx0dmFyIGosIG9yaWdDb3VudCwgdG1wLFxyXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcclxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxyXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKSAmJiBkYXRhUHJpdi5nZXQoIGVsZW0gKTtcclxuXHJcblx0XHRpZiAoICFlbGVtRGF0YSB8fCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcclxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFsgXCJcIiBdO1xyXG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcclxuXHRcdHdoaWxlICggdC0tICkge1xyXG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XHJcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsgMSBdO1xyXG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xyXG5cclxuXHRcdFx0Ly8gVW5iaW5kIGFsbCBldmVudHMgKG9uIHRoaXMgbmFtZXNwYWNlLCBpZiBwcm92aWRlZCkgZm9yIHRoZSBlbGVtZW50XHJcblx0XHRcdGlmICggIXR5cGUgKSB7XHJcblx0XHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICsgdHlwZXNbIHQgXSwgaGFuZGxlciwgc2VsZWN0b3IsIHRydWUgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xyXG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XHJcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XHJcblx0XHRcdHRtcCA9IHRtcFsgMiBdICYmXHJcblx0XHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICk7XHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXHJcblx0XHRcdG9yaWdDb3VudCA9IGogPSBoYW5kbGVycy5sZW5ndGg7XHJcblx0XHRcdHdoaWxlICggai0tICkge1xyXG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XHJcblxyXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcclxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXHJcblx0XHRcdFx0XHQoICF0bXAgfHwgdG1wLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApICYmXHJcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8XHJcblx0XHRcdFx0XHRcdHNlbGVjdG9yID09PSBcIioqXCIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7XHJcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIGhhbmRsZU9iai5zZWxlY3RvciApIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCBzcGVjaWFsLnJlbW92ZSApIHtcclxuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgZ2VuZXJpYyBldmVudCBoYW5kbGVyIGlmIHdlIHJlbW92ZWQgc29tZXRoaW5nIGFuZCBubyBtb3JlIGhhbmRsZXJzIGV4aXN0XHJcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxyXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xyXG5cdFx0XHRcdGlmICggIXNwZWNpYWwudGVhcmRvd24gfHxcclxuXHRcdFx0XHRcdHNwZWNpYWwudGVhcmRvd24uY2FsbCggZWxlbSwgbmFtZXNwYWNlcywgZWxlbURhdGEuaGFuZGxlICkgPT09IGZhbHNlICkge1xyXG5cclxuXHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZWxlbURhdGEuaGFuZGxlICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRkZWxldGUgZXZlbnRzWyB0eXBlIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZW1vdmUgZGF0YSBhbmQgdGhlIGV4cGFuZG8gaWYgaXQncyBubyBsb25nZXIgdXNlZFxyXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XHJcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJoYW5kbGUgZXZlbnRzXCIgKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRkaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxyXG5cdFx0ZXZlbnQgPSBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApO1xyXG5cclxuXHRcdHZhciBpLCBqLCByZXQsIG1hdGNoZWQsIGhhbmRsZU9iaixcclxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXHJcblx0XHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcclxuXHRcdFx0aGFuZGxlcnMgPSAoIGRhdGFQcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSB8fCBbXSxcclxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyBldmVudC50eXBlIF0gfHwge307XHJcblxyXG5cdFx0Ly8gVXNlIHRoZSBmaXgtZWQgalF1ZXJ5LkV2ZW50IHJhdGhlciB0aGFuIHRoZSAocmVhZC1vbmx5KSBuYXRpdmUgZXZlbnRcclxuXHRcdGFyZ3NbIDAgXSA9IGV2ZW50O1xyXG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSB0aGlzO1xyXG5cclxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcclxuXHRcdGlmICggc3BlY2lhbC5wcmVEaXNwYXRjaCAmJiBzcGVjaWFsLnByZURpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGhhbmRsZXJzXHJcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XHJcblxyXG5cdFx0Ly8gUnVuIGRlbGVnYXRlcyBmaXJzdDsgdGhleSBtYXkgd2FudCB0byBzdG9wIHByb3BhZ2F0aW9uIGJlbmVhdGggdXNcclxuXHRcdGkgPSAwO1xyXG5cdFx0d2hpbGUgKCAoIG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdICkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XHJcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XHJcblxyXG5cdFx0XHRqID0gMDtcclxuXHRcdFx0d2hpbGUgKCAoIGhhbmRsZU9iaiA9IG1hdGNoZWQuaGFuZGxlcnNbIGorKyBdICkgJiZcclxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcclxuXHJcblx0XHRcdFx0Ly8gVHJpZ2dlcmVkIGV2ZW50IG11c3QgZWl0aGVyIDEpIGhhdmUgbm8gbmFtZXNwYWNlLCBvciAyKSBoYXZlIG5hbWVzcGFjZShzKVxyXG5cdFx0XHRcdC8vIGEgc3Vic2V0IG9yIGVxdWFsIHRvIHRob3NlIGluIHRoZSBib3VuZCBldmVudCAoYm90aCBjYW4gaGF2ZSBubyBuYW1lc3BhY2UpLlxyXG5cdFx0XHRcdGlmICggIWV2ZW50LnJuYW1lc3BhY2UgfHwgZXZlbnQucm5hbWVzcGFjZS50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xyXG5cdFx0XHRcdFx0ZXZlbnQuZGF0YSA9IGhhbmRsZU9iai5kYXRhO1xyXG5cclxuXHRcdFx0XHRcdHJldCA9ICggKCBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgaGFuZGxlT2JqLm9yaWdUeXBlIF0gfHwge30gKS5oYW5kbGUgfHxcclxuXHRcdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIgKS5hcHBseSggbWF0Y2hlZC5lbGVtLCBhcmdzICk7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoIGV2ZW50LnJlc3VsdCA9IHJldCApID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxyXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcclxuXHRcdFx0c3BlY2lhbC5wb3N0RGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xyXG5cdH0sXHJcblxyXG5cdGhhbmRsZXJzOiBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXJzICkge1xyXG5cdFx0dmFyIGksIG1hdGNoZXMsIHNlbCwgaGFuZGxlT2JqLFxyXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcclxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXHJcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcclxuXHJcblx0XHQvLyBTdXBwb3J0IChhdCBsZWFzdCk6IENocm9tZSwgSUU5XHJcblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXHJcblx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAoIzEzMTgwKVxyXG5cdFx0Ly9cclxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8PTQyK1xyXG5cdFx0Ly8gQXZvaWQgbm9uLWxlZnQtY2xpY2sgaW4gRkYgYnV0IGRvbid0IGJsb2NrIElFIHJhZGlvIGV2ZW50cyAoIzM4NjEsIGdoLTIzNDMpXHJcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgJiYgY3VyLm5vZGVUeXBlICYmXHJcblx0XHRcdCggZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiIHx8IGlzTmFOKCBldmVudC5idXR0b24gKSB8fCBldmVudC5idXR0b24gPCAxICkgKSB7XHJcblxyXG5cdFx0XHRmb3IgKCA7IGN1ciAhPT0gdGhpczsgY3VyID0gY3VyLnBhcmVudE5vZGUgfHwgdGhpcyApIHtcclxuXHJcblx0XHRcdFx0Ly8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpXHJcblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXHJcblx0XHRcdFx0aWYgKCBjdXIubm9kZVR5cGUgPT09IDEgJiYgKCBjdXIuZGlzYWJsZWQgIT09IHRydWUgfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiICkgKSB7XHJcblx0XHRcdFx0XHRtYXRjaGVzID0gW107XHJcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGRlbGVnYXRlQ291bnQ7IGkrKyApIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIERvbid0IGNvbmZsaWN0IHdpdGggT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzICgjMTMyMDMpXHJcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdFx0XHRcdG1hdGNoZXNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XHJcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+IC0xIDpcclxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5maW5kKCBzZWwsIHRoaXMsIG51bGwsIFsgY3VyIF0gKS5sZW5ndGg7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSApIHtcclxuXHRcdFx0XHRcdFx0XHRtYXRjaGVzLnB1c2goIGhhbmRsZU9iaiApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZiAoIG1hdGNoZXMubGVuZ3RoICkge1xyXG5cdFx0XHRcdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVzIH0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXHJcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XHJcblx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKCB7IGVsZW06IHRoaXMsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xyXG5cdH0sXHJcblxyXG5cdC8vIEluY2x1ZGVzIHNvbWUgZXZlbnQgcHJvcHMgc2hhcmVkIGJ5IEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50XHJcblx0cHJvcHM6ICggXCJhbHRLZXkgYnViYmxlcyBjYW5jZWxhYmxlIGN0cmxLZXkgY3VycmVudFRhcmdldCBkZXRhaWwgZXZlbnRQaGFzZSBcIiArXHJcblx0XHRcIm1ldGFLZXkgcmVsYXRlZFRhcmdldCBzaGlmdEtleSB0YXJnZXQgdGltZVN0YW1wIHZpZXcgd2hpY2hcIiApLnNwbGl0KCBcIiBcIiApLFxyXG5cclxuXHRmaXhIb29rczoge30sXHJcblxyXG5cdGtleUhvb2tzOiB7XHJcblx0XHRwcm9wczogXCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoIFwiIFwiICksXHJcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgd2hpY2ggZm9yIGtleSBldmVudHNcclxuXHRcdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGV2ZW50LndoaWNoID0gb3JpZ2luYWwuY2hhckNvZGUgIT0gbnVsbCA/IG9yaWdpbmFsLmNoYXJDb2RlIDogb3JpZ2luYWwua2V5Q29kZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGV2ZW50O1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdG1vdXNlSG9va3M6IHtcclxuXHRcdHByb3BzOiAoIFwiYnV0dG9uIGJ1dHRvbnMgY2xpZW50WCBjbGllbnRZIG9mZnNldFggb2Zmc2V0WSBwYWdlWCBwYWdlWSBcIiArXHJcblx0XHRcdFwic2NyZWVuWCBzY3JlZW5ZIHRvRWxlbWVudFwiICkuc3BsaXQoIFwiIFwiICksXHJcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XHJcblx0XHRcdHZhciBldmVudERvYywgZG9jLCBib2R5LFxyXG5cdFx0XHRcdGJ1dHRvbiA9IG9yaWdpbmFsLmJ1dHRvbjtcclxuXHJcblx0XHRcdC8vIENhbGN1bGF0ZSBwYWdlWC9ZIGlmIG1pc3NpbmcgYW5kIGNsaWVudFgvWSBhdmFpbGFibGVcclxuXHRcdFx0aWYgKCBldmVudC5wYWdlWCA9PSBudWxsICYmIG9yaWdpbmFsLmNsaWVudFggIT0gbnVsbCApIHtcclxuXHRcdFx0XHRldmVudERvYyA9IGV2ZW50LnRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG5cdFx0XHRcdGRvYyA9IGV2ZW50RG9jLmRvY3VtZW50RWxlbWVudDtcclxuXHRcdFx0XHRib2R5ID0gZXZlbnREb2MuYm9keTtcclxuXHJcblx0XHRcdFx0ZXZlbnQucGFnZVggPSBvcmlnaW5hbC5jbGllbnRYICtcclxuXHRcdFx0XHRcdCggZG9jICYmIGRvYy5zY3JvbGxMZWZ0IHx8IGJvZHkgJiYgYm9keS5zY3JvbGxMZWZ0IHx8IDAgKSAtXHJcblx0XHRcdFx0XHQoIGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwICk7XHJcblx0XHRcdFx0ZXZlbnQucGFnZVkgPSBvcmlnaW5hbC5jbGllbnRZICtcclxuXHRcdFx0XHRcdCggZG9jICYmIGRvYy5zY3JvbGxUb3AgIHx8IGJvZHkgJiYgYm9keS5zY3JvbGxUb3AgIHx8IDAgKSAtXHJcblx0XHRcdFx0XHQoIGRvYyAmJiBkb2MuY2xpZW50VG9wICB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wICB8fCAwICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEFkZCB3aGljaCBmb3IgY2xpY2s6IDEgPT09IGxlZnQ7IDIgPT09IG1pZGRsZTsgMyA9PT0gcmlnaHRcclxuXHRcdFx0Ly8gTm90ZTogYnV0dG9uIGlzIG5vdCBub3JtYWxpemVkLCBzbyBkb24ndCB1c2UgaXRcclxuXHRcdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSAoIGJ1dHRvbiAmIDEgPyAxIDogKCBidXR0b24gJiAyID8gMyA6ICggYnV0dG9uICYgNCA/IDIgOiAwICkgKSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Zml4OiBmdW5jdGlvbiggZXZlbnQgKSB7XHJcblx0XHRpZiAoIGV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdICkge1xyXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ3JlYXRlIGEgd3JpdGFibGUgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCBub3JtYWxpemUgc29tZSBwcm9wZXJ0aWVzXHJcblx0XHR2YXIgaSwgcHJvcCwgY29weSxcclxuXHRcdFx0dHlwZSA9IGV2ZW50LnR5cGUsXHJcblx0XHRcdG9yaWdpbmFsRXZlbnQgPSBldmVudCxcclxuXHRcdFx0Zml4SG9vayA9IHRoaXMuZml4SG9va3NbIHR5cGUgXTtcclxuXHJcblx0XHRpZiAoICFmaXhIb29rICkge1xyXG5cdFx0XHR0aGlzLmZpeEhvb2tzWyB0eXBlIF0gPSBmaXhIb29rID1cclxuXHRcdFx0XHRybW91c2VFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLm1vdXNlSG9va3MgOlxyXG5cdFx0XHRcdHJrZXlFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLmtleUhvb2tzIDpcclxuXHRcdFx0XHR7fTtcclxuXHRcdH1cclxuXHRcdGNvcHkgPSBmaXhIb29rLnByb3BzID8gdGhpcy5wcm9wcy5jb25jYXQoIGZpeEhvb2sucHJvcHMgKSA6IHRoaXMucHJvcHM7XHJcblxyXG5cdFx0ZXZlbnQgPSBuZXcgalF1ZXJ5LkV2ZW50KCBvcmlnaW5hbEV2ZW50ICk7XHJcblxyXG5cdFx0aSA9IGNvcHkubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdHByb3AgPSBjb3B5WyBpIF07XHJcblx0XHRcdGV2ZW50WyBwcm9wIF0gPSBvcmlnaW5hbEV2ZW50WyBwcm9wIF07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU3VwcG9ydDogQ29yZG92YSAyLjUgKFdlYktpdCkgKCMxMzI1NSlcclxuXHRcdC8vIEFsbCBldmVudHMgc2hvdWxkIGhhdmUgYSB0YXJnZXQ7IENvcmRvdmEgZGV2aWNlcmVhZHkgZG9lc24ndFxyXG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xyXG5cdFx0XHRldmVudC50YXJnZXQgPSBkb2N1bWVudDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgNi4wKywgQ2hyb21lPDI4XHJcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxyXG5cdFx0aWYgKCBldmVudC50YXJnZXQubm9kZVR5cGUgPT09IDMgKSB7XHJcblx0XHRcdGV2ZW50LnRhcmdldCA9IGV2ZW50LnRhcmdldC5wYXJlbnROb2RlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmaXhIb29rLmZpbHRlciA/IGZpeEhvb2suZmlsdGVyKCBldmVudCwgb3JpZ2luYWxFdmVudCApIDogZXZlbnQ7XHJcblx0fSxcclxuXHJcblx0c3BlY2lhbDoge1xyXG5cdFx0bG9hZDoge1xyXG5cclxuXHRcdFx0Ly8gUHJldmVudCB0cmlnZ2VyZWQgaW1hZ2UubG9hZCBldmVudHMgZnJvbSBidWJibGluZyB0byB3aW5kb3cubG9hZFxyXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxyXG5cdFx0fSxcclxuXHRcdGZvY3VzOiB7XHJcblxyXG5cdFx0XHQvLyBGaXJlIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3RcclxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKCB0aGlzICE9PSBzYWZlQWN0aXZlRWxlbWVudCgpICYmIHRoaXMuZm9jdXMgKSB7XHJcblx0XHRcdFx0XHR0aGlzLmZvY3VzKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNpblwiXHJcblx0XHR9LFxyXG5cdFx0Ymx1cjoge1xyXG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoIHRoaXMgPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5ibHVyICkge1xyXG5cdFx0XHRcdFx0dGhpcy5ibHVyKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNvdXRcIlxyXG5cdFx0fSxcclxuXHRcdGNsaWNrOiB7XHJcblxyXG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxyXG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoIHRoaXMudHlwZSA9PT0gXCJjaGVja2JveFwiICYmIHRoaXMuY2xpY2sgJiYgalF1ZXJ5Lm5vZGVOYW1lKCB0aGlzLCBcImlucHV0XCIgKSApIHtcclxuXHRcdFx0XHRcdHRoaXMuY2xpY2soKTtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBGb3IgY3Jvc3MtYnJvd3NlciBjb25zaXN0ZW5jeSwgZG9uJ3QgZmlyZSBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3NcclxuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0XHRyZXR1cm4galF1ZXJ5Lm5vZGVOYW1lKCBldmVudC50YXJnZXQsIFwiYVwiICk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0YmVmb3JldW5sb2FkOiB7XHJcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDIwK1xyXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cclxuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQgKSB7XHJcblx0XHRcdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XHJcblxyXG5cdC8vIFRoaXMgXCJpZlwiIGlzIG5lZWRlZCBmb3IgcGxhaW4gb2JqZWN0c1xyXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xyXG5cdFx0ZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKCB0eXBlLCBoYW5kbGUgKTtcclxuXHR9XHJcbn07XHJcblxyXG5qUXVlcnkuRXZlbnQgPSBmdW5jdGlvbiggc3JjLCBwcm9wcyApIHtcclxuXHJcblx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IHRoZSAnbmV3JyBrZXl3b3JkXHJcblx0aWYgKCAhKCB0aGlzIGluc3RhbmNlb2YgalF1ZXJ5LkV2ZW50ICkgKSB7XHJcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xyXG5cdH1cclxuXHJcblx0Ly8gRXZlbnQgb2JqZWN0XHJcblx0aWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7XHJcblx0XHR0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7XHJcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcclxuXHJcblx0XHQvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZFxyXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXHJcblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHNyYy5kZWZhdWx0UHJldmVudGVkIHx8XHJcblx0XHRcdFx0c3JjLmRlZmF1bHRQcmV2ZW50ZWQgPT09IHVuZGVmaW5lZCAmJlxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMFxyXG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xyXG5cdFx0XHRyZXR1cm5UcnVlIDpcclxuXHRcdFx0cmV0dXJuRmFsc2U7XHJcblxyXG5cdC8vIEV2ZW50IHR5cGVcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGhpcy50eXBlID0gc3JjO1xyXG5cdH1cclxuXHJcblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3RcclxuXHRpZiAoIHByb3BzICkge1xyXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcclxuXHR9XHJcblxyXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXHJcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XHJcblxyXG5cdC8vIE1hcmsgaXQgYXMgZml4ZWRcclxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcclxufTtcclxuXHJcbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xyXG4vLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDAzMDMzMS9lY21hLXNjcmlwdC1iaW5kaW5nLmh0bWxcclxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcclxuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LkV2ZW50LFxyXG5cdGlzRGVmYXVsdFByZXZlbnRlZDogcmV0dXJuRmFsc2UsXHJcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxyXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcclxuXHRpc1NpbXVsYXRlZDogZmFsc2UsXHJcblxyXG5cdHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xyXG5cclxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTtcclxuXHJcblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcclxuXHJcblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcclxuXHJcblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XHJcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XHJcblxyXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XHJcblxyXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xyXG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0fVxyXG59O1xyXG5cclxuLy8gQ3JlYXRlIG1vdXNlZW50ZXIvbGVhdmUgZXZlbnRzIHVzaW5nIG1vdXNlb3Zlci9vdXQgYW5kIGV2ZW50LXRpbWUgY2hlY2tzXHJcbi8vIHNvIHRoYXQgZXZlbnQgZGVsZWdhdGlvbiB3b3JrcyBpbiBqUXVlcnkuXHJcbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XHJcbi8vXHJcbi8vIFN1cHBvcnQ6IFNhZmFyaSA3IG9ubHlcclxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XHJcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcclxuLy8gZm9yIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYnVnIChpdCBleGlzdGVkIGluIG9sZGVyIENocm9tZSB2ZXJzaW9ucyBhcyB3ZWxsKS5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxyXG5cdG1vdXNlbGVhdmU6IFwibW91c2VvdXRcIixcclxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcclxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXHJcbn0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XHJcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcclxuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxyXG5cdFx0YmluZFR5cGU6IGZpeCxcclxuXHJcblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0dmFyIHJldCxcclxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxyXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxyXG5cdFx0XHRcdGhhbmRsZU9iaiA9IGV2ZW50LmhhbmRsZU9iajtcclxuXHJcblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXHJcblx0XHRcdC8vIE5COiBObyByZWxhdGVkVGFyZ2V0IGlmIHRoZSBtb3VzZSBsZWZ0L2VudGVyZWQgdGhlIGJyb3dzZXIgd2luZG93XHJcblx0XHRcdGlmICggIXJlbGF0ZWQgfHwgKCByZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkgKSApIHtcclxuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xyXG5cdFx0XHRcdHJldCA9IGhhbmRsZU9iai5oYW5kbGVyLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9XHJcblx0fTtcclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBvbiggdGhpcywgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xyXG5cdH0sXHJcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBvbiggdGhpcywgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgMSApO1xyXG5cdH0sXHJcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcclxuXHRcdHZhciBoYW5kbGVPYmosIHR5cGU7XHJcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcclxuXHJcblx0XHRcdC8vICggZXZlbnQgKSAgZGlzcGF0Y2hlZCBqUXVlcnkuRXZlbnRcclxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xyXG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxyXG5cdFx0XHRcdGhhbmRsZU9iai5uYW1lc3BhY2UgP1xyXG5cdFx0XHRcdFx0aGFuZGxlT2JqLm9yaWdUeXBlICsgXCIuXCIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDpcclxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcclxuXHRcdFx0XHRoYW5kbGVPYmouc2VsZWN0b3IsXHJcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcclxuXHRcdFx0KTtcclxuXHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHR9XHJcblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXHJcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XHJcblx0XHRcdFx0dGhpcy5vZmYoIHR5cGUsIHNlbGVjdG9yLCB0eXBlc1sgdHlwZSBdICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHR9XHJcblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMgWywgZm5dIClcclxuXHRcdFx0Zm4gPSBzZWxlY3RvcjtcclxuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcclxuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxudmFyXHJcblx0cnhodG1sVGFnID0gLzwoPyFhcmVhfGJyfGNvbHxlbWJlZHxocnxpbWd8aW5wdXR8bGlua3xtZXRhfHBhcmFtKSgoW1xcdzotXSspW14+XSopXFwvPi9naSxcclxuXHJcblx0Ly8gU3VwcG9ydDogSUUgMTAtMTEsIEVkZ2UgMTAyNDArXHJcblx0Ly8gSW4gSUUvRWRnZSB1c2luZyByZWdleCBncm91cHMgaGVyZSBjYXVzZXMgc2V2ZXJlIHNsb3dkb3ducy5cclxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xyXG5cdHJub0lubmVyaHRtbCA9IC88c2NyaXB0fDxzdHlsZXw8bGluay9pLFxyXG5cclxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcclxuXHRyY2hlY2tlZCA9IC9jaGVja2VkXFxzKig/OltePV18PVxccyouY2hlY2tlZC4pL2ksXHJcblx0cnNjcmlwdFR5cGVNYXNrZWQgPSAvXnRydWVcXC8oLiopLyxcclxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7XHJcblxyXG4vLyBNYW5pcHVsYXRpbmcgdGFibGVzIHJlcXVpcmVzIGEgdGJvZHlcclxuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xyXG5cdHJldHVybiBqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwidGFibGVcIiApICYmXHJcblx0XHRqUXVlcnkubm9kZU5hbWUoIGNvbnRlbnQubm9kZVR5cGUgIT09IDExID8gY29udGVudCA6IGNvbnRlbnQuZmlyc3RDaGlsZCwgXCJ0clwiICkgP1xyXG5cclxuXHRcdGVsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwidGJvZHlcIiApWyAwIF0gfHxcclxuXHRcdFx0ZWxlbS5hcHBlbmRDaGlsZCggZWxlbS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwidGJvZHlcIiApICkgOlxyXG5cdFx0ZWxlbTtcclxufVxyXG5cclxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxyXG5mdW5jdGlvbiBkaXNhYmxlU2NyaXB0KCBlbGVtICkge1xyXG5cdGVsZW0udHlwZSA9ICggZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgIT09IG51bGwgKSArIFwiL1wiICsgZWxlbS50eXBlO1xyXG5cdHJldHVybiBlbGVtO1xyXG59XHJcbmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7XHJcblx0dmFyIG1hdGNoID0gcnNjcmlwdFR5cGVNYXNrZWQuZXhlYyggZWxlbS50eXBlICk7XHJcblxyXG5cdGlmICggbWF0Y2ggKSB7XHJcblx0XHRlbGVtLnR5cGUgPSBtYXRjaFsgMSBdO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggXCJ0eXBlXCIgKTtcclxuXHR9XHJcblxyXG5cdHJldHVybiBlbGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkge1xyXG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgcGRhdGFDdXIsIHVkYXRhT2xkLCB1ZGF0YUN1ciwgZXZlbnRzO1xyXG5cclxuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLlxyXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XHJcblx0XHRwZGF0YU9sZCA9IGRhdGFQcml2LmFjY2Vzcyggc3JjICk7XHJcblx0XHRwZGF0YUN1ciA9IGRhdGFQcml2LnNldCggZGVzdCwgcGRhdGFPbGQgKTtcclxuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcclxuXHJcblx0XHRpZiAoIGV2ZW50cyApIHtcclxuXHRcdFx0ZGVsZXRlIHBkYXRhQ3VyLmhhbmRsZTtcclxuXHRcdFx0cGRhdGFDdXIuZXZlbnRzID0ge307XHJcblxyXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcclxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IGV2ZW50c1sgdHlwZSBdLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcclxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIDIuIENvcHkgdXNlciBkYXRhXHJcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcclxuXHRcdHVkYXRhT2xkID0gZGF0YVVzZXIuYWNjZXNzKCBzcmMgKTtcclxuXHRcdHVkYXRhQ3VyID0galF1ZXJ5LmV4dGVuZCgge30sIHVkYXRhT2xkICk7XHJcblxyXG5cdFx0ZGF0YVVzZXIuc2V0KCBkZXN0LCB1ZGF0YUN1ciApO1xyXG5cdH1cclxufVxyXG5cclxuLy8gRml4IElFIGJ1Z3MsIHNlZSBzdXBwb3J0IHRlc3RzXHJcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XHJcblx0dmFyIG5vZGVOYW1lID0gZGVzdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cclxuXHRpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHtcclxuXHRcdGRlc3QuY2hlY2tlZCA9IHNyYy5jaGVja2VkO1xyXG5cclxuXHQvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9uc1xyXG5cdH0gZWxzZSBpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgfHwgbm9kZU5hbWUgPT09IFwidGV4dGFyZWFcIiApIHtcclxuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRvbU1hbmlwKCBjb2xsZWN0aW9uLCBhcmdzLCBjYWxsYmFjaywgaWdub3JlZCApIHtcclxuXHJcblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xyXG5cdGFyZ3MgPSBjb25jYXQuYXBwbHkoIFtdLCBhcmdzICk7XHJcblxyXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcclxuXHRcdGkgPSAwLFxyXG5cdFx0bCA9IGNvbGxlY3Rpb24ubGVuZ3RoLFxyXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcclxuXHRcdHZhbHVlID0gYXJnc1sgMCBdLFxyXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xyXG5cclxuXHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcclxuXHRpZiAoIGlzRnVuY3Rpb24gfHxcclxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcclxuXHRcdFx0XHQhc3VwcG9ydC5jaGVja0Nsb25lICYmIHJjaGVja2VkLnRlc3QoIHZhbHVlICkgKSApIHtcclxuXHRcdHJldHVybiBjb2xsZWN0aW9uLmVhY2goIGZ1bmN0aW9uKCBpbmRleCApIHtcclxuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xyXG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XHJcblx0XHRcdFx0YXJnc1sgMCBdID0gdmFsdWUuY2FsbCggdGhpcywgaW5kZXgsIHNlbGYuaHRtbCgpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG5cclxuXHRpZiAoIGwgKSB7XHJcblx0XHRmcmFnbWVudCA9IGJ1aWxkRnJhZ21lbnQoIGFyZ3MsIGNvbGxlY3Rpb25bIDAgXS5vd25lckRvY3VtZW50LCBmYWxzZSwgY29sbGVjdGlvbiwgaWdub3JlZCApO1xyXG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xyXG5cclxuXHRcdGlmICggZnJhZ21lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDEgKSB7XHJcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXHJcblx0XHRpZiAoIGZpcnN0IHx8IGlnbm9yZWQgKSB7XHJcblx0XHRcdHNjcmlwdHMgPSBqUXVlcnkubWFwKCBnZXRBbGwoIGZyYWdtZW50LCBcInNjcmlwdFwiICksIGRpc2FibGVTY3JpcHQgKTtcclxuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xyXG5cclxuXHRcdFx0Ly8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbVxyXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcclxuXHRcdFx0Ly8gYmVpbmcgZW1wdGllZCBpbmNvcnJlY3RseSBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgKCM4MDcwKS5cclxuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcclxuXHJcblx0XHRcdFx0aWYgKCBpICE9PSBpTm9DbG9uZSApIHtcclxuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXHJcblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxyXG5cdFx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHNjcmlwdHMsIGdldEFsbCggbm9kZSwgXCJzY3JpcHRcIiApICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRjYWxsYmFjay5jYWxsKCBjb2xsZWN0aW9uWyBpIF0sIG5vZGUsIGkgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xyXG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XHJcblxyXG5cdFx0XHRcdC8vIFJlZW5hYmxlIHNjcmlwdHNcclxuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XHJcblxyXG5cdFx0XHRcdC8vIEV2YWx1YXRlIGV4ZWN1dGFibGUgc2NyaXB0cyBvbiBmaXJzdCBkb2N1bWVudCBpbnNlcnRpb25cclxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcclxuXHRcdFx0XHRcdG5vZGUgPSBzY3JpcHRzWyBpIF07XHJcblx0XHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIG5vZGUudHlwZSB8fCBcIlwiICkgJiZcclxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkge1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcclxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5fZXZhbFVybCggbm9kZS5zcmMgKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICkgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGNvbGxlY3Rpb247XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZSggZWxlbSwgc2VsZWN0b3IsIGtlZXBEYXRhICkge1xyXG5cdHZhciBub2RlLFxyXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxyXG5cdFx0aSA9IDA7XHJcblxyXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcclxuXHRcdGlmICggIWtlZXBEYXRhICYmIG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggbm9kZSApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBub2RlLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdGlmICgga2VlcERhdGEgJiYgalF1ZXJ5LmNvbnRhaW5zKCBub2RlLm93bmVyRG9jdW1lbnQsIG5vZGUgKSApIHtcclxuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xyXG5cdFx0XHR9XHJcblx0XHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggbm9kZSApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW07XHJcbn1cclxuXHJcbmpRdWVyeS5leHRlbmQoIHtcclxuXHRodG1sUHJlZmlsdGVyOiBmdW5jdGlvbiggaHRtbCApIHtcclxuXHRcdHJldHVybiBodG1sLnJlcGxhY2UoIHJ4aHRtbFRhZywgXCI8JDE+PC8kMj5cIiApO1xyXG5cdH0sXHJcblxyXG5cdGNsb25lOiBmdW5jdGlvbiggZWxlbSwgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XHJcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcclxuXHRcdFx0Y2xvbmUgPSBlbGVtLmNsb25lTm9kZSggdHJ1ZSApLFxyXG5cdFx0XHRpblBhZ2UgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xyXG5cclxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xyXG5cdFx0aWYgKCAhc3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCAmJiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgZWxlbS5ub2RlVHlwZSA9PT0gMTEgKSAmJlxyXG5cdFx0XHRcdCFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdC8vIFdlIGVzY2hldyBTaXp6bGUgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczogaHR0cDovL2pzcGVyZi5jb20vZ2V0YWxsLXZzLXNpenpsZS8yXHJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcclxuXHRcdFx0c3JjRWxlbWVudHMgPSBnZXRBbGwoIGVsZW0gKTtcclxuXHJcblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0XHRcdGZpeElucHV0KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZVxyXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0XHRpZiAoIGRlZXBEYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0XHRcdHNyY0VsZW1lbnRzID0gc3JjRWxlbWVudHMgfHwgZ2V0QWxsKCBlbGVtICk7XHJcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcclxuXHJcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XHJcblx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lLCBcInNjcmlwdFwiICk7XHJcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xyXG5cdFx0XHRzZXRHbG9iYWxFdmFsKCBkZXN0RWxlbWVudHMsICFpblBhZ2UgJiYgZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZXR1cm4gdGhlIGNsb25lZCBzZXRcclxuXHRcdHJldHVybiBjbG9uZTtcclxuXHR9LFxyXG5cclxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcyApIHtcclxuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxyXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWwsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGZvciAoIDsgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9PSB1bmRlZmluZWQ7IGkrKyApIHtcclxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBlbGVtICkgKSB7XHJcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcclxuXHRcdFx0XHRcdGlmICggZGF0YS5ldmVudHMgKSB7XHJcblx0XHRcdFx0XHRcdGZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBkYXRhLmhhbmRsZSApO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PSAzNS00NStcclxuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxyXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVByaXYuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0gMzUtNDUrXHJcblx0XHRcdFx0XHQvLyBBc3NpZ24gdW5kZWZpbmVkIGluc3RlYWQgb2YgdXNpbmcgZGVsZXRlLCBzZWUgRGF0YSNyZW1vdmVcclxuXHRcdFx0XHRcdGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHJcblx0Ly8gS2VlcCBkb21NYW5pcCBleHBvc2VkIHVudGlsIDMuMCAoZ2gtMjIyNSlcclxuXHRkb21NYW5pcDogZG9tTWFuaXAsXHJcblxyXG5cdGRldGFjaDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcclxuXHR9LFxyXG5cclxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHJldHVybiByZW1vdmUoIHRoaXMsIHNlbGVjdG9yICk7XHJcblx0fSxcclxuXHJcblx0dGV4dDogZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XHJcblx0XHRcdFx0alF1ZXJ5LnRleHQoIHRoaXMgKSA6XHJcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ICk7XHJcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xyXG5cdH0sXHJcblxyXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xyXG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcclxuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdHByZXBlbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XHJcblx0XHRcdFx0dGFyZ2V0Lmluc2VydEJlZm9yZSggZWxlbSwgdGFyZ2V0LmZpcnN0Q2hpbGQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGJlZm9yZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMgKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGVsZW0sXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xyXG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXHJcblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XHJcblxyXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXHJcblx0XHRcdFx0ZWxlbS50ZXh0Q29udGVudCA9IFwiXCI7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9LFxyXG5cclxuXHRjbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcclxuXHRcdGRlZXBEYXRhQW5kRXZlbnRzID0gZGVlcERhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGRhdGFBbmRFdmVudHMgOiBkZWVwRGF0YUFuZEV2ZW50cztcclxuXHJcblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNsb25lKCB0aGlzLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApO1xyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGh0bWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcclxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcclxuXHRcdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sXHJcblx0XHRcdFx0aSA9IDAsXHJcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xyXG5cclxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXHJcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxyXG5cdFx0XHRcdCF3cmFwTWFwWyAoIHJ0YWdOYW1lLmV4ZWMoIHZhbHVlICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCkgXSApIHtcclxuXHJcblx0XHRcdFx0dmFsdWUgPSBqUXVlcnkuaHRtbFByZWZpbHRlciggdmFsdWUgKTtcclxuXHJcblx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXSB8fCB7fTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFJlbW92ZSBlbGVtZW50IG5vZGVzIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrc1xyXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XHJcblx0XHRcdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGVsZW0gPSAwO1xyXG5cclxuXHRcdFx0XHQvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2RcclxuXHRcdFx0XHR9IGNhdGNoICggZSApIHt9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICggZWxlbSApIHtcclxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xyXG5cdFx0XHR9XHJcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xyXG5cdH0sXHJcblxyXG5cdHJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBpZ25vcmVkID0gW107XHJcblxyXG5cdFx0Ly8gTWFrZSB0aGUgY2hhbmdlcywgcmVwbGFjaW5nIGVhY2ggbm9uLWlnbm9yZWQgY29udGV4dCBlbGVtZW50IHdpdGggdGhlIG5ldyBjb250ZW50XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XHJcblxyXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xyXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggdGhpcyApICk7XHJcblx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XHJcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0Ly8gRm9yY2UgY2FsbGJhY2sgaW52b2NhdGlvblxyXG5cdFx0fSwgaWdub3JlZCApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcclxuXHRwcmVwZW5kVG86IFwicHJlcGVuZFwiLFxyXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcclxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxyXG5cdHJlcGxhY2VBbGw6IFwicmVwbGFjZVdpdGhcIlxyXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XHJcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHR2YXIgZWxlbXMsXHJcblx0XHRcdHJldCA9IFtdLFxyXG5cdFx0XHRpbnNlcnQgPSBqUXVlcnkoIHNlbGVjdG9yICksXHJcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMSxcclxuXHRcdFx0aSA9IDA7XHJcblxyXG5cdFx0Zm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHtcclxuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcclxuXHRcdFx0alF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApO1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXRcclxuXHRcdFx0Ly8gLmdldCgpIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xyXG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5cclxudmFyIGlmcmFtZSxcclxuXHRlbGVtZGlzcGxheSA9IHtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94XHJcblx0XHQvLyBXZSBoYXZlIHRvIHByZS1kZWZpbmUgdGhlc2UgdmFsdWVzIGZvciBGRiAoIzEwMjI3KVxyXG5cdFx0SFRNTDogXCJibG9ja1wiLFxyXG5cdFx0Qk9EWTogXCJibG9ja1wiXHJcblx0fTtcclxuXHJcbi8qKlxyXG4gKiBSZXRyaWV2ZSB0aGUgYWN0dWFsIGRpc3BsYXkgb2YgYSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5vZGVOYW1lIG9mIHRoZSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgRG9jdW1lbnQgb2JqZWN0XHJcbiAqL1xyXG5cclxuLy8gQ2FsbGVkIG9ubHkgZnJvbSB3aXRoaW4gZGVmYXVsdERpc3BsYXlcclxuZnVuY3Rpb24gYWN0dWFsRGlzcGxheSggbmFtZSwgZG9jICkge1xyXG5cdHZhciBlbGVtID0galF1ZXJ5KCBkb2MuY3JlYXRlRWxlbWVudCggbmFtZSApICkuYXBwZW5kVG8oIGRvYy5ib2R5ICksXHJcblxyXG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW1bIDAgXSwgXCJkaXNwbGF5XCIgKTtcclxuXHJcblx0Ly8gV2UgZG9uJ3QgaGF2ZSBhbnkgZGF0YSBzdG9yZWQgb24gdGhlIGVsZW1lbnQsXHJcblx0Ly8gc28gdXNlIFwiZGV0YWNoXCIgbWV0aG9kIGFzIGZhc3Qgd2F5IHRvIGdldCByaWQgb2YgdGhlIGVsZW1lbnRcclxuXHRlbGVtLmRldGFjaCgpO1xyXG5cclxuXHRyZXR1cm4gZGlzcGxheTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRyeSB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgZGlzcGxheSB2YWx1ZSBvZiBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBub2RlTmFtZVxyXG4gKi9cclxuZnVuY3Rpb24gZGVmYXVsdERpc3BsYXkoIG5vZGVOYW1lICkge1xyXG5cdHZhciBkb2MgPSBkb2N1bWVudCxcclxuXHRcdGRpc3BsYXkgPSBlbGVtZGlzcGxheVsgbm9kZU5hbWUgXTtcclxuXHJcblx0aWYgKCAhZGlzcGxheSApIHtcclxuXHRcdGRpc3BsYXkgPSBhY3R1YWxEaXNwbGF5KCBub2RlTmFtZSwgZG9jICk7XHJcblxyXG5cdFx0Ly8gSWYgdGhlIHNpbXBsZSB3YXkgZmFpbHMsIHJlYWQgZnJvbSBpbnNpZGUgYW4gaWZyYW1lXHJcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiIHx8ICFkaXNwbGF5ICkge1xyXG5cclxuXHRcdFx0Ly8gVXNlIHRoZSBhbHJlYWR5LWNyZWF0ZWQgaWZyYW1lIGlmIHBvc3NpYmxlXHJcblx0XHRcdGlmcmFtZSA9ICggaWZyYW1lIHx8IGpRdWVyeSggXCI8aWZyYW1lIGZyYW1lYm9yZGVyPScwJyB3aWR0aD0nMCcgaGVpZ2h0PScwJy8+XCIgKSApXHJcblx0XHRcdFx0LmFwcGVuZFRvKCBkb2MuZG9jdW1lbnRFbGVtZW50ICk7XHJcblxyXG5cdFx0XHQvLyBBbHdheXMgd3JpdGUgYSBuZXcgSFRNTCBza2VsZXRvbiBzbyBXZWJraXQgYW5kIEZpcmVmb3ggZG9uJ3QgY2hva2Ugb24gcmV1c2VcclxuXHRcdFx0ZG9jID0gaWZyYW1lWyAwIF0uY29udGVudERvY3VtZW50O1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogSUVcclxuXHRcdFx0ZG9jLndyaXRlKCk7XHJcblx0XHRcdGRvYy5jbG9zZSgpO1xyXG5cclxuXHRcdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcclxuXHRcdFx0aWZyYW1lLmRldGFjaCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFN0b3JlIHRoZSBjb3JyZWN0IGRlZmF1bHQgZGlzcGxheVxyXG5cdFx0ZWxlbWRpc3BsYXlbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGRpc3BsYXk7XHJcbn1cclxudmFyIHJtYXJnaW4gPSAoIC9ebWFyZ2luLyApO1xyXG5cclxudmFyIHJudW1ub25weCA9IG5ldyBSZWdFeHAoIFwiXihcIiArIHBudW0gKyBcIikoPyFweClbYS16JV0rJFwiLCBcImlcIiApO1xyXG5cclxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFPD0xMSssIEZpcmVmb3g8PTMwKyAoIzE1MDk4LCAjMTQxNTApXHJcblx0XHQvLyBJRSB0aHJvd3Mgb24gZWxlbWVudHMgY3JlYXRlZCBpbiBwb3B1cHNcclxuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxyXG5cdFx0dmFyIHZpZXcgPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XHJcblxyXG5cdFx0aWYgKCAhdmlldyB8fCAhdmlldy5vcGVuZXIgKSB7XHJcblx0XHRcdHZpZXcgPSB3aW5kb3c7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSApO1xyXG5cdH07XHJcblxyXG52YXIgc3dhcCA9IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBjYWxsYmFjaywgYXJncyApIHtcclxuXHR2YXIgcmV0LCBuYW1lLFxyXG5cdFx0b2xkID0ge307XHJcblxyXG5cdC8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lc1xyXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcclxuXHRcdG9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xyXG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdO1xyXG5cdH1cclxuXHJcblx0cmV0ID0gY2FsbGJhY2suYXBwbHkoIGVsZW0sIGFyZ3MgfHwgW10gKTtcclxuXHJcblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXHJcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xyXG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcmV0O1xyXG59O1xyXG5cclxuXHJcbnZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG5cclxuXHJcbiggZnVuY3Rpb24oKSB7XHJcblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLCBwaXhlbE1hcmdpblJpZ2h0VmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXHJcblx0XHRjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXHJcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XHJcblxyXG5cdC8vIEZpbmlzaCBlYXJseSBpbiBsaW1pdGVkIChub24tYnJvd3NlcikgZW52aXJvbm1lbnRzXHJcblx0aWYgKCAhZGl2LnN0eWxlICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5LTExK1xyXG5cdC8vIFN0eWxlIG9mIGNsb25lZCBlbGVtZW50IGFmZmVjdHMgc291cmNlIGVsZW1lbnQgY2xvbmVkICgjODkwOClcclxuXHRkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcImNvbnRlbnQtYm94XCI7XHJcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcclxuXHRzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSA9IGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9PT0gXCJjb250ZW50LWJveFwiO1xyXG5cclxuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjA7d2lkdGg6OHB4O2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweDtcIiArXHJcblx0XHRcInBhZGRpbmc6MDttYXJnaW4tdG9wOjFweDtwb3NpdGlvbjphYnNvbHV0ZVwiO1xyXG5cdGNvbnRhaW5lci5hcHBlbmRDaGlsZCggZGl2ICk7XHJcblxyXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxyXG5cdC8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uXHJcblx0ZnVuY3Rpb24gY29tcHV0ZVN0eWxlVGVzdHMoKSB7XHJcblx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xyXG5cdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcclxuXHRcdFx0XCItd2Via2l0LWJveC1zaXppbmc6Ym9yZGVyLWJveDstbW96LWJveC1zaXppbmc6Ym9yZGVyLWJveDtib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xyXG5cdFx0XHRcInBvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6YmxvY2s7XCIgK1xyXG5cdFx0XHRcIm1hcmdpbjphdXRvO2JvcmRlcjoxcHg7cGFkZGluZzoxcHg7XCIgK1xyXG5cdFx0XHRcInRvcDoxJTt3aWR0aDo1MCVcIjtcclxuXHRcdGRpdi5pbm5lckhUTUwgPSBcIlwiO1xyXG5cdFx0ZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBjb250YWluZXIgKTtcclxuXHJcblx0XHR2YXIgZGl2U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZGl2ICk7XHJcblx0XHRwaXhlbFBvc2l0aW9uVmFsID0gZGl2U3R5bGUudG9wICE9PSBcIjElXCI7XHJcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSBkaXZTdHlsZS5tYXJnaW5MZWZ0ID09PSBcIjJweFwiO1xyXG5cdFx0Ym94U2l6aW5nUmVsaWFibGVWYWwgPSBkaXZTdHlsZS53aWR0aCA9PT0gXCI0cHhcIjtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5XHJcblx0XHQvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3RcclxuXHRcdGRpdi5zdHlsZS5tYXJnaW5SaWdodCA9IFwiNTAlXCI7XHJcblx0XHRwaXhlbE1hcmdpblJpZ2h0VmFsID0gZGl2U3R5bGUubWFyZ2luUmlnaHQgPT09IFwiNHB4XCI7XHJcblxyXG5cdFx0ZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcclxuXHR9XHJcblxyXG5cdGpRdWVyeS5leHRlbmQoIHN1cHBvcnQsIHtcclxuXHRcdHBpeGVsUG9zaXRpb246IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gVGhpcyB0ZXN0IGlzIGV4ZWN1dGVkIG9ubHkgb25jZSBidXQgd2Ugc3RpbGwgZG8gbWVtb2l6aW5nXHJcblx0XHRcdC8vIHNpbmNlIHdlIGNhbiB1c2UgdGhlIGJveFNpemluZ1JlbGlhYmxlIHByZS1jb21wdXRpbmcuXHJcblx0XHRcdC8vIE5vIG5lZWQgdG8gY2hlY2sgaWYgdGhlIHRlc3Qgd2FzIGFscmVhZHkgcGVyZm9ybWVkLCB0aG91Z2guXHJcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdHJldHVybiBwaXhlbFBvc2l0aW9uVmFsO1xyXG5cdFx0fSxcclxuXHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGJveFNpemluZ1JlbGlhYmxlVmFsO1xyXG5cdFx0fSxcclxuXHRcdHBpeGVsTWFyZ2luUmlnaHQ6IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAtNC4zXHJcblx0XHRcdC8vIFdlJ3JlIGNoZWNraW5nIGZvciBib3hTaXppbmdSZWxpYWJsZVZhbCBoZXJlIGluc3RlYWQgb2YgcGl4ZWxNYXJnaW5SaWdodFZhbFxyXG5cdFx0XHQvLyBzaW5jZSB0aGF0IGNvbXByZXNzZXMgYmV0dGVyIGFuZCB0aGV5J3JlIGNvbXB1dGVkIHRvZ2V0aGVyIGFueXdheS5cclxuXHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHBpeGVsTWFyZ2luUmlnaHRWYWw7XHJcblx0XHR9LFxyXG5cdFx0cmVsaWFibGVNYXJnaW5MZWZ0OiBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCBvbmx5LCBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBGaXJlZm94IDw9MyAtIDM3XHJcblx0XHRcdGlmICggYm94U2l6aW5nUmVsaWFibGVWYWwgPT0gbnVsbCApIHtcclxuXHRcdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZWxpYWJsZU1hcmdpbkxlZnRWYWw7XHJcblx0XHR9LFxyXG5cdFx0cmVsaWFibGVNYXJnaW5SaWdodDogZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHQvLyBDaGVjayBpZiBkaXYgd2l0aCBleHBsaWNpdCB3aWR0aCBhbmQgbm8gbWFyZ2luLXJpZ2h0IGluY29ycmVjdGx5XHJcblx0XHRcdC8vIGdldHMgY29tcHV0ZWQgbWFyZ2luLXJpZ2h0IGJhc2VkIG9uIHdpZHRoIG9mIGNvbnRhaW5lci4gKCMzMzMzKVxyXG5cdFx0XHQvLyBXZWJLaXQgQnVnIDEzMzQzIC0gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBtYXJnaW4tcmlnaHRcclxuXHRcdFx0Ly8gVGhpcyBzdXBwb3J0IGZ1bmN0aW9uIGlzIG9ubHkgZXhlY3V0ZWQgb25jZSBzbyBubyBtZW1vaXppbmcgaXMgbmVlZGVkLlxyXG5cdFx0XHR2YXIgcmV0LFxyXG5cdFx0XHRcdG1hcmdpbkRpdiA9IGRpdi5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XHJcblxyXG5cdFx0XHQvLyBSZXNldCBDU1M6IGJveC1zaXppbmc7IGRpc3BsYXk7IG1hcmdpbjsgYm9yZGVyOyBwYWRkaW5nXHJcblx0XHRcdG1hcmdpbkRpdi5zdHlsZS5jc3NUZXh0ID0gZGl2LnN0eWxlLmNzc1RleHQgPVxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHRcdC8vIFZlbmRvci1wcmVmaXggYm94LXNpemluZ1xyXG5cdFx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94O2JveC1zaXppbmc6Y29udGVudC1ib3g7XCIgK1xyXG5cdFx0XHRcdFwiZGlzcGxheTpibG9jazttYXJnaW46MDtib3JkZXI6MDtwYWRkaW5nOjBcIjtcclxuXHRcdFx0bWFyZ2luRGl2LnN0eWxlLm1hcmdpblJpZ2h0ID0gbWFyZ2luRGl2LnN0eWxlLndpZHRoID0gXCIwXCI7XHJcblx0XHRcdGRpdi5zdHlsZS53aWR0aCA9IFwiMXB4XCI7XHJcblx0XHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XHJcblxyXG5cdFx0XHRyZXQgPSAhcGFyc2VGbG9hdCggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIG1hcmdpbkRpdiApLm1hcmdpblJpZ2h0ICk7XHJcblxyXG5cdFx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xyXG5cdFx0XHRkaXYucmVtb3ZlQ2hpbGQoIG1hcmdpbkRpdiApO1xyXG5cclxuXHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdH1cclxuXHR9ICk7XHJcbn0gKSgpO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7XHJcblx0dmFyIHdpZHRoLCBtaW5XaWR0aCwgbWF4V2lkdGgsIHJldCxcclxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcclxuXHJcblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcclxuXHRyZXQgPSBjb21wdXRlZCA/IGNvbXB1dGVkLmdldFByb3BlcnR5VmFsdWUoIG5hbWUgKSB8fCBjb21wdXRlZFsgbmFtZSBdIDogdW5kZWZpbmVkO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBPcGVyYSAxMi4xeCBvbmx5XHJcblx0Ly8gRmFsbCBiYWNrIHRvIHN0eWxlIGV2ZW4gd2l0aG91dCBjb21wdXRlZFxyXG5cdC8vIGNvbXB1dGVkIGlzIHVuZGVmaW5lZCBmb3IgZWxlbXMgb24gZG9jdW1lbnQgZnJhZ21lbnRzXHJcblx0aWYgKCAoIHJldCA9PT0gXCJcIiB8fCByZXQgPT09IHVuZGVmaW5lZCApICYmICFqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApICkge1xyXG5cdFx0cmV0ID0galF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lICk7XHJcblx0fVxyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTlcclxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG9ubHkgbmVlZGVkIGZvciAuY3NzKCdmaWx0ZXInKSAoIzEyNTM3KVxyXG5cdGlmICggY29tcHV0ZWQgKSB7XHJcblxyXG5cdFx0Ly8gQSB0cmlidXRlIHRvIHRoZSBcImF3ZXNvbWUgaGFjayBieSBEZWFuIEVkd2FyZHNcIlxyXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXHJcblx0XHQvLyBidXQgd2lkdGggc2VlbXMgdG8gYmUgcmVsaWFibHkgcGl4ZWxzLlxyXG5cdFx0Ly8gVGhpcyBpcyBhZ2FpbnN0IHRoZSBDU1NPTSBkcmFmdCBzcGVjOlxyXG5cdFx0Ly8gaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3Nzb20vI3Jlc29sdmVkLXZhbHVlc1xyXG5cdFx0aWYgKCAhc3VwcG9ydC5waXhlbE1hcmdpblJpZ2h0KCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJtYXJnaW4udGVzdCggbmFtZSApICkge1xyXG5cclxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIG9yaWdpbmFsIHZhbHVlc1xyXG5cdFx0XHR3aWR0aCA9IHN0eWxlLndpZHRoO1xyXG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xyXG5cdFx0XHRtYXhXaWR0aCA9IHN0eWxlLm1heFdpZHRoO1xyXG5cclxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxyXG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IHN0eWxlLm1heFdpZHRoID0gc3R5bGUud2lkdGggPSByZXQ7XHJcblx0XHRcdHJldCA9IGNvbXB1dGVkLndpZHRoO1xyXG5cclxuXHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xyXG5cdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xyXG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xyXG5cdFx0XHRzdHlsZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHJldCAhPT0gdW5kZWZpbmVkID9cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBJRTktMTErXHJcblx0XHQvLyBJRSByZXR1cm5zIHpJbmRleCB2YWx1ZSBhcyBhbiBpbnRlZ2VyLlxyXG5cdFx0cmV0ICsgXCJcIiA6XHJcblx0XHRyZXQ7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7XHJcblxyXG5cdC8vIERlZmluZSB0aGUgaG9vaywgd2UnbGwgY2hlY2sgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCdzIHJlYWxseSBuZWVkZWQuXHJcblx0cmV0dXJuIHtcclxuXHRcdGdldDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggY29uZGl0aW9uRm4oKSApIHtcclxuXHJcblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXHJcblx0XHRcdFx0Ly8gdG8gbWlzc2luZyBkZXBlbmRlbmN5KSwgcmVtb3ZlIGl0LlxyXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmdldDtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxyXG5cdFx0XHRyZXR1cm4gKCB0aGlzLmdldCA9IGhvb2tGbiApLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdH1cclxuXHR9O1xyXG59XHJcblxyXG5cclxudmFyXHJcblxyXG5cdC8vIFN3YXBwYWJsZSBpZiBkaXNwbGF5IGlzIG5vbmUgb3Igc3RhcnRzIHdpdGggdGFibGVcclxuXHQvLyBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcclxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcclxuXHRyZGlzcGxheXN3YXAgPSAvXihub25lfHRhYmxlKD8hLWNbZWFdKS4rKS8sXHJcblxyXG5cdGNzc1Nob3cgPSB7IHBvc2l0aW9uOiBcImFic29sdXRlXCIsIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsIGRpc3BsYXk6IFwiYmxvY2tcIiB9LFxyXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcclxuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxyXG5cdFx0Zm9udFdlaWdodDogXCI0MDBcIlxyXG5cdH0sXHJcblxyXG5cdGNzc1ByZWZpeGVzID0gWyBcIldlYmtpdFwiLCBcIk9cIiwgXCJNb3pcIiwgXCJtc1wiIF0sXHJcblx0ZW1wdHlTdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKS5zdHlsZTtcclxuXHJcbi8vIFJldHVybiBhIGNzcyBwcm9wZXJ0eSBtYXBwZWQgdG8gYSBwb3RlbnRpYWxseSB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHlcclxuZnVuY3Rpb24gdmVuZG9yUHJvcE5hbWUoIG5hbWUgKSB7XHJcblxyXG5cdC8vIFNob3J0Y3V0IGZvciBuYW1lcyB0aGF0IGFyZSBub3QgdmVuZG9yIHByZWZpeGVkXHJcblx0aWYgKCBuYW1lIGluIGVtcHR5U3R5bGUgKSB7XHJcblx0XHRyZXR1cm4gbmFtZTtcclxuXHR9XHJcblxyXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcclxuXHR2YXIgY2FwTmFtZSA9IG5hbWVbIDAgXS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSggMSApLFxyXG5cdFx0aSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcclxuXHJcblx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRuYW1lID0gY3NzUHJlZml4ZXNbIGkgXSArIGNhcE5hbWU7XHJcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcclxuXHRcdFx0cmV0dXJuIG5hbWU7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkge1xyXG5cclxuXHQvLyBBbnkgcmVsYXRpdmUgKCsvLSkgdmFsdWVzIGhhdmUgYWxyZWFkeSBiZWVuXHJcblx0Ly8gbm9ybWFsaXplZCBhdCB0aGlzIHBvaW50XHJcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XHJcblx0cmV0dXJuIG1hdGNoZXMgP1xyXG5cclxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXHJcblx0XHRNYXRoLm1heCggMCwgbWF0Y2hlc1sgMiBdIC0gKCBzdWJ0cmFjdCB8fCAwICkgKSArICggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApIDpcclxuXHRcdHZhbHVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhdWdtZW50V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEsIGlzQm9yZGVyQm94LCBzdHlsZXMgKSB7XHJcblx0dmFyIGkgPSBleHRyYSA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApID9cclxuXHJcblx0XHQvLyBJZiB3ZSBhbHJlYWR5IGhhdmUgdGhlIHJpZ2h0IG1lYXN1cmVtZW50LCBhdm9pZCBhdWdtZW50YXRpb25cclxuXHRcdDQgOlxyXG5cclxuXHRcdC8vIE90aGVyd2lzZSBpbml0aWFsaXplIGZvciBob3Jpem9udGFsIG9yIHZlcnRpY2FsIHByb3BlcnRpZXNcclxuXHRcdG5hbWUgPT09IFwid2lkdGhcIiA/IDEgOiAwLFxyXG5cclxuXHRcdHZhbCA9IDA7XHJcblxyXG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHtcclxuXHJcblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW4sIHNvIGFkZCBpdCBpZiB3ZSB3YW50IGl0XHJcblx0XHRpZiAoIGV4dHJhID09PSBcIm1hcmdpblwiICkge1xyXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgZXh0cmEgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBpc0JvcmRlckJveCApIHtcclxuXHJcblx0XHRcdC8vIGJvcmRlci1ib3ggaW5jbHVkZXMgcGFkZGluZywgc28gcmVtb3ZlIGl0IGlmIHdlIHdhbnQgY29udGVudFxyXG5cdFx0XHRpZiAoIGV4dHJhID09PSBcImNvbnRlbnRcIiApIHtcclxuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGJvcmRlciBub3IgbWFyZ2luLCBzbyByZW1vdmUgYm9yZGVyXHJcblx0XHRcdGlmICggZXh0cmEgIT09IFwibWFyZ2luXCIgKSB7XHJcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50LCBzbyBhZGQgcGFkZGluZ1xyXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblxyXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50IG5vciBwYWRkaW5nLCBzbyBhZGQgYm9yZGVyXHJcblx0XHRcdGlmICggZXh0cmEgIT09IFwicGFkZGluZ1wiICkge1xyXG5cdFx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdmFsO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApIHtcclxuXHJcblx0Ly8gU3RhcnQgd2l0aCBvZmZzZXQgcHJvcGVydHksIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGJvcmRlci1ib3ggdmFsdWVcclxuXHR2YXIgdmFsdWVJc0JvcmRlckJveCA9IHRydWUsXHJcblx0XHR2YWwgPSBuYW1lID09PSBcIndpZHRoXCIgPyBlbGVtLm9mZnNldFdpZHRoIDogZWxlbS5vZmZzZXRIZWlnaHQsXHJcblx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcclxuXHRcdGlzQm9yZGVyQm94ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIjtcclxuXHJcblx0Ly8gU29tZSBub24taHRtbCBlbGVtZW50cyByZXR1cm4gdW5kZWZpbmVkIGZvciBvZmZzZXRXaWR0aCwgc28gY2hlY2sgZm9yIG51bGwvdW5kZWZpbmVkXHJcblx0Ly8gc3ZnIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjQ5Mjg1XHJcblx0Ly8gTWF0aE1MIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDkxNjY4XHJcblx0aWYgKCB2YWwgPD0gMCB8fCB2YWwgPT0gbnVsbCApIHtcclxuXHJcblx0XHQvLyBGYWxsIGJhY2sgdG8gY29tcHV0ZWQgdGhlbiB1bmNvbXB1dGVkIGNzcyBpZiBuZWNlc3NhcnlcclxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XHJcblx0XHRpZiAoIHZhbCA8IDAgfHwgdmFsID09IG51bGwgKSB7XHJcblx0XHRcdHZhbCA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDb21wdXRlZCB1bml0IGlzIG5vdCBwaXhlbHMuIFN0b3AgaGVyZSBhbmQgcmV0dXJuLlxyXG5cdFx0aWYgKCBybnVtbm9ucHgudGVzdCggdmFsICkgKSB7XHJcblx0XHRcdHJldHVybiB2YWw7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgZm9yIHN0eWxlIGluIGNhc2UgYSBicm93c2VyIHdoaWNoIHJldHVybnMgdW5yZWxpYWJsZSB2YWx1ZXNcclxuXHRcdC8vIGZvciBnZXRDb21wdXRlZFN0eWxlIHNpbGVudGx5IGZhbGxzIGJhY2sgdG8gdGhlIHJlbGlhYmxlIGVsZW0uc3R5bGVcclxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCAmJlxyXG5cdFx0XHQoIHN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGUoKSB8fCB2YWwgPT09IGVsZW0uc3R5bGVbIG5hbWUgXSApO1xyXG5cclxuXHRcdC8vIE5vcm1hbGl6ZSBcIlwiLCBhdXRvLCBhbmQgcHJlcGFyZSBmb3IgZXh0cmFcclxuXHRcdHZhbCA9IHBhcnNlRmxvYXQoIHZhbCApIHx8IDA7XHJcblx0fVxyXG5cclxuXHQvLyBVc2UgdGhlIGFjdGl2ZSBib3gtc2l6aW5nIG1vZGVsIHRvIGFkZC9zdWJ0cmFjdCBpcnJlbGV2YW50IHN0eWxlc1xyXG5cdHJldHVybiAoIHZhbCArXHJcblx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcclxuXHRcdFx0ZWxlbSxcclxuXHRcdFx0bmFtZSxcclxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxyXG5cdFx0XHR2YWx1ZUlzQm9yZGVyQm94LFxyXG5cdFx0XHRzdHlsZXNcclxuXHRcdClcclxuXHQpICsgXCJweFwiO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XHJcblx0dmFyIGRpc3BsYXksIGVsZW0sIGhpZGRlbixcclxuXHRcdHZhbHVlcyA9IFtdLFxyXG5cdFx0aW5kZXggPSAwLFxyXG5cdFx0bGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xyXG5cclxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xyXG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcclxuXHRcdFx0Y29udGludWU7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApO1xyXG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcclxuXHRcdGlmICggc2hvdyApIHtcclxuXHJcblx0XHRcdC8vIFJlc2V0IHRoZSBpbmxpbmUgZGlzcGxheSBvZiB0aGlzIGVsZW1lbnQgdG8gbGVhcm4gaWYgaXQgaXNcclxuXHRcdFx0Ly8gYmVpbmcgaGlkZGVuIGJ5IGNhc2NhZGVkIHJ1bGVzIG9yIG5vdFxyXG5cdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gJiYgZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XHJcblx0XHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gU2V0IGVsZW1lbnRzIHdoaWNoIGhhdmUgYmVlbiBvdmVycmlkZGVuIHdpdGggZGlzcGxheTogbm9uZVxyXG5cdFx0XHQvLyBpbiBhIHN0eWxlc2hlZXQgdG8gd2hhdGV2ZXIgdGhlIGRlZmF1bHQgYnJvd3NlciBzdHlsZSBpc1xyXG5cdFx0XHQvLyBmb3Igc3VjaCBhbiBlbGVtZW50XHJcblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuKCBlbGVtICkgKSB7XHJcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YVByaXYuYWNjZXNzKFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdFwib2xkZGlzcGxheVwiLFxyXG5cdFx0XHRcdFx0ZGVmYXVsdERpc3BsYXkoIGVsZW0ubm9kZU5hbWUgKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGhpZGRlbiA9IGlzSGlkZGVuKCBlbGVtICk7XHJcblxyXG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiIHx8ICFoaWRkZW4gKSB7XHJcblx0XHRcdFx0ZGF0YVByaXYuc2V0KFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdFwib2xkZGlzcGxheVwiLFxyXG5cdFx0XHRcdFx0aGlkZGVuID8gZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiIClcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgbW9zdCBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcFxyXG5cdC8vIHRvIGF2b2lkIHRoZSBjb25zdGFudCByZWZsb3dcclxuXHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xyXG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcclxuXHRcdFx0Y29udGludWU7XHJcblx0XHR9XHJcblx0XHRpZiAoICFzaG93IHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIgfHwgZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICkge1xyXG5cdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPSBzaG93ID8gdmFsdWVzWyBpbmRleCBdIHx8IFwiXCIgOiBcIm5vbmVcIjtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBlbGVtZW50cztcclxufVxyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBBZGQgaW4gc3R5bGUgcHJvcGVydHkgaG9va3MgZm9yIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHRcclxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcclxuXHRjc3NIb29rczoge1xyXG5cdFx0b3BhY2l0eToge1xyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcclxuXHRcdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XHJcblx0XHRcdFx0XHR2YXIgcmV0ID0gY3VyQ1NTKCBlbGVtLCBcIm9wYWNpdHlcIiApO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXHJcblx0Y3NzTnVtYmVyOiB7XHJcblx0XHRcImFuaW1hdGlvbkl0ZXJhdGlvbkNvdW50XCI6IHRydWUsXHJcblx0XHRcImNvbHVtbkNvdW50XCI6IHRydWUsXHJcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXHJcblx0XHRcImZsZXhHcm93XCI6IHRydWUsXHJcblx0XHRcImZsZXhTaHJpbmtcIjogdHJ1ZSxcclxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxyXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXHJcblx0XHRcIm9wYWNpdHlcIjogdHJ1ZSxcclxuXHRcdFwib3JkZXJcIjogdHJ1ZSxcclxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxyXG5cdFx0XCJ3aWRvd3NcIjogdHJ1ZSxcclxuXHRcdFwiekluZGV4XCI6IHRydWUsXHJcblx0XHRcInpvb21cIjogdHJ1ZVxyXG5cdH0sXHJcblxyXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcclxuXHQvLyBzZXR0aW5nIG9yIGdldHRpbmcgdGhlIHZhbHVlXHJcblx0Y3NzUHJvcHM6IHtcclxuXHRcdFwiZmxvYXRcIjogXCJjc3NGbG9hdFwiXHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcclxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcclxuXHJcblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcclxuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lXHJcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcclxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXHJcblx0XHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcclxuXHJcblx0XHRuYW1lID0galF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdIHx8XHJcblx0XHRcdCggalF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdID0gdmVuZG9yUHJvcE5hbWUoIG9yaWdOYW1lICkgfHwgb3JpZ05hbWUgKTtcclxuXHJcblx0XHQvLyBHZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uLCB0aGVuIHVucHJlZml4ZWQgdmVyc2lvblxyXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlXHJcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XHJcblxyXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXHJcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiAmJiAoIHJldCA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKSApICYmIHJldFsgMSBdICkge1xyXG5cdFx0XHRcdHZhbHVlID0gYWRqdXN0Q1NTKCBlbGVtLCBuYW1lLCByZXQgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4ZXMgYnVnICM5MjM3XHJcblx0XHRcdFx0dHlwZSA9IFwibnVtYmVyXCI7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG51bGwgYW5kIE5hTiB2YWx1ZXMgYXJlbid0IHNldCAoIzcxMTYpXHJcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiBhIG51bWJlciB3YXMgcGFzc2VkIGluLCBhZGQgdGhlIHVuaXQgKGV4Y2VwdCBmb3IgY2VydGFpbiBDU1MgcHJvcGVydGllcylcclxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICkge1xyXG5cdFx0XHRcdHZhbHVlICs9IHJldCAmJiByZXRbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIG9yaWdOYW1lIF0gPyBcIlwiIDogXCJweFwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFOS0xMStcclxuXHRcdFx0Ly8gYmFja2dyb3VuZC0qIHByb3BzIGFmZmVjdCBvcmlnaW5hbCBjbG9uZSdzIHZhbHVlc1xyXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XHJcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IFwiaW5oZXJpdFwiO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWVcclxuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8XHJcblx0XHRcdFx0KCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xyXG5cclxuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gdmFsdWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXHJcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdCggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBmYWxzZSwgZXh0cmEgKSApICE9PSB1bmRlZmluZWQgKSB7XHJcblxyXG5cdFx0XHRcdHJldHVybiByZXQ7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0XHJcblx0XHRcdHJldHVybiBzdHlsZVsgbmFtZSBdO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XHJcblx0XHR2YXIgdmFsLCBudW0sIGhvb2tzLFxyXG5cdFx0XHRvcmlnTmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUgKTtcclxuXHJcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcclxuXHRcdG5hbWUgPSBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gfHxcclxuXHRcdFx0KCBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggb3JpZ05hbWUgKSB8fCBvcmlnTmFtZSApO1xyXG5cclxuXHRcdC8vIFRyeSBwcmVmaXhlZCBuYW1lIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIG5hbWVcclxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xyXG5cclxuXHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXHJcblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgKSB7XHJcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxyXG5cdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDb252ZXJ0IFwibm9ybWFsXCIgdG8gY29tcHV0ZWQgdmFsdWVcclxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xyXG5cdFx0XHR2YWwgPSBjc3NOb3JtYWxUcmFuc2Zvcm1bIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNYWtlIG51bWVyaWMgaWYgZm9yY2VkIG9yIGEgcXVhbGlmaWVyIHdhcyBwcm92aWRlZCBhbmQgdmFsIGxvb2tzIG51bWVyaWNcclxuXHRcdGlmICggZXh0cmEgPT09IFwiXCIgfHwgZXh0cmEgKSB7XHJcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xyXG5cdFx0XHRyZXR1cm4gZXh0cmEgPT09IHRydWUgfHwgaXNGaW5pdGUoIG51bSApID8gbnVtIHx8IDAgOiB2YWw7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdmFsO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdID0ge1xyXG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQsIGV4dHJhICkge1xyXG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cclxuXHRcdFx0XHQvLyBDZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJseSBzaG93IHRoZW1cclxuXHRcdFx0XHQvLyBidXQgaXQgbXVzdCBoYXZlIGEgY3VycmVudCBkaXNwbGF5IHN0eWxlIHRoYXQgd291bGQgYmVuZWZpdFxyXG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmXHJcblx0XHRcdFx0XHRlbGVtLm9mZnNldFdpZHRoID09PSAwID9cclxuXHRcdFx0XHRcdFx0c3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XHJcblx0XHRcdFx0XHRcdH0gKSA6XHJcblx0XHRcdFx0XHRcdGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIGV4dHJhICkge1xyXG5cdFx0XHR2YXIgbWF0Y2hlcyxcclxuXHRcdFx0XHRzdHlsZXMgPSBleHRyYSAmJiBnZXRTdHlsZXMoIGVsZW0gKSxcclxuXHRcdFx0XHRzdWJ0cmFjdCA9IGV4dHJhICYmIGF1Z21lbnRXaWR0aE9ySGVpZ2h0KFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdG5hbWUsXHJcblx0XHRcdFx0XHRleHRyYSxcclxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXHJcblx0XHRcdFx0XHRzdHlsZXNcclxuXHRcdFx0XHQpO1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCB0byBwaXhlbHMgaWYgdmFsdWUgYWRqdXN0bWVudCBpcyBuZWVkZWRcclxuXHRcdFx0aWYgKCBzdWJ0cmFjdCAmJiAoIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJlxyXG5cdFx0XHRcdCggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApICE9PSBcInB4XCIgKSB7XHJcblxyXG5cdFx0XHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IHZhbHVlO1xyXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xyXG5cdFx0fVxyXG5cdH07XHJcbn0gKTtcclxuXHJcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5MZWZ0ID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnJlbGlhYmxlTWFyZ2luTGVmdCxcclxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XHJcblx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cdFx0XHRyZXR1cm4gKCBwYXJzZUZsb2F0KCBjdXJDU1MoIGVsZW0sIFwibWFyZ2luTGVmdFwiICkgKSB8fFxyXG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXHJcblx0XHRcdFx0XHRzd2FwKCBlbGVtLCB7IG1hcmdpbkxlZnQ6IDAgfSwgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XHJcblx0XHRcdFx0XHR9IClcclxuXHRcdFx0XHQpICsgXCJweFwiO1xyXG5cdFx0fVxyXG5cdH1cclxuKTtcclxuXHJcbi8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXHJcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5SaWdodCA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5yZWxpYWJsZU1hcmdpblJpZ2h0LFxyXG5cdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcclxuXHRcdGlmICggY29tcHV0ZWQgKSB7XHJcblx0XHRcdHJldHVybiBzd2FwKCBlbGVtLCB7IFwiZGlzcGxheVwiOiBcImlubGluZS1ibG9ja1wiIH0sXHJcblx0XHRcdFx0Y3VyQ1NTLCBbIGVsZW0sIFwibWFyZ2luUmlnaHRcIiBdICk7XHJcblx0XHR9XHJcblx0fVxyXG4pO1xyXG5cclxuLy8gVGhlc2UgaG9va3MgYXJlIHVzZWQgYnkgYW5pbWF0ZSB0byBleHBhbmQgcHJvcGVydGllc1xyXG5qUXVlcnkuZWFjaCgge1xyXG5cdG1hcmdpbjogXCJcIixcclxuXHRwYWRkaW5nOiBcIlwiLFxyXG5cdGJvcmRlcjogXCJXaWR0aFwiXHJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcclxuXHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdID0ge1xyXG5cdFx0ZXhwYW5kOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdHZhciBpID0gMCxcclxuXHRcdFx0XHRleHBhbmRlZCA9IHt9LFxyXG5cclxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcclxuXHRcdFx0XHRwYXJ0cyA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnNwbGl0KCBcIiBcIiApIDogWyB2YWx1ZSBdO1xyXG5cclxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xyXG5cdFx0XHRcdGV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID1cclxuXHRcdFx0XHRcdHBhcnRzWyBpIF0gfHwgcGFydHNbIGkgLSAyIF0gfHwgcGFydHNbIDAgXTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGV4cGFuZGVkO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdGlmICggIXJtYXJnaW4udGVzdCggcHJlZml4ICkgKSB7XHJcblx0XHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXHJcblx0XHRcdFx0bWFwID0ge30sXHJcblx0XHRcdFx0aSA9IDA7XHJcblxyXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBuYW1lICkgKSB7XHJcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICk7XHJcblx0XHRcdFx0bGVuID0gbmFtZS5sZW5ndGg7XHJcblxyXG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0XHRcdFx0bWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0cmV0dXJuIG1hcDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XHJcblx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xyXG5cdFx0fSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XHJcblx0fSxcclxuXHRzaG93OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xyXG5cdH0sXHJcblx0aGlkZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcclxuXHR9LFxyXG5cdHRvZ2dsZTogZnVuY3Rpb24oIHN0YXRlICkge1xyXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xyXG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZiAoIGlzSGlkZGVuKCB0aGlzICkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuc2hvdygpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcclxuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xyXG59XHJcbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xyXG5cclxuVHdlZW4ucHJvdG90eXBlID0ge1xyXG5cdGNvbnN0cnVjdG9yOiBUd2VlbixcclxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XHJcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xyXG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcclxuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHQ7XHJcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcclxuXHRcdHRoaXMuZW5kID0gZW5kO1xyXG5cdFx0dGhpcy51bml0ID0gdW5pdCB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKTtcclxuXHR9LFxyXG5cdGN1cjogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xyXG5cclxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xyXG5cdFx0XHRob29rcy5nZXQoIHRoaXMgKSA6XHJcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcclxuXHR9LFxyXG5cdHJ1bjogZnVuY3Rpb24oIHBlcmNlbnQgKSB7XHJcblx0XHR2YXIgZWFzZWQsXHJcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcclxuXHJcblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcclxuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXHJcblx0XHRcdFx0cGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uXHJcblx0XHRcdCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0gcGVyY2VudDtcclxuXHRcdH1cclxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcclxuXHJcblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xyXG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XHJcblx0XHRcdGhvb2tzLnNldCggdGhpcyApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG59O1xyXG5cclxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xyXG5cclxuVHdlZW4ucHJvcEhvb2tzID0ge1xyXG5cdF9kZWZhdWx0OiB7XHJcblx0XHRnZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcclxuXHRcdFx0dmFyIHJlc3VsdDtcclxuXHJcblx0XHRcdC8vIFVzZSBhIHByb3BlcnR5IG9uIHRoZSBlbGVtZW50IGRpcmVjdGx5IHdoZW4gaXQgaXMgbm90IGEgRE9NIGVsZW1lbnQsXHJcblx0XHRcdC8vIG9yIHdoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgc3R5bGUgcHJvcGVydHkgdGhhdCBleGlzdHMuXHJcblx0XHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAhPT0gMSB8fFxyXG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSAhPSBudWxsICYmIHR3ZWVuLmVsZW0uc3R5bGVbIHR3ZWVuLnByb3AgXSA9PSBudWxsICkge1xyXG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxyXG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLlxyXG5cdFx0XHQvLyBTaW1wbGUgdmFsdWVzIHN1Y2ggYXMgXCIxMHB4XCIgYXJlIHBhcnNlZCB0byBGbG9hdDtcclxuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cclxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xyXG5cclxuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXHJcblx0XHRcdHJldHVybiAhcmVzdWx0IHx8IHJlc3VsdCA9PT0gXCJhdXRvXCIgPyAwIDogcmVzdWx0O1xyXG5cdFx0fSxcclxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xyXG5cclxuXHRcdFx0Ly8gVXNlIHN0ZXAgaG9vayBmb3IgYmFjayBjb21wYXQuXHJcblx0XHRcdC8vIFVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZS5cclxuXHRcdFx0Ly8gVXNlIC5zdHlsZSBpZiBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZS5cclxuXHRcdFx0aWYgKCBqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdICkge1xyXG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XHJcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgPT09IDEgJiZcclxuXHRcdFx0XHQoIHR3ZWVuLmVsZW0uc3R5bGVbIGpRdWVyeS5jc3NQcm9wc1sgdHdlZW4ucHJvcCBdIF0gIT0gbnVsbCB8fFxyXG5cdFx0XHRcdFx0alF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gKSApIHtcclxuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG4vLyBTdXBwb3J0OiBJRTlcclxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXHJcblR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHtcclxuXHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcclxuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG5qUXVlcnkuZWFzaW5nID0ge1xyXG5cdGxpbmVhcjogZnVuY3Rpb24oIHAgKSB7XHJcblx0XHRyZXR1cm4gcDtcclxuXHR9LFxyXG5cdHN3aW5nOiBmdW5jdGlvbiggcCApIHtcclxuXHRcdHJldHVybiAwLjUgLSBNYXRoLmNvcyggcCAqIE1hdGguUEkgKSAvIDI7XHJcblx0fSxcclxuXHRfZGVmYXVsdDogXCJzd2luZ1wiXHJcbn07XHJcblxyXG5qUXVlcnkuZnggPSBUd2Vlbi5wcm90b3R5cGUuaW5pdDtcclxuXHJcbi8vIEJhY2sgQ29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XHJcbmpRdWVyeS5meC5zdGVwID0ge307XHJcblxyXG5cclxuXHJcblxyXG52YXJcclxuXHRmeE5vdywgdGltZXJJZCxcclxuXHRyZnh0eXBlcyA9IC9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxcclxuXHRycnVuID0gL3F1ZXVlSG9va3MkLztcclxuXHJcbi8vIEFuaW1hdGlvbnMgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHdpbGwgcnVuIHN5bmNocm9ub3VzbHlcclxuZnVuY3Rpb24gY3JlYXRlRnhOb3coKSB7XHJcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xyXG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XHJcblx0fSApO1xyXG5cdHJldHVybiAoIGZ4Tm93ID0galF1ZXJ5Lm5vdygpICk7XHJcbn1cclxuXHJcbi8vIEdlbmVyYXRlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgc3RhbmRhcmQgYW5pbWF0aW9uXHJcbmZ1bmN0aW9uIGdlbkZ4KCB0eXBlLCBpbmNsdWRlV2lkdGggKSB7XHJcblx0dmFyIHdoaWNoLFxyXG5cdFx0aSA9IDAsXHJcblx0XHRhdHRycyA9IHsgaGVpZ2h0OiB0eXBlIH07XHJcblxyXG5cdC8vIElmIHdlIGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMSB0byBkbyBhbGwgY3NzRXhwYW5kIHZhbHVlcyxcclxuXHQvLyBvdGhlcndpc2Ugc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodFxyXG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xyXG5cdGZvciAoIDsgaSA8IDQgOyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XHJcblx0XHR3aGljaCA9IGNzc0V4cGFuZFsgaSBdO1xyXG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XHJcblx0fVxyXG5cclxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcclxuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gYXR0cnM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xyXG5cdHZhciB0d2VlbixcclxuXHRcdGNvbGxlY3Rpb24gPSAoIEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdICkuY29uY2F0KCBBbmltYXRpb24udHdlZW5lcnNbIFwiKlwiIF0gKSxcclxuXHRcdGluZGV4ID0gMCxcclxuXHRcdGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xyXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XHJcblx0XHRpZiAoICggdHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSApICkge1xyXG5cclxuXHRcdFx0Ly8gV2UncmUgZG9uZSB3aXRoIHRoaXMgcHJvcGVydHlcclxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gZGVmYXVsdFByZWZpbHRlciggZWxlbSwgcHJvcHMsIG9wdHMgKSB7XHJcblx0LyoganNoaW50IHZhbGlkdGhpczogdHJ1ZSAqL1xyXG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCB0d2VlbiwgaG9va3MsIG9sZGZpcmUsIGRpc3BsYXksIGNoZWNrRGlzcGxheSxcclxuXHRcdGFuaW0gPSB0aGlzLFxyXG5cdFx0b3JpZyA9IHt9LFxyXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlLFxyXG5cdFx0aGlkZGVuID0gZWxlbS5ub2RlVHlwZSAmJiBpc0hpZGRlbiggZWxlbSApLFxyXG5cdFx0ZGF0YVNob3cgPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZnhzaG93XCIgKTtcclxuXHJcblx0Ly8gSGFuZGxlIHF1ZXVlOiBmYWxzZSBwcm9taXNlc1xyXG5cdGlmICggIW9wdHMucXVldWUgKSB7XHJcblx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgXCJmeFwiICk7XHJcblx0XHRpZiAoIGhvb2tzLnVucXVldWVkID09IG51bGwgKSB7XHJcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcclxuXHRcdFx0b2xkZmlyZSA9IGhvb2tzLmVtcHR5LmZpcmU7XHJcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcclxuXHRcdFx0XHRcdG9sZGZpcmUoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0XHRob29rcy51bnF1ZXVlZCsrO1xyXG5cclxuXHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXHJcblx0XHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xyXG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xyXG5cdFx0XHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdFx0fSApO1xyXG5cdH1cclxuXHJcblx0Ly8gSGVpZ2h0L3dpZHRoIG92ZXJmbG93IHBhc3NcclxuXHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcImhlaWdodFwiIGluIHByb3BzIHx8IFwid2lkdGhcIiBpbiBwcm9wcyApICkge1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG5vdGhpbmcgc25lYWtzIG91dFxyXG5cdFx0Ly8gUmVjb3JkIGFsbCAzIG92ZXJmbG93IGF0dHJpYnV0ZXMgYmVjYXVzZSBJRTktMTAgZG8gbm90XHJcblx0XHQvLyBjaGFuZ2UgdGhlIG92ZXJmbG93IGF0dHJpYnV0ZSB3aGVuIG92ZXJmbG93WCBhbmRcclxuXHRcdC8vIG92ZXJmbG93WSBhcmUgc2V0IHRvIHRoZSBzYW1lIHZhbHVlXHJcblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcclxuXHJcblx0XHQvLyBTZXQgZGlzcGxheSBwcm9wZXJ0eSB0byBpbmxpbmUtYmxvY2sgZm9yIGhlaWdodC93aWR0aFxyXG5cdFx0Ly8gYW5pbWF0aW9ucyBvbiBpbmxpbmUgZWxlbWVudHMgdGhhdCBhcmUgaGF2aW5nIHdpZHRoL2hlaWdodCBhbmltYXRlZFxyXG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XHJcblxyXG5cdFx0Ly8gVGVzdCBkZWZhdWx0IGRpc3BsYXkgaWYgZGlzcGxheSBpcyBjdXJyZW50bHkgXCJub25lXCJcclxuXHRcdGNoZWNrRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID9cclxuXHRcdFx0ZGF0YVByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApIHx8IGRlZmF1bHREaXNwbGF5KCBlbGVtLm5vZGVOYW1lICkgOiBkaXNwbGF5O1xyXG5cclxuXHRcdGlmICggY2hlY2tEaXNwbGF5ID09PSBcImlubGluZVwiICYmIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcclxuXHRcdFx0c3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoIG9wdHMub3ZlcmZsb3cgKSB7XHJcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XHJcblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XHJcblx0XHRcdHN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvd1sgMCBdO1xyXG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XHJcblx0XHRcdHN0eWxlLm92ZXJmbG93WSA9IG9wdHMub3ZlcmZsb3dbIDIgXTtcclxuXHRcdH0gKTtcclxuXHR9XHJcblxyXG5cdC8vIHNob3cvaGlkZSBwYXNzXHJcblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcclxuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcclxuXHRcdGlmICggcmZ4dHlwZXMuZXhlYyggdmFsdWUgKSApIHtcclxuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XHJcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcclxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyBcImhpZGVcIiA6IFwic2hvd1wiICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGRhdGFTaG93IGxlZnQgb3ZlciBmcm9tIGEgc3RvcHBlZCBoaWRlIG9yIHNob3dcclxuXHRcdFx0XHQvLyBhbmQgd2UgYXJlIGdvaW5nIHRvIHByb2NlZWQgd2l0aCBzaG93LCB3ZSBzaG91bGQgcHJldGVuZCB0byBiZSBoaWRkZW5cclxuXHRcdFx0XHRpZiAoIHZhbHVlID09PSBcInNob3dcIiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRoaWRkZW4gPSB0cnVlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcclxuXHJcblx0XHQvLyBBbnkgbm9uLWZ4IHZhbHVlIHN0b3BzIHVzIGZyb20gcmVzdG9yaW5nIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRkaXNwbGF5ID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aWYgKCAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHtcclxuXHRcdGlmICggZGF0YVNob3cgKSB7XHJcblx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcclxuXHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRhdGFTaG93ID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFN0b3JlIHN0YXRlIGlmIGl0cyB0b2dnbGUgLSBlbmFibGVzIC5zdG9wKCkudG9nZ2xlKCkgdG8gXCJyZXZlcnNlXCJcclxuXHRcdGlmICggdG9nZ2xlICkge1xyXG5cdFx0XHRkYXRhU2hvdy5oaWRkZW4gPSAhaGlkZGVuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBoaWRkZW4gKSB7XHJcblx0XHRcdGpRdWVyeSggZWxlbSApLnNob3coKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCBlbGVtICkuaGlkZSgpO1xyXG5cdFx0XHR9ICk7XHJcblx0XHR9XHJcblx0XHRhbmltLmRvbmUoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgcHJvcDtcclxuXHJcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJmeHNob3dcIiApO1xyXG5cdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XHJcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xyXG5cdFx0XHR0d2VlbiA9IGNyZWF0ZVR3ZWVuKCBoaWRkZW4gPyBkYXRhU2hvd1sgcHJvcCBdIDogMCwgcHJvcCwgYW5pbSApO1xyXG5cclxuXHRcdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XHJcblx0XHRcdFx0ZGF0YVNob3dbIHByb3AgXSA9IHR3ZWVuLnN0YXJ0O1xyXG5cdFx0XHRcdGlmICggaGlkZGVuICkge1xyXG5cdFx0XHRcdFx0dHdlZW4uZW5kID0gdHdlZW4uc3RhcnQ7XHJcblx0XHRcdFx0XHR0d2Vlbi5zdGFydCA9IHByb3AgPT09IFwid2lkdGhcIiB8fCBwcm9wID09PSBcImhlaWdodFwiID8gMSA6IDA7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdC8vIElmIHRoaXMgaXMgYSBub29wIGxpa2UgLmhpZGUoKS5oaWRlKCksIHJlc3RvcmUgYW4gb3ZlcndyaXR0ZW4gZGlzcGxheSB2YWx1ZVxyXG5cdH0gZWxzZSBpZiAoICggZGlzcGxheSA9PT0gXCJub25lXCIgPyBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheSApID09PSBcImlubGluZVwiICkge1xyXG5cdFx0c3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBwcm9wRmlsdGVyKCBwcm9wcywgc3BlY2lhbEVhc2luZyApIHtcclxuXHR2YXIgaW5kZXgsIG5hbWUsIGVhc2luZywgdmFsdWUsIGhvb2tzO1xyXG5cclxuXHQvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3NcclxuXHRmb3IgKCBpbmRleCBpbiBwcm9wcyApIHtcclxuXHRcdG5hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBpbmRleCApO1xyXG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xyXG5cdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXTtcclxuXHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XHJcblx0XHRcdGVhc2luZyA9IHZhbHVlWyAxIF07XHJcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XHJcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcclxuXHRcdFx0ZGVsZXRlIHByb3BzWyBpbmRleCBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF07XHJcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XHJcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xyXG5cdFx0XHRkZWxldGUgcHJvcHNbIG5hbWUgXTtcclxuXHJcblx0XHRcdC8vIE5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b24ndCBvdmVyd3JpdGUgZXhpc3Rpbmcga2V5cy5cclxuXHRcdFx0Ly8gUmV1c2luZyAnaW5kZXgnIGJlY2F1c2Ugd2UgaGF2ZSB0aGUgY29ycmVjdCBcIm5hbWVcIlxyXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcclxuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XHJcblx0XHRcdFx0XHRwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyBpbmRleCBdO1xyXG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcclxuXHR2YXIgcmVzdWx0LFxyXG5cdFx0c3RvcHBlZCxcclxuXHRcdGluZGV4ID0gMCxcclxuXHRcdGxlbmd0aCA9IEFuaW1hdGlvbi5wcmVmaWx0ZXJzLmxlbmd0aCxcclxuXHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIERvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxyXG5cdFx0XHRkZWxldGUgdGljay5lbGVtO1xyXG5cdFx0fSApLFxyXG5cdFx0dGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZiAoIHN0b3BwZWQgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZhciBjdXJyZW50VGltZSA9IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXHJcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHRcdC8vIEFyY2hhaWMgY3Jhc2ggYnVnIHdvbid0IGFsbG93IHVzIHRvIHVzZSBgMSAtICggMC41IHx8IDAgKWAgKCMxMjQ5NylcclxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXHJcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxyXG5cdFx0XHRcdGluZGV4ID0gMCxcclxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcclxuXHJcblx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xyXG5cdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCBwZXJjZW50ICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBwZXJjZW50LCByZW1haW5pbmcgXSApO1xyXG5cclxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJlbWFpbmluZztcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fSxcclxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHtcclxuXHRcdFx0ZWxlbTogZWxlbSxcclxuXHRcdFx0cHJvcHM6IGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wZXJ0aWVzICksXHJcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHtcclxuXHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7fSxcclxuXHRcdFx0XHRlYXNpbmc6IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHRcclxuXHRcdFx0fSwgb3B0aW9ucyApLFxyXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXHJcblx0XHRcdG9yaWdpbmFsT3B0aW9uczogb3B0aW9ucyxcclxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxyXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcclxuXHRcdFx0dHdlZW5zOiBbXSxcclxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XHJcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxyXG5cdFx0XHRcdFx0XHRhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nWyBwcm9wIF0gfHwgYW5pbWF0aW9uLm9wdHMuZWFzaW5nICk7XHJcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xyXG5cdFx0XHRcdHJldHVybiB0d2VlbjtcclxuXHRcdFx0fSxcclxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XHJcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcclxuXHJcblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcclxuXHRcdFx0XHRcdC8vIG90aGVyd2lzZSB3ZSBza2lwIHRoaXMgcGFydFxyXG5cdFx0XHRcdFx0bGVuZ3RoID0gZ290b0VuZCA/IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoIDogMDtcclxuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XHJcblx0XHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggMSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gUmVzb2x2ZSB3aGVuIHdlIHBsYXllZCB0aGUgbGFzdCBmcmFtZTsgb3RoZXJ3aXNlLCByZWplY3RcclxuXHRcdFx0XHRpZiAoIGdvdG9FbmQgKSB7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9XHJcblx0XHR9ICksXHJcblx0XHRwcm9wcyA9IGFuaW1hdGlvbi5wcm9wcztcclxuXHJcblx0cHJvcEZpbHRlciggcHJvcHMsIGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmcgKTtcclxuXHJcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xyXG5cdFx0aWYgKCByZXN1bHQgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHJlc3VsdC5zdG9wICkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCBhbmltYXRpb24uZWxlbSwgYW5pbWF0aW9uLm9wdHMucXVldWUgKS5zdG9wID1cclxuXHRcdFx0XHRcdGpRdWVyeS5wcm94eSggcmVzdWx0LnN0b3AsIHJlc3VsdCApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xyXG5cclxuXHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhbmltYXRpb24ub3B0cy5zdGFydCApICkge1xyXG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XHJcblx0fVxyXG5cclxuXHRqUXVlcnkuZngudGltZXIoXHJcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XHJcblx0XHRcdGVsZW06IGVsZW0sXHJcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcclxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXHJcblx0XHR9IClcclxuXHQpO1xyXG5cclxuXHQvLyBhdHRhY2ggY2FsbGJhY2tzIGZyb20gb3B0aW9uc1xyXG5cdHJldHVybiBhbmltYXRpb24ucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcclxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXHJcblx0XHQuZmFpbCggYW5pbWF0aW9uLm9wdHMuZmFpbCApXHJcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcclxufVxyXG5cclxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xyXG5cdHR3ZWVuZXJzOiB7XHJcblx0XHRcIipcIjogWyBmdW5jdGlvbiggcHJvcCwgdmFsdWUgKSB7XHJcblx0XHRcdHZhciB0d2VlbiA9IHRoaXMuY3JlYXRlVHdlZW4oIHByb3AsIHZhbHVlICk7XHJcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xyXG5cdFx0XHRyZXR1cm4gdHdlZW47XHJcblx0XHR9IF1cclxuXHR9LFxyXG5cclxuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcHJvcHMgKSApIHtcclxuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcclxuXHRcdFx0cHJvcHMgPSBbIFwiKlwiIF07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90d2hpdGUgKTtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgcHJvcCxcclxuXHRcdFx0aW5kZXggPSAwLFxyXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XHJcblxyXG5cdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRcdHByb3AgPSBwcm9wc1sgaW5kZXggXTtcclxuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcclxuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0udW5zaGlmdCggY2FsbGJhY2sgKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRwcmVmaWx0ZXJzOiBbIGRlZmF1bHRQcmVmaWx0ZXIgXSxcclxuXHJcblx0cHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7XHJcblx0XHRpZiAoIHByZXBlbmQgKSB7XHJcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRBbmltYXRpb24ucHJlZmlsdGVycy5wdXNoKCBjYWxsYmFjayApO1xyXG5cdFx0fVxyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LnNwZWVkID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGZuICkge1xyXG5cdHZhciBvcHQgPSBzcGVlZCAmJiB0eXBlb2Ygc3BlZWQgPT09IFwib2JqZWN0XCIgPyBqUXVlcnkuZXh0ZW5kKCB7fSwgc3BlZWQgKSA6IHtcclxuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XHJcblx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxyXG5cdFx0ZHVyYXRpb246IHNwZWVkLFxyXG5cdFx0ZWFzaW5nOiBmbiAmJiBlYXNpbmcgfHwgZWFzaW5nICYmICFqUXVlcnkuaXNGdW5jdGlvbiggZWFzaW5nICkgJiYgZWFzaW5nXHJcblx0fTtcclxuXHJcblx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4Lm9mZiA/IDAgOiB0eXBlb2Ygb3B0LmR1cmF0aW9uID09PSBcIm51bWJlclwiID9cclxuXHRcdG9wdC5kdXJhdGlvbiA6IG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzID9cclxuXHRcdFx0alF1ZXJ5LmZ4LnNwZWVkc1sgb3B0LmR1cmF0aW9uIF0gOiBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xyXG5cclxuXHQvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcclxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcclxuXHRcdG9wdC5xdWV1ZSA9IFwiZnhcIjtcclxuXHR9XHJcblxyXG5cdC8vIFF1ZXVlaW5nXHJcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcclxuXHJcblx0b3B0LmNvbXBsZXRlID0gZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHQub2xkICkgKSB7XHJcblx0XHRcdG9wdC5vbGQuY2FsbCggdGhpcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggb3B0LnF1ZXVlICkge1xyXG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0cmV0dXJuIG9wdDtcclxufTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRmYWRlVG86IGZ1bmN0aW9uKCBzcGVlZCwgdG8sIGVhc2luZywgY2FsbGJhY2sgKSB7XHJcblxyXG5cdFx0Ly8gU2hvdyBhbnkgaGlkZGVuIGVsZW1lbnRzIGFmdGVyIHNldHRpbmcgb3BhY2l0eSB0byAwXHJcblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxyXG5cclxuXHRcdFx0Ly8gQW5pbWF0ZSB0byB0aGUgdmFsdWUgc3BlY2lmaWVkXHJcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XHJcblx0fSxcclxuXHRhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XHJcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxyXG5cdFx0XHRvcHRhbGwgPSBqUXVlcnkuc3BlZWQoIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICksXHJcblx0XHRcdGRvQW5pbWF0aW9uID0gZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHRcdC8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0XHJcblx0XHRcdFx0dmFyIGFuaW0gPSBBbmltYXRpb24oIHRoaXMsIGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wICksIG9wdGFsbCApO1xyXG5cclxuXHRcdFx0XHQvLyBFbXB0eSBhbmltYXRpb25zLCBvciBmaW5pc2hpbmcgcmVzb2x2ZXMgaW1tZWRpYXRlbHlcclxuXHRcdFx0XHRpZiAoIGVtcHR5IHx8IGRhdGFQcml2LmdldCggdGhpcywgXCJmaW5pc2hcIiApICkge1xyXG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9O1xyXG5cdFx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcclxuXHJcblx0XHRyZXR1cm4gZW1wdHkgfHwgb3B0YWxsLnF1ZXVlID09PSBmYWxzZSA/XHJcblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XHJcblx0XHRcdHRoaXMucXVldWUoIG9wdGFsbC5xdWV1ZSwgZG9BbmltYXRpb24gKTtcclxuXHR9LFxyXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xyXG5cdFx0dmFyIHN0b3BRdWV1ZSA9IGZ1bmN0aW9uKCBob29rcyApIHtcclxuXHRcdFx0dmFyIHN0b3AgPSBob29rcy5zdG9wO1xyXG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcclxuXHRcdFx0c3RvcCggZ290b0VuZCApO1xyXG5cdFx0fTtcclxuXHJcblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRnb3RvRW5kID0gY2xlYXJRdWV1ZTtcclxuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XHJcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0XHRpZiAoIGNsZWFyUXVldWUgJiYgdHlwZSAhPT0gZmFsc2UgKSB7XHJcblx0XHRcdHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgZGVxdWV1ZSA9IHRydWUsXHJcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxyXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFQcml2LmdldCggdGhpcyApO1xyXG5cclxuXHRcdFx0aWYgKCBpbmRleCApIHtcclxuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xyXG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICYmIHJydW4udGVzdCggaW5kZXggKSApIHtcclxuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xyXG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiZcclxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xyXG5cclxuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcclxuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcclxuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkLlxyXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXHJcblx0XHRcdC8vIHdpbGwgZGVxdWV1ZSBidXQgb25seSBpZiB0aGV5IHdlcmUgZ290b0VuZC5cclxuXHRcdFx0aWYgKCBkZXF1ZXVlIHx8ICFnb3RvRW5kICkge1xyXG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XHJcblx0XHRcdH1cclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cdGZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7XHJcblx0XHRpZiAoIHR5cGUgIT09IGZhbHNlICkge1xyXG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGluZGV4LFxyXG5cdFx0XHRcdGRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKSxcclxuXHRcdFx0XHRxdWV1ZSA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlXCIgXSxcclxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxyXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXHJcblx0XHRcdFx0bGVuZ3RoID0gcXVldWUgPyBxdWV1ZS5sZW5ndGggOiAwO1xyXG5cclxuXHRcdFx0Ly8gRW5hYmxlIGZpbmlzaGluZyBmbGFnIG9uIHByaXZhdGUgZGF0YVxyXG5cdFx0XHRkYXRhLmZpbmlzaCA9IHRydWU7XHJcblxyXG5cdFx0XHQvLyBFbXB0eSB0aGUgcXVldWUgZmlyc3RcclxuXHRcdFx0alF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBbXSApO1xyXG5cclxuXHRcdFx0aWYgKCBob29rcyAmJiBob29rcy5zdG9wICkge1xyXG5cdFx0XHRcdGhvb2tzLnN0b3AuY2FsbCggdGhpcywgdHJ1ZSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYWN0aXZlIGFuaW1hdGlvbnMsIGFuZCBmaW5pc2ggdGhlbVxyXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xyXG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkge1xyXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggdHJ1ZSApO1xyXG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIExvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtXHJcblx0XHRcdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XHJcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XHJcblx0XHRcdFx0XHRxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVHVybiBvZmYgZmluaXNoaW5nIGZsYWdcclxuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIFsgXCJ0b2dnbGVcIiwgXCJzaG93XCIsIFwiaGlkZVwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdHZhciBjc3NGbiA9IGpRdWVyeS5mblsgbmFtZSBdO1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XHJcblx0XHRcdGNzc0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSA6XHJcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXHJcbmpRdWVyeS5lYWNoKCB7XHJcblx0c2xpZGVEb3duOiBnZW5GeCggXCJzaG93XCIgKSxcclxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcclxuXHRzbGlkZVRvZ2dsZTogZ2VuRngoIFwidG9nZ2xlXCIgKSxcclxuXHRmYWRlSW46IHsgb3BhY2l0eTogXCJzaG93XCIgfSxcclxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXHJcblx0ZmFkZVRvZ2dsZTogeyBvcGFjaXR5OiBcInRvZ2dsZVwiIH1cclxufSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICkge1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuYW5pbWF0ZSggcHJvcHMsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XHJcblx0fTtcclxufSApO1xyXG5cclxualF1ZXJ5LnRpbWVycyA9IFtdO1xyXG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciB0aW1lcixcclxuXHRcdGkgPSAwLFxyXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcclxuXHJcblx0ZnhOb3cgPSBqUXVlcnkubm93KCk7XHJcblxyXG5cdGZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHtcclxuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XHJcblxyXG5cdFx0Ly8gQ2hlY2tzIHRoZSB0aW1lciBoYXMgbm90IGFscmVhZHkgYmVlbiByZW1vdmVkXHJcblx0XHRpZiAoICF0aW1lcigpICYmIHRpbWVyc1sgaSBdID09PSB0aW1lciApIHtcclxuXHRcdFx0dGltZXJzLnNwbGljZSggaS0tLCAxICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xyXG5cdFx0alF1ZXJ5LmZ4LnN0b3AoKTtcclxuXHR9XHJcblx0ZnhOb3cgPSB1bmRlZmluZWQ7XHJcbn07XHJcblxyXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XHJcblx0alF1ZXJ5LnRpbWVycy5wdXNoKCB0aW1lciApO1xyXG5cdGlmICggdGltZXIoKSApIHtcclxuXHRcdGpRdWVyeS5meC5zdGFydCgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRqUXVlcnkudGltZXJzLnBvcCgpO1xyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5meC5pbnRlcnZhbCA9IDEzO1xyXG5qUXVlcnkuZnguc3RhcnQgPSBmdW5jdGlvbigpIHtcclxuXHRpZiAoICF0aW1lcklkICkge1xyXG5cdFx0dGltZXJJZCA9IHdpbmRvdy5zZXRJbnRlcnZhbCggalF1ZXJ5LmZ4LnRpY2ssIGpRdWVyeS5meC5pbnRlcnZhbCApO1xyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5meC5zdG9wID0gZnVuY3Rpb24oKSB7XHJcblx0d2luZG93LmNsZWFySW50ZXJ2YWwoIHRpbWVySWQgKTtcclxuXHJcblx0dGltZXJJZCA9IG51bGw7XHJcbn07XHJcblxyXG5qUXVlcnkuZnguc3BlZWRzID0ge1xyXG5cdHNsb3c6IDYwMCxcclxuXHRmYXN0OiAyMDAsXHJcblxyXG5cdC8vIERlZmF1bHQgc3BlZWRcclxuXHRfZGVmYXVsdDogNDAwXHJcbn07XHJcblxyXG5cclxuLy8gQmFzZWQgb2ZmIG9mIHRoZSBwbHVnaW4gYnkgQ2xpbnQgSGVsZmVycywgd2l0aCBwZXJtaXNzaW9uLlxyXG4vLyBodHRwOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDEwMDMyNDAxNDc0Ny9odHRwOi8vYmxpbmRzaWduYWxzLmNvbS9pbmRleC5waHAvMjAwOS8wNy9qcXVlcnktZGVsYXkvXHJcbmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkge1xyXG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XHJcblx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xyXG5cclxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xyXG5cdFx0dmFyIHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCggbmV4dCwgdGltZSApO1xyXG5cdFx0aG9va3Muc3RvcCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XHJcblx0XHR9O1xyXG5cdH0gKTtcclxufTtcclxuXHJcblxyXG4oIGZ1bmN0aW9uKCkge1xyXG5cdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApLFxyXG5cdFx0c2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJzZWxlY3RcIiApLFxyXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcclxuXHJcblx0aW5wdXQudHlwZSA9IFwiY2hlY2tib3hcIjtcclxuXHJcblx0Ly8gU3VwcG9ydDogaU9TPD01LjEsIEFuZHJvaWQ8PTQuMitcclxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcclxuXHRzdXBwb3J0LmNoZWNrT24gPSBpbnB1dC52YWx1ZSAhPT0gXCJcIjtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8PTExK1xyXG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XHJcblx0c3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDtcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw9Mi4zXHJcblx0Ly8gT3B0aW9ucyBpbnNpZGUgZGlzYWJsZWQgc2VsZWN0cyBhcmUgaW5jb3JyZWN0bHkgbWFya2VkIGFzIGRpc2FibGVkXHJcblx0c2VsZWN0LmRpc2FibGVkID0gdHJ1ZTtcclxuXHRzdXBwb3J0Lm9wdERpc2FibGVkID0gIW9wdC5kaXNhYmxlZDtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8PTExK1xyXG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXHJcblx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcclxuXHRpbnB1dC52YWx1ZSA9IFwidFwiO1xyXG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XHJcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xyXG59ICkoKTtcclxuXHJcblxyXG52YXIgYm9vbEhvb2ssXHJcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0dmFyIHJldCwgaG9va3MsXHJcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcclxuXHJcblx0XHQvLyBEb24ndCBnZXQvc2V0IGF0dHJpYnV0ZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXHJcblx0XHRpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcclxuXHRcdGlmICggdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlID09PSBcInVuZGVmaW5lZFwiICkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LnByb3AoIGVsZW0sIG5hbWUsIHZhbHVlICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsIGF0dHJpYnV0ZXMgYXJlIGxvd2VyY2FzZVxyXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxyXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XHJcblx0XHRcdG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdIHx8XHJcblx0XHRcdFx0KCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogdW5kZWZpbmVkICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xyXG5cdFx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiZcclxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIHZhbHVlICsgXCJcIiApO1xyXG5cdFx0XHRyZXR1cm4gdmFsdWU7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcclxuXHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XHJcblxyXG5cdFx0Ly8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWRcclxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcclxuXHR9LFxyXG5cclxuXHRhdHRySG9va3M6IHtcclxuXHRcdHR5cGU6IHtcclxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcclxuXHRcdFx0XHRcdGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XHJcblx0XHRcdFx0XHR2YXIgdmFsID0gZWxlbS52YWx1ZTtcclxuXHRcdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgdmFsdWUgKTtcclxuXHRcdFx0XHRcdGlmICggdmFsICkge1xyXG5cdFx0XHRcdFx0XHRlbGVtLnZhbHVlID0gdmFsO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcclxuXHRcdHZhciBuYW1lLCBwcm9wTmFtZSxcclxuXHRcdFx0aSA9IDAsXHJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKTtcclxuXHJcblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xyXG5cdFx0XHR3aGlsZSAoICggbmFtZSA9IGF0dHJOYW1lc1sgaSsrIF0gKSApIHtcclxuXHRcdFx0XHRwcm9wTmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcclxuXHJcblx0XHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGdldCBzcGVjaWFsIHRyZWF0bWVudCAoIzEwODcwKVxyXG5cdFx0XHRcdGlmICggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gU2V0IGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdG8gZmFsc2VcclxuXHRcdFx0XHRcdGVsZW1bIHByb3BOYW1lIF0gPSBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcclxuYm9vbEhvb2sgPSB7XHJcblx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIG5hbWUgKSB7XHJcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcclxuXHJcblx0XHRcdC8vIFJlbW92ZSBib29sZWFuIGF0dHJpYnV0ZXMgd2hlbiBzZXQgdG8gZmFsc2VcclxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lICk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbmFtZTtcclxuXHR9XHJcbn07XHJcbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcclxuXHR2YXIgZ2V0dGVyID0gYXR0ckhhbmRsZVsgbmFtZSBdIHx8IGpRdWVyeS5maW5kLmF0dHI7XHJcblxyXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcclxuXHRcdHZhciByZXQsIGhhbmRsZTtcclxuXHRcdGlmICggIWlzWE1MICkge1xyXG5cclxuXHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBuYW1lIF07XHJcblx0XHRcdGF0dHJIYW5kbGVbIG5hbWUgXSA9IHJldDtcclxuXHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xyXG5cdFx0XHRcdG5hbWUudG9Mb3dlckNhc2UoKSA6XHJcblx0XHRcdFx0bnVsbDtcclxuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gaGFuZGxlO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJldDtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5cclxuXHJcblxyXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXHJcblx0cmNsaWNrYWJsZSA9IC9eKD86YXxhcmVhKSQvaTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XHJcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkucHJvcCwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XHJcblx0fSxcclxuXHJcblx0cmVtb3ZlUHJvcDogZnVuY3Rpb24oIG5hbWUgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0ZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcclxuXHRcdHZhciByZXQsIGhvb2tzLFxyXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XHJcblxyXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBwcm9wZXJ0aWVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xyXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xyXG5cclxuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xyXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xyXG5cdFx0XHRob29rcyA9IGpRdWVyeS5wcm9wSG9va3NbIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdCggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRyZXR1cm4gcmV0O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gKCBlbGVtWyBuYW1lIF0gPSB2YWx1ZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgbmFtZSApICkgIT09IG51bGwgKSB7XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGVsZW1bIG5hbWUgXTtcclxuXHR9LFxyXG5cclxuXHRwcm9wSG9va3M6IHtcclxuXHRcdHRhYkluZGV4OiB7XHJcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblxyXG5cdFx0XHRcdC8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZVxyXG5cdFx0XHRcdC8vIGNvcnJlY3QgdmFsdWUgd2hlbiBpdCBoYXNuJ3QgYmVlbiBleHBsaWNpdGx5IHNldFxyXG5cdFx0XHRcdC8vIGh0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvXHJcblx0XHRcdFx0Ly8gVXNlIHByb3BlciBhdHRyaWJ1dGUgcmV0cmlldmFsKCMxMjA3MilcclxuXHRcdFx0XHR2YXIgdGFiaW5kZXggPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInRhYmluZGV4XCIgKTtcclxuXHJcblx0XHRcdFx0cmV0dXJuIHRhYmluZGV4ID9cclxuXHRcdFx0XHRcdHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKSA6XHJcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxyXG5cdFx0XHRcdFx0XHRyY2xpY2thYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSAmJiBlbGVtLmhyZWYgP1xyXG5cdFx0XHRcdFx0XHRcdDAgOlxyXG5cdFx0XHRcdFx0XHRcdC0xO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0cHJvcEZpeDoge1xyXG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXHJcblx0XHRcImNsYXNzXCI6IFwiY2xhc3NOYW1lXCJcclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxyXG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcclxuLy8gZm9yY2VzIHRoZSBicm93c2VyIHRvIHJlc3BlY3Qgc2V0dGluZyBzZWxlY3RlZFxyXG4vLyBvbiB0aGUgb3B0aW9uXHJcbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXHJcbi8vIHdoZW4gaW4gYW4gb3B0Z3JvdXBcclxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcclxuXHRqUXVlcnkucHJvcEhvb2tzLnNlbGVjdGVkID0ge1xyXG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcclxuXHRcdFx0aWYgKCBwYXJlbnQgJiYgcGFyZW50LnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH0sXHJcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xyXG5cdFx0XHRpZiAoIHBhcmVudCApIHtcclxuXHRcdFx0XHRwYXJlbnQuc2VsZWN0ZWRJbmRleDtcclxuXHJcblx0XHRcdFx0aWYgKCBwYXJlbnQucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0XHRcdHBhcmVudC5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxualF1ZXJ5LmVhY2goIFtcclxuXHRcInRhYkluZGV4XCIsXHJcblx0XCJyZWFkT25seVwiLFxyXG5cdFwibWF4TGVuZ3RoXCIsXHJcblx0XCJjZWxsU3BhY2luZ1wiLFxyXG5cdFwiY2VsbFBhZGRpbmdcIixcclxuXHRcInJvd1NwYW5cIixcclxuXHRcImNvbFNwYW5cIixcclxuXHRcInVzZU1hcFwiLFxyXG5cdFwiZnJhbWVCb3JkZXJcIixcclxuXHRcImNvbnRlbnRFZGl0YWJsZVwiXHJcbl0sIGZ1bmN0aW9uKCkge1xyXG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbnZhciByY2xhc3MgPSAvW1xcdFxcclxcblxcZl0vZztcclxuXHJcbmZ1bmN0aW9uIGdldENsYXNzKCBlbGVtICkge1xyXG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcclxufVxyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlICkge1xyXG5cdFx0XHRjbGFzc2VzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xyXG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcclxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmXHJcblx0XHRcdFx0XHQoIFwiIFwiICsgY3VyVmFsdWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBjdXIgKSB7XHJcblx0XHRcdFx0XHRqID0gMDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XHJcblx0XHRcdFx0XHRcdGlmICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApIDwgMCApIHtcclxuXHRcdFx0XHRcdFx0XHRjdXIgKz0gY2xhenogKyBcIiBcIjtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXHJcblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xyXG5cdFx0XHRcdFx0aWYgKCBjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlbW92ZUNsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmF0dHIoIFwiY2xhc3NcIiwgXCJcIiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlICkge1xyXG5cdFx0XHRjbGFzc2VzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xyXG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcclxuXHJcblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcclxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmXHJcblx0XHRcdFx0XHQoIFwiIFwiICsgY3VyVmFsdWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBjdXIgKSB7XHJcblx0XHRcdFx0XHRqID0gMDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXHJcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApID4gLTEgKSB7XHJcblx0XHRcdFx0XHRcdFx0Y3VyID0gY3VyLnJlcGxhY2UoIFwiIFwiICsgY2xhenogKyBcIiBcIiwgXCIgXCIgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXHJcblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xyXG5cdFx0XHRcdFx0aWYgKCBjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xyXG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGVWYWwgPT09IFwiYm9vbGVhblwiICYmIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxyXG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggdGhpcywgaSwgZ2V0Q2xhc3MoIHRoaXMgKSwgc3RhdGVWYWwgKSxcclxuXHRcdFx0XHRcdHN0YXRlVmFsXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgY2xhc3NOYW1lLCBpLCBzZWxmLCBjbGFzc05hbWVzO1xyXG5cclxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICkge1xyXG5cclxuXHRcdFx0XHQvLyBUb2dnbGUgaW5kaXZpZHVhbCBjbGFzcyBuYW1lc1xyXG5cdFx0XHRcdGkgPSAwO1xyXG5cdFx0XHRcdHNlbGYgPSBqUXVlcnkoIHRoaXMgKTtcclxuXHRcdFx0XHRjbGFzc05hbWVzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0XHR3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBDaGVjayBlYWNoIGNsYXNzTmFtZSBnaXZlbiwgc3BhY2Ugc2VwYXJhdGVkIGxpc3RcclxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XHJcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcclxuXHRcdFx0fSBlbHNlIGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcclxuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xyXG5cdFx0XHRcdGlmICggY2xhc3NOYW1lICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcclxuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIsIGNsYXNzTmFtZSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgYGZhbHNlYCxcclxuXHRcdFx0XHQvLyB0aGVuIHJlbW92ZSB0aGUgd2hvbGUgY2xhc3NuYW1lIChpZiB0aGVyZSB3YXMgb25lLCB0aGUgYWJvdmUgc2F2ZWQgaXQpLlxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXHJcblx0XHRcdFx0Ly8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLlxyXG5cdFx0XHRcdGlmICggdGhpcy5zZXRBdHRyaWJ1dGUgKSB7XHJcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxyXG5cdFx0XHRcdFx0XHRjbGFzc05hbWUgfHwgdmFsdWUgPT09IGZhbHNlID9cclxuXHRcdFx0XHRcdFx0XCJcIiA6XHJcblx0XHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIgKSB8fCBcIlwiXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHR2YXIgY2xhc3NOYW1lLCBlbGVtLFxyXG5cdFx0XHRpID0gMDtcclxuXHJcblx0XHRjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCI7XHJcblx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XHJcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHRcdCggXCIgXCIgKyBnZXRDbGFzcyggZWxlbSApICsgXCIgXCIgKS5yZXBsYWNlKCByY2xhc3MsIFwiIFwiIClcclxuXHRcdFx0XHRcdC5pbmRleE9mKCBjbGFzc05hbWUgKSA+IC0xXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcblxyXG5cclxudmFyIHJyZXR1cm4gPSAvXFxyL2csXHJcblx0cnNwYWNlcyA9IC9bXFx4MjBcXHRcXHJcXG5cXGZdKy9nO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHZhbDogZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0dmFyIGhvb2tzLCByZXQsIGlzRnVuY3Rpb24sXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XHJcblxyXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcclxuXHRcdFx0aWYgKCBlbGVtICkge1xyXG5cdFx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fFxyXG5cdFx0XHRcdFx0alF1ZXJ5LnZhbEhvb2tzWyBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcclxuXHJcblx0XHRcdFx0aWYgKCBob29rcyAmJlxyXG5cdFx0XHRcdFx0XCJnZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxyXG5cdFx0XHRcdCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldCA9IGVsZW0udmFsdWU7XHJcblxyXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgcmV0ID09PSBcInN0cmluZ1wiID9cclxuXHJcblx0XHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXHJcblx0XHRcdFx0XHRyZXQucmVwbGFjZSggcnJldHVybiwgXCJcIiApIDpcclxuXHJcblx0XHRcdFx0XHQvLyBIYW5kbGUgY2FzZXMgd2hlcmUgdmFsdWUgaXMgbnVsbC91bmRlZiBvciBudW1iZXJcclxuXHRcdFx0XHRcdHJldCA9PSBudWxsID8gXCJcIiA6IHJldDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlzRnVuY3Rpb24gPSBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKTtcclxuXHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcclxuXHRcdFx0dmFyIHZhbDtcclxuXHJcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcclxuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHZhbCA9IHZhbHVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBUcmVhdCBudWxsL3VuZGVmaW5lZCBhcyBcIlwiOyBjb252ZXJ0IG51bWJlcnMgdG8gc3RyaW5nXHJcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XHJcblx0XHRcdFx0dmFsID0gXCJcIjtcclxuXHJcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XHJcblx0XHRcdFx0dmFsICs9IFwiXCI7XHJcblxyXG5cdFx0XHR9IGVsc2UgaWYgKCBqUXVlcnkuaXNBcnJheSggdmFsICkgKSB7XHJcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XHJcblx0XHRcdFx0fSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgdGhpcy50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyB0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcclxuXHJcblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXHJcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoIFwic2V0XCIgaW4gaG9va3MgKSB8fCBob29rcy5zZXQoIHRoaXMsIHZhbCwgXCJ2YWx1ZVwiICkgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0dmFsSG9va3M6IHtcclxuXHRcdG9wdGlvbjoge1xyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHRcdFx0XHR2YXIgdmFsID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgXCJ2YWx1ZVwiICk7XHJcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cclxuXHRcdFx0XHRcdHZhbCA6XHJcblxyXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMC0xMStcclxuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICgjMTQ2ODYsICMxNDg1OClcclxuXHRcdFx0XHRcdC8vIFN0cmlwIGFuZCBjb2xsYXBzZSB3aGl0ZXNwYWNlXHJcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxyXG5cdFx0XHRcdFx0alF1ZXJ5LnRyaW0oIGpRdWVyeS50ZXh0KCBlbGVtICkgKS5yZXBsYWNlKCByc3BhY2VzLCBcIiBcIiApO1xyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG5cdFx0c2VsZWN0OiB7XHJcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sXHJcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxyXG5cdFx0XHRcdFx0aW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsXHJcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiIHx8IGluZGV4IDwgMCxcclxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcclxuXHRcdFx0XHRcdG1heCA9IG9uZSA/IGluZGV4ICsgMSA6IG9wdGlvbnMubGVuZ3RoLFxyXG5cdFx0XHRcdFx0aSA9IGluZGV4IDwgMCA/XHJcblx0XHRcdFx0XHRcdG1heCA6XHJcblx0XHRcdFx0XHRcdG9uZSA/IGluZGV4IDogMDtcclxuXHJcblx0XHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgc2VsZWN0ZWQgb3B0aW9uc1xyXG5cdFx0XHRcdGZvciAoIDsgaSA8IG1heDsgaSsrICkge1xyXG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xyXG5cclxuXHRcdFx0XHRcdC8vIElFOC05IGRvZXNuJ3QgdXBkYXRlIHNlbGVjdGVkIGFmdGVyIGZvcm0gcmVzZXQgKCMyNTUxKVxyXG5cdFx0XHRcdFx0aWYgKCAoIG9wdGlvbi5zZWxlY3RlZCB8fCBpID09PSBpbmRleCApICYmXHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHJldHVybiBvcHRpb25zIHRoYXQgYXJlIGRpc2FibGVkIG9yIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcclxuXHRcdFx0XHRcdFx0XHQoIHN1cHBvcnQub3B0RGlzYWJsZWQgP1xyXG5cdFx0XHRcdFx0XHRcdFx0IW9wdGlvbi5kaXNhYmxlZCA6IG9wdGlvbi5nZXRBdHRyaWJ1dGUoIFwiZGlzYWJsZWRcIiApID09PSBudWxsICkgJiZcclxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0IWpRdWVyeS5ub2RlTmFtZSggb3B0aW9uLnBhcmVudE5vZGUsIFwib3B0Z3JvdXBcIiApICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXHJcblx0XHRcdFx0XHRcdHZhbHVlID0galF1ZXJ5KCBvcHRpb24gKS52YWwoKTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXHJcblx0XHRcdFx0XHRcdGlmICggb25lICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0Ly8gTXVsdGktU2VsZWN0cyByZXR1cm4gYW4gYXJyYXlcclxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdFx0dmFyIG9wdGlvblNldCwgb3B0aW9uLFxyXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcclxuXHRcdFx0XHRcdHZhbHVlcyA9IGpRdWVyeS5tYWtlQXJyYXkoIHZhbHVlICksXHJcblx0XHRcdFx0XHRpID0gb3B0aW9ucy5sZW5ndGg7XHJcblxyXG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xyXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggalF1ZXJ5LnZhbEhvb2tzLm9wdGlvbi5nZXQoIG9wdGlvbiApLCB2YWx1ZXMgKSA+IC0xXHJcblx0XHRcdFx0XHQpIHtcclxuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XHJcblx0XHRcdFx0aWYgKCAhb3B0aW9uU2V0ICkge1xyXG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIFJhZGlvcyBhbmQgY2hlY2tib3hlcyBnZXR0ZXIvc2V0dGVyXHJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xyXG5cdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdID0ge1xyXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XHJcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xyXG5cdFx0alF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0uZ2V0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbi8vIFJldHVybiBqUXVlcnkgZm9yIGF0dHJpYnV0ZXMtb25seSBpbmNsdXNpb25cclxuXHJcblxyXG52YXIgcmZvY3VzTW9ycGggPSAvXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC87XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCBqUXVlcnkuZXZlbnQsIHtcclxuXHJcblx0dHJpZ2dlcjogZnVuY3Rpb24oIGV2ZW50LCBkYXRhLCBlbGVtLCBvbmx5SGFuZGxlcnMgKSB7XHJcblxyXG5cdFx0dmFyIGksIGN1ciwgdG1wLCBidWJibGVUeXBlLCBvbnR5cGUsIGhhbmRsZSwgc3BlY2lhbCxcclxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXHJcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXHJcblx0XHRcdG5hbWVzcGFjZXMgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwibmFtZXNwYWNlXCIgKSA/IGV2ZW50Lm5hbWVzcGFjZS5zcGxpdCggXCIuXCIgKSA6IFtdO1xyXG5cclxuXHRcdGN1ciA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xyXG5cclxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXHJcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGZvY3VzL2JsdXIgbW9ycGhzIHRvIGZvY3VzaW4vb3V0OyBlbnN1cmUgd2UncmUgbm90IGZpcmluZyB0aGVtIHJpZ2h0IG5vd1xyXG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoIFwiLlwiICkgPiAtMSApIHtcclxuXHJcblx0XHRcdC8vIE5hbWVzcGFjZWQgdHJpZ2dlcjsgY3JlYXRlIGEgcmVnZXhwIHRvIG1hdGNoIGV2ZW50IHR5cGUgaW4gaGFuZGxlKClcclxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIFwiLlwiICk7XHJcblx0XHRcdHR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7XHJcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xyXG5cdFx0fVxyXG5cdFx0b250eXBlID0gdHlwZS5pbmRleE9mKCBcIjpcIiApIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xyXG5cclxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xyXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XHJcblx0XHRcdGV2ZW50IDpcclxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XHJcblxyXG5cdFx0Ly8gVHJpZ2dlciBiaXRtYXNrOiAmIDEgZm9yIG5hdGl2ZSBoYW5kbGVyczsgJiAyIGZvciBqUXVlcnkgKGFsd2F5cyB0cnVlKVxyXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XHJcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiICk7XHJcblx0XHRldmVudC5ybmFtZXNwYWNlID0gZXZlbnQubmFtZXNwYWNlID9cclxuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICkgOlxyXG5cdFx0XHRudWxsO1xyXG5cclxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxyXG5cdFx0ZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkO1xyXG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xyXG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3RcclxuXHRcdGRhdGEgPSBkYXRhID09IG51bGwgP1xyXG5cdFx0XHRbIGV2ZW50IF0gOlxyXG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcclxuXHJcblx0XHQvLyBBbGxvdyBzcGVjaWFsIGV2ZW50cyB0byBkcmF3IG91dHNpZGUgdGhlIGxpbmVzXHJcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcclxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiBzcGVjaWFsLnRyaWdnZXIgJiYgc3BlY2lhbC50cmlnZ2VyLmFwcGx5KCBlbGVtLCBkYXRhICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGV2ZW50IHByb3BhZ2F0aW9uIHBhdGggaW4gYWR2YW5jZSwgcGVyIFczQyBldmVudHMgc3BlYyAoIzk5NTEpXHJcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxyXG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFzcGVjaWFsLm5vQnViYmxlICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xyXG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xyXG5cdFx0XHRcdGN1ciA9IGN1ci5wYXJlbnROb2RlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0XHRldmVudFBhdGgucHVzaCggY3VyICk7XHJcblx0XHRcdFx0dG1wID0gY3VyO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcclxuXHRcdFx0aWYgKCB0bXAgPT09ICggZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkgKSB7XHJcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRmlyZSBoYW5kbGVycyBvbiB0aGUgZXZlbnQgcGF0aFxyXG5cdFx0aSA9IDA7XHJcblx0XHR3aGlsZSAoICggY3VyID0gZXZlbnRQYXRoWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xyXG5cclxuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cclxuXHRcdFx0XHRidWJibGVUeXBlIDpcclxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XHJcblxyXG5cdFx0XHQvLyBqUXVlcnkgaGFuZGxlclxyXG5cdFx0XHRoYW5kbGUgPSAoIGRhdGFQcml2LmdldCggY3VyLCBcImV2ZW50c1wiICkgfHwge30gKVsgZXZlbnQudHlwZSBdICYmXHJcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcclxuXHRcdFx0aWYgKCBoYW5kbGUgKSB7XHJcblx0XHRcdFx0aGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTmF0aXZlIGhhbmRsZXJcclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XHJcblx0XHRcdGlmICggaGFuZGxlICYmIGhhbmRsZS5hcHBseSAmJiBhY2NlcHREYXRhKCBjdXIgKSApIHtcclxuXHRcdFx0XHRldmVudC5yZXN1bHQgPSBoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xyXG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRldmVudC50eXBlID0gdHlwZTtcclxuXHJcblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XHJcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xyXG5cclxuXHRcdFx0aWYgKCAoICFzcGVjaWFsLl9kZWZhdWx0IHx8XHJcblx0XHRcdFx0c3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlICkgJiZcclxuXHRcdFx0XHRhY2NlcHREYXRhKCBlbGVtICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIENhbGwgYSBuYXRpdmUgRE9NIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHdpdGggdGhlIHNhbWUgbmFtZSBuYW1lIGFzIHRoZSBldmVudC5cclxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAoIzYxNzApXHJcblx0XHRcdFx0aWYgKCBvbnR5cGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIGVsZW1bIHR5cGUgXSApICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXHJcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdHlwZTtcclxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xyXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHVuZGVmaW5lZDtcclxuXHJcblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSB0bXA7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcclxuXHR9LFxyXG5cclxuXHQvLyBQaWdneWJhY2sgb24gYSBkb25vciBldmVudCB0byBzaW11bGF0ZSBhIGRpZmZlcmVudCBvbmVcclxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xyXG5cdHNpbXVsYXRlOiBmdW5jdGlvbiggdHlwZSwgZWxlbSwgZXZlbnQgKSB7XHJcblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXHJcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcclxuXHRcdFx0ZXZlbnQsXHJcblx0XHRcdHtcclxuXHRcdFx0XHR0eXBlOiB0eXBlLFxyXG5cdFx0XHRcdGlzU2ltdWxhdGVkOiB0cnVlXHJcblx0XHRcdH1cclxuXHRcdCk7XHJcblxyXG5cdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIGUsIG51bGwsIGVsZW0gKTtcclxuXHR9XHJcblxyXG59ICk7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblxyXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCB0aGlzICk7XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHR0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XHJcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcclxuXHRcdGlmICggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCBlbGVtLCB0cnVlICk7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxualF1ZXJ5LmVhY2goICggXCJibHVyIGZvY3VzIGZvY3VzaW4gZm9jdXNvdXQgbG9hZCByZXNpemUgc2Nyb2xsIHVubG9hZCBjbGljayBkYmxjbGljayBcIiArXHJcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXHJcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGVycm9yIGNvbnRleHRtZW51XCIgKS5zcGxpdCggXCIgXCIgKSxcclxuXHRmdW5jdGlvbiggaSwgbmFtZSApIHtcclxuXHJcblx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcclxuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMCA/XHJcblx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxyXG5cdFx0XHR0aGlzLnRyaWdnZXIoIG5hbWUgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0aG92ZXI6IGZ1bmN0aW9uKCBmbk92ZXIsIGZuT3V0ICkge1xyXG5cdFx0cmV0dXJuIHRoaXMubW91c2VlbnRlciggZm5PdmVyICkubW91c2VsZWF2ZSggZm5PdXQgfHwgZm5PdmVyICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxuXHJcblxyXG5zdXBwb3J0LmZvY3VzaW4gPSBcIm9uZm9jdXNpblwiIGluIHdpbmRvdztcclxuXHJcblxyXG4vLyBTdXBwb3J0OiBGaXJlZm94XHJcbi8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcclxuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02ODc3ODdcclxuLy9cclxuLy8gU3VwcG9ydDogQ2hyb21lLCBTYWZhcmlcclxuLy8gZm9jdXMoaW4gfCBvdXQpIGV2ZW50cyBmaXJlIGFmdGVyIGZvY3VzICYgYmx1ciBldmVudHMsXHJcbi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlclxyXG4vLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcclxuaWYgKCAhc3VwcG9ydC5mb2N1c2luICkge1xyXG5cdGpRdWVyeS5lYWNoKCB7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XHJcblxyXG5cdFx0Ly8gQXR0YWNoIGEgc2luZ2xlIGNhcHR1cmluZyBoYW5kbGVyIG9uIHRoZSBkb2N1bWVudCB3aGlsZSBzb21lb25lIHdhbnRzIGZvY3VzaW4vZm9jdXNvdXRcclxuXHRcdHZhciBoYW5kbGVyID0gZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBmaXggXSA9IHtcclxuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcclxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xyXG5cclxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcclxuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLFxyXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4ICkgLSAxO1xyXG5cclxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcclxuXHRcdFx0XHRcdGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XHJcblxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9ICk7XHJcbn1cclxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xyXG5cclxudmFyIG5vbmNlID0galF1ZXJ5Lm5vdygpO1xyXG5cclxudmFyIHJxdWVyeSA9ICggL1xcPy8gKTtcclxuXHJcblxyXG5cclxuLy8gU3VwcG9ydDogQW5kcm9pZCAyLjNcclxuLy8gV29ya2Fyb3VuZCBmYWlsdXJlIHRvIHN0cmluZy1jYXN0IG51bGwgaW5wdXRcclxualF1ZXJ5LnBhcnNlSlNPTiA9IGZ1bmN0aW9uKCBkYXRhICkge1xyXG5cdHJldHVybiBKU09OLnBhcnNlKCBkYXRhICsgXCJcIiApO1xyXG59O1xyXG5cclxuXHJcbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcclxualF1ZXJ5LnBhcnNlWE1MID0gZnVuY3Rpb24oIGRhdGEgKSB7XHJcblx0dmFyIHhtbDtcclxuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTlcclxuXHR0cnkge1xyXG5cdFx0eG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcclxuXHR9IGNhdGNoICggZSApIHtcclxuXHRcdHhtbCA9IHVuZGVmaW5lZDtcclxuXHR9XHJcblxyXG5cdGlmICggIXhtbCB8fCB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApLmxlbmd0aCApIHtcclxuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XHJcblx0fVxyXG5cdHJldHVybiB4bWw7XHJcbn07XHJcblxyXG5cclxudmFyXHJcblx0cmhhc2ggPSAvIy4qJC8sXHJcblx0cnRzID0gLyhbPyZdKV89W14mXSovLFxyXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcclxuXHJcblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXHJcblx0cmxvY2FsUHJvdG9jb2wgPSAvXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxcclxuXHRybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLyxcclxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXHJcblxyXG5cdC8qIFByZWZpbHRlcnNcclxuXHQgKiAxKSBUaGV5IGFyZSB1c2VmdWwgdG8gaW50cm9kdWNlIGN1c3RvbSBkYXRhVHlwZXMgKHNlZSBhamF4L2pzb25wLmpzIGZvciBhbiBleGFtcGxlKVxyXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XHJcblx0ICogICAgLSBCRUZPUkUgYXNraW5nIGZvciBhIHRyYW5zcG9ydFxyXG5cdCAqICAgIC0gQUZURVIgcGFyYW0gc2VyaWFsaXphdGlvbiAocy5kYXRhIGlzIGEgc3RyaW5nIGlmIHMucHJvY2Vzc0RhdGEgaXMgdHJ1ZSlcclxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXHJcblx0ICogNCkgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxyXG5cdCAqIDUpIGV4ZWN1dGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGNvbnRpbnVlIGRvd24gdG8gXCIqXCIgaWYgbmVlZGVkXHJcblx0ICovXHJcblx0cHJlZmlsdGVycyA9IHt9LFxyXG5cclxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXHJcblx0ICogMSkga2V5IGlzIHRoZSBkYXRhVHlwZVxyXG5cdCAqIDIpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcclxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcclxuXHQgKi9cclxuXHR0cmFuc3BvcnRzID0ge30sXHJcblxyXG5cdC8vIEF2b2lkIGNvbW1lbnQtcHJvbG9nIGNoYXIgc2VxdWVuY2UgKCMxMDA5OCk7IG11c3QgYXBwZWFzZSBsaW50IGFuZCBldmFkZSBjb21wcmVzc2lvblxyXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdCggXCIqXCIgKSxcclxuXHJcblx0Ly8gQW5jaG9yIHRhZyBmb3IgcGFyc2luZyB0aGUgZG9jdW1lbnQgb3JpZ2luXHJcblx0b3JpZ2luQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcclxuXHRvcmlnaW5BbmNob3IuaHJlZiA9IGxvY2F0aW9uLmhyZWY7XHJcblxyXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XHJcbmZ1bmN0aW9uIGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlICkge1xyXG5cclxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXHJcblx0cmV0dXJuIGZ1bmN0aW9uKCBkYXRhVHlwZUV4cHJlc3Npb24sIGZ1bmMgKSB7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRmdW5jID0gZGF0YVR5cGVFeHByZXNzaW9uO1xyXG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgZGF0YVR5cGUsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRkYXRhVHlwZXMgPSBkYXRhVHlwZUV4cHJlc3Npb24udG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XHJcblxyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZnVuYyApICkge1xyXG5cclxuXHRcdFx0Ly8gRm9yIGVhY2ggZGF0YVR5cGUgaW4gdGhlIGRhdGFUeXBlRXhwcmVzc2lvblxyXG5cdFx0XHR3aGlsZSAoICggZGF0YVR5cGUgPSBkYXRhVHlwZXNbIGkrKyBdICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFByZXBlbmQgaWYgcmVxdWVzdGVkXHJcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVsgMCBdID09PSBcIitcIiApIHtcclxuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcclxuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkudW5zaGlmdCggZnVuYyApO1xyXG5cclxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYXBwZW5kXHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkucHVzaCggZnVuYyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcbn1cclxuXHJcbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xyXG5mdW5jdGlvbiBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlLCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICkge1xyXG5cclxuXHR2YXIgaW5zcGVjdGVkID0ge30sXHJcblx0XHRzZWVraW5nVHJhbnNwb3J0ID0gKCBzdHJ1Y3R1cmUgPT09IHRyYW5zcG9ydHMgKTtcclxuXHJcblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XHJcblx0XHR2YXIgc2VsZWN0ZWQ7XHJcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xyXG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcclxuXHRcdFx0dmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTtcclxuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJlxyXG5cdFx0XHRcdCFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xyXG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XHJcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcclxufVxyXG5cclxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXHJcbi8vIHRoYXQgdGFrZXMgXCJmbGF0XCIgb3B0aW9ucyAobm90IHRvIGJlIGRlZXAgZXh0ZW5kZWQpXHJcbi8vIEZpeGVzICM5ODg3XHJcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xyXG5cdHZhciBrZXksIGRlZXAsXHJcblx0XHRmbGF0T3B0aW9ucyA9IGpRdWVyeS5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnMgfHwge307XHJcblxyXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XHJcblx0XHRpZiAoIHNyY1sga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKCBkZWVwID0ge30gKSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKCBkZWVwICkge1xyXG5cdFx0alF1ZXJ5LmV4dGVuZCggdHJ1ZSwgdGFyZ2V0LCBkZWVwICk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGFyZ2V0O1xyXG59XHJcblxyXG4vKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6XHJcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXHJcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxyXG4gKi9cclxuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcclxuXHJcblx0dmFyIGN0LCB0eXBlLCBmaW5hbERhdGFUeXBlLCBmaXJzdERhdGFUeXBlLFxyXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxyXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXM7XHJcblxyXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXHJcblx0d2hpbGUgKCBkYXRhVHlwZXNbIDAgXSA9PT0gXCIqXCIgKSB7XHJcblx0XHRkYXRhVHlwZXMuc2hpZnQoKTtcclxuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0Y3QgPSBzLm1pbWVUeXBlIHx8IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcclxuXHRpZiAoIGN0ICkge1xyXG5cdFx0Zm9yICggdHlwZSBpbiBjb250ZW50cyApIHtcclxuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcclxuXHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdHlwZSApO1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHJlc3BvbnNlIGZvciB0aGUgZXhwZWN0ZWQgZGF0YVR5cGVcclxuXHRpZiAoIGRhdGFUeXBlc1sgMCBdIGluIHJlc3BvbnNlcyApIHtcclxuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIFRyeSBjb252ZXJ0aWJsZSBkYXRhVHlwZXNcclxuXHRcdGZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkge1xyXG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1sgMCBdIF0gKSB7XHJcblx0XHRcdFx0ZmluYWxEYXRhVHlwZSA9IHR5cGU7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCAhZmlyc3REYXRhVHlwZSApIHtcclxuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZVxyXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcclxuXHR9XHJcblxyXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcclxuXHQvLyBXZSBhZGQgdGhlIGRhdGFUeXBlIHRvIHRoZSBsaXN0IGlmIG5lZWRlZFxyXG5cdC8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcclxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XHJcblx0XHRpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkge1xyXG5cdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3BvbnNlc1sgZmluYWxEYXRhVHlwZSBdO1xyXG5cdH1cclxufVxyXG5cclxuLyogQ2hhaW4gY29udmVyc2lvbnMgZ2l2ZW4gdGhlIHJlcXVlc3QgYW5kIHRoZSBvcmlnaW5hbCByZXNwb25zZVxyXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcclxuICovXHJcbmZ1bmN0aW9uIGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApIHtcclxuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcclxuXHRcdGNvbnZlcnRlcnMgPSB7fSxcclxuXHJcblx0XHQvLyBXb3JrIHdpdGggYSBjb3B5IG9mIGRhdGFUeXBlcyBpbiBjYXNlIHdlIG5lZWQgdG8gbW9kaWZ5IGl0IGZvciBjb252ZXJzaW9uXHJcblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpO1xyXG5cclxuXHQvLyBDcmVhdGUgY29udmVydGVycyBtYXAgd2l0aCBsb3dlcmNhc2VkIGtleXNcclxuXHRpZiAoIGRhdGFUeXBlc1sgMSBdICkge1xyXG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XHJcblx0XHRcdGNvbnZlcnRlcnNbIGNvbnYudG9Mb3dlckNhc2UoKSBdID0gcy5jb252ZXJ0ZXJzWyBjb252IF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XHJcblxyXG5cdC8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlXHJcblx0d2hpbGUgKCBjdXJyZW50ICkge1xyXG5cclxuXHRcdGlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkge1xyXG5cdFx0XHRqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBcHBseSB0aGUgZGF0YUZpbHRlciBpZiBwcm92aWRlZFxyXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xyXG5cdFx0XHRyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTtcclxuXHRcdH1cclxuXHJcblx0XHRwcmV2ID0gY3VycmVudDtcclxuXHRcdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcclxuXHJcblx0XHRpZiAoIGN1cnJlbnQgKSB7XHJcblxyXG5cdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xyXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xyXG5cclxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcclxuXHJcblx0XHRcdC8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnRcclxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcclxuXHJcblx0XHRcdFx0Ly8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXJcclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcclxuXHJcblx0XHRcdFx0Ly8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXJcclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xyXG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxyXG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcclxuXHRcdFx0XHRcdFx0aWYgKCB0bXBbIDEgXSA9PT0gY3VycmVudCApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XHJcblx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIHRtcFsgMCBdIF0gfHxcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XHJcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcclxuXHRcdFx0XHRcdFx0XHRcdGlmICggY29udiA9PT0gdHJ1ZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBpbnNlcnQgdGhlIGludGVybWVkaWF0ZSBkYXRhVHlwZVxyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdG1wWyAxIF0gKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXHJcblx0XHRcdFx0aWYgKCBjb252ICE9PSB0cnVlICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cclxuXHRcdFx0XHRcdGlmICggY29udiAmJiBzLnRocm93cyApIHtcclxuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XHJcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdGF0ZTogXCJwYXJzZXJlcnJvclwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50XHJcblx0XHRcdFx0XHRcdFx0fTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xyXG59XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblxyXG5cdC8vIENvdW50ZXIgZm9yIGhvbGRpbmcgdGhlIG51bWJlciBvZiBhY3RpdmUgcXVlcmllc1xyXG5cdGFjdGl2ZTogMCxcclxuXHJcblx0Ly8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdFxyXG5cdGxhc3RNb2RpZmllZDoge30sXHJcblx0ZXRhZzoge30sXHJcblxyXG5cdGFqYXhTZXR0aW5nczoge1xyXG5cdFx0dXJsOiBsb2NhdGlvbi5ocmVmLFxyXG5cdFx0dHlwZTogXCJHRVRcIixcclxuXHRcdGlzTG9jYWw6IHJsb2NhbFByb3RvY29sLnRlc3QoIGxvY2F0aW9uLnByb3RvY29sICksXHJcblx0XHRnbG9iYWw6IHRydWUsXHJcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcclxuXHRcdGFzeW5jOiB0cnVlLFxyXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXHJcblx0XHQvKlxyXG5cdFx0dGltZW91dDogMCxcclxuXHRcdGRhdGE6IG51bGwsXHJcblx0XHRkYXRhVHlwZTogbnVsbCxcclxuXHRcdHVzZXJuYW1lOiBudWxsLFxyXG5cdFx0cGFzc3dvcmQ6IG51bGwsXHJcblx0XHRjYWNoZTogbnVsbCxcclxuXHRcdHRocm93czogZmFsc2UsXHJcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXHJcblx0XHRoZWFkZXJzOiB7fSxcclxuXHRcdCovXHJcblxyXG5cdFx0YWNjZXB0czoge1xyXG5cdFx0XHRcIipcIjogYWxsVHlwZXMsXHJcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxyXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxyXG5cdFx0XHR4bWw6IFwiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbFwiLFxyXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXHJcblx0XHR9LFxyXG5cclxuXHRcdGNvbnRlbnRzOiB7XHJcblx0XHRcdHhtbDogL1xcYnhtbFxcYi8sXHJcblx0XHRcdGh0bWw6IC9cXGJodG1sLyxcclxuXHRcdFx0anNvbjogL1xcYmpzb25cXGIvXHJcblx0XHR9LFxyXG5cclxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XHJcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxyXG5cdFx0XHR0ZXh0OiBcInJlc3BvbnNlVGV4dFwiLFxyXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIERhdGEgY29udmVydGVyc1xyXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxyXG5cdFx0Y29udmVydGVyczoge1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XHJcblx0XHRcdFwiKiB0ZXh0XCI6IFN0cmluZyxcclxuXHJcblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxyXG5cdFx0XHRcInRleHQgaHRtbFwiOiB0cnVlLFxyXG5cclxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxyXG5cdFx0XHRcInRleHQganNvblwiOiBqUXVlcnkucGFyc2VKU09OLFxyXG5cclxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcclxuXHRcdFx0XCJ0ZXh0IHhtbFwiOiBqUXVlcnkucGFyc2VYTUxcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gRm9yIG9wdGlvbnMgdGhhdCBzaG91bGRuJ3QgYmUgZGVlcCBleHRlbmRlZDpcclxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcclxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXHJcblx0XHQvLyBkZWVwIGV4dGVuZGVkIChzZWUgYWpheEV4dGVuZClcclxuXHRcdGZsYXRPcHRpb25zOiB7XHJcblx0XHRcdHVybDogdHJ1ZSxcclxuXHRcdFx0Y29udGV4dDogdHJ1ZVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XHJcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxyXG5cdC8vIElmIHRhcmdldCBpcyBvbWl0dGVkLCB3cml0ZXMgaW50byBhamF4U2V0dGluZ3MuXHJcblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcclxuXHRcdHJldHVybiBzZXR0aW5ncyA/XHJcblxyXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxyXG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XHJcblxyXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXHJcblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xyXG5cdH0sXHJcblxyXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxyXG5cdGFqYXhUcmFuc3BvcnQ6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cyApLFxyXG5cclxuXHQvLyBNYWluIG1ldGhvZFxyXG5cdGFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7XHJcblxyXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcclxuXHRcdGlmICggdHlwZW9mIHVybCA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdFx0b3B0aW9ucyA9IHVybDtcclxuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XHJcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuXHJcblx0XHR2YXIgdHJhbnNwb3J0LFxyXG5cclxuXHRcdFx0Ly8gVVJMIHdpdGhvdXQgYW50aS1jYWNoZSBwYXJhbVxyXG5cdFx0XHRjYWNoZVVSTCxcclxuXHJcblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnNcclxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxyXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXHJcblxyXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxyXG5cdFx0XHR0aW1lb3V0VGltZXIsXHJcblxyXG5cdFx0XHQvLyBVcmwgY2xlYW51cCB2YXJcclxuXHRcdFx0dXJsQW5jaG9yLFxyXG5cclxuXHRcdFx0Ly8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkXHJcblx0XHRcdGZpcmVHbG9iYWxzLFxyXG5cclxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxyXG5cdFx0XHRpLFxyXG5cclxuXHRcdFx0Ly8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdFxyXG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcclxuXHJcblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XHJcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxyXG5cclxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxyXG5cdFx0XHRnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiZcclxuXHRcdFx0XHQoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xyXG5cdFx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQsXHJcblxyXG5cdFx0XHQvLyBEZWZlcnJlZHNcclxuXHRcdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKSxcclxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZCA9IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxyXG5cclxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3NcclxuXHRcdFx0c3RhdHVzQ29kZSA9IHMuc3RhdHVzQ29kZSB8fCB7fSxcclxuXHJcblx0XHRcdC8vIEhlYWRlcnMgKHRoZXkgYXJlIHNlbnQgYWxsIGF0IG9uY2UpXHJcblx0XHRcdHJlcXVlc3RIZWFkZXJzID0ge30sXHJcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcclxuXHJcblx0XHRcdC8vIFRoZSBqcVhIUiBzdGF0ZVxyXG5cdFx0XHRzdGF0ZSA9IDAsXHJcblxyXG5cdFx0XHQvLyBEZWZhdWx0IGFib3J0IG1lc3NhZ2VcclxuXHRcdFx0c3RyQWJvcnQgPSBcImNhbmNlbGVkXCIsXHJcblxyXG5cdFx0XHQvLyBGYWtlIHhoclxyXG5cdFx0XHRqcVhIUiA9IHtcclxuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxyXG5cclxuXHRcdFx0XHQvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkXHJcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XHJcblx0XHRcdFx0XHR2YXIgbWF0Y2g7XHJcblx0XHRcdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xyXG5cdFx0XHRcdFx0XHRpZiAoICFyZXNwb25zZUhlYWRlcnMgKSB7XHJcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzID0ge307XHJcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVyc1sgbWF0Y2hbIDEgXS50b0xvd2VyQ2FzZSgpIF0gPSBtYXRjaFsgMiBdO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcclxuXHRcdFx0XHRnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlID09PSAyID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxyXG5cdFx0XHRcdHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcclxuXHRcdFx0XHRcdHZhciBsbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xyXG5cdFx0XHRcdFx0XHRuYW1lID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIGxuYW1lIF0gfHwgbmFtZTtcclxuXHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNbIG5hbWUgXSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdFx0fSxcclxuXHJcblx0XHRcdFx0Ly8gT3ZlcnJpZGVzIHJlc3BvbnNlIGNvbnRlbnQtdHlwZSBoZWFkZXJcclxuXHRcdFx0XHRvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHtcclxuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xyXG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXHJcblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcclxuXHRcdFx0XHRcdHZhciBjb2RlO1xyXG5cdFx0XHRcdFx0aWYgKCBtYXAgKSB7XHJcblx0XHRcdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xyXG5cdFx0XHRcdFx0XHRcdGZvciAoIGNvZGUgaW4gbWFwICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2sgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcclxuXHRcdFx0XHRcdFx0XHRcdHN0YXR1c0NvZGVbIGNvZGUgXSA9IFsgc3RhdHVzQ29kZVsgY29kZSBdLCBtYXBbIGNvZGUgXSBdO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gRXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tzXHJcblx0XHRcdFx0XHRcdFx0anFYSFIuYWx3YXlzKCBtYXBbIGpxWEhSLnN0YXR1cyBdICk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIENhbmNlbCB0aGUgcmVxdWVzdFxyXG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcclxuXHRcdFx0XHRcdHZhciBmaW5hbFRleHQgPSBzdGF0dXNUZXh0IHx8IHN0ckFib3J0O1xyXG5cdFx0XHRcdFx0aWYgKCB0cmFuc3BvcnQgKSB7XHJcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkb25lKCAwLCBmaW5hbFRleHQgKTtcclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fTtcclxuXHJcblx0XHQvLyBBdHRhY2ggZGVmZXJyZWRzXHJcblx0XHRkZWZlcnJlZC5wcm9taXNlKCBqcVhIUiApLmNvbXBsZXRlID0gY29tcGxldGVEZWZlcnJlZC5hZGQ7XHJcblx0XHRqcVhIUi5zdWNjZXNzID0ganFYSFIuZG9uZTtcclxuXHRcdGpxWEhSLmVycm9yID0ganFYSFIuZmFpbDtcclxuXHJcblx0XHQvLyBSZW1vdmUgaGFzaCBjaGFyYWN0ZXIgKCM3NTMxOiBhbmQgc3RyaW5nIHByb21vdGlvbilcclxuXHRcdC8vIEFkZCBwcm90b2NvbCBpZiBub3QgcHJvdmlkZWQgKHByZWZpbHRlcnMgbWlnaHQgZXhwZWN0IGl0KVxyXG5cdFx0Ly8gSGFuZGxlIGZhbHN5IHVybCBpbiB0aGUgc2V0dGluZ3Mgb2JqZWN0ICgjMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSlcclxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxyXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGxvY2F0aW9uLmhyZWYgKSArIFwiXCIgKS5yZXBsYWNlKCByaGFzaCwgXCJcIiApXHJcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICk7XHJcblxyXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0XHJcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xyXG5cclxuXHRcdC8vIEV4dHJhY3QgZGF0YVR5cGVzIGxpc3RcclxuXHRcdHMuZGF0YVR5cGVzID0galF1ZXJ5LnRyaW0oIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcclxuXHJcblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gdGhlIG9yaWdpbiBkb2Vzbid0IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbi5cclxuXHRcdGlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkge1xyXG5cdFx0XHR1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LTExK1xyXG5cdFx0XHQvLyBJRSB0aHJvd3MgZXhjZXB0aW9uIGlmIHVybCBpcyBtYWxmb3JtZWQsIGUuZy4gaHR0cDovL2V4YW1wbGUuY29tOjgweC9cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHMudXJsO1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRTgtMTErXHJcblx0XHRcdFx0Ly8gQW5jaG9yJ3MgaG9zdCBwcm9wZXJ0eSBpc24ndCBjb3JyZWN0bHkgc2V0IHdoZW4gcy51cmwgaXMgcmVsYXRpdmVcclxuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHVybEFuY2hvci5ocmVmO1xyXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyBvcmlnaW5BbmNob3IuaG9zdCAhPT1cclxuXHRcdFx0XHRcdHVybEFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIHVybEFuY2hvci5ob3N0O1xyXG5cdFx0XHR9IGNhdGNoICggZSApIHtcclxuXHJcblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYW4gZXJyb3IgcGFyc2luZyB0aGUgVVJMLCBhc3N1bWUgaXQgaXMgY3Jvc3NEb21haW4sXHJcblx0XHRcdFx0Ly8gaXQgY2FuIGJlIHJlamVjdGVkIGJ5IHRoZSB0cmFuc3BvcnQgaWYgaXQgaXMgaW52YWxpZFxyXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXHJcblx0XHRpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmIHR5cGVvZiBzLmRhdGEgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xyXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XHJcblxyXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcclxuXHRcdGlmICggc3RhdGUgPT09IDIgKSB7XHJcblx0XHRcdHJldHVybiBqcVhIUjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xyXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKCMxNTExOClcclxuXHRcdGZpcmVHbG9iYWxzID0galF1ZXJ5LmV2ZW50ICYmIHMuZ2xvYmFsO1xyXG5cclxuXHRcdC8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHNcclxuXHRcdGlmICggZmlyZUdsb2JhbHMgJiYgalF1ZXJ5LmFjdGl2ZSsrID09PSAwICkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxyXG5cdFx0cy50eXBlID0gcy50eXBlLnRvVXBwZXJDYXNlKCk7XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcclxuXHRcdHMuaGFzQ29udGVudCA9ICFybm9Db250ZW50LnRlc3QoIHMudHlwZSApO1xyXG5cclxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxyXG5cdFx0Ly8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uXHJcblx0XHRjYWNoZVVSTCA9IHMudXJsO1xyXG5cclxuXHRcdC8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50XHJcblx0XHRpZiAoICFzLmhhc0NvbnRlbnQgKSB7XHJcblxyXG5cdFx0XHQvLyBJZiBkYXRhIGlzIGF2YWlsYWJsZSwgYXBwZW5kIGRhdGEgdG8gdXJsXHJcblx0XHRcdGlmICggcy5kYXRhICkge1xyXG5cdFx0XHRcdGNhY2hlVVJMID0gKCBzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdC8vICM5NjgyOiByZW1vdmUgZGF0YSBzbyB0aGF0IGl0J3Mgbm90IHVzZWQgaW4gYW4gZXZlbnR1YWwgcmV0cnlcclxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBZGQgYW50aS1jYWNoZSBpbiB1cmwgaWYgbmVlZGVkXHJcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XHJcblx0XHRcdFx0cy51cmwgPSBydHMudGVzdCggY2FjaGVVUkwgKSA/XHJcblxyXG5cdFx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYWxyZWFkeSBhICdfJyBwYXJhbWV0ZXIsIHNldCBpdHMgdmFsdWVcclxuXHRcdFx0XHRcdGNhY2hlVVJMLnJlcGxhY2UoIHJ0cywgXCIkMV89XCIgKyBub25jZSsrICkgOlxyXG5cclxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSBhZGQgb25lIHRvIHRoZSBlbmRcclxuXHRcdFx0XHRcdGNhY2hlVVJMICsgKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArIG5vbmNlKys7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxyXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHtcclxuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkge1xyXG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XHJcblx0XHRpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHtcclxuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcclxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXHJcblx0XHRcdFwiQWNjZXB0XCIsXHJcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1sgMCBdIF0gP1xyXG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdICtcclxuXHRcdFx0XHRcdCggcy5kYXRhVHlwZXNbIDAgXSAhPT0gXCIqXCIgPyBcIiwgXCIgKyBhbGxUeXBlcyArIFwiOyBxPTAuMDFcIiA6IFwiXCIgKSA6XHJcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXHJcblx0XHQpO1xyXG5cclxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxyXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XHJcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsb3cgY3VzdG9tIGhlYWRlcnMvbWltZXR5cGVzIGFuZCBlYXJseSBhYm9ydFxyXG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiZcclxuXHRcdFx0KCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBzdGF0ZSA9PT0gMiApICkge1xyXG5cclxuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXHJcblx0XHRcdHJldHVybiBqcVhIUi5hYm9ydCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEFib3J0aW5nIGlzIG5vIGxvbmdlciBhIGNhbmNlbGxhdGlvblxyXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XHJcblxyXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja3Mgb24gZGVmZXJyZWRzXHJcblx0XHRmb3IgKCBpIGluIHsgc3VjY2VzczogMSwgZXJyb3I6IDEsIGNvbXBsZXRlOiAxIH0gKSB7XHJcblx0XHRcdGpxWEhSWyBpIF0oIHNbIGkgXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEdldCB0cmFuc3BvcnRcclxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xyXG5cclxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxyXG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xyXG5cdFx0XHRkb25lKCAtMSwgXCJObyBUcmFuc3BvcnRcIiApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XHJcblxyXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxyXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xyXG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhTZW5kXCIsIFsganFYSFIsIHMgXSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhamF4U2VuZCwgc3RvcCB0aGVyZVxyXG5cdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xyXG5cdFx0XHRcdHJldHVybiBqcVhIUjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVGltZW91dFxyXG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcclxuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRqcVhIUi5hYm9ydCggXCJ0aW1lb3V0XCIgKTtcclxuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRzdGF0ZSA9IDE7XHJcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XHJcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xyXG5cclxuXHRcdFx0XHQvLyBQcm9wYWdhdGUgZXhjZXB0aW9uIGFzIGVycm9yIGlmIG5vdCBkb25lXHJcblx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XHJcblx0XHRcdFx0XHRkb25lKCAtMSwgZSApO1xyXG5cclxuXHRcdFx0XHQvLyBTaW1wbHkgcmV0aHJvdyBvdGhlcndpc2VcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dGhyb3cgZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcclxuXHRcdGZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkge1xyXG5cdFx0XHR2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLFxyXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xyXG5cclxuXHRcdFx0Ly8gQ2FsbGVkIG9uY2VcclxuXHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN0YXRlIGlzIFwiZG9uZVwiIG5vd1xyXG5cdFx0XHRzdGF0ZSA9IDI7XHJcblxyXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xyXG5cdFx0XHRpZiAoIHRpbWVvdXRUaW1lciApIHtcclxuXHRcdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb25cclxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcclxuXHRcdFx0dHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xyXG5cclxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xyXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8IFwiXCI7XHJcblxyXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxyXG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gc3RhdHVzID4gMCA/IDQgOiAwO1xyXG5cclxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcclxuXHRcdFx0aXNTdWNjZXNzID0gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDAgfHwgc3RhdHVzID09PSAzMDQ7XHJcblxyXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxyXG5cdFx0XHRpZiAoIHJlc3BvbnNlcyApIHtcclxuXHRcdFx0XHRyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KVxyXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xyXG5cclxuXHRcdFx0Ly8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmdcclxuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXHJcblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XHJcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkxhc3QtTW9kaWZpZWRcIiApO1xyXG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcclxuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJldGFnXCIgKTtcclxuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XHJcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XHJcblx0XHRcdFx0aWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09IFwiSEVBRFwiICkge1xyXG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XHJcblxyXG5cdFx0XHRcdC8vIGlmIG5vdCBtb2RpZmllZFxyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xyXG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcclxuXHJcblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSByZXNwb25zZS5zdGF0ZTtcclxuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xyXG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcclxuXHRcdFx0XHRcdGlzU3VjY2VzcyA9ICFlcnJvcjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdC8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHNcclxuXHRcdFx0XHRlcnJvciA9IHN0YXR1c1RleHQ7XHJcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XHJcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xyXG5cdFx0XHRcdFx0aWYgKCBzdGF0dXMgPCAwICkge1xyXG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gU2V0IGRhdGEgZm9yIHRoZSBmYWtlIHhociBvYmplY3RcclxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xyXG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XHJcblxyXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXHJcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xyXG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsgc3VjY2Vzcywgc3RhdHVzVGV4dCwganFYSFIgXSApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xyXG5cdFx0XHRqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7XHJcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XHJcblxyXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xyXG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxyXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ29tcGxldGVcclxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZC5maXJlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0IF0gKTtcclxuXHJcblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XHJcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheENvbXBsZXRlXCIsIFsganFYSFIsIHMgXSApO1xyXG5cclxuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXJcclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xyXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIFwiYWpheFN0b3BcIiApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBqcVhIUjtcclxuXHR9LFxyXG5cclxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcclxuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIGRhdGEsIGNhbGxiYWNrLCBcImpzb25cIiApO1xyXG5cdH0sXHJcblxyXG5cdGdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggaSwgbWV0aG9kICkge1xyXG5cdGpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHtcclxuXHJcblx0XHQvLyBTaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZGF0YSApICkge1xyXG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcclxuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xyXG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFRoZSB1cmwgY2FuIGJlIGFuIG9wdGlvbnMgb2JqZWN0ICh3aGljaCB0aGVuIG11c3QgaGF2ZSAudXJsKVxyXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KCBqUXVlcnkuZXh0ZW5kKCB7XHJcblx0XHRcdHVybDogdXJsLFxyXG5cdFx0XHR0eXBlOiBtZXRob2QsXHJcblx0XHRcdGRhdGFUeXBlOiB0eXBlLFxyXG5cdFx0XHRkYXRhOiBkYXRhLFxyXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xyXG5cdFx0fSwgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHVybCApICYmIHVybCApICk7XHJcblx0fTtcclxufSApO1xyXG5cclxuXHJcbmpRdWVyeS5fZXZhbFVybCA9IGZ1bmN0aW9uKCB1cmwgKSB7XHJcblx0cmV0dXJuIGpRdWVyeS5hamF4KCB7XHJcblx0XHR1cmw6IHVybCxcclxuXHJcblx0XHQvLyBNYWtlIHRoaXMgZXhwbGljaXQsIHNpbmNlIHVzZXIgY2FuIG92ZXJyaWRlIHRoaXMgdGhyb3VnaCBhamF4U2V0dXAgKCMxMTI2NClcclxuXHRcdHR5cGU6IFwiR0VUXCIsXHJcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcclxuXHRcdGFzeW5jOiBmYWxzZSxcclxuXHRcdGdsb2JhbDogZmFsc2UsXHJcblx0XHRcInRocm93c1wiOiB0cnVlXHJcblx0fSApO1xyXG59O1xyXG5cclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcclxuXHRcdHZhciB3cmFwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKSApIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbC5jYWxsKCB0aGlzLCBpICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdGhpc1sgMCBdICkge1xyXG5cclxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcclxuXHRcdFx0d3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7XHJcblxyXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0d3JhcC5tYXAoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBlbGVtID0gdGhpcztcclxuXHJcblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkge1xyXG5cdFx0XHRcdFx0ZWxlbSA9IGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRyZXR1cm4gZWxlbTtcclxuXHRcdFx0fSApLmFwcGVuZCggdGhpcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBJbm5lciggaHRtbC5jYWxsKCB0aGlzLCBpICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgc2VsZiA9IGpRdWVyeSggdGhpcyApLFxyXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xyXG5cclxuXHRcdFx0aWYgKCBjb250ZW50cy5sZW5ndGggKSB7XHJcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xyXG5cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0d3JhcDogZnVuY3Rpb24oIGh0bWwgKSB7XHJcblx0XHR2YXIgaXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICk7XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XHJcblx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGlzRnVuY3Rpb24gPyBodG1sLmNhbGwoIHRoaXMsIGkgKSA6IGh0bWwgKTtcclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cclxuXHR1bndyYXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMucGFyZW50KCkuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJib2R5XCIgKSApIHtcclxuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZXBsYWNlV2l0aCggdGhpcy5jaGlsZE5vZGVzICk7XHJcblx0XHRcdH1cclxuXHRcdH0gKS5lbmQoKTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5qUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdHJldHVybiAhalF1ZXJ5LmV4cHIuZmlsdGVycy52aXNpYmxlKCBlbGVtICk7XHJcbn07XHJcbmpRdWVyeS5leHByLmZpbHRlcnMudmlzaWJsZSA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHQvLyBTdXBwb3J0OiBPcGVyYSA8PSAxMi4xMlxyXG5cdC8vIE9wZXJhIHJlcG9ydHMgb2Zmc2V0V2lkdGhzIGFuZCBvZmZzZXRIZWlnaHRzIGxlc3MgdGhhbiB6ZXJvIG9uIHNvbWUgZWxlbWVudHNcclxuXHQvLyBVc2UgT1IgaW5zdGVhZCBvZiBBTkQgYXMgdGhlIGVsZW1lbnQgaXMgbm90IHZpc2libGUgaWYgZWl0aGVyIGlzIHRydWVcclxuXHQvLyBTZWUgdGlja2V0cyAjMTA0MDYgYW5kICMxMzEzMlxyXG5cdHJldHVybiBlbGVtLm9mZnNldFdpZHRoID4gMCB8fCBlbGVtLm9mZnNldEhlaWdodCA+IDAgfHwgZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCA+IDA7XHJcbn07XHJcblxyXG5cclxuXHJcblxyXG52YXIgcjIwID0gLyUyMC9nLFxyXG5cdHJicmFja2V0ID0gL1xcW1xcXSQvLFxyXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcclxuXHRyc3VibWl0dGVyVHlwZXMgPSAvXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksXHJcblx0cnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO1xyXG5cclxuZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkge1xyXG5cdHZhciBuYW1lO1xyXG5cclxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBvYmogKSApIHtcclxuXHJcblx0XHQvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cclxuXHRcdGpRdWVyeS5lYWNoKCBvYmosIGZ1bmN0aW9uKCBpLCB2ICkge1xyXG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xyXG5cclxuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXHJcblx0XHRcdFx0YWRkKCBwcmVmaXgsIHYgKTtcclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxyXG5cdFx0XHRcdGJ1aWxkUGFyYW1zKFxyXG5cdFx0XHRcdFx0cHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiICYmIHYgIT0gbnVsbCA/IGkgOiBcIlwiICkgKyBcIl1cIixcclxuXHRcdFx0XHRcdHYsXHJcblx0XHRcdFx0XHR0cmFkaXRpb25hbCxcclxuXHRcdFx0XHRcdGFkZFxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH0gKTtcclxuXHJcblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcclxuXHJcblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXHJcblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcclxuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS5cclxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcclxuXHR9XHJcbn1cclxuXHJcbi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mXHJcbi8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZ1xyXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XHJcblx0dmFyIHByZWZpeCxcclxuXHRcdHMgPSBbXSxcclxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xyXG5cclxuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXHJcblx0XHRcdHZhbHVlID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgPyB2YWx1ZSgpIDogKCB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICk7XHJcblx0XHRcdHNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoIHZhbHVlICk7XHJcblx0XHR9O1xyXG5cclxuXHQvLyBTZXQgdHJhZGl0aW9uYWwgdG8gdHJ1ZSBmb3IgalF1ZXJ5IDw9IDEuMy4yIGJlaGF2aW9yLlxyXG5cdGlmICggdHJhZGl0aW9uYWwgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdHRyYWRpdGlvbmFsID0galF1ZXJ5LmFqYXhTZXR0aW5ncyAmJiBqUXVlcnkuYWpheFNldHRpbmdzLnRyYWRpdGlvbmFsO1xyXG5cdH1cclxuXHJcblx0Ly8gSWYgYW4gYXJyYXkgd2FzIHBhc3NlZCBpbiwgYXNzdW1lIHRoYXQgaXQgaXMgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cy5cclxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBhICkgfHwgKCBhLmpxdWVyeSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGEgKSApICkge1xyXG5cclxuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xyXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRhZGQoIHRoaXMubmFtZSwgdGhpcy52YWx1ZSApO1xyXG5cdFx0fSApO1xyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXHJcblx0XHQvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cclxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xyXG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmV0dXJuIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvblxyXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICkucmVwbGFjZSggcjIwLCBcIitcIiApO1xyXG59O1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcclxuXHR9LFxyXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXHJcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcclxuXHRcdFx0cmV0dXJuIGVsZW1lbnRzID8galF1ZXJ5Lm1ha2VBcnJheSggZWxlbWVudHMgKSA6IHRoaXM7XHJcblx0XHR9IClcclxuXHRcdC5maWx0ZXIoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgdHlwZSA9IHRoaXMudHlwZTtcclxuXHJcblx0XHRcdC8vIFVzZSAuaXMoIFwiOmRpc2FibGVkXCIgKSBzbyB0aGF0IGZpZWxkc2V0W2Rpc2FibGVkXSB3b3Jrc1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5uYW1lICYmICFqUXVlcnkoIHRoaXMgKS5pcyggXCI6ZGlzYWJsZWRcIiApICYmXHJcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxyXG5cdFx0XHRcdCggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTtcclxuXHRcdH0gKVxyXG5cdFx0Lm1hcCggZnVuY3Rpb24oIGksIGVsZW0gKSB7XHJcblx0XHRcdHZhciB2YWwgPSBqUXVlcnkoIHRoaXMgKS52YWwoKTtcclxuXHJcblx0XHRcdHJldHVybiB2YWwgPT0gbnVsbCA/XHJcblx0XHRcdFx0bnVsbCA6XHJcblx0XHRcdFx0alF1ZXJ5LmlzQXJyYXkoIHZhbCApID9cclxuXHRcdFx0XHRcdGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcclxuXHRcdFx0XHRcdH0gKSA6XHJcblx0XHRcdFx0XHR7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XHJcblx0XHR9ICkuZ2V0KCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxualF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIgPSBmdW5jdGlvbigpIHtcclxuXHR0cnkge1xyXG5cdFx0cmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcclxuXHR9IGNhdGNoICggZSApIHt9XHJcbn07XHJcblxyXG52YXIgeGhyU3VjY2Vzc1N0YXR1cyA9IHtcclxuXHJcblx0XHQvLyBGaWxlIHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIGNvZGUgMCwgYXNzdW1lIDIwMFxyXG5cdFx0MDogMjAwLFxyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFOVxyXG5cdFx0Ly8gIzE0NTA6IHNvbWV0aW1lcyBJRSByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XHJcblx0XHQxMjIzOiAyMDRcclxuXHR9LFxyXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XHJcblxyXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XHJcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xyXG5cclxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIGZ1bmN0aW9uKCBvcHRpb25zICkge1xyXG5cdHZhciBjYWxsYmFjaywgZXJyb3JDYWxsYmFjaztcclxuXHJcblx0Ly8gQ3Jvc3MgZG9tYWluIG9ubHkgYWxsb3dlZCBpZiBzdXBwb3J0ZWQgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdFxyXG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBoZWFkZXJzLCBjb21wbGV0ZSApIHtcclxuXHRcdFx0XHR2YXIgaSxcclxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCk7XHJcblxyXG5cdFx0XHRcdHhoci5vcGVuKFxyXG5cdFx0XHRcdFx0b3B0aW9ucy50eXBlLFxyXG5cdFx0XHRcdFx0b3B0aW9ucy51cmwsXHJcblx0XHRcdFx0XHRvcHRpb25zLmFzeW5jLFxyXG5cdFx0XHRcdFx0b3B0aW9ucy51c2VybmFtZSxcclxuXHRcdFx0XHRcdG9wdGlvbnMucGFzc3dvcmRcclxuXHRcdFx0XHQpO1xyXG5cclxuXHRcdFx0XHQvLyBBcHBseSBjdXN0b20gZmllbGRzIGlmIHByb3ZpZGVkXHJcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcclxuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XHJcblx0XHRcdFx0XHRcdHhoclsgaSBdID0gb3B0aW9ucy54aHJGaWVsZHNbIGkgXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcclxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XHJcblx0XHRcdFx0XHR4aHIub3ZlcnJpZGVNaW1lVHlwZSggb3B0aW9ucy5taW1lVHlwZSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gWC1SZXF1ZXN0ZWQtV2l0aCBoZWFkZXJcclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXHJcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cclxuXHRcdFx0XHQvLyAoaXQgY2FuIGFsd2F5cyBiZSBzZXQgb24gYSBwZXItcmVxdWVzdCBiYXNpcyBvciBldmVuIHVzaW5nIGFqYXhTZXR1cClcclxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cclxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdICkge1xyXG5cdFx0XHRcdFx0aGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXHJcblx0XHRcdFx0Zm9yICggaSBpbiBoZWFkZXJzICkge1xyXG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQ2FsbGJhY2tcclxuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xyXG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0gZXJyb3JDYWxsYmFjayA9IHhoci5vbmxvYWQgPVxyXG5cdFx0XHRcdFx0XHRcdFx0eGhyLm9uZXJyb3IgPSB4aHIub25hYm9ydCA9IHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xyXG5cclxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHhoci5hYm9ydCgpO1xyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IFwiZXJyb3JcIiApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTlcclxuXHRcdFx0XHRcdFx0XHRcdC8vIE9uIGEgbWFudWFsIG5hdGl2ZSBhYm9ydCwgSUU5IHRocm93c1xyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gZXJyb3JzIG9uIGFueSBwcm9wZXJ0eSBhY2Nlc3MgdGhhdCBpcyBub3QgcmVhZHlTdGF0ZVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgeGhyLnN0YXR1cyAhPT0gXCJudW1iZXJcIiApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIDAsIFwiZXJyb3JcIiApO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1cyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyU3VjY2Vzc1N0YXR1c1sgeGhyLnN0YXR1cyBdIHx8IHhoci5zdGF0dXMsXHJcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUU5IG9ubHlcclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxyXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgWEhSMiBub24tdGV4dCwgbGV0IHRoZSBjYWxsZXIgaGFuZGxlIGl0IChnaC0yNDk4KVxyXG5cdFx0XHRcdFx0XHRcdFx0XHQoIHhoci5yZXNwb25zZVR5cGUgfHwgXCJ0ZXh0XCIgKSAhPT0gXCJ0ZXh0XCIgIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7IGJpbmFyeTogeGhyLnJlc3BvbnNlIH0gOlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHsgdGV4dDogeGhyLnJlc3BvbnNlVGV4dCB9LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcclxuXHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH07XHJcblxyXG5cdFx0XHRcdC8vIExpc3RlbiB0byBldmVudHNcclxuXHRcdFx0XHR4aHIub25sb2FkID0gY2FsbGJhY2soKTtcclxuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSBjYWxsYmFjayggXCJlcnJvclwiICk7XHJcblxyXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFOVxyXG5cdFx0XHRcdC8vIFVzZSBvbnJlYWR5c3RhdGVjaGFuZ2UgdG8gcmVwbGFjZSBvbmFib3J0XHJcblx0XHRcdFx0Ly8gdG8gaGFuZGxlIHVuY2F1Z2h0IGFib3J0c1xyXG5cdFx0XHRcdGlmICggeGhyLm9uYWJvcnQgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdHhoci5vbmFib3J0ID0gZXJyb3JDYWxsYmFjaztcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gQ2hlY2sgcmVhZHlTdGF0ZSBiZWZvcmUgdGltZW91dCBhcyBpdCBjaGFuZ2VzXHJcblx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIEFsbG93IG9uZXJyb3IgdG8gYmUgY2FsbGVkIGZpcnN0LFxyXG5cdFx0XHRcdFx0XHRcdC8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydFxyXG5cdFx0XHRcdFx0XHRcdC8vIEFsc28sIHNhdmUgZXJyb3JDYWxsYmFjayB0byBhIHZhcmlhYmxlXHJcblx0XHRcdFx0XHRcdFx0Ly8gYXMgeGhyLm9uZXJyb3IgY2Fubm90IGJlIGFjY2Vzc2VkXHJcblx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0ZXJyb3JDYWxsYmFjaygpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2tcclxuXHRcdFx0XHRjYWxsYmFjayA9IGNhbGxiYWNrKCBcImFib3J0XCIgKTtcclxuXHJcblx0XHRcdFx0dHJ5IHtcclxuXHJcblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pXHJcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XHJcblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gIzE0NjgzOiBPbmx5IHJldGhyb3cgaWYgdGhpcyBoYXNuJ3QgYmVlbiBub3RpZmllZCBhcyBhbiBlcnJvciB5ZXRcclxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRcdHRocm93IGU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbi8vIEluc3RhbGwgc2NyaXB0IGRhdGFUeXBlXHJcbmpRdWVyeS5hamF4U2V0dXAoIHtcclxuXHRhY2NlcHRzOiB7XHJcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBcIiArXHJcblx0XHRcdFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcclxuXHR9LFxyXG5cdGNvbnRlbnRzOiB7XHJcblx0XHRzY3JpcHQ6IC9cXGIoPzpqYXZhfGVjbWEpc2NyaXB0XFxiL1xyXG5cdH0sXHJcblx0Y29udmVydGVyczoge1xyXG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcclxuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcclxuXHRcdFx0cmV0dXJuIHRleHQ7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXHJcbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcclxuXHRpZiAoIHMuY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdHMuY2FjaGUgPSBmYWxzZTtcclxuXHR9XHJcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xyXG5cdFx0cy50eXBlID0gXCJHRVRcIjtcclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxyXG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XHJcblxyXG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gcmVxdWVzdHNcclxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XHJcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBfLCBjb21wbGV0ZSApIHtcclxuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoIFwiPHNjcmlwdD5cIiApLnByb3AoIHtcclxuXHRcdFx0XHRcdGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCxcclxuXHRcdFx0XHRcdHNyYzogcy51cmxcclxuXHRcdFx0XHR9ICkub24oXHJcblx0XHRcdFx0XHRcImxvYWQgZXJyb3JcIixcclxuXHRcdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHtcclxuXHRcdFx0XHRcdFx0c2NyaXB0LnJlbW92ZSgpO1xyXG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XHJcblx0XHRcdFx0XHRcdGlmICggZXZ0ICkge1xyXG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCBldnQudHlwZSA9PT0gXCJlcnJvclwiID8gNDA0IDogMjAwLCBldnQudHlwZSApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdFx0Ly8gVXNlIG5hdGl2ZSBET00gbWFuaXB1bGF0aW9uIHRvIGF2b2lkIG91ciBkb21NYW5pcCBBSkFYIHRyaWNrZXJ5XHJcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0WyAwIF0gKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcclxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xyXG5cclxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xyXG5qUXVlcnkuYWpheFNldHVwKCB7XHJcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcclxuXHRqc29ucENhbGxiYWNrOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlKysgKSApO1xyXG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XHJcblx0XHRyZXR1cm4gY2FsbGJhY2s7XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBEZXRlY3QsIG5vcm1hbGl6ZSBvcHRpb25zIGFuZCBpbnN0YWxsIGNhbGxiYWNrcyBmb3IganNvbnAgcmVxdWVzdHNcclxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XHJcblxyXG5cdHZhciBjYWxsYmFja05hbWUsIG92ZXJ3cml0dGVuLCByZXNwb25zZUNvbnRhaW5lcixcclxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XHJcblx0XHRcdFwidXJsXCIgOlxyXG5cdFx0XHR0eXBlb2Ygcy5kYXRhID09PSBcInN0cmluZ1wiICYmXHJcblx0XHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKVxyXG5cdFx0XHRcdFx0LmluZGV4T2YoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIgKSA9PT0gMCAmJlxyXG5cdFx0XHRcdHJqc29ucC50ZXN0KCBzLmRhdGEgKSAmJiBcImRhdGFcIlxyXG5cdFx0KTtcclxuXHJcblx0Ly8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzIFwianNvbnBcIiBvciB3ZSBoYXZlIGEgcGFyYW1ldGVyIHRvIHNldFxyXG5cdGlmICgganNvblByb3AgfHwgcy5kYXRhVHlwZXNbIDAgXSA9PT0gXCJqc29ucFwiICkge1xyXG5cclxuXHRcdC8vIEdldCBjYWxsYmFjayBuYW1lLCByZW1lbWJlcmluZyBwcmVleGlzdGluZyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggaXRcclxuXHRcdGNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBzLmpzb25wQ2FsbGJhY2sgKSA/XHJcblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcclxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xyXG5cclxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcclxuXHRcdGlmICgganNvblByb3AgKSB7XHJcblx0XHRcdHNbIGpzb25Qcm9wIF0gPSBzWyBqc29uUHJvcCBdLnJlcGxhY2UoIHJqc29ucCwgXCIkMVwiICsgY2FsbGJhY2tOYW1lICk7XHJcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcclxuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXHJcblx0XHRzLmNvbnZlcnRlcnNbIFwic2NyaXB0IGpzb25cIiBdID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xyXG5cdFx0XHRcdGpRdWVyeS5lcnJvciggY2FsbGJhY2tOYW1lICsgXCIgd2FzIG5vdCBjYWxsZWRcIiApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBGb3JjZSBqc29uIGRhdGFUeXBlXHJcblx0XHRzLmRhdGFUeXBlc1sgMCBdID0gXCJqc29uXCI7XHJcblxyXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xyXG5cdFx0b3ZlcndyaXR0ZW4gPSB3aW5kb3dbIGNhbGxiYWNrTmFtZSBdO1xyXG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXHJcblx0XHRqcVhIUi5hbHdheXMoIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gSWYgcHJldmlvdXMgdmFsdWUgZGlkbid0IGV4aXN0IC0gcmVtb3ZlIGl0XHJcblx0XHRcdGlmICggb3ZlcndyaXR0ZW4gPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRqUXVlcnkoIHdpbmRvdyApLnJlbW92ZVByb3AoIGNhbGxiYWNrTmFtZSApO1xyXG5cclxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gb3ZlcndyaXR0ZW47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNhdmUgYmFjayBhcyBmcmVlXHJcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XHJcblxyXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxyXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcclxuXHJcblx0XHRcdFx0Ly8gU2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxyXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXHJcblx0XHRcdGlmICggcmVzcG9uc2VDb250YWluZXIgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIG92ZXJ3cml0dGVuICkgKSB7XHJcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcclxuXHRcdH0gKTtcclxuXHJcblx0XHQvLyBEZWxlZ2F0ZSB0byBzY3JpcHRcclxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcblxyXG5cclxuLy8gQXJndW1lbnQgXCJkYXRhXCIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sXHJcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCxcclxuLy8gZGVmYXVsdHMgdG8gZG9jdW1lbnRcclxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xyXG5qUXVlcnkucGFyc2VIVE1MID0gZnVuY3Rpb24oIGRhdGEsIGNvbnRleHQsIGtlZXBTY3JpcHRzICkge1xyXG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9XHJcblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XHJcblx0XHRrZWVwU2NyaXB0cyA9IGNvbnRleHQ7XHJcblx0XHRjb250ZXh0ID0gZmFsc2U7XHJcblx0fVxyXG5cdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xyXG5cclxuXHR2YXIgcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICksXHJcblx0XHRzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdO1xyXG5cclxuXHQvLyBTaW5nbGUgdGFnXHJcblx0aWYgKCBwYXJzZWQgKSB7XHJcblx0XHRyZXR1cm4gWyBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIHBhcnNlZFsgMSBdICkgXTtcclxuXHR9XHJcblxyXG5cdHBhcnNlZCA9IGJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XHJcblxyXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcclxuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XHJcbn07XHJcblxyXG5cclxuLy8gS2VlcCBhIGNvcHkgb2YgdGhlIG9sZCBsb2FkIG1ldGhvZFxyXG52YXIgX2xvYWQgPSBqUXVlcnkuZm4ubG9hZDtcclxuXHJcbi8qKlxyXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXHJcbiAqL1xyXG5qUXVlcnkuZm4ubG9hZCA9IGZ1bmN0aW9uKCB1cmwsIHBhcmFtcywgY2FsbGJhY2sgKSB7XHJcblx0aWYgKCB0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiICYmIF9sb2FkICkge1xyXG5cdFx0cmV0dXJuIF9sb2FkLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHR9XHJcblxyXG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXHJcblx0XHRzZWxmID0gdGhpcyxcclxuXHRcdG9mZiA9IHVybC5pbmRleE9mKCBcIiBcIiApO1xyXG5cclxuXHRpZiAoIG9mZiA+IC0xICkge1xyXG5cdFx0c2VsZWN0b3IgPSBqUXVlcnkudHJpbSggdXJsLnNsaWNlKCBvZmYgKSApO1xyXG5cdFx0dXJsID0gdXJsLnNsaWNlKCAwLCBvZmYgKTtcclxuXHR9XHJcblxyXG5cdC8vIElmIGl0J3MgYSBmdW5jdGlvblxyXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xyXG5cclxuXHRcdC8vIFdlIGFzc3VtZSB0aGF0IGl0J3MgdGhlIGNhbGxiYWNrXHJcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcclxuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcclxuXHJcblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xyXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xyXG5cdFx0dHlwZSA9IFwiUE9TVFwiO1xyXG5cdH1cclxuXHJcblx0Ly8gSWYgd2UgaGF2ZSBlbGVtZW50cyB0byBtb2RpZnksIG1ha2UgdGhlIHJlcXVlc3RcclxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcclxuXHRcdGpRdWVyeS5hamF4KCB7XHJcblx0XHRcdHVybDogdXJsLFxyXG5cclxuXHRcdFx0Ly8gSWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZC5cclxuXHRcdFx0Ly8gTWFrZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIGV4cGxpY2l0IHNpbmNlXHJcblx0XHRcdC8vIHVzZXIgY2FuIG92ZXJyaWRlIGl0IHRocm91Z2ggYWpheFNldHVwIG1ldGhvZFxyXG5cdFx0XHR0eXBlOiB0eXBlIHx8IFwiR0VUXCIsXHJcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcclxuXHRcdFx0ZGF0YTogcGFyYW1zXHJcblx0XHR9ICkuZG9uZSggZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcclxuXHJcblx0XHRcdC8vIFNhdmUgcmVzcG9uc2UgZm9yIHVzZSBpbiBjb21wbGV0ZSBjYWxsYmFja1xyXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcclxuXHJcblx0XHRcdHNlbGYuaHRtbCggc2VsZWN0b3IgP1xyXG5cclxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcclxuXHRcdFx0XHQvLyBFeGNsdWRlIHNjcmlwdHMgdG8gYXZvaWQgSUUgJ1Blcm1pc3Npb24gRGVuaWVkJyBlcnJvcnNcclxuXHRcdFx0XHRqUXVlcnkoIFwiPGRpdj5cIiApLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcclxuXHJcblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcclxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcclxuXHJcblx0XHQvLyBJZiB0aGUgcmVxdWVzdCBzdWNjZWVkcywgdGhpcyBmdW5jdGlvbiBnZXRzIFwiZGF0YVwiLCBcInN0YXR1c1wiLCBcImpxWEhSXCJcclxuXHRcdC8vIGJ1dCB0aGV5IGFyZSBpZ25vcmVkIGJlY2F1c2UgcmVzcG9uc2Ugd2FzIHNldCBhYm92ZS5cclxuXHRcdC8vIElmIGl0IGZhaWxzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJqcVhIUlwiLCBcInN0YXR1c1wiLCBcImVycm9yXCJcclxuXHRcdH0gKS5hbHdheXMoIGNhbGxiYWNrICYmIGZ1bmN0aW9uKCBqcVhIUiwgc3RhdHVzICkge1xyXG5cdFx0XHRzZWxmLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH0gKTtcclxuXHR9XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuXHJcblxyXG5cclxuLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHNcclxualF1ZXJ5LmVhY2goIFtcclxuXHRcImFqYXhTdGFydFwiLFxyXG5cdFwiYWpheFN0b3BcIixcclxuXHRcImFqYXhDb21wbGV0ZVwiLFxyXG5cdFwiYWpheEVycm9yXCIsXHJcblx0XCJhamF4U3VjY2Vzc1wiLFxyXG5cdFwiYWpheFNlbmRcIlxyXG5dLCBmdW5jdGlvbiggaSwgdHlwZSApIHtcclxuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcclxuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xyXG5cdH07XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbmpRdWVyeS5leHByLmZpbHRlcnMuYW5pbWF0ZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcclxuXHRcdHJldHVybiBlbGVtID09PSBmbi5lbGVtO1xyXG5cdH0gKS5sZW5ndGg7XHJcbn07XHJcblxyXG5cclxuXHJcblxyXG4vKipcclxuICogR2V0cyBhIHdpbmRvdyBmcm9tIGFuIGVsZW1lbnRcclxuICovXHJcbmZ1bmN0aW9uIGdldFdpbmRvdyggZWxlbSApIHtcclxuXHRyZXR1cm4galF1ZXJ5LmlzV2luZG93KCBlbGVtICkgPyBlbGVtIDogZWxlbS5ub2RlVHlwZSA9PT0gOSAmJiBlbGVtLmRlZmF1bHRWaWV3O1xyXG59XHJcblxyXG5qUXVlcnkub2Zmc2V0ID0ge1xyXG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XHJcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxyXG5cdFx0XHRwb3NpdGlvbiA9IGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApLFxyXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXHJcblx0XHRcdHByb3BzID0ge307XHJcblxyXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxyXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcclxuXHRcdFx0ZWxlbS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcclxuXHRcdH1cclxuXHJcblx0XHRjdXJPZmZzZXQgPSBjdXJFbGVtLm9mZnNldCgpO1xyXG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xyXG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XHJcblx0XHRjYWxjdWxhdGVQb3NpdGlvbiA9ICggcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiICkgJiZcclxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZiggXCJhdXRvXCIgKSA+IC0xO1xyXG5cclxuXHRcdC8vIE5lZWQgdG8gYmUgYWJsZSB0byBjYWxjdWxhdGUgcG9zaXRpb24gaWYgZWl0aGVyXHJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcclxuXHRcdGlmICggY2FsY3VsYXRlUG9zaXRpb24gKSB7XHJcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xyXG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XHJcblx0XHRcdGN1ckxlZnQgPSBjdXJQb3NpdGlvbi5sZWZ0O1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGN1clRvcCA9IHBhcnNlRmxvYXQoIGN1ckNTU1RvcCApIHx8IDA7XHJcblx0XHRcdGN1ckxlZnQgPSBwYXJzZUZsb2F0KCBjdXJDU1NMZWZ0ICkgfHwgMDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XHJcblxyXG5cdFx0XHQvLyBVc2UgalF1ZXJ5LmV4dGVuZCBoZXJlIHRvIGFsbG93IG1vZGlmaWNhdGlvbiBvZiBjb29yZGluYXRlcyBhcmd1bWVudCAoZ2gtMTg0OClcclxuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMuY2FsbCggZWxlbSwgaSwgalF1ZXJ5LmV4dGVuZCgge30sIGN1ck9mZnNldCApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBvcHRpb25zLnRvcCAhPSBudWxsICkge1xyXG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHtcclxuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcclxuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xyXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xyXG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cclxuXHRcdFx0XHR0aGlzIDpcclxuXHRcdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcclxuXHRcdFx0XHR9ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGRvY0VsZW0sIHdpbixcclxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcclxuXHRcdFx0Ym94ID0geyB0b3A6IDAsIGxlZnQ6IDAgfSxcclxuXHRcdFx0ZG9jID0gZWxlbSAmJiBlbGVtLm93bmVyRG9jdW1lbnQ7XHJcblxyXG5cdFx0aWYgKCAhZG9jICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG5cdFx0Ly8gTWFrZSBzdXJlIGl0J3Mgbm90IGEgZGlzY29ubmVjdGVkIERPTSBub2RlXHJcblx0XHRpZiAoICFqUXVlcnkuY29udGFpbnMoIGRvY0VsZW0sIGVsZW0gKSApIHtcclxuXHRcdFx0cmV0dXJuIGJveDtcclxuXHRcdH1cclxuXHJcblx0XHRib3ggPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cdFx0d2luID0gZ2V0V2luZG93KCBkb2MgKTtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRvcDogYm94LnRvcCArIHdpbi5wYWdlWU9mZnNldCAtIGRvY0VsZW0uY2xpZW50VG9wLFxyXG5cdFx0XHRsZWZ0OiBib3gubGVmdCArIHdpbi5wYWdlWE9mZnNldCAtIGRvY0VsZW0uY2xpZW50TGVmdFxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgb2Zmc2V0UGFyZW50LCBvZmZzZXQsXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXHJcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XHJcblxyXG5cdFx0Ly8gRml4ZWQgZWxlbWVudHMgYXJlIG9mZnNldCBmcm9tIHdpbmRvdyAocGFyZW50T2Zmc2V0ID0ge3RvcDowLCBsZWZ0OiAwfSxcclxuXHRcdC8vIGJlY2F1c2UgaXQgaXMgaXRzIG9ubHkgb2Zmc2V0IHBhcmVudFxyXG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xyXG5cclxuXHRcdFx0Ly8gQXNzdW1lIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBpcyB0aGVyZSB3aGVuIGNvbXB1dGVkIHBvc2l0aW9uIGlzIGZpeGVkXHJcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50XHJcblx0XHRcdG9mZnNldFBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50KCk7XHJcblxyXG5cdFx0XHQvLyBHZXQgY29ycmVjdCBvZmZzZXRzXHJcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XHJcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggb2Zmc2V0UGFyZW50WyAwIF0sIFwiaHRtbFwiICkgKSB7XHJcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcclxuXHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJUb3BXaWR0aFwiLCB0cnVlICk7XHJcblx0XHRcdHBhcmVudE9mZnNldC5sZWZ0ICs9IGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudFsgMCBdLCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0dG9wOiBvZmZzZXQudG9wIC0gcGFyZW50T2Zmc2V0LnRvcCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luVG9wXCIsIHRydWUgKSxcclxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0Ly8gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZG9jdW1lbnRFbGVtZW50IGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6XHJcblx0Ly8gMSkgRm9yIHRoZSBlbGVtZW50IGluc2lkZSB0aGUgaWZyYW1lIHdpdGhvdXQgb2Zmc2V0UGFyZW50LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVyblxyXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xyXG5cdC8vIDIpIEZvciB0aGUgaGlkZGVuIG9yIGRldGFjaGVkIGVsZW1lbnRcclxuXHQvLyAzKSBGb3IgYm9keSBvciBodG1sIGVsZW1lbnQsIGkuZS4gaW4gY2FzZSBvZiB0aGUgaHRtbCBub2RlIC0gaXQgd2lsbCByZXR1cm4gaXRzZWxmXHJcblx0Ly9cclxuXHQvLyBidXQgdGhvc2UgZXhjZXB0aW9ucyB3ZXJlIG5ldmVyIHByZXNlbnRlZCBhcyBhIHJlYWwgbGlmZSB1c2UtY2FzZXNcclxuXHQvLyBhbmQgbWlnaHQgYmUgY29uc2lkZXJlZCBhcyBtb3JlIHByZWZlcmFibGUgcmVzdWx0cy5cclxuXHQvL1xyXG5cdC8vIFRoaXMgbG9naWMsIGhvd2V2ZXIsIGlzIG5vdCBndWFyYW50ZWVkIGFuZCBjYW4gY2hhbmdlIGF0IGFueSBwb2ludCBpbiB0aGUgZnV0dXJlXHJcblx0b2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudDtcclxuXHJcblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XHJcblx0XHRcdFx0b2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50Lm9mZnNldFBhcmVudDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2N1bWVudEVsZW1lbnQ7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcclxualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xyXG5cdHZhciB0b3AgPSBcInBhZ2VZT2Zmc2V0XCIgPT09IHByb3A7XHJcblxyXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG1ldGhvZCwgdmFsICkge1xyXG5cdFx0XHR2YXIgd2luID0gZ2V0V2luZG93KCBlbGVtICk7XHJcblxyXG5cdFx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIHdpbiApIHtcclxuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXHJcblx0XHRcdFx0XHQhdG9wID8gdmFsIDogd2luLnBhZ2VYT2Zmc2V0LFxyXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luLnBhZ2VZT2Zmc2V0XHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XHJcblx0XHRcdH1cclxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoICk7XHJcblx0fTtcclxufSApO1xyXG5cclxuLy8gU3VwcG9ydDogU2FmYXJpPDctOCssIENocm9tZTwzNy00NCtcclxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cclxuLy8gV2Via2l0IGJ1ZzogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTI5MDg0XHJcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTIyOTI4MFxyXG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0O1xyXG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwganVzdCBjaGVjayBmb3IgaXQgaGVyZVxyXG5qUXVlcnkuZWFjaCggWyBcInRvcFwiLCBcImxlZnRcIiBdLCBmdW5jdGlvbiggaSwgcHJvcCApIHtcclxuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxyXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xyXG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XHJcblxyXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxyXG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XHJcblx0XHRcdFx0XHRqUXVlcnkoIGVsZW0gKS5wb3NpdGlvbigpWyBwcm9wIF0gKyBcInB4XCIgOlxyXG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHQpO1xyXG59ICk7XHJcblxyXG5cclxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXHJcbmpRdWVyeS5lYWNoKCB7IEhlaWdodDogXCJoZWlnaHRcIiwgV2lkdGg6IFwid2lkdGhcIiB9LCBmdW5jdGlvbiggbmFtZSwgdHlwZSApIHtcclxuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sXHJcblx0XHRmdW5jdGlvbiggZGVmYXVsdEV4dHJhLCBmdW5jTmFtZSApIHtcclxuXHJcblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcclxuXHRcdGpRdWVyeS5mblsgZnVuY05hbWUgXSA9IGZ1bmN0aW9uKCBtYXJnaW4sIHZhbHVlICkge1xyXG5cdFx0XHR2YXIgY2hhaW5hYmxlID0gYXJndW1lbnRzLmxlbmd0aCAmJiAoIGRlZmF1bHRFeHRyYSB8fCB0eXBlb2YgbWFyZ2luICE9PSBcImJvb2xlYW5cIiApLFxyXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcclxuXHJcblx0XHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHtcclxuXHRcdFx0XHR2YXIgZG9jO1xyXG5cclxuXHRcdFx0XHRpZiAoIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIEFzIG9mIDUvOC8yMDEyIHRoaXMgd2lsbCB5aWVsZCBpbmNvcnJlY3QgcmVzdWx0cyBmb3IgTW9iaWxlIFNhZmFyaSwgYnV0IHRoZXJlXHJcblx0XHRcdFx0XHQvLyBpc24ndCBhIHdob2xlIGxvdCB3ZSBjYW4gZG8uIFNlZSBwdWxsIHJlcXVlc3QgYXQgdGhpcyBVUkwgZm9yIGRpc2N1c3Npb246XHJcblx0XHRcdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzc2NFxyXG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyBcImNsaWVudFwiICsgbmFtZSBdO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gR2V0IGRvY3VtZW50IHdpZHRoIG9yIGhlaWdodFxyXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xyXG5cclxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcclxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxyXG5cdFx0XHRcdFx0cmV0dXJuIE1hdGgubWF4KFxyXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcclxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXHJcblx0XHRcdFx0XHRcdGRvY1sgXCJjbGllbnRcIiArIG5hbWUgXVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cclxuXHJcblx0XHRcdFx0XHQvLyBHZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50LCByZXF1ZXN0aW5nIGJ1dCBub3QgZm9yY2luZyBwYXJzZUZsb2F0XHJcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCB0eXBlLCBleHRyYSApIDpcclxuXHJcblx0XHRcdFx0XHQvLyBTZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50XHJcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApO1xyXG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSwgbnVsbCApO1xyXG5cdFx0fTtcclxuXHR9ICk7XHJcbn0gKTtcclxuXHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblxyXG5cdGJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZGF0YSwgZm4gKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XHJcblx0fSxcclxuXHR1bmJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZm4gKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xyXG5cdH0sXHJcblxyXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XHJcblx0fSxcclxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcclxuXHJcblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXHJcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XHJcblx0XHRcdHRoaXMub2ZmKCBzZWxlY3RvciwgXCIqKlwiICkgOlxyXG5cdFx0XHR0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcclxuXHR9LFxyXG5cdHNpemU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMubGVuZ3RoO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmFuZFNlbGYgPSBqUXVlcnkuZm4uYWRkQmFjaztcclxuXHJcblxyXG5cclxuXHJcbi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlclxyXG4vLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0XHJcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxyXG4vLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlXHJcbi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZVxyXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcclxuLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLlxyXG5cclxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcclxuLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhblxyXG4vLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXHJcblxyXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xyXG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeTtcclxuXHR9ICk7XHJcbn1cclxuXHJcblxyXG5cclxudmFyXHJcblxyXG5cdC8vIE1hcCBvdmVyIGpRdWVyeSBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxyXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxyXG5cclxuXHQvLyBNYXAgb3ZlciB0aGUgJCBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxyXG5cdF8kID0gd2luZG93LiQ7XHJcblxyXG5qUXVlcnkubm9Db25mbGljdCA9IGZ1bmN0aW9uKCBkZWVwICkge1xyXG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcclxuXHRcdHdpbmRvdy4kID0gXyQ7XHJcblx0fVxyXG5cclxuXHRpZiAoIGRlZXAgJiYgd2luZG93LmpRdWVyeSA9PT0galF1ZXJ5ICkge1xyXG5cdFx0d2luZG93LmpRdWVyeSA9IF9qUXVlcnk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4galF1ZXJ5O1xyXG59O1xyXG5cclxuLy8gRXhwb3NlIGpRdWVyeSBhbmQgJCBpZGVudGlmaWVycywgZXZlbiBpbiBBTURcclxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxyXG4vLyBhbmQgQ29tbW9uSlMgZm9yIGJyb3dzZXIgZW11bGF0b3JzICgjMTM1NjYpXHJcbmlmICggIW5vR2xvYmFsICkge1xyXG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcclxufVxyXG5cclxucmV0dXJuIGpRdWVyeTtcclxufSkpO1xyXG5cbjsgYnJvd3NlcmlmeV9zaGltX19kZWZpbmVfX21vZHVsZV9fZXhwb3J0X18odHlwZW9mICQgIT0gXCJ1bmRlZmluZWRcIiA/ICQgOiB3aW5kb3cuJCk7XG5cbn0pLmNhbGwoZ2xvYmFsLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGZ1bmN0aW9uIGRlZmluZUV4cG9ydChleCkgeyBtb2R1bGUuZXhwb3J0cyA9IGV4OyB9KTtcbiIsIi8qISBsaWdodHNsaWRlciAtIHYxLjEuNiAtIDIwMTYtMTAtMjVcclxuKiBodHRwczovL2dpdGh1Yi5jb20vc2FjaGluY2hvb2x1ci9saWdodHNsaWRlclxyXG4qIENvcHlyaWdodCAoYykgMjAxNiBTYWNoaW4gTjsgTGljZW5zZWQgTUlUICovXHJcbiFmdW5jdGlvbihhLGIpe1widXNlIHN0cmljdFwiO3ZhciBjPXtpdGVtOjMsYXV0b1dpZHRoOiExLHNsaWRlTW92ZToxLHNsaWRlTWFyZ2luOjEwLGFkZENsYXNzOlwiXCIsbW9kZTpcInNsaWRlXCIsdXNlQ1NTOiEwLGNzc0Vhc2luZzpcImVhc2VcIixlYXNpbmc6XCJsaW5lYXJcIixzcGVlZDo0MDAsYXV0bzohMSxwYXVzZU9uSG92ZXI6ITEsbG9vcDohMSxzbGlkZUVuZEFuaW1hdGlvbjohMCxwYXVzZToyZTMsa2V5UHJlc3M6ITEsY29udHJvbHM6ITAscHJldkh0bWw6XCJcIixuZXh0SHRtbDpcIlwiLHJ0bDohMSxhZGFwdGl2ZUhlaWdodDohMSx2ZXJ0aWNhbDohMSx2ZXJ0aWNhbEhlaWdodDo1MDAsdlRodW1iV2lkdGg6MTAwLHRodW1iSXRlbToxMCxwYWdlcjohMCxnYWxsZXJ5OiExLGdhbGxlcnlNYXJnaW46NSx0aHVtYk1hcmdpbjo1LGN1cnJlbnRQYWdlclBvc2l0aW9uOlwibWlkZGxlXCIsZW5hYmxlVG91Y2g6ITAsZW5hYmxlRHJhZzohMCxmcmVlTW92ZTohMCxzd2lwZVRocmVzaG9sZDo0MCxyZXNwb25zaXZlOltdLG9uQmVmb3JlU3RhcnQ6ZnVuY3Rpb24oYSl7fSxvblNsaWRlckxvYWQ6ZnVuY3Rpb24oYSl7fSxvbkJlZm9yZVNsaWRlOmZ1bmN0aW9uKGEsYil7fSxvbkFmdGVyU2xpZGU6ZnVuY3Rpb24oYSxiKXt9LG9uQmVmb3JlTmV4dFNsaWRlOmZ1bmN0aW9uKGEsYil7fSxvbkJlZm9yZVByZXZTbGlkZTpmdW5jdGlvbihhLGIpe319O2EuZm4ubGlnaHRTbGlkZXI9ZnVuY3Rpb24oYil7aWYoMD09PXRoaXMubGVuZ3RoKXJldHVybiB0aGlzO2lmKHRoaXMubGVuZ3RoPjEpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe2EodGhpcykubGlnaHRTbGlkZXIoYil9KSx0aGlzO3ZhciBkPXt9LGU9YS5leHRlbmQoITAse30sYyxiKSxmPXt9LGc9dGhpcztkLiRlbD10aGlzLFwiZmFkZVwiPT09ZS5tb2RlJiYoZS52ZXJ0aWNhbD0hMSk7dmFyIGg9Zy5jaGlsZHJlbigpLGk9YSh3aW5kb3cpLndpZHRoKCksaj1udWxsLGs9bnVsbCxsPTAsbT0wLG49ITEsbz0wLHA9XCJcIixxPTAscj1lLnZlcnRpY2FsPT09ITA/XCJoZWlnaHRcIjpcIndpZHRoXCIscz1lLnZlcnRpY2FsPT09ITA/XCJtYXJnaW4tYm90dG9tXCI6XCJtYXJnaW4tcmlnaHRcIix0PTAsdT0wLHY9MCx3PTAseD1udWxsLHk9XCJvbnRvdWNoc3RhcnRcImluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCx6PXt9O3JldHVybiB6LmNoYnJlYWtwb2ludD1mdW5jdGlvbigpe2lmKGk9YSh3aW5kb3cpLndpZHRoKCksZS5yZXNwb25zaXZlLmxlbmd0aCl7dmFyIGI7aWYoZS5hdXRvV2lkdGg9PT0hMSYmKGI9ZS5pdGVtKSxpPGUucmVzcG9uc2l2ZVswXS5icmVha3BvaW50KWZvcih2YXIgYz0wO2M8ZS5yZXNwb25zaXZlLmxlbmd0aDtjKyspaTxlLnJlc3BvbnNpdmVbY10uYnJlYWtwb2ludCYmKGo9ZS5yZXNwb25zaXZlW2NdLmJyZWFrcG9pbnQsaz1lLnJlc3BvbnNpdmVbY10pO2lmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiBrJiZudWxsIT09aylmb3IodmFyIGQgaW4gay5zZXR0aW5ncylrLnNldHRpbmdzLmhhc093blByb3BlcnR5KGQpJiYoKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBmW2RdfHxudWxsPT09ZltkXSkmJihmW2RdPWVbZF0pLGVbZF09ay5zZXR0aW5nc1tkXSk7aWYoIWEuaXNFbXB0eU9iamVjdChmKSYmaT5lLnJlc3BvbnNpdmVbMF0uYnJlYWtwb2ludClmb3IodmFyIGcgaW4gZilmLmhhc093blByb3BlcnR5KGcpJiYoZVtnXT1mW2ddKTtlLmF1dG9XaWR0aD09PSExJiZ0PjAmJnY+MCYmYiE9PWUuaXRlbSYmKHE9TWF0aC5yb3VuZCh0LygoditlLnNsaWRlTWFyZ2luKSplLnNsaWRlTW92ZSkpKX19LHouY2FsU1c9ZnVuY3Rpb24oKXtlLmF1dG9XaWR0aD09PSExJiYodj0oby0oZS5pdGVtKmUuc2xpZGVNYXJnaW4tZS5zbGlkZU1hcmdpbikpL2UuaXRlbSl9LHouY2FsV2lkdGg9ZnVuY3Rpb24oYSl7dmFyIGI9YT09PSEwP3AuZmluZChcIi5sc2xpZGVcIikubGVuZ3RoOmgubGVuZ3RoO2lmKGUuYXV0b1dpZHRoPT09ITEpbT1iKih2K2Uuc2xpZGVNYXJnaW4pO2Vsc2V7bT0wO2Zvcih2YXIgYz0wO2I+YztjKyspbSs9cGFyc2VJbnQoaC5lcShjKS53aWR0aCgpKStlLnNsaWRlTWFyZ2lufXJldHVybiBtfSxkPXtkb0NzczpmdW5jdGlvbigpe3ZhciBhPWZ1bmN0aW9uKCl7Zm9yKHZhciBhPVtcInRyYW5zaXRpb25cIixcIk1velRyYW5zaXRpb25cIixcIldlYmtpdFRyYW5zaXRpb25cIixcIk9UcmFuc2l0aW9uXCIsXCJtc1RyYW5zaXRpb25cIixcIktodG1sVHJhbnNpdGlvblwiXSxiPWRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxjPTA7YzxhLmxlbmd0aDtjKyspaWYoYVtjXWluIGIuc3R5bGUpcmV0dXJuITB9O3JldHVybiBlLnVzZUNTUyYmYSgpPyEwOiExfSxrZXlQcmVzczpmdW5jdGlvbigpe2Uua2V5UHJlc3MmJmEoZG9jdW1lbnQpLm9uKFwia2V5dXAubGlnaHRzbGlkZXJcIixmdW5jdGlvbihiKXthKFwiOmZvY3VzXCIpLmlzKFwiaW5wdXQsIHRleHRhcmVhXCIpfHwoYi5wcmV2ZW50RGVmYXVsdD9iLnByZXZlbnREZWZhdWx0KCk6Yi5yZXR1cm5WYWx1ZT0hMSwzNz09PWIua2V5Q29kZT9nLmdvVG9QcmV2U2xpZGUoKTozOT09PWIua2V5Q29kZSYmZy5nb1RvTmV4dFNsaWRlKCkpfSl9LGNvbnRyb2xzOmZ1bmN0aW9uKCl7ZS5jb250cm9scyYmKGcuYWZ0ZXIoJzxkaXYgY2xhc3M9XCJsU0FjdGlvblwiPjxhIGNsYXNzPVwibFNQcmV2XCI+JytlLnByZXZIdG1sKyc8L2E+PGEgY2xhc3M9XCJsU05leHRcIj4nK2UubmV4dEh0bWwrXCI8L2E+PC9kaXY+XCIpLGUuYXV0b1dpZHRoP3ouY2FsV2lkdGgoITEpPG8mJnAuZmluZChcIi5sU0FjdGlvblwiKS5oaWRlKCk6bDw9ZS5pdGVtJiZwLmZpbmQoXCIubFNBY3Rpb25cIikuaGlkZSgpLHAuZmluZChcIi5sU0FjdGlvbiBhXCIpLm9uKFwiY2xpY2tcIixmdW5jdGlvbihiKXtyZXR1cm4gYi5wcmV2ZW50RGVmYXVsdD9iLnByZXZlbnREZWZhdWx0KCk6Yi5yZXR1cm5WYWx1ZT0hMSxcImxTUHJldlwiPT09YSh0aGlzKS5hdHRyKFwiY2xhc3NcIik/Zy5nb1RvUHJldlNsaWRlKCk6Zy5nb1RvTmV4dFNsaWRlKCksITF9KSl9LGluaXRpYWxTdHlsZTpmdW5jdGlvbigpe3ZhciBhPXRoaXM7XCJmYWRlXCI9PT1lLm1vZGUmJihlLmF1dG9XaWR0aD0hMSxlLnNsaWRlRW5kQW5pbWF0aW9uPSExKSxlLmF1dG8mJihlLnNsaWRlRW5kQW5pbWF0aW9uPSExKSxlLmF1dG9XaWR0aCYmKGUuc2xpZGVNb3ZlPTEsZS5pdGVtPTEpLGUubG9vcCYmKGUuc2xpZGVNb3ZlPTEsZS5mcmVlTW92ZT0hMSksZS5vbkJlZm9yZVN0YXJ0LmNhbGwodGhpcyxnKSx6LmNoYnJlYWtwb2ludCgpLGcuYWRkQ2xhc3MoXCJsaWdodFNsaWRlclwiKS53cmFwKCc8ZGl2IGNsYXNzPVwibFNTbGlkZU91dGVyICcrZS5hZGRDbGFzcysnXCI+PGRpdiBjbGFzcz1cImxTU2xpZGVXcmFwcGVyXCI+PC9kaXY+PC9kaXY+JykscD1nLnBhcmVudChcIi5sU1NsaWRlV3JhcHBlclwiKSxlLnJ0bD09PSEwJiZwLnBhcmVudCgpLmFkZENsYXNzKFwibFNydGxcIiksZS52ZXJ0aWNhbD8ocC5wYXJlbnQoKS5hZGRDbGFzcyhcInZlcnRpY2FsXCIpLG89ZS52ZXJ0aWNhbEhlaWdodCxwLmNzcyhcImhlaWdodFwiLG8rXCJweFwiKSk6bz1nLm91dGVyV2lkdGgoKSxoLmFkZENsYXNzKFwibHNsaWRlXCIpLGUubG9vcD09PSEwJiZcInNsaWRlXCI9PT1lLm1vZGUmJih6LmNhbFNXKCksei5jbG9uZT1mdW5jdGlvbigpe2lmKHouY2FsV2lkdGgoITApPm8pe2Zvcih2YXIgYj0wLGM9MCxkPTA7ZDxoLmxlbmd0aCYmKGIrPXBhcnNlSW50KGcuZmluZChcIi5sc2xpZGVcIikuZXEoZCkud2lkdGgoKSkrZS5zbGlkZU1hcmdpbixjKyssIShiPj1vK2Uuc2xpZGVNYXJnaW4pKTtkKyspO3ZhciBmPWUuYXV0b1dpZHRoPT09ITA/YzplLml0ZW07aWYoZjxnLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGgpZm9yKHZhciBpPTA7aTxnLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGgtZjtpKyspaC5lcShpKS5yZW1vdmUoKTtpZihmPGcuZmluZChcIi5jbG9uZS5yaWdodFwiKS5sZW5ndGgpZm9yKHZhciBqPWgubGVuZ3RoLTE7aj5oLmxlbmd0aC0xLWcuZmluZChcIi5jbG9uZS5yaWdodFwiKS5sZW5ndGg7ai0tKXEtLSxoLmVxKGopLnJlbW92ZSgpO2Zvcih2YXIgaz1nLmZpbmQoXCIuY2xvbmUucmlnaHRcIikubGVuZ3RoO2Y+aztrKyspZy5maW5kKFwiLmxzbGlkZVwiKS5lcShrKS5jbG9uZSgpLnJlbW92ZUNsYXNzKFwibHNsaWRlXCIpLmFkZENsYXNzKFwiY2xvbmUgcmlnaHRcIikuYXBwZW5kVG8oZykscSsrO2Zvcih2YXIgbD1nLmZpbmQoXCIubHNsaWRlXCIpLmxlbmd0aC1nLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGg7bD5nLmZpbmQoXCIubHNsaWRlXCIpLmxlbmd0aC1mO2wtLSlnLmZpbmQoXCIubHNsaWRlXCIpLmVxKGwtMSkuY2xvbmUoKS5yZW1vdmVDbGFzcyhcImxzbGlkZVwiKS5hZGRDbGFzcyhcImNsb25lIGxlZnRcIikucHJlcGVuZFRvKGcpO2g9Zy5jaGlsZHJlbigpfWVsc2UgaC5oYXNDbGFzcyhcImNsb25lXCIpJiYoZy5maW5kKFwiLmNsb25lXCIpLnJlbW92ZSgpLGEubW92ZShnLDApKX0sei5jbG9uZSgpKSx6LnNTVz1mdW5jdGlvbigpe2w9aC5sZW5ndGgsZS5ydGw9PT0hMCYmZS52ZXJ0aWNhbD09PSExJiYocz1cIm1hcmdpbi1sZWZ0XCIpLGUuYXV0b1dpZHRoPT09ITEmJmguY3NzKHIsditcInB4XCIpLGguY3NzKHMsZS5zbGlkZU1hcmdpbitcInB4XCIpLG09ei5jYWxXaWR0aCghMSksZy5jc3MocixtK1wicHhcIiksZS5sb29wPT09ITAmJlwic2xpZGVcIj09PWUubW9kZSYmbj09PSExJiYocT1nLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGgpfSx6LmNhbEw9ZnVuY3Rpb24oKXtoPWcuY2hpbGRyZW4oKSxsPWgubGVuZ3RofSx0aGlzLmRvQ3NzKCkmJnAuYWRkQ2xhc3MoXCJ1c2luZ0Nzc1wiKSx6LmNhbEwoKSxcInNsaWRlXCI9PT1lLm1vZGU/KHouY2FsU1coKSx6LnNTVygpLGUubG9vcD09PSEwJiYodD1hLnNsaWRlVmFsdWUoKSx0aGlzLm1vdmUoZyx0KSksZS52ZXJ0aWNhbD09PSExJiZ0aGlzLnNldEhlaWdodChnLCExKSk6KHRoaXMuc2V0SGVpZ2h0KGcsITApLGcuYWRkQ2xhc3MoXCJsU0ZhZGVcIiksdGhpcy5kb0NzcygpfHwoaC5mYWRlT3V0KDApLGguZXEocSkuZmFkZUluKDApKSksZS5sb29wPT09ITAmJlwic2xpZGVcIj09PWUubW9kZT9oLmVxKHEpLmFkZENsYXNzKFwiYWN0aXZlXCIpOmguZmlyc3QoKS5hZGRDbGFzcyhcImFjdGl2ZVwiKX0scGFnZXI6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2lmKHouY3JlYXRlUGFnZXI9ZnVuY3Rpb24oKXt3PShvLShlLnRodW1iSXRlbSplLnRodW1iTWFyZ2luLWUudGh1bWJNYXJnaW4pKS9lLnRodW1iSXRlbTt2YXIgYj1wLmZpbmQoXCIubHNsaWRlXCIpLGM9cC5maW5kKFwiLmxzbGlkZVwiKS5sZW5ndGgsZD0wLGY9XCJcIixoPTA7Zm9yKGQ9MDtjPmQ7ZCsrKXtcInNsaWRlXCI9PT1lLm1vZGUmJihlLmF1dG9XaWR0aD9oKz0ocGFyc2VJbnQoYi5lcShkKS53aWR0aCgpKStlLnNsaWRlTWFyZ2luKSplLnNsaWRlTW92ZTpoPWQqKHYrZS5zbGlkZU1hcmdpbikqZS5zbGlkZU1vdmUpO3ZhciBpPWIuZXEoZCplLnNsaWRlTW92ZSkuYXR0cihcImRhdGEtdGh1bWJcIik7aWYoZis9ZS5nYWxsZXJ5PT09ITA/JzxsaSBzdHlsZT1cIndpZHRoOjEwMCU7JytyK1wiOlwiK3crXCJweDtcIitzK1wiOlwiK2UudGh1bWJNYXJnaW4rJ3B4XCI+PGEgaHJlZj1cIiNcIj48aW1nIHNyYz1cIicraSsnXCIgLz48L2E+PC9saT4nOic8bGk+PGEgaHJlZj1cIiNcIj4nKyhkKzEpK1wiPC9hPjwvbGk+XCIsXCJzbGlkZVwiPT09ZS5tb2RlJiZoPj1tLW8tZS5zbGlkZU1hcmdpbil7ZCs9MTt2YXIgaj0yO2UuYXV0b1dpZHRoJiYoZis9JzxsaT48YSBocmVmPVwiI1wiPicrKGQrMSkrXCI8L2E+PC9saT5cIixqPTEpLGo+ZD8oZj1udWxsLHAucGFyZW50KCkuYWRkQ2xhc3MoXCJub1BhZ2VyXCIpKTpwLnBhcmVudCgpLnJlbW92ZUNsYXNzKFwibm9QYWdlclwiKTticmVha319dmFyIGs9cC5wYXJlbnQoKTtrLmZpbmQoXCIubFNQYWdlclwiKS5odG1sKGYpLGUuZ2FsbGVyeT09PSEwJiYoZS52ZXJ0aWNhbD09PSEwJiZrLmZpbmQoXCIubFNQYWdlclwiKS5jc3MoXCJ3aWR0aFwiLGUudlRodW1iV2lkdGgrXCJweFwiKSx1PWQqKGUudGh1bWJNYXJnaW4rdykrLjUsay5maW5kKFwiLmxTUGFnZXJcIikuY3NzKHtwcm9wZXJ0eTp1K1wicHhcIixcInRyYW5zaXRpb24tZHVyYXRpb25cIjplLnNwZWVkK1wibXNcIn0pLGUudmVydGljYWw9PT0hMCYmcC5wYXJlbnQoKS5jc3MoXCJwYWRkaW5nLXJpZ2h0XCIsZS52VGh1bWJXaWR0aCtlLmdhbGxlcnlNYXJnaW4rXCJweFwiKSxrLmZpbmQoXCIubFNQYWdlclwiKS5jc3Mocix1K1wicHhcIikpO3ZhciBsPWsuZmluZChcIi5sU1BhZ2VyXCIpLmZpbmQoXCJsaVwiKTtsLmZpcnN0KCkuYWRkQ2xhc3MoXCJhY3RpdmVcIiksbC5vbihcImNsaWNrXCIsZnVuY3Rpb24oKXtyZXR1cm4gZS5sb29wPT09ITAmJlwic2xpZGVcIj09PWUubW9kZT9xKz1sLmluZGV4KHRoaXMpLWsuZmluZChcIi5sU1BhZ2VyXCIpLmZpbmQoXCJsaS5hY3RpdmVcIikuaW5kZXgoKTpxPWwuaW5kZXgodGhpcyksZy5tb2RlKCExKSxlLmdhbGxlcnk9PT0hMCYmYS5zbGlkZVRodW1iKCksITF9KX0sZS5wYWdlcil7dmFyIGI9XCJsU3BnXCI7ZS5nYWxsZXJ5JiYoYj1cImxTR2FsbGVyeVwiKSxwLmFmdGVyKCc8dWwgY2xhc3M9XCJsU1BhZ2VyICcrYisnXCI+PC91bD4nKTt2YXIgYz1lLnZlcnRpY2FsP1wibWFyZ2luLWxlZnRcIjpcIm1hcmdpbi10b3BcIjtwLnBhcmVudCgpLmZpbmQoXCIubFNQYWdlclwiKS5jc3MoYyxlLmdhbGxlcnlNYXJnaW4rXCJweFwiKSx6LmNyZWF0ZVBhZ2VyKCl9c2V0VGltZW91dChmdW5jdGlvbigpe3ouaW5pdCgpfSwwKX0sc2V0SGVpZ2h0OmZ1bmN0aW9uKGEsYil7dmFyIGM9bnVsbCxkPXRoaXM7Yz1lLmxvb3A/YS5jaGlsZHJlbihcIi5sc2xpZGUgXCIpLmZpcnN0KCk6YS5jaGlsZHJlbigpLmZpcnN0KCk7dmFyIGY9ZnVuY3Rpb24oKXt2YXIgZD1jLm91dGVySGVpZ2h0KCksZT0wLGY9ZDtiJiYoZD0wLGU9MTAwKmYvbyksYS5jc3Moe2hlaWdodDpkK1wicHhcIixcInBhZGRpbmctYm90dG9tXCI6ZStcIiVcIn0pfTtmKCksYy5maW5kKFwiaW1nXCIpLmxlbmd0aD9jLmZpbmQoXCJpbWdcIilbMF0uY29tcGxldGU/KGYoKSx4fHxkLmF1dG8oKSk6Yy5maW5kKFwiaW1nXCIpLm9uKFwibG9hZFwiLGZ1bmN0aW9uKCl7c2V0VGltZW91dChmdW5jdGlvbigpe2YoKSx4fHxkLmF1dG8oKX0sMTAwKX0pOnh8fGQuYXV0bygpfSxhY3RpdmU6ZnVuY3Rpb24oYSxiKXt0aGlzLmRvQ3NzKCkmJlwiZmFkZVwiPT09ZS5tb2RlJiZwLmFkZENsYXNzKFwib25cIik7dmFyIGM9MDtpZihxKmUuc2xpZGVNb3ZlPGwpe2EucmVtb3ZlQ2xhc3MoXCJhY3RpdmVcIiksdGhpcy5kb0NzcygpfHxcImZhZGVcIiE9PWUubW9kZXx8YiE9PSExfHxhLmZhZGVPdXQoZS5zcGVlZCksYz1iPT09ITA/cTpxKmUuc2xpZGVNb3ZlO3ZhciBkLGY7Yj09PSEwJiYoZD1hLmxlbmd0aCxmPWQtMSxjKzE+PWQmJihjPWYpKSxlLmxvb3A9PT0hMCYmXCJzbGlkZVwiPT09ZS5tb2RlJiYoYz1iPT09ITA/cS1nLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGg6cSplLnNsaWRlTW92ZSxiPT09ITAmJihkPWEubGVuZ3RoLGY9ZC0xLGMrMT09PWQ/Yz1mOmMrMT5kJiYoYz0wKSkpLHRoaXMuZG9Dc3MoKXx8XCJmYWRlXCIhPT1lLm1vZGV8fGIhPT0hMXx8YS5lcShjKS5mYWRlSW4oZS5zcGVlZCksYS5lcShjKS5hZGRDbGFzcyhcImFjdGl2ZVwiKX1lbHNlIGEucmVtb3ZlQ2xhc3MoXCJhY3RpdmVcIiksYS5lcShhLmxlbmd0aC0xKS5hZGRDbGFzcyhcImFjdGl2ZVwiKSx0aGlzLmRvQ3NzKCl8fFwiZmFkZVwiIT09ZS5tb2RlfHxiIT09ITF8fChhLmZhZGVPdXQoZS5zcGVlZCksYS5lcShjKS5mYWRlSW4oZS5zcGVlZCkpfSxtb3ZlOmZ1bmN0aW9uKGEsYil7ZS5ydGw9PT0hMCYmKGI9LWIpLHRoaXMuZG9Dc3MoKT9hLmNzcyhlLnZlcnRpY2FsPT09ITA/e3RyYW5zZm9ybTpcInRyYW5zbGF0ZTNkKDBweCwgXCIrLWIrXCJweCwgMHB4KVwiLFwiLXdlYmtpdC10cmFuc2Zvcm1cIjpcInRyYW5zbGF0ZTNkKDBweCwgXCIrLWIrXCJweCwgMHB4KVwifTp7dHJhbnNmb3JtOlwidHJhbnNsYXRlM2QoXCIrLWIrXCJweCwgMHB4LCAwcHgpXCIsXCItd2Via2l0LXRyYW5zZm9ybVwiOlwidHJhbnNsYXRlM2QoXCIrLWIrXCJweCwgMHB4LCAwcHgpXCJ9KTplLnZlcnRpY2FsPT09ITA/YS5jc3MoXCJwb3NpdGlvblwiLFwicmVsYXRpdmVcIikuYW5pbWF0ZSh7dG9wOi1iK1wicHhcIn0sZS5zcGVlZCxlLmVhc2luZyk6YS5jc3MoXCJwb3NpdGlvblwiLFwicmVsYXRpdmVcIikuYW5pbWF0ZSh7bGVmdDotYitcInB4XCJ9LGUuc3BlZWQsZS5lYXNpbmcpO3ZhciBjPXAucGFyZW50KCkuZmluZChcIi5sU1BhZ2VyXCIpLmZpbmQoXCJsaVwiKTt0aGlzLmFjdGl2ZShjLCEwKX0sZmFkZTpmdW5jdGlvbigpe3RoaXMuYWN0aXZlKGgsITEpO3ZhciBhPXAucGFyZW50KCkuZmluZChcIi5sU1BhZ2VyXCIpLmZpbmQoXCJsaVwiKTt0aGlzLmFjdGl2ZShhLCEwKX0sc2xpZGU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO3ouY2FsU2xpZGU9ZnVuY3Rpb24oKXttPm8mJih0PWEuc2xpZGVWYWx1ZSgpLGEuYWN0aXZlKGgsITEpLHQ+bS1vLWUuc2xpZGVNYXJnaW4/dD1tLW8tZS5zbGlkZU1hcmdpbjowPnQmJih0PTApLGEubW92ZShnLHQpLGUubG9vcD09PSEwJiZcInNsaWRlXCI9PT1lLm1vZGUmJihxPj1sLWcuZmluZChcIi5jbG9uZS5sZWZ0XCIpLmxlbmd0aC9lLnNsaWRlTW92ZSYmYS5yZXNldFNsaWRlKGcuZmluZChcIi5jbG9uZS5sZWZ0XCIpLmxlbmd0aCksMD09PXEmJmEucmVzZXRTbGlkZShwLmZpbmQoXCIubHNsaWRlXCIpLmxlbmd0aCkpKX0sei5jYWxTbGlkZSgpfSxyZXNldFNsaWRlOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cC5maW5kKFwiLmxTQWN0aW9uIGFcIikuYWRkQ2xhc3MoXCJkaXNhYmxlZFwiKSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cT1hLHAuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLFwiMG1zXCIpLHQ9Yi5zbGlkZVZhbHVlKCksYi5hY3RpdmUoaCwhMSksZC5tb3ZlKGcsdCksc2V0VGltZW91dChmdW5jdGlvbigpe3AuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLGUuc3BlZWQrXCJtc1wiKSxwLmZpbmQoXCIubFNBY3Rpb24gYVwiKS5yZW1vdmVDbGFzcyhcImRpc2FibGVkXCIpfSw1MCl9LGUuc3BlZWQrMTAwKX0sc2xpZGVWYWx1ZTpmdW5jdGlvbigpe3ZhciBhPTA7aWYoZS5hdXRvV2lkdGg9PT0hMSlhPXEqKHYrZS5zbGlkZU1hcmdpbikqZS5zbGlkZU1vdmU7ZWxzZXthPTA7Zm9yKHZhciBiPTA7cT5iO2IrKylhKz1wYXJzZUludChoLmVxKGIpLndpZHRoKCkpK2Uuc2xpZGVNYXJnaW59cmV0dXJuIGF9LHNsaWRlVGh1bWI6ZnVuY3Rpb24oKXt2YXIgYTtzd2l0Y2goZS5jdXJyZW50UGFnZXJQb3NpdGlvbil7Y2FzZVwibGVmdFwiOmE9MDticmVhaztjYXNlXCJtaWRkbGVcIjphPW8vMi13LzI7YnJlYWs7Y2FzZVwicmlnaHRcIjphPW8td312YXIgYj1xLWcuZmluZChcIi5jbG9uZS5sZWZ0XCIpLmxlbmd0aCxjPXAucGFyZW50KCkuZmluZChcIi5sU1BhZ2VyXCIpO1wic2xpZGVcIj09PWUubW9kZSYmZS5sb29wPT09ITAmJihiPj1jLmNoaWxkcmVuKCkubGVuZ3RoP2I9MDowPmImJihiPWMuY2hpbGRyZW4oKS5sZW5ndGgpKTt2YXIgZD1iKih3K2UudGh1bWJNYXJnaW4pLWE7ZCtvPnUmJihkPXUtby1lLnRodW1iTWFyZ2luKSwwPmQmJihkPTApLHRoaXMubW92ZShjLGQpfSxhdXRvOmZ1bmN0aW9uKCl7ZS5hdXRvJiYoY2xlYXJJbnRlcnZhbCh4KSx4PXNldEludGVydmFsKGZ1bmN0aW9uKCl7Zy5nb1RvTmV4dFNsaWRlKCl9LGUucGF1c2UpKX0scGF1c2VPbkhvdmVyOmZ1bmN0aW9uKCl7dmFyIGI9dGhpcztlLmF1dG8mJmUucGF1c2VPbkhvdmVyJiYocC5vbihcIm1vdXNlZW50ZXJcIixmdW5jdGlvbigpe2EodGhpcykuYWRkQ2xhc3MoXCJscy1ob3ZlclwiKSxnLnBhdXNlKCksZS5hdXRvPSEwfSkscC5vbihcIm1vdXNlbGVhdmVcIixmdW5jdGlvbigpe2EodGhpcykucmVtb3ZlQ2xhc3MoXCJscy1ob3ZlclwiKSxwLmZpbmQoXCIubGlnaHRTbGlkZXJcIikuaGFzQ2xhc3MoXCJsc0dyYWJiaW5nXCIpfHxiLmF1dG8oKX0pKX0sdG91Y2hNb3ZlOmZ1bmN0aW9uKGEsYil7aWYocC5jc3MoXCJ0cmFuc2l0aW9uLWR1cmF0aW9uXCIsXCIwbXNcIiksXCJzbGlkZVwiPT09ZS5tb2RlKXt2YXIgYz1hLWIsZD10LWM7aWYoZD49bS1vLWUuc2xpZGVNYXJnaW4paWYoZS5mcmVlTW92ZT09PSExKWQ9bS1vLWUuc2xpZGVNYXJnaW47ZWxzZXt2YXIgZj1tLW8tZS5zbGlkZU1hcmdpbjtkPWYrKGQtZikvNX1lbHNlIDA+ZCYmKGUuZnJlZU1vdmU9PT0hMT9kPTA6ZC89NSk7dGhpcy5tb3ZlKGcsZCl9fSx0b3VjaEVuZDpmdW5jdGlvbihhKXtpZihwLmNzcyhcInRyYW5zaXRpb24tZHVyYXRpb25cIixlLnNwZWVkK1wibXNcIiksXCJzbGlkZVwiPT09ZS5tb2RlKXt2YXIgYj0hMSxjPSEwO3QtPWEsdD5tLW8tZS5zbGlkZU1hcmdpbj8odD1tLW8tZS5zbGlkZU1hcmdpbixlLmF1dG9XaWR0aD09PSExJiYoYj0hMCkpOjA+dCYmKHQ9MCk7dmFyIGQ9ZnVuY3Rpb24oYSl7dmFyIGM9MDtpZihifHxhJiYoYz0xKSxlLmF1dG9XaWR0aClmb3IodmFyIGQ9MCxmPTA7ZjxoLmxlbmd0aCYmKGQrPXBhcnNlSW50KGguZXEoZikud2lkdGgoKSkrZS5zbGlkZU1hcmdpbixxPWYrYywhKGQ+PXQpKTtmKyspO2Vsc2V7dmFyIGc9dC8oKHYrZS5zbGlkZU1hcmdpbikqZS5zbGlkZU1vdmUpO3E9cGFyc2VJbnQoZykrYyx0Pj1tLW8tZS5zbGlkZU1hcmdpbiYmZyUxIT09MCYmcSsrfX07YT49ZS5zd2lwZVRocmVzaG9sZD8oZCghMSksYz0hMSk6YTw9LWUuc3dpcGVUaHJlc2hvbGQmJihkKCEwKSxjPSExKSxnLm1vZGUoYyksdGhpcy5zbGlkZVRodW1iKCl9ZWxzZSBhPj1lLnN3aXBlVGhyZXNob2xkP2cuZ29Ub1ByZXZTbGlkZSgpOmE8PS1lLnN3aXBlVGhyZXNob2xkJiZnLmdvVG9OZXh0U2xpZGUoKX0sZW5hYmxlRHJhZzpmdW5jdGlvbigpe3ZhciBiPXRoaXM7aWYoIXkpe3ZhciBjPTAsZD0wLGY9ITE7cC5maW5kKFwiLmxpZ2h0U2xpZGVyXCIpLmFkZENsYXNzKFwibHNHcmFiXCIpLHAub24oXCJtb3VzZWRvd25cIixmdW5jdGlvbihiKXtyZXR1cm4gbz5tJiYwIT09bT8hMTp2b2lkKFwibFNQcmV2XCIhPT1hKGIudGFyZ2V0KS5hdHRyKFwiY2xhc3NcIikmJlwibFNOZXh0XCIhPT1hKGIudGFyZ2V0KS5hdHRyKFwiY2xhc3NcIikmJihjPWUudmVydGljYWw9PT0hMD9iLnBhZ2VZOmIucGFnZVgsZj0hMCxiLnByZXZlbnREZWZhdWx0P2IucHJldmVudERlZmF1bHQoKTpiLnJldHVyblZhbHVlPSExLHAuc2Nyb2xsTGVmdCs9MSxwLnNjcm9sbExlZnQtPTEscC5maW5kKFwiLmxpZ2h0U2xpZGVyXCIpLnJlbW92ZUNsYXNzKFwibHNHcmFiXCIpLmFkZENsYXNzKFwibHNHcmFiYmluZ1wiKSxjbGVhckludGVydmFsKHgpKSl9KSxhKHdpbmRvdykub24oXCJtb3VzZW1vdmVcIixmdW5jdGlvbihhKXtmJiYoZD1lLnZlcnRpY2FsPT09ITA/YS5wYWdlWTphLnBhZ2VYLGIudG91Y2hNb3ZlKGQsYykpfSksYSh3aW5kb3cpLm9uKFwibW91c2V1cFwiLGZ1bmN0aW9uKGcpe2lmKGYpe3AuZmluZChcIi5saWdodFNsaWRlclwiKS5yZW1vdmVDbGFzcyhcImxzR3JhYmJpbmdcIikuYWRkQ2xhc3MoXCJsc0dyYWJcIiksZj0hMSxkPWUudmVydGljYWw9PT0hMD9nLnBhZ2VZOmcucGFnZVg7dmFyIGg9ZC1jO01hdGguYWJzKGgpPj1lLnN3aXBlVGhyZXNob2xkJiZhKHdpbmRvdykub24oXCJjbGljay5sc1wiLGZ1bmN0aW9uKGIpe2IucHJldmVudERlZmF1bHQ/Yi5wcmV2ZW50RGVmYXVsdCgpOmIucmV0dXJuVmFsdWU9ITEsYi5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSxiLnN0b3BQcm9wYWdhdGlvbigpLGEod2luZG93KS5vZmYoXCJjbGljay5sc1wiKX0pLGIudG91Y2hFbmQoaCl9fSl9fSxlbmFibGVUb3VjaDpmdW5jdGlvbigpe3ZhciBhPXRoaXM7aWYoeSl7dmFyIGI9e30sYz17fTtwLm9uKFwidG91Y2hzdGFydFwiLGZ1bmN0aW9uKGEpe2M9YS5vcmlnaW5hbEV2ZW50LnRhcmdldFRvdWNoZXNbMF0sYi5wYWdlWD1hLm9yaWdpbmFsRXZlbnQudGFyZ2V0VG91Y2hlc1swXS5wYWdlWCxiLnBhZ2VZPWEub3JpZ2luYWxFdmVudC50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZLGNsZWFySW50ZXJ2YWwoeCl9KSxwLm9uKFwidG91Y2htb3ZlXCIsZnVuY3Rpb24oZCl7aWYobz5tJiYwIT09bSlyZXR1cm4hMTt2YXIgZj1kLm9yaWdpbmFsRXZlbnQ7Yz1mLnRhcmdldFRvdWNoZXNbMF07dmFyIGc9TWF0aC5hYnMoYy5wYWdlWC1iLnBhZ2VYKSxoPU1hdGguYWJzKGMucGFnZVktYi5wYWdlWSk7ZS52ZXJ0aWNhbD09PSEwPygzKmg+ZyYmZC5wcmV2ZW50RGVmYXVsdCgpLGEudG91Y2hNb3ZlKGMucGFnZVksYi5wYWdlWSkpOigzKmc+aCYmZC5wcmV2ZW50RGVmYXVsdCgpLGEudG91Y2hNb3ZlKGMucGFnZVgsYi5wYWdlWCkpfSkscC5vbihcInRvdWNoZW5kXCIsZnVuY3Rpb24oKXtpZihvPm0mJjAhPT1tKXJldHVybiExO3ZhciBkO2Q9ZS52ZXJ0aWNhbD09PSEwP2MucGFnZVktYi5wYWdlWTpjLnBhZ2VYLWIucGFnZVgsYS50b3VjaEVuZChkKX0pfX0sYnVpbGQ6ZnVuY3Rpb24oKXt2YXIgYj10aGlzO2IuaW5pdGlhbFN0eWxlKCksdGhpcy5kb0NzcygpJiYoZS5lbmFibGVUb3VjaD09PSEwJiZiLmVuYWJsZVRvdWNoKCksZS5lbmFibGVEcmFnPT09ITAmJmIuZW5hYmxlRHJhZygpKSxhKHdpbmRvdykub24oXCJmb2N1c1wiLGZ1bmN0aW9uKCl7Yi5hdXRvKCl9KSxhKHdpbmRvdykub24oXCJibHVyXCIsZnVuY3Rpb24oKXtjbGVhckludGVydmFsKHgpfSksYi5wYWdlcigpLGIucGF1c2VPbkhvdmVyKCksYi5jb250cm9scygpLGIua2V5UHJlc3MoKX19LGQuYnVpbGQoKSx6LmluaXQ9ZnVuY3Rpb24oKXt6LmNoYnJlYWtwb2ludCgpLGUudmVydGljYWw9PT0hMD8obz1lLml0ZW0+MT9lLnZlcnRpY2FsSGVpZ2h0Omgub3V0ZXJIZWlnaHQoKSxwLmNzcyhcImhlaWdodFwiLG8rXCJweFwiKSk6bz1wLm91dGVyV2lkdGgoKSxlLmxvb3A9PT0hMCYmXCJzbGlkZVwiPT09ZS5tb2RlJiZ6LmNsb25lKCksei5jYWxMKCksXCJzbGlkZVwiPT09ZS5tb2RlJiZnLnJlbW92ZUNsYXNzKFwibFNTbGlkZVwiKSxcInNsaWRlXCI9PT1lLm1vZGUmJih6LmNhbFNXKCksei5zU1coKSksc2V0VGltZW91dChmdW5jdGlvbigpe1wic2xpZGVcIj09PWUubW9kZSYmZy5hZGRDbGFzcyhcImxTU2xpZGVcIil9LDFlMyksZS5wYWdlciYmei5jcmVhdGVQYWdlcigpLGUuYWRhcHRpdmVIZWlnaHQ9PT0hMCYmZS52ZXJ0aWNhbD09PSExJiZnLmNzcyhcImhlaWdodFwiLGguZXEocSkub3V0ZXJIZWlnaHQoITApKSxlLmFkYXB0aXZlSGVpZ2h0PT09ITEmJihcInNsaWRlXCI9PT1lLm1vZGU/ZS52ZXJ0aWNhbD09PSExP2Quc2V0SGVpZ2h0KGcsITEpOmQuYXV0bygpOmQuc2V0SGVpZ2h0KGcsITApKSxlLmdhbGxlcnk9PT0hMCYmZC5zbGlkZVRodW1iKCksXCJzbGlkZVwiPT09ZS5tb2RlJiZkLnNsaWRlKCksZS5hdXRvV2lkdGg9PT0hMT9oLmxlbmd0aDw9ZS5pdGVtP3AuZmluZChcIi5sU0FjdGlvblwiKS5oaWRlKCk6cC5maW5kKFwiLmxTQWN0aW9uXCIpLnNob3coKTp6LmNhbFdpZHRoKCExKTxvJiYwIT09bT9wLmZpbmQoXCIubFNBY3Rpb25cIikuaGlkZSgpOnAuZmluZChcIi5sU0FjdGlvblwiKS5zaG93KCl9LGcuZ29Ub1ByZXZTbGlkZT1mdW5jdGlvbigpe2lmKHE+MCllLm9uQmVmb3JlUHJldlNsaWRlLmNhbGwodGhpcyxnLHEpLHEtLSxnLm1vZGUoITEpLGUuZ2FsbGVyeT09PSEwJiZkLnNsaWRlVGh1bWIoKTtlbHNlIGlmKGUubG9vcD09PSEwKXtpZihlLm9uQmVmb3JlUHJldlNsaWRlLmNhbGwodGhpcyxnLHEpLFwiZmFkZVwiPT09ZS5tb2RlKXt2YXIgYT1sLTE7cT1wYXJzZUludChhL2Uuc2xpZGVNb3ZlKX1nLm1vZGUoITEpLGUuZ2FsbGVyeT09PSEwJiZkLnNsaWRlVGh1bWIoKX1lbHNlIGUuc2xpZGVFbmRBbmltYXRpb249PT0hMCYmKGcuYWRkQ2xhc3MoXCJsZWZ0RW5kXCIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtnLnJlbW92ZUNsYXNzKFwibGVmdEVuZFwiKX0sNDAwKSl9LGcuZ29Ub05leHRTbGlkZT1mdW5jdGlvbigpe3ZhciBhPSEwO2lmKFwic2xpZGVcIj09PWUubW9kZSl7dmFyIGI9ZC5zbGlkZVZhbHVlKCk7YT1iPG0tby1lLnNsaWRlTWFyZ2lufXEqZS5zbGlkZU1vdmU8bC1lLnNsaWRlTW92ZSYmYT8oZS5vbkJlZm9yZU5leHRTbGlkZS5jYWxsKHRoaXMsZyxxKSxxKyssZy5tb2RlKCExKSxlLmdhbGxlcnk9PT0hMCYmZC5zbGlkZVRodW1iKCkpOmUubG9vcD09PSEwPyhlLm9uQmVmb3JlTmV4dFNsaWRlLmNhbGwodGhpcyxnLHEpLHE9MCxnLm1vZGUoITEpLGUuZ2FsbGVyeT09PSEwJiZkLnNsaWRlVGh1bWIoKSk6ZS5zbGlkZUVuZEFuaW1hdGlvbj09PSEwJiYoZy5hZGRDbGFzcyhcInJpZ2h0RW5kXCIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtnLnJlbW92ZUNsYXNzKFwicmlnaHRFbmRcIil9LDQwMCkpfSxnLm1vZGU9ZnVuY3Rpb24oYSl7ZS5hZGFwdGl2ZUhlaWdodD09PSEwJiZlLnZlcnRpY2FsPT09ITEmJmcuY3NzKFwiaGVpZ2h0XCIsaC5lcShxKS5vdXRlckhlaWdodCghMCkpLG49PT0hMSYmKFwic2xpZGVcIj09PWUubW9kZT9kLmRvQ3NzKCkmJihnLmFkZENsYXNzKFwibFNTbGlkZVwiKSxcIlwiIT09ZS5zcGVlZCYmcC5jc3MoXCJ0cmFuc2l0aW9uLWR1cmF0aW9uXCIsZS5zcGVlZCtcIm1zXCIpLFwiXCIhPT1lLmNzc0Vhc2luZyYmcC5jc3MoXCJ0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvblwiLGUuY3NzRWFzaW5nKSk6ZC5kb0NzcygpJiYoXCJcIiE9PWUuc3BlZWQmJmcuY3NzKFwidHJhbnNpdGlvbi1kdXJhdGlvblwiLGUuc3BlZWQrXCJtc1wiKSxcIlwiIT09ZS5jc3NFYXNpbmcmJmcuY3NzKFwidHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb25cIixlLmNzc0Vhc2luZykpKSxhfHxlLm9uQmVmb3JlU2xpZGUuY2FsbCh0aGlzLGcscSksXCJzbGlkZVwiPT09ZS5tb2RlP2Quc2xpZGUoKTpkLmZhZGUoKSxwLmhhc0NsYXNzKFwibHMtaG92ZXJcIil8fGQuYXV0bygpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXthfHxlLm9uQWZ0ZXJTbGlkZS5jYWxsKHRoaXMsZyxxKX0sZS5zcGVlZCksbj0hMH0sZy5wbGF5PWZ1bmN0aW9uKCl7Zy5nb1RvTmV4dFNsaWRlKCksZS5hdXRvPSEwLGQuYXV0bygpfSxnLnBhdXNlPWZ1bmN0aW9uKCl7ZS5hdXRvPSExLGNsZWFySW50ZXJ2YWwoeCl9LGcucmVmcmVzaD1mdW5jdGlvbigpe3ouaW5pdCgpfSxnLmdldEN1cnJlbnRTbGlkZUNvdW50PWZ1bmN0aW9uKCl7dmFyIGE9cTtpZihlLmxvb3Ape3ZhciBiPXAuZmluZChcIi5sc2xpZGVcIikubGVuZ3RoLGM9Zy5maW5kKFwiLmNsb25lLmxlZnRcIikubGVuZ3RoO2E9Yy0xPj1xP2IrKHEtYyk6cT49YitjP3EtYi1jOnEtY31yZXR1cm4gYSsxfSxnLmdldFRvdGFsU2xpZGVDb3VudD1mdW5jdGlvbigpe3JldHVybiBwLmZpbmQoXCIubHNsaWRlXCIpLmxlbmd0aH0sZy5nb1RvU2xpZGU9ZnVuY3Rpb24oYSl7cT1lLmxvb3A/YStnLmZpbmQoXCIuY2xvbmUubGVmdFwiKS5sZW5ndGgtMTphLGcubW9kZSghMSksZS5nYWxsZXJ5PT09ITAmJmQuc2xpZGVUaHVtYigpfSxnLmRlc3Ryb3k9ZnVuY3Rpb24oKXtnLmxpZ2h0U2xpZGVyJiYoZy5nb1RvUHJldlNsaWRlPWZ1bmN0aW9uKCl7fSxnLmdvVG9OZXh0U2xpZGU9ZnVuY3Rpb24oKXt9LGcubW9kZT1mdW5jdGlvbigpe30sZy5wbGF5PWZ1bmN0aW9uKCl7fSxnLnBhdXNlPWZ1bmN0aW9uKCl7fSxnLnJlZnJlc2g9ZnVuY3Rpb24oKXt9LGcuZ2V0Q3VycmVudFNsaWRlQ291bnQ9ZnVuY3Rpb24oKXt9LGcuZ2V0VG90YWxTbGlkZUNvdW50PWZ1bmN0aW9uKCl7fSxnLmdvVG9TbGlkZT1mdW5jdGlvbigpe30sZy5saWdodFNsaWRlcj1udWxsLHo9e2luaXQ6ZnVuY3Rpb24oKXt9fSxnLnBhcmVudCgpLnBhcmVudCgpLmZpbmQoXCIubFNBY3Rpb24sIC5sU1BhZ2VyXCIpLnJlbW92ZSgpLGcucmVtb3ZlQ2xhc3MoXCJsaWdodFNsaWRlciBsU0ZhZGUgbFNTbGlkZSBsc0dyYWIgbHNHcmFiYmluZyBsZWZ0RW5kIHJpZ2h0XCIpLnJlbW92ZUF0dHIoXCJzdHlsZVwiKS51bndyYXAoKS51bndyYXAoKSxnLmNoaWxkcmVuKCkucmVtb3ZlQXR0cihcInN0eWxlXCIpLGgucmVtb3ZlQ2xhc3MoXCJsc2xpZGUgYWN0aXZlXCIpLGcuZmluZChcIi5jbG9uZVwiKS5yZW1vdmUoKSxoPW51bGwseD1udWxsLG49ITEscT0wKX0sc2V0VGltZW91dChmdW5jdGlvbigpe2Uub25TbGlkZXJMb2FkLmNhbGwodGhpcyxnKX0sMTApLGEod2luZG93KS5vbihcInJlc2l6ZSBvcmllbnRhdGlvbmNoYW5nZVwiLGZ1bmN0aW9uKGEpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXthLnByZXZlbnREZWZhdWx0P2EucHJldmVudERlZmF1bHQoKTphLnJldHVyblZhbHVlPSExLHouaW5pdCgpfSwyMDApfSksdGhpc319KGpRdWVyeSk7IiwiIWZ1bmN0aW9uKGUsdCxuLGkpe1widXNlIHN0cmljdFwiO3Q9dm9pZCAwIT09dCYmdC5NYXRoPT1NYXRoP3Q6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHNlbGYmJnNlbGYuTWF0aD09TWF0aD9zZWxmOkZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSxlLmZuLmRyb3Bkb3duPWZ1bmN0aW9uKGkpe3ZhciBhLG89ZSh0aGlzKSxzPWUobikscj1vLnNlbGVjdG9yfHxcIlwiLGw9XCJvbnRvdWNoc3RhcnRcImluIG4uZG9jdW1lbnRFbGVtZW50LGM9KG5ldyBEYXRlKS5nZXRUaW1lKCksdT1bXSxkPWFyZ3VtZW50c1swXSx2PVwic3RyaW5nXCI9PXR5cGVvZiBkLGY9W10uc2xpY2UuY2FsbChhcmd1bWVudHMsMSk7cmV0dXJuIG8uZWFjaChmdW5jdGlvbihtKXt2YXIgaCxnLHAsYix3LHgsQyxTLHk9ZS5pc1BsYWluT2JqZWN0KGkpP2UuZXh0ZW5kKCEwLHt9LGUuZm4uZHJvcGRvd24uc2V0dGluZ3MsaSk6ZS5leHRlbmQoe30sZS5mbi5kcm9wZG93bi5zZXR0aW5ncyksQT15LmNsYXNzTmFtZSxUPXkubWVzc2FnZSxrPXkuZmllbGRzLEw9eS5rZXlzLEk9eS5tZXRhZGF0YSxEPXkubmFtZXNwYWNlLHE9eS5yZWdFeHAsUj15LnNlbGVjdG9yLE89eS5lcnJvcixWPXkudGVtcGxhdGVzLEU9XCIuXCIrRCxGPVwibW9kdWxlLVwiK0QsTT1lKHRoaXMpLHo9ZSh5LmNvbnRleHQpLFA9TS5maW5kKFIudGV4dCksSD1NLmZpbmQoUi5zZWFyY2gpLGo9TS5maW5kKFIuc2l6ZXIpLE49TS5maW5kKFIuaW5wdXQpLFU9TS5maW5kKFIuaWNvbiksSz1NLnByZXYoKS5maW5kKFIudGV4dCkubGVuZ3RoPjA/TS5wcmV2KCkuZmluZChSLnRleHQpOk0ucHJldigpLFc9TS5jaGlsZHJlbihSLm1lbnUpLEI9Vy5maW5kKFIuaXRlbSksJD0hMSxRPSExLFg9ITEsWT10aGlzLEc9TS5kYXRhKEYpO1M9e2luaXRpYWxpemU6ZnVuY3Rpb24oKXtTLmRlYnVnKFwiSW5pdGlhbGl6aW5nIGRyb3Bkb3duXCIseSksUy5pcy5hbHJlYWR5U2V0dXAoKT9TLnNldHVwLnJlZmVyZW5jZSgpOihTLnNldHVwLmxheW91dCgpLHkudmFsdWVzJiZTLmNoYW5nZS52YWx1ZXMoeS52YWx1ZXMpLFMucmVmcmVzaERhdGEoKSxTLnNhdmUuZGVmYXVsdHMoKSxTLnJlc3RvcmUuc2VsZWN0ZWQoKSxTLmNyZWF0ZS5pZCgpLFMuYmluZC5ldmVudHMoKSxTLm9ic2VydmVDaGFuZ2VzKCksUy5pbnN0YW50aWF0ZSgpKX0saW5zdGFudGlhdGU6ZnVuY3Rpb24oKXtTLnZlcmJvc2UoXCJTdG9yaW5nIGluc3RhbmNlIG9mIGRyb3Bkb3duXCIsUyksRz1TLE0uZGF0YShGLFMpfSxkZXN0cm95OmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiRGVzdHJveWluZyBwcmV2aW91cyBkcm9wZG93blwiLE0pLFMucmVtb3ZlLnRhYmJhYmxlKCksTS5vZmYoRSkucmVtb3ZlRGF0YShGKSxXLm9mZihFKSxzLm9mZihiKSxTLmRpc2Nvbm5lY3QubWVudU9ic2VydmVyKCksUy5kaXNjb25uZWN0LnNlbGVjdE9ic2VydmVyKCl9LG9ic2VydmVDaGFuZ2VzOmZ1bmN0aW9uKCl7XCJNdXRhdGlvbk9ic2VydmVyXCJpbiB0JiYoeD1uZXcgTXV0YXRpb25PYnNlcnZlcihTLmV2ZW50LnNlbGVjdC5tdXRhdGlvbiksQz1uZXcgTXV0YXRpb25PYnNlcnZlcihTLmV2ZW50Lm1lbnUubXV0YXRpb24pLFMuZGVidWcoXCJTZXR0aW5nIHVwIG11dGF0aW9uIG9ic2VydmVyXCIseCxDKSxTLm9ic2VydmUuc2VsZWN0KCksUy5vYnNlcnZlLm1lbnUoKSl9LGRpc2Nvbm5lY3Q6e21lbnVPYnNlcnZlcjpmdW5jdGlvbigpe0MmJkMuZGlzY29ubmVjdCgpfSxzZWxlY3RPYnNlcnZlcjpmdW5jdGlvbigpe3gmJnguZGlzY29ubmVjdCgpfX0sb2JzZXJ2ZTp7c2VsZWN0OmZ1bmN0aW9uKCl7Uy5oYXMuaW5wdXQoKSYmeC5vYnNlcnZlKE1bMF0se2NoaWxkTGlzdDohMCxzdWJ0cmVlOiEwfSl9LG1lbnU6ZnVuY3Rpb24oKXtTLmhhcy5tZW51KCkmJkMub2JzZXJ2ZShXWzBdLHtjaGlsZExpc3Q6ITAsc3VidHJlZTohMH0pfX0sY3JlYXRlOntpZDpmdW5jdGlvbigpe3c9KE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMTYpK1wiMDAwMDAwMDAwXCIpLnN1YnN0cigyLDgpLGI9XCIuXCIrdyxTLnZlcmJvc2UoXCJDcmVhdGluZyB1bmlxdWUgaWQgZm9yIGVsZW1lbnRcIix3KX0sdXNlckNob2ljZTpmdW5jdGlvbih0KXt2YXIgbixpLGE7cmV0dXJuISEodD10fHxTLmdldC51c2VyVmFsdWVzKCkpJiYodD1lLmlzQXJyYXkodCk/dDpbdF0sZS5lYWNoKHQsZnVuY3Rpb24odCxvKXshMT09PVMuZ2V0Lml0ZW0obykmJihhPXkudGVtcGxhdGVzLmFkZGl0aW9uKFMuYWRkLnZhcmlhYmxlcyhULmFkZFJlc3VsdCxvKSksaT1lKFwiPGRpdiAvPlwiKS5odG1sKGEpLmF0dHIoXCJkYXRhLVwiK0kudmFsdWUsbykuYXR0cihcImRhdGEtXCIrSS50ZXh0LG8pLmFkZENsYXNzKEEuYWRkaXRpb24pLmFkZENsYXNzKEEuaXRlbSkseS5oaWRlQWRkaXRpb25zJiZpLmFkZENsYXNzKEEuaGlkZGVuKSxuPXZvaWQgMD09PW4/aTpuLmFkZChpKSxTLnZlcmJvc2UoXCJDcmVhdGluZyB1c2VyIGNob2ljZXMgZm9yIHZhbHVlXCIsbyxpKSl9KSxuKX0sdXNlckxhYmVsczpmdW5jdGlvbih0KXt2YXIgbj1TLmdldC51c2VyVmFsdWVzKCk7biYmKFMuZGVidWcoXCJBZGRpbmcgdXNlciBsYWJlbHNcIixuKSxlLmVhY2gobixmdW5jdGlvbihlLHQpe1MudmVyYm9zZShcIkFkZGluZyBjdXN0b20gdXNlciB2YWx1ZVwiKSxTLmFkZC5sYWJlbCh0LHQpfSkpfSxtZW51OmZ1bmN0aW9uKCl7Vz1lKFwiPGRpdiAvPlwiKS5hZGRDbGFzcyhBLm1lbnUpLmFwcGVuZFRvKE0pfSxzaXplcjpmdW5jdGlvbigpe2o9ZShcIjxzcGFuIC8+XCIpLmFkZENsYXNzKEEuc2l6ZXIpLmluc2VydEFmdGVyKEgpfX0sc2VhcmNoOmZ1bmN0aW9uKGUpe2U9dm9pZCAwIT09ZT9lOlMuZ2V0LnF1ZXJ5KCksUy52ZXJib3NlKFwiU2VhcmNoaW5nIGZvciBxdWVyeVwiLGUpLFMuaGFzLm1pbkNoYXJhY3RlcnMoZSk/Uy5maWx0ZXIoZSk6Uy5oaWRlKCl9LHNlbGVjdDp7Zmlyc3RVbmZpbHRlcmVkOmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiU2VsZWN0aW5nIGZpcnN0IG5vbi1maWx0ZXJlZCBlbGVtZW50XCIpLFMucmVtb3ZlLnNlbGVjdGVkSXRlbSgpLEIubm90KFIudW5zZWxlY3RhYmxlKS5ub3QoUi5hZGRpdGlvbitSLmhpZGRlbikuZXEoMCkuYWRkQ2xhc3MoQS5zZWxlY3RlZCl9LG5leHRBdmFpbGFibGU6ZnVuY3Rpb24oZSl7ZT1lLmVxKDApO3ZhciB0PWUubmV4dEFsbChSLml0ZW0pLm5vdChSLnVuc2VsZWN0YWJsZSkuZXEoMCksbj1lLnByZXZBbGwoUi5pdGVtKS5ub3QoUi51bnNlbGVjdGFibGUpLmVxKDApO3QubGVuZ3RoPjA/KFMudmVyYm9zZShcIk1vdmluZyBzZWxlY3Rpb24gdG9cIix0KSx0LmFkZENsYXNzKEEuc2VsZWN0ZWQpKTooUy52ZXJib3NlKFwiTW92aW5nIHNlbGVjdGlvbiB0b1wiLG4pLG4uYWRkQ2xhc3MoQS5zZWxlY3RlZCkpfX0sc2V0dXA6e2FwaTpmdW5jdGlvbigpe3ZhciBlPXtkZWJ1Zzp5LmRlYnVnLHVybERhdGE6e3ZhbHVlOlMuZ2V0LnZhbHVlKCkscXVlcnk6Uy5nZXQucXVlcnkoKX0sb246ITF9O1MudmVyYm9zZShcIkZpcnN0IHJlcXVlc3QsIGluaXRpYWxpemluZyBBUElcIiksTS5hcGkoZSl9LGxheW91dDpmdW5jdGlvbigpe00uaXMoXCJzZWxlY3RcIikmJihTLnNldHVwLnNlbGVjdCgpLFMuc2V0dXAucmV0dXJuZWRPYmplY3QoKSksUy5oYXMubWVudSgpfHxTLmNyZWF0ZS5tZW51KCksUy5pcy5zZWFyY2goKSYmIVMuaGFzLnNlYXJjaCgpJiYoUy52ZXJib3NlKFwiQWRkaW5nIHNlYXJjaCBpbnB1dFwiKSxIPWUoXCI8aW5wdXQgLz5cIikuYWRkQ2xhc3MoQS5zZWFyY2gpLnByb3AoXCJhdXRvY29tcGxldGVcIixcIm9mZlwiKS5pbnNlcnRCZWZvcmUoUCkpLFMuaXMubXVsdGlwbGUoKSYmUy5pcy5zZWFyY2hTZWxlY3Rpb24oKSYmIVMuaGFzLnNpemVyKCkmJlMuY3JlYXRlLnNpemVyKCkseS5hbGxvd1RhYiYmUy5zZXQudGFiYmFibGUoKX0sc2VsZWN0OmZ1bmN0aW9uKCl7dmFyIHQ9Uy5nZXQuc2VsZWN0VmFsdWVzKCk7Uy5kZWJ1ZyhcIkRyb3Bkb3duIGluaXRpYWxpemVkIG9uIGEgc2VsZWN0XCIsdCksTS5pcyhcInNlbGVjdFwiKSYmKE49TSksTi5wYXJlbnQoUi5kcm9wZG93bikubGVuZ3RoPjA/KFMuZGVidWcoXCJVSSBkcm9wZG93biBhbHJlYWR5IGV4aXN0cy4gQ3JlYXRpbmcgZHJvcGRvd24gbWVudSBvbmx5XCIpLE09Ti5jbG9zZXN0KFIuZHJvcGRvd24pLFMuaGFzLm1lbnUoKXx8Uy5jcmVhdGUubWVudSgpLFc9TS5jaGlsZHJlbihSLm1lbnUpLFMuc2V0dXAubWVudSh0KSk6KFMuZGVidWcoXCJDcmVhdGluZyBlbnRpcmUgZHJvcGRvd24gZnJvbSBzZWxlY3RcIiksTT1lKFwiPGRpdiAvPlwiKS5hdHRyKFwiY2xhc3NcIixOLmF0dHIoXCJjbGFzc1wiKSkuYWRkQ2xhc3MoQS5zZWxlY3Rpb24pLmFkZENsYXNzKEEuZHJvcGRvd24pLmh0bWwoVi5kcm9wZG93bih0KSkuaW5zZXJ0QmVmb3JlKE4pLE4uaGFzQ2xhc3MoQS5tdWx0aXBsZSkmJiExPT09Ti5wcm9wKFwibXVsdGlwbGVcIikmJihTLmVycm9yKE8ubWlzc2luZ011bHRpcGxlKSxOLnByb3AoXCJtdWx0aXBsZVwiLCEwKSksTi5pcyhcIlttdWx0aXBsZV1cIikmJlMuc2V0Lm11bHRpcGxlKCksTi5wcm9wKFwiZGlzYWJsZWRcIikmJihTLmRlYnVnKFwiRGlzYWJsaW5nIGRyb3Bkb3duXCIpLE0uYWRkQ2xhc3MoQS5kaXNhYmxlZCkpLE4ucmVtb3ZlQXR0cihcImNsYXNzXCIpLmRldGFjaCgpLnByZXBlbmRUbyhNKSksUy5yZWZyZXNoKCl9LG1lbnU6ZnVuY3Rpb24oZSl7Vy5odG1sKFYubWVudShlLGspKSxCPVcuZmluZChSLml0ZW0pfSxyZWZlcmVuY2U6ZnVuY3Rpb24oKXtTLmRlYnVnKFwiRHJvcGRvd24gYmVoYXZpb3Igd2FzIGNhbGxlZCBvbiBzZWxlY3QsIHJlcGxhY2luZyB3aXRoIGNsb3Nlc3QgZHJvcGRvd25cIiksTT1NLnBhcmVudChSLmRyb3Bkb3duKSxHPU0uZGF0YShGKSxZPU0uZ2V0KDApLFMucmVmcmVzaCgpLFMuc2V0dXAucmV0dXJuZWRPYmplY3QoKX0scmV0dXJuZWRPYmplY3Q6ZnVuY3Rpb24oKXt2YXIgZT1vLnNsaWNlKDAsbSksdD1vLnNsaWNlKG0rMSk7bz1lLmFkZChNKS5hZGQodCl9fSxyZWZyZXNoOmZ1bmN0aW9uKCl7Uy5yZWZyZXNoU2VsZWN0b3JzKCksUy5yZWZyZXNoRGF0YSgpfSxyZWZyZXNoSXRlbXM6ZnVuY3Rpb24oKXtCPVcuZmluZChSLml0ZW0pfSxyZWZyZXNoU2VsZWN0b3JzOmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiUmVmcmVzaGluZyBzZWxlY3RvciBjYWNoZVwiKSxQPU0uZmluZChSLnRleHQpLEg9TS5maW5kKFIuc2VhcmNoKSxOPU0uZmluZChSLmlucHV0KSxVPU0uZmluZChSLmljb24pLEs9TS5wcmV2KCkuZmluZChSLnRleHQpLmxlbmd0aD4wP00ucHJldigpLmZpbmQoUi50ZXh0KTpNLnByZXYoKSxXPU0uY2hpbGRyZW4oUi5tZW51KSxCPVcuZmluZChSLml0ZW0pfSxyZWZyZXNoRGF0YTpmdW5jdGlvbigpe1MudmVyYm9zZShcIlJlZnJlc2hpbmcgY2FjaGVkIG1ldGFkYXRhXCIpLEIucmVtb3ZlRGF0YShJLnRleHQpLnJlbW92ZURhdGEoSS52YWx1ZSl9LGNsZWFyRGF0YTpmdW5jdGlvbigpe1MudmVyYm9zZShcIkNsZWFyaW5nIG1ldGFkYXRhXCIpLEIucmVtb3ZlRGF0YShJLnRleHQpLnJlbW92ZURhdGEoSS52YWx1ZSksTS5yZW1vdmVEYXRhKEkuZGVmYXVsdFRleHQpLnJlbW92ZURhdGEoSS5kZWZhdWx0VmFsdWUpLnJlbW92ZURhdGEoSS5wbGFjZWhvbGRlclRleHQpfSx0b2dnbGU6ZnVuY3Rpb24oKXtTLnZlcmJvc2UoXCJUb2dnbGluZyBtZW51IHZpc2liaWxpdHlcIiksUy5pcy5hY3RpdmUoKT9TLmhpZGUoKTpTLnNob3coKX0sc2hvdzpmdW5jdGlvbih0KXtpZih0PWUuaXNGdW5jdGlvbih0KT90OmZ1bmN0aW9uKCl7fSwhUy5jYW4uc2hvdygpJiZTLmlzLnJlbW90ZSgpJiYoUy5kZWJ1ZyhcIk5vIEFQSSByZXN1bHRzIHJldHJpZXZlZCwgc2VhcmNoaW5nIGJlZm9yZSBzaG93XCIpLFMucXVlcnlSZW1vdGUoUy5nZXQucXVlcnkoKSxTLnNob3cpKSxTLmNhbi5zaG93KCkmJiFTLmlzLmFjdGl2ZSgpKXtpZihTLmRlYnVnKFwiU2hvd2luZyBkcm9wZG93blwiKSwhUy5oYXMubWVzc2FnZSgpfHxTLmhhcy5tYXhTZWxlY3Rpb25zKCl8fFMuaGFzLmFsbFJlc3VsdHNGaWx0ZXJlZCgpfHxTLnJlbW92ZS5tZXNzYWdlKCksUy5pcy5hbGxGaWx0ZXJlZCgpKXJldHVybiEwOyExIT09eS5vblNob3cuY2FsbChZKSYmUy5hbmltYXRlLnNob3coZnVuY3Rpb24oKXtTLmNhbi5jbGljaygpJiZTLmJpbmQuaW50ZW50KCksUy5oYXMubWVudVNlYXJjaCgpJiZTLmZvY3VzU2VhcmNoKCksUy5zZXQudmlzaWJsZSgpLHQuY2FsbChZKX0pfX0saGlkZTpmdW5jdGlvbih0KXt0PWUuaXNGdW5jdGlvbih0KT90OmZ1bmN0aW9uKCl7fSxTLmlzLmFjdGl2ZSgpJiYoUy5kZWJ1ZyhcIkhpZGluZyBkcm9wZG93blwiKSwhMSE9PXkub25IaWRlLmNhbGwoWSkmJlMuYW5pbWF0ZS5oaWRlKGZ1bmN0aW9uKCl7Uy5yZW1vdmUudmlzaWJsZSgpLHQuY2FsbChZKX0pKX0saGlkZU90aGVyczpmdW5jdGlvbigpe1MudmVyYm9zZShcIkZpbmRpbmcgb3RoZXIgZHJvcGRvd25zIHRvIGhpZGVcIiksby5ub3QoTSkuaGFzKFIubWVudStcIi5cIitBLnZpc2libGUpLmRyb3Bkb3duKFwiaGlkZVwiKX0saGlkZU1lbnU6ZnVuY3Rpb24oKXtTLnZlcmJvc2UoXCJIaWRpbmcgbWVudSAgaW5zdGFudGFuZW91c2x5XCIpLFMucmVtb3ZlLmFjdGl2ZSgpLFMucmVtb3ZlLnZpc2libGUoKSxXLnRyYW5zaXRpb24oXCJoaWRlXCIpfSxoaWRlU3ViTWVudXM6ZnVuY3Rpb24oKXt2YXIgZT1XLmNoaWxkcmVuKFIuaXRlbSkuZmluZChSLm1lbnUpO1MudmVyYm9zZShcIkhpZGluZyBzdWIgbWVudXNcIixlKSxlLnRyYW5zaXRpb24oXCJoaWRlXCIpfSxiaW5kOntldmVudHM6ZnVuY3Rpb24oKXtsJiZTLmJpbmQudG91Y2hFdmVudHMoKSxTLmJpbmQua2V5Ym9hcmRFdmVudHMoKSxTLmJpbmQuaW5wdXRFdmVudHMoKSxTLmJpbmQubW91c2VFdmVudHMoKX0sdG91Y2hFdmVudHM6ZnVuY3Rpb24oKXtTLmRlYnVnKFwiVG91Y2ggZGV2aWNlIGRldGVjdGVkIGJpbmRpbmcgYWRkaXRpb25hbCB0b3VjaCBldmVudHNcIiksUy5pcy5zZWFyY2hTZWxlY3Rpb24oKXx8Uy5pcy5zaW5nbGUoKSYmTS5vbihcInRvdWNoc3RhcnRcIitFLFMuZXZlbnQudGVzdC50b2dnbGUpLFcub24oXCJ0b3VjaHN0YXJ0XCIrRSxSLml0ZW0sUy5ldmVudC5pdGVtLm1vdXNlZW50ZXIpfSxrZXlib2FyZEV2ZW50czpmdW5jdGlvbigpe1MudmVyYm9zZShcIkJpbmRpbmcga2V5Ym9hcmQgZXZlbnRzXCIpLE0ub24oXCJrZXlkb3duXCIrRSxTLmV2ZW50LmtleWRvd24pLFMuaGFzLnNlYXJjaCgpJiZNLm9uKFMuZ2V0LmlucHV0RXZlbnQoKStFLFIuc2VhcmNoLFMuZXZlbnQuaW5wdXQpLFMuaXMubXVsdGlwbGUoKSYmcy5vbihcImtleWRvd25cIitiLFMuZXZlbnQuZG9jdW1lbnQua2V5ZG93bil9LGlucHV0RXZlbnRzOmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiQmluZGluZyBpbnB1dCBjaGFuZ2UgZXZlbnRzXCIpLE0ub24oXCJjaGFuZ2VcIitFLFIuaW5wdXQsUy5ldmVudC5jaGFuZ2UpfSxtb3VzZUV2ZW50czpmdW5jdGlvbigpe1MudmVyYm9zZShcIkJpbmRpbmcgbW91c2UgZXZlbnRzXCIpLFMuaXMubXVsdGlwbGUoKSYmTS5vbihcImNsaWNrXCIrRSxSLmxhYmVsLFMuZXZlbnQubGFiZWwuY2xpY2spLm9uKFwiY2xpY2tcIitFLFIucmVtb3ZlLFMuZXZlbnQucmVtb3ZlLmNsaWNrKSxTLmlzLnNlYXJjaFNlbGVjdGlvbigpPyhNLm9uKFwibW91c2Vkb3duXCIrRSxTLmV2ZW50Lm1vdXNlZG93bikub24oXCJtb3VzZXVwXCIrRSxTLmV2ZW50Lm1vdXNldXApLm9uKFwibW91c2Vkb3duXCIrRSxSLm1lbnUsUy5ldmVudC5tZW51Lm1vdXNlZG93bikub24oXCJtb3VzZXVwXCIrRSxSLm1lbnUsUy5ldmVudC5tZW51Lm1vdXNldXApLm9uKFwiY2xpY2tcIitFLFIuaWNvbixTLmV2ZW50Lmljb24uY2xpY2spLm9uKFwiZm9jdXNcIitFLFIuc2VhcmNoLFMuZXZlbnQuc2VhcmNoLmZvY3VzKS5vbihcImNsaWNrXCIrRSxSLnNlYXJjaCxTLmV2ZW50LnNlYXJjaC5mb2N1cykub24oXCJibHVyXCIrRSxSLnNlYXJjaCxTLmV2ZW50LnNlYXJjaC5ibHVyKS5vbihcImNsaWNrXCIrRSxSLnRleHQsUy5ldmVudC50ZXh0LmZvY3VzKSxTLmlzLm11bHRpcGxlKCkmJk0ub24oXCJjbGlja1wiK0UsUy5ldmVudC5jbGljaykpOihcImNsaWNrXCI9PXkub24/TS5vbihcImNsaWNrXCIrRSxSLmljb24sUy5ldmVudC5pY29uLmNsaWNrKS5vbihcImNsaWNrXCIrRSxTLmV2ZW50LnRlc3QudG9nZ2xlKTpcImhvdmVyXCI9PXkub24/TS5vbihcIm1vdXNlZW50ZXJcIitFLFMuZGVsYXkuc2hvdykub24oXCJtb3VzZWxlYXZlXCIrRSxTLmRlbGF5LmhpZGUpOk0ub24oeS5vbitFLFMudG9nZ2xlKSxNLm9uKFwibW91c2Vkb3duXCIrRSxTLmV2ZW50Lm1vdXNlZG93bikub24oXCJtb3VzZXVwXCIrRSxTLmV2ZW50Lm1vdXNldXApLm9uKFwiZm9jdXNcIitFLFMuZXZlbnQuZm9jdXMpLFMuaGFzLm1lbnVTZWFyY2goKT9NLm9uKFwiYmx1clwiK0UsUi5zZWFyY2gsUy5ldmVudC5zZWFyY2guYmx1cik6TS5vbihcImJsdXJcIitFLFMuZXZlbnQuYmx1cikpLFcub24oXCJtb3VzZWVudGVyXCIrRSxSLml0ZW0sUy5ldmVudC5pdGVtLm1vdXNlZW50ZXIpLm9uKFwibW91c2VsZWF2ZVwiK0UsUi5pdGVtLFMuZXZlbnQuaXRlbS5tb3VzZWxlYXZlKS5vbihcImNsaWNrXCIrRSxSLml0ZW0sUy5ldmVudC5pdGVtLmNsaWNrKX0saW50ZW50OmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiQmluZGluZyBoaWRlIGludGVudCBldmVudCB0byBkb2N1bWVudFwiKSxsJiZzLm9uKFwidG91Y2hzdGFydFwiK2IsUy5ldmVudC50ZXN0LnRvdWNoKS5vbihcInRvdWNobW92ZVwiK2IsUy5ldmVudC50ZXN0LnRvdWNoKSxzLm9uKFwiY2xpY2tcIitiLFMuZXZlbnQudGVzdC5oaWRlKX19LHVuYmluZDp7aW50ZW50OmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiUmVtb3ZpbmcgaGlkZSBpbnRlbnQgZXZlbnQgZnJvbSBkb2N1bWVudFwiKSxsJiZzLm9mZihcInRvdWNoc3RhcnRcIitiKS5vZmYoXCJ0b3VjaG1vdmVcIitiKSxzLm9mZihcImNsaWNrXCIrYil9fSxmaWx0ZXI6ZnVuY3Rpb24oZSl7dmFyIHQ9dm9pZCAwIT09ZT9lOlMuZ2V0LnF1ZXJ5KCksbj1mdW5jdGlvbigpe1MuaXMubXVsdGlwbGUoKSYmUy5maWx0ZXJBY3RpdmUoKSwoZXx8IWUmJjA9PVMuZ2V0LmFjdGl2ZUl0ZW0oKS5sZW5ndGgpJiZTLnNlbGVjdC5maXJzdFVuZmlsdGVyZWQoKSxTLmhhcy5hbGxSZXN1bHRzRmlsdGVyZWQoKT95Lm9uTm9SZXN1bHRzLmNhbGwoWSx0KT95LmFsbG93QWRkaXRpb25zP3kuaGlkZUFkZGl0aW9ucyYmKFMudmVyYm9zZShcIlVzZXIgYWRkaXRpb24gd2l0aCBubyBtZW51LCBzZXR0aW5nIGVtcHR5IHN0eWxlXCIpLFMuc2V0LmVtcHR5KCksUy5oaWRlTWVudSgpKTooUy52ZXJib3NlKFwiQWxsIGl0ZW1zIGZpbHRlcmVkLCBzaG93aW5nIG1lc3NhZ2VcIix0KSxTLmFkZC5tZXNzYWdlKFQubm9SZXN1bHRzKSk6KFMudmVyYm9zZShcIkFsbCBpdGVtcyBmaWx0ZXJlZCwgaGlkaW5nIGRyb3Bkb3duXCIsdCksUy5oaWRlTWVudSgpKTooUy5yZW1vdmUuZW1wdHkoKSxTLnJlbW92ZS5tZXNzYWdlKCkpLHkuYWxsb3dBZGRpdGlvbnMmJlMuYWRkLnVzZXJTdWdnZXN0aW9uKGUpLFMuaXMuc2VhcmNoU2VsZWN0aW9uKCkmJlMuY2FuLnNob3coKSYmUy5pcy5mb2N1c2VkT25TZWFyY2goKSYmUy5zaG93KCl9O3kudXNlTGFiZWxzJiZTLmhhcy5tYXhTZWxlY3Rpb25zKCl8fCh5LmFwaVNldHRpbmdzP1MuY2FuLnVzZUFQSSgpP1MucXVlcnlSZW1vdGUodCxmdW5jdGlvbigpe3kuZmlsdGVyUmVtb3RlRGF0YSYmUy5maWx0ZXJJdGVtcyh0KSxuKCl9KTpTLmVycm9yKE8ubm9BUEkpOihTLmZpbHRlckl0ZW1zKHQpLG4oKSkpfSxxdWVyeVJlbW90ZTpmdW5jdGlvbih0LG4pe3ZhciBpPXtlcnJvckR1cmF0aW9uOiExLGNhY2hlOlwibG9jYWxcIix0aHJvdHRsZTp5LnRocm90dGxlLHVybERhdGE6e3F1ZXJ5OnR9LG9uRXJyb3I6ZnVuY3Rpb24oKXtTLmFkZC5tZXNzYWdlKFQuc2VydmVyRXJyb3IpLG4oKX0sb25GYWlsdXJlOmZ1bmN0aW9uKCl7Uy5hZGQubWVzc2FnZShULnNlcnZlckVycm9yKSxuKCl9LG9uU3VjY2VzczpmdW5jdGlvbihlKXtTLnJlbW92ZS5tZXNzYWdlKCksUy5zZXR1cC5tZW51KHt2YWx1ZXM6ZVtrLnJlbW90ZVZhbHVlc119KSxuKCl9fTtNLmFwaShcImdldCByZXF1ZXN0XCIpfHxTLnNldHVwLmFwaSgpLGk9ZS5leHRlbmQoITAse30saSx5LmFwaVNldHRpbmdzKSxNLmFwaShcInNldHRpbmdcIixpKS5hcGkoXCJxdWVyeVwiKX0sZmlsdGVySXRlbXM6ZnVuY3Rpb24odCl7dmFyIG49dm9pZCAwIT09dD90OlMuZ2V0LnF1ZXJ5KCksaT1udWxsLGE9Uy5lc2NhcGUuc3RyaW5nKG4pLG89bmV3IFJlZ0V4cChcIl5cIithLFwiaWdtXCIpO1MuaGFzLnF1ZXJ5KCkmJihpPVtdLFMudmVyYm9zZShcIlNlYXJjaGluZyBmb3IgbWF0Y2hpbmcgdmFsdWVzXCIsbiksQi5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQsYSxzPWUodGhpcyk7aWYoXCJib3RoXCI9PXkubWF0Y2h8fFwidGV4dFwiPT15Lm1hdGNoKXtpZih0PVN0cmluZyhTLmdldC5jaG9pY2VUZXh0KHMsITEpKSwtMSE9PXQuc2VhcmNoKG8pKXJldHVybiBpLnB1c2godGhpcyksITA7aWYoXCJleGFjdFwiPT09eS5mdWxsVGV4dFNlYXJjaCYmUy5leGFjdFNlYXJjaChuLHQpKXJldHVybiBpLnB1c2godGhpcyksITA7aWYoITA9PT15LmZ1bGxUZXh0U2VhcmNoJiZTLmZ1enp5U2VhcmNoKG4sdCkpcmV0dXJuIGkucHVzaCh0aGlzKSwhMH1pZihcImJvdGhcIj09eS5tYXRjaHx8XCJ2YWx1ZVwiPT15Lm1hdGNoKXtpZihhPVN0cmluZyhTLmdldC5jaG9pY2VWYWx1ZShzLHQpKSwtMSE9PWEuc2VhcmNoKG8pKXJldHVybiBpLnB1c2godGhpcyksITA7aWYoXCJleGFjdFwiPT09eS5mdWxsVGV4dFNlYXJjaCYmUy5leGFjdFNlYXJjaChuLGEpKXJldHVybiBpLnB1c2godGhpcyksITA7aWYoITA9PT15LmZ1bGxUZXh0U2VhcmNoJiZTLmZ1enp5U2VhcmNoKG4sYSkpcmV0dXJuIGkucHVzaCh0aGlzKSwhMH19KSksUy5kZWJ1ZyhcIlNob3dpbmcgb25seSBtYXRjaGVkIGl0ZW1zXCIsbiksUy5yZW1vdmUuZmlsdGVyZWRJdGVtKCksaSYmQi5ub3QoaSkuYWRkQ2xhc3MoQS5maWx0ZXJlZCl9LGZ1enp5U2VhcmNoOmZ1bmN0aW9uKGUsdCl7dmFyIG49dC5sZW5ndGgsaT1lLmxlbmd0aDtpZihlPWUudG9Mb3dlckNhc2UoKSx0PXQudG9Mb3dlckNhc2UoKSxpPm4pcmV0dXJuITE7aWYoaT09PW4pcmV0dXJuIGU9PT10O2U6Zm9yKHZhciBhPTAsbz0wO2E8aTthKyspe2Zvcih2YXIgcz1lLmNoYXJDb2RlQXQoYSk7bzxuOylpZih0LmNoYXJDb2RlQXQobysrKT09PXMpY29udGludWUgZTtyZXR1cm4hMX1yZXR1cm4hMH0sZXhhY3RTZWFyY2g6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT1lLnRvTG93ZXJDYXNlKCksdD10LnRvTG93ZXJDYXNlKCksdC5pbmRleE9mKGUpPi0xfSxmaWx0ZXJBY3RpdmU6ZnVuY3Rpb24oKXt5LnVzZUxhYmVscyYmQi5maWx0ZXIoXCIuXCIrQS5hY3RpdmUpLmFkZENsYXNzKEEuZmlsdGVyZWQpfSxmb2N1c1NlYXJjaDpmdW5jdGlvbihlKXtTLmhhcy5zZWFyY2goKSYmIVMuaXMuZm9jdXNlZE9uU2VhcmNoKCkmJihlPyhNLm9mZihcImZvY3VzXCIrRSxSLnNlYXJjaCksSC5mb2N1cygpLE0ub24oXCJmb2N1c1wiK0UsUi5zZWFyY2gsUy5ldmVudC5zZWFyY2guZm9jdXMpKTpILmZvY3VzKCkpfSxmb3JjZVNlbGVjdGlvbjpmdW5jdGlvbigpe3ZhciBlPUIubm90KEEuZmlsdGVyZWQpLmZpbHRlcihcIi5cIitBLnNlbGVjdGVkKS5lcSgwKSx0PUIubm90KEEuZmlsdGVyZWQpLmZpbHRlcihcIi5cIitBLmFjdGl2ZSkuZXEoMCksbj1lLmxlbmd0aD4wP2U6dDtpZihuLmxlbmd0aD4wJiYhUy5pcy5tdWx0aXBsZSgpKXJldHVybiBTLmRlYnVnKFwiRm9yY2luZyBwYXJ0aWFsIHNlbGVjdGlvbiB0byBzZWxlY3RlZCBpdGVtXCIsbiksdm9pZCBTLmV2ZW50Lml0ZW0uY2xpY2suY2FsbChuLHt9LCEwKTt5LmFsbG93QWRkaXRpb25zPyhTLnNldC5zZWxlY3RlZChTLmdldC5xdWVyeSgpKSxTLnJlbW92ZS5zZWFyY2hUZXJtKCkpOlMucmVtb3ZlLnNlYXJjaFRlcm0oKX0sY2hhbmdlOnt2YWx1ZXM6ZnVuY3Rpb24odCl7eS5hbGxvd0FkZGl0aW9uc3x8Uy5jbGVhcigpLFMuZGVidWcoXCJDcmVhdGluZyBkcm9wZG93biB3aXRoIHNwZWNpZmllZCB2YWx1ZXNcIix0KSxTLnNldHVwLm1lbnUoe3ZhbHVlczp0fSksZS5lYWNoKHQsZnVuY3Rpb24oZSx0KXtpZigxPT10LnNlbGVjdGVkKXJldHVybiBTLmRlYnVnKFwiU2V0dGluZyBpbml0aWFsIHNlbGVjdGlvbiB0b1wiLHQudmFsdWUpLFMuc2V0LnNlbGVjdGVkKHQudmFsdWUpLCEwfSl9fSxldmVudDp7Y2hhbmdlOmZ1bmN0aW9uKCl7WHx8KFMuZGVidWcoXCJJbnB1dCBjaGFuZ2VkLCB1cGRhdGluZyBzZWxlY3Rpb25cIiksUy5zZXQuc2VsZWN0ZWQoKSl9LGZvY3VzOmZ1bmN0aW9uKCl7eS5zaG93T25Gb2N1cyYmISQmJlMuaXMuaGlkZGVuKCkmJiFnJiZTLnNob3coKX0sYmx1cjpmdW5jdGlvbihlKXtnPW4uYWN0aXZlRWxlbWVudD09PXRoaXMsJHx8Z3x8KFMucmVtb3ZlLmFjdGl2ZUxhYmVsKCksUy5oaWRlKCkpfSxtb3VzZWRvd246ZnVuY3Rpb24oKXtTLmlzLnNlYXJjaFNlbGVjdGlvbigpP3A9ITA6JD0hMH0sbW91c2V1cDpmdW5jdGlvbigpe1MuaXMuc2VhcmNoU2VsZWN0aW9uKCk/cD0hMTokPSExfSxjbGljazpmdW5jdGlvbih0KXtlKHQudGFyZ2V0KS5pcyhNKSYmKFMuaXMuZm9jdXNlZE9uU2VhcmNoKCk/Uy5zaG93KCk6Uy5mb2N1c1NlYXJjaCgpKX0sc2VhcmNoOntmb2N1czpmdW5jdGlvbigpeyQ9ITAsUy5pcy5tdWx0aXBsZSgpJiZTLnJlbW92ZS5hY3RpdmVMYWJlbCgpLHkuc2hvd09uRm9jdXMmJlMuc2VhcmNoKCl9LGJsdXI6ZnVuY3Rpb24oZSl7Zz1uLmFjdGl2ZUVsZW1lbnQ9PT10aGlzLFMuaXMuc2VhcmNoU2VsZWN0aW9uKCkmJiFwJiYoUXx8Z3x8KHkuZm9yY2VTZWxlY3Rpb24mJlMuZm9yY2VTZWxlY3Rpb24oKSxTLmhpZGUoKSkpLHA9ITF9fSxpY29uOntjbGljazpmdW5jdGlvbihlKXtTLnRvZ2dsZSgpfX0sdGV4dDp7Zm9jdXM6ZnVuY3Rpb24oZSl7JD0hMCxTLmZvY3VzU2VhcmNoKCl9fSxpbnB1dDpmdW5jdGlvbihlKXsoUy5pcy5tdWx0aXBsZSgpfHxTLmlzLnNlYXJjaFNlbGVjdGlvbigpKSYmUy5zZXQuZmlsdGVyZWQoKSxjbGVhclRpbWVvdXQoUy50aW1lciksUy50aW1lcj1zZXRUaW1lb3V0KFMuc2VhcmNoLHkuZGVsYXkuc2VhcmNoKX0sbGFiZWw6e2NsaWNrOmZ1bmN0aW9uKHQpe3ZhciBuPWUodGhpcyksaT1NLmZpbmQoUi5sYWJlbCksYT1pLmZpbHRlcihcIi5cIitBLmFjdGl2ZSksbz1uLm5leHRBbGwoXCIuXCIrQS5hY3RpdmUpLHM9bi5wcmV2QWxsKFwiLlwiK0EuYWN0aXZlKSxyPW8ubGVuZ3RoPjA/bi5uZXh0VW50aWwobykuYWRkKGEpLmFkZChuKTpuLnByZXZVbnRpbChzKS5hZGQoYSkuYWRkKG4pO3Quc2hpZnRLZXk/KGEucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpLHIuYWRkQ2xhc3MoQS5hY3RpdmUpKTp0LmN0cmxLZXk/bi50b2dnbGVDbGFzcyhBLmFjdGl2ZSk6KGEucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpLG4uYWRkQ2xhc3MoQS5hY3RpdmUpKSx5Lm9uTGFiZWxTZWxlY3QuYXBwbHkodGhpcyxpLmZpbHRlcihcIi5cIitBLmFjdGl2ZSkpfX0scmVtb3ZlOntjbGljazpmdW5jdGlvbigpe3ZhciB0PWUodGhpcykucGFyZW50KCk7dC5oYXNDbGFzcyhBLmFjdGl2ZSk/Uy5yZW1vdmUuYWN0aXZlTGFiZWxzKCk6Uy5yZW1vdmUuYWN0aXZlTGFiZWxzKHQpfX0sdGVzdDp7dG9nZ2xlOmZ1bmN0aW9uKGUpe3ZhciB0PVMuaXMubXVsdGlwbGUoKT9TLnNob3c6Uy50b2dnbGU7Uy5pcy5idWJibGVkTGFiZWxDbGljayhlKXx8Uy5pcy5idWJibGVkSWNvbkNsaWNrKGUpfHxTLmRldGVybWluZS5ldmVudE9uRWxlbWVudChlLHQpJiZlLnByZXZlbnREZWZhdWx0KCl9LHRvdWNoOmZ1bmN0aW9uKGUpe1MuZGV0ZXJtaW5lLmV2ZW50T25FbGVtZW50KGUsZnVuY3Rpb24oKXtcInRvdWNoc3RhcnRcIj09ZS50eXBlP1MudGltZXI9c2V0VGltZW91dChmdW5jdGlvbigpe1MuaGlkZSgpfSx5LmRlbGF5LnRvdWNoKTpcInRvdWNobW92ZVwiPT1lLnR5cGUmJmNsZWFyVGltZW91dChTLnRpbWVyKX0pLGUuc3RvcFByb3BhZ2F0aW9uKCl9LGhpZGU6ZnVuY3Rpb24oZSl7Uy5kZXRlcm1pbmUuZXZlbnRJbk1vZHVsZShlLFMuaGlkZSl9fSxzZWxlY3Q6e211dGF0aW9uOmZ1bmN0aW9uKHQpe1MuZGVidWcoXCI8c2VsZWN0PiBtb2RpZmllZCwgcmVjcmVhdGluZyBtZW51XCIpO3ZhciBuPSExO2UuZWFjaCh0LGZ1bmN0aW9uKHQsaSl7aWYoZShpLnRhcmdldCkuaXMoXCJzZWxlY3RcIil8fGUoaS5hZGRlZE5vZGVzKS5pcyhcInNlbGVjdFwiKSlyZXR1cm4gbj0hMCwhMH0pLG4mJihTLmRpc2Nvbm5lY3Quc2VsZWN0T2JzZXJ2ZXIoKSxTLnJlZnJlc2goKSxTLnNldHVwLnNlbGVjdCgpLFMuc2V0LnNlbGVjdGVkKCksUy5vYnNlcnZlLnNlbGVjdCgpKX19LG1lbnU6e211dGF0aW9uOmZ1bmN0aW9uKHQpe3ZhciBuPXRbMF0saT1lKG4uYWRkZWROb2Rlcz9uLmFkZGVkTm9kZXNbMF06ITEpLGE9ZShuLnJlbW92ZWROb2Rlcz9uLnJlbW92ZWROb2Rlc1swXTohMSksbz1pLmFkZChhKSxzPW8uaXMoUi5hZGRpdGlvbil8fG8uY2xvc2VzdChSLmFkZGl0aW9uKS5sZW5ndGg+MCxyPW8uaXMoUi5tZXNzYWdlKXx8by5jbG9zZXN0KFIubWVzc2FnZSkubGVuZ3RoPjA7c3x8cj8oUy5kZWJ1ZyhcIlVwZGF0aW5nIGl0ZW0gc2VsZWN0b3IgY2FjaGVcIiksUy5yZWZyZXNoSXRlbXMoKSk6KFMuZGVidWcoXCJNZW51IG1vZGlmaWVkLCB1cGRhdGluZyBzZWxlY3RvciBjYWNoZVwiKSxTLnJlZnJlc2goKSl9LG1vdXNlZG93bjpmdW5jdGlvbigpe1E9ITB9LG1vdXNldXA6ZnVuY3Rpb24oKXtRPSExfX0saXRlbTp7bW91c2VlbnRlcjpmdW5jdGlvbih0KXt2YXIgbj1lKHQudGFyZ2V0KSxpPWUodGhpcyksYT1pLmNoaWxkcmVuKFIubWVudSksbz1pLnNpYmxpbmdzKFIuaXRlbSkuY2hpbGRyZW4oUi5tZW51KSxzPWEubGVuZ3RoPjA7IShhLmZpbmQobikubGVuZ3RoPjApJiZzJiYoY2xlYXJUaW1lb3V0KFMuaXRlbVRpbWVyKSxTLml0ZW1UaW1lcj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiU2hvd2luZyBzdWItbWVudVwiLGEpLGUuZWFjaChvLGZ1bmN0aW9uKCl7Uy5hbmltYXRlLmhpZGUoITEsZSh0aGlzKSl9KSxTLmFuaW1hdGUuc2hvdyghMSxhKX0seS5kZWxheS5zaG93KSx0LnByZXZlbnREZWZhdWx0KCkpfSxtb3VzZWxlYXZlOmZ1bmN0aW9uKHQpe3ZhciBuPWUodGhpcykuY2hpbGRyZW4oUi5tZW51KTtuLmxlbmd0aD4wJiYoY2xlYXJUaW1lb3V0KFMuaXRlbVRpbWVyKSxTLml0ZW1UaW1lcj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiSGlkaW5nIHN1Yi1tZW51XCIsbiksUy5hbmltYXRlLmhpZGUoITEsbil9LHkuZGVsYXkuaGlkZSkpfSxjbGljazpmdW5jdGlvbih0LGkpe3ZhciBhPWUodGhpcyksbz1lKHQ/dC50YXJnZXQ6XCJcIikscz1hLmZpbmQoUi5tZW51KSxyPVMuZ2V0LmNob2ljZVRleHQoYSksbD1TLmdldC5jaG9pY2VWYWx1ZShhLHIpLGM9cy5sZW5ndGg+MCx1PXMuZmluZChvKS5sZW5ndGg+MDtTLmhhcy5tZW51U2VhcmNoKCkmJmUobi5hY3RpdmVFbGVtZW50KS5ibHVyKCksdXx8YyYmIXkuYWxsb3dDYXRlZ29yeVNlbGVjdGlvbnx8KFMuaXMuc2VhcmNoU2VsZWN0aW9uKCkmJih5LmFsbG93QWRkaXRpb25zJiZTLnJlbW92ZS51c2VyQWRkaXRpb24oKSxTLnJlbW92ZS5zZWFyY2hUZXJtKCksUy5pcy5mb2N1c2VkT25TZWFyY2goKXx8MT09aXx8Uy5mb2N1c1NlYXJjaCghMCkpLHkudXNlTGFiZWxzfHwoUy5yZW1vdmUuZmlsdGVyZWRJdGVtKCksUy5zZXQuc2Nyb2xsUG9zaXRpb24oYSkpLFMuZGV0ZXJtaW5lLnNlbGVjdEFjdGlvbi5jYWxsKHRoaXMscixsKSl9fSxkb2N1bWVudDp7a2V5ZG93bjpmdW5jdGlvbihlKXt2YXIgdD1lLndoaWNoO2lmKFMuaXMuaW5PYmplY3QodCxMKSl7dmFyIG49TS5maW5kKFIubGFiZWwpLGk9bi5maWx0ZXIoXCIuXCIrQS5hY3RpdmUpLGE9KGkuZGF0YShJLnZhbHVlKSxuLmluZGV4KGkpKSxvPW4ubGVuZ3RoLHM9aS5sZW5ndGg+MCxyPWkubGVuZ3RoPjEsbD0wPT09YSxjPWErMT09byx1PVMuaXMuc2VhcmNoU2VsZWN0aW9uKCksZD1TLmlzLmZvY3VzZWRPblNlYXJjaCgpLHY9Uy5pcy5mb2N1c2VkKCksZj1kJiYwPT09Uy5nZXQuY2FyZXRQb3NpdGlvbigpO2lmKHUmJiFzJiYhZClyZXR1cm47dD09TC5sZWZ0QXJyb3c/IXYmJiFmfHxzP3MmJihlLnNoaWZ0S2V5P1MudmVyYm9zZShcIkFkZGluZyBwcmV2aW91cyBsYWJlbCB0byBzZWxlY3Rpb25cIik6KFMudmVyYm9zZShcIlNlbGVjdGluZyBwcmV2aW91cyBsYWJlbFwiKSxuLnJlbW92ZUNsYXNzKEEuYWN0aXZlKSksbCYmIXI/aS5hZGRDbGFzcyhBLmFjdGl2ZSk6aS5wcmV2KFIuc2libGluZ0xhYmVsKS5hZGRDbGFzcyhBLmFjdGl2ZSkuZW5kKCksZS5wcmV2ZW50RGVmYXVsdCgpKTooUy52ZXJib3NlKFwiU2VsZWN0aW5nIHByZXZpb3VzIGxhYmVsXCIpLG4ubGFzdCgpLmFkZENsYXNzKEEuYWN0aXZlKSk6dD09TC5yaWdodEFycm93Pyh2JiYhcyYmbi5maXJzdCgpLmFkZENsYXNzKEEuYWN0aXZlKSxzJiYoZS5zaGlmdEtleT9TLnZlcmJvc2UoXCJBZGRpbmcgbmV4dCBsYWJlbCB0byBzZWxlY3Rpb25cIik6KFMudmVyYm9zZShcIlNlbGVjdGluZyBuZXh0IGxhYmVsXCIpLG4ucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpKSxjP3U/ZD9uLnJlbW92ZUNsYXNzKEEuYWN0aXZlKTpTLmZvY3VzU2VhcmNoKCk6cj9pLm5leHQoUi5zaWJsaW5nTGFiZWwpLmFkZENsYXNzKEEuYWN0aXZlKTppLmFkZENsYXNzKEEuYWN0aXZlKTppLm5leHQoUi5zaWJsaW5nTGFiZWwpLmFkZENsYXNzKEEuYWN0aXZlKSxlLnByZXZlbnREZWZhdWx0KCkpKTp0PT1MLmRlbGV0ZUtleXx8dD09TC5iYWNrc3BhY2U/cz8oUy52ZXJib3NlKFwiUmVtb3ZpbmcgYWN0aXZlIGxhYmVsc1wiKSxjJiZ1JiYhZCYmUy5mb2N1c1NlYXJjaCgpLGkubGFzdCgpLm5leHQoUi5zaWJsaW5nTGFiZWwpLmFkZENsYXNzKEEuYWN0aXZlKSxTLnJlbW92ZS5hY3RpdmVMYWJlbHMoaSksZS5wcmV2ZW50RGVmYXVsdCgpKTpmJiYhcyYmdD09TC5iYWNrc3BhY2UmJihTLnZlcmJvc2UoXCJSZW1vdmluZyBsYXN0IGxhYmVsIG9uIGlucHV0IGJhY2tzcGFjZVwiKSxpPW4ubGFzdCgpLmFkZENsYXNzKEEuYWN0aXZlKSxTLnJlbW92ZS5hY3RpdmVMYWJlbHMoaSkpOmkucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpfX19LGtleWRvd246ZnVuY3Rpb24oZSl7dmFyIHQ9ZS53aGljaDtpZihTLmlzLmluT2JqZWN0KHQsTCkpe3ZhciBuLGk9Qi5ub3QoUi51bnNlbGVjdGFibGUpLmZpbHRlcihcIi5cIitBLnNlbGVjdGVkKS5lcSgwKSxhPVcuY2hpbGRyZW4oXCIuXCIrQS5hY3RpdmUpLmVxKDApLG89aS5sZW5ndGg+MD9pOmEscz1vLmxlbmd0aD4wP28uc2libGluZ3MoXCI6bm90KC5cIitBLmZpbHRlcmVkK1wiKVwiKS5hZGRCYWNrKCk6Vy5jaGlsZHJlbihcIjpub3QoLlwiK0EuZmlsdGVyZWQrXCIpXCIpLHI9by5jaGlsZHJlbihSLm1lbnUpLGw9by5jbG9zZXN0KFIubWVudSksYz1sLmhhc0NsYXNzKEEudmlzaWJsZSl8fGwuaGFzQ2xhc3MoQS5hbmltYXRpbmcpfHxsLnBhcmVudChSLm1lbnUpLmxlbmd0aD4wLHU9ci5sZW5ndGg+MCxkPW8ubGVuZ3RoPjAsdj1vLm5vdChSLnVuc2VsZWN0YWJsZSkubGVuZ3RoPjAsZj10PT1MLmRlbGltaXRlciYmeS5hbGxvd0FkZGl0aW9ucyYmUy5pcy5tdWx0aXBsZSgpLG09eS5hbGxvd0FkZGl0aW9ucyYmeS5oaWRlQWRkaXRpb25zJiYodD09TC5lbnRlcnx8ZikmJnY7aWYobSYmKFMudmVyYm9zZShcIlNlbGVjdGluZyBpdGVtIGZyb20ga2V5Ym9hcmQgc2hvcnRjdXRcIixvKSxTLmV2ZW50Lml0ZW0uY2xpY2suY2FsbChvLGUpLFMuaXMuc2VhcmNoU2VsZWN0aW9uKCkmJlMucmVtb3ZlLnNlYXJjaFRlcm0oKSksUy5pcy52aXNpYmxlKCkpe2lmKCh0PT1MLmVudGVyfHxmKSYmKHQ9PUwuZW50ZXImJmQmJnUmJiF5LmFsbG93Q2F0ZWdvcnlTZWxlY3Rpb24/KFMudmVyYm9zZShcIlByZXNzZWQgZW50ZXIgb24gdW5zZWxlY3RhYmxlIGNhdGVnb3J5LCBvcGVuaW5nIHN1YiBtZW51XCIpLHQ9TC5yaWdodEFycm93KTp2JiYoUy52ZXJib3NlKFwiU2VsZWN0aW5nIGl0ZW0gZnJvbSBrZXlib2FyZCBzaG9ydGN1dFwiLG8pLFMuZXZlbnQuaXRlbS5jbGljay5jYWxsKG8sZSksUy5pcy5zZWFyY2hTZWxlY3Rpb24oKSYmUy5yZW1vdmUuc2VhcmNoVGVybSgpKSxlLnByZXZlbnREZWZhdWx0KCkpLGQmJih0PT1MLmxlZnRBcnJvdyYmbFswXSE9PVdbMF0mJihTLnZlcmJvc2UoXCJMZWZ0IGtleSBwcmVzc2VkLCBjbG9zaW5nIHN1Yi1tZW51XCIpLFMuYW5pbWF0ZS5oaWRlKCExLGwpLG8ucmVtb3ZlQ2xhc3MoQS5zZWxlY3RlZCksbC5jbG9zZXN0KFIuaXRlbSkuYWRkQ2xhc3MoQS5zZWxlY3RlZCksZS5wcmV2ZW50RGVmYXVsdCgpKSx0PT1MLnJpZ2h0QXJyb3cmJnUmJihTLnZlcmJvc2UoXCJSaWdodCBrZXkgcHJlc3NlZCwgb3BlbmluZyBzdWItbWVudVwiKSxTLmFuaW1hdGUuc2hvdyghMSxyKSxvLnJlbW92ZUNsYXNzKEEuc2VsZWN0ZWQpLHIuZmluZChSLml0ZW0pLmVxKDApLmFkZENsYXNzKEEuc2VsZWN0ZWQpLGUucHJldmVudERlZmF1bHQoKSkpLHQ9PUwudXBBcnJvdyl7aWYobj1kJiZjP28ucHJldkFsbChSLml0ZW0rXCI6bm90KFwiK1IudW5zZWxlY3RhYmxlK1wiKVwiKS5lcSgwKTpCLmVxKDApLHMuaW5kZXgobik8MClyZXR1cm4gUy52ZXJib3NlKFwiVXAga2V5IHByZXNzZWQgYnV0IHJlYWNoZWQgdG9wIG9mIGN1cnJlbnQgbWVudVwiKSx2b2lkIGUucHJldmVudERlZmF1bHQoKTtTLnZlcmJvc2UoXCJVcCBrZXkgcHJlc3NlZCwgY2hhbmdpbmcgYWN0aXZlIGl0ZW1cIiksby5yZW1vdmVDbGFzcyhBLnNlbGVjdGVkKSxuLmFkZENsYXNzKEEuc2VsZWN0ZWQpLFMuc2V0LnNjcm9sbFBvc2l0aW9uKG4pLHkuc2VsZWN0T25LZXlkb3duJiZTLmlzLnNpbmdsZSgpJiZTLnNldC5zZWxlY3RlZEl0ZW0obiksZS5wcmV2ZW50RGVmYXVsdCgpfWlmKHQ9PUwuZG93bkFycm93KXtpZihuPWQmJmM/bj1vLm5leHRBbGwoUi5pdGVtK1wiOm5vdChcIitSLnVuc2VsZWN0YWJsZStcIilcIikuZXEoMCk6Qi5lcSgwKSwwPT09bi5sZW5ndGgpcmV0dXJuIFMudmVyYm9zZShcIkRvd24ga2V5IHByZXNzZWQgYnV0IHJlYWNoZWQgYm90dG9tIG9mIGN1cnJlbnQgbWVudVwiKSx2b2lkIGUucHJldmVudERlZmF1bHQoKTtTLnZlcmJvc2UoXCJEb3duIGtleSBwcmVzc2VkLCBjaGFuZ2luZyBhY3RpdmUgaXRlbVwiKSxCLnJlbW92ZUNsYXNzKEEuc2VsZWN0ZWQpLG4uYWRkQ2xhc3MoQS5zZWxlY3RlZCksUy5zZXQuc2Nyb2xsUG9zaXRpb24obikseS5zZWxlY3RPbktleWRvd24mJlMuaXMuc2luZ2xlKCkmJlMuc2V0LnNlbGVjdGVkSXRlbShuKSxlLnByZXZlbnREZWZhdWx0KCl9dD09TC5wYWdlVXAmJihTLnNjcm9sbFBhZ2UoXCJ1cFwiKSxlLnByZXZlbnREZWZhdWx0KCkpLHQ9PUwucGFnZURvd24mJihTLnNjcm9sbFBhZ2UoXCJkb3duXCIpLGUucHJldmVudERlZmF1bHQoKSksdD09TC5lc2NhcGUmJihTLnZlcmJvc2UoXCJFc2NhcGUga2V5IHByZXNzZWQsIGNsb3NpbmcgZHJvcGRvd25cIiksUy5oaWRlKCkpfWVsc2UgZiYmZS5wcmV2ZW50RGVmYXVsdCgpLHQhPUwuZG93bkFycm93fHxTLmlzLnZpc2libGUoKXx8KFMudmVyYm9zZShcIkRvd24ga2V5IHByZXNzZWQsIHNob3dpbmcgZHJvcGRvd25cIiksUy5zaG93KCksZS5wcmV2ZW50RGVmYXVsdCgpKX1lbHNlIFMuaGFzLnNlYXJjaCgpfHxTLnNldC5zZWxlY3RlZExldHRlcihTdHJpbmcuZnJvbUNoYXJDb2RlKHQpKX19LHRyaWdnZXI6e2NoYW5nZTpmdW5jdGlvbigpe3ZhciBlPW4uY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpLHQ9TlswXTt0JiYoUy52ZXJib3NlKFwiVHJpZ2dlcmluZyBuYXRpdmUgY2hhbmdlIGV2ZW50XCIpLGUuaW5pdEV2ZW50KFwiY2hhbmdlXCIsITAsITEpLHQuZGlzcGF0Y2hFdmVudChlKSl9fSxkZXRlcm1pbmU6e3NlbGVjdEFjdGlvbjpmdW5jdGlvbih0LG4pe1MudmVyYm9zZShcIkRldGVybWluaW5nIGFjdGlvblwiLHkuYWN0aW9uKSxlLmlzRnVuY3Rpb24oUy5hY3Rpb25beS5hY3Rpb25dKT8oUy52ZXJib3NlKFwiVHJpZ2dlcmluZyBwcmVzZXQgYWN0aW9uXCIseS5hY3Rpb24sdCxuKSxTLmFjdGlvblt5LmFjdGlvbl0uY2FsbChZLHQsbix0aGlzKSk6ZS5pc0Z1bmN0aW9uKHkuYWN0aW9uKT8oUy52ZXJib3NlKFwiVHJpZ2dlcmluZyB1c2VyIGFjdGlvblwiLHkuYWN0aW9uLHQsbikseS5hY3Rpb24uY2FsbChZLHQsbix0aGlzKSk6Uy5lcnJvcihPLmFjdGlvbix5LmFjdGlvbil9LGV2ZW50SW5Nb2R1bGU6ZnVuY3Rpb24odCxpKXt2YXIgYT1lKHQudGFyZ2V0KSxvPWEuY2xvc2VzdChuLmRvY3VtZW50RWxlbWVudCkubGVuZ3RoPjAscz1hLmNsb3Nlc3QoTSkubGVuZ3RoPjA7cmV0dXJuIGk9ZS5pc0Z1bmN0aW9uKGkpP2k6ZnVuY3Rpb24oKXt9LG8mJiFzPyhTLnZlcmJvc2UoXCJUcmlnZ2VyaW5nIGV2ZW50XCIsaSksaSgpLCEwKTooUy52ZXJib3NlKFwiRXZlbnQgb2NjdXJyZWQgaW4gZHJvcGRvd24sIGNhbmNlbGluZyBjYWxsYmFja1wiKSwhMSl9LGV2ZW50T25FbGVtZW50OmZ1bmN0aW9uKHQsaSl7dmFyIGE9ZSh0LnRhcmdldCksbz1hLmNsb3Nlc3QoUi5zaWJsaW5nTGFiZWwpLHM9bi5ib2R5LmNvbnRhaW5zKHQudGFyZ2V0KSxyPTA9PT1NLmZpbmQobykubGVuZ3RoLGw9MD09PWEuY2xvc2VzdChXKS5sZW5ndGg7cmV0dXJuIGk9ZS5pc0Z1bmN0aW9uKGkpP2k6ZnVuY3Rpb24oKXt9LHMmJnImJmw/KFMudmVyYm9zZShcIlRyaWdnZXJpbmcgZXZlbnRcIixpKSxpKCksITApOihTLnZlcmJvc2UoXCJFdmVudCBvY2N1cnJlZCBpbiBkcm9wZG93biBtZW51LCBjYW5jZWxpbmcgY2FsbGJhY2tcIiksITEpfX0sYWN0aW9uOntub3RoaW5nOmZ1bmN0aW9uKCl7fSxhY3RpdmF0ZTpmdW5jdGlvbih0LG4saSl7aWYobj12b2lkIDAhPT1uP246dCxTLmNhbi5hY3RpdmF0ZShlKGkpKSl7aWYoUy5zZXQuc2VsZWN0ZWQobixlKGkpKSxTLmlzLm11bHRpcGxlKCkmJiFTLmlzLmFsbEZpbHRlcmVkKCkpcmV0dXJuO1MuaGlkZUFuZENsZWFyKCl9fSxzZWxlY3Q6ZnVuY3Rpb24odCxuLGkpe2lmKG49dm9pZCAwIT09bj9uOnQsUy5jYW4uYWN0aXZhdGUoZShpKSkpe2lmKFMuc2V0LnZhbHVlKG4sZShpKSksUy5pcy5tdWx0aXBsZSgpJiYhUy5pcy5hbGxGaWx0ZXJlZCgpKXJldHVybjtTLmhpZGVBbmRDbGVhcigpfX0sY29tYm86ZnVuY3Rpb24odCxuLGkpe249dm9pZCAwIT09bj9uOnQsUy5zZXQuc2VsZWN0ZWQobixlKGkpKSxTLmhpZGVBbmRDbGVhcigpfSxoaWRlOmZ1bmN0aW9uKGUsdCxuKXtTLnNldC52YWx1ZSh0LGUpLFMuaGlkZUFuZENsZWFyKCl9fSxnZXQ6e2lkOmZ1bmN0aW9uKCl7cmV0dXJuIHd9LGRlZmF1bHRUZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIE0uZGF0YShJLmRlZmF1bHRUZXh0KX0sZGVmYXVsdFZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuIE0uZGF0YShJLmRlZmF1bHRWYWx1ZSl9LHBsYWNlaG9sZGVyVGV4dDpmdW5jdGlvbigpe3JldHVyblwiYXV0b1wiIT15LnBsYWNlaG9sZGVyJiZcInN0cmluZ1wiPT10eXBlb2YgeS5wbGFjZWhvbGRlcj95LnBsYWNlaG9sZGVyOk0uZGF0YShJLnBsYWNlaG9sZGVyVGV4dCl8fFwiXCJ9LHRleHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC50ZXh0KCl9LHF1ZXJ5OmZ1bmN0aW9uKCl7cmV0dXJuIGUudHJpbShILnZhbCgpKX0sc2VhcmNoV2lkdGg6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9dm9pZCAwIT09ZT9lOkgudmFsKCksai50ZXh0KGUpLE1hdGguY2VpbChqLndpZHRoKCkrMSl9LHNlbGVjdGlvbkNvdW50OmZ1bmN0aW9uKCl7dmFyIHQ9Uy5nZXQudmFsdWVzKCk7cmV0dXJuIFMuaXMubXVsdGlwbGUoKT9lLmlzQXJyYXkodCk/dC5sZW5ndGg6MDpcIlwiIT09Uy5nZXQudmFsdWUoKT8xOjB9LHRyYW5zaXRpb246ZnVuY3Rpb24oZSl7cmV0dXJuXCJhdXRvXCI9PXkudHJhbnNpdGlvbj9TLmlzLnVwd2FyZChlKT9cInNsaWRlIHVwXCI6XCJzbGlkZSBkb3duXCI6eS50cmFuc2l0aW9ufSx1c2VyVmFsdWVzOmZ1bmN0aW9uKCl7dmFyIHQ9Uy5nZXQudmFsdWVzKCk7cmV0dXJuISF0JiYodD1lLmlzQXJyYXkodCk/dDpbdF0sZS5ncmVwKHQsZnVuY3Rpb24oZSl7cmV0dXJuITE9PT1TLmdldC5pdGVtKGUpfSkpfSx1bmlxdWVBcnJheTpmdW5jdGlvbih0KXtyZXR1cm4gZS5ncmVwKHQsZnVuY3Rpb24obixpKXtyZXR1cm4gZS5pbkFycmF5KG4sdCk9PT1pfSl9LGNhcmV0UG9zaXRpb246ZnVuY3Rpb24oKXt2YXIgZSx0LGk9SC5nZXQoMCk7cmV0dXJuXCJzZWxlY3Rpb25TdGFydFwiaW4gaT9pLnNlbGVjdGlvblN0YXJ0Om4uc2VsZWN0aW9uPyhpLmZvY3VzKCksZT1uLnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpLHQ9ZS50ZXh0Lmxlbmd0aCxlLm1vdmVTdGFydChcImNoYXJhY3RlclwiLC1pLnZhbHVlLmxlbmd0aCksZS50ZXh0Lmxlbmd0aC10KTp2b2lkIDB9LHZhbHVlOmZ1bmN0aW9uKCl7dmFyIHQ9Ti5sZW5ndGg+MD9OLnZhbCgpOk0uZGF0YShJLnZhbHVlKSxuPWUuaXNBcnJheSh0KSYmMT09PXQubGVuZ3RoJiZcIlwiPT09dFswXTtyZXR1cm4gdm9pZCAwPT09dHx8bj9cIlwiOnR9LHZhbHVlczpmdW5jdGlvbigpe3ZhciBlPVMuZ2V0LnZhbHVlKCk7cmV0dXJuXCJcIj09PWU/XCJcIjohUy5oYXMuc2VsZWN0SW5wdXQoKSYmUy5pcy5tdWx0aXBsZSgpP1wic3RyaW5nXCI9PXR5cGVvZiBlP2Uuc3BsaXQoeS5kZWxpbWl0ZXIpOlwiXCI6ZX0scmVtb3RlVmFsdWVzOmZ1bmN0aW9uKCl7dmFyIHQ9Uy5nZXQudmFsdWVzKCksbj0hMTtyZXR1cm4gdCYmKFwic3RyaW5nXCI9PXR5cGVvZiB0JiYodD1bdF0pLGUuZWFjaCh0LGZ1bmN0aW9uKGUsdCl7dmFyIGk9Uy5yZWFkLnJlbW90ZURhdGEodCk7Uy52ZXJib3NlKFwiUmVzdG9yaW5nIHZhbHVlIGZyb20gc2Vzc2lvbiBkYXRhXCIsaSx0KSxpJiYobnx8KG49e30pLG5bdF09aSl9KSksbn0sY2hvaWNlVGV4dDpmdW5jdGlvbih0LG4pe2lmKG49dm9pZCAwIT09bj9uOnkucHJlc2VydmVIVE1MLHQpcmV0dXJuIHQuZmluZChSLm1lbnUpLmxlbmd0aD4wJiYoUy52ZXJib3NlKFwiUmV0cmlldmluZyB0ZXh0IG9mIGVsZW1lbnQgd2l0aCBzdWItbWVudVwiKSx0PXQuY2xvbmUoKSx0LmZpbmQoUi5tZW51KS5yZW1vdmUoKSx0LmZpbmQoUi5tZW51SWNvbikucmVtb3ZlKCkpLHZvaWQgMCE9PXQuZGF0YShJLnRleHQpP3QuZGF0YShJLnRleHQpOm4/ZS50cmltKHQuaHRtbCgpKTplLnRyaW0odC50ZXh0KCkpfSxjaG9pY2VWYWx1ZTpmdW5jdGlvbih0LG4pe3JldHVybiBuPW58fFMuZ2V0LmNob2ljZVRleHQodCksISF0JiYodm9pZCAwIT09dC5kYXRhKEkudmFsdWUpP1N0cmluZyh0LmRhdGEoSS52YWx1ZSkpOlwic3RyaW5nXCI9PXR5cGVvZiBuP2UudHJpbShuLnRvTG93ZXJDYXNlKCkpOlN0cmluZyhuKSl9LGlucHV0RXZlbnQ6ZnVuY3Rpb24oKXt2YXIgZT1IWzBdO3JldHVybiEhZSYmKHZvaWQgMCE9PWUub25pbnB1dD9cImlucHV0XCI6dm9pZCAwIT09ZS5vbnByb3BlcnR5Y2hhbmdlP1wicHJvcGVydHljaGFuZ2VcIjpcImtleXVwXCIpfSxzZWxlY3RWYWx1ZXM6ZnVuY3Rpb24oKXt2YXIgdD17fTtyZXR1cm4gdC52YWx1ZXM9W10sTS5maW5kKFwib3B0aW9uXCIpLmVhY2goZnVuY3Rpb24oKXt2YXIgbj1lKHRoaXMpLGk9bi5odG1sKCksYT1uLmF0dHIoXCJkaXNhYmxlZFwiKSxvPXZvaWQgMCE9PW4uYXR0cihcInZhbHVlXCIpP24uYXR0cihcInZhbHVlXCIpOmk7XCJhdXRvXCI9PT15LnBsYWNlaG9sZGVyJiZcIlwiPT09bz90LnBsYWNlaG9sZGVyPWk6dC52YWx1ZXMucHVzaCh7bmFtZTppLHZhbHVlOm8sZGlzYWJsZWQ6YX0pfSkseS5wbGFjZWhvbGRlciYmXCJhdXRvXCIhPT15LnBsYWNlaG9sZGVyJiYoUy5kZWJ1ZyhcIlNldHRpbmcgcGxhY2Vob2xkZXIgdmFsdWUgdG9cIix5LnBsYWNlaG9sZGVyKSx0LnBsYWNlaG9sZGVyPXkucGxhY2Vob2xkZXIpLHkuc29ydFNlbGVjdD8odC52YWx1ZXMuc29ydChmdW5jdGlvbihlLHQpe3JldHVybiBlLm5hbWU+dC5uYW1lPzE6LTF9KSxTLmRlYnVnKFwiUmV0cmlldmVkIGFuZCBzb3J0ZWQgdmFsdWVzIGZyb20gc2VsZWN0XCIsdCkpOlMuZGVidWcoXCJSZXRyaWV2ZWQgdmFsdWVzIGZyb20gc2VsZWN0XCIsdCksdH0sYWN0aXZlSXRlbTpmdW5jdGlvbigpe3JldHVybiBCLmZpbHRlcihcIi5cIitBLmFjdGl2ZSl9LHNlbGVjdGVkSXRlbTpmdW5jdGlvbigpe3ZhciBlPUIubm90KFIudW5zZWxlY3RhYmxlKS5maWx0ZXIoXCIuXCIrQS5zZWxlY3RlZCk7cmV0dXJuIGUubGVuZ3RoPjA/ZTpCLmVxKDApfSxpdGVtV2l0aEFkZGl0aW9uczpmdW5jdGlvbihlKXt2YXIgdD1TLmdldC5pdGVtKGUpLG49Uy5jcmVhdGUudXNlckNob2ljZShlKTtyZXR1cm4gbiYmbi5sZW5ndGg+MCYmKHQ9dC5sZW5ndGg+MD90LmFkZChuKTpuKSx0fSxpdGVtOmZ1bmN0aW9uKHQsbil7dmFyIGksYSxvPSExO3JldHVybiB0PXZvaWQgMCE9PXQ/dDp2b2lkIDAhPT1TLmdldC52YWx1ZXMoKT9TLmdldC52YWx1ZXMoKTpTLmdldC50ZXh0KCksaT1hP3QubGVuZ3RoPjA6dm9pZCAwIT09dCYmbnVsbCE9PXQsYT1TLmlzLm11bHRpcGxlKCkmJmUuaXNBcnJheSh0KSxuPVwiXCI9PT10fHwwPT09dHx8KG58fCExKSxpJiZCLmVhY2goZnVuY3Rpb24oKXt2YXIgaT1lKHRoaXMpLHM9Uy5nZXQuY2hvaWNlVGV4dChpKSxyPVMuZ2V0LmNob2ljZVZhbHVlKGkscyk7aWYobnVsbCE9PXImJnZvaWQgMCE9PXIpaWYoYSktMT09PWUuaW5BcnJheShTdHJpbmcociksdCkmJi0xPT09ZS5pbkFycmF5KHMsdCl8fChvPW8/by5hZGQoaSk6aSk7ZWxzZSBpZihuKXtpZihTLnZlcmJvc2UoXCJBbWJpZ3VvdXMgZHJvcGRvd24gdmFsdWUgdXNpbmcgc3RyaWN0IHR5cGUgY2hlY2tcIixpLHQpLHI9PT10fHxzPT09dClyZXR1cm4gbz1pLCEwfWVsc2UgaWYoU3RyaW5nKHIpPT1TdHJpbmcodCl8fHM9PXQpcmV0dXJuIFMudmVyYm9zZShcIkZvdW5kIHNlbGVjdCBpdGVtIGJ5IHZhbHVlXCIscix0KSxvPWksITB9KSxvfX0sY2hlY2s6e21heFNlbGVjdGlvbnM6ZnVuY3Rpb24oZSl7cmV0dXJuIXkubWF4U2VsZWN0aW9uc3x8KGU9dm9pZCAwIT09ZT9lOlMuZ2V0LnNlbGVjdGlvbkNvdW50KCksZT49eS5tYXhTZWxlY3Rpb25zPyhTLmRlYnVnKFwiTWF4aW11bSBzZWxlY3Rpb24gY291bnQgcmVhY2hlZFwiKSx5LnVzZUxhYmVscyYmKEIuYWRkQ2xhc3MoQS5maWx0ZXJlZCksUy5hZGQubWVzc2FnZShULm1heFNlbGVjdGlvbnMpKSwhMCk6KFMudmVyYm9zZShcIk5vIGxvbmdlciBhdCBtYXhpbXVtIHNlbGVjdGlvbiBjb3VudFwiKSxTLnJlbW92ZS5tZXNzYWdlKCksUy5yZW1vdmUuZmlsdGVyZWRJdGVtKCksUy5pcy5zZWFyY2hTZWxlY3Rpb24oKSYmUy5maWx0ZXJJdGVtcygpLCExKSl9fSxyZXN0b3JlOntkZWZhdWx0czpmdW5jdGlvbigpe1MuY2xlYXIoKSxTLnJlc3RvcmUuZGVmYXVsdFRleHQoKSxTLnJlc3RvcmUuZGVmYXVsdFZhbHVlKCl9LGRlZmF1bHRUZXh0OmZ1bmN0aW9uKCl7dmFyIGU9Uy5nZXQuZGVmYXVsdFRleHQoKTtlPT09Uy5nZXQucGxhY2Vob2xkZXJUZXh0PyhTLmRlYnVnKFwiUmVzdG9yaW5nIGRlZmF1bHQgcGxhY2Vob2xkZXIgdGV4dFwiLGUpLFMuc2V0LnBsYWNlaG9sZGVyVGV4dChlKSk6KFMuZGVidWcoXCJSZXN0b3JpbmcgZGVmYXVsdCB0ZXh0XCIsZSksUy5zZXQudGV4dChlKSl9LHBsYWNlaG9sZGVyVGV4dDpmdW5jdGlvbigpe1Muc2V0LnBsYWNlaG9sZGVyVGV4dCgpfSxkZWZhdWx0VmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT1TLmdldC5kZWZhdWx0VmFsdWUoKTt2b2lkIDAhPT1lJiYoUy5kZWJ1ZyhcIlJlc3RvcmluZyBkZWZhdWx0IHZhbHVlXCIsZSksXCJcIiE9PWU/KFMuc2V0LnZhbHVlKGUpLFMuc2V0LnNlbGVjdGVkKCkpOihTLnJlbW92ZS5hY3RpdmVJdGVtKCksUy5yZW1vdmUuc2VsZWN0ZWRJdGVtKCkpKX0sbGFiZWxzOmZ1bmN0aW9uKCl7eS5hbGxvd0FkZGl0aW9ucyYmKHkudXNlTGFiZWxzfHwoUy5lcnJvcihPLmxhYmVscykseS51c2VMYWJlbHM9ITApLFMuZGVidWcoXCJSZXN0b3Jpbmcgc2VsZWN0ZWQgdmFsdWVzXCIpLFMuY3JlYXRlLnVzZXJMYWJlbHMoKSksUy5jaGVjay5tYXhTZWxlY3Rpb25zKCl9LHNlbGVjdGVkOmZ1bmN0aW9uKCl7Uy5yZXN0b3JlLnZhbHVlcygpLFMuaXMubXVsdGlwbGUoKT8oUy5kZWJ1ZyhcIlJlc3RvcmluZyBwcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlcyBhbmQgbGFiZWxzXCIpLFMucmVzdG9yZS5sYWJlbHMoKSk6Uy5kZWJ1ZyhcIlJlc3RvcmluZyBwcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlc1wiKX0sdmFsdWVzOmZ1bmN0aW9uKCl7Uy5zZXQuaW5pdGlhbExvYWQoKSx5LmFwaVNldHRpbmdzJiZ5LnNhdmVSZW1vdGVEYXRhJiZTLmdldC5yZW1vdGVWYWx1ZXMoKT9TLnJlc3RvcmUucmVtb3RlVmFsdWVzKCk6Uy5zZXQuc2VsZWN0ZWQoKSxTLnJlbW92ZS5pbml0aWFsTG9hZCgpfSxyZW1vdGVWYWx1ZXM6ZnVuY3Rpb24oKXt2YXIgdD1TLmdldC5yZW1vdGVWYWx1ZXMoKTtTLmRlYnVnKFwiUmVjcmVhdGluZyBzZWxlY3RlZCBmcm9tIHNlc3Npb24gZGF0YVwiLHQpLHQmJihTLmlzLnNpbmdsZSgpP2UuZWFjaCh0LGZ1bmN0aW9uKGUsdCl7Uy5zZXQudGV4dCh0KX0pOmUuZWFjaCh0LGZ1bmN0aW9uKGUsdCl7Uy5hZGQubGFiZWwoZSx0KX0pKX19LHJlYWQ6e3JlbW90ZURhdGE6ZnVuY3Rpb24oZSl7dmFyIG47cmV0dXJuIHZvaWQgMD09PXQuU3RvcmFnZT92b2lkIFMuZXJyb3IoTy5ub1N0b3JhZ2UpOnZvaWQgMCE9PShuPXNlc3Npb25TdG9yYWdlLmdldEl0ZW0oZSkpJiZufX0sc2F2ZTp7ZGVmYXVsdHM6ZnVuY3Rpb24oKXtTLnNhdmUuZGVmYXVsdFRleHQoKSxTLnNhdmUucGxhY2Vob2xkZXJUZXh0KCksUy5zYXZlLmRlZmF1bHRWYWx1ZSgpfSxkZWZhdWx0VmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT1TLmdldC52YWx1ZSgpO1MudmVyYm9zZShcIlNhdmluZyBkZWZhdWx0IHZhbHVlIGFzXCIsZSksTS5kYXRhKEkuZGVmYXVsdFZhbHVlLGUpfSxkZWZhdWx0VGV4dDpmdW5jdGlvbigpe3ZhciBlPVMuZ2V0LnRleHQoKTtTLnZlcmJvc2UoXCJTYXZpbmcgZGVmYXVsdCB0ZXh0IGFzXCIsZSksTS5kYXRhKEkuZGVmYXVsdFRleHQsZSl9LHBsYWNlaG9sZGVyVGV4dDpmdW5jdGlvbigpe3ZhciBlOyExIT09eS5wbGFjZWhvbGRlciYmUC5oYXNDbGFzcyhBLnBsYWNlaG9sZGVyKSYmKGU9Uy5nZXQudGV4dCgpLFMudmVyYm9zZShcIlNhdmluZyBwbGFjZWhvbGRlciB0ZXh0IGFzXCIsZSksTS5kYXRhKEkucGxhY2Vob2xkZXJUZXh0LGUpKX0scmVtb3RlRGF0YTpmdW5jdGlvbihlLG4pe2lmKHZvaWQgMD09PXQuU3RvcmFnZSlyZXR1cm4gdm9pZCBTLmVycm9yKE8ubm9TdG9yYWdlKTtTLnZlcmJvc2UoXCJTYXZpbmcgcmVtb3RlIGRhdGEgdG8gc2Vzc2lvbiBzdG9yYWdlXCIsbixlKSxzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKG4sZSl9fSxjbGVhcjpmdW5jdGlvbigpe1MuaXMubXVsdGlwbGUoKSYmeS51c2VMYWJlbHM/Uy5yZW1vdmUubGFiZWxzKCk6KFMucmVtb3ZlLmFjdGl2ZUl0ZW0oKSxTLnJlbW92ZS5zZWxlY3RlZEl0ZW0oKSksUy5zZXQucGxhY2Vob2xkZXJUZXh0KCksUy5jbGVhclZhbHVlKCl9LGNsZWFyVmFsdWU6ZnVuY3Rpb24oKXtTLnNldC52YWx1ZShcIlwiKX0sc2Nyb2xsUGFnZTpmdW5jdGlvbihlLHQpe3ZhciBuLGksYSxvPXR8fFMuZ2V0LnNlbGVjdGVkSXRlbSgpLHM9by5jbG9zZXN0KFIubWVudSkscj1zLm91dGVySGVpZ2h0KCksbD1zLnNjcm9sbFRvcCgpLGM9Qi5lcSgwKS5vdXRlckhlaWdodCgpLHU9TWF0aC5mbG9vcihyL2MpLGQ9KHMucHJvcChcInNjcm9sbEhlaWdodFwiKSxcInVwXCI9PWU/bC1jKnU6bCtjKnUpLHY9Qi5ub3QoUi51bnNlbGVjdGFibGUpO2E9XCJ1cFwiPT1lP3YuaW5kZXgobyktdTp2LmluZGV4KG8pK3Usbj1cInVwXCI9PWU/YT49MDphPHYubGVuZ3RoLGk9bj92LmVxKGEpOlwidXBcIj09ZT92LmZpcnN0KCk6di5sYXN0KCksaS5sZW5ndGg+MCYmKFMuZGVidWcoXCJTY3JvbGxpbmcgcGFnZVwiLGUsaSksby5yZW1vdmVDbGFzcyhBLnNlbGVjdGVkKSxpLmFkZENsYXNzKEEuc2VsZWN0ZWQpLHkuc2VsZWN0T25LZXlkb3duJiZTLmlzLnNpbmdsZSgpJiZTLnNldC5zZWxlY3RlZEl0ZW0oaSkscy5zY3JvbGxUb3AoZCkpfSxzZXQ6e2ZpbHRlcmVkOmZ1bmN0aW9uKCl7dmFyIGU9Uy5pcy5tdWx0aXBsZSgpLHQ9Uy5pcy5zZWFyY2hTZWxlY3Rpb24oKSxuPWUmJnQsaT10P1MuZ2V0LnF1ZXJ5KCk6XCJcIixhPVwic3RyaW5nXCI9PXR5cGVvZiBpJiZpLmxlbmd0aD4wLG89Uy5nZXQuc2VhcmNoV2lkdGgoKSxzPVwiXCIhPT1pO2UmJmEmJihTLnZlcmJvc2UoXCJBZGp1c3RpbmcgaW5wdXQgd2lkdGhcIixvLHkuZ2x5cGhXaWR0aCksSC5jc3MoXCJ3aWR0aFwiLG8pKSxhfHxuJiZzPyhTLnZlcmJvc2UoXCJIaWRpbmcgcGxhY2Vob2xkZXIgdGV4dFwiKSxQLmFkZENsYXNzKEEuZmlsdGVyZWQpKTooIWV8fG4mJiFzKSYmKFMudmVyYm9zZShcIlNob3dpbmcgcGxhY2Vob2xkZXIgdGV4dFwiKSxQLnJlbW92ZUNsYXNzKEEuZmlsdGVyZWQpKX0sZW1wdHk6ZnVuY3Rpb24oKXtNLmFkZENsYXNzKEEuZW1wdHkpfSxsb2FkaW5nOmZ1bmN0aW9uKCl7TS5hZGRDbGFzcyhBLmxvYWRpbmcpfSxwbGFjZWhvbGRlclRleHQ6ZnVuY3Rpb24oZSl7ZT1lfHxTLmdldC5wbGFjZWhvbGRlclRleHQoKSxTLmRlYnVnKFwiU2V0dGluZyBwbGFjZWhvbGRlciB0ZXh0XCIsZSksUy5zZXQudGV4dChlKSxQLmFkZENsYXNzKEEucGxhY2Vob2xkZXIpfSx0YWJiYWJsZTpmdW5jdGlvbigpe1MuaXMuc2VhcmNoU2VsZWN0aW9uKCk/KFMuZGVidWcoXCJBZGRlZCB0YWJpbmRleCB0byBzZWFyY2hhYmxlIGRyb3Bkb3duXCIpLEgudmFsKFwiXCIpLmF0dHIoXCJ0YWJpbmRleFwiLDApLFcuYXR0cihcInRhYmluZGV4XCIsLTEpKTooUy5kZWJ1ZyhcIkFkZGVkIHRhYmluZGV4IHRvIGRyb3Bkb3duXCIpLHZvaWQgMD09PU0uYXR0cihcInRhYmluZGV4XCIpJiYoTS5hdHRyKFwidGFiaW5kZXhcIiwwKSxXLmF0dHIoXCJ0YWJpbmRleFwiLC0xKSkpfSxpbml0aWFsTG9hZDpmdW5jdGlvbigpe1MudmVyYm9zZShcIlNldHRpbmcgaW5pdGlhbCBsb2FkXCIpLGg9ITB9LGFjdGl2ZUl0ZW06ZnVuY3Rpb24oZSl7eS5hbGxvd0FkZGl0aW9ucyYmZS5maWx0ZXIoUi5hZGRpdGlvbikubGVuZ3RoPjA/ZS5hZGRDbGFzcyhBLmZpbHRlcmVkKTplLmFkZENsYXNzKEEuYWN0aXZlKX0scGFydGlhbFNlYXJjaDpmdW5jdGlvbihlKXt2YXIgdD1TLmdldC5xdWVyeSgpLmxlbmd0aDtILnZhbChlLnN1YnN0cigwLHQpKX0sc2Nyb2xsUG9zaXRpb246ZnVuY3Rpb24oZSx0KXt2YXIgbixpLGEsbyxzLHIsbCxjLHU7ZT1lfHxTLmdldC5zZWxlY3RlZEl0ZW0oKSxuPWUuY2xvc2VzdChSLm1lbnUpLGk9ZSYmZS5sZW5ndGg+MCx0PXZvaWQgMCE9PXQmJnQsZSYmbi5sZW5ndGg+MCYmaSYmKG89ZS5wb3NpdGlvbigpLnRvcCxuLmFkZENsYXNzKEEubG9hZGluZykscj1uLnNjcm9sbFRvcCgpLHM9bi5vZmZzZXQoKS50b3Asbz1lLm9mZnNldCgpLnRvcCxhPXItcytvLHR8fChsPW4uaGVpZ2h0KCksdT1yK2w8YSs1LGM9YS01PHIpLFMuZGVidWcoXCJTY3JvbGxpbmcgdG8gYWN0aXZlIGl0ZW1cIixhKSwodHx8Y3x8dSkmJm4uc2Nyb2xsVG9wKGEpLG4ucmVtb3ZlQ2xhc3MoQS5sb2FkaW5nKSl9LHRleHQ6ZnVuY3Rpb24oZSl7XCJzZWxlY3RcIiE9PXkuYWN0aW9uJiYoXCJjb21ib1wiPT15LmFjdGlvbj8oUy5kZWJ1ZyhcIkNoYW5naW5nIGNvbWJvIGJ1dHRvbiB0ZXh0XCIsZSxLKSx5LnByZXNlcnZlSFRNTD9LLmh0bWwoZSk6Sy50ZXh0KGUpKTooZSE9PVMuZ2V0LnBsYWNlaG9sZGVyVGV4dCgpJiZQLnJlbW92ZUNsYXNzKEEucGxhY2Vob2xkZXIpLFMuZGVidWcoXCJDaGFuZ2luZyB0ZXh0XCIsZSxQKSxQLnJlbW92ZUNsYXNzKEEuZmlsdGVyZWQpLHkucHJlc2VydmVIVE1MP1AuaHRtbChlKTpQLnRleHQoZSkpKX0sc2VsZWN0ZWRJdGVtOmZ1bmN0aW9uKGUpe3ZhciB0PVMuZ2V0LmNob2ljZVZhbHVlKGUpLG49Uy5nZXQuY2hvaWNlVGV4dChlLCExKSxpPVMuZ2V0LmNob2ljZVRleHQoZSwhMCk7Uy5kZWJ1ZyhcIlNldHRpbmcgdXNlciBzZWxlY3Rpb24gdG8gaXRlbVwiLGUpLFMucmVtb3ZlLmFjdGl2ZUl0ZW0oKSxTLnNldC5wYXJ0aWFsU2VhcmNoKG4pLFMuc2V0LmFjdGl2ZUl0ZW0oZSksUy5zZXQuc2VsZWN0ZWQodCxlKSxTLnNldC50ZXh0KGkpfSxzZWxlY3RlZExldHRlcjpmdW5jdGlvbih0KXt2YXIgbixpPUIuZmlsdGVyKFwiLlwiK0Euc2VsZWN0ZWQpLGE9aS5sZW5ndGg+MCYmUy5oYXMuZmlyc3RMZXR0ZXIoaSx0KSxvPSExO2EmJihuPWkubmV4dEFsbChCKS5lcSgwKSxTLmhhcy5maXJzdExldHRlcihuLHQpJiYobz1uKSksb3x8Qi5lYWNoKGZ1bmN0aW9uKCl7aWYoUy5oYXMuZmlyc3RMZXR0ZXIoZSh0aGlzKSx0KSlyZXR1cm4gbz1lKHRoaXMpLCExfSksbyYmKFMudmVyYm9zZShcIlNjcm9sbGluZyB0byBuZXh0IHZhbHVlIHdpdGggbGV0dGVyXCIsdCksUy5zZXQuc2Nyb2xsUG9zaXRpb24obyksaS5yZW1vdmVDbGFzcyhBLnNlbGVjdGVkKSxvLmFkZENsYXNzKEEuc2VsZWN0ZWQpLHkuc2VsZWN0T25LZXlkb3duJiZTLmlzLnNpbmdsZSgpJiZTLnNldC5zZWxlY3RlZEl0ZW0obykpfSxkaXJlY3Rpb246ZnVuY3Rpb24oZSl7XCJhdXRvXCI9PXkuZGlyZWN0aW9uPyhTLnJlbW92ZS51cHdhcmQoKSxTLmNhbi5vcGVuRG93bndhcmQoZSk/Uy5yZW1vdmUudXB3YXJkKGUpOlMuc2V0LnVwd2FyZChlKSxTLmlzLmxlZnR3YXJkKGUpfHxTLmNhbi5vcGVuUmlnaHR3YXJkKGUpfHxTLnNldC5sZWZ0d2FyZChlKSk6XCJ1cHdhcmRcIj09eS5kaXJlY3Rpb24mJlMuc2V0LnVwd2FyZChlKX0sdXB3YXJkOmZ1bmN0aW9uKGUpeyhlfHxNKS5hZGRDbGFzcyhBLnVwd2FyZCl9LGxlZnR3YXJkOmZ1bmN0aW9uKGUpeyhlfHxXKS5hZGRDbGFzcyhBLmxlZnR3YXJkKX0sdmFsdWU6ZnVuY3Rpb24oZSx0LG4pe3ZhciBpPVMuZXNjYXBlLnZhbHVlKGUpLGE9Ti5sZW5ndGg+MCxvPShTLmhhcy52YWx1ZShlKSxTLmdldC52YWx1ZXMoKSkscz12b2lkIDAhPT1lP1N0cmluZyhlKTplO2lmKGEpe2lmKCF5LmFsbG93UmVzZWxlY3Rpb24mJnM9PW8mJihTLnZlcmJvc2UoXCJTa2lwcGluZyB2YWx1ZSB1cGRhdGUgYWxyZWFkeSBzYW1lIHZhbHVlXCIsZSxvKSwhUy5pcy5pbml0aWFsTG9hZCgpKSlyZXR1cm47Uy5pcy5zaW5nbGUoKSYmUy5oYXMuc2VsZWN0SW5wdXQoKSYmUy5jYW4uZXh0ZW5kU2VsZWN0KCkmJihTLmRlYnVnKFwiQWRkaW5nIHVzZXIgb3B0aW9uXCIsZSksUy5hZGQub3B0aW9uVmFsdWUoZSkpLFMuZGVidWcoXCJVcGRhdGluZyBpbnB1dCB2YWx1ZVwiLGksbyksWD0hMCxOLnZhbChpKSwhMT09PXkuZmlyZU9uSW5pdCYmUy5pcy5pbml0aWFsTG9hZCgpP1MuZGVidWcoXCJJbnB1dCBuYXRpdmUgY2hhbmdlIGV2ZW50IGlnbm9yZWQgb24gaW5pdGlhbCBsb2FkXCIpOlMudHJpZ2dlci5jaGFuZ2UoKSxYPSExfWVsc2UgUy52ZXJib3NlKFwiU3RvcmluZyB2YWx1ZSBpbiBtZXRhZGF0YVwiLGksTiksaSE9PW8mJk0uZGF0YShJLnZhbHVlLHMpOyExPT09eS5maXJlT25Jbml0JiZTLmlzLmluaXRpYWxMb2FkKCk/Uy52ZXJib3NlKFwiTm8gY2FsbGJhY2sgb24gaW5pdGlhbCBsb2FkXCIseS5vbkNoYW5nZSk6eS5vbkNoYW5nZS5jYWxsKFksZSx0LG4pfSxhY3RpdmU6ZnVuY3Rpb24oKXtNLmFkZENsYXNzKEEuYWN0aXZlKX0sbXVsdGlwbGU6ZnVuY3Rpb24oKXtNLmFkZENsYXNzKEEubXVsdGlwbGUpfSx2aXNpYmxlOmZ1bmN0aW9uKCl7TS5hZGRDbGFzcyhBLnZpc2libGUpfSxleGFjdGx5OmZ1bmN0aW9uKGUsdCl7Uy5kZWJ1ZyhcIlNldHRpbmcgc2VsZWN0ZWQgdG8gZXhhY3QgdmFsdWVzXCIpLFMuY2xlYXIoKSxTLnNldC5zZWxlY3RlZChlLHQpfSxzZWxlY3RlZDpmdW5jdGlvbih0LG4pe3ZhciBpPVMuaXMubXVsdGlwbGUoKTsobj15LmFsbG93QWRkaXRpb25zP258fFMuZ2V0Lml0ZW1XaXRoQWRkaXRpb25zKHQpOm58fFMuZ2V0Lml0ZW0odCkpJiYoUy5kZWJ1ZyhcIlNldHRpbmcgc2VsZWN0ZWQgbWVudSBpdGVtIHRvXCIsbiksUy5pcy5tdWx0aXBsZSgpJiZTLnJlbW92ZS5zZWFyY2hXaWR0aCgpLFMuaXMuc2luZ2xlKCk/KFMucmVtb3ZlLmFjdGl2ZUl0ZW0oKSxTLnJlbW92ZS5zZWxlY3RlZEl0ZW0oKSk6eS51c2VMYWJlbHMmJlMucmVtb3ZlLnNlbGVjdGVkSXRlbSgpLG4uZWFjaChmdW5jdGlvbigpe3ZhciB0PWUodGhpcyksYT1TLmdldC5jaG9pY2VUZXh0KHQpLG89Uy5nZXQuY2hvaWNlVmFsdWUodCxhKSxzPXQuaGFzQ2xhc3MoQS5maWx0ZXJlZCkscj10Lmhhc0NsYXNzKEEuYWN0aXZlKSxsPXQuaGFzQ2xhc3MoQS5hZGRpdGlvbiksYz1pJiYxPT1uLmxlbmd0aDtpPyFyfHxsPyh5LmFwaVNldHRpbmdzJiZ5LnNhdmVSZW1vdGVEYXRhJiZTLnNhdmUucmVtb3RlRGF0YShhLG8pLHkudXNlTGFiZWxzPyhTLmFkZC52YWx1ZShvLGEsdCksUy5hZGQubGFiZWwobyxhLGMpLFMuc2V0LmFjdGl2ZUl0ZW0odCksUy5maWx0ZXJBY3RpdmUoKSxcclxuUy5zZWxlY3QubmV4dEF2YWlsYWJsZShuKSk6KFMuYWRkLnZhbHVlKG8sYSx0KSxTLnNldC50ZXh0KFMuYWRkLnZhcmlhYmxlcyhULmNvdW50KSksUy5zZXQuYWN0aXZlSXRlbSh0KSkpOnN8fChTLmRlYnVnKFwiU2VsZWN0ZWQgYWN0aXZlIHZhbHVlLCByZW1vdmluZyBsYWJlbFwiKSxTLnJlbW92ZS5zZWxlY3RlZChvKSk6KHkuYXBpU2V0dGluZ3MmJnkuc2F2ZVJlbW90ZURhdGEmJlMuc2F2ZS5yZW1vdGVEYXRhKGEsbyksUy5zZXQudGV4dChhKSxTLnNldC52YWx1ZShvLGEsdCksdC5hZGRDbGFzcyhBLmFjdGl2ZSkuYWRkQ2xhc3MoQS5zZWxlY3RlZCkpfSkpfX0sYWRkOntsYWJlbDpmdW5jdGlvbih0LG4saSl7dmFyIGEsbz1TLmlzLnNlYXJjaFNlbGVjdGlvbigpP0g6UCxzPVMuZXNjYXBlLnZhbHVlKHQpO2lmKGE9ZShcIjxhIC8+XCIpLmFkZENsYXNzKEEubGFiZWwpLmF0dHIoXCJkYXRhLVwiK0kudmFsdWUscykuaHRtbChWLmxhYmVsKHMsbikpLGE9eS5vbkxhYmVsQ3JlYXRlLmNhbGwoYSxzLG4pLFMuaGFzLmxhYmVsKHQpKXJldHVybiB2b2lkIFMuZGVidWcoXCJMYWJlbCBhbHJlYWR5IGV4aXN0cywgc2tpcHBpbmdcIixzKTt5LmxhYmVsLnZhcmlhdGlvbiYmYS5hZGRDbGFzcyh5LmxhYmVsLnZhcmlhdGlvbiksITA9PT1pPyhTLmRlYnVnKFwiQW5pbWF0aW5nIGluIGxhYmVsXCIsYSksYS5hZGRDbGFzcyhBLmhpZGRlbikuaW5zZXJ0QmVmb3JlKG8pLnRyYW5zaXRpb24oeS5sYWJlbC50cmFuc2l0aW9uLHkubGFiZWwuZHVyYXRpb24pKTooUy5kZWJ1ZyhcIkFkZGluZyBzZWxlY3Rpb24gbGFiZWxcIixhKSxhLmluc2VydEJlZm9yZShvKSl9LG1lc3NhZ2U6ZnVuY3Rpb24odCl7dmFyIG49Vy5jaGlsZHJlbihSLm1lc3NhZ2UpLGk9eS50ZW1wbGF0ZXMubWVzc2FnZShTLmFkZC52YXJpYWJsZXModCkpO24ubGVuZ3RoPjA/bi5odG1sKGkpOm49ZShcIjxkaXYvPlwiKS5odG1sKGkpLmFkZENsYXNzKEEubWVzc2FnZSkuYXBwZW5kVG8oVyl9LG9wdGlvblZhbHVlOmZ1bmN0aW9uKHQpe3ZhciBuPVMuZXNjYXBlLnZhbHVlKHQpO04uZmluZCgnb3B0aW9uW3ZhbHVlPVwiJytTLmVzY2FwZS5zdHJpbmcobikrJ1wiXScpLmxlbmd0aD4wfHwoUy5kaXNjb25uZWN0LnNlbGVjdE9ic2VydmVyKCksUy5pcy5zaW5nbGUoKSYmKFMudmVyYm9zZShcIlJlbW92aW5nIHByZXZpb3VzIHVzZXIgYWRkaXRpb25cIiksTi5maW5kKFwib3B0aW9uLlwiK0EuYWRkaXRpb24pLnJlbW92ZSgpKSxlKFwiPG9wdGlvbi8+XCIpLnByb3AoXCJ2YWx1ZVwiLG4pLmFkZENsYXNzKEEuYWRkaXRpb24pLmh0bWwodCkuYXBwZW5kVG8oTiksUy52ZXJib3NlKFwiQWRkaW5nIHVzZXIgYWRkaXRpb24gYXMgYW4gPG9wdGlvbj5cIix0KSxTLm9ic2VydmUuc2VsZWN0KCkpfSx1c2VyU3VnZ2VzdGlvbjpmdW5jdGlvbihlKXt2YXIgdCxuPVcuY2hpbGRyZW4oUi5hZGRpdGlvbiksaT1TLmdldC5pdGVtKGUpLGE9aSYmaS5ub3QoUi5hZGRpdGlvbikubGVuZ3RoLG89bi5sZW5ndGg+MDtpZigheS51c2VMYWJlbHN8fCFTLmhhcy5tYXhTZWxlY3Rpb25zKCkpe2lmKFwiXCI9PT1lfHxhKXJldHVybiB2b2lkIG4ucmVtb3ZlKCk7bz8obi5kYXRhKEkudmFsdWUsZSkuZGF0YShJLnRleHQsZSkuYXR0cihcImRhdGEtXCIrSS52YWx1ZSxlKS5hdHRyKFwiZGF0YS1cIitJLnRleHQsZSkucmVtb3ZlQ2xhc3MoQS5maWx0ZXJlZCkseS5oaWRlQWRkaXRpb25zfHwodD15LnRlbXBsYXRlcy5hZGRpdGlvbihTLmFkZC52YXJpYWJsZXMoVC5hZGRSZXN1bHQsZSkpLG4uaHRtbCh0KSksUy52ZXJib3NlKFwiUmVwbGFjaW5nIHVzZXIgc3VnZ2VzdGlvbiB3aXRoIG5ldyB2YWx1ZVwiLG4pKToobj1TLmNyZWF0ZS51c2VyQ2hvaWNlKGUpLG4ucHJlcGVuZFRvKFcpLFMudmVyYm9zZShcIkFkZGluZyBpdGVtIGNob2ljZSB0byBtZW51IGNvcnJlc3BvbmRpbmcgd2l0aCB1c2VyIGNob2ljZSBhZGRpdGlvblwiLG4pKSx5LmhpZGVBZGRpdGlvbnMmJiFTLmlzLmFsbEZpbHRlcmVkKCl8fG4uYWRkQ2xhc3MoQS5zZWxlY3RlZCkuc2libGluZ3MoKS5yZW1vdmVDbGFzcyhBLnNlbGVjdGVkKSxTLnJlZnJlc2hJdGVtcygpfX0sdmFyaWFibGVzOmZ1bmN0aW9uKGUsdCl7dmFyIG4saSxhPS0xIT09ZS5zZWFyY2goXCJ7Y291bnR9XCIpLG89LTEhPT1lLnNlYXJjaChcInttYXhDb3VudH1cIikscz0tMSE9PWUuc2VhcmNoKFwie3Rlcm19XCIpO3JldHVybiBTLnZlcmJvc2UoXCJBZGRpbmcgdGVtcGxhdGVkIHZhcmlhYmxlcyB0byBtZXNzYWdlXCIsZSksYSYmKG49Uy5nZXQuc2VsZWN0aW9uQ291bnQoKSxlPWUucmVwbGFjZShcIntjb3VudH1cIixuKSksbyYmKG49Uy5nZXQuc2VsZWN0aW9uQ291bnQoKSxlPWUucmVwbGFjZShcInttYXhDb3VudH1cIix5Lm1heFNlbGVjdGlvbnMpKSxzJiYoaT10fHxTLmdldC5xdWVyeSgpLGU9ZS5yZXBsYWNlKFwie3Rlcm19XCIsaSkpLGV9LHZhbHVlOmZ1bmN0aW9uKHQsbixpKXt2YXIgYSxvPVMuZ2V0LnZhbHVlcygpO2lmKFwiXCI9PT10KXJldHVybiB2b2lkIFMuZGVidWcoXCJDYW5ub3Qgc2VsZWN0IGJsYW5rIHZhbHVlcyBmcm9tIG11bHRpc2VsZWN0XCIpO2UuaXNBcnJheShvKT8oYT1vLmNvbmNhdChbdF0pLGE9Uy5nZXQudW5pcXVlQXJyYXkoYSkpOmE9W3RdLFMuaGFzLnNlbGVjdElucHV0KCk/Uy5jYW4uZXh0ZW5kU2VsZWN0KCkmJihTLmRlYnVnKFwiQWRkaW5nIHZhbHVlIHRvIHNlbGVjdFwiLHQsYSxOKSxTLmFkZC5vcHRpb25WYWx1ZSh0KSk6KGE9YS5qb2luKHkuZGVsaW1pdGVyKSxTLmRlYnVnKFwiU2V0dGluZyBoaWRkZW4gaW5wdXQgdG8gZGVsaW1pdGVkIHZhbHVlXCIsYSxOKSksITE9PT15LmZpcmVPbkluaXQmJlMuaXMuaW5pdGlhbExvYWQoKT9TLnZlcmJvc2UoXCJTa2lwcGluZyBvbmFkZCBjYWxsYmFjayBvbiBpbml0aWFsIGxvYWRcIix5Lm9uQWRkKTp5Lm9uQWRkLmNhbGwoWSx0LG4saSksUy5zZXQudmFsdWUoYSx0LG4saSksUy5jaGVjay5tYXhTZWxlY3Rpb25zKCl9fSxyZW1vdmU6e2FjdGl2ZTpmdW5jdGlvbigpe00ucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpfSxhY3RpdmVMYWJlbDpmdW5jdGlvbigpe00uZmluZChSLmxhYmVsKS5yZW1vdmVDbGFzcyhBLmFjdGl2ZSl9LGVtcHR5OmZ1bmN0aW9uKCl7TS5yZW1vdmVDbGFzcyhBLmVtcHR5KX0sbG9hZGluZzpmdW5jdGlvbigpe00ucmVtb3ZlQ2xhc3MoQS5sb2FkaW5nKX0saW5pdGlhbExvYWQ6ZnVuY3Rpb24oKXtoPSExfSx1cHdhcmQ6ZnVuY3Rpb24oZSl7KGV8fE0pLnJlbW92ZUNsYXNzKEEudXB3YXJkKX0sbGVmdHdhcmQ6ZnVuY3Rpb24oZSl7KGV8fFcpLnJlbW92ZUNsYXNzKEEubGVmdHdhcmQpfSx2aXNpYmxlOmZ1bmN0aW9uKCl7TS5yZW1vdmVDbGFzcyhBLnZpc2libGUpfSxhY3RpdmVJdGVtOmZ1bmN0aW9uKCl7Qi5yZW1vdmVDbGFzcyhBLmFjdGl2ZSl9LGZpbHRlcmVkSXRlbTpmdW5jdGlvbigpe3kudXNlTGFiZWxzJiZTLmhhcy5tYXhTZWxlY3Rpb25zKCl8fCh5LnVzZUxhYmVscyYmUy5pcy5tdWx0aXBsZSgpP0Iubm90KFwiLlwiK0EuYWN0aXZlKS5yZW1vdmVDbGFzcyhBLmZpbHRlcmVkKTpCLnJlbW92ZUNsYXNzKEEuZmlsdGVyZWQpLFMucmVtb3ZlLmVtcHR5KCkpfSxvcHRpb25WYWx1ZTpmdW5jdGlvbihlKXt2YXIgdD1TLmVzY2FwZS52YWx1ZShlKSxuPU4uZmluZCgnb3B0aW9uW3ZhbHVlPVwiJytTLmVzY2FwZS5zdHJpbmcodCkrJ1wiXScpO24ubGVuZ3RoPjAmJm4uaGFzQ2xhc3MoQS5hZGRpdGlvbikmJih4JiYoeC5kaXNjb25uZWN0KCksUy52ZXJib3NlKFwiVGVtcG9yYXJpbHkgZGlzY29ubmVjdGluZyBtdXRhdGlvbiBvYnNlcnZlclwiKSksbi5yZW1vdmUoKSxTLnZlcmJvc2UoXCJSZW1vdmluZyB1c2VyIGFkZGl0aW9uIGFzIGFuIDxvcHRpb24+XCIsdCkseCYmeC5vYnNlcnZlKE5bMF0se2NoaWxkTGlzdDohMCxzdWJ0cmVlOiEwfSkpfSxtZXNzYWdlOmZ1bmN0aW9uKCl7Vy5jaGlsZHJlbihSLm1lc3NhZ2UpLnJlbW92ZSgpfSxzZWFyY2hXaWR0aDpmdW5jdGlvbigpe0guY3NzKFwid2lkdGhcIixcIlwiKX0sc2VhcmNoVGVybTpmdW5jdGlvbigpe1MudmVyYm9zZShcIkNsZWFyZWQgc2VhcmNoIHRlcm1cIiksSC52YWwoXCJcIiksUy5zZXQuZmlsdGVyZWQoKX0sdXNlckFkZGl0aW9uOmZ1bmN0aW9uKCl7Qi5maWx0ZXIoUi5hZGRpdGlvbikucmVtb3ZlKCl9LHNlbGVjdGVkOmZ1bmN0aW9uKHQsbil7aWYoIShuPXkuYWxsb3dBZGRpdGlvbnM/bnx8Uy5nZXQuaXRlbVdpdGhBZGRpdGlvbnModCk6bnx8Uy5nZXQuaXRlbSh0KSkpcmV0dXJuITE7bi5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKSxuPVMuZ2V0LmNob2ljZVRleHQodCksaT1TLmdldC5jaG9pY2VWYWx1ZSh0LG4pO1MuaXMubXVsdGlwbGUoKT95LnVzZUxhYmVscz8oUy5yZW1vdmUudmFsdWUoaSxuLHQpLFMucmVtb3ZlLmxhYmVsKGkpKTooUy5yZW1vdmUudmFsdWUoaSxuLHQpLDA9PT1TLmdldC5zZWxlY3Rpb25Db3VudCgpP1Muc2V0LnBsYWNlaG9sZGVyVGV4dCgpOlMuc2V0LnRleHQoUy5hZGQudmFyaWFibGVzKFQuY291bnQpKSk6Uy5yZW1vdmUudmFsdWUoaSxuLHQpLHQucmVtb3ZlQ2xhc3MoQS5maWx0ZXJlZCkucmVtb3ZlQ2xhc3MoQS5hY3RpdmUpLHkudXNlTGFiZWxzJiZ0LnJlbW92ZUNsYXNzKEEuc2VsZWN0ZWQpfSl9LHNlbGVjdGVkSXRlbTpmdW5jdGlvbigpe0IucmVtb3ZlQ2xhc3MoQS5zZWxlY3RlZCl9LHZhbHVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgaSxhPVMuZ2V0LnZhbHVlcygpO1MuaGFzLnNlbGVjdElucHV0KCk/KFMudmVyYm9zZShcIklucHV0IGlzIDxzZWxlY3Q+IHJlbW92aW5nIHNlbGVjdGVkIG9wdGlvblwiLGUpLGk9Uy5yZW1vdmUuYXJyYXlWYWx1ZShlLGEpLFMucmVtb3ZlLm9wdGlvblZhbHVlKGUpKTooUy52ZXJib3NlKFwiUmVtb3ZpbmcgZnJvbSBkZWxpbWl0ZWQgdmFsdWVzXCIsZSksaT1TLnJlbW92ZS5hcnJheVZhbHVlKGUsYSksaT1pLmpvaW4oeS5kZWxpbWl0ZXIpKSwhMT09PXkuZmlyZU9uSW5pdCYmUy5pcy5pbml0aWFsTG9hZCgpP1MudmVyYm9zZShcIk5vIGNhbGxiYWNrIG9uIGluaXRpYWwgbG9hZFwiLHkub25SZW1vdmUpOnkub25SZW1vdmUuY2FsbChZLGUsdCxuKSxTLnNldC52YWx1ZShpLHQsbiksUy5jaGVjay5tYXhTZWxlY3Rpb25zKCl9LGFycmF5VmFsdWU6ZnVuY3Rpb24odCxuKXtyZXR1cm4gZS5pc0FycmF5KG4pfHwobj1bbl0pLG49ZS5ncmVwKG4sZnVuY3Rpb24oZSl7cmV0dXJuIHQhPWV9KSxTLnZlcmJvc2UoXCJSZW1vdmVkIHZhbHVlIGZyb20gZGVsaW1pdGVkIHN0cmluZ1wiLHQsbiksbn0sbGFiZWw6ZnVuY3Rpb24oZSx0KXt2YXIgbj1NLmZpbmQoUi5sYWJlbCksaT1uLmZpbHRlcihcIltkYXRhLVwiK0kudmFsdWUrJz1cIicrUy5lc2NhcGUuc3RyaW5nKGUpKydcIl0nKTtTLnZlcmJvc2UoXCJSZW1vdmluZyBsYWJlbFwiLGkpLGkucmVtb3ZlKCl9LGFjdGl2ZUxhYmVsczpmdW5jdGlvbihlKXtlPWV8fE0uZmluZChSLmxhYmVsKS5maWx0ZXIoXCIuXCIrQS5hY3RpdmUpLFMudmVyYm9zZShcIlJlbW92aW5nIGFjdGl2ZSBsYWJlbCBzZWxlY3Rpb25zXCIsZSksUy5yZW1vdmUubGFiZWxzKGUpfSxsYWJlbHM6ZnVuY3Rpb24odCl7dD10fHxNLmZpbmQoUi5sYWJlbCksUy52ZXJib3NlKFwiUmVtb3ZpbmcgbGFiZWxzXCIsdCksdC5lYWNoKGZ1bmN0aW9uKCl7dmFyIHQ9ZSh0aGlzKSxuPXQuZGF0YShJLnZhbHVlKSxpPXZvaWQgMCE9PW4/U3RyaW5nKG4pOm4sYT1TLmlzLnVzZXJWYWx1ZShpKTtpZighMT09PXkub25MYWJlbFJlbW92ZS5jYWxsKHQsbikpcmV0dXJuIHZvaWQgUy5kZWJ1ZyhcIkxhYmVsIHJlbW92ZSBjYWxsYmFjayBjYW5jZWxsZWQgcmVtb3ZhbFwiKTtTLnJlbW92ZS5tZXNzYWdlKCksYT8oUy5yZW1vdmUudmFsdWUoaSksUy5yZW1vdmUubGFiZWwoaSkpOlMucmVtb3ZlLnNlbGVjdGVkKGkpfSl9LHRhYmJhYmxlOmZ1bmN0aW9uKCl7Uy5pcy5zZWFyY2hTZWxlY3Rpb24oKT8oUy5kZWJ1ZyhcIlNlYXJjaGFibGUgZHJvcGRvd24gaW5pdGlhbGl6ZWRcIiksSC5yZW1vdmVBdHRyKFwidGFiaW5kZXhcIiksVy5yZW1vdmVBdHRyKFwidGFiaW5kZXhcIikpOihTLmRlYnVnKFwiU2ltcGxlIHNlbGVjdGlvbiBkcm9wZG93biBpbml0aWFsaXplZFwiKSxNLnJlbW92ZUF0dHIoXCJ0YWJpbmRleFwiKSxXLnJlbW92ZUF0dHIoXCJ0YWJpbmRleFwiKSl9fSxoYXM6e21lbnVTZWFyY2g6ZnVuY3Rpb24oKXtyZXR1cm4gUy5oYXMuc2VhcmNoKCkmJkguY2xvc2VzdChXKS5sZW5ndGg+MH0sc2VhcmNoOmZ1bmN0aW9uKCl7cmV0dXJuIEgubGVuZ3RoPjB9LHNpemVyOmZ1bmN0aW9uKCl7cmV0dXJuIGoubGVuZ3RoPjB9LHNlbGVjdElucHV0OmZ1bmN0aW9uKCl7cmV0dXJuIE4uaXMoXCJzZWxlY3RcIil9LG1pbkNoYXJhY3RlcnM6ZnVuY3Rpb24oZSl7cmV0dXJuIXkubWluQ2hhcmFjdGVyc3x8KGU9dm9pZCAwIT09ZT9TdHJpbmcoZSk6U3RyaW5nKFMuZ2V0LnF1ZXJ5KCkpLGUubGVuZ3RoPj15Lm1pbkNoYXJhY3RlcnMpfSxmaXJzdExldHRlcjpmdW5jdGlvbihlLHQpe3ZhciBuLGk7cmV0dXJuISghZXx8MD09PWUubGVuZ3RofHxcInN0cmluZ1wiIT10eXBlb2YgdCkmJihuPVMuZ2V0LmNob2ljZVRleHQoZSwhMSksdD10LnRvTG93ZXJDYXNlKCksaT1TdHJpbmcobikuY2hhckF0KDApLnRvTG93ZXJDYXNlKCksdD09aSl9LGlucHV0OmZ1bmN0aW9uKCl7cmV0dXJuIE4ubGVuZ3RoPjB9LGl0ZW1zOmZ1bmN0aW9uKCl7cmV0dXJuIEIubGVuZ3RoPjB9LG1lbnU6ZnVuY3Rpb24oKXtyZXR1cm4gVy5sZW5ndGg+MH0sbWVzc2FnZTpmdW5jdGlvbigpe3JldHVybiAwIT09Vy5jaGlsZHJlbihSLm1lc3NhZ2UpLmxlbmd0aH0sbGFiZWw6ZnVuY3Rpb24oZSl7dmFyIHQ9Uy5lc2NhcGUudmFsdWUoZSk7cmV0dXJuIE0uZmluZChSLmxhYmVsKS5maWx0ZXIoXCJbZGF0YS1cIitJLnZhbHVlKyc9XCInK1MuZXNjYXBlLnN0cmluZyh0KSsnXCJdJykubGVuZ3RoPjB9LG1heFNlbGVjdGlvbnM6ZnVuY3Rpb24oKXtyZXR1cm4geS5tYXhTZWxlY3Rpb25zJiZTLmdldC5zZWxlY3Rpb25Db3VudCgpPj15Lm1heFNlbGVjdGlvbnN9LGFsbFJlc3VsdHNGaWx0ZXJlZDpmdW5jdGlvbigpe3ZhciBlPUIubm90KFIuYWRkaXRpb24pO3JldHVybiBlLmZpbHRlcihSLnVuc2VsZWN0YWJsZSkubGVuZ3RoPT09ZS5sZW5ndGh9LHVzZXJTdWdnZXN0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIFcuY2hpbGRyZW4oUi5hZGRpdGlvbikubGVuZ3RoPjB9LHF1ZXJ5OmZ1bmN0aW9uKCl7cmV0dXJuXCJcIiE9PVMuZ2V0LnF1ZXJ5KCl9LHZhbHVlOmZ1bmN0aW9uKHQpe3ZhciBuPVMuZ2V0LnZhbHVlcygpO3JldHVybiEhKGUuaXNBcnJheShuKT9uJiYtMSE9PWUuaW5BcnJheSh0LG4pOm49PXQpfX0saXM6e2FjdGl2ZTpmdW5jdGlvbigpe3JldHVybiBNLmhhc0NsYXNzKEEuYWN0aXZlKX0sYnViYmxlZExhYmVsQ2xpY2s6ZnVuY3Rpb24odCl7cmV0dXJuIGUodC50YXJnZXQpLmlzKFwic2VsZWN0LCBpbnB1dFwiKSYmTS5jbG9zZXN0KFwibGFiZWxcIikubGVuZ3RoPjB9LGJ1YmJsZWRJY29uQ2xpY2s6ZnVuY3Rpb24odCl7cmV0dXJuIGUodC50YXJnZXQpLmNsb3Nlc3QoVSkubGVuZ3RoPjB9LGFscmVhZHlTZXR1cDpmdW5jdGlvbigpe3JldHVybiBNLmlzKFwic2VsZWN0XCIpJiZ2b2lkIDAhPT1NLnBhcmVudChSLmRyb3Bkb3duKS5kYXRhKEYpJiYwPT09TS5wcmV2KCkubGVuZ3RofSxhbmltYXRpbmc6ZnVuY3Rpb24oZSl7cmV0dXJuIGU/ZS50cmFuc2l0aW9uJiZlLnRyYW5zaXRpb24oXCJpcyBhbmltYXRpbmdcIik6Vy50cmFuc2l0aW9uJiZXLnRyYW5zaXRpb24oXCJpcyBhbmltYXRpbmdcIil9LGxlZnR3YXJkOmZ1bmN0aW9uKGUpe3JldHVybihlfHxXKS5oYXNDbGFzcyhBLmxlZnR3YXJkKX0sZGlzYWJsZWQ6ZnVuY3Rpb24oKXtyZXR1cm4gTS5oYXNDbGFzcyhBLmRpc2FibGVkKX0sZm9jdXNlZDpmdW5jdGlvbigpe3JldHVybiBuLmFjdGl2ZUVsZW1lbnQ9PT1NWzBdfSxmb2N1c2VkT25TZWFyY2g6ZnVuY3Rpb24oKXtyZXR1cm4gbi5hY3RpdmVFbGVtZW50PT09SFswXX0sYWxsRmlsdGVyZWQ6ZnVuY3Rpb24oKXtyZXR1cm4oUy5pcy5tdWx0aXBsZSgpfHxTLmhhcy5zZWFyY2goKSkmJiEoMD09eS5oaWRlQWRkaXRpb25zJiZTLmhhcy51c2VyU3VnZ2VzdGlvbigpKSYmIVMuaGFzLm1lc3NhZ2UoKSYmUy5oYXMuYWxsUmVzdWx0c0ZpbHRlcmVkKCl9LGhpZGRlbjpmdW5jdGlvbihlKXtyZXR1cm4hUy5pcy52aXNpYmxlKGUpfSxpbml0aWFsTG9hZDpmdW5jdGlvbigpe3JldHVybiBofSxpbk9iamVjdDpmdW5jdGlvbih0LG4pe3ZhciBpPSExO3JldHVybiBlLmVhY2gobixmdW5jdGlvbihlLG4pe2lmKG49PXQpcmV0dXJuIGk9ITAsITB9KSxpfSxtdWx0aXBsZTpmdW5jdGlvbigpe3JldHVybiBNLmhhc0NsYXNzKEEubXVsdGlwbGUpfSxyZW1vdGU6ZnVuY3Rpb24oKXtyZXR1cm4geS5hcGlTZXR0aW5ncyYmUy5jYW4udXNlQVBJKCl9LHNpbmdsZTpmdW5jdGlvbigpe3JldHVybiFTLmlzLm11bHRpcGxlKCl9LHNlbGVjdE11dGF0aW9uOmZ1bmN0aW9uKHQpe3ZhciBuPSExO3JldHVybiBlLmVhY2godCxmdW5jdGlvbih0LGkpe2lmKGkudGFyZ2V0JiZlKGkudGFyZ2V0KS5pcyhcInNlbGVjdFwiKSlyZXR1cm4gbj0hMCwhMH0pLG59LHNlYXJjaDpmdW5jdGlvbigpe3JldHVybiBNLmhhc0NsYXNzKEEuc2VhcmNoKX0sc2VhcmNoU2VsZWN0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIFMuaGFzLnNlYXJjaCgpJiYxPT09SC5wYXJlbnQoUi5kcm9wZG93bikubGVuZ3RofSxzZWxlY3Rpb246ZnVuY3Rpb24oKXtyZXR1cm4gTS5oYXNDbGFzcyhBLnNlbGVjdGlvbil9LHVzZXJWYWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4tMSE9PWUuaW5BcnJheSh0LFMuZ2V0LnVzZXJWYWx1ZXMoKSl9LHVwd2FyZDpmdW5jdGlvbihlKXtyZXR1cm4oZXx8TSkuaGFzQ2xhc3MoQS51cHdhcmQpfSx2aXNpYmxlOmZ1bmN0aW9uKGUpe3JldHVybiBlP2UuaGFzQ2xhc3MoQS52aXNpYmxlKTpXLmhhc0NsYXNzKEEudmlzaWJsZSl9LHZlcnRpY2FsbHlTY3JvbGxhYmxlQ29udGV4dDpmdW5jdGlvbigpe3ZhciBlPXouZ2V0KDApIT09dCYmei5jc3MoXCJvdmVyZmxvdy15XCIpO3JldHVyblwiYXV0b1wiPT1lfHxcInNjcm9sbFwiPT1lfSxob3Jpem9udGFsbHlTY3JvbGxhYmxlQ29udGV4dDpmdW5jdGlvbigpe3ZhciBlPXouZ2V0KDApIT09dCYmei5jc3MoXCJvdmVyZmxvdy1YXCIpO3JldHVyblwiYXV0b1wiPT1lfHxcInNjcm9sbFwiPT1lfX0sY2FuOnthY3RpdmF0ZTpmdW5jdGlvbihlKXtyZXR1cm4hIXkudXNlTGFiZWxzfHwoIVMuaGFzLm1heFNlbGVjdGlvbnMoKXx8ISghUy5oYXMubWF4U2VsZWN0aW9ucygpfHwhZS5oYXNDbGFzcyhBLmFjdGl2ZSkpKX0sb3BlbkRvd253YXJkOmZ1bmN0aW9uKGUpe3ZhciB0LG49ZXx8VyxpPSEwLGE9e307cmV0dXJuIG4uYWRkQ2xhc3MoQS5sb2FkaW5nKSx0PXtjb250ZXh0OntzY3JvbGxUb3A6ei5zY3JvbGxUb3AoKSxoZWlnaHQ6ei5vdXRlckhlaWdodCgpfSxtZW51OntvZmZzZXQ6bi5vZmZzZXQoKSxoZWlnaHQ6bi5vdXRlckhlaWdodCgpfX0sUy5pcy52ZXJ0aWNhbGx5U2Nyb2xsYWJsZUNvbnRleHQoKSYmKHQubWVudS5vZmZzZXQudG9wKz10LmNvbnRleHQuc2Nyb2xsVG9wKSxhPXthYm92ZTp0LmNvbnRleHQuc2Nyb2xsVG9wPD10Lm1lbnUub2Zmc2V0LnRvcC10Lm1lbnUuaGVpZ2h0LGJlbG93OnQuY29udGV4dC5zY3JvbGxUb3ArdC5jb250ZXh0LmhlaWdodD49dC5tZW51Lm9mZnNldC50b3ArdC5tZW51LmhlaWdodH0sYS5iZWxvdz8oUy52ZXJib3NlKFwiRHJvcGRvd24gY2FuIGZpdCBpbiBjb250ZXh0IGRvd253YXJkXCIsYSksaT0hMCk6YS5iZWxvd3x8YS5hYm92ZT8oUy52ZXJib3NlKFwiRHJvcGRvd24gY2Fubm90IGZpdCBiZWxvdywgb3BlbmluZyB1cHdhcmRcIixhKSxpPSExKTooUy52ZXJib3NlKFwiRHJvcGRvd24gY2Fubm90IGZpdCBpbiBlaXRoZXIgZGlyZWN0aW9uLCBmYXZvcmluZyBkb3dud2FyZFwiLGEpLGk9ITApLG4ucmVtb3ZlQ2xhc3MoQS5sb2FkaW5nKSxpfSxvcGVuUmlnaHR3YXJkOmZ1bmN0aW9uKGUpe3ZhciB0LG49ZXx8VyxpPSEwLGE9ITE7cmV0dXJuIG4uYWRkQ2xhc3MoQS5sb2FkaW5nKSx0PXtjb250ZXh0OntzY3JvbGxMZWZ0Onouc2Nyb2xsTGVmdCgpLHdpZHRoOnoub3V0ZXJXaWR0aCgpfSxtZW51OntvZmZzZXQ6bi5vZmZzZXQoKSx3aWR0aDpuLm91dGVyV2lkdGgoKX19LFMuaXMuaG9yaXpvbnRhbGx5U2Nyb2xsYWJsZUNvbnRleHQoKSYmKHQubWVudS5vZmZzZXQubGVmdCs9dC5jb250ZXh0LnNjcm9sbExlZnQpLGE9dC5tZW51Lm9mZnNldC5sZWZ0K3QubWVudS53aWR0aD49dC5jb250ZXh0LnNjcm9sbExlZnQrdC5jb250ZXh0LndpZHRoLGEmJihTLnZlcmJvc2UoXCJEcm9wZG93biBjYW5ub3QgZml0IGluIGNvbnRleHQgcmlnaHR3YXJkXCIsYSksaT0hMSksbi5yZW1vdmVDbGFzcyhBLmxvYWRpbmcpLGl9LGNsaWNrOmZ1bmN0aW9uKCl7cmV0dXJuIGx8fFwiY2xpY2tcIj09eS5vbn0sZXh0ZW5kU2VsZWN0OmZ1bmN0aW9uKCl7cmV0dXJuIHkuYWxsb3dBZGRpdGlvbnN8fHkuYXBpU2V0dGluZ3N9LHNob3c6ZnVuY3Rpb24oKXtyZXR1cm4hUy5pcy5kaXNhYmxlZCgpJiYoUy5oYXMuaXRlbXMoKXx8Uy5oYXMubWVzc2FnZSgpKX0sdXNlQVBJOmZ1bmN0aW9uKCl7cmV0dXJuIHZvaWQgMCE9PWUuZm4uYXBpfX0sYW5pbWF0ZTp7c2hvdzpmdW5jdGlvbih0LG4pe3ZhciBpLGE9bnx8VyxvPW4/ZnVuY3Rpb24oKXt9OmZ1bmN0aW9uKCl7Uy5oaWRlU3ViTWVudXMoKSxTLmhpZGVPdGhlcnMoKSxTLnNldC5hY3RpdmUoKX07dD1lLmlzRnVuY3Rpb24odCk/dDpmdW5jdGlvbigpe30sUy52ZXJib3NlKFwiRG9pbmcgbWVudSBzaG93IGFuaW1hdGlvblwiLGEpLFMuc2V0LmRpcmVjdGlvbihuKSxpPVMuZ2V0LnRyYW5zaXRpb24obiksUy5pcy5zZWxlY3Rpb24oKSYmUy5zZXQuc2Nyb2xsUG9zaXRpb24oUy5nZXQuc2VsZWN0ZWRJdGVtKCksITApLChTLmlzLmhpZGRlbihhKXx8Uy5pcy5hbmltYXRpbmcoYSkpJiYoXCJub25lXCI9PWk/KG8oKSxhLnRyYW5zaXRpb24oXCJzaG93XCIpLHQuY2FsbChZKSk6dm9pZCAwIT09ZS5mbi50cmFuc2l0aW9uJiZNLnRyYW5zaXRpb24oXCJpcyBzdXBwb3J0ZWRcIik/YS50cmFuc2l0aW9uKHthbmltYXRpb246aStcIiBpblwiLGRlYnVnOnkuZGVidWcsdmVyYm9zZTp5LnZlcmJvc2UsZHVyYXRpb246eS5kdXJhdGlvbixxdWV1ZTohMCxvblN0YXJ0Om8sb25Db21wbGV0ZTpmdW5jdGlvbigpe3QuY2FsbChZKX19KTpTLmVycm9yKE8ubm9UcmFuc2l0aW9uLGkpKX0saGlkZTpmdW5jdGlvbih0LG4pe3ZhciBpPW58fFcsYT0obj95LmR1cmF0aW9uOnkuZHVyYXRpb24sbj9mdW5jdGlvbigpe306ZnVuY3Rpb24oKXtTLmNhbi5jbGljaygpJiZTLnVuYmluZC5pbnRlbnQoKSxTLnJlbW92ZS5hY3RpdmUoKX0pLG89Uy5nZXQudHJhbnNpdGlvbihuKTt0PWUuaXNGdW5jdGlvbih0KT90OmZ1bmN0aW9uKCl7fSwoUy5pcy52aXNpYmxlKGkpfHxTLmlzLmFuaW1hdGluZyhpKSkmJihTLnZlcmJvc2UoXCJEb2luZyBtZW51IGhpZGUgYW5pbWF0aW9uXCIsaSksXCJub25lXCI9PW8/KGEoKSxpLnRyYW5zaXRpb24oXCJoaWRlXCIpLHQuY2FsbChZKSk6dm9pZCAwIT09ZS5mbi50cmFuc2l0aW9uJiZNLnRyYW5zaXRpb24oXCJpcyBzdXBwb3J0ZWRcIik/aS50cmFuc2l0aW9uKHthbmltYXRpb246bytcIiBvdXRcIixkdXJhdGlvbjp5LmR1cmF0aW9uLGRlYnVnOnkuZGVidWcsdmVyYm9zZTp5LnZlcmJvc2UscXVldWU6ITAsb25TdGFydDphLG9uQ29tcGxldGU6ZnVuY3Rpb24oKXt0LmNhbGwoWSl9fSk6Uy5lcnJvcihPLnRyYW5zaXRpb24pKX19LGhpZGVBbmRDbGVhcjpmdW5jdGlvbigpe1MucmVtb3ZlLnNlYXJjaFRlcm0oKSxTLmhhcy5tYXhTZWxlY3Rpb25zKCl8fChTLmhhcy5zZWFyY2goKT9TLmhpZGUoZnVuY3Rpb24oKXtTLnJlbW92ZS5maWx0ZXJlZEl0ZW0oKX0pOlMuaGlkZSgpKX0sZGVsYXk6e3Nob3c6ZnVuY3Rpb24oKXtTLnZlcmJvc2UoXCJEZWxheWluZyBzaG93IGV2ZW50IHRvIGVuc3VyZSB1c2VyIGludGVudFwiKSxjbGVhclRpbWVvdXQoUy50aW1lciksUy50aW1lcj1zZXRUaW1lb3V0KFMuc2hvdyx5LmRlbGF5LnNob3cpfSxoaWRlOmZ1bmN0aW9uKCl7Uy52ZXJib3NlKFwiRGVsYXlpbmcgaGlkZSBldmVudCB0byBlbnN1cmUgdXNlciBpbnRlbnRcIiksY2xlYXJUaW1lb3V0KFMudGltZXIpLFMudGltZXI9c2V0VGltZW91dChTLmhpZGUseS5kZWxheS5oaWRlKX19LGVzY2FwZTp7dmFsdWU6ZnVuY3Rpb24odCl7dmFyIG49ZS5pc0FycmF5KHQpLGk9XCJzdHJpbmdcIj09dHlwZW9mIHQsYT0haSYmIW4sbz1pJiYtMSE9PXQuc2VhcmNoKHEucXVvdGUpLHM9W107cmV0dXJuIGF8fCFvP3Q6KFMuZGVidWcoXCJFbmNvZGluZyBxdW90ZSB2YWx1ZXMgZm9yIHVzZSBpbiBzZWxlY3RcIix0KSxuPyhlLmVhY2godCxmdW5jdGlvbihlLHQpe3MucHVzaCh0LnJlcGxhY2UocS5xdW90ZSxcIiZxdW90O1wiKSl9KSxzKTp0LnJlcGxhY2UocS5xdW90ZSxcIiZxdW90O1wiKSl9LHN0cmluZzpmdW5jdGlvbihlKXtyZXR1cm4gZT1TdHJpbmcoZSksZS5yZXBsYWNlKHEuZXNjYXBlLFwiXFxcXCQmXCIpfX0sc2V0dGluZzpmdW5jdGlvbih0LG4pe2lmKFMuZGVidWcoXCJDaGFuZ2luZyBzZXR0aW5nXCIsdCxuKSxlLmlzUGxhaW5PYmplY3QodCkpZS5leHRlbmQoITAseSx0KTtlbHNle2lmKHZvaWQgMD09PW4pcmV0dXJuIHlbdF07ZS5pc1BsYWluT2JqZWN0KHlbdF0pP2UuZXh0ZW5kKCEwLHlbdF0sbik6eVt0XT1ufX0saW50ZXJuYWw6ZnVuY3Rpb24odCxuKXtpZihlLmlzUGxhaW5PYmplY3QodCkpZS5leHRlbmQoITAsUyx0KTtlbHNle2lmKHZvaWQgMD09PW4pcmV0dXJuIFNbdF07U1t0XT1ufX0sZGVidWc6ZnVuY3Rpb24oKXsheS5zaWxlbnQmJnkuZGVidWcmJih5LnBlcmZvcm1hbmNlP1MucGVyZm9ybWFuY2UubG9nKGFyZ3VtZW50cyk6KFMuZGVidWc9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuY2FsbChjb25zb2xlLmluZm8sY29uc29sZSx5Lm5hbWUrXCI6XCIpLFMuZGVidWcuYXBwbHkoY29uc29sZSxhcmd1bWVudHMpKSl9LHZlcmJvc2U6ZnVuY3Rpb24oKXsheS5zaWxlbnQmJnkudmVyYm9zZSYmeS5kZWJ1ZyYmKHkucGVyZm9ybWFuY2U/Uy5wZXJmb3JtYW5jZS5sb2coYXJndW1lbnRzKTooUy52ZXJib3NlPUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmNhbGwoY29uc29sZS5pbmZvLGNvbnNvbGUseS5uYW1lK1wiOlwiKSxTLnZlcmJvc2UuYXBwbHkoY29uc29sZSxhcmd1bWVudHMpKSl9LGVycm9yOmZ1bmN0aW9uKCl7eS5zaWxlbnR8fChTLmVycm9yPUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmNhbGwoY29uc29sZS5lcnJvcixjb25zb2xlLHkubmFtZStcIjpcIiksUy5lcnJvci5hcHBseShjb25zb2xlLGFyZ3VtZW50cykpfSxwZXJmb3JtYW5jZTp7bG9nOmZ1bmN0aW9uKGUpe3ZhciB0LG4saTt5LnBlcmZvcm1hbmNlJiYodD0obmV3IERhdGUpLmdldFRpbWUoKSxpPWN8fHQsbj10LWksYz10LHUucHVzaCh7TmFtZTplWzBdLEFyZ3VtZW50czpbXS5zbGljZS5jYWxsKGUsMSl8fFwiXCIsRWxlbWVudDpZLFwiRXhlY3V0aW9uIFRpbWVcIjpufSkpLGNsZWFyVGltZW91dChTLnBlcmZvcm1hbmNlLnRpbWVyKSxTLnBlcmZvcm1hbmNlLnRpbWVyPXNldFRpbWVvdXQoUy5wZXJmb3JtYW5jZS5kaXNwbGF5LDUwMCl9LGRpc3BsYXk6ZnVuY3Rpb24oKXt2YXIgdD15Lm5hbWUrXCI6XCIsbj0wO2M9ITEsY2xlYXJUaW1lb3V0KFMucGVyZm9ybWFuY2UudGltZXIpLGUuZWFjaCh1LGZ1bmN0aW9uKGUsdCl7bis9dFtcIkV4ZWN1dGlvbiBUaW1lXCJdfSksdCs9XCIgXCIrbitcIm1zXCIsciYmKHQrPVwiICdcIityK1wiJ1wiKSwodm9pZCAwIT09Y29uc29sZS5ncm91cHx8dm9pZCAwIT09Y29uc29sZS50YWJsZSkmJnUubGVuZ3RoPjAmJihjb25zb2xlLmdyb3VwQ29sbGFwc2VkKHQpLGNvbnNvbGUudGFibGU/Y29uc29sZS50YWJsZSh1KTplLmVhY2godSxmdW5jdGlvbihlLHQpe2NvbnNvbGUubG9nKHQuTmFtZStcIjogXCIrdFtcIkV4ZWN1dGlvbiBUaW1lXCJdK1wibXNcIil9KSxjb25zb2xlLmdyb3VwRW5kKCkpLHU9W119fSxpbnZva2U6ZnVuY3Rpb24odCxuLGkpe3ZhciBvLHMscixsPUc7cmV0dXJuIG49bnx8ZixpPVl8fGksXCJzdHJpbmdcIj09dHlwZW9mIHQmJnZvaWQgMCE9PWwmJih0PXQuc3BsaXQoL1tcXC4gXS8pLG89dC5sZW5ndGgtMSxlLmVhY2godCxmdW5jdGlvbihuLGkpe3ZhciBhPW4hPW8/aSt0W24rMV0uY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrdFtuKzFdLnNsaWNlKDEpOnQ7aWYoZS5pc1BsYWluT2JqZWN0KGxbYV0pJiZuIT1vKWw9bFthXTtlbHNle2lmKHZvaWQgMCE9PWxbYV0pcmV0dXJuIHM9bFthXSwhMTtpZighZS5pc1BsYWluT2JqZWN0KGxbaV0pfHxuPT1vKXJldHVybiB2b2lkIDAhPT1sW2ldPyhzPWxbaV0sITEpOihTLmVycm9yKE8ubWV0aG9kLHQpLCExKTtsPWxbaV19fSkpLGUuaXNGdW5jdGlvbihzKT9yPXMuYXBwbHkoaSxuKTp2b2lkIDAhPT1zJiYocj1zKSxlLmlzQXJyYXkoYSk/YS5wdXNoKHIpOnZvaWQgMCE9PWE/YT1bYSxyXTp2b2lkIDAhPT1yJiYoYT1yKSxzfX0sdj8odm9pZCAwPT09RyYmUy5pbml0aWFsaXplKCksUy5pbnZva2UoZCkpOih2b2lkIDAhPT1HJiZHLmludm9rZShcImRlc3Ryb3lcIiksUy5pbml0aWFsaXplKCkpfSksdm9pZCAwIT09YT9hOm99LGUuZm4uZHJvcGRvd24uc2V0dGluZ3M9e3NpbGVudDohMSxkZWJ1ZzohMSx2ZXJib3NlOiExLHBlcmZvcm1hbmNlOiEwLG9uOlwiY2xpY2tcIixhY3Rpb246XCJhY3RpdmF0ZVwiLHZhbHVlczohMSxhcGlTZXR0aW5nczohMSxzZWxlY3RPbktleWRvd246ITAsbWluQ2hhcmFjdGVyczowLGZpbHRlclJlbW90ZURhdGE6ITEsc2F2ZVJlbW90ZURhdGE6ITAsdGhyb3R0bGU6MjAwLGNvbnRleHQ6dCxkaXJlY3Rpb246XCJhdXRvXCIsa2VlcE9uU2NyZWVuOiEwLG1hdGNoOlwiYm90aFwiLGZ1bGxUZXh0U2VhcmNoOiExLHBsYWNlaG9sZGVyOlwiYXV0b1wiLHByZXNlcnZlSFRNTDohMCxzb3J0U2VsZWN0OiExLGZvcmNlU2VsZWN0aW9uOiEwLGFsbG93QWRkaXRpb25zOiExLGhpZGVBZGRpdGlvbnM6ITAsbWF4U2VsZWN0aW9uczohMSx1c2VMYWJlbHM6ITAsZGVsaW1pdGVyOlwiLFwiLHNob3dPbkZvY3VzOiEwLGFsbG93UmVzZWxlY3Rpb246ITEsYWxsb3dUYWI6ITAsYWxsb3dDYXRlZ29yeVNlbGVjdGlvbjohMSxmaXJlT25Jbml0OiExLHRyYW5zaXRpb246XCJhdXRvXCIsZHVyYXRpb246MjAwLGdseXBoV2lkdGg6MS4wMzcsbGFiZWw6e3RyYW5zaXRpb246XCJzY2FsZVwiLGR1cmF0aW9uOjIwMCx2YXJpYXRpb246ITF9LGRlbGF5OntoaWRlOjMwMCxzaG93OjIwMCxzZWFyY2g6MjAsdG91Y2g6NTB9LG9uQ2hhbmdlOmZ1bmN0aW9uKGUsdCxuKXt9LG9uQWRkOmZ1bmN0aW9uKGUsdCxuKXt9LG9uUmVtb3ZlOmZ1bmN0aW9uKGUsdCxuKXt9LG9uTGFiZWxTZWxlY3Q6ZnVuY3Rpb24oZSl7fSxvbkxhYmVsQ3JlYXRlOmZ1bmN0aW9uKHQsbil7cmV0dXJuIGUodGhpcyl9LG9uTGFiZWxSZW1vdmU6ZnVuY3Rpb24oZSl7cmV0dXJuITB9LG9uTm9SZXN1bHRzOmZ1bmN0aW9uKGUpe3JldHVybiEwfSxvblNob3c6ZnVuY3Rpb24oKXt9LG9uSGlkZTpmdW5jdGlvbigpe30sbmFtZTpcIkRyb3Bkb3duXCIsbmFtZXNwYWNlOlwiZHJvcGRvd25cIixtZXNzYWdlOnthZGRSZXN1bHQ6XCJBZGQgPGI+e3Rlcm19PC9iPlwiLGNvdW50Olwie2NvdW50fSBzZWxlY3RlZFwiLG1heFNlbGVjdGlvbnM6XCJNYXgge21heENvdW50fSBzZWxlY3Rpb25zXCIsbm9SZXN1bHRzOlwiTm8gcmVzdWx0cyBmb3VuZC5cIixzZXJ2ZXJFcnJvcjpcIlRoZXJlIHdhcyBhbiBlcnJvciBjb250YWN0aW5nIHRoZSBzZXJ2ZXJcIn0sZXJyb3I6e2FjdGlvbjpcIllvdSBjYWxsZWQgYSBkcm9wZG93biBhY3Rpb24gdGhhdCB3YXMgbm90IGRlZmluZWRcIixhbHJlYWR5U2V0dXA6XCJPbmNlIGEgc2VsZWN0IGhhcyBiZWVuIGluaXRpYWxpemVkIGJlaGF2aW9ycyBtdXN0IGJlIGNhbGxlZCBvbiB0aGUgY3JlYXRlZCB1aSBkcm9wZG93blwiLGxhYmVsczpcIkFsbG93aW5nIHVzZXIgYWRkaXRpb25zIGN1cnJlbnRseSByZXF1aXJlcyB0aGUgdXNlIG9mIGxhYmVscy5cIixtaXNzaW5nTXVsdGlwbGU6XCI8c2VsZWN0PiByZXF1aXJlcyBtdWx0aXBsZSBwcm9wZXJ0eSB0byBiZSBzZXQgdG8gY29ycmVjdGx5IHByZXNlcnZlIG11bHRpcGxlIHZhbHVlc1wiLG1ldGhvZDpcIlRoZSBtZXRob2QgeW91IGNhbGxlZCBpcyBub3QgZGVmaW5lZC5cIixub0FQSTpcIlRoZSBBUEkgbW9kdWxlIGlzIHJlcXVpcmVkIHRvIGxvYWQgcmVzb3VyY2VzIHJlbW90ZWx5XCIsbm9TdG9yYWdlOlwiU2F2aW5nIHJlbW90ZSBkYXRhIHJlcXVpcmVzIHNlc3Npb24gc3RvcmFnZVwiLG5vVHJhbnNpdGlvbjpcIlRoaXMgbW9kdWxlIHJlcXVpcmVzIHVpIHRyYW5zaXRpb25zIDxodHRwczovL2dpdGh1Yi5jb20vU2VtYW50aWMtT3JnL1VJLVRyYW5zaXRpb24+XCJ9LHJlZ0V4cDp7ZXNjYXBlOi9bLVtcXF17fSgpKis/LixcXFxcXiR8I1xcc10vZyxxdW90ZTovXCIvZ30sbWV0YWRhdGE6e2RlZmF1bHRUZXh0OlwiZGVmYXVsdFRleHRcIixkZWZhdWx0VmFsdWU6XCJkZWZhdWx0VmFsdWVcIixwbGFjZWhvbGRlclRleHQ6XCJwbGFjZWhvbGRlclwiLHRleHQ6XCJ0ZXh0XCIsdmFsdWU6XCJ2YWx1ZVwifSxmaWVsZHM6e3JlbW90ZVZhbHVlczpcInJlc3VsdHNcIix2YWx1ZXM6XCJ2YWx1ZXNcIixkaXNhYmxlZDpcImRpc2FibGVkXCIsbmFtZTpcIm5hbWVcIix2YWx1ZTpcInZhbHVlXCIsdGV4dDpcInRleHRcIn0sa2V5czp7YmFja3NwYWNlOjgsZGVsaW1pdGVyOjE4OCxkZWxldGVLZXk6NDYsZW50ZXI6MTMsZXNjYXBlOjI3LHBhZ2VVcDozMyxwYWdlRG93bjozNCxsZWZ0QXJyb3c6MzcsdXBBcnJvdzozOCxyaWdodEFycm93OjM5LGRvd25BcnJvdzo0MH0sc2VsZWN0b3I6e2FkZGl0aW9uOlwiLmFkZGl0aW9uXCIsZHJvcGRvd246XCIudWkuZHJvcGRvd25cIixoaWRkZW46XCIuaGlkZGVuXCIsaWNvbjpcIj4gLmRyb3Bkb3duLmljb25cIixpbnB1dDonPiBpbnB1dFt0eXBlPVwiaGlkZGVuXCJdLCA+IHNlbGVjdCcsaXRlbTpcIi5pdGVtXCIsbGFiZWw6XCI+IC5sYWJlbFwiLHJlbW92ZTpcIj4gLmxhYmVsID4gLmRlbGV0ZS5pY29uXCIsc2libGluZ0xhYmVsOlwiLmxhYmVsXCIsbWVudTpcIi5tZW51XCIsbWVzc2FnZTpcIi5tZXNzYWdlXCIsbWVudUljb246XCIuZHJvcGRvd24uaWNvblwiLHNlYXJjaDpcImlucHV0LnNlYXJjaCwgLm1lbnUgPiAuc2VhcmNoID4gaW5wdXQsIC5tZW51IGlucHV0LnNlYXJjaFwiLHNpemVyOlwiPiBpbnB1dC5zaXplclwiLHRleHQ6XCI+IC50ZXh0Om5vdCguaWNvbilcIix1bnNlbGVjdGFibGU6XCIuZGlzYWJsZWQsIC5maWx0ZXJlZFwifSxjbGFzc05hbWU6e2FjdGl2ZTpcImFjdGl2ZVwiLGFkZGl0aW9uOlwiYWRkaXRpb25cIixhbmltYXRpbmc6XCJhbmltYXRpbmdcIixkaXNhYmxlZDpcImRpc2FibGVkXCIsZW1wdHk6XCJlbXB0eVwiLGRyb3Bkb3duOlwidWkgZHJvcGRvd25cIixmaWx0ZXJlZDpcImZpbHRlcmVkXCIsaGlkZGVuOlwiaGlkZGVuIHRyYW5zaXRpb25cIixpdGVtOlwiaXRlbVwiLGxhYmVsOlwidWkgbGFiZWxcIixsb2FkaW5nOlwibG9hZGluZ1wiLG1lbnU6XCJtZW51XCIsbWVzc2FnZTpcIm1lc3NhZ2VcIixtdWx0aXBsZTpcIm11bHRpcGxlXCIscGxhY2Vob2xkZXI6XCJkZWZhdWx0XCIsc2l6ZXI6XCJzaXplclwiLHNlYXJjaDpcInNlYXJjaFwiLHNlbGVjdGVkOlwic2VsZWN0ZWRcIixzZWxlY3Rpb246XCJzZWxlY3Rpb25cIix1cHdhcmQ6XCJ1cHdhcmRcIixsZWZ0d2FyZDpcImxlZnRcIix2aXNpYmxlOlwidmlzaWJsZVwifX0sZS5mbi5kcm9wZG93bi5zZXR0aW5ncy50ZW1wbGF0ZXM9e2Ryb3Bkb3duOmZ1bmN0aW9uKHQpe3ZhciBuPXQucGxhY2Vob2xkZXJ8fCExLGk9KHQudmFsdWVzLFwiXCIpO3JldHVybiBpKz0nPGkgY2xhc3M9XCJkcm9wZG93biBpY29uXCI+PC9pPicsdC5wbGFjZWhvbGRlcj9pKz0nPGRpdiBjbGFzcz1cImRlZmF1bHQgdGV4dFwiPicrbitcIjwvZGl2PlwiOmkrPSc8ZGl2IGNsYXNzPVwidGV4dFwiPjwvZGl2PicsaSs9JzxkaXYgY2xhc3M9XCJtZW51XCI+JyxlLmVhY2godC52YWx1ZXMsZnVuY3Rpb24oZSx0KXtpKz10LmRpc2FibGVkPyc8ZGl2IGNsYXNzPVwiZGlzYWJsZWQgaXRlbVwiIGRhdGEtdmFsdWU9XCInK3QudmFsdWUrJ1wiPicrdC5uYW1lK1wiPC9kaXY+XCI6JzxkaXYgY2xhc3M9XCJpdGVtXCIgZGF0YS12YWx1ZT1cIicrdC52YWx1ZSsnXCI+Jyt0Lm5hbWUrXCI8L2Rpdj5cIn0pLGkrPVwiPC9kaXY+XCJ9LG1lbnU6ZnVuY3Rpb24odCxuKXt2YXIgaT10W24udmFsdWVzXXx8e30sYT1cIlwiO3JldHVybiBlLmVhY2goaSxmdW5jdGlvbihlLHQpe3ZhciBpPXRbbi50ZXh0XT8nZGF0YS10ZXh0PVwiJyt0W24udGV4dF0rJ1wiJzpcIlwiLG89dFtuLmRpc2FibGVkXT9cImRpc2FibGVkIFwiOlwiXCI7YSs9JzxkaXYgY2xhc3M9XCInK28rJ2l0ZW1cIiBkYXRhLXZhbHVlPVwiJyt0W24udmFsdWVdKydcIicraStcIj5cIixhKz10W24ubmFtZV0sYSs9XCI8L2Rpdj5cIn0pLGF9LGxhYmVsOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQrJzxpIGNsYXNzPVwiZGVsZXRlIGljb25cIj48L2k+J30sbWVzc2FnZTpmdW5jdGlvbihlKXtyZXR1cm4gZX0sYWRkaXRpb246ZnVuY3Rpb24oZSl7cmV0dXJuIGV9fX0oalF1ZXJ5LHdpbmRvdyxkb2N1bWVudCk7IiwiLyohXHJcbiAqICMgU2VtYW50aWMgVUkgMi4xLjcgLSBUcmFuc2l0aW9uXHJcbiAqIGh0dHA6Ly9naXRodWIuY29tL3NlbWFudGljLW9yZy9zZW1hbnRpYy11aS9cclxuICpcclxuICpcclxuICogQ29weXJpZ2h0IDIwMTUgQ29udHJpYnV0b3JzXHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxyXG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXHJcbiAqXHJcbiAqL1xyXG4hZnVuY3Rpb24obixlLGksdCl7XCJ1c2Ugc3RyaWN0XCI7bi5mbi50cmFuc2l0aW9uPWZ1bmN0aW9uKCl7dmFyIGEsbz1uKHRoaXMpLHI9by5zZWxlY3Rvcnx8XCJcIixzPShuZXcgRGF0ZSkuZ2V0VGltZSgpLGw9W10sdT1hcmd1bWVudHMsYz11WzBdLGQ9W10uc2xpY2UuY2FsbChhcmd1bWVudHMsMSksbT1cInN0cmluZ1wiPT10eXBlb2YgYztlLnJlcXVlc3RBbmltYXRpb25GcmFtZXx8ZS5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWV8fGUud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lfHxlLm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lfHxmdW5jdGlvbihuKXtzZXRUaW1lb3V0KG4sMCl9O3JldHVybiBvLmVhY2goZnVuY3Rpb24oZSl7dmFyIGYscCxnLHYsYix5LGgsdyxDLEE9bih0aGlzKSxTPXRoaXM7Qz17aW5pdGlhbGl6ZTpmdW5jdGlvbigpe2Y9Qy5nZXQuc2V0dGluZ3MuYXBwbHkoUyx1KSx2PWYuY2xhc3NOYW1lLGc9Zi5lcnJvcixiPWYubWV0YWRhdGEsdz1cIi5cIitmLm5hbWVzcGFjZSxoPVwibW9kdWxlLVwiK2YubmFtZXNwYWNlLHA9QS5kYXRhKGgpfHxDLHk9Qy5nZXQuYW5pbWF0aW9uRW5kRXZlbnQoKSxtJiYobT1DLmludm9rZShjKSksbT09PSExJiYoQy52ZXJib3NlKFwiQ29udmVydGVkIGFyZ3VtZW50cyBpbnRvIHNldHRpbmdzIG9iamVjdFwiLGYpLGYuaW50ZXJ2YWw/Qy5kZWxheShmLmFuaW1hdGUpOkMuYW5pbWF0ZSgpLEMuaW5zdGFudGlhdGUoKSl9LGluc3RhbnRpYXRlOmZ1bmN0aW9uKCl7Qy52ZXJib3NlKFwiU3RvcmluZyBpbnN0YW5jZSBvZiBtb2R1bGVcIixDKSxwPUMsQS5kYXRhKGgscCl9LGRlc3Ryb3k6ZnVuY3Rpb24oKXtDLnZlcmJvc2UoXCJEZXN0cm95aW5nIHByZXZpb3VzIG1vZHVsZSBmb3JcIixTKSxBLnJlbW92ZURhdGEoaCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXtDLnZlcmJvc2UoXCJSZWZyZXNoaW5nIGRpc3BsYXkgdHlwZSBvbiBuZXh0IGFuaW1hdGlvblwiKSxkZWxldGUgQy5kaXNwbGF5VHlwZX0sZm9yY2VSZXBhaW50OmZ1bmN0aW9uKCl7Qy52ZXJib3NlKFwiRm9yY2luZyBlbGVtZW50IHJlcGFpbnRcIik7dmFyIG49QS5wYXJlbnQoKSxlPUEubmV4dCgpOzA9PT1lLmxlbmd0aD9BLmRldGFjaCgpLmFwcGVuZFRvKG4pOkEuZGV0YWNoKCkuaW5zZXJ0QmVmb3JlKGUpfSxyZXBhaW50OmZ1bmN0aW9uKCl7Qy52ZXJib3NlKFwiUmVwYWludGluZyBlbGVtZW50XCIpO1Mub2Zmc2V0V2lkdGh9LGRlbGF5OmZ1bmN0aW9uKG4pe3ZhciBpLGEscj1DLmdldC5hbmltYXRpb25EaXJlY3Rpb24oKTtyfHwocj1DLmNhbi50cmFuc2l0aW9uKCk/Qy5nZXQuZGlyZWN0aW9uKCk6XCJzdGF0aWNcIiksbj1uIT09dD9uOmYuaW50ZXJ2YWwsaT1cImF1dG9cIj09Zi5yZXZlcnNlJiZyPT12Lm91dHdhcmQsYT1pfHwxPT1mLnJldmVyc2U/KG8ubGVuZ3RoLWUpKmYuaW50ZXJ2YWw6ZSpmLmludGVydmFsLEMuZGVidWcoXCJEZWxheWluZyBhbmltYXRpb24gYnlcIixhKSxzZXRUaW1lb3V0KEMuYW5pbWF0ZSxhKX0sYW5pbWF0ZTpmdW5jdGlvbihuKXtpZihmPW58fGYsIUMuaXMuc3VwcG9ydGVkKCkpcmV0dXJuIEMuZXJyb3IoZy5zdXBwb3J0KSwhMTtpZihDLmRlYnVnKFwiUHJlcGFyaW5nIGFuaW1hdGlvblwiLGYuYW5pbWF0aW9uKSxDLmlzLmFuaW1hdGluZygpKXtpZihmLnF1ZXVlKXJldHVybiFmLmFsbG93UmVwZWF0cyYmQy5oYXMuZGlyZWN0aW9uKCkmJkMuaXMub2NjdXJyaW5nKCkmJkMucXVldWluZyE9PSEwP0MuZGVidWcoXCJBbmltYXRpb24gaXMgY3VycmVudGx5IG9jY3VycmluZywgcHJldmVudGluZyBxdWV1ZWluZyBzYW1lIGFuaW1hdGlvblwiLGYuYW5pbWF0aW9uKTpDLnF1ZXVlKGYuYW5pbWF0aW9uKSwhMTtpZighZi5hbGxvd1JlcGVhdHMmJkMuaXMub2NjdXJyaW5nKCkpcmV0dXJuIEMuZGVidWcoXCJBbmltYXRpb24gaXMgYWxyZWFkeSBvY2N1cnJpbmcsIHdpbGwgbm90IGV4ZWN1dGUgcmVwZWF0ZWQgYW5pbWF0aW9uXCIsZi5hbmltYXRpb24pLCExO0MuZGVidWcoXCJOZXcgYW5pbWF0aW9uIHN0YXJ0ZWQsIGNvbXBsZXRpbmcgcHJldmlvdXMgZWFybHlcIixmLmFuaW1hdGlvbikscC5jb21wbGV0ZSgpfUMuY2FuLmFuaW1hdGUoKT9DLnNldC5hbmltYXRpbmcoZi5hbmltYXRpb24pOkMuZXJyb3IoZy5ub0FuaW1hdGlvbixmLmFuaW1hdGlvbixTKX0scmVzZXQ6ZnVuY3Rpb24oKXtDLmRlYnVnKFwiUmVzZXR0aW5nIGFuaW1hdGlvbiB0byBiZWdpbm5pbmcgY29uZGl0aW9uc1wiKSxDLnJlbW92ZS5hbmltYXRpb25DYWxsYmFja3MoKSxDLnJlc3RvcmUuY29uZGl0aW9ucygpLEMucmVtb3ZlLmFuaW1hdGluZygpfSxxdWV1ZTpmdW5jdGlvbihuKXtDLmRlYnVnKFwiUXVldWVpbmcgYW5pbWF0aW9uIG9mXCIsbiksQy5xdWV1aW5nPSEwLEEub25lKHkrXCIucXVldWVcIit3LGZ1bmN0aW9uKCl7Qy5xdWV1aW5nPSExLEMucmVwYWludCgpLEMuYW5pbWF0ZS5hcHBseSh0aGlzLGYpfSl9LGNvbXBsZXRlOmZ1bmN0aW9uKG4pe0MuZGVidWcoXCJBbmltYXRpb24gY29tcGxldGVcIixmLmFuaW1hdGlvbiksQy5yZW1vdmUuY29tcGxldGVDYWxsYmFjaygpLEMucmVtb3ZlLmZhaWxTYWZlKCksQy5pcy5sb29waW5nKCl8fChDLmlzLm91dHdhcmQoKT8oQy52ZXJib3NlKFwiQW5pbWF0aW9uIGlzIG91dHdhcmQsIGhpZGluZyBlbGVtZW50XCIpLEMucmVzdG9yZS5jb25kaXRpb25zKCksQy5oaWRlKCkpOkMuaXMuaW53YXJkKCk/KEMudmVyYm9zZShcIkFuaW1hdGlvbiBpcyBvdXR3YXJkLCBzaG93aW5nIGVsZW1lbnRcIiksQy5yZXN0b3JlLmNvbmRpdGlvbnMoKSxDLnNob3coKSk6KEMudmVyYm9zZShcIlN0YXRpYyBhbmltYXRpb24gY29tcGxldGVkXCIpLEMucmVzdG9yZS5jb25kaXRpb25zKCksZi5vbkNvbXBsZXRlLmNhbGwoUykpKX0sZm9yY2U6e3Zpc2libGU6ZnVuY3Rpb24oKXt2YXIgbj1BLmF0dHIoXCJzdHlsZVwiKSxlPUMuZ2V0LnVzZXJTdHlsZSgpLGk9Qy5nZXQuZGlzcGxheVR5cGUoKSxhPWUrXCJkaXNwbGF5OiBcIitpK1wiICFpbXBvcnRhbnQ7XCIsbz1BLmNzcyhcImRpc3BsYXlcIikscj1uPT09dHx8XCJcIj09PW47byE9PWk/KEMudmVyYm9zZShcIk92ZXJyaWRpbmcgZGVmYXVsdCBkaXNwbGF5IHRvIHNob3cgZWxlbWVudFwiLGkpLEEuYXR0cihcInN0eWxlXCIsYSkpOnImJkEucmVtb3ZlQXR0cihcInN0eWxlXCIpfSxoaWRkZW46ZnVuY3Rpb24oKXt2YXIgbj1BLmF0dHIoXCJzdHlsZVwiKSxlPUEuY3NzKFwiZGlzcGxheVwiKSxpPW49PT10fHxcIlwiPT09bjtcIm5vbmVcIj09PWV8fEMuaXMuaGlkZGVuKCk/aSYmQS5yZW1vdmVBdHRyKFwic3R5bGVcIik6KEMudmVyYm9zZShcIk92ZXJyaWRpbmcgZGVmYXVsdCBkaXNwbGF5IHRvIGhpZGUgZWxlbWVudFwiKSxBLmNzcyhcImRpc3BsYXlcIixcIm5vbmVcIikpfX0saGFzOntkaXJlY3Rpb246ZnVuY3Rpb24oZSl7dmFyIGk9ITE7cmV0dXJuIGU9ZXx8Zi5hbmltYXRpb24sXCJzdHJpbmdcIj09dHlwZW9mIGUmJihlPWUuc3BsaXQoXCIgXCIpLG4uZWFjaChlLGZ1bmN0aW9uKG4sZSl7KGU9PT12Lmlud2FyZHx8ZT09PXYub3V0d2FyZCkmJihpPSEwKX0pKSxpfSxpbmxpbmVEaXNwbGF5OmZ1bmN0aW9uKCl7dmFyIGU9QS5hdHRyKFwic3R5bGVcIil8fFwiXCI7cmV0dXJuIG4uaXNBcnJheShlLm1hdGNoKC9kaXNwbGF5Lio/Oy8sXCJcIikpfX0sc2V0OnthbmltYXRpbmc6ZnVuY3Rpb24obil7dmFyIGU7Qy5yZW1vdmUuY29tcGxldGVDYWxsYmFjaygpLG49bnx8Zi5hbmltYXRpb24sZT1DLmdldC5hbmltYXRpb25DbGFzcyhuKSxDLnNhdmUuYW5pbWF0aW9uKGUpLEMuZm9yY2UudmlzaWJsZSgpLEMucmVtb3ZlLmhpZGRlbigpLEMucmVtb3ZlLmRpcmVjdGlvbigpLEMuc3RhcnQuYW5pbWF0aW9uKGUpfSxkdXJhdGlvbjpmdW5jdGlvbihuLGUpe2U9ZXx8Zi5kdXJhdGlvbixlPVwibnVtYmVyXCI9PXR5cGVvZiBlP2UrXCJtc1wiOmUsKGV8fDA9PT1lKSYmKEMudmVyYm9zZShcIlNldHRpbmcgYW5pbWF0aW9uIGR1cmF0aW9uXCIsZSksQS5jc3Moe1wiYW5pbWF0aW9uLWR1cmF0aW9uXCI6ZX0pKX0sZGlyZWN0aW9uOmZ1bmN0aW9uKG4pe249bnx8Qy5nZXQuZGlyZWN0aW9uKCksbj09di5pbndhcmQ/Qy5zZXQuaW53YXJkKCk6Qy5zZXQub3V0d2FyZCgpfSxsb29waW5nOmZ1bmN0aW9uKCl7Qy5kZWJ1ZyhcIlRyYW5zaXRpb24gc2V0IHRvIGxvb3BcIiksQS5hZGRDbGFzcyh2Lmxvb3BpbmcpfSxoaWRkZW46ZnVuY3Rpb24oKXtBLmFkZENsYXNzKHYudHJhbnNpdGlvbikuYWRkQ2xhc3Modi5oaWRkZW4pfSxpbndhcmQ6ZnVuY3Rpb24oKXtDLmRlYnVnKFwiU2V0dGluZyBkaXJlY3Rpb24gdG8gaW53YXJkXCIpLEEucmVtb3ZlQ2xhc3Modi5vdXR3YXJkKS5hZGRDbGFzcyh2Lmlud2FyZCl9LG91dHdhcmQ6ZnVuY3Rpb24oKXtDLmRlYnVnKFwiU2V0dGluZyBkaXJlY3Rpb24gdG8gb3V0d2FyZFwiKSxBLnJlbW92ZUNsYXNzKHYuaW53YXJkKS5hZGRDbGFzcyh2Lm91dHdhcmQpfSx2aXNpYmxlOmZ1bmN0aW9uKCl7QS5hZGRDbGFzcyh2LnRyYW5zaXRpb24pLmFkZENsYXNzKHYudmlzaWJsZSl9fSxzdGFydDp7YW5pbWF0aW9uOmZ1bmN0aW9uKG4pe249bnx8Qy5nZXQuYW5pbWF0aW9uQ2xhc3MoKSxDLmRlYnVnKFwiU3RhcnRpbmcgdHdlZW5cIixuKSxBLmFkZENsYXNzKG4pLm9uZSh5K1wiLmNvbXBsZXRlXCIrdyxDLmNvbXBsZXRlKSxmLnVzZUZhaWxTYWZlJiZDLmFkZC5mYWlsU2FmZSgpLEMuc2V0LmR1cmF0aW9uKGYuZHVyYXRpb24pLGYub25TdGFydC5jYWxsKFMpfX0sc2F2ZTp7YW5pbWF0aW9uOmZ1bmN0aW9uKG4pe0MuY2FjaGV8fChDLmNhY2hlPXt9KSxDLmNhY2hlLmFuaW1hdGlvbj1ufSxkaXNwbGF5VHlwZTpmdW5jdGlvbihuKXtcIm5vbmVcIiE9PW4mJkEuZGF0YShiLmRpc3BsYXlUeXBlLG4pfSx0cmFuc2l0aW9uRXhpc3RzOmZ1bmN0aW9uKGUsaSl7bi5mbi50cmFuc2l0aW9uLmV4aXN0c1tlXT1pLEMudmVyYm9zZShcIlNhdmluZyBleGlzdGVuY2Ugb2YgdHJhbnNpdGlvblwiLGUsaSl9fSxyZXN0b3JlOntjb25kaXRpb25zOmZ1bmN0aW9uKCl7dmFyIG49Qy5nZXQuY3VycmVudEFuaW1hdGlvbigpO24mJihBLnJlbW92ZUNsYXNzKG4pLEMudmVyYm9zZShcIlJlbW92aW5nIGFuaW1hdGlvbiBjbGFzc1wiLEMuY2FjaGUpKSxDLnJlbW92ZS5kdXJhdGlvbigpfX0sYWRkOntmYWlsU2FmZTpmdW5jdGlvbigpe3ZhciBuPUMuZ2V0LmR1cmF0aW9uKCk7Qy50aW1lcj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7QS50cmlnZ2VySGFuZGxlcih5KX0sbitmLmZhaWxTYWZlRGVsYXkpLEMudmVyYm9zZShcIkFkZGluZyBmYWlsIHNhZmUgdGltZXJcIixDLnRpbWVyKX19LHJlbW92ZTp7YW5pbWF0aW5nOmZ1bmN0aW9uKCl7QS5yZW1vdmVDbGFzcyh2LmFuaW1hdGluZyl9LGFuaW1hdGlvbkNhbGxiYWNrczpmdW5jdGlvbigpe0MucmVtb3ZlLnF1ZXVlQ2FsbGJhY2soKSxDLnJlbW92ZS5jb21wbGV0ZUNhbGxiYWNrKCl9LHF1ZXVlQ2FsbGJhY2s6ZnVuY3Rpb24oKXtBLm9mZihcIi5xdWV1ZVwiK3cpfSxjb21wbGV0ZUNhbGxiYWNrOmZ1bmN0aW9uKCl7QS5vZmYoXCIuY29tcGxldGVcIit3KX0sZGlzcGxheTpmdW5jdGlvbigpe0EuY3NzKFwiZGlzcGxheVwiLFwiXCIpfSxkaXJlY3Rpb246ZnVuY3Rpb24oKXtBLnJlbW92ZUNsYXNzKHYuaW53YXJkKS5yZW1vdmVDbGFzcyh2Lm91dHdhcmQpfSxkdXJhdGlvbjpmdW5jdGlvbigpe0EuY3NzKFwiYW5pbWF0aW9uLWR1cmF0aW9uXCIsXCJcIil9LGZhaWxTYWZlOmZ1bmN0aW9uKCl7Qy52ZXJib3NlKFwiUmVtb3ZpbmcgZmFpbCBzYWZlIHRpbWVyXCIsQy50aW1lciksQy50aW1lciYmY2xlYXJUaW1lb3V0KEMudGltZXIpfSxoaWRkZW46ZnVuY3Rpb24oKXtBLnJlbW92ZUNsYXNzKHYuaGlkZGVuKX0sdmlzaWJsZTpmdW5jdGlvbigpe0EucmVtb3ZlQ2xhc3Modi52aXNpYmxlKX0sbG9vcGluZzpmdW5jdGlvbigpe0MuZGVidWcoXCJUcmFuc2l0aW9ucyBhcmUgbm8gbG9uZ2VyIGxvb3BpbmdcIiksQy5pcy5sb29waW5nKCkmJihDLnJlc2V0KCksQS5yZW1vdmVDbGFzcyh2Lmxvb3BpbmcpKX0sdHJhbnNpdGlvbjpmdW5jdGlvbigpe0EucmVtb3ZlQ2xhc3Modi52aXNpYmxlKS5yZW1vdmVDbGFzcyh2LmhpZGRlbil9fSxnZXQ6e3NldHRpbmdzOmZ1bmN0aW9uKGUsaSx0KXtyZXR1cm5cIm9iamVjdFwiPT10eXBlb2YgZT9uLmV4dGVuZCghMCx7fSxuLmZuLnRyYW5zaXRpb24uc2V0dGluZ3MsZSk6XCJmdW5jdGlvblwiPT10eXBlb2YgdD9uLmV4dGVuZCh7fSxuLmZuLnRyYW5zaXRpb24uc2V0dGluZ3Mse2FuaW1hdGlvbjplLG9uQ29tcGxldGU6dCxkdXJhdGlvbjppfSk6XCJzdHJpbmdcIj09dHlwZW9mIGl8fFwibnVtYmVyXCI9PXR5cGVvZiBpP24uZXh0ZW5kKHt9LG4uZm4udHJhbnNpdGlvbi5zZXR0aW5ncyx7YW5pbWF0aW9uOmUsZHVyYXRpb246aX0pOlwib2JqZWN0XCI9PXR5cGVvZiBpP24uZXh0ZW5kKHt9LG4uZm4udHJhbnNpdGlvbi5zZXR0aW5ncyxpLHthbmltYXRpb246ZX0pOlwiZnVuY3Rpb25cIj09dHlwZW9mIGk/bi5leHRlbmQoe30sbi5mbi50cmFuc2l0aW9uLnNldHRpbmdzLHthbmltYXRpb246ZSxvbkNvbXBsZXRlOml9KTpuLmV4dGVuZCh7fSxuLmZuLnRyYW5zaXRpb24uc2V0dGluZ3Mse2FuaW1hdGlvbjplfSl9LGFuaW1hdGlvbkNsYXNzOmZ1bmN0aW9uKG4pe3ZhciBlPW58fGYuYW5pbWF0aW9uLGk9Qy5jYW4udHJhbnNpdGlvbigpJiYhQy5oYXMuZGlyZWN0aW9uKCk/Qy5nZXQuZGlyZWN0aW9uKCkrXCIgXCI6XCJcIjtyZXR1cm4gdi5hbmltYXRpbmcrXCIgXCIrdi50cmFuc2l0aW9uK1wiIFwiK2krZX0sY3VycmVudEFuaW1hdGlvbjpmdW5jdGlvbigpe3JldHVybiBDLmNhY2hlJiZDLmNhY2hlLmFuaW1hdGlvbiE9PXQ/Qy5jYWNoZS5hbmltYXRpb246ITF9LGN1cnJlbnREaXJlY3Rpb246ZnVuY3Rpb24oKXtyZXR1cm4gQy5pcy5pbndhcmQoKT92Lmlud2FyZDp2Lm91dHdhcmR9LGRpcmVjdGlvbjpmdW5jdGlvbigpe3JldHVybiBDLmlzLmhpZGRlbigpfHwhQy5pcy52aXNpYmxlKCk/di5pbndhcmQ6di5vdXR3YXJkfSxhbmltYXRpb25EaXJlY3Rpb246ZnVuY3Rpb24oZSl7dmFyIGk7cmV0dXJuIGU9ZXx8Zi5hbmltYXRpb24sXCJzdHJpbmdcIj09dHlwZW9mIGUmJihlPWUuc3BsaXQoXCIgXCIpLG4uZWFjaChlLGZ1bmN0aW9uKG4sZSl7ZT09PXYuaW53YXJkP2k9di5pbndhcmQ6ZT09PXYub3V0d2FyZCYmKGk9di5vdXR3YXJkKX0pKSxpP2k6ITF9LGR1cmF0aW9uOmZ1bmN0aW9uKG4pe3JldHVybiBuPW58fGYuZHVyYXRpb24sbj09PSExJiYobj1BLmNzcyhcImFuaW1hdGlvbi1kdXJhdGlvblwiKXx8MCksXCJzdHJpbmdcIj09dHlwZW9mIG4/bi5pbmRleE9mKFwibXNcIik+LTE/cGFyc2VGbG9hdChuKToxZTMqcGFyc2VGbG9hdChuKTpufSxkaXNwbGF5VHlwZTpmdW5jdGlvbigpe3JldHVybiBmLmRpc3BsYXlUeXBlP2YuZGlzcGxheVR5cGU6KEEuZGF0YShiLmRpc3BsYXlUeXBlKT09PXQmJkMuY2FuLnRyYW5zaXRpb24oITApLEEuZGF0YShiLmRpc3BsYXlUeXBlKSl9LHVzZXJTdHlsZTpmdW5jdGlvbihuKXtyZXR1cm4gbj1ufHxBLmF0dHIoXCJzdHlsZVwiKXx8XCJcIixuLnJlcGxhY2UoL2Rpc3BsYXkuKj87LyxcIlwiKX0sdHJhbnNpdGlvbkV4aXN0czpmdW5jdGlvbihlKXtyZXR1cm4gbi5mbi50cmFuc2l0aW9uLmV4aXN0c1tlXX0sYW5pbWF0aW9uU3RhcnRFdmVudDpmdW5jdGlvbigpe3ZhciBuLGU9aS5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLGE9e2FuaW1hdGlvbjpcImFuaW1hdGlvbnN0YXJ0XCIsT0FuaW1hdGlvbjpcIm9BbmltYXRpb25TdGFydFwiLE1vekFuaW1hdGlvbjpcIm1vekFuaW1hdGlvblN0YXJ0XCIsV2Via2l0QW5pbWF0aW9uOlwid2Via2l0QW5pbWF0aW9uU3RhcnRcIn07Zm9yKG4gaW4gYSlpZihlLnN0eWxlW25dIT09dClyZXR1cm4gYVtuXTtyZXR1cm4hMX0sYW5pbWF0aW9uRW5kRXZlbnQ6ZnVuY3Rpb24oKXt2YXIgbixlPWkuY3JlYXRlRWxlbWVudChcImRpdlwiKSxhPXthbmltYXRpb246XCJhbmltYXRpb25lbmRcIixPQW5pbWF0aW9uOlwib0FuaW1hdGlvbkVuZFwiLE1vekFuaW1hdGlvbjpcIm1vekFuaW1hdGlvbkVuZFwiLFdlYmtpdEFuaW1hdGlvbjpcIndlYmtpdEFuaW1hdGlvbkVuZFwifTtmb3IobiBpbiBhKWlmKGUuc3R5bGVbbl0hPT10KXJldHVybiBhW25dO3JldHVybiExfX0sY2FuOnt0cmFuc2l0aW9uOmZ1bmN0aW9uKGUpe3ZhciBpLGEsbyxyLHMsbCx1LGM9Zi5hbmltYXRpb24sZD1DLmdldC50cmFuc2l0aW9uRXhpc3RzKGMpO2lmKGQ9PT10fHxlKXtpZihDLnZlcmJvc2UoXCJEZXRlcm1pbmluZyB3aGV0aGVyIGFuaW1hdGlvbiBleGlzdHNcIiksaT1BLmF0dHIoXCJjbGFzc1wiKSxhPUEucHJvcChcInRhZ05hbWVcIiksbz1uKFwiPFwiK2ErXCIgLz5cIikuYWRkQ2xhc3MoaSkuaW5zZXJ0QWZ0ZXIoQSkscj1vLmFkZENsYXNzKGMpLnJlbW92ZUNsYXNzKHYuaW53YXJkKS5yZW1vdmVDbGFzcyh2Lm91dHdhcmQpLmFkZENsYXNzKHYuYW5pbWF0aW5nKS5hZGRDbGFzcyh2LnRyYW5zaXRpb24pLmNzcyhcImFuaW1hdGlvbk5hbWVcIikscz1vLmFkZENsYXNzKHYuaW53YXJkKS5jc3MoXCJhbmltYXRpb25OYW1lXCIpLHU9by5hdHRyKFwiY2xhc3NcIixpKS5yZW1vdmVBdHRyKFwic3R5bGVcIikucmVtb3ZlQ2xhc3Modi5oaWRkZW4pLnJlbW92ZUNsYXNzKHYudmlzaWJsZSkuc2hvdygpLmNzcyhcImRpc3BsYXlcIiksQy52ZXJib3NlKFwiRGV0ZXJtaW5pbmcgZmluYWwgZGlzcGxheSBzdGF0ZVwiLHUpLEMuc2F2ZS5kaXNwbGF5VHlwZSh1KSxvLnJlbW92ZSgpLHIhPXMpQy5kZWJ1ZyhcIkRpcmVjdGlvbiBleGlzdHMgZm9yIGFuaW1hdGlvblwiLGMpLGw9ITA7ZWxzZXtpZihcIm5vbmVcIj09cnx8IXIpcmV0dXJuIHZvaWQgQy5kZWJ1ZyhcIk5vIGFuaW1hdGlvbiBkZWZpbmVkIGluIGNzc1wiLGMpO0MuZGVidWcoXCJTdGF0aWMgYW5pbWF0aW9uIGZvdW5kXCIsYyx1KSxsPSExfUMuc2F2ZS50cmFuc2l0aW9uRXhpc3RzKGMsbCl9cmV0dXJuIGQhPT10P2Q6bH0sYW5pbWF0ZTpmdW5jdGlvbigpe3JldHVybiBDLmNhbi50cmFuc2l0aW9uKCkhPT10fX0saXM6e2FuaW1hdGluZzpmdW5jdGlvbigpe3JldHVybiBBLmhhc0NsYXNzKHYuYW5pbWF0aW5nKX0saW53YXJkOmZ1bmN0aW9uKCl7cmV0dXJuIEEuaGFzQ2xhc3Modi5pbndhcmQpfSxvdXR3YXJkOmZ1bmN0aW9uKCl7cmV0dXJuIEEuaGFzQ2xhc3Modi5vdXR3YXJkKX0sbG9vcGluZzpmdW5jdGlvbigpe3JldHVybiBBLmhhc0NsYXNzKHYubG9vcGluZyl9LG9jY3VycmluZzpmdW5jdGlvbihuKXtyZXR1cm4gbj1ufHxmLmFuaW1hdGlvbixuPVwiLlwiK24ucmVwbGFjZShcIiBcIixcIi5cIiksQS5maWx0ZXIobikubGVuZ3RoPjB9LHZpc2libGU6ZnVuY3Rpb24oKXtyZXR1cm4gQS5pcyhcIjp2aXNpYmxlXCIpfSxoaWRkZW46ZnVuY3Rpb24oKXtyZXR1cm5cImhpZGRlblwiPT09QS5jc3MoXCJ2aXNpYmlsaXR5XCIpfSxzdXBwb3J0ZWQ6ZnVuY3Rpb24oKXtyZXR1cm4geSE9PSExfX0saGlkZTpmdW5jdGlvbigpe0MudmVyYm9zZShcIkhpZGluZyBlbGVtZW50XCIpLEMuaXMuYW5pbWF0aW5nKCkmJkMucmVzZXQoKSxTLmJsdXIoKSxDLnJlbW92ZS5kaXNwbGF5KCksQy5yZW1vdmUudmlzaWJsZSgpLEMuc2V0LmhpZGRlbigpLEMuZm9yY2UuaGlkZGVuKCksZi5vbkhpZGUuY2FsbChTKSxmLm9uQ29tcGxldGUuY2FsbChTKX0sc2hvdzpmdW5jdGlvbihuKXtDLnZlcmJvc2UoXCJTaG93aW5nIGVsZW1lbnRcIixuKSxDLnJlbW92ZS5oaWRkZW4oKSxDLnNldC52aXNpYmxlKCksQy5mb3JjZS52aXNpYmxlKCksZi5vblNob3cuY2FsbChTKSxmLm9uQ29tcGxldGUuY2FsbChTKX0sdG9nZ2xlOmZ1bmN0aW9uKCl7Qy5pcy52aXNpYmxlKCk/Qy5oaWRlKCk6Qy5zaG93KCl9LHN0b3A6ZnVuY3Rpb24oKXtDLmRlYnVnKFwiU3RvcHBpbmcgY3VycmVudCBhbmltYXRpb25cIiksQS50cmlnZ2VySGFuZGxlcih5KX0sc3RvcEFsbDpmdW5jdGlvbigpe0MuZGVidWcoXCJTdG9wcGluZyBhbGwgYW5pbWF0aW9uXCIpLEMucmVtb3ZlLnF1ZXVlQ2FsbGJhY2soKSxBLnRyaWdnZXJIYW5kbGVyKHkpfSxjbGVhcjp7cXVldWU6ZnVuY3Rpb24oKXtDLmRlYnVnKFwiQ2xlYXJpbmcgYW5pbWF0aW9uIHF1ZXVlXCIpLEMucmVtb3ZlLnF1ZXVlQ2FsbGJhY2soKX19LGVuYWJsZTpmdW5jdGlvbigpe0MudmVyYm9zZShcIlN0YXJ0aW5nIGFuaW1hdGlvblwiKSxBLnJlbW92ZUNsYXNzKHYuZGlzYWJsZWQpfSxkaXNhYmxlOmZ1bmN0aW9uKCl7Qy5kZWJ1ZyhcIlN0b3BwaW5nIGFuaW1hdGlvblwiKSxBLmFkZENsYXNzKHYuZGlzYWJsZWQpfSxzZXR0aW5nOmZ1bmN0aW9uKGUsaSl7aWYoQy5kZWJ1ZyhcIkNoYW5naW5nIHNldHRpbmdcIixlLGkpLG4uaXNQbGFpbk9iamVjdChlKSluLmV4dGVuZCghMCxmLGUpO2Vsc2V7aWYoaT09PXQpcmV0dXJuIGZbZV07ZltlXT1pfX0saW50ZXJuYWw6ZnVuY3Rpb24oZSxpKXtpZihuLmlzUGxhaW5PYmplY3QoZSkpbi5leHRlbmQoITAsQyxlKTtlbHNle2lmKGk9PT10KXJldHVybiBDW2VdO0NbZV09aX19LGRlYnVnOmZ1bmN0aW9uKCl7Zi5kZWJ1ZyYmKGYucGVyZm9ybWFuY2U/Qy5wZXJmb3JtYW5jZS5sb2coYXJndW1lbnRzKTooQy5kZWJ1Zz1GdW5jdGlvbi5wcm90b3R5cGUuYmluZC5jYWxsKGNvbnNvbGUuaW5mbyxjb25zb2xlLGYubmFtZStcIjpcIiksQy5kZWJ1Zy5hcHBseShjb25zb2xlLGFyZ3VtZW50cykpKX0sdmVyYm9zZTpmdW5jdGlvbigpe2YudmVyYm9zZSYmZi5kZWJ1ZyYmKGYucGVyZm9ybWFuY2U/Qy5wZXJmb3JtYW5jZS5sb2coYXJndW1lbnRzKTooQy52ZXJib3NlPUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmNhbGwoY29uc29sZS5pbmZvLGNvbnNvbGUsZi5uYW1lK1wiOlwiKSxDLnZlcmJvc2UuYXBwbHkoY29uc29sZSxhcmd1bWVudHMpKSl9LGVycm9yOmZ1bmN0aW9uKCl7Qy5lcnJvcj1GdW5jdGlvbi5wcm90b3R5cGUuYmluZC5jYWxsKGNvbnNvbGUuZXJyb3IsY29uc29sZSxmLm5hbWUrXCI6XCIpLEMuZXJyb3IuYXBwbHkoY29uc29sZSxhcmd1bWVudHMpfSxwZXJmb3JtYW5jZTp7bG9nOmZ1bmN0aW9uKG4pe3ZhciBlLGksdDtmLnBlcmZvcm1hbmNlJiYoZT0obmV3IERhdGUpLmdldFRpbWUoKSx0PXN8fGUsaT1lLXQscz1lLGwucHVzaCh7TmFtZTpuWzBdLEFyZ3VtZW50czpbXS5zbGljZS5jYWxsKG4sMSl8fFwiXCIsRWxlbWVudDpTLFwiRXhlY3V0aW9uIFRpbWVcIjppfSkpLGNsZWFyVGltZW91dChDLnBlcmZvcm1hbmNlLnRpbWVyKSxDLnBlcmZvcm1hbmNlLnRpbWVyPXNldFRpbWVvdXQoQy5wZXJmb3JtYW5jZS5kaXNwbGF5LDUwMCl9LGRpc3BsYXk6ZnVuY3Rpb24oKXt2YXIgZT1mLm5hbWUrXCI6XCIsaT0wO3M9ITEsY2xlYXJUaW1lb3V0KEMucGVyZm9ybWFuY2UudGltZXIpLG4uZWFjaChsLGZ1bmN0aW9uKG4sZSl7aSs9ZVtcIkV4ZWN1dGlvbiBUaW1lXCJdfSksZSs9XCIgXCIraStcIm1zXCIsciYmKGUrPVwiICdcIityK1wiJ1wiKSxvLmxlbmd0aD4xJiYoZSs9XCIgKFwiK28ubGVuZ3RoK1wiKVwiKSwoY29uc29sZS5ncm91cCE9PXR8fGNvbnNvbGUudGFibGUhPT10KSYmbC5sZW5ndGg+MCYmKGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoZSksY29uc29sZS50YWJsZT9jb25zb2xlLnRhYmxlKGwpOm4uZWFjaChsLGZ1bmN0aW9uKG4sZSl7Y29uc29sZS5sb2coZS5OYW1lK1wiOiBcIitlW1wiRXhlY3V0aW9uIFRpbWVcIl0rXCJtc1wiKX0pLGNvbnNvbGUuZ3JvdXBFbmQoKSksbD1bXX19LGludm9rZTpmdW5jdGlvbihlLGksbyl7dmFyIHIscyxsLHU9cDtyZXR1cm4gaT1pfHxkLG89U3x8byxcInN0cmluZ1wiPT10eXBlb2YgZSYmdSE9PXQmJihlPWUuc3BsaXQoL1tcXC4gXS8pLHI9ZS5sZW5ndGgtMSxuLmVhY2goZSxmdW5jdGlvbihpLGEpe3ZhciBvPWkhPXI/YStlW2krMV0uY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrZVtpKzFdLnNsaWNlKDEpOmU7aWYobi5pc1BsYWluT2JqZWN0KHVbb10pJiZpIT1yKXU9dVtvXTtlbHNle2lmKHVbb10hPT10KXJldHVybiBzPXVbb10sITE7aWYoIW4uaXNQbGFpbk9iamVjdCh1W2FdKXx8aT09cilyZXR1cm4gdVthXSE9PXQ/KHM9dVthXSwhMSk6ITE7dT11W2FdfX0pKSxuLmlzRnVuY3Rpb24ocyk/bD1zLmFwcGx5KG8saSk6cyE9PXQmJihsPXMpLG4uaXNBcnJheShhKT9hLnB1c2gobCk6YSE9PXQ/YT1bYSxsXTpsIT09dCYmKGE9bCkscyE9PXQ/czohMX19LEMuaW5pdGlhbGl6ZSgpfSksYSE9PXQ/YTp0aGlzfSxuLmZuLnRyYW5zaXRpb24uZXhpc3RzPXt9LG4uZm4udHJhbnNpdGlvbi5zZXR0aW5ncz17bmFtZTpcIlRyYW5zaXRpb25cIixkZWJ1ZzohMSx2ZXJib3NlOiExLHBlcmZvcm1hbmNlOiEwLG5hbWVzcGFjZTpcInRyYW5zaXRpb25cIixpbnRlcnZhbDowLHJldmVyc2U6XCJhdXRvXCIsb25TdGFydDpmdW5jdGlvbigpe30sb25Db21wbGV0ZTpmdW5jdGlvbigpe30sb25TaG93OmZ1bmN0aW9uKCl7fSxvbkhpZGU6ZnVuY3Rpb24oKXt9LHVzZUZhaWxTYWZlOiEwLGZhaWxTYWZlRGVsYXk6MTAwLGFsbG93UmVwZWF0czohMSxkaXNwbGF5VHlwZTohMSxhbmltYXRpb246XCJmYWRlXCIsZHVyYXRpb246ITEscXVldWU6ITAsbWV0YWRhdGE6e2Rpc3BsYXlUeXBlOlwiZGlzcGxheVwifSxjbGFzc05hbWU6e2FuaW1hdGluZzpcImFuaW1hdGluZ1wiLGRpc2FibGVkOlwiZGlzYWJsZWRcIixoaWRkZW46XCJoaWRkZW5cIixpbndhcmQ6XCJpblwiLGxvYWRpbmc6XCJsb2FkaW5nXCIsbG9vcGluZzpcImxvb3BpbmdcIixvdXR3YXJkOlwib3V0XCIsdHJhbnNpdGlvbjpcInRyYW5zaXRpb25cIix2aXNpYmxlOlwidmlzaWJsZVwifSxlcnJvcjp7bm9BbmltYXRpb246XCJFbGVtZW50IGlzIG5vIGxvbmdlciBhdHRhY2hlZCB0byBET00uIFVuYWJsZSB0byBhbmltYXRlLlwiLHJlcGVhdGVkOlwiVGhhdCBhbmltYXRpb24gaXMgYWxyZWFkeSBvY2N1cnJpbmcsIGNhbmNlbGxpbmcgcmVwZWF0ZWQgYW5pbWF0aW9uXCIsbWV0aG9kOlwiVGhlIG1ldGhvZCB5b3UgY2FsbGVkIGlzIG5vdCBkZWZpbmVkXCIsc3VwcG9ydDpcIlRoaXMgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IENTUyBhbmltYXRpb25zXCJ9fX0oalF1ZXJ5LHdpbmRvdyxkb2N1bWVudCk7IiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgUmVmbHV4LmNyZWF0ZUFjdGlvbnMoWyd0b2dnbGVGaWx0ZXInLCAnY2xlYXJGaWx0ZXJzJywgJ3VwZGF0ZUZpbHRlcnMnXSk7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IENhcnRBcGkgZnJvbSAnLi4vX2FwaS9jYXJ0X2FwaSc7XHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuXHJcbmxldCBDYXJ0QWN0aW9ucyA9IFJlZmx1eC5jcmVhdGVBY3Rpb25zKHtcclxuICAnbG9hZENhcnQnOiB7XHJcbiAgICBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ11cclxuICB9LFxyXG5cdCd1cGRhdGVDYXJ0SXRlbSc6IHt9LFxyXG5cdCdkZWxldGVDYXJ0SXRlbSc6IHt9LFxyXG4gICdjbGVhckNhcnQnOiB7fSxcclxuICAnYWRkQ2FydEl0ZW0nIDoge30sXHJcbiAgJ2FkZENhcnRJdGVtcycgOiB7fSxcclxuICAncXVpY2tCdXknIDoge30sXHJcbiAgJ3F1aWNrQnV5SXRlbXMnIDoge31cclxufSk7XHJcblxyXG5DYXJ0QWN0aW9ucy5sb2FkQ2FydC5saXN0ZW4oKG9uTW91bnQpID0+IHtcclxuICBDYXJ0QXBpLmNhcnRpdGVtcygpXHJcblx0XHQudGhlbigocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0Q2FydEFjdGlvbnMubG9hZENhcnQuY29tcGxldGVkKHJlc3BvbnNlKTtcclxuXHRcdFx0aWYob25Nb3VudCl7XHJcblx0XHRcdFx0bGV0IGNhcnQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XHJcblx0XHRcdFx0Q3VzdG9tRXZlbnRzLmxvYWRDYXJ0RXZlbnQoY2FydCk7XHJcblx0XHRcdH1cclxuICAgIH0pXHJcblx0XHQuY2F0Y2goQ2FydEFjdGlvbnMubG9hZENhcnQuZmFpbGVkKTtcclxufSk7XHJcblxyXG5DYXJ0QWN0aW9ucy51cGRhdGVDYXJ0SXRlbS5saXN0ZW4oKHNrdUlkLCBxdWFudGl0eSkgPT4ge1xyXG4gIENhcnRBcGkudXBkYXRlY2FydGl0ZW0oc2t1SWQsIHF1YW50aXR5KVxyXG4gICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdENhcnRBY3Rpb25zLmxvYWRDYXJ0LmNvbXBsZXRlZChyZXNwb25zZSwgc2t1SWQpO1xyXG5cdFx0XHRsZXQgY2FydCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpKTtcclxuICAgICAgQ3VzdG9tRXZlbnRzLm1vZGlmeUNhcnRFdmVudChjYXJ0KTtcclxuICAgIH0pXHJcbiAgICAvLyAudGhlbihDYXJ0QWN0aW9ucy5sb2FkQ2FydC5jb21wbGV0ZWQpXHJcblx0XHQuY2F0Y2goKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgIENhcnRBY3Rpb25zLmxvYWRDYXJ0LmZhaWxlZChza3VJZClcclxuICAgIH0pO1xyXG59KTtcclxuXHJcbkNhcnRBY3Rpb25zLmRlbGV0ZUNhcnRJdGVtLmxpc3RlbigoYXJncykgPT4ge1xyXG5cdENhcnRBcGkuZGVsZXRlY2FydGl0ZW0oYXJncylcclxuICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICBDYXJ0QWN0aW9ucy5sb2FkQ2FydC5jb21wbGV0ZWQocmVzcG9uc2UpO1xyXG5cdFx0XHRsZXQgZGVsZXRlSXRlbSAgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy5kZWxldGVDYXJ0RXZlbnQoZGVsZXRlSXRlbSk7XHJcbiAgICB9KVxyXG4gICAgLmNhdGNoKENhcnRBY3Rpb25zLmxvYWRDYXJ0LmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuQ2FydEFjdGlvbnMuY2xlYXJDYXJ0Lmxpc3RlbigoKSA9PiB7XHJcblx0Q2FydEFwaS5jbGVhcmNhcnQoKVxyXG4gICAgLnRoZW4oQ2FydEFjdGlvbnMubG9hZENhcnQuY29tcGxldGVkKVxyXG4gICAgLmNhdGNoKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICBDYXJ0QXBpLmNhcnRpdGVtcygpXHJcbiAgICAgICAgLnRoZW4oQ2FydEFjdGlvbnMubG9hZENhcnQuY29tcGxldGVkKVxyXG4gICAgICAgIC5jYXRjaChDYXJ0QWN0aW9ucy5sb2FkQ2FydC5mYWlsZWQpO1xyXG4gICAgfSk7XHJcbn0pO1xyXG5cclxuXHJcbkNhcnRBY3Rpb25zLmFkZENhcnRJdGVtLmxpc3Rlbigoc2t1SWQsIHF1YW50aXR5LCBwcm9kdWN0Q29udGV4dCkgPT4ge1xyXG4gIENhcnRBcGkuYWRkQ2FydEl0ZW0oc2t1SWQsIHF1YW50aXR5KVxyXG4gICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdENhcnRBY3Rpb25zLmxvYWRDYXJ0LmNvbXBsZXRlZChyZXNwb25zZSk7XHJcblx0XHRcdGxldCBhZGRlZCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuQWRkZWQpKTtcclxuXHRcdFx0bGV0IGNhcnQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLkNhcnQpKTtcclxuICAgICAgdHJpZ2dlckFkZFRvQ2FydEV2ZW50KGFkZGVkLCBjYXJ0LCBwcm9kdWN0Q29udGV4dCk7XHJcbiAgICB9KVxyXG4gICAgLmNhdGNoKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICBDYXJ0QWN0aW9ucy5sb2FkQ2FydC5mYWlsZWQocmVzcG9uc2UsIHNrdUlkKTtcclxuICAgIH0pO1xyXG4gICAgLy8gLmNhdGNoKENhcnRBY3Rpb25zLmxvYWRDYXJ0LmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuQ2FydEFjdGlvbnMuYWRkQ2FydEl0ZW1zLmxpc3RlbigoaXRlbXMpID0+IHtcclxuICBDYXJ0QXBpLmFkZENhcnRJdGVtcyhpdGVtcylcclxuICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICBDYXJ0QWN0aW9ucy5sb2FkQ2FydC5jb21wbGV0ZWQocmVzcG9uc2UpO1xyXG5cdFx0XHRsZXQgYWRkZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLkFkZGVkKSk7XHJcblx0XHRcdGxldCBjYXJ0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyZXNwb25zZS5DYXJ0KSk7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyQWRkVG9DYXJ0QmF0Y2hFdmVudChhZGRlZCwgY2FydCk7XHJcbiAgICB9KVxyXG4gICAgLmNhdGNoKCgpID0+IHtcclxuICAgICAgQ2FydEFjdGlvbnMubG9hZENhcnQuZmFpbGVkKClcclxuICAgIH0pO1xyXG59KTtcclxuQ2FydEFjdGlvbnMucXVpY2tCdXkubGlzdGVuKChza3VJZCwgcXVhbnRpdHksIHByb2R1Y3RDb250ZXh0KSA9PiB7XHJcbiAgQ2FydEFwaS5hZGRDYXJ0SXRlbShza3VJZCwgcXVhbnRpdHkpXHJcbiAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcblx0XHR3aW5kb3cubG9jYXRpb24uaHJlZiA9IGhpYWJjb25maWcucXVpY2tidXkudXJsO1xyXG5cdFx0bGV0IGFkZGVkID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyZXNwb25zZS5BZGRlZCkpO1xyXG5cdFx0bGV0IGNhcnQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLkNhcnQpKTtcclxuICAgIHRyaWdnZXJBZGRUb0NhcnRFdmVudChhZGRlZCwgY2FydCwgcHJvZHVjdENvbnRleHQpO1xyXG4gIH0pXHJcblx0LmNhdGNoKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0Q2FydEFjdGlvbnMubG9hZENhcnQuZmFpbGVkKHJlc3BvbnNlLCBza3VJZCk7XHJcblx0fSk7XHJcbn0pO1xyXG5DYXJ0QWN0aW9ucy5xdWlja0J1eUl0ZW1zLmxpc3RlbigoaXRlbXMpID0+IHtcclxuICBDYXJ0QXBpLmFkZENhcnRJdGVtcyhpdGVtcywgdHJ1ZSlcclxuICAudGhlbigocmVzcG9uc2UpID0+IHtcclxuXHRcdHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gaGlhYmNvbmZpZy5xdWlja2J1eS51cmw7XHJcblx0XHRsZXQgYWRkZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLkFkZGVkKSk7XHJcblx0XHRsZXQgY2FydCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuQ2FydCkpO1xyXG4gICAgQ3VzdG9tRXZlbnRzLnRyaWdnZXJRdWlja0J1eUJhdGNoRXZlbnQoYWRkZWQsIGNhcnQpO1xyXG4gIH0pXHJcbiAgLmNhdGNoKENhcnRBY3Rpb25zLmxvYWRDYXJ0LmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuLy8gVGhlIGxpc3Qgb2YgYWRkZWQgcHJvZHVjdHMgdGhhdCBpcyByZXR1cm5lZCB3aGVuIGFkZGluZyB0byBjYXJ0IGRvZXMgbm90IGNvbnRhaW5cclxuLy8gYW55IHByb2R1Y3QgaW5mb3JtYXRpb24uIEdldCBkZXRhaWxzIGZyb20gdGhlIGxpc3Qgb2YgYWxsIGNhcnQgaXRlbXMsIGJ1dCByZXRhaW5cclxuLy8gdGhlIHF1YW50aXR5IGZyb20gYGFkZGVkSXRlbXNgXHJcbmZ1bmN0aW9uIGdldEFkZGVkUHJvZHVjdHMoYWRkZWRJdGVtcywgYWxsSXRlbXMpIHtcclxuICByZXR1cm4gYWRkZWRJdGVtcy5tYXAoYWRkZWRJdGVtID0+IHtcclxuICAgIGxldCBzYW1lSXRlbUZyb21BbGxJdGVtcyA9IGFsbEl0ZW1zLmZpbHRlcih4ID0+IHguQ29kZSA9PSBhZGRlZEl0ZW0uQ29kZSkucG9wKCk7XHJcbiAgICBzYW1lSXRlbUZyb21BbGxJdGVtcy5RdWFudGl0eSA9IGFkZGVkSXRlbS5RdWFudGl0eTtcclxuICAgIHNhbWVJdGVtRnJvbUFsbEl0ZW1zLk9sZFF1YW50aXR5ID0gYWRkZWRJdGVtLk9sZFF1YW50aXR5O1xyXG4gICAgc2FtZUl0ZW1Gcm9tQWxsSXRlbXMuVXBkYXRlZCA9IGFkZGVkSXRlbS5VcGRhdGVkO1xyXG5cclxuICAgIHJldHVybiBzYW1lSXRlbUZyb21BbGxJdGVtcztcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZm9ybWF0UHJvZHVjdHNGb3JEYXRhTGF5ZXIocHJvZHVjdHMpIHtcclxuICByZXR1cm4gcHJvZHVjdHMubWFwKHAgPT4gKHtcclxuICAgICduYW1lJzogcC5EaXNwbGF5TmFtZSxcclxuICAgICdpZCc6IHAuQ29kZSxcclxuICAgICdwcmljZSc6IHAuUmF3UHJpY2UsXHJcbiAgICAncXVhbnRpdHknOiBwLlF1YW50aXR5XHJcbiAgfSkpO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0cmlnZ2VyQWRkVG9DYXJ0RXZlbnQoYWRkZWRJdGVtcywgY2FydCwgcHJvZHVjdENvbnRleHQpIHtcclxuICBpZih0eXBlb2Ygd2luZG93LmRhdGFMYXllciA9PT0gJ3VuZGVmaW5lZCcgJiYgIWhpYWJjb25maWcuRW5hYmxlR29vZ2xlVGFnTWFuYWdlcikgcmV0dXJuIGZhbHNlO1xyXG4gIHZhciBwcm9kdWN0cyA9IGdldEFkZGVkUHJvZHVjdHMoYWRkZWRJdGVtcywgY2FydC5DYXJ0SXRlbXMpO1xyXG4gIHdpbmRvdy5kYXRhTGF5ZXIucHVzaCh7XHJcbiAgICAnZXZlbnQnOiAnYWRkVG9DYXJ0JyxcclxuICAgICdlY29tbWVyY2UnOiB7XHJcbiAgICAgICdjdXJyZW5jeUNvZGUnOiBjYXJ0LkN1cnJlbmN5Q29kZSxcclxuICAgICAgJ2FkZCc6IGZvcm1hdFByb2R1Y3RzRm9yRGF0YUxheWVyKHByb2R1Y3RzKVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICBDdXN0b21FdmVudHMuYWRkVG9DYXJ0RXZlbnQocHJvZHVjdHMsIGNhcnQsIHByb2R1Y3RDb250ZXh0KTtcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2FydEFjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFJlZmx1eC5jcmVhdGVBY3Rpb25zKFsndG9nZ2xlRmlsdGVyJywgJ2NsZWFyRmlsdGVycycsICd1cGRhdGVGaWx0ZXJzJ10pO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBDaGVja291dEFwaSBmcm9tICcuLi9fYXBpL2NoZWNrb3V0X2FwaSc7XHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuL2NhcnRfYWN0aW9ucyc7XHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuXHJcbmxldCBDaGVja291dEFjdGlvbnMgPSBSZWZsdXguY3JlYXRlQWN0aW9ucyh7XHJcbiAgJ2xvYWRDaGVja291dCc6IHtcclxuICAgIGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXVxyXG4gIH0sXHJcbiAgJ3VwZGF0ZUNoZWNrb3V0Q2FydEl0ZW0nOiB7fSxcclxuICAnZGVsZXRlQ2hlY2tvdXRDYXJ0SXRlbSc6IHt9LFxyXG4gICd1cGRhdGVDaGVja291dENhcnRJdGVtQ3VzdG9tZXJDb21tZW50Jzoge30sXHJcbiAgJ3VwZGF0ZVNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eSc6IHt9LFxyXG4gIC8vICd1cGRhdGVTaGlwcGluZ09wdGlvbic6IHt9LFxyXG4gICd1cGRhdGVDb3VudHJ5Q29kZSc6IHt9LFxyXG59KTtcclxuXHJcbkNoZWNrb3V0QWN0aW9ucy5sb2FkQ2hlY2tvdXQubGlzdGVuKChhcmdzKSA9PiB7XHJcbiAgQ2hlY2tvdXRBcGkuZ2V0Q2hlY2tvdXQoYXJncylcclxuICAgIC50aGVuKENoZWNrb3V0QWN0aW9ucy5sb2FkQ2hlY2tvdXQuY29tcGxldGVkKVxyXG4gICAgLmNhdGNoKENoZWNrb3V0QWN0aW9ucy5sb2FkQ2hlY2tvdXQuZmFpbGVkKTtcclxufSk7XHJcblxyXG5DaGVja291dEFjdGlvbnMudXBkYXRlQ2hlY2tvdXRDYXJ0SXRlbS5saXN0ZW4oKHNrdUlkLCBxdWFudGl0eSkgPT4ge1xyXG4gIENoZWNrb3V0QXBpLnVwZGF0ZUNhcnRJdGVtUXVhbnRpdHkoc2t1SWQsIHF1YW50aXR5KVxyXG4gICAgLnRoZW4oKHJlcykgPT4ge1xyXG4gICAgICAvL0xvYWQgY2hlY2tvdXRcclxuICAgICAgQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5jb21wbGV0ZWQocmVzKTtcclxuXHJcbiAgICAgIC8vVHJpZ2dlciBsb2FkIGNhcnRcclxuICAgICAgQ2FydEFjdGlvbnMubG9hZENhcnQoKTtcclxuXHRcdFx0bGV0IGNoZWNrb3V0PSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlcykpO1xyXG4gICAgICBDdXN0b21FdmVudHMubW9kaWZ5Q2FydEV2ZW50RnJvbUNoZWNrb3V0KGNoZWNrb3V0KTtcclxuICAgIH0pXHJcbiAgICAuY2F0Y2goQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkNoZWNrb3V0QWN0aW9ucy5kZWxldGVDaGVja291dENhcnRJdGVtLmxpc3RlbigoYXJncykgPT4ge1xyXG5cdENoZWNrb3V0QXBpLmRlbGV0ZUNhcnRJdGVtKGFyZ3MpXHJcbiAgICAudGhlbigocmVzKSA9PiB7XHJcbiAgICAgIC8vTG9hZCBjaGVja291dFxyXG4gICAgICBDaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0LmNvbXBsZXRlZChyZXMpO1xyXG5cclxuICAgICAgLy9UcmlnZ2VyIGxvYWQgY2FydFxyXG4gICAgICBDYXJ0QWN0aW9ucy5sb2FkQ2FydCgpO1xyXG5cdFx0XHRsZXQgY2hlY2tvdXQ9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocmVzKSk7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy5tb2RpZnlDYXJ0RXZlbnRGcm9tQ2hlY2tvdXQoY2hlY2tvdXQpO1xyXG4gICAgfSlcclxuICAgIC5jYXRjaChDaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0LmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuQ2hlY2tvdXRBY3Rpb25zLnVwZGF0ZUNoZWNrb3V0Q2FydEl0ZW1DdXN0b21lckNvbW1lbnQubGlzdGVuKChpZCwgY29tbWVudCkgPT4ge1xyXG5cdENoZWNrb3V0QXBpLnVwZGF0ZUNhcnRJdGVtQ3VzdG9tZXJDb21tZW50KGlkLCBjb21tZW50KVxyXG4gICAgLnRoZW4oQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkNoZWNrb3V0QWN0aW9ucy51cGRhdGVTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkubGlzdGVuKChkYXRhKSA9PiB7XHJcbiAgQ2hlY2tvdXRBcGkudXBkYXRlU2hpcHBpbmdPcHRpb25PclByaW9yaXR5KGRhdGEpXHJcbiAgICAudGhlbigocmVzKSA9PiB7XHJcbiAgICAgIC8vTG9hZCBjaGVja291dFxyXG4gICAgICBDaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0LmNvbXBsZXRlZChyZXMpO1xyXG5cclxuICAgICAgLy9UcmlnZ2VyIGxvYWQgY2FydFxyXG4gICAgICBDYXJ0QWN0aW9ucy5sb2FkQ2FydCgpO1xyXG4gICAgfSlcclxuICAgIC5jYXRjaChDaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0LmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuXHJcbkNoZWNrb3V0QWN0aW9ucy51cGRhdGVDb3VudHJ5Q29kZS5saXN0ZW4oKGNvZGUpID0+IHtcclxuICBDaGVja291dEFwaS51cGRhdGVDb3VudHJ5Q29kZShjb2RlKVxyXG4gICAgLnRoZW4oKHJlcykgPT4ge1xyXG4gICAgICAvL0xvYWQgY2hlY2tvdXRcclxuICAgICAgQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5jb21wbGV0ZWQocmVzKTtcclxuXHJcbiAgICAgIC8vVHJpZ2dlciBsb2FkIGNhcnRcclxuICAgICAgQ2FydEFjdGlvbnMubG9hZENhcnQoKTtcclxuICAgIH0pXHJcbiAgICAuY2F0Y2goQ2hlY2tvdXRBY3Rpb25zLmxvYWRDaGVja291dC5mYWlsZWQpO1xyXG59KTtcclxuXHJcblxyXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEFjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IENoZWNrb3V0QXBpIGZyb20gJy4uL19hcGkvY2hlY2tvdXRfYXBpLW5ldyc7XHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuL2NhcnRfYWN0aW9ucyc7XHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuXHJcblxyXG5pbXBvcnQgQ2hlY2tvdXRDYXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydFRvdGFsU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X3RvdGFsX3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydEFsZXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X2FsZXJ0X3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydFdhcm5pbmdTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X2NhcnRfd2FybmluZ19zdG9yZSc7XHJcblxyXG5cclxuaW1wb3J0IENoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfZGFuZ2Vyb3VzX2dvb2RzX2FsZXJ0X3N0b3JlJztcclxuXHJcbmltcG9ydCBDaGVja291dFNoaXBwaW5nU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9zaGlwcGluZ19zdG9yZSc7XHJcbmltcG9ydCBDaGVja291dEFkZHJlc3Nlc1N0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfYWRkcmVzc2VzX3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0QmlsbGluZ1N0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfYmlsbGluZ19zdG9yZSc7XHJcbmltcG9ydCBDaGVja291dEFkZHJlc3Nlc0FsZXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9hZGRyZXNzZXNfYWxlcnRfc3RvcmUnO1xyXG5cclxuaW1wb3J0IENoZWNrb3V0U3VtbWFyeVN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfc3VtbWFyeV9zdG9yZSc7XHJcbmltcG9ydCBDaGVja291dFRyYWNraW5nRGF0YVN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfdHJhY2tpbmdfZGF0YV9zdG9yZSc7XHJcbmltcG9ydCBDaGVja291dExvYWRpbmdTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X2xvYWRpbmdfc3RvcmUnO1xyXG5cclxuaW1wb3J0IENoZWNrb3V0T3JkZXJTaW11bGF0aW9uU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9vcmRlcl9zaW11bGF0aW9uX3N0b3JlJztcclxuXHJcbmxldCBDaGVja291dEFjdGlvbnMgPSBSZWZsdXguY3JlYXRlQWN0aW9ucyh7XHJcbiAgJ2xvYWRDaGVja291dCc6IHtcclxuICAgIGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXVxyXG4gIH0sXHJcblx0J3NldENoZWNrb3V0Jzoge30sXHJcbiAgJ3VwZGF0ZUNoZWNrb3V0Q2FydEl0ZW0nOiB7fSxcclxuICAnZGVsZXRlQ2hlY2tvdXRDYXJ0SXRlbSc6IHt9LFxyXG4gICd1cGRhdGVDaGVja291dENhcnRJdGVtQ3VzdG9tZXJDb21tZW50Jzoge30sXHJcbiAgJ3VwZGF0ZVNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eSc6IHt9LFxyXG4gIC8vICd1cGRhdGVTaGlwcGluZ09wdGlvbic6IHt9LFxyXG4gICdjaGFuZ2VTaGlwcGluZ0FkZHJlc3MnOiB7fSxcclxuICAnY2hhbmdlQmlsbGluZ0FkZHJlc3MnOiB7fSxcclxuICAndXBkYXRlQ291bnRyeUNvZGUnOiB7fSxcclxuICAnc2ltdWxhdGVPcmRlcic6IHt9LFxyXG5cclxufSk7XHJcblxyXG5DaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0Lmxpc3RlbigoYXJncykgPT4ge1xyXG5cdENoZWNrb3V0QXBpLmdldENoZWNrb3V0KGFyZ3MpXHJcblx0LnRoZW4oKHJlcykgPT4ge1xyXG5cdH0pXHJcblx0LmNhdGNoKChyZXMpID0+IHtcclxuXHRcdC8vY29uc29sZS5sb2cocmVzKTtcclxuXHR9KTtcclxufSk7XHJcblxyXG5DaGVja291dEFjdGlvbnMuc2V0Q2hlY2tvdXQubGlzdGVuKChyZXMpID0+IHtcclxuXHQvL2NvbnNvbGUubG9nKHJlcyk7XHJcblx0aWYocmVzLlN1Y2Nlc3Mpe1xyXG5cdFx0Q2hlY2tvdXRMb2FkaW5nU3RvcmUuc2V0U3RvcmUoZmFsc2UpO1xyXG5cdH1lbHNle1xyXG5cdFx0Ly9oYXMgZXJyb3JcclxuXHRcdENoZWNrb3V0TG9hZGluZ1N0b3JlLnNldFN0b3JlKGZhbHNlKTtcclxuXHRcdC8vIGNvbnNvbGUubG9nKFwiZXJyb3JcIik7XHJcblx0XHRsb2NhdGlvbi5yZWxvYWQodHJ1ZSk7Ly8gcmVsb2FkIHBhZ2UgZnJvbSBzZXJ2ZXJcclxuXHR9XHJcblx0aWYocmVzLm9rKXtcclxuXHRcdC8vSGFzIGVycm9yXHJcblx0XHRDaGVja291dExvYWRpbmdTdG9yZS5zZXRTdG9yZShmYWxzZSk7XHJcblx0fVxyXG5cdGlmKHJlcy5DaGVja291dEh0bWwpe1xyXG5cdFx0bGV0IENoZWNrb3V0SHRtbFJlcyA9IHJlcy5DaGVja291dEh0bWw7XHJcblx0XHQvL0NBUlRcclxuXHRcdGlmKENoZWNrb3V0SHRtbFJlcy5DYXJ0TGluZUl0ZW1zKXtcclxuXHRcdFx0Q2hlY2tvdXRDYXJ0U3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLkNhcnRMaW5lSXRlbXMpO1xyXG5cdFx0fVxyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLkNhcnRUb3RhbCl7XHJcblx0XHRcdENoZWNrb3V0Q2FydFRvdGFsU3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLkNhcnRUb3RhbCk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLkNhcnRBbGVydCl7XHJcblx0XHRcdENoZWNrb3V0Q2FydEFsZXJ0U3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLkNhcnRBbGVydCk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0Q2hlY2tvdXRDYXJ0QWxlcnRTdG9yZS5zZXRTdG9yZSgnJyk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLkNhcnRXYXJuaW5ncyl7XHJcblx0XHRcdENoZWNrb3V0Q2FydFdhcm5pbmdTdG9yZS5zZXRTdG9yZShDaGVja291dEh0bWxSZXMuQ2FydFdhcm5pbmdzKTtcclxuXHRcdH1lbHNle1xyXG5cdFx0XHRDaGVja291dENhcnRXYXJuaW5nU3RvcmUuc2V0U3RvcmUoJycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vREFOR0VST1VTIEdPRFNcclxuXHRcdGlmKENoZWNrb3V0SHRtbFJlcy5TcGVjaWFsU2hpcHBpbmdIYW5kbGluZyl7XHJcblx0XHRcdENoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydFN0b3JlLnNldFN0b3JlKENoZWNrb3V0SHRtbFJlcy5TcGVjaWFsU2hpcHBpbmdIYW5kbGluZyk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0Q2hlY2tvdXREYW5nZXJvdXNHb29kc0FsZXJ0U3RvcmUuc2V0U3RvcmUoJycpO1xyXG5cdFx0fVxyXG5cdFx0Ly9TSElQUElOR1xyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLlNoaXBwaW5nQWRkcmVzc2VzKXtcclxuXHRcdFx0Q2hlY2tvdXRBZGRyZXNzZXNTdG9yZS5zZXRTdG9yZShDaGVja291dEh0bWxSZXMuU2hpcHBpbmdBZGRyZXNzZXMpO1xyXG5cdFx0fVxyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLkJpbGxpbmdJbmZvcm1hdGlvbil7XHJcblx0XHRcdENoZWNrb3V0QmlsbGluZ1N0b3JlLnNldFN0b3JlKENoZWNrb3V0SHRtbFJlcy5CaWxsaW5nSW5mb3JtYXRpb24pO1xyXG5cdFx0fVxyXG5cdFx0aWYoQ2hlY2tvdXRIdG1sUmVzLlNoaXBwaW5nQWRkcmVzc2VzQWxlcnQpe1xyXG5cdFx0XHRDaGVja291dEFkZHJlc3Nlc0FsZXJ0U3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLlNoaXBwaW5nQWRkcmVzc2VzQWxlcnQpO1xyXG5cdFx0fWVsc2V7XHJcblx0XHRcdENoZWNrb3V0QWRkcmVzc2VzQWxlcnRTdG9yZS5zZXRTdG9yZShcIlwiKTtcclxuXHRcdH1cclxuXHRcdGlmKENoZWNrb3V0SHRtbFJlcy5TaGlwcGluZ09wdGlvbnMpe1xyXG5cdFx0XHRDaGVja291dFNoaXBwaW5nU3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLlNoaXBwaW5nT3B0aW9ucyk7XHJcblx0XHR9XHJcblx0XHRpZihDaGVja291dEh0bWxSZXMuQ2hlY2tvdXRTdW1tYXJ5KXtcclxuXHRcdFx0Q2hlY2tvdXRTdW1tYXJ5U3RvcmUuc2V0U3RvcmUoQ2hlY2tvdXRIdG1sUmVzLkNoZWNrb3V0U3VtbWFyeSk7XHJcblx0XHR9XHJcblx0XHRpZihDaGVja291dEh0bWxSZXMuVHJhY2tpbmdEYXRhKXtcclxuXHRcdFx0Q2hlY2tvdXRUcmFja2luZ0RhdGFTdG9yZS5zZXRTdG9yZShDaGVja291dEh0bWxSZXMuVHJhY2tpbmdEYXRhKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG59KTtcclxuLy9OZXdcclxuQ2hlY2tvdXRBY3Rpb25zLnVwZGF0ZUNoZWNrb3V0Q2FydEl0ZW0ubGlzdGVuKChza3VJZCwgcXVhbnRpdHksIHVwZ3JhZGVkKSA9PiB7XHJcblx0Q2hlY2tvdXRMb2FkaW5nU3RvcmUuc2V0U3RvcmUodHJ1ZSk7XHJcbiAgQ2hlY2tvdXRBcGkudXBkYXRlQ2FydEl0ZW0oc2t1SWQsIHF1YW50aXR5LCB1cGdyYWRlZClcclxuICAgIC50aGVuKChyZXMpID0+IHtcclxuXHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnNldENoZWNrb3V0KHJlcyk7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy5tb2RpZnlDYXJ0RXZlbnRGcm9tQ2hlY2tvdXQocmVzKTtcclxuICAgIH0pXHJcbiAgICAuY2F0Y2goKHJlcykgPT4ge1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMuc2V0Q2hlY2tvdXQocmVzKTtcclxuXHRcdH0pO1xyXG59KTtcclxuXHJcbkNoZWNrb3V0QWN0aW9ucy5kZWxldGVDaGVja291dENhcnRJdGVtLmxpc3Rlbigoc2t1SWQpID0+IHtcclxuXHRDaGVja291dExvYWRpbmdTdG9yZS5zZXRTdG9yZSh0cnVlKTtcclxuXHRDaGVja291dEFwaS5kZWxldGVDYXJ0SXRlbShza3VJZClcclxuICAgIC50aGVuKChyZXMpID0+IHtcclxuXHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnNldENoZWNrb3V0KHJlcyk7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy5tb2RpZnlDYXJ0RXZlbnRGcm9tQ2hlY2tvdXQocmVzKTtcclxuICAgIH0pXHJcbiAgICAuY2F0Y2goKHJlcyk9PiB7XHJcblx0XHRcdENoZWNrb3V0QWN0aW9ucy5zZXRDaGVja291dChyZXMpO1xyXG5cdFx0fSk7XHJcbn0pO1xyXG5cclxuQ2hlY2tvdXRBY3Rpb25zLnVwZGF0ZVNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eS5saXN0ZW4oKGRhdGEpID0+IHtcclxuXHRDaGVja291dExvYWRpbmdTdG9yZS5zZXRTdG9yZSh0cnVlKTtcclxuICBDaGVja291dEFwaS51cGRhdGVTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkoZGF0YSlcclxuICAgIC50aGVuKChyZXMpID0+IHtcclxuXHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnNldENoZWNrb3V0KHJlcyk7XHJcbiAgICB9KVxyXG5cdFx0LmNhdGNoKChyZXMpPT4ge1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMuc2V0Q2hlY2tvdXQocmVzKTtcclxuXHRcdH0pO1xyXG59KTtcclxuXHJcbi8vTkVXXHJcbkNoZWNrb3V0QWN0aW9ucy5jaGFuZ2VTaGlwcGluZ0FkZHJlc3MubGlzdGVuKChpZCkgPT4ge1xyXG5cdENoZWNrb3V0TG9hZGluZ1N0b3JlLnNldFN0b3JlKHRydWUpO1xyXG4gIENoZWNrb3V0QXBpLmxvYWRTaGlwcGluZ0FkZHJlc3MoaWQpXHJcbiAgICAudGhlbigocmVzKSA9PiB7XHJcblx0XHRcdENoZWNrb3V0QWN0aW9ucy5zZXRDaGVja291dChyZXMpO1xyXG4gICAgfSlcclxuXHRcdC5jYXRjaCgocmVzKT0+IHtcclxuXHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnNldENoZWNrb3V0KHJlcyk7XHJcblx0XHR9KTtcclxufSk7XHJcbkNoZWNrb3V0QWN0aW9ucy5jaGFuZ2VCaWxsaW5nQWRkcmVzcy5saXN0ZW4oKGlkKSA9PiB7XHJcblx0Q2hlY2tvdXRMb2FkaW5nU3RvcmUuc2V0U3RvcmUodHJ1ZSk7XHJcbiAgQ2hlY2tvdXRBcGkubG9hZEJpbGxpbmdBZGRyZXNzKGlkKVxyXG4gICAgLnRoZW4oKHJlcykgPT4ge1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMuc2V0Q2hlY2tvdXQocmVzKTtcclxuICAgIH0pXHJcblx0XHQuY2F0Y2goKHJlcyk9PiB7XHJcblx0XHRcdENoZWNrb3V0QWN0aW9ucy5zZXRDaGVja291dChyZXMpO1xyXG5cdFx0fSk7XHJcbn0pO1xyXG5cclxuXHJcbkNoZWNrb3V0QWN0aW9ucy51cGRhdGVDb3VudHJ5Q29kZS5saXN0ZW4oKHNoaXBwaW5nQWRkcmVzcykgPT4ge1xyXG5cdENoZWNrb3V0TG9hZGluZ1N0b3JlLnNldFN0b3JlKHRydWUpO1xyXG4gIENoZWNrb3V0QXBpLnVwZGF0ZUNvdW50cnlDb2RlKHNoaXBwaW5nQWRkcmVzcylcclxuICAgIC50aGVuKChyZXMpID0+IHtcclxuXHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnNldENoZWNrb3V0KHJlcyk7XHJcbiAgICB9KVxyXG5cdFx0LmNhdGNoKChyZXMpPT4ge1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMuc2V0Q2hlY2tvdXQocmVzKTtcclxuXHRcdH0pO1xyXG59KTtcclxuXHJcbkNoZWNrb3V0QWN0aW9ucy5zaW11bGF0ZU9yZGVyLmxpc3RlbigodG9rZW4sIGFkZHJlc3NlcywgY29zdCkgPT4ge1xyXG5cdENoZWNrb3V0TG9hZGluZ1N0b3JlLnNldFN0b3JlKHRydWUpO1xyXG5cclxuICBDaGVja291dEFwaS5vcmRlclNpbXVsYXRpb24odG9rZW4sIGFkZHJlc3NlcywgY29zdClcclxuICAgIC50aGVuKChyZXMpID0+IHtcclxuXHRcdFx0Q2hlY2tvdXRPcmRlclNpbXVsYXRpb25TdG9yZS5zZXRTdG9yZShyZXMpO1xyXG5cdFx0XHRDaGVja291dExvYWRpbmdTdG9yZS5zZXRTdG9yZShmYWxzZSk7XHJcbiAgICB9KVxyXG5cdFx0LmNhdGNoKChyZXMpPT4ge1xyXG5cdFx0XHRDaGVja291dE9yZGVyU2ltdWxhdGlvblN0b3JlLnNldFN0b3JlKHJlcyk7XHJcblx0XHRcdENoZWNrb3V0TG9hZGluZ1N0b3JlLnNldFN0b3JlKGZhbHNlKTtcclxuXHRcdH0pO1xyXG59KTtcclxuXHJcblxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRBY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcblxyXG5sZXQgSGlzdG9yeUFjdGlvbnMgPSBSZWZsdXguY3JlYXRlQWN0aW9ucyh7XHJcbiAgJ3N0b3JlVXBkYXRlZCc6IHt9XHJcbn0pO1xyXG5cclxuSGlzdG9yeUFjdGlvbnMuc3RvcmVVcGRhdGVkLmxpc3RlbigoYXJncykgPT4ge1xyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEhpc3RvcnlBY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBJbGx1c3RyYXRpb25BcGkgZnJvbSAnLi4vX2FwaS9pbGx1c3RyYXRpb25fYXBpJztcclxuaW1wb3J0IElsbHVzdHJhdGlvbkZvck92ZXJsYXlBcGkgZnJvbSAnLi4vX2FwaS9pbGx1c3RyYXRpb25Gb3JPdmVybGF5X2FwaSc7XHJcblxyXG5sZXQgSWxsdXN0cmF0aW9uQWN0aW9ucyA9IFJlZmx1eC5jcmVhdGVBY3Rpb25zKHtcclxuICAnbG9hZElsbHVzdHJhdGlvbic6IHtcclxuICAgIGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXVxyXG4gIH0sXHJcbiAgJ2xvYWRJbGx1c3RyYXRpb25Gb3JPdmVybGF5Jzoge1xyXG4gICAgY2hpbGRyZW46IFsnY29tcGxldGVkJywgJ2ZhaWxlZCddXHJcbiAgfVxyXG59KTtcclxuXHJcbklsbHVzdHJhdGlvbkFjdGlvbnMubG9hZElsbHVzdHJhdGlvbi5saXN0ZW4oKGlsbHVzdHJhdGlvbklkLG1vZGVsSWQpID0+IHtcclxuXHQvLyBjb25zb2xlLmxvZyhpbGx1c3RyYXRpb25JZCsnICcrbW9kZWxJZCk7XHJcbiAgSWxsdXN0cmF0aW9uQXBpLmdldElsbHVzdHJhdGlvbihpbGx1c3RyYXRpb25JZCxtb2RlbElkKVxyXG4gICAgLnRoZW4oSWxsdXN0cmF0aW9uQWN0aW9ucy5sb2FkSWxsdXN0cmF0aW9uLmNvbXBsZXRlZClcclxuICAgIC5jYXRjaChJbGx1c3RyYXRpb25BY3Rpb25zLmxvYWRJbGx1c3RyYXRpb24uZmFpbGVkKTtcclxufSk7XHJcblxyXG5JbGx1c3RyYXRpb25BY3Rpb25zLmxvYWRJbGx1c3RyYXRpb25Gb3JPdmVybGF5Lmxpc3RlbigoYXJncywgbm9kZVR5cGUpID0+IHtcclxuICBJbGx1c3RyYXRpb25Gb3JPdmVybGF5QXBpLmdldElsbHVzdHJhdGlvbihhcmdzLCBub2RlVHlwZSlcclxuICAgIC50aGVuKElsbHVzdHJhdGlvbkFjdGlvbnMubG9hZElsbHVzdHJhdGlvbkZvck92ZXJsYXkuY29tcGxldGVkKVxyXG4gICAgLmNhdGNoKElsbHVzdHJhdGlvbkFjdGlvbnMubG9hZElsbHVzdHJhdGlvbkZvck92ZXJsYXkuZmFpbGVkKTtcclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJbGx1c3RyYXRpb25BY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBNb2RlbFNlYXJjaEFwaSBmcm9tICcuLi9fYXBpL21vZGVsc2VhcmNoX2FwaSc7XHJcblxyXG5sZXQgTW9kZWxTZWFyY2hBY3Rpb25zID0gUmVmbHV4LmNyZWF0ZUFjdGlvbnMoe1xyXG4gICdsb2FkTW9kZWwnOiB7XHJcbiAgICBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ11cclxuICB9XHJcbn0pO1xyXG5cclxuTW9kZWxTZWFyY2hBY3Rpb25zLmxvYWRNb2RlbC5saXN0ZW4oKGFyZ3MpID0+IHtcclxuICBNb2RlbFNlYXJjaEFwaS5zZWFyY2goYXJncylcclxuICAgIC50aGVuKE1vZGVsU2VhcmNoQWN0aW9ucy5sb2FkTW9kZWwuY29tcGxldGVkKVxyXG4gICAgLmNhdGNoKE1vZGVsU2VhcmNoQWN0aW9ucy5sb2FkTW9kZWwuZmFpbGVkKTtcclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBNb2RlbFNlYXJjaEFjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IE9yZGVyTGluZXNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL29yZGVybGluZXNfc3RvcmUnO1xyXG5pbXBvcnQgQ3VzdG9tRXZlbnRzIGZyb20gJy4uL19saWIvY3VzdG9tLWV2ZW50cyc7XHJcblxyXG5sZXQgT3JkZXJMaW5lc0FjdGlvbnMgPSBSZWZsdXguY3JlYXRlQWN0aW9ucyh7XHJcbiAgJ2FkZCc6IHt9LFxyXG5cdCdjbGVhcic6IHt9LFxyXG5cdCdyZW1vdmVPcmRlckxpbmUnOiB7fVxyXG59KTtcclxuXHJcbk9yZGVyTGluZXNBY3Rpb25zLmFkZC5saXN0ZW4oKGlkLCBvcmRlcmxpbmUpID0+IHtcclxuXHRPcmRlckxpbmVzU3RvcmUuYWRkKGlkLCBvcmRlcmxpbmUpO1xyXG4gIEN1c3RvbUV2ZW50cy5iYXRjaEFkZFJvdyhvcmRlcmxpbmUpO1xyXG59KTtcclxuXHJcbk9yZGVyTGluZXNBY3Rpb25zLmNsZWFyLmxpc3RlbigoKSA9PiB7XHJcblx0T3JkZXJMaW5lc1N0b3JlLmNsZWFyKCk7XHJcbn0pO1xyXG5cclxuT3JkZXJMaW5lc0FjdGlvbnMucmVtb3ZlT3JkZXJMaW5lLmxpc3RlbigoaWQpID0+IHtcclxuXHRPcmRlckxpbmVzU3RvcmUucmVtb3ZlT3JkZXJMaW5lKGlkKTtcclxuICBDdXN0b21FdmVudHMuYmF0Y2hSZW1vdmVSb3coaWQpO1xyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IE9yZGVyTGluZXNBY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xyXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwcm9taXNlJztcclxuaW1wb3J0IFByaWNlU2VydmljZVN0b3JlIGZyb20gJy4uL19zdG9yZXMvcHJpY2Vfc2VydmljZV9zdG9yZS5qcyc7XHJcblxyXG5sZXQgUHJpY2VTZXJ2aWNlQWN0aW9ucyA9IFJlZmx1eC5jcmVhdGVBY3Rpb25zKHtcclxuXHQnYWRkTWF0ZXJpYWxzJyA6IHt9LFxyXG5cdCdhYm9ydEZldGNoUHJpY2VzJyA6IHt9LFxyXG5cdCdmZXRjaFByaWNlcycgOiB7fVxyXG59KTtcclxuXHJcbmxldCBtYXRlcmlhbFRvUmVxdWVzdCA9IFtdO1xyXG5sZXQgY3VycmVudFJlcXVlc3QgPSBudWxsO1xyXG5cclxuUHJpY2VTZXJ2aWNlQWN0aW9ucy5hZGRNYXRlcmlhbHMubGlzdGVuKChtYXRlcmlhbCkgPT4ge1xyXG5cdG1hdGVyaWFsVG9SZXF1ZXN0LnB1c2gobWF0ZXJpYWwpO1xyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGxvb3BWYXJpYW50cyhhbGxNYXRlcmlhbHMsIGJhdGNoU2l6ZSl7XHJcblx0aWYgKGFsbE1hdGVyaWFscy5sZW5ndGggPiBiYXRjaFNpemUgKiA1IClcclxuXHRcdGJhdGNoU2l6ZSA9IE1hdGguY2VpbChhbGxNYXRlcmlhbHMubGVuZ3RoIC8gNSlcclxuXHRcclxuXHRsZXQgbWF0ZXJpYWxCYXRjaCA9IFtdO1xyXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgYmF0Y2hTaXplOyBpKyspIHtcclxuXHRcdFx0bWF0ZXJpYWxCYXRjaC5wdXNoKGFsbE1hdGVyaWFscy5zaGlmdCgpKTtcclxuXHRcdFx0aWYgKG1hdGVyaWFsQmF0Y2gubGVuZ3RoID09IGJhdGNoU2l6ZSB8fCBhbGxNYXRlcmlhbHMubGVuZ3RoID09PSAwKSB7XHJcblx0XHRcdFx0XHRtYWtlQWpheENhbGwobWF0ZXJpYWxCYXRjaCk7XHJcblx0XHRcdFx0XHRpZiAoYWxsTWF0ZXJpYWxzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHRsb29wVmFyaWFudHMoYWxsTWF0ZXJpYWxzLCBiYXRjaFNpemUpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChhbGxNYXRlcmlhbHMubGVuZ3RoIDw9IDApIHtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBtYWtlQWpheENhbGwobWF0ZXJpYWxzKXtcclxuXHJcblx0aWYobWF0ZXJpYWxzLmxlbmd0aCA8PSAwKXtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdGxldCB1cmwgPSAnL2FwaS9wcm9kdWN0aW5mb3JtYXRpb24vcHJvZHVjdGluZm8/Y29kZXM9JyArIG1hdGVyaWFscy5qb2luKFwiJmNvZGVzPVwiKSArICcnO1xyXG5cdFx0Y3VycmVudFJlcXVlc3QgPSByZXF1ZXN0XHJcblx0XHRcdC5nZXQodXJsKVxyXG5cdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdC5zZXQoJ2NyZWRlbnRpYWxzJywgJ3NhbWUtb3JpZ2luJylcclxuXHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0aWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdFByaWNlU2VydmljZVN0b3JlLmFkZFByaWNlcyhyZXNwb25zZS5ib2R5KTtcclxuXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdFx0UHJpY2VTZXJ2aWNlU3RvcmUuaGFuZGxlRXJyb3IobWF0ZXJpYWxzKTtcclxuXHRcdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9KTtcclxufVxyXG5cclxuUHJpY2VTZXJ2aWNlQWN0aW9ucy5mZXRjaFByaWNlcy5saXN0ZW4oKGJhdGNoU2l6ZSkgPT57XHJcblx0Ly8gY29uc29sZS5sb2coJ2ZldGNoUHJpY2VzJyk7XHJcblx0aWYobWF0ZXJpYWxUb1JlcXVlc3QubGVuZ3RoID4gMCl7XHJcblx0XHRsb29wVmFyaWFudHMobWF0ZXJpYWxUb1JlcXVlc3QsIGJhdGNoU2l6ZSk7XHJcblx0XHQvLyBjb25zb2xlLmxvZygnZmV0Y2hQcmljZXMtMycpO1xyXG5cdH1cclxufSk7XHJcblxyXG5QcmljZVNlcnZpY2VBY3Rpb25zLmFib3J0RmV0Y2hQcmljZXMubGlzdGVuKCgpID0+e1xyXG5cdGN1cnJlbnRSZXF1ZXN0LmFib3J0KClcclxufSk7XHJcbmV4cG9ydCBkZWZhdWx0IFByaWNlU2VydmljZUFjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFJlZmx1eC5jcmVhdGVBY3Rpb25zKFsndG9nZ2xlRmlsdGVyJywgJ29uQ2xlYXJGaWx0ZXJzJywgJ3VwZGF0ZUZpbHRlcnMnXSk7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IEN1c3RvbUV2ZW50cyBmcm9tICcuLi9fbGliL2N1c3RvbS1ldmVudHMnO1xyXG5pbXBvcnQgUmVjb21tZW5kYXRpb25zQXBpIGZyb20gJy4uL19hcGkvc2FsZXNmb3JjZV9yZWNvbW1lbmRhdGlvbnNfYXBpJztcclxuXHJcbmltcG9ydCBMaXN0IGZyb20gJy4uL3NhbGVzZm9yY2VyZWNvbW1lbmRhdGlvbnMvbGlzdCc7XHJcbmltcG9ydCBTbGlkZXIgZnJvbSAnLi4vc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9zbGlkZXInO1xyXG5cclxubGV0IFJlY29tbWVuZGF0aW9uc0FjdGlvbnMgPSBSZWZsdXguY3JlYXRlQWN0aW9ucyh7XHJcbiAgJ2xvYWRSZWNvbW1lbmRhdGlvbnMnOiB7XHJcbiAgICBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ11cclxuICB9LFxyXG4gICdyZW5kZXJSZWNvbW1lbmRhdGlvbnMnIDogIHt9LFxyXG59KTtcclxuXHJcblJlY29tbWVuZGF0aW9uc0FjdGlvbnMubG9hZFJlY29tbWVuZGF0aW9ucy5saXN0ZW4oKHJlY29tbWVuZGF0aW9uUmVxdWVzdCkgPT4ge1xyXG4gIFJlY29tbWVuZGF0aW9uc0FwaS5mZXRjaFJlY29tbWVuZGF0aW9ucyhyZWNvbW1lbmRhdGlvblJlcXVlc3QpXHJcblx0XHQudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgICAgUmVjb21tZW5kYXRpb25zQWN0aW9ucy5yZW5kZXJSZWNvbW1lbmRhdGlvbnMocmVzcG9uc2UpO1xyXG5cdFx0XHRSZWNvbW1lbmRhdGlvbnNBY3Rpb25zLmxvYWRSZWNvbW1lbmRhdGlvbnMuY29tcGxldGVkKHJlc3BvbnNlKTtcclxuICAgIH0pXHJcblx0XHQuY2F0Y2goUmVjb21tZW5kYXRpb25zQWN0aW9ucy5sb2FkUmVjb21tZW5kYXRpb25zLmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuUmVjb21tZW5kYXRpb25zQWN0aW9ucy5yZW5kZXJSZWNvbW1lbmRhdGlvbnMubGlzdGVuKChyZXNwb25zZSkgPT4ge1xyXG4gIGlmIChyZXNwb25zZSA9PSBudWxsKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlmKHJlc3BvbnNlLlJlY29tbWVuZGF0aW9ucyA9PSBudWxsKSB7XHJcbiAgICAgICQoXCIucHJvZHVjdC1yZWNvbW1lbmRhdGlvbnMuXCIgKyByZXNwb25zZS5JZCkuaGlkZSgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlmIChyZXNwb25zZS5CbG9ja1N0eWxlID09ICdsaXN0JyB8fCByZXNwb25zZS5CbG9ja1N0eWxlID09ICdsaXN0LWNvbGxhcHNlZCcpIHtcclxuICAgICAgJChcIiNcIiArIHJlc3BvbnNlLklkKS5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgUmVhY3RET00ucmVuZGVyKDxMaXN0IHJlc3BvbnNlPXtyZXNwb25zZX0gLz4sIHRoaXMpO1xyXG4gICAgICAgIGlmKHJlc3BvbnNlLkJsb2NrU3R5bGUgPT0gJ2xpc3QtY29sbGFwc2VkJyAmJiByZXNwb25zZS5SZWNvbW1lbmRhdGlvbnMubGVuZ3RoID09PSAxKXtcclxuICAgICAgICAgICQoXCIucHJvZHVjdC1yZWNvbW1lbmRhdGlvbnMuXCIgKyByZXNwb25zZS5JZCArIFwiIC5jb2xsYXBzZS13cmFwcGVyLnJvd1wiKS5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9ZWxzZSBpZiAocmVzcG9uc2UuQmxvY2tTdHlsZSA9PSAnc2xpZGVyJyB8fCByZXNwb25zZS5CbG9ja1N0eWxlID09ICdjb25kZW5zZWQtc2xpZGVyJykge1xyXG4gICAgICAkKFwiI1wiICsgcmVzcG9uc2UuSWQpLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICAkKCcjJyArIHJlc3BvbnNlLklkKS5yZW1vdmVDbGFzcygnbG9hZC1za2VsZXRvbi1zbGlkZXInKTtcclxuICAgICAgICBSZWFjdERPTS5yZW5kZXIoPFNsaWRlciByZXNwb25zZT17cmVzcG9uc2V9IC8+LCB0aGlzKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFJlY29tbWVuZGF0aW9uc0FjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcblxyXG5pbXBvcnQgQnJhbmRGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2JyYW5kX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IFVzYWdlVHlwZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvdXNhZ2VfdHlwZV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBDYXRlZ29yeUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2F0ZWdvcnlfZmlsdGVyX2FjdGlvbnMnO1xyXG5pbXBvcnQgVG9wQ2F0ZWdvcnlGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3RvcF9jYXRlZ29yeV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBQcm9kdWN0TGluZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvcHJvZHVjdF9saW5lX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IFNlcmlhbE51bWJlckZpbHRlckFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvc2VyaWFsX251bWJlcl9maWx0ZXJfYWN0aW9ucyc7XHJcblxyXG5pbXBvcnQgQnJhbmRGaWx0ZXJTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2JyYW5kX2ZpbHRlcl9zdG9yZSc7XHJcbmltcG9ydCBVc2FnZVR5cGVGaWx0ZXJTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3VzYWdlX3R5cGVfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IENhdGVnb3J5RmlsdGVyU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jYXRlZ29yeV9maWx0ZXJfc3RvcmUnO1xyXG5pbXBvcnQgQ3VzdG9tU2VhcmNoRXZlbnRzIGZyb20gJy4uL19saWIvY3VzdG9tLXNlYXJjaC1ldmVudHMnO1xyXG5pbXBvcnQgVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3RvcF9jYXRlZ29yeV9maWx0ZXJfc3RvcmUnO1xyXG5pbXBvcnQgUHJvZHVjdExpbmVGaWx0ZXJTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3Byb2R1Y3RfbGluZV9maWx0ZXJfc3RvcmUnO1xyXG5pbXBvcnQgU2VyaWFsTnVtYmVyRmlsdGVyU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9zZXJpYWxfbnVtYmVyX2ZpbHRlcl9zdG9yZSc7XHJcblxyXG5jb25zdCB3YWl0aW5nRm9yQW5vdGhlckNoZWNrID0gIDEwMDA7XHJcbmxldCBmaWx0ZXJUaW1lciA9IG51bGw7XHJcbmxldCBjdXJyZW50UmVxdWVzdCA9IG51bGw7XHJcblxyXG5sZXQgU2VhcmNoQWN0aW9ucyA9IFJlZmx1eC5jcmVhdGVBY3Rpb25zKHtcclxuICBpbnZhbGlkYXRlOiB7IGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXSB9LFxyXG4gIGludmFsaWRhdGVTcGFyZVBhcnRzOiB7IGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXSB9LFxyXG4gIGxvYWROZXh0UGFnZTogeyBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ10gfSxcclxuICBzZXRRdWVyeToge30sXHJcbiAgc2V0UXVlcnlUb1VybDoge31cclxufSk7XHJcblxyXG5cclxuXHJcbmxldCBmZXRjaFNlYXJjaFJlc3VsdHMgPSAoYmFzZVVybCwgc2VhcmNoT3B0aW9ucykgPT4ge1xyXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICBpZiAoY3VycmVudFJlcXVlc3QgIT0gbnVsbCkge1xyXG4gICAgICBjdXJyZW50UmVxdWVzdC5hYm9ydCgpO1xyXG4gICAgfVxyXG4gICAgLy8gY29uc29sZS5sb2coc2VhcmNoT3B0aW9ucyk7XHJcbiAgICBzZWFyY2hPcHRpb25zWydlcHNMYW5ndWFnZSddID0gaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlO1xyXG4gICAgY3VycmVudFJlcXVlc3QgPSByZXF1ZXN0XHJcbiAgICAgIC5nZXQoYmFzZVVybClcclxuICAgICAgLnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcbiAgICAgIC5xdWVyeShzZWFyY2hPcHRpb25zKVxyXG4gICAgICAuZW5kKChlcnIsIHJlcykgPT4ge1xyXG4gICAgICAgIGN1cnJlbnRSZXF1ZXN0ID0gbnVsbDtcclxuICAgICAgICBpZiAoIWVyciAmJiByZXMuYm9keSkge1xyXG4gICAgICAgICAgcmVzb2x2ZShyZXMuYm9keSk7XHJcbiAgICAgICAgICBzZXRRdWVyeVRvVXJsKHNlYXJjaE9wdGlvbnMpO1xyXG5cdFx0XHRcdFx0aWYodHlwZW9mIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoLXBhZ2VcIikgIT0gJ3VuZGVmaW5lZCcpe1xyXG5cdFx0XHRcdFx0XHRDdXN0b21TZWFyY2hFdmVudHMudHJhY2tGdWxsU2VhcmNoKHNlYXJjaE9wdGlvbnMucXVlcnksIHJlcy5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gIH0pO1xyXG59XHJcblxyXG5sZXQgZ2V0U2VhcmNoT3B0aW9uc0Zyb21TdG9yZXMgPSAoKSA9PiB7XHJcbiAgdmFyIG9wdGlvbnMgPSB7XHJcbiAgICBjYXRlZ29yaWVzOiBDYXRlZ29yeUZpbHRlclN0b3JlLmZpbHRlcnMsXHJcbiAgICBicmFuZHM6IEJyYW5kRmlsdGVyU3RvcmUuc2VsZWN0ZWRGaWx0ZXJzKCkubWFwKHggPT4geC5uYW1lKSxcclxuICAgIHVzYWdlVHlwZXM6IFVzYWdlVHlwZUZpbHRlclN0b3JlLnNlbGVjdGVkRmlsdGVycygpLm1hcCh4ID0+IHgubmFtZSksXHJcbiAgICBwcm9kdWN0TGluZXM6IFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUuc2VsZWN0ZWRGaWx0ZXJzKCkubWFwKHggPT4geC5uYW1lKSxcclxuICAgIHRvcExldmVsQ2F0ZWdvcmllczogVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZS5zZWxlY3RlZEZpbHRlcnMoKS5tYXAoeCA9PiB4Lm5hbWUpLFxyXG4gICAgc2VyaWFsTnVtYmVyOiBTZXJpYWxOdW1iZXJGaWx0ZXJTdG9yZS5zZXJpYWxOdW1iZXJcclxuICB9O1xyXG4gIGlmIChTZWFyY2hTdG9yZS5zdGF0ZS5xdWVyeSAhPSAnJykgeyBvcHRpb25zLnF1ZXJ5ID0gU2VhcmNoU3RvcmUuc3RhdGUucXVlcnk7IH1cclxuICBpZiAoU29ydFN0b3JlLnN0YXRlLmZpZWxkKSB7IG9wdGlvbnMuc29ydEZpZWxkID0gU29ydFN0b3JlLnN0YXRlLmZpZWxkOyB9XHJcbiAgaWYgKFNvcnRTdG9yZS5zdGF0ZS5vcmRlcikgeyBvcHRpb25zLnNvcnRPcmRlciA9IFNvcnRTdG9yZS5zdGF0ZS5vcmRlcjsgfVxyXG4gIHJldHVybiBvcHRpb25zO1xyXG59XHJcblxyXG5TZWFyY2hBY3Rpb25zLmludmFsaWRhdGUubGlzdGVuKGZ1bmN0aW9uKCkge1xyXG4gIGxldCBvcHRpb25zID0gZ2V0U2VhcmNoT3B0aW9uc0Zyb21TdG9yZXMoKTtcclxuICBvcHRpb25zLnBhZ2UgPSAxO1xyXG4gIGZldGNoU2VhcmNoUmVzdWx0cyhTZWFyY2hTdG9yZS5zdGF0ZS5zZWFyY2hVcmwgKyAnZXZlcnl0aGluZycsIG9wdGlvbnMpXHJcbiAgICAudGhlbihcclxuICAgICAgKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgQnJhbmRGaWx0ZXJBY3Rpb25zLnVwZGF0ZUZpbHRlcnMocmVzcG9uc2UubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwuYnJhbmRGYWNldHMpO1xyXG4gICAgICAgIFVzYWdlVHlwZUZpbHRlckFjdGlvbnMudXBkYXRlRmlsdGVycyhyZXNwb25zZS5saWdodFNwYXJlUGFydFZpZXdNb2RlbC51c2FnZVR5cGVGYWNldHMpO1xyXG5cdFx0XHRcdENhdGVnb3J5RmlsdGVyQWN0aW9ucy51cGRhdGVGaWx0ZXJzKHJlc3BvbnNlLmxpZ2h0U3BhcmVQYXJ0Vmlld01vZGVsLmNhdGVnb3J5RmFjZXRzKTtcclxuXHRcdFx0XHRQcm9kdWN0TGluZUZpbHRlckFjdGlvbnMudXBkYXRlRmlsdGVycyhyZXNwb25zZS5saWdodFNwYXJlUGFydFZpZXdNb2RlbC5wcm9kdWN0TGluZUZhY2V0cyk7XHJcbiAgICAgICAgVG9wQ2F0ZWdvcnlGaWx0ZXJBY3Rpb25zLnVwZGF0ZUZpbHRlcnMocmVzcG9uc2UubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwudG9wQ2F0ZWdvcnlGYWNldHMpO1xyXG4gICAgICAgIFNlcmlhbE51bWJlckZpbHRlckFjdGlvbnMudXBkYXRlRmlsdGVycyhyZXNwb25zZS5saWdodFNwYXJlUGFydFZpZXdNb2RlbC5zZXJpYWxOdW1iZXIpO1xyXG4gICAgICAgIHRoaXMuY29tcGxldGVkKHJlc3BvbnNlKTtcclxuICAgICAgfSxcclxuICAgICAgKGVycm9yKSA9PiB0aGlzLmZhaWxlZChlcnJvcilcclxuICAgICk7XHJcbn0pO1xyXG5cclxuXHJcbmxldCBkb0ZpbHRlciA9IChzZWxmKSA9PiB7XHJcblx0bGV0IG9wdGlvbnMgPSBnZXRTZWFyY2hPcHRpb25zRnJvbVN0b3JlcygpO1xyXG5cdG9wdGlvbnMucGFnZSA9IDE7XHJcblx0ZmV0Y2hTZWFyY2hSZXN1bHRzKFNlYXJjaFN0b3JlLnN0YXRlLnNlYXJjaFVybCArICdsaWdodFNwYXJlUGFydHMnLCBvcHRpb25zKVxyXG5cdFx0LnRoZW4oXHJcblx0XHRcdChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdEJyYW5kRmlsdGVyQWN0aW9ucy51cGRhdGVGaWx0ZXJzKHJlc3BvbnNlLmJyYW5kRmFjZXRzKTtcclxuXHRcdFx0XHRVc2FnZVR5cGVGaWx0ZXJBY3Rpb25zLnVwZGF0ZUZpbHRlcnMocmVzcG9uc2UudXNhZ2VUeXBlRmFjZXRzKTtcclxuXHRcdFx0XHRDYXRlZ29yeUZpbHRlckFjdGlvbnMudXBkYXRlRmlsdGVycyhyZXNwb25zZS5jYXRlZ29yeUZhY2V0cyk7XHJcblx0XHRcdFx0UHJvZHVjdExpbmVGaWx0ZXJBY3Rpb25zLnVwZGF0ZUZpbHRlcnMocmVzcG9uc2UucHJvZHVjdExpbmVGYWNldHMpO1xyXG5cdFx0XHRcdFRvcENhdGVnb3J5RmlsdGVyQWN0aW9ucy51cGRhdGVGaWx0ZXJzKHJlc3BvbnNlLnRvcENhdGVnb3J5RmFjZXRzKTtcclxuICAgICAgICBpZihyZXNwb25zZS5zZXJpYWxOb0ludmFsaWQgPT09IHRydWUpIHtcclxuICAgICAgICAgIFNlcmlhbE51bWJlckZpbHRlckFjdGlvbnMudXBkYXRlRmlsdGVycyhyZXNwb25zZS5zZXJpYWxOb0ludmFsaWQpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBTZXJpYWxOdW1iZXJGaWx0ZXJBY3Rpb25zLnVwZGF0ZUZpbHRlcnMoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2VsZi5jb21wbGV0ZWQocmVzcG9uc2UpO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHQoZXJyb3IpID0+IHNlbGYuZmFpbGVkKGVycm9yKVxyXG5cdFx0KTtcclxufVxyXG5cclxuU2VhcmNoQWN0aW9ucy5pbnZhbGlkYXRlU3BhcmVQYXJ0cy5saXN0ZW4oZnVuY3Rpb24oKSB7XHJcblx0aWYoZmlsdGVyVGltZXIpIGNsZWFyVGltZW91dChmaWx0ZXJUaW1lcik7XHJcblxyXG5cdGZpbHRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRkb0ZpbHRlcih0aGlzKTtcclxuXHR9LCB3YWl0aW5nRm9yQW5vdGhlckNoZWNrKTtcclxuXHJcblxyXG59KTtcclxuXHJcblxyXG5cclxuXHJcblNlYXJjaEFjdGlvbnMubG9hZE5leHRQYWdlLmxpc3RlbihmdW5jdGlvbihncm91cCkge1xyXG4gIGxldCBvcHRpb25zID0gZ2V0U2VhcmNoT3B0aW9uc0Zyb21TdG9yZXMoKTtcclxuICBpZihnZXRVcmxWYXJzKClbJ3BhZ2UnXSAmJiBwYXJzZUludChnZXRVcmxWYXJzKClbJ3BhZ2UnXSwgMTApICE9PSBOYU4gKXtcclxuICAgIG9wdGlvbnMucGFnZSA9IHBhcnNlSW50KGdldFVybFZhcnMoKVsncGFnZSddKSArIDE7XHJcbiAgfVxyXG4gIGVsc2Uge1xyXG4gICAgb3B0aW9ucy5wYWdlID0gKFNlYXJjaFN0b3JlLnN0YXRlLnBhZ2VzTG9hZGVkQnlHcm91cFtncm91cF0gfHwgMSkgKyAxO1xyXG4gIH1cclxuXHJcbiAgbGV0IGFjdGlvbk1ldGhvZE5hbWUgPSBcIlwiO1xyXG4gIHN3aXRjaChncm91cCkge1xyXG4gICAgICBjYXNlIFwibGlnaHRTcGFyZVBhcnRWaWV3TW9kZWxcIjpcclxuICAgICAgICBhY3Rpb25NZXRob2ROYW1lID0gXCJMaWdodFNwYXJlUGFydHNcIjtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSBcInNwYXJlUGFydHNcIjpcclxuICAgICAgICBhY3Rpb25NZXRob2ROYW1lID0gXCJTcGFyZVBhcnRzXCI7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgXCJwYWdlc1wiOlxyXG4gICAgICAgIGFjdGlvbk1ldGhvZE5hbWUgPSBcIlBhZ2VzXCI7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgYWN0aW9uTWV0aG9kTmFtZSA9IGdyb3VwO1xyXG4gIH1cclxuXHJcbiAgZmV0Y2hTZWFyY2hSZXN1bHRzKFNlYXJjaFN0b3JlLnN0YXRlLnNlYXJjaFVybCArIGFjdGlvbk1ldGhvZE5hbWUsIG9wdGlvbnMpXHJcbiAgICAudGhlbihcclxuICAgICAgKHJlc3BvbnNlKSA9PiB0aGlzLmNvbXBsZXRlZChncm91cCwgcmVzcG9uc2UuaXRlbXMsIHJlc3BvbnNlLm1vcmVSZXN1bHRzQXZhaWxhYmxlKSxcclxuICAgICAgKGVycm9yKSA9PiB0aGlzLmZhaWxlZChlcnJvcilcclxuICAgICk7XHJcbn0pO1xyXG5cclxuXHJcbmxldCBzZXRRdWVyeVRvVXJsID0gKG9wdGlvbnMpID0+IHtcclxuICBsZXQgdXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoJz8nKTtcclxuICBsZXQgcXVlcnkgPSAnPyc7XHJcblxyXG4gICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbihrZXkpe1xyXG4gICAgICBpZihvcHRpb25zW2tleV0gJiYgb3B0aW9uc1trZXldLmNvbnN0cnVjdG9yID09PSBBcnJheSl7XHJcbiAgICAgICAgaWYob3B0aW9uc1trZXldLmxlbmd0aCA+IDApe1xyXG4gICAgICAgICAgb3B0aW9uc1trZXldLmZvckVhY2goZnVuY3Rpb24odmFsdWUpe1xyXG4gICAgICAgICAgICBxdWVyeSArPSBrZXkgKyAob3B0aW9uc1trZXldLmxlbmd0aCA9PT0gMSA/ICcnIDogJ1tdJykgKyc9JyArIGVuY29kZVVSSSh2YWx1ZSkgKyAnJic7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgaWYoa2V5ICE9PSAnc29ydEZpZWxkJyAmJiBrZXkgIT09ICdzb3J0T3JkZXInICYmIG9wdGlvbnNba2V5XSAhPT0gdW5kZWZpbmVkICl7XHJcbiAgICAgICAgICBxdWVyeSArPSBrZXkgKyAnPScgKyBvcHRpb25zW2tleV0gKyAnJic7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAocXVlcnkuc3Vic3RyaW5nKHF1ZXJ5Lmxlbmd0aC0xKSA9PT0gJyYnKXtcclxuICAgICAgICBxdWVyeSA9IHF1ZXJ5LnN1YnN0cmluZygwLCBxdWVyeS5sZW5ndGgtMSk7XHJcbiAgICB9XHJcblxyXG4gIGhpc3RvcnkucHVzaFN0YXRlKHsgU2VhcmNoSGlhYjogJ0hpYWIgcHJvZHVjdCBzZWFyY2gnIH0sICdTZWFyY2gnLCBxdWVyeSk7XHJcbn07XHJcblxyXG5cclxuXHJcbmxldCBnZXRVcmxWYXJzID0gKCkgPT4ge1xyXG4gIHZhciB2YXJzID0ge307XHJcbiAgdmFyIHBhcnRzID0gd2luZG93LmxvY2F0aW9uLmhyZWYucmVwbGFjZSgvWz8mXSsoW149Jl0rKT0oW14mXSopL2dpLFxyXG4gIGZ1bmN0aW9uKG0sa2V5LHZhbHVlKSB7XHJcbiAgICB2YXJzW2tleV0gPSB2YWx1ZTtcclxuICB9KTtcclxuICByZXR1cm4gdmFycztcclxufTtcclxuXHJcblxyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNlYXJjaEFjdGlvbnM7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFJlZmx1eC5jcmVhdGVBY3Rpb25zKFsnYXBwbHlGaWx0ZXInLCAnY2xlYXJGaWx0ZXInLCAndXBkYXRlRmlsdGVycyddKTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5cclxubGV0IFNvcnRBY3Rpb25zID0gUmVmbHV4LmNyZWF0ZUFjdGlvbnMoWydzZXRPcmRlcicsICdzZXRGaWVsZCddKTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNvcnRBY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSZWZsdXguY3JlYXRlQWN0aW9ucyhbJ3RvZ2dsZUZpbHRlcicsICdvbkNsZWFyRmlsdGVycycsICd1cGRhdGVGaWx0ZXJzJ10pO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBUcmVlVmlld0FwaSBmcm9tICcuLi9fYXBpL3RyZWV2aWV3X2FwaSc7XHJcblxyXG5sZXQgVHJlZVZpZXdBY3Rpb25zID0gUmVmbHV4LmNyZWF0ZUFjdGlvbnMoe1xyXG4gICdsb2FkTm9kZXMnOiB7XHJcbiAgICBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ11cclxuICB9LFxyXG4gICdzZWFyY2hOb2Rlc0luTW9kZWwnOiB7XHJcbiAgICBjaGlsZHJlbjogWydjb21wbGV0ZWQnLCAnZmFpbGVkJ11cclxuICB9XHJcbn0pO1xyXG5cclxuVHJlZVZpZXdBY3Rpb25zLmxvYWROb2Rlcy5saXN0ZW4oKGFyZ3MpID0+IHtcclxuXHRUcmVlVmlld0FwaS5nZXROb2RlcyhhcmdzKVxyXG4gICAgLnRoZW4oVHJlZVZpZXdBY3Rpb25zLmxvYWROb2Rlcy5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goVHJlZVZpZXdBY3Rpb25zLmxvYWROb2Rlcy5mYWlsZWQpO1xyXG59KTtcclxuXHJcblRyZWVWaWV3QWN0aW9ucy5zZWFyY2hOb2Rlc0luTW9kZWwubGlzdGVuKChxdWVyeSwgbW9kZWxJZCwgaXNNYWNoaW5lKSA9PiB7XHJcblx0VHJlZVZpZXdBcGkuc2VhcmNoTm9kZXNJbk1vZGVsKHF1ZXJ5LCBtb2RlbElkLCBpc01hY2hpbmUpXHJcbiAgICAudGhlbihUcmVlVmlld0FjdGlvbnMuc2VhcmNoTm9kZXNJbk1vZGVsLmNvbXBsZXRlZClcclxuICAgIC5jYXRjaChUcmVlVmlld0FjdGlvbnMuc2VhcmNoTm9kZXNJbk1vZGVsLmZhaWxlZCk7XHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgVHJlZVZpZXdBY3Rpb25zO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSZWZsdXguY3JlYXRlQWN0aW9ucyhbJ3RvZ2dsZUZpbHRlcicsICdvbkNsZWFyRmlsdGVycycsICd1cGRhdGVGaWx0ZXJzJ10pO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBBZGRyZXNzQXBpIGZyb20gJy4uL19hcGkvdXNlcl9hZGRyZXNzZXNfYXBpJztcclxuaW1wb3J0IFVzZXJEZWZhdWx0QWRkcmVzc2VzU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy91c2VyX2RlZmF1bHRfYWRkcmVzc2VzX3N0b3JlJztcclxuaW1wb3J0IFVzZXJDb3VudHJ5T3B0aW9uc1N0b3JlIGZyb20gJy4uL19zdG9yZXMvdXNlcl9jb3VudHJ5X29wdGlvbnNfc3RvcmUnO1xyXG5pbXBvcnQgQWRkcmVzc0ZpZWxkU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9hZGRyZXNzX2ZpZWxkX3N0b3JlJztcclxuXHJcbmxldCBBZGRyZXNzQWN0aW9ucyA9IFJlZmx1eC5jcmVhdGVBY3Rpb25zKHtcclxuICAnbG9hZEFkZHJlc3Nlcyc6IHtcclxuICAgIGNoaWxkcmVuOiBbJ2NvbXBsZXRlZCcsICdmYWlsZWQnXVxyXG4gIH0sXHJcblx0J2RlbGV0ZUFkZHJlc3MnOiB7fSxcclxuXHQndXBkYXRlQWRkcmVzcyc6IHt9LFxyXG4gICdjcmVhdGVBZGRyZXNzJyA6IHt9LFxyXG4gICdjaGVja1Bvc3RhbENvZGUnOiB7fSxcclxuICAnc2V0RGVmYXVsdEFkZHJlc3MnIDoge30sXHJcbiAgJ3NldENvdW50cmllcycgOiB7fSxcclxuICAnZ2V0Q291bnRyaWVzJyA6IHt9XHJcbn0pO1xyXG5cclxuQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5saXN0ZW4oKGFyZ3MpID0+IHtcclxuICBBZGRyZXNzQXBpLmFkZHJlc3NlcyhhcmdzKVxyXG4gICAgLnRoZW4oQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLnNldERlZmF1bHRBZGRyZXNzLmxpc3RlbigoZGVmYXVsdEFkZHJlc3MpID0+e1xyXG4gIFVzZXJEZWZhdWx0QWRkcmVzc2VzU3RvcmUuc2V0RGVmYXVsdEFkZHJlc3MoZGVmYXVsdEFkZHJlc3MpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLnNldENvdW50cmllcy5saXN0ZW4oKGNvdW50cmllcykgPT57XHJcbiAgVXNlckNvdW50cnlPcHRpb25zU3RvcmUuc2V0Q291bnRyaWVzKGNvdW50cmllcyk7XHJcbn0pO1xyXG5BZGRyZXNzQWN0aW9ucy5nZXRDb3VudHJpZXMubGlzdGVuKChjb3VudHJpZXMpID0+e1xyXG4gIFVzZXJDb3VudHJ5T3B0aW9uc1N0b3JlLmdldENvdW50cmllcyhjb3VudHJpZXMpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLmRlbGV0ZUFkZHJlc3MubGlzdGVuKChhZGRyZXNzZXMpID0+IHtcclxuICBBZGRyZXNzQXBpLmRlbGV0ZWFkZHJlc3MoYWRkcmVzc2VzKVxyXG4gICAgLnRoZW4oQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLnVwZGF0ZUFkZHJlc3MubGlzdGVuKChhZGRyZXNzZXMpID0+IHtcclxuICBBZGRyZXNzQXBpLnVwZGF0ZWFkZHJlc3MoYWRkcmVzc2VzKVxyXG4gICAgLnRoZW4oQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLmNyZWF0ZUFkZHJlc3MubGlzdGVuKChhZGRyZXNzZXMpID0+IHtcclxuICBBZGRyZXNzQXBpLmNyZWF0ZWFkZHJlc3MoYWRkcmVzc2VzKVxyXG4gICAgLnRoZW4oQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5jb21wbGV0ZWQpXHJcbiAgICAuY2F0Y2goQWRkcmVzc0FjdGlvbnMubG9hZEFkZHJlc3Nlcy5mYWlsZWQpO1xyXG59KTtcclxuXHJcbkFkZHJlc3NBY3Rpb25zLmNoZWNrUG9zdGFsQ29kZS5saXN0ZW4oKGNvdW50cnlDb2RlLCB2YWx1ZSkgPT4ge1xyXG4gIEFkZHJlc3NBcGkuY2hlY2tQb3N0YWxDb2RlKGNvdW50cnlDb2RlLCB2YWx1ZSlcclxuICAgIC50aGVuKEFkZHJlc3NGaWVsZFN0b3JlLmNoZWNrUG9zdGFsQ29kZUNvbXBsZXRlZClcclxuICAgIC5jYXRjaChBZGRyZXNzRmllbGRTdG9yZS5jaGVja1Bvc3RhbENvZGVGYWlsZWQpO1xyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEFkZHJlc3NBY3Rpb25zO1xyXG4iLCJpbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcclxuaW1wb3J0IEJyZWFkY3J1bWJTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2JyZWFkY3J1bWJfc3RvcmUnO1xyXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwcm9taXNlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuXHRnZXRCcmVhZGNydW1iKG1vZGVsSWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9CcmVhZGNydW1icy8nICsgbW9kZWxJZCArICcuanNvbic7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuYXBpQmFzZVVybCArICdCcmVhZGNydW1icy8nICsgbW9kZWxJZDtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdEJyZWFkY3J1bWJTdG9yZS5pbml0KCk7XHJcblx0XHRcdFx0XHRcdEJyZWFkY3J1bWJTdG9yZS5zZXQobW9kZWxJZCwgcmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblx0Z2V0TWFjaGluZUJyZWFkY3J1bWIobW9kZWxJZCkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0Ly9sZXQgdXJsID0gJy9kdW1teS9qc29uL0JyZWFkY3J1bWJzLycgKyBtb2RlbElkICsgJy5qc29uJztcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5hcGlCYXNlVXJsICsgJ01hY2hpbmVCcmVhZGNydW1icy8nICsgbW9kZWxJZDtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdEJyZWFkY3J1bWJTdG9yZS5pbml0KCk7XHJcblx0XHRcdFx0XHRcdEJyZWFkY3J1bWJTdG9yZS5zZXQobW9kZWxJZCwgcmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblx0Z2V0TW9kZWxCcmVhZGNydW1iKG1vZGVsSWQpe1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5hcGlCYXNlVXJsICsgJ01vZGVsQnJlYWRjcnVtYnMvJyArIG1vZGVsSWQ7XHJcblxyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LmdldCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdCAgaWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0XHRCcmVhZGNydW1iU3RvcmUuaW5pdCgpO1xyXG5cdFx0XHRcdFx0XHRCcmVhZGNydW1iU3RvcmUuc2V0KG1vZGVsSWQsIHJlc3BvbnNlLmJvZHkpO1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG5cdCAgICAgICAgfVxyXG5cdCAgICAgICAgZWxzZSB7XHJcblx0ICAgICAgICAgIHJlamVjdCgnRXJyb3InKTtcclxuXHQgICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG5cdGNhcnRpdGVtcygpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNhcnQuYXBpQmFzZVVybCArICdnZXRjYXJ0JztcclxuXHRcdFx0Ly8gdXJsID0gJ2R1bW15L2pzb24vY2FydC9jYXJ0aXRlbXMuanNvbic7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblxyXG5cdGNsZWFyY2FydCgpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNhcnQuYXBpQmFzZVVybCArICdjbGVhcmNhcnQnO1xyXG5cclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblxyXG5cdGFkZGNhcnRpdGVtKHNrdUlkLCBxdWFudGl0eSkge1xyXG5cdFx0Ly8gY29uc29sZS5sb2coJ0NhcnRBcGkjYWRkY2FydGl0ZW0gaXMgZGVwcmVjYXRlZC4gVXNlIENhcnRBcGkjYWRkQ2FydEl0ZW0gb3IgQ2FydEFwaSNhZGRDYXJ0SXRlbXMgaW5zdGVhZC4nKVxyXG5cdFx0bGV0IGNhcnRJdGVtcyA9IFt7IENvZGU6IHNrdUlkLCBRdWFudGl0eTogcXVhbnRpdHkgfV1cclxuXHRcdC8vIEFjY291bnQgZm9yIGJhY2tlbmQgY2hhbmdlcyBzaW5jZSBkZXByZWNhdGlvblxyXG5cdFx0cmV0dXJuIHRoaXMuYWRkQ2FydEl0ZW1zKGNhcnRJdGVtcykudGhlbihcclxuXHRcdFx0KHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZS5DYXJ0KTtcclxuXHRcdFx0fVxyXG5cdFx0KVxyXG5cdH0sXHJcblxyXG5cdGFkZENhcnRJdGVtKGNvZGUsIHF1YW50aXR5KSB7XHJcblx0XHRyZXR1cm4gdGhpcy5hZGRDYXJ0SXRlbXMoW3sgY29kZTogY29kZSwgcXVhbnRpdHk6IHF1YW50aXR5IH1dKTtcclxuXHR9LFxyXG5cdC8vIC8qKlxyXG5cdC8vICAqIEBwYXJhbSB7T2JqZWN0W119IGNhcnRJdGVtc1xyXG5cdC8vICAqIEBwYXJhbSB7c3RyaW5nfSBjYXJ0SXRlbXNbXS5jb2RlIC0gc2t1SWRcclxuXHQvLyAgKiBAcGFyYW0ge2ludGVnZXJ9IGNhcnRJdGVtc1tdLnF1YW50aXR5IC0gaW50ZXJwcmV0ZWQgYXMgZGVjaW1hbCBieSBiYWNrZW5kICg/KVxyXG5cdC8vICAqL1xyXG5cdGFkZENhcnRJdGVtcyhjYXJ0SXRlbXMsIGlzUXVpY2tCdXlCYXRjaCA9IGZhbHNlKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jYXJ0LmFwaUJhc2VVcmwgKyAnYWRkY2FydGl0ZW1zP3FiY29udGV4dD0nICsgaXNRdWlja0J1eUJhdGNoICsgJyZsYW5ndWFnZT0nK2hpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZTtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2VuZChjYXJ0SXRlbXMpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihlcnJvciB8fCAhcmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QoZXJyb3IgfHwgXCJubyByZXNwb25zZSBib2R5XCIpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cclxuXHR1cGRhdGVjYXJ0aXRlbShza3VJZCwgcXVhbnRpdHkpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNhcnQuYXBpQmFzZVVybCArICd1cGRhdGVjYXJ0aXRlbXF1YW50aXR5P2xhbmd1YWdlPScraGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlLFxyXG5cdFx0XHRcdFx0Y2FydEl0ZW0gPSB7IGNvZGU6IHNrdUlkLCBxdWFudGl0eTogcXVhbnRpdHkgfTtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2VuZChjYXJ0SXRlbSlcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHQgIGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHQgICAgICAgIH1cclxuXHQgICAgICAgIGVsc2Uge1xyXG5cdCAgICAgICAgICByZWplY3QoJ0Vycm9yJyk7XHJcblx0ICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblx0fSxcclxuXHJcblx0ZGVsZXRlY2FydGl0ZW0oc2t1SWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jYXJ0LmFwaUJhc2VVcmwgKyAnZGVsZXRlY2FydGl0ZW0vJyArIHNrdUlkO1xyXG5cdFx0XHQvL1x0dXJsID0gJy9kdW1teS9qc29uL2NhcnQvZGVsZXRlaXRlbS5qc29uJztcclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQvLy5nZXQodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHQgIGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHQgICAgICAgIH1cclxuXHQgICAgICAgIGVsc2Uge1xyXG5cdCAgICAgICAgICByZWplY3QoJ0Vycm9yJyk7XHJcblx0ICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblx0fVxyXG5cclxufVxyXG4iLCJpbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcclxuaW1wb3J0IFByb21pc2UgZnJvbSAncHJvbWlzZSc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcblxyXG5cdGN1cnJlbnRSZXF1ZXN0U2hpcHBpbmdPcHRpb25PclByaW9yaXR5OiBudWxsLFxyXG5cdGN1cnJlbnRSZXF1ZXN0T3JkZXJTaW11bGF0aW9uOiBudWxsLFxyXG5cdGN1cnJlbnRSZXF1ZXN0Q291bnRyeUNvZGU6IG51bGwsXHJcblxyXG5cdGdldENoZWNrb3V0KCkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0Ly9sZXQgdXJsID0gJy9kdW1teS9qc29uL0NoZWNrb3V0L2NoZWNrb3V0Lmpzb24nO1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ2dldGNoZWNrb3V0JztcclxuXHRcdFx0dXJsID0gJ2R1bW15L2pzb24vQ2hlY2tvdXQvY2hlY2tvdXQtMi5qc29uJztcclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5nZXQodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHQgIGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHQgICAgICAgIH1cclxuXHQgICAgICAgIGVsc2Uge1xyXG5cdCAgICAgICAgICByZWplY3QocmVzcG9uc2UpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblxyXG5cdG9yZGVyU2ltdWxhdGlvbihkYXRhKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cclxuXHRcdFx0aWYodGhpcy5jdXJyZW50UmVxdWVzdE9yZGVyU2ltdWxhdGlvbiAhPT0gbnVsbCApe1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3RPcmRlclNpbXVsYXRpb24uYWJvcnQoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ09yZGVyU2ltdWxhdGlvbkpzb24nO1xyXG5cdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0T3JkZXJTaW11bGF0aW9uID0gcmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChkYXRhKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlamVjdChyZXNwb25zZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdH0sXHJcblx0dXBkYXRlU2hpcHBpbmdPcHRpb25PclByaW9yaXR5KG9wdGlvbikge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcblx0XHRcdGlmKHRoaXMuY3VycmVudFJlcXVlc3RTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkgIT09IG51bGwgKXtcclxuXHRcdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0U2hpcHBpbmdPcHRpb25PclByaW9yaXR5LmFib3J0KCk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAndXBkYXRlU2hpcHBpbmdPcHRpb25Kc29uJztcclxuXHJcblxyXG5cdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0U2hpcHBpbmdPcHRpb25PclByaW9yaXR5ID0gcmVxdWVzdFxyXG5cdFx0XHRcdC8vLmdldCh1cmwpXHJcblx0XHRcdFx0LnBvc3QodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKVxyXG5cdFx0XHRcdC5zZW5kKG9wdGlvbilcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUNvdW50cnlDb2RlKHNoaXBwaW5nQWRkcmVzcykge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0aWYodGhpcy5jdXJyZW50UmVxdWVzdENvdW50cnlDb2RlICE9PSBudWxsICl7XHJcblx0XHRcdFx0dGhpcy5jdXJyZW50UmVxdWVzdENvdW50cnlDb2RlLmFib3J0KCk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAnVXBkYXRlU2hpcHBpbmdDb3VudHJ5SnNvbic7XHJcblxyXG5cdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0Q291bnRyeUNvZGUgPSByZXF1ZXN0XHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcblx0XHRcdFx0LnNlbmQoeyBzaGlwcGluZ0FkZHJlc3Nlczogc2hpcHBpbmdBZGRyZXNzIH0pXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KHJlc3BvbnNlKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGVDYXJ0SXRlbShza3VJZCwgcXVhbnRpdHksIHVwZ3JhZGVkKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ3VwZGF0ZUNhcnRJdGVtSnNvbicsXHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9jaGVja291dC9jaGVja291dC5odG1sJyxcclxuXHRcdFx0XHRcdGNhcnRJdGVtID0geyBjb2RlOiBza3VJZCwgcXVhbnRpdHk6IHF1YW50aXR5LCB1cGdyYWRlZDogdXBncmFkZWQgfTtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQvLy5nZXQodXJsKVxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChjYXJ0SXRlbSlcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGRlbGV0ZUNhcnRJdGVtKHNrdUlkKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ2RlbGV0ZWNhcnRpdGVtSnNvbic7XHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9jaGVja291dC9jaGVja291dC5odG1sJztcclxuXHRcdFx0bGV0IGlkID0geyBcImlkXCI6IHNrdUlkIH07XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChpZClcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUNhcnRJdGVtQ3VzdG9tZXJDb21tZW50KGlkLCBjb21tZW50KSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ3VwZGF0ZWNhcnRpdGVtY3VzdG9tZXJjb21tZW50SnNvbic7XHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9jaGVja291dC9jaGVja291dC5odG1sJyxcclxuXHRcdFx0bGV0IGNhcnRJdGVtID0geyBpZDogaWQsIGNvbW1lbnQ6IGNvbW1lbnQgfTtcclxuXHRcdFx0Ly9XaWxsIHNlbmQgc3VjY2VzIG9yIGZhbHNlXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChjYXJ0SXRlbSlcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGxvYWRTaGlwcGluZ0FkZHJlc3MoaWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAnc2V0U2hpcHBpbmdBZGRyZXNzQnlJZEpzb24nLFxyXG5cdFx0XHQvL2xldCB1cmwgPSAnL2R1bW15L2pzb24vY2hlY2tvdXQvY2hlY2tvdXQuaHRtbCcsXHJcblx0XHRcdFx0XHRhZGRyZXNzSWQgPSB7IGlkOiBpZCB9O1xyXG5cclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQvLy5nZXQodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKVxyXG5cdFx0XHRcdC5zZW5kKGFkZHJlc3NJZClcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblx0bG9hZEJpbGxpbmdBZGRyZXNzKGlkKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ3NldEJpbGxpbmdBZGRyZXNzQnlJZEpzb24nLFxyXG5cdFx0XHQvL2xldCB1cmwgPSAnL2R1bW15L2pzb24vY2hlY2tvdXQvY2hlY2tvdXQuaHRtbCcsXHJcblx0XHRcdFx0XHRhZGRyZXNzSWQgPSB7IGlkOiBpZCB9O1xyXG5cclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQvLy5nZXQodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKVxyXG5cdFx0XHRcdC5zZW5kKGFkZHJlc3NJZClcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcbn1cclxuIiwiaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG5cclxuXHRjdXJyZW50UmVxdWVzdFNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eTogbnVsbCxcclxuXHRjdXJyZW50UmVxdWVzdENvdW50cnlDb2RlOiBudWxsLFxyXG5cclxuXHRnZXRDaGVja291dCgpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9DaGVja291dC9jaGVja291dC5qc29uJztcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuY2hlY2tvdXQuYXBpQmFzZVVybCArICdnZXRjaGVja291dCc7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblxyXG5cclxuXHR1cGRhdGVTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkob3B0aW9uKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cclxuXHRcdFx0aWYodGhpcy5jdXJyZW50UmVxdWVzdFNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eSAhPT0gbnVsbCApe1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3RTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkuYWJvcnQoKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuY2hlY2tvdXQuYXBpQmFzZVVybCArICd1cGRhdGVTaGlwcGluZ09wdGlvbic7XHJcblxyXG5cclxuXHRcdFx0dGhpcy5jdXJyZW50UmVxdWVzdFNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eSA9IHJlcXVlc3RcclxuXHRcdFx0XHQvLy5nZXQodXJsKVxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChvcHRpb24pXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS50ZXh0KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UudGV4dCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUNvdW50cnlDb2RlKGNvZGUpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGlmKHRoaXMuY3VycmVudFJlcXVlc3RDb3VudHJ5Q29kZSAhPT0gbnVsbCApe1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3RDb3VudHJ5Q29kZS5hYm9ydCgpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ1VwZGF0ZVNoaXBwaW5nQ291bnRyeSc7XHJcblxyXG5cdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0Q291bnRyeUNvZGUgPSByZXF1ZXN0XHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcblx0XHRcdFx0LnNlbmQoeyBjb3VudHJ5Q29kZTogY29kZSB9KVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYocmVzcG9uc2UudGV4dCkge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLnRleHQpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlamVjdCgnRXJyb3InKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHJcblx0dXBkYXRlQ2FydEl0ZW1RdWFudGl0eShza3VJZCwgcXVhbnRpdHkpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAndXBkYXRlY2FydGl0ZW1xdWFudGl0eScsXHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9jaGVja291dC9jaGVja291dC5odG1sJyxcclxuXHRcdFx0XHRcdGNhcnRJdGVtID0geyBjb2RlOiBza3VJZCwgcXVhbnRpdHk6IHF1YW50aXR5IH07XHJcblxyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcblx0XHRcdFx0LnNlbmQoY2FydEl0ZW0pXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS50ZXh0KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UudGV4dCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGRlbGV0ZUNhcnRJdGVtKHNrdUlkKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsICsgJ2RlbGV0ZWNhcnRpdGVtJztcclxuXHRcdFx0Ly9sZXQgdXJsID0gJy9kdW1teS9qc29uL2NoZWNrb3V0L2NoZWNrb3V0Lmh0bWwnO1xyXG5cdFx0XHRsZXQgaWQgPSB7IFwiaWRcIjogc2t1SWQgfTtcclxuXHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0Ly8uZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JylcclxuXHRcdFx0XHQuc2VuZChpZClcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLnRleHQpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS50ZXh0KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QoJ0Vycm9yJyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlQ2FydEl0ZW1DdXN0b21lckNvbW1lbnQoaWQsIGNvbW1lbnQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAndXBkYXRlY2FydGl0ZW1jdXN0b21lcmNvbW1lbnQnO1xyXG5cdFx0XHQvL2xldCB1cmwgPSAnL2R1bW15L2pzb24vY2hlY2tvdXQvY2hlY2tvdXQuaHRtbCcsXHJcblx0XHRcdGxldCBjYXJ0SXRlbSA9IHsgaWQ6IGlkLCBjb21tZW50OiBjb21tZW50IH07XHJcblxyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LnBvc3QodXJsKVxyXG5cdFx0XHRcdC8vLmdldCh1cmwpXHJcblx0XHRcdFx0LnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcblx0XHRcdFx0LnNlbmQoY2FydEl0ZW0pXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS50ZXh0KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UudGV4dCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGxvYWRTaGlwcGluZ0FkZHJlc3MoaWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmNoZWNrb3V0LmFwaUJhc2VVcmwgKyAnR2V0U2hpcHBpbmdBZGRyZXNzQnlJZC8nICsgaWQsXHJcblx0XHRcdC8vbGV0IHVybCA9ICcvZHVtbXkvanNvbi9jaGVja291dC9jaGVja291dC5odG1sJyxcclxuXHRcdFx0XHRcdGFkZHJlc3NJZCA9IHsgaWQ6IGlkIH07XHJcblxyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LnBvc3QodXJsKVxyXG5cdFx0XHRcdC8vLmdldCh1cmwpXHJcblx0XHRcdFx0LnNldCgnWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcblx0XHRcdFx0LnF1ZXJ5KGFkZHJlc3NJZClcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLnRleHQpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS50ZXh0KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QoJ0Vycm9yJyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcbn1cclxuIiwiaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG4vKipcclxuICogSWxsdXN0cmF0aW9uIGFwaSBtb2R1bGVcclxuICogQG1vZHVsZSBfYXBpL2lsbHVzdHJhdGlvbl9hcGlcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuXHQvKipcclxuICogR2V0IGlsbHVzdHJhdGlvbiBieSBndWlkXHJcbiAqIEBwYXJhbSB7Z3VpZH0gZ3VpZCAtIHBhcmVudCBub2RlIGd1aWRcclxuICovXHJcblx0Z2V0SWxsdXN0cmF0aW9uKGd1aWQsIG5vZGVUeXBlKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRpZighZ3VpZCkge1xyXG5cdFx0XHRcdHJldHVybiByZWplY3QoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmFwaUJhc2VVcmwgKyAnR2V0SWxsdXN0cmF0aW9uLycgKyBndWlkICsnP25vZGV0eXBlPScgKyBub2RlVHlwZSsnJm1vZGVsSWQ9JztcclxuXHJcblx0XHRcdHJlcXVlc3QuZ2V0KHVybCkuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgIHJlamVjdCgnRXJyb3InKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xyXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwcm9taXNlJztcclxuLyoqXHJcbiAqIElsbHVzdHJhdGlvbiBhcGkgbW9kdWxlXHJcbiAqIEBtb2R1bGUgX2FwaS9pbGx1c3RyYXRpb25fYXBpXHJcbiAqL1xyXG5leHBvcnQgZGVmYXVsdCB7XHJcblx0LyoqXHJcbiAqIEdldCBpbGx1c3RyYXRpb24gYnkgZ3VpZFxyXG4gKiBAcGFyYW0ge2d1aWR9IGd1aWQgLSBwYXJlbnQgbm9kZSBndWlkXHJcbiAqL1xyXG5cdGdldElsbHVzdHJhdGlvbihndWlkLG1vZGVsSWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGlmKCFndWlkKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJlamVjdCgpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmFwaUJhc2VVcmwgKyAnR2V0SWxsdXN0cmF0aW9uLycgKyBndWlkICsnP21vZGVsaWQ9Jyttb2RlbElkO1xyXG5cdFx0XHRyZXF1ZXN0LmdldCh1cmwpLmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdCAgaWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICByZWplY3QoJ0Vycm9yJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcclxuaW1wb3J0IFByb21pc2UgZnJvbSAncHJvbWlzZSc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcblx0aW1wZXJzb25hdGVkVXNlcigpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmltcGVyc29uYXRvci5hcGlCYXNlVXJsICsgJ2dldCc7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdFx0fVxyXG4gICAgICBcdH0pO1xyXG4gICAgfSk7XHJcblx0fSxcclxuXHJcblx0aW1wZXJzb25hdGVkU2lnbmluKGlkKSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5pbXBlcnNvbmF0b3IuYXBpQmFzZVVybCArICdTaWduSW4vJyArIGlkO1xyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LnBvc3QodXJsKVxyXG5cdFx0XHRcdC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2V0KCdMYW5ndWFnZScsIGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZSlcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlamVjdChyZXNwb25zZSk7XHJcblx0XHRcdFx0XHR9XHJcbiAgICAgIFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRpbXBlcnNvbmF0ZWRTaWdub3V0KCkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuaW1wZXJzb25hdG9yLmFwaUJhc2VVcmwgKyAnU2lnbk91dCdcclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LnNldCgnTGFuZ3VhZ2UnLCBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmUpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZihyZXNwb25zZS5zdGF0dXMgPT09IDIwMCkge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QoJ0Vycm9yJyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG5cclxuXHRjdXJyZW50UmVxdWVzdDogbnVsbCxcclxuXHJcblx0ZmV0Y2hNb2RlbFR5cGVzKHNlcmlhbE51bWJlcil7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRpZih0aGlzLmN1cnJlbnRSZXF1ZXN0ICE9PSBudWxsICl7XHJcblx0XHRcdFx0dGhpcy5jdXJyZW50UmVxdWVzdC5hYm9ydCgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuYXBpQmFzZVVybCArICdtb2RlbHNlYXJjaC8nICsgbW9kZWxRdWVyeTsgLy9BcGkvU2FsZXNmb3JjZVJlY29tbWVuZGF0aW9ucy9HZXRSZWNvbW1lbmRhdGlvbnM7XHJcblx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3QgPSByZXF1ZXN0XHJcblx0XHRcdC5nZXQodXJsKVxyXG5cdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdC5zZW5kKHNlcmlhbE51bWJlcilcclxuXHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0aWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0cmVqZWN0KCdFcnJvcicpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcbiAgICBcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHNlYXJjaChtb2RlbFF1ZXJ5KSB7XHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG5cdFx0XHRpZih0aGlzLmN1cnJlbnRSZXF1ZXN0ICE9PSBudWxsICl7XHJcblx0XHRcdFx0dGhpcy5jdXJyZW50UmVxdWVzdC5hYm9ydCgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuYXBpQmFzZVVybCArICdtb2RlbHNlYXJjaC8nICsgbW9kZWxRdWVyeTtcclxuXHRcdFx0dGhpcy5jdXJyZW50UmVxdWVzdCA9IHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0ICBpZihyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0ICAgICAgICB9XHJcblx0ICAgICAgICBlbHNlIHtcclxuXHQgICAgICAgICAgcmVqZWN0KCdFcnJvcicpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cdH0sXHJcblxyXG5cdGFib3J0U2VhcmNoKCl7XHJcblx0XHRpZih0aGlzLmN1cnJlbnRSZXF1ZXN0ICE9PSBudWxsICl7XHJcblx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3QuYWJvcnQoKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG5cdGlzYnV5YWJsZShwcm9kdWN0SWQpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmJhdGNoT3JkZXIuYXBpQmFzZVVybCArICdpc2J1eWFibGUnO1xyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LmdldCh1cmwpXHJcblx0XHRcdFx0LnF1ZXJ5KHsgaWQ6IHByb2R1Y3RJZCB9KVxyXG5cdFx0XHRcdC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKGVycm9yIHx8ICFyZXNwb25zZS5ib2R5KSB7XHJcblx0XHRcdFx0XHRcdHJlamVjdChlcnJvciB8fCAnTm8gcmVzcG9uc2UgYm9keScpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdCAgZWxzZSAge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG5cdCAgICAgICAgfVxyXG4gICAgICBcdH0pO1xyXG4gICAgfSk7XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xyXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwcm9taXNlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuXHRmZXRjaFJlY29tbWVuZGF0aW9ucyhyZWNvbW1lbmRhdGlvblJlcXVlc3QpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSAnL0FwaS9TYWxlc2ZvcmNlUmVjb21tZW5kYXRpb25zL0dldFJlY29tbWVuZGF0aW9ucyc7XHJcblx0XHRcdGxldCBkYXRhID0gSlNPTi5zdHJpbmdpZnkocmVjb21tZW5kYXRpb25SZXF1ZXN0KTtcclxuXHRcdFx0cmVxdWVzdFxyXG5cdFx0XHRcdC5wb3N0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZW5kKGRhdGEpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHRpZiAocmVzcG9uc2UgfHwgcmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yIHx8IFwibm8gcmVzcG9uc2UgYm9keVwiKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcclxuaW1wb3J0IFRyZWVWaWV3U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy90cmVldmlld19zdG9yZSc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBQcm9taXNlIGZyb20gJ3Byb21pc2UnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG5cdGdldE5vZGVzKHBhcmVudCkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0bGV0IGFwaVR5cGUgPSAnR2V0Tm9kZXMvJztcclxuXHJcblx0XHRcdGlmKCFwYXJlbnQpe1xyXG5cdFx0XHRcdHBhcmVudCA9IDA7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHZhciBpc01hY2hpbmUgPSBwYXJlbnQuc3Vic3RyaW5nKDAsIDgpID09ICdtYWNoaW5lLSc7XHJcblx0XHRcdFx0dmFyIGlzTW9kZWwgPSBwYXJlbnQuc3Vic3RyaW5nKDAsIDYpID09ICdtb2RlbC0nO1xyXG5cdFx0XHRcdGlmKGlzTWFjaGluZSl7XHJcblx0XHRcdFx0XHRhcGlUeXBlID0gJ0dldE1hY2hpbmVOb2Rlcy8nXHJcblx0XHRcdFx0XHRwYXJlbnQgPSBwYXJlbnQucmVwbGFjZSgnbWFjaGluZS0nLCcnKTtcclxuXHRcdFx0XHR9ZWxzZSBpZihpc01vZGVsKXtcclxuXHRcdFx0XHRcdHBhcmVudCA9IHBhcmVudC5yZXBsYWNlKCdtb2RlbC0nLCcnKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGxldCBjYWNoZUtleSA9IHBhcmVudDtcclxuXHRcdFx0bGV0IGZpbmRJbkNhY2hlID0gVHJlZVZpZXdTdG9yZS5nZXQoY2FjaGVLZXkpO1xyXG5cdFx0XHQgIFxyXG5cdFx0XHRpZighXy5pc1VuZGVmaW5lZChmaW5kSW5DYWNoZSkpIHtcclxuXHRcdFx0XHRyZXR1cm4gcmVzb2x2ZShmaW5kSW5DYWNoZS5kYXRhKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5hcGlCYXNlVXJsICsgYXBpVHlwZSArIHBhcmVudDtcclxuXHRcdFx0cmVxdWVzdC5nZXQodXJsKS5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0KGNhY2hlS2V5LCByZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdFx0XHRsZXQgZXJyb3IgPSByZXNwb25zZS5zdGF0dXNDb2RlID09PSAyMDQgPyByZXNwb25zZS5zdGF0dXNDb2RlIDogJ0Vycm9yJztcclxuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XHJcblx0XHRcdFx0fVxyXG4gICAgICBcdFx0fSk7XHJcbiAgICBcdH0pO1xyXG5cdH0sXHJcblx0Z2V0QXNjZW5kYW50Tm9kZXMobW9kZWxJZCwgaWxsdXN0cmF0aW9uSWQsIG5vZGVJZCkge1xyXG5cdFx0dmFyIGlzTWFjaGluZSA9IG1vZGVsSWQuc3Vic3RyaW5nKDAsIDgpID09ICdtYWNoaW5lLSc7XHJcblx0XHRsZXQgYXBpVHlwZSA9IGlsbHVzdHJhdGlvbklkID8gJ0FuY2VzdG9yc0ZvcklsbHVzdHJhdGlvbicgOiAnQW5jZXN0b3JzRm9yU2VjdGlvbic7XHJcblx0XHRsZXQgaWQgPSBpbGx1c3RyYXRpb25JZCA/IGlsbHVzdHJhdGlvbklkIDogbm9kZUlkO1xyXG5cclxuXHRcdGlmKCBpc01hY2hpbmUgJiYgaWxsdXN0cmF0aW9uSWQgKXtcclxuXHRcdFx0YXBpVHlwZSA9ICdHZXRNYWNoaW5lTm9kZXMnO1xyXG5cdFx0XHRtb2RlbElkID0gbW9kZWxJZC5yZXBsYWNlKCdtYWNoaW5lLScsJycpO1xyXG5cdFx0XHRpZCA9IG1vZGVsSWQ7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuYXBpQmFzZVVybCArIGFwaVR5cGUgKycvJyArIGlkO1xyXG5cdFx0XHRsZXQgcGFyYW1zID0ge1xyXG5cdFx0XHRcdGJhc2VNb2RlbElkOiBtb2RlbElkXHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHRpZihpbGx1c3RyYXRpb25JZCAmJiAhaXNNYWNoaW5lKXtcclxuXHRcdFx0XHRyZXF1ZXN0LmdldCh1cmwpLnF1ZXJ5KHBhcmFtcykuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdFx0XHRcdHJlamVjdCgnRXJyb3InKTtcclxuXHRcdFx0XHRcdH1cclxuXHQgICAgIFx0XHQgfSk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHJlcXVlc3QuZ2V0KHVybCkuZW5kKChlcnJvciwgcmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdGlmKHJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdFx0XHRcdHJlamVjdCgnRXJyb3InKTtcclxuXHRcdFx0XHRcdH1cclxuXHQgICAgICBcdFx0fSk7XHJcblx0XHRcdH1cclxuICAgIFx0fSk7XHJcblx0fSxcclxuXHJcblx0Y3VycmVudFJlcXVlc3Q6IG51bGwsXHJcblxyXG5cdHNlYXJjaE5vZGVzSW5Nb2RlbChxdWVyeSwgbW9kZWxJZCwgaXNNYWNoaW5lKSB7XHJcblx0XHRsZXQgZW5kUG9pbnQgPSAnU2VhcmNoSW5Nb2RlbCc7XHJcblx0XHRpZiAoaXNNYWNoaW5lKXtcclxuXHRcdFx0bW9kZWxJZCA9IG1vZGVsSWQucmVwbGFjZSgnbWFjaGluZS0nLCcnKTtcclxuXHRcdFx0ZW5kUG9pbnQgPSAnU2VhcmNoSW5NYWNoaW5lJ1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0aWYodGhpcy5jdXJyZW50UmVxdWVzdCAhPT0gbnVsbCApe1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFJlcXVlc3QuYWJvcnQoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmFwaUJhc2VVcmwgKyBlbmRQb2ludCArJy8/cXVlcnk9JytxdWVyeSsnJm1vZGVsaWQ9Jyttb2RlbElkO1xyXG5cdFx0XHR0aGlzLmN1cnJlbnRSZXF1ZXN0ID0gcmVxdWVzdFxyXG5cdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0aWYocmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKGZhbHNlKTtcclxuXHRcdFx0XHRcdHJlamVjdCgnRXJyb3InKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fSxcclxufVxyXG4iLCJpbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcclxuaW1wb3J0IFByb21pc2UgZnJvbSAncHJvbWlzZSc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcblx0YWRkcmVzc2VzKCkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuYWRkcmVzc2VzLmFwaUJhc2VVcmwgKyAnSW5kZXgnO1xyXG5cdFx0XHRyZXF1ZXN0XHJcblx0XHRcdFx0LmdldCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdCAgaWYocmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keSkge1xyXG5cdFx0XHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG5cdCAgICAgICAgfVxyXG5cdCAgICAgICAgZWxzZSB7XHJcblx0ICAgICAgICAgIHJlamVjdCgnRXJyb3InKTtcclxuXHQgICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHR9LFxyXG5cclxuXHRkZWxldGVhZGRyZXNzKGFkZHJlc3MpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5hcGlCYXNlVXJsICsgJ0RlbGV0ZSc7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2VuZChhZGRyZXNzKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYoZXJyb3IgfHwgIXJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yIHx8IFwibm8gcmVzcG9uc2UgYm9keVwiKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGVhZGRyZXNzKGFkZHJlc3MpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5hcGlCYXNlVXJsICsgJ1VwZGF0ZSc7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2VuZChhZGRyZXNzKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYoZXJyb3IgfHwgIXJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yIHx8IFwibm8gcmVzcG9uc2UgYm9keVwiKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRjcmVhdGVhZGRyZXNzKGFkZHJlc3MpIHtcclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblx0XHRcdGxldCB1cmwgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5hcGlCYXNlVXJsICsgJ0NyZWF0ZSc7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQucG9zdCh1cmwpXHJcblx0XHRcdFx0LnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJylcclxuXHRcdFx0XHQuc2VuZChhZGRyZXNzKVxyXG5cdFx0XHRcdC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYoZXJyb3IgfHwgIXJlc3BvbnNlLmJvZHkpIHtcclxuXHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yIHx8IFwibm8gcmVzcG9uc2UgYm9keVwiKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UuYm9keSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHJcblx0Y2hlY2tQb3N0YWxDb2RlKGNvdW50cnlDb2RlLCB2YWx1ZSkge1xyXG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHRcdFx0bGV0IHVybCA9IGhpYWJjb25maWcuYWRkcmVzc2VzLmFwaUJhc2VVcmwgKyAnVmFsaWRhdGVQb3N0YWxDb2RlP2NvdW50cnlDb2RlPScrY291bnRyeUNvZGUrJyZwb3N0YWxjb2RlPScrdmFsdWU7XHJcblx0XHRcdHJlcXVlc3RcclxuXHRcdFx0XHQuZ2V0KHVybClcclxuXHRcdFx0XHQuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXHJcblx0XHRcdFx0LnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKVxyXG5cdFx0XHRcdC8vIC5zZW5kKGRhdGEpXHJcblx0XHRcdFx0LmVuZCgoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XHJcblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZygnQVBJJyk7XHJcblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyhyZXNwb25zZSk7XHJcblx0XHRcdFx0XHRpZihlcnJvcikge1xyXG5cdFx0XHRcdFx0XHRyZWplY3QoZXJyb3IgfHwgXCJubyByZXNwb25zZSBib2R5XCIpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcbn1cclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmxldCBhZGRjbGFzcyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0bGV0IGlzT25FeHBsb2RlZFZpZXdQYWdlID0gJCgnI2lsbHVzdHJhdGlvbicpLmxlbmd0aCA+IDAgPyB0cnVlIDogZmFsc2U7XHJcblx0XHR2YXIgdXJsUGFydHMgPSB3aW5kb3cubG9jYXRpb24uaHJlZi5zcGxpdCgnLycpO1xyXG5cdFx0dmFyIGV4cGxvZGVkVmlld1VybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzTmFtZUluVXJsO1xyXG5cdFx0Ly8gY29uc29sZS5sb2coaXNPbkV4cGxvZGVkVmlld1BhZ2UpO1xyXG5cdFx0Ly8gY29uc29sZS5sb2codXJsUGFydHMpO1xyXG5cdFx0Ly8gY29uc29sZS5sb2codXJsUGFydHMuaW5kZXhPZignZXhwbG9kZWQtdmlldycpKTtcclxuXHRcdC8vIGNvbnNvbGUubG9nKHVybFBhcnRzW3VybFBhcnRzLmluZGV4T2YoJ2V4cGxvZGVkLXZpZXcnKSArIDFdKTtcclxuXHJcblx0XHQkKCAnYm9keScgKS5vbignY2xpY2snLCAnW2RhdGEtYWRkLWNsYXNzXScsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0aWYoaXNPbkV4cGxvZGVkVmlld1BhZ2Upe1xyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHRpZigkKHRoaXMpLmF0dHIoJ2RhdGEtYnJhbmR0cmVlLWNsb3NlJykgPT09ICcnICYmIHVybFBhcnRzLmluZGV4T2YoZXhwbG9kZWRWaWV3VXJsKSAhPT0gLTEgJiYgdXJsUGFydHNbdXJsUGFydHMuaW5kZXhPZihleHBsb2RlZFZpZXdVcmwpICsgMV0gPT09ICcnKXtcclxuXHRcdFx0XHRcdGlmKGRvY3VtZW50LnJlZmVycmVyLnNwbGl0KCcvJylbMl0hPWxvY2F0aW9uLmhvc3RuYW1lKXtcclxuXHRcdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uLmhyZWYgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xyXG5cdFx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRcdGhpc3RvcnkuYmFjaygpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdCAgICAgIH1lbHNle1xyXG5cdFx0XHRcdFx0JCggJCh0aGlzKS5kYXRhKCAnYWRkLWNsYXNzJykgKS50b2dnbGVDbGFzcyggJCh0aGlzKS5kYXRhKCdhZGRlZC1jbGFzcycpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0JCggJCh0aGlzKS5kYXRhKCAnYWRkLWNsYXNzJykgKS50b2dnbGVDbGFzcyggJCh0aGlzKS5kYXRhKCdhZGRlZC1jbGFzcycpKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgYWRkY2xhc3M7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jYXJ0X2FjdGlvbnMnO1xyXG5pbXBvcnQgQ2FydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2FydF9zdG9yZSc7XHJcblxyXG5sZXQgYWRkdG9jYXJ0ID0ge1xyXG5cdGluaXQoKSB7XHJcblxyXG5cdFx0bGV0IGNoYW5nZVF1YW50aXR5O1xyXG5cdFx0bGV0IHByb2R1Y3RzTmJyID0gW107XHJcblxyXG5cdFx0ZnVuY3Rpb24gQ2FydElzV29ya2luZygpIHtcclxuXHRcdFx0cmV0dXJuICQoJyNjb250cm9sbC1jYXJ0JykuaGFzQ2xhc3MoJ2FkZGluZycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdCQoJy5hbW91bnQnKS5jaGFuZ2UoZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0bGV0IG5ld1F1YW50aXR5ID0gJCh0aGlzKS52YWwoKTtcclxuXHRcdFx0XHRsZXQgY29kZSA9ICQodGhpcykuYXR0cignZGF0YS1wcm9kdWN0LXNrdScpO1xyXG5cdFx0XHRcdGxldCBhbW91bnRFbGVtZW50cyA9ICQoXCIuYW1vdW50W2RhdGEtcHJvZHVjdC1za3U9J1wiICsgY29kZSArIFwiJ11cIik7XHJcblxyXG5cdFx0XHRcdGFtb3VudEVsZW1lbnRzLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHQkKHRoaXMpLnZhbChuZXdRdWFudGl0eSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pXHJcblxyXG5cdFx0JCgnLnByb2R1Y3QtZGV0YWlscGFnZSAuYW1vdW50JykudW5iaW5kKCdrZXl1cCcpLmJpbmQoJ2tleXVwJyxmdW5jdGlvbihldmVudCl7XHJcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0XHRpZiAoZXZlbnQud2hpY2ggPT0gMTMpIHtcclxuXHRcdFx0XHRsZXQgc2t1SUQgPSAkKHRoaXMpLmRhdGEoJ3Byb2R1Y3Qtc2t1Jyk7XHJcblxyXG5cdFx0XHRcdGlmKENhcnRJc1dvcmtpbmcoKSB8fMKgJCgnYnV0dG9uLmFkZC10by1jYXJ0W2RhdGEtcHJvZHVjdC1za3U9XCInICsgc2t1SUQgKyAnXCJdJykuaGFzQ2xhc3MoJ2xvYWRpbmcnKSkge1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0JCh0aGlzKS5hbmltYXRlKHtcclxuXHRcdFx0XHRcdGxpbmVIZWlnaHQ6IFwiNjBweFwiLFxyXG5cdFx0XHRcdFx0b3BhY2l0eTogXCIwLjFcIlxyXG5cdFx0XHRcdH0sIHtcclxuXHRcdFx0XHRcdGR1cmF0aW9uOiAzMDAsXHJcblx0XHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7XHJcblx0XHRcdFx0XHRcdGxpbmVIZWlnaHQ6IFwibGluZWFyXCJcclxuXHRcdFx0XHRcdH0sXHJcblx0XHRcdFx0XHRjb21wbGV0ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdCQodGhpcykuYW5pbWF0ZSh7XHJcblx0XHRcdFx0XHRcdFx0bGluZUhlaWdodDogXCIxOHB4XCIsXHJcblx0XHRcdFx0XHRcdFx0b3BhY2l0eTogXCIxXCJcclxuXHRcdFx0XHRcdFx0fSwgMjAwKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRsZXQgcXVhbnRpdHkgPSAkKHRoaXMpLnZhbCgpO1xyXG5cdFx0XHRcdCQoJyNjb250cm9sbC1jYXJ0JylbMF0uY2xhc3NOYW1lICs9ICcgYWRkaW5nJztcclxuXHRcdFx0XHQkKCcudWMtaGVhZGVyY2FydCcpWzBdLmNsYXNzTmFtZSArPSAnIGFkZGluZyc7XHJcblx0XHRcdFx0JCgnYnV0dG9uLmFkZC10by1jYXJ0W2RhdGEtcHJvZHVjdC1za3U9XCInICsgc2t1SUQgKyAnXCJdJykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHQkKCcudWMtaGVhZGVyY2FydCcpLnJlbW92ZUNsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHRcdHByb2R1Y3RzTmJyLnB1c2goc2t1SUQudG9TdHJpbmcoKSk7XHJcblx0XHRcdFx0Q2FydEFjdGlvbnMuYWRkQ2FydEl0ZW0oc2t1SUQsIHF1YW50aXR5KTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJ2J1dHRvbi5ub3QtYnV5YWJsZScsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0aWYoQ2FydElzV29ya2luZygpKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJ2J1dHRvbi5hZGQtdG8tY2FydCcsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuXHRcdFx0aWYoICQodGhpcykuaGFzQ2xhc3MoJ2xvYWRpbmcnKSB8fCAkKCdidXR0b24ucXVpY2stYnV5JykuaGFzQ2xhc3MoJ2xvYWRpbmcnKSApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdCQoJyNjb250cm9sbC1jYXJ0JylbMF0uY2xhc3NOYW1lICs9ICcgYWRkaW5nJztcclxuXHRcdFx0JCgnLnVjLWhlYWRlcmNhcnQnKVswXS5jbGFzc05hbWUgKz0gJyBhZGRpbmcnO1xyXG5cdFx0XHQkKHRoaXMpWzBdLmNsYXNzTmFtZSArPSAnIGxvYWRpbmcnO1xyXG5cdFx0XHRsZXQgc2t1SUQgPSAkKHRoaXMpLmRhdGEoJ3Byb2R1Y3Qtc2t1Jyk7XHJcblx0XHRcdGxldCBxdWFudGl0eSA9ICQoXCIuYW1vdW50W2RhdGEtcHJvZHVjdC1za3U9J1wiICsgc2t1SUQgKyBcIiddXCIpLnZhbCgpO1xyXG5cdFx0XHRpZiAoISBxdWFudGl0eSkge1xyXG5cdFx0XHRcdHF1YW50aXR5ID0gMTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IHByb2R1Y3RDb250ZXh0ID0gJCh0aGlzKS5wYXJlbnQoKS5kYXRhKCdwcm9kdWN0LWNvbnRleHQnKTtcclxuXHJcblx0XHRcdCQoJy51Yy1oZWFkZXJjYXJ0JykucmVtb3ZlQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdHByb2R1Y3RzTmJyLnB1c2goc2t1SUQudG9TdHJpbmcoKSk7XHJcblx0XHRcdENhcnRBY3Rpb25zLmFkZENhcnRJdGVtKHNrdUlELCBxdWFudGl0eSwgcHJvZHVjdENvbnRleHQpO1xyXG5cdFx0fSk7XHJcblxyXG5cclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnYnV0dG9uLnF1aWNrLWJ1eScsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cclxuXHRcdFx0aWYoQ2FydElzV29ya2luZygpKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQkKCcjY29udHJvbGwtY2FydCcpLmFkZENsYXNzKCdhZGRpbmcnKTtcclxuXHRcdFx0JCgnLnVjLWhlYWRlcmNhcnQnKS5hZGRDbGFzcygnYWRkaW5nJyk7XHJcblx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0bGV0IHNrdUlEID0gJCh0aGlzKS5kYXRhKCdwcm9kdWN0LXNrdScpO1xyXG5cdFx0XHRsZXQgcXVhbnRpdHkgPSAkKFwiLmFtb3VudFtkYXRhLXByb2R1Y3Qtc2t1PSdcIiArIHNrdUlEICsgXCInXVwiKS52YWwoKTtcclxuXHRcdFx0aWYgKCEgcXVhbnRpdHkpe1xyXG5cdFx0XHRcdHF1YW50aXR5ID0gMTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IHByb2R1Y3RDb250ZXh0ID0gJCh0aGlzKS5wYXJlbnQoKS5kYXRhKCdwcm9kdWN0LWNvbnRleHQnKTtcclxuXHJcblx0XHRcdCQoJy51Yy1oZWFkZXJjYXJ0JykucmVtb3ZlQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdENhcnRBY3Rpb25zLnF1aWNrQnV5KHNrdUlELCBxdWFudGl0eSwgcHJvZHVjdENvbnRleHQpO1xyXG5cclxuXHRcdH0pO1xyXG5cclxuXHJcblxyXG5cdFx0Q2FydFN0b3JlLmxpc3RlbiggKHJlcykgPT4ge1xyXG5cdFx0XHRsZXQgbnVtYmVyT2ZJdGVtc0NvbXBsZXRlZCA9IDA7XHJcblx0XHRcdGlmKCAkKCdbZGF0YS1wcm9kdWN0LXNrdV0nKS5sZW5ndGggPiAwIC8qJiYgISQoJy5kcmF3ZXItbWFpbicpLmhhc0NsYXNzKCdtb3ZlLWxlZnQnKSovKXtcclxuXHJcblx0XHRcdFx0Zm9yICh2YXIgaXRlbSBpbiByZXMuQWRkZWQpIHtcclxuXHRcdFx0XHRcdGlmIChyZXMuQWRkZWQuaGFzT3duUHJvcGVydHkoaXRlbSkpIHtcclxuXHRcdFx0XHRcdFx0bGV0IGluZGV4ID0gcHJvZHVjdHNOYnIuaW5kZXhPZihyZXMuQWRkZWRbaXRlbV0uQ29kZSk7XHJcblx0XHRcdFx0XHRcdGlmKGluZGV4ICE9PSAtMSl7XHJcblx0XHRcdFx0XHRcdFx0dmFyIGJ1dHRvbiA9ICQoJ2J1dHRvbltkYXRhLXByb2R1Y3Qtc2t1PVwiJyArIHJlcy5BZGRlZFtpdGVtXS5Db2RlICsgJ1wiXScpWzBdO1xyXG5cdFx0XHRcdFx0XHRcdGJ1dHRvbi5jbGFzc05hbWUgPSBidXR0b24uY2xhc3NOYW1lLnJlcGxhY2UoJyBsb2FkaW5nJywgJycpO1xyXG5cdFx0XHRcdFx0XHRcdHByb2R1Y3RzTmJyLnNwbGljZShpbmRleCwgMSk7XHJcblx0XHRcdFx0XHRcdFx0bnVtYmVyT2ZJdGVtc0NvbXBsZXRlZCsrO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRmb3IgKHZhciBpdGVtIGluIHJlcy5GYWlsZWQpIHtcclxuXHRcdFx0XHRcdGlmIChyZXMuRmFpbGVkLmhhc093blByb3BlcnR5KGl0ZW0pKSB7XHJcblx0XHRcdFx0XHRcdGxldCBpbmRleCA9IHByb2R1Y3RzTmJyLmluZGV4T2YocmVzLkZhaWxlZFtpdGVtXS5Db2RlKTtcclxuXHRcdFx0XHRcdFx0aWYoaW5kZXggIT09IC0xKXtcclxuXHRcdFx0XHRcdFx0XHR2YXIgYnV0dG9uID0gJCgnYnV0dG9uW2RhdGEtcHJvZHVjdC1za3U9XCInICsgcmVzLkZhaWxlZFtpdGVtXS5Db2RlICsgJ1wiXScpWzBdO1xyXG5cdFx0XHRcdFx0XHRcdGJ1dHRvbi5jbGFzc05hbWUgPSBidXR0b24uY2xhc3NOYW1lLnJlcGxhY2UoJyBsb2FkaW5nJywgJycpO1xyXG5cdFx0XHRcdFx0XHRcdHByb2R1Y3RzTmJyLnNwbGljZShpbmRleCwgMSk7XHJcblx0XHRcdFx0XHRcdFx0bnVtYmVyT2ZJdGVtc0NvbXBsZXRlZCsrO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR2YXIgaGVhZGVyQ2FydCA9ICQoJy51Yy1oZWFkZXJjYXJ0JylbMF07XHJcblx0XHRcdFx0dmFyIGNvbnRyb2xsQ2FydCA9ICQoJyNjb250cm9sbC1jYXJ0JylbMF07XHJcblx0XHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBudW1iZXJPZkl0ZW1zQ29tcGxldGVkOyBpKyspIHtcclxuXHRcdFx0XHRcdGhlYWRlckNhcnQuY2xhc3NOYW1lID0gaGVhZGVyQ2FydC5jbGFzc05hbWUucmVwbGFjZSgnIGFkZGluZycsICcnKTtcclxuXHRcdFx0XHRcdGNvbnRyb2xsQ2FydC5jbGFzc05hbWUgPSBjb250cm9sbENhcnQuY2xhc3NOYW1lLnJlcGxhY2UoJyBhZGRpbmcnLCAnJyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGFkZHRvY2FydDtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmxldCBhdXRvc3VibWl0ID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHQkKCdbZGF0YS1hdXRvc3VibWl0XScpLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdCQodGhpcykucGFyZW50cygnZm9ybScpLnN1Ym1pdCgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGF1dG9zdWJtaXQ7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgQnJhbmROYXZpZ2F0aW9uIGZyb20gJy4uL2NvbXBvbmVudHMvYnJhbmRuYXZpZ2F0aW9uL2JyYW5kbmF2aWdhdGlvbic7XHJcbmltcG9ydCBIaXN0b3J5U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9oaXN0b3J5X3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2hpc3RvcnlfYWN0aW9ucyc7XHJcbmltcG9ydCBNb2RlbFNlYXJjaCBmcm9tICcuLi9jb21wb25lbnRzL2JyYW5kbmF2aWdhdGlvbi9tb2RlbHNlYXJjaCc7XHJcbmltcG9ydCBNb2RlbFNlYXJjaFJlc3VsdCBmcm9tICcuLi9jb21wb25lbnRzL2JyYW5kbmF2aWdhdGlvbi9tb2RlbHNlYXJjaC1yZXN1bHQnO1xyXG5cclxubGV0IGJyYW5kdHJlZSA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0JCgnW2RhdGEtYnJhbmR0cmVlLWNsb3NlXScpLm9uKCdjbGljaycsIHRoaXMub25DbG9zZSk7XHJcblx0XHRpZigkKCcjYnJhbmR0cmVlLWxpc3R2aWV3JykubGVuZ3RoID4gMCkgUmVhY3RET00ucmVuZGVyKDxCcmFuZE5hdmlnYXRpb24vPiwgJCgnI2JyYW5kdHJlZS1saXN0dmlldycpWzBdKTtcclxuXHRcdGlmKCQoJyNtb2RlbC1zZWFyY2gnKS5sZW5ndGggPiAwKSBSZWFjdERPTS5yZW5kZXIoPE1vZGVsU2VhcmNoLz4sICQoJyNtb2RlbC1zZWFyY2gnKVswXSk7XHJcblx0XHRpZigkKCcjbW9kZWwtc2VhcmNoLXJlc3VsdCcpLmxlbmd0aCA+IDApIFJlYWN0RE9NLnJlbmRlcig8TW9kZWxTZWFyY2hSZXN1bHQvPiwgJCgnI21vZGVsLXNlYXJjaC1yZXN1bHQnKVswXSk7XHJcblx0fSxcclxuXHJcblx0b25DbG9zZSgpIHtcclxuXHRcdC8vUmVzZXQgaGlzdG9yeVxyXG5cdFx0SGlzdG9yeVN0b3JlLmluaXQoKTtcclxuXHRcdEhpc3RvcnlBY3Rpb25zLnN0b3JlVXBkYXRlZCgpO1xyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGJyYW5kdHJlZTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jYXJ0X2FjdGlvbnMnO1xyXG5pbXBvcnQgQ2FydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2FydF9zdG9yZSc7XHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuXHJcbmxldCBjbGVhcmNhcnQgPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdHZhciBlbGVtZW50O1xyXG5cclxuXHRcdCQoJy5pbm5lci13cmFwJykub24oJ2NsaWNrJywgJy5kby1jbGVhci1jYXJ0JywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0JCgnI2NoZWNrb3V0LWJ1dHRvbicpLnByb3AoXCJkaXNhYmxlZFwiLHRydWUpO1xyXG5cdFx0XHQkKCcuY2xlYXItY2FydCAuY2xvc2UnKS5wcm9wKFwiZGlzYWJsZWRcIix0cnVlKTtcclxuXHRcdFx0ZWxlbWVudCA9ICQodGhpcyk7XHJcblxyXG5cdFx0XHRsZXQgY2FydCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoQ2FydFN0b3JlLmdldFN0b3JlKCkpKTtcclxuXHRcdFx0Q3VzdG9tRXZlbnRzLmNsZWFyQ2FydEV2ZW50KGNhcnQuQ2FydC5DYXJ0SXRlbXMsIGNhcnQuQ2FydC5DYXJ0SWQpO1xyXG5cclxuXHRcdFx0Q2FydEFjdGlvbnMuY2xlYXJDYXJ0KCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRDYXJ0U3RvcmUubGlzdGVuKCAocmVzKSA9PiB7XHJcblx0XHRcdGlmKHJlcy5DYXJ0LkNhcnRJdGVtcyAmJiByZXMuQ2FydC5DYXJ0SXRlbXMubGVuZ3RoID09PSAwKXtcclxuXHRcdFx0XHRsZXQgcGF0aE5hbWVQYXJ0cyA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5zcGxpdCgnLycpLmZpbHRlcihmdW5jdGlvbihuKXsgcmV0dXJuIG4gIT09ICcnIH0pO1xyXG5cdFx0XHRcdGlmKHBhdGhOYW1lUGFydHNbcGF0aE5hbWVQYXJ0cy5sZW5ndGgtMV0gPT09ICdjaGVja291dCcpe1xyXG5cdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uLmhyZWYgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdGlmKGVsZW1lbnQpe1xyXG5cdFx0XHRcdFx0XHRlbGVtZW50LnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcblx0XHRcdFx0XHRcdCQoJy5jbGVhci1jYXJ0JykucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0XHRcdFx0JCgnI2NoZWNrb3V0LWJ1dHRvbicpLnByb3AoXCJkaXNhYmxlZFwiLGZhbHNlKTtcclxuXHRcdFx0XHRcdFx0JCgnLmNsZWFyLWNhcnQgLmNsb3NlJykucHJvcChcImRpc2FibGVkXCIsZmFsc2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHJcblx0fVxyXG59O1xyXG5cclxuXHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGVhcmNhcnQ7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcblxyXG5sZXQgY29tcGxhaW50dmlldyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICdbZGF0YS1wcm9kdWN0LWlkXScsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHR2YXIgY291bnQgPSAwO1xyXG5cdFx0XHQkKCcjY29tcGxhaW50IHVsLnRhYnMgbGkudGFiLXRpdGxlJykuZWFjaChmdW5jdGlvbigpe1xyXG5cdFx0XHRcdGlmKGNvdW50ID09PSAwKXtcclxuXHRcdFx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdFx0JCgnYScsICQodGhpcykpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHQkKHRoaXMpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHRcdCQoJ2EnLCAkKHRoaXMpKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgZmFsc2UpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRjb3VudCsrO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdHZhciBuZXRQcmljZSA9ICQodGhpcykuYXR0cignZGF0YS1uZXQtcHJpY2UnKTtcclxuXHRcdFx0aWYobmV0UHJpY2Upe1xyXG5cdFx0XHQkKCcjY29tcGxhaW50LXByaWNlLW5ldHByaWNlJykudmFsKG5ldFByaWNlLnNwbGl0KCcgJylbMF0ucmVwbGFjZSgnLCcsJy4nKSk7XHJcblx0XHRcdH1cclxuXHRcdFx0dmFyIGVuZEN1c3RvbWVyUHJpY2UgPSAkKHRoaXMpLmF0dHIoJ2RhdGEtZW5kLWN1c3RvbWVyLXByaWNlJyk7XHJcblx0XHRcdGlmKGVuZEN1c3RvbWVyUHJpY2Upe1xyXG5cdFx0XHRcdCQoJyNjb21wbGFpbnQtcHJpY2UtZW5kLWNvc3R1bWVyJykudmFsKGVuZEN1c3RvbWVyUHJpY2Uuc3BsaXQoJyAnKVswXS5yZXBsYWNlKCcsJywnLicpKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IGQgPSBuZXcgRGF0ZSgpO1xyXG5cdFx0XHRsZXQgbW9udGggPSBkLmdldE1vbnRoKCkgKyAxO1xyXG5cdFx0XHRsZXQgZGF5ID0gZC5nZXREYXRlKCk7XHJcblx0XHRcdGxldCBkYXRlID0gZC5nZXRGdWxsWWVhcigpICsgJyAtICcgK1xyXG5cdFx0XHRcdCgoJycgKyBtb250aCkubGVuZ3RoIDwgMiA/ICcwJyA6ICcnKSArIG1vbnRoICsgJyAtICcgK1xyXG5cdFx0XHRcdCgoJycgKyBkYXkpLmxlbmd0aCA8IDIgPyAnMCcgOiAnJykgKyBkYXk7XHJcblxyXG5cdFx0XHRpZighJCh0aGlzKS5kYXRhKFwiZGF0YS1pcy1idXlhYmxlXCIpKXtcclxuXHRcdFx0XHQkKCcjY29tcGxhaW50IHVsIGxpJykuaGlkZSgpO1xyXG5cdFx0XHRcdCQoJyNjb21wbGFpbnQgLnRhYnMtY29udGVudCAuY29udGVudCcpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHJcblx0XHRcdFx0JCgnI2NvbXBsYWludCB1bCBsaSBhW2hyZWY9XCIjb3RoZXJcIl0nKS5wYXJlbnQoKS5zaG93KCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdCQoJyNvdGhlcicpLnNob3coKS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblxyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdCQoJyMnICsgJCh0aGlzKS5kYXRhKFwiYWN0aXZlLXRhYlwiKSkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQkKCcjY29tcGxhaW50JykuZm91bmRhdGlvbigncmV2ZWFsJywgJ29wZW4nKTtcclxuXHJcblx0XHRcdCQoJy5jb21wbGFpbnQtcHJvZHVjdGlkJykudmFsKCQodGhpcykuZGF0YSgncHJvZHVjdC1pZCcpKTtcclxuXHRcdFx0JCgnLmNvbXBsYWludC1kYXRlJykudmFsKGRhdGUpO1xyXG5cclxuXHRcdFx0Ly8gJCgnI2NvbXBsYWludCAudGFicyBsaScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0Ly8gJCgnYVtocmVmPSMnICsgJCh0aGlzKS5kYXRhKFwiYWN0aXZlLXRhYlwiKSArICddJykucGFyZW50KCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cclxuXHJcblxyXG5cdFx0fSk7XHJcblxyXG5cclxuXHRcdCQoJyNjb21wbGFpbnQtYXZhaWxhYmlsaXR5LXN0YXR1cycpLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHtcclxuXHRcdFx0aWYoICQodGhpcykudmFsKCkgPT0gaGlhYmNvbmZpZy5jb21wbGFpbnRWaWV3LmxhbmcuYXZhaWxhYmlsaXR5U3RhdHVzT3RoZXIgKXtcclxuXHRcdFx0XHQkKCcuYXZhaWxhYmlsaXR5LXN0YXR1cy1vdGhlcicpLmNzcygnZGlzcGxheScsJ2Jsb2NrJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZXtcclxuXHRcdFx0XHQkKCcuYXZhaWxhYmlsaXR5LXN0YXR1cy1vdGhlcicpLmNzcygnZGlzcGxheScsJ25vbmUnKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cclxuXHRcdCQoJ2JvZHknKS5vbigndmFsaWQuZm5kdG4uYWJpZGUnLCAnI2NvbXBsYWludCAudGFicy1jb250ZW50IC5jb250ZW50LmFjdGl2ZSAucm93IGZvcm0nLCBmdW5jdGlvbihlKSB7XHJcblxyXG5cdFx0XHQvLyBkYXRhLW5ldC1wcmljZT1cIjIwXCIgZGF0YS1lbmQtY3VzdG9tZXItcHJpY2U9XCIyNVwiXHJcblxyXG5cdFx0XHRsZXQgZm9ybURhdGEgPSAkKCcjY29tcGxhaW50IC50YWJzLWNvbnRlbnQgLmNvbnRlbnQuYWN0aXZlIC5yb3cgZm9ybScpLnNlcmlhbGl6ZUFycmF5KCk7XHJcblx0XHRcdGxldCBmb3JtRGF0YU5pY2UgPSB7fTtcclxuXHRcdFx0Zm9yICh2YXIgdmFyaWFibGUgaW4gZm9ybURhdGEpIHtcclxuXHRcdFx0XHRpZiAoZm9ybURhdGEuaGFzT3duUHJvcGVydHkodmFyaWFibGUpKSB7XHJcblx0XHRcdFx0XHRpZiAoZm9ybURhdGFbdmFyaWFibGVdLm5hbWUgPT09ICdEYXRlJykge1xyXG5cdFx0XHRcdFx0XHR2YXIgZCA9IG5ldyBEYXRlKCk7XHJcblx0XHRcdFx0XHRcdGZvcm1EYXRhTmljZVtmb3JtRGF0YVt2YXJpYWJsZV0ubmFtZV0gPSAgZC50b1VUQ1N0cmluZygpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdGZvcm1EYXRhTmljZVtmb3JtRGF0YVt2YXJpYWJsZV0ubmFtZV0gPSBmb3JtRGF0YVt2YXJpYWJsZV0udmFsdWU7XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRmb3JtRGF0YU5pY2UuTWFya2V0SWQgPSBoaWFiY29uZmlnLm1hcmtldElkO1xyXG5cdFx0XHQvLyBjb25zb2xlLmxvZyhmb3JtRGF0YU5pY2UpO1xyXG5cdFx0XHR2YXIgZnJvbUlkID0gJCgnI2NvbXBsYWludCAudGFicy1jb250ZW50IC5jb250ZW50LmFjdGl2ZSBmb3JtJykuYXR0cignaWQnKTtcclxuXHRcdFx0dmFyIHVybDtcclxuXHJcblx0XHRcdHN3aXRjaCAoZnJvbUlkKSB7XHJcblx0XHRcdFx0Y2FzZSAnY29tcGxhaW50LXByaWNlJzpcclxuXHRcdFx0XHRcdHVybCA9ICcvYXBpLycraGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlKycvQ3VzdG9tZXJGZWVkYmFjay9QcmljZSc7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRjYXNlICdjb21wbGFpbnQtYXZhaWxhYmlsaXR5JzpcclxuXHRcdFx0XHRcdHVybCA9ICcvYXBpLycraGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlKycvQ3VzdG9tZXJGZWVkYmFjay9BdmFpbGFiaWxpdHknO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0Y2FzZSAnY29tcGxhaW50LW90aGVyJzpcclxuXHRcdFx0XHRcdHVybCA9ICcvYXBpLycraGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlKycvQ3VzdG9tZXJGZWVkYmFjay9PdGhlcic7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQkKCcjY29tcGxhaW50IC50YWJzLWNvbnRlbnQgLmNvbnRlbnQuYWN0aXZlIGZvcm0gYnV0dG9uLnNlbmQtY29tcGxhaW50JykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0JCgnI2NvbXBsYWludCAudGFicy1jb250ZW50IC5jb250ZW50LmFjdGl2ZSBmb3JtIC5lcnJvck1zZycpLmhpZGUoKTtcclxuXHRcdFx0JCgnI2NvbXBsYWludCAudGFicy1jb250ZW50IC5jb250ZW50LmFjdGl2ZSBmb3JtIC5zdWNjZXNzTXNnJykuaGlkZSgpO1xyXG5cdFx0XHQvLyAkLmFqYXhQcmVmaWx0ZXIoZnVuY3Rpb24gKG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIpIHtcclxuXHRcdFx0Ly9cclxuXHRcdFx0Ly8gfSk7XHJcblx0XHRcdCQuYWpheCh7XHJcblx0XHRcdFx0XHR0eXBlOiAnUE9TVCcsIC8vIGRlZmluZSB0aGUgdHlwZSBvZiBIVFRQIHZlcmIgd2Ugd2FudCB0byB1c2UgKFBPU1QgZm9yIG91ciBmb3JtKVxyXG5cdFx0XHRcdFx0dXJsOiB1cmwsIC8vIHRoZSB1cmwgd2hlcmUgd2Ugd2FudCB0byBQT1NUXHJcblx0XHRcdFx0XHRkYXRhOiBmb3JtRGF0YU5pY2UsIC8vIG91ciBkYXRhIG9iamVjdFxyXG5cdFx0XHRcdFx0aGVhZGVyczogeydYLVhTUkYtVG9rZW4nOiBmb3JtRGF0YU5pY2VbJ19fUmVxdWVzdFZlcmlmaWNhdGlvblRva2VuJ119XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0XHQvLyB1c2luZyB0aGUgZG9uZSBwcm9taXNlIGNhbGxiYWNrXHJcblx0XHRcdFx0LmRvbmUoZnVuY3Rpb24oZGF0YSkge1xyXG5cdFx0XHRcdFx0Ly8gbG9nIGRhdGEgdG8gdGhlIGNvbnNvbGUgc28gd2UgY2FuIHNlZVxyXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coZGF0YSk7XHJcblx0XHRcdFx0XHQkKCcjY29tcGxhaW50IC50YWJzLWNvbnRlbnQgLmNvbnRlbnQuYWN0aXZlIGZvcm0gLnN1Y2Nlc3NNc2cnKS5zaG93KCk7XHJcblx0XHRcdFx0XHQvLyBoZXJlIHdlIHdpbGwgaGFuZGxlIGVycm9ycyBhbmQgdmFsaWRhdGlvbiBtZXNzYWdlc1xyXG5cdFx0XHRcdFx0JCgnI2NvbXBsYWludCAudGFicy1jb250ZW50IC5jb250ZW50LmFjdGl2ZSBmb3JtIGJ1dHRvbi5zZW5kLWNvbXBsYWludCcpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0XHQuZXJyb3IoZnVuY3Rpb24oanFYSFIsICB0ZXh0U3RhdHVzLCBlcnJvclRocm93bikge1xyXG5cdFx0XHRcdC8vIFRPRE86IEhhbmRsZSBlcnJvclxyXG5cdFx0XHRcdCAgLy8gY29uc29sZS5sb2coICdSZXF1ZXN0IGZhaWxlZDoganFYSFIgJyArIHRleHRTdGF0dXMgKyAnIHRleHRTdGF0dXMgJyArIHRleHRTdGF0dXMgKyAnIGVycm9yVGhyb3duICcgKyBlcnJvclRocm93bik7XHJcblxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHQvLyBzdG9wIHRoZSBmb3JtIGZyb20gc3VibWl0dGluZyB0aGUgbm9ybWFsIHdheSBhbmQgcmVmcmVzaGluZyB0aGUgcGFnZVxyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cclxuXHRcdCQoJyNjb21wbGFpbnQgLnRhYnMtY29udGVudCAuY29udGVudCAucm93IGZvcm0nKS5lYWNoKGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0JCh0aGlzKS5vbignc3VibWl0JywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHQvL2NvbnNvbGUubG9nKCdzdGFubmEnKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblxyXG5cclxuXHRcdCQoJ2JvZHknKS5vbignY2hhbmdlJywgJyNjb21wbGFpbnQtYXZhaWxhYmlsaXR5LXN0YXR1cycsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0Ly9jb25zb2xlLmxvZygkKCcjY29tcGxhaW50LWF2YWlsYWJpbGl0eS1zdGF0dXMgb3B0aW9uOmxhc3Qtb2YtdHlwZScpLnRleHQoKS50cmltKCkpO1xyXG5cdFx0XHQvL2NvbnNvbGUubG9nKCQodGhpcykudmFsKCkpO1xyXG5cdFx0XHRpZigkKHRoaXMpLnZhbCgpID09PSAkKCcjY29tcGxhaW50LWF2YWlsYWJpbGl0eS1zdGF0dXMgb3B0aW9uOmxhc3Qtb2YtdHlwZScpLnRleHQoKS50cmltKCkpe1xyXG5cdFx0XHRcdCQoJyNjb21wbGFpbnQtYXZhaWxhYmlsaXR5LW90aGVyJykucGFyZW50KCkuc2hvdygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdCQoJyNjb21wbGFpbnQtYXZhaWxhYmlsaXR5LW90aGVyJykucGFyZW50KCkuaGlkZSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdC8vICQoJyMnICskKCcjY29tcGxhaW50IC50YWJzLWNvbnRlbnQgLmNvbnRlbnQuYWN0aXZlIGZvcm0nKS5hdHRyKCdpZCcpICkuZm91bmRhdGlvbigpO1xyXG5cdFx0fSk7XHJcblxyXG5cclxuXHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY29tcGxhaW50dmlldztcclxuIiwiaW1wb3J0IEN1c3RvbUV2ZW50cyBmcm9tICcuL2N1c3RvbS1ldmVudHMnO1xyXG5cclxubGV0IGNvbmZpcm1hdGlvblBhZ2UgPSB7XHJcbiAgaW5pdCgpe1xyXG4gICAgaWYoJCgnLnVjLWNoZWNrb3V0LWNhcnQtY29uZmlybWF0aW9uJykubGVuZ3RoID4gMCl7XHJcbiAgICAgIGlmKHBlcmZvcm1hbmNlLm5hdmlnYXRpb24udHlwZSAgIT0gMSApe1xyXG4gICAgICAgIC8vVVNFIFRISVMgTEFURVJcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgLy9jb25zb2xlLmxvZygncmVsb2FkJyk7XHJcbiAgICAgIH1cclxuICAgICAgdmFyIG9yZGVycyA9IGNvbmZpcm1hdGlvbkRhdGEub3JkZXJzO1xyXG4gICAgICBpZihvcmRlcnMubGVuZ3RoID4gMCl7XHJcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG9yZGVycy5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICB2YXIgb3JkZXIgPSBvcmRlcnNbaV07XHJcbiAgICAgICAgICBDdXN0b21FdmVudHMuY29uZmlybWF0aW9uUGFnZUFkZFRyYW5zKG9yZGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjb25maXJtYXRpb25QYWdlO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQganFjb29raWUgZnJvbSAnanF1ZXJ5LmNvb2tpZSc7XHJcblxyXG5sZXQgY29va2llID0ge1xyXG5cclxuICBpbml0OiBmdW5jdGlvbigpe1xyXG4gICAgdGhpcy5jbG9zZUNvb2tpZSgpO1xyXG5cclxuICAgIGlmKCQoJy5qc0Nvb2tpZXMnKS5sZW5ndGggPiAwKXtcclxuICAgICAgaWYoISQuY29va2llKCdoaWFiZWNvbS1jb29raWUnKSl7XHJcbiAgICAgICAgJCgnLmpzQ29va2llcycpLnNob3coKTtcclxuICAgICAgICAkLmNvb2tpZSgnaGlhYmVjb20tY29va2llJywgJ3t9JywgeyBleHBpcmVzOiAzMSwgcGF0aDogJy8nIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHZhciByZXMgPSBKU09OLnBhcnNlKCQuY29va2llKCdoaWFiZWNvbS1jb29raWUnKSk7XHJcbiAgICAgICAgaWYocmVzLmFwcHJvdmVkKXtcclxuICAgICAgICAgICQoJy5qc0Nvb2tpZXMnKS5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgJCgnLmpzQ29va2llcycpLnNob3coKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcblx0XHRpZigkKCcjbWFpbnRlbmFuY2UtYmFubmVyJykubGVuZ3RoID4gMCl7XHJcbiAgICAgIGxldCBtYWludGVuYW5jZUlkID0gJCgnI21haW50ZW5hbmNlLWJhbm5lcicpLmRhdGEoJ21haW50ZW5hbmNlLWlkJyk7XHJcbiAgICAgIGlmKCEkLmNvb2tpZSgnaGlhYmVjb20tbWFpbnRlbmFuY2UnK21haW50ZW5hbmNlSWQpKXtcclxuXHRcdFx0XHQkKCcjbWFpbnRlbmFuY2UtYmFubmVyJykuc2hvdygpO1xyXG4gICAgICAgICQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZScrbWFpbnRlbmFuY2VJZCwgJ3t9JywgeyBleHBpcmVzOiAzMSwgcGF0aDogJy8nIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHZhciByZXMgPSBKU09OLnBhcnNlKCQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZScrbWFpbnRlbmFuY2VJZCkpO1xyXG4gICAgICAgIGlmKHJlcy5hcHByb3ZlZCl7XHJcbiAgICAgICAgICAkKCcjbWFpbnRlbmFuY2UtYmFubmVyJykuaGlkZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICQoJyNtYWludGVuYW5jZS1iYW5uZXInKS5zaG93KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG5cdFx0aWYoJCgnI21haW50ZW5hbmNlLXRha2VvdmVyLmFjdGl2ZScpLmxlbmd0aCA+IDApe1xyXG4gICAgICBsZXQgbWFpbnRlbmFuY2VJZCA9ICQoJyNtYWludGVuYW5jZS10YWtlb3Zlci5hY3RpdmUnKS5kYXRhKCdtYWludGVuYW5jZS1pZCcpO1xyXG4gICAgICBpZighJC5jb29raWUoJ2hpYWJlY29tLW1haW50ZW5hbmNlLXRha2VvdmVyJyttYWludGVuYW5jZUlkKSl7XHJcblx0XHRcdFx0JCgnI21haW50ZW5hbmNlLXRha2VvdmVyJykuY3NzKCdkaXNwbGF5JywndGFibGUnKTtcclxuICAgICAgICAkKCdib2R5JykuYWRkQ2xhc3MoJ2hhcy1tYWludGVuYW5jZS10YWtlb3ZlcicpO1xyXG4gICAgICAgICQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZS10YWtlb3ZlcicrbWFpbnRlbmFuY2VJZCwgJ3t9JywgeyBleHBpcmVzOiAzMSwgcGF0aDogJy8nIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHZhciByZXMgPSBKU09OLnBhcnNlKCQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZS10YWtlb3ZlcicrbWFpbnRlbmFuY2VJZCkpO1xyXG4gICAgICAgIGlmKHJlcy5hcHByb3ZlZCl7XHJcbiAgICAgICAgICAkKCcjbWFpbnRlbmFuY2UtdGFrZW92ZXInKS5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgJCgnI21haW50ZW5hbmNlLXRha2VvdmVyJykuY3NzKCdkaXNwbGF5JywndGFibGUnKTtcclxuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKCdhZGQgY2xhc3MgdG8gYm9keSEnKTtcclxuXHRcdFx0XHRcdCQoJ2JvZHknKS5hZGRDbGFzcygnaGFzLW1haW50ZW5hbmNlLXRha2VvdmVyJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgY2xvc2VDb29raWU6IGZ1bmN0aW9uKCl7XHJcblxyXG4gICAgdmFyIG9rQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzQ29va2llc0J0bicpO1xyXG5cdFx0dmFyIG1haW50ZW5hbmNlQmFubmVyQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1haW50ZW5hbmNlLWJhbm5lci1idG4nKTtcclxuXHRcdHZhciBtYWludGVuYW5jZVRha2VvdmVyQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1haW50ZW5hbmNlLXRha2VvdmVyLWJ0bicpO1xyXG5cclxuICAgIGlmKG9rQnV0dG9uKXtcclxuICAgICAgKCdjbGljayB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hsZWF2ZSB0b3VjaGNhbmNlbCcuc3BsaXQoJyAnKSkuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICBva0J1dHRvbi5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgdmFyIHJlcyA9IEpTT04ucGFyc2UoJC5jb29raWUoJ2hpYWJlY29tLWNvb2tpZScpKTtcclxuICAgICAgICAgICQucmVtb3ZlQ29va2llKCdoaWFiZWNvbS1jb29raWUnLCB7IHBhdGg6ICcvJyB9KTtcclxuICAgICAgICAgIHJlcy5hcHByb3ZlZCA9IHRydWU7XHJcbiAgICAgICAgICAkLmNvb2tpZSgnaGlhYmVjb20tY29va2llJywgSlNPTi5zdHJpbmdpZnkocmVzKSwgeyBleHBpcmVzOiAzMSwgcGF0aDogJy8nIH0pO1xyXG4gICAgICAgICAgJCgnLmpzQ29va2llcycpLmhpZGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cdFx0aWYobWFpbnRlbmFuY2VCYW5uZXJCdXR0b24pe1xyXG4gICAgICBsZXQgbWFpbnRlbmFuY2VJZCA9ICQoJyNtYWludGVuYW5jZS1iYW5uZXInKS5kYXRhKCdtYWludGVuYW5jZS1pZCcpO1xyXG5cclxuICAgICAgKCdjbGljayB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hsZWF2ZSB0b3VjaGNhbmNlbCcuc3BsaXQoJyAnKSkuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICBtYWludGVuYW5jZUJhbm5lckJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgdmFyIHJlcyA9IEpTT04ucGFyc2UoJC5jb29raWUoJ2hpYWJlY29tLW1haW50ZW5hbmNlJyttYWludGVuYW5jZUlkKSk7XHJcbiAgICAgICAgICAkLnJlbW92ZUNvb2tpZSgnaGlhYmVjb20tbWFpbnRlbmFuY2UnK21haW50ZW5hbmNlSWQsIHsgcGF0aDogJy8nIH0pO1xyXG4gICAgICAgICAgcmVzLmFwcHJvdmVkID0gdHJ1ZTtcclxuICAgICAgICAgICQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZScrbWFpbnRlbmFuY2VJZCwgSlNPTi5zdHJpbmdpZnkocmVzKSwgeyBleHBpcmVzOiAzMSwgcGF0aDogJy8nIH0pO1xyXG4gICAgICAgICAgJCgnI21haW50ZW5hbmNlLWJhbm5lcicpLmhpZGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cdFx0aWYobWFpbnRlbmFuY2VUYWtlb3ZlckJ1dHRvbil7XHJcbiAgICAgIGxldCBtYWludGVuYW5jZUlkID0gJCgnI21haW50ZW5hbmNlLXRha2VvdmVyLmFjdGl2ZScpLmRhdGEoJ21haW50ZW5hbmNlLWlkJyk7XHJcblxyXG4gICAgICAoJ2NsaWNrIHRvdWNobW92ZSB0b3VjaGVuZCB0b3VjaGxlYXZlIHRvdWNoY2FuY2VsJy5zcGxpdCgnICcpKS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIG1haW50ZW5hbmNlVGFrZW92ZXJCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIHZhciByZXMgPSBKU09OLnBhcnNlKCQuY29va2llKCdoaWFiZWNvbS1tYWludGVuYW5jZS10YWtlb3ZlcicrbWFpbnRlbmFuY2VJZCkpO1xyXG4gICAgICAgICAgJC5yZW1vdmVDb29raWUoJ2hpYWJlY29tLW1haW50ZW5hbmNlLXRha2VvdmVyJyttYWludGVuYW5jZUlkLCB7IHBhdGg6ICcvJyB9KTtcclxuICAgICAgICAgIHJlcy5hcHByb3ZlZCA9IHRydWU7XHJcbiAgICAgICAgICAkLmNvb2tpZSgnaGlhYmVjb20tbWFpbnRlbmFuY2UtdGFrZW92ZXInK21haW50ZW5hbmNlSWQsIEpTT04uc3RyaW5naWZ5KHJlcyksIHsgZXhwaXJlczogMzEsIHBhdGg6ICcvJyB9KTtcclxuICAgICAgICAgICQoJyNtYWludGVuYW5jZS10YWtlb3ZlcicpLmhpZGUoKTtcclxuXHRcdFx0XHRcdCQoJ2JvZHknKS5yZW1vdmVDbGFzcygnaGFzLW1haW50ZW5hbmNlLXRha2VvdmVyJyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjb29raWU7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcblxyXG5sZXQgQ3VzdG9tRXZlbnRzID0ge1xyXG5cdGluaXQ6IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7XHJcbiAgICAgIGluaXRFdmVudHMoKTtcclxuICBcdH0pO1xyXG5cdH0sXHJcblx0dHJpZ2dlckRhdGFMYXllclB1c2g6IGZ1bmN0aW9uKG9iamVjdCl7XHJcblx0XHRpZihoaWFiY29uZmlnLkVuYWJsZUdvb2dsZVRhZ01hbmFnZXIpe1xyXG5cdFx0XHRkYXRhTGF5ZXIucHVzaChvYmplY3QpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblx0dHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2g6IGZ1bmN0aW9uKG9iamVjdCl7XHJcblx0XHRpZihoaWFiY29uZmlnLkVuYWJsZUdvb2dsZVRhZ01hbmFnZXIpe1xyXG5cdFx0XHR3aW5kb3cuZGF0YUxheWVyLnB1c2gob2JqZWN0KTtcclxuXHRcdH1cclxuXHR9LFxyXG4gIHRyaWdnZXJMb2dpbkV2ZW50OiBmdW5jdGlvbihib2R5KXtcclxuICAgIGlmKCF3aW5kb3cuZGF0YUxheWVyKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgdmFyIGNvbW1vbkNvbnRleHQgPSBKU09OLnBhcnNlKGJvZHkuQ29tbW9uQ29udGV4dCk7XHJcblxyXG4gICAgQ3VzdG9tRXZlbnRzLnRyaWdnZXJEYXRhTGF5ZXJQdXNoKHtcclxuICAgICAgJ2V2ZW50JzogJ3RyYWNrTG9naW5FdmVudCcsXHJcbiAgICAgICdjb21tb25Db250ZXh0JzogY29tbW9uQ29udGV4dFxyXG4gICAgICB9KTtcclxuICB9LFxyXG4gIHRyaWdnZXJMb2dvdXRFdmVudDogZnVuY3Rpb24oYm9keSl7XHJcbiAgICBpZighd2luZG93LmRhdGFMYXllcikgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyRGF0YUxheWVyUHVzaCh7XHJcbiAgICAgICdldmVudCc6ICd0cmFja0xvZ291dEV2ZW50JyxcclxuICAgICAgJ2NvbW1vbkNvbnRleHQnOiBib2R5LkNvbW1vbkNvbnRleHRcclxuICAgICAgfSk7XHJcbiAgfSxcclxuICB0cmlnZ2VyU2xpZGVyQWRJbXByZXNzaW9uRXZlbnQ6IGZ1bmN0aW9uKGVsKXtcclxuICAgICAgdmFyIHNsaWRlSW1nID0gJChlbCkuZmluZCgnLmFjdGl2ZScpLmZpbmQoJy5zbGlkZS1pbWcnKSxcclxuICAgICAgICAgIGJhbm5lcklkID0gc2xpZGVJbWcuZGF0YSgnYmFubmVyLWlkJyksXHJcbiAgICAgICAgICB6b25lSWQgPSBzbGlkZUltZy5kYXRhKCd6b25lLWlkJyksXHJcbiAgICAgICAgICBiYW5uZXJOYW1lID0gc2xpZGVJbWcuZGF0YSgnYmFubmVyLW5hbWUnKSxcclxuICAgICAgICAgIGJhbm5lclR5cGUgPSBzbGlkZUltZy5kYXRhKCdiYW5uZXItdHlwZScpLFxyXG4gICAgICAgICAgYmFubmVySW5zdGFuY2UgPSBzbGlkZUltZy5kYXRhKCdiYW5uZXItaW5zdGFuY2UnKTtcclxuXHJcbiAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyRGF0YUxheWVyUHVzaCh7XHJcbiAgICAgICAgJ2V2ZW50JzogJ3RyYWNrQWRJbXByZXNzaW9uJyxcclxuICAgICAgICAnYWRDb250ZXh0Jzoge1xyXG4gICAgICAgICAgXCJiYW5uZXJfbmFtZVwiOiBiYW5uZXJOYW1lLFxyXG4gICAgICAgICAgXCJiYW5uZXJfdHlwZVwiOiBiYW5uZXJUeXBlLFxyXG4gICAgICAgICAgXCJiYW5uZXJfaW5zdGFuY2VcIjogYmFubmVySW5zdGFuY2V9LFxyXG4gICAgICAgICdiYW5uZXJJZCc6IGJhbm5lcklkLFxyXG4gICAgICAgICd6b25lSWQnOiB6b25lSWRcclxuICAgICAgfSk7XHJcbiAgfSxcclxuICB0cmlnZ2VyU2xpZGVyQWRDbGlja0V2ZW50OiBmdW5jdGlvbihlKSB7XHJcbiAgICAgIHZhciBlbCA9ICQoZS50YXJnZXQpLFxyXG5cdFx0XHRcdHNsaWRlckltZyA9IGVsLnBhcmVudHMoJy5zbGlkZS1pbWcnKSxcclxuXHRcdFx0XHRiYW5uZXJJZCA9IHNsaWRlckltZy5kYXRhKCdiYW5uZXItaWQnKSxcclxuXHRcdFx0XHR6b25lSWQgPSBzbGlkZXJJbWcuZGF0YSgnem9uZS1pZCcpLFxyXG5cdFx0XHRcdGJhbm5lck5hbWUgPSBzbGlkZXJJbWcuZGF0YSgnYmFubmVyLW5hbWUnKSxcclxuXHRcdFx0XHRiYW5uZXJUeXBlID0gc2xpZGVySW1nLmRhdGEoJ2Jhbm5lci10eXBlJyksXHJcblx0XHRcdFx0YmFubmVySW5zdGFuY2UgPSBzbGlkZXJJbWcuZGF0YSgnYmFubmVyLWluc3RhbmNlJyk7XHJcblxyXG5cdFx0XHRDdXN0b21FdmVudHMudHJpZ2dlckRhdGFMYXllclB1c2goe1xyXG5cdFx0XHRcdCdldmVudCc6ICd0cmFja0FkQ2xpY2snLFxyXG5cdFx0XHRcdCdhZENvbnRleHQnOiB7XCJiYW5uZXJfbmFtZVwiOiBiYW5uZXJOYW1lLCBcImJhbm5lcl90eXBlXCI6IGJhbm5lclR5cGUsIFwiYmFubmVyX2luc3RhbmNlXCI6IGJhbm5lckluc3RhbmNlfSxcclxuXHRcdFx0XHQnYmFubmVySWQnOiBiYW5uZXJJZCxcclxuXHRcdFx0XHQnem9uZUlkJzogem9uZUlkXHJcblx0XHRcdH0pO1xyXG4gIH0sXHJcblx0dHJpZ2dlckltcGVyc29uYXRpb25TdGFydEV2ZW50OiBmdW5jdGlvbihib2R5KSB7XHJcblx0XHRDdXN0b21FdmVudHMudHJpZ2dlckRhdGFMYXllclB1c2goe1xyXG5cdFx0XHQnZXZlbnQnOiAnaW1wZXJzb25hdGlvblN0YXJ0JyxcclxuXHRcdFx0J2NhdGVnb3J5JzogJ2FkbWluJyxcclxuICAgICAgJ2FjdGlvbic6ICdpbXBlcnNvbmF0ZScsXHJcbiAgICAgICdsYWJlbCc6IGJvZHkuQ3VzdG9tZXJOYW1lLFxyXG4gICAgICAndmFsdWUnOiBib2R5LkN1c3RvbWVySWRcclxuICAgIH0pO1xyXG5cdH0sXHJcbiAgYWRkVG9DYXJ0RXZlbnQ6IGZ1bmN0aW9uKHByb2R1Y3RzLCBjYXJ0LCBwcm9kdWN0Q29udGV4dCkge1xyXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IHByb2R1Y3RzLmxlbmd0aDsgaSsrKXtcclxuICAgICAgdmFyIHByb2R1Y3QgPSBwcm9kdWN0c1tpXTtcclxuXHJcbiAgICAgIHZhciB0cmFja2luZ0V2ZW50ID0gcHJvZHVjdC5VcGRhdGVkID8gJ21vZGlmeUNhcnQnIDogJ2FkZFRvQ2FydEV2ZW50JztcclxuICAgICAgQ3VzdG9tRXZlbnRzLnRyaWdnZXJXaW5kb3dEYXRhTGF5ZXJQdXNoKHtcclxuXHRcdFx0XHQnZXZlbnQnOiB0cmFja2luZ0V2ZW50LFxyXG5cdFx0XHRcdCdjYXJ0Q29udGV4dCc6IHtcclxuICAgICAgICAgIHNrdTogcHJvZHVjdC5Db2RlLFxyXG4gICAgICAgICAgbmFtZTogcHJvZHVjdC5EaXNwbGF5TmFtZSxcclxuICAgICAgICAgIGNhdGVnb3J5OiBoaWFiY29uZmlnLnRyYWNraW5nLmNhdGVnb3J5LFxyXG4gICAgICAgICAgbmV0UHJpY2U6IHByb2R1Y3QuUGxhY2VkUHJpY2UsXHJcbiAgICAgICAgICBvbGRfcXVhbnRpdHk6IHByb2R1Y3QuT2xkUXVhbnRpdHksXHJcbiAgICAgICAgICBxdWFudGl0eTogcHJvZHVjdC5RdWFudGl0eSArIHByb2R1Y3QuT2xkUXVhbnRpdHksXHJcbiAgICAgICAgICBjdXJyZW5jeTogY2FydC5DdXJyZW5jeSxcclxuXHRcdFx0XHRcdGNhcnRDb250ZW50OiBjYXJ0LkNhcnRJdGVtcyxcclxuXHRcdFx0XHRcdGNhcnRJZDogY2FydC5DYXJ0SWRcclxuICAgICAgICB9LFxyXG4gICAgICAgICdwcm9kdWN0Q29udGV4dCc6IHByb2R1Y3RDb250ZXh0XHJcblx0XHRcdH0pO1xyXG4gICAgfVxyXG4gIH0sXHJcbiAgdHJpZ2dlckFkZFRvQ2FydEJhdGNoRXZlbnQ6IGZ1bmN0aW9uKHByb2R1Y3RzLCBjYXJ0KSB7XHJcbiAgICBiYXRjaENhcnRFdmVudChjYXJ0LCAnYmF0Y2hBZGRUb0NhcnQnLCAnYWRkdG9jYXJ0Jyk7XHJcbiAgfSxcclxuICB0cmlnZ2VyUXVpY2tCdXlCYXRjaEV2ZW50OiBmdW5jdGlvbihwcm9kdWN0cywgY2FydCkge1xyXG4gICAgYmF0Y2hDYXJ0RXZlbnQoY2FydCwgJ2JhdGNoUXVpY2tidXknLCAncXVpY2tidXknKTtcclxuICB9LFxyXG5cdGxvYWRDYXJ0RXZlbnQ6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XHJcblx0XHRDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goe1xyXG5cdFx0XHQnZXZlbnQnOiAnbG9hZENhcnQnLFxyXG5cdFx0XHQnY2FydENvbnRleHQnOiB7XHJcblx0XHRcdFx0Y2FydENvbnRlbnQ6IHJlc3BvbnNlLkNhcnQuQ2FydEl0ZW1zLFxyXG5cdFx0XHRcdGNhcnRJZDogcmVzcG9uc2UuQ2FydC5DYXJ0SWRcclxuXHRcdFx0fSxcclxuXHRcdFx0J2NhdGVnb3J5JzogJ21pbmljYXJ0J1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHRsb2FkQ2FydEV2ZW50Q2hlY2tvdXQ6IGZ1bmN0aW9uKGNhcnRDb250ZW50LCBjYXJ0SWQpIHtcclxuXHJcblx0XHRDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goe1xyXG5cdFx0XHQnZXZlbnQnOiAnbG9hZENhcnQnLFxyXG5cdFx0XHQnY2FydENvbnRleHQnOiB7XHJcblx0XHRcdFx0Y2FydENvbnRlbnQ6IGNhcnRDb250ZW50LFxyXG5cdFx0XHRcdGNhcnRJZDogY2FydElkXHJcblx0XHRcdH0sXHJcblx0XHRcdCdjYXRlZ29yeSc6ICdjaGVja291dCdcclxuXHRcdH0pO1xyXG5cdH0sXHJcblx0Y2xlYXJDYXJ0RXZlbnQ6IGZ1bmN0aW9uKGNhcnRDb250ZW50LCBjYXJ0SWQpIHtcclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdldmVudCc6ICdjbGVhckNhcnQnLFxyXG5cdFx0XHQnY2FydENvbnRleHQnOiB7XHJcblx0XHRcdFx0Y2FydENvbnRlbnQ6IGNhcnRDb250ZW50LFxyXG5cdFx0XHRcdGNhcnRJZDogY2FydElkXHJcblx0XHRcdH0sXHJcblx0XHRcdCdjYXRlZ29yeSc6ICdtaW5pY2FydCdcclxuXHRcdH0pO1xyXG5cdH0sXHJcbiAgbW9kaWZ5Q2FydEV2ZW50OiBmdW5jdGlvbihyZXNwb25zZSkge1xyXG5cdFx0dmFyIGxpbmUgPSBnZXRMaW5lKHJlc3BvbnNlLkNhcnQuQ2FydEl0ZW1zLCByZXNwb25zZS5Qcm9kdWN0Q29udGV4dC5QYXJ0TnVtYmVyKTtcclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdldmVudCc6ICdtb2RpZnlDYXJ0JyxcclxuXHRcdFx0J2NhcnRDb250ZXh0Jzoge1xyXG5cdFx0XHRcdHNrdTogbGluZS5Db2RlLFxyXG5cdFx0XHRcdG5hbWU6IGxpbmUuRGlzcGxheU5hbWUsXHJcblx0XHRcdFx0Y2F0ZWdvcnk6ICdtaW5pY2FydCcsXHJcblx0XHRcdFx0bmV0UHJpY2U6IGxpbmUuUGxhY2VkUHJpY2UsXHJcblx0XHRcdFx0b2xkX3F1YW50aXR5OiByZXNwb25zZS5PbGRRdWFudGl0eSxcclxuXHRcdFx0XHRxdWFudGl0eTogbGluZS5RdWFudGl0eSxcclxuXHRcdFx0XHRjdXJyZW5jeTogcmVzcG9uc2UuQ2FydC5DdXJyZW5jeSxcclxuXHRcdFx0XHRjYXJ0Q29udGVudDogcmVzcG9uc2UuQ2FydC5DYXJ0SXRlbXMsXHJcblx0XHRcdFx0Y2FydElkOiByZXNwb25zZS5DYXJ0LkNhcnRJZFxyXG5cdFx0XHR9LFxyXG5cdFx0XHQncHJvZHVjdENvbnRleHQnOiByZXNwb25zZS5Qcm9kdWN0Q29udGV4dCxcclxuXHRcdFx0J2NhdGVnb3J5JzogJ21pbmljYXJ0J1xyXG5cdFx0fSk7XHJcbiAgfSxcclxuICBkZWxldGVDYXJ0RXZlbnQ6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XHJcbiAgICAgIHZhciBsaW5lID0gcmVzcG9uc2UuRGVsZXRlZExpbmU7XHJcbiAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdFx0ICAnZXZlbnQnOiAnbW9kaWZ5Q2FydCcsXHJcblx0XHRcdFx0ICAnY2FydENvbnRleHQnOiB7XHJcbiAgICAgICAgICAgIHNrdTogbGluZS5Db2RlLFxyXG4gICAgICAgICAgICBuYW1lOiBsaW5lLkRpc3BsYXlOYW1lLFxyXG4gICAgICAgICAgICBjYXRlZ29yeTogJ21pbmljYXJ0JyxcclxuICAgICAgICAgICAgbmV0UHJpY2U6IGxpbmUuUGxhY2VkUHJpY2UsXHJcbiAgICAgICAgICAgIG9sZF9xdWFudGl0eTogbGluZS5RdWFudGl0eSxcclxuICAgICAgICAgICAgcXVhbnRpdHk6IDAsXHJcbiAgICAgICAgICAgIGN1cnJlbmN5OiByZXNwb25zZS5DYXJ0LkN1cnJlbmN5LFxyXG5cdFx0XHRcdFx0XHRjYXJ0Q29udGVudDogcmVzcG9uc2UuQ2FydC5DYXJ0SXRlbXMsXHJcblx0XHRcdFx0XHRcdGNhcnRJZDogcmVzcG9uc2UuQ2FydC5DYXJ0SWRcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICAncHJvZHVjdENvbnRleHQnOiByZXNwb25zZS5Qcm9kdWN0Q29udGV4dCxcclxuICAgICAgICAgICdjYXRlZ29yeSc6ICdtaW5pY2FydCdcclxuXHRcdFx0fSk7XHJcbiAgfSxcclxuICBtb2RpZnlDYXJ0RXZlbnRGcm9tQ2hlY2tvdXQ6IGZ1bmN0aW9uKHJlcykge1xyXG5cdFx0dmFyIHRyYWNraW5nRGF0YSA9IHJlcy5UcmFja2luZ0RhdGE7XHJcblx0XHR2YXIgY2FydENvbnRleHQgPSBKU09OLnBhcnNlKHRyYWNraW5nRGF0YS5DYXJ0Q29udGV4dCk7XHJcblxyXG5cdFx0Y2FydENvbnRleHQuY2FydElkID0gdHJhY2tpbmdEYXRhLkNhcnRJZDtcclxuXHRcdGNhcnRDb250ZXh0LmNhcnRDb250ZW50ID0gdHJhY2tpbmdEYXRhLkNhcnRDb250ZW50O1xyXG5cclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdldmVudCc6ICdtb2RpZnlDYXJ0JyxcclxuXHRcdFx0J2NhcnRDb250ZXh0JzogY2FydENvbnRleHQsXHJcblx0XHRcdCdwcm9kdWN0Q29udGV4dCc6IHRyYWNraW5nRGF0YS5Qcm9kdWN0Q29udGV4dCxcclxuXHRcdFx0J2NhdGVnb3J5JzogJ2NoZWNrb3V0J1xyXG5cdFx0fSk7XHJcbiAgfSxcclxuXHRiYXRjaFVwbG9hZDogZnVuY3Rpb24oZGF0YSl7XHJcblx0XHRsZXQgbWF0ZXJpYWxzID0gW107XHJcblx0XHQkLmVhY2goZGF0YS5yZXN1bHQuQnV5YWJsZXMsIGZ1bmN0aW9uIChpbmRleCwgdmFsdWUpIHtcclxuXHRcdFx0bWF0ZXJpYWxzLnB1c2godmFsdWUuTWF0ZXJpYWxJZCk7XHJcblx0XHR9KTtcclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdiYXRjaEltcG9ydENvbnRleHQnIDoge1xyXG5cdFx0XHRcdCdyb3dfY291bnQnOiBkYXRhLnJlc3VsdC5CdXlhYmxlcy5sZW5ndGggKyBkYXRhLnJlc3VsdC5FcnJvcnMubGVuZ3RoLFxyXG5cdFx0XHRcdCdmYWlsX2NvdW50JzogZGF0YS5yZXN1bHQuRXJyb3JzLmxlbmd0aCxcclxuXHRcdFx0XHQnaW1wb3J0X2NvdW50JzogZGF0YS5yZXN1bHQuQnV5YWJsZXMubGVuZ3RoLFxyXG5cdFx0XHRcdCdmaWxlX3R5cGUnOiBkYXRhLmZpbGVzWzBdLm5hbWUuaW5jbHVkZXMoJy54bHMnKSA/ICdFeGNlbCcgOiAnQ1NWJyxcclxuXHRcdFx0XHQnbWF0ZXJpYWxzJzogbWF0ZXJpYWxzXHJcblx0XHRcdH0sXHJcblx0XHRcdCdjdXN0b21TdHJ1Y3R1cmVkRXZlbnQnIDoge1xyXG5cdFx0XHRcdCdjYXRlZ29yeSc6ICdiYXRjaCcsXHJcblx0XHRcdFx0J2FjdGlvbic6ICdpbXBvcnQnXHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0sXHJcblx0YmF0Y2hBZGRSb3c6IGZ1bmN0aW9uIChvcmRlcmxpbmUpIHtcclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdjdXN0b21TdHJ1Y3R1cmVkRXZlbnQnIDoge1xyXG5cdFx0XHRcdCdDYXRlZ29yeSc6ICdiYXRjaCcsXHJcblx0XHRcdFx0J0FjdGlvbic6ICdhZGQnLFxyXG5cdFx0XHRcdCdMYWJlbCc6IG9yZGVybGluZS5tYXRlcmlhbCxcclxuXHRcdFx0XHQnVmFsdWUnOiBvcmRlcmxpbmUucXVhbnRpdHlcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHRiYXRjaFJlbW92ZVJvdzogZnVuY3Rpb24gKGlkKXtcclxuXHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaCh7XHJcblx0XHRcdCdjdXN0b21TdHJ1Y3R1cmVkRXZlbnQnOiB7XHJcblx0XHQgICAgJ0NhdGVnb3J5JzogJ2JhdGNoJyxcclxuXHRcdCAgICAnQWN0aW9uJzogJ3JlbW92ZScsXHJcblx0XHQgICAgJ0xhYmVsJzogaWRcclxuXHRcdCAgfVxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHRjb25maXJtYXRpb25QYWdlQWRkVHJhbnM6IGZ1bmN0aW9uIChvcmRlcil7XHJcbiAgICB2YXIgdHJhbnNhY3Rpb25Qcm9kdWN0cyA9IFtdO1xyXG4gICAgZm9yKHZhciBpID0gMDsgaSA8IG9yZGVyLml0ZW1zLmxlbmd0aDsgaSsrKXtcclxuICAgICAgdmFyIGl0ZW0gPSBvcmRlci5pdGVtc1tpXTtcclxuICAgICAgdHJhbnNhY3Rpb25Qcm9kdWN0cy5wdXNoKGNvbmZpcm1hdGlvblBhZ2VBZGRJdGVtKGl0ZW0pKTtcclxuICAgIH1cclxuXHJcbiAgICBDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goe1xyXG4gICAgICAnZXZlbnQnOiAnb3JkZXJDb25maXJtYXRpb24nLFxyXG4gICAgICAndHJhbnNhY3Rpb25JZCc6IG9yZGVyLm9yZGVySWQsXHJcbiAgICAgICd0cmFuc2FjdGlvbkFmZmlsaWF0aW9uJzogJycsXHJcbiAgICAgICd0cmFuc2FjdGlvblRvdGFsJzogb3JkZXIudG90YWwsXHJcbiAgICAgICd0cmFuc2FjdGlvblRheCc6ICcnLFxyXG4gICAgICAndHJhbnNhY3Rpb25TaGlwcGluZyc6IG9yZGVyLnNoaXBwaW5nLFxyXG4gICAgICAndHJhbnNhY3Rpb25DaXR5Jzogb3JkZXIuY2l0eSxcclxuICAgICAgJ3RyYW5zYWN0aW9uQ291bnRyeSc6IG9yZGVyLmNvdW50cnksXHJcbiAgICAgICd0cmFuc2FjdGlvblN0YXRlJzogb3JkZXIuc3RhdGUsXHJcbiAgICAgICdjdXJyZW5jeSc6IG9yZGVyLmN1cnJlbmN5LFxyXG4gICAgICAnb3JkZXJDb250ZXh0Jzp7XHJcbiAgICAgICAgJ3NoaXBwaW5nX29wdGlvbic6IG9yZGVyLnNoaXBwaW5nX29wdGlvbixcclxuICAgICAgICAncHJpb3JpdHknOiBvcmRlci5wcmlvcml0eSxcclxuICAgICAgICAnZGVsaXZlcnlfZGF0ZSc6IG9yZGVyLmRlbGl2ZXJ5X2RhdGUsXHJcbiAgICAgICAgJ29yZGVyX3Byb21vdGlvbic6IG9yZGVyLm9yZGVyX3Byb21vdGlvbixcclxuICAgICAgICAncGxhbnQnOiBvcmRlci5wbGFudFxyXG4gICAgICB9LFxyXG4gICAgICAndHJhbnNhY3Rpb25Qcm9kdWN0cyc6IHRyYW5zYWN0aW9uUHJvZHVjdHNcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5mdW5jdGlvbiBnZXRMaW5lKGxpbmVzLCBjb2RlKSB7XHJcbiAgZm9yKHZhciBpPTA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgaWYgKGxpbmVzW2ldLkNvZGUgPT09IGNvZGUpIHtcclxuICAgICAgcmV0dXJuIGxpbmVzW2ldO1xyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gbnVsbDtcclxufVxyXG5mdW5jdGlvbiBnZXRTZWFyY2hQYXJhbSgpIHtcclxuICAgIHZhciBzUGFnZVVSTCA9IGRlY29kZVVSSUNvbXBvbmVudCh3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKSksXHJcbiAgICAgICAgc1VSTFZhcmlhYmxlcyA9IHNQYWdlVVJMLnNwbGl0KCcmJyksXHJcbiAgICAgICAgc1BhcmFtZXRlck5hbWUsXHJcbiAgICAgICAgaTtcclxuXHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgc1VSTFZhcmlhYmxlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHNQYXJhbWV0ZXJOYW1lID0gc1VSTFZhcmlhYmxlc1tpXS5zcGxpdCgnPScpO1xyXG4gICAgICAgIGlmIChzUGFyYW1ldGVyTmFtZVswXSA9PT0gJ3F1ZXJ5Jykge1xyXG4gICAgICAgICAgICByZXR1cm4gc1BhcmFtZXRlck5hbWVbMV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGJhdGNoQ2FydEV2ZW50KGNhcnQsIGV2ZW50TmFtZSwgYWN0aW9uTmFtZSkge1xyXG4gICAgdmFyIGJhdGNoUXVpY2tCdXlDb250ZXh0cyA9IGNhcnQuQmF0Y2hRdWlja0J1eUNvbnRleHRzO1xyXG5cclxuICAgIGZvciAodmFyIGk9MDsgaSA8IGJhdGNoUXVpY2tCdXlDb250ZXh0cy5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgdmFyIGl0ZW0gPSBiYXRjaFF1aWNrQnV5Q29udGV4dHNbaV07XHJcblxyXG4gICAgICB2YXIgYmF0Y2hRdWlja2J1eUNvbnRleHQgPSB7XHJcbiAgICAgICAgcHJpY2VfZ3Jvc3M6IGl0ZW0uUHJpY2VHcm9zcyxcclxuICAgICAgICBwcmljZV9uZXQ6IGl0ZW0uUHJpY2VOZXQsXHJcbiAgICAgICAgcGFydF9idXNpbmVzc19hcmVhOiBpdGVtLlBhcnRCdXNpbmVzc0FyZWEsXHJcbiAgICAgICAgcGFydF9kZXNjcmlwdGlvbjogaXRlbS5QYXJ0RGVzY3JpcHRpb24sXHJcbiAgICAgICAgcGFydF9udW1iZXI6IGl0ZW0uUGFydE51bWJlcixcclxuICAgICAgICBwYXJ0X3Byb2R1Y3RfbGluZTogaXRlbS5QYXJ0UHJvZHVjdExpbmUsXHJcbiAgICAgICAgaGFzX3ByaWNlOiBpdGVtLkhhc1ByaWNlLFxyXG4gICAgICAgIGlzX2J1eWFibGU6IGl0ZW0uSXNCdXlhYmxlLFxyXG4gICAgICAgIHF1YW50aXR5OiBpdGVtLlF1YW50aXR5LFxyXG4gICAgICAgIGF2YWlsYWJsZV9xdWFudGl0eTogaXRlbS5BdmFpbGFibGVRdWFudGl0eSxcclxuXHRcdFx0XHRjYXJ0Q29udGVudDogY2FydC5DYXJ0SXRlbXMsXHJcblx0XHRcdFx0Y2FydElkOiBjYXJ0LkNhcnRJZFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIGJhdGNoRXZlbnQgPSB7XHJcbiAgICAgICAgJ2V2ZW50JzogZXZlbnROYW1lLFxyXG4gICAgICAgICdiYXRjaFF1aWNrYnV5Q29udGV4dCc6IGJhdGNoUXVpY2tidXlDb250ZXh0XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goYmF0Y2hFdmVudCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY29uZmlybWF0aW9uUGFnZUFkZEl0ZW0ob3JkZXIpe1xyXG4gIHJldHVybiB7XHJcbiAgICAnb3JkZXJJZCc6IG9yZGVyLm9yZGVyLFxyXG4gICAgJ3NrdSc6IG9yZGVyLnNrdSxcclxuICAgICduYW1lJzogb3JkZXIubmFtZSxcclxuICAgICdwcmljZSc6IG9yZGVyLnByaWNlLFxyXG4gICAgJ3F1YW50aXR5Jzogb3JkZXIucXVhbnRpdHksXHJcbiAgICAnb3JkZXJMaW5lQ29udGV4dCc6IHtcclxuICAgICAgJ2xpbmVfcHJvbW90aW9uJzogb3JkZXIubGluZV9wcm9tb3Rpb24sXHJcbiAgICAgICdhdmFpbGFibGVfcXVhbnRpdHknOiBvcmRlci5hdmFpbGFibGVfcXVhbnRpdHksXHJcbiAgICAgICdwcmljZV9ncm9zcyc6IG9yZGVyLnByaWNlX2dyb3NzLFxyXG4gICAgICAncHJpY2VfbmV0Jzogb3JkZXIucHJpY2VfbmV0LFxyXG4gICAgICAncGFydF9idXNpbmVzc19hcmVhJzogb3JkZXIucGFydF9idXNpbmVzc19hcmVhLFxyXG4gICAgICAncGFydF9wcm9kdWN0X2xpbmUnOiBvcmRlci5wYXJ0X2J1c2luZXNzX2FyZWEsXHJcbiAgICB9XHJcbiAgfTtcclxufVxyXG5mdW5jdGlvbiBpbml0RXZlbnRzKCkge1xyXG5cclxuICAgICAgaWYgKCQoJy5qc0ltYWdlVGV4dEJsb2NrJykubGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgJCgnLmpzVHJhY2tJbWFnZVRleHRCbG9ja0FkQ2xpY2snKS5vbignY2xpY2snLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICB2YXIgZWwgPSAkKGUudGFyZ2V0KSxcclxuICAgICAgICAgICAgICBwYXJlbnQgPSBlbC5wYXJlbnRzKCcuanNJbWFnZVRleHRCbG9jaycpLFxyXG4gICAgICAgICAgICAgIGJhbm5lcklkID0gcGFyZW50LmRhdGEoJ2Jhbm5lci1pZCcpLFxyXG4gICAgICAgICAgICAgIHpvbmVJZCA9IHBhcmVudC5kYXRhKCd6b25lLWlkJyksXHJcbiAgICAgICAgICAgICAgYmFubmVyTmFtZSA9IHBhcmVudC5kYXRhKCdiYW5uZXItbmFtZScpLFxyXG4gICAgICAgICAgICAgIGJhbm5lclR5cGUgPSBwYXJlbnQuZGF0YSgnYmFubmVyLXR5cGUnKSxcclxuICAgICAgICAgICAgICBiYW5uZXJJbnN0YW5jZSA9IHBhcmVudC5kYXRhKCdiYW5uZXItaW5zdGFuY2UnKTtcclxuXHJcbiAgICAgICAgICBDdXN0b21FdmVudHMudHJpZ2dlckRhdGFMYXllclB1c2goe1xyXG4gICAgICAgICAgICAnZXZlbnQnOiAndHJhY2tBZENsaWNrJyxcclxuICAgICAgICAgICAgJ2FkQ29udGV4dCc6IHtcclxuICAgICAgICAgICAgICAnYmFubmVyX25hbWUnOiBiYW5uZXJOYW1lLFxyXG4gICAgICAgICAgICAgICdiYW5uZXJfdHlwZSc6IGJhbm5lclR5cGUsXHJcbiAgICAgICAgICAgICAgJ2Jhbm5lcl9pbnN0YW5jZSc6IGJhbm5lckluc3RhbmNlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICdiYW5uZXJJZCc6IGJhbm5lcklkLFxyXG4gICAgICAgICAgICAnem9uZUlkJzogem9uZUlkXHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgICAgIGlmICgkKCcucHJvZHVjdC1kZXRhaWxwYWdlJykubGVuZ3RoICE9PSAwICYmIHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoXCJxdWVyeVwiKSA+IC0xKSB7XHJcbiAgICAgICAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyRGF0YUxheWVyUHVzaCh7XHJcbiAgICAgICAgICAgICAgICAnZXZlbnQnOiAnU2VhcmNoTGlua0NsaWNrJyxcclxuICAgICAgICAgICAgICAgICdlbGVtZW50VXJsJzogd2luZG93LmxvY2F0aW9uLmhyZWYsXHJcbiAgICAgICAgICAgICAgICAnZWxlbWVudENvbnRlbnQnOiBnZXRTZWFyY2hQYXJhbSgpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxufVxyXG5leHBvcnQgZGVmYXVsdCBDdXN0b21FdmVudHM7XHJcbiIsImxldCBDdXN0b21TZWFyY2hFdmVudHMgPSB7XHJcblx0aW5pdDogZnVuY3Rpb24oKSB7XHJcbiAgICB9LFxyXG5cdFx0dHJpZ2dlckRhdGFMYXllclB1c2g6IGZ1bmN0aW9uKG9iamVjdCl7XHJcblx0XHRcdGlmKGhpYWJjb25maWcuRW5hYmxlR29vZ2xlVGFnTWFuYWdlcil7XHJcblx0XHRcdFx0ZGF0YUxheWVyLnB1c2goe29iamVjdH0pO1xyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG4gICAgdHJhY2tGdWxsU2VhcmNoOiBmdW5jdGlvbihzZWFyY2hUZXJtLCByZXNwb25zZUJvZHkpIHtcclxuXHRcdFx0dmFyIHNlYXJjaFJlc3VsdCA9IFwiXCI7XHJcblx0XHRcdGlmICh0eXBlb2YgcmVzcG9uc2VCb2R5LmxpZ2h0U3BhcmVQYXJ0Vmlld01vZGVsICE9ICd1bmRlZmluZWQnKXtcclxuXHRcdFx0XHRzZWFyY2hSZXN1bHQgPSByZXNwb25zZUJvZHkubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwubWF0Y2hpbmc7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHNlYXJjaFJlc3VsdCA9IHJlc3BvbnNlQm9keS5tYXRjaGluZztcclxuXHRcdFx0fVxyXG4gICAgICAgIEN1c3RvbVNlYXJjaEV2ZW50cy50cmlnZ2VyRGF0YUxheWVyUHVzaCh7XHJcbiAgICAgICAgICAgICdldmVudCc6ICd0cmFja1NlYXJjaEV2ZW50JyxcclxuICAgICAgICAgICAgJ1NlYXJjaFRlcm1zJzogW3NlYXJjaFRlcm1dLFxyXG4gICAgICAgICAgICAnU2VhcmNoRmlsdGVycyc6IHsnc2VhcmNoVHlwZSc6ICdmdWxsJ30sXHJcbiAgICAgICAgICAgICdTZWFyY2hSZXN1bHQnOiBzZWFyY2hSZXN1bHQsXHJcbiAgICAgICAgICAgICdTZWFyY2hSZXN1bHRPbkZpcnN0UGFnZSc6IHR5cGVvZiByZXNwb25zZUJvZHkubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwgIT0gJ3VuZGVmaW5lZCcgPyByZXNwb25zZUJvZHkubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwuaXRlbXMubGVuZ3RoIDogcmVzcG9uc2VCb2R5Lml0ZW1zLmxlbmd0aFxyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuICAgIHRyYWNrUXVpY2tTZWFyY2g6IGZ1bmN0aW9uKHNlYXJjaFRlcm0sIHNlYXJjaFJlc3VsdCwgcmVzdWx0cykge1xyXG4gICAgICAgIHZhciBzZWFyY2hSZXN1bHRPbkZpcnN0UGFnZSA9IDA7XHJcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgc2VhcmNoUmVzdWx0T25GaXJzdFBhZ2UgPSBzZWFyY2hSZXN1bHRPbkZpcnN0UGFnZSArIHJlc3VsdHNbaV0ucmVzdWx0cy5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBDdXN0b21TZWFyY2hFdmVudHMudHJpZ2dlckRhdGFMYXllclB1c2goe1xyXG4gICAgICAgICAgICAnZXZlbnQnOiAndHJhY2tTZWFyY2hFdmVudCcsXHJcbiAgICAgICAgICAgICdTZWFyY2hUZXJtcyc6IFtzZWFyY2hUZXJtXSxcclxuICAgICAgICAgICAgJ1NlYXJjaEZpbHRlcnMnOiB7J3NlYXJjaFR5cGUnOiAncXVpY2snfSxcclxuICAgICAgICAgICAgJ1NlYXJjaFJlc3VsdCc6IHNlYXJjaFJlc3VsdCxcclxuICAgICAgICAgICAgJ1NlYXJjaFJlc3VsdE9uRmlyc3RQYWdlJzogc2VhcmNoUmVzdWx0T25GaXJzdFBhZ2VcclxuICAgICAgICB9KTtcclxuICB9LFxyXG5cdHRyYWNrRnVsbFNlYXJjaFBhZ2VMb2FkOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0aWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2pzU2VhcmNoUGFnZVRyYWNraW5nRGF0YScpKSB7XHJcblx0XHRcdFx0XHR2YXIgZGF0YUVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnanNTZWFyY2hQYWdlVHJhY2tpbmdEYXRhJyksXHJcblx0XHRcdFx0XHRcdFx0dHJhY2tpbmdEYXRhID0gSlNPTi5wYXJzZShkYXRhRWxlbWVudC5kYXRhc2V0LnNlYXJjaFRyYWNraW5nRGF0YSk7XHJcblxyXG5cdFx0XHRcdFx0d2luZG93LmRhdGFMYXllci5wdXNoKHtcclxuXHRcdFx0XHRcdFx0XHQnZXZlbnQnOiAndHJhY2tTZWFyY2hFdmVudCcsXHJcblx0XHRcdFx0XHRcdFx0J1NlYXJjaFRlcm1zJzogdHJhY2tpbmdEYXRhLnNlYXJjaFRlcm1zLFxyXG5cdFx0XHRcdFx0XHRcdCdTZWFyY2hGaWx0ZXJzJzogeydzZWFyY2hUeXBlJzogJ2Z1bGwnfSxcclxuXHRcdFx0XHRcdFx0XHQnU2VhcmNoUmVzdWx0JzogdHJhY2tpbmdEYXRhLnNlYXJjaFJlc3VsdCxcclxuXHRcdFx0XHRcdFx0XHQnU2VhcmNoUmVzdWx0T25GaXJzdFBhZ2UnOiB0cmFja2luZ0RhdGEuc2VhcmNoUmVzdWx0T25GaXJzdFBhZ2VcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblx0fVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ3VzdG9tU2VhcmNoRXZlbnRzO1xyXG4iLCI7KGZ1bmN0aW9uKCQpe1xyXG5cdCQuZm4uZmRhdGVwaWNrZXIuZGF0ZXNbJ2hpYWInXSA9IHtcclxuXHRcdGRheXM6IGhpYWJjb25maWcuZGF0ZXBpY2tlci5sYW5nLmRheXMsXHJcblx0XHRkYXlzU2hvcnQ6IGhpYWJjb25maWcuZGF0ZXBpY2tlci5sYW5nLmRheXNNaW4sXHJcblx0XHRkYXlzTWluOiBoaWFiY29uZmlnLmRhdGVwaWNrZXIubGFuZy5kYXlzTWluLFxyXG5cdFx0bW9udGhzOiBoaWFiY29uZmlnLmRhdGVwaWNrZXIubGFuZy5tb250aHMsXHJcblx0XHRtb250aHNTaG9ydDogaGlhYmNvbmZpZy5kYXRlcGlja2VyLmxhbmcubW9udGhzU2hvcnQsXHJcblx0XHR0b2RheTogaGlhYmNvbmZpZy5kYXRlcGlja2VyLmxhbmcudG9kYXksXHJcblx0XHRjbGVhcjogaGlhYmNvbmZpZy5kYXRlcGlja2VyLmxhbmcuY2xlYXIsXHJcblx0XHR3ZWVrU3RhcnQ6IGhpYWJjb25maWcuZGF0ZXBpY2tlci5sYW5nLndlZWtTdGFydCxcclxuXHRcdGZvcm1hdDogaGlhYmNvbmZpZy5kYXRlcGlja2VyLmxhbmcuZm9ybWF0XHJcblx0fTtcclxufShqUXVlcnkpKTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IGRhdGVwaWNrZXIgZnJvbSAnZm91bmRhdGlvbi1kYXRlcGlja2VyJztcclxuXHJcbmxldCBmb3JtYXQgPSBoaWFiY29uZmlnLmRhdGVwaWNrZXIubGFuZy5mb3JtYXQ7XHJcblxyXG5sZXQgZm91bmRhdGlvbmRhdGVwaWNrZXIgPSB7XHJcblxyXG5cdGluaXQoKSB7XHJcblx0XHRcclxuXHRcdGlmICggZm9ybWF0LnJlcGxhY2UoL1tebV0vZywgXCJcIikubGVuZ3RoIDwgMiApIHtcclxuXHRcdFx0bGV0IHN0cmluZyA9IGZvcm1hdC5yZXBsYWNlKCdtJywgJ21tJyk7XHJcblx0XHRcdGZvcm1hdCA9IHN0cmluZztcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGZvcm1hdC5yZXBsYWNlKC9bXmRdL2csIFwiXCIpLmxlbmd0aCA8IDIgKSB7XHJcblx0XHRcdGxldCBzdHJpbmcgPSBmb3JtYXQucmVwbGFjZSgnZCcsICdkZCcpO1xyXG5cdFx0XHRmb3JtYXQgPSBzdHJpbmc7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGNoZWNraW4gPSAkKCcjZGF0ZWZyb20nKS5mZGF0ZXBpY2tlcih7XHJcblx0XHRcdGxhbmd1YWdlOiAnaGlhYicsXHJcblx0XHRcdGZvcm1hdDogZm9ybWF0LFxyXG5cdFx0fSkub24oJ2NoYW5nZURhdGUnLCBmdW5jdGlvbiAoZXYpIHtcclxuXHRcdFx0JCgnI2RhdGV0bycpWzBdLmZvY3VzKCk7XHJcblx0XHR9KS5kYXRhKCdkYXRlcGlja2VyJyk7XHJcblx0XHRcclxuXHRcdHZhciBjaGVja291dCA9ICQoJyNkYXRldG8nKS5mZGF0ZXBpY2tlcih7XHJcblx0XHRcdGxhbmd1YWdlOiAnaGlhYicsXHJcblx0XHRcdGZvcm1hdDogZm9ybWF0LFxyXG5cdFx0fSkub24oJ2NoYW5nZURhdGUnLCBmdW5jdGlvbiAoZXYpIHtcclxuXHRcdFx0Y2hlY2tvdXQuaGlkZSgpO1xyXG5cdFx0fSkuZGF0YSgnZGF0ZXBpY2tlcicpO1xyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZvdW5kYXRpb25kYXRlcGlja2VyO1xyXG4iLCJsZXQgZGV0ZWN0VmVuZG9yID0ge1xyXG5cclxuICBpbml0OiBmdW5jdGlvbigpe1xyXG5cdFx0aWYgKChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCdNU0lFJykgIT0gLTEpIHx8IGRldGVjdFZlbmRvci5pc0lFMTAoKSB8fCBkZXRlY3RWZW5kb3IuaXNJRTYoKSB8fCBkZXRlY3RWZW5kb3IuaXNJRTExKCkpIHtcclxuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTmFtZSArPSAnIGllJztcclxuXHRcdH1cclxuXHRcdC8vIGlmICh3aW5kb3cubmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQgJiYgbmF2aWdhdG9yLm1zTWF4VG91Y2hQb2ludHMgPiAwKSB7XHJcblx0XHQvLyBcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc05hbWUgKz0gJyBzdXJmYWNlJztcclxuXHRcdC8vIH1cclxuXHJcblx0XHRpZigvaVBhZHxpUGhvbmV8aVBvZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAhd2luZG93Lk1TU3RyZWFtKSB7XHJcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc05hbWUgKz0gJyBpT1MnO1xyXG5cdFx0fVxyXG5cdFx0dmFyIHZlcnNpb24gPSBkZXRlY3RWZW5kb3IuZ2V0QnJvd3NlcigpO1xyXG5cdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTmFtZSArPSAnICcrdmVyc2lvblswXSsnICcrdmVyc2lvblswXSsnLScrdmVyc2lvblsxXTtcclxuICB9LFxyXG5cdGdldEJyb3dzZXI6IGZ1bmN0aW9uKCl7XHJcblx0XHR2YXIgdWE9IG5hdmlnYXRvci51c2VyQWdlbnQsIHRlbSxcclxuXHRcdE09IHVhLm1hdGNoKC8ob3BlcmF8Y2hyb21lfHNhZmFyaXxmaXJlZm94fG1zaWV8dHJpZGVudCg/PVxcLykpXFwvP1xccyooXFxkKykvaSkgfHwgW107XHJcblx0XHRpZigvdHJpZGVudC9pLnRlc3QoTVsxXSkpe1xyXG5cdFx0XHRcdHRlbT0gIC9cXGJydlsgOl0rKFxcZCspL2cuZXhlYyh1YSkgfHwgW107XHJcblx0XHRcdFx0cmV0dXJuICdJRSAnKyh0ZW1bMV0gfHwgJycpO1xyXG5cdFx0fVxyXG5cdFx0aWYoTVsxXT09PSAnQ2hyb21lJyl7XHJcblx0XHRcdFx0dGVtPSB1YS5tYXRjaCgvXFxiKE9QUnxFZGdlKVxcLyhcXGQrKS8pO1xyXG5cdFx0XHRcdGlmKHRlbSE9IG51bGwpIHJldHVybiB0ZW0uc2xpY2UoMSkuam9pbignICcpLnJlcGxhY2UoJ09QUicsICdPcGVyYScpO1xyXG5cdFx0fVxyXG5cdFx0TT0gTVsyXT8gW01bMV0sIE1bMl1dOiBbbmF2aWdhdG9yLmFwcE5hbWUsIG5hdmlnYXRvci5hcHBWZXJzaW9uLCAnLT8nXTtcclxuXHRcdGlmKCh0ZW09IHVhLm1hdGNoKC92ZXJzaW9uXFwvKFxcZCspL2kpKSE9IG51bGwpIE0uc3BsaWNlKDEsIDEsIHRlbVsxXSk7XHJcblx0XHRyZXR1cm4gTTtcclxuXHR9LFxyXG5cclxuXHRpc0lFNjogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoL1xcYk1TSUUgNi8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAhd2luZG93Lm9wZXJhKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGlzSUU3OiBmdW5jdGlvbigpIHtcclxuXHRcdGlmIChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCdNU0lFIDcuJykgIT0gLTEpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0aXNJRTg6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aWYgKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoJ01TSUUgOC4nKSAhPSAtMSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRpc0lFOTogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAobmF2aWdhdG9yLmFwcFZlcnNpb24uaW5kZXhPZignTVNJRSA5LicpICE9IC0xKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGlzSUUxMDogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoIC8qQGNjX29uIUAqLyBmYWxzZSAmJiBkb2N1bWVudC5kb2N1bWVudE1vZGUgPT09IDEwKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGlzSUUxMTogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoISFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9UcmlkZW50LipydlsgOl0qMTFcXC4vKSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHR9LFxyXG5cdGlzRWRnZTogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoISFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9UcmlkZW50LipydlsgOl0qMTFcXC4vKSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHR9LFxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZGV0ZWN0VmVuZG9yO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQganFjb29raWUgZnJvbSAnanF1ZXJ5LmNvb2tpZSc7XHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi9jdXN0b20tZXZlbnRzJztcclxuXHJcbnZhciBtb2RlbCA9IHt9O1xyXG52YXIgc2VyaWFsTm8gPSBcIlwiO1xyXG52YXIgZGF0YSA9IHt9O1xyXG5cclxubGV0IGZpdHNNeU1hY2hpbmUgPSB7XHJcbiAgICBpbml0KCkge1xyXG4gICAgICAgIHRoaXMuaG93VG9GaW5kU2VyaWFsTm9UcmlnZ2VyID0gJCgnLmhvdy10by1maW5kLXNlcmlhbC1ubycpO1xyXG4gICAgICAgIHRoaXMuc2VyaWFsTm9TZWFyY2hUcmlnZ2VyID0gJCgnI3NlcmlhbE5vU2VhcmNoJyk7XHJcbiAgICAgICAgdGhpcy5zZXJpYWxOdW1iZXJJbnB1dFRyaWdnZXIgPSAkKCcjc2VyaWFsTm8nKTtcclxuICAgICAgICB0aGlzLmVuYWJsZUNsZWFyQnV0dG9uVHJpZ2dlciA9ICQoJyNjbGVhcicpO1xyXG5cclxuICAgICAgICB0aGlzLnNlcmlhbE5vU2VhcmNoVHJpZ2dlci5jbGljayhmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICBmaXRzTXlNYWNoaW5lLkNyZWF0ZU1hdGNoTWFjaGluZU1vZGVsKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy9PcGVuIGNvbmZpZ3VyZSB0ZXh0IGRpYWxvZ1xyXG5cdFx0dGhpcy5ob3dUb0ZpbmRTZXJpYWxOb1RyaWdnZXIub24oJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHQkKCcjaG93LXRvLWZpbmQtc2VyaWFsLW5vLW1vZGFsJykuZm91bmRhdGlvbigncmV2ZWFsJywgJ29wZW4nKTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIHRoaXMuc2VyaWFsTnVtYmVySW5wdXRUcmlnZ2VyLm9uKCdrZXl1cCcsZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xyXG4gICAgICAgICAgICAkKCcjY2xlYXInKS5zaG93KCk7XHJcbiAgICAgICAgICAgIGlmKHZhbHVlICE9ICcnICYmIHZhbHVlLmxlbmd0aCA+IDMgJiYgdmFsdWUubGVuZ3RoIDwgMjUpIHtcclxuICAgICAgICAgICAgICAgICQoJyNzZXJpYWxOb1NlYXJjaCcpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09ICcnKXtcclxuICAgICAgICAgICAgICAgICQoJyNjbGVhcicpLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICQoJyNzZXJpYWxOb1NlYXJjaCcpLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgJCgnI3NlcmlhbE5vU2VhcmNoJykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGUud2hpY2ggPT09IDEzICYmIHZhbHVlICE9ICcnICYmIHZhbHVlLmxlbmd0aCA+IDMgJiYgdmFsdWUubGVuZ3RoIDwgMjUpIHtcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgZml0c015TWFjaGluZS5DcmVhdGVNYXRjaE1hY2hpbmVNb2RlbCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICQoJyNjbGVhcicpLm9uKCdjbGljaycsZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICQoJyNzZXJpYWxObycpLnZhbCgnJyk7XHJcbiAgICAgICAgICAgICQoJyNjbGVhcicpLmhpZGUoKTtcclxuICAgICAgICAgICAgZml0c015TWFjaGluZS5IaWRlU3RhdHVzKClcclxuICAgICAgICAgICAgJCgnLmRvZXMtdGhpcy1maXQtbXktbWFjaGluZSAuaW5mbycpLnNob3coKTtcclxuICAgICAgICAgICAgJCgnI3NlcmlhbE5vU2VhcmNoJykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgICAgICAgICAgJC5yZW1vdmVDb29raWUoJ21hdGNoLW1hY2hpbmUnLCB7IHBhdGg6ICcvJyB9KTtcclxuICAgICAgICAgICAgZGF0YSA9IHsgaW5wdXRDbGVhcjogdHJ1ZSB9XHJcbiAgICAgICAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaChkYXRhKVxyXG4gICAgICAgIH0pXHJcblxyXG4gICAgICAgIGlmKHRoaXMuc2VyaWFsTnVtYmVySW5wdXRUcmlnZ2VyLmxlbmd0aCA+IDApe1xyXG4gICAgICAgICAgICB2YXIgY29va2llID0gJC5jb29raWUoJ21hdGNoLW1hY2hpbmUnKTtcclxuICAgICAgICAgICAgaWYoY29va2llICE9IG51bGwgJiYgY29va2llLmxlbmd0aCA+IDApe1xyXG4gICAgICAgICAgICAgICAgZml0c015TWFjaGluZS5DcmVhdGVNYXRjaE1hY2hpbmVNb2RlbChjb29raWUpO1xyXG4gICAgICAgICAgICAgICAgZml0c015TWFjaGluZS5BZGRDb29raWVWYWx1ZVRvSW5wdXQoY29va2llKTtcclxuICAgICAgICAgICAgICAgIGRhdGEgPSB7IHZhbHVlRnJvbUNvb2tpZTogdHJ1ZX1cclxuICAgICAgICAgICAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaChkYXRhKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIEFkZENvb2tpZVZhbHVlVG9JbnB1dChjb29raWUpe1xyXG4gICAgICAgICAgICBpZihjb29raWUubGVuZ3RoID4gMCl7XHJcbiAgICAgICAgICAgICAgICAkKCcjc2VyaWFsTm8nKS52YWwoY29va2llKTtcclxuICAgICAgICAgICAgICAgICQoJyNjbGVhcicpLnNob3coKTtcclxuICAgICAgICAgICAgICAgICQoJyNzZXJpYWxOb1NlYXJjaCcpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgSGlkZVN0YXR1cygpe1xyXG4gICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC5pbmZvJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC51bmFibGUtdG8tdmVyaWZ5JykuaGlkZSgpO1xyXG4gICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC50b28tbWFueS1zZWFyY2hlcycpLmhpZGUoKTtcclxuICAgICAgICAgICAgJCgnLmRvZXMtdGhpcy1maXQtbXktbWFjaGluZSAubm90LWF1dGhlbnRpY2F0ZWQnKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLm5vdC1mb3VuZCcpLmhpZGUoKTtcclxuICAgICAgICAgICAgJCgnLmRvZXMtdGhpcy1maXQtbXktbWFjaGluZSAudmVyaWZpZWQnKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLnZhbGlkYXRpb24tZXJyb3InKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLmVycm9yJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC5zZWFyY2gnKS5oaWRlKCk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgQ3JlYXRlTWF0Y2hNYWNoaW5lTW9kZWwoc2VyaWFsTm8gPSBcIlwiKXtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRTZXJpYWxObyA9IHNlcmlhbE5vO1xyXG5cclxuICAgICAgICAgICAgaWYoY3VycmVudFNlcmlhbE5vID09PSBcIlwiKXtcclxuICAgICAgICAgICAgICAgIGRhdGEgPSB7IHZhbHVlRnJvbUNvb2tpZTogZmFsc2V9XHJcbiAgICAgICAgICAgICAgICBDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goZGF0YSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmaXRzTXlNYWNoaW5lLkhpZGVTdGF0dXMoKVxyXG4gICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC5zZWFyY2gnKS5zaG93KCk7XHJcblxyXG4gICAgICAgICAgICBtb2RlbCA9IHtcclxuICAgICAgICAgICAgICAgIENvZGU6ICQoXCJpbnB1dFtuYW1lPWNvZGVdXCIpLnZhbCgpLFxyXG4gICAgICAgICAgICAgICAgU2VyaWFsTnVtYmVyOiBjdXJyZW50U2VyaWFsTm8gPT09IFwiXCIgPyAkKFwiaW5wdXRbbmFtZT1zZXJpYWxOb11cIikudmFsKCkgOiBjdXJyZW50U2VyaWFsTm8sXHJcbiAgICAgICAgICAgICAgICBTdGF0dXM6XCJcIlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmKG1vZGVsLlNlcmlhbE51bWJlciA9PT0gXCJcIil7XHJcbiAgICAgICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC5zZWFyY2gnKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC52YWxpZGF0aW9uLWVycm9yJykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZpdHNNeU1hY2hpbmUuTWF0Y2hNYWNoaW5lKG1vZGVsKVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIE1hdGNoTWFjaGluZShtb2RlbCl7XHJcbiAgICAgICAgICAgICQuYWpheCh7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcIlBPU1RcIixcclxuICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIixcclxuICAgICAgICAgICAgICAgIHVybDogJy9hcGkvc2VyaWFsbnVtYmVyc2VhcmNoL2ZpdHNteW1hY2hpbmUnLFxyXG4gICAgICAgICAgICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkobW9kZWwpLFxyXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6IFwianNvblwiLFxyXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC5zZWFyY2gnKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLmVycm9yJykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLnNlYXJjaCcpLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXR1c1RleHQgID0gXCJcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYocmVzcG9uc2UuU3RhdHVzID09PSAxKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLm5vdC1mb3VuZCcpLnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c1RleHQgPSBcIk5vdCBmb3VuZC5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYocmVzcG9uc2UuU3RhdHVzID09PSAyKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLnZlcmlmaWVkJykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzVGV4dCA9IFwiVmVyaWZpZWQuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHJlc3BvbnNlLlN0YXR1cyA9PT0gMyl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lIC51bmFibGUtdG8tdmVyaWZ5Jykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzVGV4dCA9IFwiVW5hYmxlIHRvIHZlcmlmeS5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYocmVzcG9uc2UuU3RhdHVzID09PSA0KXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLnZhbGlkYXRpb24tZXJyb3InKS5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0ID0gXCJWYWxpZGF0aW9uIGVycm9yLlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihyZXNwb25zZS5TdGF0dXMgPT09IDUpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnLmRvZXMtdGhpcy1maXQtbXktbWFjaGluZSAudG9vLW1hbnktc2VhcmNoZXMnKS5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0ID0gXCJUb28gbWFueSBzZWFyY2hlcy5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYocmVzcG9uc2UuU3RhdHVzID09PSA2KXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLm5vdC1hdXRoZW50aWNhdGVkJykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzVGV4dCA9IFwiTm90IGF1dGhlbnRpY2F0ZWQuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAkLmNvb2tpZSgnbWF0Y2gtbWFjaGluZScsIHJlc3BvbnNlLlNlcmlhbE51bWJlciwgeyBwYXRoOiAnLycgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEgPSB7IFN0YXR1czogcmVzcG9uc2UuU3RhdHVzLCBTZXJpYWxOdW1iZXI6IHJlc3BvbnNlLlNlcmlhbE51bWJlciwgQ29kZTogcmVzcG9uc2UuQ29kZSwgU3RhdHVzVGV4dDogc3RhdHVzVGV4dH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhzdGF0dXNUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBDdXN0b21FdmVudHMudHJpZ2dlcldpbmRvd0RhdGFMYXllclB1c2goZGF0YSlcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgJCgnLmRvZXMtdGhpcy1maXQtbXktbWFjaGluZSAuc2VhcmNoJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICQoJy5kb2VzLXRoaXMtZml0LW15LW1hY2hpbmUgLmVycm9yJykuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEgPSB7IFN0YXR1czogbnVsbCwgU2VyaWFsTnVtYmVyOiBudWxsLCBDb2RlOiBudWxsLCBTdGF0dXNUZXh0OiBcIlVuZXhwcmV4dGVkIGVycm9yLlwiLCAgfVxyXG4gICAgICAgICAgICAgICAgICAgIEN1c3RvbUV2ZW50cy50cmlnZ2VyV2luZG93RGF0YUxheWVyUHVzaChkYXRhKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZml0c015TWFjaGluZTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmxldCBJRWVxdWFsaXplckZpeCA9IHtcclxuXHJcbiAgaW5pdDogZnVuY3Rpb24oKXtcclxuICAgIHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG4gICAgdmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG4gICAgdmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpO1xyXG5cclxuICAgIGlmIChtc2llID4gMCB8fCB0cmlkZW50ID4gMCkge1xyXG4gICAgICBsZXQgcmVzdWx0U3BhcmVQYXJ0cyA9ICAkKCcucmVzdWx0LXNwYXJlLXBhcnRzJykubGVuZ3RoID4gMCA/IHRydWUgOiBmYWxzZTtcclxuICAgICAgbGV0IHVjUHJvZHVjdGxpc3QgPSAgJCgnLnVjLXByb2R1Y3RsaXN0JykubGVuZ3RoID4gMCA/IHRydWUgOiBmYWxzZTtcclxuICAgICAgbGV0IHVjUHJvZHVjdGxpc3RVbCA9ICQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpLmxlbmd0aCA+IDAgPyB0cnVlIDogZmFsc2U7XHJcblx0XHRcdGxldCBpdGVtTmFtZVdhdGNoID0gJCgnLml0ZW0tbmFtZS13YXRjaCcpLmxlbmd0aCA+IDAgPyB0cnVlIDogZmFsc2U7XHJcbiAgICAgIGxldCBhbW91bnRwUHJpY2VTdG9jayA9ICQoJy5hbW91bnQtcHJpY2Utc3RvY2std2F0Y2gnKS5sZW5ndGggPiAwID8gdHJ1ZSA6IGZhbHNlO1xyXG5cclxuXHJcbiAgICAgIGlmKHVjUHJvZHVjdGxpc3RVbCB8fCB1Y1Byb2R1Y3RsaXN0KXtcclxuICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpKTtcclxuICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCcpKTtcclxuICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5hbW91bnQtcHJpY2Utc3RvY2std2F0Y2gnKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICQod2luZG93KS5vbigncmVzaXplJywgZnVuY3Rpb24oKXtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygncmVzaXplJyk7XHJcbiAgICAgICAgaWYocmVzdWx0U3BhcmVQYXJ0cyl7XHJcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygncmVzdWx0LXNwYXJlLXBhcnRzJyk7XHJcbiAgICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5yZXN1bHQtc3BhcmUtcGFydHMnKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZih1Y1Byb2R1Y3RsaXN0VWwpe1xyXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coJ3VjLWNhbXBhaW5nLWJsb2NrIHVsJyk7XHJcbiAgICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKHVjUHJvZHVjdGxpc3Qpe1xyXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coJ3VjLXByb2R1Y3RsaXN0Jyk7XHJcbiAgICAgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKGFtb3VudHBQcmljZVN0b2NrKXtcclxuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdhbW91bnRwUHJpY2VTdG9jaycpO1xyXG4gICAgICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuYW1vdW50LXByaWNlLXN0b2NrLXdhdGNoJykpO1xyXG4gICAgICAgIH1cclxuXHRcdFx0XHRpZihpdGVtTmFtZVdhdGNoKXtcclxuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKCdpdGVtTmFtZVdhdGNoJyk7XHJcblx0XHRcdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5pdGVtLW5hbWUtd2F0Y2gnKSk7XHJcblx0XHRcdFx0fVxyXG4gICAgICB9KTtcclxuXHJcbiAgICB9XHJcbiAgfSxcclxuXHJcblxyXG4gIC8vIGVxdWFsSGVpZ2h0OiBmdW5jdGlvbihncm91cCkge1xyXG4gIC8vICAgdmFyIHRhbGxlc3QgPSAwO1xyXG4gIC8vICAgZ3JvdXAuZWFjaChmdW5jdGlvbigpIHtcclxuICAvLyAgICAgJCh0aGlzKS5jc3MoJ2hlaWdodCcsICdhdXRvJyk7XHJcbiAgLy8gICAgIHZhciB0aGlzSGVpZ2h0ID0gJCh0aGlzKS5oZWlnaHQoKTtcclxuICAvLyAgICAgY29uc29sZS5sb2codGhpc0hlaWdodCk7XHJcbiAgLy8gICAgIGlmICh0aGlzSGVpZ2h0ID4gdGFsbGVzdCkge1xyXG4gIC8vICAgICAgIHRhbGxlc3QgPSB0aGlzSGVpZ2h0O1xyXG4gIC8vICAgICB9XHJcbiAgLy8gICB9KTtcclxuICAvL1xyXG4gIC8vICAgZ3JvdXAuaGVpZ2h0KHRhbGxlc3QpO1xyXG4gIC8vIH1cclxuXHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgSUVlcXVhbGl6ZXJGaXg7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcblxyXG5sZXQgbGlzdHZpZXd0b2dnbGUgPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdC8vdG9nZ2xlIGxpc3R2aWV3IGxheW91dFxyXG5cdFx0JCggJ2JvZHknICkub24oJ2NsaWNrJywgJy51Yy1sYXlvdXQtdG9nZ2xlIGJ1dHRvbicsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRpZighJCh0aGlzKS5oYXNDbGFzcygnYWN0aXZlJykpe1xyXG5cdFx0XHRcdCQoJy51Yy1sYXlvdXQtdG9nZ2xlIGJ1dHRvbicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZigkKHRoaXMpLmlzKFwiI2dyaWRcIikpe1xyXG5cdFx0XHRcdCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpLnJlbW92ZUNsYXNzKCdsaXN0Jyk7XHJcblx0XHRcdFx0dmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XHJcblx0XHQgICAgdmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG5cdFx0ICAgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTtcclxuXHJcblx0XHQgICAgaWYgKG1zaWUgPiAwIHx8IHRyaWRlbnQgPiAwKSB7XHJcblx0XHRcdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpKTtcclxuXHRcdFx0XHRcdEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnVjLXByb2R1Y3RsaXN0JykpO1xyXG5cdFx0XHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuYW1vdW50LXByaWNlLXN0b2NrLXdhdGNoJykpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdCQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ2VxdWFsaXplcicsICdyZWZsb3cnKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZXtcclxuXHRcdFx0XHQkKCcudWMtcHJvZHVjdGxpc3QgdWwnKS5hZGRDbGFzcygnbGlzdCcpO1xyXG5cdFx0XHRcdCQoJy5pdGVtLW5hbWUnKS5jc3MoJ2hlaWdodCcsJ2F1dG8nKTtcclxuXHRcdFx0XHQkKCcuYW1vdW50LXByaWNlLXN0b2NrJykuY3NzKCdoZWlnaHQnLCdhdXRvJyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vdG9nZ2xlIHVjLXRyZWVtZW51IHBhcmVudHNcclxuXHRcdCQoICdib2R5JyApLm9uKCdjbGljaycsICcjY2F0ZWdvcnlsaXN0IC5leHBhbmQnLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdGlmKCAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmhhc0NsYXNzKCdpcy1vcGVuJykgKXtcclxuXHRcdFx0XHQkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdCQodGhpcykucGFyZW50KCkucGFyZW50KCkuYWRkQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgbGlzdHZpZXd0b2dnbGU7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCAkcGFuem9vbSBmcm9tICdqcXVlcnkucGFuem9vbSc7XHJcblxyXG5cclxubGV0IHBhbnpvb20gPSB7XHJcblxyXG5cdHBhbnpvb206IG51bGwsXHJcblxyXG5cdG9wdGlvbnM6IHtcclxuXHRcdG1pblNjYWxlOiAxLFxyXG5cdFx0bWF4U2NhbGU6IDQsXHJcblx0XHRyYW5nZVN0ZXA6IDAuMSxcclxuXHRcdGNvbnRhaW46ICdpbnZlcnQnLFxyXG5cdFx0ZWFzaW5nOiBcImVhc2UtaW4tb3V0XCJcclxuXHR9LFxyXG5cclxuXHRpbml0KGVsbSkge1xyXG5cclxuXHRcdC8vJChcIi5leHBsb2RlZHZpZXctem9vbS1jb250YWluZXJcIikucGFuem9vbSgnZGVzdHJveScpO1xyXG5cdFx0aWYoJCgnLmV4cGxvZGVkdmlldy16b29tLWNvbnRhaW5lciAuYXNwZWN0LXJhdGlvJywgZWxtKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdHRoaXMucGFuem9vbSA9ICQoJy5leHBsb2RlZHZpZXctem9vbS1jb250YWluZXIgLmFzcGVjdC1yYXRpbycsIGVsbSkucGFuem9vbSh0aGlzLm9wdGlvbnMpO1xyXG5cdFx0XHQkKCcuZXhwbG9kZWR2aWV3LXpvb20tY29udGFpbmVyIC5hc3BlY3QtcmF0aW8nKS5wYW56b29tKCdyZXNldCcsIGZhbHNlKTtcclxuXHJcblx0XHRcdCQoJ2ltZycpLmJpbmQoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24oZSkge1xyXG5cdCAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHQgICAgICByZXR1cm4gZmFsc2U7XHJcblx0ICAgIH0pO1xyXG5cclxuXHRcdFx0dGhpcy56b29tQ29udHJvbHMoKTtcclxuXHRcdFx0dGhpcy5zY3JvbGxXaGVlbFpvb20oKTtcclxuXHRcdFx0dGhpcy5kb3VibGlja2xpY2tab29tKCk7XHJcblx0XHRcdHRoaXMucmVzZXREaW1lbnNpb25zKCk7XHJcblx0XHR9XHJcblxyXG5cdH0sXHJcblxyXG5cdHNjcm9sbFdoZWVsWm9vbSgpIHtcclxuXHRcdHRoaXMucGFuem9vbS5vbignbW91c2V3aGVlbC5mb2NhbCcsIChlKSA9PiB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0bGV0IGRlbHRhID0gZS5kZWx0YSB8fCBlLm9yaWdpbmFsRXZlbnQud2hlZWxEZWx0YTtcclxuXHJcblx0XHRcdGxldCB6b29tT3V0ID0gZGVsdGEgPyBkZWx0YSA8IDAgOiBlLm9yaWdpbmFsRXZlbnQuZGVsdGFZID4gMDtcclxuXHRcdFx0dGhpcy56b29tKHpvb21PdXQsIGUsIDAuMDEsIGZhbHNlKTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHpvb21Db250cm9scygpIHtcclxuXHRcdCQoJy56b29tLWluJykub24oJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHR0aGlzLnpvb20oZmFsc2UsIG51bGwsIDAuMDgsIHRydWUpO1xyXG5cdFx0fSk7XHJcblx0XHQkKCcuem9vbS1vdXQnKS5vbignY2xpY2snLCAoZSkgPT4ge1xyXG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdHRoaXMuem9vbSh0cnVlLCBudWxsLCAwLjA4LCB0cnVlKTtcclxuXHRcdH0pO1xyXG5cdFx0JCgnLnpvb20tcmVzZXQnKS5vbignY2xpY2snLCAoZSkgPT4ge1xyXG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdHRoaXMuem9vbShcInJlc2V0Wm9vbVwiLCBmYWxzZSk7XHJcblx0XHRcdHRoaXMuem9vbShcInJlc2V0UGFuXCIsIGZhbHNlKTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGRvdWJsaWNrbGlja1pvb20oKSB7XHJcblx0XHR0aGlzLnBhbnpvb20ucGFyZW50KCkub24oJ2RibGNsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuXHRcdFx0aWYoJChlLnRhcmdldCkuaXMoJy56b29tJykpIHJldHVybjtcclxuXHJcblx0XHRcdHRoaXMuem9vbShmYWxzZSwgZSwgMSwgdHJ1ZSk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHR6b29tKHpvb21PdXQsIGZvY2FsLCBpbmNyZW1lbnQsIGFuaW1hdGUpIHtcclxuXHRcdHRoaXMucGFuem9vbS5wYW56b29tKCd6b29tJywgem9vbU91dCwge1xyXG5cdFx0XHRpbmNyZW1lbnQ6IGluY3JlbWVudCxcclxuXHRcdFx0YW5pbWF0ZTogYW5pbWF0ZSxcclxuXHRcdFx0Zm9jYWw6IGZvY2FsXHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRyZXNldERpbWVuc2lvbnMoKSB7XHJcblx0XHQkKHdpbmRvdykub24oJ3Jlc2l6ZScsICgpID0+IHtcclxuXHJcblx0XHRcdGlmKHRoaXMucGFuem9vbSkge1xyXG5cdFx0XHRcdHRoaXMucGFuem9vbS5wYW56b29tKCdyZXNldERpbWVuc2lvbnMnKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgcGFuem9vbTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxubGV0IHByaW50ID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHQkKCcucHJpbnQnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdHdpbmRvdy5wcmludCgpO1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9KTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IHByaW50O1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcclxuaW1wb3J0IFNwYXJlUGFydEZvb3RlciBmcm9tICcuLi9jb21wb25lbnRzL3NlYXJjaC9zcGFyZV9wYXJ0X2Zvb3Rlcic7XHJcbmltcG9ydCBQcmljZVNlcnZpY2VBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3ByaWNlX3NlcnZpY2VfYWN0aW9ucyc7XHJcbmltcG9ydCBQcmljZVNlcnZpY2VTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3ByaWNlX3NlcnZpY2Vfc3RvcmUnO1xyXG5cclxuXHJcbmxldCBQcm9kdWN0Q2FyZEZvb3RlciA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0bGV0IG1hdGVyaWFscyA9IFtdO1xyXG5cdFx0JCgnW2RhdGEtZm9vdGVyLWVsZW1lbnRdJykuZWFjaChmdW5jdGlvbigpe1xyXG5cclxuXHRcdFx0bGV0IG1hdGVyaWFsTnVtYmVyID0gJCh0aGlzKS5kYXRhKCdmb290ZXItZWxlbWVudCcpO1xyXG5cdFx0XHRsZXQgZGV0YWlsc1VybCA9ICQodGhpcykuZGF0YSgncGFydC11cmwnKTtcclxuXHRcdFx0bGV0IGdvdFNjYWxlZFByaWNlcyA9ICgkKHRoaXMpLmRhdGEoJ2dvdC1zY2FsZWQtcHJpY2VzJykudG9Mb3dlckNhc2UoKSA9PSBcInRydWVcIik7XHJcblx0XHRcdGxldCB1c2VySXNEZWFsZXIgPSAkKCdib2R5LmlzLWRlYWxlcicpLmxlbmd0aCA+IDA7XHJcblx0XHRcdGxldCB0cmFuc2xhdGlvbnMgPSBoaWFiY29uZmlnLlNwYXJlUGFydEZvb3Rlci5sYW5nO1xyXG5cdFx0XHRSZWFjdERPTS5yZW5kZXIoPFNwYXJlUGFydEZvb3RlciBpc0RlYWxlcj17dXNlcklzRGVhbGVyfSBtYXRlcmlhbE51bWJlcj17bWF0ZXJpYWxOdW1iZXJ9IGdvdFNjYWxlZFByaWNlcz17Z290U2NhbGVkUHJpY2VzfSB1cmw9e2RldGFpbHNVcmx9ICB0cmFuc2xhdGlvbnM9e3RyYW5zbGF0aW9uc30vPiwgJCh0aGlzKVswXSk7XHJcblx0XHRcdG1hdGVyaWFscy5wdXNoKG1hdGVyaWFsTnVtYmVyKTtcclxuXHRcdH0pO1xyXG5cdFx0UHJvZHVjdENhcmRGb290ZXIuZmV0Y2hQcmljZShtYXRlcmlhbHMpO1xyXG5cdH0sXHJcblx0ZmV0Y2hQcmljZSAobWF0ZXJpYWxzKXtcclxuXHRcdHZhciBwcmljZXNJblN0b3JlID0gUHJpY2VTZXJ2aWNlU3RvcmUuZ2V0UHJpY2VzKCk7XHJcblx0XHR2YXIgcHJpY2VzSW5TdG9yZUNvZGVzID0gcHJpY2VzSW5TdG9yZS5tYXAoIGZ1bmN0aW9uKHByaWNlSW5TdG9yZSl7IHJldHVybiBwcmljZUluU3RvcmUuQ29kZTsgfSk7XHJcblxyXG5cdFx0dmFyIHJlc3VsdEl0ZW1zTm90SW5QcmljZVN0b3JlID0gbWF0ZXJpYWxzLmZpbHRlciggZnVuY3Rpb24ocmVzdWx0SXRlbSkge1xyXG5cdFx0ICByZXR1cm4gcHJpY2VzSW5TdG9yZUNvZGVzLmluZGV4T2YocmVzdWx0SXRlbSkgPCAwXHJcblx0XHR9KTtcclxuXHJcblx0XHRyZXN1bHRJdGVtc05vdEluUHJpY2VTdG9yZS5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHQgIFByaWNlU2VydmljZUFjdGlvbnMuYWRkTWF0ZXJpYWxzKGl0ZW0pO1xyXG5cdFx0fSk7XHJcblx0XHRQcmljZVNlcnZpY2VBY3Rpb25zLmZldGNoUHJpY2VzKGhpYWJjb25maWcuanNQcmljZUJhdGNoQW1vdW50KTtcclxuXHR9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0Q2FyZEZvb3RlcjtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxubGV0IHByb2R1Y3RDb250YWlucyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0JCgnLnVjLXByb2R1Y3QtY29udGFpbnM6bm90KC5raXQpJykuZWFjaChmdW5jdGlvbigpe1xyXG5cdFx0XHRpZigkKHRoaXMpLmZpbmQoJ3VsJykuY2hpbGRyZW4oKS5sZW5ndGggPiAxMSl7XHJcblx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnaGFzLW1vcmUnKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBwcm9kdWN0Q29udGFpbnM7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBlelBsdXMgZnJvbSAnZXotcGx1cyc7XHJcbmltcG9ydCBsaWdodFNsaWRlciBmcm9tICdsaWdodHNsaWRlcic7XHJcblxyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9wcmljZV9zZXJ2aWNlX3N0b3JlJztcclxuXHJcbmxldCBzZXRIZWlnaHQgPSAwO1xyXG5sZXQgbmFtZUhlaWdodCA9IDA7XHJcbmxldCBhbXRIZWlnaHQgPSAwO1xyXG52YXIgcHJvZHVjdEltYWdlcyA9IG51bGw7XHJcblxyXG5sZXQgcHJvZHVjdGltYWdlem9vbSA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0JCh3aW5kb3cpLm9uKFwicmVzaXplXCIsIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHQkKCcuem9vbUNvbnRhaW5lcicpLnJlbW92ZSgpO1xyXG5cdFx0XHQkKCcjcHJvZHVjdEltYWdlcyAubHNsaWRlLmFjdGl2ZSBpbWcnKS5lelBsdXMoe1xyXG5cdFx0XHRcdHJlc3BvbnNpdmU6IHRydWUsXHJcblx0XHRcdFx0em9vbVdpbmRvd1Bvc2l0aW9uOiAxMSxcclxuXHRcdFx0XHRyZXNwb25kOiBbXHJcblx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdHJhbmdlOiAnMC04MDAnLFxyXG5cdFx0XHRcdFx0XHRlbmFibGVkOiBmYWxzZVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdF1cclxuXHRcdFx0fSk7XHJcblx0XHRcdHZhciB3aWR0aCA9ICQoZG9jdW1lbnQpLndpZHRoKCk7XHJcblx0ICAgIGlmICh3aWR0aCA8PSA4MDApIHtcclxuXHRcdFx0XHRwcm9kdWN0SW1hZ2VzLnJlZnJlc2goKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cHJvZHVjdEltYWdlcyA9ICQoJyNwcm9kdWN0SW1hZ2VzJykubGlnaHRTbGlkZXIoe1xyXG5cdFx0XHRyZXBzb25zaXZlOiB0cnVlLFxyXG5cdFx0XHRnYWxsZXJ5OiB0cnVlLFxyXG5cdFx0XHRpdGVtOiAxLFxyXG5cdFx0XHRsb29wOiBmYWxzZSxcclxuXHRcdFx0c2xpZGVNYXJnaW46IDIsXHJcblx0XHRcdGVuYWJsZURyYWc6IGZhbHNlLFxyXG5cdFx0XHRjdXJyZW50UGFnZXJQb3NpdGlvbjogJ2xlZnQnLFxyXG5cdFx0XHR2ZXJ0aWNhbDogdHJ1ZSxcclxuICAgIFx0XHR2ZXJ0aWNhbEhlaWdodDogMjYxLFxyXG4gICAgXHRcdHZUaHVtYldpZHRoOiA2MCxcclxuXHRcdFx0dGh1bWJNYXJnaW46IDEwLFxyXG5cdFx0XHR0aHVtYkl0ZW06IDQsXHJcblx0XHRcdGFkYXB0aXZlSGVpZ2h0OiBmYWxzZSxcclxuXHRcdFx0Y29udHJvbHM6IGZhbHNlLFxyXG5cdFx0XHRyZXNwb25zaXZlIDogW1xyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGJyZWFrcG9pbnQ6ODAwLFxyXG5cdFx0XHRcdFx0c2V0dGluZ3M6IHtcclxuXHRcdFx0XHRcdFx0Z2FsbGVyeTogZmFsc2UsXHJcblx0XHRcdFx0XHRcdHZlcnRpY2FsOiBmYWxzZSxcclxuXHRcdFx0XHRcdFx0dmVydGljYWxIZWlnaHQ6IDAsXHJcblx0XHRcdFx0XHRcdHZUaHVtYldpZHRoOiAwLFxyXG5cdFx0XHRcdFx0XHR0aHVtYk1hcmdpbjogMTAsXHJcblx0XHRcdFx0XHRcdHRodW1iSXRlbTogNCxcclxuXHRcdFx0XHRcdFx0YWRhcHRpdmVIZWlnaHQ6IHRydWUsXHJcblx0XHRcdFx0XHRcdGVuYWJsZURyYWc6IHRydWUsXHJcblx0XHRcdFx0XHRcdGN1cnJlbnRQYWdlclBvc2l0aW9uOiAnbWlkZGxlJyxcclxuXHRcdFx0XHRcdFx0bW9kZTogJ2ZhZGUnLFxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XSxcclxuXHRcdFx0b25TbGlkZXJMb2FkOiBmdW5jdGlvbihlbCkge1xyXG5cdFx0XHRcdCQoJ2ltZycpLmJpbmQoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24oZSkge1xyXG5cdFx0ICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0ICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cdFx0ICAgIH0pO1xyXG5cdFx0XHRcdCQoJyNwcm9kdWN0SW1hZ2VzIC5sc2xpZGUuYWN0aXZlIGltZycpLmV6UGx1cyh7XHJcblx0XHRcdFx0XHRyZXNwb25zaXZlOiB0cnVlLFxyXG5cdFx0XHRcdFx0em9vbVdpbmRvd1Bvc2l0aW9uOiAxMSxcclxuXHRcdFx0XHRcdHJlc3BvbmQ6IFt7XHJcblx0XHRcdFx0XHRcdHJhbmdlOiAnMC04MDAnLFxyXG5cdFx0XHRcdFx0XHRlbmFibGVkOiBmYWxzZVxyXG5cdFx0XHRcdFx0fV1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSxcclxuXHRcdFx0b25CZWZvcmVTbGlkZTogZnVuY3Rpb24oZWwpIHtcclxuXHRcdFx0XHQkKCdpbWcnKS5iaW5kKCdjb250ZXh0bWVudScsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdCAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdCAgICAgIHJldHVybiBmYWxzZTtcclxuXHRcdCAgICB9KTtcclxuXHRcdFx0XHQkKCcuem9vbUNvbnRhaW5lcicpLnJlbW92ZSgpO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRvbkFmdGVyU2xpZGU6IGZ1bmN0aW9uKGVsKSB7XHJcblx0XHRcdFx0JCgnaW1nJykuYmluZCgnY29udGV4dG1lbnUnLCBmdW5jdGlvbihlKSB7XHJcblx0XHQgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHQgICAgICByZXR1cm4gZmFsc2U7XHJcblx0XHQgICAgfSk7XHJcblx0XHRcdFx0JCgnI3Byb2R1Y3RJbWFnZXMgLmxzbGlkZS5hY3RpdmUgaW1nJykuZXpQbHVzKHtcclxuXHRcdFx0XHRcdHJlc3BvbnNpdmU6IHRydWUsXHJcblx0XHRcdFx0XHR6b29tV2luZG93UG9zaXRpb246IDExLFxyXG5cdFx0XHRcdFx0cmVzcG9uZDogW1xyXG5cdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0cmFuZ2U6ICcwLTgwMCcsXHJcblx0XHRcdFx0XHRcdFx0ZW5hYmxlZDogZmFsc2VcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyB2YXIgcHJvZHVjdFNsaWRlciA9ICQoJy5wcm9kdWN0ZGV0YWlsLXNsaWRlcicpLmxpZ2h0U2xpZGVyKHtcclxuXHRcdC8vIFx0aXRlbTozLFxyXG5cdFx0Ly8gXHRsb29wOmZhbHNlLFxyXG5cdFx0Ly8gXHRzbGlkZU1vdmU6MyxcclxuXHRcdC8vIFx0c2xpZGVNYXJnaW46IDAsXHJcblx0XHQvLyBcdHNwZWVkOiA3MDAsIC8vbXMnXHJcbiAgICAvLyAgIGF1dG86IGZhbHNlLFxyXG4gICAgLy8gICBzbGlkZUVuZEFuaW1hdGlvbjogdHJ1ZSxcclxuXHRcdC8vIFx0ZW5hYmxlRHJhZzogZmFsc2UsXHJcblx0XHQvLyBcdGFkYXB0aXZlSGVpZ2h0OiB0cnVlLFxyXG5cdFx0Ly8gXHRyZXNwb25zaXZlIDogW1xyXG5cdFx0Ly8gXHRcdHtcclxuXHRcdC8vIFx0XHRcdGJyZWFrcG9pbnQ6MTQyMCxcclxuXHRcdC8vIFx0XHRcdHNldHRpbmdzOiB7XHJcblx0XHQvLyBcdFx0XHRcdGl0ZW06MixcclxuXHRcdC8vIFx0XHRcdFx0c2xpZGVNb3ZlOjIsXHJcblx0XHQvLyBcdFx0XHR9XHJcblx0XHQvLyBcdFx0fSxcclxuXHRcdC8vIFx0XHR7XHJcblx0XHQvLyBcdFx0XHRicmVha3BvaW50Ojk3MCxcclxuXHRcdC8vIFx0XHRcdHNldHRpbmdzOiB7XHJcblx0XHQvLyBcdFx0XHRcdGl0ZW06MSxcclxuXHRcdC8vIFx0XHRcdFx0c2xpZGVNb3ZlOjEsXHJcblx0XHQvLyBcdFx0XHR9XHJcblx0XHQvLyBcdFx0fSxcclxuXHRcdC8vIFx0XHR7XHJcblx0XHQvLyBcdFx0XHRicmVha3BvaW50OjgwMCxcclxuXHRcdC8vIFx0XHRcdHNldHRpbmdzOiB7XHJcblx0XHQvLyBcdFx0XHRcdGl0ZW06MyxcclxuXHRcdC8vIFx0XHRcdFx0c2xpZGVNb3ZlOjMsXHJcblx0XHQvLyBcdFx0XHR9XHJcblx0XHQvLyBcdFx0fSxcclxuXHRcdC8vIFx0XHR7XHJcblx0XHQvLyBcdFx0XHRicmVha3BvaW50OjcwMCxcclxuXHRcdC8vIFx0XHRcdHNldHRpbmdzOiB7XHJcblx0XHQvLyBcdFx0XHRcdGl0ZW06MixcclxuXHRcdC8vIFx0XHRcdFx0c2xpZGVNb3ZlOjIsXHJcblx0XHQvLyBcdFx0XHR9XHJcblx0XHQvLyBcdFx0fSxcclxuXHRcdC8vIFx0XHR7XHJcblx0XHQvLyBcdFx0XHRicmVha3BvaW50OjUwMCxcclxuXHRcdC8vIFx0XHRcdHNldHRpbmdzOiB7XHJcblx0XHQvLyBcdFx0XHRcdGl0ZW06MSxcclxuXHRcdC8vIFx0XHRcdFx0c2xpZGVNb3ZlOjEsXHJcblx0XHQvLyBcdFx0XHR9XHJcblx0XHQvLyBcdFx0fVxyXG5cdFx0Ly8gXHRdLFxyXG5cdFx0Ly8gXHRvblNsaWRlckxvYWQoZWwpe1xyXG5cdFx0Ly8gXHRcdHByb2R1Y3RpbWFnZXpvb20ucmVmbG93KCk7XHJcblx0XHQvLyBcdH1cclxuXHRcdC8vIH0pO1xyXG5cclxuXHRcdC8vIHRoaXMudW5zdWJzY3JpYmUgPSBQcmljZVNlcnZpY2VTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdC8vIFx0c2V0SGVpZ2h0ID0gMDtcclxuXHRcdC8vIFx0bmFtZUhlaWdodCA9IDA7XHJcblx0XHQvLyBcdGFtdEhlaWdodCA9IDA7XHJcblx0XHQvLyBcdHByb2R1Y3RpbWFnZXpvb20ucmVmbG93KCk7XHJcbiAgICAvLyB9KTtcclxuXHJcblx0fSxcclxuXHQvLyByZWZsb3coKXtcclxuXHQvL1xyXG5cdC8vIFx0dmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XHJcblx0Ly8gXHR2YXIgdHJpZGVudCA9IHVhLmluZGV4T2YoJ1RyaWRlbnQvJyk7XHJcblx0Ly8gXHR2YXIgbXNpZSA9IHVhLmluZGV4T2YoJ01TSUUgJyk7XHJcblx0Ly8gXHRpZiAobXNpZSA+IDAgfHwgdHJpZGVudCA+IDApIHtcclxuXHQvLyBcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuYW1vdW50LXByaWNlLXN0b2NrLXdhdGNoJykpO1xyXG5cdC8vIFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5pdGVtLW5hbWUtd2F0Y2gnKSk7XHJcblx0Ly8gXHR9ZWxzZXtcclxuXHQvLyBcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbignZXF1YWxpemVyJywncmVmbG93Jyk7XHJcblx0Ly8gXHR9XHJcblx0Ly8gXHQkKCcucHJvZHVjdGRldGFpbC1zbGlkZXIgbGknKS5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcclxuXHQvLyBcdFx0aWYoJCh0aGlzKS5oZWlnaHQoKSA+IHNldEhlaWdodCl7XHJcblx0Ly8gXHRcdFx0c2V0SGVpZ2h0ID0gJCh0aGlzKS5oZWlnaHQoKTtcclxuXHQvLyBcdFx0fVxyXG5cdC8vIFx0XHRsZXQgaXRlbU5hbWUgPSAkKHRoaXMpLmNoaWxkcmVuKCkuZmluZCgnLml0ZW0tbmFtZScpO1xyXG5cdC8vIFx0XHRsZXQgYW10SXRlbSA9ICQodGhpcykuY2hpbGRyZW4oKS5maW5kKCcuZm9vdGVyJykuY2hpbGRyZW4oJy5hbW91bnQtcHJpY2Utc3RvY2snKTtcclxuXHQvLyBcdFx0aWYoaXRlbU5hbWUuaGVpZ2h0KCkgPiBuYW1lSGVpZ2h0KXtcclxuXHQvLyBcdFx0XHRuYW1lSGVpZ2h0ID0gaXRlbU5hbWUuaGVpZ2h0KCk7XHJcblx0Ly8gXHRcdH1cclxuXHQvLyBcdFx0aWYoYW10SXRlbS5oZWlnaHQoKSA+IGFtdEhlaWdodCl7XHJcblx0Ly8gXHRcdFx0YW10SGVpZ2h0ID0gYW10SXRlbS5oZWlnaHQoKTtcclxuXHQvLyBcdFx0fVxyXG5cdC8vIFx0fSk7XHJcblx0Ly9cclxuXHQvLyBcdCQoJy5wcm9kdWN0ZGV0YWlsLXNsaWRlciAuaXRlbS1uYW1lJykuaGVpZ2h0KG5hbWVIZWlnaHQpO1xyXG5cdC8vIFx0JCgnLnByb2R1Y3RkZXRhaWwtc2xpZGVyIC5hbW91bnQtcHJpY2Utc3RvY2snKS5oZWlnaHQoYW10SGVpZ2h0KTtcclxuXHQvLyBcdCQoJy5wcm9kdWN0ZGV0YWlsLXNsaWRlcicpLmhlaWdodChzZXRIZWlnaHQpO1xyXG5cdC8vIFx0JCgnLnVjLXByb2R1Y3QtdXBzZWxsIC5sU1NsaWRlV3JhcHBlcicpLmhlaWdodChzZXRIZWlnaHQpO1xyXG5cdC8vIH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHByb2R1Y3RpbWFnZXpvb207XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcblxyXG5sZXQgdHlwaW5nVGltZXIgPSBudWxsO1xyXG5jb25zdCBkb25lVHlwaW5nSW50ZXJ2YWwgPSAgNzUwO1xyXG5cclxubGV0IHNjYWxlZFByaWNlcyA9IHtcclxuXHRpbml0KCkge1xyXG5cclxuXHRcdGxldCBzY2FsZWRQcmljZXMgPSBbXTtcclxuXHJcblx0XHRsZXQgJHByb2R1Y3RJbmZvQW1vdW50ID0gJCgnLmlubmVyLnVjLXByb2R1Y3QtaW5mb3JtYXRpb24gLm1haW5BbW91bnQnKTtcclxuXHRcdGxldCAkcHJvZHVjdEluZm9QcmljZSA9ICQoJy5pbm5lci51Yy1wcm9kdWN0LWluZm9ybWF0aW9uIC5tYWluUHJpY2UnKTtcclxuXHJcblx0XHRsZXQgJHN0aWNreUluZm9BbW91bnQgPSAkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSAubWFpbkFtb3VudCcpO1xyXG5cdFx0bGV0ICRzdGlja3lJbmZvUHJpY2UgPSAkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSAubWFpblByaWNlJyk7XHJcblxyXG5cdFx0JCgnLnNjYWxlZC1wcmljZXMgc2VsZWN0IG9wdGlvbicpLmVhY2goZnVuY3Rpb24oIGluZGV4ICkge1xyXG5cdFx0XHRsZXQgcmFuZ2VNaW4gPSAkKHRoaXMpLmRhdGEoJ3JhbmdlLW1pbicpO1xyXG5cdFx0XHRsZXQgcmFuZ2VNYXggPSAkKHRoaXMpLmRhdGEoJ3JhbmdlLW1heCcpO1xyXG5cdFx0XHRsZXQgcHJpY2UgPSAkKHRoaXMpLmRhdGEoJ3ByaWNlJyk7XHJcblx0XHRcdHNjYWxlZFByaWNlcy5wdXNoKHttaW46cmFuZ2VNaW4sIG1heDpyYW5nZU1heCwgcHJpY2U6cHJpY2UsIHZhbHVlOiByYW5nZU1pbn0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0JChkb2N1bWVudCkub24oJ2NoYW5nZScsICcuc2NhbGVkLXByaWNlcyBzZWxlY3QnLCBmdW5jdGlvbigpe1xyXG5cdFx0XHRsZXQgcmFuZ2VNaW4gPSAkKHRoaXMpLmZpbmQoJ29wdGlvbjpzZWxlY3RlZCcpLmRhdGEoJ3JhbmdlLW1pbicpO1xyXG5cdFx0XHRsZXQgcHJpY2UgPSAkKHRoaXMpLmZpbmQoJ29wdGlvbjpzZWxlY3RlZCcpLmRhdGEoJ3ByaWNlJyk7XHJcblxyXG5cdFx0XHQkcHJvZHVjdEluZm9BbW91bnRbMF0udmFsdWUgPSByYW5nZU1pbjtcclxuXHRcdFx0JHByb2R1Y3RJbmZvQW1vdW50WzBdLmRlZmF1bHRWYWx1ZSA9IHJhbmdlTWluO1xyXG5cdFx0XHQkcHJvZHVjdEluZm9QcmljZVswXS5pbm5lckhUTUwgPSBwcmljZTtcclxuXHJcblx0XHRcdCRzdGlja3lJbmZvQW1vdW50WzBdLnZhbHVlID0gcmFuZ2VNaW47XHJcblx0XHRcdCRzdGlja3lJbmZvQW1vdW50WzBdLmRlZmF1bHRWYWx1ZSA9IHJhbmdlTWluO1xyXG5cdFx0XHQkc3RpY2t5SW5mb1ByaWNlWzBdLmlubmVySFRNTCA9IHByaWNlO1xyXG5cclxuXHRcdFx0YW5pbWF0ZSgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0JChkb2N1bWVudCkub24oJ2lucHV0JywgJy5pbm5lci51Yy1wcm9kdWN0LWluZm9ybWF0aW9uIC5tYWluQW1vdW50JywgZnVuY3Rpb24oKXtcclxuXHRcdFx0aWYodHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0eXBpbmdUaW1lcik7XHJcblx0XHRcdHR5cGluZ1RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0dXBkYXRlSW5wdXQodGhpcylcclxuXHRcdFx0fSwgZG9uZVR5cGluZ0ludGVydmFsKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoZG9jdW1lbnQpLm9uKCdpbnB1dCcsICcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSAubWFpbkFtb3VudCcsIGZ1bmN0aW9uKCl7XHJcblx0XHRcdGlmKHR5cGluZ1RpbWVyKSBjbGVhclRpbWVvdXQodHlwaW5nVGltZXIpO1xyXG5cdFx0XHR0eXBpbmdUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cdFx0XHRcdHVwZGF0ZUlucHV0KHRoaXMpXHJcblx0XHRcdH0sIGRvbmVUeXBpbmdJbnRlcnZhbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRmdW5jdGlvbiB1cGRhdGVJbnB1dChlbCkge1xyXG5cdFx0XHRpZiAoZWwudmFsdWUgIT09IGVsLmRlZmF1bHRWYWx1ZSkge1xyXG5cclxuXHRcdFx0XHQkc3RpY2t5SW5mb0Ftb3VudFswXS52YWx1ZSA9IGVsLnZhbHVlO1xyXG5cdFx0XHRcdCRzdGlja3lJbmZvQW1vdW50WzBdLmRlZmF1bHRWYWx1ZSA9IGVsLnZhbHVlO1xyXG5cdFx0XHRcdCRwcm9kdWN0SW5mb0Ftb3VudFswXS52YWx1ZSA9IGVsLnZhbHVlO1xyXG5cdFx0XHRcdCRwcm9kdWN0SW5mb0Ftb3VudFswXS5kZWZhdWx0VmFsdWUgPSBlbC52YWx1ZTtcclxuXHJcblx0XHRcdFx0bGV0IHByZXZWYWx1ZSA9ICQoJy5zY2FsZWQtcHJpY2VzIHNlbGVjdCcpLnZhbCgpO1xyXG5cdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgc2NhbGVkUHJpY2VzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdFx0XHRpZiggZWwudmFsdWUgPiBzY2FsZWRQcmljZXNbaV0ubWluIHx8IGVsLnZhbHVlID09IHNjYWxlZFByaWNlc1tpXS5taW4gfHwgZWwudmFsdWUgPT0gc2NhbGVkUHJpY2VzW2ldLm1heCApe1xyXG5cdFx0XHRcdFx0XHQkcHJvZHVjdEluZm9QcmljZVswXS5pbm5lckhUTUwgPSBzY2FsZWRQcmljZXNbaV0ucHJpY2U7XHJcblx0XHRcdFx0XHRcdCRzdGlja3lJbmZvUHJpY2VbMF0uaW5uZXJIVE1MID0gc2NhbGVkUHJpY2VzW2ldLnByaWNlO1xyXG5cdFx0XHRcdFx0XHQkKCcuc2NhbGVkLXByaWNlcyBzZWxlY3QnKS52YWwoc2NhbGVkUHJpY2VzW2ldLnZhbHVlKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0YW5pbWF0ZShwcmV2VmFsdWUpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0ZnVuY3Rpb24gYW5pbWF0ZShwcmV2VmFsdWUpIHtcclxuXHRcdFx0aWYoJCgnLnNjYWxlZC1wcmljZXMgc2VsZWN0JykudmFsKCkgIT09IHByZXZWYWx1ZSl7XHJcblx0XHRcdFx0JHByb2R1Y3RJbmZvUHJpY2UucmVtb3ZlQ2xhc3MoKS5hZGRDbGFzcygnYm91bmNlSW4nICsgJyBhbmltYXRlZCcrJyBtYWluUHJpY2UnKS5vbmUoJ3dlYmtpdEFuaW1hdGlvbkVuZCBtb3pBbmltYXRpb25FbmQgTVNBbmltYXRpb25FbmQgb2FuaW1hdGlvbmVuZCBhbmltYXRpb25lbmQnLCBmdW5jdGlvbigpe1xyXG5cdFx0XHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcygpO1xyXG5cdFx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnbWFpblByaWNlJyk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0JHN0aWNreUluZm9QcmljZS5yZW1vdmVDbGFzcygpLmFkZENsYXNzKCdib3VuY2VJbicgKyAnIGFuaW1hdGVkJysnIG1haW5QcmljZScpLm9uZSgnd2Via2l0QW5pbWF0aW9uRW5kIG1vekFuaW1hdGlvbkVuZCBNU0FuaW1hdGlvbkVuZCBvYW5pbWF0aW9uZW5kIGFuaW1hdGlvbmVuZCcsIGZ1bmN0aW9uKCl7XHJcblx0XHRcdFx0XHQkKHRoaXMpLnJlbW92ZUNsYXNzKCk7XHJcblx0XHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdtYWluUHJpY2UnKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgc2NhbGVkUHJpY2VzO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5cclxudmFyIHByb2R1Y3RBZGRUb0NhcnQgPSBcIlwiO1xyXG52YXIgcHJvZHVjdEFkZFRvQ2FydE9mZnNldCA9IDA7XHJcbnZhciBhZGRpdGlvbmFsTmF2ID0gXCJcIjtcclxudmFyIGFkZGl0aW9uYWxOYXZPZmZzZXQgPSAwO1xyXG5cclxubGV0IHNjcm9sbGNvbnRyb2xzUHJvZHVjdERldGFpbCA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0cHJvZHVjdEFkZFRvQ2FydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlY3Rpb24udWMtcHJvZHVjdC1pbmZvcm1hdGlvbiAuaW5wdXQtYnV0dG9ucycpO1xyXG5cdFx0aWYgKCQocHJvZHVjdEFkZFRvQ2FydCkubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRwcm9kdWN0QWRkVG9DYXJ0T2Zmc2V0ID0gJCgnLnVjLXNjcm9sbGNvbnRyb2xzLXN0aWNreScpLmhlaWdodCgpO1xyXG5cdFx0XHRpZiAoIXNjcm9sbGNvbnRyb2xzUHJvZHVjdERldGFpbC5pc0luVmlld3BvcnQocHJvZHVjdEFkZFRvQ2FydCwgcHJvZHVjdEFkZFRvQ2FydE9mZnNldCkpIHtcclxuXHRcdFx0XHQkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSAucHJvZHVjdC1jb250ZW50JykuYWRkQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRhZGRpdGlvbmFsTmF2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmFkZGl0aW9uYWwtbmF2aWdhdGlvbi13cmFwcGVyIC5hZGRpdGlvbmFsLW5hdicpO1xyXG5cdFx0aWYgKCQoYWRkaXRpb25hbE5hdikubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRhZGRpdGlvbmFsTmF2T2Zmc2V0ID0gJCgnLnVjLXNjcm9sbGNvbnRyb2xzLXN0aWNreScpLmhlaWdodCgpICsgJCgnLnByb2R1Y3Qtc3VtbWFyeS1zdGlja3kgLnByb2R1Y3QtY29udGVudCcpLmhlaWdodCgpIC0gJCgnLmFkZGl0aW9uYWwtbmF2aWdhdGlvbi13cmFwcGVyIC5hZGRpdGlvbmFsLW5hdicpLmhlaWdodCgpO1xyXG5cdFx0XHRpZiAoIXNjcm9sbGNvbnRyb2xzUHJvZHVjdERldGFpbC5pc0luVmlld3BvcnQoYWRkaXRpb25hbE5hdiwgYWRkaXRpb25hbE5hdk9mZnNldCkpIHtcclxuXHRcdFx0XHQkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSBuYXYnKS5hZGRDbGFzcygnb25zY3JlZW4nKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblx0aXNJblZpZXdwb3J0KGVsZW0sIG9mZnNldCkge1xyXG5cdFx0aWYgKGVsZW0gPT09IDAgfHwgZWxlbSA9PT0gbnVsbCB8fCBlbGVtID09PSBcIlwiKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdHZhciBib3VuZGluZyA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRib3VuZGluZy50b3AgPj0gb2Zmc2V0XHJcblx0XHQpO1xyXG5cdH1cclxufVxyXG52YXIgc2Nyb2xsU3RvcCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XHJcblx0aWYgKCFjYWxsYmFjayB8fCB0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHJldHVybjtcclxuXHR2YXIgaXNTY3JvbGxpbmc7XHJcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcblx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KGlzU2Nyb2xsaW5nKTtcclxuXHRcdGlzU2Nyb2xsaW5nID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcclxuXHRcdFx0Y2FsbGJhY2soKTtcclxuXHRcdH0sIDMzKTtcclxuXHR9LCBmYWxzZSk7XHJcbn07XHJcbnNjcm9sbFN0b3AoZnVuY3Rpb24oKSB7XHJcblx0aWYgKCFzY3JvbGxjb250cm9sc1Byb2R1Y3REZXRhaWwuaXNJblZpZXdwb3J0KHByb2R1Y3RBZGRUb0NhcnQsIHByb2R1Y3RBZGRUb0NhcnRPZmZzZXQpKSB7XHJcblx0XHQkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSAucHJvZHVjdC1jb250ZW50JykuYWRkQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0fSBlbHNlIHtcclxuXHRcdCQoJy5wcm9kdWN0LXN1bW1hcnktc3RpY2t5IC5wcm9kdWN0LWNvbnRlbnQnKS5yZW1vdmVDbGFzcygnb25zY3JlZW4nKTtcclxuXHRcdCQoJy5wcm9kdWN0LXN1bW1hcnktc3RpY2t5IG5hdicpLnJlbW92ZUNsYXNzKCdvbnNjcmVlbicpO1xyXG5cdH1cclxuXHJcblx0aWYgKCFzY3JvbGxjb250cm9sc1Byb2R1Y3REZXRhaWwuaXNJblZpZXdwb3J0KGFkZGl0aW9uYWxOYXYsIGFkZGl0aW9uYWxOYXZPZmZzZXQpKSB7XHJcblx0XHQkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreSBuYXYnKS5hZGRDbGFzcygnb25zY3JlZW4nKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0JCgnLnByb2R1Y3Qtc3VtbWFyeS1zdGlja3kgbmF2JykucmVtb3ZlQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBzY3JvbGxjb250cm9sc1Byb2R1Y3REZXRhaWw7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBpbnZpZXcgZnJvbSAnanF1ZXJ5Lmludmlldyc7XHJcblxyXG5sZXQgc2Nyb2xsY29udHJvbHMgPSB7XHJcblx0aW5pdCgpIHtcclxuXHJcblx0XHR2YXIgaGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnVjLXNpdGVoZWFkZXInKTtcclxuXHRcdGlmICghc2Nyb2xsY29udHJvbHMuaXNJblZpZXdwb3J0KGhlYWRlciwgMCkpIHtcclxuXHRcdFx0JCgnLnVjLXNjcm9sbGNvbnRyb2xzLXN0aWNreScpLmFkZENsYXNzKCdvbnNjcmVlbicpO1xyXG5cdFx0XHQkKCdib2R5JykuYWRkQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0XHR9XHJcblx0XHQkKGhlYWRlcikuYmluZCgnaW52aWV3JywgZnVuY3Rpb24oZXZlbnQsIGlzSW5WaWV3KSB7XHJcblx0XHRcdGlmIChpc0luVmlldykge1xyXG5cdFx0XHRcdCQoJy51Yy1zY3JvbGxjb250cm9scy1zdGlja3knKS5yZW1vdmVDbGFzcygnb25zY3JlZW4nKTtcclxuXHRcdFx0XHQkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0XHRcdFx0JCgnLnByb2R1Y3Qtc3VtbWFyeS1zdGlja3kgLnByb2R1Y3QtY29udGVudCcpLnJlbW92ZUNsYXNzKCdvbnNjcmVlbicpO1xyXG5cdFx0XHRcdCQoJy5wcm9kdWN0LXN1bW1hcnktc3RpY2t5IG5hdicpLnJlbW92ZUNsYXNzKCdvbnNjcmVlbicpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdCQoJy51Yy1zY3JvbGxjb250cm9scy1zdGlja3knKS5hZGRDbGFzcygnb25zY3JlZW4nKTtcclxuXHRcdFx0XHQkKCdib2R5JykuYWRkQ2xhc3MoJ29uc2NyZWVuJyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHR9LFxyXG5cdGlzSW5WaWV3cG9ydChlbGVtLCBvZmZzZXQpIHtcclxuXHRcdHZhciBib3VuZGluZyA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRib3VuZGluZy50b3AgPj0gb2Zmc2V0XHJcblx0XHQpO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgc2Nyb2xsY29udHJvbHM7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBTZWFyY2hSZXN1bHRTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3NlYXJjaF9yZXN1bHRfc3RvcmUnO1xyXG5cclxubGV0IGlzUHJvZHVjdFBhZ2UgPSAkKCcucHJvZHVjdC1kZXRhaWxwYWdlJykubGVuZ3RoID4gMDtcclxuXHJcbmxldCBzY3JvbGx0byA9IHtcclxuXHRpbml0KCkge1xyXG5cclxuXHRcdGxldCBvZmZzZXRIZWFkZXIgPSAkKCcudWMtc2Nyb2xsY29udHJvbHMtc3RpY2t5JykuaGVpZ2h0KCk7XHJcblx0XHRsZXQgb2Zmc2V0UHJvZHVjdFN1bW1hcnkgPSAkKCcucHJvZHVjdC1zdW1tYXJ5LXN0aWNreScpLmhlaWdodCgpO1xyXG5cdFx0bGV0IGFkZGl0aW9uYWxPZmZzZXQgPSBpc1Byb2R1Y3RQYWdlID8gLTEgOiAwO1xyXG5cclxuXHRcdGxldCBvZmZzZXRIZWlnaHQgPSBvZmZzZXRIZWFkZXIgKyBvZmZzZXRQcm9kdWN0U3VtbWFyeSArIGFkZGl0aW9uYWxPZmZzZXQ7XHJcblxyXG5cdFx0JCggJ2JvZHknICkub24oJ2NsaWNrJywgJ1tkYXRhLXNjcm9sbC10b10nLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHJcblx0XHRcdGlmICggJCgnLnVjLW9yZGVyLWRldGFpbCcpLmxlbmd0aCA+IDAgKSB7XHJcblx0XHRcdFx0JCgnLm9yZGVyLWludm9pY2UnKS5yZW1vdmVDbGFzcygnaW52b2ljZS1zZWxlY3RlZCcpO1xyXG5cdFx0XHRcdCQoJCh0aGlzKS5kYXRhKCdzY3JvbGwtdG8nKSkuYWRkQ2xhc3MoJ2ludm9pY2Utc2VsZWN0ZWQnKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0JCgnaHRtbCwgYm9keScpLmFuaW1hdGUoe1xyXG4gICAgICAgIHNjcm9sbFRvcDogJCgkKHRoaXMpLmRhdGEoXCJzY3JvbGwtdG9cIikpLm9mZnNldCgpLnRvcCAtIG9mZnNldEhlaWdodFxyXG4gICAgXHR9KTtcclxuXHJcblx0XHR9KTtcclxuXHJcblx0XHRsZXQgZmluZHNlcnZpY2VJc0Rvd24gPSBTZWFyY2hSZXN1bHRTdG9yZS5jaGVja0ZpbmRzZXJ2aWNlSXNEb3duKCk7XHJcblx0XHRpZihmaW5kc2VydmljZUlzRG93bi5wYWdlcyB8fCBmaW5kc2VydmljZUlzRG93bi5zcGFyZVBhcnRzKXtcclxuXHRcdFx0JCgnLnByaWNlLW1hbmFnZS1pbmZvJykuc2hvdygpO1xyXG5cdFx0XHRpZigkKHdpbmRvdykuc2Nyb2xsVG9wKCkgPiAkKCcucHJpY2UtbWFuYWdlLWluZm8nKS5vZmZzZXQoKS50b3Ape1xyXG5cdFx0XHRcdCQoJ2h0bWwsIGJvZHknKS5hbmltYXRlKHtcclxuXHRcdFx0XHRcdHNjcm9sbFRvcDogJCgnLnByaWNlLW1hbmFnZS1pbmZvJykub2Zmc2V0KCkudG9wIC0gb2Zmc2V0SGVpZ2h0XHJcblx0XHRcdFx0fSwgMTAwMCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRTZWFyY2hSZXN1bHRTdG9yZS5saXN0ZW4oIChzZWFyY2hTdG9yZVN0YXRlKSA9PiB7XHJcbiAgICAgIGxldCByZXMgPSBTZWFyY2hSZXN1bHRTdG9yZS5jaGVja0ZpbmRzZXJ2aWNlSXNEb3duKCk7XHJcblx0ICAgIGlmKHJlcy5wYWdlcyB8fCByZXMuc3BhcmVQYXJ0cyl7XHJcblx0ICAgICAgJCgnLnByaWNlLW1hbmFnZS1pbmZvJykuc2hvdygpO1xyXG5cdCAgICAgIGlmKCQod2luZG93KS5zY3JvbGxUb3AoKSA+ICQoJy5wcmljZS1tYW5hZ2UtaW5mbycpLm9mZnNldCgpLnRvcCl7XHJcblx0ICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZSh7XHJcblx0ICAgICAgICAgIHNjcm9sbFRvcDogJCgnLnByaWNlLW1hbmFnZS1pbmZvJykub2Zmc2V0KCkudG9wIC0gb2Zmc2V0SGVpZ2h0XHJcblx0ICAgICAgICB9LCAxMDAwKTtcclxuXHQgICAgICB9XHJcblx0ICAgIH1cclxuXHQgICAgZWxzZSB7XHJcblx0ICAgICAgJCgnLnByaWNlLW1hbmFnZS1pbmZvJykuaGlkZSgpO1xyXG5cdCAgICB9XHJcblxyXG4gICAgfSk7XHJcblxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHNjcm9sbHRvO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcclxuaW1wb3J0IFNlYXJjaEZpZWxkIGZyb20gJy4uL2NvbXBvbmVudHMvc2VhcmNoL3NlYXJjaF9maWVsZCc7XHJcblxyXG5sZXQgc2VhcmNocmVzdWx0ID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHRpZigkKCcjc2VhcmNoLWZpZWxkJykubGVuZ3RoID4gMCkgUmVhY3RET00ucmVuZGVyKDxTZWFyY2hGaWVsZCAvPiwgJCgnI3NlYXJjaC1maWVsZCcpWzBdKTtcclxuXHRcdGlmKCQoJyNzZWFyY2gtZmllbGQtbW9kYWwnKS5sZW5ndGggPiAwKSBSZWFjdERPTS5yZW5kZXIoPFNlYXJjaEZpZWxkIC8+LCAkKCcjc2VhcmNoLWZpZWxkLW1vZGFsJylbMF0pO1xyXG5cdH1cclxuXHRcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHNlYXJjaHJlc3VsdDtcclxuIiwibGV0IHNlbGZyZWdpc3RyYXRpb24gPSB7XHJcblx0aW5pdCgpIHtcdFx0XHJcblx0XHQkKCcjanNSZWNhcHRjaGFFcnJvcicpLmhpZGUoKTtcclxuXHRcdCQoXCJmb3JtXCIpLnN1Ym1pdCgoZXZlbnQpID0+IHtcclxuXHRcdFx0dmFyIHJlY2FwdGNoYSA9ICQoXCIjZy1yZWNhcHRjaGEtcmVzcG9uc2VcIikudmFsKCk7XHJcblx0XHRcdGlmIChyZWNhcHRjaGEgPT09IFwiXCIpIHtcclxuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdCQoJyNqc1JlY2FwdGNoYUVycm9yJykuc2hvdygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdCQoJyNqc1JlY2FwdGNoYUVycm9yJykuaGlkZSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdCQoXCJkaXZbY2xhc3NePSdzci1jdXN0b20tZXJyb3InXVwiKS5oaWRlKCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR3aW5kb3cucmVjYXB0Y2hhQ2hlY2tlZCA9ICgpID0+IHtcclxuXHRcdFx0JCgnI2pzUmVjYXB0Y2hhRXJyb3InKS5oaWRlKCk7XHJcblx0XHR9O1xyXG5cclxuXHRcdCQoXCJpbnB1dFwiKS5mb2N1c291dChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdCQodGhpcykucGFyZW50KCkubmV4dEFsbCgnLnNyLWN1c3RvbS1lcnJvcjpmaXJzdCcpLmhpZGUoKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoXCIjY291bnRyeVwiKS5jaGFuZ2UoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHQkKHRoaXMpLnBhcmVudCgpLm5leHRBbGwoJy5zci1jdXN0b20tZXJyb3I6Zmlyc3QnKS5oaWRlKCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKCcjYnRuQWRkU2VyaWFsTnVtYmVyJykub24oJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHRhZGRTZXJpYWxOdW1iZXIoKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoJ2lucHV0I2pzU2VyaWFsTnVtYmVyJykub24oJ2lucHV0JywgZnVuY3Rpb24oKSB7XHRcdFxyXG5cdFx0XHRpZiAoJCh0aGlzKS52YWwoKSAhPT0gJycpIHtcclxuXHRcdFx0XHQkKFwiI2J0bkFkZFNlcmlhbE51bWJlclwiKS5yZW1vdmVBdHRyKFwiZGlzYWJsZWRcIik7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0JChcIiNidG5BZGRTZXJpYWxOdW1iZXJcIikuYXR0cihcImRpc2FibGVkXCIsIFwidHJ1ZVwiKTsgICAgICAgIFxyXG5cdFx0XHR9XHJcblx0XHR9KTsgICBcclxuXHRcdFxyXG5cdFx0ZnVuY3Rpb24gYWRkU2VyaWFsTnVtYmVyKCkge1xyXG5cdFx0XHQkKCcuc3ItY3VzdG9tLWVycm9yX19zZXJpYWxudW1iZXJzJykuaGlkZSgpO1xyXG5cdFx0XHRjb25zdCBzZXJpYWxOdW1iZXJzID0gJCgnaW5wdXQjanNTZXJpYWxOdW1iZXInKS52YWwoKTtcdFx0XHRcclxuXHRcdFx0bGV0IHNlcmlhbE51bWJlciA9ICQoJ2lucHV0I2pzU2VyaWFsTnVtYmVyJykudmFsKCk7XHJcblx0XHRcdGNvbnN0IHJlZ0V4cCA9IG5ldyBSZWdFeHAoXCJeKD8hLiotLSlbYS16QS1aMC05LC1cXFxcc10rJFwiKTtcclxuXHRcdFx0aWYgKCFyZWdFeHAudGVzdChzZXJpYWxOdW1iZXIpKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdFxyXG5cdFx0XHRpZiAoIXZhbGlkYXRlU2VyaWFsTnVtYmVyc0xlbmd0aChzZXJpYWxOdW1iZXJzKSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y29uc3Qgc2VyaWFsTnVtYmVyc0FyciA9IHNlcmlhbE51bWJlcnMuc3BsaXQoXCIsXCIpO1xyXG5cdFx0XHRzZXJpYWxOdW1iZXJzQXJyLmZvckVhY2goKHNlcmlhbE51bWJlcikgPT4ge1x0XHRcdFx0XHJcblx0XHRcdFx0c2VyaWFsTnVtYmVyID0gc2VyaWFsTnVtYmVyLnRyaW0oKTtcclxuXHRcdFx0XHRpZiAoc2VyaWFsTnVtYmVyID09PSAnJykge1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRhZGRTZXJpYWxNb2RlbCgpO1xyXG5cdFx0XHRcdGNvbnN0IGluZGV4ID0gJChcIiNqc1NlcmlhbE51bWJlckxpc3RcIikuY2hpbGRyZW4oXCJsaVwiKS5sZW5ndGg7XHJcblx0XHRcdFx0Y29uc3QgaW5kZXhGaWVsZCA9IFwiPGlucHV0IHR5cGU9J2hpZGRlbicgbmFtZT0nU2VyaWFsTnVtYmVycy5JbmRleCcgdmFsdWU9J1wiICsgaW5kZXggKyBcIicgLz5cIjtcclxuXHRcdFx0XHRjb25zdCBoaWRkZW5WYWx1ZUZpZWxkID0gXCI8aW5wdXQgdHlwZT0naGlkZGVuJyBpZD0nU2VyaWFsTnVtYmVyc19cIiArIGluZGV4ICsgXCJfX05hbWUnIG5hbWU9J0Zvcm1Nb2RlbC5TZXJpYWxOdW1iZXJzW1wiICsgaW5kZXggKyBcIl0uVmFsdWUnIHZhbHVlPSdcIiArIHNlcmlhbE51bWJlciArIFwiJyAvPlwiO1xyXG5cdFx0XHRcdGNvbnN0IHZpc2libGVWYWx1ZSA9IFwiPHNwYW4gY2xhc3M9J3NyLXNlcmlhbC1udW1iZXJfX3JlbW92ZS1idXR0b24td3JhcCc+XCIgKyBzZXJpYWxOdW1iZXIgKyBcIjxpbnB1dCBpZD0nYnRuUmVtb3ZlU2VyaWFsTnVtYmVyJyBjbGFzcz0nc3Itc2VyaWFsLW51bWJlcl9fcmVtb3ZlLWJ1dHRvbicgdHlwZT0nYnV0dG9uJyBvbmNsaWNrPSdyZW1vdmVTZXJpYWxOdW1iZXIoXCIgKyBpbmRleCArIFwiKTsnIC8+PC9zcGFuPlwiO1xyXG5cdFx0XHRcdGNvbnN0IGxpc3RJdGVtID0gXCI8bGkgaWQ9J2pzU2VyaWFsTnVtYmVyXCIgKyBpbmRleCArIFwiJyBjbGFzcz0nc3Itc2VyaWFsLW51bWJlcl9faXRlbSc+XCIgKyBpbmRleEZpZWxkICsgaGlkZGVuVmFsdWVGaWVsZCArIHZpc2libGVWYWx1ZSArIFwiPC9saT5cIjtcclxuXHRcdFx0XHQkKCcjanNTZXJpYWxOdW1iZXJMaXN0JykuYXBwZW5kKGxpc3RJdGVtKTtcclxuXHRcdFx0fSk7XHJcblx0XHRcdCQoJ2lucHV0I2pzU2VyaWFsTnVtYmVyJykudmFsKFwiXCIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZ1bmN0aW9uIHZhbGlkYXRlU2VyaWFsTnVtYmVyc0xlbmd0aChzZXJpYWxOdW1iZXJzKSB7XHJcblx0XHRcdCQoJyNqc1NlcmlhbE1vZGVsRXJyb3InKS5oaWRlKCk7XHRcdFx0XHJcblx0XHRcdGxldCBzZXJpYWxOdW1iZXJzRm9ybWF0dGVkID0gc2VyaWFsTnVtYmVycy5yZXBsYWNlKC9cXHMvZywgJycpO1xyXG5cdFx0XHRzZXJpYWxOdW1iZXJzLnJlcGxhY2UoJywnLCAnJyk7XHJcblx0XHRcdGlmIChzZXJpYWxOdW1iZXJzRm9ybWF0dGVkLmxlbmd0aCA+IDEwMDApIHtcclxuXHRcdFx0XHQkKCcuc3ItY3VzdG9tLWVycm9yX19zZXJpYWxudW1iZXJzJykuc2hvdygpO1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IGV4aXN0aW5nU2VyaWFsc0xlbmd0aCA9IDA7XHJcblx0XHRcdCQoXCJsaS5zci1zZXJpYWwtbnVtYmVyX19pdGVtXCIpLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0ZXhpc3RpbmdTZXJpYWxzTGVuZ3RoICs9ICQodGhpcykudGV4dCgpICE9PSB1bmRlZmluZWQgPyAkKHRoaXMpLnRleHQoKS50cmltKCkubGVuZ3RoIDogMDtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRpZiAoZXhpc3RpbmdTZXJpYWxzTGVuZ3RoICsgc2VyaWFsTnVtYmVyc0Zvcm1hdHRlZC5sZW5ndGggPiAxMDAwKSB7XHJcblx0XHRcdFx0JCgnLnNyLWN1c3RvbS1lcnJvcl9fc2VyaWFsbnVtYmVycycpLnNob3coKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cdFx0XHRcdFx0XHRcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblxyXG5cdFx0d2luZG93LnJlbW92ZVNlcmlhbE51bWJlciA9IChpbmRleCkgPT4ge1xyXG5cdFx0XHRjb25zdCBzZXJpYWxUb0JlUmVtb3ZlZCA9IFwibGkjanNTZXJpYWxOdW1iZXJcIiArIGluZGV4O1xyXG5cdFx0XHQkKHNlcmlhbFRvQmVSZW1vdmVkKS5yZW1vdmUoKTtcclxuXHRcdFx0Y29uc3Qgc2VyaWFsTnVtYmVycyA9ICQoJ2lucHV0I2pzU2VyaWFsTnVtYmVyJykudmFsKCk7XHJcblx0XHRcdHZhbGlkYXRlU2VyaWFsTnVtYmVyc0xlbmd0aChzZXJpYWxOdW1iZXJzKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHNlbGZyZWdpc3RyYXRpb247IiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IHRyYW5zaXRpb24gZnJvbSAnc2VtYW50aWMtdWktdHJhbnNpdGlvbic7XHJcbmltcG9ydCBkcm9wZG93biBmcm9tICdzZW1hbnRpYy11aS1kcm9wZG93bic7XHJcbmxldCBzZW1hbnRpY2Ryb3Bkb3duID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHRpZigkKCcudWkuZHJvcGRvd24uc2VsZWN0Ym94JykubGVuZ3RoID4gMCl7XHJcblx0XHRcdCQoJy51aS5kcm9wZG93bicpLmRyb3Bkb3duKCk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHNlbWFudGljZHJvcGRvd247XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBjbGlwYm9hcmQgZnJvbSAnY2xpcGJvYXJkJztcclxuLy8gaW1wb3J0IGRyb3Bkb3duIGZyb20gJ2Ryb3Bkb3duJztcclxuXHJcbmxldCBzaGFyZSA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0aWYoICQoJy5zaGFyZS1tb2RhbCAuZW1haWwtY29udGFpbmVyJykubGVuZ3RoID4gMCl7XHJcblx0XHRcdHNoYXJlLnJlbmRlckVtYWlsU2VhcmNoKCk7XHJcblx0XHR9XHJcblx0XHR2YXIgY2xpcCA9IG5ldyBjbGlwYm9hcmQoJy5jb3B5LXVybCcpO1xyXG5cdFx0Y2xpcC5vbignc3VjY2VzcycsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0c2hhcmUuYW5pbWF0ZVNoYXJlQnV0dG9uKGUudHJpZ2dlcix0cnVlKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGNsaXAub24oJ2Vycm9yJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRzaGFyZS5hbmltYXRlU2hhcmVCdXR0b24oZS50cmlnZ2VyLGZhbHNlKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoICdib2R5JyApLm9uKCdjbGljaycsICdbZGF0YS1zaGFyZS10eXBlPVwiZW1haWxcIl0nLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdCQoJy5zaGFyZS1tb2RhbCcpLmFkZENsYXNzKCdlbWFpbC1zaGFyZS1vcGVuJyk7XHJcblx0XHR9KTtcclxuXHRcdCQoICdib2R5JyApLm9uKCdjbGljaycsICcuZW1haWwtY29udGFpbmVyIC5iYWNrJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHQkKCcuc2hhcmUtbW9kYWwnKS5yZW1vdmVDbGFzcygnZW1haWwtc2hhcmUtb3BlbicpO1xyXG5cdFx0fSk7XHJcblx0XHQkKCAnYm9keScgKS5vbignY2xpY2snLCAnLmVtYWlsLWNvbnRhaW5lciAuc2VuZCcsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0JCgnLmVtYWlsLWNvbnRhaW5lcicpLmFkZENsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2lzLWxvYWRpbmcnKTtcclxuXHJcblx0XHR9KTtcclxuXHJcblx0fSxcclxuXHRhbmltYXRlU2hhcmVCdXR0b24oZWwsIGRpZFN1Y2NlZWQpe1xyXG5cdFx0aWYoIGRpZFN1Y2NlZWQpe1xyXG5cdFx0XHQkKGVsKS5hZGRDbGFzcygnc2hhcmUtc3VjY2VzcycpO1xyXG5cdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdCQoZWwpLnJlbW92ZUNsYXNzKCdzaGFyZS1zdWNjZXNzJyk7XHJcblx0XHRcdFx0JChlbCkuYWRkQ2xhc3MoJ3NoYXJlLWRvbmUnKTtcclxuXHRcdFx0fSwgMTUwMCk7XHJcblx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0JChlbCkucmVtb3ZlQ2xhc3MoJ3NoYXJlLWRvbmUnKTtcclxuXHRcdFx0fSwgNzUwMCk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0Ly8gVE9ETzogZG8gc29tZXRoaW5nIGZvciB0aGUgZXJyb3JcclxuXHRcdH1cclxuXHR9LFxyXG5cdHJlbmRlckVtYWlsU2VhcmNoKCl7XHJcblx0XHQkKCcuZW1haWwtY29udGFpbmVyIC51aS5kcm9wZG93bicpLmRyb3Bkb3duKHtcclxuXHRcdFx0ZnVsbFRleHRTZWFyY2g6IHRydWUsXHJcblx0XHRcdGFsbG93QWRkaXRpb25zOiB0cnVlLFxyXG5cdFx0XHRtZXNzYWdlOiB7XHJcblx0XHRcdFx0YWRkUmVzdWx0OiAnIyFTZW5kIHRvOiA8Yj57dGVybX08L2I+J1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24odmFsdWUsIHRleHQsICRjaG9pY2UpIHtcclxuXHRcdFx0XHRsZXQgYnRuID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKCdidXR0b24nKTtcclxuXHRcdFx0XHRidG4ucHJvcCgnZGlzYWJsZWQnLCBzaGFyZS52YWxpZGF0ZUFzRW1haWwodmFsdWUpKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0b25BZGQ6IGZ1bmN0aW9uKGFkZGVkVmFsdWUsIGFkZGVkVGV4dCwgJGFkZGVkQ2hvaWNlKXtcclxuXHRcdFx0XHRsZXQgYnRuID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKCdidXR0b24nKTtcclxuXHRcdFx0XHRidG4ucHJvcCgnZGlzYWJsZWQnLCBzaGFyZS52YWxpZGF0ZUFzRW1haWwoYWRkZWRWYWx1ZSkpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cdHZhbGlkYXRlQXNFbWFpbCh2YWx1ZSl7XHJcblx0XHR2YXIgcmUgPSAvXigoW148PigpXFxbXFxdXFxcXC4sOzpcXHNAXCJdKyhcXC5bXjw+KClcXFtcXF1cXFxcLiw7Olxcc0BcIl0rKSopfChcIi4rXCIpKUAoKFxcW1swLTldezEsM31cXC5bMC05XXsxLDN9XFwuWzAtOV17MSwzfVxcLlswLTldezEsM31dKXwoKFthLXpBLVpcXC0wLTldK1xcLikrW2EtekEtWl17Mix9KSkkLztcclxuICAgIHJldHVybiAhcmUudGVzdCh2YWx1ZSk7XHJcblx0fVxyXG5cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHNoYXJlO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgbGlnaHRzbGlkZXIgZnJvbSAnbGlnaHRzbGlkZXInO1xyXG5pbXBvcnQgQ3VzdG9tRXZlbnRzIGZyb20gJy4vY3VzdG9tLWV2ZW50cyc7XHJcblxyXG5sZXQgc3RhcnRwYWdlc2xpZGVyID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHR2YXIgc2xpZGVyID0gJChcIiNzdGFydHBhZ2Utc2xpZGVyXCIpLmxpZ2h0U2xpZGVyKHtcclxuXHRcdFx0aXRlbTogMSxcclxuXHRcdFx0c2xpZGVNb3ZlOiAxLFxyXG5cdFx0XHRzbGlkZU1hcmdpbjogMCxcclxuXHRcdFx0c3BlZWQ6IDcwMCwgLy9tcydcclxuICAgICAgYXV0bzogdHJ1ZSxcclxuICAgICAgbG9vcDogdHJ1ZSxcclxuXHRcdFx0cGF1c2VPbkhvdmVyOiB0cnVlLFxyXG4gICAgICBwYXVzZTogNTAwMCxcclxuXHRcdFx0Y29udHJvbHM6IGZhbHNlLFxyXG5cdFx0XHRyZXBzb25zaXZlOiB0cnVlLFxyXG5cdFx0XHRvblNsaWRlckxvYWQ6IGZ1bmN0aW9uIChlbCkge1xyXG5cdFx0XHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyU2xpZGVyQWRJbXByZXNzaW9uRXZlbnQoZWwpO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRvbkFmdGVyU2xpZGU6IGZ1bmN0aW9uIChlbCkge1xyXG5cdFx0XHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyU2xpZGVyQWRJbXByZXNzaW9uRXZlbnQoZWwpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKCcuanNUcmFja0FkQ2xpY2snKS5vbignY2xpY2snLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VyU2xpZGVyQWRDbGlja0V2ZW50KGUpO1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnI3NsaWRlci1wbGF5JywgZnVuY3Rpb24oZSkge1xyXG4gICAgICBzbGlkZXIucGxheSgpO1xyXG5cdFx0XHQkKHRoaXMpLmhpZGUoKTtcclxuXHRcdFx0JCgnI3NsaWRlci1wYXVzZScpLnNob3coKTtcclxuICAgIH0pO1xyXG4gICAgJCgnYm9keScpLm9uKCdjbGljaycsICcjc2xpZGVyLXBhdXNlJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICBzbGlkZXIucGF1c2UoKTtcclxuXHRcdFx0JCh0aGlzKS5oaWRlKCk7XHJcblx0XHRcdCQoJyNzbGlkZXItcGxheScpLnNob3coKTtcclxuICAgIH0pO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgc3RhcnRwYWdlc2xpZGVyO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5cclxubGV0IHRvZ2dsZXIgPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdHRoaXMuYmluZEV2ZW50cygpO1xyXG5cdFx0JCgnaHRtbCcpLmNsaWNrKGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGlmICgkKCcudWMtbGFuZ3VhZ2Utc2VsZWN0b3InKS5oYXNDbGFzcygnaXMtb3BlbicpKSB7XHJcblx0XHRcdFx0aWYgKCQoZS50YXJnZXQpLmRhdGEoJ3RvZ2dsZScpICE9ICcudWMtbGFuZ3VhZ2Utc2VsZWN0b3InKSB7XHJcblx0XHRcdFx0XHQkKCcudWMtbGFuZ3VhZ2Utc2VsZWN0b3InKS5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0Ly8gYmluZEV2ZW50cyhpLCB0b2dnbGVyRWxtKSB7XHJcblx0YmluZEV2ZW50cygpIHtcclxuXHRcdGxldCBzZWxmID0gdGhpcztcclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnW2RhdGEtdG9nZ2xlXScsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0bGV0IHNsaWRlRWxtID0gJCh0aGlzKS5hdHRyKCdkYXRhLXRvZ2dsZS1zbGlkZScpO1xyXG5cclxuXHRcdFx0aWYgKHNsaWRlRWxtKSB7XHJcblx0XHRcdFx0c2VsZi5zbGlkZVRvZ2dsZShzbGlkZUVsbSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHNlbGYuc2V0U3RhdGVzKHRoaXMsICQodGhpcykuYXR0cignZGF0YS10b2dnbGUnKSk7XHJcblxyXG5cdFx0XHQvL1NldCBmb2N1cyBlbGVtZW50XHJcblx0XHRcdHNlbGYuc2V0Rm9jdXMoJCh0aGlzKS5hdHRyKCdkYXRhLXRvZ2dsZS1zZXRmb2N1c3RvJykpO1xyXG5cclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHNldFN0YXRlcyhlbCwgb2JqKSB7XHJcblx0XHRsZXQgJGVsID0gJChlbCk7XHJcblx0XHRsZXQgJHNwYW5TaG93ID0gJGVsLmZpbmQoXCJzcGFuLnNob3dcIik7XHJcblx0XHRsZXQgJHNwYW5IaWRlID0gJGVsLmZpbmQoXCJzcGFuLmhpZGVcIik7XHJcblxyXG5cdFx0bGV0ICRvYmo7XHJcblx0XHRpZiAob2JqLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0JG9iaiA9IG9iaiA9PSAncGFyZW50JyA/ICRlbC5wYXJlbnQoKSA6ICQob2JqKTtcclxuXHRcdH1cclxuXHRcdGlmICgkb2JqLmlzKCcuaXMtb3BlbicpKSB7XHJcblx0XHRcdCRlbC5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHQkb2JqLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdGlmICgkc3BhbkhpZGUuaXMoXCI6dmlzaWJsZVwiKSkge1xyXG5cdFx0XHRcdCRzcGFuSGlkZS5oaWRlKCk7XHJcblx0XHRcdFx0JHNwYW5TaG93LnNob3coKTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0JGVsLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdCRvYmouYWRkQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0aWYgKCRzcGFuU2hvdy5pcyhcIjp2aXNpYmxlXCIpKSB7XHJcblx0XHRcdFx0JHNwYW5TaG93LmhpZGUoKTtcclxuXHRcdFx0XHQkc3BhbkhpZGUuc2hvdygpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0c2V0Rm9jdXMoZWwpIHtcclxuXHRcdGxldCAkZWwgPSAkKGVsKTtcclxuXHRcdGlmICgkZWwubGVuZ3RoID4gMCkgJGVsLmZvY3VzKCk7XHJcblx0fSxcclxuXHJcblx0c2xpZGVUb2dnbGUoZWwpIHtcclxuXHRcdGxldCAkZWwgPSAkKGVsKTtcclxuXHRcdGlmICgkZWwuaXMoJy5pcy1vcGVuJykpIHtcclxuXHRcdFx0JGVsLnNsaWRlVXAoKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdCRlbC5zbGlkZURvd24oKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgdG9nZ2xlcjtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmxldCB0b2dnbGVySGVhZGVyID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHR0aGlzLmJpbmRFdmVudHMoKTtcclxuXHRcdCQoJ2h0bWwnKS5jbGljayhmdW5jdGlvbihlKSB7XHJcblx0XHRcdGlmKCAkKCcudWMtbGFuZ3VhZ2Utc2VsZWN0b3InKS5oYXNDbGFzcygnaXMtb3BlbicpICl7XHJcblx0XHRcdFx0aWYoICQoZS50YXJnZXQpLmRhdGEoJ3RvZ2dsZScpICE9ICcudWMtbGFuZ3VhZ2Utc2VsZWN0b3InKXtcclxuXHRcdFx0XHRcdCQoJy51Yy1sYW5ndWFnZS1zZWxlY3RvcicpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRiaW5kRXZlbnRzKCkge1xyXG5cdFx0bGV0IHNlbGYgPSB0aGlzO1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICdbZGF0YS10b2dnbGUtaGVhZGVyXScsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRcdGxldCAkZWwgPSAkKCQodGhpcykuZGF0YSgndG9nZ2xlLWhlYWRlcicpKTtcclxuXHRcdFx0bGV0ICRlbEJ0biA9ICQoJCh0aGlzKSk7XHJcblxyXG5cdFx0XHRpZigkZWwuaXMoJy5pcy1vcGVuJykpIHtcclxuXHRcdFx0XHQkKCcuaGVhZGVyLWRpYWxvZycpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0JCgnW2RhdGEtdG9nZ2xlLWhlYWRlcl0nKS5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdCQoJy5oZWFkZXItZGlhbG9nJykucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0XHQkKCdbZGF0YS10b2dnbGUtaGVhZGVyXScpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0JGVsLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0JGVsQnRuLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdH1cclxuXHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgdG9nZ2xlckhlYWRlcjtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XHJcbmltcG9ydCBVc2VyQWRkcmVzc2VzRGVmYXVsdCBmcm9tICcuLi91c2VyX2FkZHJlc3Nlcy91c2VyX2FkZHJlc3Nlc19kZWZhdWx0JztcclxuaW1wb3J0IFVzZXJBZGRyZXNzZXNJdGVtIGZyb20gJy4uL3VzZXJfYWRkcmVzc2VzL3VzZXJfYWRkcmVzc2VzX2l0ZW0nO1xyXG5pbXBvcnQgVXNlckFkZHJlc3Nlc0FkZEl0ZW0gZnJvbSAnLi4vdXNlcl9hZGRyZXNzZXMvYWRkcmVzc19hZGRfaXRlbSc7XHJcblxyXG5sZXQgdXNlcmFkZHJlc3NlcyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0aWYoJCgnI3VzZXJEZWZhdWx0QWRkcmVzcycpLmxlbmd0aCA+IDApIFJlYWN0RE9NLnJlbmRlcig8VXNlckFkZHJlc3Nlc0RlZmF1bHQvPiwgJCgnI3VzZXJEZWZhdWx0QWRkcmVzcycpWzBdKTtcclxuXHRcdGlmKCQoJyN1c2VyQWRkcmVzc2VzJykubGVuZ3RoID4gMCkgUmVhY3RET00ucmVuZGVyKDxVc2VyQWRkcmVzc2VzSXRlbS8+LCAkKCcjdXNlckFkZHJlc3NlcycpWzBdKTtcclxuXHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJy5hZGQtYWRkcmVzcyBidXR0b24nLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0JCgnLnVzZXItYWRkcmVzcy5hZGQtbmV3JykuYWRkQ2xhc3MoJ2FkZGluZycpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICcuYWRkLWFkZHJlc3MgYnV0dG9uJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdCQoJy51c2VyLWFkZHJlc3MuYWRkLW5ldycpLmFkZENsYXNzKCdhZGRpbmcnKTtcclxuXHRcdH0pO1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICcjdG9nZ2xlLXNoaXBwaW5nLWFkZHJlc3MnLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdHZhciAkZWwgPSAkKCcjdXNlci1zaGlwcGluZy1hZGRyZXNzJyk7XHJcblx0XHRcdGxldCAkc3BhblNob3cgPSAkKHRoaXMpLmZpbmQoXCJzcGFuLnNob3dcIik7XHJcblx0XHRcdGxldCAkc3BhbkhpZGUgPSAkKHRoaXMpLmZpbmQoXCJzcGFuLmhpZGVcIik7XHJcblxyXG5cdFx0XHRpZiAoJGVsLmhhc0NsYXNzKCdpcy1vcGVuJykpIHtcclxuXHRcdFx0XHQkZWwucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0XHQkc3BhblNob3cuaGlkZSgpO1xyXG5cdFx0XHRcdCRzcGFuSGlkZS5zaG93KCk7XHJcblxyXG5cdFx0XHR9ZWxzZSB7XHJcblx0XHRcdFx0JGVsLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0JHNwYW5IaWRlLmhpZGUoKTtcclxuXHRcdFx0XHQkc3BhblNob3cuc2hvdygpO1xyXG5cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJyN0b2dnbGUtYmlsbGluZy1hZGRyZXNzJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHR2YXIgJGVsID0gJCgnI3VzZXItYmlsbGluZy1hZGRyZXNzJyk7XHJcblx0XHRcdGxldCAkc3BhblNob3cgPSAkKHRoaXMpLmZpbmQoXCJzcGFuLnNob3dcIik7XHJcblx0XHRcdGxldCAkc3BhbkhpZGUgPSAkKHRoaXMpLmZpbmQoXCJzcGFuLmhpZGVcIik7XHJcblxyXG5cdFx0XHRpZiAoJGVsLmhhc0NsYXNzKCdpcy1vcGVuJykpIHtcclxuXHRcdFx0XHQkZWwucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0XHQkc3BhblNob3cuaGlkZSgpO1xyXG5cdFx0XHRcdCRzcGFuSGlkZS5zaG93KCk7XHJcblx0XHRcdH1lbHNlIHtcclxuXHRcdFx0XHQkZWwuYWRkQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHJcblx0XHRcdFx0JHNwYW5IaWRlLmhpZGUoKTtcclxuXHRcdFx0XHQkc3BhblNob3cuc2hvdygpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCB1c2VyYWRkcmVzc2VzO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBBZGRyZXNzQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy91c2VyX2FkZHJlc3Nlc19hY3Rpb25zJztcclxuXHJcbmxldCBBZGRyZXNzRmllbGRTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBBZGRyZXNzQWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuXHRcdHRoaXMucG9zdGFsQ29kZUlzVmFsaWQgPSBmYWxzZTtcclxuICB9LFxyXG5cclxuXHRjaGVja1Bvc3RhbENvZGVDb21wbGV0ZWQocmVzdWx0KXtcclxuICAgIHRoaXMucG9zdGFsQ29kZUlzVmFsaWQgPSByZXN1bHQ7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5wb3N0YWxDb2RlSXNWYWxpZCk7XHJcbiAgfSxcclxuXHJcbiAgLy8gY2hlY2tQb3N0YWxDb2RlRmFpbGVkKHJlc3VsdCl7XHJcbiAgLy8gICB0aGlzLnBvc3RhbENvZGVJc1ZhbGlkID0gcmVzdWx0O1xyXG5cdC8vIFx0dGhpcy50cmlnZ2VyKHRoaXMucG9zdGFsQ29kZUlzVmFsaWQpO1xyXG4gIC8vIH0sXHJcblxyXG4gIGlzUG9zdGFsQ29ycmVjdCgpe1xyXG4gICAgcmV0dXJuIHRoaXMucG9zdGFsQ29kZUlzVmFsaWQ7XHJcbiAgfSxcclxuXHJcbiAgcmVzZXRQb3N0YWxDb2RlKCl7XHJcbiAgICB0aGlzLnBvc3RhbENvZGVJc1ZhbGlkID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gfSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBBZGRyZXNzRmllbGRTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgQnJhbmRGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2JyYW5kX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IFRvZ2dsZUZpbHRlclN0b3JlTWl4aW4gZnJvbSAnLi90b2dnbGVfZmlsdGVyX3N0b3JlX21peGluJztcclxuXHJcbmxldCBCcmFuZEZpbHRlclN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHRsaXN0ZW5hYmxlczogQnJhbmRGaWx0ZXJBY3Rpb25zLFxyXG4gIG1peGluczogW1RvZ2dsZUZpbHRlclN0b3JlTWl4aW5dLFxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJyYW5kRmlsdGVyU3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxubGV0IEJyZWFkY3J1bWJTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmJyZWFkY3VtYiA9IFtdO1xyXG4gIH0sXHJcblxyXG4gIGdldFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuYnJlYWRjdW1iO1xyXG4gIH0sXHJcblxyXG4gIGdldChjYWNoZUtleSkge1xyXG4gICAgcmV0dXJuIF8uZmluZFdoZXJlKHRoaXMuYnJlYWRjdW1iLCB7IGtleTogY2FjaGVLZXkgfSk7XHJcbiAgfSxcclxuXHJcbiAgc2V0KGtleSwgZGF0YSkge1xyXG4gICAgdGhpcy5icmVhZGN1bWIucHVzaCh7IGtleToga2V5LCBkYXRhOiBkYXRhIH0pO1xyXG4gIH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQnJlYWRjcnVtYlN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jYXJ0X2FjdGlvbnMnO1xyXG5cclxubGV0IENhcnRTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDYXJ0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMuY2FydCA9IFtdO1xyXG5cdFx0dGhpcy5lcnJvciA9IHt9O1xyXG4gIH0sXHJcblxyXG4gIGdldFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2FydDtcclxuICB9LFxyXG5cclxuXHRvbkxvYWRDYXJ0OiBmdW5jdGlvbigpIHtcclxuXHRcdHRoaXMuY2FydCA9IFtdO1xyXG4gICAgdGhpcy5sb2FkRXJyb3IgPSBudWxsO1xyXG4gIH0sXHJcblxyXG4gIG9uTG9hZENhcnRDb21wbGV0ZWQocmVzLCB1cGRhdGVkUXVhbnRpdHkpIHtcclxuXHRcdHRoaXMuY2FydCA9IHJlcztcclxuICAgIHRoaXMubG9hZEVycm9yID0gJyc7XHJcblx0XHRpZihyZXMuZXJyb3Ipe1xyXG5cdFx0XHR0aGlzLmVycm9yID0gcmVzLmVycm9yO1xyXG5cdFx0fVxyXG5cdFx0aWYodXBkYXRlZFF1YW50aXR5KXtcclxuXHRcdFx0dGhpcy5jYXJ0LlVwZGF0ZWRJdGVtID0gdXBkYXRlZFF1YW50aXR5O1xyXG5cdFx0fVxyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuY2FydCk7XHJcbiAgfSxcclxuXHJcblxyXG4gIG9uTG9hZENhcnRGYWlsZWQocmVzcG9uc2UsIHNrdUlkKSB7XHJcbiAgICAvLyB0aGlzLmxvYWRFcnJvciA9IFwiQ291bGQgbm90IGxvYWQgY2FydC5cIjtcclxuXHRcdHRoaXMuY2FydC5lcnJvciA9IHt9O1xyXG5cdFx0dGhpcy5jYXJ0LmVycm9yLkZhaWxlZCA9IFtdO1xyXG5cdFx0dGhpcy5jYXJ0LmVycm9yLkZhaWxlZC5wdXNoKHtDb2RlOiBza3VJZCwgV2FybmluZ01lc3NhZ2U6ICdDb3VsZCBub3QgbG9hZCBjYXJ0LicsUmVzcG9uc2U6IHJlc3BvbnNlfSk7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5jYXJ0KTtcclxuICB9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENhcnRTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5cclxubGV0IENhdGVnb3J5RmlsdGVyU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG4gIGluaXQoKSB7XHJcbiAgICB0aGlzLmZpbHRlcnMgPSB0aGlzLmZpbHRlcnMgfHwgW107XHJcbiAgfSxcclxuXHJcbiAgZ2V0SW5pdGlhbFN0YXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZmlsdGVycztcclxuICB9LFxyXG5cclxuXHRoeWRyYXRlKHN0YXRlKSB7XHJcblx0XHR0aGlzLmZpbHRlcnMgPSBzdGF0ZS5maWx0ZXJzO1xyXG5cdH0sXHJcblxyXG5cdGRlaHlkcmF0ZSgpIHtcclxuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh7IGZpbHRlcnM6IHRoaXMuZmlsdGVycyB9KTtcclxuXHR9XHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2F0ZWdvcnlGaWx0ZXJTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2NoZWNrb3V0X2FjdGlvbnMnO1xyXG5cclxubGV0IENoZWNrb3V0QWRkcmVzc2VzQWxlcnRTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmNoZWNrb3V0QWRkcmVzc2VzQWxlcnQgPSB7fTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0QWRkcmVzc2VzQWxlcnQ7XHJcbiAgfSxcclxuXHRzZXRTdG9yZShzdG9yZSkge1xyXG5cdFx0dGhpcy5jaGVja291dEFkZHJlc3Nlc0FsZXJ0ID0gc3RvcmU7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dEFkZHJlc3Nlc0FsZXJ0KTtcclxuXHR9XHJcblx0Ly8gLFxyXG5cdC8vXHJcblx0Ly8gb25Mb2FkY2hlY2tvdXRBZGRyZXNzZXNBbGVydDogZnVuY3Rpb24oKSB7XHJcblx0Ly8gXHR0aGlzLmNoZWNrb3V0QWRkcmVzc2VzQWxlcnQgPSBudWxsO1xyXG5cdC8vIFx0dGhpcy5sb2FkRXJyb3IgPSBudWxsO1xyXG4gIC8vIH0sXHJcbiAgLy8gb25Mb2FkY2hlY2tvdXRBZGRyZXNzZXNBbGVydENvbXBsZXRlZChyZXMpIHtcclxuXHQvLyBcdHRoaXMuY2hlY2tvdXRBZGRyZXNzZXNBbGVydCA9IHJlcztcclxuICAvLyAgIHRoaXMubG9hZEVycm9yID0gJyc7XHJcblx0Ly8gXHQvLyAkKCcjc2hpcHBpbmctYWRkcmVzcywgLnVjLWNoZWNrb3V0LXN1bW1hcnksIC51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuICAvLyAgIHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0QWRkcmVzc2VzQWxlcnQpO1xyXG4gIC8vIH0sXHJcblx0Ly9cclxuICAvLyBvbkxvYWRjaGVja291dEFkZHJlc3Nlc0FsZXJ0RmFpbGVkKCkge1xyXG4gIC8vICAgdGhpcy5sb2FkRXJyb3IgPSBcIkNvdWxkIG5vdCBsb2FkIGNhcnQuXCI7XHJcblx0Ly8gXHQkKCcjc2hpcHBpbmctYWRkcmVzcywgLnVjLWNoZWNrb3V0LXN1bW1hcnksIC51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuICAvLyAgIHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0QWRkcmVzc2VzQWxlcnQpO1xyXG4gIC8vIH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRBZGRyZXNzZXNBbGVydFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRBZGRyZXNzZXNTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmNoZWNrb3V0QWRkcmVzc2VzID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja291dEFkZHJlc3NlcztcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0QWRkcmVzc2VzID0gc3RvcmU7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dEFkZHJlc3Nlcyk7XHJcblx0fVxyXG5cdC8vICxcclxuXHQvL1xyXG5cdC8vIG9uTG9hZGNoZWNrb3V0QWRkcmVzc2VzOiBmdW5jdGlvbigpIHtcclxuXHQvLyBcdHRoaXMuY2hlY2tvdXRBZGRyZXNzZXMgPSBudWxsO1xyXG5cdC8vIFx0dGhpcy5sb2FkRXJyb3IgPSBudWxsO1xyXG4gIC8vIH0sXHJcbiAgLy8gb25Mb2FkY2hlY2tvdXRBZGRyZXNzZXNDb21wbGV0ZWQocmVzKSB7XHJcblx0Ly8gXHR0aGlzLmNoZWNrb3V0QWRkcmVzc2VzID0gcmVzO1xyXG4gIC8vICAgdGhpcy5sb2FkRXJyb3IgPSAnJztcclxuXHQvLyBcdC8vICQoJyNzaGlwcGluZy1hZGRyZXNzLCAudWMtY2hlY2tvdXQtc3VtbWFyeSwgLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMnKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG4gIC8vICAgdGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXRBZGRyZXNzZXMpO1xyXG4gIC8vIH0sXHJcblx0Ly9cclxuICAvLyBvbkxvYWRjaGVja291dEFkZHJlc3Nlc0ZhaWxlZCgpIHtcclxuICAvLyAgIHRoaXMubG9hZEVycm9yID0gXCJDb3VsZCBub3QgbG9hZCBjYXJ0LlwiO1xyXG5cdC8vIFx0JCgnI3NoaXBwaW5nLWFkZHJlc3MsIC51Yy1jaGVja291dC1zdW1tYXJ5LCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucycpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgLy8gICB0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dEFkZHJlc3Nlcyk7XHJcbiAgLy8gfVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEFkZHJlc3Nlc1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRCaWxsaW5nU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogQ2hlY2tvdXRBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG4gICAgdGhpcy5jaGVja291dEJpbGxpbmcgPSB7fTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0QmlsbGluZztcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0QmlsbGluZyA9IHN0b3JlO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXRCaWxsaW5nKTtcclxuXHR9XHJcblx0Ly8gLFxyXG5cdC8vXHJcblx0Ly8gb25Mb2FkY2hlY2tvdXRBZGRyZXNzZXM6IGZ1bmN0aW9uKCkge1xyXG5cdC8vIFx0dGhpcy5jaGVja291dEFkZHJlc3NlcyA9IG51bGw7XHJcblx0Ly8gXHR0aGlzLmxvYWRFcnJvciA9IG51bGw7XHJcbiAgLy8gfSxcclxuICAvLyBvbkxvYWRjaGVja291dEFkZHJlc3Nlc0NvbXBsZXRlZChyZXMpIHtcclxuXHQvLyBcdHRoaXMuY2hlY2tvdXRBZGRyZXNzZXMgPSByZXM7XHJcbiAgLy8gICB0aGlzLmxvYWRFcnJvciA9ICcnO1xyXG5cdC8vIFx0Ly8gJCgnI3NoaXBwaW5nLWFkZHJlc3MsIC51Yy1jaGVja291dC1zdW1tYXJ5LCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucycpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgLy8gICB0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dEFkZHJlc3Nlcyk7XHJcbiAgLy8gfSxcclxuXHQvL1xyXG4gIC8vIG9uTG9hZGNoZWNrb3V0QWRkcmVzc2VzRmFpbGVkKCkge1xyXG4gIC8vICAgdGhpcy5sb2FkRXJyb3IgPSBcIkNvdWxkIG5vdCBsb2FkIGNhcnQuXCI7XHJcblx0Ly8gXHQkKCcjc2hpcHBpbmctYWRkcmVzcywgLnVjLWNoZWNrb3V0LXN1bW1hcnksIC51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuICAvLyAgIHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0QWRkcmVzc2VzKTtcclxuICAvLyB9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QmlsbGluZ1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRDYXJ0QWxlcnRTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmNoZWNrb3V0Q2FydEFsZXJ0ID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja291dENhcnRBbGVydDtcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0Q2FydEFsZXJ0ID0gc3RvcmU7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dENhcnRBbGVydCk7XHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDaGVja291dENhcnRBbGVydFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRDYXJ0U3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogQ2hlY2tvdXRBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG4gICAgdGhpcy5jaGVja291dENhcnQgPSB7fTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0Q2FydDtcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0Q2FydCA9IHN0b3JlO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXRDYXJ0KTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Q2FydFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRDYXJ0VG90YWxTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmNoZWNrb3V0Q2FydFRvdGFsID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja291dENhcnRUb3RhbDtcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0Q2FydFRvdGFsID0gc3RvcmU7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dENhcnRUb3RhbCk7XHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDaGVja291dENhcnRUb3RhbFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRDYXJ0V2FybmluZ1N0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IENoZWNrb3V0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMuY2hlY2tvdXRDYXJ0V2FybmluZyA9IHt9O1xyXG4gIH0sXHJcblxyXG4gIGdldFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2hlY2tvdXRDYXJ0V2FybmluZztcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0Q2FydFdhcm5pbmcgPSBzdG9yZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0Q2FydFdhcm5pbmcpO1xyXG5cdH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRDYXJ0V2FybmluZ1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXREYW5nZXJvdXNHb29kc0FsZXJ0U3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogQ2hlY2tvdXRBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG4gICAgdGhpcy5jaGVja291dERhbmdlcm91c0dvb2RzQWxlcnQgPSB7fTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydDtcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydCA9IHN0b3JlO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXREYW5nZXJvdXNHb29kc0FsZXJ0KTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRMb2FkaW5nU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogQ2hlY2tvdXRBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG4gICAgdGhpcy5jaGVja291dExvYWRpbmcgPSBmYWxzZTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0TG9hZGluZztcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0TG9hZGluZyA9IHN0b3JlO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXRMb2FkaW5nKTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0TG9hZGluZ1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRPcmRlclNpbXVsYXRpb25TdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLnNpbXVsYXRlZE9yZGVyID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zaW11bGF0ZWRPcmRlcjtcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLnNpbXVsYXRlZE9yZGVyID0gc3RvcmU7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5zaW11bGF0ZWRPcmRlcik7XHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDaGVja291dE9yZGVyU2ltdWxhdGlvblN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRTaGlwcGluZ1N0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IENoZWNrb3V0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMuY2hlY2tvdXRTaGlwcGluZyA9IHt9O1xyXG4gIH0sXHJcblxyXG4gIGdldFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2hlY2tvdXRTaGlwcGluZztcclxuICB9LFxyXG5cdHNldFN0b3JlKHN0b3JlKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0U2hpcHBpbmcgPSBzdG9yZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0U2hpcHBpbmcpO1xyXG5cdH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRTaGlwcGluZ1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9ucyc7XHJcblxyXG5sZXQgQ2hlY2tvdXRTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBDaGVja291dEFjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLmNoZWNrb3V0ID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja291dDtcclxuICB9LFxyXG5cclxuXHRvbkxvYWRDaGVja291dDogZnVuY3Rpb24oKSB7XHJcblx0XHR0aGlzLmNoZWNrb3V0ID0gbnVsbDtcclxuXHRcdHRoaXMubG9hZEVycm9yID0gbnVsbDtcclxuICB9LFxyXG5cclxuICBvbkxvYWRDaGVja291dENvbXBsZXRlZChyZXMpIHtcclxuXHRcdHRoaXMuY2hlY2tvdXQgPSByZXM7XHJcbiAgICB0aGlzLmxvYWRFcnJvciA9ICcnO1xyXG5cdFx0JCgnI3NoaXBwaW5nLWFkZHJlc3MsIC51Yy1jaGVja291dC1zdW1tYXJ5LCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucycpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dCk7XHJcbiAgfSxcclxuXHJcbiAgb25Mb2FkQ2hlY2tvdXRGYWlsZWQoKSB7XHJcbiAgICB0aGlzLmxvYWRFcnJvciA9IFwiQ291bGQgbm90IGxvYWQgY2FydC5cIjtcclxuXHRcdCQoJyNzaGlwcGluZy1hZGRyZXNzLCAudWMtY2hlY2tvdXQtc3VtbWFyeSwgLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMnKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuY2hlY2tvdXQpO1xyXG4gIH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2NoZWNrb3V0X2FjdGlvbnMnO1xyXG5cclxubGV0IENoZWNrb3V0U3VtbWFyeVN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IENoZWNrb3V0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMuY2hlY2tvdXRTdW1tYXJ5ID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0U3RvcmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jaGVja291dFN1bW1hcnk7XHJcbiAgfSxcclxuXHRzZXRTdG9yZShzdG9yZSkge1xyXG5cdFx0dGhpcy5jaGVja291dFN1bW1hcnkgPSBzdG9yZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0U3VtbWFyeSk7XHJcblx0fVxyXG5cdC8vICxcclxuXHQvL1xyXG5cdC8vIG9uTG9hZGNoZWNrb3V0U3VtbWFyeTogZnVuY3Rpb24oKSB7XHJcblx0Ly8gXHR0aGlzLmNoZWNrb3V0U3VtbWFyeSA9IG51bGw7XHJcblx0Ly8gXHR0aGlzLmxvYWRFcnJvciA9IG51bGw7XHJcbiAgLy8gfSxcclxuICAvLyBvbkxvYWRjaGVja291dFN1bW1hcnlDb21wbGV0ZWQocmVzKSB7XHJcblx0Ly8gXHR0aGlzLmNoZWNrb3V0U3VtbWFyeSA9IHJlcztcclxuICAvLyAgIHRoaXMubG9hZEVycm9yID0gJyc7XHJcblx0Ly8gXHQvLyAkKCcjc2hpcHBpbmctYWRkcmVzcywgLnVjLWNoZWNrb3V0LXN1bW1hcnksIC51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuICAvLyAgIHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0U3VtbWFyeSk7XHJcbiAgLy8gfSxcclxuXHQvL1xyXG4gIC8vIG9uTG9hZGNoZWNrb3V0U3VtbWFyeUZhaWxlZCgpIHtcclxuICAvLyAgIHRoaXMubG9hZEVycm9yID0gXCJDb3VsZCBub3QgbG9hZCBjYXJ0LlwiO1xyXG5cdC8vIFx0JCgnI3NoaXBwaW5nLWFkZHJlc3MsIC51Yy1jaGVja291dC1zdW1tYXJ5LCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucycpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgLy8gICB0aGlzLnRyaWdnZXIodGhpcy5jaGVja291dFN1bW1hcnkpO1xyXG4gIC8vIH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRTdW1tYXJ5U3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IENoZWNrb3V0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zJztcclxuXHJcbmxldCBDaGVja291dFRyYWNraW5nRGF0YVN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IENoZWNrb3V0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMuY2hlY2tvdXRUcmFja2luZ0RhdGEgPSB7fTtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmNoZWNrb3V0VHJhY2tpbmdEYXRhO1xyXG4gIH0sXHJcblx0c2V0U3RvcmUoc3RvcmUpIHtcclxuXHRcdHRoaXMuY2hlY2tvdXRUcmFja2luZ0RhdGEgPSBzdG9yZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmNoZWNrb3V0VHJhY2tpbmdEYXRhKTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0VHJhY2tpbmdEYXRhU3RvcmU7XHJcbiIsIlxyXG5pbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBCcmFuZEZpbHRlclN0b3JlIGZyb20gJy4vYnJhbmRfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IFVzYWdlVHlwZUZpbHRlclN0b3JlIGZyb20gJy4vdXNhZ2VfdHlwZV9maWx0ZXJfc3RvcmUnO1xyXG5cclxubGV0IHN0YXRlID0ge1xyXG4gIGJyYW5kRmlsdGVyQ291bnQ6IDAsXHJcbiAgdXNhZ2VUeXBlRmlsdGVyQ291bnQ6IDBcclxufTtcclxuXHJcbmxldCBGaWx0ZXJDb3VudFN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5saXN0ZW5UbyhCcmFuZEZpbHRlclN0b3JlLCB0aGlzLm9uQnJhbmRGaWx0ZXJzQ2hhbmdlKTtcclxuICAgIHRoaXMubGlzdGVuVG8oVXNhZ2VUeXBlRmlsdGVyU3RvcmUsIHRoaXMub25Vc2FnZVR5cGVGaWx0ZXJDaGFuZ2UpO1xyXG4gIH0sXHJcblxyXG4gIGdldEluaXRpYWxTdGF0ZSgpIHtcclxuICAgIHN0YXRlLmJyYW5kRmlsdGVyQ291bnQgPSBCcmFuZEZpbHRlclN0b3JlLnNlbGVjdGVkRmlsdGVycy5sZW5ndGg7XHJcbiAgICBzdGF0ZS51c2FnZVR5cGVGaWx0ZXJDb3VudCA9IFVzYWdlVHlwZUZpbHRlclN0b3JlLnNlbGVjdGVkRmlsdGVycy5sZW5ndGg7XHJcbiAgICByZXR1cm4gdGhpcy5jb3VudDtcclxuICB9LFxyXG5cclxuICBvbkJyYW5kRmlsdGVyc0NoYW5nZShmaWx0ZXJzKSB7XHJcbiAgICBzdGF0ZS5icmFuZEZpbHRlckNvdW50ID0gZmlsdGVycy5maWx0ZXIoeCA9PiB4LnNlbGVjdGVkKS5sZW5ndGg7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5jb3VudCk7XHJcbiAgfSxcclxuXHJcbiAgb25Vc2FnZVR5cGVGaWx0ZXJDaGFuZ2UoZmlsdGVycykge1xyXG4gICAgc3RhdGUudXNhZ2VUeXBlRmlsdGVyQ291bnQgPSBmaWx0ZXJzLmZpbHRlcih4ID0+IHguc2VsZWN0ZWQpLmxlbmd0aDtcclxuICAgIHRoaXMudHJpZ2dlcih0aGlzLmNvdW50KTtcclxuICB9LFxyXG5cclxuICBnZXQgY291bnQoKSB7XHJcbiAgICByZXR1cm4gc3RhdGUuYnJhbmRGaWx0ZXJDb3VudCArIHN0YXRlLnVzYWdlVHlwZUZpbHRlckNvdW50O1xyXG4gIH1cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBGaWx0ZXJDb3VudFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBIaXN0b3J5QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9oaXN0b3J5X2FjdGlvbnMnO1xyXG5cclxubGV0IEhpc3RvcnlTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBIaXN0b3J5QWN0aW9ucyxcclxuXHJcbiAgaW5pdCgpIHtcclxuICAgIHRoaXMuaGlzdG9yeSA9IFtdO1xyXG5cdFx0dGhpcy5jdXJyZW50TmF2ID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLnJvb3RNb2RlbDtcclxuICB9LFxyXG5cclxuICBnZXRTdG9yZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmhpc3Rvcnk7XHJcbiAgfSxcclxuXHJcbiAgZ2V0KGNhY2hlS2V5KSB7XHJcbiAgICByZXR1cm4gXy5maW5kV2hlcmUodGhpcy5oaXN0b3J5LCB7IGtleTogY2FjaGVLZXkgfSk7XHJcbiAgfSxcclxuXHJcblx0cmVtb3ZlSGlzdG9yeUFmdGVyKGNhY2hlS2V5KSB7XHJcblx0XHRsZXQgaW5kZXggPSBfLmluZGV4T2YodGhpcy5oaXN0b3J5LCBfLmZpbmQodGhpcy5oaXN0b3J5LCB7a2V5OiBjYWNoZUtleX0pKTtcclxuXHRcdHRoaXMuaGlzdG9yeS5zcGxpY2UoaW5kZXgsIHRoaXMuaGlzdG9yeS5sZW5ndGgpO1xyXG5cdH0sXHJcblxyXG4gIHNldChrZXksIGRhdGEpIHtcclxuXHRcdGxldCBmaW5kID0gdGhpcy5nZXQoa2V5KTtcclxuXHRcdGlmKCFfLmlzVW5kZWZpbmVkKGZpbmQpKSB7XHJcblx0XHRcdGxldCBpbmRleCA9IF8uaW5kZXhPZih0aGlzLmhpc3RvcnksIF8uZmluZCh0aGlzLmhpc3RvcnksIHtrZXk6IGtleX0pKTtcclxuXHRcdFx0dGhpcy5oaXN0b3J5LnNwbGljZShpbmRleCwgMSk7XHJcblx0XHR9XHJcblx0XHR0aGlzLmhpc3RvcnkucHVzaCh7IGtleToga2V5LCBkYXRhOiBkYXRhIH0pO1xyXG4gIH0sXHJcblxyXG5cdGdldEN1cnJlbnROYXYoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jdXJyZW50TmF2O1xyXG5cdH0sXHJcblxyXG5cdHNldEN1cnJlbnROYXYobm9kZSkge1xyXG5cdFx0dGhpcy5jdXJyZW50TmF2ID0gbm9kZTtcclxuXHR9LFxyXG5cclxuXHRvblN0b3JlVXBkYXRlZCgpIHtcclxuXHRcdHRoaXMudHJpZ2dlcigpO1xyXG5cdH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgSGlzdG9yeVN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBJbGx1c3RyYXRpb25BY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2lsbHVzdHJhdGlvbl9hY3Rpb25zJztcclxuXHJcbmxldCBJbGx1c3RyYXRpb25Gb3JPdmVybGF5U3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuICBsaXN0ZW5hYmxlczogSWxsdXN0cmF0aW9uQWN0aW9ucyxcclxuXHJcbiAgaW5pdCgpIHtcclxuICAgIHRoaXMuZGF0YSA9IHt9O1xyXG4gICAgdGhpcy5sb2FkaW5nU3RhdGUgPSBmYWxzZTtcclxuICB9LFxyXG5cclxuXHRvbkxvYWRJbGx1c3RyYXRpb25Gb3JPdmVybGF5Q29tcGxldGVkKHJlcykge1xyXG5cdFx0dGhpcy5kYXRhLmlsbHVzdHJhdGlvbiA9IHJlcztcclxuXHRcdHRoaXMuZGF0YS5sb2FkRXJyb3IgPSAnJztcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmRhdGEpO1xyXG5cdH0sXHJcblxyXG5cdG9uTG9hZElsbHVzdHJhdGlvbkZvck92ZXJsYXlGYWlsZWQoKSB7XHJcbiAgICB0aGlzLmRhdGEuaWxsdXN0cmF0aW9uID0ge307XHJcblx0XHR0aGlzLmRhdGEubG9hZEVycm9yID0gXCJDb3VsZCBub3QgbG9hZCBpbGx1c3RyYXRpb24uXCI7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5kYXRhKTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IElsbHVzdHJhdGlvbkZvck92ZXJsYXlTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9pbGx1c3RyYXRpb25fYWN0aW9ucyc7XHJcbmxldCBJbGx1c3RyYXRpb25TdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG4gIGxpc3RlbmFibGVzOiBJbGx1c3RyYXRpb25BY3Rpb25zLFxyXG5cclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5kYXRhID0ge307XHJcbiAgICB0aGlzLmxvYWRpbmdTdGF0ZSA9IGZhbHNlO1xyXG4gIH0sXHJcblxyXG5cdGdldElsbHVzdHJhdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmRhdGE7XHJcblx0fSxcclxuICBzZXRMb2FkaW5nU3RhdGUoc3RhdGUpe1xyXG4gICAgdGhpcy5sb2FkaW5nU3RhdGUgPSBzdGF0ZTtcclxuICAgIHRoaXMudHJpZ2dlcih0aGlzLmxvYWRpbmdTdGF0ZSk7XHJcbiAgfSxcclxuICBnZXRMb2FkaW5nU3RhdGUoKXtcclxuICAgIHJldHVybiB0aGlzLmxvYWRpbmdTdGF0ZTtcclxuICB9LFxyXG5cdG9uTG9hZElsbHVzdHJhdGlvbjogZnVuY3Rpb24oKSB7XHJcbiAgICB0aGlzLmRhdGEuaWxsdXN0cmF0aW9uID0ge307XHJcblx0XHR0aGlzLmRhdGEubG9hZEVycm9yID0gbnVsbDtcclxuXHR9LFxyXG5cclxuXHRvbkxvYWRJbGx1c3RyYXRpb25Db21wbGV0ZWQocmVzKSB7XHJcblx0XHR0aGlzLmRhdGEuaWxsdXN0cmF0aW9uID0gcmVzO1xyXG5cdFx0dGhpcy5kYXRhLmxvYWRFcnJvciA9ICcnO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuZGF0YSk7XHJcblx0fSxcclxuXHJcblx0b25Mb2FkSWxsdXN0cmF0aW9uRmFpbGVkKCkge1xyXG4gICAgdGhpcy5kYXRhLmlsbHVzdHJhdGlvbiA9IHt9O1xyXG5cdFx0dGhpcy5kYXRhLmxvYWRFcnJvciA9IFwiQ291bGQgbm90IGxvYWQgaWxsdXN0cmF0aW9uLlwiO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuZGF0YSk7XHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJbGx1c3RyYXRpb25TdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5cclxubGV0IExvY2FsaXphdGlvblN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IHtcclxuICAgICAgdHJhbnNsYXRpb25zOiB7fVxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICBnZXRUcmFuc2xhdGlvbihrZXkpIHtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlLnRyYW5zbGF0aW9uc1trZXldO1xyXG4gIH0sXHJcblxyXG4gIGh5ZHJhdGUoc3RhdGUpIHtcclxuICAgIE9iamVjdC5hc3NpZ24odGhpcy5zdGF0ZSwgc3RhdGUpO1xyXG4gIH0sXHJcblxyXG4gIGRlaHlkcmF0ZSgpIHtcclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnN0YXRlKTtcclxuICB9XHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgTG9jYWxpemF0aW9uU3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IFRyZWVWaWV3QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy90cmVldmlld19hY3Rpb25zJztcclxuXHJcbmxldCBNb2RlbFRyZWVTZWFyY2hTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBUcmVlVmlld0FjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XHJcbiAgfSxcclxuXHJcblx0c2VhcmNoTm9kZXNJbk1vZGVsQ29tcGxldGVkKHJlcykge1xyXG5cdFx0dGhpcy50cmlnZ2VyKHJlcyk7XHJcblx0fSxcclxuXHJcblx0c2VhcmNoTm9kZXNJbk1vZGVsRmFpbGVkKCkge1xyXG5cdFx0dGhpcy50cmlnZ2VyKCdDb3VsZCBub3QgbG9hZCBtb2RlbC4nKTtcclxuXHR9LFxyXG5cclxuXHRzZXRTZWFyY2hWYWx1ZSh2YWx1ZSkge1xyXG5cdFx0dGhpcy5zZWFyY2hWYWx1ZSA9IHZhbHVlO1xyXG5cdH0sXHJcblxyXG5cdGdldFNlYXJjaFZhbHVlKCl7XHJcblx0XHRyZXR1cm4gdGhpcy5zZWFyY2hWYWx1ZTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IE1vZGVsVHJlZVNlYXJjaFN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBNb2RlbFNlYXJjaEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvbW9kZWxzZWFyY2hfYWN0aW9uJztcclxubGV0IE1vZGVsU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogTW9kZWxTZWFyY2hBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG4gICAgdGhpcy5tb2RlbCA9IFtdO1xyXG5cdFx0dGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcbiAgfSxcclxuXHJcblx0Z2V0TW9kZWwoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5tb2RlbDtcclxuXHR9LFxyXG5cdGdldExvYWRpbmdTdGF0ZSgpe1xyXG5cdFx0cmV0dXJuIHRoaXMubG9hZGluZztcclxuXHR9LFxyXG5cdG9uTG9hZE1vZGVsOiBmdW5jdGlvbigpIHtcclxuICAgIHRoaXMubW9kZWwubW9kZWxpdGVtID0gW107XHJcblx0XHR0aGlzLm1vZGVsLmxvYWRFcnJvciA9IG51bGw7XHJcblx0XHR0aGlzLmxvYWRpbmcgPSB0cnVlO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMubG9hZGluZyk7XHJcblx0fSxcclxuXHRzZXROb3RFbm91Z2hDaGFyYWN0ZXJzOiBmdW5jdGlvbigpIHtcclxuICAgIHRoaXMubW9kZWwubW9kZWxpdGVtID0gW107XHJcblx0XHR0aGlzLm1vZGVsLmxvYWRFcnJvciA9IG51bGw7XHJcblx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmxvYWRpbmcpO1xyXG5cdH0sXHJcblx0b25Mb2FkTW9kZWxDb21wbGV0ZWQocmVzKSB7XHJcblx0XHR0aGlzLm1vZGVsLm1vZGVsaXRlbSA9IHJlcztcclxuXHRcdHRoaXMubW9kZWwubG9hZEVycm9yID0gJyc7XHJcblx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLm1vZGVsKTtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmxvYWRpbmcpO1xyXG5cdH0sXHJcblxyXG5cdG9uTG9hZE1vZGVsRmFpbGVkKCkge1xyXG5cdFx0dGhpcy5tb2RlbC5sb2FkRXJyb3IgPSBcIkNvdWxkIG5vdCBsb2FkIG1vZGVsLlwiO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMubW9kZWwpO1xyXG5cdH1cclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgTW9kZWxTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xyXG5pbXBvcnQgT3JkZXJsTGluZXNBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL29yZGVybGluZXNfYWN0aW9ucyc7XHJcblxyXG5sZXQgT3JkZXJMaW5lc1N0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IE9yZGVybExpbmVzQWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMub3JkZXJsaW5lcyA9IFtdO1xyXG4gIH0sXHJcblxyXG4gIGdldFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMub3JkZXJsaW5lcztcclxuICB9LFxyXG5cclxuXHRjbGVhcigpIHtcclxuXHRcdHRoaXMuaW5pdCgpO1xyXG5cdFx0dGhpcy50cmlnZ2VyKCk7XHJcblx0fSxcclxuXHJcblx0Z2V0KG1hdGVyaWFsSWQpIHtcclxuICAgIHJldHVybiBfLmZpbmQodGhpcy5vcmRlcmxpbmVzLCB7IGtleTogbWF0ZXJpYWxJZCB9KTtcclxuICB9LFxyXG5cclxuXHRhZGQoaWQsIG9yZGVybGluZSkge1xyXG5cdFx0dGhpcy5vcmRlcmxpbmVzLnVuc2hpZnQoeyBrZXk6IGlkLCBkYXRhOiBvcmRlcmxpbmUgfSk7XHJcblx0XHR0aGlzLnRyaWdnZXIoKTtcclxuICB9LFxyXG5cclxuXHR1cGRhdGVMaW5lKGlkLCBvcmRlcmxpbmUpe1xyXG5cdFx0dmFyIGluZGV4ID0gXy5pbmRleE9mKHRoaXMub3JkZXJsaW5lcywgXy5maW5kKHRoaXMub3JkZXJsaW5lcywge2tleTogaWR9KSk7XHJcblx0XHR0aGlzLm9yZGVybGluZXMuc3BsaWNlKGluZGV4LCAxLCB7IGtleTogaWQsIGRhdGE6IG9yZGVybGluZSB9KTtcclxuXHRcdHRoaXMudHJpZ2dlcigpO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZU9yZGVyTGluZShpZCkge1xyXG5cdFx0Xy5yZW1vdmUodGhpcy5vcmRlcmxpbmVzLCB7a2V5OmlkfSk7XHJcblx0XHR0aGlzLnRyaWdnZXIoKTtcclxuXHR9XHJcblxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IE9yZGVyTGluZXNTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9wcmljZV9zZXJ2aWNlX2FjdGlvbnMnO1xyXG5cclxubGV0IFByaWNlU2VydmljZVN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHRsaXN0ZW5hYmxlczogUHJpY2VTZXJ2aWNlQWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuICAgIHRoaXMucHJpY2VzID0gW107XHJcbiAgfSxcclxuXHJcbiAgZ2V0UHJpY2VzKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucHJpY2VzO1xyXG4gIH0sXHJcblx0Z2V0UHJpY2VzRm9yTWF0ZXJpYWwobWF0ZXJpYWwpIHtcclxuXHRcdHZhciBwcmljZUZvck1hdGVyaWFsID0gdGhpcy5wcmljZXMuZmlsdGVyKGZ1bmN0aW9uKCBwcmljZSApIHtcclxuICBcdFx0cmV0dXJuIHByaWNlLkNvZGUgPT0gbWF0ZXJpYWw7XHJcblx0XHR9KTtcclxuXHRcdGxldCBwbGFjZWhvbGRlciA9IFtdO1xyXG5cdFx0aWYocHJpY2VGb3JNYXRlcmlhbC5sZW5ndGggPiAwKXtcclxuXHRcdFx0cmV0dXJuIHByaWNlRm9yTWF0ZXJpYWw7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0cmV0dXJuIHBsYWNlaG9sZGVyO1xyXG5cdFx0fVxyXG4gIH0sXHJcbiAgYWRkUHJpY2VzKHByaWNlcykge1xyXG5cdFx0dGhpcy5wcmljZXMgPSB0aGlzLnByaWNlcy5jb25jYXQocHJpY2VzKTtcclxuICAgIHRoaXMudHJpZ2dlcih0aGlzLnByaWNlcyk7XHJcbiAgfSxcclxuXHRoYW5kbGVFcnJvcihtYXRlcmlhbHMpe1xyXG5cdFx0bGV0IHByaWNlcyA9IFtdO1xyXG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBtYXRlcmlhbHMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0cHJpY2VzLnB1c2goe1xyXG5cdFx0XHRcdEJ1eWFibGU6IGZhbHNlLFxyXG5cdCAgICAgIEluU3RvY2tRdWFudGl0eTogMCxcclxuXHQgICAgICBMb2FkZWQ6IGZhbHNlLFxyXG5cdCAgICAgIENvZGU6IG1hdGVyaWFsc1tpXSxcclxuXHQgICAgICBQcmljZTogXCJcIixcclxuXHQgICAgICBTaGlwcGluZ0RhdGU6IFwiXCIsXHJcblx0XHRcdFx0SXNEaXNjb3VudGVkOiBmYWxzZSxcclxuXHRcdFx0XHREZWZhdWx0UHJpY2U6IFwiXCIsXHJcblx0XHRcdFx0RGlzY291bnRQZXJjZW50OiBcIlwiLFxyXG5cdFx0XHRcdFByb2R1Y3RDb250ZXh0OiB7fSxcclxuXHRcdFx0XHRQcm9tb3Rpb25EaXNjb3VudFBlcmNlbnQ6IFwiXCIsXHJcblx0XHRcdFx0UHJvbW90aW9uUHJpY2U6IFwiXCIsXHJcblx0XHRcdFx0SGFzUHJvbW90aW9uOiBmYWxzZSxcclxuXHRcdFx0XHRIYXNFcnJvcjogdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0KVxyXG5cdFx0fVxyXG5cdFx0dGhpcy5hZGRQcmljZXMocHJpY2VzKTtcclxuXHR9LFxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFByaWNlU2VydmljZVN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBQcm9kdWN0TGluZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvcHJvZHVjdF9saW5lX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IFRvZ2dsZUZpbHRlclN0b3JlTWl4aW4gZnJvbSAnLi90b2dnbGVfZmlsdGVyX3N0b3JlX21peGluJztcclxuXHJcbmxldCBQcm9kdWN0TGluZUZpbHRlclN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHRsaXN0ZW5hYmxlczogUHJvZHVjdExpbmVGaWx0ZXJBY3Rpb25zLFxyXG4gIG1peGluczogW1RvZ2dsZUZpbHRlclN0b3JlTWl4aW5dXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgUHJvZHVjdExpbmVGaWx0ZXJTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgU2VhcmNoQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9zZWFyY2hfYWN0aW9ucyc7XHJcblxyXG5sZXQgU2VhcmNoUmVzdWx0U3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG4gIGxpc3RlbmFibGVzOiBbU2VhcmNoQWN0aW9uc10sXHJcblxyXG4gIGluaXQoKSB7XHJcbiAgICB0aGlzLnN0YXRlID0ge307XHJcbiAgfSxcclxuXHJcbiAgZ2V0SW5pdGlhbFN0YXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGU7XHJcbiAgfSxcclxuXHJcbiAgb25Hcm91cFNlbGVjdG9yQ2hhbmdlKHNlbGVjdGVkKXtcclxuICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cCA9IHNlbGVjdGVkO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpO1xyXG4gIH0sXHJcbiAgZ2V0QmF0Y2hTaXplKCl7XHJcbiAgICBpZiAodHlwZW9mKHRoaXMuc3RhdGUuanNQcmljZUJhdGNoQW1vdW50KSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuanNQcmljZUJhdGNoQW1vdW50O1xyXG4gICAgfWVsc2V7XHJcbiAgICAgIHJldHVybiAzO1xyXG4gICAgfVxyXG4gIH0sXHJcbiAgZ2V0VXNlclNpZ25lZEluKCl7XHJcbiAgICBpZiAodHlwZW9mKHRoaXMuc3RhdGUudXNlcklzU2lnbmVkSW4pICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm4gdGhpcy5zdGF0ZS51c2VySXNTaWduZWRJbjtcclxuICAgIH1lbHNle1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfSxcclxuICBnZXRTZWxlY3RlZEdyb3VwKCl7XHJcbiAgICBpZiAodHlwZW9mKHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cCkgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnN0YXRlLnNlbGVjdGVkR3JvdXA7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChsZXQgZ3JvdXAgaW4gdGhpcy5zdGF0ZS5ncm91cHMpIHtcclxuICAgICAgaWYgKHRoaXMuc3RhdGUuZ3JvdXBzW2dyb3VwXS5tYXRjaGluZyA+IDApIHtcclxuICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cCA9IGdyb3VwO1xyXG4gICAgICAgICAgcmV0dXJuIGdyb3VwO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwID0gT2JqZWN0LmtleXModGhpcy5zdGF0ZS5ncm91cHMpWzBdO1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cDtcclxuICB9LFxyXG5cclxuICBjaGVja0ZpbmRzZXJ2aWNlSXNEb3duKCl7XHJcbiAgICBpZih0aGlzLnN0YXRlLmdyb3VwcyAmJiB0aGlzLnN0YXRlLmdyb3Vwcy5wYWdlcyl7XHJcbiAgICAgIHJldHVybiB7cGFnZXM6IHRoaXMuc3RhdGUuZ3JvdXBzLnBhZ2VzLmZpbmRTZXJ2aWNlVW5hdmFpbGFibGUsIHNwYXJlUGFydHM6IHRoaXMuc3RhdGUuZ3JvdXBzLmxpZ2h0U3BhcmVQYXJ0Vmlld01vZGVsLmZpbmRTZXJ2aWNlVW5hdmFpbGFibGV9O1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHJldHVybiB7cGFnZXM6IG51bGwsIHNwYXJlUGFydHM6IG51bGx9O1xyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIGdldFRvdGFsTWF0Y2hpbmcoKSB7XHJcbiAgICBsZXQgdG90YWxNYXRjaGluZyA9IDA7XHJcbiAgICBmb3IgKGxldCBncm91cCBpbiB0aGlzLnN0YXRlLmdyb3Vwcykge1xyXG4gICAgICBpZighaXNOYU4odGhpcy5zdGF0ZS5ncm91cHNbZ3JvdXBdLm1hdGNoaW5nKSl7XHJcbiAgICAgICAgdG90YWxNYXRjaGluZyArPSB0aGlzLnN0YXRlLmdyb3Vwc1tncm91cF0ubWF0Y2hpbmc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0b3RhbE1hdGNoaW5nO1xyXG4gIH0sXHJcblxyXG4gIGdldExvYWRpbmcoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5sb2FkaW5nO1xyXG4gIH0sXHJcblxyXG4gIGdldFNvcnRGaWVsZHMoKXtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlLmdyb3Vwc1t0aGlzLmdldFNlbGVjdGVkR3JvdXAoKV0uc29ydEZpZWxkcztcclxuICB9LFxyXG5cclxuICBnZXRNb3JlUmVzdWx0c0F2YWlsYWJsZSgpIHtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlLmdyb3Vwc1t0aGlzLmdldFNlbGVjdGVkR3JvdXAoKV0ubW9yZVJlc3VsdHNBdmFpbGFibGU7XHJcbiAgfSxcclxuXHJcbiAgZ2V0U2VsZWN0ZWRJdGVtcygpe1xyXG4gICAgLy9jb25zb2xlLmxvZygnZ2V0IGl0ZW1zIHN0b3JlJyk7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5ncm91cHNbdGhpcy5nZXRTZWxlY3RlZEdyb3VwKCldLml0ZW1zO1xyXG4gIH0sXHJcblxyXG4gIG9uSW52YWxpZGF0ZSgpIHtcclxuICAgIHRoaXMuc3RhdGUubG9hZGluZyA9IHRydWU7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5zdGF0ZSk7XHJcbiAgfSxcclxuXHJcbiAgb25JbnZhbGlkYXRlQ29tcGxldGVkKHJlc3VsdCkge1xyXG4gICAgdGhpcy5zdGF0ZS5sb2FkaW5nID0gZmFsc2U7XHJcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUuZ3JvdXBzLCByZXN1bHQpO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpO1xyXG4gIH0sXHJcblxyXG4gIG9uSW52YWxpZGF0ZVNwYXJlUGFydHMoKSB7XHJcbiAgICB0aGlzLnN0YXRlLmxvYWRpbmcgPSB0cnVlO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpO1xyXG4gIH0sXHJcblxyXG4gIG9uSW52YWxpZGF0ZVNwYXJlUGFydHNDb21wbGV0ZWQocmVzdWx0KSB7XHJcbiAgICB0aGlzLnN0YXRlLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgIGlmKHRoaXMuc3RhdGUuZ3JvdXBzLmxpZ2h0U3BhcmVQYXJ0Vmlld01vZGVsID09PSB1bmRlZmluZWQpe1xyXG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUuZ3JvdXBzLnNwYXJlUGFydHMsIHJlc3VsdCk7XHJcbiAgICB9ZWxzZXtcclxuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLnN0YXRlLmdyb3Vwcy5saWdodFNwYXJlUGFydFZpZXdNb2RlbCwgcmVzdWx0KTtcclxuICAgIH1cclxuICAgIHRoaXMudHJpZ2dlcih0aGlzLnN0YXRlKTtcclxuICB9LFxyXG5cclxuICBvbkxvYWROZXh0UGFnZSgpIHtcclxuICAgIHRoaXMuc3RhdGUubG9hZGluZyA9IHRydWU7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5zdGF0ZSlcclxuICB9LFxyXG5cclxuICBvbkxvYWROZXh0UGFnZUNvbXBsZXRlZChncm91cCwgaXRlbXMsIG1vcmVSZXN1bHRzQXZhaWxhYmxlKSB7XHJcbiAgICB0aGlzLnN0YXRlLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgIHRoaXMuc3RhdGUuZ3JvdXBzW2dyb3VwXS5pdGVtcyA9IFsuLi50aGlzLnN0YXRlLmdyb3Vwc1tncm91cF0uaXRlbXMsIC4uLml0ZW1zXTtcclxuICAgIHRoaXMuc3RhdGUuZ3JvdXBzW2dyb3VwXS5tb3JlUmVzdWx0c0F2YWlsYWJsZSA9IG1vcmVSZXN1bHRzQXZhaWxhYmxlO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpO1xyXG4gIH0sXHJcblxyXG4gIG9uTG9hZE5leHRQYWdlRmFpbGVkKGVycm9yKSB7XHJcbiAgICB0aGlzLnN0YXRlLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgIHRoaXMuc3RhdGUuZ3JvdXBzLnBhZ2VzLmZpbmRTZXJ2aWNlVW5hdmFpbGFibGUgPSB0cnVlO1xyXG4gICAgdGhpcy5zdGF0ZS5ncm91cHMubGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwuZmluZFNlcnZpY2VVbmF2YWlsYWJsZSA9IHRydWU7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5zdGF0ZSk7XHJcbiAgfSxcclxuXHJcbiAgaHlkcmF0ZShzdGF0ZSkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IHt9XHJcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUsIHN0YXRlKTtcclxuICB9LFxyXG5cclxuICBkZWh5ZHJhdGUoKSB7XHJcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5zdGF0ZSk7XHJcbiAgfSxcclxuXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgU2VhcmNoUmVzdWx0U3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IFNvcnRTdG9yZSBmcm9tICcuL3NvcnRfc3RvcmUnO1xyXG5pbXBvcnQgU2VhcmNoQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9zZWFyY2hfYWN0aW9ucyc7XHJcblxyXG5sZXQgU2VhcmNoU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG4gIGxpc3RlbmFibGVzOiBbU2VhcmNoQWN0aW9uc10sXHJcblxyXG4gIGluaXQoKSB7XHJcbiAgICB0aGlzLnN0YXRlID0ge1xyXG4gICAgICBwYWdlc0xvYWRlZEJ5R3JvdXA6IHt9XHJcbiAgICB9O1xyXG4gIH0sXHJcblxyXG4gIGdldEluaXRpYWxTdGF0ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlO1xyXG4gIH0sXHJcblxyXG4gIGdldFF1ZXJ5KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGUucXVlcnk7XHJcbiAgfSxcclxuXHJcbiAgb25JbnZhbGlkYXRlQ29tcGxldGVkKCkge1xyXG4gICAgZm9yIChsZXQgZ3JvdXBLZXkgaW4gdGhpcy5zdGF0ZS5wYWdlc0xvYWRlZEJ5R3JvdXApIHtcclxuICAgICAgdGhpcy5zdGF0ZS5wYWdlc0xvYWRlZEJ5R3JvdXBbZ3JvdXBLZXldID0gMTtcclxuICAgIH1cclxuICB9LFxyXG5cclxuICBvbkludmFsaWRhdGVTcGFyZVBhcnRzQ29tcGxldGVkKCkge1xyXG4gICAgdGhpcy5zdGF0ZS5wYWdlc0xvYWRlZEJ5R3JvdXBbJ3NwYXJlUGFydHMnXSA9IDE7XHJcbiAgfSxcclxuXHJcbiAgb25Mb2FkTmV4dFBhZ2VDb21wbGV0ZWQoZ3JvdXAsIGl0ZW1zKSB7XHJcbiAgICB0aGlzLnN0YXRlLnBhZ2VzTG9hZGVkQnlHcm91cFtncm91cF0gPSB0aGlzLnN0YXRlLnBhZ2VzTG9hZGVkQnlHcm91cFtncm91cF0gfHwgMTtcclxuICAgIHRoaXMuc3RhdGUucGFnZXNMb2FkZWRCeUdyb3VwW2dyb3VwXSArPSAxO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpO1xyXG4gIH0sXHJcblxyXG4gIG9uU2V0UXVlcnkobmV3UXVlcnkpIHtcclxuICAgIHRoaXMuc3RhdGUucXVlcnkgPSBuZXdRdWVyeTtcclxuICAgIFNlYXJjaEFjdGlvbnMuaW52YWxpZGF0ZSgpO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuc3RhdGUpXHJcbiAgfSxcclxuXHJcbiAgaHlkcmF0ZShzdGF0ZSkge1xyXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnN0YXRlLCBzdGF0ZSk7XHJcbiAgfSxcclxuXHJcbiAgZGVoeWRyYXRlKCkge1xyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuc3RhdGUpO1xyXG4gIH1cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBTZWFyY2hTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgU2VhcmNoQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9zZWFyY2hfYWN0aW9ucyc7XHJcbmltcG9ydCBTZXJpYWxOdW1iZXJGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3NlcmlhbF9udW1iZXJfZmlsdGVyX2FjdGlvbnMnO1xyXG5cclxubGV0IFNlcmlhbE51bWJlckZpbHRlclN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuICBsaXN0ZW5hYmxlczogU2VyaWFsTnVtYmVyRmlsdGVyQWN0aW9ucyxcclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5zZXJpYWxOdW1iZXIgPSB0aGlzLnNlcmlhbE51bWJlciB8fCBcIlwiO1xyXG4gICAgdGhpcy5zZXJpYWxOb0ludmFsaWQgPSB0aGlzLnNlcmlhbE5vSW52YWxpZCB8fCBmYWxzZTtcclxuICB9LFxyXG4gIG9uQXBwbHlGaWx0ZXIoc2VyaWFsKSB7XHJcbiAgICBTZWFyY2hBY3Rpb25zLmludmFsaWRhdGVTcGFyZVBhcnRzKCk7XHJcbiAgICB0aGlzLnNlcmlhbE51bWJlciA9IHNlcmlhbDtcclxuICB9LFxyXG4gIG9uQ2xlYXJGaWx0ZXIoKSB7XHJcbiAgICB0aGlzLnNlcmlhbE51bWJlciA9IFwiXCI7XHJcbiAgICB0aGlzLnNlcmlhbE5vSW52YWxpZCA9IGZhbHNlO1xyXG4gICAgU2VhcmNoQWN0aW9ucy5pbnZhbGlkYXRlU3BhcmVQYXJ0cygpO1xyXG4gIH0sXHJcbiAgb25VcGRhdGVGaWx0ZXJzKGZsYWcpIHtcclxuICAgIC8vU2VlIHNlYXJjaF9hY3Rpb25zLmpzIGFuZCB0aGVyZSBcImxldCBkb0ZpbHRlcj1cIiB0byBzZWUgd2hlcmUgYW5kIGhvdyB0aGlzIGlzIGNhbGxlZFxyXG4gICAgaWYoZmxhZyA9PT0gdHJ1ZSkge1xyXG4gICAgICAvL1VwZGF0ZSBmaWx0ZXIgaXMgY2FsbGVkIHdpdGggSlNPTiBoYXZpbmcgXCJzZXJpYWxOb0ludmFsaWQ6IHRydWVcIiAtZmxhZy5cclxuICAgICAgdGhpcy5zZXJpYWxOb0ludmFsaWQgPSBmbGFnO1xyXG4gICAgICB0aGlzLnRyaWdnZXIodGhpcy5zZXJpYWxOb0ludmFsaWQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy9TZXJpYWwgaXMgdmFsaWQsIG5vIHNlcmlhbE5vSW52YWxpZCAtcHJvcGVydHkgaW4gSlNPTi5cclxuICAgICAgdGhpcy5zZXJpYWxOb0ludmFsaWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy50cmlnZ2VyKCk7XHJcbiAgICB9XHJcbiAgfSxcclxuICBnZXRJbml0aWFsU3RhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXJpYWxOdW1iZXI7XHJcbiAgfSxcclxuICBoeWRyYXRlKHN0YXRlKSB7XHJcbiAgICB0aGlzLnNlcmlhbE51bWJlciA9IHN0YXRlLnNlcmlhbE51bWJlcjtcclxuICB9LFxyXG4gIGRlaHlkcmF0ZSgpIHtcclxuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh7IHNlcmlhbE51bWJlcjogdGhpcy5zZXJpYWxOdW1iZXIgfSk7XHJcblx0fVxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNlcmlhbE51bWJlckZpbHRlclN0b3JlOyIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IFNvcnRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3NvcnRfYWN0aW9ucyc7XHJcbmltcG9ydCBTZWFyY2hBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3NlYXJjaF9hY3Rpb25zJztcclxuaW1wb3J0IFNlYXJjaFN0b3JlIGZyb20gJy4uL19zdG9yZXMvc2VhcmNoX3N0b3JlJztcclxuXHJcbmxldCBTb3J0U3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cdGxpc3RlbmFibGVzOiBTb3J0QWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuXHRcdHRoaXMuc3RhdGUgPSB7fTtcclxuXHR9LFxyXG5cclxuICBnZXRJbml0aWFsU3RhdGUoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5zdGF0ZTtcclxuXHR9LFxyXG5cclxuICBvblNldEZpZWxkKGZpZWxkKSB7XHJcbiAgICB0aGlzLnN0YXRlLmZpZWxkID0gZmllbGQ7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5zdGF0ZSk7XHJcblx0XHRpZiAoaXNPblNlYXJjaFBhZ2UoKSkge1xyXG5cdFx0XHRTZWFyY2hBY3Rpb25zLmludmFsaWRhdGUoKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdFNlYXJjaEFjdGlvbnMuaW52YWxpZGF0ZVNwYXJlUGFydHMoKTtcclxuXHRcdH1cclxuICB9LFxyXG5cclxuICBvblNldE9yZGVyKG9yZGVyKSB7XHJcbiAgICB0aGlzLnN0YXRlLm9yZGVyID0gb3JkZXI7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5zdGF0ZSk7XHJcblx0XHRpZiAoaXNPblNlYXJjaFBhZ2UoKSkge1xyXG5cdFx0XHRTZWFyY2hBY3Rpb25zLmludmFsaWRhdGUoKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdFNlYXJjaEFjdGlvbnMuaW52YWxpZGF0ZVNwYXJlUGFydHMoKTtcclxuXHRcdH1cclxuICB9LFxyXG5cclxuICBoeWRyYXRlKHN0YXRlKSB7XHJcblx0XHRPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUsIHN0YXRlKTtcclxuICB9LFxyXG5cclxuICBkZWh5ZHJhdGUoKSB7XHJcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5zdGF0ZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGlzT25TZWFyY2hQYWdlKCkge1xyXG5cdHJldHVybiAhIVNlYXJjaFN0b3JlLmdldFF1ZXJ5KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNvcnRTdG9yZTtcclxuIiwiaW1wb3J0IFNlYXJjaEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvc2VhcmNoX2FjdGlvbnMnO1xyXG5cclxubGV0IFRvZ2dsZUZpbHRlclN0b3JlTWl4aW4gPSB7XHJcbiAgaW5pdCgpIHtcclxuICAgIHRoaXMuZmlsdGVycyA9IHRoaXMuZmlsdGVycyB8fCBbXTtcclxuICB9LFxyXG5cclxuICBvblRvZ2dsZUZpbHRlcihuYW1lKSB7XHJcbiAgICBmb3IgKGxldCBmaWx0ZXIgb2YgdGhpcy5maWx0ZXJzKSB7XHJcbiAgICAgIGlmIChmaWx0ZXIubmFtZSA9PSBuYW1lKSB7XHJcbiAgICAgICAgZmlsdGVyLnNlbGVjdGVkID0gIWZpbHRlci5zZWxlY3RlZDtcclxuICAgICAgICBTZWFyY2hBY3Rpb25zLmludmFsaWRhdGVTcGFyZVBhcnRzKCk7XHJcbiAgICAgICAgdGhpcy50cmlnZ2VyKHRoaXMuZmlsdGVycyk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9LFxyXG5cclxuXHRvbkNsZWFyRmlsdGVycygpIHtcclxuICAgIGxldCBtb2RpZmllZCAgPSBmYWxzZTtcclxuXHJcbiAgICBmb3IgKGxldCBmaWx0ZXIgb2YgdGhpcy5maWx0ZXJzKSB7XHJcbiAgICAgIGlmIChmaWx0ZXIuc2VsZWN0ZWQpIHtcclxuICAgICAgICBmaWx0ZXIuc2VsZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICBtb2RpZmllZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAobW9kaWZpZWQpIHtcclxuICAgICAgU2VhcmNoQWN0aW9ucy5pbnZhbGlkYXRlU3BhcmVQYXJ0cygpO1xyXG4gICAgICB0aGlzLnRyaWdnZXIodGhpcy5maWx0ZXJzKTtcclxuICAgIH1cclxuXHR9LFxyXG5cclxuICBvblVwZGF0ZUZpbHRlcnMoZmlsdGVycykge1xyXG4gICAgdGhpcy5maWx0ZXJzID0gZmlsdGVycyA9PT0gdW5kZWZpbmVkID8gW10gOiBmaWx0ZXJzO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuZmlsdGVycyk7XHJcbiAgfSxcclxuXHJcbiAgZ2V0SW5pdGlhbFN0YXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZmlsdGVycztcclxuICB9LFxyXG5cclxuICBzZWxlY3RlZEZpbHRlcnMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJzLmZpbHRlcih4ID0+IHguc2VsZWN0ZWQpXHJcbiAgfSxcclxuXHJcblx0aHlkcmF0ZShzdGF0ZSkge1xyXG5cdFx0dGhpcy5maWx0ZXJzID0gc3RhdGUuZmlsdGVycztcclxuXHR9LFxyXG5cclxuXHRkZWh5ZHJhdGUoKSB7XHJcblx0XHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyBmaWx0ZXJzOiB0aGlzLmZpbHRlcnMgfSk7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgVG9nZ2xlRmlsdGVyU3RvcmVNaXhpbjtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgVG9wQ2F0ZWdvcnlGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3RvcF9jYXRlZ29yeV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBUb2dnbGVGaWx0ZXJTdG9yZU1peGluIGZyb20gJy4vdG9nZ2xlX2ZpbHRlcl9zdG9yZV9taXhpbic7XHJcblxyXG5sZXQgVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblx0bGlzdGVuYWJsZXM6IFRvcENhdGVnb3J5RmlsdGVyQWN0aW9ucyxcclxuICBtaXhpbnM6IFtUb2dnbGVGaWx0ZXJTdG9yZU1peGluXVxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFRvcENhdGVnb3J5RmlsdGVyU3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IFRyZWVWaWV3QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy90cmVldmlld19hY3Rpb25zJztcclxuXHJcbmxldCBUcmVlVmlld1N0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcbiAgbGlzdGVuYWJsZXM6IFRyZWVWaWV3QWN0aW9ucyxcclxuXHJcbiAgaW5pdCgpIHtcclxuXHRcdHRoaXMudHJlZSA9IFtdO1xyXG4gICAgdGhpcy5zZWxlY3RlZE5vZGUgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmxvYWRpbmdTdGF0ZSA9IHRydWU7XHJcblx0fSxcclxuXHJcblx0Z2V0VHJlZSgpIHtcclxuXHRcdHJldHVybiB0aGlzLnRyZWU7XHJcblx0fSxcclxuXHJcblx0Z2V0KGNhY2hlS2V5KSB7XHJcblx0XHRyZXR1cm4gXy5maW5kV2hlcmUodGhpcy50cmVlLCB7IGtleTogY2FjaGVLZXkgfSk7XHJcblx0fSxcclxuXHJcblx0ZmluZFdoZXJlSW5kZXgoY2FjaGVLZXkpIHtcclxuXHRcdHJldHVybiBfLndoZXJlKHRoaXMudHJlZSwge2tleSwgY2FjaGVLZXl9KTtcclxuXHR9LFxyXG5cclxuXHRzZXQoa2V5LCBkYXRhKSB7XHJcblx0XHR0aGlzLnRyZWUucHVzaCh7IGtleToga2V5LCBkYXRhOiBkYXRhIH0pO1xyXG4gIH0sXHJcblxyXG4gIHNldFNlbGVjdGVkTm9kZShzZWxlY3RlZE5vZGUpe1xyXG4gICAgdGhpcy5zZWxlY3RlZE5vZGUgPSBzZWxlY3RlZE5vZGU7XHJcbiAgfSxcclxuICBnZXRTZWxlY3RlZE5vZGUoY3VycmVudE5vZGUpe1xyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWROb2RlO1xyXG4gIH0sXHJcbiAgc2V0TG9hZGluZ1N0YXRlKHN0YXRlKXtcclxuICAgIHRoaXMubG9hZGluZ1N0YXRlID0gc3RhdGU7XHJcbiAgICB0aGlzLnRyaWdnZXIodGhpcy5sb2FkaW5nU3RhdGUpO1xyXG4gIH0sXHJcbiAgZ2V0TG9hZGluZ1N0YXRlKCl7XHJcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nU3RhdGU7XHJcbiAgfSxcclxuXHRvbkxvYWROb2RlczogZnVuY3Rpb24oKSB7XHJcblx0XHQvL3RoaXMuZGF0YS5sb2FkRXJyb3IgPSBudWxsO1xyXG5cdH0sXHJcblxyXG5cdG9uTG9hZE5vZGVzQ29tcGxldGVkKHJlcykge1xyXG5cdFx0LypyZXMuZm9yRWFjaCgoY2hpbGQpID0+IHtcclxuXHRcdFx0XHR0aGlzLmRhdGEudHJlZVtjaGlsZC5JZF0gPSBjaGlsZDtcclxuXHRcdH0pO1xyXG5cclxuXHRcdHRoaXMuZGF0YS5sb2FkRXJyb3IgPSAnJztcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmRhdGEpOyovXHJcblx0fSxcclxuXHJcblx0b25Mb2FkTm9kZXNGYWlsZWQoKSB7XHJcblx0XHQvKnRoaXMuZGF0YS5sb2FkRXJyb3IgPSBcIkNvdWxkIG5vdCBsb2FkIGlsbHVzdHJhdGlvbi5cIjtcclxuXHRcdHRoaXMudHJpZ2dlcih0aGlzLmRhdGEpOyovXHJcblx0fVxyXG5cclxufSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUcmVlVmlld1N0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBVc2FnZVR5cGVGaWx0ZXJBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3VzYWdlX3R5cGVfZmlsdGVyX2FjdGlvbnMnO1xyXG5pbXBvcnQgVG9nZ2xlRmlsdGVyU3RvcmVNaXhpbiBmcm9tICcuL3RvZ2dsZV9maWx0ZXJfc3RvcmVfbWl4aW4nO1xyXG5cclxubGV0IFVzYWdlVHlwZUZpbHRlclN0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHRsaXN0ZW5hYmxlczogVXNhZ2VUeXBlRmlsdGVyQWN0aW9ucyxcclxuICBtaXhpbnM6IFtUb2dnbGVGaWx0ZXJTdG9yZU1peGluXVxyXG59KTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFVzYWdlVHlwZUZpbHRlclN0b3JlO1xyXG4iLCJpbXBvcnQgUmVmbHV4IGZyb20gJ3JlZmx1eCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBBZGRyZXNzQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy91c2VyX2FkZHJlc3Nlc19hY3Rpb25zJztcclxuXHJcbmxldCBVc2VyQWRkcmVzc2VzU3RvcmUgPSBSZWZsdXguY3JlYXRlU3RvcmUoe1xyXG5cclxuXHRsaXN0ZW5hYmxlczogQWRkcmVzc0FjdGlvbnMsXHJcblxyXG5cdGluaXQoKSB7XHJcblx0XHR0aGlzLmFkZHJlc3NlcyA9IFtdO1xyXG5cdFx0dGhpcy5jb3VudHJpZXMgPSBbXTtcclxuXHRcdHRoaXMuUG9zdGFsQ29kZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5DdXN0b21lclR5cGUgPSBmYWxzZTtcclxuICB9LFxyXG5cclxuICBnZXRBZGRyZXNzZXMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5hZGRyZXNzZXMuQWRkcmVzc2VzO1xyXG5cdH0sXHJcblx0Z2V0QmlsbGluZ0FkZHJlc3NlcygpIHtcclxuICAgIHJldHVybiB0aGlzLmFkZHJlc3Nlcy5CaWxsaW5nQWRkcmVzc2VzO1xyXG4gIH0sXHJcblx0Z2V0U3RhdHVzKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuYWRkcmVzc2VzLlN1Y2Nlc3M7XHJcblx0fSxcclxuXHRnZXRDb3VudHJ5T3B0aW9ucygpIHtcclxuICAgIHJldHVybiB0aGlzLmNvdW50cmllcztcclxuICB9LFxyXG5cdHNldFBvc3RhbENvZGVJc0NvcnJlY3QodmFsdWUpe1xyXG5cdFx0dGhpcy5Qb3N0YWxDb2RlID0gdmFsdWU7XHJcblx0fSxcclxuXHRnZXRQb3N0YWxDb2RlSXNDb3JyZWN0KCl7XHJcblx0XHRyZXR1cm4gdGhpcy5Qb3N0YWxDb2RlO1xyXG5cdH0sXHJcblx0Z2V0Q3VzdG9tZXJUeXBlKCl7XHJcblx0XHRyZXR1cm4gdGhpcy5DdXN0b21lclR5cGU7XHJcblx0fSxcclxuXHRvbkxvYWRBZGRyZXNzZXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5hZGRyZXNzZXMgPSBbXTtcclxuICAgIHRoaXMubG9hZEVycm9yID0gbnVsbDtcclxuICB9LFxyXG5cclxuICBvbkxvYWRBZGRyZXNzZXNDb21wbGV0ZWQocmVzKSB7XHJcblx0XHQvL3RoaXMuYWRkcmVzc2VzID0gcmVzO1xyXG5cclxuXHRcdHRoaXMuYWRkcmVzc2VzID0gcmVzO1xyXG5cdFx0aWYocmVzLkNvdW50cnlPcHRpb25zKSB0aGlzLmNvdW50cmllcyA9IHJlcy5Db3VudHJ5T3B0aW9ucztcclxuICAgIHRoaXMubG9hZEVycm9yID0gJyc7XHJcblx0XHR0aGlzLkN1c3RvbWVyVHlwZSA9IHJlcy5Jc0JpZ0N1c3RvbWVyO1xyXG5cclxuICAgIHRoaXMudHJpZ2dlcih0aGlzLmFkZHJlc3Nlcyk7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jb3VudHJpZXMpO1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuQ3VzdG9tZXJUeXBlKTtcclxuICB9LFxyXG5cclxuICBvbkxvYWRBZGRyZXNzZXNGYWlsZWQoKSB7XHJcbiAgICB0aGlzLmxvYWRFcnJvciA9IFwiQ291bGQgbm90IGxvYWQgYWRkcmVzc2VzLlwiO1xyXG4gICAgdGhpcy50cmlnZ2VyKHRoaXMuYWRkcmVzc2VzKTtcclxuICB9XHJcblxyXG4gfSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBVc2VyQWRkcmVzc2VzU3RvcmU7XHJcbiIsImltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IEFkZHJlc3NBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3VzZXJfYWRkcmVzc2VzX2FjdGlvbnMnO1xyXG5cclxubGV0IFVzZXJDb3VudHJ5T3B0aW9uc1N0b3JlID0gUmVmbHV4LmNyZWF0ZVN0b3JlKHtcclxuXHJcblx0bGlzdGVuYWJsZXM6IEFkZHJlc3NBY3Rpb25zLFxyXG5cclxuXHRpbml0KCkge1xyXG5cdFx0dGhpcy5jb3VudHJ5T3B0aW9ucyA9IHt9O1xyXG4gIH0sXHJcblx0c2V0Q291bnRyeU9wdGlvbnMoY291bnRyaWVzKXtcclxuICAgIHRoaXMuY291bnRyeU9wdGlvbnMgPSBjb3VudHJpZXM7XHJcblx0XHR0aGlzLnRyaWdnZXIodGhpcy5jb3VudHJ5T3B0aW9ucyk7XHJcbiAgfSxcclxuICBnZXRDb3VudHJ5T3B0aW9ucygpe1xyXG4gICAgcmV0dXJuIHRoaXMuY291bnRyeU9wdGlvbnNcclxuICB9XHJcblxyXG4gfSk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBVc2VyQ291bnRyeU9wdGlvbnNTdG9yZTtcclxuIiwiaW1wb3J0IFJlZmx1eCBmcm9tICdyZWZsdXgnO1xyXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xyXG5pbXBvcnQgQWRkcmVzc0FjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvdXNlcl9hZGRyZXNzZXNfYWN0aW9ucyc7XHJcblxyXG5sZXQgVXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZSA9IFJlZmx1eC5jcmVhdGVTdG9yZSh7XHJcblxyXG5cdGxpc3RlbmFibGVzOiBBZGRyZXNzQWN0aW9ucyxcclxuXHJcblx0aW5pdCgpIHtcclxuXHRcdHRoaXMuZGVmYXVsdEFkZHJlc3MgPSB7fTtcclxuICB9LFxyXG5cdHNldERlZmF1bHRBZGRyZXNzKGlzRGVmYXVsdCl7XHJcbiAgICB0aGlzLmRlZmF1bHRBZGRyZXNzID0gaXNEZWZhdWx0O1xyXG5cdFx0dGhpcy50cmlnZ2VyKHRoaXMuZGVmYXVsdEFkZHJlc3MpO1xyXG4gIH0sXHJcbiAgZ2V0RGVmYXVsdEFkZHJlc3MoKXtcclxuICAgIHJldHVybiB0aGlzLmRlZmF1bHRBZGRyZXNzXHJcbiAgfVxyXG5cclxuIH0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgVXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IENhcnRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2NhcnRfYWN0aW9ucyc7XHJcbmltcG9ydCBvcmRlcmxpbmVzIGZyb20gJy4vYmF0Y2hvcmRlcic7XHJcblxyXG5sZXQgYmF0Y2hvcmRlcmNhcnQgPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdGxldCBjaGFuZ2VRdWFudGl0eTtcclxuXHJcblx0XHQkKCAnLnF1YW50aXR5JyApLmNoYW5nZShmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGNoYW5nZVF1YW50aXR5ID0gICQodGhpcykudmFsKCk7XHJcblx0XHRcdCQodGhpcykudmFsKGNoYW5nZVF1YW50aXR5KTtcclxuXHRcdH0pXHJcblx0XHQuY2hhbmdlKCk7XHJcblxyXG5cdFx0ZnVuY3Rpb24gQ2FydElzV29ya2luZygpIHtcclxuXHRcdFx0cmV0dXJuICQoJyNjb250cm9sbC1jYXJ0JykuaGFzQ2xhc3MoJ2FkZGluZycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnYnV0dG9uLmJhdGNoLWFkZC10by1jYXJ0JywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0XHRpZiggJCh0aGlzKS5oYXNDbGFzcygnbG9hZGluZycpIHx8ICQoJ2J1dHRvbi5iYXRjaC1xdWljay1idXknKS5oYXNDbGFzcygnbG9hZGluZycpICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0JCgnYnV0dG9uLmJhdGNoLXF1aWNrLWJ1eScpLnRvZ2dsZUNsYXNzKCdpbmFjdGl2ZScpO1xyXG5cclxuXHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHQkKCcjY29udHJvbGwtY2FydCcpLmFkZENsYXNzKCdhZGRpbmcnKTtcclxuXHRcdFx0JCgnLnVjLWhlYWRlcmNhcnQnKS5hZGRDbGFzcygnYWRkaW5nJyk7XHJcblx0XHRcdGxldCBpdGVtcyA9IFtdO1xyXG5cdFx0XHQkKCdbZGF0YS1saW5lLWl0ZW1dLnJvdycpLmVhY2goZnVuY3Rpb24oaW5kZXgsIHNjb3BlKSB7XHJcblx0XHRcdFx0bGV0IGl0ZW0gPSB7fTtcclxuXHRcdFx0XHRsZXQgc2t1SUQgPSAkKHRoaXMpLmRhdGEoJ2xpbmUtaXRlbScpO1xyXG5cdFx0XHRcdGxldCBxdWFudGl0eSA9ICQoXCIucXVhbnRpdHlbZGF0YS1saW5lLWl0ZW09J1wiICsgc2t1SUQgICtcIiddXCIsIHNjb3BlKS52YWwoKTtcclxuXHRcdFx0XHRpdGVtWydjb2RlJ10gPSBza3VJRDtcclxuXHRcdFx0XHRpdGVtWydxdWFudGl0eSddID0gcXVhbnRpdHk7XHJcblx0XHRcdFx0aXRlbXMucHVzaChpdGVtKVxyXG5cdFx0XHR9KTtcclxuXHRcdFx0JCgnLnVjLWhlYWRlcmNhcnQnKS5yZW1vdmVDbGFzcygncmlnaHQtb2ZmLWNhbnZhcy10b2dnbGUnKTtcclxuXHRcdFx0Q2FydEFjdGlvbnMuYWRkQ2FydEl0ZW1zKGl0ZW1zKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnYnV0dG9uLmJhdGNoLXF1aWNrLWJ1eScsIGZ1bmN0aW9uKGUpIHtcclxuXHJcblx0XHRcdGlmKENhcnRJc1dvcmtpbmcoKSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHQkKCcjY29udHJvbGwtY2FydCcpLmFkZENsYXNzKCdhZGRpbmcnKTtcclxuXHRcdFx0JCgnLnVjLWhlYWRlcmNhcnQnKS5hZGRDbGFzcygnYWRkaW5nJyk7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0bGV0IGl0ZW1zID0gW107XHJcblx0XHRcdCQoJ1tkYXRhLWxpbmUtaXRlbV0ucm93JykuZWFjaChmdW5jdGlvbihpbmRleCwgc2NvcGUpIHtcclxuXHRcdFx0XHRsZXQgaXRlbSA9IHt9O1xyXG5cdFx0XHRcdGxldCBza3VJRCA9ICQodGhpcykuZGF0YSgnbGluZS1pdGVtJyk7XHJcblx0XHRcdFx0bGV0IHF1YW50aXR5ID0gJChcIi5xdWFudGl0eVtkYXRhLWxpbmUtaXRlbT0nXCIgKyBza3VJRCAgK1wiJ11cIiwgc2NvcGUpLnZhbCgpO1xyXG5cdFx0XHRcdGl0ZW1bJ2NvZGUnXSA9IHNrdUlEO1xyXG5cdFx0XHRcdGl0ZW1bJ3F1YW50aXR5J10gPSBxdWFudGl0eTtcclxuXHRcdFx0XHRpdGVtcy5wdXNoKGl0ZW0pXHJcblx0XHRcdH0pO1xyXG5cdFx0XHQkKCcudWMtaGVhZGVyY2FydCcpLnJlbW92ZUNsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHRDYXJ0QWN0aW9ucy5xdWlja0J1eUl0ZW1zKGl0ZW1zKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBiYXRjaG9yZGVyY2FydDtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IE9yZGVyTGluZXNBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL29yZGVybGluZXNfYWN0aW9ucyc7XHJcbmltcG9ydCBPcmRlckxpbmVzU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9vcmRlcmxpbmVzX3N0b3JlJztcclxuaW1wb3J0IFByb2R1Y3RBcGkgZnJvbSAnLi4vX2FwaS9wcm9kdWN0X2FwaSc7XHJcblxyXG5sZXQgb3JkZXJsaW5lcyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0Ly9Gb3JtIGV2ZW50c1xyXG5cdFx0dGhpcy5tYXRlcmlhbElucHV0ICAgICAgICA9ICQoJyNhZGQtbWF0ZXJpYWwnKTtcclxuXHRcdHRoaXMucXVhbnRpdHlJbnB1dCAgICAgICAgPSAkKCcjYWRkLXF1YW50aXR5Jyk7XHJcblx0XHR0aGlzLmFkZEJ1dHRvbiAgICAgICAgICAgID0gJCgnI2FkZC1vcmRlcmxpbmUnKTtcclxuXHRcdHRoaXMucmVtb3ZlQWxsQnV0dG9uICAgICAgPSAkKCcjcmVtb3ZlLWFsbC1saW5lcycpO1xyXG5cdFx0dGhpcy5hZGRMaW5lc0J1dHRvbnMgICAgICA9ICQoJyNhZGQtbGluZXMtYnV0dG9ucycpO1xyXG5cdFx0dGhpcy5tZXNzYWdlRWxtICAgICAgICAgICA9ICQoJy5vcmRlcmxpbmUtbWVzc2FnZScpO1xyXG5cdFx0dGhpcy5jb25maWd1cmVGaWxlVHJpZ2dlciA9ICQoJy5jb25maWd1cmV0ZXh0Jyk7XHJcblx0XHR0aGlzLm1lc3NhZ2VJZCAgICAgICAgICAgID0gJCgnLm1lc3NhZ2Utb3JkZXItbGluZS1pZCcpO1xyXG5cdFx0dGhpcy5tZXNzYWdlT2tFbG0gICAgICAgICA9ICQoJyNhZGQtb3JkZXJsaW5lLW1lc3NhZ2Utb2snKTtcclxuXHRcdHRoaXMubWVzc2FnZU5vdEZvdW5kRWxtICAgPSAkKCcjYWRkLW9yZGVybGluZS1tZXNzYWdlLW5vdGZvdW5kJyk7XHJcblx0XHR0aGlzLm1lc3NhZ2VOb3RCdXlhYmxlRWxtID0gJCgnI2FkZC1vcmRlcmxpbmUtbWVzc2FnZS1ub3RidXlhYmxlJyk7XHJcblx0XHR0aGlzLm1lc3NhZ2VSZXN0cmljdGVkRWxtID0gJCgnI2FkZC1vcmRlcmxpbmUtbWVzc2FnZS1yZXN0cmljdGVkJyk7XHJcblx0XHR0aGlzLm1lc3NhZ2VDb250YWN0UHJpbmNldG9uRGVhbGVyRWxtID0gJCgnI2FkZC1vcmRlcmxpbmUtbWVzc2FnZS1jb250YWN0cHJpbmNldG9uZGVhbGVyJyk7XHJcblx0XHR0aGlzLm1lc3NhZ2VFeGlzdHNFbG0gICAgID0gJCgnI2FkZC1vcmRlcmxpbmUtbWVzc2FnZS1leGlzdHMnKTtcclxuXHRcdHRoaXMuZmlsZU1lc3NhZ2VzRWxtICAgICAgPSAkKCcjZmlsZXVwbG9hZC1tZXNzYWdlcycpO1xyXG5cdFx0dGhpcy5leGNlbE1lc3NhZ2VzRWxtIFx0XHQ9ICQoJy5maWxldXBsb2FkLW1lc3NhZ2VzJyk7XHJcblxyXG5cdFx0JChkb2N1bWVudCkub24oJ2JsdXInLCAnI2xpbmUtaXRlbXMgLnF1YW50aXR5JywgZnVuY3Rpb24oKXtcclxuXHRcdFx0Ly8gdGhpcy5kZWZhdWx0VmFsdWUgPSB0aGlzLnZhbHVlO1xyXG5cdFx0XHR2YXIgdmFsID0gdGhpcy52YWx1ZTtcclxuICAgICAgaWYgKHZhbCAhPT0gdGhpcy5kZWZhdWx0VmFsdWUpIHtcclxuICAgICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gdGhpcy52YWx1ZTtcclxuXHRcdFx0XHRcdGxldCBtYXRlcmlhbElkID0gJCh0aGlzKS5kYXRhKCdsaW5lLWl0ZW0nKSxcclxuXHRcdFx0XHRcdCAgICBxdWFudGl0eSAgID0gaXNOYU4oJCh0aGlzKS52YWwoKSkgfHwgJCh0aGlzKS52YWwoKSA9PT0gJycgPyAxIDogJCh0aGlzKS52YWwoKTtcclxuXHJcblx0XHRcdFx0XHRsZXQgbWF0ZXJpYWwgPSB7XHJcblx0XHRcdFx0XHRcdFx0XHRtYXRlcmlhbDogbWF0ZXJpYWxJZC50b1N0cmluZygpLFxyXG5cdFx0XHRcdFx0XHRcdFx0cXVhbnRpdHk6IE51bWJlcihxdWFudGl0eSlcclxuXHJcblx0XHRcdFx0XHRcdFx0fTtcclxuXHRcdFx0XHRcdE9yZGVyTGluZXNTdG9yZS51cGRhdGVMaW5lKG1hdGVyaWFsLm1hdGVyaWFsLCBtYXRlcmlhbCk7XHJcbiAgICAgIH1cclxuXHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLm1hdGVyaWFsSW5wdXQub24oJ2tleWRvd24nLCAoZSkgPT4ge1xyXG5cdFx0XHRcdGlmIChlLndoaWNoID09PSAxMykge1xyXG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vT3BlbiBjb25maWd1cmUgdGV4dCBkaWFsb2dcclxuXHRcdHRoaXMuY29uZmlndXJlRmlsZVRyaWdnZXIub24oJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHQkKCcjY29uZmlndXJlLW9yZGVybGluZScpLmZvdW5kYXRpb24oJ3JldmVhbCcsICdvcGVuJyk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL0FkZCBsaW5lIG9uIHRhYlxyXG5cdFx0dGhpcy5hZGRCdXR0b24ub24oJ2tleWRvd24nLCAoZSkgPT4ge1xyXG5cdFx0XHRpZihlLndoaWNoID09PSA5ICYmICFlLnNoaWZ0S2V5KSB7XHJcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdHRoaXMuYWRkQnV0dG9uLnRyaWdnZXIoJ2NsaWNrJyk7XHJcblx0XHRcdH1cclxuXHJcblx0XHR9KTtcclxuXHRcdHRoaXMucXVhbnRpdHlJbnB1dC5vbigna2V5ZG93bicsIChlKSA9PiB7XHJcblx0XHRcdGlmKGUud2hpY2ggPT09IDEzKSB7XHJcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdHRoaXMuYWRkQnV0dG9uLnRyaWdnZXIoJ2NsaWNrJyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vQWRkIGxpbmUgb24gY2xpY2svZW50ZXJcclxuXHRcdHRoaXMuYWRkQnV0dG9uLm9uKCdjbGljaycsIHRoaXMubWF0ZXJpYWxJc0J1eWFibGUuYmluZCh0aGlzKSk7XHJcblxyXG5cdFx0Ly9SZW1vdmUgbWVzc2FnZXMgd2hlbiBzdGFydGluZyB0byB0eXBlXHJcblx0XHR0aGlzLm1hdGVyaWFsSW5wdXQub24oJ2tleWRvd24nLCB0aGlzLmhpZGVNZXNzYWdlcy5iaW5kKHRoaXMpKTtcclxuXHJcblx0XHQvL1JlbW92ZSBhbGwgYmF0Y2ggbGluZSBpdGVtc1xyXG5cdFx0dGhpcy5yZW1vdmVBbGxCdXR0b24ub24oJ2NsaWNrJywgdGhpcy5yZW1vdmVBbGxPcmRlckxpbmVzLmJpbmQodGhpcykpO1xyXG5cclxuXHRcdC8vUmVtb3ZlIGxpbmUgaXRlbVxyXG5cdFx0bGV0IHNlbGYgPSB0aGlzO1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICcucmVtb3ZlLW9yZGVybGluZScsIGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0bGV0IGxpbmVJZCA9ICQodGhpcykuYXR0cignZGF0YS1saW5lLWlkJyk7XHJcblx0XHRcdHNlbGYucmVtb3ZlT3JkZXJMaW5lKGxpbmVJZCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL0ZvY3VzIG9uIG1hdGVyaWFsIHRoYXQgYWxyZWFkeSBleGlzdHMgaW4gb3JkZXJsaW5lc1xyXG5cdFx0JCgnI29yZGVybGluZS1leGlzdHMtZm9jdXMtaGFuZGxlcicpLm9uKCdjbGljaycsIChlKSA9PiB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0JCgnLnF1YW50aXR5JywgJ1tkYXRhLWxpbmUtaXRlbT0nICsgdGhpcy5tZXNzYWdlSWQuaHRtbCgpICsgJ10nKS5mb2N1cygpO1xyXG5cdFx0fSk7XHJcblx0XHQkKCBcIi51Yy1vcmRlcmxpbmVzIGZvcm1cIiApLnN1Ym1pdChmdW5jdGlvbiggZXZlbnQgKSB7XHJcbiAgXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL0xpc3RlbiB0byBjaGFuZ2VzIGluIHN0b3JlXHJcblx0XHRPcmRlckxpbmVzU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdHRoaXMuY291bnRPcmRlckxpbmVzKCk7XHJcblx0XHRcdHRoaXMuaGFuZGxlVmlzaWJpbGl0eSgpO1xyXG5cdFx0XHR0aGlzLnJlbmRlck9yZGVyTGluZXMoKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9LFxyXG5cclxuXHRtYXRlcmlhbElzQnV5YWJsZSgpIHtcclxuXHJcblxyXG5cdFx0bGV0IG1hdGVyaWFsSWQgPSB0aGlzLm1hdGVyaWFsSW5wdXQudmFsKCksXHJcblx0XHQgICAgcXVhbnRpdHkgICA9IGlzTmFOKHRoaXMucXVhbnRpdHlJbnB1dC52YWwoKSkgfHwgdGhpcy5xdWFudGl0eUlucHV0LnZhbCgpID09PSAnJyA/IDEgOiB0aGlzLnF1YW50aXR5SW5wdXQudmFsKCk7XHJcblxyXG5cdFx0bGV0IG1hdGVyaWFsID0ge1xyXG5cdFx0XHRcdFx0bWF0ZXJpYWw6IG1hdGVyaWFsSWQsXHJcblx0XHRcdFx0XHRxdWFudGl0eTogcXVhbnRpdHlcclxuXHRcdFx0XHR9O1xyXG5cclxuXHRcdGxldCBtYXRlcmlhbEFkZGVkID0gT3JkZXJMaW5lc1N0b3JlLmdldChtYXRlcmlhbC5tYXRlcmlhbCk7XHJcblxyXG5cdFx0aWYoIG1hdGVyaWFsLm1hdGVyaWFsICYmIG1hdGVyaWFsLnF1YW50aXR5ID4gMCl7XHJcblx0XHRcdFx0JCh0aGlzLmFkZEJ1dHRvbikuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHQkKHRoaXMuYWRkQnV0dG9uKS5wcm9wKFwiZGlzYWJsZWRcIix0cnVlKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZihtYXRlcmlhbEFkZGVkKSB7XHJcblx0XHRcdC8vU2hvdyBtYXRlcmlhbCBhbHJlYWR5IGFkZGVkIGluIG9yZGVybGluZXMgbWVzc2FnZVxyXG5cdFx0XHQkKHRoaXMuYWRkQnV0dG9uKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHQkKHRoaXMuYWRkQnV0dG9uKS5wcm9wKFwiZGlzYWJsZWRcIixmYWxzZSk7XHJcblx0XHRcdHRoaXMuc2hvd01lc3NhZ2UoJ2V4aXN0cycsIG1hdGVyaWFsKTtcclxuXHRcdFx0Ly9Gb2N1cyBmaWVsZFxyXG5cdFx0XHR0aGlzLm1hdGVyaWFsSW5wdXQuZm9jdXMoKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYoIG1hdGVyaWFsSWQubGVuZ3RoID09PSAwIHx8IHF1YW50aXR5Lmxlbmd0aCA9PT0gMCl7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRQcm9kdWN0QXBpLmlzYnV5YWJsZShtYXRlcmlhbElkKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHQkKHRoaXMuYWRkQnV0dG9uKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHQkKHRoaXMuYWRkQnV0dG9uKS5wcm9wKFwiZGlzYWJsZWRcIixmYWxzZSk7XHJcblx0XHRcdC8vIGlmKHJlc3BvbnNlLk1lc3NhZ2UpIHtcclxuXHRcdFx0Ly8gXHR0aGlzLnNob3dNZXNzYWdlKCdub3Rmb3VuZCcsIG1hdGVyaWFsKTtcclxuXHRcdFx0Ly8gXHR0aGlzLm1hdGVyaWFsSW5wdXQuZm9jdXMoKTtcclxuXHRcdFx0Ly8gfVxyXG5cdFx0XHRpZihyZXNwb25zZS5Jc0J1eWFibGUpIHtcclxuXHRcdFx0XHQvL1Nob3cgbWVzc2FnZVxyXG5cdFx0XHRcdG1hdGVyaWFsID0ge1xyXG5cdFx0XHRcdFx0XHRcdG1hdGVyaWFsOiByZXNwb25zZS5JZCxcclxuXHRcdFx0XHRcdFx0XHRxdWFudGl0eTogcXVhbnRpdHksXHJcblx0XHRcdFx0XHRcdFx0Y29zdDogcmVzcG9uc2UuQ29zdFxyXG5cdFx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdHRoaXMuc2hvd01lc3NhZ2UoJ3N1Y2Nlc3MnLCBtYXRlcmlhbCk7XHJcblx0XHRcdFx0Ly9BZGQgb3JlcmxpbmUgdG8gc3RvcmVcclxuXHRcdFx0XHR0aGlzLmFkZE9yZGVyTGluZShtYXRlcmlhbCk7XHJcblx0XHRcdFx0Ly9DbGVhciBpbnB1dCBmaWVsZHMgYW5kIGZvY3VzXHJcblx0XHRcdFx0dGhpcy5tYXRlcmlhbElucHV0LnZhbCgnJyk7XHJcblx0XHRcdFx0dGhpcy5xdWFudGl0eUlucHV0LnZhbCgnJyk7XHJcblx0XHRcdFx0dGhpcy5tYXRlcmlhbElucHV0LmZvY3VzKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0Ly8gY29uc29sZS5sb2cocmVzcG9uc2UpO1xyXG5cclxuXHRcdFx0XHQvL1Nob3cgbWVzc2FnZVxyXG5cdFx0XHRcdHRoaXMuc2hvd01lc3NhZ2UocmVzcG9uc2UuU3RhdHVzLCBtYXRlcmlhbCwgcmVzcG9uc2UuTWVzc2FnZSk7XHJcblx0XHRcdFx0Ly9Gb2N1cyBmaWVsZFxyXG5cdFx0XHRcdHRoaXMubWF0ZXJpYWxJbnB1dC5mb2N1cygpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0fSkuY2F0Y2goKG1lc3NhZ2UpID0+IHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0c2hvd01lc3NhZ2UobWVzc2FnZSwgbWF0ZXJpYWwsIHRleHQgPSBudWxsLCkge1xyXG5cdFx0dGhpcy5oaWRlTWVzc2FnZXMoKTtcclxuXHRcdHN3aXRjaChtZXNzYWdlKSB7XHJcblx0XHRcdGNhc2UgJ3N1Y2Nlc3MnOlxyXG5cdFx0XHRcdHRoaXMubWVzc2FnZU9rRWxtLnJlbW92ZUNsYXNzKCd1LWhpZGRlbicpO1xyXG5cdFx0XHRcdHRoaXMubWVzc2FnZUlkLmh0bWwobWF0ZXJpYWwubWF0ZXJpYWwpO1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRjYXNlICdJdGVtTm90Rm91bmQnOlxyXG5cdFx0XHRcdHRoaXMubWVzc2FnZU5vdEZvdW5kRWxtLnJlbW92ZUNsYXNzKCd1LWhpZGRlbicpO1xyXG5cdFx0XHRcdHRoaXMubWVzc2FnZUlkLmh0bWwobWF0ZXJpYWwubWF0ZXJpYWwpO1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRjYXNlICdJdGVtTm90QnV5YWJsZSc6XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlTm90QnV5YWJsZUVsbS5yZW1vdmVDbGFzcygndS1oaWRkZW4nKTtcclxuXHRcdFx0XHR0aGlzLm1lc3NhZ2VJZC5odG1sKG1hdGVyaWFsLm1hdGVyaWFsKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0Y2FzZSAnUmVzdHJpY3RlZCc6XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlUmVzdHJpY3RlZEVsbS5maW5kKCcubWVzc2FnZS1vcmRlci1saW5lLWlkJykubmV4dCgpLmh0bWwodGV4dCk7XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlUmVzdHJpY3RlZEVsbS5yZW1vdmVDbGFzcygndS1oaWRkZW4nKTtcclxuXHRcdFx0XHR0aGlzLm1lc3NhZ2VJZC5odG1sKG1hdGVyaWFsLm1hdGVyaWFsKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0Y2FzZSAnQ29udGFjdFByaW5jZXRvbkRlYWxlcic6XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlQ29udGFjdFByaW5jZXRvbkRlYWxlckVsbS5yZW1vdmVDbGFzcygndS1oaWRkZW4nKTtcclxuXHRcdFx0XHR0aGlzLm1lc3NhZ2VJZC5odG1sKG1hdGVyaWFsLm1hdGVyaWFsKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0Y2FzZSAnZXhpc3RzJzpcclxuXHRcdFx0XHR0aGlzLm1lc3NhZ2VFeGlzdHNFbG0ucmVtb3ZlQ2xhc3MoJ3UtaGlkZGVuJyk7XHJcblx0XHRcdFx0dGhpcy5tZXNzYWdlSWQuaHRtbChtYXRlcmlhbC5tYXRlcmlhbCk7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0YWRkT3JkZXJMaW5lKG1hdGVyaWFsKSB7XHJcblx0XHQvL0FkZCBtYXRlcmlhbCB0byBzdG9yZVxyXG5cdFx0JCgnI2FkZC10by1jYXJ0LXN1Y2Nlc3MnKS5oaWRlKCk7XHJcblx0XHRPcmRlckxpbmVzQWN0aW9ucy5hZGQobWF0ZXJpYWwubWF0ZXJpYWwsIG1hdGVyaWFsKTtcclxuXHR9LFxyXG5cclxuXHJcblx0cmVuZGVyT3JkZXJMaW5lcygpIHtcclxuXHRcdCQoJyNsaW5lLWl0ZW1zJykuZW1wdHkoKTtcclxuXHRcdGxldCBsaW5lSXRlbXMgPSBPcmRlckxpbmVzU3RvcmUuZ2V0U3RvcmUoKTtcclxuXHRcdGxldCBsaW5lSXRlbXNDb3JyZWN0T3JkZXIgPSBbXTtcclxuXHJcblx0XHRmb3IgKHZhciBpID0gT2JqZWN0LmtleXMobGluZUl0ZW1zKS5sZW5ndGggLSAxOyBpID4gLTE7IGktLSkge1xyXG5cdFx0XHRsaW5lSXRlbXNDb3JyZWN0T3JkZXIucHVzaChsaW5lSXRlbXNbaV0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxpbmVJdGVtc0NvcnJlY3RPcmRlci5mb3JFYWNoKChsaW5lSXRlbSkgPT4ge1xyXG5cdFx0XHRjb25zb2xlLmxvZyhsaW5lSXRlbSk7XHJcblx0XHRcdGxldCBpdGVtICA9ICc8ZGl2IGNsYXNzPVwicm93XCIgZGF0YS1saW5lLWl0ZW09XCInICsgbGluZUl0ZW0ua2V5ICsgJ1wiID4nO1xyXG5cdFx0XHRcdFx0aXRlbSArPSAnPGRpdiBjbGFzcz1cInNtYWxsLTYgbWVkaXVtLTcgY29sdW1uc1wiPic7XHJcblx0XHRcdFx0XHRpdGVtICs9ICc8aW5wdXQgY2xhc3M9XCJtYXRlcmlhbG51bWJlclwiIHR5cGU9XCJ0ZXh0XCIgcmVhZG9ubHkgdmFsdWU9XCInICsgbGluZUl0ZW0uZGF0YS5tYXRlcmlhbCArICdcIiAvPic7XHJcblx0XHRcdFx0XHRpdGVtICs9ICc8L2Rpdj4nXHJcblx0XHRcdFx0XHRpdGVtICs9ICc8ZGl2IGNsYXNzPVwic21hbGwtNiBtZWRpdW0tNSBjb2x1bW5zXCI+JztcclxuXHRcdFx0XHRcdGl0ZW0gKz0gJzxpbnB1dCBkYXRhLXByb2R1Y3QtY29zdD1cIicrIGxpbmVJdGVtLmRhdGEuY29zdCArJ1wiIGRhdGEtbGluZS1pdGVtPVwiJyArIGxpbmVJdGVtLmtleSArICdcIiBjbGFzcz1cInF1YW50aXR5XCIgdHlwZT1cInRleHRcIiB2YWx1ZT1cIicgKyBsaW5lSXRlbS5kYXRhLnF1YW50aXR5ICsgJ1wiIC8+JztcclxuXHRcdFx0XHRcdGl0ZW0gKz0gJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtbGluZS1pZD1cIicgKyBsaW5lSXRlbS5rZXkgKyAnXCIgY2xhc3M9XCJidXR0b24gb3V0bGluZWQgdGhpbiByZW1vdmUtb3JkZXJsaW5lXCI+JztcclxuXHRcdFx0XHRcdGl0ZW0gKz0gJzxpIGNsYXNzPVwiaWNvbi10cmFzaFwiPjwvaT48c3Bhbj4nICsgaGlhYmNvbmZpZy5iYXRjaE9yZGVyLmxhbmcucmVtb3ZlT3JkZXJsaW5lICsgJzwvc3Bhbj4nO1xyXG5cdFx0XHRcdFx0aXRlbSArPSAnPC9idXR0b24+JztcclxuXHRcdFx0XHRcdGl0ZW0gKz0gJzwvZGl2Pic7XHJcblx0XHRcdFx0XHRpdGVtICs9ICc8L2Rpdj4nO1xyXG5cdFx0XHQkKCcjbGluZS1pdGVtcycpLmFwcGVuZChpdGVtKTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGNvdW50T3JkZXJMaW5lcygpIHtcclxuXHRcdCQoJyNvcmRlcmxpbmVzLWNvdW50JykuaHRtbChPcmRlckxpbmVzU3RvcmUuZ2V0U3RvcmUoKS5sZW5ndGggKyAnICcpO1xyXG5cdH0sXHJcblxyXG5cdGhhbmRsZVZpc2liaWxpdHkoKSB7XHJcblx0XHRpZihPcmRlckxpbmVzU3RvcmUuZ2V0U3RvcmUoKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdHRoaXMucmVtb3ZlQWxsQnV0dG9uLmFkZENsYXNzKCd1LXZpc2libGUnKTtcclxuXHRcdFx0dGhpcy5hZGRMaW5lc0J1dHRvbnMuYWRkQ2xhc3MoJ3UtdmlzaWJsZS1rZWVwLWxheW91dCcpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHRoaXMucmVtb3ZlQWxsQnV0dG9uLnJlbW92ZUNsYXNzKCd1LXZpc2libGUnKTtcclxuXHRcdFx0dGhpcy5hZGRMaW5lc0J1dHRvbnMucmVtb3ZlQ2xhc3MoJ3UtdmlzaWJsZS1rZWVwLWxheW91dCcpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHJlbW92ZU9yZGVyTGluZShpZCkge1xyXG5cdFx0T3JkZXJMaW5lc0FjdGlvbnMucmVtb3ZlT3JkZXJMaW5lKGlkKTtcclxuXHRcdHRoaXMuaGlkZU1lc3NhZ2VzKCk7XHJcblx0fSxcclxuXHJcblx0cmVtb3ZlQWxsT3JkZXJMaW5lcyhlKSB7XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHQvL0NsZWFyIHN0b3JlIVxyXG5cdFx0T3JkZXJMaW5lc0FjdGlvbnMuY2xlYXIoKTtcclxuXHRcdHRoaXMuaGlkZU1lc3NhZ2VzKCk7XHJcblx0XHR0aGlzLmhpZGVJbXBvcnRFeGNlbE1lc3NhZ2UoKTtcclxuXHR9LFxyXG5cclxuXHRoaWRlTWVzc2FnZXMoKSB7XHJcblx0XHR0aGlzLm1lc3NhZ2VFbG0uYWRkQ2xhc3MoJ3UtaGlkZGVuJyk7XHJcblx0XHR0aGlzLmZpbGVNZXNzYWdlc0VsbS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0fSxcclxuXHQvL0hpZGUgbWVzc2FnZSBmcm9tIGV4Y2VsIHdoZW4gcmVtb3Zpbmcgb3JkZXJsaW5lc1xyXG5cdGhpZGVJbXBvcnRFeGNlbE1lc3NhZ2UoKXtcclxuXHRcdHRoaXMuZXhjZWxNZXNzYWdlc0VsbS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0fVxyXG5cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG9yZGVybGluZXM7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBmaWxldXBsb2FkIGZyb20gJ2ZpbGV1cGxvYWQnO1xyXG5pbXBvcnQgT3JkZXJMaW5lc0FjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvb3JkZXJsaW5lc19hY3Rpb25zJztcclxuaW1wb3J0IEN1c3RvbUV2ZW50cyBmcm9tICcuLi9fbGliL2N1c3RvbS1ldmVudHMnO1xyXG5cclxubGV0IHVwbG9hZGZpbGUgPSB7XHJcblx0aW5pdCgpIHtcclxuXHJcblx0XHRsZXQgYnV5YWJsZXMgPSBbXTtcclxuXHRcdGxldCBlcnJvcnMgPSBbXTtcclxuXHJcbiAgICBsZXQgdXJsID0gaGlhYmNvbmZpZy5iYXRjaE9yZGVyLmFwaUJhc2VVcmwgKyAnVXBsb2FkRmlsZSc7XHJcbiAgICAkKCcjZmlsZXVwbG9hZCcpLmZpbGV1cGxvYWQoe1xyXG5cdFx0XHRzaW5nbGVGaWxlVXBsb2FkczogdHJ1ZSxcclxuXHRcdFx0bGltaXRNdWx0aUZpbGVVcGxvYWRTaXplOiAxMDAwMDAwLFxyXG5cdFx0XHR1cmw6IHVybCxcclxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcclxuXHRcdFx0YWRkOiBmdW5jdGlvbiAoZSwgZGF0YSkge1xyXG5cdFx0XHRcdCQoJyNhZGQtdG8tY2FydC1zdWNjZXNzJykuaGlkZSgpO1xyXG5cdFx0XHRcdCQoJyNmaWxldXBsb2FkIGJ1dHRvbicpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblx0XHRcdFx0JCgnLmZpbGV1cGxvYWQtbWVzc2FnZXMgcCAuZXJyb3ItaW1wb3J0JykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdCQoJy5maWxldXBsb2FkLW1lc3NhZ2VzIHAgLmltcG9ydGVkJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdCQoJy5maWxldXBsb2FkLWVycm9ycycpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHQkKCcuZmlsZXVwbG9hZC1tZXNzYWdlcyBwIC5pbXBvcnRpbmcnKS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0ZGF0YS5zdWJtaXQoKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0ZG9uZTogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuXHRcdFx0XHRidXlhYmxlcyA9IGRhdGEucmVzdWx0LkJ1eWFibGVzO1xyXG5cdFx0XHRcdGVycm9ycyA9IGRhdGEucmVzdWx0LkVycm9ycztcclxuXHRcdFx0XHQkKCcjZmlsZXVwbG9hZCBidXR0b24nKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHRcdGlmKCBlcnJvcnMubGVuZ3RoID4gMCl7XHJcblx0XHRcdFx0XHQkKCcuZmlsZXVwbG9hZC1lcnJvcnMnKS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0XHQkKCcuZXJyb3ItaW1wb3J0LWNvdW50JykudGV4dChlcnJvcnMubGVuZ3RoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0JCgnLmZpbGV1cGxvYWQtbWVzc2FnZXMnKS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblxyXG5cdFx0XHRcdCQuZWFjaChidXlhYmxlcywgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkge1xyXG5cdFx0XHRcdFx0bGV0IG1hdGVyaWFsID0ge1xyXG5cdFx0XHRcdFx0XHRcdFx0bWF0ZXJpYWw6IHZhbHVlLk1hdGVyaWFsSWQsXHJcblx0XHRcdFx0XHRcdFx0XHRxdWFudGl0eTogdmFsdWUuUXVhbnRpdHksXHJcblx0XHRcdFx0XHRcdFx0XHRjb3N0OiB2YWx1ZS5Db3N0XHJcblx0XHRcdFx0XHRcdFx0fTtcclxuXHRcdFx0XHRcdE9yZGVyTGluZXNBY3Rpb25zLmFkZChtYXRlcmlhbC5tYXRlcmlhbCwgbWF0ZXJpYWwpO1xyXG4gICAgXHRcdH0pO1xyXG5cdFx0XHRcdEN1c3RvbUV2ZW50cy5iYXRjaFVwbG9hZChkYXRhKTtcclxuXHJcblx0XHRcdFx0JCgnLmVycm9yLW1vZGFsIHVsJykuZW1wdHkoKTtcclxuXHRcdFx0XHQkLmVhY2goZXJyb3JzLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7XHJcblx0XHRcdFx0XHQkKCcuZXJyb3ItbW9kYWwgdWwnKS5hcHBlbmQoJzxsaT4nK3ZhbHVlLkVycm9yTWVzc2FnZSsnPC9saT4nKTtcclxuICAgIFx0XHR9KTtcclxuXHJcblx0XHRcdFx0JC5lYWNoKGRhdGEuZmlsZXMsIGZ1bmN0aW9uIChpbmRleCwgZmlsZSkge1xyXG5cdFx0XHRcdFx0XHQkKCcuZmlsZS1uYW1lJykudGV4dChmaWxlLm5hbWUpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdCQoJy5pbXBvcnQtY291bnQnKS50ZXh0KGJ1eWFibGVzLmxlbmd0aCk7XHJcblx0XHRcdFx0JCgnLmZpbGV1cGxvYWQtbWVzc2FnZXMgcCAuaW1wb3J0aW5nJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdCQoJy5maWxldXBsb2FkLW1lc3NhZ2VzIHAgLmltcG9ydGVkJykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cclxuICAgICAgfSxcclxuXHRcdFx0ZmFpbDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuXHRcdFx0XHQkKCcuZmlsZXVwbG9hZC1tZXNzYWdlcycpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHQkKCcuZmlsZXVwbG9hZC1tZXNzYWdlcyBwIC5pbXBvcnRpbmcnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0JCgnLmZpbGV1cGxvYWQtbWVzc2FnZXMgcCAuZXJyb3ItaW1wb3J0IC5tZXNzYWdlJykudGV4dChkYXRhLl9yZXNwb25zZS5qcVhIUi5yZXNwb25zZUpTT04pO1xyXG5cdFx0XHRcdCQoJy5maWxldXBsb2FkLW1lc3NhZ2VzIHAgLmVycm9yLWltcG9ydCcpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHQkKCcjZmlsZXVwbG9hZCBidXR0b24nKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHR9LFxyXG4gICAgICBwcm9ncmVzc2FsbDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcclxuICAgICAgICAgIC8vdmFyIHByb2dyZXNzID0gcGFyc2VJbnQoZGF0YS5sb2FkZWQgLyBkYXRhLnRvdGFsICogMTAwLCAxMCk7XHJcbiAgICAgIH1cclxuICAgIH0pLnByb3AoJ2Rpc2FibGVkJywgISQuc3VwcG9ydC5maWxlSW5wdXQpXHJcbiAgICAgICAgLnBhcmVudCgpLmFkZENsYXNzKCQuc3VwcG9ydC5maWxlSW5wdXQgPyB1bmRlZmluZWQgOiAnZGlzYWJsZWQnKTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IHVwbG9hZGZpbGU7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbi8vIGltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBDaGVja291dENhcnRMaW5lSXRlbVVwZGF0ZSBmcm9tICcuL2NoZWNrb3V0X2NhcnRfbGluZWl0ZW1fdXBkYXRlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydExpbmVJdGVtRGVsZXRlIGZyb20gJy4vY2hlY2tvdXRfY2FydF9saW5laXRlbV9kZWxldGUnO1xyXG5pbXBvcnQgQ2hlY2tvdXRDYXJ0TGluZUl0ZW1Db21tZW50IGZyb20gJy4vY2hlY2tvdXRfY2FydF9saW5laXRlbV9jb21tZW50JztcclxuaW1wb3J0IENoZWNrb3V0U2hpcHBpbmcgZnJvbSAnLi9jaGVja291dF9zaGlwcGluZ19uZXcnO1xyXG5cclxuaW1wb3J0IENoZWNrb3V0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zX25ldyc7XHJcblxyXG5pbXBvcnQgQ2hlY2tvdXRMb2FkaW5nU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9sb2FkaW5nX3N0b3JlJztcclxuXHJcbmltcG9ydCBDaGVja291dE9yZGVyU2ltdWxhdGlvblN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfb3JkZXJfc2ltdWxhdGlvbl9zdG9yZSc7XHJcblxyXG5pbXBvcnQgQ2hlY2tvdXRDYXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydFRvdGFsU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X3RvdGFsX3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydEFsZXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9jYXJ0X2FsZXJ0X3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0Q2FydFdhcm5pbmdTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X2NhcnRfd2FybmluZ19zdG9yZSc7XHJcblxyXG5pbXBvcnQgQ2hlY2tvdXREYW5nZXJvdXNHb29kc0FsZXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF9kYW5nZXJvdXNfZ29vZHNfYWxlcnRfc3RvcmUnO1xyXG5pbXBvcnQgQ2hlY2tvdXRTaGlwcGluZ1N0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfc2hpcHBpbmdfc3RvcmUnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBZGRyZXNzZXNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X2FkZHJlc3Nlc19zdG9yZSc7XHJcbmltcG9ydCBDaGVja291dEJpbGxpbmdTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X2JpbGxpbmdfc3RvcmUnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBZGRyZXNzZXNBbGVydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfYWRkcmVzc2VzX2FsZXJ0X3N0b3JlJztcclxuXHJcbmltcG9ydCBDaGVja291dFN1bW1hcnlTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X3N1bW1hcnlfc3RvcmUnO1xyXG5cclxuaW1wb3J0IENoZWNrb3V0VHJhY2tpbmdEYXRhU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jaGVja291dF90cmFja2luZ19kYXRhX3N0b3JlJztcclxuXHJcbmltcG9ydCBDdXN0b21FdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuXHJcbmxldCBhbHRlcm5hdGl2ZUxheW91dCA9IGhpYWJjb25maWcubWFya2V0SWQgPT0gXCJKUDAyXCIgPyB0cnVlIDogZmFsc2U7XHJcblxyXG5sZXQgdmFsaWRhdGlvbiA9IHtcclxuXHRcInRlcm1zQXBwcm92ZWRcIiA6IGZhbHNlLFxyXG5cdFwibWluaW1hbEFsbG93ZWRQYXNzZWRcIiA6IGZhbHNlLFxyXG5cdFwiYWRkcmVzc1ZhbGlkXCIgOiBmYWxzZSxcclxuXHRcImhhc1NoaXBwaW5nT3B0aW9uc1wiIDogZmFsc2UsXHJcblx0XCJoYXNWYWxpZFBheW1lbnRPcHRpb25cIiA6IGZhbHNlLFxyXG5cdFwiaGFzTm9FcnJvc1wiIDogZmFsc2VcclxufTtcclxubGV0IGNoZWNrb3V0TGFuZyA9IGhpYWJjb25maWcuY2hlY2tvdXQubGFuZztcclxuXHJcbmxldCBjaGVja291dCA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0aWYoJCgnLnVjLWNoZWNrb3V0LWNhcnQnKS5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHRcdHRoaXMudmFsaWRhdGUoKTtcclxuXHRcdHRoaXMucmVSZW5kZXJDaGVja291dCgpO1xyXG5cdFx0dGhpcy5jaGVja291dENoYW5nZXMoKTtcclxuXHRcdHRoaXMuY2hlY2tvdXRGdW5jdGlvbmFsaXR5KCk7XHJcblx0XHR0aGlzLnNldFNoaXBwaW5nQWRkcmVzc0ZvclN1bW1hcnkoKTtcclxuXHJcblx0fSxcclxuXHJcblx0dmFsaWRhdGUoKXtcclxuXHRcdEZvdW5kYXRpb24ubGlicy5hYmlkZS52YWxpZGF0ZSgkKCcjY2hlY2tvdXRmb3JtJykuZmluZCgnaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEnKSwge3R5cGU6Jyd9KTtcclxuXHJcblx0XHR2YWxpZGF0aW9uLnRlcm1zQXBwcm92ZWQgPSBcdFx0XHRcdCQoJyNjaGVja291dC10ZXJtcy1jb25kaXRpb24nKS5pcygnOmNoZWNrZWQnKTtcclxuXHRcdHZhbGlkYXRpb24uYWRkcmVzc1ZhbGlkID0gXHRcdFx0XHQkKCcuY2hlY2tvdXQtYWRkcmVzcy1pbmZvIC5pbnB1dC13cmFwcGVyLmVycm9yJykubGVuZ3RoID09PSAwICYmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JCgnLmNoZWNrb3V0LWFkZHJlc3MtaW5mbyAuaW5wdXQtd3JhcHBlci5pbnZhbGlkJykubGVuZ3RoID09PSAwICYmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JCgnLmRlbGl2ZXJ5LWFkZHJlc3Nlcy1jb250YWluZXInKS5sZW5ndGggPiAwO1xyXG5cclxuXHRcdHZhbGlkYXRpb24uaGFzU2hpcHBpbmdPcHRpb25zID0gXHQkKCcjbm8tc2hpcHBpbmctb3B0aW9ucycpLmxlbmd0aCA9PT0gMDtcclxuXHJcblx0XHRsZXQgYWN0aXZlUGF5bWVudE9wdGlvbnMgPSAkKCcucGF5bWVudC10eXBlJykuZmlsdGVyKFwiOm5vdCguZGlzYWJsZWQpXCIpO1xyXG5cdFx0aWYoYWN0aXZlUGF5bWVudE9wdGlvbnMubGVuZ3RoICE9IDApIHtcclxuXHRcdFx0dmFsaWRhdGlvbi5oYXNWYWxpZFBheW1lbnRPcHRpb24gPSB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhbGlkYXRpb24ubWluaW1hbEFsbG93ZWRQYXNzZWQgPSAkKCcudXBkYXRlLWNhcnQtYW1tb3VudCcpLmxlbmd0aCA9PT0gMDtcclxuXHRcdHZhbGlkYXRpb24uaGFzTm9FcnJvcyA9IFx0XHRcdFx0XHQkKCcudWMtbWVzc2FnZS5lcnJvcicpLmxlbmd0aCA9PT0gMDtcclxuXHJcblx0XHRsZXQgdmFsaWRhdGlvbkVycm9yV3JhcHBlciA9ICQoJy52YWxpZGF0aW9uLWVycm9ycycpO1xyXG5cdFx0bGV0IHZhbGlkYXRpb25FcnJvciA9ICQoJy52YWxpZGF0aW9uLWVycm9ycyB1bCcpO1xyXG5cdFx0bGV0IGNvbXBsZXRlUHVyY2hhc2VCdXR0b24gPSAkKCcjY29tcGxldGUtcHVyY2hhc2UtYnV0dG9uJyk7XHJcblxyXG5cdFx0Zm9yKHZhciBzdGF0dXMgaW4gdmFsaWRhdGlvbikge1xyXG5cdFx0XHRpZiAodmFsaWRhdGlvbltzdGF0dXNdID09PSBmYWxzZSkge1xyXG5cdFx0XHRcdGNvbXBsZXRlUHVyY2hhc2VCdXR0b24ucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHRjb21wbGV0ZVB1cmNoYXNlQnV0dG9uLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcblx0XHRcdFx0dmFsaWRhdGlvbkVycm9yV3JhcHBlci5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0dGhpcy52YWxpZGF0ZUVycm9yc0FjdGlvbnModmFsaWRhdGlvbkVycm9yV3JhcHBlciwgdmFsaWRhdGlvbkVycm9yKTtcclxuXHRcdCAgICBicmVhaztcclxuXHRcdCAgfWVsc2V7XHJcblx0XHRcdFx0Y29tcGxldGVQdXJjaGFzZUJ1dHRvbi5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcclxuXHRcdFx0XHRpZigkKHZhbGlkYXRpb25FcnJvcikuY2hpbGRyZW4oKS5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRcdCQodmFsaWRhdGlvbkVycm9yKS5jaGlsZHJlbigpLnJlbW92ZSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR2YWxpZGF0aW9uRXJyb3JXcmFwcGVyLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblx0dmFsaWRhdGVFcnJvcnNBY3Rpb25zKHZhbGlkYXRpb25FcnJvcldyYXBwZXIsIHZhbGlkYXRpb25FcnJvcil7XHJcblx0XHRpZigkKHZhbGlkYXRpb25FcnJvcikuY2hpbGRyZW4oKS5sZW5ndGggPiAwKXtcclxuXHRcdFx0JCh2YWxpZGF0aW9uRXJyb3IpLmNoaWxkcmVuKCkucmVtb3ZlKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IGNoZWNrb3V0TXNnID0gY2hlY2tvdXRMYW5nLmNhcnRFcnJvcjtcclxuXHRcdGxldCBjaGVja291dEVycm9yID0gJzxsaT48YSBocmVmPVwiI1wiIGRhdGEtc2Nyb2xsLXRvPVwiLnVjLW1lc3NhZ2UuZXJyb3JcIj4nK2NoZWNrb3V0TXNnKyc8L2E+IC0gJytjaGVja291dExhbmcucmV2aWV3Kyc8L2xpPic7XHJcblx0XHRpZighdmFsaWRhdGlvbi5oYXNOb0Vycm9zKXtcclxuXHRcdFx0dmFsaWRhdGlvbkVycm9yLmFwcGVuZChjaGVja291dEVycm9yKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgY2FydE1zZyA9ICQoJy51Yy1jaGVja291dC1jYXJ0IGgzJykudGV4dCgpO1xyXG5cdFx0bGV0IGNhcnRFcnJvciA9ICc8bGk+PGEgaHJlZj1cIiNcIiBkYXRhLXNjcm9sbC10bz1cIi51Yy1jaGVja291dC1jYXJ0XCI+JytjYXJ0TXNnKyc8L2E+IC0gJytjaGVja291dExhbmcucmV2aWV3Kyc8L2xpPic7XHJcblx0XHRpZighdmFsaWRhdGlvbi5taW5pbWFsQWxsb3dlZFBhc3NlZCl7XHJcblx0XHRcdHZhbGlkYXRpb25FcnJvci5hcHBlbmQoY2FydEVycm9yKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgYWRkcmVzc01zZyA9ICQoJy51Yy1jaGVja291dC1zaGlwcGluZyAuY2hlY2tvdXQtYWRkcmVzcy1pbmZvIGg0OmZpcnN0LWNoaWxkJykudGV4dCgpO1xyXG5cdFx0bGV0IGFkZHJlc3NFcnJvciA9ICc8bGk+PGEgaHJlZj1cIiNcIiBkYXRhLXNjcm9sbC10bz1cIi51Yy1jaGVja291dC1zaGlwcGluZyAuZGVsaXZlcnktYWRkcmVzc2VzLWNvbnRhaW5lclwiPicrYWRkcmVzc01zZysnPC9hPiAtICcrY2hlY2tvdXRMYW5nLnJldmlldysnPC9saT4nO1xyXG5cdFx0aWYoIXZhbGlkYXRpb24uYWRkcmVzc1ZhbGlkKXtcclxuXHRcdFx0dmFsaWRhdGlvbkVycm9yLmFwcGVuZChhZGRyZXNzRXJyb3IpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBzaGlwcGluZ01zZyA9ICQoJy51Yy1jaGVja291dC1zaGlwcGluZyAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucyBoNDpmaXJzdC1jaGlsZCcpLnRleHQoKTtcclxuXHRcdGxldCBzaGlwcGluZ0Vycm9yID0gJzxsaT48YSBocmVmPVwiI1wiIGRhdGEtc2Nyb2xsLXRvPVwiLnVjLWNoZWNrb3V0LXNoaXBwaW5nIC51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zXCI+JytzaGlwcGluZ01zZysnPC9hPiAtICcrY2hlY2tvdXRMYW5nLnJldmlldysnPC9saT4nO1xyXG5cdFx0aWYoIXZhbGlkYXRpb24uaGFzU2hpcHBpbmdPcHRpb25zKXtcclxuXHRcdFx0dmFsaWRhdGlvbkVycm9yLmFwcGVuZChzaGlwcGluZ0Vycm9yKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgcGF5bWVudE9wdGlvbkVycm9yTXNnID0gJCgnLnNoaXBwaW5nLXBsYW50IGg1JykudGV4dCgpO1xyXG5cdFx0bGV0IHBheW1lbnRPcHRpb25FcnJvciA9ICc8bGk+PGEgaHJlZj1cIiNcIiBkYXRhLXNjcm9sbC10bz1cIi5wYXltZW50LW9wdGlvbnNcIj4nK3BheW1lbnRPcHRpb25FcnJvck1zZysnPC9hPiAtICcrY2hlY2tvdXRMYW5nLnJldmlldysnPC9saT4nO1xyXG5cclxuXHRcdGlmKCF2YWxpZGF0aW9uLmhhc1ZhbGlkUGF5bWVudE9wdGlvbikge1xyXG5cdFx0XHR2YWxpZGF0aW9uRXJyb3IuYXBwZW5kKHBheW1lbnRPcHRpb25FcnJvcik7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHRlcm1zTXNnID0gJCgnLnVjLWNoZWNrb3V0LXRlcm1zIGgzJykudGV4dCgpO1xyXG5cdFx0bGV0IHRlcm1zRXJyb3IgPSAnPGxpPjxhIGhyZWY9XCIjXCIgZGF0YS1zY3JvbGwtdG89XCIudWMtY2hlY2tvdXQtdGVybXNcIj4nK3Rlcm1zTXNnKyc8L2E+IC0gJytjaGVja291dExhbmcucmV2aWV3Kyc8L2xpPic7XHJcblx0XHRpZighdmFsaWRhdGlvbi50ZXJtc0FwcHJvdmVkKXtcclxuXHRcdFx0dmFsaWRhdGlvbkVycm9yLmFwcGVuZCh0ZXJtc0Vycm9yKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cdHJlUmVuZGVyQ2hlY2tvdXQoKSB7XHJcblx0XHRjaGVja291dC5zaW11bGF0ZU9yZGVyKCk7XHJcblxyXG5cdFx0Q3VzdG9tRXZlbnRzLmxvYWRDYXJ0RXZlbnRDaGVja291dCh3aW5kb3cuY2FydENvbnRlbnQsd2luZG93LmNhcnRJZCk7XHJcblxyXG5cdFx0Q2hlY2tvdXRPcmRlclNpbXVsYXRpb25TdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0bGV0IHNpbXVsYXRpb25JbmZvID0gQ2hlY2tvdXRPcmRlclNpbXVsYXRpb25TdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHQkKCcuc2ltdWxhdGlvbi1jYWxjdWxhdGlvbicpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcblxyXG5cdFx0XHRpZihzaW11bGF0aW9uSW5mby5zdGF0dXNDb2RlKXtcclxuXHRcdFx0XHQkKCcuc2ltdWxhdGlvbi1pdGVtJykucmVtb3ZlQ2xhc3MoJ2xvYWRlZCcpO1xyXG5cdFx0XHRcdGlmKCAkKCcudWMtbWVzc2FnZS5lcnJvci5vcmRlci1zaW11bGF0aW9uJykubGVuZ3RoID09IDApe1xyXG5cdFx0XHRcdFx0bGV0IGVycm9yRWxtID1cclxuXHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwidWMtbWVzc2FnZSBlcnJvciBvcmRlci1zaW11bGF0aW9uIDUwMC1lcnJvclwiPjxkaXYgY2xhc3M9XCJyb3dcIj48ZGl2IGNsYXNzPVwibGFyZ2UtNiBjb2x1bW5zXCI+JytcclxuXHRcdFx0XHRcdCc8cD4nK2NoZWNrb3V0TGFuZy5jYXJ0RXJyb3IrJzxici8+JytjaGVja291dExhbmcuc2ltdWxhdGlvbkVycm9yKyc8L3A+JytcclxuXHRcdFx0XHRcdCc8L2Rpdj48L2Rpdj48L2Rpdj4nO1xyXG5cdFx0XHRcdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLmNhcnQtd2FybmluZ3MnKS5hcHBlbmQoZXJyb3JFbG0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0aWYoc2ltdWxhdGlvbkluZm8uRXJyb3JWaWV3TW9kZWwgIT0gbnVsbCl7XHJcblx0XHRcdFx0XHRpZihzaW11bGF0aW9uSW5mby5FcnJvclZpZXdNb2RlbC5IYXNFcnJvcil7XHJcblx0XHRcdFx0XHRcdCQoJy5zaW11bGF0aW9uLWl0ZW0nKS5yZW1vdmVDbGFzcygnbG9hZGVkJyk7XHJcblx0XHRcdFx0XHRcdGlmKCAkKCcudWMtbWVzc2FnZS5lcnJvci5vcmRlci1zaW11bGF0aW9uJykubGVuZ3RoID09IDApe1xyXG5cdFx0XHRcdFx0XHRcdCQoJy51Yy1jaGVja291dC1jYXJ0IC5jYXJ0LXdhcm5pbmdzJykucHJlcGVuZChzaW11bGF0aW9uSW5mby5FcnJvclZpZXdNb2RlbC5FcnJvckh0bWwpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHQkKCcudWMtbWVzc2FnZS5lcnJvci5vcmRlci1zaW11bGF0aW9uJykucmVtb3ZlKCk7XHJcblxyXG5cdFx0XHRcdFx0JCgnLnRvdGFsIC5rZXkuc2hpcHBpbmcnKVxyXG5cdFx0XHRcdFx0JCgnLnRvdGFsIC52YWx1ZS5zaGlwcGluZycpLnRleHQoc2ltdWxhdGlvbkluZm8uU2hpcHBpbmdBbW91bnQpO1xyXG5cclxuXHRcdFx0XHRcdCQoJy5zaW11bGF0aW9uLWl0ZW0nKS5hZGRDbGFzcygnbG9hZGVkJyk7XHJcblx0XHRcdFx0XHQkKCcuSlMtVGF4RGVzY3JpcHRpb24nKS50ZXh0KHNpbXVsYXRpb25JbmZvLlRheERlc2NyaXB0aW9uKTtcclxuXHRcdFx0XHRcdCQoJy5KUy1UYXhQZXJjZW50YWdlJykudGV4dChzaW11bGF0aW9uSW5mby5UYXhQZXJjZW50YWdlKTtcclxuXHRcdFx0XHRcdCQoJy5KUy1UYXhBbW91bnQnKS50ZXh0KHNpbXVsYXRpb25JbmZvLlRheEFtb3VudCk7XHJcblx0XHRcdFx0XHQkKCcuSlMtVGF4VG90YWwnKS50ZXh0KHNpbXVsYXRpb25JbmZvLlRvdGFsKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vQ0FSVFxyXG5cdFx0Q2hlY2tvdXRDYXJ0U3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBodG1sID0gQ2hlY2tvdXRDYXJ0U3RvcmUuZ2V0U3RvcmUoKTtcclxuXHRcdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLmNoZWNrb3V0LWNhcnQtY29udGVudCcpLmh0bWwoaHRtbCk7XHJcblx0XHR9KTtcclxuXHRcdENoZWNrb3V0Q2FydFRvdGFsU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBodG1sID0gQ2hlY2tvdXRDYXJ0VG90YWxTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHQkKCcudWMtY2hlY2tvdXQtY2FydCAub3JkZXItdG90YWwnKS5odG1sKGh0bWwpO1xyXG5cdFx0fSk7XHJcblx0XHRDaGVja291dENhcnRBbGVydFN0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRsZXQgaHRtbCA9IENoZWNrb3V0Q2FydEFsZXJ0U3RvcmUuZ2V0U3RvcmUoKTtcclxuXHRcdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLmNhcnQtdXBkYXRlLXdyYXBwZXInKS5odG1sKGh0bWwpO1xyXG5cdFx0fSk7XHJcblx0XHRDaGVja291dENhcnRXYXJuaW5nU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBodG1sID0gQ2hlY2tvdXRDYXJ0V2FybmluZ1N0b3JlLmdldFN0b3JlKCk7XHJcblx0XHRcdCQoJy51Yy1jaGVja291dC1jYXJ0IC5jYXJ0LXdhcm5pbmdzJykuaHRtbChodG1sKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vU0hJUFBJTkdcclxuXHRcdENoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydFN0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRsZXQgaHRtbCA9IENoZWNrb3V0RGFuZ2Vyb3VzR29vZHNBbGVydFN0b3JlLmdldFN0b3JlKCk7XHJcblx0XHRcdCQoJy51Yy1jaGVja291dC1zaGlwcGluZyAuZGFuZ2Vyb3VzLWdvb2RzLWluZGljYXRvcicpLmh0bWwoaHRtbCk7XHJcblx0XHR9KTtcclxuXHRcdENoZWNrb3V0QWRkcmVzc2VzU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBodG1sID0gQ2hlY2tvdXRBZGRyZXNzZXNTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHQkKCcudWMtY2hlY2tvdXQtc2hpcHBpbmcgLmRlbGl2ZXJ5LWFkZHJlc3Nlcy13cmFwcGVyJykuaHRtbChodG1sKTtcclxuXHRcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbignYWJpZGUnLCAncmVmbG93Jyk7XHJcblxyXG5cdFx0XHQvL1VwZGF0ZSBzdW1tYXJ5XHJcblx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNoZWNrb3V0LnNldFNoaXBwaW5nQWRkcmVzc0ZvclN1bW1hcnkoKTsgfSwgMTAwKTtcclxuXHJcblx0XHRcdC8vIGlmIGJpZyBjdXN0b21lciBubyB2YWxpZGF0aW9uIGlzIG5lZWRlZFxyXG5cdFx0XHRpZigkKCcjY291bnRyeUNvZGVDaGVja291dCBvcHRpb24nKS5sZW5ndGggPT09IDApe1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly9WYWxpZGF0ZSBuZXcgYWRkcmVzc1xyXG5cdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjaGVja291dC52YWxpZGF0ZSgpOyB9LCAxMDApO1xyXG5cclxuXHRcdFx0Ly9WYWxpZGF0ZSBuZXcgcG9zdGFsIGNvZGUgYWdhaW5zdCBzZXJ2aWNlXHJcblx0XHRcdGxldCB2YWx1ZSA9ICQoJyNwb3N0YWxDb2RlQ2hlY2tvdXQnKS52YWwoKTtcclxuXHRcdFx0bGV0IHBvc3RhbENvZGVJbnB1dFdyYXBwZXIgPSAkKCcjcG9zdGFsQ29kZUNoZWNrb3V0JykucGFyZW50KCkucGFyZW50KCk7XHJcblx0XHRcdGxldCBjb3VudHJ5Q29kZSA9ICQoJyNjb3VudHJ5Q29kZUNoZWNrb3V0IG9wdGlvbjpzZWxlY3RlZCcpLnZhbCgpO1xyXG5cdFx0XHRDaGVja291dFNoaXBwaW5nLmhhbmRsZVNoaXBwaW5nQWRkcmVzc1Bvc3RhbENvZGUocG9zdGFsQ29kZUlucHV0V3JhcHBlciwgdmFsdWUsIGNvdW50cnlDb2RlKTtcclxuXHJcblx0XHR9KTtcclxuXHRcdENoZWNrb3V0QmlsbGluZ1N0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRsZXQgaHRtbCA9IENoZWNrb3V0QmlsbGluZ1N0b3JlLmdldFN0b3JlKCk7XHJcblx0XHRcdCQoJy5iaWxsaW5nLWFkZHJlc3Nlcy1jb250YWluZXInKS5odG1sKGh0bWwpO1xyXG5cdFx0fSk7XHJcblx0XHRDaGVja291dEFkZHJlc3Nlc0FsZXJ0U3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBodG1sID0gQ2hlY2tvdXRBZGRyZXNzZXNBbGVydFN0b3JlLmdldFN0b3JlKCk7XHJcblx0XHRcdCQoJy51Yy1jaGVja291dC1zaGlwcGluZyAuZGVsaXZlcnktYWRkcmVzc2VzLWFsZXJ0JykuaHRtbChodG1sKTtcclxuXHRcdH0pO1xyXG5cdFx0Q2hlY2tvdXRTaGlwcGluZ1N0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRsZXQgaHRtbCA9IENoZWNrb3V0U2hpcHBpbmdTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHQkKCcudWMtY2hlY2tvdXQtc2hpcHBpbmcgLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMnKS5odG1sKGh0bWwpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9TVU1NQVJZXHJcblx0XHRDaGVja291dFN1bW1hcnlTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0bGV0IGh0bWwgPSBDaGVja291dFN1bW1hcnlTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHQkKCcudWMtY2hlY2tvdXQtc3VtbWFyeSAudGFibGUtd3JhcHBlcicpLmh0bWwoaHRtbCk7XHJcblx0XHRcdGNoZWNrb3V0LnNldFNoaXBwaW5nQWRkcmVzc0ZvclN1bW1hcnkoKTtcclxuXHRcdFx0aWYoISQoJy5zaW11bGF0aW9uLWNhbGN1bGF0aW9uJykuaGFzQ2xhc3MoJ2xvYWRpbmcnKSl7XHJcblx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHsgY2hlY2tvdXQuc2ltdWxhdGVPcmRlcigpOyB9LCAxMDApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9UUkFDS0lORyBEQVRBXHJcblx0XHRDaGVja291dFRyYWNraW5nRGF0YVN0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRsZXQgaHRtbCA9IENoZWNrb3V0VHJhY2tpbmdEYXRhU3RvcmUuZ2V0U3RvcmUoKTtcclxuXHRcdFx0JCgnLnRyYWNraW5nLWRhdGEtd3JhcHBlcicpLmh0bWwoaHRtbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL0NBUlQgTE9BRElORyBTVEFURVxyXG5cdFx0Q2hlY2tvdXRMb2FkaW5nU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGxldCBpc0xvYWRpbmcgPSBDaGVja291dExvYWRpbmdTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHRpZihpc0xvYWRpbmcpe1xyXG5cdFx0XHRcdCQoJy5keW5hbWljLWNvbnRlbnQnKS5hZGRDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyAkKCcuZHluYW1pYy1jb250ZW50JykucmVtb3ZlQ2xhc3MoJ2lzLWxvYWRpbmcnKTsgfSwgMTAwKTtcclxuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjaGVja291dC52YWxpZGF0ZSgpOyB9LCAyNTUpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cdHNpbXVsYXRlT3JkZXIoKXtcclxuXHJcblx0XHQkKCcuc2ltdWxhdGlvbi1jYWxjdWxhdGlvbicpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblxyXG5cdFx0bGV0IHRva2VuID0gJCgnaW5wdXRbbmFtZT1cIl9fUmVxdWVzdFZlcmlmaWNhdGlvblRva2VuXCJdJywgJCgnI2NoZWNrb3V0Zm9ybScpKS52YWwoKTtcclxuXHJcblx0XHQvLyBpZiBub3QgYmlnIGN1c3RvbWVyXHJcblx0XHR2YXIgY291bnRyeUNvZGUgPSAkKCdzZWxlY3RbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Db3VudHJ5Q29kZVwiXSBvcHRpb246c2VsZWN0ZWQnKS52YWwoKTtcclxuXHRcdHZhciByZWdpb24gPSAkKCdzZWxlY3RbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0gb3B0aW9uOnNlbGVjdGVkJykudmFsKCk7XHJcblxyXG5cdFx0Ly8gaWYgYmlnIGN1c3RvbWVyXHJcblx0XHRpZihjb3VudHJ5Q29kZSA9PSBudWxsKXtcclxuXHRcdFx0Y291bnRyeUNvZGUgPSAkKCcjY291bnRyeUNvZGVDaGVja291dCcpLnZhbCgpO1xyXG5cdFx0fVxyXG5cdFx0aWYocmVnaW9uID09IG51bGwpe1xyXG5cdFx0XHRyZWdpb24gPSAkKCcjcmVnaW9uQ29kZUNoZWNrb3V0JykudmFsKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IFNoaXBwaW5nQWRkcmVzcyA9IHtcclxuXHRcdFx0Q291bnRyeUNvZGU6IGNvdW50cnlDb2RlLFxyXG5cdFx0XHRSZWdpb246IHJlZ2lvbixcclxuXHRcdFx0UG9zdGFsQ29kZTogJCgnaW5wdXRbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Qb3N0YWxDb2RlXCJdJykudmFsKCksXHJcblx0XHRcdENpdHk6ICQoJ2lucHV0W25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuQ2l0eVwiXScpLnZhbCgpXHJcblx0XHR9O1xyXG5cclxuXHRcdGxldCBTaGlwcGluZ0Nvc3RzID0gW107XHJcblx0XHQkKCdbZGF0YS1wbGFudF0nKS5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcclxuXHRcdFx0bGV0IHBsYW50ID0gJCh0aGlzKS5kYXRhKCdwbGFudCcpO1xyXG5cdFx0XHRsZXQgcHJpY2UgPSAkKHRoaXMpLmNoaWxkcmVuKCkuZmluZCgnLnNoaXAtdHlwZS5hY3RpdmUnKS5kYXRhKCdzaGlwcGluZy1jb3N0Jyk7XHJcblxyXG5cdFx0XHRsZXQgU2hpcHBpbmdDb3N0ID0ge1xyXG5cdFx0XHRcdEtleTogcGxhbnQsXHJcblx0XHRcdFx0VmFsdWU6IHByaWNlXHJcblx0XHRcdH07XHJcblx0XHRcdFNoaXBwaW5nQ29zdHMucHVzaChTaGlwcGluZ0Nvc3QpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IERlbGl2ZXJ5UHJpb3JpdGllcyA9IFtdO1xyXG5cdFx0bGV0ICRkaXJlY3REZWxpdmVyeSA9ICQoJyNkaXJlY3REZWxpdmVyeScpO1xyXG5cdFx0aWYoICRkaXJlY3REZWxpdmVyeS5sZW5ndGggPiAwKXtcclxuXHRcdFx0bGV0IHBsYW50ID0gXCJcIjtcclxuXHRcdFx0bGV0IHByaWNlID0gJGRpcmVjdERlbGl2ZXJ5LmRhdGEoJ3NoaXBwaW5nLWNvc3QnKTtcclxuXHRcdFx0bGV0IFNoaXBwaW5nQ29zdCA9IHtcclxuXHRcdFx0XHRLZXk6IHBsYW50LFxyXG5cdFx0XHRcdFZhbHVlOiBwcmljZVxyXG5cdFx0XHR9O1xyXG5cdFx0XHRTaGlwcGluZ0Nvc3RzLnB1c2goU2hpcHBpbmdDb3N0KTtcclxuXHJcblx0XHRcdGxldCBkZWxpdmVyeVByaW9yaXR5ID0ge1xyXG5cdFx0XHRcdEtleTogJGRpcmVjdERlbGl2ZXJ5LmRhdGEoJ3BsYW50LWNvZGUnKSxcclxuXHRcdFx0XHRWYWx1ZTogJGRpcmVjdERlbGl2ZXJ5LmRhdGEoJ3ByaW9yaXR5JylcclxuXHRcdFx0fTtcclxuXHRcdFx0RGVsaXZlcnlQcmlvcml0aWVzLnB1c2goZGVsaXZlcnlQcmlvcml0eSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0ICRzaGlwcGluZ1R5cGUgPSAkKCcuc2hpcHBpbmctdHlwZScpO1xyXG5cdFx0aWYoJHNoaXBwaW5nVHlwZS5sZW5ndGgpe1xyXG5cdFx0XHQkKCcuc2hpcHBpbmctdHlwZScpLmVhY2goZnVuY3Rpb24oIGluZGV4ICkge1xyXG5cdFx0XHRcdGxldCAkc2VsZWN0ZWQgPSAkKHRoaXMpLmZpbmQoJ3NlbGVjdCBvcHRpb246c2VsZWN0ZWQnKTtcclxuXHJcblx0XHRcdFx0bGV0IHByaW9yaXR5UGxhbnQgPSAkKHRoaXMpLnBhcmVudCgpLnBhcmVudCgpLmRhdGEoJ3BsYW50Jyk7XHJcblx0XHRcdFx0bGV0IHByaW9yaXR5SWQgPSAkc2VsZWN0ZWQuZGF0YSgncHJpb3JpdHknKTtcclxuXHJcblx0XHRcdFx0bGV0IGRlbGl2ZXJ5UHJpb3JpdHkgPSB7XHJcblx0XHRcdFx0XHRLZXk6IHByaW9yaXR5UGxhbnQsXHJcblx0XHRcdFx0XHRWYWx1ZTogcHJpb3JpdHlJZFxyXG5cdFx0XHRcdH07XHJcblx0XHRcdFx0RGVsaXZlcnlQcmlvcml0aWVzLnB1c2goZGVsaXZlcnlQcmlvcml0eSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBkYXRhID0ge1xyXG5cdFx0XHRfX1JlcXVlc3RWZXJpZmljYXRpb25Ub2tlbjogdG9rZW4sXHJcblx0XHRcdFNoaXBwaW5nQWRkcmVzc2VzOiB7XHJcblx0XHRcdFx0U2hpcHBpbmdBZGRyZXNzXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0IFNoaXBwaW5nQ29zdHMsXHJcblx0XHRcdCBEZWxpdmVyeVByaW9yaXRpZXNcclxuXHRcdH07XHJcblxyXG5cdFx0Q2hlY2tvdXRBY3Rpb25zLnNpbXVsYXRlT3JkZXIoZGF0YSk7XHJcblx0fSxcclxuXHRjaGVja291dENoYW5nZXMoKSB7XHJcblxyXG5cdFx0Ly9FcnJvciBsaXN0IHRvZ2dsZVxyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICcudWMtbWVzc2FnZS5lcnJvci5jb2xsYXBzZWQnLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHR2YXIgZWwgPSAkKHRoaXMpO1xyXG5cdFx0XHRlbC5oYXNDbGFzcyhcImluXCIpID8gZWwucmVtb3ZlQ2xhc3MoXCJpblwiKSA6IGVsLmFkZENsYXNzKFwiaW5cIik7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL0NhcnQgY2hhbmdlc1xyXG5cdFx0Ly9Db21tZW50c1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsICcudWMtY2hlY2tvdXQtY2FydCAuY29tbWVudCcsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdENoZWNrb3V0Q2FydExpbmVJdGVtQ29tbWVudC50b2dnbGVDb21tZW50Um93KGUsIHRoaXMpO1xyXG5cdFx0fSk7XHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJy51Yy1jaGVja291dC1jYXJ0IC5jbGVhci1jb21tZW50JywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0Q2hlY2tvdXRDYXJ0TGluZUl0ZW1Db21tZW50LnJlbW92ZUNvbW1lbnQoZSwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnLnVjLWNoZWNrb3V0LWNhcnQgLmFkZC1jb21tZW50JywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0Q2hlY2tvdXRDYXJ0TGluZUl0ZW1Db21tZW50LmFkZENvbW1lbnQoZSwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHRcdC8vUXVhbnRpdHksIGRlbGV0ZSBhbmQgdXBncmFkZVxyXG5cdFx0JCgnYm9keScpLm9uKCdmb2N1cyBibHVyIGtleXByZXNzJywgJy51Yy1jaGVja291dC1jYXJ0IFtuYW1lPVwicXVhbnRpdHlcIl0nLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHRDaGVja291dENhcnRMaW5lSXRlbVVwZGF0ZS5oYW5kbGVDaGFuZ2UoZSwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnLnVjLWNoZWNrb3V0LWNhcnQgLnJlbW92ZS1idXR0b24nLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHRDaGVja291dENhcnRMaW5lSXRlbURlbGV0ZS5oYW5kbGVEZWxldGUoZSwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnLnVjLWNoZWNrb3V0LWNhcnQgLmNoZWNrYm94LWl0ZW0gaW5wdXRbdHlwZT1jaGVja2JveF0nLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRDaGVja291dENhcnRMaW5lSXRlbVVwZGF0ZS5oYW5kbGVDaGFuZ2UoZSwgdGhpcyk7XHJcblx0XHRcdC8vc2VuZCB0byBhY3Rpb25cclxuXHRcdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLmNoZWNrYm94LWl0ZW0gaW5wdXRbdHlwZT1jaGVja2JveF0nKS5vZmYoJ2NoYW5nZScpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9TaGlwcGluZyBjaGFuZ2VzXHJcblx0XHQkKCcjc2F2ZWQtc2hpcHBpbmctaW5mby1zZWxlY3QnKS5kcm9wZG93bih7XHJcblx0XHRcdGZ1bGxUZXh0U2VhcmNoOiAnZXhhY3QnLFxyXG5cdFx0XHRtYXRjaDogJ3RleHQnLFxyXG5cdFx0XHRmb3JjZVNlbGVjdGlvbjogZmFsc2UsXHJcblx0XHRcdG1lc3NhZ2U6IHtcclxuXHRcdFx0XHRub1Jlc3VsdHM6IGNoZWNrb3V0TGFuZy5ub0FkZHJlc3Nlc0ZvdW5kXHJcblx0XHRcdH0sXHJcblx0XHRcdG9uQ2hhbmdlKHZhbHVlLCB0ZXh0LCAkY2hvaWNlKXtcclxuXHRcdFx0XHRDaGVja291dFNoaXBwaW5nLmhhbmRsZVNoaXBwaW5nQWRkcmVzc0NoYW5nZSh2YWx1ZSk7XHJcblx0XHRcdH1cclxuXHRcdCB9KTtcclxuXHJcblx0XHRpZiggJCgnI3NhdmVkLWJpbGxpbmctaW5mby1zZWxlY3QnKS5sZW5ndGggPiAwICl7XHJcblx0XHRcdCQoJyNzYXZlZC1iaWxsaW5nLWluZm8tc2VsZWN0JykuZHJvcGRvd24oe1xyXG5cdFx0XHRcdGZ1bGxUZXh0U2VhcmNoOiAnZXhhY3QnLFxyXG5cdFx0XHRcdG1hdGNoOiAndGV4dCcsXHJcblx0XHRcdFx0Zm9yY2VTZWxlY3Rpb246IGZhbHNlLFxyXG5cdFx0XHRcdG1lc3NhZ2U6IHtcclxuXHRcdFx0XHRcdG5vUmVzdWx0czogY2hlY2tvdXRMYW5nLm5vQWRkcmVzc2VzRm91bmRcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdG9uQ2hhbmdlKHZhbHVlLCB0ZXh0LCAkY2hvaWNlKXtcclxuXHRcdFx0XHRcdENoZWNrb3V0U2hpcHBpbmcuaGFuZGxlQmlsbGluZ0FkZHJlc3NDaGFuZ2UodmFsdWUpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0IH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qQ2hhbmdlIGNvdW50cnkgJnwgcmVnaW9uKi9cclxuXHRcdCQoJ2JvZHknKS5vbignY2hhbmdlJywgJy5jaGVja291dC1hZGRyZXNzLWluZm8gc2VsZWN0JywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0dmFyIHNoaXBwaW5nQWRkcmVzcyA9IHt9O1xyXG5cdFx0XHQkKCcuY2hlY2tvdXQtYWRkcmVzcy1pbmZvIC5pbnB1dC13cmFwcGVyIGlucHV0JykuZWFjaChmdW5jdGlvbigpIHtcclxuXHRcdFx0ICAgIHNoaXBwaW5nQWRkcmVzc1skKHRoaXMpLmF0dHIoJ25hbWUnKV0gPSAkKHRoaXMpLnZhbCgpO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdC8vIGlmIG5vdCBiaWcgY3VzdG9tZXJcclxuXHRcdFx0dmFyIGNvdW50cnlDb2RlID0gJCgnI2NvdW50cnlDb2RlQ2hlY2tvdXQnKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS52YWwoKTtcclxuXHRcdFx0dmFyIHJlZ2lvbiA9ICQoJyNyZWdpb25Db2RlQ2hlY2tvdXQnKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS52YWwoKTtcclxuXHJcblx0XHRcdC8vIGlmIGJpZyBjdXN0b21lclxyXG5cdFx0XHRpZihjb3VudHJ5Q29kZSA9PSBudWxsKXtcclxuXHRcdFx0XHRjb3VudHJ5Q29kZSA9ICQoJyNjb3VudHJ5Q29kZUNoZWNrb3V0JykudmFsKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYocmVnaW9uID09IG51bGwpe1xyXG5cdFx0XHRcdHJlZ2lvbiA9ICQoJyNyZWdpb25Db2RlQ2hlY2tvdXQnKS52YWwoKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0c2hpcHBpbmdBZGRyZXNzWydTaGlwcGluZ0FkZHJlc3MuQ291bnRyeUNvZGUnXSA9IGNvdW50cnlDb2RlO1xyXG5cdFx0XHRzaGlwcGluZ0FkZHJlc3NbJ1NoaXBwaW5nQWRkcmVzcy5SZWdpb24nXSA9IHJlZ2lvbjtcclxuXHRcdFx0c2hpcHBpbmdBZGRyZXNzWydVcGRhdGVBZGRyZXNzJ10gPSAkKCcjVXBkYXRlQWRkcmVzcycpLmlzKCc6Y2hlY2tlZCcpO1xyXG5cdFx0XHRDaGVja291dFNoaXBwaW5nLmhhbmRsZUNvdW50cnlDb2RlQ2hhbmdlKHNoaXBwaW5nQWRkcmVzcyk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKCdib2R5Jykub24oJ2JsdXInLCAnLmNoZWNrb3V0LWFkZHJlc3MtaW5mbyBpbnB1dCcsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGlmKCBlLnRhcmdldC5pZCA9PT0gJ3Bvc3RhbENvZGVDaGVja291dCcgKXtcclxuXHRcdFx0XHRsZXQgcG9zdGFsQ29kZUlucHV0V3JhcHBlciA9ICQoJyNwb3N0YWxDb2RlQ2hlY2tvdXQnKS5wYXJlbnQoKS5wYXJlbnQoKTtcclxuXHJcblx0XHRcdFx0aWYodGhpcy52YWx1ZSAhPT0gdGhpcy5kZWZhdWx0VmFsdWUpe1xyXG5cdFx0XHRcdFx0dGhpcy5kZWZhdWx0VmFsdWUgPSB0aGlzLnZhbHVlO1xyXG5cdFx0XHRcdFx0bGV0IHZhbHVlID0gdGhpcy52YWx1ZTtcclxuXHRcdFx0XHRcdGxldCBjb3VudHJ5Q29kZSA9ICQoJy5jaGVja291dC1hZGRyZXNzLWluZm8gc2VsZWN0IG9wdGlvbjpzZWxlY3RlZCcpLnZhbCgpO1xyXG5cdFx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHsgQ2hlY2tvdXRTaGlwcGluZy5oYW5kbGVTaGlwcGluZ0FkZHJlc3NQb3N0YWxDb2RlKHBvc3RhbENvZGVJbnB1dFdyYXBwZXIsIHZhbHVlLCBjb3VudHJ5Q29kZSk7IH0sIDI1NSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjaGVja291dC52YWxpZGF0ZSgpOyB9LCAyNTUpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQvKlNlbGVjdCBzaGlwcGluZyBwcmlvcmlyeSAqL1xyXG5cdFx0JCgnYm9keScpLm9uKCdjaGFuZ2UnLCAnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMgc2VsZWN0JywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0bGV0IHByaW9yaXR5ID0gJCh0aGlzKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS5kYXRhKCdwcmlvcml0eScpO1xyXG5cdFx0XHRsZXQgcGxhbnRWYWwgPSAkKGUudGFyZ2V0LnBhcmVudEVsZW1lbnQpLnBhcmVudCgpLnBhcmVudCgpLmRhdGEoJ3BsYW50Jyk7XHJcblx0XHRcdENoZWNrb3V0U2hpcHBpbmcuaGFuZGxlT3B0aW9uT3JQcmlvcml0eUNoYW5nZShlLCB0aGlzLnZhbHVlLCBwcmlvcml0eSwgJycsIHBsYW50VmFsKTtcclxuXHJcblx0XHRcdCQoJy51Yy1jaGVja291dC1zaGlwcGluZy1vcHRpb25zIHNlbGVjdCcpLm9mZignY2hhbmdlJyk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvKlNlbGVjdCBzaGlwcGluZyB0eXBlKi9cclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMgLnNoaXAtdHlwZTpub3QoLmFjdGl2ZSkgaW5wdXQuc2hpcG9wdGlvblt0eXBlPXJhZGlvXScsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcblx0XHRcdGxldCBwbGFudFZhbCA9ICQoZS50YXJnZXQucGFyZW50RWxlbWVudCkucGFyZW50KCkucGFyZW50KCkucGFyZW50KCkucGFyZW50KCkucGFyZW50KCkuZGF0YSgncGxhbnQnKTtcclxuXHRcdFx0Q2hlY2tvdXRTaGlwcGluZy5oYW5kbGVPcHRpb25PclByaW9yaXR5Q2hhbmdlKGUsJycsJycsIHRoaXMudmFsdWUsIHBsYW50VmFsKTtcclxuXHRcdFx0JCgnY2xpY2snLCAnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMgLnNoaXAtdHlwZTpub3QoLmFjdGl2ZSkgaW5wdXQuc2hpcG9wdGlvblt0eXBlPXJhZGlvXScpLm9mZignY2hhbmdlJyk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJy51Yy1jaGVja291dC1zaGlwcGluZy5wYXltZW50LW9wdGlvbnMgLnBheW1lbnQtdHlwZTpub3QoLmRpc2FibGVkKTpub3QoLmFjdGl2ZSkgbGFiZWwucGF5bWVudC1vcHRpb24nLCBmdW5jdGlvbiAoZSkge1xyXG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHQkKCcucGF5bWVudC10eXBlJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHQkKHRoaXMpLnBhcmVudCgpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHJcblx0XHRcdHZhciBhY3RpdmVQYXltZW50ID0gJCh0aGlzKS5maW5kKCdpbnB1dCcpLnZhbCgpO1xyXG5cdFx0XHRjaGVja291dC5zd2l0Y2hCdG5UZXh0KGFjdGl2ZVBheW1lbnQpO1xyXG5cclxuXHRcdFx0JCgnY2xpY2snLCAnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLnBheW1lbnQtb3B0aW9ucyAucGF5bWVudC10eXBlOm5vdCguZGlzYWJsZWQpOm5vdCguYWN0aXZlKSBsYWJlbC5wYXltZW50LW9wdGlvbicpLm9mZignY2hhbmdlJyk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cdHN3aXRjaEJ0blRleHQodmFsdWUpIHtcclxuXHRcdGxldCBidG5UZXh0ID0gaGlhYmNvbmZpZy5jaGVja291dC5sYW5nW3ZhbHVlXTtcclxuXHRcdCQoJyNjb21wbGV0ZS1wdXJjaGFzZS1idXR0b24nKS50ZXh0KGJ0blRleHQpO1xyXG5cdH0sXHJcblx0Y2hlY2tvdXRGdW5jdGlvbmFsaXR5KCkge1xyXG5cclxuXHRcdHZhciBhY3RpdmVQYXltZW50ID0gJCgnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLnBheW1lbnQtb3B0aW9ucyAucGF5bWVudC10eXBlLmFjdGl2ZSBsYWJlbC5wYXltZW50LW9wdGlvbiBpbnB1dCcpLnZhbCgpO1xyXG5cdFx0Y2hlY2tvdXQuc3dpdGNoQnRuVGV4dChhY3RpdmVQYXltZW50KTtcclxuXHJcblx0XHQvKkRhbmdlcm91cyBnb29kcyovXHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJy51Yy1jaGVja291dC1jYXJ0IC5kYW5nZXJvdXMtZ29vZHMgaScsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdCQodGhpcykubmV4dCgpLnRvZ2dsZSgpO1xyXG5cdFx0XHQkKCcudWMtY2hlY2tvdXQtY2FydCAuZGFuZ2Vyb3VzLWdvb2RzIGknKS5vZmYoJ2NsaWNrJyk7XHJcblx0XHR9KTtcclxuXHRcdCQoJ2JvZHknKS5vbignY2xpY2snLCAnLnVjLWNoZWNrb3V0LWNhcnQgLmRhbmdlcm91cy1nb29kcyBzcGFuJywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0JCh0aGlzKS5oaWRlKCk7XHJcblx0XHRcdCQoJy51Yy1jaGVja291dC1jYXJ0IC5kYW5nZXJvdXMtZ29vZHMgc3BhbicpLm9mZignY2xpY2snKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8qSWYgc2hpcCB0eXBlIGlzIG9ubHkgb25lIGl0cyBzaG91bGQgaGF2ZSByZWd1bGFyIGN1cnNvciovXHJcblx0XHQkKCcudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucyAuc2hpcC10eXBlIC5zaGlwLW9wdGlvbnMnKS5lYWNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0aWYodGhpcy5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID09PSAxKXtcclxuXHRcdFx0XHR0aGlzLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5jaGlsZHJlblswXS5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8qQ29tcGxldGUgcHVyY2hhc2UtZm9vdGVyKi9cclxuXHRcdC8qKkhhbmRsZSBhcHByb3YgY2hlY2tib3ggY2xpY2sqL1xyXG5cdFx0JCgnYm9keScpLm9uKCdjbGljaycsJyNjaGVja291dC10ZXJtcy1jb25kaXRpb24nLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNoZWNrb3V0LnZhbGlkYXRlKCk7IH0sIDI1NSk7XHJcblx0XHRcdCQoJyNjaGVja291dC10ZXJtcy1jb25kaXRpb24nKS5vZmYoJ2NsaWNrJyk7XHJcblx0XHR9KTtcclxuXHRcdC8qKlByZXZlbnQgcG9zdCB3aGVuIHByZXNzaW5nIGVudGVyKi9cclxuXHRcdCQoJ2JvZHknKS5vbigna2V5cHJlc3MnLCAnI2NoZWNrb3V0Zm9ybSBpbnB1dCcsJyNjaGVja291dGZvcm0nLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlID09IDEzKXtcclxuICAgICAgICBcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcblx0XHQvL2FkZCBsb2FkaW5nIGNsYXNzIHRvIGNvbXBsZXRlIHB1cmNoYXNlXHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywnI2NvbXBsZXRlLXB1cmNoYXNlLWJ1dHRvbjpub3QoW2Rpc2FibGVkXSknLCBmdW5jdGlvbihlKSB7XHJcblx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHsgY2hlY2tvdXQudmFsaWRhdGUoKTsgfSwgMjU1KTtcclxuICAgIH0pO1xyXG5cdFx0Ly9hZGQgY2hhbmdlZCBhZGRyZXNzIHRvIHN1bW1hcnlcclxuXHRcdCQoJ2JvZHknKS5vbignYmx1cicsJy5pbnB1dC13cmFwcGVyIGlucHV0JywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjaGVja291dC52YWxpZGF0ZSgpOyB9LCAyNTUpO1xyXG5cdFx0XHRjaGVja291dC5zZXRTaGlwcGluZ0FkZHJlc3NGb3JTdW1tYXJ5KCk7XHJcbiAgICB9KTtcclxuXHRcdCQoJ2JvZHknKS5vbignY2hhbmdlJywnLmlucHV0LXdyYXBwZXIgW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjaGVja291dC52YWxpZGF0ZSgpOyB9LCAyNTUpO1xyXG5cdFx0XHRjaGVja291dC5zZXRTaGlwcGluZ0FkZHJlc3NGb3JTdW1tYXJ5KCk7XHJcbiAgICB9KTtcclxuXHJcblx0fSxcclxuXHRzZXRTaGlwcGluZ0FkZHJlc3NGb3JTdW1tYXJ5KCkge1xyXG5cclxuXHRcdGxldCByZWdpb25BZGRyZXNzID0gXCJcIjtcclxuXHRcdGxldCBjb3VudHJ5QWRkcmVzcyA9IFwiXCI7XHJcblx0XHRsZXQgc3RyZWV0bGluZTIgPSBcIlwiO1xyXG5cdFx0aWYoYWx0ZXJuYXRpdmVMYXlvdXQpe1xyXG5cdFx0XHRpZiggJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykubGVuZ3RoID4gMCAmJiAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0nKS52YWwoKSl7XHJcblx0XHRcdFx0cmVnaW9uQWRkcmVzcyA9ICc8c3BhbiBjbGFzcz1cImxpbmVcIj4nXHJcblx0XHRcdFx0XHQrICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLlJlZ2lvblwiXScpLmZpbmQoJ29wdGlvbjpzZWxlY3RlZCcpLnRleHQoKVxyXG5cdFx0XHRcdFx0KycsICdcclxuXHRcdFx0XHRcdCskKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5DaXR5XCJdJykudmFsKClcclxuXHRcdFx0XHRcdCsgJzwvc3Bhbj4nO1xyXG5cclxuXHRcdFx0XHRcdGlmKHR5cGVvZiAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0nKS52YWwoKSA9PT0gJ3VuZGVmaW5lZCcpe1xyXG5cdFx0XHRcdFx0XHRyZWdpb25BZGRyZXNzID0gJzxzcGFuIGNsYXNzPVwibGluZVwiPidcclxuXHRcdFx0XHRcdFx0KyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0nKS52YWwoKVxyXG5cdFx0XHRcdFx0XHQrJywgJ1xyXG5cdFx0XHRcdFx0XHQrJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuQ2l0eVwiXScpLnZhbCgpXHJcblx0XHRcdFx0XHRcdCsgJzwvc3Bhbj4nO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHR9ZWxzZXtcclxuXHJcblx0XHRcdFx0aWYoJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpID09PSBcIlwiKXtcclxuXHRcdFx0XHRcdHJlZ2lvbkFkZHJlc3MgPSAnPHNwYW4gY2xhc3M9XCJsaW5lXCI+JyArICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLlJlZ2lvblwiXScpLnZhbCgpOyArICc8L3NwYW4+JztcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYodHlwZW9mICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLlJlZ2lvblwiXScpLnZhbCgpID09PSAndW5kZWZpbmVkJyl7XHJcblx0XHRcdFx0XHRyZWdpb25BZGRyZXNzID0gXCJcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblxyXG5cclxuXHRcdH1lbHNle1xyXG5cdFx0XHRpZiggJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykubGVuZ3RoID4gMCAmJiAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0nKS52YWwoKSl7XHJcblx0XHRcdFx0cmVnaW9uQWRkcmVzcyA9ICc8c3BhbiBjbGFzcz1cImxpbmVcIj4nICsgJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpICsgJzwvc3Bhbj4nO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZigkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5SZWdpb25cIl0nKS5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS50ZXh0KCkgPT09IFwiXCIpe1xyXG4gICAgICAgICAgICAgICAgcmVnaW9uQWRkcmVzcyA9ICc8c3BhbiBjbGFzcz1cImxpbmVcIj4nICsgJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykudmFsKCk7ICsgJzwvc3Bhbj4nO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZih0eXBlb2YgJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCJdJykudmFsKCkgPT09ICd1bmRlZmluZWQnKXtcclxuICAgICAgICAgICAgICAgIHJlZ2lvbkFkZHJlc3MgPSBcIlwiO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkNvdW50cnlDb2RlXCJdJykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudmFsKCkgKXtcclxuXHRcdFx0Y291bnRyeUFkZHJlc3MgPSAnPHNwYW4gY2xhc3M9XCJsaW5lXCI+JyArICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkNvdW50cnlDb2RlXCJdJykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpICsgJzwvc3Bhbj4nO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKCQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkNvdW50cnlDb2RlXCJdJykuZmluZCgnb3B0aW9uOnNlbGVjdGVkJykudGV4dCgpID09PSBcIlwiKXtcclxuXHRcdFx0Y291bnRyeUFkZHJlc3MgPSAnPHNwYW4gY2xhc3M9XCJsaW5lXCI+JyArICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkNvdW50cnlDb2RlXCJdJykudmFsKCk7ICsgJzwvc3Bhbj4nO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKHR5cGVvZiAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5MaW5lMlwiXScpLnZhbCgpID09PSAndW5kZWZpbmVkJyl7XHJcblx0XHRcdHN0cmVldGxpbmUyID0gXCJcIjtcclxuXHRcdH1lbHNle1xyXG5cdFx0XHRzdHJlZXRsaW5lMiA9ICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkxpbmUyXCJdJykudmFsKClcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgc2hpcHBpbmdBZGRyZXNzID0gJyc7XHJcblxyXG5cdFx0aWYoYWx0ZXJuYXRpdmVMYXlvdXQpe1xyXG5cdFx0XHRzaGlwcGluZ0FkZHJlc3MgPSBcdFx0Y291bnRyeUFkZHJlc3MgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JzxzcGFuIGNsYXNzPVwibGluZVwiPicgKyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Qb3N0YWxDb2RlXCJdJykudmFsKCkgKyAnPC9zcGFuPicgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVnaW9uQWRkcmVzcyArXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnPHNwYW4gY2xhc3M9XCJsaW5lXCI+JyArICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkxpbmUxXCJdJykudmFsKCkgKyAnPC9zcGFuPicgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c3RyZWV0bGluZTIgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JzxzcGFuIGNsYXNzPVwibGluZVwiPicgKyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Db21wYW55TmFtZVwiXScpLnZhbCgpICsgJzwvc3Bhbj4nICtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCc8c3BhbiBjbGFzcz1cImxpbmVcIj4nICsgJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuRmlyc3ROYW1lXCJdJykudmFsKCkgKyAnPC9zcGFuPicgO1xyXG5cclxuXHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0c2hpcHBpbmdBZGRyZXNzID0gJzxzcGFuIGNsYXNzPVwibGluZVwiPicgKyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Db21wYW55TmFtZVwiXScpLnZhbCgpICsgJzwvc3Bhbj4nICtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCc8c3BhbiBjbGFzcz1cImxpbmVcIj4nICsgJCgnW25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuRmlyc3ROYW1lXCJdJykudmFsKCkgKyAnPC9zcGFuPicgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Y291bnRyeUFkZHJlc3MgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVnaW9uQWRkcmVzcyArXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnPHNwYW4gY2xhc3M9XCJsaW5lXCI+JyArICQoJ1tuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLkxpbmUxXCJdJykudmFsKCkgKyAnPC9zcGFuPicgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c3RyZWV0bGluZTIgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JzxzcGFuIGNsYXNzPVwibGluZVwiPicgKyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Qb3N0YWxDb2RlXCJdJykudmFsKCkgKyAnPC9zcGFuPicgK1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0JzxzcGFuIGNsYXNzPVwibGluZVwiPicgKyAkKCdbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5DaXR5XCJdJykudmFsKCkgKyAnPC9zcGFuPic7XHJcblx0XHR9XHJcblxyXG5cdFx0JCgnLmNoZWNrb3V0LXNoaXBwaW5nLWFkZHJlc3MnKS5odG1sKHNoaXBwaW5nQWRkcmVzcyk7XHJcblx0XHQkKCcjY2hlY2tvdXQtc2hpcHBpbmctYWRkcmVzcy1tb2JpbGUnKS5odG1sKHNoaXBwaW5nQWRkcmVzcyk7XHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgY2hlY2tvdXQ7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBcGkgZnJvbSAnLi4vX2FwaS9jaGVja291dF9hcGktbmV3JztcclxuaW1wb3J0IENoZWNrb3V0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zX25ldyc7XHJcbmltcG9ydCBDaGVja291dENhcnRMaW5lSXRlbUxvYWRpbmcgZnJvbSAnLi9jaGVja291dF9jYXJ0X2xpbmVpdGVtX2xvYWRpbmcnO1xyXG5cclxuXHJcbmxldCBDaGVja291dENhcnRMaW5lSXRlbUNvbW1lbnQgPSB7XHJcblxyXG5cdGFkZENvbW1lbnQoZSwgZWxtKSB7XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0bGV0IHNrdUlkICAgICAgID0gJChlbG0pLmF0dHIoJ2RhdGEtc2t1LWlkJyksXHJcblx0XHQgICAgY29tbWVudCAgICAgPSAkKCdbZGF0YS1jb21tZW50LWlucHV0LWlkPVxcJycgKyBza3VJZCArICdcXCddJykudmFsKCk7XHJcblxyXG5cdFx0Ly8gQ2hlY2tvdXRDYXJ0TGluZUl0ZW1Mb2FkaW5nLmhhbmRsZUxvYWRpbmdFdmVudChza3VJZCk7XHJcblx0XHR0aGlzLnNhdmVDb21tZW50KHNrdUlkLCBjb21tZW50KTtcclxuXHR9LFxyXG5cclxuXHRyZW1vdmVDb21tZW50KGUsIGVsbSkge1xyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuXHRcdGxldCBza3VJZCAgICAgID0gJChlbG0pLmF0dHIoJ2RhdGEtc2t1LWlkJyksXHJcblx0XHQgICAgY29tbWVudCAgICA9ICQoJ1tkYXRhLWNvbW1lbnQtaW5wdXQtaWQ9XFwnJyArIHNrdUlkICsgJ1xcJ10nKTtcclxuXHJcblx0XHQvLyBDaGVja291dENhcnRMaW5lSXRlbUxvYWRpbmcuaGFuZGxlTG9hZGluZ0V2ZW50KHNrdUlkKTtcclxuXHRcdGNvbW1lbnQudmFsKCcnKTtcclxuXHJcblx0XHR0aGlzLnNhdmVDb21tZW50KHNrdUlkLCBjb21tZW50LnZhbCgpKTtcclxuXHR9LFxyXG5cclxuXHRzYXZlQ29tbWVudChza3VJZCwgY29tbWVudCkge1xyXG5cdFx0bGV0IHBhcmVudFJvdyAgPSAkKCdbZGF0YS1saW5lLWlkPVxcJycgKyBza3VJZCArICdcXCddJyksXHJcbiAgICAgICAgY29tbWVudFJvdyA9ICQoJ1tkYXRhLWNvbW1lbnQtaWQ9XFwnJyArIHNrdUlkICsgJ1xcJ10nKTtcclxuXHJcblx0XHRDaGVja291dEFwaS51cGRhdGVDYXJ0SXRlbUN1c3RvbWVyQ29tbWVudChza3VJZCwgY29tbWVudClcclxuXHRcdC8vIG5ldyB3YXkgdG8gaGFuZGxlIGl0XHJcblx0XHQudGhlbigocmVzKSA9PiB7XHJcblx0XHRcdGlmKHJlcy5TdWNjZXNzKXtcclxuXHRcdFx0XHRjb21tZW50Um93LnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0cGFyZW50Um93LnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdFx0XHRwYXJlbnRSb3cuYWRkQ2xhc3MoJ2lzLXNhdmVkJyk7XHJcblx0XHRcdFx0aWYoY29tbWVudCAhPT0gXCJcIil7XHJcblx0XHRcdFx0XHRwYXJlbnRSb3cuYWRkQ2xhc3MoJ2hhcy1jb21tZW50Jyk7XHJcblx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRwYXJlbnRSb3cucmVtb3ZlQ2xhc3MoJ2hhcy1jb21tZW50Jyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KVxyXG5cdFx0LmNhdGNoKChyZXMpPT4ge1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMubG9hZENoZWNrb3V0LmZhaWxlZChyZXMpO1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0dG9nZ2xlQ29tbWVudFJvdyhlLCBlbG0pIHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGxldCBza3VJZCAgICAgID0gJChlbG0pLmF0dHIoJ2RhdGEtc2t1LWlkJyksXHJcblx0XHQgICAgcGFyZW50Um93ICA9ICQoJ1tkYXRhLWxpbmUtaWQ9XFwnJyArIHNrdUlkICsgJ1xcJ10nKSxcclxuICAgICAgICBjb21tZW50Um93ID0gJCgnW2RhdGEtY29tbWVudC1pZD1cXCcnICsgc2t1SWQgKyAnXFwnXScpO1xyXG5cclxuXHRcdGlmKGNvbW1lbnRSb3cuaXMoJy5pcy1vcGVuJykpIHtcclxuXHRcdFx0Y29tbWVudFJvdy5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHRwYXJlbnRSb3cucmVtb3ZlQ2xhc3MoJ2lzLWFjdGl2ZScpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdGNvbW1lbnRSb3cuYWRkQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdFx0cGFyZW50Um93LmFkZENsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Q2FydExpbmVJdGVtQ29tbWVudDtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IENoZWNrb3V0Q2FydExpbmVJdGVtTG9hZGluZyBmcm9tICcuL2NoZWNrb3V0X2NhcnRfbGluZWl0ZW1fbG9hZGluZyc7XHJcbmltcG9ydCBDaGVja291dEFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvY2hlY2tvdXRfYWN0aW9uc19uZXcnO1xyXG5cclxubGV0IENoZWNrb3V0Q2FydExpbmVJdGVtRGVsZXRlID0ge1xyXG5cdGhhbmRsZURlbGV0ZShlLCBlbG0pIHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGxldCBza3VJZCAgID0gJChlbG0pLmF0dHIoJ2RhdGEtc2t1LWlkJyk7XHJcblx0XHQvLyBDaGVja291dENhcnRMaW5lSXRlbUxvYWRpbmcuaGFuZGxlTG9hZGluZ0V2ZW50KHNrdUlkKTtcclxuXHRcdENoZWNrb3V0QWN0aW9ucy5kZWxldGVDaGVja291dENhcnRJdGVtKHNrdUlkKTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Q2FydExpbmVJdGVtRGVsZXRlO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5cclxubGV0IENoZWNrb3V0Q2FydExpbmVJdGVtTG9hZGluZyA9IHtcclxuXHRoYW5kbGVMb2FkaW5nRXZlbnQoc2t1SWQpIHtcclxuXHRcdGxldCBsaW5lSXRlbVJvdyA9ICQoJ1tkYXRhLWxpbmUtaWQ9XFwnJyArIHNrdUlkICsgJ1xcJ10nKSxcclxuXHRcdCAgICBjb21tZW50Um93ICA9ICQoJ1tkYXRhLWNvbW1lbnQtaWQ9XFwnJyArIHNrdUlkICsgJ1xcJ10nKTtcclxuXHJcblx0XHRsaW5lSXRlbVJvdy5hZGRDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cdFx0Y29tbWVudFJvdy5hZGRDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cdFx0JCgnLnVjLWNoZWNrb3V0LXNoaXBwaW5nLW9wdGlvbnMsICAudWMtY2hlY2tvdXQtc3VtbWFyeScpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblxyXG5cclxuXHRcdC8vUmVtb3ZlIGV2ZW50IGZyb20gYnV0dG9uc1xyXG5cdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgW25hbWU9XCJxdWFudGl0eVwiXScpLm9mZigpO1xyXG5cdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLnJlbW92ZS1idXR0b24nKS5vZmYoKTtcclxuXHRcdCQoJy51Yy1jaGVja291dC1jYXJ0IC5jb21tZW50Jykub2ZmKCk7XHJcblx0XHQkKCcudWMtY2hlY2tvdXQtY2FydCAuY2xlYXItY29tbWVudCcpLm9mZigpO1xyXG5cdFx0JCgnLnVjLWNoZWNrb3V0LWNhcnQgLmFkZC1jb21tZW50Jykub2ZmKCk7XHJcblxyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRDYXJ0TGluZUl0ZW1Mb2FkaW5nO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgQ2hlY2tvdXRTdG9yZSBmcm9tICcuLi9fc3RvcmVzL2NoZWNrb3V0X3N0b3JlJztcclxuaW1wb3J0IENoZWNrb3V0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zX25ldyc7XHJcbmltcG9ydCBDaGVja291dENhcnRMaW5lSXRlbUxvYWRpbmcgZnJvbSAnLi9jaGVja291dF9jYXJ0X2xpbmVpdGVtX2xvYWRpbmcnO1xyXG5cclxubGV0IENoZWNrb3V0Q2FydExpbmVJdGVtVXBkYXRlID0ge1xyXG5cdGN1cnJlbnRWYWwgOiBudWxsLFxyXG5cdGlzSW50KHZhbHVlKSB7XHJcbiAgXHR2YXIgeDtcclxuXHRcdHZhciBpc0ludCA9IGlzTmFOKHZhbHVlKSA/ICExIDogKHggPSBwYXJzZUZsb2F0KHZhbHVlKSwgKDAgfCB4KSA9PT0geCk7XHJcblx0XHRpZihpc0ludCl7XHJcblx0XHRcdHJldHVybiB2YWx1ZSA8IDEgJiYgdmFsdWUubGVuZ3RoID09PSAxID8gZmFsc2UgOiB0cnVlO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRoYW5kbGVDaGFuZ2UoZSwgZWxtKSB7XHJcblx0XHRsZXQgc2t1SWQgICAgICAgPSAkKGVsbSkuYXR0cignZGF0YS1za3UtaWQnKSxcclxuXHRcdCAgICBxdWFudGl0eSAgICA9IG51bGwsXHJcblx0XHRcdFx0dXBncmFkZWRcdFx0PSBudWxsO1xyXG5cdFx0aWYoZS50YXJnZXQudHlwZSA9PT0gJ2NoZWNrYm94Jyl7XHJcblx0XHRcdHF1YW50aXR5ICAgID0gbnVsbCxcclxuXHRcdFx0dXBncmFkZWRcdFx0PSBlLnRhcmdldC5jaGVja2VkO1xyXG5cdFx0XHRDaGVja291dEFjdGlvbnMudXBkYXRlQ2hlY2tvdXRDYXJ0SXRlbShza3VJZCwgcXVhbnRpdHksIHVwZ3JhZGVkKTtcclxuXHRcdH1lbHNle1xyXG5cdFx0XHRxdWFudGl0eSAgICA9ICQoZWxtKS52YWwoKSxcclxuXHRcdFx0dXBncmFkZWRcdFx0PSBudWxsO1xyXG5cclxuXHRcdFx0aWYoIXRoaXMuaXNJbnQocXVhbnRpdHkpKSByZXR1cm47XHJcblxyXG5cdFx0XHRpZihlLnR5cGUgPT09ICdmb2N1c2luJykge1xyXG5cdFx0XHRcdHRoaXMuY3VycmVudFZhbCA9IHF1YW50aXR5O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZihlLnR5cGUgPT09ICdrZXlwcmVzcycgJiYgZS53aGljaCA9PT0gMTMpIHtcclxuXHRcdFx0XHRDaGVja291dEFjdGlvbnMudXBkYXRlQ2hlY2tvdXRDYXJ0SXRlbShza3VJZCwgcXVhbnRpdHksIHVwZ3JhZGVkKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZihlLnR5cGUgPT09ICdmb2N1c291dCcgJiYgdGhpcy5jdXJyZW50VmFsICE9IHF1YW50aXR5KSB7XHJcblx0XHRcdFx0Q2hlY2tvdXRBY3Rpb25zLnVwZGF0ZUNoZWNrb3V0Q2FydEl0ZW0oc2t1SWQsIHF1YW50aXR5LCB1cGdyYWRlZCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Q2FydExpbmVJdGVtVXBkYXRlXHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBDaGVja291dFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2hlY2tvdXRfc3RvcmUnO1xyXG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2NoZWNrb3V0X2FjdGlvbnMnO1xyXG5cclxubGV0IENoZWNrb3V0U2hpcHBpbmcgPSB7XHJcblx0Y3VycmVudFZhbCA6IG51bGwsXHJcblx0aXNJbnQodmFsdWUpIHtcclxuICBcdHZhciB4O1xyXG5cdFx0dmFyIGlzSW50ID0gaXNOYU4odmFsdWUpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQodmFsdWUpLCAoMCB8IHgpID09PSB4KTtcclxuXHRcdGlmKGlzSW50KXtcclxuXHRcdFx0cmV0dXJuIHZhbHVlIDwgMSAmJiB2YWx1ZS5sZW5ndGggPT09IDEgPyBmYWxzZSA6IHRydWU7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGhhbmRsZU9wdGlvbk9yUHJpb3JpdHlDaGFuZ2UoZSwgcHJpb3JpdHlWYWwsIG9wdGlvblZhbCwgcGxhbnRWYWwpIHtcclxuXHRcdCQoJyNzaGlwcGluZy1hZGRyZXNzLCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucywgIC51Yy1jaGVja291dC1zdW1tYXJ5JykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHRDaGVja291dEFjdGlvbnMudXBkYXRlU2hpcHBpbmdPcHRpb25PclByaW9yaXR5KHtwcmlvcml0eTogcHJpb3JpdHlWYWwsIG9wdGlvbjogb3B0aW9uVmFsLCBwbGFudDogcGxhbnRWYWx9KTtcclxuXHR9LFxyXG5cdGhhbmRsZU9wdGlvbk9yUHJpb3JpdHlDaGFuZ2VVcyhlLCBwcmlvcml0eVZhbCwgb3B0aW9uVmFsLCBwbGFudFZhbCwgc3BlY1Byb2MpIHtcclxuXHRcdCQoJyNzaGlwcGluZy1hZGRyZXNzLCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucywgIC51Yy1jaGVja291dC1zdW1tYXJ5JykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdENoZWNrb3V0QWN0aW9ucy51cGRhdGVTaGlwcGluZ09wdGlvbk9yUHJpb3JpdHkoe3ByaW9yaXR5OiBwcmlvcml0eVZhbCwgb3B0aW9uOiBvcHRpb25WYWwsIHBsYW50OiBwbGFudFZhbCwgc3BlY1Byb2M6IHNwZWNQcm9jfSk7XHJcblx0fSxcclxuXHRoYW5kbGVDb3VudHJ5Q29kZUNoYW5nZShlLCB2YWx1ZSkge1xyXG5cdFx0JCgnI3NoaXBwaW5nLWFkZHJlc3MgaW5wdXRbbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Qb3N0YWxDb2RlXCJdLCAudWMtY2hlY2tvdXQtc2hpcHBpbmctb3B0aW9ucywgIC51Yy1jaGVja291dC1zdW1tYXJ5JykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHRDaGVja291dEFjdGlvbnMudXBkYXRlQ291bnRyeUNvZGUodmFsdWUpO1xyXG5cdH1cclxuXHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRTaGlwcGluZztcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IENoZWNrb3V0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jaGVja291dF9hY3Rpb25zX25ldyc7XHJcbmltcG9ydCBjaGVja291dCBmcm9tICcuL2NoZWNrb3V0LW5ldyc7XHJcblxyXG5sZXQgcG9zdGFsQ29kZUlucHV0ID0gJCgnI3Bvc3RhbENvZGVDaGVja291dCcpO1xyXG5cclxubGV0IENoZWNrb3V0U2hpcHBpbmcgPSB7XHJcblx0Y3VycmVudFZhbCA6IG51bGwsXHJcblx0aXNJbnQodmFsdWUpIHtcclxuICBcdHZhciB4O1xyXG5cdFx0dmFyIGlzSW50ID0gaXNOYU4odmFsdWUpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQodmFsdWUpLCAoMCB8IHgpID09PSB4KTtcclxuXHRcdGlmKGlzSW50KXtcclxuXHRcdFx0cmV0dXJuIHZhbHVlIDwgMSAmJiB2YWx1ZS5sZW5ndGggPT09IDEgPyBmYWxzZSA6IHRydWU7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGhhbmRsZU9wdGlvbk9yUHJpb3JpdHlDaGFuZ2UoZSwgc2VydmljZUlkLCBwcmlvcml0eVZhbCwgb3B0aW9uVmFsLCBwbGFudFZhbCkge1xyXG5cdFx0Q2hlY2tvdXRBY3Rpb25zLnVwZGF0ZVNoaXBwaW5nT3B0aW9uT3JQcmlvcml0eSh7c2VydmljZUlkOiBzZXJ2aWNlSWQgLHByaW9yaXR5OiBwcmlvcml0eVZhbCwgb3B0aW9uOiBvcHRpb25WYWwsIHBsYW50OiBwbGFudFZhbH0pO1xyXG5cdH0sXHJcblx0aGFuZGxlQ291bnRyeUNvZGVDaGFuZ2Uoc2hpcHBpbmdBZGRyZXNzKSB7XHJcblx0XHRDaGVja291dEFjdGlvbnMudXBkYXRlQ291bnRyeUNvZGUoc2hpcHBpbmdBZGRyZXNzKTtcclxuXHR9LFxyXG5cdGhhbmRsZVNoaXBwaW5nQWRkcmVzc0NoYW5nZShpZCkge1xyXG5cdFx0Q2hlY2tvdXRBY3Rpb25zLmNoYW5nZVNoaXBwaW5nQWRkcmVzcyhpZCk7XHJcblx0fSxcclxuXHRoYW5kbGVCaWxsaW5nQWRkcmVzc0NoYW5nZShpZCkge1xyXG5cdFx0Q2hlY2tvdXRBY3Rpb25zLmNoYW5nZUJpbGxpbmdBZGRyZXNzKGlkKTtcclxuXHR9LFxyXG5cdGhhbmRsZVNoaXBwaW5nQWRkcmVzc1Bvc3RhbENvZGUocG9zdGFsQ29kZUlucHV0V3JhcHBlciwgdmFsdWUsIGNvdW50cnlDb2RlKXtcclxuXHJcblx0XHRpZiAoIHZhbHVlLmxlbmd0aCA9PT0gMCl7XHJcblx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIuYWRkQ2xhc3MoJ2ludmFsaWQnKTtcclxuXHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5hZGRDbGFzcygnZXJyb3InKTtcclxuXHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5yZW1vdmVDbGFzcygnbWlzc2luZy1jb3VudHJ5Jyk7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1lbHNle1xyXG5cdFx0XHRpZiggY291bnRyeUNvZGUubGVuZ3RoID09PSAwICl7XHJcblx0XHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5hZGRDbGFzcygnaW52YWxpZCcpO1xyXG5cdFx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIuYWRkQ2xhc3MoJ21pc3NpbmctY291bnRyeScpO1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIucmVtb3ZlQ2xhc3MoJ21pc3NpbmctY291bnRyeScpO1xyXG5cdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5yZW1vdmVDbGFzcygncmVxdWVzdC1lcnJvcicpO1xyXG5cdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5yZW1vdmVDbGFzcygnZXJyb3InKTtcclxuXHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcclxuXHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHQkLmFqYXgoe1xyXG5cdFx0XHRcdHR5cGU6ICdHRVQnLFxyXG5cdFx0XHRcdHVybDogaGlhYmNvbmZpZy5hZGRyZXNzZXMuYXBpQmFzZVVybCArICdWYWxpZGF0ZVBvc3RhbENvZGU/Y291bnRyeUNvZGU9Jytjb3VudHJ5Q29kZSsnJnBvc3RhbGNvZGU9Jyt2YWx1ZSxcclxuXHRcdFx0fSkuZG9uZShmdW5jdGlvbihkYXRhKSB7XHJcblx0XHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHRcdGlmKGRhdGEgPT09IHRydWUpe1xyXG5cdFx0XHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5yZW1vdmVDbGFzcygnZXJyb3InKTtcclxuXHRcdFx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcclxuXHRcdFx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIucmVtb3ZlQ2xhc3MoJ3JlcXVlc3QtZXJyb3InKTtcclxuXHRcdFx0XHRcdGNoZWNrb3V0LnNpbXVsYXRlT3JkZXIoKTtcclxuXHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIuYWRkQ2xhc3MoJ2Vycm9yJyk7XHJcblx0XHRcdFx0XHRwb3N0YWxDb2RlSW5wdXRXcmFwcGVyLmFkZENsYXNzKCdpbnZhbGlkJyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGNoZWNrb3V0LnZhbGlkYXRlKCk7XHJcblx0XHRcdH0pXHJcblx0XHRcdC5lcnJvcihmdW5jdGlvbihqcVhIUiwgIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XHJcblx0XHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5hZGRDbGFzcygnZXJyb3InKTtcclxuXHRcdFx0XHRwb3N0YWxDb2RlSW5wdXRXcmFwcGVyLmFkZENsYXNzKCdpbnZhbGlkJyk7XHJcblx0XHRcdFx0cG9zdGFsQ29kZUlucHV0V3JhcHBlci5hZGRDbGFzcygncmVxdWVzdC1lcnJvcicpO1xyXG5cdFx0XHRcdHBvc3RhbENvZGVJbnB1dFdyYXBwZXIucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHRjaGVja291dC52YWxpZGF0ZSgpO1xyXG5cdFx0XHR9KTtcclxuXHR9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRTaGlwcGluZztcclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgVHJlZVZpZXdBcGkgZnJvbSAnLi4vLi4vX2FwaS90cmVldmlld19hcGknO1xyXG5pbXBvcnQgVHJlZVZpZXdTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3RyZWV2aWV3X3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2hpc3Rvcnlfc3RvcmUnO1xyXG5pbXBvcnQgQnJhbmROYXZpZ2F0aW9uSGlzdG9yeSBmcm9tICcuL2JyYW5kbmF2aWdhdGlvbl9oaXN0b3J5JztcclxuaW1wb3J0IEJyYW5kTmF2aWdhdGlvblRyZWUgZnJvbSAnLi9icmFuZG5hdmlnYXRpb25fdHJlZSc7XHJcbmltcG9ydCBWaXN1YWxCcm93c2luZyBmcm9tICcuL3Zpc3VhbGJyb3dzaW5nJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBCcmFuZHMgZnJvbSAnLi9icmFuZHMnO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uRm9yT3ZlcmxheVN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvaWxsdXN0cmF0aW9uRm9yT3ZlcmxheV9zdG9yZSc7XHJcblxyXG5jbGFzcyBCcmFuZE5hdmlnYXRpb24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHsgY3VycmVudENoaWxkOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbjogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICAgIElzUm9vdDogICAgICBudWxsIH0sXHJcbiAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgZGF0YTogICAgICAgIFtdIH0sXHJcbiAgICAgICAgICAgICAgICAgICBoaXN0b3J5OiAgICAgICAgW10sXHJcbiAgICAgICAgICAgICAgICAgICBpc0xvYWRpbmc6ICAgICAgZmFsc2UsXHJcblx0XHRcdFx0XHRcdFx0XHQgIElsbHVzdHJhdGlvbjogbnVsbFxyXG5cdFx0XHRcdFx0XHRcdFx0IH07XHJcblx0fVxyXG5cclxuXHRmZXRjaE5vZGVzKCkge1xyXG5cdFx0bGV0IGN1cnJlbnRuYXYgPSBIaXN0b3J5U3RvcmUuZ2V0Q3VycmVudE5hdigpLFxyXG5cdFx0XHRcdGlkXHRcdFx0XHQgPSAwO1xyXG5cclxuXHRcdGlmKCFjdXJyZW50bmF2LklzUm9vdCkgaWQgPSBjdXJyZW50bmF2LklkO1xyXG5cclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHQvL2N1cnJlbnRDaGlsZDogY3VycmVudG5hdixcclxuXHRcdFx0aXNMb2FkaW5nOiAgICB0cnVlXHJcblx0XHR9KTtcclxuXHJcblx0XHRUcmVlVmlld0FwaS5nZXROb2RlcyhpZCkudGhlbigocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7IGN1cnJlbnRDaGlsZDogY3VycmVudG5hdixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNoaWxkcmVuOiBcdFx0VHJlZVZpZXdTdG9yZS5nZXQoaWQpLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aGlzdG9yeTogXHRcdFx0SGlzdG9yeVN0b3JlLmdldFN0b3JlKCksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0ICBpc0xvYWRpbmc6ICAgIGZhbHNlIH0pO1xyXG5cclxuXHRcdH0pLmNhdGNoKChtZXNzYWdlKSA9PiB7XHJcblx0XHRcdGlmKG1lc3NhZ2UgPT09IDIwNCAmJiBjdXJyZW50bmF2LkRvY3VtZW50cy5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRsZXQgaGlzdG9yeSA9IEhpc3RvcnlTdG9yZS5nZXRTdG9yZSgpO1xyXG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoeyBjdXJyZW50Q2hpbGQ6IGN1cnJlbnRuYXYsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNoaWxkcmVuOiBcdHtkYXRhOiBbXSwga2V5OmN1cnJlbnRuYXYuSWR9LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRoaXN0b3J5OiBcdFx0XHRIaXN0b3J5U3RvcmUuZ2V0U3RvcmUoKSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0aXNMb2FkaW5nOiAgICBmYWxzZSB9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRlbHNlIHtcclxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblxyXG5cdFx0dGhpcy5mZXRjaE5vZGVzKCk7XHJcblx0XHQvL0xpc3RlbiBmb3IgY2hhbmdlcyBpbiBoaXN0b3J5IHN0b3JlIVxyXG5cdFx0dGhpcy51bnN1YnNjcmliZSA9IEhpc3RvcnlTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0dGhpcy5mZXRjaE5vZGVzKCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlMiA9IElsbHVzdHJhdGlvbkZvck92ZXJsYXlTdG9yZS5saXN0ZW4oIChyZXMpID0+IHtcclxuXHRcdFx0aWYocmVzLmlsbHVzdHJhdGlvbiAmJiB0aGlzLnN0YXRlLmN1cnJlbnRDaGlsZC5JbGx1c3RyYXRpb25MaW5rID09PSByZXMuaWxsdXN0cmF0aW9uLklkKXtcclxuXHRcdFx0XHR0aGlzLnN0YXRlLmN1cnJlbnRDaGlsZC5JbGx1c3RyYXRpb24gPSByZXMuaWxsdXN0cmF0aW9uO1xyXG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUodGhpcy5zdGF0ZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50V2lsbFVubW91bnQoKSB7XHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlKCk7XHJcblxyXG5cdFx0dGhpcy51bnN1YnNjcmliZTIoKTtcclxuXHR9XHJcblxyXG5cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGxldCBsb2dvTmF2Q2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J3Jvdyc6IHRydWUsXHJcblx0XHRcdCd1LXZpc2libGUnOiB0aGlzLnN0YXRlLmN1cnJlbnRDaGlsZC5Jc1Jvb3QsXHJcblx0XHRcdCd1LWhpZGRlbic6ICF0aGlzLnN0YXRlLmN1cnJlbnRDaGlsZC5Jc1Jvb3RcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCBuYXZDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQncm93JzogdHJ1ZSxcclxuXHRcdFx0J3UtdmlzaWJsZSc6ICF0aGlzLnN0YXRlLmN1cnJlbnRDaGlsZC5Jc1Jvb3QsXHJcblx0XHRcdCd1LWhpZGRlbic6IHRoaXMuc3RhdGUuY3VycmVudENoaWxkLklzUm9vdFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IGxvYWRpbmdDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnbGFyZ2UtNCBtZWRpdW0tOCBzbWFsbC03IGNvbHVtbnMgdS1ibC1ibGFjayBmdWxsLWhlaWdodCBicmFuZC1uYXYtbWFpbiBpcy1sb2FkaW5nJzogdGhpcy5zdGF0ZS5pc0xvYWRpbmcsXHJcblx0XHRcdCdsYXJnZS00IG1lZGl1bS04IHNtYWxsLTcgY29sdW1ucyB1LWJsLWJsYWNrIGZ1bGwtaGVpZ2h0IGJyYW5kLW5hdi1tYWluJzogIXRoaXMuc3RhdGUuaXNMb2FkaW5nXHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBsZXQgYnJhbmRDaGlsZHJlbiA9IHRoaXMuc3RhdGUuYnJhbmRDaGlsZHJlbiA/IHRoaXMuc3RhdGUuYnJhbmRDaGlsZHJlbiA6IHRoaXMuc3RhdGUuY2hpbGRyZW47XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJmdWxsLWhlaWdodFwiPlxyXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPXtsb2dvTmF2Q2xhc3N9PlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJsYXJnZS0xMiBjb2x1bW5zIHRleHQtY2VudGVyXCI+XHJcblx0XHRcdFx0XHRcdDxCcmFuZHMgaXRlbXM9e3RoaXMuc3RhdGUuY2hpbGRyZW59IGN1cnJlbnRDaGlsZD17dGhpcy5zdGF0ZS5jdXJyZW50Q2hpbGR9IC8+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT17bmF2Q2xhc3N9PlxyXG5cclxuXHRcdFx0XHRcdDxCcmFuZE5hdmlnYXRpb25IaXN0b3J5IGhpc3Rvcnk9e3RoaXMuc3RhdGUuaGlzdG9yeX0gZmV0Y2hub2Rlcz17dGhpcy5mZXRjaE5vZGVzLmJpbmQodGhpcyl9IGN1cnJlbnRDaGlsZD17dGhpcy5zdGF0ZS5jdXJyZW50Q2hpbGR9ICAvPlxyXG5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPXtsb2FkaW5nQ2xhc3N9PlxyXG5cdFx0XHRcdFx0XHQ8QnJhbmROYXZpZ2F0aW9uVHJlZSBpdGVtcz17dGhpcy5zdGF0ZS5jaGlsZHJlbn0gZmV0Y2hub2Rlcz17dGhpcy5mZXRjaE5vZGVzLmJpbmQodGhpcyl9IGN1cnJlbnRDaGlsZD17dGhpcy5zdGF0ZS5jdXJyZW50Q2hpbGR9IC8+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImxhcmdlLTYgY29sdW1ucyBzaG93LWZvci1sYXJnZS11cFwiPlxyXG5cdFx0XHRcdFx0XHQ8VmlzdWFsQnJvd3NpbmcgaXRlbXM9e3RoaXMuc3RhdGUuY2hpbGRyZW59IGN1cnJlbnRDaGlsZD17dGhpcy5zdGF0ZS5jdXJyZW50Q2hpbGR9IC8+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEJyYW5kTmF2aWdhdGlvbjtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgQnJhbmROYXZpZ2F0aW9uSGlzdG9yeUl0ZW0gZnJvbSAnLi9icmFuZG5hdmlnYXRpb25faGlzdG9yeV9pdGVtJztcclxuaW1wb3J0IEhpc3RvcnlTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2hpc3Rvcnlfc3RvcmUnO1xyXG5pbXBvcnQgSGlzdG9yeUFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvaGlzdG9yeV9hY3Rpb25zJztcclxuXHJcbmNsYXNzIEJyYW5kTmF2aWdhdGlvbkhpc3RvcnkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0XHRoaXN0b3J5OiBbXVxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHJcblx0XHRsZXQgaGlzdG9yeSA9IHRoaXMucHJvcHMuaGlzdG9yeS5tYXAoKGhpc3Rvcnlub2RlLCBpbmRleCkgPT4ge1xyXG5cdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdDxCcmFuZE5hdmlnYXRpb25IaXN0b3J5SXRlbSBrZXk9e2luZGV4fSBpdGVtPXtoaXN0b3J5bm9kZX0gZmV0Y2hub2Rlcz17dGhpcy5wcm9wcy5mZXRjaG5vZGVzfSAvPlxyXG5cdFx0XHQpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJsYXJnZS0yIG1lZGl1bS00IHNtYWxsLTUgY29sdW1ucyB1LXR4dC1yaWdodCBmdWxsLWhlaWdodFwiPlxyXG5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImJyYW5kLWhlYWRlciBjbGVhcmZpeFwiPlxyXG5cdFx0XHRcdDwvZGl2PlxyXG5cclxuXHRcdFx0XHQ8bmF2IGNsYXNzTmFtZT1cImJyYW5kdHJlZS1oaXN0b3J5XCI+XHJcblx0XHRcdFx0XHQ8dWw+XHJcblx0XHRcdFx0XHRcdHtoaXN0b3J5fVxyXG5cdFx0XHRcdFx0PC91bD5cclxuXHRcdFx0XHQ8L25hdj5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBCcmFuZE5hdmlnYXRpb25IaXN0b3J5O1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBIaXN0b3J5U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9oaXN0b3J5X3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL2hpc3RvcnlfYWN0aW9ucyc7XHJcblxyXG5jbGFzcyBCcmFuZE5hdmlnYXRpb25IaXN0b3J5SXRlbSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHJcblx0fVxyXG5cclxuXHRoYW5kbGVDbGljayA9IChlKSA9PiB7XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRIaXN0b3J5U3RvcmUucmVtb3ZlSGlzdG9yeUFmdGVyKHRoaXMucHJvcHMuaXRlbS5kYXRhLklkKTtcclxuXHRcdEhpc3RvcnlTdG9yZS5zZXRDdXJyZW50TmF2KHRoaXMucHJvcHMuaXRlbS5kYXRhKTtcclxuXHRcdEhpc3RvcnlBY3Rpb25zLnN0b3JlVXBkYXRlZCgpO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGxldCBpdGVtID0gdGhpcy5wcm9wcy5pdGVtO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxsaT5cclxuXHRcdFx0XHQ8YSBvbkNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcyl9IGhyZWY9JyMnPjxpIGNsYXNzTmFtZT1cImljb24tYW5nbGUtbGVmdFwiPjwvaT57aXRlbS5kYXRhLkRlc2NyaXB0aW9ufTwvYT5cclxuXHRcdFx0PC9saT5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEJyYW5kTmF2aWdhdGlvbkhpc3RvcnlJdGVtO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBCcmFuZE5hdmlnYXRpb25UcmVlSXRlbSBmcm9tICcuL2JyYW5kbmF2aWdhdGlvbl90cmVlX2l0ZW0nO1xyXG5pbXBvcnQgRG9jdW1lbnRzIGZyb20gJy4vZG9jdW1lbnRzJztcclxuXHJcbmNsYXNzIEJyYW5kTmF2aWdhdGlvbkhpc3RvcnkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0bGV0IGNoaWxkcmVuO1xyXG5cdFx0aWYodGhpcy5wcm9wcy5pdGVtcyAmJiB0aGlzLnByb3BzLml0ZW1zLmRhdGEubGVuZ3RoID4gMCl7XHJcblx0XHRcdGNoaWxkcmVuID0gdGhpcy5wcm9wcy5pdGVtcy5kYXRhLm1hcCgoY2hpbGRub2RlKSA9PiB7XHJcblx0XHRcdFx0Ly9EbyBub3Qgc2hvdyB0b3Agbm9kZSBsZXZlbCBpbiBuYXZpZ2F0aW9uXHJcblx0XHRcdFx0aWYoY2hpbGRub2RlLlBhcmVudCA9PT0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLnJvb3RNb2RlbC5JZCkgcmV0dXJuO1xyXG5cclxuXHRcdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdFx0PEJyYW5kTmF2aWdhdGlvblRyZWVJdGVtIGtleT17Y2hpbGRub2RlLklkfSBpdGVtPXtjaGlsZG5vZGV9IGN1cnJlbnRDaGlsZD17dGhpcy5wcm9wcy5jdXJyZW50Q2hpbGR9IC8+XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IG5vZGVOYW1lIFx0PSBudWxsLFxyXG5cdFx0XHRcdGRvY3VtZW50cyA9IFtdO1xyXG5cclxuXHRcdGlmKHRoaXMucHJvcHMuY3VycmVudENoaWxkICE9PSBudWxsKSB7XHJcblx0XHRcdG5vZGVOYW1lXHQ9IHRoaXMucHJvcHMuY3VycmVudENoaWxkLkRlc2NyaXB0aW9uO1xyXG5cdFx0XHRkb2N1bWVudHMgPSB0aGlzLnByb3BzLmN1cnJlbnRDaGlsZC5Eb2N1bWVudHM7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJmdWxsLWhlaWdodFwiPlxyXG5cdFx0XHRcdDxoND57bm9kZU5hbWV9PC9oND5cclxuXHRcdFx0XHQ8bmF2IGNsYXNzTmFtZT1cImJyYW5kdHJlZS1tZW51IGZ1bGwtaGVpZ2h0XCI+XHJcblx0XHRcdFx0XHQ8RG9jdW1lbnRzIGRvY3VtZW50cz17ZG9jdW1lbnRzfSAvPlxyXG5cdFx0XHRcdFx0PHVsPlxyXG5cdFx0XHRcdFx0XHR7Y2hpbGRyZW59XHJcblx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdDwvbmF2PlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEJyYW5kTmF2aWdhdGlvbkhpc3Rvcnk7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFRyZWVWaWV3U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy90cmVldmlld19zdG9yZSc7XHJcbmltcG9ydCBIaXN0b3J5U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9oaXN0b3J5X3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL2hpc3RvcnlfYWN0aW9ucyc7XHJcbmltcG9ydCBJbGx1c3RyYXRpb25BY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL2lsbHVzdHJhdGlvbl9hY3Rpb25zJztcclxuXHJcbmNsYXNzIEJyYW5kTmF2aWdhdGlvblRyZWVJdGVtIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2xpY2sgPSAoZSkgPT4ge1xyXG5cdFx0aWYodGhpcy5wcm9wcy5pdGVtLk5vZGVUeXBlICE9PSAwKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0SGlzdG9yeVN0b3JlLnNldCh0aGlzLnByb3BzLmN1cnJlbnRDaGlsZC5JZCwgdGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQpO1xyXG5cdFx0XHRIaXN0b3J5U3RvcmUuc2V0Q3VycmVudE5hdih0aGlzLnByb3BzLml0ZW0pO1xyXG5cdFx0XHRIaXN0b3J5QWN0aW9ucy5zdG9yZVVwZGF0ZWQoKTtcclxuXHRcdFx0aWYodGhpcy5wcm9wcy5pdGVtLklsbHVzdHJhdGlvbkxpbmsgJiYgdGhpcy5wcm9wcy5pdGVtLklsbHVzdHJhdGlvbkxpbmsgIT09IFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIpe1xyXG5cdFx0XHRcdElsbHVzdHJhdGlvbkFjdGlvbnMubG9hZElsbHVzdHJhdGlvbkZvck92ZXJsYXkodGhpcy5wcm9wcy5pdGVtLklsbHVzdHJhdGlvbkxpbmssIHRoaXMucHJvcHMuaXRlbS5Ob2RlVHlwZSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGNvbnN0IHsgaXRlbTogeyBJZCwgRGVzY3JpcHRpb24sIE5vZGVUeXBlICB9IH0gPSB0aGlzLnByb3BzO1xyXG5cdFx0Y29uc3QgdXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmV4cGxvZGVkVmlld3NVUkwgKyBJZDtcclxuXHJcblx0XHRjb25zdCBpc01vZGVsID0gTm9kZVR5cGUgPT09IDA7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGxpPlxyXG5cdFx0XHRcdHtpc01vZGVsXHJcblx0XHRcdFx0XHQ/IDxhIGNsYXNzTmFtZT1cImxpbmtcIiBocmVmPXt1cmx9PjxpIGNsYXNzTmFtZT1cImljb24tYW5nbGUtcmlnaHRcIj48L2k+e0Rlc2NyaXB0aW9ufTwvYT5cclxuXHRcdFx0XHRcdDogPGEgb25DbGljaz17dGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpfSBocmVmPScjJz48aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLXJpZ2h0XCI+PC9pPntEZXNjcmlwdGlvbn08L2E+IH1cclxuXHRcdFx0PC9saT5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEJyYW5kTmF2aWdhdGlvblRyZWVJdGVtO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBIaXN0b3J5U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9oaXN0b3J5X3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL2hpc3RvcnlfYWN0aW9ucyc7XHJcblxyXG5jbGFzcyBCcmFuZHMgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0XHRjdXJyZW50Q2hpbGQ6IG51bGwsXHJcblx0XHRcdGl0ZW1zOiBbXVxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZUNsaWNrID0gKGl0ZW0sIGUpID0+IHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHQvL1B1c2ggcGFyZW50IHRvIGhpc3RvcnkgbmF2aWdhdGlvblxyXG5cdFx0SGlzdG9yeVN0b3JlLnNldCh0aGlzLnByb3BzLmN1cnJlbnRDaGlsZC5JZCwgdGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQpO1xyXG5cclxuXHRcdGUuY3VycmVudFRhcmdldC5jbGFzc05hbWUgPSBlLmN1cnJlbnRUYXJnZXQuY2xhc3NOYW1lICsgJyBpcy1sb2FkaW5nJztcclxuXHRcdEhpc3RvcnlTdG9yZS5zZXRDdXJyZW50TmF2KGl0ZW0pO1xyXG5cdFx0SGlzdG9yeUFjdGlvbnMuc3RvcmVVcGRhdGVkKCk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblxyXG5cdFx0bGV0IGJyYW5kcyA9IFtdO1xyXG5cdFx0aWYodGhpcy5wcm9wcy5pdGVtcy5kYXRhKXtcclxuXHRcdFx0YnJhbmRzID0gdGhpcy5wcm9wcy5pdGVtcy5kYXRhLm1hcCgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdHJldHVybihcclxuXHRcdFx0XHRcdDxsaSBrZXk9e2l0ZW0uSWR9PjxhIGhyZWY9XCIjXCIgb25DbGljaz17dGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMsIGl0ZW0pfT48c3Bhbj57aXRlbS5EZXNjcmlwdGlvbn08L3NwYW4+PC9hPjwvbGk+XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHQvLyBjb25zb2xlLmxvZygnYnJhbmRzJyk7XHJcblx0XHQvLyBjb25zb2xlLmxvZyhicmFuZHMpO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PG5hdiBjbGFzc05hbWU9XCJicmFuZC1sb2dvc1wiPlxyXG5cdFx0XHRcdDx1bD5cclxuXHRcdFx0XHRcdHticmFuZHN9XHJcblx0XHRcdFx0PC91bD5cclxuXHRcdFx0PC9uYXY+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBCcmFuZHM7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuXHJcbmNsYXNzIERvY3VtZW50cyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMucHJvcHMgPSB7XHJcblx0XHRcdGRvY3VtZW50czpbXVxyXG5cdFx0fTtcclxuXHJcblxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGlmKCF0aGlzLnByb3BzLmRvY3VtZW50cykgcmV0dXJuIG51bGw7XHJcbiBcdFx0aWYodGhpcy5wcm9wcy5kb2N1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgZG9jdW1lbnRzID0gdGhpcy5wcm9wcy5kb2N1bWVudHMubWFwKChkb2N1bWVudCkgPT4ge1xyXG5cdFx0XHRyZXR1cm4oPGxpPjxhIGhyZWY9e2RvY3VtZW50LkRvY3VtZW50TGlua30gdGFyZ2V0PSdfYmxhbmsnPjxpIGNsYXNzTmFtZT0naWNvbi1kb2MnPjwvaT57ZG9jdW1lbnQuRGVzY3JpcHRpb259PC9hPjwvbGk+KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDx1bCBjbGFzc05hbWU9J2RvY3VtZW50cyc+XHJcblx0XHRcdFx0e2RvY3VtZW50c31cclxuXHRcdFx0PC91bD5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IERvY3VtZW50cztcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IE1vZGVsU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9tb2RlbHNlYXJjaF9zdG9yZSc7XHJcblxyXG5jbGFzcyBNb2RlbFNlYXJjaFJlc3VsdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdHNlYXJjaFJlc3VsdHM6IFtdLFxyXG5cdFx0fVxyXG5cdH1cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUgPSBNb2RlbFN0b3JlLmxpc3RlbiggKCkgPT57XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe3NlYXJjaFJlc3VsdHM6IE1vZGVsU3RvcmUuZ2V0TW9kZWwoKS5tb2RlbGl0ZW19KTtcclxuXHRcdFx0JCgnI3NlYXJjaC1yZXN1bHQnKS5hZGRDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG5cdH1cclxuXHRoYW5kbGVDbGljayA9ICh1cmwsIGUpID0+IHtcclxuXHRcdGlmKHRoaXMucHJvcHMuaXRlbS5Ob2RlVHlwZSA9PT0gMCkge1xyXG5cdFx0XHRpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaWxsdXN0cmF0aW9uJykpIHJldHVybiB3aW5kb3cubG9jYXRpb24ucmVsb2FkKHRydWUpO1xyXG5cdFx0XHRyZXR1cm4gd2luZG93LmxvY2F0aW9uID0gdXJsO1xyXG5cdFx0fVxyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0aWYoIXRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cykgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IG1vZGVscyA9IFtdO1xyXG5cdFx0bGV0IHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMO1xyXG5cclxuXHRcdG1vZGVscyA9IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5tYXAoIChtb2RlbCk9PntcclxuXHRcdFx0aWYgKG1vZGVsLkRvY3VtZW50cy5sZW5ndGggPT09IDApe1xyXG5cdFx0XHRcdHJldHVybihcclxuXHRcdFx0XHRcdDxsaSBrZXk9e21vZGVsLklkfT5cclxuXHRcdFx0XHRcdFx0PGEgb25DbGljaz17dGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMsIHVybCl9IGhyZWY9e3VybCttb2RlbC5JZH0+PGkgY2xhc3NOYW1lPVwiaWNvbi1hbmdsZS1yaWdodFwiPjwvaT57bW9kZWwuRGVzY3JpcHRpb259PC9hPlxyXG5cdFx0XHRcdFx0PC9saT5cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRyZXR1cm4oXHJcblx0XHRcdFx0XHRmYWxzZVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PHVsPlxyXG5cdFx0XHRcdHttb2RlbHN9XHJcblx0XHRcdDwvdWw+XHJcblx0XHQpXHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTW9kZWxTZWFyY2hSZXN1bHQ7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IE1vZGVsU2VhcmNoQXBpIGZyb20gJy4uLy4uL19hcGkvbW9kZWxzZWFyY2hfYXBpJztcclxuaW1wb3J0IE1vZGVsU2VhcmNoQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9tb2RlbHNlYXJjaF9hY3Rpb24nO1xyXG5pbXBvcnQgTW9kZWxTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL21vZGVsc2VhcmNoX3N0b3JlJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5jb25zdCBkb25lVHlwaW5nSW50ZXJ2YWwgPSAgMjAwO1xyXG5cclxuY2xhc3MgTW9kZWxTZWFyY2ggZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnN0YXRlID0ge1xyXG5cdFx0XHRsb2FkaW5nOiBNb2RlbFN0b3JlLmdldExvYWRpbmdTdGF0ZSgpLFxyXG5cdFx0fVxyXG5cdFx0dGhpcy50eXBpbmdUaW1lciA9IG51bGw7XHJcblxyXG5cdH1cclxuXHJcblx0ZG9TZWFyY2goZSkge1xyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0bGV0IHNlYXJjaCA9IGUudGFyZ2V0LnZhbHVlXHJcblxyXG5cdFx0aWYoZS50YXJnZXQudGFnTmFtZSA9PT0gJ0JVVFRPTicpe1xyXG5cdFx0XHRzZWFyY2ggPSB0aGlzLnJlZnMuc2VhcmNoSW5wdXQudmFsdWU7XHJcblx0XHR9XHJcblx0XHRpZihzZWFyY2gudHJpbSgpLmxlbmd0aCA+IDEpe1xyXG5cdFx0XHRNb2RlbFNlYXJjaEFjdGlvbnMubG9hZE1vZGVsKHNlYXJjaCk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yLXJlcScpLmhpZGUoKTtcclxuXHRcdFx0JCgnI3NlYXJjaC1yZXN1bHQgaDQuc2VhcmNoLXJlcy1mb3InKS5zaG93KCk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yIHNwYW4nKS50ZXh0KCcgJyskKCcjbW9kZWwtc2VhcmNoIC5zZWFyY2gtbWFpbicpLnZhbCgpICk7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGxvYWRpbmc6IE1vZGVsU3RvcmUuZ2V0TG9hZGluZ1N0YXRlKClcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0Ly8gY29uc29sZS5sb2coJ2hlaicpO1xyXG5cdFx0XHRNb2RlbFNlYXJjaEFwaS5hYm9ydFNlYXJjaCgpO1xyXG5cdFx0XHRNb2RlbFN0b3JlLnNldE5vdEVub3VnaENoYXJhY3RlcnMoKTtcclxuXHRcdFx0JCgnI3NlYXJjaC1yZXN1bHQgaDQuc2VhcmNoLXJlcy1mb3InKS5oaWRlKCk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yLXJlcScpLnNob3coKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZUtleXVwKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmKHRoaXMudHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnR5cGluZ1RpbWVyKTtcclxuXHJcblx0XHRsZXQgdmFsdWUgPSBlLnRhcmdldC52YWx1ZTtcclxuXHQgIHRoaXMudHlwaW5nVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0dGhpcy5kb25lVHlwaW5nKHZhbHVlKTtcclxuXHRcdH0sIGRvbmVUeXBpbmdJbnRlcnZhbCk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVLZXlkb3duKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdC8vIGNvbnNvbGUubG9nKCdpbnRlcnVwdCcpO1xyXG5cdFx0aWYodGhpcy50eXBpbmdUaW1lcikgY2xlYXJUaW1lb3V0KHRoaXMudHlwaW5nVGltZXIpO1xyXG5cdH1cclxuXHJcblx0ZG9uZVR5cGluZyAodmFsdWUpIHtcclxuXHRcdGlmKHZhbHVlLnRyaW0oKS5sZW5ndGggPiAxKXtcclxuXHRcdFx0TW9kZWxTZWFyY2hBY3Rpb25zLmxvYWRNb2RlbCh2YWx1ZSk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yLXJlcScpLmhpZGUoKTtcclxuXHRcdFx0JCgnI3NlYXJjaC1yZXN1bHQgaDQuc2VhcmNoLXJlcy1mb3InKS5zaG93KCk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yIHNwYW4nKS50ZXh0KCcgJyskKCcjbW9kZWwtc2VhcmNoIC5zZWFyY2gtbWFpbicpLnZhbCgpICk7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGxvYWRpbmc6IE1vZGVsU3RvcmUuZ2V0TG9hZGluZ1N0YXRlKClcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0Ly8gY29uc29sZS5sb2coJ2hlaicpO1xyXG5cdFx0XHRNb2RlbFNlYXJjaEFwaS5hYm9ydFNlYXJjaCgpO1xyXG5cdFx0XHRNb2RlbFN0b3JlLnNldE5vdEVub3VnaENoYXJhY3RlcnMoKTtcclxuXHRcdFx0JCgnI3NlYXJjaC1yZXN1bHQgaDQuc2VhcmNoLXJlcy1mb3InKS5oaWRlKCk7XHJcblx0XHRcdCQoJyNzZWFyY2gtcmVzdWx0IGg0LnNlYXJjaC1yZXMtZm9yLXJlcScpLnNob3coKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZE1vdW50KCkge1xyXG5cdFx0dGhpcy51bnN1YnNjcmliZSA9IE1vZGVsU3RvcmUubGlzdGVuKCAoKSA9PntcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0bG9hZGluZzogTW9kZWxTdG9yZS5nZXRMb2FkaW5nU3RhdGUoKVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHQvL29uQ2hhbmdlPXt0aGlzLmRvU2VhcmNoLmJpbmQodGhpcyl9XHJcblx0Ly9vbktleVVwPXt0aGlzLmhhbmRsZUtleXVwLmJpbmQodGhpcyl9IG9uS2V5RG93bj17dGhpcy5oYW5kbGVLZXlkb3duLmJpbmQodGhpcyl9XHJcblx0cmVuZGVyKCkge1xyXG5cdFx0bGV0IGxhbmcgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZztcclxuXHRcdGxldCBidG5DbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnbG9hZGluZyc6IHRoaXMuc3RhdGUubG9hZGluZyxcclxuICAgICAgJ2J1dHRvbic6IHRydWVcclxuXHRcdH0pO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGZvcm0gb25TdWJtaXQ9e3RoaXMuZG9TZWFyY2guYmluZCh0aGlzKX0+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJyb3cgY29sbGFwc2VcIj5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwibWVkaXVtLTEwIHNtYWxsLTkgY29sdW1uc1wiPlxyXG5cdFx0XHRcdFx0PGlucHV0IGNsYXNzTmFtZT1cInNlYXJjaC1tYWluXCIgcmVmPVwic2VhcmNoSW5wdXRcIiB0eXBlPVwic2VhcmNoXCIgcGxhY2Vob2xkZXI9e2xhbmcuc2VhcmNoRm9yfSBuYW1lPVwibW9kZWxcIlxyXG52YWx1ZT17dGhpcy5zdGF0ZS5zZWFyY2h9IG9uS2V5VXA9e3RoaXMuaGFuZGxlS2V5dXAuYmluZCh0aGlzKX0gb25LZXlEb3duPXt0aGlzLmhhbmRsZUtleWRvd24uYmluZCh0aGlzKX0gLz5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJtZWRpdW0tMiBzbWFsbC0zIGNvbHVtbnNcIj5cclxuXHRcdFx0XHRcdFx0PGJ1dHRvbiBjbGFzc05hbWU9e2J0bkNsYXNzfSBvbkNsaWNrPXt0aGlzLmRvU2VhcmNoLmJpbmQodGhpcyl9PntsYW5nLnNlYXJjaEJ0bn08L2J1dHRvbj5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHQ8L2Zvcm0+XHJcblx0XHQpXHJcblx0fVxyXG5cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IE1vZGVsU2VhcmNoO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBUcmVlVmlld1N0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvdHJlZXZpZXdfc3RvcmUnO1xyXG5pbXBvcnQgSGlzdG9yeVN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvaGlzdG9yeV9zdG9yZSc7XHJcbmltcG9ydCBIaXN0b3J5QWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9oaXN0b3J5X2FjdGlvbnMnO1xyXG5pbXBvcnQgSG90U3BvdHMgZnJvbSAnLi4vaWxsdXN0cmF0aW9uL2hvdHNwb3RzJztcclxuaW1wb3J0IElsbHVzdGF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9pbGx1c3RyYXRpb25fc3RvcmUnO1xyXG5cclxuY2xhc3MgVmlzdWFsQnJvd3NpbmcgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0XHRjdXJyZW50Q2hpbGQ6IG51bGxcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aWxsdXN0cmF0aW9uOiB7XHJcblx0XHRcdFx0aW1nOiB7XHJcblx0XHRcdFx0XHRoZWlnaHQ6bnVsbCxcclxuXHRcdFx0XHRcdHdpZHRoOm51bGxcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRoYW5kbGVDbGljayA9IChob3RzcG90LCBlKSA9PiB7XHJcblxyXG5cdFx0aWYoaG90c3BvdC5JbGx1c3RyYXRpb25MaW5rTm9kZVR5cGUgPT09IDIpIHtcclxuXHRcdFx0Ly9QdXNoIHBhcmVudCB0byBoaXN0b3J5IG5hdmlnYXRpb25cclxuXHRcdFx0SGlzdG9yeVN0b3JlLnNldCh0aGlzLnByb3BzLmN1cnJlbnRDaGlsZC5JZCwgdGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQpO1xyXG5cdFx0XHRIaXN0b3J5U3RvcmUuc2V0Q3VycmVudE5hdih7XHJcblx0XHRcdFx0J0lkJzogaG90c3BvdC5JbGx1c3RyYXRpb25MaW5rLFxyXG5cdFx0XHRcdCdEZXNjcmlwdGlvbic6IGhvdHNwb3QuSWxsdXN0cmF0aW9uTGlua05vZGVEZXNjcmlwdGlvbixcclxuXHRcdFx0XHQnSXNSb290JzogZmFsc2VcclxuXHRcdFx0fSk7XHJcblx0XHRcdEhpc3RvcnlBY3Rpb25zLnN0b3JlVXBkYXRlZCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKGhvdHNwb3QuSWxsdXN0cmF0aW9uTGlua05vZGVUeXBlID09PSAwKSB7XHJcblx0XHRcdGxldCBsaW5rVXJsID0gd2luZG93LmxvY2F0aW9uLm9yaWdpbiArIGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMICsgaG90c3BvdC5JbGx1c3RyYXRpb25MaW5rO1xyXG5cdFx0XHR3aW5kb3cubG9jYXRpb24uaHJlZiA9IGxpbmtVcmw7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHRpbWdPbkxvYWQgPSAoZSkgPT4ge1xyXG5cclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRpbGx1c3RyYXRpb246IHtcclxuXHRcdFx0XHRpbWc6IHtcclxuXHRcdFx0XHRcdGhlaWdodDplLnRhcmdldC5uYXR1cmFsSGVpZ2h0LFxyXG5cdFx0XHRcdFx0d2lkdGg6ZS50YXJnZXQubmF0dXJhbFdpZHRoXHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0fVxyXG5cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0aWYoIXRoaXMucHJvcHMuY3VycmVudENoaWxkLklsbHVzdHJhdGlvbiB8fCAkLmlzRW1wdHlPYmplY3QodGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQuSWxsdXN0cmF0aW9uKSkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IGhvdHNwb3RzID0gW107XHJcblxyXG5cdFx0dGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQuSWxsdXN0cmF0aW9uLkhvdHNwb3RzLmZvckVhY2goKGhvdHNwb3QsIGtleSkgPT4ge1xyXG5cdFx0XHRsZXQgaG90c3BvdEtleSA9ICdob3RzcG90JyArIGtleTtcclxuXHRcdFx0aG90c3BvdHMucHVzaCg8SG90U3BvdHMga2V5PXtob3RzcG90S2V5fSBob3RzcG90PXtob3RzcG90fSBpbWdwcm9wcz17dGhpcy5zdGF0ZS5pbGx1c3RyYXRpb24uaW1nfSBjbGlja0hhbmRsZXI9e3RoaXMuaGFuZGxlQ2xpY2suYmluZCh0aGlzLCBob3RzcG90KX0gLz4pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9sZXQgaW1nc3JjRGV2ID0gJ2h0dHA6Ly9oaWFiZWNvbS1kZXYua25vd2l0ZWNvbW1lcmNlLnNlLycgKyB0aGlzLnByb3BzLmN1cnJlbnRDaGlsZC5JbGx1c3RyYXRpb24uSW1hZ2U7XHJcblx0XHRsZXQgaW1nc3JjID0gdGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQuSWxsdXN0cmF0aW9uLkltYWdlO1xyXG5cclxuXHRcdC8vbGV0IGltZ3NyYyA9ICdodHRwOi8vaGlhYmVjb20tZGV2Lmtub3dpdGVjb21tZXJjZS5zZS8nICsgdGhpcy5wcm9wcy5jdXJyZW50Q2hpbGQuSWxsdXN0cmF0aW9uLkltYWdlO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxmaWd1cmUgY2xhc3NOYW1lPScnPlxyXG5cdFx0XHRcdDxpbWcgc3JjPXtpbWdzcmN9IGFsdD0nJyBvbkxvYWQ9e3RoaXMuaW1nT25Mb2FkLmJpbmQodGhpcyl9IC8+XHJcblx0XHRcdFx0e2hvdHNwb3RzfVxyXG5cdFx0XHQ8L2ZpZ3VyZT5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IFZpc3VhbEJyb3dzaW5nO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBCcmVhZGNydW1iSXRlbSBmcm9tICcuL2JyZWFkY3J1bWJfaXRlbSc7XHJcbmltcG9ydCBCcmVhZGNydW1iQXBpIGZyb20gJy4uLy4uL19hcGkvYnJlYWRjcnVtYl9hcGknO1xyXG5cclxuY2xhc3MgQnJlYWRjcnVtYiBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHJcblx0XHR0aGlzLnN0YXRlID0gIHtcclxuXHRcdFx0YnJlYWRjcnVtYjogW10sXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0ZmV0Y2hCcmVhZGNydW1iKG1vZGVsSWQpIHtcclxuXHRcdGxldCBpc01hY2hpbmUgPSBmYWxzZTtcclxuXHRcdGxldCBpc01vZGVsID0gZmFsc2U7XHJcblx0XHRpZihoaWFiY29uZmlnLmhhc0VxdWlwbWVudFR5cGVSZXN0cmljdGlvbil7XHJcblx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJ1Yy1icmVhZGNydW1iXCIpWzBdLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKG1vZGVsSWQuc3Vic3RyaW5nKDAsIDgpID09ICdtYWNoaW5lLScpe1xyXG5cdFx0XHRpc01hY2hpbmUgPSB0cnVlO1xyXG5cdFx0XHRtb2RlbElkID0gbW9kZWxJZC5yZXBsYWNlKCdtYWNoaW5lLScsJycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKG1vZGVsSWQuc3Vic3RyaW5nKDAsIDYpPT0gJ21vZGVsLScpe1xyXG5cdFx0XHRpc01vZGVsID0gdHJ1ZTtcclxuXHRcdFx0bW9kZWxJZCA9IG1vZGVsSWQucmVwbGFjZSgnbW9kZWwtJywnJyk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoaXNNYWNoaW5lKXtcclxuXHRcdFx0QnJlYWRjcnVtYkFwaS5nZXRNYWNoaW5lQnJlYWRjcnVtYihtb2RlbElkKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoeyBicmVhZGNydW1iOiBbcmVzcG9uc2VdIH0pO1xyXG5cdFx0XHR9KS5jYXRjaCgobWVzc2FnZSkgPT4ge1xyXG5cdFx0XHRcdHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9ZWxzZSBpZihpc01vZGVsKXtcclxuXHRcdFx0QnJlYWRjcnVtYkFwaS5nZXRNb2RlbEJyZWFkY3J1bWIobW9kZWxJZCkudGhlbigocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHsgYnJlYWRjcnVtYjogW3Jlc3BvbnNlXSB9KTtcclxuXHRcdFx0fSkuY2F0Y2goKG1lc3NhZ2UpID0+IHtcclxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fWVsc2V7XHJcblx0XHRcdEJyZWFkY3J1bWJBcGkuZ2V0QnJlYWRjcnVtYihtb2RlbElkKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoeyBicmVhZGNydW1iOiByZXNwb25zZSB9KTtcclxuXHRcdFx0fSkuY2F0Y2goKG1lc3NhZ2UpID0+IHtcclxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHRpZih0aGlzLnByb3BzLm1vZGVsKXtcclxuXHRcdFx0dGhpcy5mZXRjaEJyZWFkY3J1bWIodGhpcy5wcm9wcy5tb2RlbCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblxyXG5cdFx0aWYoIXRoaXMucHJvcHMubW9kZWwpIFxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IGJyZWRjcnVtYkl0ZW1zID0gbnVsbDtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5zZWFyY2gubGFuZztcdFx0XHJcblx0XHRsZXQgbG9hZGluZyA9IFwiYnJlYWRjcnVtYnMgaXMtbG9hZGluZ1wiXHJcblx0XHRsZXQgaXNNYWNoaW5lID0gdGhpcy5wcm9wcy5tb2RlbC5zdWJzdHJpbmcoMCwgOCkgPT0gJ21hY2hpbmUtJztcclxuXHRcdGxldCBpc01vZGVsID0gdGhpcy5wcm9wcy5tb2RlbC5zdWJzdHJpbmcoMCwgNikgPT0gJ21vZGVsLSc7XHJcblxyXG5cdFx0aWYodGhpcy5zdGF0ZS5icmVhZGNydW1iLmxlbmd0aCA+IDApe1xyXG5cdFx0XHRsb2FkaW5nID0gXCJicmVhZGNydW1ic1wiO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKGlzTWFjaGluZSl7XHJcblx0XHRcdGlmKHRoaXMuc3RhdGUuYnJlYWRjcnVtYi5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRicmVkY3J1bWJJdGVtcyA9IDxsaSBjbGFzc05hbWU9XCJtYWNoaW5lLWJyZWFkY3J1bWItaXRlbVwiPntsYW5nLnNlcmlhbG51bWJlcn06IHt0aGlzLnN0YXRlLmJyZWFkY3J1bWJbMF0ubGFiZWx9IHzCoHt0aGlzLnN0YXRlLmJyZWFkY3J1bWJbMF0ubWF0ZXJpYWxudW1iZXJ9PC9saT5cclxuXHRcdFx0fVxyXG5cdFx0fWVsc2UgaWYoaXNNb2RlbCl7XHJcblx0XHRcdGlmKHRoaXMuc3RhdGUuYnJlYWRjcnVtYi5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRicmVkY3J1bWJJdGVtcyA9IDxsaSBjbGFzc05hbWU9XCJtYWNoaW5lLWJyZWFkY3J1bWItaXRlbVwiPnt0aGlzLnN0YXRlLmJyZWFkY3J1bWJbMF0ubW9kZWxOYW1lfTwvbGk+XHJcblx0XHRcdH1cclxuXHRcdH1lbHNle1xyXG5cdFx0XHRicmVkY3J1bWJJdGVtcyA9IHRoaXMuc3RhdGUuYnJlYWRjcnVtYi5tYXAoKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdFx0PEJyZWFkY3J1bWJJdGVtIGtleT17aXRlbS5JZH0gaXRlbT17aXRlbX0gbW9kZWw9e3RoaXMucHJvcHMubW9kZWx9IC8+XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8dWwgY2xhc3NOYW1lPXtsb2FkaW5nfT5cclxuXHRcdFx0XHR7IGJyZWRjcnVtYkl0ZW1zIH1cclxuXHRcdFx0PC91bD5cclxuXHRcdCk7XHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgQnJlYWRjcnVtYjtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQge0xpbmt9IGZyb20gJ3JlYWN0LXJvdXRlcic7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBCcmVhZGNydW1iU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9icmVhZGNydW1iX3N0b3JlJztcclxuaW1wb3J0IEhpc3RvcnlTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2hpc3Rvcnlfc3RvcmUnO1xyXG5pbXBvcnQgSGlzdG9yeUFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvaGlzdG9yeV9hY3Rpb25zJztcclxuXHJcbmNsYXNzIEJyZWFkY3J1bWJJdGVtIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2xpY2sgPSAoZSkgPT4ge1xyXG5cdFx0aWYodGhpcy5wcm9wcy5pdGVtLklkID09PSB0aGlzLnByb3BzLm1vZGVsKSByZXR1cm4gd2luZG93LmxvY2F0aW9uLnJlbG9hZCh0cnVlKTtcclxuXHRcdHRoaXMucHVzaFRvSGlzdG9yeSgpO1xyXG5cdFx0SGlzdG9yeVN0b3JlLnJlbW92ZUhpc3RvcnlBZnRlcih0aGlzLnByb3BzLml0ZW0uSWQpO1xyXG5cdFx0SGlzdG9yeVN0b3JlLnNldEN1cnJlbnROYXYoe1xyXG5cdFx0XHRJZDogdGhpcy5wcm9wcy5pdGVtLklkLFxyXG5cdFx0XHREZXNjcmlwdGlvbjogdGhpcy5wcm9wcy5pdGVtLkRlc2NyaXB0aW9uLFxyXG5cdFx0XHRJbGx1c3RyYXRpb246IHRoaXMucHJvcHMuaXRlbS5JbGx1c3RyYXRpb25cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vTm90aWZ5IG90aGVyIGNvbXBvbmVudHMgdGhhdCBoaXN0b3J5IGNoYW5nZWRcclxuXHRcdEhpc3RvcnlBY3Rpb25zLnN0b3JlVXBkYXRlZCgpO1xyXG5cdFx0JCgnYm9keScpLmFkZENsYXNzKCdicmFuZHRyZWUtb3BlbicpO1xyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdH1cclxuXHJcblx0cHVzaFRvSGlzdG9yeSgpIHtcclxuXHRcdC8vUHVzaCByb290IGVsZW1lbnQgdG8gaGlzdG9yeVxyXG5cdFx0SGlzdG9yeVN0b3JlLnNldChIaXN0b3J5U3RvcmUuZ2V0Q3VycmVudE5hdigpLklkLCBIaXN0b3J5U3RvcmUuZ2V0Q3VycmVudE5hdigpKTtcclxuXHJcblx0XHQvL1B1c2ggaXQgdG8gaGlzb3RyeVxyXG5cdFx0bGV0IGJyZWFkY3J1bWl0ZW1zID0gQnJlYWRjcnVtYlN0b3JlLmdldCh0aGlzLnByb3BzLm1vZGVsKS5kYXRhO1xyXG5cdFx0Zm9yKGxldCBpPTA7aTxicmVhZGNydW1pdGVtcy5sZW5ndGg7aSsrKSB7XHJcblx0XHRcdGxldCBpdGVtID0gYnJlYWRjcnVtaXRlbXNbaV07XHJcblx0XHRcdGxldCBoaXN0b3J5SXRlbSA9IHsgSWQ6IGl0ZW0uSWQsXHJcblx0XHRcdFx0XHRcdFx0XHREZXNjcmlwdGlvbjogaXRlbS5EZXNjcmlwdGlvbixcclxuXHRcdFx0XHRcdFx0XHRcdElsbHVzdHJhdGlvbjogaXRlbS5JbGx1c3RyYXRpb25cclxuXHRcdFx0XHRcdFx0XHR9O1xyXG5cclxuXHRcdFx0SGlzdG9yeVN0b3JlLnNldChoaXN0b3J5SXRlbS5JZCwgaGlzdG9yeUl0ZW0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0Y29uc3QgZXhwbG9kZWRWaWV3c1VybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMO1xyXG5cdFx0bGV0IGl0ZW0gPSB0aGlzLnByb3BzLml0ZW07XHJcblx0XHRsZXQgYnJlYWRDcnVtSXRlbSA9IDxMaW5rIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2suYmluZCh0aGlzKX0gdG89e2V4cGxvZGVkVmlld3NVcmwgKyB0aGlzLnByb3BzLm1vZGVsfT57aXRlbS5EZXNjcmlwdGlvbn08L0xpbms+O1xyXG5cdFx0XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8bGk+XHJcblx0XHRcdFx0e2JyZWFkQ3J1bUl0ZW19XHJcblx0XHRcdDwvbGk+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBCcmVhZGNydW1iSXRlbTtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBCcmFuZEZpbHRlclN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvYnJhbmRfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IEJyYW5kRmlsdGVyQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9icmFuZF9maWx0ZXJfYWN0aW9ucyc7XHJcblxyXG5pbXBvcnQgRmlsdGVyVG9nZ2xlIGZyb20gJy4vZmlsdGVyX3RvZ2dsZSc7XHJcblxyXG5sZXQgYnJhbmRMb2dvcyA9IHtcclxuICAnSGlhYnx8SElBQic6ICcvU3R5bGVzL0ltYWdlcy9Mb2dvcy9oaWFiX3NtYWxsLnBuZycsXHJcbiAgJ0pvbnNlcmVkfHxKT05TRVJFRCc6ICcvU3R5bGVzL0ltYWdlcy9Mb2dvcy9qb25zZXJlZF9zbWFsbC5wbmcnLFxyXG4gICdMb2dsaWZ0fHxMT0dMSUZUJzogJy9TdHlsZXMvSW1hZ2VzL0xvZ29zL2xvZ2xpZnRfc21hbGwucG5nJyxcclxuICAnTXVsdGlsaWZ0fHxNVUxUSUxJRlQnOiAnL1N0eWxlcy9JbWFnZXMvTG9nb3MvbXVsdGlsaWZ0X3NtYWxsLnBuZycsXHJcbiAgJ01vZmZldHR8fE1PRkZFVFQnOiAnL1N0eWxlcy9JbWFnZXMvTG9nb3MvbW9mZmV0dF9zbWFsbC5wbmcnLFxyXG4gICdEZWx8fERFTCc6ICcvU3R5bGVzL0ltYWdlcy9Mb2dvcy9kZWxfc21hbGwucG5nJyxcclxuICAnWmVwcm98fFpFUFJPJzogJy9TdHlsZXMvSW1hZ2VzL0xvZ29zL3plcHJvX3NtYWxsLnBuZycsXHJcbiAgJ1dhbHRjb3x8V0FMVENPJzogJy9TdHlsZXMvSW1hZ2VzL0xvZ29zL3dhbHRjb19zbWFsbC5wbmcnXHJcbn1cclxuXHJcbmxldCB0cmFuc2xhdGlvbnMgPSB7fTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJyYW5kRmlsdGVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG5cclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGZpbHRlcnM6IEJyYW5kRmlsdGVyU3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCksXHJcbiAgICB9XHJcblxyXG4gICAgdHJhbnNsYXRpb25zLmJyYW5kID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvQnJhbmQnKTtcclxuICB9XHJcblxyXG4gIGNvbXBvbmVudERpZE1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSA9IEJyYW5kRmlsdGVyU3RvcmUubGlzdGVuKHRoaXMub25GaWx0ZXJzQ2hhbmdlLmJpbmQodGhpcykpO1xyXG5cclxuICAgIC8vIG9uZSBtaW5vciBwcm9ibGVtOlxyXG4gICAgLy8gc29tZW9uZSBjbGlja2luZyBhIGNoZWNrYm94IGJlZm9yZSByZWFjdCBpcyBob29rZWQuIHBvc3NpYmxlIHNvbHV0aW9uczpcclxuICAgIC8vIDEpIExvb2sgdGhyb3VnaCBjaGVjYm94ZXMgaW4gdGhpcyBmdW5jdGlvbiBhbmQgc2V0IHN0YXRlIGFjY29yZGluZ2x5XHJcbiAgICAvLyAyKSBPciBrZWVwIGFsbCBjaGVja2JveGVzIGRpc2FibGVkXHJcbiAgfVxyXG5cclxuICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIG9uRmlsdGVyc0NoYW5nZShmaWx0ZXJzKSB7XHJcbiAgICB0aGlzLnNldFN0YXRlKHsgZmlsdGVycyB9KVxyXG4gIH1cclxuXHJcbiAgaGFuZGxlRmlsdGVyVG9nZ2xlKGJyYW5kKSB7XHJcbiAgICBCcmFuZEZpbHRlckFjdGlvbnMudG9nZ2xlRmlsdGVyKGJyYW5kKTtcclxuICB9XHJcblxyXG4gIGhhbmRsZUFsbEZpbHRlclRvZ2dsZSgpIHtcclxuICAgIC8vICdhbGwnIGZpbHRlciA9PSBubyBmaWx0ZXJcclxuICAgIEJyYW5kRmlsdGVyQWN0aW9ucy5jbGVhckZpbHRlcnMoKTtcclxuICB9XHJcblxyXG4gIHJlbmRlcigpIHtcclxuXHRcdC8vIGNvbnNvbGUubG9nKHRoaXMuc3RhdGUuZmlsdGVycyk7XHJcblx0XHQvLyByZXR1cm4gZmFsc2U7XHJcblx0XHRpZih0aGlzLnN0YXRlLmZpbHRlcnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgY29uc3Qgbm9GaWx0ZXJTZWxlY3RlZCA9IHRoaXMuc3RhdGUuZmlsdGVycy5maWx0ZXIoeCA9PiB4LnNlbGVjdGVkKS5sZW5ndGggPT0gMDtcclxuXHRcdHZhciBzZWxlY3RlZEFibGVJdGVtcyA9IGZhbHNlO1xyXG5cclxuXHRcdGxldCBpbnB1dHMgPSB0aGlzLnN0YXRlLmZpbHRlcnMubWFwKCh4KSA9PiB7XHJcblx0XHRcdFx0cmV0dXJuIDxGaWx0ZXJUb2dnbGUga2V5PXt4Lm5hbWV9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb3VudD17eC5jb3VudH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG5hbWU9e3gubmFtZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGxhYmVsPXt4LmRpc3BsYXlOYW1lfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bG9nbz17YnJhbmRMb2dvc1t4Lm5hbWVdfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aW5hY3RpdmU9e3guY291bnQgPT0gMH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHNlbGVjdGVkPXt4LnNlbGVjdGVkfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dG9nZ2xlPXt0aGlzLmhhbmRsZUZpbHRlclRvZ2dsZS5iaW5kKHRoaXMsIHgubmFtZSl9IC8+XHJcblx0XHR9KTtcclxuXHJcblx0XHRpZihpbnB1dHMubGVuZ3RoID4gMCl7XHJcblx0XHRcdHNlbGVjdGVkQWJsZUl0ZW1zID0gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgYnJhbmRPcGVuID0gY2xhc3NOYW1lcyh7XHJcblx0ICAgICdmaWx0ZXItd3JhcHBlcic6IHRydWUsXHJcblx0ICAgICdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0ICAgICdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHQgIH0pO1xyXG5cdCAgbGV0IGJyYW5kVG9nZ2xlID0gY2xhc3NOYW1lcyh7XHJcblx0ICAgICdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0ICAgICdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHQgIH0pO1xyXG5cclxuXHQgIHJldHVybiAoXHJcblx0ICAgIDxkaXYgY2xhc3NOYW1lPVwiZmlsdGVyLWl0ZW1cIj5cclxuXHQgICAgICA8aDMgY2xhc3NOYW1lPXticmFuZFRvZ2dsZX0gZGF0YS10b2dnbGU9XCIjYnJhbmQtZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy5icmFuZH08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuXHQgICAgICA8ZGl2IGNsYXNzTmFtZT17YnJhbmRPcGVufSBpZD1cImJyYW5kLWZpbHRlclwiPlxyXG5cdFx0XHRcdFx0PG5hdj5cclxuXHRcdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoZWNrYm94LWZpbHRlclwiPlxyXG5cdFx0XHRcdFx0XHR7c2VsZWN0ZWRBYmxlSXRlbXMgPyA8RmlsdGVyVG9nZ2xlIGxhYmVsPVwiQWxsXCIgc2VsZWN0ZWQ9e25vRmlsdGVyU2VsZWN0ZWR9IGluYWN0aXZlPXtmYWxzZX0gdG9nZ2xlPXt0aGlzLmhhbmRsZUFsbEZpbHRlclRvZ2dsZS5iaW5kKHRoaXMpfSAvPiA6IG51bGx9XHJcblx0XHRcdFx0XHRcdHtzZWxlY3RlZEFibGVJdGVtcyA/IGlucHV0cyA6IG51bGx9XHJcblx0XHRcdFx0XHRcdDwvdWw+XHJcblx0XHRcdFx0XHQ8L25hdj5cclxuXHQgICAgICA8L2Rpdj5cclxuXHQgICAgPC9kaXY+XHJcblx0ICApO1xyXG5cclxuICAgIC8vIHJldHVybiAoXHJcbiAgICAvLyAgIDxkaXYgY2xhc3NOYW1lPVwidWMtZmlsdGVyLWJyYW5kXCI+XHJcbiAgICAvLyAgICAgPGRpdiBjbGFzc05hbWU9XCJyb3dcIj5cclxuICAgIC8vICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic21hbGwtMTIgY29sdW1uc1wiPlxyXG4gICAgLy8gICAgICAgICA8dWwgY2xhc3NOYW1lPVwiY2hlY2tib3gtZmlsdGVyXCI+XHJcbiAgICAvLyAgICAgICAgICAgPEZpbHRlclRvZ2dsZSBsYWJlbD1cIkFsbFwiIHNlbGVjdGVkPXtub0ZpbHRlclNlbGVjdGVkfSBpbmFjdGl2ZT17ZmFsc2V9IHRvZ2dsZT17dGhpcy5oYW5kbGVBbGxGaWx0ZXJUb2dnbGUuYmluZCh0aGlzKX0gLz5cclxuXHRcdC8vXHJcbiAgICAvLyAgICAgICAgICAge3RoaXMuc3RhdGUuZmlsdGVycy5tYXAoeCA9PlxyXG4gICAgLy8gICAgICAgICAgICAgPEZpbHRlclRvZ2dsZSBrZXk9e3gubmFtZX1cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT17eC5uYW1lfVxyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17eC5uYW1lLnNwbGl0KFwifHxcIilbMV19XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ289e2JyYW5kTG9nb3NbeC5uYW1lXX1cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU9e3guY291bnQgPT0gMCAmJiAheC5zZWxlY3RlZH1cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ9e3guc2VsZWN0ZWR9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvZ2dsZT17dGhpcy5oYW5kbGVGaWx0ZXJUb2dnbGUuYmluZCh0aGlzLCB4Lm5hbWUpfSAvPiApfVxyXG4gICAgLy8gICAgICAgICA8L3VsPlxyXG4gICAgLy8gICAgICAgPC9kaXY+XHJcbiAgICAvLyAgICAgPC9kaXY+XHJcbiAgICAvLyAgIDwvZGl2PlxyXG4gICAgLy8gKVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgRmlsdGVyQ291bnRTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2ZpbHRlcl9jb3VudF9zdG9yZSc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGaWx0ZXJDb3VudCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGZpbHRlckNvdW50OiBGaWx0ZXJDb3VudFN0b3JlLmdldEluaXRpYWxTdGF0ZSgpXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlID0gRmlsdGVyQ291bnRTdG9yZS5saXN0ZW4odGhpcy5vbkZpbHRlckNvdW50VXBkYXRlLmJpbmQodGhpcykpO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBvbkZpbHRlckNvdW50VXBkYXRlKGZpbHRlckNvdW50KSB7XHJcbiAgICB0aGlzLnNldFN0YXRlKHsgZmlsdGVyQ291bnQgfSk7XHJcbiAgfVxyXG5cclxuICByZW5kZXIoKSB7XHJcbiAgICBjb25zdCB7IGZpbHRlckNvdW50IH0gPSB0aGlzLnN0YXRlO1xyXG5cclxuICAgIHJldHVybiAoXHJcbiAgICAgIDxzcGFuIGlkPVwiYWN0aXZlLWZpbHRlcnNcIj57ZmlsdGVyQ291bnR9PC9zcGFuPlxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuXHJcbmxldCBGaWx0ZXJUb2dnbGUgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7IGxhYmVsLCBuYW1lLCBjb3VudCwgbG9nbywgc2VsZWN0ZWQsIGluYWN0aXZlLCB0b2dnbGUgfSA9IHByb3BzO1xyXG5cclxuICBsZXQgY2xhc3NOYW1lID0gc2VsZWN0ZWQgPyAnaXMtc2VsZWN0ZWQgJyA6ICcnO1xyXG4gICAgICBjbGFzc05hbWUgKz0gaW5hY3RpdmUgPyAnaW5hY3RpdmUnIDogJyc7XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICA8bGkgY2xhc3NOYW1lPXtjbGFzc05hbWV9PlxyXG4gICAgICA8bGFiZWwgaHRtbEZvcj17bmFtZX0+XHJcblx0XHRcdFx0PGlucHV0IGlkPXtuYW1lfSBkaXNhYmxlZD17aW5hY3RpdmV9IGNoZWNrZWQ9e3NlbGVjdGVkfSB0eXBlPVwiY2hlY2tib3hcIiBvbkNoYW5nZT17dG9nZ2xlfSAvPlxyXG4gICAgICAgIHtsb2dvID8gPGltZyBzcmM9e2xvZ299IGFsdD17bGFiZWx9IC8+IDogbGFiZWx9XHJcblx0XHRcdFx0e3R5cGVvZiBjb3VudCAhPSAndW5kZWZpbmVkJyA/IDxzcGFuIGNsYXNzTmFtZT1cImNvdW50XCI+e2NvdW50fTwvc3Bhbj4gOiBudWxsfVxyXG4gICAgICA8L2xhYmVsPlxyXG4gICAgPC9saT5cclxuICApXHJcbn1cclxuXHJcbkZpbHRlclRvZ2dsZS5Qcm9wVHlwZXMgPSB7XHJcbiAgbGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgbG9nbzogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICBzZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2xlYW4sXHJcbiAgaW5hY3RpdmU6IFJlYWN0LlByb3BUeXBlcy5ib29sZWFuLFxyXG4gIHRvZ2dsZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmN0aW9uXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZpbHRlclRvZ2dsZTtcclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBTZWFyY2hSZXN1bHRTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3NlYXJjaF9yZXN1bHRfc3RvcmUnO1xyXG5pbXBvcnQgTG9jYWxpemF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9sb2NhbGl6YXRpb25fc3RvcmUnO1xyXG5pbXBvcnQgVXNhZ2VUeXBlRmlsdGVyQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy91c2FnZV90eXBlX2ZpbHRlcl9hY3Rpb25zJztcclxuXHJcbi8vIGltcG9ydCBHcm91cFNlbGVjdG9yIGZyb20gJy4uL3NlYXJjaC9ncm91cF9zZWxlY3Rvcic7XHJcbmltcG9ydCBGaWx0ZXJDb3VudCBmcm9tICcuL2ZpbHRlcl9jb3VudCc7XHJcbmltcG9ydCBVc2FnZVR5cGVGaWx0ZXIgZnJvbSAnLi91c2FnZV90eXBlX2ZpbHRlcic7XHJcbmltcG9ydCBTZXJpYWxOdW1iZXJGaWx0ZXIgZnJvbSAnLi9zZXJpYWxfbnVtYmVyX2ZpbHRlcic7XHJcbmltcG9ydCBCcmFuZEZpbHRlciBmcm9tICcuL2JyYW5kX2ZpbHRlcic7XHJcbi8vIGltcG9ydCBVc2FnZVR5cGVGaWx0ZXJTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3VzYWdlX3R5cGVfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IFByb2R1Y3RMaW5lRmlsdGVyIGZyb20gJy4vcHJvZHVjdF9saW5lX2ZpbHRlcic7XHJcbi8vIGltcG9ydCBQcm9kdWN0TGluZUZpbHRlclN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvcHJvZHVjdF9saW5lX2ZpbHRlcl9zdG9yZSc7XHJcbmltcG9ydCBUb3BDYXRlZ29yeUZpbHRlciBmcm9tICcuL3RvcF9jYXRlZ29yeV9maWx0ZXInO1xyXG4vLyBpbXBvcnQgVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3RvcF9jYXRlZ29yeV9maWx0ZXJfc3RvcmUnO1xyXG4vLyBpbXBvcnQgU2lnc0ZpbHRlciBmcm9tICcuL3NpZ3NfZmlsdGVyJztcclxuLy8gaW1wb3J0IFNvcnRlciBmcm9tICcuL3NvcnRlcic7XHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0ge307XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGaWx0ZXJzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG4gICAgdGhpcy5zdGF0ZSA9IHtcclxuICAgICAgc2VsZWN0ZWRHcm91cDogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0U2VsZWN0ZWRHcm91cCgpLFxyXG4gICAgICB0b3RhbE1hdGNoaW5nOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRUb3RhbE1hdGNoaW5nKCksXHJcbiAgICAgIGxvYWRpbmc6IFNlYXJjaFJlc3VsdFN0b3JlLmdldExvYWRpbmcoKSxcclxuICAgICAgcXVlcnk6IFNlYXJjaFN0b3JlLmdldFF1ZXJ5KCksXHJcbiAgICAgIHNob3dFeHRyYUZpbHRlcnM6IGZhbHNlLFxyXG5cdFx0XHQvLyBwcm9kdWN0TGluZUZpbHRlcnM6IFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCksXHJcblx0XHRcdC8vIHVzYWdlVHlwZUZpbHRlcnM6IFVzYWdlVHlwZUZpbHRlclN0b3JlLmdldEluaXRpYWxTdGF0ZSgpLFxyXG5cdFx0XHQvLyB0b3BDYXRlZ29yeUZpbHRlcnM6IFRvcENhdGVnb3J5RmlsdGVyU3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCksXHJcbiAgICB9O1xyXG5cclxuICAgIHRyYW5zbGF0aW9ucy5maWx0ZXJzID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9GaWx0ZXIvRmlsdGVycycpO1xyXG4gICAgdHJhbnNsYXRpb25zLmNsZWFyQWxsID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9GaWx0ZXIvQ2xlYXJBbGwnKTtcclxuICAgIHRyYW5zbGF0aW9ucy55b3VyU2VhcmNoRm9yID0gIExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL1NlYXJjaEZvcicpO1xyXG4gICAgdHJhbnNsYXRpb25zLnJlc3VsdGVkSW4gPSAgTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvUmVzdWx0ZWRJbicpO1xyXG4gICAgdHJhbnNsYXRpb25zLmhpdHMgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9IaXRzJyk7XHJcbiAgICB0cmFuc2xhdGlvbnMuaGl0ID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvSGl0Jyk7XHJcblx0ICB0cmFuc2xhdGlvbnMuc2VhcmNoaW5nID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvU2VhcmNoaW5nJyk7XHJcbiAgICB0cmFuc2xhdGlvbnMubG9hZGluZyA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL0xvYWRpbmcnKTtcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgdG9nZ2xlRXh0cmFGaWx0ZXJzKCkge1xyXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dFeHRyYUZpbHRlcnM6ICF0aGlzLnN0YXRlLnNob3dFeHRyYUZpbHRlcnMgfSk7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIGNvbXBvbmVudERpZE1vdW50KCl7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlMSA9IFNlYXJjaFJlc3VsdFN0b3JlLmxpc3RlbiggKCkgPT5cclxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XHJcbiAgICAgICAgc2VsZWN0ZWRHcm91cDogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0U2VsZWN0ZWRHcm91cCgpLFxyXG4gICAgICAgIHRvdGFsTWF0Y2hpbmc6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFRvdGFsTWF0Y2hpbmcoKSxcclxuICAgICAgICBsb2FkaW5nOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRMb2FkaW5nKCksXHJcblx0XHRcdFx0Ly8gcHJvZHVjdExpbmVGaWx0ZXJzOiBQcm9kdWN0TGluZUZpbHRlclN0b3JlLmdldEluaXRpYWxTdGF0ZSgpLFxyXG5cdFx0XHRcdC8vIHVzYWdlVHlwZUZpbHRlcnM6IFVzYWdlVHlwZUZpbHRlclN0b3JlLmdldEluaXRpYWxTdGF0ZSgpLFxyXG5cdFx0XHRcdC8vIHRvcENhdGVnb3J5RmlsdGVyczogVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZS5nZXRJbml0aWFsU3RhdGUoKSxcclxuICAgICAgfSlcclxuICAgICk7XHJcblxyXG4gICAgdGhpcy51bnN1YnNjcmliZTIgPSBTZWFyY2hTdG9yZS5saXN0ZW4oKCkgPT4ge1xyXG4gICAgICB0aGlzLnNldFN0YXRlKHtcclxuICAgICAgICBxdWVyeTogU2VhcmNoU3RvcmUuZ2V0UXVlcnkoKVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlMigpO1xyXG4gIH1cclxuXHJcbiAgcmVuZGVyKCkge1xyXG4gICAgY29uc3Qge3NlbGVjdGVkR3JvdXAsIHRvdGFsTWF0Y2hpbmcsIHF1ZXJ5LCBsb2FkaW5nLCBzaG93RXh0cmFGaWx0ZXJzfSA9IHRoaXMuc3RhdGU7XHJcbiAgICBsZXQgc2hvd0ZpbHRlcnMgPSAoc2VsZWN0ZWRHcm91cCA9PSAnc3BhcmVQYXJ0cycgfHwgc2VsZWN0ZWRHcm91cCA9PSAnbGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwnKSA/IHRydWUgOiBmYWxzZTtcclxuXHJcbiAgICBsZXQgaXNPblNlYXJjaFBhZ2UgPSB0eXBlb2YocXVlcnkpICE9PSAndW5kZWZpbmVkJztcclxuXHJcblx0XHQvLyBsZXQgaGFzVXNhZ2VUeXBlID0gdGhpcy5zdGF0ZS51c2FnZVR5cGVGaWx0ZXJzLmxlbmd0aCA+IDAgPyB0cnVlIDogZmFsc2U7XHJcblx0XHQvLyBsZXQgaGFzUHJvZHVjTGluZSA9IHRoaXMuc3RhdGUucHJvZHVjdExpbmVGaWx0ZXJzLmxlbmd0aCA+IDAgPyB0cnVlIDogZmFsc2U7XHJcblx0XHQvLyBsZXQgaGFzVG9wQ2F0ZWdvcnkgPSB0aGlzLnN0YXRlLnRvcENhdGVnb3J5RmlsdGVycy5sZW5ndGggPiAwID8gdHJ1ZSA6IGZhbHNlO1xyXG5cclxuXHRcdGxldCBmaWx0ZXJzQ2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J3VjLWZpbHRlcnMnOiB0cnVlLFxyXG5cdFx0XHQnaXMtbG9hZGluZyc6IHRoaXMuc3RhdGUubG9hZGluZ1xyXG5cdFx0fSk7XHJcblx0XHQvLyB7aXNPblNlYXJjaFBhZ2UgPyA8VXNhZ2VUeXBlIGlzT3Blbj17dHJ1ZX0gaGFzSXRlbXM9e2hhc1VzYWdlVHlwZX0gLz4gOiA8VXNhZ2VUeXBlIGlzT3Blbj17ZmFsc2V9IGhhc0l0ZW1zPXtoYXNVc2FnZVR5cGV9IC8+fVxyXG5cdFx0Ly8ge2lzT25TZWFyY2hQYWdlID8gPFByb2R1Y3RMaW5lIGlzT3Blbj17dHJ1ZX0gaGFzSXRlbXM9e2hhc1Byb2R1Y0xpbmV9IC8+IDogPFByb2R1Y3RMaW5lIGlzT3Blbj17ZmFsc2V9IGhhc0l0ZW1zPXtoYXNQcm9kdWNMaW5lfSAvPn1cclxuXHRcdC8vIHtpc09uU2VhcmNoUGFnZSA/IDxUb3BDYXRlZ29yeSBpc09wZW49e3RydWV9IGhhc0l0ZW1zPXtoYXNUb3BDYXRlZ29yeX0gLz4gOiBudWxsfVxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPHNlY3Rpb24gY2xhc3NOYW1lPXtmaWx0ZXJzQ2xhc3N9PlxyXG4gICAgICAgIHsgU2VhcmNoUmVzdWx0U3RvcmUuZ2V0VXNlclNpZ25lZEluKCkgPyAoaXNPblNlYXJjaFBhZ2UgPyA8U2VyaWFsTnVtYmVyRmlsdGVyIGlzT3Blbj17dHJ1ZX0gLz4gOiBudWxsKSA6IG51bGwgfVxyXG5cdFx0XHRcdHtpc09uU2VhcmNoUGFnZSA/IDxCcmFuZEZpbHRlciBpc09wZW49e3RydWV9ICAvPiA6IDxCcmFuZEZpbHRlciBpc09wZW49e2ZhbHNlfSAgLz59XHJcblx0XHRcdFx0e2lzT25TZWFyY2hQYWdlID8gPFByb2R1Y3RMaW5lRmlsdGVyIGlzT3Blbj17dHJ1ZX0gIC8+IDogPFByb2R1Y3RMaW5lRmlsdGVyIGlzT3Blbj17ZmFsc2V9ICAvPn1cclxuXHRcdFx0XHR7aXNPblNlYXJjaFBhZ2UgPyA8VG9wQ2F0ZWdvcnlGaWx0ZXIgaXNPcGVuPXt0cnVlfSAgLz4gOiBudWxsfVxyXG4gICAgICAgIHtpc09uU2VhcmNoUGFnZSA/IDxVc2FnZVR5cGVGaWx0ZXIgaXNPcGVuPXt0cnVlfSAgLz4gOiA8VXNhZ2VUeXBlRmlsdGVyIGlzT3Blbj17ZmFsc2V9ICAvPn1cclxuICAgICAgPC9zZWN0aW9uPlxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuXHJcbi8vIGNvbnN0IFVzYWdlVHlwZSA9IChwcm9wcykgPT57XHJcbi8vXHJcbi8vICAgbGV0IHVzYWdlVHlwZU9wZW4gPSBjbGFzc05hbWVzKHtcclxuLy8gICAgICdmaWx0ZXItd3JhcHBlcic6IHRydWUsXHJcbi8vICAgICAnaXMtb3Blbic6IHByb3BzLmlzT3BlbixcclxuLy8gICAgICdoYXMtaXRlbXMnOiBwcm9wcy5oYXNJdGVtc1xyXG4vLyAgIH0pO1xyXG4vLyAgIGxldCB1c2FnZVR5cGVUb2dnbGUgPSBjbGFzc05hbWVzKHtcclxuLy8gICAgICdpcy1vcGVuJzogcHJvcHMuaXNPcGVuLFxyXG4vLyAgICAgJ2hhcy1pdGVtcyc6IHByb3BzLmhhc0l0ZW1zXHJcbi8vICAgfSk7XHJcbi8vXHJcbi8vICAgcmV0dXJuKFxyXG4vLyAgICAgPGRpdiBjbGFzc05hbWU9XCJmaWx0ZXItaXRlbVwiPlxyXG4vLyAgICAgICA8aDMgY2xhc3NOYW1lPXt1c2FnZVR5cGVUb2dnbGV9IGRhdGEtdG9nZ2xlPVwiI3VzYWdlLXR5cGUtZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy51c2FnZVR5cGV9PGkgY2xhc3NOYW1lPVwiaWNvbi1hbmdsZS1kb3duXCI+PC9pPjwvaDM+XHJcbi8vICAgICAgIDxkaXYgY2xhc3NOYW1lPXt1c2FnZVR5cGVPcGVufSBpZD1cInVzYWdlLXR5cGUtZmlsdGVyXCI+XHJcbi8vICAgICAgICAgPFVzYWdlVHlwZUZpbHRlciAvPlxyXG4vLyAgICAgICA8L2Rpdj5cclxuLy8gICAgIDwvZGl2PlxyXG4vLyAgICk7XHJcbi8vIH1cclxuLy9cclxuLy8gY29uc3QgUHJvZHVjdExpbmUgPSAocHJvcHMpID0+e1xyXG4vL1xyXG4vLyAgIGxldCBwcm9kdWN0TGluZU9wZW4gPSBjbGFzc05hbWVzKHtcclxuLy8gICAgICdmaWx0ZXItd3JhcHBlcic6IHRydWUsXHJcbi8vICAgICAnaXMtb3Blbic6IHByb3BzLmlzT3BlbixcclxuLy8gICAgICdoYXMtaXRlbXMnOiBwcm9wcy5oYXNJdGVtc1xyXG4vLyAgIH0pO1xyXG4vLyAgIGxldCBwcm9kdWN0TGluZVRvZ2dsZSA9IGNsYXNzTmFtZXMoe1xyXG4vLyAgICAgJ2lzLW9wZW4nOiBwcm9wcy5oYXNJdGVtcyxcclxuLy8gICAgICdoYXMtaXRlbXMnOiBwcm9wcy5oYXNJdGVtc1xyXG4vLyAgIH0pO1xyXG4vL1xyXG4vLyAgIHJldHVybiAoXHJcbi8vICAgICA8ZGl2IGNsYXNzTmFtZT1cImZpbHRlci1pdGVtXCI+XHJcbi8vICAgICAgIDxoMyBjbGFzc05hbWU9e3Byb2R1Y3RMaW5lVG9nZ2xlfSBkYXRhLXRvZ2dsZT1cIiNwcm9kdWN0LWxpbmUtZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy5wcm9kdWN0TGluZX08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuLy8gICAgICAgPGRpdiBjbGFzc05hbWU9e3Byb2R1Y3RMaW5lT3Blbn0gaWQ9XCJwcm9kdWN0LWxpbmUtZmlsdGVyXCI+XHJcbi8vICAgICAgICAgPFByb2R1Y3RMaW5lRmlsdGVyIC8+XHJcbi8vICAgICAgIDwvZGl2PlxyXG4vLyAgICAgPC9kaXY+XHJcbi8vICAgKTtcclxuLy8gfVxyXG4vL1xyXG4vLyBjb25zdCBUb3BDYXRlZ29yeSA9IChwcm9wcykgPT57XHJcbi8vXHJcbi8vICAgbGV0IHRvcENhdGVnb3J5T3BlbiA9IGNsYXNzTmFtZXMoe1xyXG4vLyAgICAgJ2ZpbHRlci13cmFwcGVyJzogdHJ1ZSxcclxuLy8gICAgICdpcy1vcGVuJzogcHJvcHMuaXNPcGVuLFxyXG4vLyAgICAgJ2hhcy1pdGVtcyc6IHByb3BzLmhhc0l0ZW1zXHJcbi8vICAgfSk7XHJcbi8vICAgbGV0IHRvcENhdGVnb3J5VG9nZ2xlID0gY2xhc3NOYW1lcyh7XHJcbi8vICAgICAnaXMtb3Blbic6IHByb3BzLmlzT3BlbixcclxuLy8gICAgICdoYXMtaXRlbXMnOiBwcm9wcy5oYXNJdGVtc1xyXG4vLyAgIH0pO1xyXG4vL1xyXG4vLyAgIHJldHVybiAoXHJcbi8vICAgICA8ZGl2IGNsYXNzTmFtZT1cImZpbHRlci1pdGVtXCI+XHJcbi8vICAgICAgIDxoMyBjbGFzc05hbWU9e3RvcENhdGVnb3J5VG9nZ2xlfSBkYXRhLXRvZ2dsZT1cIiN0b3AtY2F0ZWdvcnktZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy50b3BDYXRlZ29yeX08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuLy8gICAgICAgPGRpdiBjbGFzc05hbWU9e3RvcENhdGVnb3J5T3Blbn0gaWQ9XCJ0b3AtY2F0ZWdvcnktZmlsdGVyXCI+XHJcbi8vICAgICAgICAgPFRvcENhdGVnb3J5RmlsdGVyIC8+XHJcbi8vICAgICAgIDwvZGl2PlxyXG4vLyAgICAgPC9kaXY+XHJcbi8vICAgKTtcclxuLy8gfVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9wcm9kdWN0X2xpbmVfZmlsdGVyX3N0b3JlJztcclxuLy8gaW1wb3J0IFVzYWdlVHlwZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvdXNhZ2VfdHlwZV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBQcm9kdWN0TGluZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvcHJvZHVjdF9saW5lX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IExvY2FsaXphdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvbG9jYWxpemF0aW9uX3N0b3JlJztcclxuXHJcbmltcG9ydCBGaWx0ZXJUb2dnbGUgZnJvbSAnLi9maWx0ZXJfdG9nZ2xlJztcclxuXHJcbmxldCB0cmFuc2xhdGlvbnMgPSB7fTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByb2R1Y3RMaW5lRmlsdGVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG5cclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGZpbHRlcnM6IFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCksXHJcbiAgICB9XHJcblxyXG5cdFx0dHJhbnNsYXRpb25zLnByb2R1Y3RMaW5lID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvUHJvZHVjdExpbmVUaXRsZScpO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlID0gUHJvZHVjdExpbmVGaWx0ZXJTdG9yZS5saXN0ZW4odGhpcy5vbkZpbHRlcnNDaGFuZ2UuYmluZCh0aGlzKSk7XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIG9uRmlsdGVyc0NoYW5nZShmaWx0ZXJzKSB7XHJcbiAgICB0aGlzLnNldFN0YXRlKHsgZmlsdGVycyB9KVxyXG4gIH1cclxuXHJcblx0aGFuZGxlRmlsdGVyVG9nZ2xlKHByb2R1Y3RMaW5lKSB7XHJcblx0XHQvLyBjb25zb2xlLmxvZygna2xpY2snKTtcclxuXHRcdFByb2R1Y3RMaW5lRmlsdGVyQWN0aW9ucy50b2dnbGVGaWx0ZXIocHJvZHVjdExpbmUpO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQWxsRmlsdGVyVG9nZ2xlKCkge1xyXG5cdFx0Ly8gJ2FsbCcgZmlsdGVyID09IG5vIGZpbHRlclxyXG5cdFx0UHJvZHVjdExpbmVGaWx0ZXJBY3Rpb25zLm9uQ2xlYXJGaWx0ZXJzKCk7XHJcblx0fVxyXG5cclxuICByZW5kZXIoKSB7XHJcblx0XHRpZih0aGlzLnN0YXRlLmZpbHRlcnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgY29uc3Qgbm9GaWx0ZXJTZWxlY3RlZCA9IHRoaXMuc3RhdGUuZmlsdGVycy5maWx0ZXIoeCA9PiB4LnNlbGVjdGVkKS5sZW5ndGggPT0gMDtcclxuXHRcdHZhciBzZWxlY3RlZEFibGVJdGVtcyA9IGZhbHNlO1xyXG5cclxuXHRcdGxldCBpbnB1dHMgPSB0aGlzLnN0YXRlLmZpbHRlcnMubWFwKCh4KSA9PiB7XHJcblx0XHRcdFx0cmV0dXJuIDxGaWx0ZXJUb2dnbGUga2V5PXt4Lm5hbWV9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb3VudD17eC5jb3VudH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG5hbWU9e3gubmFtZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGxhYmVsPXt4LmRpc3BsYXlOYW1lfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aW5hY3RpdmU9e3guY291bnQgPT0gMH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHNlbGVjdGVkPXt4LnNlbGVjdGVkfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dG9nZ2xlPXt0aGlzLmhhbmRsZUZpbHRlclRvZ2dsZS5iaW5kKHRoaXMsIHgubmFtZSl9IC8+XHJcblx0XHR9KTtcclxuXHJcblx0XHRpZihpbnB1dHMubGVuZ3RoID4gMCl7XHJcblx0XHRcdHNlbGVjdGVkQWJsZUl0ZW1zID0gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgcHJvZHVjdExpbmVPcGVuID0gY2xhc3NOYW1lcyh7XHJcblx0ICAgICdmaWx0ZXItd3JhcHBlcic6IHRydWUsXHJcblx0ICAgICdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0ICAgICdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHQgIH0pO1xyXG5cdCAgbGV0IHByb2R1Y3RMaW5lVG9nZ2xlID0gY2xhc3NOYW1lcyh7XHJcblx0ICAgICdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0ICAgICdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHQgIH0pO1xyXG5cclxuXHQgIHJldHVybiAoXHJcblx0ICAgIDxkaXYgY2xhc3NOYW1lPVwiZmlsdGVyLWl0ZW1cIj5cclxuXHQgICAgICA8aDMgY2xhc3NOYW1lPXtwcm9kdWN0TGluZVRvZ2dsZX0gZGF0YS10b2dnbGU9XCIjcHJvZHVjdC1saW5lLWZpbHRlclwiPnt0cmFuc2xhdGlvbnMucHJvZHVjdExpbmV9PGkgY2xhc3NOYW1lPVwiaWNvbi1hbmdsZS1kb3duXCI+PC9pPjwvaDM+XHJcblx0ICAgICAgPGRpdiBjbGFzc05hbWU9e3Byb2R1Y3RMaW5lT3Blbn0gaWQ9XCJwcm9kdWN0LWxpbmUtZmlsdGVyXCI+XHJcblx0XHRcdFx0XHQ8bmF2PlxyXG5cdFx0XHRcdFx0XHQ8dWwgY2xhc3NOYW1lPVwiY2hlY2tib3gtZmlsdGVyXCI+XHJcblx0XHRcdFx0XHRcdHtzZWxlY3RlZEFibGVJdGVtcyA/IDxGaWx0ZXJUb2dnbGUgbGFiZWw9XCJBbGxcIiBzZWxlY3RlZD17bm9GaWx0ZXJTZWxlY3RlZH0gaW5hY3RpdmU9e2ZhbHNlfSB0b2dnbGU9e3RoaXMuaGFuZGxlQWxsRmlsdGVyVG9nZ2xlLmJpbmQodGhpcyl9IC8+IDogbnVsbH1cclxuXHRcdFx0XHRcdFx0e3NlbGVjdGVkQWJsZUl0ZW1zID8gaW5wdXRzIDogbnVsbH1cclxuXHRcdFx0XHRcdFx0PC91bD5cclxuXHRcdFx0XHRcdDwvbmF2PlxyXG5cdCAgICAgIDwvZGl2PlxyXG5cdCAgICA8L2Rpdj5cclxuXHQgICk7XHJcblxyXG4gICAgLy8gcmV0dXJuIChcclxuXHRcdC8vIFx0PG5hdj5cclxuXHQgIC8vICAgICA8dWwgY2xhc3NOYW1lPVwiY2hlY2tib3gtZmlsdGVyXCI+XHJcblx0XHQvLyBcdFx0e3NlbGVjdGVkQWJsZUl0ZW1zID8gPEZpbHRlclRvZ2dsZSBsYWJlbD1cIkFsbFwiIHNlbGVjdGVkPXtub0ZpbHRlclNlbGVjdGVkfSBpbmFjdGl2ZT17ZmFsc2V9IHRvZ2dsZT17dGhpcy5oYW5kbGVBbGxGaWx0ZXJUb2dnbGUuYmluZCh0aGlzKX0gLz4gOiBudWxsfVxyXG5cdFx0Ly8gXHRcdHtzZWxlY3RlZEFibGVJdGVtcyA/IGlucHV0cyA6IG51bGx9XHJcblx0XHQvLyBcdFx0e3NlbGVjdGVkQWJsZUl0ZW1zID8gbnVsbCA6IG5vSXRlbXN9XHJcblx0ICAvLyAgICAgPC91bD5cclxuXHRcdC8vIFx0PC9uYXY+XHJcbiAgICAvLyApXHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWZsdXggZnJvbSAncmVmbHV4JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBTZXJpYWxOdW1iZXJGaWx0ZXJTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3NlcmlhbF9udW1iZXJfZmlsdGVyX3N0b3JlJztcclxuLy8gaW1wb3J0IFVzYWdlVHlwZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvdXNhZ2VfdHlwZV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBTZXJpYWxOdW1iZXJGaWx0ZXJBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3NlcmlhbF9udW1iZXJfZmlsdGVyX2FjdGlvbnMnO1xyXG5pbXBvcnQgTG9jYWxpemF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9sb2NhbGl6YXRpb25fc3RvcmUnO1xyXG5cclxuaW1wb3J0IEZpbHRlclRvZ2dsZSBmcm9tICcuL2ZpbHRlcl90b2dnbGUnO1xyXG5cclxubGV0IHRyYW5zbGF0aW9ucyA9IHt9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VyaWFsTnVtYmVyRmlsdGVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0Ly8gQ29ubmVjdHMgdGhpcy5zdGF0ZSBpbiBjb21wb25lbnQgdG8gdGhpcy5kYXRhIGluIHN0b3JlXHJcbiBcdFx0bWl4aW5zOiBbIFJlZmx1eC5jb25uZWN0KFNlcmlhbE51bWJlckZpbHRlclN0b3JlLCBcInNlcmlhbE51bWJlckZpbHRlclwiKSBdLFxyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0c2VyaWFsTnVtYmVyOiBcIlwiLFxyXG5cdFx0XHRzaG93RW1wdHlWYWx1ZUJ1dHRvbjogZmFsc2UsXHJcblx0XHRcdHNlcmlhbE5vSW52YWxpZDogZmFsc2VcclxuXHRcdH1cclxuXHJcblx0XHR0cmFuc2xhdGlvbnMuc2VyaWFsQXBwbHlCdXR0b25UZXh0ID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvRmlsdGVycy9TZXJpYWwvQXBwbHlCdXR0b25UZXh0JylcclxuXHRcdHRyYW5zbGF0aW9ucy5zZXJpYWxQbGFjZWhvbGRlclRleHQgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9GaWx0ZXJzL1NlcmlhbC9QbGFjZWhvbGRlclRleHQnKVxyXG5cdFx0dHJhbnNsYXRpb25zLnNlcmlhbERlc2NyaXB0aW9uID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvRmlsdGVycy9TZXJpYWwvRGVzY3JpcHRpb24nKVxyXG5cdFx0dHJhbnNsYXRpb25zLnNlcmlhbFRpdGxlID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvRmlsdGVycy9TZXJpYWwvVGl0bGUnKVxyXG5cdFx0dHJhbnNsYXRpb25zLnNlcmlhbEVycm9yTm90Rm91bmQgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9GaWx0ZXJzL1NlcmlhbC9FcnJvci9TZXJpYWxOb3RGb3VuZCcpXHJcblx0fVxyXG5cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBTZXJpYWxOdW1iZXJGaWx0ZXJTdG9yZS5saXN0ZW4odGhpcy5vblVwZGF0ZUZpbHRlcnMuYmluZCh0aGlzKSk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUoKTtcclxuXHR9XHJcblx0ZW1wdHlGaWx0ZXJGaWVsZCA9ICgpID0+IHtcclxuXHRcdHRoaXMuc2V0U3RhdGUoeyBzZXJpYWxOdW1iZXI6IFwiXCIsIHNlcmlhbE5vSW52YWxpZDogZmFsc2UgfSk7XHJcblx0XHRTZXJpYWxOdW1iZXJGaWx0ZXJBY3Rpb25zLmNsZWFyRmlsdGVyKCk7XHJcblx0fVxyXG5cdGhhbmRsZUZpbHRlclRvZ2dsZSgpIHtcclxuXHRcdFNlcmlhbE51bWJlckZpbHRlckFjdGlvbnMuYXBwbHlGaWx0ZXIodGhpcy5zdGF0ZS5zZXJpYWxOdW1iZXIpO1xyXG5cdH1cclxuXHRvblVwZGF0ZUZpbHRlcnMoKSB7XHJcblx0XHR0aGlzLnNldFN0YXRlKHsgc2VyaWFsTm9JbnZhbGlkOiBTZXJpYWxOdW1iZXJGaWx0ZXJTdG9yZS5zZXJpYWxOb0ludmFsaWR9KVxyXG5cdFx0aWYodGhpcy5zdGF0ZS5zZXJpYWxOdW1iZXIgPT0gXCJcIikge1xyXG5cdFx0XHQvL0JhY2tlbmQgcmV0dXJucyBzZXJpYWwgaXMgaW52YWxpZCAtZmxhZyB3aXRoIGFuIGVtcHR5IHNlcmlhbCBwYXNzZWQsIHNvIGhhbmRsZSB0aGF0IGhlcmUuICh0aGVyZSBzaG91bGQgbm90IGJlIGEgdmlzdWFsIGVycm9yIGRpc3BsYXllZCB0aGVuKVxyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHsgc2VyaWFsTm9JbnZhbGlkOiBmYWxzZSB9KVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHJcblx0XHRsZXQgc2VyaWFsRmlsdGVyT3BlbiA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnZmlsdGVyLXdyYXBwZXInOiB0cnVlLFxyXG5cdFx0XHQnaXMtb3Blbic6IHRoaXMucHJvcHMuaXNPcGVuLFxyXG5cdFx0XHQnaGFzLWl0ZW1zJzogdHJ1ZSwgLy9wcm9wcy5oYXNJdGVtc1xyXG5cdFx0XHQnc2VyaWFsLWZpbHRlci13cmFwcGVyJzogdHJ1ZVxyXG5cdFx0fSk7XHJcblx0XHRsZXQgc2VyaWFsRmlsdGVyVG9nZ2xlID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0XHRcdCdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiZmlsdGVyLWl0ZW1cIj5cclxuXHRcdFx0XHQ8aDMgY2xhc3NOYW1lPXtzZXJpYWxGaWx0ZXJUb2dnbGV9IGRhdGEtdG9nZ2xlPVwiI3NlcmlhbC1udW1iZXItZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy5zZXJpYWxUaXRsZX08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT17c2VyaWFsRmlsdGVyT3Blbn0gaWQ9XCJzZXJpYWwtbnVtYmVyLWZpbHRlclwiPlxyXG5cdFx0XHRcdFx0PHN0cm9uZz57dHJhbnNsYXRpb25zLnNlcmlhbERlc2NyaXB0aW9ufTwvc3Ryb25nPlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJzZXJpYWwtZmlsdGVyLWlucHV0LXdyYXBwZXJcIj5cclxuXHRcdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJ0ZXh0XCIgbmFtZT1cInNlcmlhbC1maWx0ZXItaW5wdXRcIiBwbGFjZWhvbGRlcj17dHJhbnNsYXRpb25zLnNlcmlhbFBsYWNlaG9sZGVyVGV4dH0gY2xhc3NOYW1lPXt0aGlzLnN0YXRlLnNlcmlhbE5vSW52YWxpZCA/ICdzZXJpYWwtZmlsdGVyLWlucHV0IGVycm9yJyA6ICdzZXJpYWwtZmlsdGVyLWlucHV0J30gdmFsdWU9e3RoaXMuc3RhdGUuc2VyaWFsTnVtYmVyfSBvbkNoYW5nZT17ZSA9PiB0aGlzLnNldFN0YXRlKHtzZXJpYWxOdW1iZXI6IGUudGFyZ2V0LnZhbHVlfSl9PjwvaW5wdXQ+XHJcblx0XHRcdFx0XHRcdHsgdGhpcy5zdGF0ZS5maWx0ZXJWYWx1ZSAhPSBcIlwiID8gPGEgaHJlZj1cIiNcIiBjbGFzc05hbWU9XCJlbXB0eS1maWx0ZXItdmFsdWVcIiBvbkNsaWNrPXt0aGlzLmVtcHR5RmlsdGVyRmllbGQuYmluZCh0aGlzKX0+PGkgY2xhc3NOYW1lPVwiaWNvbi1jYW5jZWwtY2lyY2xlZFwiPjwvaT48L2E+IDogXCJcIiB9XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdHt0aGlzLnN0YXRlLnNlcmlhbE5vSW52YWxpZCAmJlxyXG5cdFx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJlcnJvclwiPnt0cmFuc2xhdGlvbnMuc2VyaWFsRXJyb3JOb3RGb3VuZH08L3NwYW4+XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiB3YXZlcy1lZmZlY3Qgd2F2ZXMtbGlnaHQgc2VyaWFsLWZpbHRlci1hcHBseS1idXR0b25cIiBvbkNsaWNrPXt0aGlzLmhhbmRsZUZpbHRlclRvZ2dsZS5iaW5kKHRoaXMpfT57dHJhbnNsYXRpb25zLnNlcmlhbEFwcGx5QnV0dG9uVGV4dH08L2J1dHRvbj5cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgU29ydFN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvc29ydF9zdG9yZSc7XHJcbmltcG9ydCBTb3J0QWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9zb3J0X2FjdGlvbnMnO1xyXG5pbXBvcnQgTG9jYWxpemF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9sb2NhbGl6YXRpb25fc3RvcmUnO1xyXG5pbXBvcnQgU2VhcmNoUmVzdWx0U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9zZWFyY2hfcmVzdWx0X3N0b3JlJztcclxuXHJcbmxldCB0cmFuc2xhdGlvbnMgPSB7fTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNvcnRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuXHJcbiAgICB2YXIgc29ydFN0b3JlU3RhdGUgPSBTb3J0U3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCk7XHJcbiAgICB0aGlzLnN0YXRlID0ge1xyXG4gICAgICBvcmRlcjogc29ydFN0b3JlU3RhdGUub3JkZXIsXHJcbiAgICAgIGZpZWxkOiBzb3J0U3RvcmVTdGF0ZS5maWVsZCxcclxuICAgICAgc29ydEZpZWxkczogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0U29ydEZpZWxkcygpXHJcbiAgICB9O1xyXG5cclxuICAgIHRyYW5zbGF0aW9ucy5zb3J0QnkgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL0ZpbHRlci9Tb3J0QnknKTtcclxuICAgIHRyYW5zbGF0aW9ucy5hc2NlbmRpbmcgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL0ZpbHRlci9Bc2NlbmRpbmcnKTtcclxuICAgIHRyYW5zbGF0aW9ucy5kZXNjZW5kaW5nID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9GaWx0ZXIvRGVzY2VuZGluZycpO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XHJcbiAgICB0aGlzLnNvcnRVbnN1YnNjcmliZSA9IFNvcnRTdG9yZS5saXN0ZW4odGhpcy5vblNvcnRTdG9yZVVwZGF0ZS5iaW5kKHRoaXMpKTtcclxuXHJcbiAgICB0aGlzLnNlYXJjaFJlc3VsdFVuc3Vic2NyaWJlID0gU2VhcmNoUmVzdWx0U3RvcmUubGlzdGVuKCAoKSA9PlxyXG4gICAgICB0aGlzLnNldFN0YXRlKHtcclxuICAgICAgICBzb3J0RmllbGRzOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRTb3J0RmllbGRzKClcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMuc29ydFVuc3Vic2NyaWJlKCk7XHJcbiAgICB0aGlzLnNlYXJjaFJlc3VsdFVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuXHJcbiAgb25Tb3J0U3RvcmVVcGRhdGUoc3RvcmVTdGF0ZSkge1xyXG4gICAgdGhpcy5zZXRTdGF0ZShzdG9yZVN0YXRlKTtcclxuICB9XHJcblxyXG4gIGhhbmRsZUZpZWxkQ2hhbmdlKGUpIHtcclxuICAgIGxldCBmaWVsZCA9IGUudGFyZ2V0LnZhbHVlO1xyXG4gICAgU29ydEFjdGlvbnMuc2V0RmllbGQoZmllbGQpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlT3JkZXJDaGFuZ2UoZSkge1xyXG4gICAgbGV0IG9yZGVyID0gZS50YXJnZXQudmFsdWU7XHJcbiAgICBTb3J0QWN0aW9ucy5zZXRPcmRlcihvcmRlcik7XHJcbiAgfVxyXG5cclxuICByZW5kZXIoKSB7XHJcbiAgICBsZXQgc29ydE9wdGlvbnMgPSBbXTtcclxuICAgIGZvciAobGV0IGZpZWxkIGluIHRoaXMuc3RhdGUuc29ydEZpZWxkcykge1xyXG4gICAgICBsZXQgZmllbGROYW1lID0gdGhpcy5zdGF0ZS5zb3J0RmllbGRzW2ZpZWxkXTtcclxuICAgICAgc29ydE9wdGlvbnMucHVzaCg8b3B0aW9uIHZhbHVlPXtmaWVsZH0ga2V5PXtcInNvcnQtXCIgKyBmaWVsZH0+e2ZpZWxkTmFtZX08L29wdGlvbj4pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJ1Yy1saXN0LXNvcnRlclwiPlxyXG4gICAgICAgIDxzZWxlY3RcclxuICAgICAgICAgIGtleT1cInNvcnQtYnlcIlxyXG4gICAgICAgICAgc2VsZWN0ZWQ9e3RoaXMuc3RhdGUuc29ydEJ5VHlwZX1cclxuICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUZpZWxkQ2hhbmdlfVxyXG4gICAgICAgICAgY2xhc3NOYW1lPVwic29ydC1ieSBsZWZ0IHR5cGVcIlxyXG4gICAgICAgICAgaWQ9XCJzb3J0eWJ5XCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICB7c29ydE9wdGlvbnN9XHJcbiAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgIFx0PHNlbGVjdCBjbGFzc05hbWU9XCJzb3J0LWRpcmVjdGlvblwiXHJcbiAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5zdGF0ZS5vcmRlcn1cclxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZU9yZGVyQ2hhbmdlfT5cclxuICAgICAgXHRcdDxvcHRpb24gdmFsdWU9XCJhc2NlbmRpbmdcIj57dHJhbnNsYXRpb25zLmFzY2VuZGluZ308L29wdGlvbj5cclxuICAgICAgXHRcdDxvcHRpb24gdmFsdWU9XCJkZXNjZW5kaW5nXCI+e3RyYW5zbGF0aW9ucy5kZXNjZW5kaW5nfTwvb3B0aW9uPlxyXG4gICAgICBcdDwvc2VsZWN0PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5pbXBvcnQgVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3RvcF9jYXRlZ29yeV9maWx0ZXJfc3RvcmUnO1xyXG4vLyBpbXBvcnQgVXNhZ2VUeXBlRmlsdGVyQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy91c2FnZV90eXBlX2ZpbHRlcl9hY3Rpb25zJztcclxuaW1wb3J0IFRvcENhdGVnb3J5RmlsdGVyQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy90b3BfY2F0ZWdvcnlfZmlsdGVyX2FjdGlvbnMnO1xyXG5pbXBvcnQgTG9jYWxpemF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9sb2NhbGl6YXRpb25fc3RvcmUnO1xyXG5cclxuaW1wb3J0IEZpbHRlclRvZ2dsZSBmcm9tICcuL2ZpbHRlcl90b2dnbGUnO1xyXG5cclxubGV0IHRyYW5zbGF0aW9ucyA9IHt9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2lnc0ZpbHRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuXHJcbiAgICB0aGlzLnN0YXRlID0ge1xyXG4gICAgICBmaWx0ZXJzOiBUb3BDYXRlZ29yeUZpbHRlclN0b3JlLmdldEluaXRpYWxTdGF0ZSgpLFxyXG4gICAgfVxyXG5cclxuICAgIHRyYW5zbGF0aW9ucy50b3BDYXRlZ29yeSA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL1RvcENhdGVnb3JpZXNUaXRsZScpO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlID0gVG9wQ2F0ZWdvcnlGaWx0ZXJTdG9yZS5saXN0ZW4odGhpcy5vbkZpbHRlcnNDaGFuZ2UuYmluZCh0aGlzKSk7XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIG9uRmlsdGVyc0NoYW5nZShmaWx0ZXJzKSB7XHJcbiAgICB0aGlzLnNldFN0YXRlKHsgZmlsdGVycyB9KVxyXG4gIH1cclxuXHJcblx0aGFuZGxlRmlsdGVyVG9nZ2xlKHRvcENhdGVnb3J5KSB7XHJcblx0XHRUb3BDYXRlZ29yeUZpbHRlckFjdGlvbnMudG9nZ2xlRmlsdGVyKHRvcENhdGVnb3J5KTtcclxuXHR9XHJcblxyXG4gIGhhbmRsZUFsbEZpbHRlclRvZ2dsZSgpIHtcclxuICAgIC8vICdhbGwnIGZpbHRlciA9PSBubyBmaWx0ZXJcclxuICAgIFRvcENhdGVnb3J5RmlsdGVyU3RvcmUub25DbGVhckZpbHRlcnMoKTtcclxuICB9XHJcblxyXG4gIHJlbmRlcigpIHtcclxuXHRcdGlmKHRoaXMuc3RhdGUuZmlsdGVycy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICBjb25zdCBub0ZpbHRlclNlbGVjdGVkID0gdGhpcy5zdGF0ZS5maWx0ZXJzLmZpbHRlcih4ID0+IHguc2VsZWN0ZWQpLmxlbmd0aCA9PSAwO1xyXG5cdFx0dmFyIHNlbGVjdGVkQWJsZUl0ZW1zID0gZmFsc2U7XHJcblxyXG5cdFx0bGV0IGlucHV0cyA9IHRoaXMuc3RhdGUuZmlsdGVycy5tYXAoKHgpID0+IHtcclxuXHRcdFx0XHRyZXR1cm4gPEZpbHRlclRvZ2dsZSBrZXk9e3gubmFtZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGNvdW50PXt4LmNvdW50fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bmFtZT17eC5uYW1lfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bGFiZWw9e3guZGlzcGxheU5hbWV9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpbmFjdGl2ZT17eC5jb3VudCA9PSAwfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0c2VsZWN0ZWQ9e3guc2VsZWN0ZWR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0b2dnbGU9e3RoaXMuaGFuZGxlRmlsdGVyVG9nZ2xlLmJpbmQodGhpcywgeC5uYW1lKX0gLz5cclxuXHRcdH0pO1xyXG5cclxuXHRcdGlmKGlucHV0cy5sZW5ndGggPiAwKXtcclxuXHRcdFx0c2VsZWN0ZWRBYmxlSXRlbXMgPSB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCB0b3BDYXRlZ29yeU9wZW4gPSBjbGFzc05hbWVzKHtcclxuXHQgICAgJ2ZpbHRlci13cmFwcGVyJzogdHJ1ZSxcclxuXHQgICAgJ2lzLW9wZW4nOiB0aGlzLnByb3BzLmlzT3BlbixcclxuXHQgICAgJ2hhcy1pdGVtcyc6IHRydWUsLy9wcm9wcy5oYXNJdGVtc1xyXG5cdCAgfSk7XHJcblx0ICBsZXQgdG9wQ2F0ZWdvcnlUb2dnbGUgPSBjbGFzc05hbWVzKHtcclxuXHQgICAgJ2lzLW9wZW4nOiB0aGlzLnByb3BzLmlzT3BlbixcclxuXHQgICAgJ2hhcy1pdGVtcyc6IHRydWUsLy9wcm9wcy5oYXNJdGVtc1xyXG5cdCAgfSk7XHJcblxyXG5cdCAgcmV0dXJuIChcclxuXHQgICAgPGRpdiBjbGFzc05hbWU9XCJmaWx0ZXItaXRlbVwiPlxyXG5cdCAgICAgIDxoMyBjbGFzc05hbWU9e3RvcENhdGVnb3J5VG9nZ2xlfSBkYXRhLXRvZ2dsZT1cIiN0b3AtY2F0ZWdvcnktZmlsdGVyXCI+e3RyYW5zbGF0aW9ucy50b3BDYXRlZ29yeX08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuXHQgICAgICA8ZGl2IGNsYXNzTmFtZT17dG9wQ2F0ZWdvcnlPcGVufSBpZD1cInRvcC1jYXRlZ29yeS1maWx0ZXJcIj5cclxuXHRcdFx0XHRcdDxuYXY+XHJcblx0XHRcdFx0XHRcdDx1bCBjbGFzc05hbWU9XCJjaGVja2JveC1maWx0ZXJcIj5cclxuXHRcdFx0XHRcdFx0e3NlbGVjdGVkQWJsZUl0ZW1zID8gPEZpbHRlclRvZ2dsZSBsYWJlbD1cIkFsbFwiIHNlbGVjdGVkPXtub0ZpbHRlclNlbGVjdGVkfSBpbmFjdGl2ZT17ZmFsc2V9IHRvZ2dsZT17dGhpcy5oYW5kbGVBbGxGaWx0ZXJUb2dnbGUuYmluZCh0aGlzKX0gLz4gOiBudWxsfVxyXG5cdFx0XHRcdFx0XHR7c2VsZWN0ZWRBYmxlSXRlbXMgPyBpbnB1dHMgOiBudWxsfVxyXG5cdFx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdFx0PC9uYXY+XHJcblx0ICAgICAgPC9kaXY+XHJcblx0ICAgIDwvZGl2PlxyXG5cdCAgKTtcclxuXHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5pbXBvcnQgVXNhZ2VUeXBlRmlsdGVyU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy91c2FnZV90eXBlX2ZpbHRlcl9zdG9yZSc7XHJcbmltcG9ydCBVc2FnZVR5cGVGaWx0ZXJBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3VzYWdlX3R5cGVfZmlsdGVyX2FjdGlvbnMnO1xyXG5pbXBvcnQgTG9jYWxpemF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9sb2NhbGl6YXRpb25fc3RvcmUnO1xyXG5cclxuaW1wb3J0IEZpbHRlclRvZ2dsZSBmcm9tICcuL2ZpbHRlcl90b2dnbGUnO1xyXG5cclxubGV0IHRyYW5zbGF0aW9ucyA9IHt9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVXNhZ2VUeXBlRmlsdGVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG5cclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGZpbHRlcnM6IFVzYWdlVHlwZUZpbHRlclN0b3JlLmdldEluaXRpYWxTdGF0ZSgpLFxyXG4gICAgfVxyXG5cclxuXHRcdHRyYW5zbGF0aW9ucy51c2FnZVR5cGUgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL0ZpbHRlci9Vc2FnZVR5cGUnKTtcclxuICB9XHJcblxyXG4gIGNvbXBvbmVudERpZE1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSA9IFVzYWdlVHlwZUZpbHRlclN0b3JlLmxpc3Rlbih0aGlzLm9uRmlsdGVyc0NoYW5nZS5iaW5kKHRoaXMpKTtcclxuICB9XHJcblxyXG4gIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgb25GaWx0ZXJzQ2hhbmdlKGZpbHRlcnMpIHtcclxuICAgIHRoaXMuc2V0U3RhdGUoeyBmaWx0ZXJzIH0pXHJcbiAgfVxyXG5cclxuICBoYW5kbGVGaWx0ZXJUb2dnbGUodXNhZ2VUeXBlKSB7XHJcbiAgICBVc2FnZVR5cGVGaWx0ZXJBY3Rpb25zLnRvZ2dsZUZpbHRlcih1c2FnZVR5cGUpO1xyXG4gIH1cclxuXHJcbiAgaGFuZGxlQWxsRmlsdGVyVG9nZ2xlKCkge1xyXG4gICAgLy8gJ2FsbCcgZmlsdGVyID09IG5vIGZpbHRlclxyXG4gICAgVXNhZ2VUeXBlRmlsdGVyQWN0aW9ucy5vbkNsZWFyRmlsdGVycygpO1xyXG4gIH1cclxuXHJcbiAgcmVuZGVyKCkge1xyXG5cdFx0aWYodGhpcy5zdGF0ZS5maWx0ZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgIGNvbnN0IG5vRmlsdGVyU2VsZWN0ZWQgPSB0aGlzLnN0YXRlLmZpbHRlcnMuZmlsdGVyKHggPT4geC5zZWxlY3RlZCkubGVuZ3RoID09IDA7XHJcblx0XHR2YXIgc2VsZWN0ZWRBYmxlSXRlbXMgPSBmYWxzZTtcclxuXHJcblx0XHRsZXQgaW5wdXRzID0gdGhpcy5zdGF0ZS5maWx0ZXJzLm1hcCgoeCkgPT4ge1xyXG5cdFx0XHRcdHJldHVybiA8RmlsdGVyVG9nZ2xlIGtleT17eC5uYW1lfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Y291bnQ9e3guY291bnR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRuYW1lPXt4Lm5hbWV9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRsYWJlbD17eC5kaXNwbGF5TmFtZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGluYWN0aXZlPXt4LmNvdW50ID09IDB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzZWxlY3RlZD17eC5zZWxlY3RlZH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRvZ2dsZT17dGhpcy5oYW5kbGVGaWx0ZXJUb2dnbGUuYmluZCh0aGlzLCB4Lm5hbWUpfSAvPlxyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYoaW5wdXRzLmxlbmd0aCA+IDApe1xyXG5cdFx0XHRzZWxlY3RlZEFibGVJdGVtcyA9IHRydWU7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHVzYWdlVHlwZU9wZW4gPSBjbGFzc05hbWVzKHtcclxuXHQgICAgJ2ZpbHRlci13cmFwcGVyJzogdHJ1ZSxcclxuXHQgICAgJ2lzLW9wZW4nOiB0aGlzLnByb3BzLmlzT3BlbixcclxuXHQgICAgJ2hhcy1pdGVtcyc6IHRydWUsLy9wcm9wcy5oYXNJdGVtc1xyXG5cdCAgfSk7XHJcblx0ICBsZXQgdXNhZ2VUeXBlVG9nZ2xlID0gY2xhc3NOYW1lcyh7XHJcblx0ICAgICdpcy1vcGVuJzogdGhpcy5wcm9wcy5pc09wZW4sXHJcblx0ICAgICdoYXMtaXRlbXMnOiB0cnVlLC8vcHJvcHMuaGFzSXRlbXNcclxuXHQgIH0pO1xyXG5cclxuLy97c2VsZWN0ZWRBYmxlSXRlbXMgPyBudWxsIDogbm9JdGVtc31cclxuXHQgIHJldHVybihcclxuXHQgICAgPGRpdiBjbGFzc05hbWU9XCJmaWx0ZXItaXRlbVwiPlxyXG5cdCAgICAgIDxoMyBjbGFzc05hbWU9e3VzYWdlVHlwZVRvZ2dsZX0gZGF0YS10b2dnbGU9XCIjdXNhZ2UtdHlwZS1maWx0ZXJcIj57dHJhbnNsYXRpb25zLnVzYWdlVHlwZX08aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+PC9oMz5cclxuXHQgICAgICA8ZGl2IGNsYXNzTmFtZT17dXNhZ2VUeXBlT3Blbn0gaWQ9XCJ1c2FnZS10eXBlLWZpbHRlclwiPlxyXG5cdFx0XHRcdFx0PG5hdj5cclxuXHRcdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoZWNrYm94LWZpbHRlclwiPlxyXG5cdFx0XHRcdFx0XHRcdHtzZWxlY3RlZEFibGVJdGVtcyA/IDxGaWx0ZXJUb2dnbGUgbGFiZWw9XCJBbGxcIiBzZWxlY3RlZD17bm9GaWx0ZXJTZWxlY3RlZH0gaW5hY3RpdmU9e2ZhbHNlfSB0b2dnbGU9e3RoaXMuaGFuZGxlQWxsRmlsdGVyVG9nZ2xlLmJpbmQodGhpcyl9IC8+IDogbnVsbH1cclxuXHRcdFx0XHRcdFx0XHR7c2VsZWN0ZWRBYmxlSXRlbXMgPyBpbnB1dHMgOiBudWxsfVxyXG5cdFx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdFx0PC9uYXY+XHJcblx0ICAgICAgPC9kaXY+XHJcblx0ICAgIDwvZGl2PlxyXG5cdCAgKTtcclxuXHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xyXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwcm9taXNlJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmNsYXNzIExhbmd1YWdlU2VsZWN0b3Ige1xyXG4gIGluaXQoKSB7XHJcblx0XHRsZXQgbGFuZ3VhZ2VTZWxlY3RvciA9ICQoJy51Yy1sYW5ndWFnZS1zZWxlY3RvcicpXHJcbiAgICBsZXQgdGhhdCA9IHRoaXM7XHJcblx0XHRsZXQgcGF0aE5hbWUgPSAnJztcclxuXHJcbiAgICBsYW5ndWFnZVNlbGVjdG9yLmZpbmQoJ2EnKS5jbGljaygoZSkgPT4ge1xyXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIGxldCBsaW5rID0gJChlLnRhcmdldCk7XHJcbiAgICAgIGxldCBsYW5ndWFnZSA9IGxpbmsuZGF0YSgnbGFuZ3VhZ2UnKTtcclxuXHRcdFx0bGV0IHVybCA9ICcnO1xyXG4gICAgICB0aGF0LnNldChsYW5ndWFnZSkudGhlbihcclxuICAgICAgICAocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gcmVzcG9uc2UuVXJsO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvL2NvbnNvbGUubG9nKCdjb3VsZCBub3Qgc2V0IGxhbmd1YWdlOicsIGVycm9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNldChsYW5ndWFnZSkge1xyXG4gICAgJCgnLnVjLWxhbmd1YWdlcyAuaWNvbi1nbG9iZScpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgbGV0IHVybCA9ICcvSGVhZGVyL1NldExhbmd1YWdlJztcclxuICAgICAgcmVxdWVzdFxyXG4gICAgICAgIC5wb3N0KHVybClcclxuICAgICAgICAuc2VuZCh7IGxhbmd1YWdlOiBsYW5ndWFnZSB9KVxyXG4gICAgICAgIC5lbmQoKGVycm9yLCByZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgaWYgKHJlc3BvbnNlLmJhZFJlcXVlc3QpIHtcclxuICAgICAgICAgICAgcmVqZWN0KGAnJHtsYW5ndWFnZX0nIGlzIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UuYm9keSkge1xyXG4gICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlLmJvZHkpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmVqZWN0KCdodHRwIGVycm9yJyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAkKCcudWMtbGFuZ3VhZ2VzIC5pY29uLWdsb2JlJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgbmV3IExhbmd1YWdlU2VsZWN0b3IoKTtcclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IFdpc2hsaXN0SGVhZGVyIGZyb20gJy4vLi4vd2lzaGxpc3Qvd2lzaGxpc3RIZWFkZXInO1xyXG5cclxuY2xhc3MgQWRkVG9DYXJ0QnV0dG9ucyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmxhbmc7XHJcblx0XHRsZXQgZXhwYW5kS2l0ID0gJy4nK3RoaXMucHJvcHMucGFydC5JZDtcclxuXHRcdGxldCBhZGRCdXR0b25zID0gbnVsbDtcclxuXHRcdGxldCB0ZENsYXNzID0gJ2J1eSc7XHJcblx0XHRsZXQgY29udGV4dCA9IEpTT04uc3RyaW5naWZ5KHRoaXMucHJvcHMuUHJvZHVjdENvbnRleHQpO1xyXG5cdFx0bGV0IG1hdGVyaWFsTnVtYmVyQXNJZCA9IHRoaXMucHJvcHMucGFydC5NYXRlcmlhbElkLnNwbGl0KCcuJykuam9pbignLScpO1xyXG5cclxuXHRcdGxldCB0b2dnbGVPZkNhbnZhcyA9IFdpc2hsaXN0SGVhZGVyLkdldFNlbGVjdGVkV2lzaGxpc3REYXRhKCkgPT0gbnVsbDtcclxuXHJcblx0XHRsZXQgc2F2ZWRDYXJ0Q2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J2J1dHRvbic6IHRydWUsXHJcblx0XHRcdCd3aXNobGlzdCc6IHRydWUsXHJcblx0XHRcdCdleHBsb2RlZC1zYXZlZC1jYXJ0LWFkZCc6IHRydWUsXHJcblx0XHRcdCdzYXZlZC1jYXJ0LWFkZCc6IHRydWUsXHJcblx0XHRcdCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZSc6IHRvZ2dsZU9mQ2FudmFzXHJcblx0XHR9KTtcclxuXHJcblx0XHRpZih0aGlzLnByb3BzLkJ1eWFibGUgJiYgIXRoaXMucHJvcHMucGFydC5Jc0Jsb2NrZWQpIHtcclxuXHRcdFx0dGRDbGFzcyArPSAnIG5vLXBhZGRpbmctdG9wJztcclxuXHRcdFx0YWRkQnV0dG9ucyA9IChcclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImJ1dHRvbi13cmFwcGVyXCIgZGF0YS1wcm9kdWN0LWNvbnRleHQ9e2NvbnRleHR9PlxyXG5cdFx0XHRcdFx0PGJ1dHRvbiBkYXRhLXByb2R1Y3Qtc2t1PXt0aGlzLnByb3BzLnBhcnQuTWF0ZXJpYWxJZH0gY2xhc3NOYW1lPXtzYXZlZENhcnRDbGFzc30+PGkgY2xhc3NOYW1lPVwiaWNvbi1zYXZlZC1jYXJ0LWFkZFwiPjwvaT48L2J1dHRvbj5cclxuXHRcdFx0XHRcdDxidXR0b24gZGF0YS1wcm9kdWN0LXNrdT17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGNsYXNzTmFtZT1cImJ1dHRvbiBhZGQtdG8tY2FydFwiPntsYW5nLmFkZHRvY2FydH08L2J1dHRvbj5cclxuXHRcdFx0XHRcdDxidXR0b24gZGF0YS1wcm9kdWN0LXNrdT17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGNsYXNzTmFtZT1cImJ1dHRvbiBxdWljay1idXlcIj57bGFuZy5xdWlja2J1eX08L2J1dHRvbj5cclxuXHRcdFx0XHRcdHt0aGlzLnByb3BzLmlzS2l0ID4gMCA/IDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIGV4cGFuZC1raXRcIiBkYXRhLXRvZ2dsZT17ZXhwYW5kS2l0fT48aSBjbGFzc05hbWU9XCJpY29uLWRvd24tb3BlblwiPjwvaT48L2J1dHRvbj4gOiBudWxsfVxyXG5cdFx0XHRcdFx0PGRpdiBpZD17bWF0ZXJpYWxOdW1iZXJBc0lkfWNsYXNzTmFtZT1cIlNwYXJlUGFydFJlc3VsdC1pbmZvXCI+PC9kaXY+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdCk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0aWYodGhpcy5wcm9wcy5pc0tpdCl7XHJcblx0XHRcdFx0YWRkQnV0dG9ucyA9IChcclxuXHRcdFx0XHRcdDxkaXY+XHJcblx0XHRcdFx0XHRcdDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIGV4cGFuZC1raXRcIiBkYXRhLXRvZ2dsZT17ZXhwYW5kS2l0fT48aSBjbGFzc05hbWU9XCJpY29uLWRvd24tb3BlblwiPjwvaT48L2J1dHRvbj5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8dGQgY2xhc3NOYW1lPXt0ZENsYXNzfSBjb2xTcGFuPVwiN1wiPlxyXG5cdFx0XHRcdHthZGRCdXR0b25zfVxyXG5cdFx0XHQ8L3RkPlxyXG5cdFx0KTtcclxuXHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgQWRkVG9DYXJ0QnV0dG9ucztcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IElsbHVzdHJhdGlvbkFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvaWxsdXN0cmF0aW9uX2FjdGlvbnMnO1xyXG5cclxuY2xhc3MgSG90U3BvdHMgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblxyXG5cdFx0dGhpcy5wcm9wcyA9ICB7XHJcblx0XHRcdGhvdHNwb3Q6IHtcclxuXHRcdFx0XHRJbGx1c3RyYXRpb25MaW5rOiBudWxsXHJcblx0XHRcdH0sXHJcblx0XHRcdGltZ3Byb3BzOiB7XHJcblx0XHRcdFx0aGVpZ2h0OjAsXHJcblx0XHRcdFx0d2lkdGg6MFxyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0Y2FsY3VsYXRlUG9zaXRpb24oaG90c3BvdCkge1xyXG5cclxuXHRcdGxldCB3aWR0aCA9ICB0aGlzLnByb3BzLmltZ3Byb3BzLndpZHRoLFxyXG5cdFx0XHRcdGhlaWdodCA9IHRoaXMucHJvcHMuaW1ncHJvcHMuaGVpZ2h0LFxyXG5cdFx0XHRcdGhvdHNwb3RIZWlnaHQgPSBob3RzcG90LkhlaWdodCA+IDAgPyBob3RzcG90LkhlaWdodCsxMCA6IGhvdHNwb3QuSGVpZ2h0LFxyXG5cdFx0XHRcdGhvdHNwb3RXaWR0aCA9IGhvdHNwb3QuV2lkdGggPiAwID8gaG90c3BvdC5XaWR0aCsxMCA6IGhvdHNwb3QuV2lkdGg7XHJcblxyXG5cclxuXHRcdC8vUmVsYXRpdmUgcG9zaXRpb25cclxuXHRcdGlmKChob3RzcG90LllQZXJjZW50ICE9IG51bGwgJiYgaG90c3BvdC5YUGVyY2VudCAhPSBudWxsKSAmJiAoaG90c3BvdC5YUGVyY2VudCAhPSAwICYmIGhvdHNwb3QuWVBlcmNlbnQgIT0gMCkpe1xyXG5cdFx0XHRsZXQgcG9zID0ge1xyXG5cdFx0XHRcdFx0eFBvczogaG90c3BvdC5YUGVyY2VudCxcclxuXHRcdFx0XHRcdHlQb3M6IGhvdHNwb3QuWVBlcmNlbnQsXHJcblx0XHRcdFx0XHRoZWlnaHQ6IChob3RzcG90SGVpZ2h0IC8gaGVpZ2h0KSAqIDEwMCxcclxuXHRcdFx0XHRcdHdpZHRoOiAoaG90c3BvdFdpZHRoIC8gd2lkdGgpICogMTAwXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gcG9zO1xyXG5cdFx0fVxyXG5cdFx0bGV0IHBvcyA9IHtcclxuXHRcdFx0XHRcdHhQb3M6IChob3RzcG90LlggLyB3aWR0aCkgKiAxMDAsXHJcblx0XHRcdFx0XHR5UG9zOiAoaG90c3BvdC5ZIC8gaGVpZ2h0KSAqIDEwMCxcclxuXHRcdFx0XHRcdGhlaWdodDogKGhvdHNwb3RIZWlnaHQgLyBoZWlnaHQpICogMTAwLFxyXG5cdFx0XHRcdFx0d2lkdGg6IChob3RzcG90V2lkdGggLyB3aWR0aCkgKiAxMDBcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBvcztcclxuXHR9XHJcblxyXG5cdHBvc2l0aW9uU3R5bGVIb3RzcG90KGhvdHNwb3QpIHtcclxuXHRcdGxldCBwb3MgPSB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uKGhvdHNwb3QpO1xyXG5cdFx0bGV0IHN0eWxlID0ge1xyXG5cdFx0XHRoZWlnaHQ6IHBvcy5oZWlnaHQgKyAnJScsXHJcblx0XHRcdGxlZnQ6IHBvcy54UG9zICsgJyUnLFxyXG5cdFx0XHR0b3A6IHBvcy55UG9zICsgJyUnLFxyXG5cdFx0XHR3aWR0aDogcG9zLndpZHRoICsgJyUnXHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHN0eWxlO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2xpY2sgPSAoZSkgPT4ge1xyXG5cdFx0bGV0IGhvdHNwb3QgPSB0aGlzLnByb3BzLmhvdHNwb3QsXHJcblx0XHRcdFx0bm9WYWx1ZSA9ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnO1xyXG5cdFx0Ly9JZiBob3RzcG90IGRpZmZlciBmcm9tIG5vVmFsdWUgdGhlbiBsaW5rIHRvIGFub3RoZXIgaWxsdXN0cmF0aW9uXHJcblx0XHRpZihob3RzcG90LklsbHVzdHJhdGlvbkxpbmsgIT09IG5vVmFsdWUpIHtcclxuXHJcblx0XHRcdGxldCBtb2RlbCA9IGhvdHNwb3QuTW9kZWxGb3JJbGx1c3RyYXRpb25MaW5rID09PSBub1ZhbHVlID8gdGhpcy5wcm9wcy5tb2RlbCA6IGhvdHNwb3QuTW9kZWxGb3JJbGx1c3RyYXRpb25MaW5rO1xyXG5cdFx0XHR3aW5kb3cubG9jYXRpb24gPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuZXhwbG9kZWRWaWV3c1VSTCArIG1vZGVsICsgJy8nICsgdGhpcy5wcm9wcy5ob3RzcG90LklsbHVzdHJhdGlvbkxpbms7XHJcblx0XHRcdHJldHVybiB3aW5kb3cubG9jYXRpb24ucmVsb2FkKHRydWUpO1xyXG5cclxuXHRcdH1cclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdHRoaXMucHJvcHMuc2V0SG90c3BvdCh0aGlzLnByb3BzLmhvdHNwb3QpO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGxldCBzdHlsZSA9IHRoaXMucG9zaXRpb25TdHlsZUhvdHNwb3QodGhpcy5wcm9wcy5ob3RzcG90KTtcclxuXHRcdGxldCBjbGlja0hhbmRsZXIgPSB0aGlzLnByb3BzLmNsaWNrSGFuZGxlciA/IHRoaXMucHJvcHMuY2xpY2tIYW5kbGVyIDogdGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpO1xyXG5cdFx0bGV0IGhvdHNwb3RUZXh0ID0gKHRoaXMucHJvcHMuaG90c3BvdC5UeXBlID09PSAyIHx8IHRoaXMucHJvcHMuaG90c3BvdC5UeXBlID09PSAzKSA/ICcnIDogdGhpcy5wcm9wcy5ob3RzcG90LlRleHQ7XHJcblxyXG5cdFx0dmFyIGNsYXNzZXMgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J2hvdHNwb3QnOiB0cnVlLFxyXG5cdFx0XHQndHJhbnNwYXJlbnQnOiAodGhpcy5wcm9wcy5ob3RzcG90LlR5cGUgPT09IDIgfHwgdGhpcy5wcm9wcy5ob3RzcG90LlR5cGUgPT09IDMpLFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBzdHlsZT17c3R5bGV9IGNsYXNzTmFtZT17Y2xhc3Nlc30gb25DbGljaz17Y2xpY2tIYW5kbGVyfT48c3BhbiBjbGFzc05hbWU9XCJob3RzcG90LXRleHRcIj57aG90c3BvdFRleHR9PC9zcGFuPjwvZGl2PlxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBIb3RTcG90cztcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuXHJcbmNsYXNzIElsbHVzdHJhdGlvbkluZm8gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblxyXG5cdFx0dGhpcy5wcm9wcyA9ICB7XHJcblx0XHRcdGlsbHVzdHJhdGlvbjogbnVsbFxyXG5cdFx0fTtcclxuXHJcblx0XHR0aGlzLnN0YXRlID0ge1xyXG5cdFx0XHRpbGx1c3RyYXRpb246IG51bGxcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZiggdGhpcy5wcm9wcy5sb2FkaW5nVHJlZVZpZXcgfHwgdGhpcy5wcm9wcy5sb2FkaW5nSWxsdXN0cmF0aW9uKSByZXR1cm4gbnVsbDtcclxuICAgIGlmKCF0aGlzLnByb3BzLmlsbHVzdHJhdGlvbikgcmV0dXJuIG51bGw7XHJcblx0XHRpZighXy5pc0VtcHR5KHRoaXMucHJvcHMuaWxsdXN0cmF0aW9uKSkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PHNlY3Rpb24gY2xhc3NOYW1lPVwidGV4dC1pbWFnZS1ibG9jay1za2V3XCI+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJsaW5rLXdyYXBwXCI+XHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImltYWdlXCI+XHJcblx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImljb24tZHJhd2luZ1wiPjwvaT5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjb250ZW50XCI+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidGV4dC13cmFwcGVyXCI+XHJcblx0XHRcdFx0XHRcdFx0PHA+e2hpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5pbmZvVGV4dH08L3A+XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdDwvc2VjdGlvbj5cclxuXHRcdCk7XHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgSWxsdXN0cmF0aW9uSW5mbztcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcclxuaW1wb3J0IEhvdFNwb3RzIGZyb20gJy4vaG90c3BvdHMnO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9pbGx1c3RyYXRpb25fc3RvcmUnO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9pbGx1c3RyYXRpb25fYWN0aW9ucyc7XHJcbmltcG9ydCBwYW56b29tIGZyb20gJy4uLy4uL19saWIvcGFuem9vbSc7XHJcblxyXG5jbGFzcyBJbGx1c3RyYXRpb24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblxyXG5cdFx0dGhpcy5wcm9wcyA9ICB7XHJcblx0XHRcdGlsbHVzdHJhdGlvbjoge1xyXG5cdFx0XHRcdEhvdHNwb3RzOiBbXVxyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGlsbHVzdHJhdGlvbjoge1xyXG5cdFx0XHRcdGltZzoge1xyXG5cdFx0XHRcdFx0aGVpZ2h0Om51bGwsXHJcblx0XHRcdFx0XHR3aWR0aDpudWxsXHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdGltZ09uTG9hZCA9IChlKSA9PiB7XHJcblxyXG5cdFx0JCgnaW1nJykuYmluZCgnY29udGV4dG1lbnUnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSk7XHJcblxyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdGlsbHVzdHJhdGlvbjoge1xyXG5cdFx0XHRcdGltZzoge1xyXG5cdFx0XHRcdFx0aGVpZ2h0OmUudGFyZ2V0Lm5hdHVyYWxIZWlnaHQsXHJcblx0XHRcdFx0XHR3aWR0aDplLnRhcmdldC5uYXR1cmFsV2lkdGhcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0SWxsdXN0cmF0aW9uU3RvcmUuc2V0TG9hZGluZ1N0YXRlKGZhbHNlKTtcclxuXHJcblx0fVxyXG5cclxuXHRjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcclxuXHRcdHBhbnpvb20uaW5pdChSZWFjdERPTS5maW5kRE9NTm9kZSh0aGlzKSk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcbiAgICBpZighdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24pIHJldHVybiBudWxsO1xyXG5cdFx0aWYoIXRoaXMucHJvcHMuaWxsdXN0cmF0aW9uLkltYWdlKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgaG90c3BvdHMgPSBbXTtcclxuXHJcblx0XHR0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5Ib3RzcG90cy5mb3JFYWNoKChob3RzcG90LCBrZXkpID0+IHtcclxuXHRcdFx0bGV0IGhvdHNwb3RLZXkgPSAnaG90c3BvdCcgKyBrZXk7XHJcblx0XHRcdGhvdHNwb3RzLnB1c2goPEhvdFNwb3RzIGtleT17aG90c3BvdEtleX0gaG90c3BvdD17aG90c3BvdH0gaW1ncHJvcHM9e3RoaXMuc3RhdGUuaWxsdXN0cmF0aW9uLmltZ30gc2V0SG90c3BvdD17dGhpcy5wcm9wcy5zZXRIb3RzcG90fSBtb2RlbD17dGhpcy5wcm9wcy5tb2RlbH0gLz4pO1xyXG5cdFx0fSk7XHJcblx0XHQvL2xldCBpbWdzcmMgPSAnaHR0cDovL2hpYWJlY29tLWRldi5rbm93aXRlY29tbWVyY2Uuc2UnICsgdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uSW1hZ2U7XHJcblx0XHRsZXQgaW1nc3JjID0gdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uSW1hZ2U7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHJcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidWMtZXhwbG9kZWR2aWV3XCI+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJleHBsb2RlZHZpZXctem9vbS1jb250YWluZXJcIj5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFzcGVjdC1yYXRpb1wiPlxyXG5cdFx0XHRcdFx0PGZpZ3VyZT5cclxuXHRcdFx0XHRcdFx0PGltZyBzcmM9e2ltZ3NyY30gYWx0PScnIG9uTG9hZD17dGhpcy5pbWdPbkxvYWQuYmluZCh0aGlzKX0gb25FcnJvcj17dGhpcy5pbWdPbkxvYWQuYmluZCh0aGlzKX0gLz5cclxuXHRcdFx0XHRcdFx0e2hvdHNwb3RzfVxyXG5cdFx0XHRcdFx0PC9maWd1cmU+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJ6b29tLWNvbnRyb2xzXCI+XHJcblx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBsaW5rIHpvb20taW4gem9vbVwiPis8L2J1dHRvbj5cclxuXHRcdFx0XHRcdDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIGxpbmsgem9vbS1vdXQgem9vbVwiPi08L2J1dHRvbj5cclxuXHRcdFx0XHRcdDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIGxpbmsgem9vbS1yZXNldCB6b29tXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1yZXNpemUtc21hbGxcIj48L2k+PC9idXR0b24+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdDwvZGl2PlxyXG5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IElsbHVzdHJhdGlvbjtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBJbGx1c3RyYXRpb24gZnJvbSAnLi9pbGx1c3RyYXRpb24nO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uSW5mbyBmcm9tICcuL2lsbHVzdHJhdGlvbi1pbmZvJztcclxuaW1wb3J0IElsbHVzdHJhdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvaWxsdXN0cmF0aW9uX3N0b3JlJztcclxuaW1wb3J0IElsbHVzdHJhdGlvbkFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvaWxsdXN0cmF0aW9uX2FjdGlvbnMnO1xyXG5pbXBvcnQgUGFydExpc3QgZnJvbSAnLi9wYXJ0bGlzdCc7XHJcbmltcG9ydCBNb2RlbFRyZWUgZnJvbSAnLi4vdHJlZXZpZXcvbW9kZWx0cmVlJztcclxuaW1wb3J0IFRyZWVWaWV3QXBpIGZyb20gJy4uLy4uL19hcGkvdHJlZXZpZXdfYXBpJztcclxuaW1wb3J0IFRyZWVWaWV3U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy90cmVldmlld19zdG9yZSc7XHJcbmltcG9ydCBNb2RlbFRyZWVWaWV3U2VhcmNoU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9tb2RlbF90cmVlX3NlYXJjaF9zdG9yZSc7XHJcbmltcG9ydCBNb2RlbFRyZWVTZWFyY2ggZnJvbSAnLi4vdHJlZXZpZXcvbW9kZWx0cmVlc2VhcmNoJztcclxuaW1wb3J0IEJyZWFkY3J1bWIgZnJvbSAnLi4vYnJlYWRjcnVtYi9icmVhZGNydW1iJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuY2xhc3MgSWxsdXN0cmF0aW9uQ29udGFpbmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGlsbHVzdHJhdGlvbjogbnVsbCxcclxuICAgICAgaG90c3BvdElkOiBudWxsLFxyXG5cdFx0XHRsb2FkaW5nVHJlZVZpZXc6IFRyZWVWaWV3U3RvcmUuZ2V0TG9hZGluZ1N0YXRlKCksXHJcblx0XHRcdGxvYWRpbmdJbGx1c3RyYXRpb246IElsbHVzdHJhdGlvblN0b3JlLmdldExvYWRpbmdTdGF0ZSgpLFxyXG5cdFx0XHRtb2RlbFRyZWVTZWFyY2hSZXN1bHQ6IG51bGwsXHJcblx0XHRcdG1vZGVsVHJlZVNlYXJjaFZhbHVlOiAnJyxcclxuXHRcdFx0aXNNYWNoaW5lOiBmYWxzZVxyXG4gICAgfTtcclxuXHR9XHJcblxyXG4gIHNldEhvdHNwb3QoaG90c3BvdCkge1xyXG5cclxuICAgIHRoaXMuc2V0U3RhdGUoe1xyXG4gICAgICBob3RzcG90SWQ6IGhvdHNwb3QuSWRcclxuICAgIH0pO1xyXG5cclxuICAgIC8vU2Nyb2xsIHRvIHBhcnRcclxuICAgIGxldCAkdGFyZ2V0ID0gJCgnI2hvdHNwb3QtJyArIGhvdHNwb3QuSWQpO1xyXG5cdFx0bGV0ICR0YXJnZXRPZmZzZXQgPSAkdGFyZ2V0Lm9mZnNldCgpLnRvcDtcclxuXHRcdGxldCAkdGFyZ2V0SGVpZ2h0ID0gJHRhcmdldC5oZWlnaHQoKTtcclxuXHRcdGxldCAkd2luZG93SGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xyXG5cdFx0bGV0ICRvZmZzZXQgPSAkdGFyZ2V0T2Zmc2V0O1xyXG5cclxuXHRcdGlmKCR0YXJnZXQubGVuZ3RoID09PSAwICYmICR0YXJnZXRIZWlnaHQgPiAkd2luZG93SGVpZ2h0KSByZXR1cm47XHJcblxyXG5cdFx0JG9mZnNldCA9ICR0YXJnZXRPZmZzZXQgLSAoKCR3aW5kb3dIZWlnaHQgLyAyKSAtICgkdGFyZ2V0SGVpZ2h0IC8gMikpO1xyXG5cclxuICAgICQoJ2h0bWwsIGJvZHknKS5zdG9wKCkuYW5pbWF0ZSh7XHJcbiAgICAgICdzY3JvbGxUb3AnOiAkb2Zmc2V0XHJcbiAgICB9LCA2MDAsICdzd2luZycsIGZ1bmN0aW9uICgpIHt9KTtcclxuXHJcbiAgfVxyXG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XHJcblx0XHRJbGx1c3RyYXRpb25BY3Rpb25zLmxvYWRJbGx1c3RyYXRpb24obmV4dFByb3BzLnBhcmFtcy5pbGx1c3RyYXRpb24sbmV4dFByb3BzLnBhcmFtcy5tb2RlbCk7XHJcbiAgfVxyXG5cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRsb2FkaW5nSWxsdXN0cmF0aW9uOiB0cnVlXHJcblx0XHR9KTtcclxuXHJcblx0XHRJbGx1c3RyYXRpb25BY3Rpb25zLmxvYWRJbGx1c3RyYXRpb24odGhpcy5wcm9wcy5wYXJhbXMuaWxsdXN0cmF0aW9uLHRoaXMucHJvcHMucGFyYW1zLm1vZGVsKTtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRsb2FkaW5nSWxsdXN0cmF0aW9uOiB0cnVlXHJcblx0XHR9KTtcclxuXHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlID0gSWxsdXN0cmF0aW9uU3RvcmUubGlzdGVuKCgpID0+IHtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aWxsdXN0cmF0aW9uOiBJbGx1c3RyYXRpb25TdG9yZS5nZXRJbGx1c3RyYXRpb24oKS5pbGx1c3RyYXRpb24sXHJcblx0XHRcdFx0aG90c3BvdElkOiBudWxsLFxyXG5cdFx0XHRcdGxvYWRpbmdJbGx1c3RyYXRpb246IElsbHVzdHJhdGlvblN0b3JlLmdldExvYWRpbmdTdGF0ZSgpXHJcblx0XHRcdH0pO1xyXG5cdFx0XHR0cmlnZ2VyQW5hbHl0aWNzUGFnZVZpZXcoaWxsdXN0cmF0aW9uLkNvZGUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBUcmVlVmlld1N0b3JlLmxpc3RlbigoKSA9PiB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGxvYWRpbmdUcmVlVmlldzogVHJlZVZpZXdTdG9yZS5nZXRMb2FkaW5nU3RhdGUoKVxyXG5cdFx0XHR9KVxyXG5cdFx0fSk7XHJcblxyXG5cclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBNb2RlbFRyZWVWaWV3U2VhcmNoU3RvcmUubGlzdGVuKChyZXMpID0+IHtcclxuXHRcdFx0aWYoIXJlcy5FeGNlcHRpb25NZXNzYWdlKXtcclxuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudWMtbW9kZWwtdHJlZS1zZWFyY2gtcmVzdWx0LWNvbnRhaW5lcicpLmNsYXNzTmFtZSA9ICd1Yy1tb2RlbC10cmVlLXNlYXJjaC1yZXN1bHQtY29udGFpbmVyJztcclxuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdG1vZGVsVHJlZVNlYXJjaFJlc3VsdDogcmVzLFxyXG5cdFx0XHRcdFx0bW9kZWxUcmVlU2VhcmNoVmFsdWU6IE1vZGVsVHJlZVZpZXdTZWFyY2hTdG9yZS5nZXRTZWFyY2hWYWx1ZSgpXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2xvc2VTZWFyY2hSZXNDb250YWluZXIgPSAoZSkgPT57XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRpZihlLnRhcmdldC50YWdOYW1lID09PSAnSScpe1xyXG5cdFx0XHRlLnRhcmdldC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQuY2xhc3NOYW1lICs9ICcgaGlkZSc7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0ZS50YXJnZXQucGFyZW50RWxlbWVudC5jbGFzc05hbWUgKz0gJyBoaWRlJztcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKCF0aGlzLnByb3BzLnBhcmFtcykgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IGxhbmcgPSBcdGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nO1xyXG5cdFx0bGV0IGlsbHVzdHJhdGlvbkNsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdpcy1sb2FkaW5nJzogZmFsc2UsXHJcblx0XHRcdCdyb3cnOiB0cnVlLFxyXG5cdFx0XHQnd2hpdGUnOiB0cnVlLFxyXG5cdFx0XHQnZXhwbG9kZWR2aWV3JzogdHJ1ZVxyXG5cdFx0fSk7XHJcblx0XHRpZih0aGlzLnN0YXRlLmxvYWRpbmdUcmVlVmlldyB8fCB0aGlzLnN0YXRlLmxvYWRpbmdJbGx1c3RyYXRpb24pe1xyXG5cdFx0XHRpbGx1c3RyYXRpb25DbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHRcdCdpcy1sb2FkaW5nJzogdHJ1ZSxcclxuXHRcdFx0XHQncm93JzogdHJ1ZSxcclxuXHRcdFx0XHQnd2hpdGUnOiB0cnVlLFxyXG5cdFx0XHRcdCdleHBsb2RlZHZpZXcnOiB0cnVlXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0bGV0IG9wZW5EcmF3aW5nQnRuID0gbnVsbDtcclxuXHRcdGlmKHRoaXMuc3RhdGUuaWxsdXN0cmF0aW9uICYmIHR5cGVvZiB0aGlzLnN0YXRlLmlsbHVzdHJhdGlvbi5JbWFnZSAhPT0gJ3VuZGVmaW5lZCcpe1xyXG5cdFx0XHRsZXQgbGFuZ3VhZ2UgPSBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmU7IFxyXG5cdFx0XHRsZXQgaXNNYWNoaW5lID0gdGhpcy5wcm9wcy5wYXJhbXMubW9kZWwuc3Vic3RyaW5nKDAsIDgpID09ICdtYWNoaW5lLSc7XHJcblx0XHRcdGxldCB1cmwgPSAnJztcclxuXHRcdFx0aWYoaXNNYWNoaW5lKXtcclxuXHRcdFx0XHR1cmwgPSBoaWFiY29uZmlnLnByaW50YWJsZUlsbHVzdHJhdGlvbi5iYXNlVXJsICsgJz9sYW5nPScgKyBsYW5ndWFnZSArICcmaWQ9JyArIHRoaXMucHJvcHMucGFyYW1zLmlsbHVzdHJhdGlvbiArICcmbW9kZWxJZD0nICsgdGhpcy5wcm9wcy5wYXJhbXMubW9kZWwucmVwbGFjZSgnbWFjaGluZS0nLCAnJyk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHVybCA9IGhpYWJjb25maWcucHJpbnRhYmxlSWxsdXN0cmF0aW9uLmJhc2VVcmwgKyAnP2xhbmc9JyArIGxhbmd1YWdlICsgJyZpZD0nICsgdGhpcy5wcm9wcy5wYXJhbXMuaWxsdXN0cmF0aW9uICsgJyZtb2RlbElkPScgKyB0aGlzLnByb3BzLnBhcmFtcy5tb2RlbC5yZXBsYWNlKCdtb2RlbC0nLCAnJyk7O1xyXG5cdFx0XHR9XHJcblx0XHRcdG9wZW5EcmF3aW5nQnRuID0gPGEgaHJlZj17dXJsfSB0YXJnZXQ9XCJfYmxhbmtcIiBjbGFzc05hbWU9XCJidXR0b24gb3V0bGluZWQgdGhpbiBidXR0b24tbW9kZWx0cmVlIHJpZ2h0XCI+e2xhbmcub3BlbkRyYXdpbmd9PC9hPjtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgbW9kZWxUcmVlU2VhcmNoUmVzdWx0cyA9IFtdO1xyXG5cdFx0bGV0IHNlYXJjaFJlc3VsdEZvciA9IGhpYWJjb25maWcuc2VhcmNoSW5Nb2RlbC5sYW5nLnNlYXJjaEZvcjtcclxuXHJcblx0XHRpZih0aGlzLnN0YXRlLm1vZGVsVHJlZVNlYXJjaFJlc3VsdCl7XHJcblx0XHRcdC8vIGNvbnNvbGUubG9nKHRoaXMuc3RhdGUubW9kZWxUcmVlU2VhcmNoUmVzdWx0KTtcclxuXHRcdFx0bGV0IGlzTWFjaGluZSA9IHRoaXMucHJvcHMucGFyYW1zLm1vZGVsLnN1YnN0cmluZygwLCA4KSA9PSAnbWFjaGluZS0nO1xyXG5cdFx0XHRpZih0aGlzLnN0YXRlLm1vZGVsVHJlZVNlYXJjaFJlc3VsdC5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHR0aGlzLnN0YXRlLm1vZGVsVHJlZVNlYXJjaFJlc3VsdC5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0XHRsZXQga2V5ID0gJ3NlYXJjaC0nICsgaXRlbS5JbGx1c3RyYXRpb25Db2RlO1xyXG5cdFx0XHRcdFx0bGV0IHVybCA9IG51bGw7XHJcblx0XHRcdFx0XHRpZiggaXNNYWNoaW5lICl7XHJcblx0XHRcdFx0XHRcdHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMICsgJ21hY2hpbmUtJyArIGl0ZW0uTWFjaGluZUlkICsgJy8nK2l0ZW0uUGFyZW50KycvJytpdGVtLklsbHVzdHJhdGlvbkxpbmsgO1xyXG5cdFx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRcdHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMICsgaXRlbS5CYXNlTW9kZWxJZCArIChpdGVtLklkID8gJy8nICsgaXRlbS5JZCA6ICcnKSArIChpdGVtLklsbHVzdHJhdGlvbkxpbmsgPyAnLycgKyBpdGVtLklsbHVzdHJhdGlvbkxpbmsgOiAnJyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRtb2RlbFRyZWVTZWFyY2hSZXN1bHRzLnB1c2goPGxpIGtleT17a2V5fT48YSBocmVmPXt1cmx9PntpdGVtLklsbHVzdHJhdGlvbkNvZGV9IC0ge2l0ZW0uRGVzY3JpcHRpb259PC9hPjwvbGk+KTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRtb2RlbFRyZWVTZWFyY2hSZXN1bHRzLnB1c2goPGxpIGtleT17aGlhYmNvbmZpZy5zZWFyY2gubGFuZy5ub1Jlc3VsdHN9PntoaWFiY29uZmlnLnNlYXJjaC5sYW5nLm5vUmVzdWx0c308L2xpPik7XHJcblx0XHRcdH1cclxuXHJcblx0XHR9XHJcblx0XHRyZXR1cm4gKFxyXG4gICAgICA8ZGl2PlxyXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidWMtYnJlYWRjcnVtYiB0ZXh0LWNlbnRlclwiPlxyXG5cdFx0XHRcdFx0PEJyZWFkY3J1bWIgbW9kZWw9e3RoaXMucHJvcHMucGFyYW1zLm1vZGVsfS8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICBcdFx0PGRpdiBjbGFzc05hbWU9e2lsbHVzdHJhdGlvbkNsYXNzfT5cclxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibG9jYWwtb2ZmY2FudmFzIGNsZWFyZml4IGlzLW9wZW5cIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtZWRpdW0tMyBjb2x1bW5zIGRyYXdlciBkcmF3ZXItbGVmdFwiPlxyXG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIG91dGxpbmVkIHRoaW4gaGlkZS1mb3ItbGFyZ2UtdXBcIiBkYXRhLXRvZ2dsZT1cIi5sb2NhbC1vZmZjYW52YXNcIj57bGFuZy50b2dnbGVFeHBsb2RlZHZpZXd9PGkgY2xhc3NOYW1lPVwiaWNvbi1hbmdsZS1kb3VibGUtcmlnaHRcIj48L2k+PC9idXR0b24+XHJcblxyXG4gICAgICAgICAgICAgIDxNb2RlbFRyZWUgbW9kZWw9e3RoaXMucHJvcHMucGFyYW1zLm1vZGVsfSBub2RlSWQ9e3RoaXMucHJvcHMucGFyYW1zLm5vZGVJZH0gaWxsdXN0cmF0aW9uPXt0aGlzLnByb3BzLnBhcmFtcy5pbGx1c3RyYXRpb259IGNoaWxkcmVuPXt0aGlzLnN0YXRlLmNoaWxkcmVufSAvPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtZWRpdW0tMTIgbGFyZ2UtOSBjb2x1bW5zIHUtY29sbGFwc2UtbGVmdC1mb3ItbGFyZ2UtdXBcIj5cclxuXHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNsZWFyZml4XCI+XHJcblx0XHRcdFx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBvdXRsaW5lZCB0aGluIGhpZGUtZm9yLWxhcmdlLXVwIGJ1dHRvbi1tb2RlbHRyZWUgbGVmdFwiIGRhdGEtdG9nZ2xlPVwiLmxvY2FsLW9mZmNhbnZhc1wiPjxpIGNsYXNzTmFtZT1cImljb24tYW5nbGUtZG91YmxlLWxlZnRcIj48L2k+e2xhbmcudG9nZ2xlU3BhcmVwYXJ0c308L2J1dHRvbj5cclxuXHRcdFx0XHRcdFx0XHRcdHtvcGVuRHJhd2luZ0J0bn1cclxuXHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0XHQ8SWxsdXN0cmF0aW9uSW5mbyBsb2FkaW5nVHJlZVZpZXc9e3RoaXMuc3RhdGUubG9hZGluZ1RyZWVWaWV3fSBsb2FkaW5nSWxsdXN0cmF0aW9uPXt0aGlzLnN0YXRlLmxvYWRpbmdJbGx1c3RyYXRpb259IGlsbHVzdHJhdGlvbj17dGhpcy5zdGF0ZS5pbGx1c3RyYXRpb259IC8+XHJcblx0XHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9J3VjLW1vZGVsLXRyZWUtc2VhcmNoLXJlc3VsdC1jb250YWluZXIgaGlkZSc+XHJcblx0XHRcdFx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBjaXJjbGUgYWN0aXZlIHJpZ2h0XCIgdHlwZT1cImJ1dHRvblwiIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xvc2VTZWFyY2hSZXNDb250YWluZXIuYmluZCh0aGlzKX0+PGkgY2xhc3NOYW1lPVwiaWNvbi1jbG9zZVwiPjwvaT48L2J1dHRvbj5cclxuXHRcdFx0XHRcdFx0XHRcdDxoND57c2VhcmNoUmVzdWx0Rm9yfSB7dGhpcy5zdGF0ZS5tb2RlbFRyZWVTZWFyY2hWYWx1ZX08L2g0PlxyXG5cdFx0XHRcdFx0XHRcdFx0PHVsPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHR7bW9kZWxUcmVlU2VhcmNoUmVzdWx0c31cclxuXHRcdFx0XHRcdFx0XHRcdDwvdWw+XHJcblx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcbiAgICAgICAgICAgICAgPElsbHVzdHJhdGlvbiBpbGx1c3RyYXRpb249e3RoaXMuc3RhdGUuaWxsdXN0cmF0aW9ufSBzZXRIb3RzcG90PXt0aGlzLnNldEhvdHNwb3QuYmluZCh0aGlzKX0gbW9kZWw9e3RoaXMucHJvcHMucGFyYW1zLm1vZGVsfSAvPlxyXG4gICAgICAgICAgICAgIDxQYXJ0TGlzdCBpbGx1c3RyYXRpb249e3RoaXMuc3RhdGUuaWxsdXN0cmF0aW9ufSBob3RzcG90SWQ9e3RoaXMuc3RhdGUuaG90c3BvdElkfSBtb2RlbD17dGhpcy5wcm9wcy5wYXJhbXMubW9kZWx9IC8+XHJcbiAgICAgIFx0XHRcdFx0PGEgaHJlZj1cIiNcIiBkYXRhLXRvZ2dsZT1cIi5sb2NhbC1vZmZjYW52YXNcIiBjbGFzc05hbWU9XCJleGl0LWxvY2FsLW9mZi1jYW52YXNcIj48L2E+XHJcbiAgICAgIFx0XHRcdDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuXHRcdCk7XHJcblx0fVxyXG5cclxufTtcclxuXHJcbmZ1bmN0aW9uIHRyaWdnZXJBbmFseXRpY3NQYWdlVmlldyhjb2RlLCB1cmwpIHtcclxuXHRpZih0eXBlb2YgZ2xvYmFsLmRhdGFMYXllciA9PT0gJ3VuZGVmaW5lZCcgJiYgIWhpYWJjb25maWcuRW5hYmxlR29vZ2xlVGFnTWFuYWdlcikgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRnbG9iYWwuZGF0YUxheWVyLnB1c2goe1xyXG5cdCAgJ2V2ZW50JzogJ3ZpcnR1YWxQYWdlVmlldycsXHJcblx0ICAndmlydHVhbFBhZ2VVcmwnOiB1cmwsXHJcblx0ICAndmlydHVhbFBhZ2VUaXRsZScgOiAnRXhwbG9kZWQgdmlld3MgLSAnICsgY29kZVxyXG5cdH0pO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJbGx1c3RyYXRpb25Db250YWluZXI7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XHJcbmltcG9ydCB7TGlua30gZnJvbSAncmVhY3Qtcm91dGVyJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IElsbHVzdHJhdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvaWxsdXN0cmF0aW9uX3N0b3JlJztcclxuaW1wb3J0IFRyZWVWaWV3U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy90cmVldmlld19zdG9yZSc7XHJcbmltcG9ydCBBZGRUb0NhcnRCdXR0b25zIGZyb20gJy4vYWRkdG9jYXJ0X2J1dHRvbnMnO1xyXG5pbXBvcnQgSG90U3BvdHMgZnJvbSAnLi9ob3RzcG90cyc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5pbXBvcnQgQ2FydEFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvY2FydF9hY3Rpb25zJztcclxuXHJcbmxldCBsYW5nID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmxhbmc7XHJcbmxldCBwcmluY2V0b25EZWFsZXJzVXJsID0gaGlhYmNvbmZpZy51cmxzLnByaW5jZXRvbkRlYWxlcnM7XHJcbmxldCBwcmluY2V0b25EZWFsZXJzVXJsVGl0bGUgPSBsYW5nLnByaW5jZXRvbkRlYWxlcnNUaXRsZTtcclxuXHJcbmNsYXNzIEtpdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0XHRwYXJ0OiBudWxsLFxyXG5cdFx0XHRJc1F1ZXJ5YWJsZTogZmFsc2VcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0cXVhbnRpdHk6IDEsXHJcblx0XHRcdEJ1eWFibGU6IGZhbHNlLFxyXG5cdFx0XHRJblN0b2NrUXVhbnRpdHk6IDAsXHJcblx0XHRcdExvYWRlZDogZmFsc2UsXHJcblx0XHRcdENvZGU6IFwiXCIsXHJcblx0XHRcdFByaWNlOiBcIlwiLFxyXG5cdFx0XHRTaGlwcGluZ0RhdGU6IFwiXCIsXHJcblx0XHRcdElzRGlzY291bnRlZDogZmFsc2UsXHJcblx0XHRcdERlZmF1bHRQcmljZTogXCJcIixcclxuXHRcdFx0RGlzY291bnRQZXJjZW50OiBcIlwiLFxyXG5cdFx0XHRQcm9kdWN0Q29udGV4dDogbnVsbCxcclxuXHRcdFx0UHJvbW90aW9uRGlzY291bnRQZXJjZW50OiBcIlwiLFxyXG5cdFx0XHRQcm9tb3Rpb25QcmljZTogXCJcIixcclxuXHRcdFx0SGFzUHJvbW90aW9uOiBmYWxzZSxcclxuXHRcdFx0SGFzRXJyb3I6IGZhbHNlXHJcblx0XHR9XHJcblx0fVxyXG5cdGNvbXBvbmVudERpZFVwZGF0ZSgpe1xyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlcyl7XHJcblx0XHRcdCQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ3Rvb2x0aXAnLCAncmVmbG93Jyk7XHJcblx0XHR9XHJcblx0fVxyXG5cdGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKXtcclxuXHRcdGlmKG5leHRQcm9wcy5wcmljZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG5cdFx0dGhpcy5zZXRTdGF0ZUZyb21Qcm9wcyhuZXh0UHJvcHMucHJpY2UpO1xyXG5cdH1cclxuXHRzZXRTdGF0ZUZyb21Qcm9wcyhwcmljZSl7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0QnV5YWJsZTogcHJpY2VbMF0uQnV5YWJsZSxcclxuXHRcdFx0SW5TdG9ja1F1YW50aXR5OiBwcmljZVswXS5JblN0b2NrUXVhbnRpdHksXHJcblx0XHRcdExvYWRlZDogdHJ1ZSxcclxuXHRcdFx0Q29kZTogcHJpY2VbMF0uQ29kZSxcclxuXHRcdFx0UHJpY2U6IHByaWNlWzBdLlByaWNlLFxyXG5cdFx0XHRTaGlwcGluZ0RhdGU6IHByaWNlWzBdLlNoaXBwaW5nRGF0ZSxcclxuXHRcdFx0SXNEaXNjb3VudGVkOiBwcmljZVswXS5Jc0Rpc2NvdW50ZWQsXHJcblx0XHRcdERlZmF1bHRQcmljZTogcHJpY2VbMF0uRGVmYXVsdFByaWNlLFxyXG5cdFx0XHREaXNjb3VudFBlcmNlbnQ6IHByaWNlWzBdLkRpc2NvdW50UGVyY2VudCxcclxuXHRcdFx0UHJvZHVjdENvbnRleHQ6IHByaWNlWzBdLlByb2R1Y3RDb250ZXh0LFxyXG5cdFx0XHRQcm9tb3Rpb25EaXNjb3VudFBlcmNlbnQ6IHByaWNlWzBdLlByb21vdGlvbkRpc2NvdW50UGVyY2VudCxcclxuXHRcdFx0UHJvbW90aW9uUHJpY2U6IHByaWNlWzBdLlByb21vdGlvblByaWNlLFxyXG5cdFx0XHRIYXNQcm9tb3Rpb246IHByaWNlWzBdLkhhc1Byb21vdGlvbixcclxuXHRcdFx0SGFzRXJyb3I6IHByaWNlWzBdLkhhc1Byb21vdGlvblxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLmZvcmNlVXBkYXRlKCk7XHJcblx0fVxyXG5cdGlzSW50KHZhbHVlLCBsZW5ndGgpIHtcclxuICBcdGxldCB4O1xyXG5cdFx0bGV0IGlzSW50ID0gaXNOYU4odmFsdWUpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQodmFsdWUpLCAoMCB8IHgpID09PSB4KTtcclxuXHRcdGlmKGlzSW50KXtcclxuXHRcdFx0cmV0dXJuIHZhbHVlIDwgMSAmJiB2YWx1ZS5sZW5ndGggPT09IGxlbmd0aCA/IGZhbHNlIDogdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2hhbmdlKGV2ZW50KSB7XHJcblx0XHQvLyBsZXQgcXVhbnRpdHkgPSB0aGlzLnJlZnMucXVhbnRpdHkudmFsdWU7XHJcblx0XHRldmVudC50YXJnZXQudmFsdWUgPSBldmVudC50YXJnZXQudmFsdWUuc3Vic3RyaW5nKDAsIDkpO1xyXG5cdFx0aWYoZXZlbnQudGFyZ2V0LnZhbHVlICE9PSAnJyAmJiAhdGhpcy5pc0ludChldmVudC50YXJnZXQudmFsdWUsIDEpKSB7ZXZlbnQudGFyZ2V0LnZhbHVlID0gdGhpcy5zdGF0ZS5xdWFudGl0eX1cclxuXHQgICAgdGhpcy5zZXRTdGF0ZSh7cXVhbnRpdHk6IGV2ZW50LnRhcmdldC52YWx1ZX0pO1xyXG4gIH1cclxuXHRoYW5kbGVCbHVyKGV2ZW50KSB7XHJcblx0XHQvLyBsZXQgcXVhbnRpdHkgPSB0aGlzLnJlZnMucXVhbnRpdHkudmFsdWU7XHJcblx0XHRpZihldmVudC50YXJnZXQudmFsdWUgPT09ICcnKXtcclxuXHRcdFx0ZXZlbnQudGFyZ2V0LnZhbHVlID0gdGhpcy5zdGF0ZS5xdWFudGl0eTtcclxuXHRcdH1cclxuXHJcbiAgICB0aGlzLnNldFN0YXRlKHtxdWFudGl0eTogZXZlbnQudGFyZ2V0LnZhbHVlfSk7XHJcblx0fVxyXG5cdGhhbmRsZUtleURvd24oZSkge1xyXG5cdFx0bGV0IGlucHV0ID0gdGhpcy5yZWZzLnF1YW50aXR5O1xyXG5cdFx0Ly8gY29uc29sZS5sb2coZSk7XHJcblx0XHRlLnRhcmdldC52YWx1ZSA9IGUudGFyZ2V0LnZhbHVlLnN1YnN0cmluZygwLCA5KTtcclxuXHRcdGlmKGUudGFyZ2V0LnZhbHVlICE9PSAnJyAmJiAhdGhpcy5pc0ludChpbnB1dC52YWx1ZSwgMCkpIHtlLnRhcmdldC52YWx1ZSA9IHRoaXMuc3RhdGUucXVhbnRpdHl9XHJcblx0XHRlLnRhcmdldC52YWx1ZSA9IHBhcnNlSW50KGUudGFyZ2V0LnZhbHVlLCAxMCk7XHJcblxyXG5cdFx0bGV0IHF1YW50aXR5ID0gaW5wdXQudmFsdWU7XHJcblx0XHRsZXQgc2t1SUQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcHJvZHVjdC1za3UnKTtcclxuXHJcblx0XHRpZiAoIGUud2hpY2ggPT0gMTMgKSB7XHJcblx0XHRcdCQoaW5wdXQpLmFuaW1hdGUoe1xyXG5cdFx0XHRcdGxpbmVIZWlnaHQ6IFwiNjBweFwiLFxyXG5cdFx0XHRcdG9wYWNpdHk6IFwiMC4xXCJcclxuXHRcdFx0fSwge1xyXG5cdFx0XHRcdGR1cmF0aW9uOiAzMDAsXHJcblx0XHRcdFx0c3BlY2lhbEVhc2luZzoge1xyXG5cdFx0XHRcdFx0bGluZUhlaWdodDogXCJsaW5lYXJcIlxyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0Y29tcGxldGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0JChpbnB1dCkuYW5pbWF0ZSh7XHJcblx0XHRcdFx0XHRcdGxpbmVIZWlnaHQ6IFwiMThweFwiLFxyXG5cdFx0XHRcdFx0XHRvcGFjaXR5OiBcIjFcIlxyXG5cdFx0XHRcdFx0fSwgMjAwKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRDYXJ0QWN0aW9ucy5hZGRDYXJ0SXRlbShza3VJRCwgcXVhbnRpdHkpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0ID09PSBudWxsKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgZGlzY291bnRDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnZ3Jvc3MtZGlzY291bnQtY29udGlhbmVyJzogdHJ1ZSxcclxuXHRcdFx0J2RlZmF1bHQnOiB0aGlzLnN0YXRlLkhhc1Byb21vdGlvblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IHN0b2NrSW5mbyA9IHRoaXMuc3RhdGUuSW5TdG9ja1F1YW50aXR5O1xyXG5cclxuXHRcdGlmIChzdG9ja0luZm8gPT09IHVuZGVmaW5lZCB8fCAhIHN0b2NrSW5mbyB8fCAoc3RvY2tJbmZvID09PSAwICYmIHRoaXMuc3RhdGUuU2hpcHBpbmdEYXRlICE9PSAnJykpXHJcblx0XHRcdHN0b2NrSW5mbyA9IHRoaXMuc3RhdGUuU2hpcHBpbmdEYXRlO1xyXG5cclxuXHRcdGxldCBwcm9kdWN0ID0gPGEgaHJlZj17dGhpcy5wcm9wcy5wYXJ0LlVybH0gY2xhc3NOYW1lPVwiYS1ibGFja1wiPjxzdHJvbmc+e3RoaXMucHJvcHMucGFydC5OYW1lfTwvc3Ryb25nPiA8c3BhbiBjbGFzc05hbWU9XCJzZXJpYWwtbm9cIj57dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9PC9zcGFuPjwvYT47XHJcblxyXG5cdFx0bGV0IHByaWNlID0gKDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50XCI+e3RoaXMucHJvcHMucGFydC5QcmljZX08L3NwYW4+KTtcclxuXHJcblx0XHRsZXQgbm9uRGVhbGVyRGlzY291bnQgPSB0aGlzLnN0YXRlLkhhc1Byb21vdGlvbiA/IHRoaXMuc3RhdGUuUHJpY2UrJyAtICcrbGFuZy5ncm9zc3ByaWNlKyc6ICcrdGhpcy5zdGF0ZS5EZWZhdWx0UHJpY2UgOiBsYW5nLmdyb3NzcHJpY2UrJzogJyt0aGlzLnN0YXRlLkRlZmF1bHRQcmljZTtcclxuXHJcblx0XHRsZXQgZ3Jvc3NEaXNjb3VudENvbnRpYW5lciA9IHRoaXMuc3RhdGUuSXNEaXNjb3VudGVkID8gKFxyXG5cdFx0XHQ8c3BhbiBjbGFzc05hbWU9e2Rpc2NvdW50Q2xhc3N9PlxyXG5cdFx0XHRcdDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50IHNwYW52YWxcIj5cclxuXHRcdFx0XHRcdHt0aGlzLnByb3BzLmlzRGVhbGVyID8gbGFuZy5uZXRQcmljZSsnOiAnK3RoaXMuc3RhdGUuUHJpY2UgOiBub25EZWFsZXJEaXNjb3VudCB9XHJcblx0XHRcdFx0PC9zcGFuPlxyXG5cdFx0XHRcdDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50IHNwYW52YWxcIj5cclxuXHRcdFx0XHRcdHtsYW5nLmRpc2NvdW50fToge3RoaXMuc3RhdGUuRGlzY291bnRQZXJjZW50fSVcclxuXHRcdFx0XHQ8L3NwYW4+XHJcblx0XHRcdDwvc3Bhbj4pIDpcclxuXHRcdFx0PHNwYW4gY2xhc3NOYW1lPXtkaXNjb3VudENsYXNzfT5cclxuXHRcdFx0XHQ8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT1cImNvbXBsYWludCBzcGFudmFsXCI+e3RoaXMuc3RhdGUuUHJpY2V9PC9zcGFuPlxyXG5cdFx0XHQ8L3NwYW4+O1xyXG5cclxuXHRcdGxldCBzdG9jayA9IHN0b2NrSW5mbyAhPT0gdW5kZWZpbmVkICYmIHN0b2NrSW5mbyAmJiBzdG9ja0luZm8gIT09ICcnID8gKDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cImF2YWlsYWJpbGl0eVwiIGNsYXNzTmFtZT1cImNvbXBsYWludFwiPjxpIGNsYXNzTmFtZT1cImljb24tY3ViZXNcIj48L2k+e3N0b2NrSW5mb308L3NwYW4+KSA6ICcnO1xyXG5cclxuXHRcdGlmKHRoaXMucHJvcHMucGFydC5VcmwgPT09ICcnKSB7XHJcblx0XHRcdHByb2R1Y3QgPSA8c3Bhbj48c3Ryb25nPnt0aGlzLnByb3BzLnBhcnQuTmFtZX08L3N0cm9uZz4gPHNwYW4gY2xhc3NOYW1lPVwic2VyaWFsLW5vXCI+e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfTwvc3Bhbj48L3NwYW4+O1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKCF0aGlzLnN0YXRlLkJ1eWFibGUpIHtcclxuXHRcdFx0Z3Jvc3NEaXNjb3VudENvbnRpYW5lciA9IG51bGw7XHJcblx0XHRcdHN0b2NrID0gbnVsbDtcclxuXHRcdFx0aWYodGhpcy5zdGF0ZS5IYXNFcnJvcil7XHJcblx0XHRcdFx0cHJpY2UgPSA8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT1cImNvbXBsYWludFwiPntoaWFiY29uZmlnLlNwYXJlUGFydEZvb3Rlci5sYW5nLnByaWNlRXJyb3J9PC9zcGFuPjtcclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0cHJpY2UgPSA8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT1cImNvbXBsYWludFwiPntoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZy5zZW5kRmVlZEJhY2t9PC9zcGFuPjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBkaXNwbGF5UHJpY2UgPSB0aGlzLnByb3BzLmlzRGVhbGVyICYmIHRoaXMuc3RhdGUuSXNEaXNjb3VudGVkID8gdGhpcy5zdGF0ZS5EZWZhdWx0UHJpY2UgOiB0aGlzLnN0YXRlLlByaWNlO1xyXG5cdFx0bGV0IGNvc3QgPSB0aGlzLnN0YXRlLlByaWNlO1xyXG5cclxuXHRcdGxldCB0b2dnbGVJZCA9IHRoaXMucHJvcHMucGFydC5JZDtcclxuXHJcblx0XHRsZXQgcGFydHNXcmFwcGVyQ2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J2tpdC1pdGVtIG1lZGl1bS11cC1hZGQtdG9jYXJ0JyA6IHRydWUsXHJcblx0XHRcdHRvZ2dsZUlkOiB0cnVlLFxyXG5cdFx0XHQnbWVkaXVtLXVwLWFkZC10b2NhcnQnOiB0cnVlLFxyXG5cdFx0XHQvLyAnaXMtYWN0aXZlJzogdGhpcy5wcm9wcy5ob3RzcG90SWQgPT09IHRoaXMucHJvcHMucGFydC5Ib3RzcG90SWQsXHJcblx0XHRcdCdoYXMtdGlwJzogdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMucHJvcHMucGFydC5Hb3RTY2FsZWRQcmljZXMsXHJcblx0XHRcdCd0aXAtdG9wJzogdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMucHJvcHMucGFydC5Hb3RTY2FsZWRQcmljZXNcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCB0b29sVGlwICBcdFx0XHQ9IHRoaXMuc3RhdGUuQnV5YWJsZSAmJiB0aGlzLnByb3BzLnBhcnQuR290U2NhbGVkUHJpY2VzID8geydkYXRhLXRvb2x0aXAnOiAndHJ1ZSd9IDogbnVsbDtcclxuXHRcdGxldCB0b29sVGlwVGl0bGUgXHQ9IHRoaXMuc3RhdGUuQnV5YWJsZSAmJiB0aGlzLnByb3BzLnBhcnQuR290U2NhbGVkUHJpY2VzID8geyd0aXRsZSc6IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nLnNjYWxsZWRQcmljZXNUb29sdGlwfSA6IG51bGw7XHJcblx0XHRsZXQgdG9vbFRpcEFyaWEgXHQ9IHRoaXMuc3RhdGUuQnV5YWJsZSAmJiB0aGlzLnByb3BzLnBhcnQuR290U2NhbGVkUHJpY2VzID8geydhcmlhLWhhc3BvcHVwJzogJ3RydWUnfSA6IG51bGw7XHJcblxyXG5cdFx0bGV0IHBhcmVudEtleSA9ICdwYXJlbnQtJyt0aGlzLnByb3BzLnBhcnQuSWQ7XHJcblx0XHRsZXQgYmxvY2tlZEluZm8gPSBudWxsO1xyXG5cclxuXHRcdC8vIGNvbnNvbGUubG9nKHRoaXMucHJvcHMucGFydCk7XHJcblxyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0LklzQmxvY2tlZCAmJiB0aGlzLnByb3BzLnBhcnQuUmVzdHJpY3Rpb25UeXBlID09ICdQcmluY2V0b24nKSB7XHJcblx0XHRcdGJsb2NrZWRJbmZvID0gKFxyXG5cdFx0XHRcdHByaW5jZXRvbkRlYWxlcnNVcmwgIT0gXCJcIiA/XHJcblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmVcIj48YSB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPXtwcmluY2V0b25EZWFsZXJzVXJsfSB0aXRsZT17cHJpbmNldG9uRGVhbGVyc1VybFRpdGxlfT57dGhpcy5wcm9wcy5wYXJ0LlJlc3RyaWN0aW9uVGV4dH08L2E+PC9zcGFuPjpcclxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZVwiPnt0aGlzLnByb3BzLnBhcnQuUmVzdHJpY3Rpb25UZXh0fTwvc3Bhbj5cclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHRcdGVsc2UgaWYodGhpcy5wcm9wcy5wYXJ0LklzQmxvY2tlZCkge1xyXG5cdFx0XHRibG9ja2VkSW5mbyA9IChcclxuXHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmVcIj57dGhpcy5wcm9wcy5wYXJ0LlJlc3RyaWN0aW9uVGV4dH08L3NwYW4+XHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0LklzQmxvY2tlZCkge1xyXG5cdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdDx0ciBrZXk9e3BhcmVudEtleX0+XHJcblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwiaXRlbVwiPntsYW5nLmtpdH08L3RkPlxyXG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cInByb2R1Y3RcIj57cHJvZHVjdH08L3RkPlxyXG5cdFx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwicHJvZHVjdFwiIGNvbFNwYW49XCI1XCI+XHJcblx0XHRcdFx0XHRcdHtibG9ja2VkSW5mb31cclxuXHRcdFx0XHRcdFx0PC90ZD5cclxuXHRcdFx0XHRcdDxBZGRUb0NhcnRCdXR0b25zIGlzS2l0PXt0cnVlfSBwYXJ0PXt0aGlzLnByb3BzLnBhcnR9IEJ1eWFibGU9e3RoaXMuc3RhdGUuQnV5YWJsZX0gUHJvZHVjdENvbnRleHQ9e3RoaXMuc3RhdGUuUHJvZHVjdENvbnRleHR9IGlzQmxvY2tlZD17dGhpcy5wcm9wcy5pc0Jsb2NrZWR9IC8+XHJcblx0XHRcdFx0PC90cj5cclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8dHIga2V5PXtwYXJlbnRLZXl9IGNsYXNzTmFtZT17cGFydHNXcmFwcGVyQ2xhc3N9IHsuLi50b29sVGlwfSB7Li4udG9vbFRpcFRpdGxlfSB7Li4udG9vbFRpcEFyaWF9PlxyXG5cdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJpdGVtXCI+e2xhbmcua2l0fTwvdGQ+XHJcblx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cInByb2R1Y3RcIj57cHJvZHVjdH08L3RkPlxyXG5cdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJxdWFudGl0eVwiPlxyXG5cdFx0XHRcdFx0PGlucHV0IGNsYXNzTmFtZT1cImFtb3VudFwiIHR5cGU9XCJ0ZXh0XCJcclxuXHRcdFx0XHRcdFx0ZGF0YS1wcm9kdWN0LXNrdT17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9XHJcblx0XHRcdFx0XHRcdGRhdGEtcHJvZHVjdC1jb3N0PXtjb3N0fVxyXG5cdFx0XHRcdFx0XHRvbkNoYW5nZT17dGhpcy5oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKX1cclxuXHRcdFx0XHRcdFx0cmVmPVwicXVhbnRpdHlcIlxyXG5cdFx0XHRcdFx0XHRyZWFkT25seT17IXRoaXMuc3RhdGUuQnV5YWJsZX1cclxuXHRcdFx0XHRcdFx0b25CbHVyPXt0aGlzLmhhbmRsZUJsdXIuYmluZCh0aGlzKX1cclxuXHRcdFx0XHRcdFx0ZGVmYXVsdFZhbHVlPXt0aGlzLnN0YXRlLnF1YW50aXR5fVxyXG5cdFx0XHRcdFx0Lz5cclxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInVuaXRcIj57dGhpcy5wcm9wcy5wYXJ0LlVvTX08L3NwYW4+XHJcblx0XHRcdFx0PC90ZD5cclxuXHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwicHJpY2VcIj57IHRoaXMuc3RhdGUuQnV5YWJsZSA/IDxQcmljZSBpc0RlYWxlcj17dGhpcy5wcm9wcy5pc0RlYWxlcn0gaGFzUHJvbW90aW9uPXt0aGlzLnN0YXRlLkhhc1Byb21vdGlvbn0gcHJvbW90aW9uUHJpY2U9e3RoaXMuc3RhdGUuUHJvbW90aW9uUHJpY2V9IHByb21vdGlvblBlcmNlbnQ9e3RoaXMuc3RhdGUuUHJvbW90aW9uRGlzY291bnRQZXJjZW50fSBnb3RTY2FsZWRQcmljZXM9e3RoaXMucHJvcHMucGFydC5Hb3RTY2FsZWRQcmljZXN9IFByaWNlPXtkaXNwbGF5UHJpY2V9IE1hdGVyaWFsSWQ9e3RoaXMuc3RhdGUuQ29kZX0gLz4gOiAhdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMuc3RhdGUuTG9hZGVkID8gcHJpY2UgOiA8RmV0Y2hQcmljZSAvPiB9PC90ZD5cclxuXHRcdFx0XHQ8dGQ+e2dyb3NzRGlzY291bnRDb250aWFuZXJ9PC90ZD5cclxuXHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwic3RvY2tcIj57c3RvY2t9PC90ZD5cclxuXHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwic3Vidmlld1wiPjwvdGQ+XHJcblx0XHRcdFx0PEFkZFRvQ2FydEJ1dHRvbnMgaXNLaXQ9e3RydWV9IHBhcnQ9e3RoaXMucHJvcHMucGFydH0gQnV5YWJsZT17dGhpcy5zdGF0ZS5CdXlhYmxlfSBQcm9kdWN0Q29udGV4dD17dGhpcy5zdGF0ZS5Qcm9kdWN0Q29udGV4dH0gLz5cclxuXHRcdFx0PC90cj5cclxuXHRcdFx0KTtcclxuXHR9XHJcblxyXG59O1xyXG5cclxuY29uc3QgRmV0Y2hQcmljZSA9IChwcm9wcykgPT4ge1xyXG5cdHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZldGNoaW5nXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHQgdGV4dC1jZW50ZXJcIj5cclxuICAgICAgICA8aSBjbGFzc05hbWU9XCJpY29uLXNwaW40IGFuaW1hdGUtc3BpbiB0ZXh0LWNlbnRlclwiIHN0eWxlPXt7XCJmbG9hdFwiIDogXCJsZWZ0XCJ9fT48L2k+IDxzcGFuIGNsYXNzTmFtZT1cInRleHQtY2VudGVyXCIgc3R5bGU9e3tcImZsb2F0XCIgOiBcImxlZnRcIiwgXCJwYWRkaW5nbGVmdFwiIDogXCIxMHB4XCJ9fT57bGFuZy5mZXRjaGluZ0luZm9ybWF0aW9ufTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICApO1xyXG59XHJcblxyXG5jb25zdCBQcmljZSA9IChwcm9wcykgPT4ge1xyXG4gIGNvbnN0IHsgTWF0ZXJpYWxJZCwgaXNEZWFsZXIsIFByaWNlLCBnb3RTY2FsZWRQcmljZXMsIGhhc1Byb21vdGlvbiwgcHJvbW90aW9uUGVyY2VudCwgcHJvbW90aW9uUHJpY2UgfSA9IHByb3BzO1xyXG5cdGxldCBnb3RTY2FsZWRQcmljZXNJY29uID0gZ290U2NhbGVkUHJpY2VzID8gPGkgY2xhc3NOYW1lPVwiaWNvbi1tb25leVwiPjwvaT4gOiBudWxsO1xyXG5cdGxldCBwcm9tb3Rpb25JY29uID0gaGFzUHJvbW90aW9uID8gPGkgY2xhc3NOYW1lPVwiaWNvbi10YWdzXCI+PC9pPiA6IG51bGw7XHJcblx0bGV0IHByb21vdGlvbkVsZW1lbnQgPSBoYXNQcm9tb3Rpb24gPyBwcm9tb3Rpb25QcmljZSsnIC0gJytsYW5nLnByb21vdGlvblRpdGxlKycgJytwcm9tb3Rpb25QZXJjZW50KyclJyA6IG51bGw7XHJcblx0bGV0IGRlYWxlclByaWNlID0gPHNwYW4+e2xhbmcuZ3Jvc3NwcmljZX06PHN0cm9uZz57UHJpY2V9PC9zdHJvbmc+PC9zcGFuPjtcclxuXHRsZXQgcHJpY2VFbG0gPSBpc0RlYWxlciA/IGRlYWxlclByaWNlIDogUHJpY2U7XHJcblx0bGV0IGtsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHQnY29tcGxhaW50JzogdHJ1ZSxcclxuXHRcdCdkaXNjb3VudC1wcmljZSc6IGhhc1Byb21vdGlvblxyXG5cdH0pO1xyXG5cclxuICByZXR1cm4gKFxyXG5cdFx0PGRpdj5cclxuXHRcdFx0e2hhc1Byb21vdGlvbiAmJiBpc0RlYWxlciA/IGRlYWxlclByaWNlIDogbnVsbH1cclxuXHRcdFx0PHNwYW4gZGF0YS1wcm9kdWN0LWlkPXtNYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT17a2xhc3N9Pntnb3RTY2FsZWRQcmljZXNJY29ufXtwcm9tb3Rpb25JY29ufXtoYXNQcm9tb3Rpb24gPyBwcm9tb3Rpb25FbGVtZW50IDogcHJpY2VFbG19PC9zcGFuPlxyXG5cdFx0PC9kaXY+XHJcbiAgKVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBLaXQ7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XHJcbmltcG9ydCB7TGlua30gZnJvbSAncmVhY3Qtcm91dGVyJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5cclxuY2xhc3MgS2l0UGFydCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHJcblx0XHR0aGlzLnByb3BzID0ge1xyXG5cdFx0XHRwYXJ0c0xpc3Q6IG51bGwsXHJcblx0XHRcdGtpdE5hbWU6IG51bGwsXHJcblx0XHRcdGtpdElkOiBudWxsLFxyXG5cdFx0XHR0b2dnbGVJZDogbnVsbFxyXG5cdFx0fTtcclxuXHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZih0aGlzLnByb3BzLnBhcnRzTGlzdCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IGtpdE5hbWUgPXRoaXMucHJvcHMua2l0TmFtZTtcclxuXHRcdGxldCBraXRJZCA9dGhpcy5wcm9wcy5raXRJZDtcclxuXHRcdGxldCBwYXJ0cyA9IFtdO1xyXG5cdFx0bGV0IGxpS2V5ID0gMDtcclxuXHRcdC8vdGhpcyBpcyB1bnRlc3RlZFxyXG5cdFx0dGhpcy5wcm9wcy5wYXJ0c0xpc3QuZm9yRWFjaCgocGFydCkgPT4ge1xyXG5cdFx0XHRsZXQgcHJvZHVjdCA9IDxhIGhyZWY9e3BhcnQuVXJsfSBjbGFzc05hbWU9XCJhLWJsYWNrXCI+PHN0cm9uZz57cGFydC5OYW1lfTwvc3Ryb25nPiA8c3BhbiBjbGFzc05hbWU9XCJzZXJpYWwtbm9cIj57cGFydC5NYXRlcmlhbElkfTwvc3Bhbj48L2E+O1xyXG5cdFx0XHRpZihwYXJ0LlVybCA9PT0gJycpIHtcclxuXHRcdFx0XHRwcm9kdWN0ID0gPHNwYW4+PHN0cm9uZz57cGFydC5OYW1lfTwvc3Ryb25nPiA8c3BhbiBjbGFzc05hbWU9XCJzZXJpYWwtbm9cIj57cGFydC5NYXRlcmlhbElkfTwvc3Bhbj48L3NwYW4+O1xyXG5cdFx0XHR9XHJcblx0XHRcdGxldCBxdWFudGl0eSA9PHNwYW4+IC0ge3BhcnQuUXVhbnRpdHl9IHtwYXJ0LlVvTX08L3NwYW4+O1xyXG5cdFx0XHRsZXQga2V5ID0gcGFydC5JZCArIGxpS2V5O1xyXG5cdFx0XHRsaUtleSsrO1xyXG5cdFx0XHQvLyBjb25zb2xlLmxvZyhwYXJ0KTtcclxuXHRcdFx0cGFydHMucHVzaCg8bGkga2V5PXtrZXl9IGNsYXNzTmFtZT1cInByb2R1Y3RcIj57cHJvZHVjdH17cXVhbnRpdHl9PC9saT4pO1xyXG5cdFx0fSk7XHJcblx0XHRsZXQga2l0Q2xhc3MgPSBcImtpdC1wYXJ0cy1saXN0LXJvdyBcIit0aGlzLnByb3BzLnRvZ2dsZUlkO1xyXG5cdFx0Ly90aGlzIGlzIHVudGVzdGVkIGVuZFxyXG5cdFx0Ly90aGUgcmV0dXJuIGZ1bmN0aW9uIGlzIGFsbHNvIHVudGVzdGVkXHJcblx0XHQvLyA8bGkga2V5PVwiaGVhZGVyXCIgY2xhc3NOYW1lPVwiaGVhZGVyXCI+XHJcblx0XHQvLyBcdHtoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZy5raXR9IHtraXROYW1lfSB7a2l0SWR9IHtoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZy5jb250YWluc306XHJcblx0XHQvLyA8L2xpPlxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PHRyIGNsYXNzTmFtZT17a2l0Q2xhc3N9PlxyXG5cdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJ3cmFwcGVyXCIgY29sU3Bhbj1cIjhcIj5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwia2l0LXBhcnRzLWxpc3Qtcm93XCI+XHJcblx0XHRcdFx0XHRcdDx1bD5cclxuXHRcdFx0XHRcdFx0XHR7cGFydHN9XHJcblx0XHRcdFx0XHRcdDwvdWw+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8L3RkPlxyXG5cdFx0XHQ8L3RyPlxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBLaXRQYXJ0O1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQge0xpbmt9IGZyb20gJ3JlYWN0LXJvdXRlcic7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBJbGx1c3RyYXRpb25TdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2lsbHVzdHJhdGlvbl9zdG9yZSc7XHJcbmltcG9ydCBUcmVlVmlld1N0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvdHJlZXZpZXdfc3RvcmUnO1xyXG5pbXBvcnQgQWRkVG9DYXJ0QnV0dG9ucyBmcm9tICcuL2FkZHRvY2FydF9idXR0b25zJztcclxuaW1wb3J0IEhvdFNwb3RzIGZyb20gJy4vaG90c3BvdHMnO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IENhcnRBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL2NhcnRfYWN0aW9ucyc7XHJcblxyXG5sZXQgbGFuZyA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nO1xyXG5sZXQgcHJpbmNldG9uRGVhbGVyc1VybCA9IGhpYWJjb25maWcudXJscy5wcmluY2V0b25EZWFsZXJzO1xyXG5sZXQgcHJpbmNldG9uRGVhbGVyc1VybFRpdGxlID0gbGFuZy5wcmluY2V0b25EZWFsZXJzVGl0bGU7XHJcblxyXG5jbGFzcyBQYXJ0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cclxuXHRcdHRoaXMucHJvcHMgPSB7XHJcblx0XHRcdHBhcnQ6IG51bGwsXHJcblx0XHRcdGhvdHNwb3RJZDogbnVsbCxcclxuXHRcdFx0ZWxlbWVudFZhbHVlOiAnJ1xyXG5cdFx0fTtcclxuXHJcblx0XHR0aGlzLnN0YXRlID0ge1xyXG5cdFx0XHRCdXlhYmxlOiBmYWxzZSxcclxuXHRcdFx0SW5TdG9ja1F1YW50aXR5OiAwLFxyXG5cdFx0XHRMb2FkZWQ6IGZhbHNlLFxyXG5cdFx0XHRDb2RlOiBcIlwiLFxyXG5cdFx0XHRQcmljZTogXCJcIixcclxuXHRcdFx0U2hpcHBpbmdEYXRlOiBcIlwiLFxyXG5cdFx0XHRJc0Rpc2NvdW50ZWQ6IGZhbHNlLFxyXG5cdFx0XHREZWZhdWx0UHJpY2U6IFwiXCIsXHJcblx0XHRcdERpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0UHJvZHVjdENvbnRleHQ6IG51bGwsXHJcblx0XHRcdFByb21vdGlvbkRpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0UHJvbW90aW9uUHJpY2U6IFwiXCIsXHJcblx0XHRcdEhhc1Byb21vdGlvbjogZmFsc2UsXHJcblx0XHRcdEhhc0Vycm9yOiBmYWxzZVxyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0Y29tcG9uZW50RGlkVXBkYXRlKCl7XHJcblx0XHRpZih0aGlzLnByb3BzLnBhcnQuR290U2NhbGVkUHJpY2VzKXtcclxuXHRcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbigndG9vbHRpcCcsICdyZWZsb3cnKTtcclxuXHRcdH1cclxuXHR9XHJcblx0Y29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpe1xyXG5cdFx0aWYobmV4dFByb3BzLnByaWNlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XHJcblx0XHR0aGlzLnNldFN0YXRlRnJvbVByb3BzKG5leHRQcm9wcy5wcmljZSk7XHJcblx0fVxyXG5cdHNldFN0YXRlRnJvbVByb3BzKHByaWNlKXtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRCdXlhYmxlOiBwcmljZVswXS5CdXlhYmxlLFxyXG5cdFx0XHRJblN0b2NrUXVhbnRpdHk6IHByaWNlWzBdLkluU3RvY2tRdWFudGl0eSxcclxuXHRcdFx0TG9hZGVkOiB0cnVlLFxyXG5cdFx0XHRDb2RlOiBwcmljZVswXS5Db2RlLFxyXG5cdFx0XHRQcmljZTogcHJpY2VbMF0uUHJpY2UsXHJcblx0XHRcdFNoaXBwaW5nRGF0ZTogcHJpY2VbMF0uU2hpcHBpbmdEYXRlLFxyXG5cdFx0XHRJc0Rpc2NvdW50ZWQ6IHByaWNlWzBdLklzRGlzY291bnRlZCxcclxuXHRcdFx0RGVmYXVsdFByaWNlOiBwcmljZVswXS5EZWZhdWx0UHJpY2UsXHJcblx0XHRcdERpc2NvdW50UGVyY2VudDogcHJpY2VbMF0uRGlzY291bnRQZXJjZW50LFxyXG5cdFx0XHRQcm9kdWN0Q29udGV4dDogcHJpY2VbMF0uUHJvZHVjdENvbnRleHQsXHJcblx0XHRcdFByb21vdGlvbkRpc2NvdW50UGVyY2VudDogcHJpY2VbMF0uUHJvbW90aW9uRGlzY291bnRQZXJjZW50LFxyXG5cdFx0XHRQcm9tb3Rpb25QcmljZTogcHJpY2VbMF0uUHJvbW90aW9uUHJpY2UsXHJcblx0XHRcdEhhc1Byb21vdGlvbjogcHJpY2VbMF0uSGFzUHJvbW90aW9uLFxyXG5cdFx0XHRIYXNFcnJvcjogcHJpY2VbMF0uSGFzRXJyb3JcclxuXHRcdH0pO1xyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlcyl7XHJcblx0XHRcdCQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ3Rvb2x0aXAnLCAncmVmbG93Jyk7XHJcblx0XHR9XHJcblx0XHR0aGlzLmZvcmNlVXBkYXRlKCk7XHJcblx0fVxyXG5cclxuXHRpbGx1c3RyYXRpb25MaW5rQnV0dG9uKCkge1xyXG5cdFx0bGV0IHBhcnQgPSB0aGlzLnByb3BzLnBhcnQsXHJcblx0XHRcdFx0bm9WYWx1ZSA9ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnO1xyXG5cdFx0aWYocGFydC5JbGx1c3RyYXRpb25MaW5rICE9PSBub1ZhbHVlICYmIHBhcnQuU2VjdGlvbkZvcklsbHVzdHJhdGlvbiAhPT0gbm9WYWx1ZSkge1xyXG5cdFx0XHRsZXQgbW9kZWwgPSBwYXJ0Lk1vZGVsRm9ySWxsdXN0cmF0aW9uTGluayA9PT0gbm9WYWx1ZSA/IHRoaXMucHJvcHMubW9kZWwgOiBwYXJ0Lk1vZGVsRm9ySWxsdXN0cmF0aW9uTGluaztcclxuXHRcdFx0Y29uc3QgZXhwbG9kZWRWaWV3c1VybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMO1xyXG5cdFx0XHRsZXQgdXJsID0gYCR7ZXhwbG9kZWRWaWV3c1VybH0ke21vZGVsfS8ke3BhcnQuU2VjdGlvbkZvcklsbHVzdHJhdGlvbn0vJHtwYXJ0LklsbHVzdHJhdGlvbkxpbmt9YDtcclxuXHRcdFx0cmV0dXJuIChcclxuXHRcdFx0XHQ8YSBjbGFzc05hbWU9J2J1dHRvbiBsaW5rJyBocmVmPXt1cmx9PjxpIGNsYXNzTmFtZT1cImljb24tbGV2ZWwtZG93blwiPjwvaT48L2E+XHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHRpc0ludCh2YWx1ZSwgbGVuZ3RoKSB7XHJcbiAgXHRsZXQgeDtcclxuXHRcdGxldCBpc0ludCA9IGlzTmFOKHZhbHVlKSA/ICExIDogKHggPSBwYXJzZUZsb2F0KHZhbHVlKSwgKDAgfCB4KSA9PT0geCk7XHJcblx0XHRpZihpc0ludCl7XHJcblx0XHRcdHJldHVybiB2YWx1ZSA8IDEgJiYgdmFsdWUubGVuZ3RoID09PSBsZW5ndGggPyBmYWxzZSA6IHRydWU7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcblxyXG5cdGhhbmRsZUNoYW5nZShldmVudCkge1xyXG5cdFx0Ly8gbGV0IHF1YW50aXR5ID0gdGhpcy5yZWZzLnF1YW50aXR5LnZhbHVlO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LnZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlLnN1YnN0cmluZygwLCA5KTtcclxuXHRcdGlmKGV2ZW50LnRhcmdldC52YWx1ZSAhPT0gJycgJiYgIXRoaXMuaXNJbnQoZXZlbnQudGFyZ2V0LnZhbHVlLCAxKSkge2V2ZW50LnRhcmdldC52YWx1ZSA9IHRoaXMucHJvcHMucGFydC5RdWFudGl0eX1cclxuXHQgICAgdGhpcy5zZXRTdGF0ZSh7cXVhbnRpdHk6IGV2ZW50LnRhcmdldC52YWx1ZX0pO1xyXG5cclxuICB9XHJcblx0aGFuZGxlQmx1cihldmVudCkge1xyXG5cdFx0bGV0IHF1YW50aXR5ID0gdGhpcy5yZWZzLnF1YW50aXR5LnZhbHVlO1xyXG5cdFx0aWYoZXZlbnQudGFyZ2V0LnZhbHVlID09PSAnJyl7XHJcblx0XHRcdGV2ZW50LnRhcmdldC52YWx1ZSA9IHRoaXMucHJvcHMucGFydC5RdWFudGl0eTtcclxuXHRcdH1cclxuICAgIHRoaXMuc2V0U3RhdGUoe3F1YW50aXR5OiBldmVudC50YXJnZXQudmFsdWV9KTtcclxuXHR9XHJcblx0aGFuZGxlS2V5RG93bihlKSB7XHJcblx0XHRsZXQgaW5wdXQgPSB0aGlzLnJlZnMucXVhbnRpdHk7XHJcblx0XHQvLyBjb25zb2xlLmxvZyhlKTtcclxuXHRcdGUudGFyZ2V0LnZhbHVlID0gZS50YXJnZXQudmFsdWUuc3Vic3RyaW5nKDAsIDkpO1xyXG5cdFx0aWYoZS50YXJnZXQudmFsdWUgIT09ICcnICYmICF0aGlzLmlzSW50KGlucHV0LnZhbHVlLCAwKSkge2UudGFyZ2V0LnZhbHVlID0gdGhpcy5wcm9wcy5wYXJ0LlF1YW50aXR5fVxyXG5cdFx0ZS50YXJnZXQudmFsdWUgPSBwYXJzZUludChlLnRhcmdldC52YWx1ZSwgMTApO1xyXG5cclxuXHRcdGxldCBxdWFudGl0eSA9IGlucHV0LnZhbHVlO1xyXG5cdFx0bGV0IHNrdUlEID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXByb2R1Y3Qtc2t1Jyk7XHJcblxyXG5cdFx0aWYgKCBlLndoaWNoID09IDEzICkge1xyXG5cdFx0XHQkKGlucHV0KS5hbmltYXRlKHtcclxuXHRcdFx0XHRsaW5lSGVpZ2h0OiBcIjYwcHhcIixcclxuXHRcdFx0XHRvcGFjaXR5OiBcIjAuMVwiXHJcblx0XHRcdH0sIHtcclxuXHRcdFx0XHRkdXJhdGlvbjogMzAwLFxyXG5cdFx0XHRcdHNwZWNpYWxFYXNpbmc6IHtcclxuXHRcdFx0XHRcdGxpbmVIZWlnaHQ6IFwibGluZWFyXCJcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdGNvbXBsZXRlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRcdCQoaW5wdXQpLmFuaW1hdGUoe1xyXG5cdFx0XHRcdFx0XHRsaW5lSGVpZ2h0OiBcIjE4cHhcIixcclxuXHRcdFx0XHRcdFx0b3BhY2l0eTogXCIxXCJcclxuXHRcdFx0XHRcdH0sIDIwMCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdFx0Q2FydEFjdGlvbnMuYWRkQ2FydEl0ZW0oc2t1SUQsIHF1YW50aXR5KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHJcblx0XHRpZih0aGlzLnByb3BzLnBhcnQgPT09IG51bGwpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdGxldCBrbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnbWVkaXVtLXVwLWFkZC10b2NhcnQnOiB0cnVlLFxyXG5cdFx0XHQnaXMtYWN0aXZlJzogdGhpcy5wcm9wcy5ob3RzcG90SWQgPT09IHRoaXMucHJvcHMucGFydC5Ib3RzcG90SWQsXHJcblx0XHRcdCdoYXMtdGlwJzogdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMucHJvcHMucGFydC5Hb3RTY2FsZWRQcmljZXMsXHJcblx0XHRcdCd0aXAtdG9wJzogdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMucHJvcHMucGFydC5Hb3RTY2FsZWRQcmljZXNcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCBzdG9ja0luZm8gPSB0aGlzLnN0YXRlLkluU3RvY2tRdWFudGl0eTtcclxuXHJcblx0XHRpZiAoc3RvY2tJbmZvID09PSB1bmRlZmluZWQgfHwgISBzdG9ja0luZm8gfHwgKHN0b2NrSW5mbyA9PT0gMCAmJiB0aGlzLnN0YXRlLlNoaXBwaW5nRGF0ZSAhPT0gJycpKVxyXG5cdFx0XHRzdG9ja0luZm8gPSB0aGlzLnN0YXRlLlNoaXBwaW5nRGF0ZTtcclxuXHJcblx0XHRsZXQgaG90c3BvdElkID0gJ2hvdHNwb3QtJyArIHRoaXMucHJvcHMucGFydC5Ib3RzcG90SWQ7XHJcblxyXG5cdFx0bGV0IHByaWNlID0gKDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50XCI+e3RoaXMucHJvcHMucGFydC5QcmljZX08L3NwYW4+KTtcclxuXHJcblx0XHRsZXQgZGlzY291bnRDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnZ3Jvc3MtZGlzY291bnQtY29udGlhbmVyJzogdHJ1ZSxcclxuXHRcdFx0J2RlZmF1bHQnOiB0aGlzLnN0YXRlLkhhc1Byb21vdGlvblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IG5vbkRlYWxlckRpc2NvdW50ID0gdGhpcy5zdGF0ZS5IYXNQcm9tb3Rpb24gPyB0aGlzLnN0YXRlLlByaWNlKycgLSAnK2xhbmcuZ3Jvc3NwcmljZSsnOiAnK3RoaXMuc3RhdGUuRGVmYXVsdFByaWNlIDogbGFuZy5ncm9zc3ByaWNlKyc6ICcrdGhpcy5zdGF0ZS5EZWZhdWx0UHJpY2U7XHJcblxyXG5cdFx0bGV0IGdyb3NzRGlzY291bnRDb250aWFuZXIgPSB0aGlzLnN0YXRlLklzRGlzY291bnRlZCA/IChcclxuXHRcdFx0PHNwYW4gY2xhc3NOYW1lPXtkaXNjb3VudENsYXNzfT5cclxuXHRcdFx0XHQ8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT1cImNvbXBsYWludCBzcGFudmFsXCI+XHJcblx0XHRcdFx0XHR7dGhpcy5wcm9wcy5pc0RlYWxlciA/IGxhbmcubmV0UHJpY2UrJzogJyt0aGlzLnN0YXRlLlByaWNlIDogbm9uRGVhbGVyRGlzY291bnQgfVxyXG5cdFx0XHRcdDwvc3Bhbj5cclxuXHRcdFx0XHQ8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfSBkYXRhLWFjdGl2ZS10YWI9XCJwcmljZVwiIGNsYXNzTmFtZT1cImNvbXBsYWludCBzcGFudmFsXCI+XHJcblx0XHRcdFx0XHR7bGFuZy5kaXNjb3VudH06IHt0aGlzLnN0YXRlLkRpc2NvdW50UGVyY2VudH0lXHJcblx0XHRcdFx0PC9zcGFuPlxyXG5cdFx0XHQ8L3NwYW4+KSA6XHJcblx0XHRcdDxzcGFuIGNsYXNzTmFtZT17ZGlzY291bnRDbGFzc30+XHJcblx0XHRcdFx0PHNwYW4gZGF0YS1wcm9kdWN0LWlkPXt0aGlzLnByb3BzLnBhcnQuTWF0ZXJpYWxJZH0gZGF0YS1hY3RpdmUtdGFiPVwicHJpY2VcIiBjbGFzc05hbWU9XCJjb21wbGFpbnQgc3BhbnZhbFwiPnt0aGlzLnN0YXRlLlByaWNlfTwvc3Bhbj5cclxuXHRcdFx0PC9zcGFuPjtcclxuXHJcblxyXG5cdFx0bGV0IHN0b2NrID0gc3RvY2tJbmZvICE9PSB1bmRlZmluZWQgJiYgc3RvY2tJbmZvICYmIHN0b2NrSW5mbyAhPT0gJycgPyAoPHNwYW4gZGF0YS1wcm9kdWN0LWlkPXt0aGlzLnByb3BzLnBhcnQuTWF0ZXJpYWxJZH0gZGF0YS1hY3RpdmUtdGFiPVwiYXZhaWxhYmlsaXR5XCIgY2xhc3NOYW1lPVwiY29tcGxhaW50XCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1jdWJlc1wiPjwvaT57c3RvY2tJbmZvfTwvc3Bhbj4pIDogJyc7XHJcblx0XHRsZXQgcHJvZHVjdCA9IDxhIGhyZWY9e3RoaXMucHJvcHMucGFydC5Vcmx9IGNsYXNzTmFtZT1cImEtYmxhY2tcIj48c3Ryb25nPnt0aGlzLnByb3BzLnBhcnQuTmFtZX08L3N0cm9uZz48c3BhbiBjbGFzc05hbWU9XCJzZXJpYWwtbm9cIj57dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9PC9zcGFuPjwvYT47XHJcblxyXG5cdFx0aWYoIXRoaXMuc3RhdGUuQnV5YWJsZSkge1xyXG5cdFx0XHRncm9zc0Rpc2NvdW50Q29udGlhbmVyID0gbnVsbDtcclxuXHRcdFx0c3RvY2sgPSBudWxsO1xyXG5cdFx0XHRpZih0aGlzLnN0YXRlLkhhc0Vycm9yKXtcclxuXHRcdFx0XHRwcmljZSA9IDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50XCI+e2hpYWJjb25maWcuU3BhcmVQYXJ0Rm9vdGVyLmxhbmcucHJpY2VFcnJvcn08L3NwYW4+O1xyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRwcmljZSA9IDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17dGhpcy5wcm9wcy5wYXJ0Lk1hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPVwiY29tcGxhaW50XCI+e2hpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nLnNlbmRGZWVkQmFja308L3NwYW4+O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IGRpc3BsYXlQcmljZSA9IHRoaXMucHJvcHMuaXNEZWFsZXIgJiYgdGhpcy5zdGF0ZS5Jc0Rpc2NvdW50ZWQgPyB0aGlzLnN0YXRlLkRlZmF1bHRQcmljZSA6IHRoaXMuc3RhdGUuUHJpY2U7XHJcblx0XHRsZXQgY29zdCA9IHRoaXMuc3RhdGUuUHJpY2U7XHJcblxyXG5cdFx0aWYodGhpcy5wcm9wcy5wYXJ0LlVybCA9PT0gJycpIHtcclxuXHRcdFx0cHJvZHVjdCA9IDxzcGFuIGNsYXNzTmFtZT1cInNlcmlhbC1ub1wiPnt0aGlzLnByb3BzLnBhcnQuTWF0ZXJpYWxJZH08L3NwYW4+XHJcblx0XHR9XHJcblx0XHRsZXQgdG9vbFRpcCAgXHRcdFx0PSB0aGlzLnN0YXRlLkJ1eWFibGUgJiYgdGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlcyA/IHsnZGF0YS10b29sdGlwJzogJ3RydWUnfSA6IG51bGw7XHJcblx0XHRsZXQgdG9vbFRpcFRpdGxlIFx0PSB0aGlzLnN0YXRlLkJ1eWFibGUgJiYgdGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlcyA/IHsndGl0bGUnOiBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZy5zY2FsbGVkUHJpY2VzVG9vbHRpcH0gOiBudWxsO1xyXG5cdFx0bGV0IHRvb2xUaXBBcmlhIFx0PSB0aGlzLnN0YXRlLkJ1eWFibGUgJiYgdGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlcyA/IHsnYXJpYS1oYXNwb3B1cCc6ICd0cnVlJ30gOiBudWxsO1xyXG5cclxuXHRcdGxldCBibG9ja2VkSW5mbyA9IG51bGw7XHJcblxyXG5cdFx0Ly8gY29uc29sZS5sb2codGhpcy5wcm9wcy5wYXJ0KTtcclxuXHJcblx0XHRpZih0aGlzLnByb3BzLnBhcnQuSXNCbG9ja2VkICYmIHRoaXMucHJvcHMucGFydC5SZXN0cmljdGlvblR5cGUgPT0gJ1ByaW5jZXRvbicpIHtcclxuXHRcdFx0YmxvY2tlZEluZm8gPSAoXHJcblx0XHRcdFx0cHJpbmNldG9uRGVhbGVyc1VybCAhPSBcIlwiID9cclxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZVwiPjxhIHRhcmdldD1cIl9ibGFua1wiIGhyZWY9e3ByaW5jZXRvbkRlYWxlcnNVcmx9IHRpdGxlPXtwcmluY2V0b25EZWFsZXJzVXJsVGl0bGV9Pnt0aGlzLnByb3BzLnBhcnQuUmVzdHJpY3Rpb25UZXh0fTwvYT48L3NwYW4+OlxyXG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lXCI+e3RoaXMucHJvcHMucGFydC5SZXN0cmljdGlvblRleHR9PC9zcGFuPlxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSBpZih0aGlzLnByb3BzLnBhcnQuSXNCbG9ja2VkKSB7XHJcblx0XHRcdGJsb2NrZWRJbmZvID0gKFxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZVwiPnt0aGlzLnByb3BzLnBhcnQuUmVzdHJpY3Rpb25UZXh0fTwvc3Bhbj5cclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRpZih0aGlzLnByb3BzLnBhcnQuSXNCbG9ja2VkKSB7XHJcblx0XHRcdHJldHVybihcclxuXHRcdFx0XHQ8dHIgY2xhc3NOYW1lPXtrbGFzc30+XHJcblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwiaXRlbVwiPnt0aGlzLnByb3BzLnBhcnQuSG90c3BvdElkfTwvdGQ+XHJcblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwicHJvZHVjdFwiPlxyXG5cdFx0XHRcdFx0XHR7cHJvZHVjdH1cclxuXHRcdFx0XHRcdDwvdGQ+XHJcblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwicHJvZHVjdFwiIGNvbFNwYW49XCI2XCI+XHJcblx0XHRcdFx0XHR7YmxvY2tlZEluZm99XHJcblx0XHRcdFx0XHQ8L3RkPlxyXG5cdFx0XHRcdDwvdHI+XHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdDx0ciBjbGFzc05hbWU9e2tsYXNzfSBpZD17aG90c3BvdElkfSB7Li4udG9vbFRpcH0gey4uLnRvb2xUaXBUaXRsZX0gey4uLnRvb2xUaXBBcmlhfT5cclxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJpdGVtXCI+e3RoaXMucHJvcHMucGFydC5Ib3RzcG90SWR9PC90ZD5cclxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJwcm9kdWN0XCI+XHJcblx0XHRcdFx0XHRcdHtwcm9kdWN0fVxyXG5cdFx0XHRcdFx0PC90ZD5cclxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJxdWFudGl0eVwiPlxyXG5cdFx0XHRcdFx0XHQ8aW5wdXQgY2xhc3NOYW1lPVwiYW1vdW50XCIgdHlwZT1cInRleHRcIlxyXG5cdFx0XHRcdFx0XHRcdGRhdGEtcHJvZHVjdC1za3U9e3RoaXMucHJvcHMucGFydC5NYXRlcmlhbElkfVxyXG5cdFx0XHRcdFx0XHRcdGRhdGEtcHJvZHVjdC1jb3N0PXtjb3N0fVxyXG5cdFx0XHRcdFx0XHRcdG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUNoYW5nZS5iaW5kKHRoaXMpfVxyXG5cdFx0XHRcdFx0XHRcdHJlZj1cInF1YW50aXR5XCJcclxuXHRcdFx0XHRcdFx0XHRyZWFkT25seT17IXRoaXMuc3RhdGUuQnV5YWJsZX1cclxuXHRcdFx0XHRcdFx0XHRvbkJsdXI9e3RoaXMuaGFuZGxlQmx1ci5iaW5kKHRoaXMpfVxyXG5cdFx0XHRcdFx0XHRcdGRlZmF1bHRWYWx1ZT17dGhpcy5wcm9wcy5wYXJ0LlF1YW50aXR5fSAvPlxyXG5cdFx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJ1bml0XCI+e3RoaXMucHJvcHMucGFydC5Vb019PC9zcGFuPlxyXG5cdFx0XHRcdFx0PC90ZD5cclxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJwcmljZVwiPnsgdGhpcy5zdGF0ZS5CdXlhYmxlID8gPFByaWNlIGlzRGVhbGVyPXt0aGlzLnByb3BzLmlzRGVhbGVyfSBoYXNQcm9tb3Rpb249e3RoaXMuc3RhdGUuSGFzUHJvbW90aW9ufSBwcm9tb3Rpb25QcmljZT17dGhpcy5zdGF0ZS5Qcm9tb3Rpb25QcmljZX0gcHJvbW90aW9uUGVyY2VudD17dGhpcy5zdGF0ZS5Qcm9tb3Rpb25EaXNjb3VudFBlcmNlbnR9IGdvdFNjYWxlZFByaWNlcz17dGhpcy5wcm9wcy5wYXJ0LkdvdFNjYWxlZFByaWNlc30gUHJpY2U9e2Rpc3BsYXlQcmljZX0gTWF0ZXJpYWxJZD17dGhpcy5zdGF0ZS5Db2RlfSAvPiA6ICF0aGlzLnN0YXRlLkJ1eWFibGUgJiYgdGhpcy5zdGF0ZS5Mb2FkZWQgPyBwcmljZSA6IDxGZXRjaFByaWNlIC8+IH08L3RkPlxyXG5cdFx0XHRcdFx0PHRkPntncm9zc0Rpc2NvdW50Q29udGlhbmVyfTwvdGQ+XHJcblx0XHRcdFx0XHQ8dGQgY2xhc3NOYW1lPVwic3RvY2tcIj57c3RvY2t9PC90ZD5cclxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJzdWJ2aWV3XCI+e3RoaXMuaWxsdXN0cmF0aW9uTGlua0J1dHRvbigpfTwvdGQ+XHJcblx0XHRcdFx0XHQ8QWRkVG9DYXJ0QnV0dG9ucyBwYXJ0PXt0aGlzLnByb3BzLnBhcnR9IEJ1eWFibGU9e3RoaXMuc3RhdGUuQnV5YWJsZX0gUHJvZHVjdENvbnRleHQ9e3RoaXMuc3RhdGUuUHJvZHVjdENvbnRleHR9IC8+XHJcblx0XHRcdFx0PC90cj5cclxuXHRcdFx0KTtcclxuXHR9XHJcbn07XHJcblxyXG5jb25zdCBGZXRjaFByaWNlID0gKHByb3BzKSA9PiB7XHJcblx0cmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZmV0Y2hpbmdcIj5cclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhbW91bnQtcHJpY2Utc3RvY2sgdS1kdCB0ZXh0LWNlbnRlclwiPlxyXG4gICAgICAgIDxpIGNsYXNzTmFtZT1cImljb24tc3BpbjQgYW5pbWF0ZS1zcGluIHRleHQtY2VudGVyXCIgc3R5bGU9e3tcImZsb2F0XCIgOiBcImxlZnRcIn19PjwvaT4gPHNwYW4gY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIiBzdHlsZT17e1wiZmxvYXRcIiA6IFwibGVmdFwiLCBcInBhZGRpbmdsZWZ0XCIgOiBcIjEwcHhcIn19PntsYW5nLmZldGNoaW5nSW5mb3JtYXRpb259PC9zcGFuPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICk7XHJcbn1cclxuXHJcbmNvbnN0IFByaWNlID0gKHByb3BzKSA9PiB7XHJcbiAgY29uc3QgeyBNYXRlcmlhbElkLCBpc0RlYWxlciwgUHJpY2UsIGdvdFNjYWxlZFByaWNlcywgaGFzUHJvbW90aW9uLCBwcm9tb3Rpb25QZXJjZW50LCBwcm9tb3Rpb25QcmljZSB9ID0gcHJvcHM7XHJcblx0bGV0IGdvdFNjYWxlZFByaWNlc0ljb24gPSBnb3RTY2FsZWRQcmljZXMgPyA8aSBjbGFzc05hbWU9XCJpY29uLW1vbmV5XCI+PC9pPiA6IG51bGw7XHJcblx0bGV0IHByb21vdGlvbkljb24gPSBoYXNQcm9tb3Rpb24gPyA8aSBjbGFzc05hbWU9XCJpY29uLXRhZ3NcIj48L2k+IDogbnVsbDtcclxuXHRsZXQgcHJvbW90aW9uRWxlbWVudCA9IGhhc1Byb21vdGlvbiA/IHByb21vdGlvblByaWNlKycgLSAnK2xhbmcucHJvbW90aW9uVGl0bGUrJyAnK3Byb21vdGlvblBlcmNlbnQrJyUnIDogbnVsbDtcclxuXHRsZXQgZGVhbGVyUHJpY2UgPSA8c3Bhbj57bGFuZy5ncm9zc3ByaWNlfTo8c3Ryb25nPntQcmljZX08L3N0cm9uZz48L3NwYW4+O1xyXG5cdGxldCBwcmljZUVsbSA9IGlzRGVhbGVyID8gZGVhbGVyUHJpY2UgOiBQcmljZTtcclxuXHRsZXQga2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdCdjb21wbGFpbnQnOiB0cnVlLFxyXG5cdFx0J2Rpc2NvdW50LXByaWNlJzogaGFzUHJvbW90aW9uXHJcblx0fSk7XHJcblxyXG4gIHJldHVybiAoXHJcblx0XHQ8ZGl2PlxyXG5cdFx0XHR7aGFzUHJvbW90aW9uICYmIGlzRGVhbGVyID8gZGVhbGVyUHJpY2UgOiBudWxsfVxyXG5cdFx0XHQ8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e01hdGVyaWFsSWR9IGRhdGEtYWN0aXZlLXRhYj1cInByaWNlXCIgY2xhc3NOYW1lPXtrbGFzc30+e2dvdFNjYWxlZFByaWNlc0ljb259e3Byb21vdGlvbkljb259e2hhc1Byb21vdGlvbiA/IHByb21vdGlvbkVsZW1lbnQgOiBwcmljZUVsbX08L3NwYW4+XHJcblx0XHQ8L2Rpdj5cclxuICApXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBhcnQ7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFBhcnQgZnJvbSAnLi9wYXJ0JztcclxuaW1wb3J0IEtpdCBmcm9tICcuL2tpdCc7XHJcbmltcG9ydCBLaXRQYXJ0IGZyb20gJy4va2l0cGFydCc7XHJcbmltcG9ydCBBZGRUb0NhcnRCdXR0b25zIGZyb20gJy4vYWRkdG9jYXJ0X2J1dHRvbnMnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9wcmljZV9zZXJ2aWNlX2FjdGlvbnMnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9wcmljZV9zZXJ2aWNlX3N0b3JlJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcblxyXG5jbGFzcyBQYXJ0TGlzdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMucHJvcHMgPSAge1xyXG5cdFx0XHRpbGx1c3RyYXRpb246IHtcclxuXHRcdFx0XHRQYXJ0TGlzdDogW11cclxuXHRcdFx0fSxcclxuXHRcdFx0aG90c3BvdElkOm51bGwsXHJcblxyXG5cdFx0fTtcclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdHByaWNlczogW11cclxuXHRcdH1cclxuXHR9XHJcblx0Y29tcG9uZW50RGlkTW91bnQoKXtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBQcmljZVNlcnZpY2VTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0cHJpY2VzOiBQcmljZVNlcnZpY2VTdG9yZS5nZXRQcmljZXMoKVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG4gIH1cclxuXHJcblx0Y29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpe1xyXG5cdFx0aWYoIXRoaXMucHJvcHMuaWxsdXN0cmF0aW9uKSByZXR1cm4gbnVsbDtcclxuXHRcdGlmKCF0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5QYXJ0TGlzdCkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0Ly8gY29uc29sZS5sb2coJ3BhcnRsaXN0LTEnKTtcclxuXHJcblx0XHRpZih0aGlzLnN0YXRlLnByaWNlcy5sZW5ndGggPT09IDAgJiYgdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uSWQgPT09IG5leHRQcm9wcy5pbGx1c3RyYXRpb24uSWQpe1xyXG5cdFx0XHR0aGlzLnByaWNlUmVxdWVzdCgpO1xyXG5cdFx0fVxyXG5cdFx0aWYodGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uSWQgIT09IG5leHRQcm9wcy5pbGx1c3RyYXRpb24uSWQpe1xyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRwcmljZXM6IFtdXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRwcmljZVJlcXVlc3QoKXtcclxuXHJcblx0XHR0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5LaXRzLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgaWYoaXRlbS5Jc1F1ZXJ5YWJsZSAmJiAhaXRlbS5Jc0Jsb2NrZWQpe1xyXG4gICAgICAgIFByaWNlU2VydmljZUFjdGlvbnMuYWRkTWF0ZXJpYWxzKGl0ZW0uTWF0ZXJpYWxJZCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uUGFydExpc3QuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG4gICAgICBpZihpdGVtLklzUXVlcnlhYmxlICYmICFpdGVtLklzQmxvY2tlZCl7XHJcbiAgICAgICAgUHJpY2VTZXJ2aWNlQWN0aW9ucy5hZGRNYXRlcmlhbHMoaXRlbS5NYXRlcmlhbElkKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG5cclxuICAgIFByaWNlU2VydmljZUFjdGlvbnMuZmV0Y2hQcmljZXMoaGlhYmNvbmZpZy5qc1ByaWNlQmF0Y2hBbW91bnQpO1xyXG4gIH1cclxuXHRyZW5kZXIoKSB7XHJcblxyXG5cdFx0aWYoIXRoaXMucHJvcHMuaWxsdXN0cmF0aW9uKSByZXR1cm4gbnVsbDtcclxuXHRcdGlmKCF0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5QYXJ0TGlzdCAmJiAhdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uS2l0cykgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IFByaWNlU2VydmljZVVuYXZhaWxhYmxlTWVzc2FnZTtcclxuXHRcdGlmKHRoaXMucHJvcHMuaWxsdXN0cmF0aW9uLlByaWNlU2VydmljZVVuYXZhaWxhYmxlTWVzc2FnZSl7XHJcblx0XHRcdFByaWNlU2VydmljZVVuYXZhaWxhYmxlTWVzc2FnZSA9IDxwIGNsYXNzTmFtZT1cInByaWNlLW1hbmFnZS1pbmZvXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1hdHRlbnRpb24tY2lyY2xlZFwiPjwvaT57dGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uUHJpY2VTZXJ2aWNlVW5hdmFpbGFibGVNZXNzYWdlfTwvcD47XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHBhcnRzID0gW107XHJcblx0XHRsZXQga2l0UGFydHMgPSBbXTtcclxuXHJcblx0XHRpZih0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5LaXRzKXtcclxuXHRcdFx0dGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uS2l0cy5mb3JFYWNoKChraXQpID0+IHtcclxuXHJcblx0XHRcdFx0bGV0IGtleSA9ICdtb2JpbGUnICsga2l0LklkO1xyXG5cdFx0XHRcdGxldCBwYXJ0cyA9ICdwYXJ0cy0nK2tpdC5JZDtcclxuXHJcblx0XHRcdFx0bGV0IHByaWNlID0gW107XHJcblxyXG5cdFx0XHRcdGlmKGtpdC5Jc1F1ZXJ5YWJsZSl7XHJcblx0XHRcdFx0XHRwcmljZSA9IHRoaXMuc3RhdGUucHJpY2VzLmZpbHRlcihmdW5jdGlvbiggcHJpY2UgKSB7XHJcblx0XHRcdCAgXHRcdHJldHVybiBwcmljZS5Db2RlID09IGtpdC5NYXRlcmlhbElkO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRwcmljZSA9IFt7XHJcblx0XHRcdFx0XHRcdEJ1eWFibGU6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHRJblN0b2NrUXVhbnRpdHk6IDAsXHJcblx0XHRcdFx0XHRcdENvZGU6IGtpdC5NYXRlcmlhbElkLFxyXG5cdFx0XHRcdFx0XHRQcmljZTogXCJcIixcclxuXHRcdFx0XHRcdFx0U2hpcHBpbmdEYXRlOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRJc0Rpc2NvdW50ZWQ6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHREZWZhdWx0UHJpY2U6IFwiXCIsXHJcblx0XHRcdFx0XHRcdERpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0XHRcdFx0UHJvZHVjdENvbnRleDogbnVsbFxyXG5cdFx0XHRcdFx0fV07XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRraXRQYXJ0cy5wdXNoKDxLaXQgaXNEZWFsZXI9e3RoaXMuc3RhdGUuaXNEZWFsZXJ9IHByaWNlPXtwcmljZX0gcGFydD17a2l0fSBrZXk9e2tpdC5JZH0gaXNCbG9ja2VkPXtraXQuaXNCbG9ja2VkfSAvPik7XHJcblxyXG5cdFx0XHRcdGlmKGtpdC5QYXJ0TGlzdC5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRcdGtpdFBhcnRzLnB1c2goPEtpdFBhcnQgdG9nZ2xlSWQ9e2tpdC5JZH0ga2l0TmFtZT17dGhpcy5wcm9wcy5pbGx1c3RyYXRpb24uTmFtZX0ga2l0SWQ9e3RoaXMucHJvcHMuaWxsdXN0cmF0aW9uLk1hdGVyaWFsSWR9IHBhcnRzTGlzdD17a2l0LlBhcnRMaXN0fSBrZXk9e3BhcnRzfS8+KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGV0IHByb2R1Y3RDb250ZXh0ID0gbnVsbDtcclxuXHRcdFx0XHRsZXQgYnV5YWJsZSA9IGZhbHNlO1xyXG5cdFx0XHRcdGlmKHR5cGVvZiBwcmljZVswXSAhPT0gJ3VuZGVmaW5lZCcpe1xyXG5cdFx0XHRcdFx0YnV5YWJsZSA9IHByaWNlWzBdLkJ1eWFibGU7XHJcblx0XHRcdFx0XHRwcm9kdWN0Q29udGV4dCA9IHByaWNlWzBdLlByb2R1Y3RDb250ZXh0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihraXQuSXNRdWVyeWFibGUpe1xyXG5cdFx0XHRcdFx0a2l0UGFydHMucHVzaCg8dHIga2V5PXtrZXl9IGNsYXNzTmFtZT1cInNtYWxsLWFkZC10b2NhcnRcIj48QWRkVG9DYXJ0QnV0dG9ucyBCdXlhYmxlPXtidXlhYmxlfSBwYXJ0PXtraXR9IGlzS2l0PXt0cnVlfSBQcm9kdWN0Q29udGV4dD17cHJvZHVjdENvbnRleHR9IC8+PC90cj4pO1xyXG5cdFx0XHRcdFx0Ly9raXRQYXJ0cy5wdXNoKDx0ciBrZXk9e2tleX0gY2xhc3NOYW1lPVwic21hbGwtYWRkLXRvY2FydFwiPjxBZGRUb0NhcnRCdXR0b25zIEJ1eWFibGU9e2J1eWFibGV9IHBhcnQ9e2tpdH0gaXNLaXQ9e3RydWV9IC8+PC90cj4pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRpZih0aGlzLnByb3BzLmlsbHVzdHJhdGlvbi5QYXJ0TGlzdCl7XHJcblx0XHRcdHRoaXMucHJvcHMuaWxsdXN0cmF0aW9uLlBhcnRMaXN0LmZvckVhY2goKHBhcnQpID0+IHtcclxuXHRcdFx0XHRsZXQga2V5ID0gJ21vYmlsZScgKyBwYXJ0LklkO1xyXG5cdFx0XHRcdGxldCBwcmljZSA9IFtdO1xyXG5cdFx0XHRcdGlmKHBhcnQuSXNRdWVyeWFibGUpe1xyXG5cdFx0XHRcdFx0cHJpY2UgPSB0aGlzLnN0YXRlLnByaWNlcy5maWx0ZXIoZnVuY3Rpb24oIHByaWNlICkge1xyXG5cdFx0XHQgIFx0XHRyZXR1cm4gcHJpY2UuQ29kZSA9PSBwYXJ0Lk1hdGVyaWFsSWQ7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdHByaWNlID0gW3tcclxuXHRcdFx0XHRcdFx0QnV5YWJsZTogZmFsc2UsXHJcblx0XHRcdFx0XHRcdEluU3RvY2tRdWFudGl0eTogMCxcclxuXHRcdFx0XHRcdFx0Q29kZTogcGFydC5NYXRlcmlhbElkLFxyXG5cdFx0XHRcdFx0XHRQcmljZTogXCJcIixcclxuXHRcdFx0XHRcdFx0U2hpcHBpbmdEYXRlOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRJc0Rpc2NvdW50ZWQ6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHREZWZhdWx0UHJpY2U6IFwiXCIsXHJcblx0XHRcdFx0XHRcdERpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0XHRcdFx0UHJvZHVjdENvbnRleDogbnVsbFxyXG5cdFx0XHRcdFx0fV07XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRwYXJ0cy5wdXNoKDxQYXJ0IGlzRGVhbGVyPXt0aGlzLnN0YXRlLmlzRGVhbGVyfSBwcmljZT17cHJpY2V9IHBhcnQ9e3BhcnR9IGtleT17cGFydC5JZH0gaG90c3BvdElkPXt0aGlzLnByb3BzLmhvdHNwb3RJZH0gaXNCbG9ja2VkPXtwYXJ0LmlzQmxvY2tlZH0gbW9kZWw9e3RoaXMucHJvcHMubW9kZWx9Lz4pO1xyXG5cclxuXHRcdFx0XHRsZXQgYnV5YWJsZSA9IGZhbHNlO1xyXG5cdFx0XHRcdGxldCBwcm9kdWN0Q29udGV4dCA9IG51bGw7XHJcblx0XHRcdFx0aWYodHlwZW9mIHByaWNlWzBdICE9PSAndW5kZWZpbmVkJyl7XHJcblx0XHRcdFx0XHRidXlhYmxlID0gcHJpY2VbMF0uQnV5YWJsZTtcclxuXHRcdFx0XHRcdHByb2R1Y3RDb250ZXh0ID0gcHJpY2VbMF0uUHJvZHVjdENvbnRleHQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmKHBhcnQuSXNRdWVyeWFibGUpe1xyXG5cdFx0XHRcdFx0cGFydHMucHVzaCg8dHIga2V5PXtrZXl9IGNsYXNzTmFtZT1cInNtYWxsLWFkZC10b2NhcnRcIj48QWRkVG9DYXJ0QnV0dG9ucyBCdXlhYmxlPXtidXlhYmxlfSBwYXJ0PXtwYXJ0fSBQcm9kdWN0Q29udGV4dD17cHJvZHVjdENvbnRleHR9IC8+PC90cj4pO1xyXG5cdFx0XHRcdFx0Ly9wYXJ0cy5wdXNoKDx0ciBrZXk9e2tleX0gY2xhc3NOYW1lPVwic21hbGwtYWRkLXRvY2FydFwiPjxBZGRUb0NhcnRCdXR0b25zIEJ1eWFibGU9e2J1eWFibGV9IHBhcnQ9e3BhcnR9IC8+PC90cj4pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHJcblx0XHRpZihwYXJ0cy5sZW5ndGggPT09IDAgJiYga2l0UGFydHMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgbGFuZyA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblxyXG5cdFx0XHQ8ZGl2PlxyXG5cdFx0XHRcdHtQcmljZVNlcnZpY2VVbmF2YWlsYWJsZU1lc3NhZ2V9XHJcblx0XHRcdFx0PHRhYmxlIGNsYXNzTmFtZT1cInVjLXByb2R1Y3R0YWJsZVwiPlxyXG5cdFx0XHRcdFx0PHRoZWFkPlxyXG5cdFx0XHRcdFx0XHQ8dHI+XHJcblx0XHRcdFx0XHRcdFx0PHRoIHNjb3BlPVwiY29sXCI+IzwvdGg+XHJcblx0XHRcdFx0XHRcdFx0PHRoIHNjb3BlPVwiY29sXCI+e2xhbmcucGFydH08L3RoPlxyXG5cdFx0XHRcdFx0XHRcdDx0aCBzY29wZT1cImNvbFwiPntsYW5nLnF1YW50aXR5fTwvdGg+XHJcblx0XHRcdFx0XHRcdFx0PHRoIHNjb3BlPVwiY29sXCI+e2xhbmcucHJpY2V9PC90aD5cclxuXHRcdFx0XHRcdFx0XHQ8dGg+PC90aD5cclxuXHRcdFx0XHRcdFx0XHQ8dGggc2NvcGU9XCJjb2xcIj57bGFuZy5zdG9ja308L3RoPlxyXG5cdFx0XHRcdFx0XHRcdDx0aCBzY29wZT1cImNvbFwiPjwvdGg+XHJcblx0XHRcdFx0XHRcdFx0PHRoIHNjb3BlPVwiY29sXCI+PC90aD5cclxuXHRcdFx0XHRcdFx0PC90cj5cclxuXHRcdFx0XHRcdDwvdGhlYWQ+XHJcblx0XHRcdFx0XHQ8dGJvZHk+XHJcblx0XHRcdFx0XHRcdHtraXRQYXJ0c31cclxuXHRcdFx0XHRcdFx0e3BhcnRzfVxyXG5cdFx0XHRcdFx0PC90Ym9keT5cclxuXHRcdFx0XHQ8L3RhYmxlPlxyXG5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBQYXJ0TGlzdDtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiXHJcbmxldCBVcmxIYW5kbGVyID0ge1xyXG4gICAgR2V0VXJsUGFyYW1ldGVycygpXHJcbiAgICB7XHJcbiAgICAgICAgbGV0IHZhcnMgPSBbXSwgaGFzaDtcclxuICAgICAgICBsZXQgaGFzaGVzID0gd2luZG93LmxvY2F0aW9uLmhyZWYuc2xpY2Uod2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZignPycpICsgMSkuc3BsaXQoJyYnKTtcclxuXHJcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGhhc2hlcy5sZW5ndGg7IGkrKylcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIGhhc2ggPSBoYXNoZXNbaV0uc3BsaXQoJz0nKTtcclxuICAgICAgICAgICAgdmFycy5wdXNoKGhhc2hbMF0pO1xyXG4gICAgICAgICAgICB2YXJzW2hhc2hbMF1dID0gaGFzaFsxXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHZhcnMpO1xyXG4gICAgICAgIHJldHVybiB2YXJzO1xyXG4gICAgfSxcclxuXHJcbiAgICBHZXRQYXJhbWV0ZXJCeVN0cmluZyhwYXJhbSkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBVcmxIYW5kbGVyLkdldFVybFBhcmFtZXRlcnMoKVtwYXJhbV07XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2cocmVzdWx0KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFVybEhhbmRsZXI7IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBTZWFyY2hSZXN1bHRTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3NlYXJjaF9yZXN1bHRfc3RvcmUnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR3JvdXBTZWxlY3RvciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGdyb3VwczogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCkuZ3JvdXBzLFxyXG4gICAgICBzZWxlY3RlZEdyb3VwOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRTZWxlY3RlZEdyb3VwKCksXHJcblx0XHRcdGxvYWRpbmc6IFNlYXJjaFJlc3VsdFN0b3JlLmdldExvYWRpbmcoKVxyXG4gICAgfTtcclxuICB9XHJcbiAgY29tcG9uZW50RGlkTW91bnQoKXtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBTZWFyY2hSZXN1bHRTdG9yZS5saXN0ZW4oICgpID0+XHJcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGdyb3VwczogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0SW5pdGlhbFN0YXRlKCkuZ3JvdXBzLFxyXG4gICAgICAgIHNlbGVjdGVkR3JvdXA6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkR3JvdXAoKSxcclxuICAgICAgICBsb2FkaW5nOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRMb2FkaW5nKClcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuICBoYW5kbGVDaGFuZ2UoZSl7XHJcbiAgICB0aGlzLnNldFN0YXRlKHtcclxuICAgICAgc2VsZWN0ZWRHcm91cDogZS50YXJnZXQudmFsdWVcclxuICAgIH0pO1xyXG4gICAgU2VhcmNoUmVzdWx0U3RvcmUub25Hcm91cFNlbGVjdG9yQ2hhbmdlKGUudGFyZ2V0LnZhbHVlKTtcclxuICB9XHJcbiAgcmVuZGVyKCkge1xyXG4gICAgbGV0IHsgZ3JvdXBzIH0gPSB0aGlzLnN0YXRlO1xyXG4gICAgbGV0IGdyb3VwTmFtZXMgPSBPYmplY3Qua2V5cyhncm91cHMpO1xyXG5cclxuXHRcdGxldCByYWRpb0ZpbHRlckNsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdyYWRpby1maWx0ZXInOiB0cnVlLFxyXG5cdFx0XHQnaXMtbG9hZGluZyc6IHRoaXMuc3RhdGUubG9hZGluZ1xyXG5cdFx0fSk7XHJcblxyXG4gICAgaWYoZ3JvdXBOYW1lcy5sZW5ndGggPCAyKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICByZXR1cm4gKFxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cInVjLWZpbHRlci10eXBlXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJyb3dcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic21hbGwtMTIgY29sdW1uc1wiIGlkPVwiZ3JvdXAtc2VsZWN0b3JcIj5cclxuICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT17cmFkaW9GaWx0ZXJDbGFzc30+XHJcbiAgICAgICAgICAgICAge2dyb3VwTmFtZXMubWFwKG5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGdyb3VwID0gZ3JvdXBzW25hbWVdO1xyXG4gICAgICAgICAgICAgICAgbGV0IHtsYWJlbCwgbWF0Y2hpbmd9ID0gZ3JvdXA7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXNTZWxlY3RlZCA9IG5hbWUgPT09IHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cDtcclxuXHRcdFx0XHRcdFx0XHRcdGlmKGxhYmVsICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAgICAgICA8bGkga2V5PXtuYW1lfT5cclxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj17XCJmaWx0ZXItXCIgKyBuYW1lfT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiZmlsdGVyLXR5cGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZD17XCJmaWx0ZXItXCIgKyBuYW1lfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17bmFtZX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZD17aXNTZWxlY3RlZH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbmdlLmJpbmQodGhpcyl9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXttYXRjaGluZyA9PSAwICYmICFpc1NlbGVjdGVkfVxyXG4gICAgICAgICAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgICAgICAgICAgIHtsYWJlbH0gPHNwYW4gY2xhc3NOYW1lPVwiaGl0c1wiPnttYXRjaGluZ308L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICB9KX1cclxuICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBPdGhlclJlc3VsdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICB9XHJcblx0aW1nT25Mb2FkKCl7XHJcblx0XHR2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuXHRcdHZhciB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTtcclxuXHRcdHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTtcclxuXHJcblx0XHRpZiAobXNpZSA+IDAgfHwgdHJpZGVudCA+IDApIHtcclxuXHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcudWMtcHJvZHVjdGxpc3QgdWwnKSk7XHJcblx0XHRcdEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnVjLXByb2R1Y3RsaXN0JykpO1xyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5hbW91bnQtcHJpY2Utc3RvY2std2F0Y2gnKSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbignZXF1YWxpemVyJywgJ3JlZmxvdycpO1xyXG5cdFx0fVxyXG5cdH1cclxuICByZW5kZXIoKSB7XHJcblx0XHRsZXQgaXRlbSA9IHRoaXMucHJvcHMuaXRlbTtcclxuXHJcblx0XHRsZXQgaW1hZ2VzID0gPGRpdiBjbGFzc05hbWU9XCJpY29uXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1kb2MtaW52XCI+PC9pPjwvZGl2PjtcclxuXHRcdGxldCB0YXJnZXQgPSBudWxsO1xyXG5cdFx0aWYoaXRlbS5pbWFnZXMpe1xyXG5cdFx0XHRsZXQgaW1hZ2UgPSAnL2ltZy9wcm9kdWN0LXBsYWNlaG9sZGVyMngyLnBuZyc7XHJcblx0XHRcdGlmKGl0ZW0uaW1hZ2VzWzBdLnVybCAmJiBpdGVtLmltYWdlc1swXS51cmwgIT09ICcnKSBpbWFnZSA9IGl0ZW0uaW1hZ2VzWzBdLnVybDtcclxuXHRcdFx0aW1hZ2VzID0gPGRpdiBjbGFzc05hbWU9XCJpbWFnZVwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiaW1hZ2VcIj48aW1nIG9uTG9hZD17dGhpcy5pbWdPbkxvYWQuYmluZCh0aGlzKX0gb25FcnJvcj17dGhpcy5pbWdPbkxvYWQuYmluZCh0aGlzKX0gc3JjPXtpbWFnZX0gYWx0PXtpdGVtLm5hbWV9Lz48L2Rpdj5cclxuXHRcdH1cclxuXHRcdGlmKGl0ZW0udGFyZ2V0KXtcclxuXHRcdFx0dGFyZ2V0ID0gaXRlbS50YXJnZXQ7XHJcblx0XHR9XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICA8bGkga2V5PXtpdGVtLnVybH0+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpdGVtLXdyYXBwZXJcIj5cclxuICBcdFx0XHRcdHtpbWFnZXN9XHJcbiAgXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tbmFtZVwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiaXRlbS1uYW1lXCI+XHJcbiAgXHRcdFx0XHRcdDxoND57aXRlbS5uYW1lfTwvaDQ+XHJcbiAgXHRcdFx0XHQ8L2Rpdj5cclxuICBcdFx0XHRcdDxkaXYgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJhZGQtdG8tYnRucyB1LWR0XCIgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiPlxyXG4gIFx0XHRcdFx0XHQ8YSBocmVmPXtpdGVtLnVybH0gdGFyZ2V0PXt0YXJnZXR9IGNsYXNzTmFtZT1cImJ1dHRvbiBjZW50ZXIgbm90LWJ1eWFibGUgYWRkLXRvLWNhcnRcIj57aXRlbS5saW5rVGV4dH08L2E+XHJcbiAgXHRcdFx0XHQ8L2Rpdj5cclxuICBcdFx0XHQ8L2Rpdj5cclxuICBcdFx0PC9saT5cclxuICAgICk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBPdGhlclJlc3VsdCBmcm9tICcuL290aGVyX3Jlc3VsdCc7XHJcbmltcG9ydCBTcGFyZVBhcnRSZXN1bHQgZnJvbSAnLi9zcGFyZV9wYXJ0X3Jlc3VsdCc7XHJcbmltcG9ydCBTZWFyY2hSZXN1bHRTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3NlYXJjaF9yZXN1bHRfc3RvcmUnO1xyXG5pbXBvcnQgU2VhcmNoU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9zZWFyY2hfc3RvcmUnO1xyXG5pbXBvcnQgU2VhcmNoQWN0aW9ucyBmcm9tICcuLi8uLi9fYWN0aW9ucy9zZWFyY2hfYWN0aW9ucyc7XHJcbmltcG9ydCBMb2NhbGl6YXRpb25TdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2xvY2FsaXphdGlvbl9zdG9yZSc7XHJcbmltcG9ydCBQcmljZVNlcnZpY2VBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3ByaWNlX3NlcnZpY2VfYWN0aW9ucyc7XHJcbmltcG9ydCBQcmljZVNlcnZpY2VTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3ByaWNlX3NlcnZpY2Vfc3RvcmUnO1xyXG5pbXBvcnQgQ3VzdG9tU2VhcmNoRXZlbnRzIGZyb20gJy4uLy4uL19saWIvY3VzdG9tLXNlYXJjaC1ldmVudHMnXHJcblxyXG52YXIgdHJhbnNsYXRpb25zID0ge31cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc3VsdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGJhdGNoU2l6ZTogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0QmF0Y2hTaXplKCksXHJcblx0XHRcdHNlbGVjdGVkR3JvdXA6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkR3JvdXAoKSxcclxuXHRcdFx0cmVzdWx0SXRlbXM6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkSXRlbXMoKSxcclxuXHRcdFx0bW9yZVJlc3VsdHNBdmFpbGFibGU6IFNlYXJjaFJlc3VsdFN0b3JlLmdldE1vcmVSZXN1bHRzQXZhaWxhYmxlKCksXHJcblx0XHRcdGlzU2lnbmVkSW46IFNlYXJjaFJlc3VsdFN0b3JlLmdldFVzZXJTaWduZWRJbigpLFxyXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcclxuXHRcdFx0aXNEZWFsZXI6IGZhbHNlXHJcbiAgICB9O1xyXG5cclxuICAgIHRyYW5zbGF0aW9ucy5sb2FkTW9yZSA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL0xvYWRNb3JlJyk7XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnREaWRNb3VudCgpe1xyXG4gICAgcmVmbG93KCk7XHJcblxyXG4gICAgaWYodGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwID09ICdsaWdodFNwYXJlUGFydFZpZXdNb2RlbCcgfHwgdGhpcy5zdGF0ZS5zZWxlY3RlZEdyb3VwID09ICdzcGFyZVBhcnRzJyl7XHJcbiAgICAgIHRoaXMucHJpY2VSZXF1ZXN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy51bnN1YnNjcmliZSA9IFNlYXJjaFJlc3VsdFN0b3JlLmxpc3RlbiggKHNlYXJjaFN0b3JlU3RhdGUpID0+IHtcclxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XHJcbiAgICAgICAgYmF0Y2hTaXplOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRCYXRjaFNpemUoKSxcclxuICAgICAgICBzZWxlY3RlZEdyb3VwOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRTZWxlY3RlZEdyb3VwKCksXHJcbiAgICAgICAgcmVzdWx0SXRlbXM6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkSXRlbXMoKSxcclxuICAgICAgICBtb3JlUmVzdWx0c0F2YWlsYWJsZTogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0TW9yZVJlc3VsdHNBdmFpbGFibGUoKSxcclxuXHRcdFx0XHRpc1NpZ25lZEluOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRVc2VyU2lnbmVkSW4oKSxcclxuICAgICAgICBsb2FkaW5nOiBzZWFyY2hTdG9yZVN0YXRlLmxvYWRpbmdcclxuICAgICAgfSk7XHJcbiAgICAgIGlmKHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cCA9PSAnbGlnaHRTcGFyZVBhcnRWaWV3TW9kZWwnIHx8IHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cCA9PSAnc3BhcmVQYXJ0cycpe1xyXG4gICAgICAgIHRoaXMucHJpY2VSZXF1ZXN0KCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy51bnN1YnNjcmliZTIgPSBQcmljZVNlcnZpY2VTdG9yZS5saXN0ZW4oIChwcmljZVNlcnZpY2VTdG9yZSkgPT4ge1xyXG4gICAgICByZWZsb3coKTtcclxuICAgIH0pO1xyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdGlzRGVhbGVyOiAkKCdib2R5LmlzLWRlYWxlcicpLmxlbmd0aCA+IDBcclxuXHRcdH0pO1xyXG4gICAgQ3VzdG9tU2VhcmNoRXZlbnRzLnRyYWNrRnVsbFNlYXJjaFBhZ2VMb2FkKCk7XHJcbiAgfVxyXG5cclxuICBsb2FkTmV4dFBhZ2UoKSB7XHJcbiAgICBTZWFyY2hBY3Rpb25zLmxvYWROZXh0UGFnZSh0aGlzLnN0YXRlLnNlbGVjdGVkR3JvdXApO1xyXG4gIH1cclxuXHJcbiAgcHJpY2VSZXF1ZXN0KCl7XHJcbiAgICB2YXIgcHJpY2VzSW5TdG9yZSA9IFByaWNlU2VydmljZVN0b3JlLmdldFByaWNlcygpO1xyXG4gICAgdmFyIHByaWNlc0luU3RvcmVDb2RlcyA9IHByaWNlc0luU3RvcmUubWFwKCBmdW5jdGlvbihwcmljZUluU3RvcmUpeyByZXR1cm4gcHJpY2VJblN0b3JlLkNvZGU7IH0pO1xyXG5cclxuICAgIHZhciByZXN1bHRJdGVtc05vdEluUHJpY2VTdG9yZSA9IHRoaXMuc3RhdGUucmVzdWx0SXRlbXMuZmlsdGVyKCBmdW5jdGlvbihyZXN1bHRJdGVtKSB7XHJcbiAgICAgIHJldHVybiBwcmljZXNJblN0b3JlQ29kZXMuaW5kZXhPZihyZXN1bHRJdGVtLm1hdGVyaWFsTnVtYmVyKSA8IDBcclxuICAgIH0pO1xyXG5cclxuICAgIHJlc3VsdEl0ZW1zTm90SW5QcmljZVN0b3JlLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgaWYoaXRlbS5pc1F1ZXJ5YWJsZSl7XHJcbiAgICAgICAgUHJpY2VTZXJ2aWNlQWN0aW9ucy5hZGRNYXRlcmlhbHMoaXRlbS5tYXRlcmlhbE51bWJlcik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgUHJpY2VTZXJ2aWNlQWN0aW9ucy5mZXRjaFByaWNlcyhTZWFyY2hSZXN1bHRTdG9yZS5nZXRCYXRjaFNpemUoKSk7XHJcbiAgfVxyXG5cclxuICByZW5kZXIoKSB7XHJcblxyXG4gICAgbGV0IHsgc2VsZWN0ZWRHcm91cCwgbG9hZGluZywgcmVzdWx0SXRlbXMsIG1vcmVSZXN1bHRzQXZhaWxhYmxlIH0gPSB0aGlzLnN0YXRlO1xyXG4gICAgaWYoIXJlc3VsdEl0ZW1zKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBsZXQgcmVzdWx0ID0gW107XHJcbiAgICBpZihzZWxlY3RlZEdyb3VwID09ICdsaWdodFNwYXJlUGFydFZpZXdNb2RlbCcgfHwgc2VsZWN0ZWRHcm91cCA9PSAnc3BhcmVQYXJ0cycpe1xyXG4gICAgICByZXN1bHQgPSByZXN1bHRJdGVtcy5tYXAoKHgpID0+IHtcclxuICBcdFx0XHRyZXR1cm4gKFxyXG4gIFx0XHRcdFx0PFNwYXJlUGFydFJlc3VsdCBpc0RlYWxlcj17dGhpcy5zdGF0ZS5pc0RlYWxlcn0gdXNlcklzU2lnbmVkSW49e3RoaXMuc3RhdGUuaXNTaWduZWRJbn0gdHlwZT17c2VsZWN0ZWRHcm91cH0ga2V5PXt4Lm1hdGVyaWFsTnVtYmVyfSB7Li4ueH0gLz5cclxuICBcdFx0XHQpO1xyXG4gIFx0XHR9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJlc3VsdCA9IHJlc3VsdEl0ZW1zLm1hcCgocmVzdWx0SXRlbSkgPT4ge1xyXG4gIFx0XHRcdHJldHVybiAoXHJcbiAgXHRcdFx0XHQ8T3RoZXJSZXN1bHQga2V5PXtyZXN1bHRJdGVtLnVybH0gaXRlbT17cmVzdWx0SXRlbX0gLz5cclxuICBcdFx0XHQpO1xyXG4gIFx0XHR9KTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgc2VjdGlvbkNsYXNzID0gJ3VjLXByb2R1Y3RsaXN0JztcclxuICAgICAgICBzZWN0aW9uQ2xhc3MgKz0gbG9hZGluZyA/ICcgbG9hZGluZycgOiAnJztcclxuICAgIGxldCBsaXN0Q2xhc3MgPSBzZWxlY3RlZEdyb3VwID09ICdzcGFyZVBhcnRzJyA/IFwicmVzdWx0LXNwYXJlLXBhcnRzXCIgOiBcInJlc3VsdC1vdGhlclwiO1xyXG5cclxuICAgIHJldHVybiAoXHJcbiAgICAgIDxzZWN0aW9uIGRhdGEtZXF1YWxpemVyPVwiYWRkLXRvLWJ0bnNcIiBkYXRhLW9wdGlvbnM9XCJlcXVhbGl6ZV9vbl9zdGFjazogdHJ1ZVwiIGRhdGEtZXF1YWxpemVyLW1xPVwic21hbGwtdXBcIiBjbGFzc05hbWU9e3NlY3Rpb25DbGFzc30+XHJcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJhbW91bnQtcHJpY2Utc3RvY2std2F0Y2hcIiBkYXRhLWVxdWFsaXplcj1cImFtb3VudC1wcmljZS1zdG9ja1wiIGRhdGEtb3B0aW9ucz1cImVxdWFsaXplX29uX3N0YWNrOiB0cnVlXCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0td3JhcHBlci13YXRjaFwiPlxyXG4gICAgICAgICAgICA8dWwgZGF0YS1lcXVhbGl6ZXI9XCJpdGVtLW5hbWVcIiBkYXRhLW9wdGlvbnM9XCJlcXVhbGl6ZV9vbl9zdGFjazogdHJ1ZVwiIGRhdGEtZXF1YWxpemVyLW1xPVwic21hbGwtdXBcIiBjbGFzc05hbWU9e2xpc3RDbGFzc30+XHJcbiAgICAgICAgICAgICAge3Jlc3VsdH1cclxuICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAge21vcmVSZXN1bHRzQXZhaWxhYmxlID8gPExvYWRNb3JlQnV0dG9uIG9uQ2xpY2s9e3RoaXMubG9hZE5leHRQYWdlLmJpbmQodGhpcyl9IC8+IDogbnVsbH1cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L3NlY3Rpb24+XHJcbiAgICApO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVmbG93KCkge1xyXG4gIHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG4gIHZhciB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTtcclxuICB2YXIgbXNpZSA9IHVhLmluZGV4T2YoJ01TSUUgJyk7XHJcbiAgaWYgKG1zaWUgPiAwIHx8IHRyaWRlbnQgPiAwKSB7XHJcbiAgICAkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG4gICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5yZXN1bHQtc3BhcmUtcGFydHMnKSk7XHJcbiAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnVjLXByb2R1Y3RsaXN0JykpO1xyXG4gICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5hbW91bnQtcHJpY2Utc3RvY2std2F0Y2gnKSk7XHJcblx0XHRcdEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLml0ZW0tbmFtZS13YXRjaCcpKTtcclxuICAgIH0pO1xyXG5cclxuICB9XHJcbiAgZWxzZSB7XHJcbiAgICAkKGRvY3VtZW50KS5mb3VuZGF0aW9uKCdlcXVhbGl6ZXInLCAncmVmbG93Jyk7XHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBMb2FkTW9yZUJ1dHRvbiA9IChwcm9wcykgPT4ge1xyXG4gIHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cInVjLWxvYWRtb3JlLXByb2R1Y3RzXCI+XHJcbiAgICAgIDxidXR0b24gb25DbGljaz17cHJvcHMub25DbGlja30+e3RyYW5zbGF0aW9ucy5sb2FkTW9yZX0gPGkgY2xhc3NOYW1lPVwiYW5pbWF0ZS1zcGluIGljb24tc3BpbjRcIj48L2k+PC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICApO1xyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBTZWFyY2hBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3NlYXJjaF9hY3Rpb25zJztcclxuaW1wb3J0IFNlYXJjaFN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvc2VhcmNoX3N0b3JlJztcclxuaW1wb3J0IFNlYXJjaFJlc3VsdFN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvc2VhcmNoX3Jlc3VsdF9zdG9yZSc7XHJcbmltcG9ydCBzbWFydHNlYXJjaCBmcm9tICcuLi8uLi9zZWFyY2gvc21hcnRfc2VhcmNoJztcclxuaW1wb3J0IGNsYXNzbmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBQcmljZVNlcnZpY2VBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3ByaWNlX3NlcnZpY2VfYWN0aW9ucyc7XHJcbmltcG9ydCBCcmFuZEZpbHRlclN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvYnJhbmRfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9wcm9kdWN0X2xpbmVfZmlsdGVyX3N0b3JlJztcclxuaW1wb3J0IFVzYWdlVHlwZUZpbHRlclN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvdXNhZ2VfdHlwZV9maWx0ZXJfc3RvcmUnO1xyXG5pbXBvcnQgVG9wTGV2ZWxDYXRlZ29yeUZpbHRlclN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvdG9wX2NhdGVnb3J5X2ZpbHRlcl9zdG9yZSc7XHJcblxyXG5jb25zdCBkb25lVHlwaW5nSW50ZXJ2YWwgPSAzMDA7XHJcbmxldCBsYW5nID0gaGlhYmNvbmZpZy5zZWFyY2gubGFuZztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlYXJjaEZpZWxkIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0bG9hZGluZzogZmFsc2UsXHJcblx0XHRcdHNlYXJjaFNlcmlhbDogZmFsc2UsXHJcblx0XHRcdHNlYXJjaFRhYnNNb2RhbDogZmFsc2VcclxuXHRcdH07XHJcblx0XHR0aGlzLnR5cGluZ1RpbWVyID0gbnVsbDtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZE1vdW50KCkge1xyXG5cdFx0dGhpcy5pbml0U21hcnRTZWFyY2godGhpcy5zdGF0ZS5zZWFyY2hTZXJpYWwpO1xyXG5cdFx0U2VhcmNoUmVzdWx0U3RvcmUubGlzdGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFTZWFyY2hSZXN1bHRTdG9yZS5nZXRMb2FkaW5nKCkpIHtcclxuXHRcdFx0XHRpZiAoJCgnI3NlYXJjaC1maWVsZC1tb2RhbCAuc3Bpbm5lcicpLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdCQoJyNzZWFyY2gtZmllbGQtbW9kYWwgLnNwaW5uZXInKS5yZW1vdmUoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCQoJy51Yy1zZWFyY2htb2RhbCcpLmhhc0NsYXNzKCdpcy1vcGVuJykgJiYgJCgnYm9keScpLmhhc0NsYXNzKCdzZWFyY2htb2RhbC1vcGVuJykpIHtcclxuXHRcdFx0XHRcdCQoJy51Yy1zZWFyY2htb2RhbCcpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0XHQkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ3NlYXJjaG1vZGFsLW9wZW4nKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0U2VhcmNoU3RvcmUubGlzdGVuKChzZWFyY2hTdG9yZVN0YXRlKSA9PiB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGxvYWRpbmc6IHNlYXJjaFN0b3JlU3RhdGUubG9hZGluZ1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRpbml0U21hcnRTZWFyY2goc2VhcmNoU2VyaWFsKSB7XHJcblx0XHRpZiAoaXNPblNlYXJjaFBhZ2UoKSkge1xyXG5cdFx0XHRpZiAoc2VhcmNoU2VyaWFsKSB7XHJcblx0XHRcdFx0c21hcnRzZWFyY2guaW5pdChzZWFyY2hTZXJpYWwsIGlzT25TZWFyY2hQYWdlKCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzbWFydHNlYXJjaC5pbml0KHNlYXJjaFNlcmlhbCwgaXNPblNlYXJjaFBhZ2UoKSk7XHJcblx0XHR9XHJcblx0fVxyXG5cdGhhbmRsZVF1ZXJ5Q2hhbmdlKHF1ZXJ5KSB7XHJcblx0XHRpZiAocXVlcnkgIT0gJycgJiYgcXVlcnkubGVuZ3RoID4gMSkge1xyXG5cdFx0XHRpZiAoaXNPblNlYXJjaFBhZ2UoKSkge1xyXG5cdFx0XHRcdGlmICghdGhpcy5zdGF0ZS5zZWFyY2hTZXJpYWwpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnR5cGluZ1RpbWVyKSBjbGVhclRpbWVvdXQodGhpcy50eXBpbmdUaW1lcik7XHJcblx0XHRcdFx0XHR0aGlzLnR5cGluZ1RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZG9uZVR5cGluZyhxdWVyeSk7XHJcblx0XHRcdFx0XHR9LCBkb25lVHlwaW5nSW50ZXJ2YWwpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cdFxyXG5cclxuXHRkb25lVHlwaW5nKHF1ZXJ5KSB7XHJcblx0XHQvLyBjbGVhciBmaWx0ZXJzIHdoZW4gbWFrZWluZyBhIG5ldyBzZXJhY2hcclxuXHRcdEJyYW5kRmlsdGVyU3RvcmUub25DbGVhckZpbHRlcnMoKTtcclxuXHRcdFByb2R1Y3RMaW5lRmlsdGVyU3RvcmUub25DbGVhckZpbHRlcnMoKTtcclxuXHRcdFVzYWdlVHlwZUZpbHRlclN0b3JlLm9uQ2xlYXJGaWx0ZXJzKCk7XHJcblx0XHRUb3BMZXZlbENhdGVnb3J5RmlsdGVyU3RvcmUub25DbGVhckZpbHRlcnMoKTtcclxuXHJcblx0XHRQcmljZVNlcnZpY2VBY3Rpb25zLmFib3J0RmV0Y2hQcmljZXMoKTtcclxuXHRcdFNlYXJjaEFjdGlvbnMuc2V0UXVlcnkocXVlcnkpO1xyXG5cdFx0bGV0IHNwaW5uZXIgPSAnPGRpdiBjbGFzcz1cInNwaW5uZXJcIj4nICsgbGFuZy5zZWFyY2hpbmcgKyAnIDxpIGNsYXNzPVwiYW5pbWF0ZS1zcGluIGljb24tc3BpbjRcIj48L2k+PC9kaXY+JztcclxuXHRcdGlmICgkKCcudWMtc2VhcmNobW9kYWwnKS5oYXNDbGFzcygnaXMtb3BlbicpICYmICQoJ2JvZHknKS5oYXNDbGFzcygnc2VhcmNobW9kYWwtb3BlbicpKSB7XHJcblx0XHRcdGlmICgkKCcjc2VhcmNoLWZpZWxkLW1vZGFsIC5zcGlubmVyJykubGVuZ3RoID09PSAwKSB7XHJcblx0XHRcdFx0JCgnI3NlYXJjaC1maWVsZC1tb2RhbCcpLmFwcGVuZChzcGlubmVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Y2xpY2tFbnRlclN1Ym1pdChlKSB7XHJcblx0XHRmdW5jdGlvbiBzZXRMb2FkZXJJY29uQW5kU3VibWl0KCkge1xyXG5cdFx0XHRsZXQgYnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNzZWFyY2gtZmllbGQgYnV0dG9uLCAjc2VhcmNoLWZpZWxkLW1vZGFsIGJ1dHRvbicpO1xyXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHRidXR0b25zW2ldLmNsYXNzTmFtZSArPSAnIGxvYWRpbmcnO1xyXG5cdFx0XHR9XHJcblx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWFyY2gtbWFpbicpLmZvcm0uc3VibWl0KCk7XHJcblx0XHR9XHJcblx0XHRpZiAodGhpcy5zdGF0ZS5zZWFyY2hTZXJpYWwpIHtcclxuXHRcdFx0Y29uc3Qga2V5ID0gZS53aGljaCB8fCBlLmNoYXJDb2RlIHx8IGUua2V5Q29kZTtcclxuXHRcdFx0aWYgKGtleSA9PT0gMTMgfHwgZS50YXJnZXQubm9kZU5hbWUgPT09ICdCVVRUT04nIHx8IGUudGFyZ2V0Lm5vZGVOYW1lID09PSAnU1BBTicgfHwgZS50YXJnZXQubm9kZU5hbWUgPT09ICdJJykge1xyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSBcclxuXHRcdGVsc2UgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbGx1c3RyYXRpb24nKSkge1xyXG5cdFx0XHRjb25zdCBrZXkgPSBlLndoaWNoIHx8IGUuY2hhckNvZGUgfHwgZS5rZXlDb2RlO1xyXG5cdFx0XHRpZiAoa2V5ID09PSAxMyB8fCBlLnRhcmdldC5ub2RlTmFtZSA9PT0gJ0JVVFRPTicgfHwgZS50YXJnZXQubm9kZU5hbWUgPT09ICdTUEFOJyB8fCBlLnRhcmdldC5ub2RlTmFtZSA9PT0gJ0knKSB7XHJcblx0XHRcdFx0c2V0TG9hZGVySWNvbkFuZFN1Ym1pdCgpO1x0XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGVsc2UgaWYgKGlzT25TZWFyY2hQYWdlKCkpIHtcdFx0XHRcclxuXHRcdFx0Y29uc3QgcXVlcnkgPSAkKCcjc2VhcmNoLW1haW4nKS52YWwoKTtcclxuXHRcdFx0aWYgKHF1ZXJ5ICE9ICcnICYmIHF1ZXJ5Lmxlbmd0aCA+IDEpIHtcclxuXHRcdFx0XHR0aGlzLmRvbmVUeXBpbmcocXVlcnkpO1xyXG5cdFx0XHR9XHJcblx0XHRcdCQoJyNzZWFyY2gtbWFpbicpLmZvY3VzKCk7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0c2V0TG9hZGVySWNvbkFuZFN1Ym1pdCgpO1xyXG5cdFx0fVx0XHRcdFx0XHJcblx0fVxyXG5cclxuXHJcblx0aGFuZGxlU3VibWl0KGUpIHtcclxuXHRcdGlmIChpc09uU2VhcmNoUGFnZSgpICYmICF0aGlzLnN0YXRlLnNlYXJjaFNlcmlhbCkge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFNlYXJjaEFjdGlvbnMuaW52YWxpZGF0ZSgpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdGlmICh0aGlzLnN0YXRlLnNlYXJjaFNlcmlhbCkge1xyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRsZXQgYnV0dG9ucyA9IGUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbicpO1xyXG5cdFx0XHRcdGZvciAodmFyIGJ1dHRvbiBpbiBidXR0b25zKSB7XHJcblx0XHRcdFx0XHRpZiAoYnV0dG9ucy5oYXNPd25Qcm9wZXJ0eShidXR0b24pKSB7XHJcblx0XHRcdFx0XHRcdGJ1dHRvbnNbYnV0dG9uXS5jbGFzc05hbWUgKz0gJyBsb2FkaW5nJztcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHRvZ2dsZVNlYXJjaE1vZGFsKCkge1xyXG5cdFx0aWYgKCQoJy51Yy1zZWFyY2htb2RhbCcpLmlzKCcuaXMtb3BlbicpKSB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoeyBzZWFyY2hUYWJzTW9kYWw6IGZhbHNlIH0pO1xyXG5cdFx0XHQkKCcudWMtc2VhcmNobW9kYWwnKS5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoeyBzZWFyY2hUYWJzTW9kYWw6IHRydWUgfSk7XHJcblx0XHRcdCQoJy51Yy1zZWFyY2htb2RhbCcpLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdCQoJ2JvZHknKS5hZGRDbGFzcygnc2VhcmNobW9kYWwtb3BlbicpO1xyXG5cdFx0XHQkKCcuc2VhcmNoLW1haW4nKS5mb2N1cygpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRoYW5kbGVDaGFuZ2VQYXRoKGUpIHtcclxuXHRcdGxldCBzZWFyY2hTZWxlY3RvclZhbHVlID0gZS50YXJnZXQudmFsdWUgPT09IGxhbmcuc2VyaWFsbnVtYmVyO1xyXG5cdFx0dGhpcy5zdGF0ZS5zZWFyY2hTZXJpYWwgPSBzZWFyY2hTZWxlY3RvclZhbHVlO1xyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdHNlYXJjaFNlcmlhbDogZS50YXJnZXQudmFsdWUgPT09IGxhbmcuc2VyaWFsbnVtYmVyXHJcblx0XHR9KTtcclxuXHJcblx0XHRzbWFydHNlYXJjaC5zZXRDb250ZXh0KHRoaXMuc3RhdGUuc2VhcmNoU2VyaWFsLCBpc09uU2VhcmNoUGFnZSgpKTtcclxuXHJcblx0XHRpZiAoaXNPblNlYXJjaFBhZ2UoKSkge1xyXG5cdFx0XHQvLyBUT0RPOiBUZXJtaW5hdGUgY3VycmVudCByZXF1ZXN0c1xyXG5cdFx0XHRpZiAodGhpcy5zdGF0ZS5zZWFyY2hTZXJpYWwpIHtcclxuXHRcdFx0XHR0aGlzLmluaXRTbWFydFNlYXJjaCh0aGlzLnN0YXRlLnNlYXJjaFNlcmlhbCwgdHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0aWYgKCQoJyNzZWFyY2gtZmllbGQgLnVjLXNlYXJjaGZpZWxkIC51aS1hdXRvY29tcGxldGUtaW5wdXQnKS5sZW5ndGggPiAwIHx8ICQoJyNzZWFyY2gtZmllbGQtbW9kYWwgLnVjLXNlYXJjaGZpZWxkIC51aS1hdXRvY29tcGxldGUtaW5wdXQnKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0XHRzbWFydHNlYXJjaC5kZXN0cm95QXV0b0NvbXBsZXRlKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmluaXRTbWFydFNlYXJjaCh0aGlzLnN0YXRlLnNlYXJjaFNlcmlhbCwgZmFsc2UpO1xyXG5cdFx0XHQkKCcjc2VhcmNoLW1haW4nKS5mb2N1cygpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0bGV0IGlucHV0Q2xhc3NuYW1lcyA9IGNsYXNzbmFtZXMoe1xyXG5cdFx0XHQnc2VhcmNoLW1haW4nOiB0cnVlLFxyXG5cdFx0XHRsb2FkaW5nOiB0aGlzLnN0YXRlLmxvYWRpbmdcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCBpbnB1dFByb3BzID0ge1xyXG5cdFx0XHRvbktleURvd246IGUgPT4gdGhpcy5jbGlja0VudGVyU3VibWl0LmJpbmQodGhpcyksXHJcblx0XHRcdG9uS2V5VXA6IGUgPT4gdGhpcy5oYW5kbGVRdWVyeUNoYW5nZShlLnRhcmdldC52YWx1ZSksXHJcblx0XHRcdGRlZmF1bHRWYWx1ZTogU2VhcmNoU3RvcmUuZ2V0UXVlcnkoKSxcclxuXHRcdFx0dHlwZTogJ3NlYXJjaCcsXHJcblx0XHRcdGlkOiAnc2VhcmNoLW1haW4nLFxyXG5cdFx0XHRjbGFzc05hbWU6IGlucHV0Q2xhc3NuYW1lcyxcclxuXHRcdFx0bmFtZTogJ3F1ZXJ5JyxcclxuXHRcdFx0cGxhY2Vob2xkZXI6IGhpYWJjb25maWcudXNlckxvZ2dlZEluID8gKHRoaXMuc3RhdGUuc2VhcmNoU2VyaWFsID8gbGFuZy5wbGFjZWhvbGRlclNlcmlhbCA6IGxhbmcucGxhY2Vob2xkZXJDYXRhbG9nKSA6IGxhbmcucGxhY2Vob2xkZXJcclxuXHRcdH1cclxuXHRcdGxldCBkYXRhQWRkQ2xhc3MgPSAnJztcclxuXHRcdGxldCBkYXRhQWRkZWRDbGFzcyA9ICcnO1xyXG5cdFx0aWYgKGlzT25TZWFyY2hQYWdlKCkgJiYgIXRoaXMuc3RhdGUuc2VhcmNoU2VyaWFsKSB7XHJcblx0XHRcdGlucHV0UHJvcHNbXCJkYXRhLWRpc2FibGUtYXV0b2NvbXBsZXRlXCJdID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHRpZiAoIXRoaXMuc3RhdGUuc2VhcmNoU2VyaWFsKSB7XHJcblx0XHRcdFx0ZGF0YUFkZENsYXNzID0gJyNzZWFyY2gtZmllbGQgYnV0dG9uLXNlYXJjaC1kZXNrdG9wJztcclxuXHRcdFx0XHRkYXRhQWRkZWRDbGFzcyA9ICdsb2FkaW5nJztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBzZWFyY2hJbnB1dCA9IDxkaXYgY2xhc3NOYW1lPVwiY2xlYXJmaXhcIj48aW5wdXQgey4uLmlucHV0UHJvcHN9IC8+PC9kaXY+LFxyXG5cdFx0XHRzZWFyY2hUYWJzID0gXCJcIjtcclxuXHJcblx0XHRpZiAoaGlhYmNvbmZpZy51c2VyTG9nZ2VkSW4pIHtcclxuXHRcdFx0c2VhcmNoSW5wdXQgPSA8ZGl2IGNsYXNzTmFtZT1cImNsZWFyZml4IHVpIGFjdGlvbiBpbnB1dFwiPjxpbnB1dCB7Li4uaW5wdXRQcm9wc30gLz48L2Rpdj47XHJcblx0XHRcdHNlYXJjaFRhYnMgPSA8ZGl2IGNsYXNzTmFtZT1cInNlYXJjaC10YWJzXCI+PGRpdiBjbGFzc05hbWU9XCJzZWFyY2gtdGFiXCI+PGlucHV0IHR5cGU9XCJyYWRpb1wiIGlkPXt0aGlzLnN0YXRlLnNlYXJjaFRhYnNNb2RhbCA/IFwicGFydC1udW1iZXItbW9iaWxlXCIgOiBcInBhcnQtbnVtYmVyXCJ9IG5hbWU9XCJzZWFyY2gtZm9yXCIgZGVmYXVsdENoZWNrZWQgdmFsdWU9e2xhbmcuY2F0YWxvZ30gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbmdlUGF0aC5iaW5kKHRoaXMpfSAvPjxsYWJlbCBodG1sRm9yPXt0aGlzLnN0YXRlLnNlYXJjaFRhYnNNb2RhbCA/IFwicGFydC1udW1iZXItbW9iaWxlXCIgOiBcInBhcnQtbnVtYmVyXCJ9PjxzcGFuIGNsYXNzTmFtZT1cImljb24tc2VhcmNoXCI+PC9zcGFuPntsYW5nLmNhdGFsb2d9PC9sYWJlbD48L2Rpdj48ZGl2IGNsYXNzTmFtZT1cInNlYXJjaC10YWJcIj48aW5wdXQgdHlwZT1cInJhZGlvXCIgaWQ9e3RoaXMuc3RhdGUuc2VhcmNoVGFic01vZGFsID8gXCJzZXJpYWwtbW9iaWxlXCIgOiBcInNlcmlhbFwifSBuYW1lPVwic2VhcmNoLWZvclwiIHZhbHVlPXtsYW5nLnNlcmlhbG51bWJlcn0gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbmdlUGF0aC5iaW5kKHRoaXMpfSAvPjxsYWJlbCBodG1sRm9yPXt0aGlzLnN0YXRlLnNlYXJjaFRhYnNNb2RhbCA/IFwic2VyaWFsLW1vYmlsZVwiIDogXCJzZXJpYWxcIn0+PHNwYW4gY2xhc3NOYW1lPVwiaWNvbi1zZWFyY2hcIj48L3NwYW4+e2xhbmcuc2VyaWFsbnVtYmVyfTwvbGFiZWw+PC9kaXY+PC9kaXY+XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInVjLXNlYXJjaGZpZWxkIGNsZWFyZml4XCI+XHJcblx0XHRcdFx0PGZvcm0gYWN0aW9uPXtoaWFiY29uZmlnLnNlYXJjaFBhZ2UudXJsfSBtZXRob2Q9XCJnZXRcIiBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXQuYmluZCh0aGlzKX0+XHJcblx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBidXR0b24tc2VhcmNoLXRhYmxldCBzZWFyY2hNb2RhbFwiIHR5cGU9XCJidXR0b25cIiBvbkNsaWNrPXt0aGlzLnRvZ2dsZVNlYXJjaE1vZGFsLmJpbmQodGhpcyl9PjxpIGNsYXNzTmFtZT1cImljb24tc2VhcmNoXCI+PC9pPjxzcGFuPntsYW5nLnNlYXJjaH08L3NwYW4+PC9idXR0b24+XHJcblx0XHRcdFx0XHR7c2VhcmNoVGFic31cclxuXHRcdFx0XHRcdDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIGpzLWluaXQtc2VhcmNoXCIgZGF0YS1hZGQtY2xhc3M9e2RhdGFBZGRDbGFzc30gZGF0YS1hZGRlZC1jbGFzcz17ZGF0YUFkZGVkQ2xhc3N9IHR5cGU9XCJidXR0b25cIiBvbkNsaWNrPXt0aGlzLmNsaWNrRW50ZXJTdWJtaXQuYmluZCh0aGlzKX0+PGkgY2xhc3NOYW1lPVwiaWNvbi1zZWFyY2hcIj48L2k+PHNwYW4+e2xhbmcuc2VhcmNofTwvc3Bhbj48L2J1dHRvbj5cclxuXHRcdFx0XHRcdHtzZWFyY2hJbnB1dH1cclxuXHRcdFx0XHQ8L2Zvcm0+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KVxyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gaXNPblNlYXJjaFBhZ2UoKSB7XHJcblx0cmV0dXJuICEhU2VhcmNoU3RvcmUuZ2V0UXVlcnkoKTtcclxufVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgU2VhcmNoUmVzdWx0U3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9zZWFyY2hfcmVzdWx0X3N0b3JlJztcclxuaW1wb3J0IExvY2FsaXphdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvbG9jYWxpemF0aW9uX3N0b3JlJztcclxuaW1wb3J0IFVzYWdlVHlwZUZpbHRlckFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvdXNhZ2VfdHlwZV9maWx0ZXJfYWN0aW9ucyc7XHJcbmltcG9ydCBCcmFuZEZpbHRlckFjdGlvbnMgZnJvbSAnLi4vLi4vX2FjdGlvbnMvYnJhbmRfZmlsdGVyX2FjdGlvbnMnO1xyXG5cclxuLy8gaW1wb3J0IEdyb3VwU2VsZWN0b3IgZnJvbSAnLi4vc2VhcmNoL2dyb3VwX3NlbGVjdG9yJztcclxuaW1wb3J0IEZpbHRlckNvdW50IGZyb20gJy4uL2ZpbHRlci9maWx0ZXJfY291bnQnO1xyXG5pbXBvcnQgVXNhZ2VUeXBlRmlsdGVyIGZyb20gJy4uL2ZpbHRlci91c2FnZV90eXBlX2ZpbHRlcic7XHJcbmltcG9ydCBCcmFuZEZpbHRlciBmcm9tICcuLi9maWx0ZXIvYnJhbmRfZmlsdGVyJztcclxuaW1wb3J0IFNvcnRlciBmcm9tICcuLi9maWx0ZXIvc29ydGVyJztcclxuXHJcbmxldCB0cmFuc2xhdGlvbnMgPSB7fTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlYXJjaEhlYWRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIHNlbGVjdGVkR3JvdXA6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkR3JvdXAoKSxcclxuICAgICAgdG90YWxNYXRjaGluZzogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0VG90YWxNYXRjaGluZygpLFxyXG4gICAgICBsb2FkaW5nOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRMb2FkaW5nKCksXHJcbiAgICAgIHF1ZXJ5OiBTZWFyY2hTdG9yZS5nZXRRdWVyeSgpLFxyXG4gICAgICBzaG93RXh0cmFGaWx0ZXJzOiBmYWxzZVxyXG4gICAgfTtcclxuXHJcbiAgICB0cmFuc2xhdGlvbnMuZmlsdGVycyA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvRmlsdGVyL0ZpbHRlcnMnKTtcclxuICAgIHRyYW5zbGF0aW9ucy5jbGVhckFsbCA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvRmlsdGVyL0NsZWFyQWxsJyk7XHJcbiAgICB0cmFuc2xhdGlvbnMueW91clNlYXJjaEZvciA9ICBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9TZWFyY2hGb3InKTtcclxuICAgIHRyYW5zbGF0aW9ucy5yZXN1bHRlZEluID0gIExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL1Jlc3VsdGVkSW4nKTtcclxuICAgIHRyYW5zbGF0aW9ucy5oaXRzID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9TZWFyY2gvSGl0cycpO1xyXG4gICAgdHJhbnNsYXRpb25zLmhpdCA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL0hpdCcpO1xyXG5cdCAgdHJhbnNsYXRpb25zLnNlYXJjaGluZyA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvU2VhcmNoL1NlYXJjaGluZycpO1xyXG4gICAgdHJhbnNsYXRpb25zLmxvYWRpbmcgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9Mb2FkaW5nJyk7XHJcbiAgfVxyXG5cclxuICBoYW5kbGVDbGVhckFsbENsaWNrKCkge1xyXG4gICAgLy8gdG9kbzogbWFrZSBzdXJlIHRoaXMgZG9lcyBub3QgdHJpZ2dlciBmaWZ0eSBhamF4IHJlcXVlc3RzXHJcbiAgICBVc2FnZVR5cGVGaWx0ZXJBY3Rpb25zLmNsZWFyRmlsdGVycygpO1xyXG4gICAgQnJhbmRGaWx0ZXJBY3Rpb25zLmNsZWFyRmlsdGVycygpO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlRXh0cmFGaWx0ZXJzKCkge1xyXG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dFeHRyYUZpbHRlcnM6ICF0aGlzLnN0YXRlLnNob3dFeHRyYUZpbHRlcnMgfSk7XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnREaWRNb3VudCgpe1xyXG4gICAgdGhpcy51bnN1YnNjcmliZTEgPSBTZWFyY2hSZXN1bHRTdG9yZS5saXN0ZW4oICgpID0+XHJcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xyXG4gICAgICAgIHNlbGVjdGVkR3JvdXA6IFNlYXJjaFJlc3VsdFN0b3JlLmdldFNlbGVjdGVkR3JvdXAoKSxcclxuICAgICAgICB0b3RhbE1hdGNoaW5nOiBTZWFyY2hSZXN1bHRTdG9yZS5nZXRUb3RhbE1hdGNoaW5nKCksXHJcbiAgICAgICAgbG9hZGluZzogU2VhcmNoUmVzdWx0U3RvcmUuZ2V0TG9hZGluZygpXHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMudW5zdWJzY3JpYmUyID0gU2VhcmNoU3RvcmUubGlzdGVuKCgpID0+IHtcclxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XHJcbiAgICAgICAgcXVlcnk6IFNlYXJjaFN0b3JlLmdldFF1ZXJ5KClcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy51bnN1YnNjcmliZTIoKTtcclxuICB9XHJcblxyXG4gIHJlbmRlcigpIHtcclxuICAgIGNvbnN0IHtzZWxlY3RlZEdyb3VwLCB0b3RhbE1hdGNoaW5nLCBxdWVyeSwgbG9hZGluZywgc2hvd0V4dHJhRmlsdGVyc30gPSB0aGlzLnN0YXRlO1xyXG4gICAgbGV0IHNob3dGaWx0ZXJzID0gKHNlbGVjdGVkR3JvdXAgPT0gJ3NwYXJlUGFydHMnIHx8IHNlbGVjdGVkR3JvdXAgPT0gJ2xpZ2h0U3BhcmVQYXJ0Vmlld01vZGVsJykgPyB0cnVlIDogZmFsc2U7XHJcblxyXG4gICAgbGV0IGlzT25TZWFyY2hQYWdlID0gdHlwZW9mKHF1ZXJ5KSAhPT0gJ3VuZGVmaW5lZCc7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuICAgICAgPHNlY3Rpb24gY2xhc3NOYW1lPVwidWMtZmlsdGVyXCI+XHJcbiAgICAgIFx0PGRpdiBjbGFzc05hbWU9XCJyb3dcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic21hbGwtMTIgY29sdW1ucyBmaWx0ZXItc29ydGVyXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmlsdGVyLXNvcnRlci1sZWZ0XCI+XHJcbiAgICAgICAgICAgICAgPFJlc3VsdFN1bW1hcnkgcXVlcnk9e3F1ZXJ5fSB0b3RhbE1hdGNoaW5nPXt0b3RhbE1hdGNoaW5nfSBpc09uU2VhcmNoUGFnZT17aXNPblNlYXJjaFBhZ2V9IGxvYWRpbmc9e2xvYWRpbmd9IC8+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImZpbHRlci1zb3J0ZXItcmlnaHRcIj5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInVjLWxheW91dC10b2dnbGUgcmlnaHQgaGlkZS1mb3Itc21hbGxcIj5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gaWQ9XCJncmlkXCIgY2xhc3NOYW1lPVwiYnV0dG9uIGNpcmNsZSBhY3RpdmVcIj48aSBjbGFzc05hbWU9XCJpY29uLXRoLWxhcmdlXCI+PC9pPjwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBpZD1cImxpc3RcIiBjbGFzc05hbWU9XCJidXR0b24gY2lyY2xlXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1tZW51LTFcIj48L2k+PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgIFx0PC9kaXY+XHJcblxyXG4gICAgICA8L3NlY3Rpb24+XHJcbiAgICApO1xyXG4gIH1cclxufVxyXG5cclxuY29uc3QgRXh0cmFGaWx0ZXJzID0gKHByb3BzKSA9PntcclxuICByZXR1cm4gKFxyXG4gICAgPGRpdiBjbGFzc05hbWU9XCJtZWRpdW0tNCBtZWRpdW0tcHVsbC04IGxhcmdlLTMgbGFyZ2UtcHVsbC05IGNvbHVtbnMgZmlsdGVyLXRvZ2dsZVwiPlxyXG4gICAgICA8YnV0dG9uIGNsYXNzTmFtZT1cInJvdW5kIGJ1dHRvbiBsZWZ0IGZpbHRlcnMtZXhwYW5kXCIgb25DbGljaz17cHJvcHMudG9nZ2xlRXh0cmFGaWx0ZXJzfT48aSBjbGFzc05hbWU9XCJpY29uLWFuZ2xlLWRvd25cIj48L2k+e3RyYW5zbGF0aW9ucy5maWx0ZXJzfTogPEZpbHRlckNvdW50IC8+PC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIHRleHQgZmlsdGVycy1jbGVhclwiIG9uQ2xpY2s9e3Byb3BzLmhhbmRsZUNsZWFyQWxsfT57dHJhbnNsYXRpb25zLmNsZWFyQWxsfTwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcbiAgKTtcclxufVxyXG5cclxuY29uc3QgUmVzdWx0U3VtbWFyeSA9IChwcm9wcykgPT4ge1xyXG4gIGNvbnN0IHtxdWVyeSwgdG90YWxNYXRjaGluZywgbG9hZGluZywgaXNPblNlYXJjaFBhZ2V9ID0gcHJvcHM7XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cInVjLXJlc3VsdC1oZWFkZXJcIj5cclxuICAgICAge2xvYWRpbmcgPyA8aDQ+PGkgY2xhc3NOYW1lPVwiYW5pbWF0ZS1zcGluIGljb24tc3BpbjRcIj48L2k+IHt0cmFuc2xhdGlvbnMuc2VhcmNoaW5nfTwvaDQ+IDogbnVsbH1cclxuICAgICAge2lzT25TZWFyY2hQYWdlICYmICFsb2FkaW5nID8gPGg0Pnt0cmFuc2xhdGlvbnMueW91clNlYXJjaEZvcn0gPHNwYW4gY2xhc3NOYW1lPVwicXVlcnlcIj57cXVlcnl9PC9zcGFuPiB7dHJhbnNsYXRpb25zLnJlc3VsdGVkSW59IDxzcGFuIGNsYXNzTmFtZT1cImhpdHNcIj57dG90YWxNYXRjaGluZ30ge3RvdGFsTWF0Y2hpbmcgPT0gMSA/IHRyYW5zbGF0aW9ucy5oaXQgOiB0cmFuc2xhdGlvbnMuaGl0cyB9PC9zcGFuPjwvaDQ+IDogbnVsbH1cclxuICAgIDwvZGl2PlxyXG4gICk7XHJcbn1cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IHN0cmluZ2Zvcm1hdCBmcm9tICdzdHJpbmdmb3JtYXQnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlU3RvcmUgZnJvbSAnLi4vLi4vX3N0b3Jlcy9wcmljZV9zZXJ2aWNlX3N0b3JlJztcclxuaW1wb3J0IExvY2FsaXphdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvbG9jYWxpemF0aW9uX3N0b3JlJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0ge307XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTcGFyZVBhcnRGb290ZXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG5cclxuICAgIHRyYW5zbGF0aW9ucy5tYXRlcmlhbE51bWJlciA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvUHJvZHVjdC9JbmZvcm1hdGlvbi9NYXRlcmlhbE51bWJlcicpO1xyXG4gICAgdHJhbnNsYXRpb25zLmFkZFRvQ2FydCA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvUHJvZHVjdC9JbmZvcm1hdGlvbi9BZGRUb0NhcnQnKTtcclxuICAgIHRyYW5zbGF0aW9ucy5xdWlja0J1eSA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvUHJvZHVjdC9JbmZvcm1hdGlvbi9RdWlja0J1eScpO1xyXG4gICAgdHJhbnNsYXRpb25zLnJlcGxhY2VkQnkgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9SZXBsYWNlZEJ5U2hvcnQnKTtcclxuICAgIHRyYW5zbGF0aW9ucy52aWV3UmVwbGFjaW5nUHJvZHVjdCA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvUHJvZHVjdC9JbmZvcm1hdGlvbi9Ob3RCdXlhYmxlL1ZpZXdSZXBsYWNpbmdQcm9kdWN0Jyk7XHJcbiAgICB0cmFuc2xhdGlvbnMudmlld0RldGFpbHMgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL0ZpbHRlci9WaWV3RGV0YWlscycpO1xyXG4gICAgdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9Ob3RCdXlhYmxlJyk7XHJcbiAgICB0cmFuc2xhdGlvbnMuZGlzY291bnQgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vRGlzY291bnQnKTtcclxuXHRcdHRyYW5zbGF0aW9ucy5mZXRjaGluZ0luZm8gPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1NlYXJjaC9GZXRjaGluZ0luZm9ybWF0aW9uJyk7XHJcblx0XHR0cmFuc2xhdGlvbnMucHJvbW90aW9uVGl0bGUgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL0dlbmVyYWwvUHJvbW90aW9uL0Rpc2NvdW50L1RpdGxlJyk7XHJcblx0XHR0cmFuc2xhdGlvbnMucHJvbW90aW9uV2FzID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9HZW5lcmFsL1Byb21vdGlvbi9XYXMnKTtcclxuXHRcdHRyYW5zbGF0aW9ucy5wcmljZUVycm9yID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9Qcm9kdWN0L1ByaWNlRXJyb3InKTtcclxuXHRcdHRyYW5zbGF0aW9ucy5ncm9zc1ByaWNlID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9Qcm9kdWN0L0luZm9ybWF0aW9uL1ByaWNlL1dhcycpO1xyXG5cclxuXHRcdGlmKHRoaXMucHJvcHMudHJhbnNsYXRpb25zKXtcclxuXHQgICAgdHJhbnNsYXRpb25zLm1hdGVyaWFsTnVtYmVyID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMubWF0ZXJpYWxOdW1iZXI7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy5hZGRUb0NhcnQgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5hZGRUb0NhcnQ7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy5xdWlja0J1eSA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnF1aWNrQnV5O1xyXG5cdCAgICB0cmFuc2xhdGlvbnMucmVwbGFjZWRCeSA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnJlcGxhY2VkQnk7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy52aWV3UmVwbGFjaW5nUHJvZHVjdCA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnZpZXdSZXBsYWNpbmdQcm9kdWN0O1xyXG5cdCAgICB0cmFuc2xhdGlvbnMudmlld0RldGFpbHMgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy52aWV3RGV0YWlscztcclxuXHQgICAgdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5ub3RCdXlhYmxlO1xyXG5cdCAgICB0cmFuc2xhdGlvbnMuZGlzY291bnQgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5kaXNjb3VudDtcclxuXHRcdFx0dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mbyA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLmZldGNoaW5nSW5mbztcclxuXHRcdFx0dHJhbnNsYXRpb25zLnByb21vdGlvblRpdGxlID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMucHJvbW90aW9uVGl0bGU7XHJcblx0XHRcdHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXMgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXM7XHJcblx0XHRcdHRyYW5zbGF0aW9ucy5wcmljZUVycm9yID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMucHJpY2VFcnJvcjtcclxuXHRcdFx0dHJhbnNsYXRpb25zLmdyb3NzUHJpY2UgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5ncm9zc1ByaWNlO1xyXG5cdFx0fVxyXG5cclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIEJ1eWFibGU6IGZhbHNlLFxyXG4gICAgICBJblN0b2NrUXVhbnRpdHk6IDAsXHJcbiAgICAgIExvYWRlZDogZmFsc2UsXHJcbiAgICAgIENvZGU6IFwiXCIsXHJcbiAgICAgIFByaWNlOiBcIlwiLFxyXG4gICAgICBTaGlwcGluZ0RhdGU6IFwiXCIsXHJcblx0XHRcdElzRGlzY291bnRlZDogZmFsc2UsXHJcblx0XHRcdERlZmF1bHRQcmljZTogXCJcIixcclxuXHRcdFx0RGlzY291bnRQZXJjZW50OiBcIlwiLFxyXG5cdFx0XHRQcm9kdWN0Q29udGV4dDoge30sXHJcblx0XHRcdFByb21vdGlvbkRpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0UHJvbW90aW9uUHJpY2U6IFwiXCIsXHJcblx0XHRcdEhhc1Byb21vdGlvbjogZmFsc2UsXHJcblx0XHRcdEhhc0Vycm9yOiBmYWxzZVxyXG4gICAgfTtcclxuICB9XHJcblx0Y29tcG9uZW50RGlkVXBkYXRlKCl7XHJcblx0XHRpZih0aGlzLnN0YXRlLkxvYWRlZCl7XHJcblx0XHRcdHRoaXMucmVmbG93KCk7XHJcblx0XHR9XHJcblx0fVxyXG4gIGNvbXBvbmVudERpZE1vdW50KCkge1xyXG5cdFx0Ly90aGlzLnJlZmxvdygpO1xyXG5cclxuXHRcdGxldCBwcmljZSA9IFByaWNlU2VydmljZVN0b3JlLmdldFByaWNlc0Zvck1hdGVyaWFsKHRoaXMucHJvcHMubWF0ZXJpYWxOdW1iZXIpO1xyXG5cdFx0aWYocHJpY2UubGVuZ3RoID4gMCl7XHJcblx0XHRcdHRoaXMuc2V0UHJpY2VGb3JGb290ZXIocHJpY2UpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBQcmljZVNlcnZpY2VTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0aWYoIXRoaXMuc3RhdGUuTG9hZGVkKXtcclxuXHRcdFx0XHRsZXQgcHJpY2UgPSBQcmljZVNlcnZpY2VTdG9yZS5nZXRQcmljZXNGb3JNYXRlcmlhbCh0aGlzLnByb3BzLm1hdGVyaWFsTnVtYmVyKTtcclxuXHRcdFx0XHRpZihwcmljZS5sZW5ndGggPiAwKXtcclxuXHRcdFx0XHRcdHRoaXMuc2V0UHJpY2VGb3JGb290ZXIocHJpY2UpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50ICgpIHtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUoKTtcclxuXHR9XHJcblx0c2V0UHJpY2VGb3JGb290ZXIocHJpY2Upe1xyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdEJ1eWFibGU6IHByaWNlWzBdLkJ1eWFibGUsXHJcblx0XHRcdEluU3RvY2tRdWFudGl0eTogcHJpY2VbMF0uSW5TdG9ja1F1YW50aXR5LFxyXG5cdFx0XHRMb2FkZWQ6IHRydWUsXHJcblx0XHRcdENvZGU6IHByaWNlWzBdLkNvZGUsXHJcblx0XHRcdFByaWNlOiBwcmljZVswXS5QcmljZSxcclxuXHRcdFx0U2hpcHBpbmdEYXRlOiBwcmljZVswXS5TaGlwcGluZ0RhdGUsXHJcblx0XHRcdElzRGlzY291bnRlZDogcHJpY2VbMF0uSXNEaXNjb3VudGVkLFxyXG5cdFx0XHREZWZhdWx0UHJpY2U6IHByaWNlWzBdLkRlZmF1bHRQcmljZSxcclxuXHRcdFx0RGlzY291bnRQZXJjZW50OiBwcmljZVswXS5EaXNjb3VudFBlcmNlbnQsXHJcblx0XHRcdFByb2R1Y3RDb250ZXh0OiBwcmljZVswXS5Qcm9kdWN0Q29udGV4dCxcclxuXHRcdFx0UHJvbW90aW9uRGlzY291bnRQZXJjZW50OiBwcmljZVswXS5Qcm9tb3Rpb25EaXNjb3VudFBlcmNlbnQsXHJcblx0XHRcdFByb21vdGlvblByaWNlOiBwcmljZVswXS5Qcm9tb3Rpb25QcmljZSxcclxuXHRcdFx0SGFzUHJvbW90aW9uOiBwcmljZVswXS5IYXNQcm9tb3Rpb24sXHJcblx0XHRcdEhhc0Vycm9yOiBwcmljZVswXS5IYXNFcnJvclxyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IG1hdGVyaWFsTnVtYmVyID0gdGhpcy5zdGF0ZS5Db2RlLnNwbGl0KCcuJykuam9pbignLScpO1xyXG5cdFx0bGV0IHByb2R1Y3RDYXJkQmFubmVyID0gJyc7XHJcblxyXG5cdFx0aWYoIHRoaXMuc3RhdGUuSGFzUHJvbW90aW9uICl7XHJcblx0XHRcdC8vIGxldCB0cmFuc2xhdGlvblByb21vaXRpb25EaXNjb3VudCA9IHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25UaXRsZTtcclxuXHRcdFx0Ly8gbGV0IHByb21vdGlvblBlcmNlbnQgPSB0cmFuc2xhdGlvblByb21vaXRpb25EaXNjb3VudCsnICcrdGhpcy5zdGF0ZS5Qcm9tb3Rpb25EaXNjb3VudFBlcmNlbnQrJyUnO1xyXG5cdFx0XHRwcm9kdWN0Q2FyZEJhbm5lciA9ICc8ZGl2IGNsYXNzPVwiZGlzY291bnQtcHJpY2VcIj48c3BhbiBjbGFzcz1cInByaWNlXCI+PGkgY2xhc3M9XCJpY29uLXRhZ3NcIj48L2k+PC9zcGFuPjwvZGl2Pic7XHJcblx0XHRcdC8vIHByb2R1Y3RDYXJkQmFubmVyID0gJzxkaXYgY2xhc3M9XCJkaXNjb3VudC1wcmljZVwiPjxzcGFuIGNsYXNzPVwicHJpY2VcIj48aSBjbGFzcz1cImljb24tdGFnc1wiPjwvaT4nK3Byb21vdGlvblBlcmNlbnQrJzwvc3Bhbj48L2Rpdj4nO1xyXG5cdFx0XHQkKCcjbGktJyttYXRlcmlhbE51bWJlcisnIC5pbWFnZScpLmFwcGVuZChwcm9kdWN0Q2FyZEJhbm5lcik7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoIXRoaXMuc3RhdGUuSGFzUHJvbW90aW9uICYmIHRoaXMucHJvcHMuZ290U2NhbGVkUHJpY2VzICYmIHRoaXMuc3RhdGUuQnV5YWJsZSl7XHJcblx0XHRcdHByb2R1Y3RDYXJkQmFubmVyID0gJzxkaXYgY2xhc3M9XCJkaXNjb3VudC1wcmljZVwiPjxzcGFuIGNsYXNzPVwicHJpY2VcIj48aSBjbGFzcz1cImljb24tbW9uZXlcIj48L2k+PC9zcGFuPjwvZGl2Pic7XHJcblx0XHRcdC8vIHByb2R1Y3RDYXJkQmFubmVyID0gJzxkaXYgY2xhc3M9XCJkaXNjb3VudC1wcmljZVwiPjxzcGFuIGNsYXNzPVwicHJpY2VcIj48aSBjbGFzcz1cImljb24tbW9uZXlcIj48L2k+PC9zcGFuPjwvZGl2Pic7XHJcblx0XHRcdCQoJyNsaS0nK21hdGVyaWFsTnVtYmVyKycgLmltYWdlJykuYXBwZW5kKHByb2R1Y3RDYXJkQmFubmVyKTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnJlZmxvdygpO1xyXG5cdH1cclxuXHRyZWZsb3coKXtcclxuXHRcdHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG5cdFx0dmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG5cdFx0dmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpO1xyXG5cclxuXHRcdGlmIChtc2llID4gMCB8fCB0cmlkZW50ID4gMCkge1xyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpKTtcclxuXHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcudWMtcHJvZHVjdGxpc3QnKSk7XHJcblx0XHRcdEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLmFtb3VudC1wcmljZS1zdG9jay13YXRjaCcpKTtcclxuXHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuaXRlbS1uYW1lLXdhdGNoJykpO1xyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5tYWluLWxpLXdhdGNoJykpO1xyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5hZGQtdG8tYnRucycpKTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHQkKGRvY3VtZW50KS5mb3VuZGF0aW9uKCdlcXVhbGl6ZXInLCAncmVmbG93Jyk7XHJcblx0XHR9XHJcblx0fVxyXG4gIHJlbmRlcigpIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIDxkaXY+XHJcblx0XHRcdHsgdGhpcy5zdGF0ZS5CdXlhYmxlID8gPEJ1eUZvb3RlciBtYXRlcmlhbE51bWJlcj17dGhpcy5zdGF0ZS5Db2RlfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJpY2U9e3RoaXMuc3RhdGUuUHJpY2V9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpblN0b2NrUXVhbnRpdHk9e3RoaXMuc3RhdGUuSW5TdG9ja1F1YW50aXR5fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c2hpcHBpbmdEYXRlPXt0aGlzLnN0YXRlLlNoaXBwaW5nRGF0ZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlzRGlzY291bnRlZD17dGhpcy5zdGF0ZS5Jc0Rpc2NvdW50ZWR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZWZhdWx0UHJpY2U9e3RoaXMuc3RhdGUuRGVmYXVsdFByaWNlfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGlzY291bnRQZXJjZW50PXt0aGlzLnN0YXRlLkRpc2NvdW50UGVyY2VudH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RDb250ZXh0PXt0aGlzLnN0YXRlLlByb2R1Y3RDb250ZXh0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Z290U2NhbGVkUHJpY2VzPXt0aGlzLnByb3BzLmdvdFNjYWxlZFByaWNlc31cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVzZXJJc0RlYWxlcj17dGhpcy5wcm9wcy5pc0RlYWxlcn1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGhhc1Byb21vdGlvbj17dGhpcy5zdGF0ZS5IYXNQcm9tb3Rpb259XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRwcm9tb3Rpb25QcmljZT17dGhpcy5zdGF0ZS5Qcm9tb3Rpb25QcmljZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0OiAhdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMuc3RhdGUuTG9hZGVkID8gPFZpZXdEZXRhaWxzRm9vdGVyIGhhc0Vycm9yPXt0aGlzLnN0YXRlLkhhc0Vycm9yfSBkZXRhaWxzVXJsPXt0aGlzLnByb3BzLnVybH0gLz4gOiA8RmV0Y2hQcmljZUZvb3RlciAvPiB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IEZldGNoUHJpY2VGb290ZXIgPSAocHJvcHMpID0+IHtcclxuXHRyZXR1cm4gKFxyXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmb290ZXIgbG9hZGluZ1wiPlxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNhbXBhaW5nLXdyYXBwZXJcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImNhbXBhaW5nLXdyYXBwZXJcIj5cclxuXHRcdFx0PC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgICAgIDxpIGNsYXNzTmFtZT1cImljb24tc3BpbjQgYW5pbWF0ZS1zcGluIHRleHQtY2VudGVyXCIgc3R5bGU9e3tcImRpc3BsYXlcIiA6IFwiYmxvY2tcIn19PjwvaT5cclxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LWNlbnRlclwiIHN0eWxlPXt7XCJkaXNwbGF5XCIgOiBcImJsb2NrXCJ9fT57dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mb308L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9XCJidXR0b24gbGVmdCBhZGQtdG8tY2FydFwiPnt0cmFuc2xhdGlvbnMuYWRkVG9DYXJ0fTwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIHJpZ2h0IHF1aWNrLWJ1eVwiPnt0cmFuc2xhdGlvbnMucXVpY2tCdXl9PC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgKTtcclxufVxyXG5cclxuY29uc3QgQnV5Rm9vdGVyID0gKHByb3BzKSA9PiB7XHJcbiAgY29uc3QgeyBtYXRlcmlhbE51bWJlciwgcHJpY2UsIGluU3RvY2tRdWFudGl0eSwgc2hpcHBpbmdEYXRlLCBpc0Rpc2NvdW50ZWQsIGRlZmF1bHRQcmljZSwgZGlzY291bnRQZXJjZW50LCBwcm9kdWN0Q29udGV4dCwgZ290U2NhbGVkUHJpY2VzLCBwcm9tb3Rpb25QcmljZSwgaGFzUHJvbW90aW9uLCB1c2VySXNEZWFsZXJ9ID0gcHJvcHM7XHJcblxyXG4gIGxldCBtYXRlcmlhbE51bWJlckFzSWQgPSBtYXRlcmlhbE51bWJlci5zcGxpdCgnLicpLmpvaW4oJy0nKTtcclxuICBsZXQgY29udGV4dCA9IEpTT04uc3RyaW5naWZ5KHByb2R1Y3RDb250ZXh0KTtcclxuXHQvLyBsZXQgZ290U2NhbGVkUHJpY2VzSWNvbiA9IGdvdFNjYWxlZFByaWNlcyAmJiAhaGFzUHJvbW90aW9uID8gPGkgY2xhc3NOYW1lPVwiaWNvbi1tb25leVwiPjwvaT4gOiBudWxsO1xyXG5cclxuXHRsZXQgZ290U2NhbGVkUHJpY2VzSWNvbiA9ICcnO1xyXG5cclxuXHRsZXQgZGVhbGVySW5kaWNhdGlvbiA9ICcnO1xyXG5cdGlmKCB1c2VySXNEZWFsZXIgKXtcclxuXHRcdGlmKCBpc0Rpc2NvdW50ZWQgKXtcclxuXHRcdFx0ZGVhbGVySW5kaWNhdGlvbiA9IHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXMrJzogJztcclxuXHRcdH1lbHNle1xyXG5cdFx0XHRkZWFsZXJJbmRpY2F0aW9uID0gdHJhbnNsYXRpb25zLmdyb3NzUHJpY2UrJzogJztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGxldCB0cmFuc2xhdGlvbkdyb3NzID0gdHJhbnNsYXRpb25zLmRpc2NvdW50LnN1YnN0cmluZygwLCAodHJhbnNsYXRpb25zLmRpc2NvdW50LmluZGV4T2YoJ30nKSArIDEpKTtcclxuXHRsZXQgdHJhbnNsYXRpb25EaXNjb3VudCA9IHRyYW5zbGF0aW9ucy5kaXNjb3VudC5zdWJzdHJpbmcoKHRyYW5zbGF0aW9ucy5kaXNjb3VudC5pbmRleE9mKCd9JykgKyAyKSkucmVwbGFjZShcIjFcIiwgXCIwXCIpO1xyXG5cdGxldCB0cmFuc2xhdGlvbldhcyA9IHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXM7XHJcblx0bGV0IHRyYW5zbGF0aW9uUHJvbW9pdGlvbkRpc2NvdW50ID0gdHJhbnNsYXRpb25zLnByb21vdGlvblRpdGxlO1xyXG5cclxuXHRsZXQgZGVmYXVsdFByaWNlVGV4dCA9IHN0cmluZ2Zvcm1hdCh0cmFuc2xhdGlvbkdyb3NzLCBkZWZhdWx0UHJpY2UpO1xyXG5cdGxldCBkaXNjb3VudFBlcmNlbnRUZXh0ID0gc3RyaW5nZm9ybWF0KHRyYW5zbGF0aW9uRGlzY291bnQsIGRpc2NvdW50UGVyY2VudCk7XHJcblx0bGV0IHByb21vdGlvblByaWNlVGV4dCA9IHRyYW5zbGF0aW9uV2FzICsgJzogJyArIHByaWNlO1xyXG5cdGxldCBzaGlwcGluZ0luZm8gPSBudWxsO1xyXG5cdC8qXHJcblx0c2hpcHBpbmdJbmZvID0gPGRpdiBjbGFzc05hbWU9XCJzaGlwcHBpbmctZGF0ZVwiPjxwPiMhU2hpcHM6IHtzaGlwcGluZ0RhdGV9PC9wPjwvZGl2PlxyXG5cdCovXHJcblxyXG5cdGxldCBjYW1wYWluZ0luZm8gPSBjbGFzc05hbWVzKHtcclxuXHRcdCdjYW1wYWluZy1pbmZvJzogdHJ1ZSxcclxuXHRcdCdjbGVhcmZpeCc6IHRydWUsXHJcblx0XHQnZGVmYXVsdCc6IGlzRGlzY291bnRlZCAmJiBoYXNQcm9tb3Rpb24sXHJcblx0XHQnaGlkZSc6ICFpc0Rpc2NvdW50ZWQgJiYgIWhhc1Byb21vdGlvblxyXG5cdH0pO1xyXG5cclxuXHRsZXQgY29zdCA9IHByaWNlO1xyXG5cdGxldCBoYXNTZWxlY3RlZFdpc2hsaXN0ID0gJCgnLndpc2hsaXN0LXRvZ2dsZScpLmhhc0NsYXNzKCdhY3RpdmUnKTtcclxuXHJcblx0bGV0IHNhdmVkQ2FydENsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHQnc21sJzogdHJ1ZSxcclxuXHRcdCdidXR0b24nOiB0cnVlLFxyXG5cdFx0J3dpc2hsaXN0JzogdHJ1ZSxcclxuXHRcdCdzZWFyY2gtc2F2ZWQtY2FydC1hZGQnOiB0cnVlLFxyXG5cdFx0J3NhdmVkLWNhcnQtYWRkJzogdHJ1ZSxcclxuXHRcdCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZSc6ICFoYXNTZWxlY3RlZFdpc2hsaXN0XHJcblx0fSk7XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZvb3RlclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFtb3VudC1wcmljZS1zdG9jayB1LWR0XCIgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJhbW91bnQtcHJpY2Utc3RvY2tcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImxlZnRcIj5cclxuICAgICAgICAgIDxpbnB1dCBkYXRhLXByb2R1Y3Qtc2t1PXttYXRlcmlhbE51bWJlcn0gZGF0YS1wcm9kdWN0LWNvc3Q9e2Nvc3R9IGNsYXNzTmFtZT1cImFtb3VudFwiIG5hbWU9XCJhdW1vbnQteFwiIGRlZmF1bHRWYWx1ZT1cIjFcIiAvPlxyXG4gICAgICAgICAgPHNwYW4gZGF0YS1wcm9kdWN0LWlkPXttYXRlcmlhbE51bWJlcn0gZGF0YS1hY3RpdmUtdGFiPVwicHJpY2VcIiBjbGFzc05hbWU9XCJwcmljZSBsZWZ0XCI+XHJcblx0XHRcdFx0XHRcdHtoYXNQcm9tb3Rpb24gPyBudWxsIDogZ290U2NhbGVkUHJpY2VzSWNvbn17aGFzUHJvbW90aW9uID8gYCR7cHJvbW90aW9uUHJpY2V9YCA6IGAke2RlYWxlckluZGljYXRpb259JHtwcmljZX1gfVxyXG5cdFx0XHRcdFx0PC9zcGFuPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwicmlnaHRcIj5cclxuICAgICAgICAgIHtpblN0b2NrUXVhbnRpdHkgIT09IHVuZGVmaW5lZCAmJiBpblN0b2NrUXVhbnRpdHlcclxuICAgICAgICAgICAgPyA8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e21hdGVyaWFsTnVtYmVyfSBkYXRhLWFjdGl2ZS10YWI9XCJhdmFpbGFiaWxpdHlcIiBjbGFzc05hbWU9XCJzdG9jayByaWdodCB0eHQtbGVmdFwiPjxpIGNsYXNzTmFtZT1cImljb24tY3ViZXNcIj48L2k+e2luU3RvY2tRdWFudGl0eX08L3NwYW4+XHJcbiAgICAgICAgICAgIDogc2hpcHBpbmdEYXRlICE9PSB1bmRlZmluZWQgJiYgc2hpcHBpbmdEYXRlICE9PSAnJ1xyXG4gICAgICAgICAgICAgID8gPHNwYW4gZGF0YS1wcm9kdWN0LWlkPXttYXRlcmlhbE51bWJlcn0gZGF0YS1hY3RpdmUtdGFiPVwiYXZhaWxhYmlsaXR5XCIgY2xhc3NOYW1lPVwic3RvY2sgcmlnaHQgdHh0LWxlZnRcIj48aSBjbGFzc05hbWU9XCJpY29uLWN1YmVzXCI+PC9pPntzaGlwcGluZ0RhdGV9PC9zcGFuPlxyXG4gICAgICAgICAgICAgIDogbnVsbH1cclxuICAgICAgICA8L2Rpdj5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImJvdHRvbSBjbGVhcmZpeFwiPlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9e2NhbXBhaW5nSW5mb30+XHJcblx0XHRcdFx0XHRcdHtpc0Rpc2NvdW50ZWQgJiYgIWhhc1Byb21vdGlvbiA/XHJcblx0XHRcdFx0XHRcdDxzcGFuPjxwIGNsYXNzTmFtZT1cImdyb3NzXCI+e2RlZmF1bHRQcmljZVRleHR9PC9wPjxwPntkaXNjb3VudFBlcmNlbnRUZXh0fTwvcD48L3NwYW4+IDogJyd9XHJcblx0XHRcdFx0XHRcdHtpc0Rpc2NvdW50ZWQgJiYgaGFzUHJvbW90aW9uID9cclxuXHRcdFx0XHRcdFx0PHNwYW4+PHAgY2xhc3NOYW1lPVwiZ3Jvc3NcIj57ZGVmYXVsdFByaWNlVGV4dH08L3A+PHA+e2Rpc2NvdW50UGVyY2VudFRleHR9PC9wPjxwIGNsYXNzTmFtZT1cImRlZmF1bHQtY2FtcGFpbmdcIj57cHJvbW90aW9uUHJpY2VUZXh0fTwvcD48L3NwYW4+IDogJyd9XHJcblx0XHRcdFx0XHRcdHshaXNEaXNjb3VudGVkICYmIGhhc1Byb21vdGlvbiA/XHJcblx0XHRcdFx0XHRcdDxzcGFuPjxwIGNsYXNzTmFtZT1cImRlZmF1bHQtY2FtcGFpbmdcIj57cHJvbW90aW9uUHJpY2VUZXh0fTwvcD48L3NwYW4+IDogJyd9XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdHtzaGlwcGluZ0luZm99XHJcblx0XHRcdFx0PC9kaXY+XHJcblxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYWRkLXRvLWJ0bnNcIiBkYXRhLXByb2R1Y3QtY29udGV4dD17Y29udGV4dH0+XHJcblx0XHRcdFx0XHQ8YnV0dG9uIGRhdGEtcHJvZHVjdC1za3U9e21hdGVyaWFsTnVtYmVyfSBjbGFzc05hbWU9e3NhdmVkQ2FydENsYXNzfT48aSBjbGFzc05hbWU9XCJpY29uLXNhdmVkLWNhcnQtYWRkXCI+PC9pPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0PGJ1dHRvbiBkYXRhLXByb2R1Y3Qtc2t1PXttYXRlcmlhbE51bWJlcn0gY2xhc3NOYW1lPVwiYnV0dG9uIGFkZC10by1jYXJ0XCI+e3RyYW5zbGF0aW9ucy5hZGRUb0NhcnR9PC9idXR0b24+XHJcblx0XHRcdFx0XHQ8YnV0dG9uIGRhdGEtcHJvZHVjdC1za3U9e21hdGVyaWFsTnVtYmVyfSBjbGFzc05hbWU9XCJidXR0b24gcXVpY2stYnV5XCI+e3RyYW5zbGF0aW9ucy5xdWlja0J1eX08L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgaWQ9e21hdGVyaWFsTnVtYmVyQXNJZH0gY2xhc3NOYW1lPVwiU3BhcmVQYXJ0UmVzdWx0LWluZm9cIj48L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIClcclxufVxyXG5cclxuQnV5Rm9vdGVyLnByb3BUeXBlcyA9IHtcclxuXHRkaXNjb3VudFBlcmNlbnQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcblx0ZGVmYXVsdFByaWNlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gIG1hdGVyaWFsTnVtYmVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gIHByaWNlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gIGluU3RvY2tRdWFudGl0eTogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcclxuICBzaGlwcGluZ0RhdGU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcclxufVxyXG5cclxuY29uc3QgVmlld0RldGFpbHNGb290ZXIgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7ZGV0YWlsc1VybCwgaGFzRXJyb3J9ID0gcHJvcHM7XHJcblx0bGV0IGRldGFpbHNUZXh0ID0gaGFzRXJyb3IgPyB0cmFuc2xhdGlvbnMucHJpY2VFcnJvciA6IHRyYW5zbGF0aW9ucy5ub3RCdXlhYmxlO1xyXG4gIHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZvb3RlclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFtb3VudC1wcmljZS1zdG9jayB1LWR0XCIgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJhbW91bnQtcHJpY2Utc3RvY2tcIj5cclxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ1LXR4dC1jZW50ZXIgdS1kdFwiPntkZXRhaWxzVGV4dH08L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgICAgICAgPGEgY2xhc3NOYW1lPVwiYnV0dG9uIGNlbnRlciBub3QtYnV5YWJsZVwiIGhyZWY9e2RldGFpbHNVcmx9Pnt0cmFuc2xhdGlvbnMudmlld0RldGFpbHN9PC9hPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICk7XHJcbn1cclxuXHJcblZpZXdEZXRhaWxzRm9vdGVyLnByb3BUeXBlcyA9IHtcclxuICBkZXRhaWxzVXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXHJcbn1cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IExhenlMb2FkIGZyb20gJ3JlYWN0LWxhenktbG9hZCc7XHJcbmltcG9ydCBzdHJpbmdmb3JtYXQgZnJvbSAnc3RyaW5nZm9ybWF0JztcclxuaW1wb3J0IFNwYXJlUGFydEZvb3RlciBmcm9tICcuL3NwYXJlX3BhcnRfZm9vdGVyJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBMb2NhbGl6YXRpb25TdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL2xvY2FsaXphdGlvbl9zdG9yZSc7XHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0ge307XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTcGFyZVBhcnRSZXN1bHQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG4gICAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgICAgICBzdXBlcihwcm9wcyk7XHJcblxyXG4gICAgICAgIHRyYW5zbGF0aW9ucy5tYXRlcmlhbE51bWJlciA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvUHJvZHVjdC9JbmZvcm1hdGlvbi9NYXRlcmlhbE51bWJlcicpO1xyXG4gICAgICAgIHRyYW5zbGF0aW9ucy5hZGRUb0NhcnQgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vQWRkVG9DYXJ0Jyk7XHJcbiAgICAgICAgdHJhbnNsYXRpb25zLnF1aWNrQnV5ID0gTG9jYWxpemF0aW9uU3RvcmUuZ2V0VHJhbnNsYXRpb24oJy9Qcm9kdWN0L0luZm9ybWF0aW9uL1F1aWNrQnV5Jyk7XHJcbiAgICAgICAgdHJhbnNsYXRpb25zLnJlcGxhY2VkQnkgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9SZXBsYWNlZEJ5U2hvcnQnKTtcclxuICAgICAgICB0cmFuc2xhdGlvbnMudmlld1JlcGxhY2luZ1Byb2R1Y3QgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9WaWV3UmVwbGFjaW5nUHJvZHVjdCcpO1xyXG4gICAgICAgIHRyYW5zbGF0aW9ucy52aWV3RGV0YWlscyA9IExvY2FsaXphdGlvblN0b3JlLmdldFRyYW5zbGF0aW9uKCcvRmlsdGVyL1ZpZXdEZXRhaWxzJyk7XHJcbiAgICAgICAgdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9Ob3RCdXlhYmxlJyk7XHJcbiAgICAgICAgdHJhbnNsYXRpb25zLm5vdEJ1eWFibGVTaWduSW4gPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vTm90QnV5YWJsZS9Ob3RCdXlhYmxlU2lnbkluJyk7XHJcblx0XHRcdFx0dHJhbnNsYXRpb25zLnNjYWxlZFByaWNlc1Rvb2x0aXAgPSBMb2NhbGl6YXRpb25TdG9yZS5nZXRUcmFuc2xhdGlvbignL1Byb2R1Y3QvSW5mb3JtYXRpb24vU2NhbGVkUHJpY2VzL1Rvb2x0aXAnKTtcclxuXHJcbiAgICB9XHJcblx0XHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdFx0Ly8gdGhpcy5pbWdPbkxvYWQoKTtcclxuXHRcdH1cclxuXHRcdGNvbXBvbmVudERpZFVwZGF0ZSgpe1xyXG5cdFx0XHQvLyB0aGlzLmltZ09uTG9hZCgpO1xyXG5cdFx0XHRpZih0aGlzLnByb3BzLmdvdFNjYWxlZFByaWNlcyl7XHJcblx0XHRcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbigndG9vbHRpcCcsICdyZWZsb3cnKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdH1cclxuICAgIGlzUmVwbGFjZWQoKSB7XHJcbiAgICAgIHJldHVybiAhIXRoaXMucHJvcHMucmVwbGFjZW1lbnROYW1lICYmICF0aGlzLnByb3BzLmlzUXVlcnlhYmxlO1xyXG4gICAgICB0aGlzLmltZ09uTG9hZCgpO1xyXG4gICAgfVxyXG5cdFx0aXNRdWVyeWFibGUoKXtcclxuICAgICAgcmV0dXJuIHRoaXMucHJvcHMuaXNRdWVyeWFibGU7XHJcbiAgICAgIHRoaXMuaW1nT25Mb2FkKCk7XHJcblx0XHR9XHJcbiAgICBpbWdPbkxvYWQoKXtcclxuXHRcdFx0dmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XHJcblx0XHQgIHZhciB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTtcclxuXHRcdCAgdmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpO1xyXG5cdFx0ICBpZiAobXNpZSA+IDAgfHwgdHJpZGVudCA+IDApIHtcclxuXHRcdCAgICAkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG5cdFx0ICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcucmVzdWx0LXNwYXJlLXBhcnRzJykpO1xyXG5cdFx0ICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcudWMtcHJvZHVjdGxpc3QnKSk7XHJcblx0XHQgICAgICBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5hbW91bnQtcHJpY2Utc3RvY2std2F0Y2gnKSk7XHJcblx0XHQgICAgICAvLyBGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy5tYWluLWxpLXdhdGNoJykpO1xyXG5cdFx0ICAgIH0pO1xyXG5cclxuXHRcdCAgfVxyXG5cdFx0ICBlbHNlIHtcclxuXHRcdCAgICAkKGRvY3VtZW50KS5mb3VuZGF0aW9uKCdlcXVhbGl6ZXInLCAncmVmbG93Jyk7XHJcblx0XHQgIH1cclxuICAgIH1cclxuICAgIHJlbmRlcigpIHsvL3JlbmRlcmVkIG9uY2UgZm9yIGVhY2ggbWF0ZXJpYWxcclxuICAgICAgICBjb25zdCB7IG5hbWUsIG1hdGVyaWFsTnVtYmVyLCB1cmwsIHByaWNlLCBpblN0b2NrUXVhbnRpdHksIGlzQnV5YWJsZSxcclxuICAgICAgICAgICAgICAgIGltYWdlcyxyZXBsYWNlbWVudE1hdGVyaWFsTnVtYmVyLCByZXBsYWNlbWVudFVybCwgc2hpcHBpbmdEYXRlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdFByaWNlLCBpc1F1ZXJ5YWJsZSwgZ290U2NhbGVkUHJpY2VzLCBpc0Jsb2NrZWQsIHJlc3RyaWN0aW9uVHlwZSwgcmVzdHJpY3Rpb25UZXh0IH0gPSB0aGlzLnByb3BzO1xyXG5cclxuXHRcdFx0XHRjb25zdCBoYXNJbWFnZSA9IGltYWdlcyAmJiBpbWFnZXMubGVuZ3RoPjA7XHJcbiAgICAgICAgbGV0IG1hdGVyaWFsTnVtYmVyQXNJZCA9J2xpLScrbWF0ZXJpYWxOdW1iZXIuc3BsaXQoJy4nKS5qb2luKCctJyk7XHJcblx0XHRcdFx0bGV0IHRvb2xUaXAgIFx0XHRcdD0gZ290U2NhbGVkUHJpY2VzICYmIGlzUXVlcnlhYmxlID8geydkYXRhLXRvb2x0aXAnOiAndHJ1ZSd9IDogbnVsbDtcclxuXHRcdFx0XHRsZXQgdG9vbFRpcFRpdGxlIFx0PSBnb3RTY2FsZWRQcmljZXMgJiYgaXNRdWVyeWFibGUgPyB7J3RpdGxlJzogdHJhbnNsYXRpb25zLnNjYWxlZFByaWNlc1Rvb2x0aXB9IDogbnVsbDtcclxuXHRcdFx0XHRsZXQgdG9vbFRpcEFyaWEgXHQ9IGdvdFNjYWxlZFByaWNlcyAmJiBpc1F1ZXJ5YWJsZSA/IHsnYXJpYS1oYXNwb3B1cCc6ICd0cnVlJ30gOiBudWxsO1xyXG5cclxuXHRcdFx0XHRsZXQgaXRlbVdyYXBwZXJDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHRcdFx0J2l0ZW0td3JhcHBlcic6IHRydWUsXHJcblx0XHRcdFx0XHQnaGFzLXRpcCc6IGdvdFNjYWxlZFByaWNlcyxcclxuXHRcdFx0XHRcdCd0aXAtdG9wJzogZ290U2NhbGVkUHJpY2VzXHJcblx0XHRcdFx0fSk7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgIDxsaSBpZD17bWF0ZXJpYWxOdW1iZXJBc0lkfT5cclxuXHRcdCAgICAgICAgPGRpdiBjbGFzc05hbWU9e2l0ZW1XcmFwcGVyQ2xhc3N9IHsuLi50b29sVGlwfSB7Li4udG9vbFRpcFRpdGxlfSB7Li4udG9vbFRpcEFyaWF9PlxyXG5cdFx0XHQgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaW1hZ2VcIj5cclxuXHRcdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiZmlsbGVyXCIgLz5cclxuXHRcdFx0XHRcdFx0XHRcdDxMYXp5TG9hZCBoZWlnaHQ9ezEzM30gb2Zmc2V0VmVydGljYWw9ezM4MH0+XHJcblx0XHRcdFx0ICAgICAgICBcdHtoYXNJbWFnZSA/IDxhIGhyZWY9e3VybH0+PGltZyBzcmM9e2ltYWdlc1swXS51cmwrJz9wcmVzZXQ9bGlzdCd9IGFsdD17aW1hZ2VzWzBdLnNlb1RleHR9IC8+PC9hPiA6IG51bGwgfVxyXG5cdFx0XHRcdFx0XHRcdFx0PC9MYXp5TG9hZD5cclxuXHRcdFx0ICAgICAgICA8L2Rpdj5cclxuXHRcdFx0ICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tbmFtZVwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiaXRlbS1uYW1lXCI+XHJcblx0XHRcdFx0ICAgICAgICA8aDQ+PGEgaHJlZj17dXJsfT57bmFtZX08L2E+PC9oND5cclxuXHRcdFx0XHQgICAgICAgIDxwPlxyXG4gICAgICAgICAgICAgICAgICA8c3Bhbj57bWF0ZXJpYWxOdW1iZXJ9PC9zcGFuPlxyXG5cdFx0XHRcdCAgICAgICAgPC9wPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjYW1wYWluZy1pbmZvXCI+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHRcdFx0ICAgICAgICA8L2Rpdj5cclxuXHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImZvb3Rlci13cmFwcGVyXCI+XHJcblx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuaXNSZXBsYWNlZCgpID9cclxuXHRcdFx0XHRcdFx0XHRcdFx0PFJlcGxhY2VtZW50Rm9vdGVyIHJlcGxhY2VtZW50VXJsPXtyZXBsYWNlbWVudFVybH0gcmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcj17cmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcn0gLz4gOlxyXG5cdFx0XHRcdFx0XHRcdFx0ICB0aGlzLmlzUXVlcnlhYmxlKCkgJiYgIWlzQmxvY2tlZCA/XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PFNwYXJlUGFydEZvb3RlciBpc0RlYWxlcj17dGhpcy5wcm9wcy5pc0RlYWxlcn0gZ290U2NhbGVkUHJpY2VzPXtnb3RTY2FsZWRQcmljZXN9IG1hdGVyaWFsTnVtYmVyPXttYXRlcmlhbE51bWJlcn0gdXJsPXt1cmx9IC8+IDpcclxuICAgICAgICAgICAgICAgICAgICA8Vmlld0RldGFpbHNGb290ZXIgaWQ9e21hdGVyaWFsTnVtYmVyQXNJZH0gc2lnbmVkSW49e3RoaXMucHJvcHMudXNlcklzU2lnbmVkSW59IGRldGFpbHNVcmw9e3VybH0gaXNCbG9ja2VkPXtpc0Jsb2NrZWR9IHJlc3RyaWN0aW9uVHlwZT17cmVzdHJpY3Rpb25UeXBlfSByZXN0cmljdGlvblRleHQ9e3Jlc3RyaWN0aW9uVGV4dH0gLz5cclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdCAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgIDwvbGk+XHJcbiAgICAgICApO1xyXG4gICAgfVxyXG59XHJcblxyXG5TcGFyZVBhcnRSZXN1bHQucHJvcFR5cGVzID0ge1xyXG4gICAgbmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIG1hdGVyaWFsTnVtYmVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgdXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgcHJpY2U6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICBzdG9jazogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIGlzQnV5YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXHJcbiAgICBpbWFnZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcclxuICAgIHJlcGxhY2VtZW50TmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXI6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICByZXBsYWNlbWVudFVybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xyXG59O1xyXG5cclxuY29uc3QgUmVwbGFjZW1lbnRGb290ZXIgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7IHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXIsIHJlcGxhY2VtZW50VXJsIH0gPSBwcm9wcztcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZm9vdGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgXHQgIDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17cmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcn0gZGF0YS1hY3RpdmUtdGFiPVwib3RoZXJcIiBjbGFzc05hbWU9XCJ1LXR4dC1jZW50ZXIgcmVwbGFjZWQgdGV4dC1jZW50ZXJcIiBzdHlsZT17e1wiZGlzcGxheVwiIDogXCJibG9ja1wifX0+e3RyYW5zbGF0aW9ucy5yZXBsYWNlZEJ5fTogPGEgaHJlZj17cmVwbGFjZW1lbnRVcmx9PntyZXBsYWNlbWVudE1hdGVyaWFsTnVtYmVyfTwvYT48L3NwYW4+XHJcblx0XHRcdDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgXHRcdFx0PGEgY2xhc3NOYW1lPVwiYnV0dG9uIGNlbnRlciBub3QtYnV5YWJsZVwiIGhyZWY9e3JlcGxhY2VtZW50VXJsfT57dHJhbnNsYXRpb25zLnZpZXdSZXBsYWNpbmdQcm9kdWN0fTwvYT5cclxuICBcdFx0PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICApO1xyXG59XHJcblxyXG5SZXBsYWNlbWVudEZvb3Rlci5wcm9wVHlwZXMgPSB7XHJcbiAgcmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICByZXBsYWNlbWVudFVybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xyXG59XHJcblxyXG4vL3Nob3duIGlmIG5vdCBxdWVyeWFibGVcclxuY29uc3QgVmlld0RldGFpbHNGb290ZXIgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7aWQsIGRldGFpbHNVcmwsIHNpZ25lZEluLCBpc0Jsb2NrZWQsIHJlc3RyaWN0aW9uVHlwZSwgcmVzdHJpY3Rpb25UZXh0fSA9IHByb3BzO1xyXG5cclxuICBsZXQgbWF0ZXJpYWxTdGF0dXMgPVxyXG4gICAgaXNCbG9ja2VkICYmIHJlc3RyaWN0aW9uVHlwZSAhPSBudWxsICYmIHJlc3RyaWN0aW9uVHlwZS5sZW5ndGggPiAwID8gcmVzdHJpY3Rpb25UZXh0IDpcclxuICAgIHNpZ25lZEluID8gdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgOiB0cmFuc2xhdGlvbnMubm90QnV5YWJsZVNpZ25JbjtcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZm9vdGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInUtdHh0LWNlbnRlciB1LWR0XCI+e21hdGVyaWFsU3RhdHVzfTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYWRkLXRvLWJ0bnNcIj5cclxuICAgICAgICA8YSBjbGFzc05hbWU9XCJidXR0b24gY2VudGVyIG5vdC1idXlhYmxlXCIgaHJlZj17ZGV0YWlsc1VybH0+e3RyYW5zbGF0aW9ucy52aWV3RGV0YWlsc308L2E+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgKTtcclxufVxyXG5cclxuVmlld0RldGFpbHNGb290ZXIucHJvcFR5cGVzID0ge1xyXG4gIGRldGFpbHNVcmw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcclxufVxyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBUcmVlVmlld1N0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvdHJlZXZpZXdfc3RvcmUnO1xyXG5pbXBvcnQgTW9kZWxUcmVlSXRlbSBmcm9tICcuL21vZGVsdHJlZWl0ZW0nO1xyXG5pbXBvcnQgVHJlZVZpZXdBcGkgZnJvbSAnLi4vLi4vX2FwaS90cmVldmlld19hcGknO1xyXG5pbXBvcnQgTW9kZWxUcmVlU2VhcmNoIGZyb20gJy4vbW9kZWx0cmVlc2VhcmNoJztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5jbGFzcyBNb2RlbFRyZWUgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblxyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0Y2hpbGRyZW46IHtcclxuXHRcdFx0XHRkYXRhOiBbXSxcclxuXHRcdFx0XHRpc01hY2hpbmU6IGZhbHNlLFxyXG5cdFx0XHR9LFxyXG5cdFx0XHRzZWN0aW9uQ2hpbGRyZW46e31cclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRwcmVmZXRjaE5vZGVzKG1vZGVsKSB7XHJcblx0XHRpZighdGhpcy5wcm9wcy5tb2RlbCkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUodHJ1ZSk7XHJcblx0XHR2YXIgaXNNYWNoaW5lID0gdGhpcy5wcm9wcy5tb2RlbC5zdWJzdHJpbmcoMCwgOCkgPT0gJ21hY2hpbmUtJztcclxuXHRcdHZhciBpc01vZGVsID0gdGhpcy5wcm9wcy5tb2RlbC5zdWJzdHJpbmcoMCwgNikgPT0gJ21vZGVsLSc7XHJcblxyXG5cdFx0aWYoaXNNYWNoaW5lKXtcclxuXHRcdFx0bW9kZWwgPSB0aGlzLnByb3BzLm1vZGVsLnJlcGxhY2UoJ21hY2hpbmUtJywnJyk7XHJcblx0XHR9ZWxzZSBpZihpc01vZGVsKXtcclxuXHRcdFx0bW9kZWwgPSB0aGlzLnByb3BzLm1vZGVsLnJlcGxhY2UoJ21vZGVsLScsJycpO1xyXG5cdFx0fWVsc2V7XHJcblx0XHRcdG1vZGVsID0gdGhpcy5wcm9wcy5tb2RlbDtcclxuXHRcdH1cclxuXHJcblx0XHRUcmVlVmlld0FwaS5nZXROb2Rlcyh0aGlzLnByb3BzLm1vZGVsKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdGlmKGlzTWFjaGluZSl7XHJcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRjaGlsZHJlbjoge1xyXG5cdFx0XHRcdFx0XHRrZXk6IG1vZGVsLFxyXG5cdFx0XHRcdFx0XHRpc01hY2hpbmU6IHRydWUsXHJcblx0XHRcdFx0XHRcdGRhdGE6IFtyZXNwb25zZV1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0bGV0IHJvb3RNb2RlbENoaWxkID0gVHJlZVZpZXdTdG9yZS5nZXQobW9kZWwpO1xyXG5cdFx0XHRcdGNvbnNvbGUubG9nKHJvb3RNb2RlbENoaWxkKVxyXG5cclxuXHRcdFx0XHRpZighcm9vdE1vZGVsQ2hpbGQuZGF0YVswXSkgcmV0dXJuO1xyXG5cdFx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKHRydWUpO1xyXG5cclxuXHRcdFx0XHRUcmVlVmlld0FwaS5nZXROb2Rlcyhyb290TW9kZWxDaGlsZC5kYXRhWzBdLklkKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRcdGNoaWxkcmVuOiByb290TW9kZWxDaGlsZCxcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0VHJlZVZpZXdTdG9yZS5zZXRTZWxlY3RlZE5vZGUocm9vdE1vZGVsQ2hpbGQuZGF0YVswXS5JZClcclxuXHRcdFx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKGZhbHNlKTtcclxuXHRcdFx0XHR9KS5jYXRjaCgobWVzc2FnZSkgPT4ge1xyXG5cdFx0XHRcdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUoZmFsc2UpO1xyXG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblx0XHR9KS5jYXRjaCgobWVzc2FnZSkgPT4ge1xyXG5cdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0c2VsZWN0Tm9kZShub2RlSWQpIHtcclxuXHRcdFRyZWVWaWV3U3RvcmUuc2V0U2VsZWN0ZWROb2RlKG5vZGVJZCk7XHJcblx0fVxyXG5cclxuXHRmZXRjaEFzY2VuZGFudE5vZGVzKHNlY3Rpb25DaGlsZHJlbikge1xyXG5cdFx0aWYoIXRoaXMucHJvcHMubW9kZWwpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdHZhciBpc01hY2hpbmUgPSB0aGlzLnByb3BzLm1vZGVsLnN1YnN0cmluZygwLCA4KSA9PSAnbWFjaGluZS0nO1xyXG5cdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUodHJ1ZSk7XHJcblx0XHQkKCcjaWxsdXN0cmF0aW9uJykuYWRkQ2xhc3MoJ2lzLWxvYWRpbmctbWVudS1hbicpO1xyXG5cdFx0VHJlZVZpZXdBcGkuZ2V0QXNjZW5kYW50Tm9kZXModGhpcy5wcm9wcy5tb2RlbCwgdGhpcy5wcm9wcy5pbGx1c3RyYXRpb24sIHRoaXMucHJvcHMubm9kZUlkKS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICBcdFx0Ly91cGRhdGUgc3RvcmVcclxuXHRcdFx0aWYoaXNNYWNoaW5lKXtcclxuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdGNoaWxkcmVuOiB7XHJcblx0XHRcdFx0XHRcdGtleTogdGhpcy5wcm9wcy5tb2RlbC5yZXBsYWNlKCdtYWNoaW5lLScsJycpLFxyXG5cdFx0XHRcdFx0XHRpc01hY2hpbmU6IHRydWUsXHJcblx0XHRcdFx0XHRcdGRhdGE6IFtyZXNwb25zZV1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0bGV0IHBhcmVudHMgPSBfLnVuaXEocmVzcG9uc2UsIGZ1bmN0aW9uIChub2RlKXtcclxuXHRcdFx0XHRcdHJldHVybiBub2RlLlBhcmVudDtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRwYXJlbnRzLmZvckVhY2goKG5vZGUpID0+IHtcclxuXHRcdFx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0KG5vZGUuUGFyZW50LCBfLndoZXJlKHJlc3BvbnNlLCB7IFBhcmVudDogbm9kZS5QYXJlbnQgfSkpO1xyXG5cdCAgICAgIFx0XHR9KTtcclxuXHJcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRjaGlsZHJlbjogVHJlZVZpZXdTdG9yZS5nZXQodGhpcy5wcm9wcy5tb2RlbCksXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUoZmFsc2UpO1xyXG5cdFx0XHQkKCcjaWxsdXN0cmF0aW9uJykucmVtb3ZlQ2xhc3MoJ2lzLWxvYWRpbmctbWVudS1hbicpO1xyXG5cdFx0fSkuY2F0Y2goKG1lc3NhZ2UpID0+IHtcclxuXHRcdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUoZmFsc2UpO1xyXG5cdFx0XHQkKCcjaWxsdXN0cmF0aW9uJykucmVtb3ZlQ2xhc3MoJ2lzLWxvYWRpbmctbWVudS1hbicpO1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHR9KTtcclxuXHJcbiAgfVxyXG5cclxuXHRmZXRjaENoaWxkTm9kZXMocGFyZW50LCBpc29wZW4pIHtcclxuXHRcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKHRydWUpO1xyXG5cdFx0JCgnI2lsbHVzdHJhdGlvbicpLmFkZENsYXNzKCdpcy1sb2FkaW5nLW1lbnUtY24nKTtcclxuXHRcdFRyZWVWaWV3QXBpLmdldE5vZGVzKHBhcmVudCkudGhlbigocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0bGV0IGNoaWxkcmVuID0gXy5pc1VuZGVmaW5lZChyZXNwb25zZSkgPyB7fSA6IFRyZWVWaWV3U3RvcmUuZ2V0KHBhcmVudCk7XHJcblx0XHRcdHRoaXMuc3RhdGUuc2VjdGlvbkNoaWxkcmVuID0gY2hpbGRyZW47XHJcblx0XHRcdGNvbnNvbGUubG9nKGNoaWxkcmVuKVxyXG5cdFx0ICBcdHRoaXMuZmV0Y2hBc2NlbmRhbnROb2RlcygpO1xyXG5cdFx0ICBcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKGZhbHNlKTtcclxuXHRcdFx0JCgnI2lsbHVzdHJhdGlvbicpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nLW1lbnUtY24nKTtcclxuXHRcdH0pLmNhdGNoKChtZXNzYWdlKSA9PiB7XHJcblx0XHRcdGlmKG1lc3NhZ2UgPT09IDIwNCl7XHJcblx0XHRcdFx0bGV0IGNoaWxkcmVuID0ge307XHJcblx0XHRcdFx0dGhpcy5zdGF0ZS5zZWN0aW9uQ2hpbGRyZW4gPSBjaGlsZHJlbjtcclxuXHRcdFx0XHR0aGlzLmZldGNoQXNjZW5kYW50Tm9kZXMoKTtcclxuXHRcdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdFx0JCgnI2lsbHVzdHJhdGlvbicpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nLW1lbnUtY24nKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHRcdFx0JCgnI2lsbHVzdHJhdGlvbicpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nLW1lbnUtY24nKTtcclxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50V2lsbE1vdW50KCkge1xyXG5cdFx0aWYodGhpcy5wcm9wcy5tb2RlbCAmJiB0aGlzLnByb3BzLmlsbHVzdHJhdGlvbikge1xyXG5cdFx0XHR0aGlzLmZldGNoQ2hpbGROb2Rlcyh0aGlzLnByb3BzLm5vZGVJZCwgdHJ1ZSk7XHJcblx0XHRcdHRoaXMuc2VsZWN0Tm9kZSh0aGlzLnByb3BzLmlsbHVzdHJhdGlvbik7XHJcblx0XHR9XHJcblx0XHRlbHNlIGlmICh0aGlzLnByb3BzLm1vZGVsICYmIHRoaXMucHJvcHMubm9kZUlkKSB7XHJcblx0XHRcdHRoaXMuZmV0Y2hDaGlsZE5vZGVzKHRoaXMucHJvcHMubm9kZUlkLCB0cnVlKTtcclxuXHRcdFx0dGhpcy5zZWxlY3ROb2RlKHRoaXMucHJvcHMubm9kZUlkKTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHR0aGlzLnByZWZldGNoTm9kZXModGhpcy5wcm9wcy5tb2RlbCk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0aWYoIXRoaXMucHJvcHMubW9kZWwpIHJldHVybiBudWxsO1xyXG5cdFx0bGV0IGlzTWFjaGluZSA9IHRoaXMucHJvcHMubW9kZWwuc3Vic3RyaW5nKDAsIDgpID09ICdtYWNoaW5lLSc7XHJcblx0XHRsZXQgY2hpbGRyZW4gPSBudWxsO1xyXG5cdFx0bGV0IG1vZGVsVHJlZUl0ZW1Qcm9wcyA9IG51bGw7XHJcblxyXG5cdFx0aWYodGhpcy5zdGF0ZS5jaGlsZHJlbi5pc01hY2hpbmUpe1xyXG5cdFx0XHRtb2RlbFRyZWVJdGVtUHJvcHMgPSB7XHJcblx0XHRcdFx0aXNNYWNoaW5lOiB0cnVlLFxyXG5cdFx0XHRcdGtleTogdGhpcy5wcm9wcy5tb2RlbCxcclxuXHRcdFx0XHRub2RlOiB0aGlzLnN0YXRlLmNoaWxkcmVuLmRhdGEsXHJcblx0XHRcdFx0bW9kZWw6IHRoaXMucHJvcHMubW9kZWwsXHJcblx0XHRcdFx0c2VsZWN0ZWROb2RlSWQ6IFRyZWVWaWV3U3RvcmUuZ2V0U2VsZWN0ZWROb2RlKCksXHJcblx0XHRcdFx0b25TZWxlY3ROb2RlOiB0aGlzLnNlbGVjdE5vZGUuYmluZCh0aGlzKSxcclxuXHRcdFx0XHRzZWN0aW9uQ2hpbGRyZW46IHRoaXMuc3RhdGUuY2hpbGRyZW4uZGF0YVswXVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjaGlsZHJlbiA9IDxNb2RlbFRyZWVJdGVtIHsuLi5tb2RlbFRyZWVJdGVtUHJvcHN9IC8+XHJcblxyXG5cdFx0fWVsc2V7XHJcblx0XHRcdGNoaWxkcmVuID0gdGhpcy5zdGF0ZS5jaGlsZHJlbi5kYXRhLm1hcCgobm9kZSkgPT4ge1xyXG5cdFx0XHRcdG1vZGVsVHJlZUl0ZW1Qcm9wcyA9IHtcclxuXHRcdFx0XHRcdGlzTWFjaGluZTogZmFsc2UsXHJcblx0XHRcdFx0XHRrZXk6IG5vZGUuSWQsXHJcblx0XHRcdFx0XHRub2RlOiBub2RlLFxyXG5cdFx0XHRcdFx0ZG9jdW1lbnRzOiBub2RlLkRvY3VtZW50cyxcclxuXHRcdFx0XHRcdG1vZGVsOiB0aGlzLnByb3BzLm1vZGVsLFxyXG5cdFx0XHRcdFx0c2VsZWN0ZWROb2RlSWQ6IFRyZWVWaWV3U3RvcmUuZ2V0U2VsZWN0ZWROb2RlKCksXHJcblx0XHRcdFx0XHRvblNlbGVjdE5vZGU6IHRoaXMuc2VsZWN0Tm9kZS5iaW5kKHRoaXMpLFxyXG5cdFx0XHRcdFx0c2VjdGlvbkNoaWxkcmVuOiAodGhpcy5zdGF0ZS5zZWN0aW9uQ2hpbGRyZW4gPyB0aGlzLnN0YXRlLnNlY3Rpb25DaGlsZHJlbiA6IG51bGwpXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybihcclxuXHRcdFx0XHRcdDxNb2RlbFRyZWVJdGVtIHsuLi5tb2RlbFRyZWVJdGVtUHJvcHN9IC8+XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdGxldCB1bENsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdtYWNoaW5lJzogaXNNYWNoaW5lXHJcblx0XHR9KTtcclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxuYXYgY2xhc3NOYW1lPVwidWMtdHJlZW1lbnVcIj5cclxuXHRcdFx0XHQ8ZGl2PlxyXG5cdFx0XHRcdFx0PE1vZGVsVHJlZVNlYXJjaCBpc01hY2hpbmU9e2lzTWFjaGluZX0gbW9kZWxJZD17dGhpcy5wcm9wcy5tb2RlbH0vPlxyXG5cdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdDx1bCBjbGFzc05hbWU9e3VsQ2xhc3N9PlxyXG5cdFx0XHRcdFx0e2NoaWxkcmVufVxyXG5cdFx0XHRcdDwvdWw+XHJcblx0XHRcdDwvbmF2PlxyXG5cdFx0KTtcclxuXHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTW9kZWxUcmVlO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCB7IFJvdXRlciwgUm91dGUsIExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXInO1xyXG5pbXBvcnQgVHJlZVZpZXdTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3RyZWV2aWV3X3N0b3JlJztcclxuaW1wb3J0IFRyZWVWaWV3QXBpIGZyb20gJy4uLy4uL19hcGkvdHJlZXZpZXdfYXBpJztcclxuaW1wb3J0IElsbHVzdHJhdGlvblN0b3JlIGZyb20gJy4uLy4uL19zdG9yZXMvaWxsdXN0cmF0aW9uX3N0b3JlJztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5jbGFzcyBNb2RlbFRyZWVJdGVtIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGNoaWxkcmVuOiB7XHJcblx0XHRcdFx0ZGF0YTogW11cclxuXHRcdFx0fSxcclxuXHRcdFx0aXNvcGVuOiBmYWxzZSxcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5wcm9wcyA9IHt9O1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHRsZXQgY2hpbGRyZW4gPSBUcmVlVmlld1N0b3JlLmdldCh0aGlzLnByb3BzLm5vZGUuSWQpO1xyXG5cdFx0aWYgKCFjaGlsZHJlbiAmJiAhdGhpcy5wcm9wcy5zZWN0aW9uQ2hpbGRyZW4pIHJldHVybjtcclxuXHRcdGlmICh0aGlzLnByb3BzLmlzTWFjaGluZSkge1xyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRjaGlsZHJlbjoge1xyXG5cdFx0XHRcdFx0ZGF0YTogdGhpcy5wcm9wcy5zZWN0aW9uQ2hpbGRyZW5cclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdGlzb3BlbjogdHJ1ZVxyXG5cdFx0XHR9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGNoaWxkcmVuOiAoY2hpbGRyZW4gPyBjaGlsZHJlbiA6IHRoaXMucHJvcHMuc2VjdGlvbkNoaWxkcmVuKSxcclxuXHRcdFx0XHRpc29wZW46IHRydWVcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0dXBkYXRlU2VsZWN0ZWROb2RlT25CYWNrQ2xpY2soc2VsZikge1xyXG5cdFx0JCh3aW5kb3cpLmJpbmQoJ3BvcHN0YXRlJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcblx0XHRcdGxldCBocmVmID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcblx0XHRcdGxldCBJbGx1c3RyYXRpb25MaW5rID0gaHJlZi5zdWJzdHIoaHJlZi5sYXN0SW5kZXhPZignLycpICsgMSk7XHJcblx0XHRcdGxldCBsaW5rcyA9IGhyZWYuc3BsaXQoJy8nKTtcclxuXHJcblxyXG5cdFx0XHRsZXQgaWRzID0gW107XHJcblx0XHRcdGZvciAodmFyIGkgPSBsaW5rcy5sZW5ndGggLSAzOyBpIDwgbGlua3MubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHRpZiAobGlua3NbaV0ubGVuZ3RoID09PSAzNikge1xyXG5cdFx0XHRcdFx0aWRzLnB1c2gobGlua3NbaV0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWRzLnJldmVyc2UoKTtcclxuXHJcblx0XHRcdGxldCBsaVRvU2V0U2VsZWN0ZWQ7XHJcblx0XHRcdHN3aXRjaCAoaWRzLmxlbmd0aCkge1xyXG5cdFx0XHRcdGNhc2UgMTpcclxuXHRcdFx0XHRcdGxpVG9TZXRTZWxlY3RlZCA9ICQoJy51Yy10cmVlbWVudSB1bCA+IGxpOmZpcnN0LW9mLXR5cGUnKS5hdHRyKCdkYXRhLW5vZGUtaWQnKTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdGNhc2UgMjpcclxuXHRcdFx0XHRcdGxpVG9TZXRTZWxlY3RlZCA9IGlkc1swXTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdGNhc2UgMzpcclxuXHRcdFx0XHRcdGxpVG9TZXRTZWxlY3RlZCA9IGlkc1sxXTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRsZXQgY2hhbmdlZFNlbGVjdGVkID0gZmFsc2U7XHJcblx0XHRcdGlmIChzZWxmLnByb3BzLm5vZGUuSWQgPT09IGxpVG9TZXRTZWxlY3RlZCkge1xyXG5cdFx0XHRcdCQoJy51Yy10cmVlbWVudSBsaVtkYXRhLW5vZGUtaWQ9XCInICsgc2VsZi5wcm9wcy5ub2RlLklkICsgJ1wiXScpLmFkZENsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdCQoJy51Yy10cmVlbWVudSBsaVtkYXRhLW5vZGUtaWQ9XCInICsgc2VsZi5wcm9wcy5ub2RlLklkICsgJ1wiXScpLnJlbW92ZUNsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGZldGNoQ2hpbGROb2RlcyhwYXJlbnQsIGlzb3Blbikge1xyXG5cdFx0VHJlZVZpZXdTdG9yZS5zZXRMb2FkaW5nU3RhdGUodHJ1ZSk7XHJcblxyXG5cdFx0VHJlZVZpZXdBcGkuZ2V0Tm9kZXMocGFyZW50KS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG5cdFx0XHRsZXQgY2hpbGRyZW4gPSBfLmlzVW5kZWZpbmVkKHJlc3BvbnNlKSA/IHt9IDogVHJlZVZpZXdTdG9yZS5nZXQocGFyZW50KTtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0Y2hpbGRyZW46IGNoaWxkcmVuLFxyXG5cdFx0XHRcdGlzb3BlbjogaXNvcGVuXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRUcmVlVmlld1N0b3JlLnNldExvYWRpbmdTdGF0ZShmYWxzZSk7XHJcblx0XHR9KS5jYXRjaCgobWVzc2FnZSkgPT4ge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcblx0XHRcdFRyZWVWaWV3U3RvcmUuc2V0TG9hZGluZ1N0YXRlKGZhbHNlKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0dG9nZ2xlRXhwYW5kID0gKGUpID0+IHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGxldCBpc29wZW4gPSAhdGhpcy5zdGF0ZS5pc29wZW47XHJcblx0XHR0aGlzLmZldGNoQ2hpbGROb2Rlcyh0aGlzLnByb3BzLm5vZGUuSWQsIGlzb3Blbik7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVDbGljayA9IChlKSA9PiB7XHJcblx0XHRpZih0aGlzLnN0YXRlLmlzb3Blbil7XHJcblx0XHRcdGxldCBwYXJlbnQgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KCdsaScpO1xyXG5cdFx0XHRpZiAocGFyZW50Lmhhc0NsYXNzKCdpcy1vcGVuJykpIHtcclxuXHRcdFx0XHRwYXJlbnQucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKVxyXG5cdFx0XHRcdHBhcmVudC5yZW1vdmVDbGFzcygnaXMtc2VsZWN0ZWQnKVxyXG5cdFx0XHRcdHRoaXMuc3RhdGUuaXNvcGVuID0gZmFsc2U7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMucHJvcHMuaXNNYWNoaW5lIHx8IHRoaXMucHJvcHMuaXNNb2RlbFR5cGUpIHtcclxuXHRcdFx0aWYgKCEkKGUudGFyZ2V0KS5oYXNDbGFzcygnYWN0aXZlJykpIHtcclxuXHRcdFx0XHRJbGx1c3RyYXRpb25TdG9yZS5zZXRMb2FkaW5nU3RhdGUodHJ1ZSk7XHJcblx0XHRcdFx0dGhpcy5wcm9wcy5vblNlbGVjdE5vZGUoJChlLnRhcmdldCkuZGF0YSgnbm9kZS1pZCcpKTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aWYgKHRoaXMucHJvcHMubm9kZS5JbGx1c3RyYXRpb25MaW5rICYmIHRoaXMucHJvcHMubm9kZS5JbGx1c3RyYXRpb25MaW5rICE9PSAnMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwJykge1xyXG5cdFx0XHRcdGlmICh0aGlzLnByb3BzLm5vZGUuSWxsdXN0cmF0aW9uTGluayAhPSBJbGx1c3RyYXRpb25TdG9yZS5nZXRJbGx1c3RyYXRpb24oKS5pbGx1c3RyYXRpb24uSWQpIHtcclxuXHRcdFx0XHRcdElsbHVzdHJhdGlvblN0b3JlLnNldExvYWRpbmdTdGF0ZSh0cnVlKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5wcm9wcy5vblNlbGVjdE5vZGUodGhpcy5wcm9wcy5ub2RlLklkKTtcclxuXHJcblx0XHRcdGlmICh0aGlzLnByb3BzLm5vZGUuSXNMZWFmICYmICF0aGlzLnByb3BzLmRvY3VtZW50cykgcmV0dXJuO1xyXG5cclxuXHRcdFx0bGV0IGNoaWxkcmVuID0gdGhpcy5mZXRjaENoaWxkTm9kZXModGhpcy5wcm9wcy5ub2RlLklkLCB0cnVlKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblxyXG5cdFx0bGV0IGxhbmcgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MubGFuZztcclxuXHRcdGxldCBtYWNoaW5lSXRlbXMgPSBudWxsO1xyXG5cdFx0bGV0IGNoaWxkcmVuID0gbnVsbDtcclxuXHRcdGxldCB1cmwgPSBudWxsO1xyXG5cdFx0bGV0IGNvZGUgPSAnJztcclxuXHRcdGxldCBpbGx1c3RyYXRpb25JZCA9ICcnO1xyXG5cdFx0bGV0IGNsYXNzZXMgPSBudWxsO1xyXG5cdFx0bGV0IGV4cGFuZCA9ICcnO1xyXG5cdFx0bGV0IG51bWJlciA9IDA7XHJcblxyXG5cdFx0bGV0IHZpZXdVcmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuZXhwbG9kZWRWaWV3c1VSTFxyXG5cdFx0aWYoaGlhYmNvbmZpZy5oYXNFcXVpcG1lbnRUeXBlUmVzdHJpY3Rpb24pe1xyXG5cdFx0XHR2aWV3VXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLnNlYXJjaERyYXdpbmdzUGFnZVVybDsgXHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMucHJvcHMuaXNNYWNoaW5lKSB7XHJcblx0XHRcdGNvbnN0IG1hY2hpbmVVcmwgPSB2aWV3VXJsICsgdGhpcy5wcm9wcy5tb2RlbCArICcvJztcclxuXHJcblx0XHRcdG1hY2hpbmVJdGVtcyA9IHRoaXMucHJvcHMuc2VjdGlvbkNoaWxkcmVuLm1hcCgoY2hpbGRub2RlKSA9PiB7XHJcblx0XHRcdFx0bGV0IGlzQWN0aXZlID0gY2hpbGRub2RlLklsbHVzdHJhdGlvbkxpbmsgIT09ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnO1xyXG5cdFx0XHRcdGxldCBkZXNjcmlwdGlvbiA9IGNoaWxkbm9kZS5EZXNjcmlwdGlvbiA/IGAgLSAke2NoaWxkbm9kZS5EZXNjcmlwdGlvbn1gIDogJyc7XHJcblx0XHRcdFx0bGV0IGtleUlkID0gJ2tleS0nICsgY2hpbGRub2RlLklkO1xyXG5cdFx0XHRcdGxldCBsaW5rQ2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0XHRcdCdsaW5rJzogdHJ1ZSxcclxuXHRcdFx0XHRcdCdtYWNoaW5lLWxpbmsnOiB0cnVlLFxyXG5cdFx0XHRcdFx0J2luYWN0aXZlJzogIWlzQWN0aXZlXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0cmV0dXJuIChcclxuXHRcdFx0XHRcdDxsaSBrZXk9e2tleUlkfSBkYXRhLW5vZGUtaWQ9e2NoaWxkbm9kZS5JZH0+XHJcblx0XHRcdFx0XHRcdDxkaXY+XHJcblx0XHRcdFx0XHRcdFx0e2lzQWN0aXZlID9cclxuXHRcdFx0XHRcdFx0XHRcdDxMaW5rIGRhdGEtbm9kZS1pZD17Y2hpbGRub2RlLklkfSBjbGFzc05hbWU9J2xpbmsgbWFjaGluZS1saW5rJyBvbkNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcyl9IHRvPXttYWNoaW5lVXJsICsgY2hpbGRub2RlLklkICsgJy8nICsgY2hpbGRub2RlLklsbHVzdHJhdGlvbkxpbmt9PntjaGlsZG5vZGUuTW9kZWxDb2RlfXtkZXNjcmlwdGlvbn08L0xpbms+IDpcclxuXHRcdFx0XHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT17bGlua0NsYXNzfT57Y2hpbGRub2RlLk1vZGVsQ29kZX17ZGVzY3JpcHRpb259PGk+IC0ge2xhbmcuaW5hY3RpdmVOb2RlfTwvaT48L3NwYW4+XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDwvbGk+XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRjaGlsZHJlbiA9IHRoaXMuc3RhdGUuY2hpbGRyZW4uZGF0YS5tYXAoKGNoaWxkbm9kZSkgPT4ge1xyXG5cdFx0XHRcdGxldCBtb2RlbFRyZWVJdGVtUHJvcHMgPSB7XHJcblx0XHRcdFx0XHRrZXk6IGNoaWxkbm9kZS5JZCxcclxuXHRcdFx0XHRcdG5vZGU6IGNoaWxkbm9kZSxcclxuXHRcdFx0XHRcdG1vZGVsOiB0aGlzLnByb3BzLm1vZGVsLFxyXG5cdFx0XHRcdFx0b25TZWxlY3ROb2RlOiB0aGlzLnByb3BzLm9uU2VsZWN0Tm9kZSxcclxuXHRcdFx0XHRcdHNlbGVjdGVkTm9kZUlkOiB0aGlzLnByb3BzLnNlbGVjdGVkTm9kZUlkLFxyXG5cdFx0XHRcdFx0aWxsdXN0cmF0aW9uOiB0aGlzLnByb3BzLmlsbHVzdHJhdGlvbixcclxuXHRcdFx0XHRcdGRvY3VtZW50czogY2hpbGRub2RlLkRvY3VtZW50cy5tYXAoKGRvY3VtZW50Tm9kZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRsZXQgaWQgPSBudW1iZXIrKyArIFwiLVwiICsgZG9jdW1lbnROb2RlLkRlc2NyaXB0aW9uO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdFx0XHRcdDxsaSBrZXk9e2lkfSBjbGFzc05hbWU9XCJkb2N1bWVudFwiIGRhdGEtbm9kZS1pZD17aWR9PlxyXG5cdFx0XHRcdFx0XHRcdFx0PGRpdj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PGEgZGF0YS1ub2RlLWlkPXtpZH0gaHJlZj17ZG9jdW1lbnROb2RlLkRvY3VtZW50TGlua30gdGFyZ2V0PVwiX2JsYW5rXCIgY2xhc3NOYW1lPSdsaW5rJyA+PGkgY2xhc3NOYW1lPVwiaWNvbi1kb2NcIiAvPntkb2N1bWVudE5vZGUuRGVzY3JpcHRpb259PC9hPlxyXG5cdFx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0PC9saT5cclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdH0pLFxyXG5cdFx0XHRcdH07XHJcblxyXG5cdFx0XHRcdHJldHVybiAoXHJcblx0XHRcdFx0XHQ8TW9kZWxUcmVlSXRlbSB7Li4ubW9kZWxUcmVlSXRlbVByb3BzfSAvPlxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdFx0XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dGhpcy51cGRhdGVTZWxlY3RlZE5vZGVPbkJhY2tDbGljayh0aGlzKTtcclxuXHJcblx0XHRcdGlmICh0aGlzLnByb3BzLm5vZGUuSWxsdXN0cmF0aW9uTGluayAmJiB0aGlzLnByb3BzLm5vZGUuSWxsdXN0cmF0aW9uTGluayAhPT0gJzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCcpIHtcclxuXHRcdFx0XHRjb2RlID0gdGhpcy5wcm9wcy5ub2RlLk5vZGVUeXBlLnRvU3RyaW5nKCkgPT09ICcwJyA/IHRoaXMucHJvcHMubm9kZS5JbGx1c3RyYXRpb25Db2RlICsgJyAnIDogJyc7XHJcblx0XHRcdFx0aWxsdXN0cmF0aW9uSWQgPSB0aGlzLnByb3BzLm5vZGUuSWxsdXN0cmF0aW9uTGluaztcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y2xhc3NlcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHRcdCdoYXMtY2hpbGRyZW4nOiB0cnVlLFxyXG5cdFx0XHRcdCdpcy1vcGVuJzogdGhpcy5zdGF0ZS5pc29wZW4sXHJcblx0XHRcdFx0J2lzLXNlbGVjdGVkJzogdGhpcy5wcm9wcy5zZWxlY3RlZE5vZGVJZCA9PT0gdGhpcyB8fFxyXG5cdFx0XHRcdFx0dGhpcy5wcm9wcy5zZWxlY3RlZE5vZGVJZCA9PT0gdGhpcy5wcm9wcy5ub2RlLklkIHx8XHJcblx0XHRcdFx0XHR0aGlzLnByb3BzLnNlbGVjdGVkTm9kZUlkID09PSBpbGx1c3RyYXRpb25JZFxyXG5cdFx0XHR9KTtcclxuXHRcdFx0aWYgKCF0aGlzLnByb3BzLm5vZGUuSXNMZWFmIHx8IHRoaXMucHJvcHMubm9kZS5Eb2N1bWVudHMpIHtcclxuXHRcdFx0XHRleHBhbmQgPSA8YSBjbGFzc05hbWU9XCJleHBhbmRcIiBocmVmPVwiI1wiIG9uQ2xpY2s9e3RoaXMudG9nZ2xlRXhwYW5kLmJpbmQodGhpcyl9PjxpIGNsYXNzTmFtZT1cImljb24tYW5nbGUtZG93blwiPjwvaT48L2E+XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHVybCA9IHZpZXdVcmwgKyB0aGlzLnByb3BzLm1vZGVsICsgKHRoaXMucHJvcHMubm9kZS5JZCA/ICcvJyArIHRoaXMucHJvcHMubm9kZS5JZCA6ICcnKSArIChpbGx1c3RyYXRpb25JZCA/ICcvJyArIGlsbHVzdHJhdGlvbklkIDogJycpO1xyXG5cdFxyXG5cdFx0fVxyXG5cclxuXHRcclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxkaXY+XHJcblx0XHRcdFx0eyB0aGlzLnByb3BzLmlzTWFjaGluZSA/IG1hY2hpbmVJdGVtcyA6XHJcblx0XHRcdFx0XHQ8bGkgY2xhc3NOYW1lPXtjbGFzc2VzfSBkYXRhLW5vZGUtaWQ9e3RoaXMucHJvcHMubm9kZS5JZH0+XHJcblx0XHRcdFx0XHRcdDxkaXY+XHJcblx0XHRcdFx0XHRcdFx0PExpbmsgZGF0YS1ub2RlLWlkPXt0aGlzLnByb3BzLm5vZGUuSWR9IGNsYXNzTmFtZT0nbGluaycgb25DbGljaz17dGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpfSB0bz17dXJsfT57Y29kZX17dGhpcy5wcm9wcy5ub2RlLkRlc2NyaXB0aW9ufTwvTGluaz5cclxuXHRcdFx0XHRcdFx0XHR7ZXhwYW5kfVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PHVsPlxyXG5cdFx0XHRcdFx0XHRcdHt0aGlzLnByb3BzLmRvY3VtZW50c31cclxuXHRcdFx0XHRcdFx0XHR7Y2hpbGRyZW59XHJcblx0XHRcdFx0XHRcdDwvdWw+XHJcblx0XHRcdFx0XHQ8L2xpPlxyXG5cdFx0XHRcdH1cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgTW9kZWxUcmVlSXRlbTtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgVHJlZVZpZXdBY3Rpb25zIGZyb20gJy4uLy4uL19hY3Rpb25zL3RyZWV2aWV3X2FjdGlvbnMnO1xyXG5pbXBvcnQgVHJlZVZpZXdTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL3RyZWV2aWV3X3N0b3JlJztcclxuaW1wb3J0IFRyZWVWaWV3QXBpIGZyb20gJy4uLy4uL19hcGkvdHJlZXZpZXdfYXBpJztcclxuaW1wb3J0IE1vZGVsVHJlZVZpZXdTZWFyY2hTdG9yZSBmcm9tICcuLi8uLi9fc3RvcmVzL21vZGVsX3RyZWVfc2VhcmNoX3N0b3JlJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5jb25zdCBkb25lVHlwaW5nSW50ZXJ2YWwgPSAgMzAwO1xyXG5cclxuY2xhc3MgTW9kZWxUcmVlU2VhcmNoIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aXNMb2FkaW5nOiBmYWxzZVxyXG5cdFx0fTtcclxuXHRcdC8vIHRoaXMucHJvcHMgPSB7fTtcclxuXHRcdHRoaXMudHlwaW5nVGltZXIgPSBudWxsO1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlID0gTW9kZWxUcmVlVmlld1NlYXJjaFN0b3JlLmxpc3RlbigocmVzKSA9PiB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzTG9hZGluZzogZmFsc2VcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG5cdFx0dGhpcy51bnN1YnNjcmliZSgpO1xyXG5cdH1cclxuXHJcblxyXG5cdGhhbmRsZUtleXVwKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmKHRoaXMudHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnR5cGluZ1RpbWVyKTtcclxuXHJcblx0XHRsZXQgdmFsdWUgPSBlLnRhcmdldC52YWx1ZTtcclxuXHQgIHRoaXMudHlwaW5nVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0dGhpcy5kb25lVHlwaW5nKHZhbHVlKTtcclxuXHRcdH0sIGRvbmVUeXBpbmdJbnRlcnZhbCk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVLZXlkb3duKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmKHRoaXMudHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnR5cGluZ1RpbWVyKTtcclxuXHR9XHJcblxyXG5cdGRvbmVUeXBpbmcgKHZhbHVlKSB7XHJcblx0XHRUcmVlVmlld0FjdGlvbnMuc2VhcmNoTm9kZXNJbk1vZGVsKHZhbHVlLHRoaXMucHJvcHMubW9kZWxJZCwgdGhpcy5wcm9wcy5pc01hY2hpbmUpO1xyXG5cdFx0TW9kZWxUcmVlVmlld1NlYXJjaFN0b3JlLnNldFNlYXJjaFZhbHVlKHZhbHVlKTtcclxuXHRcdGlmKCF0aGlzLnN0YXRlLmlzTG9hZGluZyl7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzTG9hZGluZzogdHJ1ZVxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cclxuXHRoYW5kbGVTdWJtaXQgPSAoZSkgPT57XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRUcmVlVmlld0FjdGlvbnMuc2VhcmNoTm9kZXNJbk1vZGVsKGUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9XCJ0ZXh0XCJdJykudmFsdWUgLHRoaXMucHJvcHMubW9kZWxJZCwgdGhpcy5wcm9wcy5pc01hY2hpbmUpO1xyXG5cdFx0aWYoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKXtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aXNMb2FkaW5nOiB0cnVlXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2xpY2sgPSAoZSkgPT57XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRsZXQgdmFsdWUgPSBlLnRhcmdldC50YWdOYW1lID09PSAnSScgPyBlLnRhcmdldC5wYXJlbnRFbGVtZW50LmZvcm0ucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1cInRleHRcIl0nKS52YWx1ZSA6IGUudGFyZ2V0LmZvcm0ucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1cInRleHRcIl0nKS52YWx1ZTtcclxuXHRcdFRyZWVWaWV3QWN0aW9ucy5zZWFyY2hOb2Rlc0luTW9kZWwodmFsdWUgLHRoaXMucHJvcHMubW9kZWxJZCwgdGhpcy5wcm9wcy5pc01hY2hpbmUpO1xyXG5cdFx0aWYoIXRoaXMuc3RhdGUuaXNMb2FkaW5nKXtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aXNMb2FkaW5nOiB0cnVlXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGxldCBidXR0b25DbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnYnV0dG9uIGxvYWRpbmcnOiB0aGlzLnN0YXRlLmlzTG9hZGluZyxcclxuXHRcdFx0J2J1dHRvbic6ICF0aGlzLnN0YXRlLmlzTG9hZGluZ1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJ1Yy1tb2RlbC10cmVlLXNlYXJjaFwiPlxyXG4gICAgICAgIDxmb3JtIGFjdGlvbj1cIlwiIG1ldGhvZD1cImdldFwiIG9uU3VibWl0PXt0aGlzLmhhbmRsZVN1Ym1pdC5iaW5kKHRoaXMpfT5cclxuICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG5hbWU9XCJtb2RlbC10cmVlLXNlYXJjaC10ZXh0XCIgb25LZXlVcD17dGhpcy5oYW5kbGVLZXl1cC5iaW5kKHRoaXMpfSBvbktleURvd249e3RoaXMuaGFuZGxlS2V5ZG93bi5iaW5kKHRoaXMpfSAvPlxyXG5cdFx0XHRcdFx0PGJ1dHRvbiBjbGFzc05hbWU9e2J1dHRvbkNsYXNzfSB0eXBlPVwic3VibWl0XCIgb25DbGljaz17dGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpfT48aSBjbGFzc05hbWU9XCJpY29uLXNlYXJjaFwiIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2suYmluZCh0aGlzKX0+PC9pPjwvYnV0dG9uPlxyXG4gICAgICAgIDwvZm9ybT5cclxuICAgICAgPC9kaXY+XHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTW9kZWxUcmVlU2VhcmNoO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgV2lzaGxpc3RIZWFkZXIgZnJvbSAnLi93aXNobGlzdEhlYWRlcic7XHJcbmltcG9ydCBJbmplY3RvciBmcm9tICcuLy4uLy4uL25vdGlmaWNhdGlvbnMvbWVzc2FnZUluamVjdG9yJztcclxuXHJcbmxldCBpbnZva2luZ0VsZW1lbnQgPSBudWxsO1xyXG5sZXQgd2lzaGxpc3RMaW5laXRlbXMgPSBbXTtcclxubGV0IG1vYmlsZVdpc2hsaXN0VG9nZ2xlID0gJCgnLnNob3ctZm9yLW1lZGl1bS1kb3duIC53aXNobGlzdC10b2dnbGUnKTtcclxuXHJcbmxldCBMaW5laXRlbUhhbmRsZXIgPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdC8vaGFuZGxlIGFkZCBsaW5lIGl0ZW0gb24gcHJvZHVjdCBkZXRhaWwgcGFnZVxyXG5cdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJ2J1dHRvbi5zYXZlZC1jYXJ0LWFkZCcsIChlKSA9PiB7XHJcblx0XHRcdGlmIChXaXNobGlzdEhlYWRlci5HZXRTZWxlY3RlZFdpc2hsaXN0RGF0YSgpID09IG51bGwpIHtcclxuXHRcdFx0XHQkKCcjd2lzaGxpc3RDb250cm9sbHMnKS5hZGRDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHRcdCQoJy5kcmF3ZXItbWFpbiAuZHJhd2VyLXJpZ2h0JykuYWRkQ2xhc3MoJ3dpc2hsaXN0LWFjdGl2ZScpO1xyXG5cdFx0XHRcdGxldCB3aXNobGlzdHNFeGlzdHMgPSAkKCcjd2lzaGxpc3RTZWxlY3QgLm1lbnUgLml0ZW0nKS5sZW5ndGggPiAwO1xyXG5cdFx0XHRcdGlmKCF3aXNobGlzdHNFeGlzdHMpIHtcclxuXHRcdFx0XHRcdCQoJy53aXNobGlzdC1tYW5hZ2UnKS5oaWRlKCk7XHJcblx0XHRcdFx0XHQkKCcud2lzaGxpc3QtY3JlYXRlJykuc2hvdygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aW52b2tpbmdFbGVtZW50ID0gJChlLmN1cnJlbnRUYXJnZXQpO1xyXG5cdFx0XHR3aXNobGlzdExpbmVpdGVtcyA9IFtdO1xyXG5cdFx0XHRsZXQgY29kZSA9IGludm9raW5nRWxlbWVudC5kYXRhKCdwcm9kdWN0LXNrdScpO1xyXG5cdFx0XHRsZXQgcXVhbnRpdHkgPSAkKFwiLmFtb3VudFtkYXRhLXByb2R1Y3Qtc2t1PSdcIiArIGNvZGUgKyBcIiddXCIpLnZhbCgpO1xyXG5cdFx0XHRsZXQgY29zdCA9ICQoXCIuYW1vdW50W2RhdGEtcHJvZHVjdC1za3U9J1wiICsgY29kZSArIFwiJ11cIikuZGF0YSgncHJvZHVjdC1jb3N0Jyk7XHJcblxyXG5cdFx0XHRsZXQgaXRlbSA9IHtcclxuXHRcdFx0XHRDb2RlOiBjb2RlLFxyXG5cdFx0XHRcdFF1YW50aXR5OiBxdWFudGl0eSxcclxuXHRcdFx0XHRDb3N0OiBjb3N0XHJcblx0XHRcdH07XHJcblx0XHRcdHdpc2hsaXN0TGluZWl0ZW1zLnB1c2goaXRlbSk7XHJcblxyXG5cdFx0XHRpZiAoV2lzaGxpc3RIZWFkZXIuR2V0U2VsZWN0ZWRXaXNobGlzdERhdGEoKSA9PSBudWxsKSByZXR1cm47XHJcblx0XHRcdExpbmVpdGVtSGFuZGxlci5BZGRUb1dpc2hsaXN0KCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL2hhbmRsZSBhZGQgbGluZSBpdGVtIG9uIGJhdGNob3JkZXIgcGFnZVxyXG5cdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJ2J1dHRvbi5iYXRjaC1zYXZlZC1jYXJ0LWFkZCcsIChlKSA9PiB7XHJcblx0XHRcdGlmIChXaXNobGlzdEhlYWRlci5HZXRTZWxlY3RlZFdpc2hsaXN0RGF0YSgpID09IG51bGwpIHtcclxuXHRcdFx0XHQkKCcjd2lzaGxpc3RDb250cm9sbHMnKS5hZGRDbGFzcygnaXMtb3BlbicpO1xyXG5cdFx0XHRcdCQoJy5kcmF3ZXItbWFpbiAuZHJhd2VyLXJpZ2h0JykuYWRkQ2xhc3MoJ3dpc2hsaXN0LWFjdGl2ZScpO1xyXG5cdFx0XHRcdGxldCB3aXNobGlzdHNFeGlzdHMgPSAkKCcjd2lzaGxpc3RTZWxlY3QgLm1lbnUgLml0ZW0nKS5sZW5ndGggPiAwO1xyXG5cdFx0XHRcdGlmKCF3aXNobGlzdHNFeGlzdHMpIHtcclxuXHRcdFx0XHRcdCQoJy53aXNobGlzdC1tYW5hZ2UnKS5oaWRlKCk7XHJcblx0XHRcdFx0XHQkKCcud2lzaGxpc3QtY3JlYXRlJykuc2hvdygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aW52b2tpbmdFbGVtZW50ID0gJChlLmN1cnJlbnRUYXJnZXQpO1xyXG5cdFx0XHR3aXNobGlzdExpbmVpdGVtcyA9IFtdO1xyXG5cclxuXHRcdFx0JCgnZGl2I2xpbmUtaXRlbXMgLnJvdyBpbnB1dC5xdWFudGl0eScpLmVhY2goZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0bGV0IGN1cnJlbnRSb3cgPSAkKHRoaXMpO1xyXG5cdFx0XHRcdGxldCBjb2RlID0gY3VycmVudFJvdy5kYXRhKCdsaW5lLWl0ZW0nKTtcclxuXHRcdFx0XHRsZXQgY29zdCA9IGN1cnJlbnRSb3cuZGF0YSgncHJvZHVjdC1jb3N0Jyk7XHJcblx0XHRcdFx0Y29uc29sZS5sb2coY29zdCk7XHJcblx0XHRcdFx0bGV0IHF1YW50aXR5ID0gY3VycmVudFJvdy52YWwoKTtcclxuXHRcdFx0XHRsZXQgaXRlbSA9IHtcclxuXHRcdFx0XHRcdENvZGU6IGNvZGUsXHJcblx0XHRcdFx0XHRRdWFudGl0eTogcXVhbnRpdHksXHJcblx0XHRcdFx0XHRDb3N0OiBjb3N0XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0XHR3aXNobGlzdExpbmVpdGVtcy5wdXNoKGl0ZW0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGlmIChXaXNobGlzdEhlYWRlci5HZXRTZWxlY3RlZFdpc2hsaXN0RGF0YSgpID09IG51bGwpIHJldHVybjtcclxuXHRcdFx0TGluZWl0ZW1IYW5kbGVyLkFkZFRvV2lzaGxpc3QoQmF0Y2hTdWNjZXNzQ2FsbGJhY2spO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0ZnVuY3Rpb24gQmF0Y2hTdWNjZXNzQ2FsbGJhY2soKSB7XHJcblx0XHRcdGlmICgkKCcuZmlsZXVwbG9hZC1tZXNzYWdlcycpLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRsZXQgdGV4dCA9IGhpYWJjb25maWcud2lzaGxpc3QuYWRkZWRJdGVtVG9XaXNobGlzdDtcclxuXHRcdFx0XHRsZXQgaHRtbCA9IFwiPHA+XCIgKyB0ZXh0ICsgXCI8L3A+XCI7XHJcblx0XHRcdFx0JCgnI2FkZC10by1jYXJ0LXN1Y2Nlc3MgLnVjLW1lc3NhZ2Uuc3VjY2VzcycpLmh0bWwoaHRtbCk7XHJcblx0XHRcdFx0JCgnI2FkZC10by1jYXJ0LXN1Y2Nlc3MnKS5zaG93KCk7XHJcblx0XHRcdFx0JCgnI3JlbW92ZS1hbGwtbGluZXMnKS5jbGljaygpO1xyXG5cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblx0QWRkVG9XaXNobGlzdChzdWNjZXNzQ2FsbGJhY2sgPSBudWxsKSB7XHJcblxyXG5cdFx0aWYgKCBpbnZva2luZ0VsZW1lbnQgPT0gbnVsbCAmJiB3aXNobGlzdExpbmVpdGVtcy5sZW5ndGggPT0gMCApIHJldHVybjtcclxuXHJcblx0XHRsZXQgdXJsID0gXCIvYXBpL3dpc2hsaXN0L0FkZExpbmVpdGVtVG9XaXNobGlzdD9wcmVmZXJyZWRDdWx0dXJlPVwiICsgaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlO1xyXG5cdFx0bGV0IGhlYWRlckJ0biA9ICQoJy51Yy13aXNobGlzdC53aXNobGlzdC1oZWFkZXIgYnV0dG9uJyk7XHJcblx0XHRsZXQgaGVhZGVyQ29udHJvbGxzQnRuID0gJCgnI3dpc2hsaXN0Q29udHJvbGxzIGJ1dHRvbicpO1xyXG5cdFx0bGV0IGhlYWRlckJ0bkh0bWwgPSBoZWFkZXJCdG4uaHRtbCgpO1xyXG5cdFx0bGV0IG5ySXRlbXNBZGRlZCA9IHdpc2hsaXN0TGluZWl0ZW1zLmxlbmd0aDtcclxuXHRcdCQoJyN3aXNobGlzdENvbnRyb2xscycpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblx0XHRtb2JpbGVXaXNobGlzdFRvZ2dsZS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdGhlYWRlckJ0bi5odG1sKFdpc2hsaXN0SGVhZGVyLkdldExvYWRTcGlubmVySHRtbCgpKTtcclxuXHRcdGhlYWRlckJ0bi5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0aGVhZGVyQnRuLmFkZENsYXNzKCdhZGRpbmcnKTtcclxuXHJcblx0XHRtb2JpbGVXaXNobGlzdFRvZ2dsZS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHRoZWFkZXJDb250cm9sbHNCdG4uYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcclxuXHRcdGludm9raW5nRWxlbWVudC5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cclxuXHRcdCQuYWpheCh7XHJcblx0XHRcdHR5cGU6IFwiUE9TVFwiLFxyXG5cdFx0XHRjb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsXHJcblx0XHRcdHVybDogdXJsLFxyXG5cdFx0XHRkYXRhOiBKU09OLnN0cmluZ2lmeSh3aXNobGlzdExpbmVpdGVtcyksXHJcblx0XHRcdGRhdGFUeXBlOiBcImpzb25cIixcclxuXHRcdFx0c3VjY2VzczogZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdFx0XHRpZiAocmVzcG9uc2UuU2VsZWN0ZWRXaXNoTGlzdCA9PSBudWxsKSB7XHJcblx0XHRcdFx0XHRoZWFkZXJCdG4uaHRtbChoZWFkZXJCdG5IdG1sKTtcclxuXHRcdFx0XHRcdCQoJy5vZmYtY2FudmFzLXdyYXAnKS5mb3VuZGF0aW9uKCdvZmZjYW52YXMnLCAnc2hvdycsICdtb3ZlLWxlZnQnKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0V2lzaGxpc3RIZWFkZXIuUmVkcmF3QWxsKHJlc3BvbnNlKTtcclxuXHRcdFx0XHRcdGxldCBodG1sID0gXCI8c3BhbiBjbGFzcz0nbGluZWl0ZW0tYWRkZWQnPlwiICsgXCIgK1wiICsgbnJJdGVtc0FkZGVkICsgXCI8L3NwYW4+XCI7XHJcblx0XHRcdFx0XHRJbmplY3Rvci5JbnNlcnRBZnRlcihodG1sLCAnLnVjLXdpc2hsaXN0Lndpc2hsaXN0LWhlYWRlciBidXR0b24gc3BhbicpO1xyXG5cdFx0XHRcdFx0JCgnI3dpc2hsaXN0Q29udHJvbGxzJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHRcdEluamVjdG9yLkluc2VydEFmdGVyKGh0bWwsICcjd2lzaGxpc3RTZWxlY3QgLnRleHQnKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoc3VjY2Vzc0NhbGxiYWNrICE9IG51bGwpIHtcclxuXHRcdFx0XHRcdFx0c3VjY2Vzc0NhbGxiYWNrKCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGludm9raW5nRWxlbWVudC5hdHRyKCdkaXNhYmxlZCcsIGZhbHNlKTtcclxuXHRcdFx0XHRpbnZva2luZ0VsZW1lbnQgPSBudWxsO1xyXG5cdFx0XHRcdHdpc2hsaXN0TGluZWl0ZW1zID0gW107XHJcblx0XHRcdH0sXHJcblx0XHRcdGVycm9yOiBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdFx0JCgnI3dpc2hsaXN0Q29udHJvbGxzJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHRoZWFkZXJCdG4uYXR0cignZGlzYWJsZWQnLCBmYWxzZSk7XHJcblx0XHRcdFx0aGVhZGVyQ29udHJvbGxzQnRuLmF0dHIoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG5cdFx0XHRcdGludm9raW5nRWxlbWVudC5hdHRyKCdkaXNhYmxlZCcsIGZhbHNlKTtcclxuXHJcblx0XHRcdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUuYXR0cignZGlzYWJsZWQnLCBmYWxzZSk7XHJcblx0XHRcdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHRcdFx0aW52b2tpbmdFbGVtZW50ID0gbnVsbDtcclxuXHRcdFx0XHR3aXNobGlzdExpbmVpdGVtcyA9IFtdO1xyXG5cclxuXHRcdFx0XHRsZXQgZXJyb3JIdG1sID0gXCI8c3Bhbj5cIiArIGhpYWJjb25maWcud2lzaGxpc3QuYWRkSXRlbUVycm9yICsgXCI8L3NwYW4+XCI7XHJcblx0XHRcdFx0JCgnLnJpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJykudHJpZ2dlcignY2xpY2snKTtcclxuXHRcdFx0XHRJbmplY3Rvci5JbnNlcnRBZnRlcihlcnJvckh0bWwsICcjd2lzaGxpc3RTZWxlY3QnKTtcclxuXHRcdFx0XHRjb25zb2xlLmxvZyhcImNvdWxkIG5vdCBhZGQgbGluZWl0ZW0gdG8gd2lzaGxpc3RcIik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgTGluZWl0ZW1IYW5kbGVyO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgV2lzaGxpc3RIZWFkZXIgZnJvbSAnLi93aXNobGlzdEhlYWRlcic7XHJcbmltcG9ydCBJbmplY3RvciBmcm9tICcuLy4uLy4uL25vdGlmaWNhdGlvbnMvbWVzc2FnZUluamVjdG9yJztcclxuaW1wb3J0IFVybEhhbmRsZXIgZnJvbSAnLi8uLi9taXNjZWxsYW5lb3VzL3VybEhhbmRsZXInO1xyXG5pbXBvcnQgZm91bmRhdGlvbiBmcm9tICcuLy4uLy4uL3ZlbmRvcnMvZm91bmRhdGlvbic7XHJcblxyXG5sZXQgY3VycmVudFdpc2hsaXN0SUQgPSBudWxsO1xyXG5sZXQgY3VycmVudFZhbHVlID0gbnVsbDtcclxubGV0IGlucHV0VGltZXI7XHJcbmxldCBkZWZhdWx0VGltZXJEZWxheSA9IDMwMDA7XHJcbmxldCBpc0VkaXRpbmdDYXJ0ID0gZmFsc2U7XHJcblxyXG5sZXQgV2lzaGxpc3REZXRhaWxzID0ge1xyXG5cclxuICAgIC8vZGlzYWJsZXMgdWkgY29udHJvbHNcclxuICAgIERpc2FibGVVSUNvbnRyb2xzKCkge1xyXG4gICAgICAgICQoJy51aS1jb250cm9sJykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgIH0sXHJcblxyXG5cdGlzSW50KHZhbHVlKSB7XHJcblx0dmFyIHg7XHJcblx0XHR2YXIgaXNJbnQgPSBpc05hTih2YWx1ZSkgPyAhMSA6ICh4ID0gcGFyc2VGbG9hdCh2YWx1ZSksICgwIHwgeCkgPT09IHgpO1xyXG5cdFx0aWYoaXNJbnQpe1xyXG5cdFx0XHRyZXR1cm4gdmFsdWUgPCAxICYmIHZhbHVlLmxlbmd0aCA9PT0gMSA/IGZhbHNlIDogdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcbiAgICAvL2VuYWJsZXMgdWkgY29udHJvbHNcclxuICAgIEVuYWJsZVVJQ29udHJvbHMoKSB7XHJcbiAgICAgICAgJCgnLnVpLWNvbnRyb2wnKS5hdHRyKCdkaXNhYmxlZCcsIGZhbHNlKTtcclxuICAgICAgICBsZXQgaGFzTGluZUl0ZW1zID0gJCgnI3NhdmVkLWNhcnQgdGJvZHknKS5odG1sKCkubGVuZ3RoID4gMDtcclxuICAgICAgICBpZighaGFzTGluZUl0ZW1zKSB7XHJcbiAgICAgICAgICAgICQoJ2J1dHRvbi5wdXJjaGFzZScpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICQoJ2J1dHRvbi5wcmludCcpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvdW5kYXRpb24uaW5pdCgpO1xyXG4gICAgICAgICQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ2FiaWRlJywgJ3JlZmxvdycpO1xyXG5cclxuXHRcdFx0XHRpZigkKCcudWMtd2lzaGxpc3QudWMtY2hlY2tvdXQtY2FydCAudWMtdGFibGUgdGJvZHknKS5jaGlsZHJlbigpLmxlbmd0aCA+IDIxKXtcclxuXHRcdFx0XHRcdCQoJy51Yy13aXNobGlzdC51Yy1jaGVja291dC1jYXJ0IC51Yy10YWJsZScpLmFkZENsYXNzKCdoYXMtbW9yZScpO1xyXG5cdFx0XHRcdFx0aWYoaXNFZGl0aW5nQ2FydCl7XHJcblx0XHRcdFx0XHRcdCQoJy51Yy13aXNobGlzdC51Yy1jaGVja291dC1jYXJ0IC51Yy10YWJsZScpLmFkZENsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHQkKCcudWMtd2lzaGxpc3QudWMtY2hlY2tvdXQtY2FydCAudWMtdGFibGUnKS5yZW1vdmVDbGFzcygnaGFzLW1vcmUnKTtcclxuXHRcdFx0XHR9XHJcbiAgICB9LFxyXG5cclxuICAgIFJlZHJhd0J1dHRvbnMoKSB7XHJcbiAgICAgICAgbGV0IHVybCA9IFwiR2V0QnV0dG9uc1BhcnRpYWw/aWQ9XCIgKyBjdXJyZW50V2lzaGxpc3RJRCAgKyAnJnByZWZlcnJlZEN1bHR1cmU9JyArIGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZTtcclxuICAgICAgICAkKCcud2lzaGxpc3QtZGV0YWlsIC5idXR0b24tZ3JvdXAnKS5sb2FkKHVybCk7XHJcbiAgICB9LFxyXG5cclxuICAgIFNlbGVjdFdpc2hsaXN0KGV2KSB7XHJcbiAgICAgICAgV2lzaGxpc3REZXRhaWxzLkRpc2FibGVVSUNvbnRyb2xzKCk7XHJcblxyXG4gICAgICAgIGxldCBodG1sQ29udGFpbmVyID0gJChldi5jdXJyZW50VGFyZ2V0KS5wYXJlbnRzKCdzZWN0aW9uJyk7XHJcbiAgICAgICAgbGV0IGRhdGEgPSB7cHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlfTtcclxuICAgICAgICBsZXQgdXJsID0gXCJTZWxlY3RXaXNobGlzdD9pZD1cIiArIGN1cnJlbnRXaXNobGlzdElEO1xyXG4gICAgICAgIGh0bWxDb250YWluZXIubG9hZCh1cmwsIGRhdGEsICgpID0+IHtcclxuICAgICAgICAgICAgV2lzaGxpc3REZXRhaWxzLkVuYWJsZVVJQ29udHJvbHMoKTtcclxuICAgICAgICAgICAgV2lzaGxpc3RIZWFkZXIuTG9hZFdpc2hsaXN0SW5mbygpO1xyXG4gICAgICAgICAgICAkKCcud2lzaGxpc3QtZGV0YWlsIGJ1dHRvbi5zZWxlY3QnKS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICAvL3JlZHJhdyBpbnB1dCBmaWVsZHNcclxuICAgIFJlZHJhd0lucHV0RmllbGRzKCkge1xyXG4gICAgICAgIGxldCB1cmwgPSBcIlJlZHJhd0lucHV0RmllbGRzP2lkPVwiICsgY3VycmVudFdpc2hsaXN0SUQgICsgJyZwcmVmZXJyZWRDdWx0dXJlPScgKyBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmU7XHJcbiAgICAgICAgJCgnLndpc2hsaXN0LWRldGFpbCAjQ2FydEZvcm1OYW1lJykubG9hZCh1cmwsIG51bGwsICgpID0+IHsgfSk7XHJcblx0fSxcclxuXHRcclxuXHQvL3VwZGF0ZXMgaW5mbyBwYXJ0aWFsIGZyb20gc2VydmVyXHJcblx0VXBkYXRlQWRkaXRpb25hbEluZm8oKSB7XHJcblx0XHRsZXQgdXJsID0gXCJHZXRBZGRpdGlvbmFsSW5mb1BhcnRpYWw/aWQ9XCIgKyBjdXJyZW50V2lzaGxpc3RJRCAgKyAnJnByZWZlcnJlZEN1bHR1cmU9JyArIGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZTtcclxuXHRcdCQoJy53aXNobGlzdC1kZXRhaWwgLmluZm9ybWF0aW9uLWZvcm0gZGl2LmFkZGl0aW9uYWwnKS5sb2FkKHVybCwgbnVsbCwgKCkgPT4ge1xyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0R2V0V2lzaGxpc3RMaW5laXRlbUJ5SUQoaWQpIHtcclxuXHRcdGxldCBpdGVtID0gJCgnLnVjLXRhYmxlIHRib2R5IHRyJykuZmlsdGVyKGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXR1cm4gJCh0aGlzKS5kYXRhKCdsaW5lLWlkJykgPT0gaWQ7XHJcblx0XHR9KTtcclxuXHRcdC8vIGNvbnNvbGUubG9nKGl0ZW0pO1xyXG5cdFx0cmV0dXJuIGl0ZW07XHJcblx0fSxcclxuXHJcblx0SGFuZGxlSW5wdXRDaGFuZ2UodmFsdWUsIHR5cGUsIGlkKSB7XHJcblx0XHRpZighY3VycmVudFZhbHVlKSByZXR1cm47XHJcblxyXG5cdFx0Y2xlYXJUaW1lb3V0KGlucHV0VGltZXIpO1xyXG5cdFx0Y3VycmVudFZhbHVlID0gbnVsbDtcclxuXHJcblx0XHRpZih0eXBlID09ICdxdWFudGl0eScpIHtcclxuXHRcdFx0V2lzaGxpc3REZXRhaWxzLkRpc2FibGVVSUNvbnRyb2xzKCk7XHJcblx0XHRcdGxldCB1cmwgPSBcIlVwZGF0ZUxpbmVpdGVtP2lkPVwiICsgY3VycmVudFdpc2hsaXN0SURcclxuXHRcdFx0bGV0IGxpbmVpdGVtID0gdGhpcy5HZXRXaXNobGlzdExpbmVpdGVtQnlJRChpZCk7XHJcblx0XHRcdGxldCBpdGVtUHJpY2UgPSAkKGxpbmVpdGVtKS5maW5kKCdpbnB1dCcpLmRhdGEoJ3Byb2R1Y3QtY29zdCcpO1xyXG5cdFx0XHRsZXQgZGF0YSA9IHsgaWQ6aWQsIHF1YW50aXR5OnZhbHVlLCBwcmljZTppdGVtUHJpY2UsIHByZWZlcnJlZEN1bHR1cmU6aGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlIH07XHJcblxyXG5cdFx0XHQkLmFqYXgoe1xyXG5cdFx0XHRcdHR5cGU6IFwiUE9TVFwiLFxyXG5cdFx0XHRcdHVybDogdXJsLFxyXG5cdFx0XHRcdGRhdGE6IGRhdGEsXHJcblx0XHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcclxuXHRcdFx0XHRzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcclxuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcclxuXHRcdFx0XHRcdGxpbmVpdGVtLmZpbmQoJy5pdGVtLXRvdGFsJykuaHRtbChyZXNwb25zZS5Ub3RhbCk7XHJcblx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuVXBkYXRlQWRkaXRpb25hbEluZm8oKTtcclxuXHRcdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5FbmFibGVVSUNvbnRyb2xzKCk7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHRlcnJvcjogZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLlVwZGF0ZUFkZGl0aW9uYWxJbmZvKCk7XHJcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhcImNvdWxkIG5vdCB1cGRhdGUgbGluZSBpdGVtXCIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYodHlwZSA9PSAnY2FydE5hbWUnKSB7XHJcblx0XHRcdFdpc2hsaXN0RGV0YWlscy5EaXNhYmxlVUlDb250cm9scygpO1xyXG5cdFx0XHRsZXQgdXJsID0gXCJTYXZlTmFtZT9pZD1cIiArIGN1cnJlbnRXaXNobGlzdElEO1xyXG5cdFx0XHRsZXQgZGF0YSA9IHsgaW5wdXQgOiB2YWx1ZSwgcHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlfTtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWRldGFpbCAjQ2FydEZvcm1OYW1lJykubG9hZCh1cmwsIGRhdGEsICgpID0+IHtcclxuXHRcdFx0XHRXaXNobGlzdEhlYWRlci5Mb2FkV2lzaGxpc3RJbmZvKCk7XHJcblx0XHRcdFx0bGV0IGh0bWwgPSBcIjxzcGFuPlwiICsgaGlhYmNvbmZpZy53aXNobGlzdC5zYXZlZFVwZGF0ZVdpc2hsaXN0ICsgXCI8L3NwYW4+XCI7XHJcblx0XHRcdFx0SW5qZWN0b3IuSW5zZXJ0QWZ0ZXIoaHRtbCwgJ2lucHV0W25hbWU9XCJOZXdDYXJ0Lk5hbWVcIl0nKTtcclxuXHRcdFx0XHRXaXNobGlzdERldGFpbHMuVXBkYXRlQWRkaXRpb25hbEluZm8oKTtcclxuXHRcdFx0XHRXaXNobGlzdERldGFpbHMuRW5hYmxlVUlDb250cm9scygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0XHRpZih0eXBlID09ICdjYXJ0RGVzYycpIHtcclxuXHRcdFx0V2lzaGxpc3REZXRhaWxzLkRpc2FibGVVSUNvbnRyb2xzKCk7XHJcblx0XHRcdGxldCB1cmwgPSBcIlNhdmVEZXNjcmlwdGlvbj9pZD1cIiArIGN1cnJlbnRXaXNobGlzdElEO1xyXG5cdFx0XHRsZXQgZGF0YSA9IHsgaW5wdXQgOiB2YWx1ZSwgcHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlfTtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWRldGFpbCAjQ2FydEZvcm1OYW1lJykubG9hZCh1cmwsIGRhdGEsICgpID0+IHtcclxuXHRcdFx0XHRcdFdpc2hsaXN0SGVhZGVyLkxvYWRXaXNobGlzdEluZm8oKTtcclxuXHRcdFx0XHRcdGxldCBodG1sID0gXCI8c3Bhbj5cIiArIGhpYWJjb25maWcud2lzaGxpc3Quc2F2ZWRVcGRhdGVXaXNobGlzdCArIFwiPC9zcGFuPlwiO1xyXG5cdFx0XHRcdFx0SW5qZWN0b3IuSW5zZXJ0QWZ0ZXIoaHRtbCwgJ2lucHV0W25hbWU9XCJOZXdDYXJ0LkRlc2NcIl0nKTtcclxuXHRcdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5VcGRhdGVBZGRpdGlvbmFsSW5mbygpO1xyXG5cdFx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLkVuYWJsZVVJQ29udHJvbHMoKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdH0sXHJcblxyXG4gICAgaW5pdCgpIHtcclxuICAgICAgICBpZigkKCcudWMtd2lzaGxpc3QudWMtY2hlY2tvdXQtY2FydCAudWMtdGFibGUgdGJvZHknKS5jaGlsZHJlbigpLmxlbmd0aCA+IDIxKSB7XHJcblx0XHRcdCQoJy51Yy13aXNobGlzdC51Yy1jaGVja291dC1jYXJ0IC51Yy10YWJsZScpLmFkZENsYXNzKCdoYXMtbW9yZScpO1xyXG5cdFx0fVxyXG5cdFx0bGV0IHB1cmNoYXNlQnRuID0gJCgnLnVjLXdpc2hsaXN0Lndpc2hsaXN0LWRldGFpbCAuYnV0dG9uLWdyb3VwIGJ1dHRvbi5wdXJjaGFzZScpO1xyXG5cdFx0cHVyY2hhc2VCdG4ucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcbiAgICAgICAgLy9hZGRzIGJ0bnMgdG8gY29uZmlybSBvciBjYW5jZWwgY2FydCBkZWxldGVcclxuICAgICAgICBmdW5jdGlvbiBJbmplY3RPa0NhbmNlbEJ1dHRvbnMoKSB7XHJcbiAgICAgICAgICAgIGxldCBva0J0biA9IFwiPGJ1dHRvbiBjbGFzcz0nb2sgcmlnaHQgc21sJz5cIiArIGhpYWJjb25maWcud2lzaGxpc3QuYnRuVGV4dE9rICsgXCI8L2J1dHRvbj5cIjtcclxuICAgICAgICAgICAgbGV0IGNhbmNlbEJ0biA9IFwiPGJ1dHRvbiBjbGFzcz0nY2FuY2VsIHJpZ2h0IHNtbCcgbmFtZT0nV2lzaGxpc3QuQ2FuY2VsJz5cIiArIGhpYWJjb25maWcud2lzaGxpc3QuYnRuVGV4dENhbmNlbCArIFwiPC9idXR0b24+XCI7XHJcbiAgICAgICAgICAgIGxldCBkZWxldGVCdG4gPSAkKCdidXR0b24uZGVsZXRlJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAkKG9rQnRuKS5pbnNlcnRBZnRlcihkZWxldGVCdG4pO1xyXG4gICAgICAgICAgICAkKGNhbmNlbEJ0bikuaW5zZXJ0QWZ0ZXIoZGVsZXRlQnRuKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvL2hhbmRsZXMgcHVyY2hhc2UgYnRuIGNsaWNrXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oJ2NsaWNrJywgJ2J1dHRvbi5wdXJjaGFzZScsICgpID0+IHtcclxuXHRcdFx0bGV0IGJ0biA9ICQoJy51Yy13aXNobGlzdC53aXNobGlzdC1kZXRhaWwgLmJ1dHRvbi1ncm91cCBidXR0b24ucHVyY2hhc2UnKTtcclxuXHRcdFx0YnRuLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblxyXG4gICAgICAgICAgICBXaXNobGlzdERldGFpbHMuRGlzYWJsZVVJQ29udHJvbHMoKTtcclxuICAgICAgICAgICAgbGV0IHVybCA9IFwiUHVyY2hhc2VXaXNobGlzdD9pZD1cIiArIGN1cnJlbnRXaXNobGlzdElEO1xyXG5cdFx0XHRsZXQgZGF0YSA9IHsgcHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlIH07XHJcblxyXG4gICAgICAgICAgICAkLmFqYXgoe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogXCJQT1NUXCIsXHJcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcclxuXHRcdFx0XHRkYXRhOiBkYXRhLFxyXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcclxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xyXG5cdFx0XHRcdFx0YnRuLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSByZXNwb25zZS5Vcmw7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBXaXNobGlzdERldGFpbHMuRW5hYmxlVUlDb250cm9scygpO1xyXG5cdFx0XHRcdFx0YnRuLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvL2hhbmRsZXMgc2VsZWN0IGJ0biBjbGlja1xyXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICdidXR0b24uc2VsZWN0JywgKGV2KSA9PiB7XHJcbiAgICAgICAgICAgIFdpc2hsaXN0RGV0YWlscy5TZWxlY3RXaXNobGlzdChldik7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vaGFuZGxlcyBkZWxldGUgb2sgYnRuIGNsaWNrXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53aXNobGlzdC1kZXRhaWwgYnV0dG9uLm9rJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBXaXNobGlzdERldGFpbHMuRGlzYWJsZVVJQ29udHJvbHMoKTtcclxuXHJcbiAgICAgICAgICAgIGxldCB1cmwgPSBcIkRlbGV0ZVdpc2hsaXN0P2lkPVwiICsgY3VycmVudFdpc2hsaXN0SUQ7XHJcblx0XHRcdGxldCBkYXRhID0geyBwcmVmZXJyZWRDdWx0dXJlOiBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmUgfTtcclxuXHRcdFx0XHJcbiAgICAgICAgICAgICQuYWpheCh7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcIlBPU1RcIixcclxuICAgICAgICAgICAgICAgIHVybDogdXJsLFxyXG5cdFx0XHRcdGRhdGE6IGRhdGEsXHJcbiAgICAgICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxyXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSByZXNwb25zZS5Vcmw7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBXaXNobGlzdERldGFpbHMuRW5hYmxlVUlDb250cm9scygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy9oYW5kbGVzIGRlbGV0ZSBjYW5jZWwgYnRuIGNsaWNrXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oJ2NsaWNrJywgJ2J1dHRvbltuYW1lPVwiV2lzaGxpc3QuQ2FuY2VsXCJdJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBXaXNobGlzdERldGFpbHMuUmVkcmF3QnV0dG9ucygpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvL2hhbmRsZXMgZGVsZXRlIGJ0biBjbGlja1xyXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICdidXR0b24uZGVsZXRlJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBJbmplY3RPa0NhbmNlbEJ1dHRvbnMoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy9hdXRvIHNhdmUgbmFtZSB3aGVuIHVwZGF0ZWRcclxuICAgICAgICAkKGRvY3VtZW50KS5vbignZm9jdXMgYmx1ciBrZXlwcmVzcycsICdpbnB1dFtuYW1lPVwiTmV3Q2FydC5OYW1lXCJdJywgKGUpID0+IHtcclxuXHRcdFx0bGV0IGVsID0gJChlLmN1cnJlbnRUYXJnZXQpO1xyXG5cdFx0XHRsZXQgaW5wdXRUZXh0ID0gZWwudmFsKCk7XHJcblxyXG5cdFx0XHRpZihpbnB1dFRleHQubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRcdGlmKHR5cGVvZiBpbnB1dFRpbWVyICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcblx0XHRcdFx0XHRcdGNsZWFyVGltZW91dChpbnB1dFRpbWVyKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmKGUudHlwZSA9PT0gJ2ZvY3VzaW4nKXtcclxuXHRcdFx0XHRcdGN1cnJlbnRWYWx1ZSA9IGlucHV0VGV4dDtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmKGUudHlwZSA9PT0gJ2ZvY3Vzb3V0JyAgJiYgY3VycmVudFZhbHVlICE9IGlucHV0VGV4dCl7XHJcblx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuSGFuZGxlSW5wdXRDaGFuZ2UoaW5wdXRUZXh0LCdjYXJ0TmFtZScpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0aWYoZS50eXBlID09PSAna2V5cHJlc3MnICYmIGUud2hpY2ggPT09IDEzICYmIGN1cnJlbnRWYWx1ZSAmJiBjdXJyZW50VmFsdWUgIT0gaW5wdXRUZXh0KSB7XHJcblx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuSGFuZGxlSW5wdXRDaGFuZ2UoaW5wdXRUZXh0LCdjYXJ0TmFtZScpO1xyXG5cdFx0XHRcdH1cclxuXHJcbiAgICAgICAgICAgIFx0aWYoZS50eXBlID09PSAna2V5cHJlc3MnICYmIGN1cnJlbnRWYWx1ZSAhPSBpbnB1dFRleHQpe1xyXG5cdFx0XHRcdFx0aW5wdXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuSGFuZGxlSW5wdXRDaGFuZ2UoJChlLmN1cnJlbnRUYXJnZXQpLnZhbCgpLCdjYXJ0TmFtZScpO1xyXG5cdFx0XHRcdFx0fSwgZGVmYXVsdFRpbWVyRGVsYXkpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oJ2ZvY3VzIGJsdXIga2V5cHJlc3MnLCAnaW5wdXRbbmFtZT1cIk5ld0NhcnQuRGVzY1wiXScsIChlKSA9PiB7XHJcblx0XHRcdGxldCBlbCA9ICQoZS5jdXJyZW50VGFyZ2V0KTtcclxuXHRcdFx0bGV0IGlucHV0VGV4dCA9IGVsLnZhbCgpO1xyXG5cdFx0XHRpZih0eXBlb2YgaW5wdXRUaW1lciAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG5cdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KGlucHV0VGltZXIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZihlLnR5cGUgPT09ICdmb2N1c2luJyl7XHJcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRUZXh0O1xyXG5cdFx0XHRcdGlmKGlucHV0VGV4dC5sZW5ndGggPT0gMCkge1xyXG5cdFx0XHRcdFx0Y3VycmVudFZhbHVlID0gXCIgXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZihlLnR5cGUgPT09ICdmb2N1c291dCcgICYmIGN1cnJlbnRWYWx1ZSAhPSBpbnB1dFRleHQpe1xyXG5cdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5IYW5kbGVJbnB1dENoYW5nZShpbnB1dFRleHQsJ2NhcnREZXNjJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYoZS50eXBlID09PSAna2V5cHJlc3MnICYmIGUud2hpY2ggPT09IDEzICYmIGN1cnJlbnRWYWx1ZSAmJiBjdXJyZW50VmFsdWUgIT0gaW5wdXRUZXh0KSB7XHJcblx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLkhhbmRsZUlucHV0Q2hhbmdlKGlucHV0VGV4dCwnY2FydERlc2MnKTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0aWYoZS50eXBlID09PSAna2V5cHJlc3MnICYmIGN1cnJlbnRWYWx1ZSAhPSBpbnB1dFRleHQpe1xyXG5cdFx0XHRcdGlucHV0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5IYW5kbGVJbnB1dENoYW5nZSgkKGUuY3VycmVudFRhcmdldCkudmFsKCksJ2NhcnREZXNjJyk7XHJcblx0XHRcdFx0fSwgZGVmYXVsdFRpbWVyRGVsYXkpO1xyXG5cdFx0XHR9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdmb2N1cyBibHVyIGtleXByZXNzIGVudGVyS2V5JywgJy51Yy1jaGVja291dC1jYXJ0LnVjLXdpc2hsaXN0IGlucHV0W25hbWU9XCJxdWFudGl0eVwiXScsIChlKSA9PiB7XHJcblx0XHRcdGxldCBlbCA9ICQoZS5jdXJyZW50VGFyZ2V0KTtcclxuXHRcdFx0bGV0IGlucHV0VGV4dCA9IGVsLnZhbCgpO1xyXG5cdFx0XHRsZXQgaWQgPSBlbC5kYXRhKCdza3UtaWQnKTtcclxuXHRcdFx0aXNFZGl0aW5nQ2FydCA9IHRydWU7XHJcblxyXG5cdFx0XHRpZihXaXNobGlzdERldGFpbHMuaXNJbnQoaW5wdXRUZXh0KSl7XHJcblx0XHRcdFx0aWYodHlwZW9mIGlucHV0VGltZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuXHRcdFx0XHRcdGNsZWFyVGltZW91dChpbnB1dFRpbWVyKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYoZS50eXBlID09PSAnZm9jdXNpbicpe1xyXG5cdFx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRUZXh0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihlLnR5cGUgPT09ICdmb2N1c291dCcgICYmIGN1cnJlbnRWYWx1ZSAhPSBpbnB1dFRleHQpe1xyXG5cdFx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuSGFuZGxlSW5wdXRDaGFuZ2UoaW5wdXRUZXh0LCdxdWFudGl0eScsaWQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihlLnR5cGUgPT09ICdrZXlwcmVzcycgJiYgZS53aGljaCA9PT0gMTMgJiYgY3VycmVudFZhbHVlICYmIGN1cnJlbnRWYWx1ZSAhPSBpbnB1dFRleHQpIHtcclxuXHRcdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5IYW5kbGVJbnB1dENoYW5nZShpbnB1dFRleHQsJ3F1YW50aXR5JyxpZCk7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG4gICAgICAgICAgICBcdGlmKGUudHlwZSA9PT0gJ2tleXByZXNzJyAmJiBjdXJyZW50VmFsdWUgIT0gaW5wdXRUZXh0KXtcclxuXHRcdFx0XHRcdGlucHV0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLkhhbmRsZUlucHV0Q2hhbmdlKCQoZS5jdXJyZW50VGFyZ2V0KS52YWwoKSwncXVhbnRpdHknLGlkKTtcclxuXHRcdFx0XHRcdH0sIGRlZmF1bHRUaW1lckRlbGF5KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy9oYW5kbGUgZGVsZXRlIGJ0biBjbGljayBvbiBsaW5laXRlbVxyXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICdidXR0b24ucmVtb3ZlLWJ1dHRvbicsIChlKSA9PiB7XHJcbiAgICAgICAgICAgIFdpc2hsaXN0RGV0YWlscy5EaXNhYmxlVUlDb250cm9scygpO1xyXG5cclxuXHRcdFx0bGV0IGVsID0gJChlLmN1cnJlbnRUYXJnZXQpO1xyXG4gICAgICAgICAgICBsZXQgaWQgPSBlbC5kYXRhKCdza3UtaWQnKTtcclxuICAgICAgICAgICAgbGV0IHVybCA9IFwiRGVsZXRlTGluZWl0ZW0/aWQ9XCIgKyBjdXJyZW50V2lzaGxpc3RJRFxyXG4gICAgICAgICAgICBsZXQgZGF0YSA9IHsgaWQgOiBpZCwgcHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlIH07XHJcblx0XHRcdGlzRWRpdGluZ0NhcnQgPSB0cnVlO1xyXG5cclxuXHRcdFx0JC5hamF4KHtcclxuXHRcdFx0XHR0eXBlOiBcIlBPU1RcIixcclxuXHRcdFx0XHR1cmw6IHVybCxcclxuXHRcdFx0XHRkYXRhOiBkYXRhLFxyXG5cdFx0XHRcdGRhdGFUeXBlOiAnanNvbicsXHJcblx0XHRcdFx0c3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XHJcblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyhyZXNwb25zZSk7XHJcblx0XHRcdFx0XHRsZXQgbGluZWl0ZW1Sb3cgPSBlbC5wYXJlbnRzKCd0cicpO1xyXG5cdFx0XHRcdFx0Ly9nZXQgdmFyaWFudCBodG1sLi5cclxuXHRcdFx0XHRcdGlmKGxpbmVpdGVtUm93Lmhhc0NsYXNzKCd0YWJsZS1zdWItZGF0YScpKSB7XHJcblx0XHRcdFx0XHRcdGxpbmVpdGVtUm93LnByZXYoKS5yZW1vdmUoKTsvL3JlbW92ZXMgZGVza3RvcCBodG1sXHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZihsaW5laXRlbVJvdy5oYXNDbGFzcygnbGluZWl0ZW0nKSkge1xyXG5cdFx0XHRcdFx0XHRsaW5laXRlbVJvdy5uZXh0KCkucmVtb3ZlKCk7Ly9yZW1vdmVzIG1vYmlsZSBodG1sXHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRsaW5laXRlbVJvdy5yZW1vdmUoKTtcclxuXHRcdFx0XHRcdGxldCBpdGVtQ291bnQgPSAkKCcjc2F2ZWQtY2FydCB0ci5saW5laXRlbScpLmxlbmd0aDtcclxuXHRcdFx0XHRcdCQoJy53aXNobGlzdC1kZXRhaWwgLmxpbmVpdGVtcyBzcGFuOmZpcnN0LW9mLXR5cGUnKS5odG1sKGl0ZW1Db3VudCk7XHJcblx0XHRcdFx0XHRVcGRhdGVMaW5laXRlbVJvd0NvdW50KCk7XHJcblxyXG5cdFx0XHRcdFx0V2lzaGxpc3RIZWFkZXIuTG9hZFdpc2hsaXN0SW5mbygpO1xyXG5cdFx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLlVwZGF0ZUFkZGl0aW9uYWxJbmZvKCk7XHJcblx0XHRcdFx0XHRXaXNobGlzdERldGFpbHMuRW5hYmxlVUlDb250cm9scygpO1xyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0ZXJyb3I6IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFdpc2hsaXN0RGV0YWlscy5VcGRhdGVBZGRpdGlvbmFsSW5mbygpO1xyXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXCJjb3VsZCBub3QgcmVtb3ZlIGxpbmUgaXRlbVwiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0XHRcclxuXHRcdGZ1bmN0aW9uIFVwZGF0ZUxpbmVpdGVtUm93Q291bnQoKSB7XHJcblx0XHRcdGxldCByb3dzID0gJCgnI3NhdmVkLWNhcnQgdHIubGluZWl0ZW0gdGQ6Zmlyc3Qtb2YtdHlwZSBzcGFuJyk7XHJcblx0XHRcdGxldCByb3dzTW9iaWxlID0gJCgnI3NhdmVkLWNhcnQgdHIudGFibGUtc3ViLWRhdGEgdGQ6Zmlyc3Qtb2YtdHlwZSBzcGFuJyk7XHJcblx0XHRcdGxldCByb3dDb3VudCA9IDE7XHJcblx0XHRcdHJvd3MuZWFjaChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHQkKHRoaXMpLmh0bWwocm93Q291bnQpO1xyXG5cdFx0XHRcdHJvd0NvdW50ICs9IDE7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRyb3dDb3VudCA9IDE7XHJcblx0XHRcdHJvd3NNb2JpbGUuZWFjaChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHQkKHRoaXMpLmh0bWwocm93Q291bnQpO1xyXG5cdFx0XHRcdHJvd0NvdW50ICs9IDE7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuICAgICAgICAvL2dldCB3aXNobGlzdCBpZCBmcm9tIHVybCBvbiBwYWdlIGxvYWRcclxuICAgICAgICAkKCgpID0+IHtcclxuICAgICAgICAgICAgY3VycmVudFdpc2hsaXN0SUQgPSBVcmxIYW5kbGVyLkdldFBhcmFtZXRlckJ5U3RyaW5nKFwiaWRcIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBXaXNobGlzdERldGFpbHM7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBmb3VuZGF0aW9uIGZyb20gJy4vLi4vLi4vdmVuZG9ycy9mb3VuZGF0aW9uJztcclxuaW1wb3J0IExpbmVpdGVtSGFuZGxlciBmcm9tICcuL2xpbmVpdGVtSGFuZGxlcic7XHJcbmltcG9ydCBJbmplY3RvciBmcm9tICcuLy4uLy4uL25vdGlmaWNhdGlvbnMvbWVzc2FnZUluamVjdG9yJztcclxuaW1wb3J0IFdpc2hsaXN0RGV0YWlscyBmcm9tICcuL3dpc2hsaXN0RGV0YWlsJztcclxuaW1wb3J0IFdpc2hsaXN0TGlzdGluZyBmcm9tICcuL3dpc2hsaXN0TGlzdGluZyc7XHJcblxyXG5sZXQgc2VsZWN0ZWRXaXNobGlzdERhdGEgPSBudWxsO1xyXG5sZXQgbW9iaWxlV2lzaGxpc3RUb2dnbGUgPSAkKCcuc2hvdy1mb3ItbWVkaXVtLWRvd24gLndpc2hsaXN0LXRvZ2dsZScpO1xyXG5cclxubGV0IFdpc2hsaXN0SGVhZGVyID0ge1xyXG5cdEdldFNlbGVjdGVkV2lzaGxpc3REYXRhKCkge1xyXG5cdFx0cmV0dXJuIHNlbGVjdGVkV2lzaGxpc3REYXRhO1xyXG5cdH0sXHJcblxyXG5cdEdldExvYWRTcGlubmVySHRtbCgpIHtcclxuXHRcdHJldHVybiBcIjxpIGNsYXNzPSdhbmltYXRlLXNwaW4gaWNvbi1zcGluNCc+PC9pPlwiO1xyXG5cdH0sXHJcblxyXG5cdC8vcmVsb2FkcyBodG1sXHJcblx0UmVkcmF3QWxsKHJlc3BvbnNlKSB7XHJcblxyXG5cdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUuYXR0cignZGlzYWJsZWQnLCBmYWxzZSk7XHJcblx0XHRtb2JpbGVXaXNobGlzdFRvZ2dsZS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cclxuXHRcdFdpc2hsaXN0SGVhZGVyLkhhbmRsZUhlYWRlckluZm8ocmVzcG9uc2UpO1xyXG5cdFx0JCgnLmRyYXdlci1yaWdodCAudWMtd2lzaGxpc3QnKS5odG1sKHJlc3BvbnNlLk9mZkNhbnZhcyk7XHJcblx0XHRXaXNobGlzdEhlYWRlci5TZXR1cFdpc2hsaXN0RHJvcGRvd24oKTtcclxuXHRcdGZvdW5kYXRpb24uaW5pdCgpO1xyXG5cdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbignYWJpZGUnLCAncmVmbG93Jyk7XHJcblx0fSxcclxuXHJcblx0Ly9vdXRwdXRzIHNlbGVjdGVkIHdpc2hsaXN0IGluZm8gaW4gaGVhZGVyIGNvbnRyb2xzXHJcblx0SGFuZGxlSGVhZGVySW5mbyhyZXNwb25zZSkge1xyXG5cdFx0JCgnLnVjLXdpc2hsaXN0Lndpc2hsaXN0LWhlYWRlci5zaG93LWZvci1sYXJnZS11cCcpLnJlcGxhY2VXaXRoKHJlc3BvbnNlLkhlYWRlckJ1dHRvbkxhcmdlVXApO1xyXG5cdFx0JCgnLnVjLXdpc2hsaXN0Lndpc2hsaXN0LWhlYWRlci5zaG93LWZvci1tZWRpdW0tdXAnKS5yZXBsYWNlV2l0aChyZXNwb25zZS5IZWFkZXJCdXR0b25NZWRpdW1VcCk7XHJcblx0XHQkKCcudWMtd2lzaGxpc3Qud2lzaGxpc3QtaGVhZGVyLnNob3ctZm9yLXNtYWxsLW9ubHknKS5yZXBsYWNlV2l0aChyZXNwb25zZS5IZWFkZXJCdXR0b25TbWFsbE9ubHkpO1xyXG5cclxuXHRcdGxldCBzZWxlY3RlZENhcnRJbmZvID0gcmVzcG9uc2UuU2VsZWN0ZWRXaXNoTGlzdDtcclxuXHRcdGlmKHNlbGVjdGVkQ2FydEluZm8gIT0gbnVsbCAmJiBzZWxlY3RlZENhcnRJbmZvLk5hbWUubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRsZXQgc2VsZWN0ZWRDYXJ0VGV4dCA9IHNlbGVjdGVkQ2FydEluZm8uTmFtZSArIFwiIC0gXCIgKyBzZWxlY3RlZENhcnRJbmZvLkxpbmVJdGVtcy5sZW5ndGggKyBcIiBcIiArIGhpYWJjb25maWcud2lzaGxpc3QubnJMaW5laXRlbXM7XHJcblx0XHRcdGxldCBuZXdIdG1sID0gXCI8c3Bhbj5cIiArIHNlbGVjdGVkQ2FydFRleHQgKyBcIjwvc3Bhbj5cIjtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWhlYWRlci5zdGlja3knKS5odG1sKG5ld0h0bWwpO1xyXG5cdFx0XHQkKCcud2lzaGxpc3QtaGVhZGVyLnN0aWNreScpLnJlbW92ZUNsYXNzKCd3aXNobGlzdC1lbXB0eScpLmFkZENsYXNzKCd3aXNobGlzdC1zZWxlY3RlZCcpO1xyXG5cdFx0XHQkKCcuc2F2ZWQtY2FydC1hZGQnKS5yZW1vdmVDbGFzcygncmlnaHQtb2ZmLWNhbnZhcy10b2dnbGUnKTtcclxuXHRcdFx0JCgnLmJhdGNoLXNhdmVkLWNhcnQtYWRkJykucmVtb3ZlQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdCQoJyNjb250cm9sbC13aXNobGlzdCBidXR0b24gc3BhbicpLmhpZGUoKTtcclxuXHRcdFx0JCgnLnNpdGVoZWFkZXItbWFpbi1yaWdodCAud2lzaGxpc3QtdG9nZ2xlIHNwYW4nKS5oaWRlKCk7XHJcblx0XHRcdCQoJyNjb250cm9sbC13aXNobGlzdCcpLmFkZENsYXNzKCd3aXNobGlzdC1zZWxlY3RlZCcpO1xyXG5cdFx0XHQkKCcudWMtc2Nyb2xsY29udHJvbHMtc3RpY2t5JykuYWRkQ2xhc3MoJ3dpc2hsaXN0LXNlbGVjdGVkJyk7XHJcblxyXG5cdFx0XHRpZigkKCcudWMtc2Nyb2xsY29udHJvbHMtc3RpY2t5JykuY3NzKCdkaXNwbGF5JykgPT0gJ2Jsb2NrJyl7XHJcblx0XHRcdFx0Ly9DaGFuZ2UgcG9zaXRpb24gdG9wIGZvciBwcm9kdWN0LXN1bW1hcnktc3RpY2t5IHRvIGF2b2lkIGRpc3BsYXlpbmcgdW5kZXJuZWl0aCB3aXNobGlzdC1oZWFkZXIuXHJcblx0XHRcdFx0JCgnYm9keScpLmFkZENsYXNzKFwid2lzaGxpc3QtaGVhZGVyLWlzLXZpc2libGVcIik7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdCQoJ2JvZHknKS5yZW1vdmVDbGFzcyhcIndpc2hsaXN0LWhlYWRlci1pcy12aXNpYmxlXCIpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0bGV0IG51bWJlcm9md2lzaGxpc3QgPSAkKCcud2lzaGxpc3QtaGVhZGVyLnNob3ctZm9yLWxhcmdlLXVwIGJ1dHRvbiBzcGFuJykuYXR0cignZGF0YS1udW1iZXJvZndpc2hsaXN0Jyk7XHJcblx0XHRcdCQoJy53aXNobGlzdC1oZWFkZXIud2lzaGxpc3Qtc2VsZWN0ZWQuc3RpY2t5JykucmVtb3ZlQ2xhc3MoJ3dpc2hsaXN0LXNlbGVjdGVkJykuYWRkQ2xhc3MoJ3dpc2hsaXN0LWVtcHR5JykuZW1wdHkoKTtcclxuXHRcdFx0JCgnLnNhdmVkLWNhcnQtYWRkJykuYWRkQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdCQoJy5iYXRjaC1zYXZlZC1jYXJ0LWFkZCcpLmFkZENsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHQkKCcjY29udHJvbGwtd2lzaGxpc3QnKS5yZW1vdmVDbGFzcygnd2lzaGxpc3Qtc2VsZWN0ZWQnKTtcclxuXHRcdFx0JCgnLnVjLXNjcm9sbGNvbnRyb2xzLXN0aWNreScpLnJlbW92ZUNsYXNzKCd3aXNobGlzdC1zZWxlY3RlZCcpO1xyXG5cdFx0XHQkKCcjY29udHJvbGwtd2lzaGxpc3QgYnV0dG9uIHNwYW4nKS5zaG93KCkuaHRtbChudW1iZXJvZndpc2hsaXN0KTtcclxuXHRcdFx0JCgnLnNpdGVoZWFkZXItbWFpbi1yaWdodCAud2lzaGxpc3QtdG9nZ2xlIHNwYW4nKS5zaG93KCkuaHRtbChudW1iZXJvZndpc2hsaXN0KTtcclxuXHJcblx0XHRcdGlmKCQoJy51Yy1zY3JvbGxjb250cm9scy1zdGlja3knKS5jc3MoJ2Rpc3BsYXknKSA9PSAnbm9uZScpe1xyXG5cdFx0XHRcdC8vQ2hhbmdlIHBvc2l0aW9uIHRvcCBmb3IgcHJvZHVjdC1zdW1tYXJ5LXN0aWNreSB0byBhdm9pZCBkaXNwbGF5aW5nIHVuZGVybmVpdGggd2lzaGxpc3QtaGVhZGVyLlxyXG5cdFx0XHRcdCQoJ2JvZHknKS5yZW1vdmVDbGFzcyhcIndpc2hsaXN0LWhlYWRlci1pcy12aXNpYmxlXCIpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly9vZmZtZW51IGNhbnZhcyB3aXNobGlzdCBjaGFuZ2VkXHJcblx0U2V0dXBXaXNobGlzdERyb3Bkb3duKCkge1xyXG5cdFx0bGV0IGRyb3Bkb3duU2V0dGluZ3MgPSB7XHJcblx0XHRcdGZ1bGxUZXh0U2VhcmNoOiAnZXhhY3QnLFxyXG5cdFx0XHRtYXRjaDogJ3RleHQnLFxyXG5cdFx0XHRtaW5DaGFyYWN0ZXJzOiAzLFxyXG5cdFx0XHRmb3JjZVNlbGVjdGlvbjogZmFsc2UsXHJcblx0XHRcdHNlbGVjdE9uS2V5ZG93bjogZmFsc2UsXHJcblx0XHRcdC8vIGFjdGlvbjogJ3NlbGVjdCcsXHJcblx0XHRcdG1lc3NhZ2U6IHtcclxuXHRcdFx0XHRub1Jlc3VsdHM6IGhpYWJjb25maWcud2lzaGxpc3Qubm9TYXZlZFdpc2hsaXN0c1xyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cdFx0bGV0IGRkID0gJCgnI3dpc2hsaXN0U2VsZWN0Jyk7XHJcblx0XHRkZC5kcm9wZG93bigncmVmcmVzaCcpO1xyXG5cclxuXHRcdGRkLmRyb3Bkb3duKHtcclxuXHRcdFx0ZHJvcGRvd25TZXR0aW5ncyxcclxuXHRcdFx0b25DaGFuZ2UodmFsdWUsIHRleHQsICRjaG9pY2Upe1xyXG5cdFx0XHRcdFdpc2hsaXN0SGVhZGVyLlNlbGVjdFdpc2hsaXN0KHZhbHVlKTtcclxuXHRcdFx0fSxcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdFNlbGVjdFdpc2hsaXN0KHZhbHVlKSB7XHJcblx0XHRsZXQgdXJsID0gIFwiL2FwaS93aXNobGlzdC9TZWxlY3RXaXNobGlzdFwiO1xyXG5cdFx0bGV0IGRhdGEgPSB7IG5hbWU6dmFsdWUsIHByZWZlcnJlZEN1bHR1cmU6IGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZSB9O1xyXG5cdFx0JCgnYnV0dG9uLnB1cmNoYXNlJykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcclxuXHJcblx0XHRtb2JpbGVXaXNobGlzdFRvZ2dsZS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0bW9iaWxlV2lzaGxpc3RUb2dnbGUuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHJcblx0XHQkLmFqYXgoe1xyXG5cdFx0XHR0eXBlOiBcIkdFVFwiLFxyXG5cdFx0XHR1cmw6IHVybCxcclxuXHRcdFx0ZGF0YTogZGF0YSxcclxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcclxuXHRcdFx0c3VjY2VzczogZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdFx0XHRzZWxlY3RlZFdpc2hsaXN0RGF0YSA9IHJlc3BvbnNlLlNlbGVjdGVkV2lzaExpc3Q7XHJcblx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLlJlZHJhd0J1dHRvbnMoKTtcclxuXHRcdFx0XHRXaXNobGlzdEhlYWRlci5SZWRyYXdBbGwocmVzcG9uc2UpO1xyXG5cdFx0XHRcdCQoJy5zYXZlZC1jYXJ0LWFkZCcpLnJlbW92ZUNsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHRcdExpbmVpdGVtSGFuZGxlci5BZGRUb1dpc2hsaXN0KCk7XHJcblx0XHRcdFx0bGV0IGhlYWRlckJ0biA9ICQoJy51Yy13aXNobGlzdC53aXNobGlzdC1oZWFkZXIgYnV0dG9uJyk7XHJcblx0XHRcdFx0aWYoaGVhZGVyQnRuLmhhc0NsYXNzKCdhZGRpbmcnKSkge1xyXG5cdFx0XHRcdFx0JCgnLmNsb3NlLW9mZi1jYW52YXMnKS50cmlnZ2VyKCdjbGljaycpO1xyXG5cdFx0XHRcdH1cclxuXHRcdH0sXHJcblx0XHRcdGVycm9yOiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0Y29uc29sZS5sb2coXCJlcnJvciBmZXRjaGluZyB3aXNobGlzdCBpbmZvXCIpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRMb2FkV2lzaGxpc3RJbmZvKCkge1xyXG5cclxuXHRcdG1vYmlsZVdpc2hsaXN0VG9nZ2xlLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcblx0XHRtb2JpbGVXaXNobGlzdFRvZ2dsZS5hZGRDbGFzcygnbG9hZGluZycpO1xyXG5cclxuXHRcdGxldCB1cmwgPSAgXCIvYXBpL3dpc2hsaXN0L0dldEFsbFdpc2hsaXN0c1wiO1xyXG5cdFx0bGV0IGRhdGEgPSB7IHByZWZlcnJlZEN1bHR1cmU6IGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZSB9O1xyXG5cdFx0JC5hamF4KHtcclxuXHRcdFx0dHlwZTogXCJHRVRcIixcclxuXHRcdFx0dXJsOiB1cmwsXHJcblx0XHRcdGRhdGFUeXBlOiAnanNvbicsXHJcblx0XHRcdGRhdGE6IGRhdGEsXHJcblx0XHRcdHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XHJcblx0XHRcdFx0c2VsZWN0ZWRXaXNobGlzdERhdGEgPSByZXNwb25zZS5TZWxlY3RlZFdpc2hMaXN0O1xyXG5cdFx0XHRcdFdpc2hsaXN0SGVhZGVyLlJlZHJhd0FsbChyZXNwb25zZSk7XHJcblx0XHRcdFx0JCgnYnV0dG9uLmJ1dHRvbi53aXNobGlzdCcpLmF0dHIoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG5cdFx0XHRcdGlmKHNlbGVjdGVkV2lzaGxpc3REYXRhID09IG51bGwpIHtcclxuXHRcdFx0XHRcdCQoJ2J1dHRvbi5idXR0b24ud2lzaGxpc3QnKS5hZGRDbGFzcygncmlnaHQtb2ZmLWNhbnZhcy10b2dnbGUnKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblx0XHRcdGVycm9yOiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0Y29uc29sZS5sb2coXCJlcnJvciBmZXRjaGluZyB3aXNobGlzdCBpbmZvIGZvciBoZWFkZXJcIik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGluaXQoKSB7XHJcblx0XHQvL3RvZ2dsZXMgdmlzaWJpbGl0eSwgY2xlYXJzIGlucHV0cywgcmVzZXRzIHZhbGlkYXRpb25cclxuXHRcdGZ1bmN0aW9uIFJlc2V0VUlDb250cm9scygpIHtcclxuXHRcdFx0JCgnLndpc2hsaXN0LW1hbmFnZScpLnNob3coKTtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZScpLmhpZGUoKTtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZSBpbnB1dFtuYW1lPVwibmFtZVwiXScpLnZhbChcIlwiKTtcclxuXHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZSBpbnB1dFtuYW1lPVwiZGVzY1wiXScpLnZhbChcIlwiKTtcclxuXHRcdFx0JCgnI05ld0NhcnRGb3JtLU9mZkNhbnZhcyAuaW5wdXQtd3JhcHBlcicpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xyXG5cdFx0XHQkKCcud2lzaGxpc3QtY3JlYXRlIGJ1dHRvbltuYW1lPVwiV2lzaGxpc3QuU2F2ZVwiXScpLmF0dHIoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vZW5hYmxlcyB3aXNobGlzdCBvbiBvZmYtY2FudmFzXHJcblx0XHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLndpc2hsaXN0LXRvZ2dsZScsICgpID0+IHtcclxuXHRcdFx0JCgnLmRyYXdlci1tYWluIC5kcmF3ZXItcmlnaHQnKS5hZGRDbGFzcygnd2lzaGxpc3QtYWN0aXZlJyk7XHJcblx0XHRcdC8vc2hvdyBjcmVhdGUgY29udHJvbHMgaWYgbm8gd2lzaGxpc3QgYXZhaWxhYmxlXHJcblx0XHRcdGxldCB3aXNobGlzdHNFeGlzdHMgPSAkKCcjd2lzaGxpc3RTZWxlY3QgLm1lbnUgLml0ZW0nKS5sZW5ndGggPiAwO1xyXG5cdFx0XHRpZighd2lzaGxpc3RzRXhpc3RzKSB7XHJcblx0XHRcdFx0JCgnLndpc2hsaXN0LW1hbmFnZScpLmhpZGUoKTtcclxuXHRcdFx0XHQkKCcud2lzaGxpc3QtY3JlYXRlJykuc2hvdygpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLmNsb3NlLW9mZi1jYW52YXMnLCAoKSA9PiB7XHJcblx0XHRcdCQoJyN3aXNobGlzdEhlYWRlckNvbnRhaW5lcicpLnJlbW92ZUNsYXNzKCdpcy1vcGVuJyk7XHJcblx0XHRcdFJlc2V0VUlDb250cm9scygpO1xyXG5cdFx0XHRzZXRUaW1lb3V0KCAoKSA9PiB7XHJcblx0XHRcdFx0JCgnLmRyYXdlci1tYWluIC5kcmF3ZXItcmlnaHQnKS5yZW1vdmVDbGFzcygnd2lzaGxpc3QtYWN0aXZlJyk7XHJcblx0XHRcdH0sIDMwMCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvL2hhY2sgZm9yIHZhbGlkYXRpbmcgcmVxdWlyZWQgaW5wdXQgKGJlY2F1c2UgYWJpZGUgc3Vja3MpXHJcblx0XHQkKCdib2R5Jykub24oJ2JsdXIgY2hhbmdlIGtleXByZXNzJywgJyNOZXdDYXJ0Rm9ybS1PZmZDYW52YXMgaW5wdXRbcmVxdWlyZWRdJywgKGUpID0+IHtcclxuXHRcdFx0bGV0IGlucHV0ID0gJChlLmN1cnJlbnRUYXJnZXQpO1xyXG5cdFx0XHRpZihpbnB1dC52YWwoKS5sZW5ndGggPT0gMCkge1xyXG5cdFx0XHRcdGlucHV0LmNsb3Nlc3QoJy5pbnB1dC13cmFwcGVyJykuYWRkQ2xhc3MoJ2Vycm9yJyk7XHJcblx0XHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZSBidXR0b25bbmFtZT1cIldpc2hsaXN0LlNhdmVcIl0nKS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdGlucHV0LmNsb3Nlc3QoJy5pbnB1dC13cmFwcGVyJykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XHJcblx0XHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZSBidXR0b25bbmFtZT1cIldpc2hsaXN0LlNhdmVcIl0nKS5hdHRyKCdkaXNhYmxlZCcsIGZhbHNlKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly91c2Ugc2VydmljZSB0byBtZXJnZSBjYXJ0c1xyXG5cdFx0Ly90aGVuIHJlZGlyZWN0IHRvIHVybCBjaGVja291dFxyXG5cdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53aXNobGlzdC1tYW5hZ2UgYnV0dG9uLnB1cmNoYXNlJywgKCkgPT4ge1xyXG5cclxuXHRcdFx0bGV0IGJ0biA9ICQoJy53aXNobGlzdC1tYW5hZ2UgYnV0dG9uLnB1cmNoYXNlJyk7XHJcblxyXG5cdFx0XHRsZXQgaWQgPSBzZWxlY3RlZFdpc2hsaXN0RGF0YS5JZDtcclxuXHRcdFx0bGV0IHVybCA9IFwiL2FwaS93aXNobGlzdC9QdXJjaGFzZVdpc2hsaXN0XCI7XHJcblx0XHRcdGxldCBkYXRhID0geyB3aXNobGlzdE5hbWU6IGlkLCBwcmVmZXJyZWRDdWx0dXJlOiBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmUgfTtcclxuXHJcblx0XHRcdGJ0bi5hZGRDbGFzcygnbG9hZGluZycpO1xyXG5cclxuXHRcdFx0JC5hamF4KHtcclxuXHRcdFx0XHR0eXBlOiBcIkdFVFwiLFxyXG5cdFx0XHRcdHVybDogdXJsLFxyXG5cdFx0XHRcdGRhdGE6IGRhdGEsXHJcblx0XHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcclxuXHRcdFx0XHRzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcclxuXHRcdFx0XHRcdGJ0bi5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHRcdFx0aWYocmVzcG9uc2UuRXJyb3IubGVuZ3RoID09IDApXHJcblx0XHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gaGlhYmNvbmZpZy5jaGVja291dC5hcGlCYXNlVXJsO1xyXG5cdFx0XHRcdFx0fSxcclxuXHRcdFx0XHRcdGVycm9yOiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRcdGJ0bi5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9zaG93cyBjb250cm9scyBmb3IgY3JlYXRpbmdcclxuXHRcdCQoZG9jdW1lbnQpLm9uKCdjbGljaycsICcud2lzaGxpc3QtbWFuYWdlIGJ1dHRvbi5jcmVhdGUnLCAoKSA9PiB7XHJcblx0XHRcdCQoJy53aXNobGlzdC1jcmVhdGUgaW5wdXRbbmFtZT1cIm5hbWVcIl0nKS52YWwoXCJcIik7XHJcblx0XHRcdCQoJy53aXNobGlzdC1jcmVhdGUgaW5wdXRbbmFtZT1cImRlc2NcIl0nKS52YWwoXCJcIik7XHJcblx0XHRcdCQoJy53aXNobGlzdC1tYW5hZ2UnKS5oaWRlKCk7XHJcblx0XHRcdCQoJy53aXNobGlzdC1jcmVhdGUnKS5zaG93KCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLndpc2hsaXN0LWNyZWF0ZSBidXR0b25bbmFtZT1cIldpc2hsaXN0LlNhdmVcIl0nLCAoZSkgPT4ge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuYWJpZGUudmFsaWRhdGUoJCgnI05ld0NhcnRGb3JtLU9mZkNhbnZhcycpLmZpbmQoJ2lucHV0JyksIHt0eXBlOicnfSk7XHJcblxyXG5cdFx0XHRsZXQgbmFtZSA9ICQoJy53aXNobGlzdC1jcmVhdGUgaW5wdXRbbmFtZT1cIm5hbWVcIl0nKS52YWwoKTtcclxuXHRcdFx0bGV0IGRlc2MgPSAkKCcud2lzaGxpc3QtY3JlYXRlIGlucHV0W25hbWU9XCJkZXNjXCJdJykudmFsKCk7XHJcblxyXG5cdFx0XHRsZXQgbm9FcnJvciA9ICQoJyNOZXdDYXJ0Rm9ybS1PZmZDYW52YXMgLmlucHV0LXdyYXBwZXIuZXJyb3InKS5sZW5ndGggPT09IDA7XHJcblx0XHRcdGxldCBoYXNMZW5ndGggPSBuYW1lLmxlbmd0aCA+IDA7XHJcblxyXG5cdFx0XHRpZiggbm9FcnJvciAmJiBoYXNMZW5ndGggKSB7XHJcblx0XHRcdFx0bGV0IGlkID0gbnVsbDtcclxuXHRcdFx0XHRsZXQgdXJsID0gXCIvYXBpL3dpc2hsaXN0L0NyZWF0ZU9yVXBkYXRlV2lzaGxpc3RcIjtcclxuXHRcdFx0XHRsZXQgZGF0YSA9IHsgaWQ6aWQsIG5hbWU6bmFtZSwgZGVzYzpkZXNjLCBwcmVmZXJyZWRDdWx0dXJlOiBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmUgfTtcclxuXHJcblx0XHRcdFx0JCgnLndpc2hsaXN0LWNyZWF0ZSBidXR0b24nKS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xyXG5cdFx0XHRcdCQuYWpheCh7XHJcblx0XHRcdFx0XHR0eXBlOiBcIkdFVFwiLFxyXG5cdFx0XHRcdFx0dXJsOiB1cmwsXHJcblx0XHRcdFx0XHRkYXRhOiBkYXRhLFxyXG5cdFx0XHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcclxuXHRcdFx0XHRcdHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XHJcblx0XHRcdFx0XHRcdHNlbGVjdGVkV2lzaGxpc3REYXRhID0gcmVzcG9uc2UuU2VsZWN0ZWRXaXNoTGlzdDtcclxuXHRcdFx0XHRcdFx0V2lzaGxpc3RIZWFkZXIuUmVkcmF3QWxsKHJlc3BvbnNlKTtcclxuXHRcdFx0XHRcdFx0V2lzaGxpc3REZXRhaWxzLlJlZHJhd0lucHV0RmllbGRzKCk7XHJcblx0XHRcdFx0XHRcdFdpc2hsaXN0TGlzdGluZy5SZWRyYXdMaXN0aW5nKHNlbGVjdGVkV2lzaGxpc3REYXRhLklkKTsvL25ldyB2YWx1ZSFcclxuXHRcdFx0XHRcdFx0bGV0IGh0bWwgPSBcIjxzcGFuPlwiICsgaGlhYmNvbmZpZy53aXNobGlzdC5zYXZlZFdpc2hsaXN0ICsgXCI8L3NwYW4+XCI7XHJcblx0XHRcdFx0XHRcdEluamVjdG9yLkluc2VydEFmdGVyKGh0bWwsICcjd2lzaGxpc3RTZWxlY3QnKTtcclxuXHRcdFx0XHRcdFx0aWYoJCgnLnVjLXdpc2hsaXN0IC51Yy1vcmRlci1maWx0ZXJzIGg0JykubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRcdFx0XHRcdFdpc2hsaXN0TGlzdGluZy5SZWRyYXdXaXNobGlzdENvdW50KCk7XHJcblx0XHRcdFx0XHRcdFx0V2lzaGxpc3RMaXN0aW5nLlVwZGF0ZVBhZ2luYXRpb24oKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRMaW5laXRlbUhhbmRsZXIuQWRkVG9XaXNobGlzdCgpO1xyXG5cdFx0XHRcdFx0XHRsZXQgaGVhZGVyQnRuID0gJCgnLnVjLXdpc2hsaXN0Lndpc2hsaXN0LWhlYWRlciBidXR0b24nKTtcclxuXHRcdFx0XHRcdFx0aWYoaGVhZGVyQnRuLmhhc0NsYXNzKCdhZGRpbmcnKSkgeyAkKCcuY2xvc2Utb2ZmLWNhbnZhcycpLnRyaWdnZXIoJ2NsaWNrJyk7IH1cclxuXHRcdFx0XHRcdH0sXHJcblx0XHRcdFx0XHRlcnJvcjogZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcImVycm9yIHNhdmluZyB3aXNobGlzdCBpbmZvXCIpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53aXNobGlzdC1jcmVhdGUgYnV0dG9uW25hbWU9XCJXaXNobGlzdC5DYW5jZWxcIl0nLCAoZSkgPT4ge1xyXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFJlc2V0VUlDb250cm9scygpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly9sb2FkIHdpc2hsaXN0IGluZm8gYXN5bmMgd2hlbiBwYWdlIGxvYWRlZFxyXG5cdFx0JCggKCkgPT4ge1xyXG5cdFx0XHRXaXNobGlzdEhlYWRlci5Mb2FkV2lzaGxpc3RJbmZvKCk7XHJcblx0XHRcdExpbmVpdGVtSGFuZGxlci5pbml0KCk7XHJcblx0XHR9KTtcclxuXHR9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBXaXNobGlzdEhlYWRlcjtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IFdpc2hsaXN0SGVhZGVyIGZyb20gJy4vd2lzaGxpc3RIZWFkZXInO1xyXG5pbXBvcnQgSW5qZWN0b3IgZnJvbSAnLi8uLi8uLi9ub3RpZmljYXRpb25zL21lc3NhZ2VJbmplY3Rvcic7XHJcbmltcG9ydCBmb3VuZGF0aW9uIGZyb20gJy4vLi4vLi4vdmVuZG9ycy9mb3VuZGF0aW9uJztcclxuXHJcbmxldCBXaXNobGlzdExpc3RpbmcgPSB7XHJcblxyXG4gICAgUmVkcmF3TGlzdGluZyhpZCkge1xyXG4gICAgICAgIGxldCB1cmwgPSBcIkdldFdpc2hsaXN0UGFydGlhbD9pZD1cIiArIGlkICsgJyZwcmVmZXJyZWRDdWx0dXJlPScgKyBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmU7XHJcbiAgICAgICAgJCgnLnVjLW9yZGVyLWhpc3RvcnktdGFibGUnKS5sb2FkKHVybCk7XHJcbiAgICB9LFxyXG5cclxuICAgIFJlZHJhd1dpc2hsaXN0Q291bnQoKSB7XHJcbiAgICAgICAgbGV0IHVwZGF0ZU51bWJlclVybCA9IFwiVXBkYXRlVG90YWxXaXNobGlzdE5vXCIgKyAnP3ByZWZlcnJlZEN1bHR1cmU9JyArIGhpYWJjb25maWcucHJlZmVycmVkQ3VsdHVyZTs7XHJcbiAgICAgICAgJCgnLnVjLW9yZGVyLWZpbHRlcnMnKS5sb2FkKHVwZGF0ZU51bWJlclVybCk7XHJcbiAgICB9LFxyXG5cclxuICAgIFVwZGF0ZVBhZ2luYXRpb24oKSB7XHJcbiAgICAgICAgdmFyIHVybCA9IFwiVXBkYXRlUGFnaW5hdGlvblwiICsgJz9wcmVmZXJyZWRDdWx0dXJlPScgKyBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmU7O1xyXG4gICAgICAgICQoJy5wYWdpbmF0aW9uLWNlbnRlcmVkJykubG9hZCh1cmwpO1xyXG4gICAgfSxcclxuXHJcbiAgICBpbml0KCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIFJlc2V0Q29udHJvbHMoKSB7XHJcbiAgICAgICAgICAgICQoJyNOZXdDYXJ0Rm9ybSBpbnB1dFtyZXF1aXJlZF0nKS52YWwoXCJcIik7XHJcbiAgICAgICAgICAgICQoJ2lucHV0I2Rlc2NyaXB0aW9uJykudmFsKFwiXCIpO1xyXG4gICAgICAgICAgICAkKCcjTmV3Q2FydEZvcm0gLmlucHV0LXdyYXBwZXInKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcclxuICAgICAgICAgICAgZm91bmRhdGlvbi5pbml0KCk7XHJcbiAgICAgICAgICAgICQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ2FiaWRlJywgJ3JlZmxvdycpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vY2FuY2VsIGxpbmsgbmF2aWdhdGlvbiB3aGlsZSBsaXN0IGlzIGxvYWRpbmdcclxuICAgICAgICAkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLnVjLW9yZGVyLWhpc3RvcnktdGFibGUubG9hZGluZyBhJywgKGUpID0+e1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvL2hhbmRsZSBzYXZlIGJ0biBjbGlja1xyXG4gICAgICAgICQoJyNOZXdDYXJ0Rm9ybSBidXR0b25bbmFtZT1cIldpc2hsaXN0LlNhdmVcIl0nKS5jbGljayhmdW5jdGlvbihlKSB7XHJcblx0XHRcdFx0XHRGb3VuZGF0aW9uLmxpYnMuYWJpZGUudmFsaWRhdGUoJCgnI05ld0NhcnRGb3JtJykuZmluZCgnaW5wdXQnKSwge3R5cGU6Jyd9KTtcclxuXHJcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG5cdFx0XHRcdFx0bGV0IGlucHV0TmFtZSA9ICQoJyNOZXdDYXJ0Rm9ybSBpbnB1dFtuYW1lPVwiTmV3Q2FydC5OYW1lXCJdJyk7XHJcblx0XHRcdFx0XHRsZXQgbmFtZSA9IGlucHV0TmFtZS52YWwoKTtcclxuXHJcblx0ICAgICAgICBsZXQgaW5wdXREZXNjID0gJCgnI05ld0NhcnRGb3JtIGlucHV0W25hbWU9XCJOZXdDYXJ0LkRlc2NcIl0nKTtcclxuXHRcdFx0XHRcdGxldCBkZXNjcmlwdGlvbiA9IGlucHV0RGVzYy52YWwoKTtcclxuXHJcblx0XHRcdFx0XHRsZXQgbm9FcnJvciA9ICQoJyNOZXdDYXJ0Rm9ybSAuaW5wdXQtd3JhcHBlci5lcnJvcicpLmxlbmd0aCA9PT0gMDtcclxuXHRcdFx0XHRcdGxldCBoYXNMZW5ndGggPSBuYW1lLmxlbmd0aCA+IDA7XHJcblxyXG5cdCAgICAgICAgaWYoIG5vRXJyb3IgJiYgaGFzTGVuZ3RoICkge1xyXG5cdCAgICAgICAgICAgIEluamVjdG9yLlJlcGxhY2UoXCI8aSBjbGFzcz0nYW5pbWF0ZS1zcGluIGljb24tc3BpbjQnPjwvaT5cIiwgXCIubXNnLWNvbnRhaW5lclwiKTtcclxuXHQgICAgICAgICAgICBsZXQgdGFibGUgPSAkKCcudWMtb3JkZXItaGlzdG9yeS10YWJsZScpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcblx0ICAgICAgICAgICAgdGFibGUuZmluZCgnYnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcclxuXHQgICAgICAgICAgICBsZXQgdXJsID0gXCJDcmVhdGVOZXdXaXNobGlzdFwiO1xyXG5cdCAgICAgICAgICAgIGxldCBkYXRhID0geyBuYW1lIDogbmFtZSwgZGVzYyA6IGRlc2NyaXB0aW9uLCBwcmVmZXJyZWRDdWx0dXJlOiBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmUgfTtcclxuXHJcblx0ICAgICAgICAgICAgJCgnLnVjLW9yZGVyLWhpc3RvcnktdGFibGUnKS5sb2FkKHVybCwgZGF0YSwgKCkgPT4ge1xyXG5cdFx0ICAgICAgICBcdFx0XHRXaXNobGlzdEhlYWRlci5Mb2FkV2lzaGxpc3RJbmZvKCk7XHJcblx0ICAgICAgICAgICAgICAgIFdpc2hsaXN0TGlzdGluZy5SZWRyYXdXaXNobGlzdENvdW50KCk7XHJcblx0ICAgICAgICAgICAgICAgIFdpc2hsaXN0TGlzdGluZy5VcGRhdGVQYWdpbmF0aW9uKCk7XHJcblx0ICAgICAgICAgICAgICAgIHRhYmxlLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcblx0ICAgICAgICAgICAgICAgIHRhYmxlLmZpbmQoJ2J1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG5cdCAgICAgICAgICAgICAgICB2YXIgaHRtbCA9IFwiPHNwYW4+XCIgKyBoaWFiY29uZmlnLndpc2hsaXN0LmFkZGVkV2lzaGxpc3QgKyBcIjwvc3Bhbj5cIjtcclxuXHQgICAgICAgICAgICAgICAgSW5qZWN0b3IuUmVwbGFjZShodG1sLCBcIi5tc2ctY29udGFpbmVyXCIpO1xyXG5cdCAgICAgICAgICAgICAgICBSZXNldENvbnRyb2xzKCk7XHJcblx0ICAgICAgICAgICAgfSk7XHJcblx0ICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vaGFuZGxlIGNhbmNlbCBidG4gY2xpY2tcclxuICAgICAgICAkKCcjTmV3Q2FydEZvcm0gYnV0dG9uW25hbWU9XCJXaXNobGlzdC5DYW5jZWxcIl0nKS5jbGljayhmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBSZXNldENvbnRyb2xzKCkgfSwgMzAwKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy9oYW5kbGUgc2VsZWN0IGNhcnQgY2xpY2tcclxuICAgICAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsICcudWMtb3JkZXItaGlzdG9yeS10YWJsZSBidXR0b24nLCBmdW5jdGlvbihlKXtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGVsID0gJCh0aGlzKTtcclxuICAgICAgICAgICAgdmFyIGlkVGV4dCA9IGVsLnBhcmVudHMoJ3RyJykuZmluZCgnLm5hbWUtaWQnKS5kYXRhKCdpZCcpO1xyXG4gICAgICAgICAgICB2YXIgdXJsID0gXCJTZXRTZWxlY3RlZFdpc2hsaXN0XCI7XHJcbiAgICAgICAgICAgIHZhciBkYXRhID0geyBpZCA6IGlkVGV4dCwgcHJlZmVycmVkQ3VsdHVyZTogaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlIH07XHJcbiAgICAgICAgICAgICQoJy51Yy1vcmRlci1oaXN0b3J5LXRhYmxlJykubG9hZCh1cmwsIGRhdGEsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgV2lzaGxpc3RMaXN0aW5nLlVwZGF0ZVBhZ2luYXRpb24oKTtcclxuICAgICAgICAgICAgICAgIFdpc2hsaXN0SGVhZGVyLlNlbGVjdFdpc2hsaXN0KGlkVGV4dCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvL2hhbmRsZSBwYWdpbmF0aW9uIGNsaWNrXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCAnLnBhZ2luYXRpb24udWMtcGFnaW5hdGlvbiBsaScsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgZWwgPSAkKHRoaXMpO1xyXG4gICAgICAgICAgICBpZighZWwuaGFzQ2xhc3MoJ2N1cnJlbnQnKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNsaWNrZWRQYWdlTm8gPSBFeHRyYWN0UGFnZU5vRnJvbUhyZWYoZWwpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHVybCA9IFwiR2V0UGFnZS8/cGFnZT1cIiArIGNsaWNrZWRQYWdlTm87XHJcbiAgICAgICAgICAgICAgICAkKCcudWMtb3JkZXItaGlzdG9yeS10YWJsZScpLmxvYWQodXJsLCBudWxsLCBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICBXaXNobGlzdExpc3RpbmcuVXBkYXRlUGFnaW5hdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gRXh0cmFjdFBhZ2VOb0Zyb21IcmVmKGVsKSB7XHJcbiAgICAgICAgICAgIHZhciBocmVmID0gZWwuZmluZCgnYScpLmF0dHIoJ2hyZWYnKTtcclxuICAgICAgICAgICAgdmFyIGNsaWNrZWRQYWdlTm8gPSBocmVmLnN1YnN0cmluZyg2KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBjbGlja2VkUGFnZU5vO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9jaGVjayBmb3IgZGVsZXRlZCBjYXJ0IGFuZCBvdXRwdXQgbXNnIGlmIGZvdW5kXHJcbiAgICAgICAgJCggKCkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgdXJsID0gXCJHZXREZWxldGVkV2lzaGxpc3RcIiArICc/cHJlZmVycmVkQ3VsdHVyZT0nICsgaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlO1xyXG4gICAgICAgICAgICAkLmFqYXgoe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogXCJHRVRcIixcclxuICAgICAgICAgICAgICAgIHVybDogdXJsLFxyXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcclxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKHJlc3BvbnNlLmlkICE9IFwiXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGh0bWwgPSBcIjxzcGFuPlwiICsgaGlhYmNvbmZpZy53aXNobGlzdC5yZW1vdmVkV2lzaGxpc3QgKyBcIjwvc3Bhbj5cIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgSW5qZWN0b3IuUmVwbGFjZShodG1sLCBcIi5tc2ctY29udGFpbmVyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiZXJyb3JcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgV2lzaGxpc3RMaXN0aW5nO1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgUm91dGVyIGZyb20gJ3JlYWN0LXJvdXRlcic7XHJcbmltcG9ydCBJbGx1c3RyYXRpb25Db250YWluZXIgZnJvbSAnLi9jb21wb25lbnRzL2lsbHVzdHJhdGlvbi9pbGx1c3RyYXRpb25fY29udGFpbmVyJztcclxuXHJcbmxldCBSb3V0ZUhhbmRsZXIgPSBSb3V0ZXIuUm91dGVIYW5kbGVyLFxyXG4gICAgUm91dGUgPSBSb3V0ZXIuUm91dGUsXHJcbiAgICBEZWZhdWx0Um91dGUgPSBSb3V0ZXIuRGVmYXVsdFJvdXRlO1xyXG5cclxuXHJcbmNsYXNzIE90aGVyQ29udGFpbmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XHJcblxyXG4gIH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0cmV0dXJuKFxyXG4gICAgICA8Um91dGVIYW5kbGVyIC8+XHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuXHJcbmxldCB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3MuZXhwbG9kZWRWaWV3c1VSTDtcclxuXHJcbmlmKGhpYWJjb25maWcuaGFzRXF1aXBtZW50VHlwZVJlc3RyaWN0aW9uKXtcclxuICB1cmwgPSBoaWFiY29uZmlnLmV4cGxvZGVkVmlld3Muc2VhcmNoRHJhd2luZ3NQYWdlVXJsOyBcclxufVxyXG5cclxubGV0IHJvdXRlcyA9IChcclxuICA8Um91dGUgaGFuZGxlcj17T3RoZXJDb250YWluZXJ9IGlnbm9yZVNjcm9sbEJlaGF2aW9yIHBhdGg9e3VybH0+XHJcbiAgICA8RGVmYXVsdFJvdXRlIGhhbmRsZXI9e0lsbHVzdHJhdGlvbkNvbnRhaW5lcn0vPlxyXG4gICAgPFJvdXRlIG5hbWU9J21vZGVsJyBwYXRoPSc6bW9kZWwnIGhhbmRsZXI9e0lsbHVzdHJhdGlvbkNvbnRhaW5lcn0gLz5cclxuICAgIDxSb3V0ZSBuYW1lPSdub2RlSWQnIHBhdGg9Jzptb2RlbC86bm9kZUlkJyBoYW5kbGVyPXtJbGx1c3RyYXRpb25Db250YWluZXJ9IC8+XHJcbiAgICA8Um91dGUgbmFtZT0naWxsdXN0cmF0aW9uJyBwYXRoPSc6bW9kZWwvOm5vZGVJZC86aWxsdXN0cmF0aW9uJyBoYW5kbGVyPXtJbGx1c3RyYXRpb25Db250YWluZXJ9IC8+XHJcbiAgPC9Sb3V0ZT5cclxuKTtcclxuXHJcblJvdXRlci5ydW4ocm91dGVzLCBSb3V0ZXIuSGlzdG9yeUxvY2F0aW9uLCBmdW5jdGlvbihIYW5kbGVyKSB7XHJcbiAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2lsbHVzdHJhdGlvbicpID09PSBudWxsKSByZXR1cm47XHJcblx0UmVhY3RET00ucmVuZGVyKDxIYW5kbGVyLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbGx1c3RyYXRpb24nKSk7XHJcbn0pO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IElsbHVzdHJhdGlvbkNvbnRhaW5lcjtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5cclxuY2xhc3MgSW1wZXJzb25hdGVkVXNlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKCF0aGlzLnByb3BzLmltcGVyc29uYXRlZCB8fCAhdGhpcy5wcm9wcy5pbXBlcnNvbmF0ZWQuSXNJbXBlcnNvbmF0ZWQpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5pbXBlcnNvbmF0b3IubGFuZztcclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImltcGVyc29uYXRlZC11c2VyXCI+XHJcblx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaGVhZGVyXCI+e2xhbmcuaW1wZXJzb25hdGVoZWFkZXJ9PC9zcGFuPlxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInVzZXItZGF0YVwiPnt0aGlzLnByb3BzLmltcGVyc29uYXRlZC5DdXN0b21lck5hbWV9IC0ge3RoaXMucHJvcHMuaW1wZXJzb25hdGVkLkN1c3RvbWVySWR9PC9zcGFuPlxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInVzZXItZGF0YVwiPnt0aGlzLnByb3BzLmltcGVyc29uYXRlZC5Db21wYW55TmFtZX08L3NwYW4+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEltcGVyc29uYXRlZFVzZXI7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgSW1wZXJzb25hdG9yQ29udGFpbmVyIGZyb20gJy4vaW1wZXJzb25hdG9yX2NvbnRhaW5lcic7XHJcblxyXG5sZXQgSW1wZXJzb25hdG9yID0ge1xyXG5cdGluaXQoKSB7XHJcblx0XHR0aGlzLmltcGVyc29uYXRvciA9ICQoJyNpbXBlcnNvbmF0b3InKTtcclxuXHJcblx0XHQvL1JlbmRlciBpbXBlcnNvbmF0b3JcclxuXHRcdHRoaXMucmVuZGVyUmVhY3RDb21wb25lbnRzKCk7XHJcblxyXG5cdH0sXHJcblxyXG5cdHJlbmRlclJlYWN0Q29tcG9uZW50cygpIHtcclxuXHRcdGlmKHRoaXMuaW1wZXJzb25hdG9yLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0UmVhY3RET00ucmVuZGVyKDxJbXBlcnNvbmF0b3JDb250YWluZXIvPiwgdGhpcy5pbXBlcnNvbmF0b3JbMF0pO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEltcGVyc29uYXRvcjtcclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5cclxuY2xhc3MgSW1wZXJzb25hdG9yQXV0b0NvbXBsZXRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZU5vSGl0c1NlYXJjaCA9IChlKSA9PiB7XHJcblx0XHQkKCAnLnVzZXItc2VhcmNoLWZpZWxkJyApLmF1dG9jb21wbGV0ZShcInNlYXJjaFwiLCAkKCAnLnVzZXItc2VhcmNoLWZpZWxkJyApLnZhbCgpKTtcclxuXHRcdCQoXCIuaW1wZXJzb25hdGlvbi1lcnJvclwiKS5hZGRDbGFzcygnaGlkZGVuJyk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5pbXBlcnNvbmF0b3IubGFuZztcclxuXHQgICQoIFwiLnVzZXItc2VhcmNoLWZpZWxkXCIgKS5hdXRvY29tcGxldGUoe1xyXG5cdCBcdCBtaW5MZW5ndGg6IDIsXHJcblx0XHQgZGVsYXk6IDMwMCxcclxuXHQgXHQgc291cmNlOiAocmVxdWVzdCwgcmVzcG9uc2UpID0+IHtcclxuXHQgXHRcdFx0JC5hamF4KHtcclxuXHQgXHRcdFx0XHR1cmw6IGhpYWJjb25maWcuaW1wZXJzb25hdG9yLmFwaUJhc2VVcmwgKyAnU2VhcmNoJyxcclxuXHQgXHRcdFx0XHRkYXRhOiB7XHJcblx0IFx0XHRcdFx0XHRxdWVyeTogcmVxdWVzdC50ZXJtXHJcblx0IFx0XHRcdFx0fSxcclxuXHRcdFx0XHRcdGJlZm9yZVNlbmQ6ZnVuY3Rpb24oKXtcclxuICAgICAgICBcdFx0JCgnLnVzZXItc2VhcmNoIGJ1dHRvbicpLmFkZENsYXNzKCdsb2FkaW5nJyk7XHJcbiAgICBcdFx0XHR9LFxyXG5cdFx0XHRcdFx0Y29tcGxldGU6ZnVuY3Rpb24oKXtcclxuXHRcdFx0XHRcdFx0JCgnLnVzZXItc2VhcmNoIGJ1dHRvbicpLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XHJcblx0XHRcdCAgICB9LFxyXG5cdCBcdFx0XHRcdHN1Y2Nlc3M6IGZ1bmN0aW9uIChkYXRhKSB7XHJcblx0XHRcdCBcdFx0XHQkKFwiLmltcGVyc29uYXRpb24tZXJyb3JcIikuYWRkQ2xhc3MoJ2hpZGRlbicpO1xyXG5cdCBcdFx0XHRcdFx0aWYgKGRhdGEubGVuZ3RoID09IDApIHtcclxuXHQgXHRcdFx0XHRcdFx0ZGF0YS5wdXNoKHtcclxuXHQgXHRcdFx0XHRcdFx0XHROb0hpdHM6IHRydWUsXHJcblx0IFx0XHRcdFx0XHRcdFx0VGl0bGU6IGxhbmcubm9oaXRzKyAnOiAnICsgcmVxdWVzdC50ZXJtXHJcblx0IFx0XHRcdFx0XHRcdH0pO1xyXG5cdCBcdFx0XHRcdFx0fVxyXG5cdCBcdFx0XHRcdFx0cmVzcG9uc2UoZGF0YSk7XHJcblx0IFx0XHRcdFx0fVxyXG5cdCBcdFx0XHR9KTtcclxuXHQgXHRcdH0sXHJcblxyXG5cdCBcdCBhcHBlbmRUbzogJCgnLnVzZXItc2VhcmNoJykuYWZ0ZXIoKSxcclxuXHQgXHQgb3BlbjogKCBldmVudCwgdWkgKSA9PiB7XHJcblx0IFx0XHQgJCgnLnVzZXItc2VhcmNoIC5oZWFkZXInKS5vbignbW91c2VvdmVyIGNsaWNrJywgKCkgPT4ge1xyXG5cdCBcdFx0XHQgcmV0dXJuIGZhbHNlO1xyXG5cdCBcdFx0IH0pO1xyXG5cdCBcdCB9LFxyXG5cdCBcdCBzZWxlY3Q6ICggZXZlbnQsIHVpICkgPT4ge1xyXG5cdCBcdFx0IHRoaXMucHJvcHMuaGFuZGxlQ2xpY2sodWkuaXRlbSwgZXZlbnQpO1xyXG5cdCBcdCB9XHJcblx0ICB9KTtcclxuXHJcblx0ICAkKCcudXNlci1zZWFyY2gtZmllbGQnKS5hdXRvY29tcGxldGUoICdpbnN0YW5jZScgKS5fcmVuZGVySXRlbSA9ICggdWwsIGl0ZW0gKSA9PiB7XHJcblx0IFx0bGV0IGh0bWwgPSAgJzxkaXYgY2xhc3M9XCJyb3dcIj4nICtcclxuXHQgXHRcdFx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwic21hbGwtNSBjb2x1bW5zXCI+PHNwYW4+JyArXHJcblx0IFx0XHRcdFx0XHRcdFx0XHRcdGl0ZW0uQ29tcGFueU5hbWUgK1xyXG5cdCBcdFx0XHRcdFx0XHRcdFx0Jzwvc3Bhbj48L2Rpdj4nICtcclxuXHQgXHRcdFx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwic21hbGwtNCBjb2x1bW5zXCI+PHNwYW4+JyArXHJcblx0IFx0XHRcdFx0XHRcdFx0XHRcdGl0ZW0uQ3VzdG9tZXJOYW1lICtcclxuXHQgXHRcdFx0XHRcdFx0XHRcdCc8L3NwYW4+PC9kaXY+JyArXHJcblx0IFx0XHRcdFx0XHRcdFx0XHQnPGRpdiBjbGFzcz1cInNtYWxsLTMgY29sdW1uc1wiPjxzcGFuPicgK1xyXG5cdCBcdFx0XHRcdFx0XHRcdFx0XHRpdGVtLkN1c3RvbWVySWQgK1xyXG5cdCBcdFx0XHRcdFx0XHRcdFx0Jzwvc3Bhbj48L2Rpdj4nICtcclxuXHQgXHRcdFx0XHRcdFx0XHQnPC9kaXY+JztcclxuXHQgXHQgcmV0dXJuICQoJzxsaT4nIClcclxuXHQgXHRcdCAuYXBwZW5kKGh0bWwpXHJcblx0IFx0XHQgLmFwcGVuZFRvKCB1bCApO1xyXG5cdCAgfTtcclxuXHJcblx0ICAkKCcudXNlci1zZWFyY2gtZmllbGQnKS5hdXRvY29tcGxldGUoICdpbnN0YW5jZScgKS5fcmVuZGVyTWVudSA9IGZ1bmN0aW9uKHVsLCBpdGVtcykge1xyXG5cclxuXHQgXHQgdmFyIHRoYXQgPSB0aGlzO1xyXG5cdCBcdCBsZXQgaHRtbCA9ICQoJzxsaSBjbGFzcz1cImhlYWRlclwiPjxkaXYgY2xhc3M9XCJyb3dcIj4nICtcclxuXHQgXHRcdFx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwic21hbGwtNSBjb2x1bW5zXCI+JyArIGxhbmcuY29tcGFueSArICc8L2Rpdj4nICtcclxuXHQgXHRcdFx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwic21hbGwtNCBjb2x1bW5zXCI+JyArIGxhbmcuY3VzdG9tZXIgKyAnPC9kaXY+JyArXHJcblx0IFx0XHRcdFx0XHRcdFx0XHQnPGRpdiBjbGFzcz1cInNtYWxsLTMgY29sdW1uc1wiPicgKyBsYW5nLmN1c3RvbWVybnIgKyAnPC9kaXY+JyArXHJcblx0IFx0XHRcdFx0XHRcdFx0JzwvZGl2PjwvbGk+Jyk7XHJcblxyXG5cclxuXHQgXHQgaWYoaXRlbXNbMF0uTm9IaXRzKSB7XHJcblx0IFx0XHQgaHRtbCA9ICQoJzxsaSBjbGFzcz1cImhlYWRlclwiPjxkaXYgY2xhc3M9XCJyb3dcIj48ZGl2IGNsYXNzPVwic21hbGwtMTIgY29sdW1uc1wiPicgKyBpdGVtc1swXS5UaXRsZSAgKyAnPC9kaXY+PC9kaXY+PC9saT4nKTtcclxuXHQgXHRcdCBodG1sLmFwcGVuZFRvKHVsKTtcclxuXHQgXHRcdCByZXR1cm47XHJcblx0IFx0IH1cclxuXHQgXHQgaHRtbC5hcHBlbmRUbyh1bCk7XHJcblxyXG5cdCBcdCAkLmVhY2goIGl0ZW1zLCBmdW5jdGlvbiggaW5kZXgsIGl0ZW0gKSB7XHJcblx0IFx0XHQgdGhhdC5fcmVuZGVySXRlbURhdGEoIHVsLCBpdGVtICk7XHJcblx0IFx0IH0pO1xyXG5cdCAgfTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5pbXBlcnNvbmF0b3IubGFuZztcclxuXHRcdGlmKHRoaXMucHJvcHMuaXNPcGVuKSB0aGlzLmZpbmR1c2VyLmZvY3VzKCk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJ1c2VyLXNlYXJjaFwiPlxyXG5cdFx0XHRcdDxpbnB1dCB0YWJJbmRleD1cIi0xXCIgY2xhc3NOYW1lPVwidXNlci1zZWFyY2gtZmllbGRcIiByZWY9eyhyZWYpID0+IHRoaXMuZmluZHVzZXIgPSByZWZ9IHBsYWNlaG9sZGVyPXtsYW5nLnBsYWNlaG9sZGVyfSB0eXBlPVwidGV4dFwiIG5hbWU9XCJmaW5kdXNlclwiIC8+XHJcblx0XHRcdFx0PGJ1dHRvbiBjbGFzc05hbWU9XCJidXR0b25cIiBvbkNsaWNrPXt0aGlzLmhhbmRsZU5vSGl0c1NlYXJjaC5iaW5kKHRoaXMpfSB0eXBlPVwiYnV0dG9uXCI+e2xhbmcuZmluZH08L2J1dHRvbj5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgSW1wZXJzb25hdG9yQXV0b0NvbXBsZXRlcjtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQganF1ZXJ5dWkgZnJvbSAnanF1ZXJ5LnVpJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBJbXBlcnNvbmF0ZWRVc2VyIGZyb20gJy4vaW1wZXJzb25hdGVkX3VzZXInO1xyXG5pbXBvcnQgSW1wZXJzb25hdGVkU2lnbm91dCBmcm9tICcuL2ltcGVyc29uYXRvcl9zaWdub3V0JztcclxuaW1wb3J0IEltcGVyc29uYXRvckF1dG9Db21wbGV0ZXIgZnJvbSAnLi9pbXBlcnNvbmF0b3JfYXV0b2NvbXBsZXRlcic7XHJcbmltcG9ydCBJbXBlcnNvbmF0b3JBcGkgZnJvbSAnLi4vX2FwaS9pbXBlcnNvbmF0b3JfYXBpJztcclxuaW1wb3J0IEN1c3RvbUV2ZW50cyBmcm9tICcuLi9fbGliL2N1c3RvbS1ldmVudHMnO1xyXG5cclxuY2xhc3MgSW1wZXJzb25hdG9yQ29udGFpbmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aXNPcGVuOmZhbHNlLFxyXG5cdFx0XHRpc0ltcGVyc29uYXRlZDogZmFsc2UsXHJcblx0XHRcdGltcGVyc29uYXRlZDogbnVsbCxcclxuXHRcdFx0aXNMb2FkaW5nOiBmYWxzZSxcclxuXHRcdFx0c2lnbkluRXJyb3I6IGZhbHNlXHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRoYW5kbGVDbGljayA9IChpdGVtLCBlKSA9PiB7XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNMb2FkaW5nOiB0cnVlLFxyXG5cdFx0XHRzaWduSW5FcnJvcjogZmFsc2VcclxuXHRcdH0pO1xyXG5cclxuXHRcdEltcGVyc29uYXRvckFwaS5pbXBlcnNvbmF0ZWRTaWduaW4oaXRlbS5QcmltYXJ5S2V5KVxyXG5cdFx0XHQudGhlbigocmVxdWVzdCkgPT4ge1xyXG5cdFx0XHRcdEN1c3RvbUV2ZW50cy50cmlnZ2VySW1wZXJzb25hdGlvblN0YXJ0RXZlbnQocmVxdWVzdC5ib2R5KTtcclxuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdHNpZ25JbkVycm9yOiBmYWxzZSxcclxuXHRcdFx0XHRcdGlzTG9hZGluZzogdHJ1ZVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlVG9nZ2xlKCk7XHJcblx0XHRcdFx0bG9jYXRpb24ucmVsb2FkKHRydWUpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQuY2F0Y2goKHJlcXVlc3QpID0+IHtcclxuXHRcdFx0XHR0aGlzLmhhbmRsZUVycm9yKCk7XHJcblx0XHRcdH0pO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlU2lnbk91dCA9IChlKSA9PiB7XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNMb2FkaW5nOiB0cnVlLFxyXG5cdFx0XHRzaWduSW5FcnJvcjogZmFsc2VcclxuXHRcdH0pO1xyXG5cclxuXHRcdEltcGVyc29uYXRvckFwaS5pbXBlcnNvbmF0ZWRTaWdub3V0KClcclxuXHRcdFx0LnRoZW4oKHJlcXVlc3QpID0+IHtcclxuXHRcdFx0XHRkb2N1bWVudC5sb2NhdGlvbi5ocmVmPVwiL1wiICsgaGlhYmNvbmZpZy5wcmVmZXJyZWRDdWx0dXJlO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQuY2F0Y2goKGVycikgPT4ge1xyXG5cdFx0XHRcdGRvY3VtZW50LmxvY2F0aW9uLmhyZWY9XCIvIy8jc2lnbi1pblwiO1xyXG5cdFx0XHR9KTtcclxuXHR9XHJcblx0aGFuZGxlRXJyb3IoKXtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRzaWduSW5FcnJvcjogdHJ1ZSxcclxuXHRcdFx0aXNMb2FkaW5nOiBmYWxzZSxcclxuXHRcdFx0aXNPcGVuOiB0cnVlXHJcblx0XHR9KTtcclxuXHR9XHJcblx0aGFuZGxlVG9nZ2xlID0gKGUpID0+IHtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRpc09wZW46IHRoaXMuc3RhdGUuaXNPcGVuID8gZmFsc2UgOiB0cnVlLFxyXG5cdFx0XHRzaWduSW5FcnJvcjogZmFsc2VcclxuXHRcdH0pO1xyXG5cdFx0JCgnLnVzZXItc2VhcmNoLWZpZWxkJykuZm9jdXMoKTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZE1vdW50KCkge1xyXG5cdCBJbXBlcnNvbmF0b3JBcGkuaW1wZXJzb25hdGVkVXNlcigpLnRoZW4oKGRhdGEpID0+IHtcclxuXHJcblx0XHQgdGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdCBpbXBlcnNvbmF0ZWQ6IGRhdGEsXHJcblx0XHRcdCBpc0ltcGVyc29uYXRlZDogZGF0YS5Jc0ltcGVyc29uYXRlZFxyXG5cdFx0IH0pO1xyXG5cdCB9KTtcclxuXHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5zdGF0ZS5pbXBlcnNvbmF0ZWQpIHJldHVybiBudWxsO1xyXG5cdFx0bGV0IGhhc0Vycm9yID0gdGhpcy5zdGF0ZS5zaWduSW5FcnJvcjtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5pbXBlcnNvbmF0b3IubGFuZztcclxuXHRcdGxldCBpc09wZW5DbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQndWMtaW1wZXJzb25hdG9yJzogdHJ1ZSxcclxuXHRcdFx0J2lzLW9wZW4nOiB0aGlzLnN0YXRlLmlzT3BlbixcclxuXHRcdFx0J2lzLWltcGVyc29uYXRlZCc6IHRoaXMuc3RhdGUuaXNJbXBlcnNvbmF0ZWQsXHJcblx0XHRcdCdpcy1sb2FkaW5nJzogdGhpcy5zdGF0ZS5pc0xvYWRpbmdcclxuXHRcdH0pO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9e2lzT3BlbkNsYXNzfT5cclxuXHRcdFx0XHR7aGFzRXJyb3IgPyA8ZGl2IGNsYXNzTmFtZT1cImltcGVyc29uYXRpb24tZXJyb3JcIj57bGFuZy5lcnJvcn08L2Rpdj4gOiA8ZGl2IGNsYXNzTmFtZT1cImltcGVyc29uYXRpb24tZXJyb3IgaGlkZGVuXCI+e2xhbmcuZXJyb3J9PC9kaXY+IH1cclxuXHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBpbXBlcnNvbmF0b3ItdG9nZ2xlXCIgb25DbGljaz17dGhpcy5oYW5kbGVUb2dnbGUuYmluZCh0aGlzKX0gdHlwZT1cImJ1dHRvblwiPjxpIGNsYXNzTmFtZT1cImljb24tdXNlci1wbHVzXCI+PC9pPntsYW5nLmZpbmR1c2VyfTwvYnV0dG9uPlxyXG5cdFx0XHRcdDxJbXBlcnNvbmF0b3JBdXRvQ29tcGxldGVyIGhhbmRsZUNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrfSBpc09wZW49e3RoaXMuc3RhdGUuaXNPcGVufSAvPlxyXG5cdFx0XHRcdDxJbXBlcnNvbmF0ZWRVc2VyIGltcGVyc29uYXRlZD17dGhpcy5zdGF0ZS5pbXBlcnNvbmF0ZWR9IC8+XHJcblx0XHRcdFx0PEltcGVyc29uYXRlZFNpZ25vdXQgaGFuZGxlU2lnbk91dD17dGhpcy5oYW5kbGVTaWduT3V0fSBpbXBlcnNvbmF0ZWQ9e3RoaXMuc3RhdGUuaW1wZXJzb25hdGVkfSAvPlxyXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwibG9hZGluZy1vdmVybGF5XCI+PC9kaXY+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KTtcclxuXHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBJbXBlcnNvbmF0b3JDb250YWluZXI7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuXHJcbmNsYXNzIEltcGVyc29uYXRlZFNpZ25vdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5wcm9wcy5pbXBlcnNvbmF0ZWQgfHwgIXRoaXMucHJvcHMuaW1wZXJzb25hdGVkLklzSW1wZXJzb25hdGVkKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgbGFuZyA9IGhpYWJjb25maWcuaW1wZXJzb25hdG9yLmxhbmc7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpbXBlcnNvbmF0ZWQtc2lnbm91dFwiPlxyXG5cdFx0XHRcdDxhIGhyZWY9XCIjXCIgb25DbGljaz17dGhpcy5wcm9wcy5oYW5kbGVTaWduT3V0LmJpbmQodGhpcyl9PntsYW5nLnNpZ25vdXR9PC9hPlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBJbXBlcnNvbmF0ZWRTaWdub3V0O1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCJpbXBvcnQgJ2JhYmVsLXBvbHlmaWxsJztcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IGZvdW5kYXRpb24gZnJvbSAnLi92ZW5kb3JzL2ZvdW5kYXRpb24nO1xyXG5pbXBvcnQgQ3VzdG9tRXZlbnRzIGZyb20gJy4vX2xpYi9jdXN0b20tZXZlbnRzJztcclxuaW1wb3J0IHRvZ2dsZXIgZnJvbSAnLi9fbGliL3RvZ2dsZXInO1xyXG5pbXBvcnQgdG9nZ2xlckhlYWRlciBmcm9tICcuL19saWIvdG9nZ2xlckhlYWRlcic7XHJcbmltcG9ydCBzdGFydHBhZ2VzbGlkZXIgZnJvbSAnLi9fbGliL3N0YXJ0cGFnZS1zbGlkZXInO1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgSWxsdXN0cmF0aW9uQ29udGFpbmVyIGZyb20gJy4vaWxsdXN0cmF0aW9uJztcclxuaW1wb3J0IGFkZGNsYXNzIGZyb20gJy4vX2xpYi9hZGRjbGFzcyc7XHJcbmltcG9ydCBicmFuZHRyZWUgZnJvbSAnLi9fbGliL2JyYW5kdHJlZSc7XHJcbmltcG9ydCBzY3JvbGx0byBmcm9tICcuL19saWIvc2Nyb2xsdG8nO1xyXG5pbXBvcnQgTGFuZ3VhZ2VTZWxlY3RvciBmcm9tICcuL2NvbXBvbmVudHMvaGVhZGVyL2xhbmd1YWdlX3NlbGVjdG9yJztcclxuaW1wb3J0IGxpc3R2aWV3dG9nZ2xlIGZyb20gJy4vX2xpYi9saXN0dmlld3RvZ2dsZSc7XHJcbmltcG9ydCBjb21wbGFpbnR2aWV3IGZyb20gJy4vX2xpYi9jb21wbGFpbnR2aWV3JztcclxuaW1wb3J0IGJhdGNob3JkZXIgZnJvbSAnLi9iYXRjaG9yZGVyL2JhdGNob3JkZXInO1xyXG5pbXBvcnQgcHJvZHVjdGltYWdlem9vbSBmcm9tICcuL19saWIvcHJvZHVjdGltYWdlem9vbSc7XHJcbmltcG9ydCBqcXVlcnlzdHVjayBmcm9tICdqcXVlcnkuc3R1Y2snO1xyXG5pbXBvcnQgbWluaWNhcnQgZnJvbSAnLi9taW5pY2FydC9taW5pY2FydCc7XHJcbmltcG9ydCBzY3JvbGxjb250cm9scyBmcm9tICcuL19saWIvc2Nyb2xsY29udHJvbHMnO1xyXG5pbXBvcnQgc2Nyb2xsY29udHJvbHNQcm9kdWN0RGV0YWlsIGZyb20gJy4vX2xpYi9zY3JvbGxjb250cm9scy1wcm9kdWN0ZGV0YWlsJztcclxuaW1wb3J0IGFkZHRvY2FydCBmcm9tICcuL19saWIvYWRkdG9jYXJ0JztcclxuaW1wb3J0IGZpbGV1cGxvYWQgZnJvbSAnLi9iYXRjaG9yZGVyL3VwbG9hZGZpbGUnO1xyXG5pbXBvcnQgYmF0Y2hvcmRlcmNhcnQgZnJvbSAnLi9iYXRjaG9yZGVyL2JhdGNob3JkZXItY2FydCc7XHJcbmltcG9ydCBjaGVja291dCBmcm9tICcuL2NoZWNrb3V0L2NoZWNrb3V0LW5ldyc7XHJcbmltcG9ydCBub3RpZmljYXRpb25zIGZyb20gJy4vbm90aWZpY2F0aW9ucy9ub3RpZmljYXRpb25zJztcclxuaW1wb3J0IFdhdmVzIGZyb20gJ3dhdmVzJztcclxuaW1wb3J0IHVzZXJhZGRyZXNzZXMgZnJvbSAnLi9fbGliL3VzZXJhZGRyZXNzZXMnO1xyXG5pbXBvcnQgcHJpbnQgZnJvbSAnLi9fbGliL3ByaW50JztcclxuaW1wb3J0IHNlbWFudGljZHJvcGRvd24gZnJvbSAnLi9fbGliL3NlbWFudGljLWRyb3Bkb3duJztcclxuaW1wb3J0IGF1dG9zdWJtaXQgZnJvbSAnLi9fbGliL2F1dG9zdWJtaXQnO1xyXG5pbXBvcnQgaW1wZXJzb25hdG9yIGZyb20gJy4vaW1wZXJzb25hdG9yL2ltcGVyc29uYXRvcic7XHJcbmltcG9ydCBmb3VuZGF0aW9uZGF0ZXBpY2tlciBmcm9tICcuL19saWIvZGF0ZXBpY2tlcic7XHJcbmltcG9ydCAnLi9zZXJ2ZXInO1xyXG5pbXBvcnQgZm91bmRhdGlvbmRhdGVwaWNrZXJsYW5nIGZyb20gJy4vX2xpYi9kYXRlcGlja2VyLWxhbmcnO1xyXG5pbXBvcnQgc2VhcmNocmVzdWx0IGZyb20gJy4vX2xpYi9zZWFyY2hyZXN1bHQnO1xyXG5pbXBvcnQgSUVlcXVhbGl6ZXJGaXggZnJvbSAnLi9fbGliL2llLWVxdWFsaXplci1maXgnO1xyXG5pbXBvcnQgY29va2llIGZyb20gJy4vX2xpYi9jb29raWUnO1xyXG5pbXBvcnQgY2xlYXJjYXJ0IGZyb20gJy4vX2xpYi9jbGVhci1jYXJ0JztcclxuaW1wb3J0IGRldGVjdFZlbmRvciBmcm9tICcuL19saWIvZGV0ZWN0VmVuZG9yJztcclxuaW1wb3J0IHByb2R1Y3RDb250YWlucyBmcm9tICcuL19saWIvcHJvZHVjdC1jb250YWlucyc7XHJcbmltcG9ydCBjb25maXJtYXRpb25QYWdlIGZyb20gJy4vX2xpYi9jb25maXJtYXRpb25wYWdlJztcclxuaW1wb3J0IFByb2R1Y3RDYXJkRm9vdGVyIGZyb20gJy4vX2xpYi9wcm9kdWN0LWNhcmQtZm9vdGVyJztcclxuaW1wb3J0IHNjYWxlZFByaWNlcyBmcm9tICcuL19saWIvc2NhbGVkLXByaWNlcyc7XHJcbmltcG9ydCBzaGFyZSBmcm9tICcuL19saWIvc2hhcmUnO1xyXG5pbXBvcnQgV2lzaGxpc3RIZWFkZXIgZnJvbSAnLi9jb21wb25lbnRzL3dpc2hsaXN0L3dpc2hsaXN0SGVhZGVyJztcclxuaW1wb3J0IFdpc2hsaXN0TGlzdGluZyBmcm9tICcuL2NvbXBvbmVudHMvd2lzaGxpc3Qvd2lzaGxpc3RMaXN0aW5nJztcclxuaW1wb3J0IFdpc2hsaXN0RGV0YWlscyBmcm9tICcuL2NvbXBvbmVudHMvd2lzaGxpc3Qvd2lzaGxpc3REZXRhaWwnO1xyXG5pbXBvcnQgZml0c015TWFjaGluZSBmcm9tICcuL19saWIvZml0c19teV9tYWNoaW5lJztcclxuaW1wb3J0IHNlbGZyZWdpc3RyYXRpb24gZnJvbSAnLi9fbGliL3NlbGZyZWdpc3RyYXRpb24nO1xyXG5pbXBvcnQgb3JkZXJIaXN0b3J5IGZyb20gJy4vb3JkZXJoaXN0b3J5L29yZGVyaGlzdG9yeSc7XHJcbmltcG9ydCBTYWxlc2ZvcmNlUmVjb21tZW5kYXRpb25zIGZyb20gJy4vc2FsZXNmb3JjZXJlY29tbWVuZGF0aW9ucy9zYWxlc2ZvcmNlcmVjb21tZW5kYXRpb25zJztcclxuXHJcbmxldCBoaWFiID0ge1xyXG4gIGluaXQoKSB7XHJcblxyXG5cclxuICAgIGZvdW5kYXRpb24uaW5pdCgpO1xyXG4gICAgUHJvZHVjdENhcmRGb290ZXIuaW5pdCgpO1xyXG4gICAgQ3VzdG9tRXZlbnRzLmluaXQoKTtcclxuICAgIExhbmd1YWdlU2VsZWN0b3IuaW5pdCgpO1xyXG4gICAgY29va2llLmluaXQoKTtcclxuICAgIGlmICgkKCcuc3RhcnRwYWdlLXNsaWRlcicpLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0c3RhcnRwYWdlc2xpZGVyLmluaXQoKTtcclxuXHRcdH1cclxuICAgIGltcGVyc29uYXRvci5pbml0KCk7XHJcbiAgICBkZXRlY3RWZW5kb3IuaW5pdCgpO1xyXG5cdFx0aWYgKCQoJ21haW4udWMtY2hlY2tvdXQnKS5sZW5ndGggPiAwKSB7XHJcbiAgICBcdGNoZWNrb3V0LmluaXQoKTtcclxuICAgIH1cclxuICAgIFNhbGVzZm9yY2VSZWNvbW1lbmRhdGlvbnMuaW5pdCgpO1xyXG4gICAgdG9nZ2xlci5pbml0KCk7XHJcbiAgICB0b2dnbGVySGVhZGVyLmluaXQoKTtcclxuICAgIGFkZGNsYXNzLmluaXQoKTtcclxuICBcclxuICAgIGJhdGNob3JkZXIuaW5pdCgpO1xyXG4gICAgc2Nyb2xsdG8uaW5pdCgpO1xyXG5cclxuICAgIGxpc3R2aWV3dG9nZ2xlLmluaXQoKTtcclxuICAgIGNvbXBsYWludHZpZXcuaW5pdCgpO1xyXG4gICAgbWluaWNhcnQuaW5pdCgpO1xyXG4gICAgbm90aWZpY2F0aW9ucy5pbml0KCk7XHJcbiAgICBzY3JvbGxjb250cm9scy5pbml0KCk7XHJcblxyXG5cdFx0aWYoICQoJy5wcm9kdWN0LWRldGFpbHBhZ2UnKS5sZW5ndGggPiAwICl7XHJcblx0XHRcdHNjcm9sbGNvbnRyb2xzUHJvZHVjdERldGFpbC5pbml0KCk7XHJcblx0XHR9XHJcblxyXG4gICAgYWRkdG9jYXJ0LmluaXQoKTtcclxuICAgIGJhdGNob3JkZXJjYXJ0LmluaXQoKTtcclxuICAgIHVzZXJhZGRyZXNzZXMuaW5pdCgpO1xyXG4gICAgcHJpbnQuaW5pdCgpO1xyXG4gICAgc2VtYW50aWNkcm9wZG93bi5pbml0KCk7XHJcbiAgICBhdXRvc3VibWl0LmluaXQoKTtcclxuXHJcbiAgICBmb3VuZGF0aW9uZGF0ZXBpY2tlci5pbml0KCk7XHJcbiAgICBzZWFyY2hyZXN1bHQuaW5pdCgpO1xyXG5cclxuICAgIGFkZHRvY2FydC5pbml0KCk7XHJcbiAgICBJRWVxdWFsaXplckZpeC5pbml0KCk7XHJcblxyXG4gICAgY2xlYXJjYXJ0LmluaXQoKTtcclxuXHJcbiAgICAvLyBzcGlubmVyLmluaXQoKTtcclxuICAgIGNvbmZpcm1hdGlvblBhZ2UuaW5pdCgpO1xyXG5cdFx0JCh3aW5kb3cpLnN0dWNrKCk7XHJcbiAgICBpZigkKCcuYWNjb3JkaW9uJykubGVuZ3RoID4gMCl7XHJcbiAgICAgICQoZG9jdW1lbnQpLmZvdW5kYXRpb24oe1xyXG4gICAgICAgIGFjY29yZGlvbjoge1xyXG4gICAgICAgICAgbXVsdGlfZXhwYW5kOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgaWYoJCgnLmNvbXBsZW1lbnRhcnktaW5mb3JtYXRpb24nKS5sZW5ndGggPiAwKXtcclxuXHRcdFx0cHJvZHVjdENvbnRhaW5zLmluaXQoKTtcclxuXHRcdH1cclxuXHRcdGlmICgkKCcjcHJvZHVjdEltYWdlcycpLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0cHJvZHVjdGltYWdlem9vbS5pbml0KCk7XHJcblx0XHR9XHJcbiAgICBpZigkKCcuc2NhbGVkLXByaWNlcycpLmxlbmd0aCA+IDApe1xyXG4gICAgICBzY2FsZWRQcmljZXMuaW5pdCgpO1xyXG4gICAgfVxyXG5cdFx0aWYgKCQoJy51Yy1maWxldXBsb2FkJykubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRmaWxldXBsb2FkLmluaXQoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoJCgnLnNoYXJlLW1vZGFsJykubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRzaGFyZS5pbml0KCk7XHJcblx0XHR9XHJcbiAgICBpZigkKCcuZG9lcy10aGlzLWZpdC1teS1tYWNoaW5lJykubGVuZ3RoID4gMCkge1xyXG4gICAgICBmaXRzTXlNYWNoaW5lLmluaXQoKTtcclxuICAgIH1cclxuICAgIGlmKCQoJy51Yy1jbXMtY29udGVudCAuaXRlbS13cmFwcGVyJykubGVuZ3RoID4gMCl7XHJcblxyXG4gICAgICB2YXIgbmFtZUhlaWdodCA9IDA7XHJcbiAgICAgICQoJy51Yy1jbXMtY29udGVudCAuaXRlbS13cmFwcGVyIC5pdGVtLW5hbWUnKS5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgaWYoJCh0aGlzKS5oZWlnaHQoKSA+ICBuYW1lSGVpZ2h0KXtcclxuICAgICAgICAgIG5hbWVIZWlnaHQgPSAkKHRoaXMpLmhlaWdodCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAkKCcudWMtY21zLWNvbnRlbnQgLml0ZW0td3JhcHBlciAuaXRlbS1uYW1lJykuaGVpZ2h0KG5hbWVIZWlnaHQpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHZhciBwcmljZVN0b2NrSGVpZ2h0ID0gMDtcclxuICAgICAgJCgnLnVjLWNtcy1jb250ZW50IC5pdGVtLXdyYXBwZXIgLmFtb3VudC1wcmljZS1zdG9jaycpLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICBpZigkKHRoaXMpLmhlaWdodCgpID4gIHByaWNlU3RvY2tIZWlnaHQpe1xyXG4gICAgICAgICAgcHJpY2VTdG9ja0hlaWdodCA9ICQodGhpcykuaGVpZ2h0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgICQoJy51Yy1jbXMtY29udGVudCAuaXRlbS13cmFwcGVyIC5hbW91bnQtcHJpY2Utc3RvY2snKS5oZWlnaHQocHJpY2VTdG9ja0hlaWdodCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmKCQoJy51Yy1zaXRlaGVhZGVyIC51Yy13aXNobGlzdC53aXNobGlzdC1oZWFkZXInKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgIFdpc2hsaXN0SGVhZGVyLmluaXQoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZigkKCcubWFpbi1jb250ZW50LnVjLXdpc2hsaXN0Om5vdCgud2lzaGxpc3QtZGV0YWlsKScpLmxlbmd0aCA+IDApIHtcclxuICAgICAgV2lzaGxpc3RMaXN0aW5nLmluaXQoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZigkKCcubWFpbi1jb250ZW50LnVjLXdpc2hsaXN0Lndpc2hsaXN0LWRldGFpbCcpLmxlbmd0aCA+IDApIHtcclxuICAgICAgV2lzaGxpc3REZXRhaWxzLmluaXQoKTtcclxuICAgIH1cclxuXHJcblx0XHRXYXZlcy5hdHRhY2goJ2J1dHRvbicsIFsnd2F2ZXMtbGlnaHQnXSk7XHJcblx0XHRXYXZlcy5pbml0KCk7XHJcblxyXG4gICAgJCgnaW1nJykuYmluZCgnY29udGV4dG1lbnUnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnYm9keScpLm9uKCdrZXlwcmVzcycsICcucXVhbnRpdHksIC5hbW91bnQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICB2YXIgeDtcclxuICAgICAgdmFyIGlzSW50O1xyXG5cclxuICAgICAgaWYgKChlLndoaWNoICE9PSA4ICYmIGUud2hpY2ggIT09IDAgJiYgKGUud2hpY2ggPCA0OCB8fCBlLndoaWNoID4gNTcpKSB8fCBlLndoaWNoID09PSAzMikge1xyXG4gICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZXtcclxuICAgICAgICBpc0ludCA9IGlzTmFOKFN0cmluZy5mcm9tQ2hhckNvZGUoZS5rZXlDb2RlKSkgPyAhMSA6ICh4ID0gcGFyc2VGbG9hdChTdHJpbmcuZnJvbUNoYXJDb2RlKGUua2V5Q29kZSkpLCAoMCB8IHgpID09PSB4KTtcclxuICAgICAgICAvL2Uua2V5IHdvbnQgd29yayBpbiBzb21lIGJyb3dzZXJzIGNoZWNrIGlmIHVuZGVmaW5lZFxyXG4gICAgICAgIC8vaWYgaXQgaXMgdW5kZWZpbmVkIHVzZSBTdHJpbmcuZnJvbUNoYXJDb2RlKGUua2V5Q29kZSlcclxuICAgICAgICBpZih0eXBlb2YgZS5rZXkgIT09ICd1bmRlZmluZWQnKXtcclxuICAgICAgICAgIGlzSW50ID0gaXNOYU4oZS5rZXkpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQoZS5rZXkpLCAoMCB8IHgpID09PSB4KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy9DaGVjayBpZiBpbnB1dCBpcyBpbnQsIGJhY2tzcGFjZSBvciBsZWZ0LCByaWdodCwgdXAsIGRvd25cclxuICAgICAgICAvL3NvbWUgYnJvd3NlcnMgZGV0ZWN0IGJhY2tzcGFjZSBhbmQgbGVmdCwgcmlnaHQsIHVwLCBkb3duIHdoaWNoIHdvbnQgdmFsaWRhdGUgYXMgaW50c1xyXG4gICAgICAgIGlmKGlzSW50IHx8IGUud2hpY2ggPT09IDggfHwgKGUud2hpY2ggPCAzOCB8fCBlLndoaWNoID4gNDEpKXtcclxuICAgICAgICAgIC8vZS5rZXkgd29udCB3b3JrIGluIHNvbWUgYnJvd3NlcnMgY2hlY2sgaWYgdW5kZWZpbmVkXHJcbiAgICAgICAgICAvL2lmIGl0IGlzIHVuZGVmaW5lZCB1c2UgU3RyaW5nLmZyb21DaGFyQ29kZShlLmtleUNvZGUpXHJcbiAgICAgICAgICBpZih0eXBlb2YgZS5rZXkgIT09ICd1bmRlZmluZWQnKXtcclxuICAgICAgICAgICAgcmV0dXJuIGUua2V5IDwgMSAmJiBlLnRhcmdldC52YWx1ZS5sZW5ndGggPT09IDAgPyBmYWxzZSA6IHRydWU7XHJcbiAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoZS5rZXlDb2RlKSA8IDEgJiYgZS50YXJnZXQudmFsdWUubGVuZ3RoID09PSAwID8gZmFsc2UgOiB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgICQoJ2JvZHknKS5vbigna2V5dXAnLCAnLnF1YW50aXR5LCAuYW1vdW50JywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyIHg7XHJcbiAgICAgIHZhciBpc0ludCA9IGlzTmFOKHRoaXMudmFsdWUpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQodGhpcy52YWx1ZSksICgwIHwgeCkgPT09IHgpO1xyXG4gICAgICBpZihpc0ludCAmJiBwYXJzZUZsb2F0KHRoaXMudmFsdWUpID09PSAwKXtcclxuICAgICAgICB0aGlzLnZhbHVlID0gJzEnO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCdib2R5Jykub24oJ2JsdXInLCAnLnF1YW50aXR5LCAuYW1vdW50JywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgaWYodGhpcy52YWx1ZSA9PT0gJycpe1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmRlZmF1bHRWYWx1ZTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnYm9keScpLm9uKCdzdWJtaXQnLCAnLnJlc2V0LXBhc3N3b3JkJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgJCgnI2J0bkNoYW5nZVBzdycpLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZigkKCcjYWNjb3VudC1pbmZyb21hdGlvbi1mb3JtJykubGVuZ3RoID4gMCl7XHJcbiAgICAgICQoJyNhY2NvdW50LWluZnJvbWF0aW9uLWZvcm0gaW5wdXQnKS5vbignYmx1cicsIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgdmFyIGlucHV0TmFtZSA9ICQodGhpcylbMF0ubmFtZTtcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IEZvdW5kYXRpb24ubGlicy5hYmlkZS52YWxpZGF0ZSgkKCcjYWNjb3VudC1pbmZyb21hdGlvbi1mb3JtJykuZmluZCgnaW5wdXRbbmFtZT0nK2lucHV0TmFtZSsnXScpLCB7dHlwZTonJ30pOyB9LCA1MDApO1xyXG5cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYoJCgnI2lsbHVzdHJhdGlvbicpLmxlbmd0aCA+IDApe1xyXG4gICAgICBicmFuZHRyZWUuaW5pdCgpO1xyXG4gICAgICB2YXIgZXhwbG9kZWRWaWV3VXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmV4cGxvZGVkVmlld3NOYW1lSW5Vcmw7XHJcbiAgICAgIHZhciB1cmxQYXJ0cyA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcvJyk7XHJcbiAgICAgIGlmKHVybFBhcnRzLmluZGV4T2YoZXhwbG9kZWRWaWV3VXJsKSAhPT0gLTEgJiYgdXJsUGFydHNbdXJsUGFydHMuaW5kZXhPZihleHBsb2RlZFZpZXdVcmwpICsgMV0gPT09ICcnKXtcclxuICAgICAgICAkKCAnYm9keScgKS5hZGRDbGFzcygnYnJhbmR0cmVlLW9wZW4nKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmKCQoJy51Yy1vcmRlci1oaXN0b3J5JykubGVuZ3RoID4gMCkge1xyXG4gICAgICBvcmRlckhpc3RvcnkuaW5pdCgpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBpZiAoJCgnI3NlbGYtcmVnaXN0cmF0aW9uJykpXHJcbiAgICB7XHJcbiAgICAgIHNlbGZyZWdpc3RyYXRpb24uaW5pdCgpO1xyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCQpIHtcclxuXHRoaWFiLmluaXQoKTtcclxufSk7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgTWluaWNhcnRDb250ZW50IGZyb20gJy4vbWluaWNhcnRfY29udGVudCc7XHJcbmltcG9ydCBDYXJ0QXBpIGZyb20gJy4uL19hcGkvY2FydF9hcGknO1xyXG5pbXBvcnQgTWluaWNhcnRUb3RhbFByaWNlIGZyb20gJy4vbWluaWNhcnRfdG90YWxwcmljZSc7XHJcbmltcG9ydCBNaW5pY2FydFRvdGFsSXRlbXMgZnJvbSAnLi9taW5pY2FydF90b3RhbGl0ZW1zJztcclxuXHJcbmxldCBtaW5pY2FydCA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0dGhpcy5taW5pY2FydENvbnRlbnRFbG0gICAgICA9ICQoJyNtaW5pY2FydC1jb250ZW50Jyk7XHJcblx0XHR0aGlzLm1pbmljYXJ0Rm9vdGVyRWxtICAgICAgID0gJCgnI2NhcnQtZm9vdGVyLXRvdGFsLXZhbHVlJyk7XHJcblx0XHR0aGlzLm1pbmljYXJ0SGVhZGVyUHJpY2VFbG0gID0gJCgnI3RvdGFsLWNhcnQtdmFsdWUnKTtcclxuXHRcdHRoaXMubWluaWNhcnRIZWFkZXJJdGVtc0VsbSAgPSAkKCcjbnVtLW9mLWNhcnQtaXRlbXMnKTtcclxuXHRcdHRoaXMubWluaWNhcnRTdGlja3lJdGVtc0VsbSAgPSAkKCcjbnVtLW9mLWNhcnQtaXRlbXMtc3RpY2t5Jyk7XHJcblxyXG5cdFx0Ly9SZW5kZXIgbWluaWNhcnRcclxuXHRcdHRoaXMucmVuZGVyUmVhY3RDb21wb25lbnRzKCk7XHJcblxyXG5cdFx0ZnVuY3Rpb24gY2xvc2VDbGVhckNhcnQoKSB7XHJcblx0XHRcdCQoJy5jbGVhci1jYXJ0JykucmVtb3ZlQ2xhc3MoJ2lzLW9wZW4nKTtcclxuXHRcdH1cclxuXHJcblx0XHQkKCcjY2hlY2tvdXQtYnV0dG9uJykuY2xpY2soZnVuY3Rpb24oKSB7XHJcblx0XHRcdGxldCBjaGVja291dFVybCA9ICQodGhpcykuZGF0YSgnY2hlY2tvdXQtdXJsJyk7XHJcblx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0JCgnLmNsZWFyLWNhcnQgYnV0dG9uJykucHJvcChcImRpc2FibGVkXCIsdHJ1ZSk7XHJcblx0XHRcdGlmKCQoJy5jbGVhci1jYXJ0JykuaGFzQ2xhc3MoJ2lzLW9wZW4nKSl7XHJcblx0XHRcdFx0Y2xvc2VDbGVhckNhcnQoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZih0eXBlb2YgZGF0YUxheWVyICE9PSAndW5kZWZpbmVkJyAmJiBoaWFiY29uZmlnLkVuYWJsZUdvb2dsZVRhZ01hbmFnZXIpe1xyXG5cdFx0XHRcdGRhdGFMYXllci5wdXNoKHtcclxuXHRcdFx0ICAgICdldmVudCc6ICdjaGVja291dCcsXHJcblx0XHRcdCAgICAnZWNvbW1lcmNlJzoge1xyXG5cdFx0XHQgICAgICAnY2hlY2tvdXQnOiB7XHJcblx0XHRcdCAgICAgICAgJ2FjdGlvbkZpZWxkJzogeydzdGVwJzogMSB9LFxyXG5cdFx0XHQgICAgICAgICdwcm9kdWN0cyc6IFtdXHJcblx0XHRcdCAgICAgfVxyXG5cdFx0XHQgICB9XHJcblx0XHRcdCBcdH0pO1xyXG5cdFx0IFx0fVxyXG5cdFx0XHR3aW5kb3cubG9jYXRpb24uaHJlZiA9IGNoZWNrb3V0VXJsO1xyXG5cdFx0fSk7XHJcblx0XHQkKCcubWluaWNhcnQtaGVhZGVyIGJ1dHRvbicpLmNsaWNrKGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZigkKCcuY2xlYXItY2FydCcpLmhhc0NsYXNzKCdpcy1vcGVuJykpe1xyXG5cdFx0XHRcdGNsb3NlQ2xlYXJDYXJ0KCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0JCgnLmV4aXQtb2ZmLWNhbnZhcycpLmNsaWNrKGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZigkKCcuY2xlYXItY2FydCcpLmhhc0NsYXNzKCdpcy1vcGVuJykpe1xyXG5cdFx0XHRcdGNsb3NlQ2xlYXJDYXJ0KCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHJlbmRlclJlYWN0Q29tcG9uZW50cygpIHtcclxuXHRcdGlmKHRoaXMubWluaWNhcnRDb250ZW50RWxtLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0UmVhY3RET00ucmVuZGVyKDxNaW5pY2FydENvbnRlbnQvPiwgdGhpcy5taW5pY2FydENvbnRlbnRFbG1bMF0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKHRoaXMubWluaWNhcnRGb290ZXJFbG0ubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRSZWFjdERPTS5yZW5kZXIoPE1pbmljYXJ0VG90YWxQcmljZS8+LCB0aGlzLm1pbmljYXJ0Rm9vdGVyRWxtWzBdKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZih0aGlzLm1pbmljYXJ0SGVhZGVyUHJpY2VFbG0ubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRSZWFjdERPTS5yZW5kZXIoPE1pbmljYXJ0VG90YWxQcmljZS8+LCB0aGlzLm1pbmljYXJ0SGVhZGVyUHJpY2VFbG1bMF0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKHRoaXMubWluaWNhcnRIZWFkZXJJdGVtc0VsbS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFJlYWN0RE9NLnJlbmRlcig8TWluaWNhcnRUb3RhbEl0ZW1zLz4sIHRoaXMubWluaWNhcnRIZWFkZXJJdGVtc0VsbVswXSk7XHJcblx0XHR9XHJcblx0XHRpZih0aGlzLm1pbmljYXJ0U3RpY2t5SXRlbXNFbG0ubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRSZWFjdERPTS5yZW5kZXIoPE1pbmljYXJ0VG90YWxJdGVtcy8+LCB0aGlzLm1pbmljYXJ0U3RpY2t5SXRlbXNFbG1bMF0pO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG1pbmljYXJ0O1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBDYXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jYXJ0X3N0b3JlJztcclxuaW1wb3J0IENhcnRBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL2NhcnRfYWN0aW9ucyc7XHJcbmltcG9ydCBNaW5pY2FydExpbmVJdGVtIGZyb20gJy4vbWluaWNhcnRfbGluZWl0ZW0nO1xyXG5cclxuY2xhc3MgTWluaWNhcnRDb250ZW50IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0Y2FydDoge1xyXG5cdFx0XHRcdENhcnRJdGVtczogW11cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZE1vdW50KCkge1xyXG5cdFx0aWYoaGlhYmNvbmZpZy51c2VyTG9nZ2VkSW4pe1xyXG5cdFx0XHRDYXJ0QWN0aW9ucy5sb2FkQ2FydCh0cnVlKTtcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0dGhpcy51bnN1YnNjcmliZSA9IENhcnRTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0Y2FydDogQ2FydFN0b3JlLmdldFN0b3JlKCkuQ2FydFxyXG5cdFx0XHR9KVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKCF0aGlzLnN0YXRlLmNhcnQgfHwgIXRoaXMuc3RhdGUuY2FydC5DYXJ0SXRlbXMpIHJldHVybiBudWxsO1xyXG5cdFx0bGV0IGxpbmVJdGVtcyA9IHRoaXMuc3RhdGUuY2FydC5DYXJ0SXRlbXMubWFwKChsaW5lSXRlbSkgPT4ge1xyXG5cdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdDxNaW5pY2FydExpbmVJdGVtIGtleT17bGluZUl0ZW0uQ29kZX0gaXRlbT17bGluZUl0ZW19IC8+XHJcblx0XHRcdCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8dWw+XHJcblx0XHRcdFx0e2xpbmVJdGVtc31cclxuXHRcdFx0PC91bD5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTWluaWNhcnRDb250ZW50O1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBDYXJ0QWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9jYXJ0X2FjdGlvbnMnO1xyXG5pbXBvcnQgQ2FydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2FydF9zdG9yZSc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5cclxuY2xhc3MgTWluaWNhcnRMaW5lSXRlbSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGxvYWRpbmc6IGZhbHNlLFxyXG5cdFx0XHRpdGVtVmFsdWU6IDBcclxuXHRcdH07XHJcblxyXG5cdH1cclxuXHJcblx0aGFuZGxlU3VibWl0ID0gKGUpID0+IHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdHRoaXMuaGFuZGxlQmx1cigpO1xyXG5cdH1cclxuXHJcblx0aXNJbnQodmFsdWUpIHtcclxuICBcdHZhciB4O1xyXG5cdFx0dmFyIGlzSW50ID0gaXNOYU4odmFsdWUpID8gITEgOiAoeCA9IHBhcnNlRmxvYXQodmFsdWUpLCAoMCB8IHgpID09PSB4KTtcclxuXHRcdGlmKGlzSW50KXtcclxuXHRcdFx0cmV0dXJuIHZhbHVlIDwgMSAmJiB2YWx1ZS5sZW5ndGggPT09IDEgPyBmYWxzZSA6IHRydWU7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2hhbmdlKGUpIHtcclxuXHRcdGxldCBxdWFudGl0eSA9IGUudGFyZ2V0LnZhbHVlO1xyXG5cdFx0aWYocXVhbnRpdHkgIT09ICcnICYmICF0aGlzLmlzSW50KHF1YW50aXR5KSApIHJldHVybjtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe2l0ZW1WYWx1ZTogcXVhbnRpdHl9KTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZUJsdXIoKSB7XHJcblx0XHRsZXQgc2t1SUQgICAgPSB0aGlzLnByb3BzLml0ZW0uQ29kZSxcclxuXHRcdCAgICBxdWFudGl0eSA9IHRoaXMuc3RhdGUuaXRlbVZhbHVlO1xyXG5cdFx0Ly8gUmVzZXQgdG8gaW50aWFsIHF1YW50aXR5IGlmIHRoZSBmaWVsZCBpcyBlbXB0eSBvbiBibHVyXHJcblx0XHRpZihxdWFudGl0eSA9PT0gJycpe1xyXG4gXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aXRlbVZhbHVlOiB0aGlzLnByb3BzLml0ZW0uUXVhbnRpdHlcclxuXHRcdFx0fSk7XHJcblx0XHRcdHF1YW50aXR5ID0gdGhpcy5wcm9wcy5pdGVtLlF1YW50aXR5O1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRpZih0aGlzLnByb3BzLml0ZW0uUXVhbnRpdHkgIT09IHBhcnNlSW50KHF1YW50aXR5KSkge1xyXG5cdFx0XHRDYXJ0QWN0aW9ucy51cGRhdGVDYXJ0SXRlbShza3VJRCwgcXVhbnRpdHkpO1xyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtsb2FkaW5nOnRydWV9KTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRoYW5kbGVEZWxldGUgPSAoZSkgPT4ge1xyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0bGV0IHNrdUlEID0gdGhpcy5wcm9wcy5pdGVtLkNvZGU7XHJcblx0XHRDYXJ0QWN0aW9ucy5kZWxldGVDYXJ0SXRlbShza3VJRCk7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtsb2FkaW5nOnRydWV9KTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMocHJvcHMpIHtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRsb2FkaW5nOmZhbHNlLFxyXG5cdFx0XHRpdGVtVmFsdWU6IHByb3BzLml0ZW0uUXVhbnRpdHlcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb21wb25lbnREaWRNb3VudCgpe1xyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdGl0ZW1WYWx1ZTogdGhpcy5wcm9wcy5pdGVtLlF1YW50aXR5XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuXHRcdC8vIHRoaXMudXBkYXRlUXVhbnRpdHkoKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGxldCBpdGVtID0gdGhpcy5wcm9wcy5pdGVtO1xyXG5cdFx0bGV0IGltYWdlID0gJy9zdHlsZXMvaW1hZ2VzL3Byb2R1Y3QtcGxhY2Vob2xkZXIyeDIucG5nJztcclxuXHRcdGlmKGl0ZW0uSW1hZ2VVcmwgJiYgaXRlbS5JbWFnZVVybCAhPT0gJycpIGltYWdlID0gaXRlbS5JbWFnZVVybCsnP3ByZXNldD1taW5pJztcclxuXHJcblx0XHRsZXQgbGFuZyA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5sYW5nO1xyXG5cclxuXHRcdGxldCBwYXJ0T2ZDYW1wYWlnbiA9IGl0ZW0uSGFzUHJvbW90aW9uO1xyXG5cclxuXHRcdGxldCBpdGVtQ2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J2xvYWRpbmcnOiB0aGlzLnN0YXRlLmxvYWRpbmcsXHJcblx0XHRcdCdpcy1kaXNjb3VudGVkJzogcGFydE9mQ2FtcGFpZ25cclxuXHRcdH0pO1xyXG5cdFx0bGV0IGRlZmF1bHRQcmljZUNvbnRhaW5lciA9IHBhcnRPZkNhbXBhaWduID8gKDxzcGFuIGNsYXNzTmFtZT1cImRlZmF1bHRcIj57aXRlbS5QcmljZX0gLSA8L3NwYW4+KSA6IG51bGw7XHJcblx0XHRsZXQgZ3Jvc3NEaXNjb3VudENvbnRpYW5lciA9IGl0ZW0uSXNEaXNjb3VudGVkID9cclxuXHRcdFx0KDxzcGFuIGNsYXNzTmFtZT1cImdyb3NzLWRpc2NvdW50LWNvbnRpYW5lclwiPlxyXG5cdFx0XHRcdHtkZWZhdWx0UHJpY2VDb250YWluZXJ9XHJcblx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiZ3Jvc3NcIj57bGFuZy5ncm9zc3ByaWNlfSB7aXRlbS5EZWZhdWx0UHJpY2V9PC9zcGFuPlxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImRpc2NvdW50XCI+e2xhbmcucHJvbW90aW9uVGl0bGV9IHtpdGVtLkRpc2NvdW50UGVyY2VudGFnZX08L3NwYW4+XHJcblx0XHRcdDwvc3Bhbj4pIDpcclxuXHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiZ3Jvc3MtZGlzY291bnQtY29udGlhbmVyXCI+PHNwYW4gY2xhc3NOYW1lPVwiZGVmYXVsdFwiPntpdGVtLlByaWNlfTwvc3Bhbj48L3NwYW4+O1xyXG5cdFx0aWYoIWl0ZW0uSXNEaXNjb3VudGVkICYmICFpdGVtLkhhc1Byb21vdGlvbil7XHJcblx0XHRcdGdyb3NzRGlzY291bnRDb250aWFuZXIgPSBudWxsO1xyXG5cdFx0fVxyXG5cdFx0bGV0IGFsdFRleHQgPSBpdGVtLkNvZGUrXCIgXCIraXRlbS5EaXNwbGF5TmFtZTtcclxuXHRcdGxldCBwbGFjZWRQcmljZSA9IDxzcGFuIGNsYXNzTmFtZT1cInByaWNlIGxlZnRcIj54IHtpdGVtLlBsYWNlZFByaWNlfTwvc3Bhbj47XHJcblx0XHRpZihwYXJ0T2ZDYW1wYWlnbil7XHJcblx0XHRcdHBsYWNlZFByaWNlID0gPHNwYW4gY2xhc3NOYW1lPVwicHJpY2UgbGVmdFwiPnggPGRpdiBjbGFzc05hbWU9XCJkaXNjb3VudC1wcmljZVwiPjxpIGNsYXNzTmFtZT1cImljb24tdGFnc1wiPjwvaT57aXRlbS5QbGFjZWRQcmljZX08c3Bhbj4gLSA8L3NwYW4+e2xhbmcucHJvbW90aW9uVGl0bGV9IHtpdGVtLlByb21vdGlvbkRpc2NvdW50UGVyY2VudH0gJTwvZGl2Pjwvc3Bhbj47XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8bGkgY2xhc3NOYW1lPXtpdGVtQ2xhc3N9PlxyXG5cdFx0XHRcdDxmb3JtIGNsYXNzTmFtZT1cIml0ZW0td3JhcHBlciBjbGVhcmZpeCBtaW5pY2FydC1pdGVtXCIgb25TdWJtaXQ9e3RoaXMuaGFuZGxlU3VibWl0LmJpbmQodGhpcyl9PlxyXG5cdFx0XHRcdHsvKnBhcnRPZkNhbXBhaWduQ29udGFpbmVyKi99XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjYXJ0LXJvdyBjbGVhcmZpeFwiPlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImltYWdlXCI+XHJcblx0XHRcdFx0XHRcdFx0PGEgaHJlZj17aXRlbS5Vcmx9PjxpbWcgc3JjPXtpbWFnZX0gYWx0PXthbHRUZXh0fS8+PC9hPlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpdGVtLW5hbWVcIj5cclxuXHRcdFx0XHRcdFx0XHQ8aDQ+PGEgaHJlZj17aXRlbS5Vcmx9PntpdGVtLkRpc3BsYXlOYW1lfTwvYT48L2g0PlxyXG5cdFx0XHRcdFx0XHRcdDxwPlxyXG5cdFx0XHRcdFx0XHRcdFx0e2hpYWJjb25maWcuY2FydC5sYW5nLm1hdGVyaWFsTnVtYmVyfTogPHNwYW4+e2l0ZW0uQ29kZX08L3NwYW4+XHJcblx0XHRcdFx0XHRcdFx0XHR7Z3Jvc3NEaXNjb3VudENvbnRpYW5lcn1cclxuXHRcdFx0XHRcdFx0XHQ8L3A+XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tcmVtb3ZlXCI+XHJcblx0XHRcdFx0XHRcdFx0PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgb25DbGljaz17dGhpcy5oYW5kbGVEZWxldGUuYmluZCh0aGlzKX0gY2xhc3NOYW1lPVwiYnV0dG9uIG5vc3R5bGVcIj5cclxuXHRcdFx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImljb24tY2FuY2VsLWNpcmNsZWRcIj48L2k+XHJcblx0XHRcdFx0XHRcdFx0PC9idXR0b24+XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFtbW91bnQtZGF0YVwiPlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFtb3VudC1wcmljZS1zdG9jayB1LWR0XCI+XHJcblx0XHRcdFx0XHRcdFx0PGlucHV0XHJcblx0XHRcdFx0XHRcdFx0XHR0YWJJbmRleD1cIi0xXCJcclxuXHRcdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImFtb3VudFwiXHJcblx0XHRcdFx0XHRcdFx0XHRuYW1lPVwiYXVtb250LXhcIlxyXG5cdFx0XHRcdFx0XHRcdFx0b25CbHVyPXt0aGlzLmhhbmRsZUJsdXIuYmluZCh0aGlzKX1cclxuXHRcdFx0XHRcdFx0XHRcdG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUNoYW5nZS5iaW5kKHRoaXMpfVxyXG5cdFx0XHRcdFx0XHRcdFx0dmFsdWU9e3RoaXMuc3RhdGUuaXRlbVZhbHVlfSAvPlxyXG5cdFx0XHRcdFx0XHRcdFx0e3BsYWNlZFByaWNlfVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpdGVtLXRvdGFsXCI+XHJcblx0XHRcdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwicHJpY2VcIj57aXRlbS5FeHRlbmRlZFByaWNlfTwvc3Bhbj5cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8L2Zvcm0+XHJcblx0XHRcdDwvbGk+XHJcblxyXG5cdFx0KTtcclxuXHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTWluaWNhcnRMaW5lSXRlbTtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgQ2FydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2FydF9zdG9yZSc7XHJcbmltcG9ydCBPcmRlckxpbmVzQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9vcmRlcmxpbmVzX2FjdGlvbnMnO1xyXG5cclxuY2xhc3MgTWluaWNhcnRUb3RhbEl0ZW1zIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0Y2FydDoge31cclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSBDYXJ0U3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGNhcnQ6IENhcnRTdG9yZS5nZXRTdG9yZSgpLkNhcnRcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG4gICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG5cdH1cclxuXHJcblxyXG5cclxuXHRjb21wb25lbnREaWRVcGRhdGUocmVzKXtcclxuXHRcdGlmKHRoaXMuc3RhdGUuY2FydCl7XHJcblx0XHRcdC8vIGNvbnNvbGUubG9nKHRoaXMuc3RhdGUpO1xyXG5cdFx0XHQvLyBpZiggJCgnW2RhdGEtcHJvZHVjdC1za3VdJykubGVuZ3RoID4gMCAmJiAhJCgnLmRyYXdlci1tYWluJykuaGFzQ2xhc3MoJ21vdmUtbGVmdCcpKXtcclxuXHRcdFx0Ly8gXHQkKCcudWMtaGVhZGVyY2FydCcpLnJlbW92ZUNsYXNzKCdhZGRpbmcnKTtcclxuXHRcdFx0Ly8gXHQkKCcjY29udHJvbGwtY2FydCcpLnJlbW92ZUNsYXNzKCdhZGRpbmcnKTtcclxuXHRcdFx0Ly8gfVxyXG5cclxuXHRcdFx0Ly8gaWYoICQoJ1tkYXRhLWxpbmUtaXRlbV0nKS5sZW5ndGggPiAwIC8qJiYgISQoJy5kcmF3ZXItbWFpbicpLmhhc0NsYXNzKCdtb3ZlLWxlZnQnKSovKXtcclxuXHRcdFx0aWYoICQoJ1tkYXRhLWxpbmUtaXRlbV0nKS5sZW5ndGggPiAwICAmJiB0aGlzLnN0YXRlLmNhcnQuSXRlbUNvdW50ICE9PSAwKXtcclxuXHRcdFx0XHQkKCcjYWRkLXRvLWNhcnQtc3VjY2VzcycpLmZpcnN0KCkuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJyk7XHJcblx0XHRcdFx0JCgnLmZpbGV1cGxvYWQtbWVzc2FnZXMnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0JCgnLm9yZGVybGluZS1tZXNzYWdlJykuYWRkQ2xhc3MoJ3UtaGlkZGVuJyk7XHJcblx0XHRcdFx0T3JkZXJMaW5lc0FjdGlvbnMuY2xlYXIoKTtcclxuXHRcdFx0XHQkKCdidXR0b24nKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0XHRcdCQoJy51Yy1oZWFkZXJjYXJ0JykucmVtb3ZlQ2xhc3MoJ2FkZGluZycpO1xyXG5cdFx0XHRcdCQoJyNjb250cm9sbC1jYXJ0JykucmVtb3ZlQ2xhc3MoJ2FkZGluZycpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZih0aGlzLnN0YXRlLmNhcnQuSXRlbUNvdW50ID09IDApe1xyXG5cdFx0XHRcdCQoJy51Yy1oZWFkZXJjYXJ0JykucmVtb3ZlQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdFx0JCgnI2NvbnRyb2xsLWNhcnQgYnV0dG9uJykucmVtb3ZlQ2xhc3MoJ3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZXtcclxuXHRcdFx0XHQkKCcudWMtaGVhZGVyY2FydCcpLmFkZENsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHRcdCQoJyNjb250cm9sbC1jYXJ0IGJ1dHRvbicpLmFkZENsYXNzKCdyaWdodC1vZmYtY2FudmFzLXRvZ2dsZScpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZigkKCcuZHJhd2VyLW1haW4nKS5oYXNDbGFzcygnbW92ZS1sZWZ0JykgJiYgdGhpcy5zdGF0ZS5jYXJ0Lkl0ZW1Db3VudCA9PSAwKXtcclxuXHRcdFx0XHQkKCcuZHJhd2VyLW1haW4nKS5yZW1vdmVDbGFzcygnbW92ZS1sZWZ0Jyk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKCF0aGlzLnN0YXRlLmNhcnQgfHwgIXRoaXMuc3RhdGUuY2FydC5JdGVtQ291bnQgJiYgdGhpcy5zdGF0ZS5jYXJ0Lkl0ZW1Db3VudCAhPT0gMCkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PHNwYW4+XHJcblx0XHRcdFx0e3RoaXMuc3RhdGUuY2FydC5JdGVtQ291bnR9XHJcblx0XHRcdDwvc3Bhbj5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgTWluaWNhcnRUb3RhbEl0ZW1zO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBDYXJ0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9jYXJ0X3N0b3JlJztcclxuXHJcbmNsYXNzIE1pbmljYXJ0VG90YWxQcmljZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGNhcnQ6IHt9XHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlID0gQ2FydFN0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRjYXJ0OiBDYXJ0U3RvcmUuZ2V0U3RvcmUoKS5DYXJ0XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcclxuXHR9XHJcblxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5zdGF0ZS5jYXJ0IHx8ICF0aGlzLnN0YXRlLmNhcnQuU3ViVG90YWwpIHJldHVybiBudWxsO1xyXG5cdFx0XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8c3Bhbj5cclxuXHRcdFx0XHR7dGhpcy5zdGF0ZS5jYXJ0LlN1YlRvdGFsfVxyXG5cdFx0XHQ8L3NwYW4+XHJcblx0XHQpO1xyXG5cclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IE1pbmljYXJ0VG90YWxQcmljZTtcclxuLyoganNoaW50IGlnbm9yZTplbmQgKi9cclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmxldCBJbmplY3RvciA9IHtcclxuICAgIFJlcGxhY2UoaHRtbCwgY29udGFpbmVyU2VsZWN0b3IpIHtcclxuICAgICAgICBsZXQgY29udGFpbmVyID0gJChjb250YWluZXJTZWxlY3Rvcik7XHJcbiAgICAgICAgY29udGFpbmVyLmh0bWwoJChodG1sKS5hZGRDbGFzcygnbXNnJykpO1xyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgbGV0IGNvbnRhaW5lciA9ICQoY29udGFpbmVyU2VsZWN0b3IpO1xyXG4gICAgICAgICAgICBsZXQgY29udGVudCA9ICQoY29udGFpbmVyLmNoaWxkcmVuKCcubXNnJykpO1xyXG4gICAgICAgICAgICBpZihjb250ZW50Lmxlbmd0aCA8IDEpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRlbnQgPSAkKGNvbnRhaW5lclNlbGVjdG9yKS5wYXJlbnQoKS5maW5kKCcubXNnJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJChjb250ZW50KS5oaWRlKCdmYXN0JywgKCkgPT4geyAkKGNvbnRlbnQpLnJlbW92ZSgpOyB9KTtcclxuICAgICAgICB9LCAzMDAwKTtcclxuICAgIH0sXHJcblxyXG4gICAgSW5zZXJ0QWZ0ZXIoaHRtbCwgdGFyZ2V0U2VsZWN0b3IpIHtcclxuICAgICAgICBsZXQgZWxlbWVudCA9ICQodGFyZ2V0U2VsZWN0b3IpO1xyXG4gICAgICAgICQoaHRtbCkuaW5zZXJ0QWZ0ZXIoZWxlbWVudCkuYWRkQ2xhc3MoJ21zZycpO1xyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSAkKHRhcmdldFNlbGVjdG9yKS5uZXh0KCcubXNnJyk7XHJcbiAgICAgICAgICAgIGlmKGVsZW1lbnQubGVuZ3RoIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9ICQodGFyZ2V0U2VsZWN0b3IpLnBhcmVudCgpLmZpbmQoJy5tc2cnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAkKGVsZW1lbnQpLmhpZGUoJ2Zhc3QnLCAoKSA9PiB7ICQoZWxlbWVudCkucmVtb3ZlKCk7IH0pO1xyXG4gICAgICAgIH0sIDMwMDApO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgSW5qZWN0b3I7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgQ2FydFN0b3JlIGZyb20gJy4uL19zdG9yZXMvY2FydF9zdG9yZSc7XHJcblxyXG5sZXQgbm90aWZpY2F0aW9ucyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0Q2FydFN0b3JlLmxpc3RlbiggKCkgPT4ge1xyXG5cdFx0XHRpZihDYXJ0U3RvcmUuY2FydC5lcnJvcil7XHJcbiAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3JNZXNzYWdlKENhcnRTdG9yZS5jYXJ0LmVycm9yLkZhaWxlZCk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0dGhpcy5yZW1vdmVFcnJvck1lc3NhZ2UoQ2FydFN0b3JlLmNhcnQuQWRkZWQpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcbiAgICAvL1JlbmRlciBtaW5pY2FydFxyXG5cdFx0dGhpcy5yZW5kZXJSZWFjdENvbXBvbmVudHMoKTtcclxuXHJcblx0fSxcclxuXHJcblxyXG4gIGRpc3BsYXlFcnJvck1lc3NhZ2UocHJvZHVjdHMpe1xyXG5cdCAgICBmb3IgKHZhciBpdGVtIGluIHByb2R1Y3RzKSB7XHJcblx0ICAgICAgaWYgKHByb2R1Y3RzLmhhc093blByb3BlcnR5KGl0ZW0pKSB7XHJcblxyXG5cdFx0XHRcdFx0aWYodHlwZW9mIHByb2R1Y3RzW2l0ZW1dLlJlc3BvbnNlLnN0YXR1cyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdC8vIGlmKHByb2R1Y3RzW2l0ZW1dLlJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSByZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0XHRcdFx0bGV0IG1hdGVyaWFsTnVtYmVyID0gIHByb2R1Y3RzW2l0ZW1dLkNvZGUgKyAnJztcclxuXHRcdFx0XHRcdGxldCBtYXRlcmlhbE51bWJlckFzSWQgPSAnIycrbWF0ZXJpYWxOdW1iZXIuc3BsaXQoJy4nKS5qb2luKCctJyk7XHJcblx0XHRcdFx0XHRpZigkKG1hdGVyaWFsTnVtYmVyQXNJZCkuY2hpbGRyZW4oKS5sZW5ndGggPCAxKXtcclxuXHRcdCAgICAgICAgJChgPGRpdiBjbGFzcz1cInNtYWxsLTEyIGNvbHVtbnMgaW5mby1hZGQtdG8tY2FydFwiPlxyXG5cdFx0ICAgICAgICAgIDxpIGNsYXNzPVwiaWNvbi1hdHRlbnRpb24tY2lyY2xlZFwiPjwvaT5cclxuXHRcdCAgICAgICAgICA8cD5gK3Byb2R1Y3RzW2l0ZW1dLldhcm5pbmdNZXNzYWdlK2A8L3A+XHJcblx0XHQgICAgICAgIDwvZGl2PmApLmFwcGVuZFRvKG1hdGVyaWFsTnVtYmVyQXNJZCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0JChtYXRlcmlhbE51bWJlckFzSWQpLnNob3coKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHRoaXMucmVtb3ZlTG9hZGluZ0ljb25zKHByb2R1Y3RzW2l0ZW1dLkNvZGUpO1xyXG5cdFx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRcdFx0JChtYXRlcmlhbE51bWJlckFzSWQpLmhpZGUoKTtcclxuXHRcdFx0XHRcdH0sIDQwMDApO1xyXG5cdCAgICAgIH1cclxuXHQgIFx0fVxyXG4gIH0sXHJcblxyXG5cdHJlbW92ZUVycm9yTWVzc2FnZShwcm9kdWN0cyl7XHJcbiAgICBmb3IgKHZhciBpdGVtIGluIHByb2R1Y3RzKSB7XHJcbiAgICAgIGlmIChwcm9kdWN0cy5oYXNPd25Qcm9wZXJ0eShpdGVtKSkge1xyXG5cdFx0XHRcdGxldCBtYXRlcmlhbE51bWJlciA9ICBwcm9kdWN0c1tpdGVtXS5Db2RlICsgJyc7XHJcblx0XHRcdFx0bGV0IG1hdGVyaWFsTnVtYmVyQXNJZCA9ICcjJyttYXRlcmlhbE51bWJlci5zcGxpdCgnLicpLmpvaW4oJy0nKTtcclxuICAgICAgICAkKG1hdGVyaWFsTnVtYmVyQXNJZCkuaGlkZSgpO1xyXG5cdFx0XHRcdHRoaXMucmVtb3ZlTG9hZGluZ0ljb25zKHByb2R1Y3RzW2l0ZW1dLkNvZGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcblxyXG5cdHJlbW92ZUxvYWRpbmdJY29ucyhwcm9kdWN0Q29kZSl7XHJcblx0XHQkKCdidXR0b25bZGF0YS1wcm9kdWN0LXNrdT1cIicgKyBwcm9kdWN0Q29kZSArICdcIl0nKS5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xyXG5cdFx0dmFyIGhlYWRlckNhcnQgPSAkKCcudWMtaGVhZGVyY2FydCcpWzBdO1xyXG5cdFx0dmFyIGNvbnRyb2xsQ2FydCA9ICQoJyNjb250cm9sbC1jYXJ0JylbMF07XHJcblx0XHRoZWFkZXJDYXJ0LmNsYXNzTmFtZSA9IGhlYWRlckNhcnQuY2xhc3NOYW1lLnJlcGxhY2UoJyBhZGRpbmcnLCAnJyk7XHJcblx0XHRjb250cm9sbENhcnQuY2xhc3NOYW1lID0gY29udHJvbGxDYXJ0LmNsYXNzTmFtZS5yZXBsYWNlKCcgYWRkaW5nJywgJycpO1xyXG5cdH0sXHJcblxyXG5cdHJlbmRlclJlYWN0Q29tcG9uZW50cygpIHtcclxuXHR9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBub3RpZmljYXRpb25zO1xyXG4iLCJpbXBvcnQgJCBmcm9tICdqcXVlcnknO1xyXG5pbXBvcnQgQ3VzdG9tRXZlbnRzIGZyb20gJy4uL19saWIvY3VzdG9tLWV2ZW50cyc7XHJcblxyXG52YXIgc2hvd0NsZWFyRmlsdGVyID0gZmFsc2U7XHJcbnZhciBzaG93Q2xlYXJTZWFyY2ggPSBmYWxzZTtcclxudmFyIGlzT3JkZXJIaXN0b3J5ID0gZmFsc2U7XHJcbnZhciBpc09yZGVyRGV0YWlsSGlzdG9yeSA9IGZhbHNlO1xyXG52YXIgaXNNeU9wZW5PcmRlciA9IGZhbHNlO1xyXG52YXIgZGF0YSA9IHt9O1xyXG5cclxubGV0IG9yZGVySGlzdG9yeSA9IHtcclxuICBpbml0KCkge1xyXG5cclxuICAgIGlmKCQoJyNvcmRlci1oaXN0b3J5JykubGVuZ3RoID4gMCl7XHJcblxyXG4gICAgICBpc09yZGVySGlzdG9yeSA9IHRydWU7XHJcbiAgICAgIHRoaXMuc2VhcmNoT3JkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VhcmNoLW9yZGVycycpO1xyXG4gICAgICB0aGlzLnNlYXJjaEJ5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1NlYXJjaEJ5Jyk7XHJcblxyXG4gICAgICB0aGlzLmRhdGVGcm9tID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGVmcm9tJyk7XHJcbiAgICAgIHRoaXMuZGF0ZVRvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGV0bycpO1xyXG4gICAgICB0aGlzLm9yZGVyU3RhdHVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ09yZGVyU3RhdHVzJyk7XHJcblxyXG4gICAgICB0aGlzLm1hcmtldCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYXJrZXQnKTtcclxuICAgICAgdGhpcy5jdXN0b21lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjdXN0b21lcicpO1xyXG4gICAgICB0aGlzLmNvbnRhY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udGFjdCcpO1xyXG5cclxuICAgICAgdmFyIG1hcmtldCA9IG9yZGVySGlzdG9yeS5oYXNWYWx1ZSh0aGlzLm1hcmtldCk7XHJcbiAgICAgIHZhciBjdXN0b21lciA9IG9yZGVySGlzdG9yeS5oYXNWYWx1ZSh0aGlzLmN1c3RvbWVyKTtcclxuICAgICAgdmFyIGNvbnRhY3QgPSBvcmRlckhpc3RvcnkuaGFzVmFsdWUodGhpcy5jb250YWN0KTtcclxuXHJcbiAgICAgIGlmIChtYXJrZXQgfHwgY3VzdG9tZXIgfHwgY29udGFjdCkge1xyXG4gICAgICAgICQoJyNjbGVhckFkdmFuY2VkRmlsdGVyJykuYWRkQ2xhc3MoJ3Nob3cnKTtcclxuICAgICAgfWVsc2Uge1xyXG4gICAgICAgICQoJyNjbGVhckFkdmFuY2VkRmlsdGVyJykucmVtb3ZlQ2xhc3MoJ3Nob3cnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNlYXJjaE9yZGVyID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuc2VhcmNoT3JkZXIpO1xyXG4gICAgICB2YXIgc2VhcmNoQnkgPSBvcmRlckhpc3Rvcnkuc2VsZWN0SGFzTmV3VmFsdWUodGhpcy5zZWFyY2hCeSk7XHJcblxyXG4gICAgICBpZiAoc2VhcmNoT3JkZXIgfHwgc2VhcmNoQnkpIHtcclxuICAgICAgICAgIHNob3dDbGVhclNlYXJjaCA9IHRydWU7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0NsZWFyU2VhcmNoKCk7XHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICBzaG93Q2xlYXJGaWx0ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dTZWFyY2goKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGRhdGVGcm9tID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuZGF0ZUZyb20pO1xyXG4gICAgICB2YXIgZGF0ZVRvID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuZGF0ZVRvKTtcclxuICAgICAgdmFyIG9yZGVyU3RhdHVzID0gb3JkZXJIaXN0b3J5LnNlbGVjdEhhc05ld1ZhbHVlKHRoaXMub3JkZXJTdGF0dXMpO1xyXG5cclxuICAgICAgaWYgKGRhdGVUbyB8fCBkYXRlRnJvbSB8fCBvcmRlclN0YXR1cykge1xyXG4gICAgICAgICAgc2hvd0NsZWFyRmlsdGVyID0gdHJ1ZTtcclxuICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93Q2xlYXJGaWx0ZXIoKTtcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgICBzaG93Q2xlYXJGaWx0ZXIgPSBmYWxzZTtcclxuICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93RmlsdGVyKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmKCQoJyNvcGVuLW9yZGVycycpLmxlbmd0aCA+IDApe1xyXG5cclxuICAgICAgaXNNeU9wZW5PcmRlciA9IHRydWU7XHJcblxyXG4gICAgICB0aGlzLnNlYXJjaE9yZGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYXJjaC1vcmRlcnMnKTtcclxuICAgICAgdGhpcy5zZWFyY2hCeSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdTZWFyY2hCeScpO1xyXG5cclxuICAgICAgdGhpcy5kYXRlRnJvbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRlZnJvbScpO1xyXG4gICAgICB0aGlzLmRhdGVUbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRldG8nKTtcclxuICAgICAgdGhpcy5vcmRlclN0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdPcmRlclN0YXR1cycpO1xyXG5cclxuICAgICAgdmFyIHNlYXJjaE9yZGVyID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuc2VhcmNoT3JkZXIpO1xyXG4gICAgICB2YXIgc2VhcmNoQnkgPSBvcmRlckhpc3Rvcnkuc2VsZWN0SGFzTmV3VmFsdWUodGhpcy5zZWFyY2hCeSk7XHJcblxyXG4gICAgICBpZiAoc2VhcmNoT3JkZXIgfHwgc2VhcmNoQnkpIHtcclxuICAgICAgICAgIHNob3dDbGVhclNlYXJjaCA9IHRydWU7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0NsZWFyU2VhcmNoKCk7XHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICBzaG93Q2xlYXJGaWx0ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dTZWFyY2goKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGRhdGVGcm9tID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuZGF0ZUZyb20pO1xyXG4gICAgICB2YXIgZGF0ZVRvID0gb3JkZXJIaXN0b3J5Lmhhc1ZhbHVlKHRoaXMuZGF0ZVRvKTtcclxuXHJcbiAgICAgIGlmIChkYXRlVG8gfHwgZGF0ZUZyb20pIHtcclxuICAgICAgICAgIHNob3dDbGVhckZpbHRlciA9IHRydWU7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0NsZWFyRmlsdGVyKCk7XHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgICAgc2hvd0NsZWFyRmlsdGVyID0gZmFsc2U7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0ZpbHRlcigpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZigkKCcjb3JkZXItaGlzdG9yeS1kZXRhaWwnKS5sZW5ndGggPiAwKXtcclxuICAgICAgaXNPcmRlckRldGFpbEhpc3RvcnkgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgaWYoJCgnI29wZW4tb3JkZXJzJykubGVuZ3RoID4gMCB8fCAkKCcjb3JkZXItaGlzdG9yeScpLmxlbmd0aCA+IDApe1xyXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlYXJjaC1vcmRlcnNcIikuYWRkRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlPT0xMyAmJiB0aGlzLnZhbHVlID09PSAnJykge1xyXG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNsZWFyU2VhcmNoXCIpLmNsaWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgICQoJyNzZWFyY2gnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICBvcmRlckhpc3RvcnkuY3JlYXRlRGF0YU1vZGVsKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCcjZmlsdGVyJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgb3JkZXJIaXN0b3J5LmNyZWF0ZURhdGFNb2RlbCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgb3JkZXJIaXN0b3J5LmNyZWF0ZURhdGFNb2RlbCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnI3NlYXJjaC1vcmRlcnMnKS5vbihcImtleXVwXCIsZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYob3JkZXJIaXN0b3J5Lmhhc0lucHV0Q2hhbmdlZCh0aGlzKSl7XHJcbiAgICAgICAgICAkKCcjc2VhcmNoJykucHJvcCggXCJkaXNhYmxlZFwiLCBmYWxzZSk7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd1NlYXJjaCgpO1xyXG4gICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgIGlmKHNob3dDbGVhclNlYXJjaCl7XHJcbiAgICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93Q2xlYXJTZWFyY2goKVxyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWFyY2gtb3JkZXJzJykudmFsdWUgID09PSBcIlwiICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdTZWFyY2hCeScpLnZhbHVlICA9PT0gXCJPcmRlck51bWJlclwiKXtcclxuICAgICAgICAgICAgICAkKCcjc2VhcmNoJykucHJvcCggXCJkaXNhYmxlZFwiLCB0cnVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgICQoJyNTZWFyY2hCeScpLm9uKFwiY2hhbmdlXCIsZnVuY3Rpb24oKSB7XHJcbiAgICAgICQoXCIjU2VhcmNoQnkgb3B0aW9uOnNlbGVjdGVkXCIpLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYob3JkZXJIaXN0b3J5LnNlbGVjdEhhc0NoYW5nZWQodGhpcykpe1xyXG4gICAgICAgICAgJCgnI3NlYXJjaCcpLnByb3AoXCJkaXNhYmxlZFwiLCBmYWxzZSk7XHJcbiAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd1NlYXJjaCgpXHJcbiAgICAgICAgfWVsc2Uge1xyXG4gICAgICAgICAgaWYoc2hvd0NsZWFyU2VhcmNoKXtcclxuICAgICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dDbGVhclNlYXJjaCgpXHJcbiAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYXJjaC1vcmRlcnMnKS52YWx1ZSAgPT09IFwiXCIgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1NlYXJjaEJ5JykudmFsdWUgID09PSBcIk9yZGVyTnVtYmVyXCIpe1xyXG4gICAgICAgICAgICAgICQoJyNzZWFyY2gnKS5wcm9wKCBcImRpc2FibGVkXCIsIHRydWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgICQoJyNkYXRldG8nKS5vbihcImtleXVwXCIsZnVuY3Rpb24oKSB7XHJcbiAgICAgIGlmKG9yZGVySGlzdG9yeS5oYXNJbnB1dENoYW5nZWQodGhpcykpe1xyXG4gICAgICAgICAgJCgnI2ZpbHRlcicpLnByb3AoIFwiZGlzYWJsZWRcIiwgZmFsc2UgKTtcclxuICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93RmlsdGVyKCk7XHJcbiAgICAgICAgfWVsc2Uge1xyXG4gICAgICAgICAgaWYoc2hvd0NsZWFyRmlsdGVyKXtcclxuICAgICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dDbGVhckZpbHRlcigpXHJcbiAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGV0bycpLnZhbHVlICA9PT0gXCJcIiAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZSAgPT09IFwiXCIgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1NlYXJjaEJ5JykudmFsdWUgID09PSBcIkFsbFwiKXtcclxuICAgICAgICAgICAgICAkKCcjZmlsdGVyJykucHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICAkKCcjZGF0ZXRvJykub24oXCJjaGFuZ2VcIixmdW5jdGlvbigpIHtcclxuICAgICAgbGV0IGZyb21EYXRlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGVmcm9tJykudmFsdWU7XHJcbiAgICAgIGxldCB0b0RhdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZXRvJykudmFsdWU7XHJcbiAgICAgIGlmKERhdGUucGFyc2UobmV3IERhdGUoZnJvbURhdGUpKSA+IERhdGUucGFyc2UobmV3IERhdGUodG9EYXRlKSkpIHtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZSA9IHRvRGF0ZTtcclxuICAgICAgfVxyXG4gICAgICBpZihvcmRlckhpc3RvcnkuaGFzSW5wdXRDaGFuZ2VkKHRoaXMpKXtcclxuICAgICAgICAkKCcjZmlsdGVyJykucHJvcChcImRpc2FibGVkXCIsIGZhbHNlKTtcclxuICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0ZpbHRlcigpO1xyXG4gICAgICB9ZWxzZSB7XHJcbiAgICAgICAgaWYoc2hvd0NsZWFyRmlsdGVyKXtcclxuICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93Q2xlYXJGaWx0ZXIoKVxyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGV0bycpLnZhbHVlICA9PT0gXCJcIiAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZSAgPT09IFwiXCIgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1NlYXJjaEJ5JykudmFsdWUgID09PSBcIkFsbFwiKXtcclxuICAgICAgICAgICAgJCgnI2ZpbHRlcicpLnByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgICQoJyNkYXRlZnJvbScpLm9uKFwia2V5dXBcIixmdW5jdGlvbigpIHtcclxuICAgICAgICBpZihvcmRlckhpc3RvcnkuaGFzSW5wdXRDaGFuZ2VkKHRoaXMpKXtcclxuICAgICAgICAgICQoJyNmaWx0ZXInKS5wcm9wKFwiZGlzYWJsZWRcIiwgZmFsc2UpO1xyXG4gICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dGaWx0ZXIoKTtcclxuICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICBpZihzaG93Q2xlYXJGaWx0ZXIpe1xyXG4gICAgICAgICAgICBvcmRlckhpc3Rvcnkuc2hvd0NsZWFyRmlsdGVyKClcclxuICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZXRvJykudmFsdWUgID09PSBcIlwiICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRlZnJvbScpLnZhbHVlICA9PT0gXCJcIiAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnU2VhcmNoQnknKS52YWx1ZSAgPT09IFwiQWxsXCIpe1xyXG4gICAgICAgICAgICAgICQoJyNmaWx0ZXInKS5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCcjZGF0ZWZyb20nKS5vbihcImNoYW5nZVwiLGZ1bmN0aW9uKCkge1xyXG4gICAgICBsZXQgZnJvbURhdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZTtcclxuICAgICAgbGV0IHRvRGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRldG8nKS52YWx1ZTtcclxuICAgICAgaWYoRGF0ZS5wYXJzZShuZXcgRGF0ZShmcm9tRGF0ZSkpID4gRGF0ZS5wYXJzZShuZXcgRGF0ZSh0b0RhdGUpKSkge1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRldG8nKS52YWx1ZSA9IGZyb21EYXRlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmKG9yZGVySGlzdG9yeS5oYXNJbnB1dENoYW5nZWQodGhpcykpe1xyXG4gICAgICAgICQoJyNmaWx0ZXInKS5wcm9wKFwiZGlzYWJsZWRcIiwgZmFsc2UpO1xyXG4gICAgICAgIG9yZGVySGlzdG9yeS5zaG93RmlsdGVyKCk7XHJcbiAgICAgIH1lbHNlIHtcclxuICAgICAgICBpZihzaG93Q2xlYXJGaWx0ZXIpe1xyXG4gICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dDbGVhckZpbHRlcigpXHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZXRvJykudmFsdWUgID09PSBcIlwiICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRlZnJvbScpLnZhbHVlICA9PT0gXCJcIiAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnU2VhcmNoQnknKS52YWx1ZSAgPT09IFwiQWxsXCIpe1xyXG4gICAgICAgICAgICAkKCcjZmlsdGVyJykucHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnI09yZGVyU3RhdHVzJykub24oXCJjaGFuZ2VcIixmdW5jdGlvbigpIHtcclxuICAgICAgJChcIiNPcmRlclN0YXR1cyBvcHRpb246c2VsZWN0ZWRcIikuZWFjaChmdW5jdGlvbigpIHtcclxuICAgICAgICBpZihvcmRlckhpc3Rvcnkuc2VsZWN0SGFzQ2hhbmdlZCh0aGlzKSl7XHJcbiAgICAgICAgICAkKCcjZmlsdGVyJykucHJvcCggXCJkaXNhYmxlZFwiLCBmYWxzZSApO1xyXG4gICAgICAgICAgb3JkZXJIaXN0b3J5LnNob3dGaWx0ZXIoKVxyXG4gICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgIGlmKHNob3dDbGVhckZpbHRlcil7XHJcbiAgICAgICAgICAgIG9yZGVySGlzdG9yeS5zaG93Q2xlYXJGaWx0ZXIoKVxyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYXRldG8nKS52YWx1ZSAgPT09IFwiXCIgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGVmcm9tJykudmFsdWUgID09PSBcIlwiICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdTZWFyY2hCeScpLnZhbHVlICA9PT0gXCJBbGxcIil7XHJcbiAgICAgICAgICAgICAgJCgnI2ZpbHRlcicpLnByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCcjc2VhcmNoLW9yZGVyLWhpc3RvcnknKS5vbihcImtleXVwXCIsZnVuY3Rpb24oZSkge1xyXG4gICAgICBpZihvcmRlckhpc3Rvcnkuc2VsZWN0SGFzQ2hhbmdlZCh0aGlzKSl7XHJcbiAgICAgICAgJCgnI2NsZWFyLW9yZGVybGluZXMnKS5oaWRlKCk7XHJcbiAgICAgICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykuc2hvdygpLnByb3AoXCJkaXNhYmxlZFwiLCBmYWxzZSk7XHJcbiAgICAgICAgaWYoZS5rZXlDb2RlID09PSAxMykgeyAvL0hhbmRsZSBlbnRlciBrZXkgcHJlc3NcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIG9yZGVySGlzdG9yeS5maWx0ZXJPcmRlckxpbmVzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9yZGVySGlzdG9yeS5maWx0ZXJPcmRlckxpbmVzKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYoJCh0aGlzKS52YWwoKSA9PT0gXCJcIikge1xyXG4gICAgICAgICQoJyNjbGVhci1vcmRlcmxpbmVzJykuaGlkZSgpO1xyXG4gICAgICAgICQoJyNzZWFyY2gtb3JkZXJsaW5lcycpLnNob3coKTtcclxuICAgICAgICAkKCcjc2VhcmNoLW9yZGVybGluZXMnKS5wcm9wKFwiZGlzYWJsZWRcIiwgdGhpcy52YWx1ZS5sZW5ndGggPT09IDApO1xyXG4gICAgICAgIG9yZGVySGlzdG9yeS5maWx0ZXJPcmRlckxpbmVzKCk7XHJcbiAgICAgIH1cclxuICAgIH0pLm9uKCdibHVyJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZigkKHRoaXMpLnZhbCgpID09PSBcIlwiKSB7XHJcbiAgICAgICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykucHJvcChcImRpc2FibGVkXCIsIHRoaXMudmFsdWUubGVuZ3RoID09PSAwKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgb3JkZXJIaXN0b3J5LmZpbHRlck9yZGVyTGluZXMoKTtcclxuICAgIH0pO1xyXG5cclxuICAgICQoJyNjbGVhci1vcmRlcmxpbmVzJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgJCgnI2NsZWFyLW9yZGVybGluZXMnKS5oaWRlKCk7XHJcbiAgICAgICAgJCgnI3NlYXJjaC1vcmRlci1oaXN0b3J5JykudmFsKCcnKTtcclxuICAgICAgICAkKCcub3JkZXJsaW5lLXdyYXBwZXInKS5zaG93KCk7XHJcbiAgICAgICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykuc2hvdygpLnByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKTtcclxuICAgIH0pO1xyXG5cclxuICAgICQoJy5vcmRlcmxpbmUtc3RhdHVzLWZpbHRlciBpbnB1dCcpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBvcmRlckhpc3RvcnkuZmlsdGVyT3JkZXJMaW5lcygpO1xyXG4gICAgfSk7XHJcbiAgfSxcclxuXHJcbiAgZmlsdGVyT3JkZXJMaW5lcygpe1xyXG4gICAgbGV0IHN0cmluZ0ZpbHRlciA9ICQoJyNzZWFyY2gtb3JkZXItaGlzdG9yeScpLnByb3AoJ3ZhbHVlJyk7XHJcbiAgICBsZXQgc2VsZWN0ZWRTdGF0dXNGaWx0ZXIgPSAkKCcub3JkZXJsaW5lLXN0YXR1cy1maWx0ZXIgaW5wdXQ6Y2hlY2tlZCcpLmF0dHIoJ3ZhbHVlJyk7XHJcbiAgICBpZihzZWxlY3RlZFN0YXR1c0ZpbHRlciA9PT0gXCJzdGF0dXMtb3BlblwiKSB7XHJcbiAgICAgICAgJCgnLm9yZGVybGluZS13cmFwcGVyJykuaGlkZSgpO1xyXG4gICAgICAgICQoJy5pc09wZW4nKS5wYXJlbnRzKCcub3JkZXJsaW5lLXdyYXBwZXInKS5zaG93KCk7XHJcbiAgICAgICAgaWYoc3RyaW5nRmlsdGVyICE9PSBcIlwiKSB7XHJcbiAgICAgICAgICAkKCcub3JkZXJsaW5lLXdyYXBwZXInKS5oaWRlKCk7XHJcbiAgICAgICAgICAkKCcuaXNPcGVuJykucGFyZW50cygnLm9yZGVybGluZS13cmFwcGVyW2RhdGEtbWF0ZXJpYWxpZCo9XCInK3N0cmluZ0ZpbHRlcisnXCJdJykuc2hvdygpO1xyXG4gICAgICAgICAgJCgnI3NlYXJjaC1vcmRlcmxpbmVzJykuaGlkZSgpO1xyXG4gICAgICAgICAgJCgnI2NsZWFyLW9yZGVybGluZXMnKS5zaG93KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZFN0YXR1c0ZpbHRlciA9PT0gXCJzdGF0dXMtc2hpcHBlZFwiKSB7XHJcbiAgICAgICAgJCgnLm9yZGVybGluZS13cmFwcGVyJykuaGlkZSgpO1xyXG4gICAgICAgICQoJy5vcmRlcmxpbmUtd3JhcHBlcicpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICQoJy5pc1NoaXBwZWQnKS5wYXJlbnRzKCcub3JkZXJsaW5lLXdyYXBwZXInKS5zaG93KCk7XHJcbiAgICAgICAgICBpZihzdHJpbmdGaWx0ZXIgIT09IFwiXCIpIHtcclxuICAgICAgICAgICAgJCgnLm9yZGVybGluZS13cmFwcGVyJykuaGlkZSgpO1xyXG4gICAgICAgICAgICAkKCcuaXNTaGlwcGVkJykucGFyZW50cygnLm9yZGVybGluZS13cmFwcGVyW2RhdGEtbWF0ZXJpYWxpZCo9XCInK3N0cmluZ0ZpbHRlcisnXCJdJykuc2hvdygpO1xyXG4gICAgICAgICAgICAkKCcjc2VhcmNoLW9yZGVybGluZXMnKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICQoJyNjbGVhci1vcmRlcmxpbmVzJykuc2hvdygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmKHNlbGVjdGVkU3RhdHVzRmlsdGVyID09PSBcInN0YXR1cy1hbGxcIil7XHJcbiAgICAgICQoJy5vcmRlcmxpbmUtd3JhcHBlcicpLnNob3coKTtcclxuICAgICAgaWYoc3RyaW5nRmlsdGVyICE9PSBcIlwiKSB7XHJcbiAgICAgICAgJCgnLm9yZGVybGluZS13cmFwcGVyJykuaGlkZSgpO1xyXG4gICAgICAgICQoJy5vcmRlcmxpbmUtd3JhcHBlcltkYXRhLW1hdGVyaWFsaWQqPVwiJytzdHJpbmdGaWx0ZXIrJ1wiXScpLnNob3coKTtcclxuICAgICAgICAkKCcjc2VhcmNoLW9yZGVybGluZXMnKS5oaWRlKCk7XHJcbiAgICAgICAgJCgnI2NsZWFyLW9yZGVybGluZXMnKS5zaG93KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxufSxcclxuXHJcbiAgaGFzVmFsdWUoZWwpe1xyXG4gICAgaWYoZWwgIT0gbnVsbCAmJiBlbC52YWx1ZSAhPT0gXCJcIil7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH0sXHJcblxyXG4gIHNlbGVjdEhhc05ld1ZhbHVlKGVsKXtcclxuICAgIGlmKGVsICE9IG51bGwgJiYgKGVsLnZhbHVlID09PSBcIk9yZGVyTnVtYmVyXCIgfHwgZWwudmFsdWUgPT09XCJBbGxcIikpe1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9LFxyXG5cclxuICBoYXNJbnB1dENoYW5nZWQoZWwpe1xyXG4gICAgaWYoZWwgIT0gbnVsbCAmJiAoZWwudmFsdWUgIT09IFwiXCIgJiYgZWwuZGVmYXVsdFZhbHVlICE9PSBlbC52YWx1ZSkpe1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICBzZWxlY3RIYXNDaGFuZ2VkKGVsKXtcclxuICAgIGlmKGVsICE9IG51bGwgJiYgKGVsLmRlZmF1bHRWYWx1ZSAhPT0gZWwudmFsdWUgJiYgZWwuZGVmYXVsdFNlbGVjZWQgIT09IHRydWUpKXtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSxcclxuXHJcbiAgc2hvd0NsZWFyU2VhcmNoKCl7XHJcbiAgICAkKCcjc2VhcmNoJykucmVtb3ZlQ2xhc3MoJ3Nob3cnKTtcclxuICAgICQoJyNjbGVhclNlYXJjaCcpLmFkZENsYXNzKCdzaG93Jyk7XHJcbiAgfSxcclxuXHJcbiAgc2hvd1NlYXJjaCgpe1xyXG4gICAgJCgnI2NsZWFyU2VhcmNoJykucmVtb3ZlQ2xhc3MoJ3Nob3cnKTtcclxuICAgICQoJyNzZWFyY2gnKS5hZGRDbGFzcygnc2hvdycpO1xyXG4gIH0sXHJcblxyXG4gIHNob3dGaWx0ZXIoKXtcclxuICAgICQoJyNjbGVhckZpbHRlcicpLnJlbW92ZUNsYXNzKCdzaG93Jyk7XHJcbiAgICAkKCcjZmlsdGVyJykuYWRkQ2xhc3MoJ3Nob3cnKTtcclxuICB9LFxyXG5cclxuICBzaG93Q2xlYXJGaWx0ZXIoKXtcclxuICAgICQoJyNmaWx0ZXInKS5yZW1vdmVDbGFzcygnc2hvdycpO1xyXG4gICAgJCgnI2NsZWFyRmlsdGVyJykuYWRkQ2xhc3MoJ3Nob3cnKTtcclxuICB9LFxyXG4gIGNyZWF0ZURhdGFNb2RlbCgpe1xyXG4gICAgaWYoaXNPcmRlckhpc3Rvcnkpe1xyXG4gICAgICBkYXRhID0ge1xyXG4gICAgICAgICdldmVudCc6ICdPcmRlci1oaXN0b3J5LXNlYXJjaCcsXHJcbiAgICAgICAgJ3BhZ2UnOiAnT3JkZXIgaGlzdG9yeScsXHJcbiAgICAgICAgJ3NlYXJjaF9mb3InOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnU2VhcmNoQnknKS52YWx1ZSxcclxuICAgICAgICAnc2VhcmNoX3Rlcm0nOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VhcmNoLW9yZGVycycpLnZhbHVlLFxyXG4gICAgICAgICdkYXRlX3RvJzogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGV0bycpLnZhbHVlLFxyXG4gICAgICAgICdkYXRlX2Zyb20nOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZSxcclxuICAgICAgICAnb3JkZXJfc3RhdHVzJzogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ09yZGVyU3RhdHVzJykudmFsdWVcclxuICAgICAgfVxyXG4gICAgfWVsc2UgaWYgKGlzT3JkZXJEZXRhaWxIaXN0b3J5KSB7XHJcbiAgICAgIGRhdGEgPSB7XHJcbiAgICAgICAgJ2V2ZW50JzogJ09yZGVyLWhpc3Rvcnktc2VhcmNoJyxcclxuICAgICAgICAncGFnZSc6ICdNeSBvcGVuIG9yZGVycycsXHJcbiAgICAgICAgJ3NlYXJjaF90ZXJtJzogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYXJjaC1vcmRlci1oaXN0b3J5JykudmFsdWUsXHJcbiAgICAgIH1cclxuICAgIH1lbHNlIGlmIChpc015T3Blbk9yZGVyKSB7XHJcbiAgICAgIGRhdGEgPSB7XHJcbiAgICAgICAgJ2V2ZW50JzogJ09yZGVyLWhpc3Rvcnktc2VhcmNoJyxcclxuICAgICAgICAncGFnZSc6ICdNeSBvcGVuIG9yZGVycycsXHJcbiAgICAgICAgJ3NlYXJjaF9mb3InOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnU2VhcmNoQnknKS52YWx1ZSxcclxuICAgICAgICAnc2VhcmNoX3Rlcm0nOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VhcmNoLW9yZGVycycpLnZhbHVlLFxyXG4gICAgICAgICdkYXRlX3RvJzogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGV0bycpLnZhbHVlLFxyXG4gICAgICAgICdkYXRlX2Zyb20nOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGF0ZWZyb20nKS52YWx1ZSxcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgQ3VzdG9tRXZlbnRzLnRyaWdnZXJEYXRhTGF5ZXJQdXNoKGRhdGEpO1xyXG4gIH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IG9yZGVySGlzdG9yeTtcclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFByaWNlU2VydmljZVN0b3JlIGZyb20gJy4uL19zdG9yZXMvcHJpY2Vfc2VydmljZV9zdG9yZSc7XHJcbmltcG9ydCBzdHJpbmdmb3JtYXQgZnJvbSAnc3RyaW5nZm9ybWF0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0ge307XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJdGVtRm9vdGVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG5cclxuICAgIGlmKHRoaXMucHJvcHMudHJhbnNsYXRpb25zKXtcclxuXHQgICAgdHJhbnNsYXRpb25zLm1hdGVyaWFsTnVtYmVyID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMubWF0ZXJpYWxOdW1iZXI7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy5hZGRUb0NhcnQgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5hZGRUb0NhcnQ7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy5xdWlja0J1eSA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnF1aWNrQnV5O1xyXG5cdCAgICB0cmFuc2xhdGlvbnMucmVwbGFjZWRCeSA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnJlcGxhY2VkQnk7XHJcblx0ICAgIHRyYW5zbGF0aW9ucy52aWV3UmVwbGFjaW5nUHJvZHVjdCA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLnZpZXdSZXBsYWNpbmdQcm9kdWN0O1xyXG5cdCAgICB0cmFuc2xhdGlvbnMudmlld0RldGFpbHMgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy52aWV3RGV0YWlscztcclxuXHQgICAgdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5ub3RCdXlhYmxlO1xyXG5cdCAgICB0cmFuc2xhdGlvbnMuZGlzY291bnQgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5kaXNjb3VudDtcclxuXHRcdFx0dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mbyA9IHRoaXMucHJvcHMudHJhbnNsYXRpb25zLmZldGNoaW5nSW5mbztcclxuXHRcdFx0dHJhbnNsYXRpb25zLnByb21vdGlvblRpdGxlID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMucHJvbW90aW9uVGl0bGU7XHJcblx0XHRcdHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXMgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5wcm9tb3Rpb25XYXM7XHJcblx0XHRcdHRyYW5zbGF0aW9ucy5wcmljZUVycm9yID0gdGhpcy5wcm9wcy50cmFuc2xhdGlvbnMucHJpY2VFcnJvcjtcclxuXHRcdFx0dHJhbnNsYXRpb25zLmdyb3NzUHJpY2UgPSB0aGlzLnByb3BzLnRyYW5zbGF0aW9ucy5ncm9zc1ByaWNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdEJ1eWFibGU6IGZhbHNlLFxyXG5cdFx0XHRJblN0b2NrUXVhbnRpdHk6IDAsXHJcblx0XHRcdExvYWRlZDogZmFsc2UsXHJcblx0XHRcdENvZGU6IFwiXCIsXHJcblx0XHRcdFByaWNlOiBcIlwiLFxyXG5cdFx0XHRTaGlwcGluZ0RhdGU6IFwiXCIsXHJcblx0XHRcdElzRGlzY291bnRlZDogZmFsc2UsXHJcblx0XHRcdERlZmF1bHRQcmljZTogXCJcIixcclxuXHRcdFx0RGlzY291bnRQZXJjZW50OiBcIlwiLFxyXG5cdFx0XHRQcm9kdWN0Q29udGV4dDoge30sXHJcblx0XHRcdFByb21vdGlvbkRpc2NvdW50UGVyY2VudDogXCJcIixcclxuXHRcdFx0UHJvbW90aW9uUHJpY2U6IFwiXCIsXHJcblx0XHRcdEhhc1Byb21vdGlvbjogZmFsc2UsXHJcblx0XHRcdEhhc0Vycm9yOiBmYWxzZVxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZFVwZGF0ZSgpe1xyXG5cdFx0aWYodGhpcy5zdGF0ZS5Mb2FkZWQpe1xyXG5cdFx0XHR0aGlzLnJlZmxvdygpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdC8vdGhpcy5yZWZsb3coKTtcclxuXHJcblx0XHRsZXQgcHJpY2UgPSBQcmljZVNlcnZpY2VTdG9yZS5nZXRQcmljZXNGb3JNYXRlcmlhbCh0aGlzLnByb3BzLm1hdGVyaWFsTnVtYmVyKTtcclxuXHRcdGlmKHByaWNlLmxlbmd0aCA+IDApe1xyXG5cdFx0XHR0aGlzLnNldFByaWNlRm9yRm9vdGVyKHByaWNlKTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlID0gUHJpY2VTZXJ2aWNlU3RvcmUubGlzdGVuKCAoKSA9PiB7XHJcblx0XHRcdGlmKCF0aGlzLnN0YXRlLkxvYWRlZCl7XHJcblx0XHRcdFx0bGV0IHByaWNlID0gUHJpY2VTZXJ2aWNlU3RvcmUuZ2V0UHJpY2VzRm9yTWF0ZXJpYWwodGhpcy5wcm9wcy5tYXRlcmlhbE51bWJlcik7XHJcblx0XHRcdFx0aWYocHJpY2UubGVuZ3RoID4gMCl7XHJcblx0XHRcdFx0XHR0aGlzLnNldFByaWNlRm9yRm9vdGVyKHByaWNlKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCAoKSB7XHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlKCk7XHJcblx0fVxyXG5cdHNldFByaWNlRm9yRm9vdGVyKHByaWNlKXtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRCdXlhYmxlOiBwcmljZVswXS5CdXlhYmxlLFxyXG5cdFx0XHRJblN0b2NrUXVhbnRpdHk6IHByaWNlWzBdLkluU3RvY2tRdWFudGl0eSxcclxuXHRcdFx0TG9hZGVkOiB0cnVlLFxyXG5cdFx0XHRDb2RlOiBwcmljZVswXS5Db2RlLFxyXG5cdFx0XHRQcmljZTogcHJpY2VbMF0uUHJpY2UsXHJcblx0XHRcdFNoaXBwaW5nRGF0ZTogcHJpY2VbMF0uU2hpcHBpbmdEYXRlLFxyXG5cdFx0XHRJc0Rpc2NvdW50ZWQ6IHByaWNlWzBdLklzRGlzY291bnRlZCxcclxuXHRcdFx0RGVmYXVsdFByaWNlOiBwcmljZVswXS5EZWZhdWx0UHJpY2UsXHJcblx0XHRcdERpc2NvdW50UGVyY2VudDogcHJpY2VbMF0uRGlzY291bnRQZXJjZW50LFxyXG5cdFx0XHRQcm9kdWN0Q29udGV4dDogcHJpY2VbMF0uUHJvZHVjdENvbnRleHQsXHJcblx0XHRcdFByb21vdGlvbkRpc2NvdW50UGVyY2VudDogcHJpY2VbMF0uUHJvbW90aW9uRGlzY291bnRQZXJjZW50LFxyXG5cdFx0XHRQcm9tb3Rpb25QcmljZTogcHJpY2VbMF0uUHJvbW90aW9uUHJpY2UsXHJcblx0XHRcdEhhc1Byb21vdGlvbjogcHJpY2VbMF0uSGFzUHJvbW90aW9uLFxyXG5cdFx0XHRIYXNFcnJvcjogcHJpY2VbMF0uSGFzRXJyb3JcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCBtYXRlcmlhbE51bWJlciA9IHRoaXMuc3RhdGUuQ29kZS5zcGxpdCgnLicpLmpvaW4oJy0nKTtcclxuXHRcdGxldCBwcm9kdWN0Q2FyZEJhbm5lciA9ICcnO1xyXG5cclxuXHRcdGlmKCB0aGlzLnN0YXRlLkhhc1Byb21vdGlvbiApe1xyXG5cdFx0XHRwcm9kdWN0Q2FyZEJhbm5lciA9ICc8ZGl2IGNsYXNzPVwiZGlzY291bnQtcHJpY2VcIj48c3BhbiBjbGFzcz1cInByaWNlXCI+PGkgY2xhc3M9XCJpY29uLXRhZ3NcIj48L2k+PC9zcGFuPjwvZGl2Pic7XHJcblx0XHRcdCQoJyNsaS0nK21hdGVyaWFsTnVtYmVyKycgLmltYWdlJykuYXBwZW5kKHByb2R1Y3RDYXJkQmFubmVyKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZighdGhpcy5zdGF0ZS5IYXNQcm9tb3Rpb24gJiYgdGhpcy5wcm9wcy5nb3RTY2FsZWRQcmljZXMgJiYgdGhpcy5zdGF0ZS5CdXlhYmxlKXtcclxuXHRcdFx0cHJvZHVjdENhcmRCYW5uZXIgPSAnPGRpdiBjbGFzcz1cImRpc2NvdW50LXByaWNlXCI+PHNwYW4gY2xhc3M9XCJwcmljZVwiPjxpIGNsYXNzPVwiaWNvbi1tb25leVwiPjwvaT48L3NwYW4+PC9kaXY+JztcclxuXHRcdFx0JCgnI2xpLScrbWF0ZXJpYWxOdW1iZXIrJyAuaW1hZ2UnKS5hcHBlbmQocHJvZHVjdENhcmRCYW5uZXIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMucmVmbG93KCk7XHJcblx0fVxyXG5cclxuXHRyZWZsb3coKXtcclxuXHRcdHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG5cdFx0dmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG5cdFx0dmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpO1xyXG5cclxuXHRcdGlmIChtc2llID4gMCB8fCB0cmlkZW50ID4gMCkge1xyXG5cdFx0XHRGb3VuZGF0aW9uLmxpYnMuZXF1YWxpemVyLmVxdWFsaXplKCQoJy51Yy1wcm9kdWN0bGlzdCB1bCcpKTtcclxuXHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcudWMtcHJvZHVjdGxpc3QnKSk7XHJcblx0XHRcdEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLmFtb3VudC1wcmljZS1zdG9jay13YXRjaCcpKTtcclxuXHRcdFx0Rm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuaXRlbS1uYW1lLXdhdGNoJykpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdCQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ2VxdWFsaXplcicsICdyZWZsb3cnKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG4gIHJlbmRlcigpIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIDxkaXY+XHJcblx0XHRcdHsgdGhpcy5zdGF0ZS5CdXlhYmxlID8gPEJ1eUZvb3RlciBtYXRlcmlhbE51bWJlcj17dGhpcy5zdGF0ZS5Db2RlfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJpY2U9e3RoaXMuc3RhdGUuUHJpY2V9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpblN0b2NrUXVhbnRpdHk9e3RoaXMuc3RhdGUuSW5TdG9ja1F1YW50aXR5fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c2hpcHBpbmdEYXRlPXt0aGlzLnN0YXRlLlNoaXBwaW5nRGF0ZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlzRGlzY291bnRlZD17dGhpcy5zdGF0ZS5Jc0Rpc2NvdW50ZWR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZWZhdWx0UHJpY2U9e3RoaXMuc3RhdGUuRGVmYXVsdFByaWNlfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGlzY291bnRQZXJjZW50PXt0aGlzLnN0YXRlLkRpc2NvdW50UGVyY2VudH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RDb250ZXh0PXt0aGlzLnN0YXRlLlByb2R1Y3RDb250ZXh0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Z290U2NhbGVkUHJpY2VzPXt0aGlzLnByb3BzLmdvdFNjYWxlZFByaWNlc31cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVzZXJJc0RlYWxlcj17dGhpcy5wcm9wcy5pc0RlYWxlcn1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGhhc1Byb21vdGlvbj17dGhpcy5zdGF0ZS5IYXNQcm9tb3Rpb259XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRwcm9tb3Rpb25QcmljZT17dGhpcy5zdGF0ZS5Qcm9tb3Rpb25QcmljZX1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0OiAhdGhpcy5zdGF0ZS5CdXlhYmxlICYmIHRoaXMuc3RhdGUuTG9hZGVkID8gPFZpZXdEZXRhaWxzRm9vdGVyIGhhc0Vycm9yPXt0aGlzLnN0YXRlLkhhc0Vycm9yfSBkZXRhaWxzVXJsPXt0aGlzLnByb3BzLnVybH0gLz4gOiA8RmV0Y2hQcmljZUZvb3RlciAvPiB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IEZldGNoUHJpY2VGb290ZXIgPSAocHJvcHMpID0+IHtcclxuXHRyZXR1cm4gKFxyXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmb290ZXIgbG9hZGluZ1wiPlxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNhbXBhaW5nLXdyYXBwZXJcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImNhbXBhaW5nLXdyYXBwZXJcIj5cclxuXHRcdFx0PC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgICAgIDxpIGNsYXNzTmFtZT1cImljb24tc3BpbjQgYW5pbWF0ZS1zcGluIHRleHQtY2VudGVyXCIgc3R5bGU9e3tcImRpc3BsYXlcIiA6IFwiYmxvY2tcIn19PjwvaT5cclxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LWNlbnRlclwiIHN0eWxlPXt7XCJkaXNwbGF5XCIgOiBcImJsb2NrXCJ9fT57dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mb308L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9XCJidXR0b24gbGVmdCBhZGQtdG8tY2FydFwiPnt0cmFuc2xhdGlvbnMuYWRkVG9DYXJ0fTwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3NOYW1lPVwiYnV0dG9uIHJpZ2h0IHF1aWNrLWJ1eVwiPnt0cmFuc2xhdGlvbnMucXVpY2tCdXl9PC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgKTtcclxufVxyXG5cclxuY29uc3QgQnV5Rm9vdGVyID0gKHByb3BzKSA9PiB7XHJcbiAgY29uc3QgeyBtYXRlcmlhbE51bWJlciwgcHJpY2UsIGluU3RvY2tRdWFudGl0eSwgc2hpcHBpbmdEYXRlLCBpc0Rpc2NvdW50ZWQsIGRlZmF1bHRQcmljZSwgZGlzY291bnRQZXJjZW50LCBwcm9kdWN0Q29udGV4dCwgZ290U2NhbGVkUHJpY2VzLCBwcm9tb3Rpb25QcmljZSwgaGFzUHJvbW90aW9uLCB1c2VySXNEZWFsZXJ9ID0gcHJvcHM7XHJcblxyXG4gIGxldCBtYXRlcmlhbE51bWJlckFzSWQgPSBtYXRlcmlhbE51bWJlci5zcGxpdCgnLicpLmpvaW4oJy0nKTtcclxuICBsZXQgY29udGV4dCA9IEpTT04uc3RyaW5naWZ5KHByb2R1Y3RDb250ZXh0KTtcclxuXHJcblx0bGV0IGdvdFNjYWxlZFByaWNlc0ljb24gPSAnJztcclxuXHJcblx0bGV0IGRlYWxlckluZGljYXRpb24gPSAnJztcclxuXHRpZiggdXNlcklzRGVhbGVyICl7XHJcblx0XHRpZiggaXNEaXNjb3VudGVkICl7XHJcblx0XHRcdGRlYWxlckluZGljYXRpb24gPSB0cmFuc2xhdGlvbnMucHJvbW90aW9uV2FzKyc6ICc7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0ZGVhbGVySW5kaWNhdGlvbiA9IHRyYW5zbGF0aW9ucy5ncm9zc1ByaWNlKyc6ICc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRsZXQgdHJhbnNsYXRpb25Hcm9zcyA9IHRyYW5zbGF0aW9ucy5kaXNjb3VudC5zdWJzdHJpbmcoMCwgKHRyYW5zbGF0aW9ucy5kaXNjb3VudC5pbmRleE9mKCd9JykgKyAxKSk7XHJcblx0bGV0IHRyYW5zbGF0aW9uRGlzY291bnQgPSB0cmFuc2xhdGlvbnMuZGlzY291bnQuc3Vic3RyaW5nKCh0cmFuc2xhdGlvbnMuZGlzY291bnQuaW5kZXhPZignfScpICsgMikpLnJlcGxhY2UoXCIxXCIsIFwiMFwiKTtcclxuXHRsZXQgdHJhbnNsYXRpb25XYXMgPSB0cmFuc2xhdGlvbnMucHJvbW90aW9uV2FzO1xyXG5cdGxldCB0cmFuc2xhdGlvblByb21vaXRpb25EaXNjb3VudCA9IHRyYW5zbGF0aW9ucy5wcm9tb3Rpb25UaXRsZTtcclxuXHJcblx0bGV0IGRlZmF1bHRQcmljZVRleHQgPSBzdHJpbmdmb3JtYXQodHJhbnNsYXRpb25Hcm9zcywgZGVmYXVsdFByaWNlKTtcclxuXHRsZXQgZGlzY291bnRQZXJjZW50VGV4dCA9IHN0cmluZ2Zvcm1hdCh0cmFuc2xhdGlvbkRpc2NvdW50LCBkaXNjb3VudFBlcmNlbnQpO1xyXG5cdGxldCBwcm9tb3Rpb25QcmljZVRleHQgPSB0cmFuc2xhdGlvbldhcyArICc6ICcgKyBwcmljZTtcclxuXHRsZXQgc2hpcHBpbmdJbmZvID0gbnVsbDtcclxuXHJcblx0bGV0IGNhbXBhaW5nSW5mbyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0J2NhbXBhaW5nLWluZm8nOiB0cnVlLFxyXG5cdFx0J2NsZWFyZml4JzogdHJ1ZSxcclxuXHRcdCdkZWZhdWx0JzogaXNEaXNjb3VudGVkICYmIGhhc1Byb21vdGlvbixcclxuXHRcdCdoaWRlJzogIWlzRGlzY291bnRlZCAmJiAhaGFzUHJvbW90aW9uXHJcblx0fSk7XHJcblxyXG5cdGxldCBjb3N0ID0gcHJpY2U7XHJcblx0bGV0IGhhc1NlbGVjdGVkV2lzaGxpc3QgPSAkKCcud2lzaGxpc3QtdG9nZ2xlJykuaGFzQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cclxuXHRsZXQgc2F2ZWRDYXJ0Q2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdCdzbWwnOiB0cnVlLFxyXG5cdFx0J2J1dHRvbic6IHRydWUsXHJcblx0XHQnd2lzaGxpc3QnOiB0cnVlLFxyXG5cdFx0J3NlYXJjaC1zYXZlZC1jYXJ0LWFkZCc6IHRydWUsXHJcblx0XHQnc2F2ZWQtY2FydC1hZGQnOiB0cnVlLFxyXG5cdFx0J3JpZ2h0LW9mZi1jYW52YXMtdG9nZ2xlJzogIWhhc1NlbGVjdGVkV2lzaGxpc3RcclxuXHR9KTtcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZm9vdGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwicHJpY2Utc3RvY2std3JhcHBlclwiPlxyXG4gICAgICAgICAgPHNwYW4gZGF0YS1wcm9kdWN0LWlkPXttYXRlcmlhbE51bWJlcn0gZGF0YS1hY3RpdmUtdGFiPVwicHJpY2VcIiBjbGFzc05hbWU9XCJwcmljZSBsZWZ0XCI+XHJcblx0XHRcdFx0XHRcdHtoYXNQcm9tb3Rpb24gPyBudWxsIDogZ290U2NhbGVkUHJpY2VzSWNvbn17aGFzUHJvbW90aW9uID8gYCR7cHJvbW90aW9uUHJpY2V9YCA6IGAke2RlYWxlckluZGljYXRpb259JHtwcmljZX1gfVxyXG5cdFx0XHRcdFx0PC9zcGFuPlxyXG5cdFx0XHRcdFx0e2luU3RvY2tRdWFudGl0eSAhPT0gdW5kZWZpbmVkICYmIGluU3RvY2tRdWFudGl0eVxyXG4gICAgICAgICAgICA/IDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17bWF0ZXJpYWxOdW1iZXJ9IGRhdGEtYWN0aXZlLXRhYj1cImF2YWlsYWJpbGl0eVwiIGNsYXNzTmFtZT1cInN0b2NrXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1jdWJlc1wiPjwvaT57aW5TdG9ja1F1YW50aXR5fTwvc3Bhbj5cclxuXHRcdFx0XHRcdFx0OiBzaGlwcGluZ0RhdGUgIT09IHVuZGVmaW5lZCAmJiBzaGlwcGluZ0RhdGUgIT09ICcnXHJcbiAgICAgICAgICAgICAgPyA8c3BhbiBkYXRhLXByb2R1Y3QtaWQ9e21hdGVyaWFsTnVtYmVyfSBkYXRhLWFjdGl2ZS10YWI9XCJhdmFpbGFiaWxpdHlcIiBjbGFzc05hbWU9XCJzdG9ja1wiPjxpIGNsYXNzTmFtZT1cImljb24tY3ViZXNcIj48L2k+e3NoaXBwaW5nRGF0ZX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgOiBudWxsXHJcblx0XHRcdFx0XHRcdH1cclxuICAgICAgICA8L2Rpdj5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPXtjYW1wYWluZ0luZm99PlxyXG5cdFx0XHRcdFx0e2lzRGlzY291bnRlZCAmJiAhaGFzUHJvbW90aW9uID9cclxuXHRcdFx0XHRcdDxzcGFuPjxwIGNsYXNzTmFtZT1cImdyb3NzXCI+e2RlZmF1bHRQcmljZVRleHR9PC9wPjxwPntkaXNjb3VudFBlcmNlbnRUZXh0fTwvcD48L3NwYW4+IDogJyd9XHJcblx0XHRcdFx0XHR7aXNEaXNjb3VudGVkICYmIGhhc1Byb21vdGlvbiA/XHJcblx0XHRcdFx0XHQ8c3Bhbj48cCBjbGFzc05hbWU9XCJncm9zc1wiPntkZWZhdWx0UHJpY2VUZXh0fTwvcD48cD57ZGlzY291bnRQZXJjZW50VGV4dH08L3A+PHAgY2xhc3NOYW1lPVwiZGVmYXVsdC1jYW1wYWluZ1wiPntwcm9tb3Rpb25QcmljZVRleHR9PC9wPjwvc3Bhbj4gOiAnJ31cclxuXHRcdFx0XHRcdHshaXNEaXNjb3VudGVkICYmIGhhc1Byb21vdGlvbiA/XHJcblx0XHRcdFx0XHQ8c3Bhbj48cCBjbGFzc05hbWU9XCJkZWZhdWx0LWNhbXBhaW5nXCI+e3Byb21vdGlvblByaWNlVGV4dH08L3A+PC9zcGFuPiA6ICcnfVxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCIgZGF0YS1wcm9kdWN0LWNvbnRleHQ9e2NvbnRleHR9PlxyXG5cdFx0XHRcdFx0PGlucHV0IGRhdGEtcHJvZHVjdC1za3U9e21hdGVyaWFsTnVtYmVyfSBjbGFzc05hbWU9XCJhbW91bnRcIiBuYW1lPVwiYXVtb250LXhcIiBkZWZhdWx0VmFsdWU9XCIxXCIgLz5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiYnV0dG9uc1wiPlxyXG5cdFx0XHRcdFx0XHQ8YnV0dG9uIGRhdGEtcHJvZHVjdC1za3U9e21hdGVyaWFsTnVtYmVyfSBjbGFzc05hbWU9e3NhdmVkQ2FydENsYXNzfT48aSBjbGFzc05hbWU9XCJpY29uLXNhdmVkLWNhcnQtYWRkXCI+PC9pPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHQ8YnV0dG9uIGRhdGEtcHJvZHVjdC1za3U9e21hdGVyaWFsTnVtYmVyfSBjbGFzc05hbWU9XCJidXR0b24gYWRkLXRvLWNhcnRcIj48aSBjbGFzc05hbWU9XCJpY29uLW1pbmljYXJ0XCI+PC9pPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGlkPXttYXRlcmlhbE51bWJlckFzSWR9IGNsYXNzTmFtZT1cIlNwYXJlUGFydFJlc3VsdC1pbmZvXCI+PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICApXHJcbn1cclxuXHJcbkJ1eUZvb3Rlci5wcm9wVHlwZXMgPSB7XHJcblx0ZGlzY291bnRQZXJjZW50OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG5cdGRlZmF1bHRQcmljZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICBtYXRlcmlhbE51bWJlcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICBwcmljZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICBpblN0b2NrUXVhbnRpdHk6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXHJcbiAgc2hpcHBpbmdEYXRlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXHJcbn1cclxuXHJcbmNvbnN0IFZpZXdEZXRhaWxzRm9vdGVyID0gKHByb3BzKSA9PiB7XHJcbiAgY29uc3Qge2RldGFpbHNVcmwsIGhhc0Vycm9yfSA9IHByb3BzO1xyXG5cdGxldCBkZXRhaWxzVGV4dCA9IGhhc0Vycm9yID8gdHJhbnNsYXRpb25zLnByaWNlRXJyb3IgOiB0cmFuc2xhdGlvbnMubm90QnV5YWJsZTtcclxuICByZXR1cm4gKFxyXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmb290ZXJcIj5cclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhbW91bnQtcHJpY2Utc3RvY2sgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYW1vdW50LXByaWNlLXN0b2NrXCI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidS10eHQtY2VudGVyIHUtZHRcIj57ZGV0YWlsc1RleHR9PC9zcGFuPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhZGQtdG8tYnRucyB1LWR0XCIgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJhZGQtdG8tYnRuc1wiPlxyXG4gICAgICAgIDxhIGNsYXNzTmFtZT1cImJ1dHRvbiBjZW50ZXIgbm90LWJ1eWFibGVcIiBocmVmPXtkZXRhaWxzVXJsfT57dHJhbnNsYXRpb25zLnZpZXdEZXRhaWxzfTwvYT5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICApO1xyXG59XHJcblxyXG5WaWV3RGV0YWlsc0Zvb3Rlci5wcm9wVHlwZXMgPSB7XHJcbiAgZGV0YWlsc1VybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBMYXp5TG9hZCBmcm9tICdyZWFjdC1sYXp5LWxvYWQnO1xyXG5pbXBvcnQgU3BhcmVQYXJ0Rm9vdGVyIGZyb20gJy4uL2NvbXBvbmVudHMvc2VhcmNoL3NwYXJlX3BhcnRfZm9vdGVyJztcclxuaW1wb3J0IHN0cmluZ2Zvcm1hdCBmcm9tICdzdHJpbmdmb3JtYXQnO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuXHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0ge307XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJdGVtUmVzdWx0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcbiAgICAgICAgc3VwZXIocHJvcHMpO1xyXG4gICAgfVxyXG5cdFx0Y29tcG9uZW50RGlkVXBkYXRlKCl7XHJcblx0XHRcdC8vIHRoaXMuaW1nT25Mb2FkKCk7XHJcblx0XHRcdGlmKHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzKXtcclxuXHRcdFx0XHQkKGRvY3VtZW50KS5mb3VuZGF0aW9uKCd0b29sdGlwJywgJ3JlZmxvdycpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0fVxyXG4gICAgaW1nT25Mb2FkKCl7XHJcblx0XHRcdHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG5cdFx0ICB2YXIgdHJpZGVudCA9IHVhLmluZGV4T2YoJ1RyaWRlbnQvJyk7XHJcblx0XHQgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTtcclxuXHRcdCAgaWYgKG1zaWUgPiAwIHx8IHRyaWRlbnQgPiAwKSB7XHJcblx0XHQgICAgJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcclxuXHRcdCAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnJlc3VsdC1zcGFyZS1wYXJ0cycpKTtcclxuXHRcdCAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnVjLXByb2R1Y3RsaXN0JykpO1xyXG5cdFx0ICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuYW1vdW50LXByaWNlLXN0b2NrLXdhdGNoJykpO1xyXG5cdFx0ICAgIH0pO1xyXG5cclxuXHRcdCAgfVxyXG5cdFx0ICBlbHNlIHtcclxuXHRcdCAgICAkKGRvY3VtZW50KS5mb3VuZGF0aW9uKCdlcXVhbGl6ZXInLCAncmVmbG93Jyk7XHJcblx0XHQgIH1cclxuICAgIH1cclxuICAgIHJlbmRlcigpIHtcclxuXHJcblx0XHRcdFx0Y29uc3QgaGFzSW1hZ2UgPSB0aGlzLnByb3BzLkltYWdlcyAmJiB0aGlzLnByb3BzLkltYWdlcy5sZW5ndGg+MDtcclxuICAgICAgICBsZXQgbWF0ZXJpYWxOdW1iZXJBc0lkID0gdGhpcy5wcm9wcy5NYXRlcmlhbE51bWJlciA/ICdsaS0nK3RoaXMucHJvcHMuTWF0ZXJpYWxOdW1iZXIuc3BsaXQoJy4nKS5qb2luKCctJykgOiBcIlwiO1xyXG5cdFx0XHRcdGxldCB0b29sVGlwICBcdFx0XHQ9IHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzICYmIHRoaXMucHJvcHMuSXNRdWVyeWFibGUgPyB7J2RhdGEtdG9vbHRpcCc6ICd0cnVlJ30gOiBudWxsO1xyXG5cdFx0XHRcdGxldCB0b29sVGlwVGl0bGUgXHQ9IHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzICYmIHRoaXMucHJvcHMuSXNRdWVyeWFibGUgPyB7J3RpdGxlJzogdHJhbnNsYXRpb25zLnNjYWxlZFByaWNlc1Rvb2x0aXB9IDogbnVsbDtcclxuXHRcdFx0XHRsZXQgdG9vbFRpcEFyaWEgXHQ9IHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzICYmIHRoaXMucHJvcHMuSXNRdWVyeWFibGUgPyB7J2FyaWEtaGFzcG9wdXAnOiAndHJ1ZSd9IDogbnVsbDtcclxuICAgICAgICBsZXQgdHJhbnNsYXRpb25zID0gaGlhYmNvbmZpZy5TcGFyZVBhcnRGb290ZXIubGFuZztcclxuXHRcdFx0XHRsZXQgaXRlbVdyYXBwZXJDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHRcdFx0J2l0ZW0td3JhcHBlcic6IHRydWUsXHJcblx0XHRcdFx0XHQnaGFzLXRpcCc6IHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzLFxyXG5cdFx0XHRcdFx0J3RpcC10b3AnOiB0aGlzLnByb3BzLkdvdFNjYWxlZFByaWNlc1xyXG5cdFx0XHRcdH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gKFxyXG5cclxuICAgICAgICAgIDxsaSBpZD17bWF0ZXJpYWxOdW1iZXJBc0lkfT5cclxuXHRcdCAgICAgICAgPGRpdiBjbGFzc05hbWU9e2l0ZW1XcmFwcGVyQ2xhc3N9IHsuLi50b29sVGlwfSB7Li4udG9vbFRpcFRpdGxlfSB7Li4udG9vbFRpcEFyaWF9PlxyXG5cdFx0XHQgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaW1hZ2VcIj5cclxuXHRcdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiZmlsbGVyXCIgLz5cclxuXHRcdFx0XHQgICAgICAgIFx0e2hhc0ltYWdlID8gPGEgaHJlZj17dGhpcy5wcm9wcy5Vcmx9PjxpbWcgc3JjPXt0aGlzLnByb3BzLkltYWdlc1swXS5VcmwrJz9wcmVzZXQ9bGlzdCd9IGFsdD17dGhpcy5wcm9wcy5JbWFnZXNbMF0uU2VvVGV4dH0gLz48L2E+IDogbnVsbCB9XHJcblx0XHRcdCAgICAgICAgPC9kaXY+XHJcblx0XHRcdCAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpdGVtLW5hbWVcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cIml0ZW0tbmFtZVwiPlxyXG5cdFx0XHRcdCAgICAgICAgPGg0PjxhIGhyZWY9e3RoaXMucHJvcHMuVXJsfT57dGhpcy5wcm9wcy5OYW1lfTwvYT48L2g0PlxyXG5cdFx0XHRcdCAgICAgICAgPHA+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt0aGlzLnByb3BzLk1hdGVyaWFsTnVtYmVyfTwvc3Bhbj5cclxuXHRcdFx0XHQgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY2FtcGFpbmctaW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblx0XHRcdCAgICAgICAgPC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJmb290ZXItd3JhcHBlclwiPlxyXG5cdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnByb3BzLklzUmVwbGFjZWQgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8UmVwbGFjZW1lbnRGb290ZXIgcmVwbGFjZW1lbnRVcmw9e3RoaXMucHJvcHMuUmVwbGFjZW1lbnRVcmx9IHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXI9e3RoaXMucHJvcHMuUmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcn0gdHJhbnNsYXRpb25zPXt0cmFuc2xhdGlvbnN9Lz4gOlxyXG5cdFx0XHRcdFx0XHRcdFx0ICB0aGlzLnByb3BzLklzUXVlcnlhYmxlICYmICF0aGlzLnByb3BzLklzQmxvY2tlZCA/XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PFNwYXJlUGFydEZvb3RlciBpc0RlYWxlcj17dGhpcy5wcm9wcy5pc0RlYWxlcn0gZ290U2NhbGVkUHJpY2VzPXt0aGlzLnByb3BzLkdvdFNjYWxlZFByaWNlc30gbWF0ZXJpYWxOdW1iZXI9e3RoaXMucHJvcHMuTWF0ZXJpYWxOdW1iZXJ9IHVybD17dGhpcy5wcm9wcy5Vcmx9IHRyYW5zbGF0aW9ucz17dHJhbnNsYXRpb25zfSBpc0J1eWFibGU9e3RoaXMucHJvcHMuSXNCdXlhYmxlfSB7Li4udGhpcy5wcm9wc30vPiA6XHJcblx0ICAgICAgICAgICAgICAgICAgPFZpZXdEZXRhaWxzRm9vdGVyIGlkPXttYXRlcmlhbE51bWJlckFzSWR9IHNpZ25lZEluPXt0aGlzLnByb3BzLnVzZXJJc1NpZ25lZElufSBkZXRhaWxzVXJsPXt0aGlzLnByb3BzLlVybH0gaXNCbG9ja2VkPXt0aGlzLnByb3BzLklzQmxvY2tlZH0gcmVzdHJpY3Rpb25UeXBlPXt0aGlzLnByb3BzLlJlc3RyaWN0aW9uVHlwZX0gdHJhbnNsYXRpb25zPXt0cmFuc2xhdGlvbnN9Lz5cclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdCAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgIDwvbGk+XHJcblxyXG4gICAgICAgKTtcclxuICAgIH1cclxufVxyXG5cclxuSXRlbVJlc3VsdC5wcm9wVHlwZXMgPSB7XHJcbiAgICBuYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgbWF0ZXJpYWxOdW1iZXI6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICB1cmw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICBwcmljZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIHN0b2NrOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgaXNCdXlhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcclxuICAgIGltYWdlczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxyXG4gICAgcmVwbGFjZW1lbnROYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgcmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIHJlcGxhY2VtZW50VXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXHJcbn07XHJcblxyXG5jb25zdCBSZXBsYWNlbWVudEZvb3RlciA9IChwcm9wcykgPT4ge1xyXG4gIGNvbnN0IHsgcmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlciwgcmVwbGFjZW1lbnRVcmwgfSA9IHByb3BzO1xyXG5cclxuICByZXR1cm4gKFxyXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmb290ZXJcIj5cclxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhbW91bnQtcHJpY2Utc3RvY2sgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYW1vdW50LXByaWNlLXN0b2NrXCI+XHJcbiAgICBcdCAgPHNwYW4gZGF0YS1wcm9kdWN0LWlkPXtyZXBsYWNlbWVudE1hdGVyaWFsTnVtYmVyfSBkYXRhLWFjdGl2ZS10YWI9XCJvdGhlclwiIGNsYXNzTmFtZT1cInUtdHh0LWNlbnRlciByZXBsYWNlZCB0ZXh0LWNlbnRlclwiIHN0eWxlPXt7XCJkaXNwbGF5XCIgOiBcImJsb2NrXCJ9fT57dHJhbnNsYXRpb25zLnJlcGxhY2VkQnl9OiA8YSBocmVmPXtyZXBsYWNlbWVudFVybH0+e3JlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXJ9PC9hPjwvc3Bhbj5cclxuXHRcdFx0PC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYWRkLXRvLWJ0bnNcIj5cclxuICBcdFx0XHQ8YSBjbGFzc05hbWU9XCJidXR0b24gY2VudGVyIG5vdC1idXlhYmxlXCIgaHJlZj17cmVwbGFjZW1lbnRVcmx9Pnt0cmFuc2xhdGlvbnMudmlld1JlcGxhY2luZ1Byb2R1Y3R9PC9hPlxyXG4gIFx0XHQ8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICk7XHJcbn1cclxuXHJcblJlcGxhY2VtZW50Rm9vdGVyLnByb3BUeXBlcyA9IHtcclxuICByZXBsYWNlbWVudE1hdGVyaWFsTnVtYmVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gIHJlcGxhY2VtZW50VXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXHJcbn1cclxuXHJcbi8vc2hvd24gaWYgbm90IHF1ZXJ5YWJsZVxyXG5jb25zdCBWaWV3RGV0YWlsc0Zvb3RlciA9IChwcm9wcykgPT4ge1xyXG4gIGNvbnN0IHtpZCwgZGV0YWlsc1VybCwgc2lnbmVkSW4sIGlzQmxvY2tlZCwgcmVzdHJpY3Rpb25UeXBlLCB0cmFuc2xhdGlvbnN9ID0gcHJvcHM7XHJcblxyXG4gIGxldCBtYXRlcmlhbFN0YXR1cyA9XHJcbiAgICBpc0Jsb2NrZWQgJiYgcmVzdHJpY3Rpb25UeXBlICE9IG51bGwgJiYgcmVzdHJpY3Rpb25UeXBlID09ICdQcmluY2V0b24nID8gdHJhbnNsYXRpb25zLnByaW5jZXRvbiA6XHJcbiAgICBzaWduZWRJbiA/IHRyYW5zbGF0aW9ucy5ub3RCdXlhYmxlIDogdHJhbnNsYXRpb25zLm5vdEJ1eWFibGVTaWduSW47XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZvb3RlclwiPlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFtb3VudC1wcmljZS1zdG9jayB1LWR0XCIgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJhbW91bnQtcHJpY2Utc3RvY2tcIj5cclxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ1LXR4dC1jZW50ZXIgdS1kdFwiPnttYXRlcmlhbFN0YXR1c308L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgICAgICAgPGEgY2xhc3NOYW1lPVwiYnV0dG9uIGNlbnRlciBub3QtYnV5YWJsZVwiIGhyZWY9e2RldGFpbHNVcmx9Pnt0cmFuc2xhdGlvbnMudmlld0RldGFpbHN9PC9hPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICk7XHJcbn1cclxuXHJcblZpZXdEZXRhaWxzRm9vdGVyLnByb3BUeXBlcyA9IHtcclxuICBkZXRhaWxzVXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXHJcbn1cclxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IExhenlMb2FkIGZyb20gJ3JlYWN0LWxhenktbG9hZCc7XHJcbmltcG9ydCBJdGVtRm9vdGVyIGZyb20gJy4vZm9vdGVyX2NvbmRlbnNlZCc7XHJcbmltcG9ydCBzdHJpbmdmb3JtYXQgZnJvbSAnc3RyaW5nZm9ybWF0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5cclxubGV0IHRyYW5zbGF0aW9ucyA9IHt9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29uZGVuc2VkSXRlbVJlc3VsdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgICAgIHN1cGVyKHByb3BzKTtcclxuICAgIH1cclxuXHRcdGNvbXBvbmVudERpZFVwZGF0ZSgpe1xyXG5cdFx0XHRpZih0aGlzLnByb3BzLkdvdFNjYWxlZFByaWNlcyl7XHJcblx0XHRcdFx0JChkb2N1bWVudCkuZm91bmRhdGlvbigndG9vbHRpcCcsICdyZWZsb3cnKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG4gICAgaW1nT25Mb2FkKCl7XHJcblx0XHRcdHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG5cdFx0ICB2YXIgdHJpZGVudCA9IHVhLmluZGV4T2YoJ1RyaWRlbnQvJyk7XHJcblx0XHQgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTtcclxuXHRcdCAgaWYgKG1zaWUgPiAwIHx8IHRyaWRlbnQgPiAwKSB7XHJcblx0XHQgICAgJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcclxuICAgICAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnJlc3VsdC1zcGFyZS1wYXJ0cycpKTtcclxuXHRcdCAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnLnVjLXByb2R1Y3RsaXN0JykpO1xyXG5cdFx0ICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcuYW1vdW50LXByaWNlLXN0b2NrLXdhdGNoJykpO1xyXG5cdFx0ICAgIH0pO1xyXG5cdFx0ICB9XHJcblx0XHQgIGVsc2Uge1xyXG5cdFx0ICAgICQoZG9jdW1lbnQpLmZvdW5kYXRpb24oJ2VxdWFsaXplcicsICdyZWZsb3cnKTtcclxuXHRcdCAgfVxyXG4gICAgfVxyXG4gICAgcmVuZGVyKCkge1xyXG5cdFx0XHRcdGNvbnN0IGhhc0ltYWdlID0gdGhpcy5wcm9wcy5JbWFnZXMgJiYgdGhpcy5wcm9wcy5JbWFnZXMubGVuZ3RoPjA7XHJcblxyXG4gICAgICAgIGxldCBtYXRlcmlhbE51bWJlckFzSWQgPSB0aGlzLnByb3BzLk1hdGVyaWFsTnVtYmVyID8gJ2xpLScrdGhpcy5wcm9wcy5NYXRlcmlhbE51bWJlci5zcGxpdCgnLicpLmpvaW4oJy0nKSA6IFwiXCI7XHJcblx0XHRcdFx0bGV0IHRvb2xUaXAgIFx0XHRcdD0gdGhpcy5wcm9wcy5Hb3RTY2FsZWRQcmljZXMgJiYgdGhpcy5wcm9wcy5Jc1F1ZXJ5YWJsZSA/IHsnZGF0YS10b29sdGlwJzogJ3RydWUnfSA6IG51bGw7XHJcblx0XHRcdFx0bGV0IHRvb2xUaXBUaXRsZSBcdD0gdGhpcy5wcm9wcy5Hb3RTY2FsZWRQcmljZXMgJiYgdGhpcy5wcm9wcy5Jc1F1ZXJ5YWJsZSA/IHsndGl0bGUnOiB0cmFuc2xhdGlvbnMuc2NhbGVkUHJpY2VzVG9vbHRpcH0gOiBudWxsO1xyXG5cdFx0XHRcdGxldCB0b29sVGlwQXJpYSBcdD0gdGhpcy5wcm9wcy5Hb3RTY2FsZWRQcmljZXMgJiYgdGhpcy5wcm9wcy5Jc1F1ZXJ5YWJsZSA/IHsnYXJpYS1oYXNwb3B1cCc6ICd0cnVlJ30gOiBudWxsO1xyXG4gICAgICAgIGxldCB0cmFuc2xhdGlvbnMgPSBoaWFiY29uZmlnLlNwYXJlUGFydEZvb3Rlci5sYW5nO1xyXG5cclxuICAgICAgICBsZXQgaXRlbVdyYXBwZXJDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHRcdFx0J2l0ZW0td3JhcHBlcic6IHRydWUsXHJcblx0XHRcdFx0XHQnaGFzLXRpcCc6IHRoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzLFxyXG5cdFx0XHRcdFx0J3RpcC10b3AnOiB0aGlzLnByb3BzLkdvdFNjYWxlZFByaWNlc1xyXG5cdFx0XHRcdH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gKFxyXG5cclxuICAgICAgICAgIDxsaSBpZD17bWF0ZXJpYWxOdW1iZXJBc0lkfT5cclxuXHRcdCAgICAgICAgPGRpdiBjbGFzc05hbWU9e2l0ZW1XcmFwcGVyQ2xhc3N9IHsuLi50b29sVGlwfSB7Li4udG9vbFRpcFRpdGxlfSB7Li4udG9vbFRpcEFyaWF9PlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaGVhZGVyXCI+XHJcbiAgXHRcdFx0ICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImltYWdlXCI+XHJcbiAgXHRcdFx0XHQgICAgICAgIFx0e2hhc0ltYWdlID8gPGEgaHJlZj17dGhpcy5wcm9wcy5Vcmx9PjxpbWcgc3JjPXt0aGlzLnByb3BzLkltYWdlc1swXS5VcmwrJz9wcmVzZXQ9bGlzdCd9IGFsdD17dGhpcy5wcm9wcy5JbWFnZXNbMF0uU2VvVGV4dH0gLz48L2E+IDogbnVsbCB9XHJcbiAgXHRcdFx0ICAgICAgICA8L2Rpdj5cclxuICBcdFx0XHQgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS1uYW1lXCIgZGF0YS1lcXVhbGl6ZXItd2F0Y2g9XCJpdGVtLW5hbWVcIj5cclxuICBcdFx0XHRcdCAgICAgICAgPGg0PjxhIGhyZWY9e3RoaXMucHJvcHMuVXJsfT57dGhpcy5wcm9wcy5OYW1lfTwvYT48L2g0PlxyXG4gIFx0XHRcdFx0ICAgICAgICA8cD5cclxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57dGhpcy5wcm9wcy5NYXRlcmlhbE51bWJlcn08L3NwYW4+XHJcbiAgXHRcdFx0XHQgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjYW1wYWluZy1pbmZvXCI+XHJcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gIFx0XHRcdCAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJmb290ZXItd3JhcHBlclwiPlxyXG5cdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnByb3BzLklzUmVwbGFjZWQgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8UmVwbGFjZW1lbnRGb290ZXIgcmVwbGFjZW1lbnRVcmw9e3RoaXMucHJvcHMuUmVwbGFjZW1lbnRVcmx9IHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXI9e3RoaXMucHJvcHMuUmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcn0gIHRyYW5zbGF0aW9ucz17dHJhbnNsYXRpb25zfS8+IDpcclxuXHRcdFx0XHRcdFx0XHRcdCAgdGhpcy5wcm9wcy5Jc1F1ZXJ5YWJsZSAmJiAhdGhpcy5wcm9wcy5Jc0Jsb2NrZWQgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdDxJdGVtRm9vdGVyIGlzRGVhbGVyPXt0aGlzLnByb3BzLmlzRGVhbGVyfSBnb3RTY2FsZWRQcmljZXM9e3RoaXMucHJvcHMuR290U2NhbGVkUHJpY2VzfSBtYXRlcmlhbE51bWJlcj17dGhpcy5wcm9wcy5NYXRlcmlhbE51bWJlcn0gdXJsPXt0aGlzLnByb3BzLlVybH0gdHJhbnNsYXRpb25zPXt0cmFuc2xhdGlvbnN9IGlzQnV5YWJsZT17dGhpcy5wcm9wcy5pc0J1eWFibGV9IC8+IDpcclxuXHQgICAgICAgICAgICAgICAgICA8Vmlld0RldGFpbHNGb290ZXIgaWQ9e21hdGVyaWFsTnVtYmVyQXNJZH0gc2lnbmVkSW49e3RoaXMucHJvcHMudXNlcklzU2lnbmVkSW59IGRldGFpbHNVcmw9e3RoaXMucHJvcHMuVXJsfSBpc0Jsb2NrZWQ9e3RoaXMucHJvcHMuSXNCbG9ja2VkfSByZXN0cmljdGlvblR5cGU9e3RoaXMucHJvcHMuUmVzdHJpY3Rpb25UeXBlfSB0cmFuc2xhdGlvbnM9e3RyYW5zbGF0aW9uc30vPlxyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0ICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgPC9saT5cclxuICAgICAgICk7XHJcbiAgICB9XHJcbn1cclxuXHJcbkNvbmRlbnNlZEl0ZW1SZXN1bHQucHJvcFR5cGVzID0ge1xyXG4gICAgbmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIG1hdGVyaWFsTnVtYmVyOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgdXJsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxyXG4gICAgcHJpY2U6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICBzdG9jazogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIGlzQnV5YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXHJcbiAgICBpbWFnZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcclxuICAgIHJlcGxhY2VtZW50TmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICAgIHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXI6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXHJcbiAgICByZXBsYWNlbWVudFVybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xyXG59O1xyXG5cclxuY29uc3QgUmVwbGFjZW1lbnRGb290ZXIgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7IHJlcGxhY2VtZW50TWF0ZXJpYWxOdW1iZXIsIHJlcGxhY2VtZW50VXJsIH0gPSBwcm9wcztcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZm9vdGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgXHQgIDxzcGFuIGRhdGEtcHJvZHVjdC1pZD17cmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcn0gZGF0YS1hY3RpdmUtdGFiPVwib3RoZXJcIiBjbGFzc05hbWU9XCJ1LXR4dC1jZW50ZXIgcmVwbGFjZWQgdGV4dC1jZW50ZXJcIiBzdHlsZT17e1wiZGlzcGxheVwiIDogXCJibG9ja1wifX0+e3RyYW5zbGF0aW9ucy5yZXBsYWNlZEJ5fTogPGEgaHJlZj17cmVwbGFjZW1lbnRVcmx9PntyZXBsYWNlbWVudE1hdGVyaWFsTnVtYmVyfTwvYT48L3NwYW4+XHJcblx0XHRcdDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFkZC10by1idG5zXCI+XHJcbiAgXHRcdFx0PGEgY2xhc3NOYW1lPVwiYnV0dG9uIGNlbnRlciBub3QtYnV5YWJsZVwiIGhyZWY9e3JlcGxhY2VtZW50VXJsfT57dHJhbnNsYXRpb25zLnZpZXdSZXBsYWNpbmdQcm9kdWN0fTwvYT5cclxuICBcdFx0PC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICApO1xyXG59XHJcblxyXG5SZXBsYWNlbWVudEZvb3Rlci5wcm9wVHlwZXMgPSB7XHJcbiAgcmVwbGFjZW1lbnRNYXRlcmlhbE51bWJlcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcclxuICByZXBsYWNlbWVudFVybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xyXG59XHJcblxyXG4vL3Nob3duIGlmIG5vdCBxdWVyeWFibGVcclxuY29uc3QgVmlld0RldGFpbHNGb290ZXIgPSAocHJvcHMpID0+IHtcclxuICBjb25zdCB7aWQsIGRldGFpbHNVcmwsIHNpZ25lZEluLCBpc0Jsb2NrZWQsIHJlc3RyaWN0aW9uVHlwZX0gPSBwcm9wcztcclxuXHJcbiAgbGV0IG1hdGVyaWFsU3RhdHVzID1cclxuICAgIGlzQmxvY2tlZCAmJiByZXN0cmljdGlvblR5cGUgIT0gbnVsbCAmJiByZXN0cmljdGlvblR5cGUgPT0gJ1ByaW5jZXRvbicgPyB0cmFuc2xhdGlvbnMucHJpbmNldG9uIDpcclxuICAgIHNpZ25lZEluID8gdHJhbnNsYXRpb25zLm5vdEJ1eWFibGUgOiB0cmFuc2xhdGlvbnMubm90QnV5YWJsZVNpZ25JbjtcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZm9vdGVyXCI+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIiBkYXRhLWVxdWFsaXplci13YXRjaD1cImFtb3VudC1wcmljZS1zdG9ja1wiPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInUtdHh0LWNlbnRlciB1LWR0XCI+e21hdGVyaWFsU3RhdHVzfTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiIGRhdGEtZXF1YWxpemVyLXdhdGNoPVwiYWRkLXRvLWJ0bnNcIj5cclxuICAgICAgICA8YSBjbGFzc05hbWU9XCJidXR0b24gY2VudGVyIG5vdC1idXlhYmxlXCIgaHJlZj17ZGV0YWlsc1VybH0+e3RyYW5zbGF0aW9ucy52aWV3RGV0YWlsc308L2E+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgKTtcclxufVxyXG5cclxuVmlld0RldGFpbHNGb290ZXIucHJvcFR5cGVzID0ge1xyXG4gIGRldGFpbHNVcmw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcclxufVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy9wcmljZV9zZXJ2aWNlX2FjdGlvbnMnO1xyXG5pbXBvcnQgUHJpY2VTZXJ2aWNlU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9wcmljZV9zZXJ2aWNlX3N0b3JlJztcclxuaW1wb3J0IFNlYXJjaFJlc3VsdFN0b3JlIGZyb20gJy4uL19zdG9yZXMvc2VhcmNoX3Jlc3VsdF9zdG9yZSc7XHJcbmltcG9ydCBJdGVtUmVzdWx0IGZyb20gJy4vaXRlbSc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG4gICAgdGhpcy5zdGF0ZSA9IHtcclxuICAgICAgaXNTaWduZWRJbjogJCgnYm9keS51c2VyTG9nZ2VkSW4nKS5sZW5ndGggPiAwLFxyXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcclxuICAgICAgaXNEZWFsZXI6ICQoJ2JvZHkuaXMtZGVhbGVyJykubGVuZ3RoID4gMCxcclxuICAgIH07XHJcbiAgICB0aGlzLnByaWNlUmVxdWVzdCgpO1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKXtcclxuXHJcbiAgfVxyXG4gIGNvbXBvbmVudFdpbGxVbk1vdW50KCl7XHJcbiAgICBSZWNvbW1lbmRhdGlvbnNTdG9yZS51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpY2VSZXF1ZXN0KCl7XHJcblxyXG4gICAgdGhpcy5wcm9wcy5yZXNwb25zZS5SZWNvbW1lbmRhdGlvbnMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG4gICAgICBpZihpdGVtLklzUXVlcnlhYmxlKXtcclxuICAgICAgICBQcmljZVNlcnZpY2VBY3Rpb25zLmFkZE1hdGVyaWFscyhpdGVtLk1hdGVyaWFsTnVtYmVyKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICBQcmljZVNlcnZpY2VBY3Rpb25zLmZldGNoUHJpY2VzKFNlYXJjaFJlc3VsdFN0b3JlLmdldEJhdGNoU2l6ZSgpKTtcclxuICB9XHJcblxyXG4gIHJlbmRlcigpIHtcclxuICAgIGlmKCF0aGlzLnByb3BzLnJlc3BvbnNlLlJlY29tbWVuZGF0aW9ucyl7XHJcbiAgICAgICQoXCIucHJvZHVjdC1yZWNvbW1lbmRhdGlvbnMuXCIgKyB0aGlzLnByb3BzLnJlc3BvbnNlLklkKS5oaWRlKCk7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZXN1bHRJdGVtcyA9IHRoaXMucHJvcHMucmVzcG9uc2UuUmVjb21tZW5kYXRpb25zO1xyXG4gICAgbGV0IHJlc3VsdCA9IFtdO1xyXG5cclxuICAgIHJlc3VsdCA9IHJlc3VsdEl0ZW1zLm1hcCgoeCkgPT4ge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIDxJdGVtUmVzdWx0IGlzRGVhbGVyPXt0aGlzLnN0YXRlLmlzRGVhbGVyfSB1c2VySXNTaWduZWRJbj17dGhpcy5zdGF0ZS5pc1NpZ25lZElufSBrZXk9e3guTWF0ZXJpYWxOdW1iZXJ9IHsuLi54fSAvPlxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPHVsIGNsYXNzTmFtZT1cImxpc3RcIj5cclxuICAgICAgICAgIHtyZXN1bHR9XHJcbiAgICAgIDwvdWw+XHJcbiAgICApO1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5cclxubGV0IHRyYW5zbGF0aW9ucyA9IGhpYWJjb25maWcuU3BhcmVQYXJ0Rm9vdGVyLmxhbmc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0U2tlbGV0b24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcbiAgICBzdXBlcihwcm9wcyk7XHJcbiAgICB0aGlzLnN0YXRlID0ge1xyXG5cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBjb21wb25lbnREaWRNb3VudCgpe1xyXG5cclxuICB9XHJcbiAgY29tcG9uZW50V2lsbFVuTW91bnQoKXtcclxuICAgIFJlY29tbWVuZGF0aW9uc1N0b3JlLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICByZW5kZXIoKSB7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPHVsIGNsYXNzTmFtZT1cInJlc3VsdC1zcGFyZS1wYXJ0cyBsaXN0XCI+XHJcbiAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS13cmFwcGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpbWFnZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZpbGxlclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIkxhenlMb2FkIGlzLXZpc2libGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL1N0eWxlcy9pbWFnZXMvcHJvZHVjdC1wbGFjZWhvbGRlcjJ4Mi5wbmdcIiBhbHQ9XCJwcm9kdWN0IG5hbWVcIi8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImRpc2NvdW50LXByaWNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS1uYW1lIHNrZWxldG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWVuYW1lPVwidGV4dC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3NOYW1lPVwiaWNvbi1zcGluNCBhbmltYXRlLXNwaW4gdGV4dC1jZW50ZXJcIj48L2k+IHt0cmFuc2xhdGlvbnMuZmV0Y2hpbmdJbmZvfVxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjYW1wYWluZy1pbmZvXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgPGxpPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpdGVtLXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImltYWdlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmlsbGVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiTGF6eUxvYWQgaXMtdmlzaWJsZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvU3R5bGVzL2ltYWdlcy9wcm9kdWN0LXBsYWNlaG9sZGVyMngyLnBuZ1wiIGFsdD1cInByb2R1Y3QgbmFtZVwiLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZGlzY291bnQtcHJpY2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpdGVtLW5hbWUgc2tlbGV0b25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lbmFtZT1cInRleHQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3NOYW1lPVwiaWNvbi1zcGluNCBhbmltYXRlLXNwaW4gdGV4dC1jZW50ZXJcIj48L2k+IHt0cmFuc2xhdGlvbnMuZmV0Y2hpbmdJbmZvfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY2FtcGFpbmctaW5mb1wiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS13cmFwcGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpbWFnZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZpbGxlclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIkxhenlMb2FkIGlzLXZpc2libGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL1N0eWxlcy9pbWFnZXMvcHJvZHVjdC1wbGFjZWhvbGRlcjJ4Mi5wbmdcIiBhbHQ9XCJwcm9kdWN0IG5hbWVcIi8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImRpc2NvdW50LXByaWNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS1uYW1lIHNrZWxldG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZW5hbWU9XCJ0ZXh0LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzTmFtZT1cImljb24tc3BpbjQgYW5pbWF0ZS1zcGluIHRleHQtY2VudGVyXCI+PC9pPiB7dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mb31cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImNhbXBhaW5nLWluZm9cIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0td3JhcHBlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaW1hZ2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmaWxsZXJcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJMYXp5TG9hZCBpcy12aXNpYmxlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9TdHlsZXMvaW1hZ2VzL3Byb2R1Y3QtcGxhY2Vob2xkZXIyeDIucG5nXCIgYWx0PVwicHJvZHVjdCBuYW1lXCIvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJkaXNjb3VudC1wcmljZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tbmFtZSBza2VsZXRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWVuYW1lPVwidGV4dC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzc05hbWU9XCJpY29uLXNwaW40IGFuaW1hdGUtc3BpbiB0ZXh0LWNlbnRlclwiPjwvaT4ge3RyYW5zbGF0aW9ucy5mZXRjaGluZ0luZm99XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJjYW1wYWluZy1pbmZvXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9saT5cclxuICAgICAgICA8L3VsPlxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5cclxubGV0IHNldEhlaWdodCA9IDA7XHJcbmxldCBuYW1lSGVpZ2h0ID0gMDtcclxubGV0IGFtdEhlaWdodCA9IDA7XHJcblxyXG5cclxubGV0IHJlZmxvdyA9IHtcclxuXHRpbml0KCkge1xyXG5cdFx0JCh3aW5kb3cpLm9uKFwicmVzaXplXCIsIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZWZsb3cucmVmbG93KCk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuICByZWZsb3coaWQpIHtcclxuICAgIHZhciB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG4gICAgdmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG4gICAgdmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpO1xyXG4gICAgaWYgKG1zaWUgPiAwIHx8IHRyaWRlbnQgPiAwKSB7XHJcbiAgICAgIEZvdW5kYXRpb24ubGlicy5lcXVhbGl6ZXIuZXF1YWxpemUoJCgnIycgKyBpZCArICcgLmFtb3VudC1wcmljZS1zdG9jay13YXRjaCcpKTtcclxuICAgICAgRm91bmRhdGlvbi5saWJzLmVxdWFsaXplci5lcXVhbGl6ZSgkKCcjJyArIGlkICsgJyAuaXRlbS1uYW1lLXdhdGNoJykpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgJChkb2N1bWVudCkuZm91bmRhdGlvbignZXF1YWxpemVyJywgJ3JlZmxvdycpO1xyXG4gICAgfVxyXG4gICAgJCgnIycgKyBpZCArICcgLnJlY29tZW5kZWQtc2xpZGVyICBsaScpLmVhY2goZnVuY3Rpb24oaW5kZXgpIHtcclxuICAgICAgaWYgKCQodGhpcykuaGVpZ2h0KCkgPiBzZXRIZWlnaHQpIHtcclxuICAgICAgICBzZXRIZWlnaHQgPSAkKHRoaXMpLmhlaWdodCgpO1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBpdGVtTmFtZSA9ICQodGhpcykuY2hpbGRyZW4oKS5maW5kKCcuaXRlbS1uYW1lJyk7XHJcbiAgICAgIGxldCBhbXRJdGVtID0gJCh0aGlzKS5jaGlsZHJlbigpLmZpbmQoJy5mb290ZXInKS5jaGlsZHJlbignLmFtb3VudC1wcmljZS1zdG9jaycpO1xyXG4gICAgICBpZiAoaXRlbU5hbWUuaGVpZ2h0KCkgPiBuYW1lSGVpZ2h0KSB7XHJcbiAgICAgICAgbmFtZUhlaWdodCA9IGl0ZW1OYW1lLmhlaWdodCgpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChhbXRJdGVtLmhlaWdodCgpID4gYW10SGVpZ2h0KSB7XHJcbiAgICAgICAgYW10SGVpZ2h0ID0gYW10SXRlbS5oZWlnaHQoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG5cclxuICAgICAgICAkKCcjJyArIGlkICsgJyAucmVjb21lbmRlZC1zbGlkZXIgLml0ZW0tbmFtZScpLmhlaWdodChuYW1lSGVpZ2h0KTtcclxuICAgICAgICAkKCcjJyArIGlkICsgJyAucmVjb21lbmRlZC1zbGlkZXIgLmFtb3VudC1wcmljZS1zdG9jaycpLmhlaWdodChhbXRIZWlnaHQpO1xyXG4gICAgICAgICQoJyMnICsgaWQgKyAnIC5wcm9kdWN0ZGV0YWlsLXNsaWRlcicpLmhlaWdodChzZXRIZWlnaHQpO1xyXG4gICAgICAgICQoJyMnICsgaWQgKyAnIC51Yy1wcm9kdWN0LXVwc2VsbCAubFNTbGlkZVdyYXBwZXInKS5oZWlnaHQoc2V0SGVpZ2h0KTtcclxuICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCByZWZsb3c7XHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xyXG5pbXBvcnQgTGlzdFNrZWxldG9uIGZyb20gJy4vbGlzdF9za2VsZXRvbic7XHJcbmltcG9ydCBTbGlkZXJTa2VsZXRvbiBmcm9tICcuL3NsaWRlcl9za2VsZXRvbic7XHJcbmltcG9ydCBSZWNvbW1lbmRhdGlvbnNBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3NhbGVzZm9yY2VfcmVjb21tZW5kYXRpb25zX2FjdGlvbnMnO1xyXG5cclxudmFyIHJlY29tbWVuZGF0aW9uUmVxdWVzdCA9IHt9O1xyXG5cclxuY29uc3QgU2FsZXNmb3JjZVJlY29tbWVuZGF0aW9ucyA9IHtcclxuXHRpbml0KCkge1xyXG5cclxuICAgICQoJy5sb2FkLXNrZWxldG9uLWxpc3QnKS5lYWNoKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIFJlYWN0RE9NLnJlbmRlcig8TGlzdFNrZWxldG9uIC8+LCB0aGlzKTtcclxuICAgIH0pO1xyXG5cclxuICAgICQoJy5sb2FkLXNrZWxldG9uLXNsaWRlcicpLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgUmVhY3RET00ucmVuZGVyKDxTbGlkZXJTa2VsZXRvbiAvPiwgdGhpcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKCcucHJvZHVjdC1yZWNvbW1lbmRhdGlvbnMnKS5lYWNoKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJlY29tbWVuZGF0aW9uUmVxdWVzdCA9IHtcclxuICAgICAgICAgIElkOiAkKHRoaXMpLmRhdGEoJ2lkJyksXHJcbiAgICAgICAgICBUeXBlOiAkKHRoaXMpLmRhdGEoJ3JlY29tbWVuZGF0aW9uLXR5cGUnKSxcclxuICAgICAgICAgIE1hdGVyaWFsTnVtYmVyOiAkKHRoaXMpLmRhdGEoJ2VsZW1lbnQnKSxcclxuICAgICAgICAgIE51bWJlck9mSXRlbXM6ICQodGhpcykuZGF0YSgnYW1vdW50JyksXHJcbiAgICAgICAgICBDdXJyZW50VXJsOiB3aW5kb3cubG9jYXRpb24uaHJlZixcclxuICAgICAgICAgIEJsb2NrU3R5bGU6ICQodGhpcykuZGF0YSgnYmxvY2tzdHlsZScpLFxyXG5cdFx0XHRcdFx0TGFuZ3VhZ2VDb2RlOiBoaWFiY29uZmlnLnByZWZlcnJlZEN1bHR1cmVcclxuICAgICAgICB9XHJcbiAgICAgICAgUmVjb21tZW5kYXRpb25zQWN0aW9ucy5sb2FkUmVjb21tZW5kYXRpb25zKHJlY29tbWVuZGF0aW9uUmVxdWVzdCk7XHJcbiAgICAgIH0pO1xyXG5cdH0sXHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBTYWxlc2ZvcmNlUmVjb21tZW5kYXRpb25zO1xyXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgU2VhcmNoUmVzdWx0U3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9zZWFyY2hfcmVzdWx0X3N0b3JlJztcclxuaW1wb3J0IFByaWNlU2VydmljZUFjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvcHJpY2Vfc2VydmljZV9hY3Rpb25zJztcclxuaW1wb3J0IFByaWNlU2VydmljZVN0b3JlIGZyb20gJy4uL19zdG9yZXMvcHJpY2Vfc2VydmljZV9zdG9yZSc7XHJcbmltcG9ydCBJdGVtUmVzdWx0IGZyb20gJy4vaXRlbSc7XHJcbmltcG9ydCBDb25kZW5zZWRJdGVtUmVzdWx0IGZyb20gJy4vaXRlbV9jb25kZW5zZWQnO1xyXG5pbXBvcnQgUmVmbG93IGZyb20gJy4vcmVmbG93JztcclxuaW1wb3J0IGxpZ2h0U2xpZGVyIGZyb20gJ2xpZ2h0c2xpZGVyJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcclxuICAgIHN1cGVyKHByb3BzKTtcclxuICAgIHRoaXMuc3RhdGUgPSB7XHJcbiAgICAgIGlzU2lnbmVkSW46ICQoJ2JvZHkudXNlckxvZ2dlZEluJykubGVuZ3RoID4gMCxcclxuICAgICAgbG9hZGluZzogZmFsc2UsXHJcbiAgICAgIGlzRGVhbGVyOiAkKCdib2R5LmlzLWRlYWxlcicpLmxlbmd0aCA+IDAsXHJcbiAgICAgIGJsb2NrSWQ6IHByb3BzLnJlc3BvbnNlLklkLFxyXG4gICAgICBzbGlkZXJIZWlnaHQ6IDAsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKXtcclxuXHJcbiAgICB0aGlzLnByaWNlUmVxdWVzdCgpO1xyXG5cclxuICAgIHZhciBpZCA9IHRoaXMuc3RhdGUuYmxvY2tJZDtcclxuICAgIHZhciBzbGlkZXIgPSAkKFwiI1wiICsgaWQgKyAnIC5yZWNvbWVuZGVkLXNsaWRlcicpLmxpZ2h0U2xpZGVyKHtcclxuICAgICAgICAgIGNvbnRyb2xzOiBmYWxzZSxcclxuICAgICAgICAgIGl0ZW06IDMsXHJcbiAgICAgICAgICBsb29wOiBmYWxzZSxcclxuICAgICAgICAgIHNsaWRlTW92ZTogMSxcclxuICAgICAgICAgIHNsaWRlTWFyZ2luOiAwLFxyXG4gICAgICAgICAgc3BlZWQ6IDg1MCwgLy9tcydcclxuICAgICAgICAgIGF1dG86IGZhbHNlLFxyXG4gICAgICAgICAgc2xpZGVFbmRBbmltYXRpb246IHRydWUsXHJcbiAgICAgICAgICBlbmFibGVEcmFnOiBmYWxzZSxcclxuICAgICAgICAgIGFkYXB0aXZlSGVpZ2h0OiB0cnVlLFxyXG4gICAgICAgICAgcmVzcG9uc2l2ZTogW1xyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgYnJlYWtwb2ludDogMTIyMCxcclxuICAgICAgICAgICAgICBzZXR0aW5nczoge1xyXG4gICAgICAgICAgICAgICAgaXRlbTogM1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSx7XHJcbiAgICAgICAgICAgICAgYnJlYWtwb2ludDogOTIwLFxyXG4gICAgICAgICAgICAgIHNldHRpbmdzOiB7XHJcbiAgICAgICAgICAgICAgICBpdGVtOiAyXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LHtcclxuICAgICAgICAgICAgICBicmVha3BvaW50OiA2MzAsXHJcbiAgICAgICAgICAgICAgc2V0dGluZ3M6IHtcclxuICAgICAgICAgICAgICAgIGl0ZW06IDFcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIF0sXHJcbiAgICAgICAgICBvblNsaWRlckxvYWQoZWwpIHtcclxuICAgICAgICAgICAgdmFyIG5ld1NsaWRlcldpZHRoID0gc2xpZGVyLndpZHRoKCkgKyAxO1xyXG4gICAgICAgICAgICBzbGlkZXIud2lkdGgobmV3U2xpZGVyV2lkdGgpO1xyXG4gICAgICAgICAgICBzbGlkZXIuYWRkQ2xhc3MoJ2xvYWRlZCcpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICQoJyMnICsgaWQgKyAnIC5zbGlkZXItY29udHJvbC5uZXh0Jykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBzbGlkZXIuZ29Ub05leHRTbGlkZSgpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAkKCcjJyArIGlkICsgJyAuc2xpZGVyLWNvbnRyb2wucHJldicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgc2xpZGVyLmdvVG9QcmV2U2xpZGUoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZSA9IFByaWNlU2VydmljZVN0b3JlLmxpc3RlbigoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLnJlZmxvdyhzbGlkZXIpO1xyXG4gICAgICAgIH0pO1xyXG4gIH1cclxuICBjb21wb25lbnRXaWxsVW5Nb3VudCgpe1xyXG4gICAgUmVjb21tZW5kYXRpb25zU3RvcmUudW5zdWJzY3JpYmUoKTtcclxuICAgIFByaWNlU2VydmljZVN0b3JlLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBwcmljZVJlcXVlc3QoKXtcclxuICAgIHRoaXMucHJvcHMucmVzcG9uc2UuUmVjb21tZW5kYXRpb25zLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgaWYoaXRlbS5Jc1F1ZXJ5YWJsZSl7XHJcbiAgICAgICAgUHJpY2VTZXJ2aWNlQWN0aW9ucy5hZGRNYXRlcmlhbHMoaXRlbS5NYXRlcmlhbE51bWJlcik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgUHJpY2VTZXJ2aWNlQWN0aW9ucy5mZXRjaFByaWNlcyhTZWFyY2hSZXN1bHRTdG9yZS5nZXRCYXRjaFNpemUoKSk7XHJcbiAgfVxyXG5cclxuICByZWZsb3coc2xpZGVyKSB7XHJcblxyXG4gICAgdmFyIG5hbWVIZWlnaHQgPSAwO1xyXG4gICAgdmFyIGFtb3VudEhlaWdodCA9IDA7XHJcblxyXG4gICAgJChzbGlkZXIuY2hpbGRyZW4oKSkuZWFjaChmdW5jdGlvbihpbmRleCkge1xyXG5cdFx0XHRpZiAoJCh0aGlzKS5maW5kKCcuaXRlbS1uYW1lJykuaGVpZ2h0KCkgPiBuYW1lSGVpZ2h0KSB7XHJcblx0XHRcdFx0bmFtZUhlaWdodCA9ICQodGhpcykuZmluZCgnLml0ZW0tbmFtZScpLmhlaWdodCgpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICgkKHRoaXMpLmZpbmQoJy5hbW91bnQtcHJpY2Utc3RvY2snKS5oZWlnaHQoKSA+IGFtb3VudEhlaWdodCkge1xyXG5cdFx0XHRcdGFtb3VudEhlaWdodCA9ICQodGhpcykuZmluZCgnLmFtb3VudC1wcmljZS1zdG9jaycpLmhlaWdodCgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBzbGlkZXIuZmluZCgnLml0ZW0tbmFtZScpLmhlaWdodChuYW1lSGVpZ2h0KTtcclxuICAgIHNsaWRlci5maW5kKCcuYW1vdW50LXByaWNlLXN0b2NrJykuaGVpZ2h0KGFtb3VudEhlaWdodCk7XHJcblxyXG4gIH1cclxuXHJcbiAgcmVuZGVyKCkge1xyXG4gICAgaWYoIXRoaXMucHJvcHMucmVzcG9uc2UuUmVjb21tZW5kYXRpb25zKXtcclxuICAgICAgJChcIi5wcm9kdWN0LXJlY29tbWVuZGF0aW9ucy5cIiArIHRoaXMucHJvcHMucmVzcG9uc2UuSWQpLmhpZGUoKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHJlc3VsdEl0ZW1zID0gdGhpcy5wcm9wcy5yZXNwb25zZS5SZWNvbW1lbmRhdGlvbnM7XHJcbiAgICBsZXQgcmVzdWx0ID0gW107XHJcblxyXG4gICAgaWYgKHRoaXMucHJvcHMucmVzcG9uc2UuQmxvY2tTdHlsZSA9PSAnY29uZGVuc2VkLXNsaWRlcicpIHtcclxuICAgICAgcmVzdWx0ID0gcmVzdWx0SXRlbXMubWFwKCh4KSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgIDxDb25kZW5zZWRJdGVtUmVzdWx0IGlzRGVhbGVyPXt0aGlzLnN0YXRlLmlzRGVhbGVyfSB1c2VySXNTaWduZWRJbj17dGhpcy5zdGF0ZS5pc1NpZ25lZElufSBrZXk9e3guTWF0ZXJpYWxOdW1iZXJ9IHsuLi54fSAvPlxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG4gICAgfWVsc2V7XHJcbiAgICAgIHJlc3VsdCA9IHJlc3VsdEl0ZW1zLm1hcCgoeCkgPT4ge1xyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICA8SXRlbVJlc3VsdCBpc0RlYWxlcj17dGhpcy5zdGF0ZS5pc0RlYWxlcn0gdXNlcklzU2lnbmVkSW49e3RoaXMuc3RhdGUuaXNTaWduZWRJbn0ga2V5PXt4Lk1hdGVyaWFsTnVtYmVyfSB7Li4ueH0gLz5cclxuICAgICAgICApO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gKFxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic2xpZGVyLWNvbnRyb2wgcHJldlwiPlxyXG4gICAgICAgICAgPGltZyBzcmM9XCIvU3R5bGVzL2ltYWdlcy9zbGlkZXJOYXYucG5nXCIgYWx0PVwiXCIvPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic2xpZGVyLWNvbnRyb2wgbmV4dFwiPlxyXG4gICAgICAgICAgPGltZyBzcmM9XCIvU3R5bGVzL2ltYWdlcy9zbGlkZXJOYXYucG5nXCIgYWx0PVwiXCIvPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDx1bCBjbGFzc05hbWU9XCJyZXN1bHQtc3BhcmUtcGFydHMgcmVjb21lbmRlZC1zbGlkZXJcIiBkYXRhLWVxdWFsaXplci1tcT1cIm1lZGl1bS11cFwiIGRhdGEtb3B0aW9ucz1cImVxdWFsaXplX29uX3N0YWNrOiB0cnVlXCIgZGF0YS1lcXVhbGl6ZXI9XCJpdGVtLW5hbWVcIj5cclxuICAgICAgICAgICAge3Jlc3VsdH1cclxuICAgICAgICA8L3VsPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5sZXQgdHJhbnNsYXRpb25zID0gaGlhYmNvbmZpZy5TcGFyZVBhcnRGb290ZXIubGFuZztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNsaWRlclNrZWxldG9uIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG4gICAgc3VwZXIocHJvcHMpO1xyXG4gICAgdGhpcy5zdGF0ZSA9IHtcclxuXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgY29tcG9uZW50RGlkTW91bnQoKXtcclxuXHJcbiAgfVxyXG4gIGNvbXBvbmVudFdpbGxVbk1vdW50KCl7XHJcbiAgICBSZWNvbW1lbmRhdGlvbnNTdG9yZS51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcmVuZGVyKCkge1xyXG5cclxuICAgIHZhciBkaXZTdHlsZSA9IHtcclxuICAgICAgd2lkdGg6ICcxMDAlICFpbXBvcnRhbnQnXHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiAoXHJcbiAgICAgIDxkaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJzbGlkZXItY29udHJvbCBwcmV2XCI+XHJcbiAgICAgICAgICA8aW1nIHNyYz1cIi9TdHlsZXMvaW1hZ2VzL3NsaWRlck5hdi5wbmdcIiBhbHQ9XCJcIi8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJzbGlkZXItY29udHJvbCBuZXh0XCI+XHJcbiAgICAgICAgICA8aW1nIHNyYz1cIi9TdHlsZXMvaW1hZ2VzL3NsaWRlck5hdi5wbmdcIiBhbHQ9XCJcIi8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPHVsIGNsYXNzTmFtZT1cInJlc3VsdC1zcGFyZS1wYXJ0cyByZWNvbW1lbmRhdGlvbi1zbGlkZXJcIj5cclxuICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS13cmFwcGVyIHNrZWxldG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImhlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaW1hZ2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvU3R5bGVzL2ltYWdlcy9wcm9kdWN0LXBsYWNlaG9sZGVyMngyLnBuZ1wiIGFsdD1cInByb2R1Y3QgbmFtZVwiLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tbmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZvb3RlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHQgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIiBzdHlsZT17ZGl2U3R5bGV9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzTmFtZT1cImljb24tc3BpbjQgYW5pbWF0ZS1zcGluIHRleHQtY2VudGVyXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dHJhbnNsYXRpb25zLmZldGNoaW5nSW5mb31cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWRkLXRvLWJ0bnMgdS1kdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgPGxpPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0td3JhcHBlciBza2VsZXRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJoZWFkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImltYWdlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL1N0eWxlcy9pbWFnZXMvcHJvZHVjdC1wbGFjZWhvbGRlcjJ4Mi5wbmdcIiBhbHQ9XCJwcm9kdWN0IG5hbWVcIi8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJpdGVtLW5hbWVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmb290ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFtb3VudC1wcmljZS1zdG9jayB1LWR0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInRleHQtY2VudGVyXCIgc3R5bGU9e2RpdlN0eWxlfT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3NOYW1lPVwiaWNvbi1zcGluNCBhbmltYXRlLXNwaW4gdGV4dC1jZW50ZXJcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInRleHQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0cmFuc2xhdGlvbnMuZmV0Y2hpbmdJbmZvfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJhZGQtdG8tYnRucyB1LWR0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaXRlbS13cmFwcGVyIHNrZWxldG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImhlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaW1hZ2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvU3R5bGVzL2ltYWdlcy9wcm9kdWN0LXBsYWNlaG9sZGVyMngyLnBuZ1wiIGFsdD1cInByb2R1Y3QgbmFtZVwiLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIml0ZW0tbmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZvb3RlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYW1vdW50LXByaWNlLXN0b2NrIHUtZHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIiBzdHlsZT17ZGl2U3R5bGV9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzc05hbWU9XCJpY29uLXNwaW40IGFuaW1hdGUtc3BpbiB0ZXh0LWNlbnRlclwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3RyYW5zbGF0aW9ucy5mZXRjaGluZ0luZm99XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFkZC10by1idG5zIHUtZHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgPC91bD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICk7XHJcbiAgfVxyXG59XHJcbiIsIi8vRXh0ZW5kZWQgYXV0b2NvbXBsZXRlciB0byBzdXBwb3J0IHNlYXJjaCBzdWdnZXN0aW9ucywgcGFnZXMgYW5kIGNvbHVtbnNcclxuaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuXHJcbmxldCBsYW5nID0gaGlhYmNvbmZpZy5zZWFyY2gubGFuZztcclxuXHJcblxyXG5cclxuJC53aWRnZXQoIFwiY3VzdG9tLnNtYXJ0c2VhcmNoXCIsICQudWkuYXV0b2NvbXBsZXRlLCB7XHJcblx0YmVzdEJldHNGYWNldE5hbWU6ICdiZXN0YmV0JyxcclxuXHRfY3JlYXRlOiBmdW5jdGlvbiAoKSB7XHJcblx0XHR0aGlzLl9zdXBlcigpO1xyXG5cdFx0dGhpcy53aWRnZXQoKS5tZW51KCBcIm9wdGlvblwiLCBcIml0ZW1zXCIsIFwiPiA6bm90KC5iZXN0YmV0cywubGVmdGNvbCwucmlnaHRjb2wsLmZ1bGxXaWR0aCwgLnNob3ctYWxsLXJlc3VsdHMpXCIgKTtcclxuXHR9LFxyXG5cdF9yZW5kZXJNZW51OiBmdW5jdGlvbiAoIHVsLCBpdGVtcyApIHtcclxuXHJcblx0XHRpZihpdGVtc1swXS5sb2FkaW5nKXtcclxuXHRcdFx0dGhpcy5kaXNwbGF5TG9hZGluZyh1bCwgaXRlbXMpO1xyXG5cdFx0fWVsc2V7XHJcblx0XHRcdGlmKCBpdGVtc1swXS5lcnJvciB8fCBpdGVtc1swXS5pbnZhbGlkIHx8IGl0ZW1zWzBdLm5vaGl0cyApe1xyXG5cdFx0XHRcdGlmKGl0ZW1zWzBdLmludmFsaWQpIHRoaXMuZGlzcGxheUludmFsaWRNZXNzYWdlKHVsLCBpdGVtcyk7XHJcblx0XHRcdFx0ZWxzZSBpZihpdGVtc1swXS5lcnJvcikgdGhpcy5kaXNwbGF5RXJyb3JNZXNzYWdlKHVsLCBpdGVtcyk7XHJcblx0XHRcdFx0ZWxzZSBpZihpdGVtc1swXS5ub2hpdHMpIHRoaXMuZGlzcGxheU5vSGl0c01lc3NhZ2UodWwsIGl0ZW1zKTtcclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0aWYoaXRlbXNbMF0uZmFjZXQgPT09ICdtb2RlbHR5cGVzJyB8fCBpdGVtc1swXS5mYWNldCA9PT0gJ3NlcmlhbG51bWJlcnMnIHx8IGl0ZW1zWzBdLmZhY2V0ID09PSAnZG9jdW1lbnQnKXtcclxuXHRcdFx0XHRcdGxldCBlbXB0eU1vZGFsID0gJCgnI21hY2hpbmUtbW9kYWwgdWwnKTtcclxuXHRcdFx0XHRcdGVtcHR5TW9kYWwuZW1wdHkoKTtcclxuXHRcdFx0XHRcdHRoaXMucmVuZGVyU2VyaWFsTnVtYmVycyh1bCwgaXRlbXMpO1xyXG5cdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0aWYoaXRlbXMubGVuZ3RoID09IDEpe1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXlPbmVDb2x1bW4odWwsaXRlbXMpO1xyXG5cdFx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGl2aWRlSW50b0NvbHVtbnModWwsIGl0ZW1zKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cdF9yZW5kZXJJdGVtOiBmdW5jdGlvbiAoIHVsLCBpdGVtICkge1xyXG5cdFx0bGV0IGxpSXRlbSA9ICQoJzxsaT4nKTtcclxuXHRcdGxldCBxdWVyeVBoYXJzZSA9ICQoJy51Yy1zaXRlaGVhZGVyICNzZWFyY2gtbWFpbicpLnZhbCgpLmxlbmd0aCA+IDAgPyAkKCcudWMtc2l0ZWhlYWRlciAjc2VhcmNoLW1haW4nKS52YWwoKSA6ICQoJy51Yy1zZWFyY2htb2RhbCAjc2VhcmNoLW1haW4nKS52YWwoKTtcclxuXHRcdGxldCBxdWVyeVZhciA9ICc/cXVlcnk9JytxdWVyeVBoYXJzZTtcclxuXHRcdGxldCBpdGVtVXJsID0gaXRlbS5pc0RvY3VtZW50ID8gaXRlbS51cmwgOiBpdGVtLnVybCArIHF1ZXJ5VmFyO1xyXG5cdFx0bGV0IHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5leHBsb2RlZFZpZXdzVVJMO1xyXG5cclxuXHRcdGlmKGhpYWJjb25maWcuaGFzRXF1aXBtZW50VHlwZVJlc3RyaWN0aW9uKXtcclxuXHRcdFx0dXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLnNlYXJjaERyYXdpbmdzUGFnZVVybDsgXHJcblx0XHR9XHJcblx0XHRcclxuXHRcdGlmKGl0ZW0uaXNtYWNoaW5lKXtcclxuXHRcdFx0aWYodHlwZW9mIGl0ZW0ubWF0ZXJpYWxudW1iZXIgPT09ICd1bmRlZmluZWQnKXtcclxuXHRcdFx0XHRsaUl0ZW0uYXBwZW5kKCc8YSBocmVmPVwiJyArIHVybCArICdtYWNoaW5lLScgKyBpdGVtVXJsICsgJ1wiPjxpIGNsYXNzPVwiaWNvbi1tb2RlbFwiPjwvaT48c3Ryb25nPicgKyBpdGVtLmxhYmVsICsgXHJcblx0XHRcdFx0Jzwvc3Ryb25nPjxpIGNsYXNzPVwiaWNvbi1hbmdsZS1yaWdodFwiPjwvaT48L2E+JyApXHJcblx0XHRcdFx0LmFwcGVuZFRvKHVsKTtcclxuXHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0bGlJdGVtLmFwcGVuZCgnPGEgaHJlZj1cIicgKyB1cmwgKyAnbWFjaGluZS0nICsgaXRlbVVybCArICdcIj48aSBjbGFzcz1cImljb24tbW9kZWxcIj48L2k+PHN0cm9uZz4nICsgaXRlbS5sYWJlbCArIFxyXG5cdFx0XHRcdCc8L3N0cm9uZz48c3Bhbj4nK2l0ZW0ubWF0ZXJpYWxudW1iZXIrJzwvc3Bhbj48aSBjbGFzcz1cImljb24tYW5nbGUtcmlnaHRcIj48L2k+PC9hPicgKVxyXG5cdFx0XHRcdC5hcHBlbmRUbyh1bCk7XHJcblx0XHRcdH1cclxuXHRcdH1lbHNlIGlmKGl0ZW0uaXNtb2RlbCkge1xyXG5cdFx0XHRsaUl0ZW0uYXBwZW5kKCc8YSBocmVmPVwiJyArIHVybCArICdtb2RlbC0nICsgaXRlbVVybCArICdcIj48aSBjbGFzcz1cImljb24tbW9kZWxcIj48L2k+PHN0cm9uZz4nICsgaXRlbS5sYWJlbCArIFxyXG5cdFx0XHQnPC9zdHJvbmc+PGkgY2xhc3M9XCJpY29uLWFuZ2xlLXJpZ2h0XCI+PC9pPjwvYT4nIClcclxuXHRcdFx0LmFwcGVuZFRvKHVsKTtcclxuXHRcdH1lbHNlIGlmKGl0ZW0uaXNkb2N1bWVudCkge1xyXG5cdFx0XHRsaUl0ZW0uYXBwZW5kKCc8YSBocmVmPVwiJyArIGl0ZW1VcmwgKyAnXCIgdGFyZ2V0PVwiX2JsYW5rXCI+PHN0cm9uZz48aSBjbGFzcz1cImljb24tZG9jXCI+PC9pPicgKyBpdGVtLmxhYmVsICsgXHJcblx0XHRcdCc8L3N0cm9uZz48c3Bhbj4nK2hpYWJjb25maWcuc2VhcmNoLmxhbmcub3BlblBkZisnPGkgY2xhc3M9XCJpY29uLWFuZ2xlLXJpZ2h0XCI+PC9pPjwvc3Bhbj48L2E+JylcclxuXHRcdFx0LmFwcGVuZFRvKHVsKTsgXHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0aWYodHlwZW9mIGl0ZW0ubWF0ZXJpYWxudW1iZXIgPT09ICd1bmRlZmluZWQnKXtcclxuXHRcdFx0XHRsaUl0ZW0uYXBwZW5kKCc8YSBocmVmPVwiJyArIGl0ZW1VcmwgKyAnXCI+JyArIGl0ZW0ubGFiZWwgKyAnPC9hPicgKVxyXG5cdFx0XHRcdC5hcHBlbmRUbyh1bCk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdGxpSXRlbS5hcHBlbmQoJzxhIGhyZWY9XCInICsgaXRlbVVybCArICdcIj4nICsgaXRlbS5sYWJlbCArICc8c3Bhbj4nK2l0ZW0ubWF0ZXJpYWxudW1iZXIrJzwvc3Bhbj48L2E+JyApXHJcblx0XHRcdFx0LmFwcGVuZFRvKHVsKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGxpSXRlbTtcclxuXHR9LFxyXG5cdGRpc3BsYXlMb2FkaW5nOiBmdW5jdGlvbiAodWwsIGl0ZW1zKSB7XHJcblx0XHR1bC5yZW1vdmVDbGFzcygnc2VyaWFsLW51bWJlci1yZXN1bHQnKTtcclxuXHRcdHVsLmFkZENsYXNzKCd1aS1zdGF0ZS1kaXNhYmxlZCcpO1xyXG5cdFx0bGV0IHNwaW5uZXIgPSAkKCc8bGk+JykuYWRkQ2xhc3MoJ3NwaW5uZXInKS50ZXh0KGl0ZW1zWzBdLmxhYmVsKS5hcHBlbmQoJzxpIGNsYXNzPVwiYW5pbWF0ZS1zcGluIGljb24tc3BpbjRcIj48L2k+Jyk7XHJcblx0XHRzcGlubmVyLmFwcGVuZFRvKHVsKTtcclxuXHR9LFxyXG5cdGRpc3BsYXlOb0hpdHNNZXNzYWdlOiBmdW5jdGlvbiAodWwsIGl0ZW1zKSB7XHJcblx0XHR1bC5yZW1vdmVDbGFzcygnc2VyaWFsLW51bWJlci1yZXN1bHQnKTtcclxuXHRcdHVsLmFkZENsYXNzKCd1aS1zdGF0ZS1kaXNhYmxlZCcpO1xyXG5cdFx0bGV0IG5vSGl0cyA9ICQoJzxsaT4nKS5hZGRDbGFzcygnbm8taGl0cycpLnRleHQoaXRlbXNbMF0ubGFiZWwpO1xyXG5cdFx0bm9IaXRzLmFwcGVuZFRvKHVsKTtcclxuXHR9LFxyXG5cdGRpc3BsYXlJbnZhbGlkTWVzc2FnZTogZnVuY3Rpb24gKHVsLCBpdGVtcykge1xyXG5cdFx0dWwucmVtb3ZlQ2xhc3MoJ3NlcmlhbC1udW1iZXItcmVzdWx0Jyk7XHJcblx0XHRsZXQgbm9IaXRzID0gJCgnPGxpPicpLmFkZENsYXNzKCduby1oaXRzJykudGV4dChpdGVtc1swXS5sYWJlbCk7XHJcblx0XHRub0hpdHMuYXBwZW5kVG8odWwpO1xyXG5cdH0sXHJcblx0ZGlzcGxheUVycm9yTWVzc2FnZTogZnVuY3Rpb24gKHVsLCBpdGVtcykge1xyXG5cdFx0dWwucmVtb3ZlQ2xhc3MoJ3NlcmlhbC1udW1iZXItcmVzdWx0Jyk7XHJcblx0XHRsZXQgZXJyb3IgPSAkKCc8bGk+JykuYWRkQ2xhc3MoJ25vLWhpdHMnKS5odG1sKCc8aSBjbGFzcz1cImljb24tYXR0ZW50aW9uLWNpcmNsZWRcIj48L2k+ICcraXRlbXNbMF0ubGFiZWwpO1xyXG5cdFx0ZXJyb3IuYXBwZW5kVG8odWwpO1xyXG5cdH0sXHJcblx0cmVuZGVyU2VyaWFsTnVtYmVyczogZnVuY3Rpb24gKHVsLCBpdGVtcykge1xyXG5cdFx0dmFyIHRoYXQgPSB0aGlzO1xyXG5cclxuXHRcdHVsLmFkZENsYXNzKCdzZXJpYWwtbnVtYmVyLXJlc3VsdCcpO1xyXG5cdFx0dWwuYWRkQ2xhc3MoJ2NsZWFyZml4Jyk7XHJcblxyXG5cdFx0bGV0IGZhY2V0R3JvdXBzID0gW107XHJcblxyXG5cdFx0ZmFjZXRHcm91cHMgPSBfLmdyb3VwQnkoaXRlbXMsIGZ1bmN0aW9uKGl0ZW0pIHtcclxuXHRcdFx0cmV0dXJuIGl0ZW0uZmFjZXQ7XHJcblx0XHR9KTtcclxuXHJcblx0XHQkKCc8bGk+JykuYWRkQ2xhc3MoJ2Z1bGxXaWR0aCcpLmFwcGVuZFRvKHVsKTtcclxuXHJcblx0XHQkLmVhY2goZmFjZXRHcm91cHMsIGZ1bmN0aW9uIChpbmRleCwgZmFjZXRJdGVtKSB7XHJcblxyXG5cdFx0XHRsZXQgZmFjZXRMYWJlbCA9IGZhY2V0SXRlbVswXS5mYWNldGxhYmVsLnJlcGxhY2UoL1xccy9nLCBcIlwiKTtcclxuXHRcdFx0bGV0IG1vZGVscyA9IGZhY2V0SXRlbVswXS5mYWNldCA9PT0gJ21vZGVsdHlwZXMnID8gdHJ1ZSA6IGZhbHNlO1xyXG5cdFx0XHRsZXQgaGVhZGluZ0l0ZW0gPSBcIlwiO1xyXG5cdFx0XHRsZXQgbG9hZE1vcmUgPSBtb2RlbHMgJiYgZmFjZXRJdGVtWzBdLnJlc3VsdHMubGVuZ3RoID4gNTtcclxuXHJcblx0XHRcdGlmKG1vZGVscyAmJiBmYWNldEl0ZW1bMF0ucmVzdWx0cy5sZW5ndGggPiAxKXtcclxuXHRcdFx0XHRsZXQgbWFyZ2luID0gXCJcIjtcclxuXHRcdFx0XHRpZihPYmplY3Qua2V5cyhmYWNldEdyb3VwcykubGVuZ3RoID4gMSl7XHJcblx0XHRcdFx0XHRtYXJnaW4gPSBcIm1vZGVsLXR5cGVcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aGVhZGluZ0l0ZW0gPSAkKCc8ZGl2IGNsYXNzPVwiY2xlYXJmaXggJyArIG1hcmdpbiArICdcIj4nKS5hcHBlbmQoJzxoMz4nICsgZmFjZXRJdGVtWzBdLmZhY2V0bGFiZWwgKyAnPHNwYW4gY2xhc3M9XCJpbmZvXCI+JyArIGhpYWJjb25maWcuc2VhcmNoLmxhbmcuaW5mbyArICc8L3NwYW4+JyArICc8L2gzPicpO1xyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRoZWFkaW5nSXRlbSA9IGhlYWRpbmdJdGVtID0gJCgnPGRpdiBjbGFzcz1cImNsZWFyZml4XCI+JykuYXBwZW5kKCc8aDM+JyArIGZhY2V0SXRlbVswXS5mYWNldGxhYmVsICsgJzwvaDM+Jyk7XHJcblx0XHRcdH1cclxuXHRcdFx0XHJcblx0XHRcdCQoJ2xpLmZ1bGxXaWR0aCcsdWwgKS5hcHBlbmQoaGVhZGluZ0l0ZW0pO1xyXG5cclxuXHRcdFx0bGV0IHN1Ykl0ZW1zID0gJCgnPHVsPicpO1xyXG5cdFx0XHRzdWJJdGVtcy5hdHRyKCdpZCcsIGZhY2V0TGFiZWwpO1xyXG5cdFx0XHRzdWJJdGVtcy5hZGRDbGFzcygnc2VyaWFsLXJlc3VsdC1jb2x1bW4nKTtcclxuXHRcdFx0aGVhZGluZ0l0ZW0uYXBwZW5kKHN1Ykl0ZW1zKTtcclxuXHJcblx0XHRcdCQuZWFjaChmYWNldEl0ZW1bMF0ucmVzdWx0cywgZnVuY3Rpb24gKGksIGl0ZW0pIHtcclxuXHRcdFx0XHRpZihpIDwgNSlcclxuXHRcdFx0XHR7XHJcblx0XHRcdFx0XHR0aGF0Ll9yZW5kZXJJdGVtRGF0YSggaGVhZGluZ0l0ZW0uZmluZCgndWwnKSwgaXRlbSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRpZihsb2FkTW9yZSl7IFxyXG5cdFx0XHRcdGxldCB2aWV3QWxsTW9kYWwgPSAkKCcjbWFjaGluZS1tb2RhbCB1bCcpO1xyXG5cdFx0XHRcdGxldCBoZWFkZXIgPSAkKCc8aDQ+JyArIGZhY2V0SXRlbVswXS5mYWNldGxhYmVsICsgJzwvaDM+JylcclxuXHRcdFx0XHRsZXQgdXJsID0gaGlhYmNvbmZpZy5leHBsb2RlZFZpZXdzLmV4cGxvZGVkVmlld3NVUkw7XHJcblxyXG5cdFx0XHRcdGlmKGhpYWJjb25maWcuaGFzRXF1aXBtZW50VHlwZVJlc3RyaWN0aW9uKXtcclxuXHRcdFx0XHRcdHVybCA9IGhpYWJjb25maWcuZXhwbG9kZWRWaWV3cy5zZWFyY2hEcmF3aW5nc1BhZ2VVcmw7IFxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0dmlld0FsbE1vZGFsLmFwcGVuZChoZWFkZXIpXHRcclxuXHJcblx0XHRcdFx0JC5lYWNoKGZhY2V0SXRlbVswXS5yZXN1bHRzLCBmdW5jdGlvbiAoaSwgaXRlbSkge1xyXG5cdFx0XHRcdFx0bGV0IGxpSXRlbSA9ICQoJzxsaT4nKTtcdFx0XHRcdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdGxpSXRlbS5hcHBlbmQoJzxhIGhyZWY9XCInICsgdXJsICsgJ21vZGVsLScgKyBpdGVtLnVybCArICdcIj48aSBjbGFzcz1cImljb24tbW9kZWxcIj48L2k+PHN0cm9uZz4nICsgaXRlbS5sYWJlbCArICc8L3N0cm9uZz4nK2l0ZW0ubWF0ZXJpYWxudW1iZXIrJzxpIGNsYXNzPVwiaWNvbi1hbmdsZS1yaWdodFwiPjwvaT48L2E+JyApXHJcblx0XHRcdFx0XHRcdFx0XHQuYXBwZW5kVG8odmlld0FsbE1vZGFsKTtcdFx0XHRcdFx0XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0bGV0IHN1Ym1pdCA9ICQoJzxsaSBpZD1cInNob3ctbWFjaGluZS1tb2RhbFwiIGNsYXNzPVwic2hvdy1hbGwtcmVzdWx0c1wiPjxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnV0dG9uXCI+JyArIGxhbmcuc2hvd0FsbFJlc3VsdHMgKyAnICgnICsgZmFjZXRJdGVtWzBdLmhpdHMgKyAnKSA8L2J1dHRvbj48L2xpPicpO1xyXG5cdFx0XHRcdHN1Ym1pdC5hcHBlbmRUbyh1bCk7XHRcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0JChcIiNzaG93LW1hY2hpbmUtbW9kYWxcIikub24oJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHQkKCcjbWFjaGluZS1tb2RhbCcpLmZvdW5kYXRpb24oJ3JldmVhbCcsICdvcGVuJyk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR1bC5yZW1vdmVDbGFzcygndWktc3RhdGUtZGlzYWJsZWQnKTtcclxuXHR9LFxyXG5cdGRpc3BsYXlPbmVDb2x1bW46IGZ1bmN0aW9uICh1bCwgaXRlbXMpIHtcclxuXHRcdHVsLnJlbW92ZUNsYXNzKCdzZXJpYWwtbnVtYmVyLXJlc3VsdCcpO1xyXG5cdFx0dmFyIHRoYXQgPSB0aGlzO1xyXG5cdFx0bGV0IGZhY2V0R3JvdXBzID0gW107XHJcblx0XHRmYWNldEdyb3VwcyA9IF8uZ3JvdXBCeShpdGVtcywgZnVuY3Rpb24oaXRlbSkge1xyXG5cdFx0XHRyZXR1cm4gaXRlbS5mYWNldDtcclxuXHRcdH0pO1xyXG5cdFx0Ly9DcmVhdGUgY29sdW1uc1xyXG5cdFx0JCgnPGxpPicpLmFkZENsYXNzKCdiZXN0YmV0cycpLmFwcGVuZFRvKHVsKTtcclxuXHRcdCQoJzxsaT4nKS5hZGRDbGFzcygnZnVsbFdpZHRoJykuYXBwZW5kVG8odWwpO1xyXG5cclxuXHRcdCQuZWFjaChmYWNldEdyb3VwcywgZnVuY3Rpb24gKGluZGV4LCBmYWNldEl0ZW0pIHtcclxuXHJcblx0XHRcdGxldCBoZWFkaW5nSXRlbSA9ICQoJzxkaXY+JykuYXBwZW5kKCc8aDM+JyArIGZhY2V0SXRlbVswXS5mYWNldGxhYmVsICsgJzwvaDM+Jyk7XHJcblx0XHRcdGxldCBzdWJJdGVtcyA9ICQoJzx1bD4nKTtcclxuXHJcblx0XHRcdHN1Ykl0ZW1zLmFkZENsYXNzKCdjbGVhcmZpeCcpO1xyXG5cdFx0XHRoZWFkaW5nSXRlbS5hcHBlbmQoc3ViSXRlbXMpO1xyXG5cclxuXHRcdFx0JCgnbGkuZnVsbFdpZHRoJyx1bCApLmFwcGVuZChoZWFkaW5nSXRlbSk7XHJcblxyXG5cdFx0XHQvL1JlbmRlciBpdGVtc1xyXG5cdFx0XHQkLmVhY2goZmFjZXRJdGVtWzBdLnJlc3VsdHMsIGZ1bmN0aW9uIChpLCBpdGVtKSB7XHJcblx0XHRcdFx0dGhhdC5fcmVuZGVySXRlbURhdGEoIGhlYWRpbmdJdGVtLmZpbmQoJ3VsJyksIGl0ZW0gKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRsZXQgc3VibWl0ID0gJCgnPGxpIGNsYXNzPVwic2hvdy1hbGwtcmVzdWx0c1wiPjxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnV0dG9uXCI+JyArIGxhbmcuc2hvd0FsbFJlc3VsdHMgKyAgJzwvYnV0dG9uPjwvbGk+Jyk7XHJcblx0XHRzdWJtaXQuYXBwZW5kVG8odWwpO1xyXG5cclxuXHRcdHVsLnJlbW92ZUNsYXNzKCd1aS1zdGF0ZS1kaXNhYmxlZCcpO1xyXG5cclxuXHR9LFxyXG5cdGRpdmlkZUludG9Db2x1bW5zOiBmdW5jdGlvbiAodWwsIGl0ZW1zKSB7XHJcblx0XHR1bC5yZW1vdmVDbGFzcygnc2VyaWFsLW51bWJlci1yZXN1bHQnKTtcclxuXHJcblx0XHR2YXIgdGhhdCA9IHRoaXM7XHJcblx0XHRsZXQgZmFjZXRHcm91cHMgPSBbXTtcclxuXHRcdGZhY2V0R3JvdXBzID0gXy5ncm91cEJ5KGl0ZW1zLCBmdW5jdGlvbihpdGVtKSB7XHJcblx0XHRcdHJldHVybiBpdGVtLmZhY2V0O1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IG51bU9mSXRlbXNJbkNvbCA9IE1hdGguY2VpbCgoXy5zaXplKGZhY2V0R3JvdXBzKS0xKS8yKTtcclxuXHJcblx0XHQvL0NyZWF0ZSBjb2x1bW5zXHJcblx0XHQkKCc8bGk+JykuYWRkQ2xhc3MoJ2Jlc3RiZXRzJykuYXBwZW5kVG8odWwpO1xyXG5cdFx0JCgnPGxpPicpLmFkZENsYXNzKCdsZWZ0Y29sJykuYXBwZW5kVG8odWwpO1xyXG5cdFx0JCgnPGxpPicpLmFkZENsYXNzKCdyaWdodGNvbCcpLmFwcGVuZFRvKHVsKTtcclxuXHJcblx0XHRsZXQgY291bnRlciA9IDA7XHJcblxyXG5cdFx0JC5lYWNoKGZhY2V0R3JvdXBzLCBmdW5jdGlvbiAoaW5kZXgsIGZhY2V0SXRlbSkge1xyXG5cclxuXHRcdFx0bGV0IGhlYWRpbmdJdGVtID0gJCgnPGRpdj4nKS5hcHBlbmQoJzxoMz4nICsgZmFjZXRJdGVtWzBdLmZhY2V0bGFiZWwgKyAnPC9oMz4nKTtcclxuXHRcdFx0bGV0IHN1Ykl0ZW1zID0gJCgnPHVsPicpO1xyXG5cclxuXHRcdFx0c3ViSXRlbXMuYWRkQ2xhc3MoJ2NsZWFyZml4Jyk7XHJcblx0XHRcdGhlYWRpbmdJdGVtLmFwcGVuZChzdWJJdGVtcyk7XHJcblxyXG5cdFx0XHRpZihmYWNldEl0ZW1bMF0uZmFjZXQgPT09IHRoYXQuYmVzdEJldHNGYWNldE5hbWUpIHtcclxuXHRcdFx0XHQvL0FwcGVuZCB0byBiZXN0IGJldHMgc2VhcmNoXHJcblx0XHRcdFx0JCgnbGk6Zmlyc3QnLHVsICkuYXBwZW5kKGhlYWRpbmdJdGVtKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRlbHNlIHtcclxuXHRcdFx0XHQvL1NwbGl0IGludG8gY29sdW1uc1xyXG5cdFx0XHRcdGlmKGNvdW50ZXIgPCBudW1PZkl0ZW1zSW5Db2wpICQoJ2xpLmxlZnRjb2wnLHVsICkuYXBwZW5kKGhlYWRpbmdJdGVtKTtcclxuXHRcdFx0XHRlbHNlICQoJ2xpLnJpZ2h0Y29sJyx1bCApLmFwcGVuZChoZWFkaW5nSXRlbSk7XHJcblx0XHRcdFx0Y291bnRlcisrO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvL1JlbmRlciBpdGVtc1xyXG5cdFx0XHQkLmVhY2goZmFjZXRJdGVtWzBdLnJlc3VsdHMsIGZ1bmN0aW9uIChpLCBpdGVtKSB7XHJcblx0XHRcdFx0dGhhdC5fcmVuZGVySXRlbURhdGEoIGhlYWRpbmdJdGVtLmZpbmQoJ3VsJyksIGl0ZW0gKTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IHN1Ym1pdCA9ICQoJzxsaSBjbGFzcz1cInNob3ctYWxsLXJlc3VsdHNcIj48YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImJ1dHRvblwiPicgKyBsYW5nLnNob3dBbGxSZXN1bHRzICsgJzwvYnV0dG9uPjwvbGk+Jyk7XHJcblx0XHRzdWJtaXQuYXBwZW5kVG8odWwpO1xyXG5cclxuXHRcdHVsLnJlbW92ZUNsYXNzKCd1aS1zdGF0ZS1kaXNhYmxlZCcpO1xyXG5cclxuXHR9XHJcblxyXG59KTtcclxuIiwiaW1wb3J0ICQgZnJvbSAnanF1ZXJ5JztcclxuaW1wb3J0IGpxdWVyeXVpIGZyb20gJ2pxdWVyeS51aSc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBhdXRvY29tcGxldGVyIGZyb20gJy4vYXV0b2NvbXBsZXRlcic7XHJcbmltcG9ydCBDdXN0b21TZWFyY2hFdmVudHMgZnJvbSAnLi4vX2xpYi9jdXN0b20tc2VhcmNoLWV2ZW50cyc7XHJcblxyXG5sZXQgc2VhcmNoVmFsID0gJyc7XHJcbmxldCBzZWFyY2hpbmdGb3JTZXJpYWwgPSBmYWxzZTtcclxubGV0IGlzT25TZWFyY2hQYWdlID0gZmFsc2U7XHJcbmxldCBpbnB1dEZpZWxkID0gW107XHJcblxyXG5sZXQgc21hcnRzZWFyY2ggPSB7XHJcblx0aW5pdChzZWFyY2hTZXJpYWwsIHNlYXJjaFBhZ2UpIHtcclxuXHRcdHNlYXJjaGluZ0ZvclNlcmlhbCA9IHNlYXJjaFNlcmlhbDtcclxuXHRcdGlzT25TZWFyY2hQYWdlID0gc2VhcmNoUGFnZTtcclxuXHRcdGxldCBzZWFyY2hQYXRoID0gc2VhcmNoaW5nRm9yU2VyaWFsID8gaGlhYmNvbmZpZy5zZWFyY2guc2VyaWFsU2VhcmNoQXBpIDogaGlhYmNvbmZpZy5zZWFyY2guc21hcnRTZWFyY2hBcGk7XHJcblx0XHJcblx0XHQvLyBIYW5kbGUga2V5IGZvY3VzIGNsaWNrXHJcblx0XHQkKCcuc2VhcmNoLW1haW4nKVxyXG5cdFx0XHQuYmluZCgnZm9jdXMgY2xpY2snLCB0aGlzLmhhbmRsZUZvY3VzKTtcclxuXHRcdFxyXG5cdFx0Ly8gRW5zdXJlcyB0aGF0IHdlIG9ubHkgaGF2ZSBvbmUgZXZlbnQgaGFuZGxlciBmaXJpbmcgd2hlbmV2ZSB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkLlxyXG5cdFx0Ly8gVGhlcmUgc2VlbXMgdG8gYmUgc29tZXRoaW5nIGluIHRoZSBjb2RlIGJhc2UgdGhhdCBydW5zIHRoaXMgaW5pdC1tZXRob2Qgc2V2ZXJhbCB0aW1lcywgbWVhbmluZyB0aGF0IHdlIGVuZCB1cCB3aXRoIHRvbyBtYW55IGhhbmRsZXJzLlxyXG5cdFx0JCgnLnNlYXJjaC1tYWluJylcclxuXHRcdFx0Lm9mZigna2V5ZG93bicpLm9uKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlEb3duKTtcclxuXHJcblx0XHQkKCdib2R5Jykub24oJ2NsaWNrJywgJy5qcy1pbml0LXNlYXJjaCcsIGZ1bmN0aW9uKGUpIHtcclxuXHRcdFx0c21hcnRzZWFyY2gudHJpZ2dlclNlcmlhbFNlYXJjaChlKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vQ3JlYXRlIGF1dG9jb21wbGV0ZXJcclxuXHRcdCQoJy51Yy1zZWFyY2htb2RhbCAjc2VhcmNoLW1haW4sIC51Yy1zaXRlaGVhZGVyICNzZWFyY2gtbWFpbicpLmVhY2goZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdFx0bGV0IHNjb3BlID0gJCh0aGlzKS5wYXJlbnRzKCcudWMtc2VhcmNoZmllbGQnKTtcclxuXHJcblx0XHRcdGlucHV0RmllbGRbaW5kZXhdID0gJCh0aGlzKS5zbWFydHNlYXJjaCh7XHJcblx0XHRcdFx0YXBwZW5kVG86ICQoJ2Zvcm0nLCBzY29wZSksXHJcblx0XHRcdFx0ZGVsYXk6IDMwMCxcclxuXHRcdFx0XHRtaW5MZW5ndGg6IDEsXHJcblx0XHRcdFx0b3BlbjogZnVuY3Rpb24oZXZlbnQsIHVpKSB7XHJcblx0XHRcdFx0XHQkKCcudWMtc2VhcmNoZmllbGQnKS5yZW1vdmVDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cclxuXHRcdFx0XHRcdGxldCBhdXRvY29tcGxldGUgPSAkKCcudWktYXV0b2NvbXBsZXRlJywgc2NvcGUpO1xyXG5cdFx0XHRcdFx0c2VhcmNoVmFsID0gaW5wdXRGaWVsZFtpbmRleF0udmFsKCk7XHJcblx0XHRcdFx0XHQvL1JlbW92ZSB0YWJpbmRleFxyXG5cdFx0XHRcdFx0YXV0b2NvbXBsZXRlLnJlbW92ZUF0dHIoJ3RhYmluZGV4Jyk7XHJcblx0XHRcdFx0XHQkKCdsaScsIGF1dG9jb21wbGV0ZSkucmVtb3ZlQXR0cigndGFiaW5kZXgnKTtcclxuXHRcdFx0XHRcdCQoJ2J1dHRvbicsIGF1dG9jb21wbGV0ZSkucmVtb3ZlQXR0cigndGFiaW5kZXgnKTtcclxuXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHRjbG9zZTogZnVuY3Rpb24oZXZlbnQsIHVpKSB7XHJcblx0XHRcdFx0XHRpZiggJCgnLnVjLXNlYXJjaG1vZGFsLmlzLW9wZW4nKS5sZW5ndGggPiAwIHx8wqAkKCdib2R5LnNlYXJjaG1vZGFsLW9wZW4nKS5sZW5ndGggPiAwICkge1xyXG5cdFx0XHRcdFx0XHRpZiggJCgnLnVjLXNlYXJjaG1vZGFsIHVsLnVpLWF1dG9jb21wbGV0ZScpLmNoaWxkcmVuKCkuaGFzQ2xhc3MoJ3NwaW5uZXInKSApe1xyXG5cdFx0XHRcdFx0XHRcdCQoJy51Yy1zZWFyY2hmaWVsZCcpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblx0XHRcdFx0XHRcdFx0JCgnLnVpLWF1dG9jb21wbGV0ZScpLmVtcHR5KCk7XHJcblx0XHRcdFx0XHRcdFx0JCgnLnVpLWF1dG9jb21wbGV0ZScpLmhpZGUoKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRcdFx0JCgnLnVjLXNlYXJjaG1vZGFsIHVsLnVpLWF1dG9jb21wbGV0ZScpLnNob3coKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHQkKCcudWMtc2VhcmNoZmllbGQnKS5yZW1vdmVDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cdFx0XHRcdFx0XHQkKCcudWktYXV0b2NvbXBsZXRlJykuZW1wdHkoKTtcclxuXHRcdFx0XHRcdFx0JCgnLnVpLWF1dG9jb21wbGV0ZScpLmhpZGUoKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdHJlc3BvbnNlOiBmdW5jdGlvbihldmVudCwgdWkpIHtcclxuXHRcdFx0XHRcdCQoJy51Yy1zZWFyY2hmaWVsZCcpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblx0XHRcdFx0XHQkKCcudWktYXV0b2NvbXBsZXRlJykuc2hvdygpO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdHNlYXJjaDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHQkKCcudWktYXV0b2NvbXBsZXRlICcpLnNob3coKTtcclxuXHRcdFx0XHRcdCQodGhpcykucGFyZW50cygnLnVjLXNlYXJjaGZpZWxkJykuYWRkQ2xhc3MoJ2lzLWxvYWRpbmcnKTtcclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHRzb3VyY2U6IGZ1bmN0aW9uKHJlcSwgcmVzKSB7XHJcblx0XHRcdFx0XHQvLyBOZXcgcmVxdWVzdCAzMDBtcyBhZnRlciBrZXkgc3Ryb2tlXHJcblx0XHRcdFx0XHR2YXIgJHRoaXMgPSAkKHRoaXMpO1xyXG5cdFx0XHRcdFx0dmFyICRlbGVtZW50ID0gJCh0aGlzLmVsZW1lbnQpO1xyXG5cdFx0XHRcdFx0dmFyIHByZXZpb3VzX3JlcXVlc3QgPSAkZWxlbWVudC5kYXRhKFwianFYSFJcIik7XHJcblx0XHRcdFx0XHRpZiAocHJldmlvdXNfcmVxdWVzdCkge1xyXG5cdFx0XHRcdFx0XHQvLyBhIHByZXZpb3VzIHJlcXVlc3QgaGFzIGJlZW4gbWFkZS5cclxuXHRcdFx0XHRcdFx0Ly8gdGhvdWdoIHdlIGRvbid0IGtub3cgaWYgaXQncyBjb25jbHVkZWRcclxuXHRcdFx0XHRcdFx0Ly8gd2UgY2FuIHRyeSBhbmQga2lsbCBpdCBpbiBjYXNlIGl0IGhhc24ndFxyXG5cdFx0XHRcdFx0XHRwcmV2aW91c19yZXF1ZXN0LmFib3J0KCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQkZWxlbWVudC5kYXRhKFwianFYSFJcIiwgJC5hamF4KHtcclxuXHRcdFx0XHRcdFx0dHlwZTogJ0dFVCcsXHJcblx0XHRcdFx0XHRcdHVybDogc2VhcmNoUGF0aCArIGVuY29kZVVSSUNvbXBvbmVudChyZXEudGVybSksXHJcblx0XHRcdFx0XHRcdGRhdGFUeXBlOiAnanNvbicsXHJcblx0XHRcdFx0XHRcdGJlZm9yZVNlbmQ6IGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0XHRcdFx0XHRcdGlmIChzZWFyY2hpbmdGb3JTZXJpYWwpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChyZXEudGVybS5sZW5ndGggPCA0KSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHJlcyhbe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCdsYWJlbCc6IGhpYWJjb25maWcuc2VhcmNoLmxhbmcuaW52YWxpZExlbmd0aCxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsJzogLTEsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0J2ludmFsaWQnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCdlcnJvcic6IGZhbHNlXHJcblx0XHRcdFx0XHRcdFx0XHRcdH1dKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdFx0XHRcdFx0fWVsc2UgaWYgKC9eW2Etel0rJC9pLnRlc3QocmVxLnRlcm0pKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHJlcyhbe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCdsYWJlbCc6IGhpYWJjb25maWcuc2VhcmNoLmxhbmcuaW52YWxpZENoYXJhY3RlcnMsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0J3ZhbCc6IC0xLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCdpbnZhbGlkJzogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnZXJyb3InOiBmYWxzZVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XSk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXMoW3tcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnbGFiZWwnOiBoaWFiY29uZmlnLnNlYXJjaC5sYW5nLnNlYXJjaGluZ1NlcmlhbCxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsJzogLTEsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0J2ludmFsaWQnOiBmYWxzZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnZXJyb3InOiBmYWxzZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnbG9hZGluZyc6IHRydWVcclxuXHRcdFx0XHRcdFx0XHRcdFx0fV0pO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdFx0XHRcdHJlcyhbe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQnbGFiZWwnOiBoaWFiY29uZmlnLnNlYXJjaC5sYW5nLnNlYXJjaGluZyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J3ZhbCc6IC0xLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnaW52YWxpZCc6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnZXJyb3InOiBmYWxzZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J2xvYWRpbmcnOiB0cnVlXHJcblx0XHRcdFx0XHRcdFx0XHR9XSk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0XHRzdWNjZXNzOiBmdW5jdGlvbihzZWFyY2gpIHtcclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VhcmNoLmZpbmRTZXJ2aWNlRXJyb3JNZXNzYWdlID09PSAnJykge1xyXG5cdFx0XHRcdFx0XHRcdFx0dmFyIGMgPSBbXTtcclxuXHRcdFx0XHRcdFx0XHRcdCQuZWFjaChzZWFyY2gucmVzdWx0cywgZnVuY3Rpb24oaW5kZXgsIGl0ZW0pIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Yy5wdXNoKGl0ZW0pXHJcblx0XHRcdFx0XHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoc2VhcmNoLmhpdHMgPT09IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0bGV0IG5vSGl0c1Rlcm0gPSBzZWFyY2hpbmdGb3JTZXJpYWwgPyBoaWFiY29uZmlnLnNlYXJjaC5sYW5nLm5vUmVzdWx0c1NlcmlhbCA6IGhpYWJjb25maWcuc2VhcmNoLmxhbmcubm9SZXN1bHRzO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXMoW3tcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnbGFiZWwnOiBub0hpdHNUZXJtLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCd2YWwnOiAtMSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQnbm9oaXRzJzogdHJ1ZVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XSk7XHJcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXMoYyk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJlcyhbe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQnbGFiZWwnOiBzZWFyY2guZmluZFNlcnZpY2VFcnJvck1lc3NhZ2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdCd2YWwnOiAtMSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J25vaGl0cyc6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnZXJyb3InOiB0cnVlXHJcblx0XHRcdFx0XHRcdFx0XHR9XSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0XHRDdXN0b21TZWFyY2hFdmVudHMudHJhY2tRdWlja1NlYXJjaChyZXEudGVybSwgc2VhcmNoLmhpdHMsIHNlYXJjaC5yZXN1bHRzKTtcclxuXHRcdFx0XHRcdFx0fSxcclxuXHRcdFx0XHRcdFx0ZXJyb3I6IGZ1bmN0aW9uKGRhdGEpIHtcclxuXHRcdFx0XHRcdFx0XHRyZXMoW3tcclxuXHRcdFx0XHRcdFx0XHRcdCdsYWJlbCc6IGhpYWJjb25maWcuc2VhcmNoLmxhbmcuZXJyb3JNc2csXHJcblx0XHRcdFx0XHRcdFx0XHQndmFsJzogLTEsXHJcblx0XHRcdFx0XHRcdFx0XHQnbm9oaXRzJzogZmFsc2UsXHJcblx0XHRcdFx0XHRcdFx0XHQnZXJyb3InOiB0cnVlXHJcblx0XHRcdFx0XHRcdFx0fV0pO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9KSk7XHJcblxyXG5cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGhhbmRsZUtleURvd24oZXZlbnQpIHtcclxuXHRcclxuXHRcdGlmKHNlYXJjaGluZ0ZvclNlcmlhbCl7XHJcbiAgICAgICAgICAgICQodGhpcykuc21hcnRzZWFyY2goe2Rpc2FibGVkOiB0cnVlfSk7XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdC8vR2V0IGEgZmxhdCBsaXN0XHJcblx0XHRsZXQgbGlzdCA9ICQoJy51aS1hdXRvY29tcGxldGUgbGkgdWwgbGknKTtcclxuXHRcdHZhciAkZWxlbWVudCA9ICQodGhpcyk7XHJcblx0XHRpZiAoZXZlbnQua2V5Q29kZSA9PSAkLnVpLmtleUNvZGUuRU5URVIpIHtcclxuXHRcdFx0JCh0aGlzKS5zbWFydHNlYXJjaCh7ZGlzYWJsZWQ6IGZhbHNlfSk7XHJcblxyXG5cdFx0XHRsZXQgc2VsZWN0ZWRJdGVtID0gJCgnLnVpLWF1dG9jb21wbGV0ZSAudWktc3RhdGUtZm9jdXMgYScpO1xyXG5cdFx0XHRpZiAoc2VsZWN0ZWRJdGVtLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHQvL1NlYXJjaCBvciBuYXZpZ2F0ZT9cclxuXHRcdFx0XHRpZiAoc2VsZWN0ZWRJdGVtLnBhcmVudHMoJy5iZXN0YmV0cycpLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHRcdGlmIChzZWxlY3RlZEl0ZW0uYXR0cigndGFyZ2V0JykgPT09ICdfYmxhbmsnKSB7XHJcblx0XHRcdFx0XHRcdHdpbmRvdy5vcGVuKHNlbGVjdGVkSXRlbS5hdHRyKCdocmVmJykpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gc2VsZWN0ZWRJdGVtLmF0dHIoJ2hyZWYnKTtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0aWYgKCFzZWFyY2hpbmdGb3JTZXJpYWwpIHtcclxuXHRcdFx0XHRcdCRlbGVtZW50LmRhdGEoXCJqcVhIUlwiKS5hYm9ydCgpO1xyXG5cdFx0XHRcdFx0JCgnI3NlYXJjaC1maWVsZCAudWMtc2VhcmNoZmllbGQgYnV0dG9uJykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcclxuXHRcdFx0XHRcdCQoJy51Yy1zZWFyY2hmaWVsZCcpLnJlbW92ZUNsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblx0XHRcdFx0XHQkKFwiLnVpLWF1dG9jb21wbGV0ZVwiKS5lYWNoKGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHRcdFx0XHRcdCQodGhpcykuZW1wdHkoKTtcclxuXHRcdFx0XHRcdFx0JCh0aGlzKS5oaWRlKCk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0c21hcnRzZWFyY2gudHJpZ2dlclNlcmlhbFNlYXJjaChldmVudCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGV2ZW50LmtleUNvZGUgPT0gJC51aS5rZXlDb2RlLlVQIHx8IGV2ZW50LmtleUNvZGUgPT0gJC51aS5rZXlDb2RlLkRPV04pIHtcclxuXHJcblx0XHRcdGlmIChldmVudC5rZXlDb2RlID09ICQudWkua2V5Q29kZS5ET1dOKSB7XHJcblx0XHRcdFx0bGV0IHNlbGVjdG5leHQgPSAkLm1hcChsaXN0LCBmdW5jdGlvbihpdGVtLCBpbmRleCkge1xyXG5cdFx0XHRcdFx0aWYgKCQoaXRlbSkuaXMoJy51aS1zdGF0ZS1mb2N1cycpKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiBsaXN0W2luZGV4ICsgMV07XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0aWYgKHNlbGVjdG5leHQubGVuZ3RoID09PSAwKSBzZWxlY3RuZXh0ID0gbGlzdFswXTtcclxuXHRcdFx0XHQkKGxpc3QpLnJlbW92ZUNsYXNzKCd1aS1zdGF0ZS1mb2N1cycpO1xyXG5cdFx0XHRcdCQoc2VsZWN0bmV4dCkuYWRkQ2xhc3MoJ3VpLXN0YXRlLWZvY3VzJyk7XHJcblxyXG5cdFx0XHRcdGlmICgkKHNlbGVjdG5leHQpLnBhcmVudHMoJ2xpJykuaXMoJy5iZXN0YmV0cycpKSB7XHJcblx0XHRcdFx0XHQkKCcjc2VhcmNoLW1haW4nKS52YWwoJChzZWxlY3RuZXh0KS50ZXh0KCkpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHQkKCcjc2VhcmNoLW1haW4nKS52YWwoc2VhcmNoVmFsKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoZXZlbnQua2V5Q29kZSA9PSAkLnVpLmtleUNvZGUuVVApIHtcclxuXHRcdFx0XHRsZXQgc2VsZWN0bmV4dCA9ICQubWFwKGxpc3QsIGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XHJcblx0XHRcdFx0XHRpZiAoJChpdGVtKS5pcygnLnVpLXN0YXRlLWZvY3VzJykpIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIGxpc3RbaW5kZXggLSAxXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRpZiAoc2VsZWN0bmV4dC5sZW5ndGggPT09IDApIHNlbGVjdG5leHQgPSBsaXN0W2xpc3QubGVuZ3RoIC0gMV07XHJcblxyXG5cdFx0XHRcdCQobGlzdCkucmVtb3ZlQ2xhc3MoJ3VpLXN0YXRlLWZvY3VzJyk7XHJcblx0XHRcdFx0JChzZWxlY3RuZXh0KS5hZGRDbGFzcygndWktc3RhdGUtZm9jdXMnKTtcclxuXHJcblx0XHRcdFx0aWYgKCQoc2VsZWN0bmV4dCkucGFyZW50cygnbGknKS5pcygnLmJlc3RiZXRzJykpIHtcclxuXHRcdFx0XHRcdCQoJyNzZWFyY2gtbWFpbicpLnZhbCgkKHNlbGVjdG5leHQpLnRleHQoKSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdCQoJyNzZWFyY2gtbWFpbicpLnZhbChzZWFyY2hWYWwpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblx0c2V0Q29udGV4dChzZWFyY2hpbmdGb3JTZXJpYWwsIHNlYXJjaFBhZ2UpIHtcclxuXHRcdHNlYXJjaGluZ0ZvclNlcmlhbCA9IHNlYXJjaGluZ0ZvclNlcmlhbDtcclxuXHRcdGlzT25TZWFyY2hQYWdlID0gc2VhcmNoUGFnZTtcclxuXHRcdFxyXG5cdH0sXHJcblx0aGFuZGxlRm9jdXMoKSB7XHJcblx0XHRpZiAoaXNPblNlYXJjaFBhZ2UpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aWYgKCBzZWFyY2hpbmdGb3JTZXJpYWwgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGlmICgkKCcjc2VhcmNoLWZpZWxkIC51Yy1zZWFyY2hmaWVsZCAudWktYXV0b2NvbXBsZXRlLWlucHV0JykubGVuZ3RoID4gMCAmJiAkKCdib2R5LnNlYXJjaG1vZGFsLW9wZW4nKS5sZW5ndGggPT0gMCkge1xyXG5cdFx0XHRcdFx0JChpbnB1dEZpZWxkKS5lYWNoKGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHRcdFx0XHRcdGlmIChpbnB1dEZpZWxkW2luZGV4XS52YWwoKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0XHRcdFx0aW5wdXRGaWVsZFtpbmRleF0uc21hcnRzZWFyY2goJ3NlYXJjaCcsIGlucHV0RmllbGRbaW5kZXhdLnZhbCgpKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdCQoJy51aS1hdXRvY29tcGxldGUgbGkgdWwgbGksIC51aS1hdXRvY29tcGxldGUgLnNob3ctYWxsLXJlc3VsdHMnKS5yZW1vdmVDbGFzcygndWktc3RhdGUtZm9jdXMnKTtcclxuXHR9LFxyXG5cclxuXHR0cmlnZ2VyU2VyaWFsU2VhcmNoKGV2ZW50KSB7XHJcblx0XHRpZiAodHlwZW9mIGV2ZW50ICE9PSBcInVuZGVmaW5lZFwiICYmIHNlYXJjaGluZ0ZvclNlcmlhbCkge1xyXG5cdFx0XHRcclxuXHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcblxyXG5cdFx0XHQkKGlucHV0RmllbGQpLmVhY2goZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdFx0XHRpZiAoaW5wdXRGaWVsZFtpbmRleF0udmFsKCkubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRcdFx0aW5wdXRGaWVsZFtpbmRleF0uc21hcnRzZWFyY2goe2Rpc2FibGVkOiBmYWxzZX0pO1xyXG5cdFx0XHRcdFx0aW5wdXRGaWVsZFtpbmRleF0uc21hcnRzZWFyY2goJ3NlYXJjaCcsIGlucHV0RmllbGRbaW5kZXhdLnZhbCgpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0JCgnI3NlYXJjaC1tYWluJykuZm9jdXMoKTtcdFxyXG5cdH0sIFxyXG5cclxuXHRkZXN0cm95QXV0b0NvbXBsZXRlKCkge1xyXG5cdFx0JChpbnB1dEZpZWxkKS5lYWNoKGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHRcdGlucHV0RmllbGRbaW5kZXhdLnNtYXJ0c2VhcmNoKCdkZXN0cm95Jyk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cdFxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBzbWFydHNlYXJjaDtcclxuIiwiLy8gUmVhY3QgaGFzIHRvIGJlIHByb3ZpZGVkIHRocm91Z2ggdGhlIGdsb2JhbCh3aW5kb3cgaW4gYnJvd3Nlcikgb2JqZWN0IHRvIGFsbG93IGR5bmFtaWNhbGx5XHJcbi8vIGhvb2tpbmcgaW50byBjb21wb25lbnRzIHJlbmRlcmVkIG9uIHRoZSBzZXJ2ZXIuXHJcbmdsb2JhbC5SZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XHJcbmdsb2JhbC5SZWFjdERPTSA9IHJlcXVpcmUoJ3JlYWN0LWRvbScpO1xyXG5nbG9iYWwuUmVhY3RET01TZXJ2ZXIgPSByZXF1aXJlKCdyZWFjdC1kb20vc2VydmVyJyk7XHJcblxyXG4vLyBnbG9iYWwuUHJvZHVjdFN0b3JlID0gcmVxdWlyZSgnLi9fc3RvcmVzL3Byb2R1Y3Rfc3RvcmUnKTtcclxuZ2xvYmFsLlNvcnRTdG9yZSA9IHJlcXVpcmUoJy4vX3N0b3Jlcy9zb3J0X3N0b3JlJyk7XHJcbmdsb2JhbC5CcmFuZEZpbHRlclN0b3JlID0gcmVxdWlyZSgnLi9fc3RvcmVzL2JyYW5kX2ZpbHRlcl9zdG9yZScpO1xyXG5nbG9iYWwuVXNhZ2VUeXBlRmlsdGVyU3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvdXNhZ2VfdHlwZV9maWx0ZXJfc3RvcmUnKTtcclxuZ2xvYmFsLlByb2R1Y3RMaW5lRmlsdGVyU3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvcHJvZHVjdF9saW5lX2ZpbHRlcl9zdG9yZScpO1xyXG5nbG9iYWwuU2VyaWFsTnVtYmVyRmlsdGVyU3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvc2VyaWFsX251bWJlcl9maWx0ZXJfc3RvcmUnKTtcclxuZ2xvYmFsLlRvcENhdGVnb3J5RmlsdGVyU3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvdG9wX2NhdGVnb3J5X2ZpbHRlcl9zdG9yZScpO1xyXG5nbG9iYWwuQ2F0ZWdvcnlGaWx0ZXJTdG9yZSA9IHJlcXVpcmUoJy4vX3N0b3Jlcy9jYXRlZ29yeV9maWx0ZXJfc3RvcmUnKTtcclxuZ2xvYmFsLkxvY2FsaXphdGlvblN0b3JlID0gcmVxdWlyZSgnLi9fc3RvcmVzL2xvY2FsaXphdGlvbl9zdG9yZScpO1xyXG5nbG9iYWwuU2VhcmNoUmVzdWx0U3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvc2VhcmNoX3Jlc3VsdF9zdG9yZScpO1xyXG5nbG9iYWwuU2VhcmNoU3RvcmUgPSByZXF1aXJlKCcuL19zdG9yZXMvc2VhcmNoX3N0b3JlJyk7XHJcblxyXG5nbG9iYWwuU2VhcmNoSGVhZGVyID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL3NlYXJjaC9zZWFyY2hfaGVhZGVyJyk7XHJcbmdsb2JhbC5Hcm91cFNlbGVjdG9yID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL3NlYXJjaC9ncm91cF9zZWxlY3RvcicpO1xyXG5nbG9iYWwuUmVzdWx0TGlzdCA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9zZWFyY2gvcmVzdWx0X2xpc3QnKTtcclxuZ2xvYmFsLkZpbHRlcnMgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlcnMnKTtcclxuIiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xyXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xyXG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcclxuaW1wb3J0IEFkZHJlc3NBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3VzZXJfYWRkcmVzc2VzX2FjdGlvbnMnO1xyXG5pbXBvcnQgQWRkcmVzc0ZpZWxkIGZyb20gJy4vYWRkcmVzc19maWVsZCc7XHJcbmltcG9ydCBDb3VudHJ5UmVnaW9uQ29udGFpbmVyIGZyb20gJy4vY291bnRyeV9yZWdpb25fY29udGFpbmVyJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBVc2VyQ291bnRyeU9wdGlvbnNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3VzZXJfY291bnRyeV9vcHRpb25zX3N0b3JlJztcclxuaW1wb3J0IEFkZHJlc3NGaWVsZFN0b3JlIGZyb20gJy4uL19zdG9yZXMvYWRkcmVzc19maWVsZF9zdG9yZSc7XHJcbmltcG9ydCBVc2VyQWRkcmVzc2VzU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy91c2VyX2FkZHJlc3Nlc19zdG9yZSc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcblxyXG5cclxubGV0IGFsdGVybmF0aXZlTGF5b3V0ID0gaGlhYmNvbmZpZy5tYXJrZXRJZCA9PSBcIkpQMDJcIiA/IHRydWUgOiBmYWxzZTtcclxuXHJcbmNsYXNzIFVzZXJBZGRyZXNzZXNBZGRJdGVtIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aXRlbToge30sXHJcblx0XHRcdGNvdW50cnlPcHRpb25zOiBbXSxcclxuXHRcdFx0Y2FuU3VibWl0OiBmYWxzZSxcclxuXHRcdFx0cmVnaW9uVmFsdWU6ICdubycsXHJcblx0XHRcdGNoYW5nZWQ6IGZhbHNlLFxyXG5cdFx0XHRpc0VkaXRpbmc6IGZhbHNlLFxyXG5cdFx0XHRzYXZlZDogZmFsc2UsXHJcblx0XHRcdG1ha2VEZWZhdWx0OiBmYWxzZSxcclxuXHRcdFx0ZXhlY3V0ZTogZmFsc2UsXHJcblx0XHRcdGlzTG9hZGluZzogZmFsc2VcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5zdGF0ZS5pdGVtID0ge1xyXG5cdFx0XHRcdElzRGVmYXVsdDogZmFsc2UsXHJcblx0XHQgICAgQWRkcmVzc0lkOiAnJyxcclxuXHRcdCAgICBNb2RpZmllZDogbmV3IERhdGUoKSxcclxuXHRcdFx0XHRDb21wYW55TmFtZTogJycsXHJcblx0XHQgICAgRmlyc3ROYW1lOiAnJyxcclxuXHRcdCAgICBMYXN0TmFtZTogJycsXHJcblx0XHQgICAgQ291bnRyeU5hbWU6ICcnLFxyXG5cdFx0ICAgIENvdW50cnlDb2RlOiAnZGVmYXVsdCcsXHJcblx0XHQgICAgQ2l0eTogJycsXHJcblx0XHQgICAgUG9zdGFsQ29kZTogJycsXHJcblx0XHQgICAgTGluZTE6ICcnLFxyXG5cdFx0ICAgIExpbmUyOiAnJyxcclxuXHRcdCAgICBSZWdpb246ICcnLFxyXG5cdFx0ICAgIEVtYWlsOiAnJyxcclxuXHRcdCAgICBEYXl0aW1lUGhvbmVOdW1iZXI6ICcnLFxyXG5cdFx0XHRcdHJlZ2lvblZhbHVlOiAnZGVmYXVsdCdcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5lbGVtZW50cyA9IHt9O1xyXG5cclxuXHR9XHJcblx0cmVzZXRGb3JtKCl7XHJcblx0XHRsZXQgaXRlbSA9IHtcclxuXHRcdFx0XHRJc0RlZmF1bHQ6IGZhbHNlLFxyXG5cdFx0XHRcdEFkZHJlc3NJZDogJycsXHJcblx0XHRcdFx0TW9kaWZpZWQ6IG5ldyBEYXRlKCksXHJcblx0XHRcdFx0Q29tcGFueU5hbWU6ICcnLFxyXG5cdFx0XHRcdEZpcnN0TmFtZTogJycsXHJcblx0XHRcdFx0TGFzdE5hbWU6ICcnLFxyXG5cdFx0XHRcdENvdW50cnlOYW1lOiAnJyxcclxuXHRcdFx0XHRDb3VudHJ5Q29kZTogJ2RlZmF1bHQnLFxyXG5cdFx0XHRcdENpdHk6ICcnLFxyXG5cdFx0XHRcdFBvc3RhbENvZGU6ICcnLFxyXG5cdFx0XHRcdExpbmUxOiAnJyxcclxuXHRcdFx0XHRMaW5lMjogJycsXHJcblx0XHRcdFx0UmVnaW9uOiAnJyxcclxuXHRcdFx0XHRFbWFpbDogJycsXHJcblx0XHRcdFx0RGF5dGltZVBob25lTnVtYmVyOiAnJyxcclxuXHRcdFx0XHRyZWdpb25WYWx1ZTogJ2RlZmF1bHQnXHJcblx0XHR9O1xyXG5cdFx0dGhpcy5zZXREaXJ0eShmYWxzZSk7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXRlbTogaXRlbSxcclxuXHRcdFx0Y291bnRyeU9wdGlvbnM6IFVzZXJDb3VudHJ5T3B0aW9uc1N0b3JlLmdldENvdW50cnlPcHRpb25zKClcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlVG9nZ2xlID0gKGZvcm1JZCkgPT4ge1xyXG5cdFx0JCgnIycrZm9ybUlkKS50b2dnbGVDbGFzcyggJ2FkZGluZycpO1xyXG5cdFx0dGhpcy5yZXNldEZvcm0oKTtcclxuICB9XHJcblxyXG5cdHNldERpcnR5KGlzRGlydHkpIHtcclxuXHRcdE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmZvckVhY2goKGtleSkgPT4ge1xyXG5cdFx0XHR0aGlzLmVsZW1lbnRzW2tleV0uc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzRGlydHk6aXNEaXJ0eVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y3JlYXRlKGUpe1xyXG5cdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHRcdGlmKGUudGFyZ2V0LnRhZ05hbWUgIT09ICdCVVRUT04nKXtcclxuXHRcdFx0ZS50YXJnZXQgPSBlLnRhcmdldC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKCFlLnRhcmdldC5kaXNhYmxlZCApe1xyXG5cdFx0XHRBZGRyZXNzQWN0aW9ucy5jaGVja1Bvc3RhbENvZGUodGhpcy5zdGF0ZS5pdGVtLkNvdW50cnlDb2RlLCB0aGlzLnN0YXRlLml0ZW0uUG9zdGFsQ29kZSk7XHJcblx0XHRcdGlmKCB0aGlzLnZhbGlkYXRlRm9ybSgpICl7XHJcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRpc0xvYWRpbmc6IHRydWVcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHR0aGlzLnN0YXRlLmV4ZWN1dGUgPSB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0c2V0QWRkcmVzc0l0ZW0gPSAoa2V5LCB2YWx1ZSkgPT4ge1xyXG5cdFx0dGhpcy5zdGF0ZS5pdGVtW2tleV0gPSB2YWx1ZTtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRpdGVtOiB0aGlzLnN0YXRlLml0ZW0sXHJcblx0XHRcdGNhblN1Ym1pdDogdGhpcy52YWxpZGF0ZUZvcm0oKVxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLmZvcmNlVXBkYXRlKCk7XHJcblx0fVxyXG5cclxuXHR2YWxpZGF0ZUZvcm0oKSB7XHJcblx0XHRyZXR1cm4gT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuZXZlcnkoKGtleSkgPT4ge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5lbGVtZW50c1trZXldLnN0YXRlLmlzVmFsaWQgJiYgJCgnI2NyZWF0ZS1hZGRyZXNzIGlucHV0LmludmFsaWQnKS5sZW5ndGggPT09IDAgJiYgJCgnI2NyZWF0ZS1hZGRyZXNzIHNlbGVjdC5pbnZhbGlkJykubGVuZ3RoID09PSAwO1xyXG4gICAgfSk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVTdWJtaXQgPSAoZSkgPT57XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHRtYWtlRGVmYXVsdChlKXtcclxuXHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0XHRpZihlLnRhcmdldC50YWdOYW1lICE9PSAnQlVUVE9OJyl7XHJcblx0XHRcdGUudGFyZ2V0ID0gZS50YXJnZXQucGFyZW50RWxlbWVudDtcclxuXHRcdH1cclxuXHRcdGxldCBzdG9wID0gZS50YXJnZXQuZGlzYWJsZWQ7XHJcblxyXG5cdFx0aWYoIXN0b3AgJiYgdGhpcy52YWxpZGF0ZUZvcm0oKSl7IC8qJiYgdGhpcy52YWxpZFBvc3RhbENvZGUoZS50YXJnZXQpKi9cclxuXHRcdFx0dGhpcy5zdGF0ZS5tYWtlRGVmYXVsdCA9IHRydWU7XHJcblx0XHRcdHRoaXMuc3RhdGUuZXhlY3V0ZSA9IHRydWU7XHJcbiBcdFx0XHRBZGRyZXNzQWN0aW9ucy5jaGVja1Bvc3RhbENvZGUodGhpcy5zdGF0ZS5pdGVtLkNvdW50cnlDb2RlLCB0aGlzLnN0YXRlLml0ZW0uUG9zdGFsQ29kZSk7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzTG9hZGluZzogdHJ1ZVxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudERpZE1vdW50KCl7XHJcblx0XHR0aGlzLnVuc3Vic2NyaWJlID0gVXNlckNvdW50cnlPcHRpb25zU3RvcmUubGlzdGVuKCAoKSA9PntcclxuXHRcdFx0aWYodGhpcy5zdGF0ZS5zYXZlZCkge1xyXG5cdFx0XHRcdHRoaXMucmVzZXRGb3JtKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRjb3VudHJ5T3B0aW9uczogVXNlckNvdW50cnlPcHRpb25zU3RvcmUuZ2V0Q291bnRyeU9wdGlvbnMoKVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy52YWxpZGF0ZUZvcm0oKTtcclxuXHJcblx0XHR0aGlzLmNyZWF0ZUFkcmVzcyA9IFVzZXJBZGRyZXNzZXNTdG9yZS5saXN0ZW4oIChyZXMpID0+e1xyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRpc0xvYWRpbmc6IGZhbHNlXHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5jcmVhdGVBZHJlc3MgPSBBZGRyZXNzRmllbGRTdG9yZS5saXN0ZW4oIChyZXMpID0+e1xyXG5cclxuXHRcdFx0aWYoIXJlcyl7XHJcblx0XHRcdFx0JCgnI2NyZWF0ZS1hZGRyZXNzIGlucHV0W25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUG9zdGFsQ29kZVwiXScpLmFkZENsYXNzKCdpbnZhbGlkJyk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdCQoJyNjcmVhdGUtYWRkcmVzcyBpbnB1dFtuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLlBvc3RhbENvZGVcIl0nKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRjYW5TdWJtaXQ6IHJlcyAmJiB0aGlzLnZhbGlkYXRlRm9ybSgpXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0aWYodGhpcy5zdGF0ZS5leGVjdXRlKXtcclxuXHRcdFx0XHRpZihyZXMpe1xyXG5cdFx0XHRcdFx0aWYodGhpcy5zdGF0ZS5tYWtlRGVmYXVsdCl7XHJcblx0XHRcdFx0XHRcdHRoaXMuc2V0QWRkcmVzc0l0ZW0oJ0lzRGVmYXVsdCcsICF0aGlzLnN0YXRlLml0ZW0uSXNEZWZhdWx0KTtcclxuXHRcdFx0XHRcdFx0dGhpcy5zdGF0ZS5tYWtlRGVmYXVsdCA9IGZhbHNlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0QWRkcmVzc0FjdGlvbnMuY3JlYXRlQWRkcmVzcyh0aGlzLnN0YXRlLml0ZW0pO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdFx0XHRzYXZlZDogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRjYW5TdWJtaXQ6IGZhbHNlXHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdFx0XHRjYW5TdWJtaXQ6IGZhbHNlLFxyXG5cdFx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50cy5wb3N0YWxjb2RlLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdFx0aXNWYWxpZDpmYWxzZVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHRoaXMuc3RhdGUuZXhlY3V0ZSA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xyXG5cdFx0dGhpcy5jcmVhdGVBZHJlc3MoKTtcclxuXHR9XHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKCF0aGlzLnN0YXRlKSByZXR1cm4gbnVsbDtcclxuXHRcdGlmKCF0aGlzLnN0YXRlLml0ZW0pIHJldHVybiBudWxsO1xyXG5cclxuXHRcdGxldCBpdGVtID0gdGhpcy5zdGF0ZS5pdGVtO1xyXG5cdFx0bGV0IGxhbmcgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nO1xyXG5cdFx0bGV0IGZvcm1JZCA9IFwiY3JlYXRlLWFkZHJlc3NcIjtcclxuXHJcblx0XHRsZXQgZm9ybUNsYXNzTmFtZXMgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J3Jvdyc6IHRydWUsXHJcblx0XHRcdCd1c2VyLWFkZHJlc3MnOiB0cnVlLFxyXG5cdFx0XHQnY29sbGFwc2UnOiB0cnVlLFxyXG5cdFx0XHQnYWRkLW5ldyc6IHRydWUsXHJcblx0XHRcdCdpcy1sb2FkaW5nJzogdGhpcy5zdGF0ZS5pc0xvYWRpbmdcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCBkZWZhdWx0QnV0dG9uID0gPGJ1dHRvbiBkaXNhYmxlZD17IXRoaXMudmFsaWRhdGVGb3JtKCl9IG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0gdHlwZT1cImJ1dHRvblwiIGNsYXNzTmFtZT1cImJ1dHRvbiBtYWtlLWRlZmF1bHQgXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1jaGVja1wiIG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0+PC9pPjxzcGFuIG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0+e2xhbmcubWFrZURlZmF1bHR9PC9zcGFuPjwvYnV0dG9uPjtcclxuXHJcblx0XHRpZihpdGVtLklzRGVmYXVsdCA9PSB0cnVlKXtcclxuXHRcdFx0ZGVmYXVsdEJ1dHRvbiA9IDxidXR0b24gZGlzYWJsZWQ9eyF0aGlzLnZhbGlkYXRlRm9ybSgpfSBvbkNsaWNrPXt0aGlzLm1ha2VEZWZhdWx0LmJpbmQodGhpcyl9IHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJidXR0b24gbWFrZS1kZWZhdWx0IFwiPjxpIGNsYXNzTmFtZT1cImljb24tY2hlY2tcIiBvbkNsaWNrPXt0aGlzLm1ha2VEZWZhdWx0LmJpbmQodGhpcyl9PjwvaT48c3BhbiBvbkNsaWNrPXt0aGlzLm1ha2VEZWZhdWx0LmJpbmQodGhpcyl9PntsYW5nLnJlc2V0RGVmYXVsdH08L3NwYW4+PC9idXR0b24+O1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBwb3N0YWxDb2RlSW5wdXQgPSA8QWRkcmVzc0ZpZWxkIHJlZj17KGMpID0+IHRoaXMuZWxlbWVudHMucG9zdGFsY29kZSA9IGN9IG5hbWU9XCJQb3N0YWxDb2RlXCIgY291bnRyeUNvZGU9e3RoaXMuc3RhdGUuaXRlbS5Db3VudHJ5Q29kZX0gdmFsdWU9e2l0ZW0uUG9zdGFsQ29kZX0gc2V0QWRkcmVzc0l0ZW09e3RoaXMuc2V0QWRkcmVzc0l0ZW0uYmluZCh0aGlzKX0gbGFiZWw9e2xhbmcucG9zdGFsQ29kZX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMVwiIG1heExlbmd0aD1cIjEwXCIvPjtcclxuXHJcblx0XHRsZXQgY291bnRyeVJlZ2lvblNlbGVjdCA9IDxDb3VudHJ5UmVnaW9uQ29udGFpbmVyIHJlZj17KGMpID0+IHRoaXMuZWxlbWVudHMuY291bnRyeVJlZ2lvbkNvbnRhaW5lciA9IGN9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGNvdW50cnlPcHRpb25zPXt0aGlzLnN0YXRlLmNvdW50cnlPcHRpb25zfSBpdGVtPXtpdGVtfSAvPjtcclxuXHJcblx0XHRpZihhbHRlcm5hdGl2ZUxheW91dCl7XHJcblx0XHRcdGNvdW50cnlSZWdpb25TZWxlY3QgPSA8Q291bnRyeVJlZ2lvbkNvbnRhaW5lciByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmNvdW50cnlSZWdpb25Db250YWluZXIgPSBjfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBjb3VudHJ5T3B0aW9ucz17dGhpcy5zdGF0ZS5jb3VudHJ5T3B0aW9uc30gcG9zdGFsQ29kZT17cG9zdGFsQ29kZUlucHV0fSBpdGVtPXtpdGVtfSAvPjtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgY29tcGFueU5hbWVJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5jb21wYW55bmFtZSA9IGN9IG5hbWU9XCJDb21wYW55TmFtZVwiIHZhbHVlPXtpdGVtLkNvbXBhbnlOYW1lfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBsYWJlbD17bGFuZy5jb21wYW55bmFtZX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMlwiIG1heExlbmd0aD1cIjM1XCIgLz47XHJcblx0XHRsZXQgYWRkaXRpb25hbElucHV0ID0gPEFkZHJlc3NGaWVsZCByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmZpcnN0bmFtZSA9IGN9IG5hbWU9XCJGaXJzdE5hbWVcIiB2YWx1ZT17aXRlbS5GaXJzdE5hbWV9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLmZpcnN0bmFtZX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMFwiIG1heExlbmd0aD1cIjM1XCIgLz47XHJcblx0XHRsZXQgcGhvbmVJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5waG9uZW51bWJlciA9IGN9IG5hbWU9XCJEYXl0aW1lUGhvbmVOdW1iZXJcIiB2YWx1ZT17aXRlbS5EYXl0aW1lUGhvbmVOdW1iZXJ9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLnBob25lTnVtYmVyfSBlcnJvck1lc3NhZ2U9e2xhbmcuZXJyb3JQaG9uZX0gdmFsaWRhdG9yPVwicGhvbmVcIiBtaW5MZW5ndGg9XCIyXCIgbWF4TGVuZ3RoPVwiMTVcIi8+O1xyXG5cdFx0bGV0IGVtYWlsSW5wdXQgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5lbWFpbEZpZWxkRW5hYmxlZCA/IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5lbWFpbCA9IGN9IG5hbWU9XCJFbWFpbFwiIHZhbHVlPXtpdGVtLkVtYWlsfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBsYWJlbD17bGFuZy5lTWFpbH0gdmFsaWRhdG9yPVwiZW1haWxcIiBlcnJvck1lc3NhZ2U9e2hpYWJjb25maWcuYWRkcmVzc2VzLmxhbmcuZXJyb3JNYWlsfSBtYXhMZW5ndGg9XCIyNDFcIi8+IDogbnVsbDtcclxuXHRcdGxldCBsaW5lMUlucHV0ID0gPEFkZHJlc3NGaWVsZCByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmxpbmUxID0gY30gbmFtZT1cIkxpbmUxXCIgdmFsdWU9e2l0ZW0uTGluZTF9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLnN0cmVldH0gb3RoZXJBZGRyZXNzRmllbGQ9e2l0ZW0uTGluZTJ9IHZhbGlkYXRvcj1cIm1pbkxlbmd0aFwiIG1pbkxlbmd0aD1cIjJcIiBtYXhMZW5ndGg9XCIzNVwiLz47XHJcblx0XHRsZXQgbGluZTJJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5saW5lMiA9IGN9IG5hbWU9XCJMaW5lMlwiIHZhbHVlPXtpdGVtLkxpbmUyfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBvdGhlckFkZHJlc3NGaWVsZD17aXRlbS5MaW5lMX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMFwiIG1heExlbmd0aD1cIjQwXCIvPjtcclxuXHJcblx0XHRsZXQgY2l0eUlucHV0ID0gPEFkZHJlc3NGaWVsZCByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmNpdHkgPSBjfSBuYW1lPVwiQ2l0eVwiIHZhbHVlPXtpdGVtLkNpdHl9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLmNpdHl9IHZhbGlkYXRvcj1cIm1pbkxlbmd0aFwiIG1pbkxlbmd0aD1cIjJcIiBtYXhMZW5ndGg9XCIzNVwiLz47XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdj5cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInVjLXVzZXItYWRkcmVzc2VzXCI+XHJcblx0XHRcdFx0XHQ8Zm9ybSBpZD1cImNyZWF0ZS1hZGRyZXNzXCIgY2xhc3NOYW1lPXtmb3JtQ2xhc3NOYW1lc30gb25TdWJtaXQ9e3RoaXMuaGFuZGxlU3VibWl0LmJpbmQodGhpcyl9PlxyXG5cdFx0XHRcdFx0XHQ8bGFiZWwgY2xhc3NOYW1lPVwidS1tYi0wXCIgaHRtbEZvcj1cIkFkZHJlc3NJZFwiPlxyXG5cdFx0XHRcdFx0XHRcdDxpbnB1dCByZWY9J2FkZHJlc3NJZCcgY2xhc3NOYW1lPVwiQWRkcmVzc0lkXCIgdHlwZT1cImhpZGRlblwiIGRlZmF1bHRWYWx1ZT17aXRlbS5BZGRyZXNzSWR9Lz5cclxuXHRcdFx0XHRcdFx0PC9sYWJlbD5cclxuXHRcdFx0XHRcdFx0PGxhYmVsIGNsYXNzTmFtZT1cInUtbWItMFwiIGh0bWxGb3I9XCJNb2RpZmllZFwiPlxyXG5cdFx0XHRcdFx0XHRcdDxpbnB1dCByZWY9J21vZGlmaWVkJyBjbGFzc05hbWU9XCJNb2RpZmllZFwiIHR5cGU9XCJoaWRkZW5cIiBkZWZhdWx0VmFsdWU9e25ldyBEYXRlKCl9Lz5cclxuXHRcdFx0XHRcdFx0PC9sYWJlbD5cclxuXHRcdFx0XHRcdFx0PGxhYmVsIGh0bWxGb3I9XCJJc0RlZmF1bHRcIiBjbGFzc05hbWU9XCJ1LW1iLTBcIj5cclxuXHRcdFx0XHRcdFx0XHQ8aW5wdXQgcmVmPSdpc0RlYXVsdCcgY2xhc3NOYW1lPVwiSXNEZWZhdWx0XCIgdHlwZT1cInJhZGlvXCIgZGVmYXVsdFZhbHVlPVwiZmFsc2VcIiBkZWZhdWx0Q2hlY2tlZCBoaWRkZW4vPlxyXG5cdFx0XHRcdFx0XHQ8L2xhYmVsPlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTQgc21hbGwtMTAgYWRkcmVzcy10aXRsZVwiPlxyXG5cdFx0XHRcdFx0XHRcdCZuYnNwO1xyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjb2x1bW5zIG1lZGl1bS04IHNtYWxsLTIgZWRpdC10b2dnbGVcIj5cclxuXHRcdFx0XHRcdFx0XHQ8YnV0dG9uIGNsYXNzTmFtZT1cImJ1dHRvbiBjaXJjbGUgcmlnaHQgZWRpdC10b2dnbGUtYnV0dG9uXCIgb25DbGljaz17dGhpcy5oYW5kbGVUb2dnbGUuYmluZCh0aGlzLGZvcm1JZCl9PjxpIGNsYXNzTmFtZT1cImljb24tYWRkcmVzc2VkaXRpbmdcIj48L2k+PC9idXR0b24+XHJcblx0XHRcdFx0XHRcdFx0PG5hdiBjbGFzc05hbWU9XCJhZGRyZXNzZWRpdGluZy1tZW51IHNtYWxsLWhpZGRlblwiPlxyXG5cdFx0XHRcdFx0XHRcdFx0PHVsPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PGJ1dHRvbiBkaXNhYmxlZD17IXRoaXMuc3RhdGUuY2FuU3VibWl0fSBvbkNsaWNrPXt0aGlzLmNyZWF0ZS5iaW5kKHRoaXMpfSB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiYnV0dG9uIHNhdmVcIj48aSBjbGFzc05hbWU9XCJpY29uLW9rXCIgb25DbGljaz17dGhpcy5jcmVhdGUuYmluZCh0aGlzKX0+PC9pPjxzcGFuIG9uQ2xpY2s9e3RoaXMuY3JlYXRlLmJpbmQodGhpcyl9PntsYW5nLnNhdmV9PC9zcGFuPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8L2xpPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0e2RlZmF1bHRCdXR0b259XHJcblx0XHRcdFx0XHRcdFx0XHRcdDwvbGk+XHJcblx0XHRcdFx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdFx0XHRcdDwvbmF2PlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjb2x1bW5zIGxhcmdlLTEyIGVkaXQtYWRkcmVzc1wiPlxyXG5cdFx0XHRcdFx0XHRcdDxuYXYgY2xhc3NOYW1lPVwiYWRkcmVzc2VkaXRpbmctbWVudS1zbWFsbFwiPlxyXG5cdFx0XHRcdFx0XHRcdFx0PHVsPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PGJ1dHRvbiBkaXNhYmxlZD17IXRoaXMuc3RhdGUuY2FuU3VibWl0fSBvbkNsaWNrPXt0aGlzLmNyZWF0ZS5iaW5kKHRoaXMpfSB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiYnV0dG9uIHNhdmVcIj48aSBjbGFzc05hbWU9XCJpY29uLW9rXCIgb25DbGljaz17dGhpcy5jcmVhdGUuYmluZCh0aGlzKX0+PC9pPjxzcGFuIG9uQ2xpY2s9e3RoaXMuY3JlYXRlLmJpbmQodGhpcyl9PntsYW5nLnNhdmV9PC9zcGFuPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8L2xpPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR7ZGVmYXVsdEJ1dHRvbn1cclxuXHRcdFx0XHRcdFx0XHRcdFx0PC9saT5cclxuXHRcdFx0XHRcdFx0XHRcdDwvdWw+XHJcblx0XHRcdFx0XHRcdFx0PC9uYXY+XHJcblx0XHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJyb3cgY29sbGFwc2UgZWRpdC1pbnB1dHNcIj5cclxuXHRcdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY29sdW1ucyBtZWRpdW0tNFwiPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHR7YWx0ZXJuYXRpdmVMYXlvdXQgPyBjb3VudHJ5UmVnaW9uU2VsZWN0IDogY29tcGFueU5hbWVJbnB1dH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gXCJcIiA6IGFkZGl0aW9uYWxJbnB1dH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gXCJcIiA6IHBob25lSW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IFwiXCIgOiBlbWFpbElucHV0fVxyXG5cdFx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTRcIj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gY2l0eUlucHV0IDogY291bnRyeVJlZ2lvblNlbGVjdH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gbGluZTFJbnB1dCA6IFwiXCJ9XHJcblx0XHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGxpbmUySW5wdXQgOiBcIlwifVxyXG5cdFx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTRcIj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gY29tcGFueU5hbWVJbnB1dCA6IGxpbmUxSW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGFkZGl0aW9uYWxJbnB1dCA6IGxpbmUySW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IHBob25lSW5wdXQgOiBwb3N0YWxDb2RlSW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGVtYWlsSW5wdXQgOiBjaXR5SW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHQ8L2Zvcm0+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJhZGQtYWRkcmVzc1wiPlxyXG5cdFx0XHRcdFx0PGJ1dHRvbiBjbGFzc05hbWU9XCJidXR0b25cIj5cclxuXHRcdFx0XHRcdFx0PGkgY2xhc3NOYW1lPVwiaWNvbi1wbHVzLWNpcmNsZWRcIj48L2k+XHJcblx0XHRcdFx0XHRcdDxzcGFuPntsYW5nLmFkZE5ld0FkZHJlc3NCdXR0b259PC9zcGFuPlxyXG5cdFx0XHRcdFx0PC9idXR0b24+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IFVzZXJBZGRyZXNzZXNBZGRJdGVtO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5jbGFzcyBBZGRyZXNzRGVmYXVsdEluZGljYXRvciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5wcm9wcy5pc0RlZmF1bHQpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiZGVmYXVsdC1pbmRpY2F0aW9uXCI+XHJcblx0XHRcdFx0PGg0PntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmRlZmF1bHRJbmRpY2F0aW9ufTwvaDQ+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IEFkZHJlc3NEZWZhdWx0SW5kaWNhdG9yO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5jbGFzcyBBZGRyZXNzRXJyb3JNZXNzYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdH1cclxuXHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGlmKHRoaXMucHJvcHMuaXNWYWxpZCkgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiZXJyb3ItbXNnLXJlYWN0XCI+e3RoaXMucHJvcHMuZXJyb3JNZXNzYWdlfTwvc3Bhbj5cclxuXHRcdCk7XHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBBZGRyZXNzRXJyb3JNZXNzYWdlO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBBZGRyZXNzRXJyb3JNZXNzYWdlIGZyb20gJy4vYWRkcmVzc19lcnJvcl9tZXNzYWdlJztcclxuaW1wb3J0IHZhbGlkYXRvciBmcm9tICd2YWxpZGF0b3InO1xyXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcclxuaW1wb3J0IEFkZHJlc3NBY3Rpb25zIGZyb20gJy4uL19hY3Rpb25zL3VzZXJfYWRkcmVzc2VzX2FjdGlvbnMnO1xyXG5cclxuY2xhc3MgQWRkcmVzc0ZpZWxkIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aXNWYWxpZDogZmFsc2UsXHJcblx0XHRcdGlzRGlydHk6IGZhbHNlLFxyXG5cdFx0XHR2YWx1ZTogbnVsbFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHZhbGlkYXRlKHZhbHVlLCBvdGhlckFkZHJlc3NMZW5ndGgpIHtcclxuXHRcdHZhciByZXNDb2xsZWN0aW9uID0gW107XHJcblx0XHR2YXIgdmFsaWRhdGlvblR5cGVzID0gdGhpcy5wcm9wcy52YWxpZGF0b3IgPyB0aGlzLnByb3BzLnZhbGlkYXRvci5zcGxpdCgnLCcpIDogW107XHJcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHZhbGlkYXRpb25UeXBlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRzd2l0Y2godmFsaWRhdGlvblR5cGVzW2ldKSB7XHJcblx0XHRcdFx0Y2FzZSAnZW1haWwnOlxyXG5cdFx0XHRcdFx0cmVzQ29sbGVjdGlvbi5wdXNoKHZhbGlkYXRvci5pc0VtYWlsKHZhbHVlKSB8fCB2YWxpZGF0b3IuaXNFbXB0eSh2YWx1ZSkpO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0Y2FzZSAncGhvbmUnOlxyXG5cdFx0XHRcdFx0cmVzQ29sbGVjdGlvbi5wdXNoKHZhbGlkYXRvci5pc0xlbmd0aCh2YWx1ZSwge21pbjp0aGlzLnByb3BzLm1pbkxlbmd0aCwgbWF4OiB0aGlzLnByb3BzLm1heExlbmd0aH0pICAmJiAhdmFsaWRhdG9yLm1hdGNoZXModmFsdWUsIC9bQS1aYS16XS8pKTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdGNhc2UgJ21pbkxlbmd0aCc6XHJcblx0XHRcdFx0XHRyZXNDb2xsZWN0aW9uLnB1c2godmFsaWRhdG9yLmlzTGVuZ3RoKHZhbHVlLCB7bWluOnRoaXMucHJvcHMubWluTGVuZ3RofSkpO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0XHRcdHJlc0NvbGxlY3Rpb24ucHVzaCh0cnVlKTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYocmVzQ29sbGVjdGlvbi5pbmRleE9mKGZhbHNlKSA+IC0xKXtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aGFuZGxlQ2hhbmdlID0gKGUpID0+IHtcclxuXHRcdGlmKGUudGFyZ2V0LnZhbHVlLmxlbmd0aCA+IHRoaXMucHJvcHMubWF4TGVuZ3RoKSByZXR1cm4gZmFsc2U7XHJcblx0XHRpZih0aGlzLnByb3BzLmNvdW50cnlDb2RlKXtcclxuXHRcdFx0QWRkcmVzc0FjdGlvbnMuY2hlY2tQb3N0YWxDb2RlKHRoaXMucHJvcHMuY291bnRyeUNvZGUsIGUudGFyZ2V0LnZhbHVlKTtcclxuXHRcdH1cclxuXHRcdHRoaXMuc3RhdGUuaXNWYWxpZCA9IHRoaXMudmFsaWRhdGUoU3RyaW5nKGUudGFyZ2V0LnZhbHVlKSk7XHJcblx0XHR0aGlzLnN0YXRlLmlzRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5wcm9wcy5zZXRBZGRyZXNzSXRlbSh0aGlzLnByb3BzLm5hbWUsIGUudGFyZ2V0LnZhbHVlKTtcclxuXHJcblx0fVxyXG5cclxuXHRoYW5kbGVCbHVyID0gKGUpID0+ICB7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNEaXJ0eTogdHJ1ZVxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLmhhbmRsZUNoYW5nZShlKTtcclxuXHR9XHJcblxyXG5cdHByZXZlbnRTdWJtaXQgPSAoZSkgPT4gIHtcclxuXHRcdHZhciBjb2RlID0gZS53aGljaCB8fCBlLmtleUNvZGU7XHJcblx0XHRpZiAoY29kZSA9PSAnMTMnKXtcclxuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHR0aGlzLnN0YXRlLmlzVmFsaWQgPSB0aGlzLnZhbGlkYXRlKFN0cmluZyh0aGlzLnByb3BzLnZhbHVlKSk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xyXG5cclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aXNWYWxpZDogdGhpcy52YWxpZGF0ZShTdHJpbmcobmV4dFByb3BzLnZhbHVlKSlcclxuXHRcdFx0fSk7XHJcblxyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cclxuXHRcdGxldCBpc1ZhbGlkID0gdGhpcy5zdGF0ZS5pc1ZhbGlkIHx8ICF0aGlzLnN0YXRlLmlzRGlydHk7XHJcblxyXG5cdFx0bGV0IGlucHV0Q2xhc3NlcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQncmVxdWlyZWQnOiB0cnVlLFxyXG5cdFx0XHQnaW52YWxpZCc6ICFpc1ZhbGlkXHJcblx0XHR9KTtcclxuXHJcblxyXG5cdFx0Ly8gcmVxdWlyZWQgZm9yIG12YyB0byBtYXAgdG8gdmlldyBtb2RlbHNcclxuXHRcdGxldCBwcmVmaXhlZE5hbWUgPSBcIlNoaXBwaW5nQWRkcmVzcy5cIiArIHRoaXMucHJvcHMubmFtZTtcclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8bGFiZWwgaHRtbEZvcj17cHJlZml4ZWROYW1lfT57dGhpcy5wcm9wcy5sYWJlbH1cclxuXHRcdFx0XHRcdDxpbnB1dCBjbGFzc05hbWU9e2lucHV0Q2xhc3Nlc30gbmFtZT17cHJlZml4ZWROYW1lfSBvbktleURvd249e3RoaXMucHJldmVudFN1Ym1pdC5iaW5kKHRoaXMpfSBvbkNoYW5nZT17dGhpcy5oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKX0gb25CbHVyPXt0aGlzLmhhbmRsZUJsdXIuYmluZCh0aGlzKX0gdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIlwiIHZhbHVlPXt0aGlzLnByb3BzLnZhbHVlfSAvPlxyXG5cdFx0XHRcdFx0PEFkZHJlc3NFcnJvck1lc3NhZ2UgaXNWYWxpZD17aXNWYWxpZH0gZXJyb3JNZXNzYWdlPXt0aGlzLnByb3BzLmVycm9yTWVzc2FnZX0gLz5cclxuXHRcdFx0PC9sYWJlbD5cclxuXHRcdCk7XHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBBZGRyZXNzRmllbGQ7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XHJcbmltcG9ydCBBZGRyZXNzQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy91c2VyX2FkZHJlc3Nlc19hY3Rpb25zJztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBVc2VyQ291bnRyeU9wdGlvbnNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3VzZXJfY291bnRyeV9vcHRpb25zX3N0b3JlJztcclxuaW1wb3J0IENvdW50cnlSZWdpb25Db250YWluZXIgZnJvbSAnLi9jb3VudHJ5X3JlZ2lvbl9jb250YWluZXInO1xyXG5pbXBvcnQgQWRkcmVzc0RlZmF1bHRJbmRpY2F0b3IgZnJvbSAnLi9hZGRyZXNzX2RlZmF1bHRfaW5kaWNhdG9yJztcclxuaW1wb3J0IEFkZHJlc3NGaWVsZCBmcm9tICcuL2FkZHJlc3NfZmllbGQnO1xyXG5pbXBvcnQgQWRkcmVzc0ZpZWxkU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy9hZGRyZXNzX2ZpZWxkX3N0b3JlJztcclxuXHJcbmxldCBhbHRlcm5hdGl2ZUxheW91dCA9IGhpYWJjb25maWcubWFya2V0SWQgPT0gXCJKUDAyXCIgPyB0cnVlIDogZmFsc2U7XHJcblxyXG5jbGFzcyBBZGRyZXNzSXRlbSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0Y29uc3RydWN0b3IocHJvcHMpIHtcclxuXHRcdHN1cGVyKHByb3BzKTtcclxuXHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdGl0ZW06IHt9LFxyXG5cdFx0XHRjb3VudHJ5T3B0aW9uczogW10sXHJcblx0XHRcdGNhblN1Ym1pdDogZmFsc2UsXHJcblx0XHRcdHJlZ2lvblZhbHVlOiAnbm8nLFxyXG5cdFx0XHRjaGFuZ2VkOiBmYWxzZSxcclxuXHRcdFx0aXNFZGl0aW5nOiBmYWxzZSxcclxuXHRcdFx0aXNPcGVuOiBmYWxzZSxcclxuXHRcdFx0bWFrZURlZmF1bHQ6IGZhbHNlLFxyXG5cdFx0XHRleGVjdXRlOiBmYWxzZSxcclxuXHRcdFx0aXNMb2FkaW5nIDogZmFsc2VcclxuXHRcdH07XHJcblxyXG5cdFx0dGhpcy5lbGVtZW50cyA9IHt9O1xyXG5cdH1cclxuXHJcblx0aGFuZGxlVG9nZ2xlRWRpdCA9IChlKSA9PiB7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNFZGl0aW5nOiAhdGhpcy5zdGF0ZS5pc0VkaXRpbmdcclxuXHRcdH0pO1xyXG5cdFx0aWYoIXRoaXMuc3RhdGUuaXNFZGl0aW5nKXtcclxuXHRcdFx0QWRkcmVzc0FjdGlvbnMuY2hlY2tQb3N0YWxDb2RlKHRoaXMucHJvcHMuaXRlbS5Db3VudHJ5Q29kZSwgdGhpcy5wcm9wcy5pdGVtLlBvc3RhbENvZGUpO1xyXG5cdFx0fVxyXG5cclxuICB9XHJcblxyXG5cdHNldEFkZHJlc3NJdGVtID0gKGtleSwgdmFsdWUpID0+IHtcclxuXHRcdHRoaXMucHJvcHMuaXRlbVtrZXldID0gdmFsdWU7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0Ly8gaXRlbTogdGhpcy5wcm9wcy5pdGVtLFxyXG5cdFx0XHRjYW5TdWJtaXQ6IHRoaXMudmFsaWRhdGVGb3JtKClcclxuXHRcdH0pO1xyXG5cdFx0dGhpcy5mb3JjZVVwZGF0ZSgpO1xyXG5cdH1cclxuXHJcblx0dmFsaWRhdGVGb3JtKCkge1xyXG5cdFx0cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZWxlbWVudHMpLmV2ZXJ5KChrZXkpID0+IHtcclxuXHRcdFx0cmV0dXJuICh0aGlzLmVsZW1lbnRzW2tleV0uc3RhdGUuaXNWYWxpZCAmJiAkKCcjJyt0aGlzLnByb3BzLml0ZW0uQWRkcmVzc0lkKycgaW5wdXQuaW52YWxpZCcpLmxlbmd0aCA9PT0gMCAmJiAkKCcjJyt0aGlzLnByb3BzLml0ZW0uQWRkcmVzc0lkKycgc2VsZWN0LmludmFsaWQnKS5sZW5ndGggPT09IDApO1xyXG4gICAgfSk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVTdWJtaXQgPSAoZSkgPT57XHJcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHRtYWtlRGVmYXVsdChlKXtcclxuXHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0XHRpZihlLnRhcmdldC50YWdOYW1lICE9PSAnQlVUVE9OJyl7XHJcblx0XHRcdGUudGFyZ2V0ID0gZS50YXJnZXQucGFyZW50RWxlbWVudDtcclxuXHRcdH1cclxuXHRcdGxldCBzdG9wID0gZS50YXJnZXQuZGlzYWJsZWQ7XHJcblx0XHRpZighc3RvcCl7XHJcblx0XHRcdHRoaXMuc3RhdGUubWFrZURlZmF1bHQgPSB0cnVlO1xyXG5cdFx0XHR0aGlzLnN0YXRlLmV4ZWN1dGUgPSB0cnVlO1xyXG5cdFx0XHRBZGRyZXNzQWN0aW9ucy5jaGVja1Bvc3RhbENvZGUodGhpcy5wcm9wcy5pdGVtLkNvdW50cnlDb2RlLCB0aGlzLnByb3BzLml0ZW0uUG9zdGFsQ29kZSk7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzTG9hZGluZzogdHJ1ZVxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cclxuXHRzYXZlKGUpe1xyXG5cdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHRcdGlmKGUudGFyZ2V0LnRhZ05hbWUgIT09ICdCVVRUT04nKXtcclxuXHRcdFx0ZS50YXJnZXQgPSBlLnRhcmdldC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmKCFlLnRhcmdldC5kaXNhYmxlZCApe1xyXG5cdFx0XHRBZGRyZXNzQWN0aW9ucy5jaGVja1Bvc3RhbENvZGUodGhpcy5wcm9wcy5pdGVtLkNvdW50cnlDb2RlLCB0aGlzLnByb3BzLml0ZW0uUG9zdGFsQ29kZSk7XHJcblx0XHRcdGlmKCB0aGlzLnZhbGlkYXRlRm9ybSgpICl7XHJcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRpc0xvYWRpbmc6IHRydWUsXHJcblx0XHRcdFx0XHRleGVjdXRlOiB0cnVlXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0dGhpcy5zdGF0ZS5leGVjdXRlID0gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmVtb3ZlKGUpe1xyXG5cdFx0QWRkcmVzc0FjdGlvbnMuZGVsZXRlQWRkcmVzcyh0aGlzLnByb3BzLml0ZW0pO1xyXG5cdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdGlzTG9hZGluZzogdHJ1ZVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHJcblx0Y29tcG9uZW50RGlkTW91bnQoKXtcclxuXHRcdHRoaXMuc2F2ZUFkcmVzcyA9IEFkZHJlc3NGaWVsZFN0b3JlLmxpc3RlbiggKHJlcykgPT4ge1xyXG5cclxuXHRcdFx0aWYoIXJlcyl7XHJcblx0XHRcdFx0JCgnIycrdGhpcy5wcm9wcy5pdGVtLkFkZHJlc3NJZCsnIGlucHV0W25hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUG9zdGFsQ29kZVwiXScpLmFkZENsYXNzKCdpbnZhbGlkJyk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdCQoJyMnK3RoaXMucHJvcHMuaXRlbS5BZGRyZXNzSWQrJyBpbnB1dFtuYW1lPVwiU2hpcHBpbmdBZGRyZXNzLlBvc3RhbENvZGVcIl0nKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRjYW5TdWJtaXQ6IHJlc1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0aWYodGhpcy5zdGF0ZS5leGVjdXRlKXtcclxuXHRcdFx0XHRpZihyZXMpe1xyXG5cdFx0XHRcdFx0aWYodGhpcy5zdGF0ZS5tYWtlRGVmYXVsdCl7XHJcblx0XHRcdFx0XHRcdHRoaXMuc3RhdGUubWFrZURlZmF1bHQgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0dGhpcy5wcm9wcy5pdGVtLklzRGVmYXVsdCA9ICF0aGlzLnByb3BzLml0ZW0uSXNEZWZhdWx0O1xyXG5cdFx0XHRcdFx0XHRBZGRyZXNzQWN0aW9ucy51cGRhdGVBZGRyZXNzKHRoaXMucHJvcHMuaXRlbSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0QWRkcmVzc0FjdGlvbnMudXBkYXRlQWRkcmVzcyh0aGlzLnByb3BzLml0ZW0pO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdFx0XHRjYW5TdWJtaXQ6IGZhbHNlLFxyXG5cdFx0XHRcdFx0XHRcdGlzT3BlbjogZmFsc2VcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0XHRcdGNhblN1Ym1pdDogZmFsc2UsXHJcblx0XHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0XHR0aGlzLmVsZW1lbnRzLnBvc3RhbGNvZGUuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdFx0XHRpc1ZhbGlkOiBmYWxzZVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR0aGlzLnN0YXRlLmV4ZWN1dGUgPSBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuXHRcdHRoaXMuc2F2ZUFkcmVzcygpO1xyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcclxuXHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHQvLyBpdGVtOiB0aGlzLnByb3BzLml0ZW0sXHJcblx0XHRcdGlzRWRpdGluZzogdGhpcy5zdGF0ZS5pc09wZW4sXHJcblx0XHRcdGlzTG9hZGluZzogZmFsc2VcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0cmVuZGVyKCkge1xyXG5cdFx0aWYoIXRoaXMucHJvcHMpIHJldHVybiBudWxsO1xyXG5cclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZztcclxuXHRcdGxldCBpdGVtID0gdGhpcy5wcm9wcy5pdGVtO1xyXG5cdFx0bGV0IGFkZHJlc3NJZCA9IGl0ZW0uQWRkcmVzc0lkO1xyXG5cdFx0bGV0IGNhbkVkaXQgPSAhdGhpcy5wcm9wcy5pc0JpZ0N1c3RvbWVyO1xyXG5cclxuXHRcdGxldCBmb3JtQ2xhc3NOYW1lcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQncm93JzogdHJ1ZSxcclxuXHRcdFx0J3VzZXItYWRkcmVzcyc6IHRydWUsXHJcblx0XHRcdCdjb2xsYXBzZSc6IHRydWUsXHJcblx0XHRcdCdkZWZhdWx0JzogaXRlbS5Jc0RlZmF1bHQsXHJcblx0XHRcdCdlZGl0aW5nJzogdGhpcy5zdGF0ZS5pc0VkaXRpbmcsXHJcblx0XHRcdCdpcy1sb2FkaW5nJzogdGhpcy5zdGF0ZS5pc0xvYWRpbmdcclxuXHRcdH0pO1xyXG5cclxuXHRcdGxldCB0aXRsZSA9IGl0ZW0uRmlyc3ROYW1lID8gaXRlbS5Db21wYW55TmFtZSsnLCAnK2l0ZW0uRmlyc3ROYW1lKycuJyA6IGl0ZW0uQ29tcGFueU5hbWUgKyAnLicgO1xyXG5cdFx0bGV0IHN0cmVldCA9IGl0ZW0uTGluZTIgPyBpdGVtLkxpbmUxICsgJyAnK2l0ZW0uTGluZTIgOiBpdGVtLkxpbmUxO1xyXG5cclxuXHRcdGxldCByZWdpb25OYW1lO1xyXG5cdFx0aWYodGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucyl7XHJcblx0XHRcdGxldCBjb3VudHJ5ID0gXy5maW5kKHRoaXMucHJvcHMuY291bnRyeU9wdGlvbnMsIChvKSA9PiB7IHJldHVybiBvLkNvdW50cnlDb2RlID09IGl0ZW0uQ291bnRyeUNvZGU7IH0pO1xyXG5cclxuXHRcdFx0aWYoY291bnRyeSl7XHJcblx0XHRcdFx0bGV0IHJlZ2lvbiA9IF8uZmluZChjb3VudHJ5LlJlZ2lvbnMsIChvKSA9PiB7IHJldHVybiBvLkNvZGUgPT0gaXRlbS5SZWdpb247IH0pO1xyXG5cdFx0XHRcdHJlZ2lvbk5hbWUgPSByZWdpb24gPyAnLCAnK3JlZ2lvbi5OYW1lIDogbnVsbDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0bGV0IGFkZHJlc3NJdGVtTmFtZUVsbSA9IDxzcGFuPnt0aXRsZX08YnIvPntzdHJlZXR9LCB7aXRlbS5Qb3N0YWxDb2RlfSB7aXRlbS5DaXR5fXtyZWdpb25OYW1lfSB7aXRlbS5Db3VudHJ5TmFtZX08L3NwYW4+O1xyXG5cdFx0aWYgKGFsdGVybmF0aXZlTGF5b3V0KXtcclxuXHRcdFx0YWRkcmVzc0l0ZW1OYW1lRWxtID0gPHNwYW4+e3RpdGxlfTxici8+e2l0ZW0uQ291bnRyeU5hbWV9IHtpdGVtLlBvc3RhbENvZGV9e3JlZ2lvbk5hbWV9LiB7aXRlbS5DaXR5fSB7c3RyZWV0fTwvc3Bhbj5cclxuXHRcdH1cclxuXHRcdHZhciBkZWZhdWx0UmFkaW8gPSA8aW5wdXQgcmVmPSdpc0RlYXVsdCcgY2xhc3NOYW1lPVwiSXNEZWZhdWx0XCIgIHR5cGU9XCJyYWRpb1wiIGRlZmF1bHRWYWx1ZT17aXRlbS5Jc0RlZmF1bHR9IGhpZGRlbi8+O1xyXG5cdFx0aWYoaXRlbS5Jc0RlZmF1bHQpe1xyXG5cdFx0XHRkZWZhdWx0UmFkaW8gPSA8aW5wdXQgcmVmPSdpc0RlYXVsdCcgY2xhc3NOYW1lPVwiSXNEZWZhdWx0XCIgdHlwZT1cInJhZGlvXCIgZGVmYXVsdFZhbHVlPXtpdGVtLklzRGVmYXVsdH0gZGVmYXVsdENoZWNrZWQgaGlkZGVuLz47XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IGRlZmF1bHRCdXR0b24gPSA8YnV0dG9uIGRpc2FibGVkPXshdGhpcy52YWxpZGF0ZUZvcm0oKX0gb25DbGljaz17dGhpcy5tYWtlRGVmYXVsdC5iaW5kKHRoaXMpfSB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiYnV0dG9uIG1ha2UtZGVmYXVsdCBcIj48aSBjbGFzc05hbWU9XCJpY29uLWNoZWNrXCIgb25DbGljaz17dGhpcy5tYWtlRGVmYXVsdC5iaW5kKHRoaXMpfT48L2k+PHNwYW4gb25DbGljaz17dGhpcy5tYWtlRGVmYXVsdC5iaW5kKHRoaXMpfT57bGFuZy5tYWtlRGVmYXVsdH08L3NwYW4+PC9idXR0b24+O1xyXG5cdFx0aWYoaXRlbS5Jc0RlZmF1bHQpe1xyXG5cdFx0XHRkZWZhdWx0QnV0dG9uID0gPGJ1dHRvbiBkaXNhYmxlZD17IXRoaXMudmFsaWRhdGVGb3JtKCl9IG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0gdHlwZT1cImJ1dHRvblwiIGNsYXNzTmFtZT1cImJ1dHRvbiBtYWtlLWRlZmF1bHQgXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1jaGVja1wiIG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0+PC9pPjxzcGFuIG9uQ2xpY2s9e3RoaXMubWFrZURlZmF1bHQuYmluZCh0aGlzKX0+e2xhbmcucmVzZXREZWZhdWx0fTwvc3Bhbj48L2J1dHRvbj47XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHBvc3RhbENvZGVJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5wb3N0YWxjb2RlID0gY30gbmFtZT1cIlBvc3RhbENvZGVcIiBjb3VudHJ5Q29kZT17dGhpcy5wcm9wcy5pdGVtLkNvdW50cnlDb2RlfSB2YWx1ZT17aXRlbS5Qb3N0YWxDb2RlfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBsYWJlbD17bGFuZy5wb3N0YWxDb2RlfSB2YWxpZGF0b3I9XCJtaW5MZW5ndGhcIiBtaW5MZW5ndGg9XCIxXCIgbWF4TGVuZ3RoPVwiMTBcIi8+O1xyXG5cclxuXHRcdGxldCBjb3VudHJ5UmVnaW9uU2VsZWN0ID0gPENvdW50cnlSZWdpb25Db250YWluZXIgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5jb3VudHJ5UmVnaW9uQ29udGFpbmVyID0gY30gc2V0QWRkcmVzc0l0ZW09e3RoaXMuc2V0QWRkcmVzc0l0ZW0uYmluZCh0aGlzKX0gY291bnRyeU9wdGlvbnM9e3RoaXMucHJvcHMuY291bnRyeU9wdGlvbnN9IGl0ZW09e3RoaXMucHJvcHMuaXRlbX0gLz47XHJcblx0XHRpZihhbHRlcm5hdGl2ZUxheW91dCl7XHJcblx0XHRcdGNvdW50cnlSZWdpb25TZWxlY3QgPSA8Q291bnRyeVJlZ2lvbkNvbnRhaW5lciByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmNvdW50cnlSZWdpb25Db250YWluZXIgPSBjfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBjb3VudHJ5T3B0aW9ucz17dGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9uc30gcG9zdGFsQ29kZT17cG9zdGFsQ29kZUlucHV0fSBpdGVtPXt0aGlzLnByb3BzLml0ZW19IC8+O1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBjaXR5SW5wdXQgPSA8QWRkcmVzc0ZpZWxkIHJlZj17KGMpID0+IHRoaXMuZWxlbWVudHMuY2l0eSA9IGN9IG5hbWU9XCJDaXR5XCIgdmFsdWU9e2l0ZW0uQ2l0eX0gc2V0QWRkcmVzc0l0ZW09e3RoaXMuc2V0QWRkcmVzc0l0ZW0uYmluZCh0aGlzKX0gbGFiZWw9e2xhbmcuY2l0eX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMlwiIG1heExlbmd0aD1cIjM1XCIvPjtcclxuXHRcdGxldCBsaW5lMUlucHV0ID0gPEFkZHJlc3NGaWVsZCByZWY9eyhjKSA9PiB0aGlzLmVsZW1lbnRzLmxpbmUxID0gY30gbmFtZT1cIkxpbmUxXCIgdmFsdWU9e2l0ZW0uTGluZTF9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLnN0cmVldH0gb3RoZXJBZGRyZXNzRmllbGQ9e2l0ZW0uTGluZTJ9IHZhbGlkYXRvcj1cIm1pbkxlbmd0aFwiIG1pbkxlbmd0aD1cIjJcIiBtYXhMZW5ndGg9XCIzNVwiIC8+O1xyXG5cdFx0bGV0IGxpbmUySW5wdXQgPSA8QWRkcmVzc0ZpZWxkIHJlZj17KGMpID0+IHRoaXMuZWxlbWVudHMubGluZTIgPSBjfSBuYW1lPVwiTGluZTJcIiB2YWx1ZT17aXRlbS5MaW5lMn0gc2V0QWRkcmVzc0l0ZW09e3RoaXMuc2V0QWRkcmVzc0l0ZW0uYmluZCh0aGlzKX0gb3RoZXJBZGRyZXNzRmllbGQ9e2l0ZW0uTGluZTF9IHZhbGlkYXRvcj1cIm1pbkxlbmd0aFwiIG1pbkxlbmd0aD1cIjBcIiBtYXhMZW5ndGg9XCI0MFwiLz47XHJcblx0XHRsZXQgY29tcGFueU5hbWVJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5jb21wYW55bmFtZSA9IGN9IG5hbWU9XCJDb21wYW55TmFtZVwiIHZhbHVlPXtpdGVtLkNvbXBhbnlOYW1lfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBsYWJlbD17bGFuZy5jb21wYW55bmFtZX0gdmFsaWRhdG9yPVwibWluTGVuZ3RoXCIgbWluTGVuZ3RoPVwiMlwiIG1heExlbmd0aD1cIjM1XCIvPjtcclxuXHRcdGxldCBhZGRpdGlvbmFsSW5wdXQgPSA8QWRkcmVzc0ZpZWxkIHJlZj17KGMpID0+IHRoaXMuZWxlbWVudHMuZmlyc3RuYW1lID0gY30gbmFtZT1cIkZpcnN0TmFtZVwiIHZhbHVlPXtpdGVtLkZpcnN0TmFtZX0gc2V0QWRkcmVzc0l0ZW09e3RoaXMuc2V0QWRkcmVzc0l0ZW0uYmluZCh0aGlzKX0gbGFiZWw9e2xhbmcuZmlyc3RuYW1lfXZhbGlkYXRvcj1cIm1pbkxlbmd0aFwiIG1pbkxlbmd0aD1cIjBcIiBtYXhMZW5ndGg9XCIzNVwiLz47XHJcblx0XHRsZXQgcGhvbmVJbnB1dCA9IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5waG9uZW51bWJlciA9IGN9IG5hbWU9XCJEYXl0aW1lUGhvbmVOdW1iZXJcIiB2YWx1ZT17aXRlbS5EYXl0aW1lUGhvbmVOdW1iZXJ9IHNldEFkZHJlc3NJdGVtPXt0aGlzLnNldEFkZHJlc3NJdGVtLmJpbmQodGhpcyl9IGxhYmVsPXtsYW5nLnBob25lTnVtYmVyfSBlcnJvck1lc3NhZ2U9e2xhbmcuZXJyb3JQaG9uZX0gdmFsaWRhdG9yPVwicGhvbmVcIiBtaW5MZW5ndGg9XCIyXCIgbWF4TGVuZ3RoPVwiMTVcIi8+O1xyXG5cdFx0bGV0IGVtYWlsSW5wdXQgPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5lbWFpbEZpZWxkRW5hYmxlZCA/IDxBZGRyZXNzRmllbGQgcmVmPXsoYykgPT4gdGhpcy5lbGVtZW50cy5lbWFpbCA9IGN9IG5hbWU9XCJFbWFpbFwiIHZhbHVlPXtpdGVtLkVtYWlsfSBzZXRBZGRyZXNzSXRlbT17dGhpcy5zZXRBZGRyZXNzSXRlbS5iaW5kKHRoaXMpfSBsYWJlbD17bGFuZy5lTWFpbH0gdmFsaWRhdG9yPVwiZW1haWxcIiBlcnJvck1lc3NhZ2U9e2hpYWJjb25maWcuYWRkcmVzc2VzLmxhbmcuZXJyb3JNYWlsfSBtYXhMZW5ndGg9XCIyNDFcIi8+IDogbnVsbDtcclxuXHRcdGxldCBkZWZhdWx0QWRkcmVzcyA9ICF0aGlzLnByb3BzLmlzQmlnQ3VzdG9tZXIgPyA8QWRkcmVzc0RlZmF1bHRJbmRpY2F0b3IgaXNEZWZhdWx0PXtpdGVtLklzRGVmYXVsdH0gLz4gOiBcIlwiO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJmb3JtLXdyYXBwZXJcIj5cclxuXHRcdFx0XHR7ZGVmYXVsdEFkZHJlc3N9XHJcblx0XHRcdFx0PGZvcm0gaWQ9e2l0ZW0uQWRkcmVzc0lkfSBjbGFzc05hbWU9e2Zvcm1DbGFzc05hbWVzfSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXQuYmluZCh0aGlzKX0+XHJcblx0XHRcdFx0XHQ8bGFiZWwgY2xhc3NOYW1lPVwidS1tYi0wXCIgaHRtbEZvcj1cIk1vZGlmaWVkXCI+XHJcblx0XHRcdFx0XHRcdDxpbnB1dCByZWY9J21vZGlmaWVkJyBjbGFzc05hbWU9XCJNb2RpZmllZFwiIHR5cGU9XCJoaWRkZW5cIiBkZWZhdWx0VmFsdWU9e25ldyBEYXRlKCl9Lz5cclxuXHRcdFx0XHRcdDwvbGFiZWw+XHJcblx0XHRcdFx0XHQ8bGFiZWwgaHRtbEZvcj1cIklzRGVmYXVsdFwiIGNsYXNzTmFtZT1cInUtbWItMFwiPntkZWZhdWx0UmFkaW99PC9sYWJlbD5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY29sdW1ucyBtZWRpdW0tMTEgc21hbGwtMTAgYWRkcmVzcy10aXRsZVwiPlxyXG5cdFx0XHRcdFx0XHR7YWRkcmVzc0l0ZW1OYW1lRWxtfVxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHR7Y2FuRWRpdCA/XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY29sdW1ucyBtZWRpdW0tNiBzbWFsbC0yIGVkaXQtdG9nZ2xlXCI+XHJcblx0XHRcdFx0XHRcdFx0PGJ1dHRvbiBjbGFzc05hbWU9XCJidXR0b24gY2lyY2xlIHJpZ2h0IGVkaXQtdG9nZ2xlLWJ1dHRvblwiIG9uQ2xpY2s9e3RoaXMuaGFuZGxlVG9nZ2xlRWRpdC5iaW5kKHRoaXMpfT48aSBjbGFzc05hbWU9XCJpY29uLWFkZHJlc3NlZGl0aW5nXCI+PC9pPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHRcdDxuYXYgY2xhc3NOYW1lPVwiYWRkcmVzc2VkaXRpbmctbWVudSBzbWFsbC1oaWRkZW5cIj5cclxuXHRcdFx0XHRcdFx0XHRcdDx1bD5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PGxpPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdDxidXR0b24gZGlzYWJsZWQ9eyF0aGlzLnN0YXRlLmNhblN1Ym1pdH0gb25DbGljaz17dGhpcy5zYXZlLmJpbmQodGhpcyl9IGRhdGEtZm9ybS1pZD17aXRlbS5BZGRyZXNzSWR9IGNsYXNzTmFtZT1cImJ1dHRvbiBzYXZlXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi1va1wiIG9uQ2xpY2s9e3RoaXMuc2F2ZS5iaW5kKHRoaXMpfT48L2k+PHNwYW4gb25DbGljaz17dGhpcy5zYXZlLmJpbmQodGhpcyl9PntsYW5nLnNhdmV9PC9zcGFuPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8L2xpPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0e2RlZmF1bHRCdXR0b259XHJcblx0XHRcdFx0XHRcdFx0XHRcdDwvbGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdDxsaT5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQ8YnV0dG9uIG9uQ2xpY2s9e3RoaXMucmVtb3ZlLmJpbmQodGhpcyl9IGRhdGEtZm9ybS1pZD17aXRlbS5BZGRyZXNzSWR9IGNsYXNzTmFtZT1cImJ1dHRvbiByZW1vdmVcIj48aSBjbGFzc05hbWU9XCJpY29uLXRyYXNoXCI+PC9pPjxzcGFuPntsYW5nLnJlbW92ZX08L3NwYW4+PC9idXR0b24+XHJcblx0XHRcdFx0XHRcdFx0XHRcdDwvbGk+XHJcblx0XHRcdFx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdFx0XHRcdDwvbmF2PlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj4gOiBcIlwifVxyXG5cdFx0XHRcdFx0e2NhbkVkaXQgP1xyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjb2x1bW5zIGxhcmdlLTEyIGVkaXQtYWRkcmVzc1wiPlxyXG5cdFx0XHRcdFx0XHQ8bmF2IGNsYXNzTmFtZT1cImFkZHJlc3NlZGl0aW5nLW1lbnUtc21hbGxcIj5cclxuXHRcdFx0XHRcdFx0XHQ8dWw+XHJcblx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdDxidXR0b24gZGlzYWJsZWQ9eyF0aGlzLnN0YXRlLmNhblN1Ym1pdH0gb25DbGljaz17dGhpcy5zYXZlLmJpbmQodGhpcyl9IGRhdGEtZm9ybS1pZD17aXRlbS5BZGRyZXNzSWR9ICBjbGFzc05hbWU9XCJidXR0b24gc2F2ZVwiPjxpIGNsYXNzTmFtZT1cImljb24tb2tcIiBvbkNsaWNrPXt0aGlzLnNhdmUuYmluZCh0aGlzKX0+PC9pPjxzcGFuIG9uQ2xpY2s9e3RoaXMuc2F2ZS5iaW5kKHRoaXMpfT57bGFuZy5zYXZlfTwvc3Bhbj48L2J1dHRvbj5cclxuXHRcdFx0XHRcdFx0XHRcdDwvbGk+XHJcblx0XHRcdFx0XHRcdFx0XHQ8bGk+XHJcblx0XHRcdFx0XHRcdFx0XHRcdHtkZWZhdWx0QnV0dG9ufVxyXG5cdFx0XHRcdFx0XHRcdFx0PC9saT5cclxuXHRcdFx0XHRcdFx0XHRcdDxsaT5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PGJ1dHRvbiBvbkNsaWNrPXt0aGlzLnJlbW92ZS5iaW5kKHRoaXMpfSBkYXRhLWZvcm0taWQ9e2l0ZW0uQWRkcmVzc0lkfSBjbGFzc05hbWU9XCJidXR0b24gcmVtb3ZlXCI+PGkgY2xhc3NOYW1lPVwiaWNvbi10cmFzaFwiPjwvaT48c3Bhbj57bGFuZy5yZW1vdmV9PC9zcGFuPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHRcdFx0PC9saT5cclxuXHRcdFx0XHRcdFx0XHQ8L3VsPlxyXG5cdFx0XHRcdFx0XHQ8L25hdj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJyb3cgY29sbGFwc2UgZWRpdC1pbnB1dHNcIj5cclxuXHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTRcIj5cclxuXHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGNvdW50cnlSZWdpb25TZWxlY3QgOiBjb21wYW55TmFtZUlucHV0fVxyXG5cdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gXCJcIiA6IGFkZGl0aW9uYWxJbnB1dH1cclxuXHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IFwiXCIgOiBwaG9uZUlucHV0fVxyXG5cdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gXCJcIiA6IGVtYWlsSW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJjb2x1bW5zIG1lZGl1bS00XCI+XHJcblx0XHRcdFx0XHRcdFx0XHR7YWx0ZXJuYXRpdmVMYXlvdXQgPyBjaXR5SW5wdXQgOiBjb3VudHJ5UmVnaW9uU2VsZWN0fVxyXG5cdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gbGluZTFJbnB1dCA6IFwiXCJ9XHJcblx0XHRcdFx0XHRcdFx0XHR7YWx0ZXJuYXRpdmVMYXlvdXQgPyBsaW5lMklucHV0IDogXCJcIn1cclxuXHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTRcIj5cclxuXHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGNvbXBhbnlOYW1lSW5wdXQgOiBsaW5lMUlucHV0fVxyXG5cdFx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gYWRkaXRpb25hbElucHV0IDogbGluZTJJbnB1dH1cclxuXHRcdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IHBob25lSW5wdXQgOiBwb3N0YWxDb2RlSW5wdXR9XHJcblx0XHRcdFx0XHRcdFx0XHR7YWx0ZXJuYXRpdmVMYXlvdXQgPyBlbWFpbElucHV0IDogY2l0eUlucHV0fVxyXG5cdFx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDwvZGl2PiA6IFwiXCJ9XHJcblx0XHRcdFx0PC9mb3JtPlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblx0fVxyXG5cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgQWRkcmVzc0l0ZW07XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XHJcblxyXG5jbGFzcyBDb3VudHJ5RHJvcGRvd24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucykgcmV0dXJuIG51bGw7XHJcblxyXG5cdFx0bGV0IGNvdW50cnlPcHRpb25zID0gdGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucy5tYXAoIChjb3VudHJ5T3B0aW9uKSA9PiB7XHJcblx0XHRcdHJldHVybiAoXHJcblx0XHRcdFx0PG9wdGlvbiBrZXk9e2NvdW50cnlPcHRpb24uQ291bnRyeUNvZGV9IHZhbHVlPXtjb3VudHJ5T3B0aW9uLkNvdW50cnlDb2RlfT57Y291bnRyeU9wdGlvbi5OYW1lfTwvb3B0aW9uPlxyXG5cdFx0XHQpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0bGV0IGlzVmFsaWQgPSB0aGlzLnByb3BzLmlzVmFsaWQ7XHJcblxyXG5cdFx0bGV0IGlucHV0Q2xhc3NlcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQnaW52YWxpZCc6ICFpc1ZhbGlkXHJcblx0XHR9KTtcclxuXHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHQ8bGFiZWwgaHRtbEZvcj1cIkNvdW50cnlOYW1lXCI+e2hpYWJjb25maWcuYWRkcmVzc2VzLmxhbmcuY291bnRyeX1cclxuXHRcdFx0XHQ8c2VsZWN0IG9uQ2hhbmdlPXt0aGlzLnByb3BzLmhhbmRsZUNvdW50cnlDaGFuZ2UuYmluZCh0aGlzKX0gb25CbHVyPXt0aGlzLnByb3BzLmhhbmRsZUJsdXIuYmluZCh0aGlzKX0gbmFtZT1cIlNoaXBwaW5nQWRkcmVzcy5Db3VudHJ5Q29kZVwiIHZhbHVlPXt0aGlzLnByb3BzLml0ZW0uQ291bnRyeUNvZGV9IGNsYXNzTmFtZT17aW5wdXRDbGFzc2VzfT5cclxuXHRcdFx0XHRcdDxvcHRpb24ga2V5PVwiY291bnRyeS5kZWZhdWx0XCIgdmFsdWU9XCJkZWZhdWx0XCIgPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLnNlbGVjdENvdW50cnl9PC9vcHRpb24+XHJcblx0XHRcdFx0XHR7Y291bnRyeU9wdGlvbnN9XHJcblx0XHRcdFx0PC9zZWxlY3Q+XHJcblx0XHRcdDwvbGFiZWw+XHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgQ291bnRyeURyb3Bkb3duO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBDb3VudHJ5RHJvcGRvd24gZnJvbSAnLi9jb3VudHJ5X2Ryb3Bkb3duJztcclxuaW1wb3J0IFJlZ2lvbkRyb3Bkb3duIGZyb20gJy4vcmVnaW9uX2Ryb3Bkb3duJztcclxuaW1wb3J0IENoZWNrb3V0U2hpcHBpbmcgZnJvbSAnLi4vY2hlY2tvdXQvY2hlY2tvdXRfc2hpcHBpbmcnO1xyXG5pbXBvcnQgQWRkcmVzc0FjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvdXNlcl9hZGRyZXNzZXNfYWN0aW9ucyc7XHJcblxyXG5jbGFzcyBDb3VudHJ5UmVnaW9uQ29udGFpbmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0aXNWYWxpZDogZmFsc2UsXHJcblx0XHRcdGlzRGlydHk6IGZhbHNlXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0dmFsaWRhdGUodmFsdWUpIHtcclxuXHRcdHJldHVybiB2YWx1ZSAhPT0gJ2RlZmF1bHQnO1xyXG5cdH1cclxuXHJcblx0aGFuZGxlQmx1ciA9IChlKSA9PiB7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNEaXJ0eTogdHJ1ZVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVDb3VudHJ5Q2hhbmdlID0gKGUpID0+IHtcclxuXHRcdGxldCBzZXRMb2FkaW5nID0gZmFsc2U7XHJcblx0XHRsZXQgc2VsZWN0ZWRDb250cnkgPSBfLmZpbmQodGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucywgKG8pID0+IHsgcmV0dXJuIG8uQ291bnRyeUNvZGUgPT09IGUudGFyZ2V0LnZhbHVlOyB9KTtcclxuXHRcdHRoaXMucHJvcHMuc2V0QWRkcmVzc0l0ZW0oJ0NvdW50cnlDb2RlJywgc2VsZWN0ZWRDb250cnkuQ291bnRyeUNvZGUpO1xyXG5cdFx0dGhpcy5wcm9wcy5zZXRBZGRyZXNzSXRlbSgnQ291bnRyeU5hbWUnLCBzZWxlY3RlZENvbnRyeS5OYW1lKTtcclxuXHRcdHRoaXMucHJvcHMuc2V0QWRkcmVzc0l0ZW0oJ1JlZ2lvbk9wdGlvbnMnLCBzZWxlY3RlZENvbnRyeS5SZWdpb25zKTtcclxuXHRcdHRoaXMucHJvcHMuc2V0QWRkcmVzc0l0ZW0oJ1JlZ2lvbicsICcnKTtcclxuXHJcblx0XHRBZGRyZXNzQWN0aW9ucy5jaGVja1Bvc3RhbENvZGUoc2VsZWN0ZWRDb250cnkuQ291bnRyeUNvZGUsIHRoaXMucHJvcHMuaXRlbS5Qb3N0YWxDb2RlKTtcclxuXHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNWYWxpZDogdGhpcy52YWxpZGF0ZShlLnRhcmdldC52YWx1ZSksXHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XHJcblx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0aXNWYWxpZDogdGhpcy52YWxpZGF0ZShuZXh0UHJvcHMuaXRlbS5Db3VudHJ5Q29kZSlcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGxldCBzZWxlY3RlZENvdW50cnkgPSBfLmZpbmQodGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucywgKG8pID0+IHsgcmV0dXJuIG8uQ291bnRyeUNvZGUgPT09IHRoaXMucHJvcHMuaXRlbS5Db3VudHJ5Q29kZTsgfSk7XHJcblx0XHRsZXQgcmVnaW9ucyA9IG51bGw7XHJcblx0XHRsZXQgY291bnRyeUNvZGUgPSBudWxsO1xyXG5cdFx0bGV0IHBvc3RhbENvZGVFbG0gPSBudWxsO1xyXG5cclxuXHRcdGlmKHNlbGVjdGVkQ291bnRyeSkgcmVnaW9ucyA9IHNlbGVjdGVkQ291bnRyeS5SZWdpb25zO1xyXG5cdFx0aWYoc2VsZWN0ZWRDb3VudHJ5KSBjb3VudHJ5Q29kZSA9IHNlbGVjdGVkQ291bnRyeS5Db3VudHJ5Q29kZTtcclxuXHRcdGlmKHRoaXMucHJvcHMucG9zdGFsQ29kZSkgcG9zdGFsQ29kZUVsbSA9IHRoaXMucHJvcHMucG9zdGFsQ29kZTtcclxuXHJcblx0XHRsZXQgY291bnRyeVByb3BzID0ge1xyXG5cdFx0XHRjb3VudHJ5T3B0aW9uczogdGhpcy5wcm9wcy5jb3VudHJ5T3B0aW9ucyxcclxuXHRcdFx0aXRlbTogdGhpcy5wcm9wcy5pdGVtLFxyXG5cdFx0XHRoYW5kbGVDb3VudHJ5Q2hhbmdlOiB0aGlzLmhhbmRsZUNvdW50cnlDaGFuZ2UsXHJcblx0XHRcdHNldEFkZHJlc3NJdGVtOiB0aGlzLnByb3BzLnNldEFkZHJlc3NJdGVtLFxyXG5cdFx0XHRpc1ZhbGlkOiB0aGlzLnN0YXRlLmlzVmFsaWQsXHJcblx0XHRcdGlzRGlydHk6IHRoaXMuc3RhdGUuaXNEaXJ0eSxcclxuXHRcdFx0aGFuZGxlQmx1cjogdGhpcy5oYW5kbGVCbHVyXHJcblx0XHR9O1xyXG5cclxuXHRcdGxldCByZWdpb25Qcm9wcyA9IHtcclxuXHRcdFx0aXRlbTogdGhpcy5wcm9wcy5pdGVtLFxyXG5cdFx0XHRyZWdpb25zOiByZWdpb25zLFxyXG5cdFx0XHRoYW5kbGVSZWdpb25DaGFuZ2U6IHRoaXMuaGFuZGxlUmVnaW9uQ2hhbmdlLFxyXG5cdFx0XHRzZXRBZGRyZXNzSXRlbTogdGhpcy5wcm9wcy5zZXRBZGRyZXNzSXRlbSxcclxuXHRcdFx0cmVxdWlyZWQ6IGNvdW50cnlDb2RlICE9PSAnSlAnXHJcblx0XHR9O1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxkaXY+XHJcblx0XHRcdFx0PENvdW50cnlEcm9wZG93biB7Li4uY291bnRyeVByb3BzfSAvPlxyXG5cdFx0XHRcdHtwb3N0YWxDb2RlRWxtfVxyXG5cdFx0XHRcdDxSZWdpb25Ecm9wZG93biB7Li4ucmVnaW9uUHJvcHN9IC8+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0KTtcclxuXHJcblx0fVxyXG59O1xyXG5leHBvcnQgZGVmYXVsdCBDb3VudHJ5UmVnaW9uQ29udGFpbmVyO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5cclxuY2xhc3MgUmVnaW9uRHJvcGRvd24gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xyXG5cdGNvbnN0cnVjdG9yKHByb3BzKSB7XHJcblx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHR0aGlzLnN0YXRlID0ge1xyXG5cdFx0XHRpc0RpcnR5OiB0cnVlLFxyXG5cdFx0XHRpc1ZhbGlkOiBmYWxzZSxcclxuXHRcdH07XHJcblx0fVxyXG5cdHZhbGlkYXRlKHZhbHVlKSB7XHJcblx0XHRyZXR1cm4gdmFsdWUgIT09ICdkZWZhdWx0JztcclxuXHR9XHJcblxyXG5cdGhhbmRsZVJlZ2lvbkNoYW5nZSA9IChlKSA9PiB7XHJcblx0XHR0aGlzLmhhbmRsZUJsdXIoZSk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVCbHVyID0gKGUpID0+IHtcclxuXHJcblx0XHRpZih0aGlzLnByb3BzLnJlcXVpcmVkKXtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0aXNEaXJ0eTogIXRoaXMudmFsaWRhdGUoZS50YXJnZXQudmFsdWUpLFxyXG5cdFx0XHRcdGlzVmFsaWQ6IHRoaXMudmFsaWRhdGUoZS50YXJnZXQudmFsdWUpLFxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGlmKCFlLnRhcmdldC52YWx1ZSB8fCBlLnRhcmdldC52YWx1ZSA9PT0gJ2RlZmF1bHQnKXtcclxuXHRcdFx0XHRpZihlLnRhcmdldC5jbGFzc05hbWUuaW5kZXhPZignaW52YWxpZCcpID09PSAtMSl7XHJcblx0XHRcdFx0XHRlLnRhcmdldC5jbGFzc05hbWUgKz0gJyBpbnZhbGlkJztcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdGUudGFyZ2V0LmNsYXNzTmFtZSA9IGUudGFyZ2V0LmNsYXNzTmFtZS5yZXBsYWNlKCcgaW52YWxpZCcsICcnKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dGhpcy5wcm9wcy5zZXRBZGRyZXNzSXRlbSgnUmVnaW9uJywgZS50YXJnZXQudmFsdWUpO1xyXG5cdFx0fWVsc2V7XHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGlzRGlydHk6IGZhbHNlLFxyXG5cdFx0XHRcdGlzVmFsaWQ6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRlLnRhcmdldC5jbGFzc05hbWUgPSBlLnRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgnIGludmFsaWQnLCAnJyk7XHJcblx0XHRcdC8vIGNvbnNvbGUubG9nKGUudGFyZ2V0LnZhbHVlKTtcclxuXHRcdFx0dGhpcy5wcm9wcy5zZXRBZGRyZXNzSXRlbSgnUmVnaW9uJywgZS50YXJnZXQudmFsdWUpO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRpZighdGhpcy5wcm9wcy5yZWdpb25zIHx8IHRoaXMucHJvcHMucmVnaW9ucy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG5cdFx0Ly8gY29uc29sZS5sb2codGhpcy5wcm9wcy5yZXF1aXJlZCk7XHJcblxyXG5cdFx0bGV0IGkgPSAwO1xyXG5cdFx0bGV0IHJlZ2lvblZhbCA9ICcnO1xyXG5cdFx0bGV0IHBvc3NpYmxlUmVnaW9uQ29kZXMgPSBbXTtcclxuXHRcdGxldCByZWdpb25PcHRpb25zID0gdGhpcy5wcm9wcy5yZWdpb25zLm1hcCggKHJlZ2lvbikgPT4ge1xyXG5cdFx0XHRsZXQga2V5ID0gdGhpcy5wcm9wcy5pdGVtLkFkZHJlc3NJZCArIHJlZ2lvbi5Db2RlICsgaSsrO1xyXG5cdFx0XHRwb3NzaWJsZVJlZ2lvbkNvZGVzLnB1c2gocmVnaW9uLkNvZGUpO1xyXG5cclxuXHRcdFx0cmV0dXJuIChcclxuXHRcdFx0XHQ8b3B0aW9uIGtleT17a2V5fSB2YWx1ZT17cmVnaW9uLkNvZGV9PntyZWdpb24uTmFtZX08L29wdGlvbj5cclxuXHRcdFx0KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdHJlZ2lvblZhbCA9IHBvc3NpYmxlUmVnaW9uQ29kZXMuaW5kZXhPZih0aGlzLnByb3BzLml0ZW0uUmVnaW9uKSAhPT0gLTEgPyB0aGlzLnByb3BzLml0ZW0uUmVnaW9uIDogJ2RlZmF1bHQnO1xyXG5cdFx0bGV0IGlzVmFsaWQgPSByZWdpb25WYWwgIT09ICdkZWZhdWx0JztcclxuXHRcdGlmKCF0aGlzLnByb3BzLnJlcXVpcmVkKSBpc1ZhbGlkID0gdHJ1ZTtcclxuXHJcblx0XHRsZXQgaW5wdXRDbGFzc2VzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdpbnZhbGlkJzogIWlzVmFsaWQsXHJcblx0XHRcdCdSZWdpb24nIDogdHJ1ZSxcclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiAoXHJcblx0XHRcdDxsYWJlbCBodG1sRm9yPVwiUmVnaW9uXCI+e2hpYWJjb25maWcuYWRkcmVzc2VzLmxhbmcucmVnaW9ufVxyXG5cdFx0XHRcdDxzZWxlY3Qgb25DaGFuZ2U9e3RoaXMuaGFuZGxlUmVnaW9uQ2hhbmdlLmJpbmQodGhpcyl9IG9uQmx1cj17dGhpcy5oYW5kbGVCbHVyLmJpbmQodGhpcyl9IG5hbWU9XCJTaGlwcGluZ0FkZHJlc3MuUmVnaW9uXCIgY2xhc3NOYW1lPXtpbnB1dENsYXNzZXN9IHZhbHVlPXtyZWdpb25WYWx9PlxyXG5cdFx0XHRcdFx0PG9wdGlvbiBrZXk9XCJyZWdpb24uZGVmYXVsdFwiIHZhbHVlPVwiZGVmYXVsdFwiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLnNlbGVjdFJlZ2lvbn08L29wdGlvbj5cclxuXHRcdFx0XHRcdHtyZWdpb25PcHRpb25zfVxyXG5cdFx0XHRcdDwvc2VsZWN0PlxyXG5cdFx0XHQ8L2xhYmVsPlxyXG5cdFx0KTtcclxuXHR9XHJcbn07XHJcbmV4cG9ydCBkZWZhdWx0IFJlZ2lvbkRyb3Bkb3duO1xyXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xyXG4iLCIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBVc2VyRGVmYXVsdEFkZHJlc3Nlc1N0b3JlIGZyb20gJy4uL19zdG9yZXMvdXNlcl9kZWZhdWx0X2FkZHJlc3Nlc19zdG9yZSc7XHJcbmltcG9ydCBBZGRyZXNzQWN0aW9ucyBmcm9tICcuLi9fYWN0aW9ucy91c2VyX2FkZHJlc3Nlc19hY3Rpb25zJztcclxuaW1wb3J0IFVzZXJBZGRyZXNzZXNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3VzZXJfYWRkcmVzc2VzX3N0b3JlJztcclxuXHJcbmxldCBhbHRlcm5hdGl2ZUxheW91dCA9IGhpYWJjb25maWcubWFya2V0SWQgPT0gXCJKUDAyXCIgPyB0cnVlIDogZmFsc2U7XHJcblxyXG5jbGFzcyBVc2VyQWRkcmVzc2VzRGVmYXVsdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XHJcblx0XHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0XHRzdXBlcihwcm9wcyk7XHJcblx0XHRcdHRoaXMuc3RhdGUgPSB7XHJcblx0XHRcdFx0bG9hZGluZzogZmFsc2UsXHJcblx0XHRcdFx0Y3VycmVudEFkZHJlc3NJdGVtOiBudWxsLFxyXG5cdFx0XHRcdGNvdW50cnlPcHRpb25zOiBVc2VyQWRkcmVzc2VzU3RvcmUuZ2V0Q291bnRyeU9wdGlvbnMoKVxyXG5cdFx0XHR9O1xyXG5cdFx0fVxyXG5cdFx0Y29tcG9uZW50RGlkTW91bnQoKSB7XHJcblx0XHRcdHRoaXMudW5zdWJzY3JpYmUgPSBVc2VyRGVmYXVsdEFkZHJlc3Nlc1N0b3JlLmxpc3RlbiggKCkgPT5cclxuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcclxuXHRcdFx0XHRcdGN1cnJlbnRBZGRyZXNzSXRlbTogVXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZS5nZXREZWZhdWx0QWRkcmVzcygpLFxyXG5cdFx0XHRcdFx0Y291bnRyeU9wdGlvbnM6IFVzZXJBZGRyZXNzZXNTdG9yZS5nZXRDb3VudHJ5T3B0aW9ucygpXHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcclxuXHQgICAgdGhpcy51bnN1YnNjcmliZSgpO1xyXG5cdFx0fVxyXG5cdHJlbmRlcigpIHtcclxuXHRcdGxldCBsYW5nID0gaGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZztcclxuXHRcdGxldCBpdGVtID0gdGhpcy5zdGF0ZS5jdXJyZW50QWRkcmVzc0l0ZW07XHJcblxyXG5cdFx0aWYoIXRoaXMuc3RhdGUuY3VycmVudEFkZHJlc3NJdGVtKSByZXR1cm4gbnVsbDtcclxuXHJcblx0XHRsZXQgcmVnaW9uTmFtZTtcclxuXHJcblx0XHRpZihpdGVtKXtcclxuXHRcdFx0bGV0IGNvdW50cnkgPSBfLmZpbmQodGhpcy5zdGF0ZS5jb3VudHJ5T3B0aW9ucywgKG8pID0+IHsgcmV0dXJuIG8uTmFtZSA9PSBpdGVtLkNvdW50cnlOYW1lOyB9KTtcclxuXHRcdFx0aWYoY291bnRyeSl7XHJcblx0XHRcdFx0bGV0IHJlZ2lvbiA9IF8uZmluZChjb3VudHJ5LlJlZ2lvbnMsIChvKSA9PiB7IHJldHVybiBvLkNvZGUgPT0gaXRlbS5SZWdpb247IH0pO1xyXG5cdFx0XHRcdHJlZ2lvbk5hbWUgPSByZWdpb24gPyByZWdpb24uTmFtZSA6IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblxyXG5cdFx0aWYoIWl0ZW0pIHJldHVybiAoXHJcblx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidWMtbWVzc2FnZVwiPlxyXG5cdFx0XHRcdDxwPntsYW5nLm5vRGVmYXVsRmlyc3RMaW5lfTwvcD5cclxuXHRcdFx0XHQ8cD57bGFuZy5ub0RlZmF1bFNlY29uZExpbmV9PC9wPlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblx0XHRsZXQgZmlyc3ROYW1lRWxtID0gbnVsbDtcclxuXHRcdGlmKCBpdGVtLkZpcnN0TmFtZS5sZW5ndGggPiAwICl7XHJcblx0XHRcdGZpcnN0TmFtZUVsbSA9XHJcblx0XHRcdDxwPlxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxNCB1LWJvbGRcIj57bGFuZy5maXJzdG5hbWV9PC9zcGFuPlxyXG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntpdGVtLkZpcnN0TmFtZX08L3NwYW4+XHJcblx0XHRcdDwvcD5cclxuXHRcdH1cclxuXHRcdGxldCByZWdpb25FbG0gPSBudWxsO1xyXG5cdFx0aWYocmVnaW9uTmFtZSl7XHJcblx0XHRcdHJlZ2lvbkVsbSA9XHJcblx0XHRcdFx0PHA+XHJcblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmUgdS1zaXplMTQgdS1ib2xkXCI+e2xhbmcucmVnaW9ufTwvc3Bhbj5cclxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntyZWdpb25OYW1lfTwvc3Bhbj5cclxuXHRcdFx0XHQ8L3A+XHJcblx0XHRcdDtcclxuXHRcdH1cclxuXHRcdGxldCB0aXRsZSA9IGl0ZW0uRmlyc3ROYW1lID8gaXRlbS5Db21wYW55TmFtZSsnLCAnK2l0ZW0uRmlyc3ROYW1lKycuJyA6IGl0ZW0uQ29tcGFueU5hbWUgKyAnLicgO1xyXG5cdFx0bGV0IHN0cmVldCA9IGl0ZW0uTGluZTIgPyBpdGVtLkxpbmUxKycgJytpdGVtLkxpbmUyIDogaXRlbS5MaW5lMTtcclxuXHRcdGxldCByZWdpb25JdGVtID0gcmVnaW9uTmFtZSA/ICcsICcrcmVnaW9uTmFtZSA6ICcnO1xyXG5cclxuXHRcdGxldCBpdGVtTmFtZUVsbSA9IDxwPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxNCB1LWJvbGRcIj57dGl0bGV9PGJyIC8+e3N0cmVldH0ge2l0ZW0uUG9zdGFsQ29kZX0ge2l0ZW0uQ2l0eX17cmVnaW9uSXRlbX0ge2l0ZW0uQ291bnRyeU5hbWV9PC9zcGFuPjwvcD47XHJcblx0XHRpZihhbHRlcm5hdGl2ZUxheW91dCl7XHJcblx0XHRcdGl0ZW1OYW1lRWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPnt0aXRsZX08YnIgLz57aXRlbS5Db3VudHJ5TmFtZX0ge2l0ZW0uUG9zdGFsQ29kZX17cmVnaW9uTmFtZX0uIHtpdGVtLkNpdHl9IHtzdHJlZXR9PC9zcGFuPjwvcD47XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IGNvbXBhbnlOYW1lRWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPntsYW5nLmNvbXBhbnluYW1lfTwvc3Bhbj48c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmUgdS1zaXplMTJcIj57aXRlbS5Db21wYW55TmFtZX08L3NwYW4+PC9wPlxyXG5cdFx0bGV0IHBob25lbnVtYmVyRWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPntsYW5nLnBob25lTnVtYmVyfTwvc3Bhbj48c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmUgdS1zaXplMTJcIj57aXRlbS5EYXl0aW1lUGhvbmVOdW1iZXJ9PC9zcGFuPjwvcD47XHJcblx0XHRsZXQgZW1haWxFbG0gPSBoaWFiY29uZmlnLmFkZHJlc3Nlcy5lbWFpbEZpZWxkRW5hYmxlZCA/IDxwPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxNCB1LWJvbGRcIj57bGFuZy5lTWFpbH08L3NwYW4+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTEyXCI+e2l0ZW0uRW1haWx9PC9zcGFuPjwvcD4gOiBudWxsIDtcclxuXHRcdGxldCBjb3VudHJ5RWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPntsYW5nLmNvdW50cnl9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntpdGVtLkNvdW50cnlOYW1lfTwvc3Bhbj48L3A+O1xyXG5cdFx0bGV0IHN0cmVldEVsbSA9IDxwPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxNCB1LWJvbGRcIj57bGFuZy5zdHJlZXR9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntpdGVtLkxpbmUxfTwvc3Bhbj48c3BhbiBjbGFzc05hbWU9XCJ1LWxpbmUgdS1zaXplMTJcIj57aXRlbS5MaW5lMn08L3NwYW4+PC9wPjtcclxuXHRcdGxldCBjaXR5RWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPntsYW5nLmNpdHl9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntpdGVtLkNpdHl9PC9zcGFuPjwvcD47XHJcblx0XHRsZXQgcG9zdGFsRWxtID0gPHA+PHNwYW4gY2xhc3NOYW1lPVwidS1saW5lIHUtc2l6ZTE0IHUtYm9sZFwiPntsYW5nLnBvc3RhbENvZGV9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cInUtbGluZSB1LXNpemUxMlwiPntpdGVtLlBvc3RhbENvZGV9PC9zcGFuPjwvcD47XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJ1Yy11c2VyLWRlZmF1bHQtYWRkcmVzc1wiPlxyXG5cdFx0XHRcdDxoZWFkZXI+XHJcblx0XHRcdFx0XHQ8aDQ+e2xhbmcuZGVmYXVsdEhlYWRlcn08L2g0PlxyXG5cdFx0XHRcdDwvaGVhZGVyPlxyXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidWMtdXNlci1kZWZhdWx0LWFkZHJlc3Mtd3JhcHBlclwiPlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJyb3dcIj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWUgPVwiY29sdW1ucyBsYXJnZS0xMlwiPlxyXG5cdFx0XHRcdFx0XHR7aXRlbU5hbWVFbG19XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImNvbHVtbnMgbWVkaXVtLTRcIj5cclxuXHRcdFx0XHRcdFx0XHR7YWx0ZXJuYXRpdmVMYXlvdXQgPyBjb3VudHJ5RWxtIDogY29tcGFueU5hbWVFbG19XHJcblx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gcG9zdGFsRWxtIDogZmlyc3ROYW1lRWxtfVxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IHJlZ2lvbkVsbSA6IHBob25lbnVtYmVyRWxtfVxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IFwiXCIgOiBlbWFpbEVsbX1cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY29sdW1ucyBtZWRpdW0tNFwiPlxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGNpdHlFbG0gOiBjb3VudHJ5RWxtfVxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IHN0cmVldEVsbSA6IHJlZ2lvbkVsbX1cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY29sdW1ucyBtZWRpdW0tNFwiPlxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGNvbXBhbnlOYW1lRWxtIDogc3RyZWV0RWxtfVxyXG5cdFx0XHRcdFx0XHRcdHthbHRlcm5hdGl2ZUxheW91dCA/IGZpcnN0TmFtZUVsbSA6IGNpdHlFbG19XHJcblx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gcGhvbmVudW1iZXJFbG0gOiBwb3N0YWxFbG19XHJcblx0XHRcdFx0XHRcdFx0e2FsdGVybmF0aXZlTGF5b3V0ID8gZW1haWxFbG0gOiBcIlwifVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgVXNlckFkZHJlc3Nlc0RlZmF1bHQ7XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cclxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XHJcbmltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xyXG5pbXBvcnQgVXNlckFkZHJlc3Nlc1N0b3JlIGZyb20gJy4uL19zdG9yZXMvdXNlcl9hZGRyZXNzZXNfc3RvcmUnO1xyXG5pbXBvcnQgQWRkcmVzc0FjdGlvbnMgZnJvbSAnLi4vX2FjdGlvbnMvdXNlcl9hZGRyZXNzZXNfYWN0aW9ucyc7XHJcbmltcG9ydCBBZGRyZXNzSXRlbSBmcm9tICcuL2FkZHJlc3NfaXRlbSc7XHJcbmltcG9ydCBVc2VyQWRkcmVzc2VzRGVmYXVsdCBmcm9tICcuL3VzZXJfYWRkcmVzc2VzX2RlZmF1bHQnO1xyXG5pbXBvcnQgVXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZSBmcm9tICcuLi9fc3RvcmVzL3VzZXJfZGVmYXVsdF9hZGRyZXNzZXNfc3RvcmUnO1xyXG5pbXBvcnQgVXNlckNvdW50cnlPcHRpb25zU3RvcmUgZnJvbSAnLi4vX3N0b3Jlcy91c2VyX2NvdW50cnlfb3B0aW9uc19zdG9yZSc7XHJcbmltcG9ydCBVc2VyQWRkcmVzc2VzQWRkSXRlbSBmcm9tICcuL2FkZHJlc3NfYWRkX2l0ZW0nO1xyXG5cclxuY29uc3QgZG9uZVR5cGluZ0ludGVydmFsID0gIDMwMDtcclxuXHJcbmNsYXNzIFVzZXJBZGRyZXNzZXNJdGVtIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcclxuXHRjb25zdHJ1Y3Rvcihwcm9wcykge1xyXG5cdFx0c3VwZXIocHJvcHMpO1xyXG5cdFx0dGhpcy5zdGF0ZSA9IHtcclxuXHRcdFx0YWRkcmVzc0l0ZW1zOiBbXSxcclxuXHRcdFx0YmlsbGluZ0FkZHJlc3NJdGVtczpbXSxcclxuXHRcdFx0Y291bnRyeU9wdGlvbnM6IFtdLFxyXG5cdFx0XHRpc1NhdmluZzogZmFsc2UsXHJcblx0XHRcdHJlc3VsdFN0YXR1czogbnVsbCxcclxuXHRcdFx0ZmlsdGVyTGlzdElzRW1wdHkgOiBmYWxzZSxcclxuXHRcdFx0ZmlsdGVyQmlsbGluZ0xpc3RJc0VtcHR5OiBmYWxzZSxcclxuXHRcdFx0aGlkZUVsZW1lbnRzOiB0cnVlLFxyXG5cdFx0XHRpc0JpZ0N1c3RvbWVyOiBmYWxzZVxyXG5cdFx0fTtcclxuXHRcdHRoaXMudHlwaW5nVGltZXIgPSBudWxsO1xyXG5cdH1cclxuXHJcblx0Y2xlYXJGaWx0ZXIoZSkge1xyXG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuXHRcdCQoJyNjbGVhci1zcGlubmVyJykuc2hvdygpO1xyXG5cdFx0JCgnI2NsZWFyLXRleHQnKS5oaWRlKCk7XHJcblx0XHRsZXQgZmlsdGVySW5wdXQgPSBSZWFjdERPTS5maW5kRE9NTm9kZSh0aGlzLnJlZnMuZmlsdGVyKTtcclxuXHRcdGZpbHRlcklucHV0LnZhbHVlID0gJyc7XHJcblx0XHRzZXRUaW1lb3V0KCgpID0+IHRoaXMuZG9uZVR5cGluZygnJyksIDEwMCk7XHJcblx0fVxyXG5cclxuXHRyZXNldEZpbHRlckFmdGVyTG9hZCgpe1xyXG5cdFx0bGV0IGZpbHRlcklucHV0ID0gUmVhY3RET00uZmluZERPTU5vZGUodGhpcy5yZWZzLmZpbHRlcik7XHJcblx0XHRmaWx0ZXJJbnB1dC52YWx1ZSA9ICcnO1xyXG5cdFx0dGhpcy5kb25lVHlwaW5nKCcnKTtcclxuXHR9XHJcblxyXG5cdGhhbmRsZUtleXVwKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmKHRoaXMudHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnR5cGluZ1RpbWVyKTtcclxuXHJcblx0XHRsZXQgdmFsdWUgPSBlLnRhcmdldC52YWx1ZTtcclxuXHQgIHRoaXMudHlwaW5nVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0dGhpcy5kb25lVHlwaW5nKHZhbHVlKTtcclxuXHRcdH0sIGRvbmVUeXBpbmdJbnRlcnZhbCk7XHJcblx0fVxyXG5cclxuXHRoYW5kbGVLZXlkb3duKGUpIHtcclxuXHRcdC8vIGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmKHRoaXMudHlwaW5nVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnR5cGluZ1RpbWVyKTtcclxuXHR9XHJcblxyXG5cdGRvbmVUeXBpbmcgKHZhbHVlKSB7XHJcblx0XHQkKCcudWMtdXNlci1hZGRyZXNzIGg0LmFsbCcpLmFkZENsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblxyXG5cdFx0dmFyIGFkZHJlc3NMaXN0ID0gVXNlckFkZHJlc3Nlc1N0b3JlLmdldEFkZHJlc3NlcygpO1xyXG5cdFx0dmFyIGJpbGxpbmdBZGRyZXNzTGlzdCA9IFVzZXJBZGRyZXNzZXNTdG9yZS5nZXRCaWxsaW5nQWRkcmVzc2VzKCk7XHJcblx0XHR2YXIgdXBkYXRlZEFkZHJlc3NMaXN0ID0gbnVsbDtcclxuXHRcdHZhciB1cGRhdGVkQmlsbGluZ0FkZHJlc3NMaXN0ID0gbnVsbDtcclxuXHJcblx0XHRpZih2YWx1ZS5sZW5ndGggPiAwICYmICF0aGlzLnN0YXRlLmlzQmlnQ3VzdG9tZXIpe1xyXG5cclxuXHRcdFx0JCgnLnNlYXJjaC1hZGRyZXNzZXMgYnV0dG9uJykuc2hvdygpO1xyXG5cclxuXHRcdFx0dXBkYXRlZEFkZHJlc3NMaXN0ID0gYWRkcmVzc0xpc3QuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pe1xyXG5cdCAgICAgIFx0XHRyZXR1cm4gaXRlbS5OYW1lLnRvTG93ZXJDYXNlKCkuc2VhcmNoKFxyXG5cdFx0XHRcdFx0dmFsdWUudG9Mb3dlckNhc2UoKSkgIT09IC0xO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xyXG5cdFx0XHRcdGFkZHJlc3NJdGVtczogdXBkYXRlZEFkZHJlc3NMaXN0LFxyXG5cdFx0XHRcdGJpbGxpbmdBZGRyZXNzSXRlbXM6IHVwZGF0ZWRCaWxsaW5nQWRkcmVzc0xpc3QsXHJcblx0XHRcdFx0ZmlsdGVyTGlzdElzRW1wdHk6IHVwZGF0ZWRBZGRyZXNzTGlzdC5sZW5ndGggPT09IDAsXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dGhpcy5mb3JjZVVwZGF0ZSgpO1xyXG5cclxuXHRcdH1lbHNlIGlmKHZhbHVlLmxlbmd0aCA+IDAgJiYgdGhpcy5zdGF0ZS5pc0JpZ0N1c3RvbWVyKXtcclxuXHJcblx0XHRcdCQoJy5zZWFyY2gtYWRkcmVzc2VzIGJ1dHRvbicpLnNob3coKTtcclxuXHRcdFx0dXBkYXRlZEFkZHJlc3NMaXN0ID0gYWRkcmVzc0xpc3QuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pe1xyXG5cdCAgICAgIFx0XHRyZXR1cm4gaXRlbS5OYW1lLnRvTG93ZXJDYXNlKCkuc2VhcmNoKFxyXG5cdFx0XHRcdFx0dmFsdWUudG9Mb3dlckNhc2UoKSkgIT09IC0xO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdHVwZGF0ZWRCaWxsaW5nQWRkcmVzc0xpc3QgPSBiaWxsaW5nQWRkcmVzc0xpc3QuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pe1xyXG5cdFx0XHRcdHJldHVybiBpdGVtLk5hbWUudG9Mb3dlckNhc2UoKS5zZWFyY2goXHJcblx0XHRcdFx0ICB2YWx1ZS50b0xvd2VyQ2FzZSgpKSAhPT0gLTE7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0YWRkcmVzc0l0ZW1zOiB1cGRhdGVkQWRkcmVzc0xpc3QsXHJcblx0XHRcdFx0YmlsbGluZ0FkZHJlc3NJdGVtczogdXBkYXRlZEJpbGxpbmdBZGRyZXNzTGlzdCxcclxuXHRcdFx0XHRmaWx0ZXJMaXN0SXNFbXB0eTogdXBkYXRlZEFkZHJlc3NMaXN0Lmxlbmd0aCA9PT0gMCxcclxuXHRcdFx0XHRmaWx0ZXJCaWxsaW5nTGlzdElzRW1wdHk6IHVwZGF0ZWRCaWxsaW5nQWRkcmVzc0xpc3QubGVuZ3RoID09PSAwXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dGhpcy5mb3JjZVVwZGF0ZSgpO1xyXG5cclxuXHRcdH1lbHNle1xyXG5cclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0YWRkcmVzc0l0ZW1zOiBhZGRyZXNzTGlzdCxcclxuXHRcdFx0XHRiaWxsaW5nQWRkcmVzc0l0ZW1zOiBiaWxsaW5nQWRkcmVzc0xpc3QsXHJcblx0XHRcdFx0ZmlsdGVyTGlzdElzRW1wdHk6IGZhbHNlLFxyXG5cdFx0XHRcdGZpbHRlckJpbGxpbmdMaXN0SXNFbXB0eTogZmFsc2VcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHR0aGlzLmZvcmNlVXBkYXRlKCk7XHJcblxyXG5cdFx0XHQkKCcuc2VhcmNoLWFkZHJlc3NlcyBidXR0b24nKS5oaWRlKCk7XHJcblx0XHRcdCQoJyNjbGVhci1zcGlubmVyJykuaGlkZSgpO1xyXG5cdFx0XHQkKCcjY2xlYXItdGV4dCcpLnNob3coKTtcclxuXHRcdH1cclxuXHRcdCQoJy51Yy11c2VyLWFkZHJlc3MgaDQuYWxsJykucmVtb3ZlQ2xhc3MoJ2lzLWxvYWRpbmcnKTtcclxuXHR9XHJcblxyXG5cclxuXHRoYW5kbGVTdWJtaXQgPSAoZSkgPT57XHJcblx0XHRsZXQgdmFsdWUgPSBlLnRhcmdldC52YWx1ZTtcclxuXHQgIHRoaXMudHlwaW5nVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0dGhpcy5kb25lVHlwaW5nKHZhbHVlKTtcclxuXHRcdH0sIGRvbmVUeXBpbmdJbnRlcnZhbCk7XHJcblx0fVxyXG5cclxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcclxuXHRcdC8vTG9hZCBjb250ZW50XHJcblx0XHRBZGRyZXNzQWN0aW9ucy5sb2FkQWRkcmVzc2VzKCk7XHJcblx0XHQkKCcudWMtdXNlci1hZGRyZXNzIGg0LmFsbCcpLmFkZENsYXNzKCdpcy1sb2FkaW5nJyk7XHJcblxyXG5cdFx0dGhpcy51bnN1YnNjcmliZSA9IFVzZXJBZGRyZXNzZXNTdG9yZS5saXN0ZW4oICgpID0+IHtcclxuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XHJcblx0XHRcdFx0YWRkcmVzc0l0ZW1zOiBVc2VyQWRkcmVzc2VzU3RvcmUuZ2V0QWRkcmVzc2VzKCksXHJcblx0XHRcdFx0YmlsbGluZ0FkZHJlc3NJdGVtczogVXNlckFkZHJlc3Nlc1N0b3JlLmdldEJpbGxpbmdBZGRyZXNzZXMoKSxcclxuXHRcdFx0XHRyZXN1bHRTdGF0dXM6IFVzZXJBZGRyZXNzZXNTdG9yZS5nZXRTdGF0dXMoKSxcclxuXHRcdFx0XHRjb3VudHJ5T3B0aW9uczogVXNlckFkZHJlc3Nlc1N0b3JlLmdldENvdW50cnlPcHRpb25zKCksXHJcblx0XHRcdFx0aGlkZUVsZW1lbnRzOiBmYWxzZSxcclxuXHRcdFx0XHRpc0JpZ0N1c3RvbWVyOiBVc2VyQWRkcmVzc2VzU3RvcmUuZ2V0Q3VzdG9tZXJUeXBlKClcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRVc2VyQ291bnRyeU9wdGlvbnNTdG9yZS5zZXRDb3VudHJ5T3B0aW9ucyh0aGlzLnN0YXRlLmNvdW50cnlPcHRpb25zKTtcclxuXHRcdFx0aWYodGhpcy5zdGF0ZS5yZXN1bHRTdGF0dXMgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuc3RhdGUucmVzdWx0U3RhdHVzICE9PSAndW5kZWZpbmVkJyl7XHJcblx0XHRcdFx0aWYoICQoJy5hZGQtbmV3LmFkZGluZycpLmxlbmd0aCA+IDApe1xyXG5cdFx0XHRcdFx0JCgnLmFkZC1uZXcnKS5yZW1vdmVDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cdFx0XHRcdFx0JCgnLmFkZC1uZXcnKS5yZW1vdmVDbGFzcygnYWRkaW5nJyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdCQoJyNhZGRyZXNzLW1lc3NhZ2UnKS5yZW1vdmVDbGFzcygnaGlkZScpO1xyXG5cdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHQkKCcjYWRkcmVzcy1tZXNzYWdlJykuYWRkQ2xhc3MoJ2hpZGUnKTtcclxuICAgICAgICB9LCAzNTAwKTtcclxuXHRcdFx0XHR0aGlzLnJlc2V0RmlsdGVyQWZ0ZXJMb2FkKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0JCgnLnVjLXVzZXItYWRkcmVzcyBoNC5hbGwnKS5yZW1vdmVDbGFzcygnaXMtbG9hZGluZycpO1xyXG5cclxuXHRcdFx0bGV0IGRlZmF1bHRBZGRyZXNzID0gXy5maW5kKFVzZXJBZGRyZXNzZXNTdG9yZS5nZXRBZGRyZXNzZXMoKSwgKG8pID0+IHsgcmV0dXJuIG8uSXNEZWZhdWx0OyB9KTtcclxuXHJcblx0XHRcdGlmKGRlZmF1bHRBZGRyZXNzKSB7XHJcblx0XHRcdFx0VXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZS5zZXREZWZhdWx0QWRkcmVzcyhkZWZhdWx0QWRkcmVzcyk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0VXNlckRlZmF1bHRBZGRyZXNzZXNTdG9yZS5zZXREZWZhdWx0QWRkcmVzcyhudWxsKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxuXHJcblx0Y29tcG9uZW50V2lsbFVubW91bnQoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlKCk7XHJcblx0fVxyXG5cclxuXHRyZW5kZXIoKSB7XHJcblx0XHRsZXQgcmVzdWx0U3RhdHVzID0gdGhpcy5zdGF0ZS5yZXN1bHRTdGF0dXM7XHJcblxyXG5cdFx0aWYoIXRoaXMuc3RhdGUuYWRkcmVzc0l0ZW1zKSByZXR1cm4gbnVsbDtcclxuXHRcdGxldCBhZGRyZXNzTGlzdCA9IHRoaXMuc3RhdGUuYWRkcmVzc0l0ZW1zO1xyXG5cclxuXHRcdGxldCBhZGRyZXNzZXMgPSBhZGRyZXNzTGlzdC5tYXAoIChhZGRyZXNzSXRlbSk9PntcclxuXHRcdFx0cmV0dXJuIChcclxuXHRcdFx0XHQ8QWRkcmVzc0l0ZW0ga2V5PXthZGRyZXNzSXRlbS5BZGRyZXNzSWR9IGlzQmlnQ3VzdG9tZXI9e3RoaXMuc3RhdGUuaXNCaWdDdXN0b21lcn0gaXRlbT17YWRkcmVzc0l0ZW19IGNvdW50cnlPcHRpb25zPXt0aGlzLnN0YXRlLmNvdW50cnlPcHRpb25zfS8+XHJcblx0XHRcdCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRsZXQgYmlsbGluZ0FkZHJlc3NlcyA9IG51bGw7XHJcblx0XHRsZXQgYmlnQ3VzdG9tZXJJbmZvID0gbnVsbDtcclxuXHJcblx0XHRpZih0aGlzLnN0YXRlLmlzQmlnQ3VzdG9tZXIpe1xyXG5cclxuXHRcdFx0aWYoIXRoaXMuc3RhdGUuYmlsbGluZ0FkZHJlc3NJdGVtcykgcmV0dXJuIG51bGw7XHJcblx0XHRcdGxldCBiaWxsaW5nQWRkcmVzc2VzTGlzdCA9IHRoaXMuc3RhdGUuYmlsbGluZ0FkZHJlc3NJdGVtcztcclxuXHJcblx0XHRcdGxldCBmaWx0ZXJCaWxsaW5nTWVzc2FnZUNsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdFx0J3VjLW1lc3NhZ2UnOiB0cnVlLFxyXG5cdFx0XHRcdCdhZGRyZXNzLXJlc3VsdC1tZXNzYWdlJzogdHJ1ZSxcclxuXHRcdFx0XHQnaW5mbyc6IHRydWUsXHJcblx0XHRcdFx0J2hpZGUnOiAhdGhpcy5zdGF0ZS5maWx0ZXJCaWxsaW5nTGlzdElzRW1wdHlcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRhZGRyZXNzZXMgPSA8ZGl2IGlkPVwidXNlci1zaGlwcGluZy1hZGRyZXNzXCIgY2xhc3NOYW1lPVwiYWRkcmVzcy1saXN0aW5nIGlzLW9wZW5cIj5cclxuXHRcdFx0XHRcdFx0XHR7YWRkcmVzc2VzfVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj47XHJcblxyXG5cdFx0XHRsZXQgZmluZEFkZHJlc3NJbmZvID0gaGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZy5maW5kQWRkcmVzc0luZm87XHJcblxyXG5cdFx0XHRiaWdDdXN0b21lckluZm8gPSA8ZGl2IGNsYXNzTmFtZT1cImNsZWFyZml4IGJpZy1jdXN0b21lci1pbmZvXCI+XHJcblx0XHRcdFx0PHA+XHJcblx0XHRcdFx0XHR7ZmluZEFkZHJlc3NJbmZvLnNsaWNlKDAsIGZpbmRBZGRyZXNzSW5mby5pbmRleE9mKCd7MH0nKSl9IDxhIGRhdGEtc2Nyb2xsLXRvPVwiLmFkZHJlc3MtdHlwZS10aXRsZS5zaGlwcGluZ1wiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLnNoaXBwaW5nQWRkcmVzc2VzfTxpIGNsYXNzTmFtZT1cImljb24tYW5nbGUtZG93blwiPjwvaT48L2E+XHJcblx0XHRcdFx0e2ZpbmRBZGRyZXNzSW5mby5zbGljZShmaW5kQWRkcmVzc0luZm8uaW5kZXhPZignezB9JykgKyAzLCBmaW5kQWRkcmVzc0luZm8uaW5kZXhPZignezF9JykpfSA8YSBkYXRhLXNjcm9sbC10bz1cIi5hZGRyZXNzLXR5cGUtdGl0bGUuYmlsbGluZ1wiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmJpbGxpbmdBZGRyZXNzZXN9PGkgY2xhc3NOYW1lPVwiaWNvbi1hbmdsZS1kb3duXCI+PC9pPjwvYT5cclxuXHRcdFx0e2ZpbmRBZGRyZXNzSW5mby5zbGljZShmaW5kQWRkcmVzc0luZm8uaW5kZXhPZignezF9JykgKyAzKX1cclxuXHRcdFx0XHQ8L3A+XHJcblx0XHRcdDwvZGl2PjtcclxuXHJcblx0XHRcdGJpbGxpbmdBZGRyZXNzZXMgPSB0aGlzLnN0YXRlLmJpbGxpbmdBZGRyZXNzSXRlbXMubWFwKCAoYWRkcmVzc0l0ZW0pPT57XHJcblx0XHRcdFx0cmV0dXJuIChcclxuXHRcdFx0XHRcdDxBZGRyZXNzSXRlbSBrZXk9e2FkZHJlc3NJdGVtLkFkZHJlc3NJZH0gaXNCaWdDdXN0b21lcj17dGhpcy5zdGF0ZS5pc0JpZ0N1c3RvbWVyfSBpdGVtPXthZGRyZXNzSXRlbX0gY291bnRyeU9wdGlvbnM9e3RoaXMuc3RhdGUuY291bnRyeU9wdGlvbnN9Lz5cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGJpbGxpbmdBZGRyZXNzZXMgPSA8ZGl2PlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImFkZHJlc3MtdHlwZS10aXRsZSBiaWxsaW5nXCI+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PGg0IGNsYXNzTmFtZT1cImFsbFwiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmFsbEJpbGxpbmdBZGRyZXNzZXN9PC9oND5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQ8YnV0dG9uIGlkPVwidG9nZ2xlLWJpbGxpbmctYWRkcmVzc1wiIGNsYXNzTmFtZT1cInNob3ctbW9yZSBhZGRyZXNzLWJvb2sgcm91bmQgYnV0dG9uIHJpZ2h0XCI+PHNwYW4gY2xhc3NOYW1lPVwic2hvd1wiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmhpZGVBbGx9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cImhpZGVcIj57aGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZy5zaG93QWxsfTwvc3Bhbj48L2J1dHRvbj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPXtmaWx0ZXJCaWxsaW5nTWVzc2FnZUNsYXNzfT5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQ8cD57aGlhYmNvbmZpZy5jaGVja291dC5sYW5nLm5vQWRkcmVzc2VzRm91bmR9PC9wPlxyXG5cdFx0XHRcdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PGRpdiBpZD1cInVzZXItYmlsbGluZy1hZGRyZXNzXCIgY2xhc3NOYW1lPVwiYWRkcmVzcy1saXN0aW5nIGlzLW9wZW5cIj5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7YmlsbGluZ0FkZHJlc3Nlc31cclxuXHRcdFx0XHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdFx0XHQ8L2Rpdj47XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHJlc3VsdE1lc3NhZ2UgPSBudWxsO1xyXG5cclxuXHRcdGlmKHJlc3VsdFN0YXR1cyA9PT0gdHJ1ZSl7XHJcblx0XHRcdHJlc3VsdE1lc3NhZ2UgPSA8ZGl2IGlkPVwiYWRkcmVzcy1tZXNzYWdlXCIgY2xhc3NOYW1lPVwidWMtbWVzc2FnZSBzdWNjZXNzIGFkZHJlc3MtcmVzdWx0LW1lc3NhZ2UgaGlkZVwiPlxyXG5cdFx0XHRcdDxwPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLnNhdmVkfTwvcD5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0cmVzdWx0TWVzc2FnZSA9IDxkaXYgaWQ9XCJhZGRyZXNzLW1lc3NhZ2VcIiBjbGFzc05hbWU9XCJ1Yy1tZXNzYWdlIGVycm9yIGFkZHJlc3MtcmVzdWx0LW1lc3NhZ2UgaGlkZVwiPlxyXG5cdFx0XHRcdDxwPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLm5vdFNhdmVkfTwvcD5cclxuXHRcdFx0PC9kaXY+XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IGZpbHRlck1lc3NhZ2VDbGFzcyA9IGNsYXNzTmFtZXMoe1xyXG5cdFx0XHQndWMtbWVzc2FnZSc6IHRydWUsXHJcblx0XHRcdCdhZGRyZXNzLXJlc3VsdC1tZXNzYWdlJzogdHJ1ZSxcclxuXHRcdFx0J2luZm8nOiB0cnVlLFxyXG5cdFx0XHQnaGlkZSc6ICF0aGlzLnN0YXRlLmZpbHRlckxpc3RJc0VtcHR5XHJcblx0XHR9KTtcclxuXHJcblx0XHRsZXQgc2VhcmNoQWRkcmVzc2VzQ2xhc3MgPSBjbGFzc05hbWVzKHtcclxuXHRcdFx0J3NlYXJjaC1hZGRyZXNzZXMtd3JhcHBlcic6IHRydWUsXHJcblx0XHRcdCdoaWRlJzogdGhpcy5zdGF0ZS5oaWRlRWxlbWVudHNcclxuXHRcdH0pO1xyXG5cdFx0bGV0IGFkZEFkZHJlc3Nlc0NsYXNzID0gY2xhc3NOYW1lcyh7XHJcblx0XHRcdCdoaWRlJzogdGhpcy5zdGF0ZS5oaWRlRWxlbWVudHMgfHwgdGhpcy5zdGF0ZS5pc0JpZ0N1c3RvbWVyXHJcblx0XHR9KTtcclxuXHJcblx0XHRyZXR1cm4oXHJcblx0XHRcdDxkaXY+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9e3NlYXJjaEFkZHJlc3Nlc0NsYXNzfT5cclxuXHRcdFx0XHRcdDxoZWFkZXI+XHJcblx0XHRcdFx0XHRcdDxoND57aGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZy5maW5kQWRkcmVzc2VzfTwvaDQ+XHJcblx0XHRcdFx0XHQ8L2hlYWRlcj5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwic2VhcmNoLWFkZHJlc3Nlc1wiPlxyXG5cdFx0XHRcdFx0XHQ8cD57aGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZy5maW5kQWRkcmVzc2VzSW5mb308L3A+XHJcblx0XHRcdFx0XHRcdDxmb3JtIGFjdGlvbj1cIlwiIG1ldGhvZD1cInBvc3RcIiBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXQuYmluZCh0aGlzKX0+XHJcblx0XHRcdFx0XHRcdFx0PGlucHV0IHJlZj0nZmlsdGVyJyB0eXBlPVwidGV4dFwiIG5hbWU9XCJtb2RlbC10cmVlLXNlYXJjaC10ZXh0XCIgb25LZXlVcD17dGhpcy5oYW5kbGVLZXl1cC5iaW5kKHRoaXMpfSBvbktleURvd249e3RoaXMuaGFuZGxlS2V5ZG93bi5iaW5kKHRoaXMpfSAvPlxyXG5cdFx0XHRcdFx0XHRcdDxidXR0b24gY2xhc3NOYW1lPVwicm91bmQgYnV0dG9uXCIgb25DbGljaz17dGhpcy5jbGVhckZpbHRlci5iaW5kKHRoaXMpfT48aSBpZD1cImNsZWFyLXNwaW5uZXJcIiBjbGFzc05hbWU9XCJoaWRlIGFuaW1hdGUtc3BpbiBpY29uLXNwaW40XCI+PC9pPjxzcGFuIGlkPVwiY2xlYXItdGV4dFwiPkNsZWFyPC9zcGFuPjwvYnV0dG9uPlxyXG5cdFx0XHRcdFx0XHQ8L2Zvcm0+XHJcblx0XHRcdFx0XHRcdHtiaWdDdXN0b21lckluZm99XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHR7cmVzdWx0TWVzc2FnZX1cclxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT17YWRkQWRkcmVzc2VzQ2xhc3N9PlxyXG5cdFx0XHRcdFx0PFVzZXJBZGRyZXNzZXNBZGRJdGVtIC8+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJhZGRyZXNzLXR5cGUtdGl0bGUgc2hpcHBpbmdcIj5cclxuXHRcdFx0XHRcdDxoNCBjbGFzc05hbWU9XCJhbGxcIj57dGhpcy5zdGF0ZS5pc0JpZ0N1c3RvbWVyID8gIGhpYWJjb25maWcuYWRkcmVzc2VzLmxhbmcuYWxsU2hpcHBpbmdBZGRyZXNzZXMgOiBoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmFsbEFkZHJlc3Nlc308L2g0PlxyXG5cdFx0XHRcdFx0e3RoaXMuc3RhdGUuaXNCaWdDdXN0b21lciA/IDxidXR0b24gaWQ9XCJ0b2dnbGUtc2hpcHBpbmctYWRkcmVzc1wiIGNsYXNzTmFtZT1cInNob3ctbW9yZSBhZGRyZXNzLWJvb2sgcm91bmQgYnV0dG9uIHJpZ2h0XCI+PHNwYW4gY2xhc3NOYW1lPVwic2hvd1wiPntoaWFiY29uZmlnLmFkZHJlc3Nlcy5sYW5nLmhpZGVBbGx9PC9zcGFuPjxzcGFuIGNsYXNzTmFtZT1cImhpZGVcIj57aGlhYmNvbmZpZy5hZGRyZXNzZXMubGFuZy5zaG93QWxsfTwvc3Bhbj48L2J1dHRvbj4gOiBudWxsfVxyXG5cdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPXtmaWx0ZXJNZXNzYWdlQ2xhc3N9PlxyXG5cdFx0XHRcdFx0PHA+e2hpYWJjb25maWcuY2hlY2tvdXQubGFuZy5ub0FkZHJlc3Nlc0ZvdW5kfTwvcD5cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHR7YWRkcmVzc2VzfVxyXG5cdFx0XHRcdHtiaWxsaW5nQWRkcmVzc2VzfVxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdCk7XHJcblxyXG5cdH1cclxufTtcclxuZXhwb3J0IGRlZmF1bHQgVXNlckFkZHJlc3Nlc0l0ZW07XHJcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXHJcbiIsImltcG9ydCAkIGZyb20gJ2pxdWVyeSc7XHJcbmltcG9ydCBmIGZyb20gJ2ZvdW5kYXRpb24nO1xyXG5pbXBvcnQgZl9vZmZjYW52YXMgZnJvbSAnZm91bmRhdGlvbi5vZmZjYW52YXMnO1xyXG5cclxubGV0IGZvdW5kYXRpb24gPSB7XHJcblx0aW5pdCgpIHtcclxuXHRcdHZhciBkYXRlZm9ybWF0ID0gaGlhYmNvbmZpZy5kYXRlcGlja2VyLmxhbmcuZm9ybWF0O1xyXG5cdFx0dmFyIGRhdGVwaWNrZXJkYXRlUmVnZXggPSBuZXcgUmVnRXhwKCdeJytkYXRlZm9ybWF0LnJlcGxhY2UoL3kvaWcsIFwiWzAtOV1cIikucmVwbGFjZSgvbW0vaWcsIFwiKCgwWzEtOV18MVswMTJdKXxbMS05XSlcIikucmVwbGFjZSgvbS9pZywgXCIoKDBbMS05XXwxWzAxMl0pfFsxLTldKVwiKS5yZXBsYWNlKC9kZC9pZywgXCIoKDBbMS05XXxbMTJdWzAtOV18M1swMV0pfFsxLTldKVwiKS5yZXBsYWNlKC9kL2lnLCBcIigoMFsxLTldfFsxMl1bMC05XXwzWzAxXSl8WzEtOV0pXCIpLnJlcGxhY2UoL1xcLy9nLCAnXFxcXC8nKS5yZXBsYWNlKC9cXC4vZywgJ1xcXFwuJykrJyQnKTtcclxuXHJcblx0XHQkKGRvY3VtZW50KS5mb3VuZGF0aW9uKHtcclxuXHRcdFx0YWJpZGUgOiB7XHJcblx0XHRcdFx0bGl2ZV92YWxpZGF0ZSA6IGZhbHNlLFxyXG5cdFx0ICAgIHZhbGlkYXRlX29uX2JsdXIgOiB0cnVlLFxyXG5cdFx0ICAgIGZvY3VzX29uX2ludmFsaWQgOiBmYWxzZSxcclxuXHRcdCAgICBlcnJvcl9sYWJlbHM6IHRydWUsXHJcblx0XHRcdFx0dGltZW91dCA6IDI1MCxcclxuXHRcdFx0XHRwYXR0ZXJuczoge1xyXG5cdFx0XHRcdFx0Y3VycmVuY3k6IC9eXFxkKyhcXC5cXGQrKSokLyxcclxuXHRcdFx0XHRcdG5hbWU6IC9eW2EtekEtWlxcc10qJC8sXHJcblx0XHRcdFx0XHR0ZXh0d2l0aG5vbmVuZ2xpc2hjaGFyczogL14oPyEuKi0tKVteXFxkXFxXXVtcXHUwMEJGLVxcdTFGRkZcXHUyQzAwLVxcdUQ3RkYtJyBhLXpBLVogXFwuXStbXFx1MDBCRi1cXHUxRkZGXFx1MkMwMC1cXHVEN0ZGYS16QS1aXVteXFxkXFxXXSokL2ksXHJcblx0XHRcdFx0XHRhZGRyZXNzOiAvXig/IS4qLS0pKD8hLioocG8gYm94fHAuby4gYm94fHAuIG8uIGJveHxwLm8ufHAub3xwLiBvLikpW1xcdTAwQkYtXFx1MUZGRlxcdTJDMDAtXFx1RDdGRi0sOicuIGEtekEtWjAtOV0rW1xcdTAwQkYtXFx1MUZGRlxcdTJDMDAtXFx1RDdGRmEtekEtWjAtOV1bXFx3Ll0qJC9pLFxyXG5cdFx0XHRcdFx0Y29tcGFueTogL14oPyEuKi0tKVtcXHUwMEJGLVxcdTFGRkZcXHUyQzAwLVxcdUQ3RkYtJyYsLiBcXHddK1tcXHUwMEJGLVxcdTFGRkZcXHUyQzAwLVxcdUQ3RkYtJyYsLiBcXHddW1xcdy5dKiQvaSwgXHJcblx0XHRcdFx0XHRwb3N0YWxjb2RlOiAvXlthLXpBLVowLTldKygtW2EtekEtWjAtOV0rKSokLyxcclxuXHRcdFx0XHRcdGNvdW50cnljb2RlOiAvXltBLVphLXpdezJ9JC8sXHJcblx0XHRcdFx0XHRwaG9uZTogL15bXmEtekEtWl17NSwxNX0kLyxcclxuXHRcdFx0XHRcdHNlbGZyZWdpc3RyYXRpb25waG9uZTogL14oXFwrfFxcKHswLDF9KSsoWzAtOS0oKSBdKXs1LDIwfVtcXGQpXSQvLFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdHNlcmlhbE51bWJlcjogL14oPyEuKi0tKVthLXpBLVowLTksLVxcc10rJC8sXHJcblx0XHRcdFx0XHRwYXNzd29yZHJlZzogL14oKD89LipbYS16XSkoPz0uKltBLVpdKSg/PS4qWzAtOV0pfCg/PS4qW2Etel0pKD89LipbQS1aXSkoPz0uKlshXCIjJCUmJygpKissLS5cXC86Ozw9Pj9AW1xcXFxcXF1eX2B7fH1+XSl8KD89LipbYS16XSkoPz0uKlswLTldKSg/PS4qWyFcIiMkJSYnKCkqKywtLlxcLzo7PD0+P0BbXFxcXFxcXV5fYHt8fX5dKXwoPz0uKltBLVpdKSg/PS4qWzAtOV0pKD89LipbIVwiIyQlJicoKSorLC0uXFwvOjs8PT4/QFtcXFxcXFxdXl9ge3x9fl0pKVthLXpBLVowLTkhXCIjJCUmJygpKissLS5cXC86Ozw9Pj9AW1xcXFxcXF1eX2B7fH1+XXs4LH0kLyxcclxuXHRcdFx0XHRcdGRhdGVwaWNrZXJkYXRlOiBkYXRlcGlja2VyZGF0ZVJlZ2V4LFxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vZmZjYW52YXNXcmFwcGVyID0gJCgnW2RhdGEtb2ZmY2FudmFzXScpO1xyXG5cdFx0dGhpcy5jbG9zZUJ0bnMgPSAkKCdbZGF0YS1vZmZjYW52YXMtY2xvc2VdJyk7XHJcblx0XHR0aGlzLmJpbmRPZmZjYW52YXNDbG9zZUV2ZW50KCk7XHJcblx0fSxcclxuXHJcblx0YmluZE9mZmNhbnZhc0Nsb3NlRXZlbnQoKSB7XHJcblx0XHR0aGlzLmNsb3NlQnRucy5vbignY2xpY2snLCB0aGlzLm9mZkNhbnZhc0Nsb3NlLmJpbmQodGhpcykpO1xyXG5cdH0sXHJcblxyXG5cdG9mZkNhbnZhc0Nsb3NlKGUpIHtcclxuXHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdHRoaXMub2ZmY2FudmFzV3JhcHBlci5yZW1vdmVDbGFzcygnbW92ZS1yaWdodCcpLnJlbW92ZUNsYXNzKCdtb3ZlLWxlZnQnKTtcclxuXHR9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZm91bmRhdGlvbjtcclxuIiwiKGZ1bmN0aW9uKCkge1xyXG4gIChmdW5jdGlvbigkKSB7XHJcbiAgICByZXR1cm4gJC5mbi5zdHVjayA9IGZ1bmN0aW9uKG9wdHMpIHtcclxuICAgICAgdmFyIFN0dWNrO1xyXG4gICAgICBTdHVjayA9IChmdW5jdGlvbigpIHtcclxuICAgICAgICBTdHVjay5wcm90b3R5cGUuZWxlbWVudHMgPSBbXTtcclxuXHJcbiAgICAgICAgU3R1Y2sucHJvdG90eXBlLnJlc2l6aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIFN0dWNrKHcsIG9wdHMpIHtcclxuICAgICAgICAgIHRoaXMud2luZG93ID0gdztcclxuICAgICAgICAgIHRoaXMuYm9keSA9ICQoXCJib2R5XCIpO1xyXG4gICAgICAgICAgdGhpcy5sb2FkRWxlbWVudHMoKTtcclxuICAgICAgICAgIHRoaXMuY2FsY3VsYXRlVG9wT2Zmc2V0KCk7XHJcbiAgICAgICAgICBpZiAodGhpcy5pc0lPUygpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYm9keS5vbih7XHJcbiAgICAgICAgICAgICAgdG91Y2htb3ZlOiAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICB9KSh0aGlzKVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMud2luZG93LnNjcm9sbCgoKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gX3RoaXMudXBkYXRlKCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICB9KSh0aGlzKSkpO1xyXG4gICAgICAgICAgdGhpcy53aW5kb3cucmVzaXplKCgoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgIHJldHVybiBfdGhpcy5yZXNpemUoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgIH0pKHRoaXMpKSk7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gICAgICAgICAgdGhpcztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIFN0dWNrLnByb3RvdHlwZS5pc0lPUyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2lzSU9TIHx8ICh0aGlzLl9pc0lPUyA9IC8oaVBhZHxpUGhvbmV8aVBvZCkvZy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBTdHVjay5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuY2FsY3VsYXRlVG9wT2Zmc2V0KCk7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFN0dWNrLnByb3RvdHlwZS5sb2FkRWxlbWVudHMgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIHZhciBjbGFzc2VzLCBjb250YWluZXIsIGRpdnMsIGksIG5hbWUsIG5vZGUsIHJlbGVhc2UsIHNwYWNlciwgdG9wLCB4LCB5O1xyXG4gICAgICAgICAgZGl2cyA9ICQoXCIuc3R1Y2tcIik7XHJcbiAgICAgICAgICBpID0gZGl2cy5sZW5ndGg7XHJcbiAgICAgICAgICB5ID0gMDtcclxuICAgICAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICAgICAgbm9kZSA9IGRpdnMuZXEoeSk7XHJcbiAgICAgICAgICAgIHkrKztcclxuICAgICAgICAgICAgcmVsZWFzZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb250YWluZXIgPSAnJztcclxuICAgICAgICAgICAgY2xhc3NlcyA9IG5vZGUuYXR0cihcImNsYXNzXCIpLnNwbGl0KC9cXHMrLyk7XHJcbiAgICAgICAgICAgIHNwYWNlciA9ICQoXCI8ZGl2Lz5cIik7XHJcbiAgICAgICAgICAgIHggPSBjbGFzc2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgd2hpbGUgKHgtLSkge1xyXG4gICAgICAgICAgICAgIG5hbWUgPSBjbGFzc2VzW3hdO1xyXG4gICAgICAgICAgICAgIGlmIChuYW1lID09PSBcInJlbGVhc2VcIikge1xyXG4gICAgICAgICAgICAgICAgcmVsZWFzZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXIgPSBub2RlLmNsb3Nlc3QoXCIucmVsZWFzZS1jb250YWluZXJcIik7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmICghKG5hbWUgPT09IFwic3R1Y2tcIiB8fCBuYW1lID09PSBcInJlbGVhc2VcIikpIHtcclxuICAgICAgICAgICAgICAgIHNwYWNlci5hZGRDbGFzcyhuYW1lKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3BhY2VyLmhlaWdodChub2RlLm91dGVySGVpZ2h0KCkpLmhpZGUoKS5jc3MoXCJiYWNrZ3JvdW5kLWNvbG9yXCIsIFwidHJhbnNwYXJlbnRcIikuYWRkQ2xhc3MoJ3NwYWNlcicpLmluc2VydEJlZm9yZShub2RlKTtcclxuICAgICAgICAgICAgdG9wID0gbm9kZS5vZmZzZXQoKS50b3AgLSBwYXJzZUludChub2RlLmNzcygnbWFyZ2luLXRvcCcpKTtcclxuICAgICAgICAgICAgdGhpcy5lbGVtZW50cy5wdXNoKHtcclxuICAgICAgICAgICAgICBub2RlOiBub2RlLFxyXG4gICAgICAgICAgICAgIHNwYWNlcjogc3BhY2VyLFxyXG4gICAgICAgICAgICAgIHRvcDogdG9wLFxyXG4gICAgICAgICAgICAgIHRvcF9vZmZzZXQ6IDAsXHJcbiAgICAgICAgICAgICAgZml4ZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgIHJlbGVhc2U6IHJlbGVhc2UsXHJcbiAgICAgICAgICAgICAgY29udGFpbmVyOiBjb250YWluZXIsXHJcbiAgICAgICAgICAgICAgY29udGFpbmVkOiBmYWxzZVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBTdHVjay5wcm90b3R5cGUuY2FsY3VsYXRlVG9wT2Zmc2V0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICB2YXIgY29sbGlkZV9mbGFnLCBjb2xsaWRlX3ksIGNvbGxpc2lvbiwgZWwsIGVsZW1lbnRzLCBpLCBtYXRyaXgsIG1heF9oZWlnaHQsIHJvd19lbGVtZW50LCB2YWx1ZSwgeCwgeSwgejtcclxuICAgICAgICAgIG1hdHJpeCA9IFtdO1xyXG4gICAgICAgICAgaSA9IHRoaXMuZWxlbWVudHMubGVuZ3RoO1xyXG4gICAgICAgICAgeCA9IDA7XHJcbiAgICAgICAgICB3aGlsZSAoaS0tKSB7XHJcbiAgICAgICAgICAgIGVsID0gdGhpcy5lbGVtZW50c1t4XTtcclxuICAgICAgICAgICAgeCsrO1xyXG4gICAgICAgICAgICB5ID0gbWF0cml4Lmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHkgPT09IDApIHtcclxuICAgICAgICAgICAgICBpZiAoIWVsLnJlbGVhc2UpIHtcclxuICAgICAgICAgICAgICAgIG1hdHJpeC5wdXNoKFtlbF0pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBjb2xsaWRlX2ZsYWcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICB3aGlsZSAoeS0tICYmICFjb2xsaWRlX2ZsYWcpIHtcclxuICAgICAgICAgICAgICAgIG1heF9oZWlnaHQgPSAwO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBtYXRyaXhbeV07XHJcbiAgICAgICAgICAgICAgICB6ID0gZWxlbWVudHMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKHotLSkge1xyXG4gICAgICAgICAgICAgICAgICByb3dfZWxlbWVudCA9IGVsZW1lbnRzW3pdO1xyXG4gICAgICAgICAgICAgICAgICBjb2xsaXNpb24gPSB0aGlzLmNvbGxpZGUocm93X2VsZW1lbnQubm9kZSwgZWwubm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChjb2xsaXNpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJvd19lbGVtZW50LnRvcF9vZmZzZXQgKyByb3dfZWxlbWVudC5ub2RlLm91dGVySGVpZ2h0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+IG1heF9oZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIG1heF9oZWlnaHQgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29sbGlkZV9mbGFnID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobWF0cml4W3kgKyAxXSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRlX3kgPSB5ICsgMTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29sbGlkZV95ID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh5ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRlX3kgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZiAoY29sbGlkZV9mbGFnKSB7XHJcbiAgICAgICAgICAgICAgICBlbC50b3Bfb2Zmc2V0ID0gbWF4X2hlaWdodDtcclxuICAgICAgICAgICAgICAgIGlmICghZWwucmVsZWFzZSkge1xyXG4gICAgICAgICAgICAgICAgICBpZiAoY29sbGlkZV95ID49IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXRyaXhbY29sbGlkZV95XS5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXRyaXgucHVzaChbZWxdKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBlbC50b3Bfb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgIGlmICghZWwucmVsZWFzZSkge1xyXG4gICAgICAgICAgICAgICAgICBtYXRyaXhbMF0ucHVzaChlbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgU3R1Y2sucHJvdG90eXBlLmNvbGxpZGUgPSBmdW5jdGlvbihub2RlMSwgbm9kZTIpIHtcclxuICAgICAgICAgIHZhciBuMWwsIG4ybDtcclxuICAgICAgICAgIG4xbCA9IG5vZGUxLm9mZnNldCgpLmxlZnQ7XHJcbiAgICAgICAgICBuMmwgPSBub2RlMi5vZmZzZXQoKS5sZWZ0O1xyXG4gICAgICAgICAgaWYgKG4xbCA9PT0gbjJsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChuMWwgPCBuMmwpIHtcclxuICAgICAgICAgICAgaWYgKE1hdGguZmxvb3IobjFsKSArIG5vZGUxLndpZHRoKCkgPiBNYXRoLmNlaWwobjJsKSkge1xyXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKE1hdGguZmxvb3IobjJsKSArIG5vZGUyLndpZHRoKCkgPiBNYXRoLmNlaWwobjFsKSkge1xyXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFN0dWNrLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIHZhciBlbCwgaSwgd2luZG93X3RvcDtcclxuICAgICAgICAgIHdpbmRvd190b3AgPSB0aGlzLndpbmRvdy5zY3JvbGxUb3AoKTtcclxuICAgICAgICAgIGkgPSB0aGlzLmVsZW1lbnRzLmxlbmd0aDtcclxuICAgICAgICAgIHdoaWxlIChpLS0pIHtcclxuICAgICAgICAgICAgZWwgPSB0aGlzLmVsZW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5yZXNpemluZykge1xyXG4gICAgICAgICAgICAgIGlmIChlbC5maXhlZCkge1xyXG4gICAgICAgICAgICAgICAgZWwudG9wID0gZWwuc3BhY2VyLm9mZnNldCgpLnRvcCAtIHBhcnNlSW50KGVsLnNwYWNlci5jc3MoJ21hcmdpbi10b3AnKSk7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGVsLnRvcCA9IGVsLm5vZGUub2Zmc2V0KCkudG9wIC0gcGFyc2VJbnQoZWwubm9kZS5jc3MoJ21hcmdpbi10b3AnKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmIChlbC5maXhlZCkge1xyXG4gICAgICAgICAgICAgICAgZWwubm9kZS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICB0b3A6IGVsLnRvcF9vZmZzZXQsXHJcbiAgICAgICAgICAgICAgICAgIGxlZnQ6IGVsLnNwYWNlci5vZmZzZXQoKS5sZWZ0LFxyXG4gICAgICAgICAgICAgICAgICB3aWR0aDogZWwuc3BhY2VyLm91dGVyV2lkdGgoKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmIChlbC5jb250YWluZWQgJiYgd2luZG93X3RvcCA+IChlbC5jb250YWluZXIub2Zmc2V0KCkudG9wICsgZWwuY29udGFpbmVyLmhlaWdodCgpIC0gZWwubm9kZS5oZWlnaHQoKSAtIGVsLnRvcF9vZmZzZXQpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRlbC5ub2RlLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXHJcbiAgICAgICAgICAgICAgICAgIHRvcDogZWwuY29udGFpbmVyLmhlaWdodCgpIC0gZWwubm9kZS5oZWlnaHQoKSxcclxuICAgICAgICAgICAgICAgICAgbGVmdDogJycsXHJcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiAnJyxcclxuICAgICAgICAgICAgICAgICAgXCJ6LWluZGV4XCI6ICcnXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGVsLmZpeGVkICYmIGVsLnJlbGVhc2UgJiYgIWVsLmNvbnRhaW5lZCAmJiB3aW5kb3dfdG9wID4gKGVsLmNvbnRhaW5lci5vZmZzZXQoKS50b3AgKyBlbC5jb250YWluZXIuaGVpZ2h0KCkgLSBlbC5ub2RlLmhlaWdodCgpIC0gZWwudG9wX29mZnNldCkpIHtcclxuXHRcdFx0XHRcdFx0XHRlbC5jb250YWluZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIGVsLmNvbnRhaW5lci5jc3MoXCJwb3NpdGlvblwiLCBcInJlbGF0aXZlXCIpO1xyXG4gICAgICAgICAgICAgIGVsLm5vZGUuY3NzKHtcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXHJcbiAgICAgICAgICAgICAgICB0b3A6IGVsLmNvbnRhaW5lci5oZWlnaHQoKSAtIGVsLm5vZGUuaGVpZ2h0KCksXHJcbiAgICAgICAgICAgICAgICBsZWZ0OiAnJyxcclxuICAgICAgICAgICAgICAgIHdpZHRoOiAnJyxcclxuICAgICAgICAgICAgICAgIFwiei1pbmRleFwiOiAnJ1xyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlbC5jb250YWluZWQgJiYgd2luZG93X3RvcCA8IChlbC5jb250YWluZXIub2Zmc2V0KCkudG9wICsgZWwuY29udGFpbmVyLmhlaWdodCgpIC0gZWwubm9kZS5oZWlnaHQoKSAtIGVsLnRvcF9vZmZzZXQpKSB7XHJcbiAgICAgICAgICAgICAgZWwuY29udGFpbmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgZWwuY29udGFpbmVyLmNzcyhcInBvc2l0aW9uXCIsICcnKTtcclxuICAgICAgICAgICAgICBlbC5ub2RlLmNzcyh7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogXCJmaXhlZFwiLFxyXG4gICAgICAgICAgICAgICAgdG9wOiBlbC50b3Bfb2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgbGVmdDogZWwuc3BhY2VyLm9mZnNldCgpLmxlZnQsXHJcbiAgICAgICAgICAgICAgICB3aWR0aDogZWwuc3BhY2VyLm91dGVyV2lkdGgoKSxcclxuICAgICAgICAgICAgICAgIFwiei1pbmRleFwiOiA5OVxyXG4gICAgICAgICAgICAgIH0pLmFkZENsYXNzKCdmaXhlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghZWwuZml4ZWQgJiYgd2luZG93X3RvcCA+IGVsLnRvcCAtIGVsLnRvcF9vZmZzZXQpIHtcclxuICAgICAgICAgICAgICBlbC5maXhlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgZWwuc3BhY2VyLnNob3coKTtcclxuICAgICAgICAgICAgICBlbC5ub2RlLmNzcyh7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogXCJmaXhlZFwiLFxyXG4gICAgICAgICAgICAgICAgdG9wOiBlbC50b3Bfb2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgbGVmdDogZWwuc3BhY2VyLm9mZnNldCgpLmxlZnQsXHJcbiAgICAgICAgICAgICAgICB3aWR0aDogZWwuc3BhY2VyLm91dGVyV2lkdGgoKSxcclxuICAgICAgICAgICAgICAgIFwiei1pbmRleFwiOiA5OVxyXG4gICAgICAgICAgICAgIH0pLmFkZENsYXNzKCdmaXhlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlbC5maXhlZCAmJiB3aW5kb3dfdG9wIDwgZWwudG9wIC0gZWwudG9wX29mZnNldCkge1xyXG4gICAgICAgICAgICAgIGVsLmZpeGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgZWwuc3BhY2VyLmhpZGUoKTtcclxuICAgICAgICAgICAgICBlbC5ub2RlLmNzcyh7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogXCJyZWxhdGl2ZVwiLFxyXG4gICAgICAgICAgICAgICAgdG9wOiAnJyxcclxuICAgICAgICAgICAgICAgIGxlZnQ6ICcnLFxyXG4gICAgICAgICAgICAgICAgd2lkdGg6ICcnLFxyXG4gICAgICAgICAgICAgICAgXCJ6LWluZGV4XCI6ICcnXHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBTdHVjay5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICBpID0gdGhpcy5lbGVtZW50cy5sZW5ndGg7XHJcbiAgICAgICAgICB3aGlsZSAoaS0tKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudHNbaV0uc3BhY2VyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy53aW5kb3cudW5iaW5kKCdzY3JvbGwnKTtcclxuICAgICAgICAgIHRoaXMud2luZG93LnVuYmluZCgncmVzaXplJyk7XHJcbiAgICAgICAgICB0aGlzLndpbmRvdyA9IHRoaXMuZWxlbWVudHMgPSBudWxsO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBTdHVjaztcclxuXHJcbiAgICAgIH0pKCk7XHJcbiAgICAgIHJldHVybiBuZXcgU3R1Y2sodGhpcywgb3B0cyk7XHJcbiAgICB9O1xyXG4gIH0pKGpRdWVyeSk7XHJcblxyXG59KS5jYWxsKHRoaXMpO1xyXG4iXX0=
;
